From 4adb8c205f7523768f741c2b6d80f0aaa04fdf8a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 18 Mar 2022 07:18:49 +0300 Subject: [PATCH 1/8] Add step to switch hosts randomly in `TestManyUsers` --- .../Multiplayer/TestSceneMultiplayerParticipantsList.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs index 292319171d..bc3bce4b3f 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs @@ -202,9 +202,11 @@ namespace osu.Game.Tests.Visual.Multiplayer [Test] public void TestManyUsers() { + const int users_count = 20; + AddStep("add many users", () => { - for (int i = 0; i < 20; i++) + for (int i = 0; i < users_count; i++) { MultiplayerClient.AddUser(new APIUser { @@ -243,6 +245,8 @@ namespace osu.Game.Tests.Visual.Multiplayer } } }); + + AddRepeatStep("switch hosts", () => MultiplayerClient.TransferHost(RNG.Next(0, users_count)), 10); } [Test] From 1c899d00b92cdea921fcad9ea15cf33fbc839064 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 18 Mar 2022 07:25:03 +0300 Subject: [PATCH 2/8] Pin multiplayer host panel to the top of the list --- .../Multiplayer/Participants/ParticipantsList.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs index afb2111023..6169ad6a9e 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -15,6 +16,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants { private FillFlowContainer panels; + [CanBeNull] + private ParticipantPanel currentHostPanel; + [BackgroundDependencyLoader] private void load() { @@ -55,6 +59,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants // Add panels for all users new to the room. foreach (var user in Room.Users.Except(panels.Select(p => p.User))) panels.Add(new ParticipantPanel(user)); + + if (currentHostPanel == null || !currentHostPanel.User.Equals(Room.Host)) + { + // Reset position of previous host back to normal, if one existing. + if (currentHostPanel != null && panels.Contains(currentHostPanel)) + panels.SetLayoutPosition(currentHostPanel, 0); + + // Change position of new host to display above all participants. + panels.SetLayoutPosition(currentHostPanel = panels.Single(u => u.User.Equals(Room.Host)), -1); + } } } } From 98b420ee6f2b256aa6e70847751fe311739b2572 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 18 Mar 2022 07:25:10 +0300 Subject: [PATCH 3/8] Remove no longer correct crown fade animation Since the host is pinned to the top without any animation, it would look jarring for the crown to fade away from the old panel (and at a 50ms duration). --- .../OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs index 96a665f33d..11dba2e52d 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs @@ -206,10 +206,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants else kickButton.FadeOut(fade_time); - if (Room.Host?.Equals(User) == true) - crown.FadeIn(fade_time); - else - crown.FadeOut(fade_time); + crown.Alpha = Room.Host?.Equals(User) == true ? 1 : 0; // If the mods are updated at the end of the frame, the flow container will skip a reflow cycle: https://github.com/ppy/osu-framework/issues/4187 // This looks particularly jarring here, so re-schedule the update to that start of our frame as a fix. From d0cc68bc97ade2891f3e1ee767588d0946b27507 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 18 Mar 2022 07:26:10 +0300 Subject: [PATCH 4/8] Add test coverage --- .../TestSceneMultiplayerParticipantsList.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs index bc3bce4b3f..50faa0a567 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs @@ -163,6 +163,25 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("second user crown visible", () => this.ChildrenOfType().ElementAt(1).ChildrenOfType().First().Alpha == 1); } + [Test] + public void TestHostGetsPinnedToTop() + { + AddStep("add user", () => MultiplayerClient.AddUser(new APIUser + { + Id = 3, + Username = "Second", + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg", + })); + + AddStep("make second user host", () => MultiplayerClient.TransferHost(3)); + AddAssert("second user above first", () => + { + var first = this.ChildrenOfType().ElementAt(0); + var second = this.ChildrenOfType().ElementAt(1); + return second.Y < first.Y; + }); + } + [Test] public void TestKickButtonOnlyPresentWhenHost() { From a7ddfc7f519d2b3583814425071eccf1d4c8d5d2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 18 Mar 2022 08:08:31 +0300 Subject: [PATCH 5/8] Add step for returning host back to local user --- .../Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs index 50faa0a567..8da077cd44 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs @@ -266,6 +266,7 @@ namespace osu.Game.Tests.Visual.Multiplayer }); AddRepeatStep("switch hosts", () => MultiplayerClient.TransferHost(RNG.Next(0, users_count)), 10); + AddStep("give host back", () => MultiplayerClient.TransferHost(API.LocalUser.Value.Id)); } [Test] From 1bd08b4a4b02499a7aed551d338494d3dd0952f6 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 18 Mar 2022 08:08:45 +0300 Subject: [PATCH 6/8] Remove kick button fading as well to not look jarring --- .../OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs index 11dba2e52d..e95ca4de32 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs @@ -201,11 +201,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants else userModsDisplay.FadeOut(fade_time); - if (Client.IsHost && !User.Equals(Client.LocalUser)) - kickButton.FadeIn(fade_time); - else - kickButton.FadeOut(fade_time); - + kickButton.Alpha = Client.IsHost && !User.Equals(Client.LocalUser) ? 1 : 0; crown.Alpha = Room.Host?.Equals(User) == true ? 1 : 0; // If the mods are updated at the end of the frame, the flow container will skip a reflow cycle: https://github.com/ppy/osu-framework/issues/4187 From 0adad3a599904f62a9f7908ae85b678c1b83e0c8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 19 Mar 2022 04:01:35 +0300 Subject: [PATCH 7/8] Handle potential null room hosts --- .../OnlinePlay/Multiplayer/Participants/ParticipantsList.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs index 6169ad6a9e..22c9940cd4 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs @@ -66,8 +66,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants if (currentHostPanel != null && panels.Contains(currentHostPanel)) panels.SetLayoutPosition(currentHostPanel, 0); + currentHostPanel = null; + // Change position of new host to display above all participants. - panels.SetLayoutPosition(currentHostPanel = panels.Single(u => u.User.Equals(Room.Host)), -1); + if (Room.Host != null) + panels.SetLayoutPosition(currentHostPanel = panels.SingleOrDefault(u => u.User.Equals(Room.Host)), -1); } } } From 9afe82a0d522adb13b9c58dc40c95fbbd66e9403 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 19 Mar 2022 14:54:58 +0300 Subject: [PATCH 8/8] Fix potentially null drawable call to `SetLayoutPosition` --- .../Multiplayer/Participants/ParticipantsList.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs index 22c9940cd4..14b930f115 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs @@ -70,7 +70,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants // Change position of new host to display above all participants. if (Room.Host != null) - panels.SetLayoutPosition(currentHostPanel = panels.SingleOrDefault(u => u.User.Equals(Room.Host)), -1); + { + currentHostPanel = panels.SingleOrDefault(u => u.User.Equals(Room.Host)); + + if (currentHostPanel != null) + panels.SetLayoutPosition(currentHostPanel, -1); + } } } }