Browse Source

Added NetworkTick and new derived NetMsgControllers

James Peret 2 years ago
parent
commit
3d2a796ed5

+ 1 - 4
Runtime/Client/ClientBehaviour.cs

@@ -61,10 +61,7 @@ namespace KairoEngine.Multiplayer
 
         public void SendNetMsgToServer(uint code, NetMsg netMsg)
         {
-            DataStreamWriter writer = new DataStreamWriter();
-            m_Driver.BeginSend(m_Connection, out writer);
-            netMsgController.SendData(code, netMsg, ref writer, this);
-            m_Driver.EndSend(writer);
+            netMsgController.SendData(code, netMsg, this);
         }
 
         public void OnDestroy()

+ 93 - 0
Runtime/Client/ClientNetMsgController.cs

@@ -0,0 +1,93 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using Unity.Networking.Transport;
+using KairoEngine.Core;
+using Sirenix.OdinInspector;
+
+namespace KairoEngine.Multiplayer
+{
+    [HideMonoScript]
+    public class ClientNetMsgController : NetMsgController
+    {
+        public ClientBehaviour client;
+        public NetworkTick networkTick;
+        
+        private List<NetMsg> sendMsgBuffer = new List<NetMsg>();
+        private List<NetMsg> receivedMsgBuffer = new List<NetMsg>();
+
+        private void Start()
+        {
+            GetNetMessageTypes();
+            networkTick.eventStreamName = client.eventStreamName;
+        }
+
+        private void OnEnable()
+        {
+            GenericEvents.StartListening($"{client.eventStreamName}_OnTick", OnTick);
+            GenericEvents.StartListening($"{client.eventStreamName}_Connected", StartTickSystem);
+        }        
+        private void OnDisable()
+        {
+            GenericEvents.StopListening($"{client.eventStreamName}_OnTick", OnTick);
+            GenericEvents.StopListening($"{client.eventStreamName}_Connected", StartTickSystem);
+        }
+
+        private void StartTickSystem(string text) => networkTick.StartTickSystem();
+
+        public override void ReceiveData(ref DataStreamReader stream, ClientBehaviour client) 
+        {
+            uint tick = stream.ReadUInt();
+            uint msgCount = stream.ReadByte();
+            for (int i = 0; i < msgCount; i++)
+            {
+                uint code = stream.ReadByte();
+                NetMsg msg = FindWithCode(code).ReceiveMessage(client, ref stream);
+                receivedMsgBuffer.Add(msg);
+            }
+        }
+
+        public override void SendData(uint code, NetMsg netMsg, ClientBehaviour client)
+        {
+            sendMsgBuffer.Add(netMsg);
+        }
+
+        private void OnTick(int tick)
+        {
+            SendBufferedData();
+            ReadBufferedData();
+        }
+
+        private void SendBufferedData()
+        {
+            if(sendMsgBuffer.Count == 0) return;
+            Debug.Log("Sending buffered data from client to server");
+            DataStreamWriter writer = new DataStreamWriter();
+            client.m_Driver.BeginSend(client.m_Connection, out writer);
+            writer.WriteUInt((uint)networkTick.tick); // Current Tick Header
+            writer.WriteByte((byte)sendMsgBuffer.Count); // Message count Header
+            for (int a = 0; a < sendMsgBuffer.Count; a++)
+            {
+                NetMsg netMsg = sendMsgBuffer[a];
+                if(netMsg != null)
+                {
+                    NetMsg typeMsg = FindWithCode(netMsg.code);
+                    if(typeMsg != null) typeMsg.SendMessage(client, netMsg, ref writer);
+                    else Debug.LogError($"Could not find NetMsg with code {netMsg.code}");
+                }
+            }
+            client.m_Driver.EndSend(writer);
+            sendMsgBuffer.Clear();
+        }
+
+        private void ReadBufferedData()
+        {
+            for (int a = 0; a < receivedMsgBuffer.Count; a++)
+            {
+                NetMsg msg = receivedMsgBuffer[a];
+                msg.ReadMessage(client);
+            }
+            receivedMsgBuffer.Clear();
+        }
+    }
+}

+ 11 - 0
Runtime/Client/ClientNetMsgController.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9ee4dfffc4a341e46b749497839d883b
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 12 - 6
Runtime/NetMsgController.cs

@@ -18,7 +18,7 @@ namespace KairoEngine.Multiplayer
             GetNetMessageTypes();
         }
 
-        private void GetNetMessageTypes()
+        protected void GetNetMessageTypes()
         {
             netMessageTypes = ReflectiveEnumerator.GetEnumerableOfType<NetMsg>()
                 .Where(x => x.code != 0)
@@ -26,7 +26,7 @@ namespace KairoEngine.Multiplayer
                 .ToList();
         }
 
-        public NetMsg FindWithCode(uint code)
+        public virtual NetMsg FindWithCode(uint code)
         {
             for (int i = 0; i < netMessageTypes.Count; i++)
             {
@@ -35,28 +35,34 @@ namespace KairoEngine.Multiplayer
             return null;
         }
 
-        public void ReceiveData(ref DataStreamReader stream, ServerBehaviour server, int clientId) 
+        public virtual void ReceiveData(ref DataStreamReader stream, ServerBehaviour server, int clientId) 
         {
             uint code = stream.ReadByte();
             NetMsg msg = FindWithCode(code).ReceiveMessage(server, ref stream, clientId);
             msg.ReadMessage(server, clientId);
         }
 
-        public void ReceiveData(ref DataStreamReader stream, ClientBehaviour client) 
+        public virtual void ReceiveData(ref DataStreamReader stream, ClientBehaviour client) 
         {
             uint code = stream.ReadByte();
             NetMsg msg = FindWithCode(code).ReceiveMessage(client, ref stream);
             msg.ReadMessage(client);
         }
 
-        public void SendData(uint code, NetMsg netMsg, ref DataStreamWriter writer, ServerBehaviour server, int clientId)
+        public virtual void SendData(uint code, NetMsg netMsg, ServerBehaviour server, int clientId)
         {
+            DataStreamWriter writer = new DataStreamWriter();
+            server.m_Driver.BeginSend(server.m_Connections[clientId], out writer);
             FindWithCode(code).SendMessage(server, netMsg, ref writer, clientId);
+            server.m_Driver.EndSend(writer);
         }
 
-        public void SendData(uint code, NetMsg netMsg, ref DataStreamWriter writer, ClientBehaviour client)
+        public virtual void SendData(uint code, NetMsg netMsg, ClientBehaviour client)
         {
+            DataStreamWriter writer = new DataStreamWriter();
+            client.m_Driver.BeginSend(client.m_Connection, out writer);
             FindWithCode(code).SendMessage(client, netMsg, ref writer);
+            client.m_Driver.EndSend(writer);
         }
 
 

+ 56 - 0
Runtime/NetworkTick.cs

@@ -0,0 +1,56 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UniRx;
+using Sirenix.OdinInspector;
+using KairoEngine.Core;
+
+namespace KairoEngine.Multiplayer
+{
+    [HideMonoScript]
+    public class NetworkTick : MonoBehaviour
+    {
+        [LabelText("Current Tick"), ShowInInspector, ReadOnly, PropertyOrder(0)] public int tick { get; private set; }
+        [LabelText("Refresh rate"), SuffixLabel("ms", true), PropertyOrder(1)] public int rate = 60;
+        [PropertyOrder(2)] public string eventStreamName = "EventStream";
+        [PropertyOrder(3)] public bool fixedCurrentTick = false;
+        [PropertyOrder(4)] public bool autoStart = false;
+
+        private bool running = false;
+
+        private void Start()
+        {
+            if(autoStart) StartTickSystem();
+        }
+
+        private void OnDisable() => StopTickSystem();
+
+        public void StartTickSystem()
+        {
+            running = true;
+            tick = 0;
+            UpdateTick();
+        }
+
+        public void StopTickSystem()
+        {
+            running = false;
+        }
+
+        private void UpdateTick()
+        {
+            if(!running) return;
+            Timer.ExecuteRealTime(rate, () => {
+                tick += 1;
+                GenericEvents.Trigger($"{eventStreamName}_OnTick", tick);
+                UpdateTick();
+            });
+        }
+
+        public void ChangeCurrentTick(int newCurrentTick)
+        {
+            if(fixedCurrentTick) return;
+            tick = newCurrentTick;
+        }
+    }
+}

+ 11 - 0
Runtime/NetworkTick.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a1d003d249a17f746b5af2e19761e82f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1 - 4
Runtime/Server/ServerBehaviour.cs

@@ -76,10 +76,7 @@ namespace KairoEngine.Multiplayer
 
         public void SendNetMsgToClient(int id, uint code, NetMsg netMsg)
         {
-            DataStreamWriter writer = new DataStreamWriter();
-            m_Driver.BeginSend(m_Connections[id], out writer);
-            netMsgController.SendData(code, netMsg, ref writer, this, id);
-            m_Driver.EndSend(writer);
+            netMsgController.SendData(code, netMsg, this, id);
         }
 
         public void SendNetMsgToAllClients(uint code, NetMsg netMsg)

+ 1 - 1
Runtime/Server/ServerHandshakeController.cs

@@ -9,7 +9,7 @@ namespace KairoEngine.Multiplayer
     {
         public ServerBehaviour server;
         public string eventStreamName = "ServerEvents";
-        private void Awake()
+        private void OnEnable()
         {
             NetMsgEvents.StartListening($"{eventStreamName}_HandshakeReceived", OnEvent);
         }

+ 110 - 0
Runtime/Server/ServerNetMsgController.cs

@@ -0,0 +1,110 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using Unity.Networking.Transport;
+using KairoEngine.Core;
+using Sirenix.OdinInspector;
+
+namespace KairoEngine.Multiplayer
+{
+    [HideMonoScript]
+    public class ServerNetMsgController : NetMsgController
+    {
+        public ServerBehaviour server;
+        public NetworkTick networkTick;
+        
+        private List<List<NetMsg>> sendMsgBuffer = new List<List<NetMsg>>();
+        private List<List<NetMsg>> receivedMsgBuffer = new List<List<NetMsg>>();
+
+        private void Start()
+        {
+            GetNetMessageTypes();
+            networkTick.eventStreamName = server.eventStreamName;
+            for (int i = 0; i < server.players; i++)
+            {
+                sendMsgBuffer.Add(new List<NetMsg>());
+                receivedMsgBuffer.Add(new List<NetMsg>());
+            }
+        }
+
+        private void OnEnable() 
+        {
+            GenericEvents.StartListening($"{server.eventStreamName}_OnTick", OnTick);
+            GenericEvents.StartListening($"{server.eventStreamName}_Listening", ServerStarted);
+        } 
+        private void OnDisable()
+        {
+            GenericEvents.StopListening($"{server.eventStreamName}_OnTick", OnTick);
+            GenericEvents.StopListening($"{server.eventStreamName}_Listening", ServerStarted);
+        }
+
+        private void ServerStarted(string text)
+        {
+            networkTick.StartTickSystem();
+        }
+        
+        public override void ReceiveData(ref DataStreamReader stream, ServerBehaviour server, int clientId) 
+        {
+            uint tick = stream.ReadUInt();
+            uint msgCount = stream.ReadByte();
+            Debug.Log($"Receiving {msgCount} messages from client {clientId}");
+            for (int i = 0; i < msgCount; i++)
+            {
+                uint code = stream.ReadByte();
+                NetMsg typeMsg = FindWithCode(code);
+                if(typeMsg != null)
+                {
+                    NetMsg msg = typeMsg.ReceiveMessage(server, ref stream, clientId);
+                    if(msg != null) 
+                    {
+                        receivedMsgBuffer[clientId].Add(msg);
+                    }
+                }
+                else Debug.LogError($"Could not find NetMsg with code {code}");
+            }
+        }
+
+        public override void SendData(uint code, NetMsg netMsg, ServerBehaviour server, int clientId)
+        {
+            sendMsgBuffer[clientId].Add(netMsg);
+        }
+
+        private void OnTick(int tick)
+        {
+            SendBufferedData();
+            ReadBufferedData();
+        }
+
+        private void SendBufferedData()
+        {
+            for (int i = 0; i < sendMsgBuffer.Count; i++)
+            {
+                if(sendMsgBuffer[i].Count == 0) continue;
+                DataStreamWriter writer = new DataStreamWriter();
+                server.m_Driver.BeginSend(server.m_Connections[i], out writer);
+                writer.WriteUInt((uint)networkTick.tick); // Current Tick Header
+                writer.WriteByte((byte)sendMsgBuffer[i].Count); // Message count Header
+                for (int a = 0; a < sendMsgBuffer[i].Count; a++)
+                {
+                    NetMsg netMsg = sendMsgBuffer[i][a];
+                    FindWithCode(netMsg.code).SendMessage(server, netMsg, ref writer, i);
+                }
+                server.m_Driver.EndSend(writer);
+                sendMsgBuffer[i].Clear();
+            }
+        }
+
+        private void ReadBufferedData()
+        {
+            for (int i = 0; i < receivedMsgBuffer.Count; i++)
+            {
+                for (int a = 0; a < receivedMsgBuffer[i].Count; a++)
+                {
+                    NetMsg msg = receivedMsgBuffer[i][a];
+                    msg.ReadMessage(server, i);
+                }
+                receivedMsgBuffer[i].Clear();
+            }
+        }
+    }
+}

+ 11 - 0
Runtime/Server/ServerNetMsgController.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bf76ef83c4c212a40b33362c0fc29b79
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: