mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 15:08:47 -07:00
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:
@@ -880,8 +880,11 @@ public class GoToController(
|
||||
callerId, playerId, theirRoom.RoomInstanceId);
|
||||
// Tell the OWNER someone tried to follow them in, as the
|
||||
// client's own "wants to join" message (RequestGameInvite,
|
||||
// from the caller), so they can send an invite.
|
||||
if (callerId is long requester)
|
||||
// from the caller), so they can send an invite. At most once
|
||||
// per requester, owner and instance per cooldown, so retrying
|
||||
// doesn't fill the owner's inbox.
|
||||
if (callerId is long requester
|
||||
&& JoinRequestCooldown.TryStart(requester, playerId, theirRoom.RoomInstanceId))
|
||||
await systemNotifications.SendAsync(playerId,
|
||||
SystemNotificationService.MessageType.RequestGameInvite, fromPlayerId: requester);
|
||||
return Ok(new MatchmakingResponseDto
|
||||
@@ -1670,3 +1673,35 @@ public class RoomInstanceDto
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Rate limit for "wants to join" messages: one per (requester,
|
||||
/// owner, room instance) per <see cref="Window"/>. Later retries and other
|
||||
/// instances still go through. Per replica, which is enough to stop a
|
||||
/// retry loop from flooding an inbox.</summary>
|
||||
internal static class JoinRequestCooldown
|
||||
{
|
||||
public static readonly TimeSpan Window = TimeSpan.FromMinutes(5);
|
||||
private static readonly System.Collections.Concurrent.ConcurrentDictionary<(long, long, long), DateTime> Last = new();
|
||||
|
||||
/// <summary>True when no request for this key was sent within the window
|
||||
/// (and records this one); false while it is cooling down.</summary>
|
||||
public static bool TryStart(long requester, long owner, long roomInstanceId)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
if (Last.Count > 10_000)
|
||||
foreach (var (key, at) in Last)
|
||||
if (now - at > Window) Last.TryRemove(key, out _);
|
||||
|
||||
var k = (requester, owner, roomInstanceId);
|
||||
while (true)
|
||||
{
|
||||
if (!Last.TryGetValue(k, out var prev))
|
||||
{
|
||||
if (Last.TryAdd(k, now)) return true;
|
||||
continue;
|
||||
}
|
||||
if (now - prev < Window) return false;
|
||||
if (Last.TryUpdate(k, now, prev)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user