diff --git a/Assets/_Project/Scripts/Client/Connection/GoInGameClientSystem.cs b/Assets/_Project/Scripts/Client/Connection/GoInGameClientSystem.cs index bf974d33f..3dd2c70d0 100644 --- a/Assets/_Project/Scripts/Client/Connection/GoInGameClientSystem.cs +++ b/Assets/_Project/Scripts/Client/Connection/GoInGameClientSystem.cs @@ -54,6 +54,7 @@ namespace ProjectM.Client } ecb.Playback(state.EntityManager); + ecb.Dispose(); } } } diff --git a/Assets/_Project/Scripts/Server/Automation/BaseRestoreSystem.cs b/Assets/_Project/Scripts/Server/Automation/BaseRestoreSystem.cs index 16edf57c9..0f8c2eb7d 100644 --- a/Assets/_Project/Scripts/Server/Automation/BaseRestoreSystem.cs +++ b/Assets/_Project/Scripts/Server/Automation/BaseRestoreSystem.cs @@ -129,6 +129,7 @@ namespace ProjectM.Server } ecb.Playback(state.EntityManager); + ecb.Dispose(); } } } diff --git a/Assets/_Project/Scripts/Server/Building/BuildPlaceSystem.cs b/Assets/_Project/Scripts/Server/Building/BuildPlaceSystem.cs index adb452a5e..4f6cfe55d 100644 --- a/Assets/_Project/Scripts/Server/Building/BuildPlaceSystem.cs +++ b/Assets/_Project/Scripts/Server/Building/BuildPlaceSystem.cs @@ -115,6 +115,7 @@ namespace ProjectM.Server } ecb.Playback(state.EntityManager); + ecb.Dispose(); occupied.Dispose(); } } diff --git a/Assets/_Project/Scripts/Server/Combat/ClassSelectReceiveSystem.cs b/Assets/_Project/Scripts/Server/Combat/ClassSelectReceiveSystem.cs index 49b8235b7..4045fd969 100644 --- a/Assets/_Project/Scripts/Server/Combat/ClassSelectReceiveSystem.cs +++ b/Assets/_Project/Scripts/Server/Combat/ClassSelectReceiveSystem.cs @@ -48,8 +48,7 @@ namespace ProjectM.Server if (!accept) continue; var conn = receive.ValueRO.SourceConnection; - if (!SystemAPI.HasComponent(conn) - || !playerByConn.TryGetValue(SystemAPI.GetComponent(conn).Value, out var player)) + if (!PlayerResolve.TryResolve(ref state, playerByConn, conn, out var player)) continue; if (!SystemAPI.HasComponent(player)) continue; diff --git a/Assets/_Project/Scripts/Server/Combat/PrepPurchaseSystem.cs b/Assets/_Project/Scripts/Server/Combat/PrepPurchaseSystem.cs index 9d40b9a30..c7f3d706f 100644 --- a/Assets/_Project/Scripts/Server/Combat/PrepPurchaseSystem.cs +++ b/Assets/_Project/Scripts/Server/Combat/PrepPurchaseSystem.cs @@ -46,8 +46,7 @@ namespace ProjectM.Server if (!accept) continue; var conn = receive.ValueRO.SourceConnection; - if (!SystemAPI.HasComponent(conn) - || !playerByConn.TryGetValue(SystemAPI.GetComponent(conn).Value, out var buyer)) + if (!PlayerResolve.TryResolve(ref state, playerByConn, conn, out var buyer)) continue; if (!PrepCatalog.TryGet(req.ValueRO.OptionId, out var row)) continue; // unknown id -> drop diff --git a/Assets/_Project/Scripts/Server/Connection/GoInGameServerSystem.cs b/Assets/_Project/Scripts/Server/Connection/GoInGameServerSystem.cs index 55ff6c8aa..59dd939ea 100644 --- a/Assets/_Project/Scripts/Server/Connection/GoInGameServerSystem.cs +++ b/Assets/_Project/Scripts/Server/Connection/GoInGameServerSystem.cs @@ -115,6 +115,7 @@ namespace ProjectM.Server } ecb.Playback(state.EntityManager); + ecb.Dispose(); } } } diff --git a/Assets/_Project/Scripts/Server/Debug/DebugCommandReceiveSystem.cs b/Assets/_Project/Scripts/Server/Debug/DebugCommandReceiveSystem.cs index e36817248..170eaf048 100644 --- a/Assets/_Project/Scripts/Server/Debug/DebugCommandReceiveSystem.cs +++ b/Assets/_Project/Scripts/Server/Debug/DebugCommandReceiveSystem.cs @@ -50,8 +50,7 @@ namespace ProjectM.Server Entity sender = Entity.Null; var connEntity = receive.ValueRO.SourceConnection; - if (SystemAPI.HasComponent(connEntity)) - playerByConn.TryGetValue(SystemAPI.GetComponent(connEntity).Value, out sender); + PlayerResolve.TryResolve(ref state, playerByConn, connEntity, out sender); switch (cmd.Op) { diff --git a/Assets/_Project/Scripts/Server/Economy/RoomFieldSystem.cs b/Assets/_Project/Scripts/Server/Economy/RoomFieldSystem.cs index 80dda33cd..730c0fa84 100644 --- a/Assets/_Project/Scripts/Server/Economy/RoomFieldSystem.cs +++ b/Assets/_Project/Scripts/Server/Economy/RoomFieldSystem.cs @@ -141,6 +141,7 @@ namespace ProjectM.Server } ecb.Playback(state.EntityManager); + ecb.Dispose(); } } } diff --git a/Assets/_Project/Scripts/Server/HomeBase/SharedStorageSpawnSystem.cs b/Assets/_Project/Scripts/Server/HomeBase/SharedStorageSpawnSystem.cs index 34c260110..a99196104 100644 --- a/Assets/_Project/Scripts/Server/HomeBase/SharedStorageSpawnSystem.cs +++ b/Assets/_Project/Scripts/Server/HomeBase/SharedStorageSpawnSystem.cs @@ -55,6 +55,7 @@ namespace ProjectM.Server ecb.DestroyEntity(spawnerEntity); ecb.Playback(state.EntityManager); + ecb.Dispose(); } } } diff --git a/Assets/_Project/Scripts/Server/HomeBase/StorageOpReceiveSystem.cs b/Assets/_Project/Scripts/Server/HomeBase/StorageOpReceiveSystem.cs index fda07a345..e3e6f6f29 100644 --- a/Assets/_Project/Scripts/Server/HomeBase/StorageOpReceiveSystem.cs +++ b/Assets/_Project/Scripts/Server/HomeBase/StorageOpReceiveSystem.cs @@ -49,6 +49,7 @@ namespace ProjectM.Server } ecb.Playback(state.EntityManager); + ecb.Dispose(); } } } diff --git a/Assets/_Project/Scripts/Server/PlayerResolve.cs b/Assets/_Project/Scripts/Server/PlayerResolve.cs new file mode 100644 index 000000000..5a7d8c54e --- /dev/null +++ b/Assets/_Project/Scripts/Server/PlayerResolve.cs @@ -0,0 +1,27 @@ +using Unity.Collections; +using Unity.Entities; +using Unity.NetCode; + +namespace ProjectM.Server +{ + /// + /// Shared server-side RPC sender resolution: a request's ReceiveRpcCommandRequest.SourceConnection → + /// its → the conn→player map that every RPC-receive system builds (the + /// AbilityUpgradeSystem / ReadyToggle idiom). The MAP BUILD stays per-caller — each system's player query + /// carries different extra required components (InventorySlot / EquipmentSlot / StatModifier / BoonOffer / + /// PlayerReady / …) — but the RESOLVE step is byte-for-byte identical across sites, so it lives here once. + /// Burst-safe (plain reads; called from [BurstCompile] receivers). + /// + public static class PlayerResolve + { + /// True (with set) iff has a + /// present in . Behaviour-identical to the inline + /// HasComponent<NetworkId>(conn) && map.TryGetValue(GetComponent<NetworkId>(conn).Value, out player). + public static bool TryResolve(ref SystemState state, NativeHashMap map, Entity conn, out Entity player) + { + player = Entity.Null; + return state.EntityManager.HasComponent(conn) + && map.TryGetValue(state.EntityManager.GetComponentData(conn).Value, out player); + } + } +} diff --git a/Assets/_Project/Scripts/Server/PlayerResolve.cs.meta b/Assets/_Project/Scripts/Server/PlayerResolve.cs.meta new file mode 100644 index 000000000..ebbf57e11 --- /dev/null +++ b/Assets/_Project/Scripts/Server/PlayerResolve.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5e602229d090fee489d063aebece5da2 \ No newline at end of file diff --git a/Assets/_Project/Scripts/Server/World/CycleDirectorSpawnSystem.cs b/Assets/_Project/Scripts/Server/World/CycleDirectorSpawnSystem.cs index 3c3fdb553..36dd81564 100644 --- a/Assets/_Project/Scripts/Server/World/CycleDirectorSpawnSystem.cs +++ b/Assets/_Project/Scripts/Server/World/CycleDirectorSpawnSystem.cs @@ -154,6 +154,7 @@ namespace ProjectM.Server ecb.DestroyEntity(spawnerEntity); ecb.Playback(state.EntityManager); + ecb.Dispose(); } } } diff --git a/Assets/_Project/Scripts/Server/World/RouteSelectSystem.cs b/Assets/_Project/Scripts/Server/World/RouteSelectSystem.cs index 83c6197a9..9510cc389 100644 --- a/Assets/_Project/Scripts/Server/World/RouteSelectSystem.cs +++ b/Assets/_Project/Scripts/Server/World/RouteSelectSystem.cs @@ -90,6 +90,7 @@ namespace ProjectM.Server ecb.DestroyEntity(requestEntity); } ecb.Playback(state.EntityManager); + ecb.Dispose(); regionByConn.Dispose(); } }