using System.Linq; using LiteNetLib; using LiteNetLib.Utils; using Syntriax.Engine.Core; using Syntriax.Engine.Core.Debug; namespace Syntriax.Engine.Network; public class LiteNetLibServer : LiteNetLibCommunicatorBase, INetworkCommunicatorServer { public string Password { get; private set; } = string.Empty; public int MaxConnectionCount { get; private set; } = 2; public int Port { get; private set; } = 8888; private readonly NetDataWriter netDataWriter = new(); public LiteNetLibServer() : this(8888, 2) { } public LiteNetLibServer(int port, int maxConnectionCount) : base() { MaxConnectionCount = maxConnectionCount; Port = port; Listener.ConnectionRequestEvent += OnConnectionRequest; } private void OnConnectionRequest(ConnectionRequest request) { logger?.Log(this, $"Connection request from ip {request.RemoteEndPoint}"); logger?.Log(this, $"Current connection count: {Connections.Count}"); if (Manager.ConnectedPeersCount < MaxConnectionCount) request.AcceptIfKey(Password); else request.Reject(); } public INetworkCommunicatorServer Start(int port, int maxConnectionCount, string? password = null) { if (!UniverseObject.IsInUniverse) throw new($"{nameof(LiteNetLibServer)} must be in an universe to start"); Password = password ?? string.Empty; MaxConnectionCount = maxConnectionCount; Port = port; logger?.Log(this, $"Starting server on port '{port}' with password '{Password}' and max connection count '{maxConnectionCount}'"); logger?.Log(this, $"Server status: {(Manager.Start(port) ? "Active" : "Failed")}"); return this; } public INetworkCommunicatorServer SendToClient(IConnection connection, T packet) where T : class, new() { netDataWriter.Reset(); netPacketProcessor.Write(netDataWriter, packet); if (Manager.ConnectedPeerList.FirstOrDefault(p => p.Id.CompareTo(connection.Id) == 0) is not NetPeer netPeer) throw new($"Peer {connection} couldn't be found."); netPeer.Send(netDataWriter, DeliveryMethod.ReliableOrdered); return this; } public INetworkCommunicatorServer SendToAll(T packet) where T : class, new() { netDataWriter.Reset(); netPacketProcessor.Write(netDataWriter, packet); Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableOrdered); return this; } private void PollEvents(IUniverse sender, IUniverse.UpdateArguments args) => Manager.PollEvents(); protected override void OnEnteredUniverse(IUniverse universe) { base.OnEnteredUniverse(universe); universe.OnPostUpdate.AddListener(PollEvents); } protected override void OnExitedUniverse(IUniverse universe) { base.OnExitedUniverse(universe); universe.OnPostUpdate.RemoveListener(PollEvents); } }