using System; using LiteNetLib; using Syntriax.Engine.Core; using Syntriax.Engine.Network.Abstract; namespace Syntriax.Engine.Network; public abstract class NetworkBehaviour : BehaviourOverride, INetworkBehaviour { public int NetworkId { get; private set; } = 0; public bool LocalAssigned { get; private set; } = false; public bool IsServer { get; private set; } = false; public bool IsClient { get; private set; } = false; public INetworkCommunicator NetworkCommunicator { get; private set; } = null!; protected override void OnInitialize() { NetworkCommunicator = BehaviourController.GetBehaviourInParent() ?? GameObject.GameManager.FindBehaviour() ?? throw new Exception($"Could not find an {nameof(INetworkCommunicator)}."); NetworkCommunicator.RegisterEntityListener(this, OnMessageReceivedInternal); if (NetworkCommunicator is INetworkClient client) { IsClient = true; return; } IsServer = true; LocalAssigned = true; } 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, }