Files
Project-M/Assets/_Project/Scripts/Server/PlayerResolve.cs
T
kronic 813c829420 Hygiene B4d: PlayerResolve dedup + explicit Temp-ECB Dispose tail
- New Server/PlayerResolve.TryResolve single-sources the RPC
  SourceConnection -> NetworkId -> conn->player map resolve (3 sites:
  ClassSelectReceive, PrepPurchase, DebugCommandReceive); EntityManager
  reads keep it source-gen-safe from Bursted receivers.
- ecb.Dispose() after Playback in 9 Temp-ECB systems (explicit-lifetime
  hygiene).
- The TuningConfig.GetOrDefault(ref state) variant of this tail was
  REVERTED: state.GetEntityQuery in OnUpdate trips the Entities
  "creates a query during OnUpdate" diagnostic per system per world
  (caught in Play smoke) - the SystemAPI.TryGetSingleton idiom is
  already source-gen-optimal, confirming the original B4 deferral.

Verified: 466/466 EditMode green on the final tree, console clean,
Play smoke 0 errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 12:39:55 -07:00

28 lines
1.5 KiB
C#

using Unity.Collections;
using Unity.Entities;
using Unity.NetCode;
namespace ProjectM.Server
{
/// <summary>
/// Shared server-side RPC sender resolution: a request's <c>ReceiveRpcCommandRequest.SourceConnection</c> →
/// its <see cref="NetworkId"/> → 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 <see cref="EntityManager"/> reads; called from <c>[BurstCompile]</c> receivers).
/// </summary>
public static class PlayerResolve
{
/// <summary>True (with <paramref name="player"/> set) iff <paramref name="conn"/> has a
/// <see cref="NetworkId"/> present in <paramref name="map"/>. Behaviour-identical to the inline
/// <c>HasComponent&lt;NetworkId&gt;(conn) &amp;&amp; map.TryGetValue(GetComponent&lt;NetworkId&gt;(conn).Value, out player)</c>.</summary>
public static bool TryResolve(ref SystemState state, NativeHashMap<int, Entity> map, Entity conn, out Entity player)
{
player = Entity.Null;
return state.EntityManager.HasComponent<NetworkId>(conn)
&& map.TryGetValue(state.EntityManager.GetComponentData<NetworkId>(conn).Value, out player);
}
}
}