diff --git a/osu.Game/Online/Spectator/SpectatorStreamingClient.cs b/osu.Game/Online/Spectator/SpectatorStreamingClient.cs
index 9def009469..13b12d9add 100644
--- a/osu.Game/Online/Spectator/SpectatorStreamingClient.cs
+++ b/osu.Game/Online/Spectator/SpectatorStreamingClient.cs
@@ -284,6 +284,18 @@ namespace osu.Game.Online.Spectator
lastSendTime = Time.Current;
}
+ ///
+ /// Attempts to retrieve the for a currently-playing user.
+ ///
+ /// The user.
+ /// The current for the user, if they're playing. null if the user is not playing.
+ /// true if successful (the user is playing), false otherwise.
+ public bool TryGetPlayingUserState(int userId, out SpectatorState state)
+ {
+ lock (userLock)
+ return playingUserStates.TryGetValue(userId, out state);
+ }
+
///
/// Bind an action to with the option of running the bound action once immediately.
///
diff --git a/osu.Game/Screens/Spectate/SpectatorScreen.cs b/osu.Game/Screens/Spectate/SpectatorScreen.cs
index 7be6c6183b..f554b15abf 100644
--- a/osu.Game/Screens/Spectate/SpectatorScreen.cs
+++ b/osu.Game/Screens/Spectate/SpectatorScreen.cs
@@ -44,7 +44,6 @@ namespace osu.Game.Screens.Spectate
private readonly object stateLock = new object();
private readonly Dictionary userMap = new Dictionary();
- private readonly Dictionary spectatorStates = new Dictionary();
private readonly Dictionary gameplayStates = new Dictionary();
private IBindable> managerUpdated;
@@ -107,9 +106,12 @@ namespace osu.Game.Screens.Spectate
lock (stateLock)
{
- foreach (var (userId, state) in spectatorStates)
+ foreach (var (userId, _) in userMap)
{
- if (beatmapSet.Beatmaps.Any(b => b.OnlineBeatmapID == state.BeatmapID))
+ if (!spectatorClient.TryGetPlayingUserState(userId, out var userState))
+ continue;
+
+ if (beatmapSet.Beatmaps.Any(b => b.OnlineBeatmapID == userState.BeatmapID))
updateGameplayState(userId);
}
}
@@ -125,7 +127,6 @@ namespace osu.Game.Screens.Spectate
if (!userMap.ContainsKey(userId))
return;
- spectatorStates[userId] = state;
Schedule(() => OnUserStateChanged(userId, state));
updateGameplayState(userId);
@@ -138,7 +139,10 @@ namespace osu.Game.Screens.Spectate
{
Debug.Assert(userMap.ContainsKey(userId));
- var spectatorState = spectatorStates[userId];
+ // The user may have stopped playing.
+ if (!spectatorClient.TryGetPlayingUserState(userId, out var spectatorState))
+ return;
+
var user = userMap[userId];
var resolvedRuleset = rulesets.AvailableRulesets.FirstOrDefault(r => r.ID == spectatorState.RulesetID)?.CreateInstance();