using System; using System.Collections.Generic; using System.Diagnostics; using LiteNetLib; using LiteNetLib.Utils; using Syntriax.Engine.Core; using Syntriax.Engine.Network.Abstract; namespace Syntriax.Engine.Network; public abstract class NetworkBase : BehaviourOverride, INetworkCommunicator { private readonly NetPacketProcessor netPacketProcessor = new(); private readonly Dictionary networkEntities = []; private readonly Dictionary> callbacks = []; private BehaviourCollector networkEntityCollector = null!; public EventBasedNetListener Listener { get; private set; } = null!; public NetManager Manager { get; private set; } = null!; public NetworkBase() { Priority = 10; Listener = new EventBasedNetListener(); Manager = new NetManager(Listener); Listener.NetworkReceiveEvent += NetworkReceiveEvent; } protected override void OnInitialize() { base.OnInitialize(); networkEntityCollector = new(GameObject.GameManager); networkEntityCollector.OnCollected += OnNetworkEntityCollected; networkEntityCollector.OnRemoved += OnNetworkEntityRemoved; } protected override void OnFinalize() { networkEntityCollector.OnCollected -= OnNetworkEntityCollected; networkEntityCollector.OnRemoved -= OnNetworkEntityRemoved; Stop(); } private void OnNetworkEntityCollected(BehaviourCollector sender, INetworkEntity behaviourCollected) => networkEntities.Add(behaviourCollected.NetworkId, behaviourCollected); private void OnNetworkEntityRemoved(BehaviourCollector sender, INetworkEntity behaviourRemoved) => networkEntities.Remove(behaviourRemoved.NetworkId); private void NetworkReceiveEvent(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod) { netPacketProcessor.ReadAllPackets(reader, peer); } public void PollEvents() => Manager.PollEvents(); public void Stop() => Manager.Stop(); protected override void OnUpdate() => PollEvents(); public void RegisterEntityPacketListener(INetworkEntity networkEntity, INetworkCommunicator.EntityPacketReceivedDelegate onPacketReceived) where T : INetSerializable { if (!callbacks.TryGetValue(typeof(T), out var list)) { list = []; callbacks.Add(typeof(T), list); netPacketProcessor.SubscribeReusable, NetPeer>(OnPacketReceived); } if (list.Contains(onPacketReceived)) return; list.Add(onPacketReceived); } public void UnregisterEntityPacketListener(INetworkEntity networkEntity, INetworkCommunicator.EntityPacketReceivedDelegate onPacketReceived) where T : INetSerializable { if (!callbacks.TryGetValue(typeof(T), out var list)) return; list.Remove(onPacketReceived); } public void SendEntityPacket(INetworkEntity networkEntity, T packet, params NetPeer[] netPeers) where T : INetSerializable { NetworkPacket networkPacket = new() { NetworkId = networkEntity.NetworkId, Data = packet }; NetDataWriter netDataWriter = new(); netPacketProcessor.Write(netDataWriter, networkPacket); foreach (var netPeer in netPeers) netPeer.Send(netDataWriter, DeliveryMethod.ReliableOrdered); } private void OnPacketReceived(NetworkPacket packet, NetPeer peer) where T : INetSerializable { Debug.WriteLine($"Packet Received: {packet.NetworkId} - {typeof(T)}"); if (!callbacks.TryGetValue(typeof(T), out var list)) return; INetworkEntity networkEntity = networkEntities[packet.NetworkId]; foreach (INetworkCommunicator.EntityPacketReceivedDelegate callback in list) callback.Invoke(networkEntity, packet, peer); } }