fix: renamed old classes and fixed packet registration issues

This commit is contained in:
Syntriax 2025-05-11 11:51:25 +03:00
parent 23a0c8e893
commit 94f7d4acfd
6 changed files with 67 additions and 73 deletions

View File

@ -4,16 +4,16 @@ public interface INetworkCommunicator
{ {
event OnPacketReceivedDelegate? OnPacketReceived; event OnPacketReceivedDelegate? OnPacketReceived;
void Stop(); INetworkCommunicator Stop();
delegate void OnPacketReceivedDelegate(INetworkCommunicator sender, object packet, string from); delegate void OnPacketReceivedDelegate(INetworkCommunicator sender, object packet, string from);
} }
public interface INetworkCommunicatorClient : INetworkCommunicator public interface INetworkCommunicatorClient : INetworkCommunicator
{ {
void Connect(string address, int port, string? password = null); INetworkCommunicatorClient Connect(string address, int port, string? password = null);
void SendToServer(INetworkPacket packet); INetworkCommunicatorClient SendToServer<T>(T packet) where T : class, new();
} }
public interface INetworkCommunicatorServer : INetworkCommunicator public interface INetworkCommunicatorServer : INetworkCommunicator
@ -22,7 +22,7 @@ public interface INetworkCommunicatorServer : INetworkCommunicator
int MaxConnectionCount { get; } int MaxConnectionCount { get; }
int Port { get; } int Port { get; }
void Start(int port, int maxConnectionCount, string? password = null); INetworkCommunicatorServer Start(int port, int maxConnectionCount, string? password = null);
void SendToClient(string to, INetworkPacket packet); INetworkCommunicatorServer SendToClient<T>(string to, T packet) where T : class, new();
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using Syntriax.Engine.Core; using Syntriax.Engine.Core;
namespace Syntriax.Engine.Network; namespace Syntriax.Engine.Network;

View File

@ -0,0 +1,28 @@
using LiteNetLib.Utils;
namespace Syntriax.Engine.Network;
public class LiteNetLibClient : LiteNetLibCommunicatorBase, INetworkCommunicatorClient
{
private readonly NetDataWriter netDataWriter = new();
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>(T packet) where T : class, new()
{
netDataWriter.Reset();
netPacketProcessor.Write(netDataWriter, packet);
Manager.FirstPeer.Send(netDataWriter, LiteNetLib.DeliveryMethod.ReliableOrdered);
return this;
}
}

View File

@ -10,7 +10,7 @@ using Syntriax.Engine.Core;
namespace Syntriax.Engine.Network; namespace Syntriax.Engine.Network;
public abstract class NetworkBase : UniverseObject, INetworkCommunicator public abstract class LiteNetLibCommunicatorBase : UniverseObject, INetworkCommunicator
{ {
public event INetworkCommunicator.OnPacketReceivedDelegate? OnPacketReceived = null; public event INetworkCommunicator.OnPacketReceivedDelegate? OnPacketReceived = null;
@ -19,7 +19,11 @@ public abstract class NetworkBase : UniverseObject, INetworkCommunicator
public EventBasedNetListener Listener { get; private set; } = null!; public EventBasedNetListener Listener { get; private set; } = null!;
public NetManager Manager { get; private set; } = null!; public NetManager Manager { get; private set; } = null!;
public void Stop() => Manager.Stop(); public INetworkCommunicator Stop()
{
Manager.Stop();
return this;
}
protected override void OnEnteringUniverse(IUniverse universe) protected override void OnEnteringUniverse(IUniverse universe)
{ {
@ -34,8 +38,7 @@ public abstract class NetworkBase : UniverseObject, INetworkCommunicator
} }
private void PollEvents(IUniverse sender, UniverseTime engineTime) => Manager.PollEvents(); private void PollEvents(IUniverse sender, UniverseTime engineTime) => Manager.PollEvents();
protected virtual void OnPacketArrived<T>(T packet, NetPeer peer) where T : INetworkPacket
private void OnPacketArrived(INetworkPacket packet, NetPeer peer)
{ {
OnPacketReceived?.Invoke(this, packet, peer.Id.ToString()); OnPacketReceived?.Invoke(this, packet, peer.Id.ToString());
} }
@ -45,54 +48,42 @@ public abstract class NetworkBase : UniverseObject, INetworkCommunicator
try { netPacketProcessor.ReadAllPackets(reader, peer); } try { netPacketProcessor.ReadAllPackets(reader, peer); }
catch { } catch { }
} }
private void SetupPackets() private void SetupPackets()
{ {
#region Packet Types Registration // Find network packets implementing INetworkPacket
IEnumerable<Type> packetTypes = Assembly.GetExecutingAssembly().GetTypes() IEnumerable<Type> packetTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes())
.Where(t => typeof(INetworkPacket).IsAssignableFrom(t) && !t.IsInterface); .Where(t => typeof(INetworkPacket).IsAssignableFrom(t) && !t.IsInterface);
MethodInfo registerPacketTypeMethodInfo = typeof(NetPacketProcessor).GetMethod(nameof(NetPacketProcessor.RegisterNestedType), BindingFlags.Instance)!; MethodInfo subscribeReusableMethod = typeof(NetPacketProcessor)
foreach (Type packetType in packetTypes)
{
MethodInfo genericRegisterPacketTypeMethodInfo = registerPacketTypeMethodInfo?.MakeGenericMethod(packetType)!;
genericRegisterPacketTypeMethodInfo.Invoke(netPacketProcessor, null);
}
#endregion
#region Deserialization Callback via netPacketProcessor.SubscribeReusable<T> to OnPacketArrived
MethodInfo subscribeMethod = netPacketProcessor.GetType()
.GetMethods() .GetMethods()
.Where(m => m.Name == nameof(NetPacketProcessor.SubscribeReusable)) .FirstOrDefault(m => m.Name == nameof(NetPacketProcessor.SubscribeReusable) &&
.FirstOrDefault(m =>
m.GetParameters().Length == 1 && m.GetParameters().Length == 1 &&
m.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(Action<,>) m.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(Action<,>)
)!; )!;
MethodInfo packetArrivedMethod = typeof(NetworkBase) MethodInfo onPacketArrivedMethod = typeof(LiteNetLibCommunicatorBase)
.GetMethod(nameof(OnPacketArrived), BindingFlags.NonPublic | BindingFlags.Instance)!; .GetMethod(nameof(OnPacketArrived), BindingFlags.NonPublic | BindingFlags.Instance)!;
// Register all network packets by calling the method bellow where T is our found network packet type
// NetPacketProcessor.SubscribeReusable<T, NetPeer>(Action<T, NetPeer> onReceive)
foreach (var packetType in packetTypes) foreach (var packetType in packetTypes)
{ {
MethodInfo genericSubscribeMethod = subscribeMethod.MakeGenericMethod(packetType, typeof(NetPeer)); var genericOnPacketArrivedMethod = onPacketArrivedMethod.MakeGenericMethod(packetType);
Action<object, NetPeer> handler = (packet, peer) => var delegateType = typeof(Action<,>).MakeGenericType(packetType, typeof(NetPeer));
{ var delegateHandler = Delegate.CreateDelegate(delegateType, this, genericOnPacketArrivedMethod);
MethodInfo handlerMethod = packetArrivedMethod.MakeGenericMethod(packetType);
handlerMethod.Invoke(this, [packet, peer]); var genericSubscribeReusableMethod = subscribeReusableMethod.MakeGenericMethod(packetType, typeof(NetPeer));
}; genericSubscribeReusableMethod.Invoke(netPacketProcessor, [delegateHandler]);
genericSubscribeMethod.Invoke(netPacketProcessor, [handler]);
} }
#endregion
} }
public NetworkBase() public LiteNetLibCommunicatorBase()
{ {
Listener = new EventBasedNetListener(); Listener = new EventBasedNetListener();
Manager = new NetManager(Listener); Manager = new NetManager(Listener);
Listener.NetworkReceiveEvent += NetworkReceiveEvent; Listener.NetworkReceiveEvent += NetworkReceiveEvent;
SetupPackets(); SetupPackets();
} }
} }

View File

@ -5,7 +5,7 @@ using LiteNetLib.Utils;
namespace Syntriax.Engine.Network; namespace Syntriax.Engine.Network;
public class NetworkServer : NetworkBase, INetworkCommunicatorServer public class LiteNetLibServer : LiteNetLibCommunicatorBase, INetworkCommunicatorServer
{ {
public string Password { get; private set; } = string.Empty; public string Password { get; private set; } = string.Empty;
public int MaxConnectionCount { get; private set; } = 2; public int MaxConnectionCount { get; private set; } = 2;
@ -13,8 +13,8 @@ public class NetworkServer : NetworkBase, INetworkCommunicatorServer
private readonly NetDataWriter netDataWriter = new(); private readonly NetDataWriter netDataWriter = new();
public NetworkServer() : this(8888, 2) { } public LiteNetLibServer() : this(8888, 2) { }
public NetworkServer(int port, int maxConnectionCount) : base() public LiteNetLibServer(int port, int maxConnectionCount) : base()
{ {
MaxConnectionCount = maxConnectionCount; MaxConnectionCount = maxConnectionCount;
Port = port; Port = port;
@ -28,33 +28,34 @@ public class NetworkServer : NetworkBase, INetworkCommunicatorServer
}; };
} }
public void Start(int port, int maxConnectionCount, string? password = null) public INetworkCommunicatorServer Start(int port, int maxConnectionCount, string? password = null)
{ {
if (!IsInUniverse) if (!IsInUniverse)
throw new($"{nameof(NetworkServer)} must be in an universe to start"); throw new($"{nameof(LiteNetLibServer)} must be in an universe to start");
Password = password ?? string.Empty; Password = password ?? string.Empty;
MaxConnectionCount = maxConnectionCount; MaxConnectionCount = maxConnectionCount;
Port = port; Port = port;
Manager.Start(port); Manager.Start(port);
return this;
} }
public void SendToClient(string to, INetworkPacket packet) public INetworkCommunicatorServer SendToClient<T>(string to, T packet) where T : class, new()
{ {
if (packet is not INetSerializable netSerializable)
throw new($"Packet trying to be sent to the server is not compatible with LiteNetLib");
bool isBroadcastToAll = to.CompareTo("*") == 0; bool isBroadcastToAll = to.CompareTo("*") == 0;
netDataWriter.Reset(); netDataWriter.Reset();
netPacketProcessor.WriteNetSerializable(netDataWriter, ref netSerializable); netPacketProcessor.Write(netDataWriter, packet);
if (isBroadcastToAll) if (isBroadcastToAll)
Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableOrdered); Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableOrdered);
else if (Manager.ConnectedPeerList.FirstOrDefault(p => p.Id.CompareTo(to) == 0) is NetPeer netPeer) else if (Manager.ConnectedPeerList.FirstOrDefault(p => p.Id.ToString().CompareTo(to) == 0) is NetPeer netPeer)
netPeer.Send(netDataWriter, DeliveryMethod.ReliableOrdered); netPeer.Send(netDataWriter, DeliveryMethod.ReliableOrdered);
else else
throw new($"Peer {to} couldn't be found."); throw new($"Peer {to} couldn't be found.");
return this;
} }
} }

View File

@ -1,27 +0,0 @@
using LiteNetLib.Utils;
namespace Syntriax.Engine.Network;
public class NetworkClient : NetworkBase, INetworkCommunicatorClient
{
private readonly NetDataWriter netDataWriter = new();
public void Connect(string address, int port, string? password = null)
{
if (!IsInUniverse)
throw new($"{nameof(NetworkClient)} must be in an universe to connect");
Manager.Start();
Manager.Connect(address, port, password ?? string.Empty);
}
public void SendToServer(INetworkPacket packet)
{
if (packet is not INetSerializable netSerializable)
throw new($"Packet trying to be sent to the server is not compatible with LiteNetLib");
netDataWriter.Reset();
netPacketProcessor.WriteNetSerializable(netDataWriter, ref netSerializable);
Manager.FirstPeer.Send(netDataWriter, LiteNetLib.DeliveryMethod.ReliableOrdered);
}
}