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