Skip to content

Commit

Permalink
Notify watched players when one of their watchers disconnects
Browse files Browse the repository at this point in the history
  • Loading branch information
bdach committed Jan 22, 2025
1 parent 5395794 commit 19f0e02
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
6 changes: 6 additions & 0 deletions osu.Server.Spectator/Hubs/Spectator/SpectatorClientState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Online.Spectator;
using osu.Game.Scoring;
Expand All @@ -26,6 +27,11 @@ public class SpectatorClientState : ClientState
/// </summary>
public long? ScoreToken;

/// <summary>
/// The list of IDs of users that this client is currently watching.
/// </summary>
public HashSet<int> WatchedUsers = new HashSet<int>();

[JsonConstructor]
public SpectatorClientState(in string connectionId, in int userId)
: base(connectionId, userId)
Expand Down
22 changes: 21 additions & 1 deletion osu.Server.Spectator/Hubs/Spectator/SpectatorHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,12 @@ public async Task EndPlaySession(SpectatorState state)
}
finally
{
usage.Destroy();
if (usage.Item != null)
{
usage.Item.State = null;
usage.Item.Score = null;
usage.Item.ScoreToken = null;
}
}
}

Expand Down Expand Up @@ -202,6 +207,12 @@ public async Task StartWatchingUser(int userId)
// user isn't tracked.
}

using (var state = await GetOrCreateLocalUserState())
{
var clientState = state.Item ??= new SpectatorClientState(Context.ConnectionId, Context.GetUserId());
clientState.WatchedUsers.Add(userId);
}

await Groups.AddToGroupAsync(Context.ConnectionId, GetGroupId(userId));

int watcherId = Context.GetUserId();
Expand All @@ -225,6 +236,12 @@ public async Task EndWatchingUser(int userId)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, GetGroupId(userId));

using (var state = await GetOrCreateLocalUserState())
{
var clientState = state.Item ??= new SpectatorClientState(Context.ConnectionId, Context.GetUserId());
clientState.WatchedUsers.Remove(userId);
}

int watcherId = Context.GetUserId();

await Clients.User(userId.ToString()).UserEndedWatching(watcherId);
Expand All @@ -245,6 +262,9 @@ protected override async Task CleanUpState(SpectatorClientState state)
if (state.State != null)
await endPlaySession(state.UserId, state.State);

foreach (int watchedUserId in state.WatchedUsers)
await Clients.User(watchedUserId.ToString()).UserEndedWatching(state.UserId);

await base.CleanUpState(state);
}

Expand Down

0 comments on commit 19f0e02

Please sign in to comment.