diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index 4521a7fa0f..2411f39ae3 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -397,6 +397,44 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("user state is idle", () => client.LocalUser?.State == MultiplayerUserState.Idle); } + [Test] + public void TestPlayStartsWithCorrectBeatmapWhileAtSongSelect() + { + createRoom(() => new Room + { + Name = { Value = "Test Room" }, + Playlist = + { + new PlaylistItem + { + Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo }, + Ruleset = { Value = new OsuRuleset().RulesetInfo }, + } + } + }); + + AddStep("Enter song select", () => + { + var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerScreenStack.CurrentScreen).CurrentSubScreen; + + ((MultiplayerMatchSubScreen)currentSubScreen).SelectBeatmap(); + }); + + AddUntilStep("wait for song select", () => this.ChildrenOfType().FirstOrDefault()?.BeatmapSetsLoaded == true); + + AddAssert("Beatmap matches current item", () => Beatmap.Value.BeatmapInfo.OnlineID == client.Room?.Playlist.First().BeatmapID); + + AddStep("Select next beatmap", () => InputManager.Key(Key.Down)); + + AddUntilStep("Beatmap doesn't match current item", () => Beatmap.Value.BeatmapInfo.OnlineID != client.Room?.Playlist.First().BeatmapID); + + AddStep("start match externally", () => client.StartMatch()); + + AddUntilStep("play started", () => multiplayerScreenStack.CurrentScreen is Player); + + AddAssert("Beatmap matches current item", () => Beatmap.Value.BeatmapInfo.OnlineID == client.Room?.Playlist.First().BeatmapID); + } + [Test] public void TestLocalPlayDoesNotStartWhileSpectatingWithNoBeatmap() { diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 7c5ed3f5cc..184ac2c563 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -319,6 +319,16 @@ namespace osu.Game.Screens.OnlinePlay.Match protected void StartPlay() { + // User may be at song select or otherwise when the host starts gameplay. + // Ensure that they first return to this screen, else global bindables (beatmap etc.) may be in a bad state. + if (!this.IsCurrentScreen()) + { + this.MakeCurrent(); + + Schedule(StartPlay); + return; + } + sampleStart?.Play(); // fallback is to allow this class to operate when there is no parent OnlineScreen (testing purposes). diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 16017a1f0e..3a25bd7b06 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -138,11 +138,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer { RelativeSizeAxes = Axes.X, Height = 40, - Action = () => - { - if (this.IsCurrentScreen()) - this.Push(new MultiplayerMatchSongSelect(Room)); - }, + Action = SelectBeatmap, Alpha = 0 }, }, @@ -224,6 +220,14 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer } }; + internal void SelectBeatmap() + { + if (!this.IsCurrentScreen()) + return; + + this.Push(new MultiplayerMatchSongSelect(Room)); + } + protected override Drawable CreateFooter() => new MultiplayerMatchFooter { OnReadyClick = onReadyClick,