Matchmade sessions respect room's subroom Max Player Count (#35)

* Avoid login kick broadcast during reconnect

* feat: Matchmade sessions respect room's subroom Max Player Count

GameSessionService previously hardcoded MaxCapacity=8 for new sessions,
fragmenting matchmade joiners 8-per-instance regardless of the host's
'Max Player Count in This Subroom' slider. New sessions now resolve the
room's entry subroom (lowest OrderIndex) RoomSceneEntity.MaxPlayers,
clamped 1-80, falling back to 8 for system rooms (dorm GUID roomIds).
This commit is contained in:
Alexa
2026-06-30 13:35:14 +03:00
committed by GitHub
parent 97f6522497
commit 193d9b343c
2 changed files with 37 additions and 13 deletions
@@ -20,7 +20,6 @@ namespace DorkNet.Server.Controllers.Match;
[ApiController]
public class MatchPlayerController(
PlayerPresenceService presence,
NotificationService notifications,
RoomService rooms,
PrivateInstanceService privateInstances,
IConfiguration config,
@@ -37,7 +36,7 @@ public class MatchPlayerController(
/// </summary>
[HttpPost("/player/login")]
[Consumes("application/x-www-form-urlencoded", "multipart/form-data")]
public async Task<IActionResult> PlayerLogin([FromForm(Name = "LoginLock")] string? loginLock)
public IActionResult PlayerLogin([FromForm(Name = "LoginLock")] string? loginLock)
{
var playerId = TryGetCurrentPlayerId();
if (playerId != 0 && !string.IsNullOrWhiteSpace(loginLock))
@@ -46,17 +45,15 @@ public class MatchPlayerController(
if (replaced)
{
log.LogWarning(
"[player-login] concurrent session for player={PlayerId}; kicking old session(s) via ModerationKick push",
"[player-login] concurrent session marker replaced for player={PlayerId}; stale SignalR connections will be evicted on hub connect",
playerId);
// The new session hasn't opened its SignalR socket yet
// (negotiate fires AFTER /player/login on the watch's
// boot sequence — verified in the live trace), so the
// ModerationKick push hits only the OLDER session's
// existing connections. They'll show the "you've been
// kicked" dialog and gracefully disconnect via the
// watch's LocalModerationKickSelf path.
await notifications.KickStaleSession(playerId,
"Your account was signed in on another device.");
// Do not broadcast ModerationKick to the whole player group
// here. During reconnects the active watch can already have a
// SignalR connection in that group, and the 2020 client crashes
// hard if it receives a malformed/stale moderation payload.
// NotifyHub.OnConnectedAsync snapshots existing connection ids
// before adding the new connection and sends a targeted kick to
// those ids only.
}
}
return Ok(Array.Empty<object>());