using System.Collections; using System.Collections.Generic; using GameNetworkLayer.Shared; using Svelto.Context; using Svelto.ECS; namespace CLre_server.API.Synergy { class ServerMessagingEngine: Engines.ServerEnginePreBuild, IWaitForFrameworkDestruction, IWaitForFrameworkInitialization { private struct MessageQueueItem { public SerializedCLreMessage msg; public int playerId; public NetworkDispatcherCode code; } private Utility.Reflection.INetMsgServerSender_SendMessage _sendMessage; private Utility.Reflection.INetMsgServerListener_RegisterListener _registerListener; private Queue _messageQueue = new Queue(10); private bool _isRunning = false; public override void Ready() { //Utility.Logging.MetaLog("Building send message delegate"); _sendMessage = Utility.Reflection.MethodAsDelegate>( "GameNetworkLayer.Server.NetMessageServerSender:SendMessage", generics: new [] {typeof(SerializedCLreMessage)}, instance: MainGameServer_SetupContainer_Patch.netMessageSender); //Utility.Logging.MetaLog("Building register listener delegate"); _registerListener = Utility.Reflection.MethodAsDelegate>( "GameNetworkLayer.Server.NetMessageServerListener:RegisterListener", generics: new [] {typeof(SerializedCLreMessage)}, instance: MainGameServer_SetupContainer_Patch.netMessageListener); _registerListener(Message.CLre_MESSAGE_NETCODE, OnMessageReceived); } private void OnMessageReceived(int playerId, ref SerializedCLreMessage data) { Message.HandleMessageReceive(playerId, ref data); } internal void EnqueueMessage(int playerId, ref SerializedCLreMessage msg) { _messageQueue.Enqueue(new MessageQueueItem { msg = msg, playerId = playerId, code = Message.CLre_MESSAGE_NETCODE, }); } public override IEntitiesDB entitiesDB { get; set; } public override IEntityFactory entityFactory { get; set; } public ServerMessagingEngine(): base() { MainServer.Server.Instance.Connected += (_, __) => { MessageSender().Run(); }; } public IEnumerator MessageSender() { while (!_isRunning) { yield return null; } while (_isRunning) { while (_messageQueue.Count != 0) { MessageQueueItem item = _messageQueue.Dequeue(); API.Utility.Logging.MetaLog($"Sending message with id {item.msg.Id}"); _sendMessage(item.code, ref item.msg, item.playerId); } yield return null; } } public void OnFrameworkDestroyed() { _isRunning = false; } public void OnFrameworkInitialized() { _isRunning = true; } } }