wip: Network
This commit is contained in:
@@ -12,4 +12,7 @@ public interface INetworkBehaviour : IBehaviour
|
||||
bool IsClient { get; }
|
||||
|
||||
INetworkCommunicator NetworkCommunicator { get; }
|
||||
|
||||
public void RequestAssignment();
|
||||
public void ReleaseAssignment();
|
||||
}
|
||||
|
@@ -15,7 +15,8 @@ public interface INetworkCommunicator
|
||||
void PollEvents();
|
||||
void Stop();
|
||||
|
||||
void RegisterEntityListener(IEntity entity, Action<NetPacketReader> onDataReceived);
|
||||
void RegisterEntityListener(IEntity entity, Action<NetPacketReader, NetPeer> onDataReceived);
|
||||
void UnregisterEntityListener(IEntity entity);
|
||||
NetDataWriter GetEntityWriter(IEntity entity);
|
||||
NetDataWriter GetMessageWriter(IEntity entity);
|
||||
}
|
||||
|
@@ -1,7 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace Syntriax.Engine.Network.Abstract;
|
||||
|
||||
internal interface INetworkEntity
|
||||
{
|
||||
Action<INetworkEntity, int> OnNetworkIdChanged { get; set; }
|
||||
int NetworkId { get; set; }
|
||||
|
||||
void SetNetworkId(int id);
|
||||
|
@@ -1,14 +1,10 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Syntriax.Engine.Core.Abstract;
|
||||
|
||||
namespace Syntriax.Engine.Network.Abstract;
|
||||
|
||||
public interface INetworkManager
|
||||
{
|
||||
Action<IGameObject>? OnNetworkGameObjectInstantiated { get; set; }
|
||||
// Action<IGameObject>? OnNetworkGameObjectInstantiated { get; set; }
|
||||
|
||||
INetworkCommunicator Communicator { get; }
|
||||
INetworkCommunicator NetworkCommunicator { get; }
|
||||
|
||||
Task<T> Instantiate<T>(params object?[]? args) where T : class, IGameObject;
|
||||
// Task<T> Instantiate<T>(params object?[]? args) where T : class, IGameObject;
|
||||
}
|
||||
|
@@ -31,17 +31,17 @@ public abstract class NetworkBase : BehaviourOverride, INetworkCommunicator
|
||||
protected override void OnUpdate() => PollEvents();
|
||||
protected override void OnFinalize() => Stop();
|
||||
|
||||
private Dictionary<string, Action<NetPacketReader>> callbacks = new(32);
|
||||
private readonly Dictionary<string, Action<NetPacketReader, NetPeer>> callbacks = new(32);
|
||||
|
||||
private void NetworkReceiveEvent(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod)
|
||||
{
|
||||
if (callbacks.TryGetValue(reader.GetString(), out var action))
|
||||
action?.Invoke(reader);
|
||||
action?.Invoke(reader, peer);
|
||||
|
||||
reader.Recycle();
|
||||
}
|
||||
|
||||
public void RegisterEntityListener(IEntity entity, Action<NetPacketReader> onDataReceived)
|
||||
public void RegisterEntityListener(IEntity entity, Action<NetPacketReader, NetPeer> onDataReceived)
|
||||
{
|
||||
if (callbacks.ContainsKey(entity.Id))
|
||||
return;
|
||||
@@ -58,6 +58,13 @@ public abstract class NetworkBase : BehaviourOverride, INetworkCommunicator
|
||||
entity.OnIdChanged -= OnEntityIdChanged;
|
||||
}
|
||||
|
||||
public NetDataWriter GetMessageWriter(IEntity entity)
|
||||
{
|
||||
NetDataWriter netDataWriter = GetEntityWriter(entity);
|
||||
netDataWriter.Put((int)MessageType.Message);
|
||||
return netDataWriter;
|
||||
}
|
||||
|
||||
public NetDataWriter GetEntityWriter(IEntity entity)
|
||||
{
|
||||
NetDataWriter netDataWriter = new();
|
||||
|
@@ -1,9 +1,13 @@
|
||||
using System;
|
||||
|
||||
using LiteNetLib;
|
||||
|
||||
using Syntriax.Engine.Core;
|
||||
using Syntriax.Engine.Network.Abstract;
|
||||
|
||||
namespace Syntriax.Engine.Network;
|
||||
|
||||
public class NetworkBehaviour : BehaviourOverride, INetworkBehaviour, INetworkEntity
|
||||
public abstract class NetworkBehaviour : BehaviourOverride, INetworkBehaviour
|
||||
{
|
||||
public int NetworkId { get; private set; } = 0;
|
||||
|
||||
@@ -18,7 +22,9 @@ public class NetworkBehaviour : BehaviourOverride, INetworkBehaviour, INetworkEn
|
||||
{
|
||||
NetworkCommunicator = BehaviourController.GetBehaviourInParent<INetworkCommunicator>()
|
||||
?? GameObject.GameManager.FindBehaviour<INetworkCommunicator>()
|
||||
?? throw new System.Exception($"Could not find an {nameof(INetworkCommunicator)}.");
|
||||
?? throw new Exception($"Could not find an {nameof(INetworkCommunicator)}.");
|
||||
|
||||
NetworkCommunicator.RegisterEntityListener(this, OnMessageReceivedInternal);
|
||||
|
||||
if (NetworkCommunicator is INetworkClient client)
|
||||
{
|
||||
@@ -28,10 +34,66 @@ public class NetworkBehaviour : BehaviourOverride, INetworkBehaviour, INetworkEn
|
||||
|
||||
IsServer = true;
|
||||
LocalAssigned = true;
|
||||
|
||||
// TODO Set and send Network Id
|
||||
}
|
||||
|
||||
int INetworkEntity.NetworkId { get => NetworkId; set => NetworkId = value; }
|
||||
void INetworkEntity.SetNetworkId(int id) => NetworkId = id;
|
||||
public void ReleaseAssignment()
|
||||
{
|
||||
if (IsServer)
|
||||
return;
|
||||
|
||||
var netDataWriter = NetworkCommunicator.GetEntityWriter(this);
|
||||
netDataWriter.Put((int)MessageType.AssignmentRelease);
|
||||
NetworkCommunicator.Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
|
||||
public void RequestAssignment()
|
||||
{
|
||||
if (IsServer)
|
||||
return;
|
||||
|
||||
var netDataWriter = NetworkCommunicator.GetEntityWriter(this);
|
||||
netDataWriter.Put((int)MessageType.AssignmentRequest);
|
||||
NetworkCommunicator.Manager.SendToAll(netDataWriter, DeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
|
||||
protected abstract void OnMessageReceived(NetPacketReader reader, NetPeer peer);
|
||||
private void OnMessageReceivedInternal(NetPacketReader reader, NetPeer peer)
|
||||
{
|
||||
MessageType messageType = (MessageType)reader.GetInt();
|
||||
|
||||
if (IsServer)
|
||||
{
|
||||
switch (messageType)
|
||||
{
|
||||
case MessageType.Message: OnMessageReceived(reader, peer); break;
|
||||
case MessageType.AssignmentRequest:
|
||||
case MessageType.AssignmentRelease:
|
||||
var netDataWriter = NetworkCommunicator.GetEntityWriter(this);
|
||||
netDataWriter.Put((int)(messageType == MessageType.AssignmentRequest ? MessageType.Assigned : MessageType.Unassigned));
|
||||
peer.Send(netDataWriter, DeliveryMethod.ReliableOrdered);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (messageType)
|
||||
{
|
||||
case MessageType.Message: OnMessageReceived(reader, peer); break;
|
||||
case MessageType.Assigned: LocalAssigned = true; break;
|
||||
case MessageType.Unassigned: LocalAssigned = false; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal enum MessageType
|
||||
{
|
||||
Message,
|
||||
AssignmentRequest,
|
||||
AssignmentRelease,
|
||||
Assigned,
|
||||
Unassigned,
|
||||
}
|
||||
|
@@ -1,34 +1,31 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using LiteNetLib;
|
||||
using Syntriax.Engine.Core;
|
||||
using Syntriax.Engine.Core.Abstract;
|
||||
|
||||
using Syntriax.Engine.Network.Abstract;
|
||||
|
||||
namespace Syntriax.Engine.Network;
|
||||
|
||||
public class NetworkManager : NetworkBehaviour, INetworkManager
|
||||
{
|
||||
public Action<IGameObject>? OnNetworkGameObjectInstantiated { get; set; } = null;
|
||||
|
||||
public INetworkCommunicator Communicator { get; private set; } = null!;
|
||||
private BehaviourCollector<INetworkEntity> entities = null!;
|
||||
|
||||
private static int networkIdIndex = 0;
|
||||
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
base.OnInitialize();
|
||||
|
||||
((INetworkEntity)this).SetNetworkId(networkIdIndex++);
|
||||
|
||||
entities = new(GameObject.GameManager);
|
||||
foreach (var entity in entities)
|
||||
entity.SetNetworkId(networkIdIndex++);
|
||||
|
||||
entities.OnCollected += OnCollected;
|
||||
}
|
||||
|
||||
public Task<T> Instantiate<T>(params object?[]? args) where T : class, IGameObject
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
if (IsServer)
|
||||
return GameObject.GameManager.InstantiateGameObject<T>(args);
|
||||
private void OnCollected(BehaviourCollector<INetworkEntity> collector, INetworkEntity entity)
|
||||
=> entity.SetNetworkId(networkIdIndex++);
|
||||
|
||||
// Request Instantiation From Server
|
||||
int id = 0;
|
||||
return GameObject.GameManager.InstantiateGameObject<T>(args);
|
||||
});
|
||||
}
|
||||
protected override void OnMessageReceived(NetPacketReader reader, NetPeer peer) { }
|
||||
}
|
||||
|
Reference in New Issue
Block a user