From 2f1dc912117f91443d912961e3f16df71ee11529 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 14 Dec 2021 11:30:42 +0900 Subject: [PATCH 1/3] Add AbortLoad() method to abort gameplay loads --- .../Multiplayer/IMultiplayerRoomServer.cs | 5 +++++ .../Online/Multiplayer/MultiplayerClient.cs | 2 ++ .../Multiplayer/OnlineMultiplayerClient.cs | 8 +++++++ .../OnlinePlay/Multiplayer/Multiplayer.cs | 21 +++++++++++++++++-- .../Multiplayer/TestMultiplayerClient.cs | 15 +++++++++++++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs b/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs index 73fda78d00..200539def7 100644 --- a/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs +++ b/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs @@ -77,6 +77,11 @@ namespace osu.Game.Online.Multiplayer /// If an attempt to start the game occurs when the game's (or users') state disallows it. Task StartMatch(); + /// + /// Aborts an ongoing gameplay load. + /// + Task AbortLoad(); + /// /// Adds an item to the playlist. /// diff --git a/osu.Game/Online/Multiplayer/MultiplayerClient.cs b/osu.Game/Online/Multiplayer/MultiplayerClient.cs index 55b4def908..78d8362170 100644 --- a/osu.Game/Online/Multiplayer/MultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/MultiplayerClient.cs @@ -333,6 +333,8 @@ namespace osu.Game.Online.Multiplayer public abstract Task StartMatch(); + public abstract Task AbortLoad(); + public abstract Task AddPlaylistItem(MultiplayerPlaylistItem item); public abstract Task EditPlaylistItem(MultiplayerPlaylistItem item); diff --git a/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs b/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs index d268d2bf69..3062cf8b99 100644 --- a/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs @@ -154,6 +154,14 @@ namespace osu.Game.Online.Multiplayer return connection.InvokeAsync(nameof(IMultiplayerServer.StartMatch)); } + public override Task AbortLoad() + { + if (!IsConnected.Value) + return Task.CompletedTask; + + return connection.InvokeAsync(nameof(IMultiplayerServer.AbortLoad)); + } + public override Task AddPlaylistItem(MultiplayerPlaylistItem item) { if (!IsConnected.Value) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs index 58b5b7bbeb..c299fd285a 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Screens; using osu.Game.Online.Multiplayer; @@ -18,8 +19,24 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer { base.OnResuming(last); - if (client.Room != null && client.LocalUser?.State != MultiplayerUserState.Spectating) - client.ChangeState(MultiplayerUserState.Idle); + if (client.Room == null) + return; + + Debug.Assert(client.LocalUser != null); + + switch (client.LocalUser.State) + { + case MultiplayerUserState.Spectating: + break; + + case MultiplayerUserState.WaitingForLoad: + client.AbortLoad(); + break; + + default: + client.ChangeState(MultiplayerUserState.Idle); + break; + } } protected override string ScreenTitle => "Multiplayer"; diff --git a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs index d22f0415e6..c928cfd137 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs @@ -242,6 +242,11 @@ namespace osu.Game.Tests.Visual.Multiplayer public override Task ChangeState(MultiplayerUserState newState) { + Debug.Assert(Room != null); + + if (newState == MultiplayerUserState.Idle && LocalUser?.State == MultiplayerUserState.WaitingForLoad) + return Task.CompletedTask; + ChangeUserState(api.LocalUser.Value.Id, newState); return Task.CompletedTask; } @@ -303,6 +308,16 @@ namespace osu.Game.Tests.Visual.Multiplayer return ((IMultiplayerClient)this).LoadRequested(); } + public override Task AbortLoad() + { + Debug.Assert(Room != null); + Debug.Assert(LocalUser != null); + + ChangeUserState(LocalUser.UserID, MultiplayerUserState.Idle); + + return Task.CompletedTask; + } + public async Task AddUserPlaylistItem(int userId, MultiplayerPlaylistItem item) { Debug.Assert(Room != null); From 750bfae9092095881432f0ab35eee1bbcbf068a5 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 14 Dec 2021 11:35:56 +0900 Subject: [PATCH 2/3] Fix TestMultiplayerClient not handling all users bailing from gameplay --- .../Tests/Visual/Multiplayer/TestMultiplayerClient.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs index c928cfd137..4c69f8f9d2 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs @@ -128,6 +128,15 @@ namespace osu.Game.Tests.Visual.Multiplayer case MultiplayerRoomState.WaitingForLoad: if (Room.Users.All(u => u.State != MultiplayerUserState.WaitingForLoad)) { + var loadedUsers = Room.Users.Where(u => u.State == MultiplayerUserState.Loaded).ToArray(); + + if (loadedUsers.Length == 0) + { + // all users have bailed from the load sequence. cancel the game start. + ChangeRoomState(MultiplayerRoomState.Open); + return; + } + foreach (var u in Room.Users.Where(u => u.State == MultiplayerUserState.Loaded)) ChangeUserState(u.UserID, MultiplayerUserState.Playing); @@ -143,8 +152,8 @@ namespace osu.Game.Tests.Visual.Multiplayer { foreach (var u in Room.Users.Where(u => u.State == MultiplayerUserState.FinishedPlay)) ChangeUserState(u.UserID, MultiplayerUserState.Results); - ChangeRoomState(MultiplayerRoomState.Open); + ChangeRoomState(MultiplayerRoomState.Open); ((IMultiplayerClient)this).ResultsReady(); FinishCurrentItem().Wait(); From 9ade8069a1b7ded46328c023eeb119e26900d1ce Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 14 Dec 2021 16:52:57 +0900 Subject: [PATCH 3/3] Rename to AbortGameplay() and handle additional states --- osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs | 2 +- osu.Game/Online/Multiplayer/MultiplayerClient.cs | 2 +- osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs | 4 ++-- osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs | 4 +++- osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs b/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs index 200539def7..073d512f90 100644 --- a/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs +++ b/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs @@ -80,7 +80,7 @@ namespace osu.Game.Online.Multiplayer /// /// Aborts an ongoing gameplay load. /// - Task AbortLoad(); + Task AbortGameplay(); /// /// Adds an item to the playlist. diff --git a/osu.Game/Online/Multiplayer/MultiplayerClient.cs b/osu.Game/Online/Multiplayer/MultiplayerClient.cs index 78d8362170..ffb9e193d4 100644 --- a/osu.Game/Online/Multiplayer/MultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/MultiplayerClient.cs @@ -333,7 +333,7 @@ namespace osu.Game.Online.Multiplayer public abstract Task StartMatch(); - public abstract Task AbortLoad(); + public abstract Task AbortGameplay(); public abstract Task AddPlaylistItem(MultiplayerPlaylistItem item); diff --git a/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs b/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs index 3062cf8b99..73b87190b1 100644 --- a/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs @@ -154,12 +154,12 @@ namespace osu.Game.Online.Multiplayer return connection.InvokeAsync(nameof(IMultiplayerServer.StartMatch)); } - public override Task AbortLoad() + public override Task AbortGameplay() { if (!IsConnected.Value) return Task.CompletedTask; - return connection.InvokeAsync(nameof(IMultiplayerServer.AbortLoad)); + return connection.InvokeAsync(nameof(IMultiplayerServer.AbortGameplay)); } public override Task AddPlaylistItem(MultiplayerPlaylistItem item) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs index c299fd285a..e136627d43 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs @@ -30,7 +30,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer break; case MultiplayerUserState.WaitingForLoad: - client.AbortLoad(); + case MultiplayerUserState.Loaded: + case MultiplayerUserState.Playing: + client.AbortGameplay(); break; default: diff --git a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs index 4c69f8f9d2..767751a808 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs @@ -317,7 +317,7 @@ namespace osu.Game.Tests.Visual.Multiplayer return ((IMultiplayerClient)this).LoadRequested(); } - public override Task AbortLoad() + public override Task AbortGameplay() { Debug.Assert(Room != null); Debug.Assert(LocalUser != null);