Test
This commit is contained in:
		@@ -1,13 +1,15 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
using LiteNetLib.Utils;
 | 
			
		||||
using Microsoft.Xna.Framework.Input;
 | 
			
		||||
 | 
			
		||||
using Syntriax.Engine.Core;
 | 
			
		||||
using Syntriax.Engine.Input;
 | 
			
		||||
using Syntriax.Engine.Network;
 | 
			
		||||
using Syntriax.Engine.Network.Abstract;
 | 
			
		||||
 | 
			
		||||
namespace Pong.Behaviours;
 | 
			
		||||
 | 
			
		||||
public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Speed) : BehaviourOverride
 | 
			
		||||
public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Speed) : NetworkBehaviour
 | 
			
		||||
{
 | 
			
		||||
    private Keys Up { get; } = Up;
 | 
			
		||||
    private Keys Down { get; } = Down;
 | 
			
		||||
@@ -26,10 +28,14 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (isUpPressed)
 | 
			
		||||
            GameObject.Transform.Position = GameObject.Transform.Position + Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed;
 | 
			
		||||
            Move(Vector2D.Up);
 | 
			
		||||
        else if (isDownPressed)
 | 
			
		||||
            GameObject.Transform.Position = GameObject.Transform.Position + -Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed;
 | 
			
		||||
            Move(-Vector2D.Up);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void Move(Vector2D vectorToMove)
 | 
			
		||||
    {
 | 
			
		||||
        GameObject.Transform.Position = GameObject.Transform.Position + vectorToMove * (float)Time.Elapsed.TotalSeconds * Speed;
 | 
			
		||||
        GameObject.Transform.Position = new Vector2D(GameObject.Transform.Position.X, MathF.Max(MathF.Min(GameObject.Transform.Position.Y, High), Low));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -54,8 +60,35 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
 | 
			
		||||
        inputs.UnregisterOnRelease(Down, OnDownReleased);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void OnUpPressed(IButtonInputs<Keys> inputs, Keys keys) => isUpPressed = true;
 | 
			
		||||
    private void OnUpReleased(IButtonInputs<Keys> inputs, Keys keys) => isUpPressed = false;
 | 
			
		||||
    private void OnDownPressed(IButtonInputs<Keys> inputs, Keys keys) => isDownPressed = true;
 | 
			
		||||
    private void OnDownReleased(IButtonInputs<Keys> inputs, Keys keys) => isDownPressed = false;
 | 
			
		||||
    private void OnUpPressed(IButtonInputs<Keys> inputs, Keys keys) { isUpPressed = true; SendData(new PaddleInputs() { IsUpPressed = isUpPressed, IsDownPressed = isDownPressed }); }
 | 
			
		||||
    private void OnUpReleased(IButtonInputs<Keys> inputs, Keys keys) { isUpPressed = false; SendData(new PaddleInputs() { IsUpPressed = isUpPressed, IsDownPressed = isDownPressed }); }
 | 
			
		||||
    private void OnDownPressed(IButtonInputs<Keys> inputs, Keys keys) { isDownPressed = true; SendData(new PaddleInputs() { IsUpPressed = isUpPressed, IsDownPressed = isDownPressed }); }
 | 
			
		||||
    private void OnDownReleased(IButtonInputs<Keys> inputs, Keys keys) { isDownPressed = false; SendData(new PaddleInputs() { IsUpPressed = isUpPressed, IsDownPressed = isDownPressed }); }
 | 
			
		||||
 | 
			
		||||
    public override void ReceiveData<T>(T data)
 | 
			
		||||
    {
 | 
			
		||||
        if (data is PaddleInputs paddleInputs)
 | 
			
		||||
        {
 | 
			
		||||
            System.Diagnostics.Debug.WriteLine($"Paddle Inputs Arrived: {paddleInputs.IsUpPressed}, {paddleInputs.IsDownPressed}");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [System.Serializable]
 | 
			
		||||
    public struct PaddleInputs : INetworkPacket
 | 
			
		||||
    {
 | 
			
		||||
        public bool IsUpPressed { get; set; }
 | 
			
		||||
        public bool IsDownPressed { get; set; }
 | 
			
		||||
 | 
			
		||||
        public void Deserialize(NetDataReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            IsUpPressed = reader.GetBool();
 | 
			
		||||
            IsDownPressed = reader.GetBool();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Serialize(NetDataWriter writer)
 | 
			
		||||
        {
 | 
			
		||||
            writer.Put(IsUpPressed);
 | 
			
		||||
            writer.Put(IsDownPressed);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,15 @@ namespace Syntriax.Engine.Network.Abstract;
 | 
			
		||||
 | 
			
		||||
public interface INetworkCommunicator
 | 
			
		||||
{
 | 
			
		||||
    event OnPacketReceivedDelegate? OnPacketReceived;
 | 
			
		||||
 | 
			
		||||
    EventBasedNetListener Listener { get; }
 | 
			
		||||
    NetManager Manager { get; }
 | 
			
		||||
 | 
			
		||||
    void PollEvents();
 | 
			
		||||
    void Stop();
 | 
			
		||||
 | 
			
		||||
    void Send<T>(NetworkPacket<T> Data);
 | 
			
		||||
 | 
			
		||||
    delegate void OnPacketReceivedDelegate(INetworkCommunicator sender, object packet);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,5 +6,7 @@ public interface INetworkEntity
 | 
			
		||||
 | 
			
		||||
    uint NetworkId { get; set; }
 | 
			
		||||
 | 
			
		||||
    void ReceiveData<T>(T data);
 | 
			
		||||
 | 
			
		||||
    delegate void OnNetworkIdChangedDelegate(INetworkEntity sender, uint previousId);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								Game/Network/Abstract/INetworkPacket.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								Game/Network/Abstract/INetworkPacket.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
using LiteNetLib.Utils;
 | 
			
		||||
 | 
			
		||||
namespace Syntriax.Engine.Network.Abstract;
 | 
			
		||||
 | 
			
		||||
public interface INetworkPacket : INetSerializable;
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using LiteNetLib;
 | 
			
		||||
using LiteNetLib.Utils;
 | 
			
		||||
 | 
			
		||||
@@ -11,11 +12,13 @@ namespace Syntriax.Engine.Network;
 | 
			
		||||
 | 
			
		||||
public abstract class NetworkBase : BehaviourOverride, INetworkCommunicator
 | 
			
		||||
{
 | 
			
		||||
    private readonly NetPacketProcessor netPacketProcessor = new();
 | 
			
		||||
    public event INetworkCommunicator.OnPacketReceivedDelegate? OnPacketReceived = null;
 | 
			
		||||
 | 
			
		||||
    private readonly Dictionary<uint, INetworkEntity> networkEntities = [];
 | 
			
		||||
    protected readonly NetPacketProcessor netPacketProcessor = new();
 | 
			
		||||
 | 
			
		||||
    private BehaviourCollector<INetworkEntity> networkEntityCollector = null!;
 | 
			
		||||
    protected readonly Dictionary<uint, INetworkEntity> networkEntities = [];
 | 
			
		||||
 | 
			
		||||
    protected BehaviourCollector<INetworkEntity> networkEntityCollector = null!;
 | 
			
		||||
 | 
			
		||||
    public EventBasedNetListener Listener { get; private set; } = null!;
 | 
			
		||||
    public NetManager Manager { get; private set; } = null!;
 | 
			
		||||
@@ -28,12 +31,80 @@ public abstract class NetworkBase : BehaviourOverride, INetworkCommunicator
 | 
			
		||||
        Manager = new NetManager(Listener);
 | 
			
		||||
 | 
			
		||||
        Listener.NetworkReceiveEvent += NetworkReceiveEvent;
 | 
			
		||||
        netPacketProcessor.SubscribeReusable<NetworkPacket<int>, NetPeer>(OnPacketArrived);
 | 
			
		||||
 | 
			
		||||
        netPacketProcessor.RegisterNestedType<Pong.Behaviours.PaddleBehaviour.PaddleInputs>();
 | 
			
		||||
        RegisterPackets();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void OnPacketArrived(NetworkPacket<int> packet, NetPeer peer)
 | 
			
		||||
    public void RegisterPackets()
 | 
			
		||||
    {
 | 
			
		||||
        Debug.WriteLine($"Packet Arrived for {packet.NetworkId}: {packet.Data}");
 | 
			
		||||
        var packetTypes = Assembly.GetExecutingAssembly().GetTypes()
 | 
			
		||||
            .Where(t => typeof(INetworkPacket).IsAssignableFrom(t) && !t.IsInterface)
 | 
			
		||||
            .ToList();
 | 
			
		||||
 | 
			
		||||
        // MethodInfo subscribeMethod = netPacketProcessor.GetType()
 | 
			
		||||
        //     .GetMethod(nameof(NetPacketProcessor.SubscribeReusable), [typeof(Action<,>)]);
 | 
			
		||||
 | 
			
		||||
        MethodInfo[] subscribeMethods = netPacketProcessor.GetType()
 | 
			
		||||
            .GetMethods()
 | 
			
		||||
            .Where(m => m.Name == nameof(NetPacketProcessor.SubscribeReusable))
 | 
			
		||||
            .ToArray();
 | 
			
		||||
 | 
			
		||||
        MethodInfo subscribeMethod = subscribeMethods
 | 
			
		||||
            .FirstOrDefault(m => m.GetParameters().Length == 1 &&
 | 
			
		||||
                                 m.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(Action<,>));
 | 
			
		||||
 | 
			
		||||
        MethodInfo[] methodInfos = typeof(NetworkBase)
 | 
			
		||||
                                .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);
 | 
			
		||||
        MethodInfo method = methodInfos
 | 
			
		||||
                        .FirstOrDefault(m => m.Name == "OnPacketArrived" && m.IsGenericMethod);
 | 
			
		||||
 | 
			
		||||
        // .GetMethod(nameof(OnPacketArrived), BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new Exception();
 | 
			
		||||
 | 
			
		||||
        foreach (var packetType in packetTypes)
 | 
			
		||||
        {
 | 
			
		||||
            var networkPacketType = typeof(NetworkPacket<>).MakeGenericType(packetType);
 | 
			
		||||
            MethodInfo genericSubscribe = subscribeMethod.MakeGenericMethod(networkPacketType, typeof(NetPeer));
 | 
			
		||||
 | 
			
		||||
            Action<object, NetPeer> handler = (packet, peer) =>
 | 
			
		||||
            {
 | 
			
		||||
                method = method.MakeGenericMethod(packetType);
 | 
			
		||||
                method.Invoke(this, [packet, peer]);
 | 
			
		||||
            };
 | 
			
		||||
            genericSubscribe.Invoke(netPacketProcessor, [handler]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // private void RegisterPackets()
 | 
			
		||||
    // {
 | 
			
		||||
    //     IEnumerable<Type> packetTypes = Assembly.GetExecutingAssembly().GetTypes().Where(
 | 
			
		||||
    //         t => t.GetInterfaces().Contains(typeof(INetworkPacket))
 | 
			
		||||
    //     );
 | 
			
		||||
 | 
			
		||||
    //     MethodInfo subscribeMethod = netPacketProcessor.GetType()
 | 
			
		||||
    //         .GetMethod(nameof(NetPacketProcessor.SubscribeReusable), [typeof(Action<,>)]) ?? throw new Exception();
 | 
			
		||||
 | 
			
		||||
    //     foreach (var packetType in packetTypes)
 | 
			
		||||
    //     {
 | 
			
		||||
    //         MethodInfo genericSubscribe = subscribeMethod.MakeGenericMethod(packetType, typeof(NetPeer));
 | 
			
		||||
    //         Action<object, NetPeer> handler = (packet, peer) =>
 | 
			
		||||
    //         {
 | 
			
		||||
    //             MethodInfo method = GetType()
 | 
			
		||||
    //                 .GetMethod(nameof(OnPacketArrived), BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new Exception();
 | 
			
		||||
    //             method = method.MakeGenericMethod(packetType.GetGenericArguments()[0]);
 | 
			
		||||
    //             method.Invoke(this, [packet, peer]);
 | 
			
		||||
    //         };
 | 
			
		||||
    //         genericSubscribe.Invoke(netPacketProcessor, [handler]);
 | 
			
		||||
    //     }
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    private void OnPacketArrived<T>(NetworkPacket<T> packet, NetPeer peer) where T : INetworkPacket//OnPacketArrived<T>(NetworkPacket<T> packet, NetPeer peer)
 | 
			
		||||
    {
 | 
			
		||||
        // Handle packet
 | 
			
		||||
        Console.WriteLine($"Packet of type {typeof(T)} arrived with data: {packet.Data}");
 | 
			
		||||
        if (networkEntities.TryGetValue(packet.NetworkId, out INetworkEntity? entity))
 | 
			
		||||
            entity.ReceiveData(packet.Data);
 | 
			
		||||
 | 
			
		||||
        OnPacketReceived?.Invoke(this, packet);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected override void OnInitialize()
 | 
			
		||||
@@ -67,4 +138,6 @@ public abstract class NetworkBase : BehaviourOverride, INetworkCommunicator
 | 
			
		||||
    public void Stop() => Manager.Stop();
 | 
			
		||||
 | 
			
		||||
    protected override void OnUpdate() => PollEvents();
 | 
			
		||||
 | 
			
		||||
    public abstract void Send<T>(NetworkPacket<T> packet);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
using System;
 | 
			
		||||
using LiteNetLib;
 | 
			
		||||
using LiteNetLib.Utils;
 | 
			
		||||
 | 
			
		||||
using Syntriax.Engine.Core;
 | 
			
		||||
using Syntriax.Engine.Network.Abstract;
 | 
			
		||||
 | 
			
		||||
@@ -48,4 +47,9 @@ public abstract class NetworkBehaviour : BehaviourOverride, INetworkBehaviour
 | 
			
		||||
 | 
			
		||||
        IsServer = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void SendData<T>(T data)
 | 
			
		||||
        => NetworkCommunicator.Send(new NetworkPacket<T>() { NetworkId = _networkId, Data = data });
 | 
			
		||||
 | 
			
		||||
    public abstract void ReceiveData<T>(T data);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,23 @@
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using LiteNetLib.Utils;
 | 
			
		||||
 | 
			
		||||
using Syntriax.Engine.Network.Abstract;
 | 
			
		||||
 | 
			
		||||
namespace Syntriax.Engine.Network;
 | 
			
		||||
 | 
			
		||||
public class NetworkClient : NetworkBase, INetworkCommunicatorClient
 | 
			
		||||
{
 | 
			
		||||
    private readonly NetDataWriter netDataWriter = new();
 | 
			
		||||
 | 
			
		||||
    public void Connect(string address, int port, string? password = null)
 | 
			
		||||
    {
 | 
			
		||||
        Manager.Start();
 | 
			
		||||
        Manager.Connect(address, port, password ?? string.Empty);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public override void Send<T>(NetworkPacket<T> packet)
 | 
			
		||||
    {
 | 
			
		||||
        netDataWriter.Reset();
 | 
			
		||||
        netPacketProcessor.Write(netDataWriter, packet);
 | 
			
		||||
        Manager.FirstPeer.Send(netDataWriter, LiteNetLib.DeliveryMethod.ReliableOrdered);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,4 +25,6 @@ public class NetworkManager : NetworkBehaviour, INetworkManager
 | 
			
		||||
 | 
			
		||||
    private void OnCollected(BehaviourCollector<INetworkEntity> collector, INetworkEntity entity)
 | 
			
		||||
        => entity.NetworkId = networkIdIndex++;
 | 
			
		||||
 | 
			
		||||
    public override void ReceiveData<T>(T data) { }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System;
 | 
			
		||||
using LiteNetLib.Utils;
 | 
			
		||||
 | 
			
		||||
using Syntriax.Engine.Network.Abstract;
 | 
			
		||||
 | 
			
		||||
namespace Syntriax.Engine.Network;
 | 
			
		||||
@@ -10,15 +11,23 @@ public class NetworkServer : NetworkBase, INetworkCommunicatorServer
 | 
			
		||||
    public int MaxConnectionCount { get; private set; } = 0;
 | 
			
		||||
    public int Port { get; private set; } = 8888;
 | 
			
		||||
 | 
			
		||||
    public NetworkServer() : base()
 | 
			
		||||
    private readonly NetDataWriter netDataWriter = new();
 | 
			
		||||
 | 
			
		||||
    public NetworkServer() : this(8888, 0) { }
 | 
			
		||||
    public NetworkServer(int port, int maxConnectionCount) : base()
 | 
			
		||||
    {
 | 
			
		||||
        MaxConnectionCount = maxConnectionCount;
 | 
			
		||||
        Port = port;
 | 
			
		||||
 | 
			
		||||
        Listener.ConnectionRequestEvent += request =>
 | 
			
		||||
        {
 | 
			
		||||
            if (Manager.ConnectedPeersCount < MaxConnectionCount)
 | 
			
		||||
            if (Manager.ConnectedPeersCount < maxConnectionCount)
 | 
			
		||||
                request.AcceptIfKey(Password);
 | 
			
		||||
            else
 | 
			
		||||
                request.Reject();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        OnPacketReceived += ServerOnPacketReceived;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void Start(int port, int maxConnectionCount, string? password = null)
 | 
			
		||||
@@ -29,4 +38,14 @@ public class NetworkServer : NetworkBase, INetworkCommunicatorServer
 | 
			
		||||
 | 
			
		||||
        Manager.Start(port);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public override void Send<T>(NetworkPacket<T> packet)
 | 
			
		||||
    {
 | 
			
		||||
        netDataWriter.Reset();
 | 
			
		||||
        netPacketProcessor.Write(netDataWriter, packet);
 | 
			
		||||
        Manager.SendToAll(netDataWriter, LiteNetLib.DeliveryMethod.ReliableOrdered);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void ServerOnPacketReceived(INetworkCommunicator sender, object packet)
 | 
			
		||||
        => Send((NetworkPacket<object>)packet);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user