using System.Threading; using System.Threading.Tasks; using LiteNetLib.Utils; using Syntriax.Engine.Core; namespace Syntriax.Engine.Network; public class LiteNetLibClient : LiteNetLibCommunicatorBase, INetworkCommunicatorClient { private readonly NetDataWriter netDataWriter = new(); private CancellationTokenSource? cancellationTokenSource = null; public INetworkCommunicatorClient Connect(string address, int port, string? password = null) { if (!IsInUniverse) throw new($"{nameof(LiteNetLibClient)} must be in an universe to connect"); Manager.Start(); Manager.Connect(address, port, password ?? string.Empty); return this; } public INetworkCommunicatorClient SendToServer(T packet) where T : class, new() { netDataWriter.Reset(); netPacketProcessor.Write(netDataWriter, packet); Manager.FirstPeer.Send(netDataWriter, LiteNetLib.DeliveryMethod.ReliableOrdered); return this; } protected override void OnEnteringUniverse(IUniverse universe) { base.OnEnteringUniverse(universe); cancellationTokenSource = new CancellationTokenSource(); PollEvents(cancellationTokenSource.Token); } protected override void OnExitingUniverse(IUniverse universe) { base.OnExitingUniverse(universe); cancellationTokenSource?.Cancel(); } /// /// Client needs to send everything as soon as possible so /// the events are polled a separate thread running constantly /// private async void PollEvents(CancellationToken cancellationToken) => await Task.Run(() => { while (true) { Manager.PollEvents(); Thread.Sleep(1); } }, cancellationToken); }