From 3755593dbbd8985ca521180755787096b33d1687 Mon Sep 17 00:00:00 2001 From: Alexa <53471801+Alexa-RR@users.noreply.github.com> Date: Mon, 15 Jun 2026 00:20:05 +0300 Subject: [PATCH] Avoid login kick broadcast during reconnect --- .../Match/MatchPlayerController.cs | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/DorkNet.Server/Controllers/Match/MatchPlayerController.cs b/DorkNet.Server/Controllers/Match/MatchPlayerController.cs index b986621..7f7f44c 100644 --- a/DorkNet.Server/Controllers/Match/MatchPlayerController.cs +++ b/DorkNet.Server/Controllers/Match/MatchPlayerController.cs @@ -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( /// [HttpPost("/player/login")] [Consumes("application/x-www-form-urlencoded", "multipart/form-data")] - public async Task 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());