Engine-Pong/Game/Network/NetworkBase.cs

110 lines
3.9 KiB
C#

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<uint, INetworkEntity> networkEntities = [];
private readonly Dictionary<Type, List<INetworkCommunicator.EntityPacketReceivedDelegate>> callbacks = [];
private BehaviourCollector<INetworkEntity> 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<INetworkEntity> sender, INetworkEntity behaviourCollected)
=> networkEntities.Add(behaviourCollected.NetworkId, behaviourCollected);
private void OnNetworkEntityRemoved(BehaviourCollector<INetworkEntity> 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<T>(INetworkEntity networkEntity, INetworkCommunicator.EntityPacketReceivedDelegate onPacketReceived) where T : INetSerializable
{
if (!callbacks.TryGetValue(typeof(T), out var list))
{
list = [];
callbacks.Add(typeof(T), list);
netPacketProcessor.SubscribeReusable<NetworkPacket<T>, NetPeer>(OnPacketReceived);
}
if (list.Contains(onPacketReceived))
return;
list.Add(onPacketReceived);
}
public void UnregisterEntityPacketListener<T>(INetworkEntity networkEntity, INetworkCommunicator.EntityPacketReceivedDelegate onPacketReceived) where T : INetSerializable
{
if (!callbacks.TryGetValue(typeof(T), out var list))
return;
list.Remove(onPacketReceived);
}
public void SendEntityPacket<T>(INetworkEntity networkEntity, T packet, params NetPeer[] netPeers) where T : INetSerializable
{
NetworkPacket<T> 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<T>(NetworkPacket<T> 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);
}
}