1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 22:22:54 +08:00

Separate passed/failed states from calling EndGameplay

This commit is contained in:
Salman Ahmed 2022-08-08 01:37:43 +03:00
parent 2fa8b61f3c
commit 8f4a2b4936
3 changed files with 24 additions and 25 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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)
/// <summary>
/// Marks an existing gameplay session as received all frames.
/// </summary>
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));
}
/// <summary>
@ -211,11 +222,10 @@ namespace osu.Game.Screens.Spectate
protected abstract void StartGameplay(int userId, [NotNull] SpectatorGameplayState spectatorGameplayState);
/// <summary>
/// Ends gameplay for a user.
/// Quits gameplay for a user.
/// </summary>
/// <param name="userId">The user to end gameplay for.</param>
/// <param name="state">The final user state.</param>
protected abstract void EndGameplay(int userId, SpectatorState state);
/// <param name="userId">The user to quit gameplay for.</param>
protected abstract void QuitGameplay(int userId);
/// <summary>
/// Stops spectating a user.
@ -223,10 +233,10 @@ namespace osu.Game.Screens.Spectate
/// <param name="userId">The user to stop spectating.</param>
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);