From 66f77831b6e4114fa021bccb2b5e4f6a2ca8bda9 Mon Sep 17 00:00:00 2001 From: michaelinfaith Date: Tue, 13 Oct 2026 21:35:05 -0400 Subject: [PATCH] Guard the scope tracking removal in ScopeOut 46eff67 moved the removal to the top of ScopeOut so the tracking is dropped even if the player can't receive the scope out. 34353af then added a TryGetValue guarded removal at the old place, after the CanReceiveGSS check, and left the unguarded index at the top. That index still throws a KeyNotFoundException when ScopeOut runs for an entity that is no longer in _scopedPlayersByEntity. Keep the removal at the top, guarded with TryGetValue, and drop the duplicate. Co-Authored-By: Claude Opus 5.5 --- .../Systems/EntityManager/EntityManager.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/UdpHosts/GameServer/Systems/EntityManager/EntityManager.cs b/UdpHosts/GameServer/Systems/EntityManager/EntityManager.cs index a8183449..19a6dc1f 100644 --- a/UdpHosts/GameServer/Systems/EntityManager/EntityManager.cs +++ b/UdpHosts/GameServer/Systems/EntityManager/EntityManager.cs @@ -1434,7 +1434,12 @@ public void ScopeIn(INetworkPlayer player, IEntity entity) public void ScopeOut(INetworkPlayer player, IEntity entity) { - _scopedPlayersByEntity[entity.EntityId].Remove(player); + // Remove the tracking even if the player can't receive the scope out. + // The entity can already be removed. Refer to the same guard in ScopeIn. + if (_scopedPlayersByEntity.TryGetValue(entity.EntityId, out var scopedPlayers)) + { + scopedPlayers.Remove(player); + } // Avoid sending messages if player is not in the appropriate state if (!player.CanReceiveGSS) @@ -1442,12 +1447,6 @@ public void ScopeOut(INetworkPlayer player, IEntity entity) return; } - // The entity can already be removed. Refer to the same guard in ScopeIn. - if (_scopedPlayersByEntity.TryGetValue(entity.EntityId, out var scopedPlayers)) - { - scopedPlayers.Remove(player); - } - if (entity is CharacterEntity character) { if (character.IsPlayerControlled && character.Player == player)