From 03082ab43bf010d12b2bbe0d3f0765f700bccbd8 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 16 May 2025 21:34:35 +0300 Subject: [PATCH] feat: engine data type packers --- .../Network/Abstract/INetworkCommunicator.cs | 7 +-- .../{ => LiteNetLib}/LiteNetLibClient.cs | 0 .../LiteNetLibCommunicatorBase.cs | 50 +++++++++++++++++-- .../{ => LiteNetLib}/LiteNetLibServer.cs | 0 .../LiteNetLib/Packers/AABBNetPacker.cs | 22 ++++++++ .../LiteNetLib/Packers/CircleNetPacker.cs | 22 ++++++++ .../LiteNetLib/Packers/ColorHSVNetPacker.cs | 24 +++++++++ .../LiteNetLib/Packers/ColorRGBANetPacker.cs | 26 ++++++++++ .../LiteNetLib/Packers/ColorRGBNetPacker.cs | 24 +++++++++ .../Packers/Line2DEquationNetPacker.cs | 22 ++++++++ .../LiteNetLib/Packers/Line2DNetPacker.cs | 22 ++++++++ .../Packers/Projection1DNetPacker.cs | 22 ++++++++ .../LiteNetLib/Packers/QuaternionNetPacker.cs | 26 ++++++++++ .../LiteNetLib/Packers/Shape2DNetPacker.cs | 27 ++++++++++ .../LiteNetLib/Packers/TriangleNetPacker.cs | 24 +++++++++ .../LiteNetLib/Packers/Vector2DNetPacker.cs | 22 ++++++++ .../LiteNetLib/Packers/Vector3DNetPacker.cs | 24 +++++++++ Shared/Network/NetworkManager.cs | 6 +-- 18 files changed, 361 insertions(+), 9 deletions(-) rename Shared/Network/{ => LiteNetLib}/LiteNetLibClient.cs (100%) rename Shared/Network/{ => LiteNetLib}/LiteNetLibCommunicatorBase.cs (59%) rename Shared/Network/{ => LiteNetLib}/LiteNetLibServer.cs (100%) create mode 100644 Shared/Network/LiteNetLib/Packers/AABBNetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/CircleNetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/ColorHSVNetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/ColorRGBANetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/ColorRGBNetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/Line2DEquationNetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/Line2DNetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/Projection1DNetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/QuaternionNetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/Shape2DNetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/TriangleNetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/Vector2DNetPacker.cs create mode 100644 Shared/Network/LiteNetLib/Packers/Vector3DNetPacker.cs diff --git a/Shared/Network/Abstract/INetworkCommunicator.cs b/Shared/Network/Abstract/INetworkCommunicator.cs index c2035e7..b6e6618 100644 --- a/Shared/Network/Abstract/INetworkCommunicator.cs +++ b/Shared/Network/Abstract/INetworkCommunicator.cs @@ -1,12 +1,13 @@ +using System; + namespace Syntriax.Engine.Network; public interface INetworkCommunicator { - event OnPacketReceivedDelegate? OnPacketReceived; - INetworkCommunicator Stop(); - delegate void OnPacketReceivedDelegate(INetworkCommunicator sender, object packet, string from); + void SubscribeToPackets(Action callback); + void UnsubscribeFromPackets(Action callback); } public interface INetworkCommunicatorClient : INetworkCommunicator diff --git a/Shared/Network/LiteNetLibClient.cs b/Shared/Network/LiteNetLib/LiteNetLibClient.cs similarity index 100% rename from Shared/Network/LiteNetLibClient.cs rename to Shared/Network/LiteNetLib/LiteNetLibClient.cs diff --git a/Shared/Network/LiteNetLibCommunicatorBase.cs b/Shared/Network/LiteNetLib/LiteNetLibCommunicatorBase.cs similarity index 59% rename from Shared/Network/LiteNetLibCommunicatorBase.cs rename to Shared/Network/LiteNetLib/LiteNetLibCommunicatorBase.cs index f4a55b1..dfc41a8 100644 --- a/Shared/Network/LiteNetLibCommunicatorBase.cs +++ b/Shared/Network/LiteNetLib/LiteNetLibCommunicatorBase.cs @@ -12,10 +12,10 @@ namespace Syntriax.Engine.Network; public abstract class LiteNetLibCommunicatorBase : UniverseObject, INetworkCommunicator { - public event INetworkCommunicator.OnPacketReceivedDelegate? OnPacketReceived = null; - protected readonly NetPacketProcessor netPacketProcessor = new(); + private readonly Dictionary> listeners = []; + public EventBasedNetListener Listener { get; private set; } = null!; public NetManager Manager { get; private set; } = null!; @@ -40,7 +40,11 @@ public abstract class LiteNetLibCommunicatorBase : UniverseObject, INetworkCommu private void PollEvents(IUniverse sender, UniverseTime engineTime) => Manager.PollEvents(); protected virtual void OnPacketArrived(T packet, NetPeer peer) where T : INetworkPacket { - OnPacketReceived?.Invoke(this, packet, peer.Id.ToString()); + if (!listeners.TryGetValue(typeof(T), out List? delegates)) + return; + + foreach (Delegate @delegate in delegates) + @delegate.InvokeSafe(packet); } private void NetworkReceiveEvent(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod) @@ -48,6 +52,7 @@ public abstract class LiteNetLibCommunicatorBase : UniverseObject, INetworkCommu try { netPacketProcessor.ReadAllPackets(reader, peer); } catch { } } + private void SetupPackets() { // Find network packets implementing INetworkPacket @@ -84,6 +89,45 @@ public abstract class LiteNetLibCommunicatorBase : UniverseObject, INetworkCommu Manager = new NetManager(Listener); Listener.NetworkReceiveEvent += NetworkReceiveEvent; + + SetupEnginePackets(); SetupPackets(); } + + private void SetupEnginePackets() + { + // I know, ugly af. I need to find a better way + netPacketProcessor.RegisterNestedType(AABBNetPacker.Write, AABBNetPacker.Read); + netPacketProcessor.RegisterNestedType(CircleNetPacker.Write, CircleNetPacker.Read); + netPacketProcessor.RegisterNestedType(ColorHSVNetPacker.Write, ColorHSVNetPacker.Read); + netPacketProcessor.RegisterNestedType(ColorRGBANetPacker.Write, ColorRGBANetPacker.Read); + netPacketProcessor.RegisterNestedType(ColorRGBNetPacker.Write, ColorRGBNetPacker.Read); + netPacketProcessor.RegisterNestedType(Line2DEquationNetPacker.Write, Line2DEquationNetPacker.Read); + netPacketProcessor.RegisterNestedType(Line2DNetPacker.Write, Line2DNetPacker.Read); + netPacketProcessor.RegisterNestedType(Projection1DNetPacker.Write, Projection1DNetPacker.Read); + netPacketProcessor.RegisterNestedType(QuaternionNetPacker.Write, QuaternionNetPacker.Read); + netPacketProcessor.RegisterNestedType(Shape2DNetPacker.Write, Shape2DNetPacker.Read); + netPacketProcessor.RegisterNestedType(TriangleNetPacker.Write, TriangleNetPacker.Read); + netPacketProcessor.RegisterNestedType(Vector2DNetPacker.Write, Vector2DNetPacker.Read); + netPacketProcessor.RegisterNestedType(Vector3DNetPacker.Write, Vector3DNetPacker.Read); + } + + public void SubscribeToPackets(Action callback) + { + if (!listeners.TryGetValue(typeof(T), out List? delegates)) + { + delegates = []; + listeners.Add(typeof(T), delegates); + } + + delegates.Add(callback); + } + + public void UnsubscribeFromPackets(Action callback) + { + if (!listeners.TryGetValue(typeof(T), out List? delegates)) + return; + + delegates.Remove(callback); + } } diff --git a/Shared/Network/LiteNetLibServer.cs b/Shared/Network/LiteNetLib/LiteNetLibServer.cs similarity index 100% rename from Shared/Network/LiteNetLibServer.cs rename to Shared/Network/LiteNetLib/LiteNetLibServer.cs diff --git a/Shared/Network/LiteNetLib/Packers/AABBNetPacker.cs b/Shared/Network/LiteNetLib/Packers/AABBNetPacker.cs new file mode 100644 index 0000000..6372cd9 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/AABBNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class AABBNetPacker +{ + internal static void Write(NetDataWriter writer, AABB data) + { + Vector2DNetPacker.Write(writer, data.LowerBoundary); + Vector2DNetPacker.Write(writer, data.UpperBoundary); + } + + internal static AABB Read(NetDataReader reader) + { + Vector2D lowerBoundary = Vector2DNetPacker.Read(reader); + Vector2D upperBoundary = Vector2DNetPacker.Read(reader); + + return new AABB(lowerBoundary, upperBoundary); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/CircleNetPacker.cs b/Shared/Network/LiteNetLib/Packers/CircleNetPacker.cs new file mode 100644 index 0000000..7c323d8 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/CircleNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class CircleNetPacker +{ + internal static void Write(NetDataWriter writer, Circle data) + { + Vector2DNetPacker.Write(writer, data.Center); + writer.Put(data.Radius); + } + + internal static Circle Read(NetDataReader reader) + { + Vector2D center = Vector2DNetPacker.Read(reader); + float radius = reader.GetFloat(); + + return new Circle(center, radius); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/ColorHSVNetPacker.cs b/Shared/Network/LiteNetLib/Packers/ColorHSVNetPacker.cs new file mode 100644 index 0000000..3580923 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/ColorHSVNetPacker.cs @@ -0,0 +1,24 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class ColorHSVNetPacker +{ + internal static void Write(NetDataWriter writer, ColorHSV data) + { + writer.Put(data.Hue); + writer.Put(data.Saturation); + writer.Put(data.Value); + } + + internal static ColorHSV Read(NetDataReader reader) + { + float hue = reader.GetFloat(); + float saturation = reader.GetFloat(); + float value = reader.GetFloat(); + + return new ColorHSV(hue, saturation, value); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/ColorRGBANetPacker.cs b/Shared/Network/LiteNetLib/Packers/ColorRGBANetPacker.cs new file mode 100644 index 0000000..d5f6b89 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/ColorRGBANetPacker.cs @@ -0,0 +1,26 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class ColorRGBANetPacker +{ + internal static void Write(NetDataWriter writer, ColorRGBA data) + { + writer.Put(data.R); + writer.Put(data.G); + writer.Put(data.B); + writer.Put(data.A); + } + + internal static ColorRGBA Read(NetDataReader reader) + { + byte red = reader.GetByte(); + byte green = reader.GetByte(); + byte blue = reader.GetByte(); + byte alpha = reader.GetByte(); + + return new ColorRGBA(red, green, blue, alpha); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/ColorRGBNetPacker.cs b/Shared/Network/LiteNetLib/Packers/ColorRGBNetPacker.cs new file mode 100644 index 0000000..b9fed97 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/ColorRGBNetPacker.cs @@ -0,0 +1,24 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class ColorRGBNetPacker +{ + internal static void Write(NetDataWriter writer, ColorRGB data) + { + writer.Put(data.R); + writer.Put(data.G); + writer.Put(data.B); + } + + internal static ColorRGB Read(NetDataReader reader) + { + byte red = reader.GetByte(); + byte green = reader.GetByte(); + byte blue = reader.GetByte(); + + return new ColorRGB(red, green, blue); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/Line2DEquationNetPacker.cs b/Shared/Network/LiteNetLib/Packers/Line2DEquationNetPacker.cs new file mode 100644 index 0000000..dc770f6 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/Line2DEquationNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class Line2DEquationNetPacker +{ + internal static void Write(NetDataWriter writer, Line2DEquation data) + { + writer.Put(data.Slope); + writer.Put(data.OffsetY); + } + + internal static Line2DEquation Read(NetDataReader reader) + { + float slope = reader.GetFloat(); + float offsetY = reader.GetFloat(); + + return new Line2DEquation(slope, offsetY); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/Line2DNetPacker.cs b/Shared/Network/LiteNetLib/Packers/Line2DNetPacker.cs new file mode 100644 index 0000000..f64b0b3 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/Line2DNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class Line2DNetPacker +{ + internal static void Write(NetDataWriter writer, Line2D data) + { + Vector2DNetPacker.Write(writer, data.From); + Vector2DNetPacker.Write(writer, data.To); + } + + internal static Line2D Read(NetDataReader reader) + { + Vector2D from = Vector2DNetPacker.Read(reader); + Vector2D to = Vector2DNetPacker.Read(reader); + + return new Line2D(from, to); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/Projection1DNetPacker.cs b/Shared/Network/LiteNetLib/Packers/Projection1DNetPacker.cs new file mode 100644 index 0000000..4307423 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/Projection1DNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class Projection1DNetPacker +{ + internal static void Write(NetDataWriter writer, Projection1D data) + { + writer.Put(data.Min); + writer.Put(data.Max); + } + + internal static Projection1D Read(NetDataReader reader) + { + float min = reader.GetFloat(); + float max = reader.GetFloat(); + + return new Projection1D(min, max); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/QuaternionNetPacker.cs b/Shared/Network/LiteNetLib/Packers/QuaternionNetPacker.cs new file mode 100644 index 0000000..63d7afa --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/QuaternionNetPacker.cs @@ -0,0 +1,26 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class QuaternionNetPacker +{ + internal static void Write(NetDataWriter writer, Quaternion data) + { + writer.Put(data.X); + writer.Put(data.Y); + writer.Put(data.Z); + writer.Put(data.W); + } + + internal static Quaternion Read(NetDataReader reader) + { + float x = reader.GetFloat(); + float y = reader.GetFloat(); + float z = reader.GetFloat(); + float w = reader.GetFloat(); + + return new Quaternion(x, y, z, w); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/Shape2DNetPacker.cs b/Shared/Network/LiteNetLib/Packers/Shape2DNetPacker.cs new file mode 100644 index 0000000..1305a58 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/Shape2DNetPacker.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class Shape2DNetPacker +{ + internal static void Write(NetDataWriter writer, Shape2D data) + { + writer.Put(data.Vertices.Count); + foreach (Vector2D vertex in data.Vertices) + Vector2DNetPacker.Write(writer, vertex); + } + + internal static Shape2D Read(NetDataReader reader) + { + int verticesCount = reader.GetInt(); + List vertices = new(verticesCount); + + for (int i = 0; i < verticesCount; i++) + vertices.Add(Vector2DNetPacker.Read(reader)); + + return new Shape2D(vertices); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/TriangleNetPacker.cs b/Shared/Network/LiteNetLib/Packers/TriangleNetPacker.cs new file mode 100644 index 0000000..0e052e3 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/TriangleNetPacker.cs @@ -0,0 +1,24 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class TriangleNetPacker +{ + internal static void Write(NetDataWriter writer, Triangle data) + { + Vector2DNetPacker.Write(writer, data.A); + Vector2DNetPacker.Write(writer, data.B); + Vector2DNetPacker.Write(writer, data.C); + } + + internal static Triangle Read(NetDataReader reader) + { + Vector2D a = Vector2DNetPacker.Read(reader); + Vector2D b = Vector2DNetPacker.Read(reader); + Vector2D c = Vector2DNetPacker.Read(reader); + + return new Triangle(a, b, c); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/Vector2DNetPacker.cs b/Shared/Network/LiteNetLib/Packers/Vector2DNetPacker.cs new file mode 100644 index 0000000..4772046 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/Vector2DNetPacker.cs @@ -0,0 +1,22 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class Vector2DNetPacker +{ + internal static void Write(NetDataWriter writer, Vector2D data) + { + writer.Put(data.X); + writer.Put(data.Y); + } + + internal static Vector2D Read(NetDataReader reader) + { + int x = reader.GetInt(); + float y = reader.GetFloat(); + + return new Vector2D(x, y); + } +} diff --git a/Shared/Network/LiteNetLib/Packers/Vector3DNetPacker.cs b/Shared/Network/LiteNetLib/Packers/Vector3DNetPacker.cs new file mode 100644 index 0000000..741c290 --- /dev/null +++ b/Shared/Network/LiteNetLib/Packers/Vector3DNetPacker.cs @@ -0,0 +1,24 @@ +using LiteNetLib.Utils; + +using Syntriax.Engine.Core; + +namespace Syntriax.Engine.Network; + +internal static class Vector3DNetPacker +{ + internal static void Write(NetDataWriter writer, Vector3D data) + { + writer.Put(data.X); + writer.Put(data.Y); + writer.Put(data.Z); + } + + internal static Vector3D Read(NetDataReader reader) + { + int x = reader.GetInt(); + float y = reader.GetFloat(); + float z = reader.GetFloat(); + + return new Vector3D(x, y, z); + } +} diff --git a/Shared/Network/NetworkManager.cs b/Shared/Network/NetworkManager.cs index 62b40e4..7ceeb1f 100644 --- a/Shared/Network/NetworkManager.cs +++ b/Shared/Network/NetworkManager.cs @@ -37,10 +37,10 @@ public class NetworkManager : UniverseObject, INetworkManager private void OnPacketReceived(INetworkCommunicator sender, object packet, string from) { - if (packet is not EntityDataPacket entityDataPacket) - return; + // if (packet is not EntityDataPacket entityDataPacket) + // return; - _networkEntities[entityDataPacket.Entity].ReceiveData(entityDataPacket.Data); + // _networkEntities[entityDataPacket.Entity].ReceiveData(entityDataPacket.Data); } private void OnCollected(IBehaviourCollector sender, INetworkEntity behaviourCollected)