50 lines
2.0 KiB
C#
50 lines
2.0 KiB
C#
using ProjectM.Simulation;
|
|
using Unity.Collections;
|
|
using Unity.Entities;
|
|
using Unity.NetCode;
|
|
using Unity.Networking.Transport;
|
|
using UnityEngine;
|
|
|
|
namespace ProjectM.Client
|
|
{
|
|
/// <summary>
|
|
/// Client/thin-client half of the M4 LAN join flow. When the per-world <see cref="ConnectionConfig"/>
|
|
/// requests <see cref="ConnectionMode.Join"/>, creates a <see cref="NetworkStreamRequestConnect"/>
|
|
/// 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: <c>NetworkEndpoint.TryParse</c>
|
|
/// takes a managed string and this is a cold path.
|
|
/// </summary>
|
|
[WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation | WorldSystemFilterFlags.ThinClientSimulation)]
|
|
public partial struct ClientConnectionControlSystem : ISystem
|
|
{
|
|
public void OnCreate(ref SystemState state)
|
|
{
|
|
state.RequireForUpdate<ConnectionConfig>();
|
|
}
|
|
|
|
public void OnUpdate(ref SystemState state)
|
|
{
|
|
var cfgRef = SystemAPI.GetSingletonRW<ConnectionConfig>();
|
|
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();
|
|
}
|
|
}
|
|
}
|