diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs
index 3d04ae8f3c..9269433ac5 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs
@@ -219,19 +219,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
protected override void StartGameplay(int userId, SpectatorGameplayState spectatorGameplayState)
=> instances.Single(i => i.UserId == userId).LoadScore(spectatorGameplayState.Score);
- protected override void EndGameplay(int userId, SpectatorState state)
+ protected override void QuitGameplay(int userId)
{
- // Allowed passed/failed users to complete their remaining replay frames.
- // The failed state isn't really possible in multiplayer (yet?) but is added here just for safety in case it starts being used.
- if (state.State == SpectatedUserState.Passed || state.State == SpectatedUserState.Failed)
- return;
-
- // we could also potentially receive EndGameplay with "Playing" state, at which point we can only early-return and hope it's a passing player.
- // todo: this shouldn't exist, but it's here as a hotfix for an issue with multi-spectator screen not proceeding to results screen.
- // see: https://github.com/ppy/osu/issues/19593
- if (state.State == SpectatedUserState.Playing)
- return;
-
RemoveUser(userId);
var instance = instances.Single(i => i.UserId == userId);
diff --git a/osu.Game/Screens/Play/SoloSpectator.cs b/osu.Game/Screens/Play/SoloSpectator.cs
index 7eaba40640..9ef05c3a05 100644
--- a/osu.Game/Screens/Play/SoloSpectator.cs
+++ b/osu.Game/Screens/Play/SoloSpectator.cs
@@ -182,7 +182,7 @@ namespace osu.Game.Screens.Play
scheduleStart(spectatorGameplayState);
}
- protected override void EndGameplay(int userId, SpectatorState state)
+ protected override void QuitGameplay(int userId)
{
scheduledStart?.Cancel();
immediateSpectatorGameplayState = null;
diff --git a/osu.Game/Screens/Spectate/SpectatorScreen.cs b/osu.Game/Screens/Spectate/SpectatorScreen.cs
index 8218ddf641..7081db4793 100644
--- a/osu.Game/Screens/Spectate/SpectatorScreen.cs
+++ b/osu.Game/Screens/Spectate/SpectatorScreen.cs
@@ -142,9 +142,11 @@ namespace osu.Game.Screens.Spectate
break;
case SpectatedUserState.Passed:
- case SpectatedUserState.Failed:
+ markReceivedAllFrames(userId);
+ break;
+
case SpectatedUserState.Quit:
- endGameplay(userId, newState);
+ quitGameplay(userId);
break;
}
}
@@ -182,18 +184,27 @@ namespace osu.Game.Screens.Spectate
Schedule(() => StartGameplay(userId, gameplayState));
}
- private void endGameplay(int userId, SpectatorState state)
+ ///
+ /// Marks an existing gameplay session as received all frames.
+ ///
+ private void markReceivedAllFrames(int userId)
+ {
+ if (gameplayStates.TryGetValue(userId, out var gameplayState))
+ gameplayState.Score.Replay.HasReceivedAllFrames = true;
+ }
+
+ private void quitGameplay(int userId)
{
if (!userMap.ContainsKey(userId))
return;
- if (!gameplayStates.TryGetValue(userId, out var gameplayState))
+ if (!gameplayStates.ContainsKey(userId))
return;
- gameplayState.Score.Replay.HasReceivedAllFrames = true;
+ markReceivedAllFrames(userId);
gameplayStates.Remove(userId);
- Schedule(() => EndGameplay(userId, state));
+ Schedule(() => QuitGameplay(userId));
}
///
@@ -211,11 +222,10 @@ namespace osu.Game.Screens.Spectate
protected abstract void StartGameplay(int userId, [NotNull] SpectatorGameplayState spectatorGameplayState);
///
- /// Ends gameplay for a user.
+ /// Quits gameplay for a user.
///
- /// The user to end gameplay for.
- /// The final user state.
- protected abstract void EndGameplay(int userId, SpectatorState state);
+ /// The user to quit gameplay for.
+ protected abstract void QuitGameplay(int userId);
///
/// Stops spectating a user.
@@ -223,10 +233,10 @@ namespace osu.Game.Screens.Spectate
/// The user to stop spectating.
protected void RemoveUser(int userId)
{
- if (!userStates.TryGetValue(userId, out var state))
+ if (!userStates.ContainsKey(userId))
return;
- endGameplay(userId, state);
+ quitGameplay(userId);
users.Remove(userId);
userMap.Remove(userId);