Original Behaviour was using old methods for detecting entering/exiting universe, they are now all under the same hood and the original is kept for UniverseEntranceManager because it needs to enter the universe without itself. The internal behaviour kept under a subnamespace of "Core.Internal" for the purpose that it might come in handy for other use cases.
103 lines
4.1 KiB
C#
103 lines
4.1 KiB
C#
using LiteNetLib;
|
|
using LiteNetLib.Utils;
|
|
|
|
using Engine.Core;
|
|
using Engine.Core.Debug;
|
|
|
|
namespace Engine.Systems.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;
|
|
}
|
|
|
|
protected override IConnection GetConnection(NetPeer peer) => new LiteNetLibClientConnection(peer);
|
|
|
|
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<T>(IConnection connection, T packet, PacketDelivery packetDelivery) 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.");
|
|
|
|
switch (packetDelivery)
|
|
{
|
|
case PacketDelivery.ReliableInOrder: netPeer.Send(netDataWriter, DeliveryMethod.ReliableOrdered); break;
|
|
case PacketDelivery.UnreliableInOrder: netPeer.Send(netDataWriter, DeliveryMethod.Sequenced); break;
|
|
case PacketDelivery.ReliableOutOfOrder: netPeer.Send(netDataWriter, DeliveryMethod.ReliableUnordered); break;
|
|
case PacketDelivery.UnreliableOutOfOrder: netPeer.Send(netDataWriter, DeliveryMethod.Unreliable); break;
|
|
default: netPeer.Send(netDataWriter, DeliveryMethod.ReliableOrdered); break;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
public INetworkCommunicatorServer SendToAll<T>(T packet, PacketDelivery packetDelivery) where T : class, new()
|
|
{
|
|
netDataWriter.Reset();
|
|
netPacketProcessor.Write(netDataWriter, packet);
|
|
|
|
switch (packetDelivery)
|
|
{
|
|
case PacketDelivery.ReliableInOrder: Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableOrdered); break;
|
|
case PacketDelivery.UnreliableInOrder: Manager.SendToAll(netDataWriter, DeliveryMethod.Sequenced); break;
|
|
case PacketDelivery.ReliableOutOfOrder: Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableUnordered); break;
|
|
case PacketDelivery.UnreliableOutOfOrder: Manager.SendToAll(netDataWriter, DeliveryMethod.Unreliable); break;
|
|
default: Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableOrdered); break;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
private void PollEvents(IUniverse sender, IUniverse.UpdateArguments args) => Manager.PollEvents();
|
|
|
|
public override void EnterUniverse(IUniverse universe)
|
|
{
|
|
base.EnterUniverse(universe);
|
|
universe.OnPostUpdate.AddListener(PollEvents);
|
|
}
|
|
|
|
public override void ExitUniverse(IUniverse universe)
|
|
{
|
|
base.ExitUniverse(universe);
|
|
universe.OnPostUpdate.RemoveListener(PollEvents);
|
|
}
|
|
}
|