fix: address review on the notification pushes

- Force-join's RoomUpdate carries the room's role grants, so it no
  longer wipes them from the client's cached room.
- The consumable push reports IsTransferable the same as the inventory
  list does.
- A rejected private-instance join sends the owner at most one "wants
  to join" message per requester and instance every 5 minutes.
- SubscribeToPlayers ignores sets over 5,000 ids and keeps the current
  subscriptions.
- The subscriber exclusion list looks up online friends' connections in
  one pipelined Redis batch instead of one call per friend.
This commit is contained in:
Alexa
2026-10-24 20:25:51 +03:00
parent e33145307f
commit afad9bbc5a
6 changed files with 99 additions and 15 deletions
@@ -148,6 +148,34 @@ public class OnlinePresenceService
lock (set) return set.ToArray();
}
/// <summary>Connection ids of every player in <paramref name="playerIds"/>,
/// in one go: the Redis lookups are issued together, so the multiplexer
/// pipelines them into one round trip instead of one per player.</summary>
public async Task<IReadOnlyCollection<string>> GetConnectionsAsync(IEnumerable<long> playerIds)
{
var ids = playerIds.Distinct().ToArray();
if (ids.Length == 0) return Array.Empty<string>();
if (_redis is { } mux)
{
try
{
var db = mux.GetDatabase();
var sets = await Task.WhenAll(ids.Select(id => db.SetMembersAsync(ConnsKey(id))));
return sets.SelectMany(s => s).Select(v => v.ToString()).ToArray();
}
catch
{
// Redis sick → fall through to the local fallback, as
// GetConnections does.
}
}
var result = new List<string>();
foreach (var id in ids)
if (_localConns.TryGetValue(id, out var set))
lock (set) result.AddRange(set);
return result;
}
/// <summary>Snapshot of currently-online player ids across the
/// cluster. Returns an empty array when nobody's online; never null.
/// Callers typically <c>.ToHashSet()</c> the result for membership