feat: IConnection interface added for connection information
This commit is contained in:
parent
7cc3bb4d83
commit
d89af5ccad
@ -65,12 +65,12 @@ public class BallBehaviour : Behaviour2D, IFirstFrameUpdate, IPhysicsUpdate, INe
|
||||
public BallBehaviour() { }
|
||||
public BallBehaviour(float speed) => Speed = speed;
|
||||
|
||||
void IPacketListenerClient<BallResetPacket>.OnClientPacketArrived(BallResetPacket packet) => ResetBall();
|
||||
void IPacketListenerClient<BallUpdatePacket>.OnClientPacketArrived(BallUpdatePacket packet)
|
||||
void IPacketListenerClient<BallResetPacket>.OnClientPacketArrived(IConnection sender, BallResetPacket packet) => ResetBall();
|
||||
void IPacketListenerClient<BallUpdatePacket>.OnClientPacketArrived(IConnection sender, BallUpdatePacket packet)
|
||||
{
|
||||
networkTween = Transform.TweenPositionAdditive(tweenManager, .25f, Transform.Position.FromTo(packet.Position));
|
||||
RigidBody.Velocity = packet.Velocity;
|
||||
physicsEngine2D.StepIndividual(RigidBody, new System.DateTime(System.DateTime.UtcNow.Ticks - packet.Timestamp).Second);
|
||||
physicsEngine2D.StepIndividual(RigidBody, sender.Ping);
|
||||
}
|
||||
|
||||
private class BallResetPacket : INetworkPacket;
|
||||
@ -78,14 +78,12 @@ public class BallBehaviour : Behaviour2D, IFirstFrameUpdate, IPhysicsUpdate, INe
|
||||
{
|
||||
public Vector2D Position { get; set; } = Vector2D.Zero;
|
||||
public Vector2D Velocity { get; set; } = Vector2D.Zero;
|
||||
public long Timestamp { get; set; } = 0;
|
||||
|
||||
public BallUpdatePacket() { }
|
||||
public BallUpdatePacket(BallBehaviour ballBehaviour)
|
||||
{
|
||||
Position = ballBehaviour.Transform.Position;
|
||||
Velocity = ballBehaviour.RigidBody.Velocity;
|
||||
Timestamp = System.DateTime.UtcNow.Ticks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
|
||||
private void OnDownPressed(IButtonInputs<Keys> sender, IButtonInputs<Keys>.ButtonCallbackArguments args) { isDownPressed = true; networkClient?.SendToServer(new PaddleKeyStatePacket(this)); }
|
||||
private void OnDownReleased(IButtonInputs<Keys> sender, IButtonInputs<Keys>.ButtonCallbackArguments args) { isDownPressed = false; networkClient?.SendToServer(new PaddleKeyStatePacket(this)); }
|
||||
|
||||
public void OnServerPacketArrived(string sender, PaddleKeyStatePacket packet)
|
||||
public void OnServerPacketArrived(IConnection sender, PaddleKeyStatePacket packet)
|
||||
{
|
||||
isUpPressed = packet.IsUpPressed;
|
||||
isDownPressed = packet.IsDownPressed;
|
||||
@ -78,7 +78,7 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
|
||||
networkServer?.SendToClient("*", new PaddleKeyStatePacket(this));
|
||||
}
|
||||
|
||||
public void OnClientPacketArrived(PaddleKeyStatePacket packet)
|
||||
public void OnClientPacketArrived(IConnection sender, PaddleKeyStatePacket packet)
|
||||
{
|
||||
isUpPressed = packet.IsUpPressed;
|
||||
isDownPressed = packet.IsDownPressed;
|
||||
|
@ -89,7 +89,7 @@ public class PongManagerBehaviour : Behaviour, INetworkEntity, IFirstFrameUpdate
|
||||
return Vector2D.Right.Rotate(isBackwards ? rotation + Syntriax.Engine.Core.Math.PI : rotation);
|
||||
}
|
||||
|
||||
void IPacketListenerServer<RequestStartPacket>.OnServerPacketArrived(string sender, RequestStartPacket packet)
|
||||
void IPacketListenerServer<RequestStartPacket>.OnServerPacketArrived(IConnection sender, RequestStartPacket packet)
|
||||
{
|
||||
if (ball.RigidBody.Velocity.MagnitudeSquared > 0.01f)
|
||||
return;
|
||||
|
8
Shared/Network/Abstract/IConnection.cs
Normal file
8
Shared/Network/Abstract/IConnection.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Syntriax.Engine.Network;
|
||||
|
||||
public interface IConnection
|
||||
{
|
||||
string Id { get; }
|
||||
float Ping { get; }
|
||||
float RoundTrip { get; }
|
||||
}
|
@ -1,13 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Syntriax.Engine.Core;
|
||||
|
||||
namespace Syntriax.Engine.Network;
|
||||
|
||||
public interface INetworkCommunicator
|
||||
{
|
||||
Event<INetworkCommunicator, IConnection> OnConnectionEstablished { get; }
|
||||
Event<INetworkCommunicator, IConnection> OnConnectionAbolished { get; }
|
||||
|
||||
IReadOnlyDictionary<string, IConnection> Connections { get; }
|
||||
|
||||
INetworkCommunicator Stop();
|
||||
|
||||
INetworkCommunicator SubscribeToPackets<T>(Event<string, T>.EventHandler callback);
|
||||
INetworkCommunicator UnsubscribeFromPackets<T>(Event<string, T>.EventHandler callback);
|
||||
INetworkCommunicator SubscribeToPackets<T>(Event<IConnection, T>.EventHandler callback);
|
||||
INetworkCommunicator UnsubscribeFromPackets<T>(Event<IConnection, T>.EventHandler callback);
|
||||
}
|
||||
|
||||
public interface INetworkCommunicatorClient : INetworkCommunicator
|
||||
|
@ -2,5 +2,5 @@ namespace Syntriax.Engine.Network;
|
||||
|
||||
public interface IPacketListenerClient<T> : INetworkEntity
|
||||
{
|
||||
void OnClientPacketArrived(T packet);
|
||||
void OnClientPacketArrived(IConnection sender, T packet);
|
||||
}
|
||||
|
@ -2,5 +2,5 @@ namespace Syntriax.Engine.Network;
|
||||
|
||||
public interface IPacketListenerServer<T> : INetworkEntity
|
||||
{
|
||||
void OnServerPacketArrived(string sender, T packet);
|
||||
void OnServerPacketArrived(IConnection sender, T packet);
|
||||
}
|
||||
|
@ -14,11 +14,16 @@ public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicat
|
||||
{
|
||||
protected readonly NetPacketProcessor netPacketProcessor = new();
|
||||
|
||||
private readonly Dictionary<Type, Event<string, object>> listeners = [];
|
||||
private readonly Dictionary<Type, Event<IConnection, object>> listeners = [];
|
||||
private readonly Dictionary<string, IConnection> _connections = [];
|
||||
|
||||
public IReadOnlyDictionary<string, IConnection> Connections => _connections;
|
||||
public EventBasedNetListener Listener { get; private set; } = null!;
|
||||
public NetManager Manager { get; private set; } = null!;
|
||||
|
||||
public Event<INetworkCommunicator, IConnection> OnConnectionEstablished { get; } = new();
|
||||
public Event<INetworkCommunicator, IConnection> OnConnectionAbolished { get; } = new();
|
||||
|
||||
public INetworkCommunicator Stop()
|
||||
{
|
||||
Manager.Stop();
|
||||
@ -33,10 +38,10 @@ public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicat
|
||||
|
||||
protected virtual void OnPacketArrived<T>(T packet, NetPeer peer) where T : INetworkPacket
|
||||
{
|
||||
if (!listeners.TryGetValue(typeof(T), out Event<string, object>? @event))
|
||||
if (!listeners.TryGetValue(typeof(T), out Event<IConnection, object>? @event))
|
||||
return;
|
||||
|
||||
@event.Invoke(peer.Id.ToString(), packet);
|
||||
@event.Invoke(Connections[peer.Id.ToString()], packet);
|
||||
}
|
||||
|
||||
private void NetworkReceiveEvent(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod)
|
||||
@ -45,6 +50,22 @@ public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicat
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void ConnectionEstablished(NetPeer peer)
|
||||
{
|
||||
LiteNetLibConnection connection = new(peer);
|
||||
_connections.Add(connection.Id, connection);
|
||||
OnConnectionEstablished.Invoke(this, connection);
|
||||
}
|
||||
|
||||
private void ConnectionAbolished(NetPeer peer, DisconnectInfo disconnectInfo)
|
||||
{
|
||||
if (!_connections.TryGetValue(peer.Id.ToString(), out var connection))
|
||||
return;
|
||||
|
||||
_connections.Remove(connection.Id);
|
||||
OnConnectionAbolished.Invoke(this, connection);
|
||||
}
|
||||
|
||||
private void SetupPackets()
|
||||
{
|
||||
// Find network packets implementing INetworkPacket
|
||||
@ -95,6 +116,8 @@ public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicat
|
||||
Manager = new NetManager(Listener);
|
||||
|
||||
Listener.NetworkReceiveEvent += NetworkReceiveEvent;
|
||||
Listener.PeerConnectedEvent += ConnectionEstablished;
|
||||
Listener.PeerDisconnectedEvent += ConnectionAbolished;
|
||||
|
||||
SetupEnginePackets();
|
||||
SetupPackets();
|
||||
@ -118,10 +141,10 @@ public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicat
|
||||
netPacketProcessor.RegisterNestedType(Vector3DNetPacker.Write, Vector3DNetPacker.Read);
|
||||
}
|
||||
|
||||
public INetworkCommunicator SubscribeToPackets<T>(Event<string, T>.EventHandler callback)
|
||||
public INetworkCommunicator SubscribeToPackets<T>(Event<IConnection, T>.EventHandler callback)
|
||||
{
|
||||
Type type = typeof(T);
|
||||
if (!listeners.TryGetValue(type, out Event<string, object>? @event))
|
||||
if (!listeners.TryGetValue(type, out Event<IConnection, object>? @event))
|
||||
{
|
||||
@event = new();
|
||||
listeners.Add(type, @event);
|
||||
@ -131,15 +154,15 @@ public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicat
|
||||
return this;
|
||||
}
|
||||
|
||||
public INetworkCommunicator UnsubscribeFromPackets<T>(Event<string, T>.EventHandler callback)
|
||||
public INetworkCommunicator UnsubscribeFromPackets<T>(Event<IConnection, T>.EventHandler callback)
|
||||
{
|
||||
Type type = typeof(T);
|
||||
if (!listeners.TryGetValue(type, out Event<string, object>? @event))
|
||||
if (!listeners.TryGetValue(type, out Event<IConnection, object>? @event))
|
||||
return this;
|
||||
|
||||
@event.RemoveListener(EventDelegateWrapper(callback));
|
||||
return this;
|
||||
}
|
||||
|
||||
private static Event<string, object>.EventHandler EventDelegateWrapper<T>(Event<string, T>.EventHandler callback) => (sender, @object) => callback.Invoke(sender, (T)@object);
|
||||
private static Event<IConnection, object>.EventHandler EventDelegateWrapper<T>(Event<IConnection, T>.EventHandler callback) => (sender, @object) => callback.Invoke(sender, (T)@object);
|
||||
}
|
||||
|
10
Shared/Network/LiteNetLib/LiteNetLibConnection.cs
Normal file
10
Shared/Network/LiteNetLib/LiteNetLibConnection.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using LiteNetLib;
|
||||
|
||||
namespace Syntriax.Engine.Network;
|
||||
|
||||
public record class LiteNetLibConnection(NetPeer NetPeer) : IConnection
|
||||
{
|
||||
public string Id { get; } = NetPeer.Id.ToString();
|
||||
public float Ping => NetPeer.Ping * .001f;
|
||||
public float RoundTrip => NetPeer.RoundTripTime * .001f;
|
||||
}
|
@ -39,7 +39,7 @@ public class LiteNetLibServer : LiteNetLibCommunicatorBase, INetworkCommunicator
|
||||
MaxConnectionCount = maxConnectionCount;
|
||||
Port = port;
|
||||
|
||||
Manager.Start(port);
|
||||
Manager.Start(8888);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -73,50 +73,50 @@ public class NetworkManager : Behaviour, INetworkManager
|
||||
#endregion
|
||||
|
||||
#region Packet Routing
|
||||
private void OnPacketReceived<T>(string senderClientId, T entityDataPacket)
|
||||
private void OnPacketReceived<T>(IConnection sender, T entityDataPacket)
|
||||
{
|
||||
if (entityDataPacket is IEntityNetworkPacket entityPacket)
|
||||
RoutePacket(senderClientId, entityDataPacket, entityPacket);
|
||||
RoutePacket(sender, entityDataPacket, entityPacket);
|
||||
else
|
||||
BroadcastPacket(senderClientId, entityDataPacket);
|
||||
BroadcastPacket(sender, entityDataPacket);
|
||||
}
|
||||
|
||||
private void RoutePacket<T>(string senderClientId, T entityDataPacket, IEntityNetworkPacket entityPacket)
|
||||
private void RoutePacket<T>(IConnection sender, T entityDataPacket, IEntityNetworkPacket entityPacket)
|
||||
{
|
||||
if (NetworkCommunicator is INetworkCommunicatorClient)
|
||||
RoutePacket(clientPacketRouters, entityPacket.EntityId, senderClientId, entityDataPacket);
|
||||
RoutePacket(clientPacketRouters, entityPacket.EntityId, sender, entityDataPacket);
|
||||
if (NetworkCommunicator is INetworkCommunicatorServer)
|
||||
RoutePacket(serverPacketRouters, entityPacket.EntityId, senderClientId, entityDataPacket);
|
||||
RoutePacket(serverPacketRouters, entityPacket.EntityId, sender, entityDataPacket);
|
||||
}
|
||||
|
||||
private void BroadcastPacket<T>(string senderClientId, T entityDataPacket)
|
||||
private void BroadcastPacket<T>(IConnection sender, T entityDataPacket)
|
||||
{
|
||||
if (NetworkCommunicator is INetworkCommunicatorClient)
|
||||
BroadcastPacket(clientPacketRouters, senderClientId, entityDataPacket);
|
||||
BroadcastPacket(clientPacketRouters, sender, entityDataPacket);
|
||||
if (NetworkCommunicator is INetworkCommunicatorServer)
|
||||
BroadcastPacket(serverPacketRouters, senderClientId, entityDataPacket);
|
||||
BroadcastPacket(serverPacketRouters, sender, entityDataPacket);
|
||||
}
|
||||
|
||||
|
||||
private static void BroadcastPacket<T>(
|
||||
Dictionary<Type, Dictionary<string, object>> packetRouters,
|
||||
string senderClientId,
|
||||
IConnection sender,
|
||||
T entityDataPacket)
|
||||
{
|
||||
if (!packetRouters.TryGetValue(entityDataPacket!.GetType(), out Dictionary<string, object>? routers))
|
||||
return;
|
||||
|
||||
foreach ((string id, object routerEventReference) in routers)
|
||||
foreach ((string behaviourId, object routerEventReference) in routers)
|
||||
{
|
||||
Event<string, T> routerEvent = (Event<string, T>)routerEventReference;
|
||||
routerEvent.Invoke(senderClientId, entityDataPacket!);
|
||||
Event<IConnection, T> routerEvent = (Event<IConnection, T>)routerEventReference;
|
||||
routerEvent.Invoke(sender, entityDataPacket!);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RoutePacket<T>(
|
||||
Dictionary<Type, Dictionary<string, object>> packetRouters,
|
||||
string entityId,
|
||||
string senderClientId,
|
||||
IConnection sender,
|
||||
T entityDataPacket)
|
||||
{
|
||||
if (!packetRouters.TryGetValue(entityDataPacket!.GetType(), out Dictionary<string, object>? routers))
|
||||
@ -125,8 +125,8 @@ public class NetworkManager : Behaviour, INetworkManager
|
||||
if (!routers.TryGetValue(entityId, out object? routerEventReference))
|
||||
return;
|
||||
|
||||
Event<string, T> routerEvent = (Event<string, T>)routerEventReference;
|
||||
routerEvent.Invoke(senderClientId, entityDataPacket!);
|
||||
Event<IConnection, T> routerEvent = (Event<IConnection, T>)routerEventReference;
|
||||
routerEvent.Invoke(sender, entityDataPacket!);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -156,7 +156,7 @@ public class NetworkManager : Behaviour, INetworkManager
|
||||
|
||||
private object CreateEventAndRegister(Type packetType, INetworkEntity behaviour, NetworkType networkType)
|
||||
{
|
||||
Type genericEventType = typeof(Event<,>).MakeGenericType(typeof(string), packetType);
|
||||
Type genericEventType = typeof(Event<,>).MakeGenericType(typeof(IConnection), packetType);
|
||||
object packetListenerEvent = Activator.CreateInstance(genericEventType)!;
|
||||
|
||||
if (!registerPacketListenersMethods.TryGetValue(packetType, out MethodInfo? registerPacketListenerMethod))
|
||||
@ -168,12 +168,12 @@ public class NetworkManager : Behaviour, INetworkManager
|
||||
|
||||
private static void RegisterPacketListenerEvent<T>(
|
||||
INetworkEntity behaviour,
|
||||
Event<string, T> packetListenerEvent,
|
||||
Event<IConnection, T> packetListenerEvent,
|
||||
NetworkType networkType)
|
||||
{
|
||||
switch (networkType)
|
||||
{
|
||||
case NetworkType.Client: packetListenerEvent.AddListener((sender, packet) => ((IPacketListenerClient<T>)behaviour).OnClientPacketArrived(packet)); break;
|
||||
case NetworkType.Client: packetListenerEvent.AddListener((sender, packet) => ((IPacketListenerClient<T>)behaviour).OnClientPacketArrived(sender, packet)); break;
|
||||
case NetworkType.Server: packetListenerEvent.AddListener((sender, packet) => ((IPacketListenerServer<T>)behaviour).OnServerPacketArrived(sender, packet)); break;
|
||||
}
|
||||
}
|
||||
@ -203,7 +203,7 @@ public class NetworkManager : Behaviour, INetworkManager
|
||||
|
||||
private static void ClearRouter<T>(object routerEventReference)
|
||||
{
|
||||
Event<string, T> routerEvent = (Event<string, T>)routerEventReference;
|
||||
Event<IConnection, T> routerEvent = (Event<IConnection, T>)routerEventReference;
|
||||
routerEvent.Clear();
|
||||
}
|
||||
|
||||
@ -262,7 +262,7 @@ public class NetworkManager : Behaviour, INetworkManager
|
||||
{
|
||||
MethodInfo genericOnPacketArrivedMethod = onPacketArrivedMethod.MakeGenericMethod(packetType);
|
||||
|
||||
Type genericDelegateType = typeof(Event<,>.EventHandler).MakeGenericType(typeof(string), packetType);
|
||||
Type genericDelegateType = typeof(Event<,>.EventHandler).MakeGenericType(typeof(IConnection), packetType);
|
||||
Delegate genericPacketReceivedDelegate = Delegate.CreateDelegate(genericDelegateType, this, genericOnPacketArrivedMethod);
|
||||
|
||||
packetRetrievalDelegates.Add((packetType, genericPacketReceivedDelegate));
|
||||
|
Loading…
x
Reference in New Issue
Block a user