From ad35f3434b210de9de114b88516cf192311fe3e3 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 1 Dec 2021 20:53:29 +0900 Subject: [PATCH] Fix queue list not considering expired items --- .../TestSceneMultiplayerQueueList.cs | 8 ++-- .../Match/Playlist/MultiplayerQueueList.cs | 37 ++++++++++++------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs index 2e24d54b59..efb4a395f4 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs @@ -15,13 +15,13 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerQueueList : OsuTestScene + public class TestSceneMultiplayerQueueList : MultiplayerTestScene { private MultiplayerQueueList list; private int currentItemId; [SetUp] - public void Setup() => Schedule(() => + public new void Setup() => Schedule(() => { Child = list = new MultiplayerQueueList { @@ -34,8 +34,10 @@ namespace osu.Game.Tests.Visual.Multiplayer }); [SetUpSteps] - public void SetUpSteps() + public override void SetUpSteps() { + base.SetUpSteps(); + // Not inside a step since this is used to affect steps added by the current test. currentItemId = 0; } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs index c1bc60becc..9184cf6aba 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -35,6 +36,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist { public readonly IBindable QueueMode = new Bindable(); + [Resolved(typeof(Room), nameof(Room.Playlist))] + private BindableList roomPlaylist { get; set; } + protected override void LoadComplete() { base.LoadComplete(); @@ -53,20 +57,25 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist .OrderBy(item => item.Model.ID); case Game.Online.Multiplayer.QueueMode.AllPlayersRoundRobin: - RearrangeableListItem[] allItems = AliveInternalChildren - .Where(d => d.IsPresent) - .OfType>() - .OrderBy(item => item.Model.ID) - .ToArray(); + RearrangeableListItem[] items = AliveInternalChildren + .Where(d => d.IsPresent) + .OfType>() + .OrderBy(item => item.Model.ID) + .ToArray(); - int totalCount = allItems.Length; + int totalCount = items.Length; if (totalCount == 0) return Enumerable.Empty(); - Dictionary perUserCounts = allItems - .Select(item => item.Model.OwnerID) - .Distinct() - .ToDictionary(u => u, _ => 0); + // Count of "expired" items per user. + Dictionary perUserCounts = roomPlaylist + .Where(item => item.Expired) + .GroupBy(item => item.OwnerID) + .ToDictionary(group => group.Key, group => group.Count()); + + // Fill the count dictionary with zeroes for all users with no currently expired items. + foreach (var item in items) + perUserCounts.TryAdd(item.Model.OwnerID, 0); List result = new List(); @@ -76,16 +85,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist // Todo: This could probably be more efficient, likely at the cost of increased complexity. while (totalCount-- > 0) { - var candidateItem = allItems + var candidateItem = items .Where(item => item != null) .OrderBy(item => perUserCounts[item.Model.OwnerID]) .First(); - int itemIndex = Array.IndexOf(allItems, candidateItem); + int itemIndex = Array.IndexOf(items, candidateItem); - result.Add(allItems[itemIndex]); + result.Add(items[itemIndex]); perUserCounts[candidateItem.Model.OwnerID]++; - allItems[itemIndex] = null; + items[itemIndex] = null; } return result;