using ProjectM.Simulation; using Unity.Collections; using Unity.Entities; using Unity.NetCode; using Unity.Networking.Transport; using UnityEngine; namespace ProjectM.Client { /// /// Client/thin-client half of the M4 LAN join flow. When the per-world /// requests , creates a /// entity for the parsed endpoint and clears the request. Runs in both full and thin client worlds so /// the editor auto-host can connect thin clients too. Not Burst-compiled: NetworkEndpoint.TryParse /// takes a managed string and this is a cold path. /// [WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation | WorldSystemFilterFlags.ThinClientSimulation)] public partial struct ClientConnectionControlSystem : ISystem { public void OnCreate(ref SystemState state) { state.RequireForUpdate(); } public void OnUpdate(ref SystemState state) { var cfgRef = SystemAPI.GetSingletonRW(); if (!cfgRef.ValueRO.Requested || cfgRef.ValueRO.Mode != ConnectionMode.Join) return; // Clear first so a malformed address does not retry-spam every frame. cfgRef.ValueRW.Requested = false; var address = cfgRef.ValueRO.Address; var port = cfgRef.ValueRO.Port; if (!NetworkEndpoint.TryParse(address.ToString(), port, out var endpoint, NetworkFamily.Ipv4)) { Debug.LogError($"[ClientConnectionControlSystem] Invalid join address '{address}'."); return; } var ecb = new EntityCommandBuffer(Allocator.Temp); var req = ecb.CreateEntity(); ecb.AddComponent(req, new NetworkStreamRequestConnect { Endpoint = endpoint }); ecb.Playback(state.EntityManager); ecb.Dispose(); } } }