From 9c587636d58db110a544098603c4ef9c4bc3dc1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Cor=C3=A9n?= <2108U9@gmail.com> Date: Fri, 9 Mar 2018 00:18:38 +0100 Subject: [PATCH 1/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ff2ad4..4ffc916 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ MLAPI (Mid level API) is a framework that hopefully simplifies building networke * Replace the integer QOS with names. When you setup the networking you specify names that are associated with a channel. This makes it easier to manage. You can thus specify that a message should be sent on the "damage" channel which handles all damage related logic and is running on the AllCostDelivery channel. * ProtocolVersion to allow making different versions not talk to each other. * NetworkedBehaviours does not have to be on the root, it's simply just a class that implements the send methods etc. -* Multiple messages processed every frame with the ability to specify a maximum to prevent freezes in the normal game logic +* Custom tickrate * Supports separate Unity projects crosstalking * Passthrough messages \[[Wiki page](https://github.com/TwoTenPvP/MLAPI/wiki/Passthrough-messages)\] * Scene Management \[[Wiki page](https://github.com/TwoTenPvP/MLAPI/wiki/Scene-Management)\] From ad41b78accff2f7c6eb01bee744b25669ffa5145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Cor=C3=A9n?= Date: Fri, 9 Mar 2018 10:21:44 +0100 Subject: [PATCH 2/5] Added different tickrates for different things --- MLAPI/Data/NetworkingConfiguration.cs | 4 +- .../MonoBehaviours/Core/NetworkingManager.cs | 124 ++++++++++-------- 2 files changed, 71 insertions(+), 57 deletions(-) diff --git a/MLAPI/Data/NetworkingConfiguration.cs b/MLAPI/Data/NetworkingConfiguration.cs index 36cfd36..99209cf 100644 --- a/MLAPI/Data/NetworkingConfiguration.cs +++ b/MLAPI/Data/NetworkingConfiguration.cs @@ -15,7 +15,9 @@ namespace MLAPI internal HashSet RegisteredPassthroughMessageTypes = new HashSet(); public List RegisteredScenes = new List(); public int MessageBufferSize = 65535; - public int Tickrate = 64; + public int ReceiveTickrate = 64; + public int SendTickrate = 64; + public int EventTickrate = 64; public int MaxConnections = 100; public int Port = 7777; public string Address = "127.0.0.1"; diff --git a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs index 258191e..8186db4 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs @@ -73,7 +73,9 @@ namespace MLAPI private ConnectionConfig Init(NetworkingConfiguration netConfig) { NetworkConfig = netConfig; - + lastSendTickTime = 0; + lastEventTickTime = 0; + lastReceiveTickTime = 0; pendingClients = new HashSet(); connectedClients = new Dictionary(); messageBuffer = new byte[NetworkConfig.MessageBufferSize]; @@ -292,75 +294,85 @@ namespace MLAPI private int channelId; private int receivedSize; private byte error; - private float lastTickTime; + private float lastReceiveTickTime; + private float lastSendTickTime; + private float lastEventTickTime; private void Update() { - if(isListening && (Time.time - lastTickTime >= (1f / NetworkConfig.Tickrate))) + if(isListening) { - foreach (KeyValuePair pair in connectedClients) + if(Time.time - lastSendTickTime >= (1f / NetworkConfig.SendTickrate)) { - NetworkTransport.SendQueuedMessages(hostId, pair.Key, out error); - } - NetworkEventType eventType = NetworkTransport.Receive(out hostId, out clientId, out channelId, messageBuffer, messageBuffer.Length, out receivedSize, out error); - NetworkError networkError = (NetworkError)error; - if (networkError == NetworkError.Timeout) - { - //Client timed out. - if (isServer) + foreach (KeyValuePair pair in connectedClients) { - OnClientDisconnect(clientId); + NetworkTransport.SendQueuedMessages(hostId, pair.Key, out error); + } + lastSendTickTime = Time.time; + } + if(Time.time - lastReceiveTickTime >= (1f / NetworkConfig.ReceiveTickrate)) + { + NetworkEventType eventType = NetworkTransport.Receive(out hostId, out clientId, out channelId, messageBuffer, messageBuffer.Length, out receivedSize, out error); + NetworkError networkError = (NetworkError)error; + if (networkError == NetworkError.Timeout) + { + //Client timed out. + if (isServer) + { + OnClientDisconnect(clientId); + return; + } + } + else if (networkError != NetworkError.Ok) + { + Debug.LogWarning("MLAPI: NetworkTransport receive error: " + networkError.ToString()); return; } - } - else if (networkError != NetworkError.Ok) - { - Debug.LogWarning("MLAPI: NetworkTransport receive error: " + networkError.ToString()); - return; - } - switch (eventType) - { - case NetworkEventType.ConnectEvent: - if (isServer) - { - pendingClients.Add(clientId); - StartCoroutine(ApprovalTimeout(clientId)); - } - else - { - int sizeOfStream = 32; - if (NetworkConfig.ConnectionApproval) - sizeOfStream += 2 + NetworkConfig.ConnectionData.Length; - - using (MemoryStream writeStream = new MemoryStream(sizeOfStream)) + switch (eventType) + { + case NetworkEventType.ConnectEvent: + if (isServer) { - using (BinaryWriter writer = new BinaryWriter(writeStream)) - { - writer.Write(NetworkConfig.GetConfig()); - if (NetworkConfig.ConnectionApproval) - { - writer.Write((ushort)NetworkConfig.ConnectionData.Length); - writer.Write(NetworkConfig.ConnectionData); - } - } - Send(clientId, "MLAPI_CONNECTION_REQUEST", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", writeStream.GetBuffer()); + pendingClients.Add(clientId); + StartCoroutine(ApprovalTimeout(clientId)); } - } - break; - case NetworkEventType.DataEvent: - HandleIncomingData(clientId, messageBuffer, channelId); - break; - case NetworkEventType.DisconnectEvent: - if (isServer) - OnClientDisconnect(clientId); - break; + else + { + int sizeOfStream = 32; + if (NetworkConfig.ConnectionApproval) + sizeOfStream += 2 + NetworkConfig.ConnectionData.Length; + + using (MemoryStream writeStream = new MemoryStream(sizeOfStream)) + { + using (BinaryWriter writer = new BinaryWriter(writeStream)) + { + writer.Write(NetworkConfig.GetConfig()); + if (NetworkConfig.ConnectionApproval) + { + writer.Write((ushort)NetworkConfig.ConnectionData.Length); + writer.Write(NetworkConfig.ConnectionData); + } + } + Send(clientId, "MLAPI_CONNECTION_REQUEST", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", writeStream.GetBuffer()); + } + } + break; + case NetworkEventType.DataEvent: + HandleIncomingData(clientId, messageBuffer, channelId); + break; + case NetworkEventType.DisconnectEvent: + if (isServer) + OnClientDisconnect(clientId); + break; + } + lastReceiveTickTime = Time.time; } - if (isServer) + if (isServer && (Time.time - lastEventTickTime >= (1f / NetworkConfig.EventTickrate))) { LagCompensationManager.AddFrames(); - NetworkedObject.InvokeSyncvarUpdate(); + NetworkedObject.InvokeSyncvafrUpdate(); + lastEventTickTime = Time.time; } - lastTickTime = Time.time; } } From 6cb02f35de5078b64f9552db282562090337f69a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Cor=C3=A9n?= Date: Fri, 9 Mar 2018 10:28:38 +0100 Subject: [PATCH 3/5] Modified tickrate behaviour to empty buffers --- .../MonoBehaviours/Core/NetworkingManager.cs | 106 +++++++++--------- 1 file changed, 55 insertions(+), 51 deletions(-) diff --git a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs index 8186db4..8b6820a 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs @@ -301,7 +301,7 @@ namespace MLAPI { if(isListening) { - if(Time.time - lastSendTickTime >= (1f / NetworkConfig.SendTickrate)) + if((Time.time - lastSendTickTime >= (1f / NetworkConfig.SendTickrate)) || NetworkConfig.SendTickrate <= 0) { foreach (KeyValuePair pair in connectedClients) { @@ -309,68 +309,72 @@ namespace MLAPI } lastSendTickTime = Time.time; } - if(Time.time - lastReceiveTickTime >= (1f / NetworkConfig.ReceiveTickrate)) + if((Time.time - lastReceiveTickTime >= (1f / NetworkConfig.ReceiveTickrate)) || NetworkConfig.ReceiveTickrate <= 0) { - NetworkEventType eventType = NetworkTransport.Receive(out hostId, out clientId, out channelId, messageBuffer, messageBuffer.Length, out receivedSize, out error); - NetworkError networkError = (NetworkError)error; - if (networkError == NetworkError.Timeout) + NetworkEventType eventType; + do { - //Client timed out. - if (isServer) + eventType = NetworkTransport.Receive(out hostId, out clientId, out channelId, messageBuffer, messageBuffer.Length, out receivedSize, out error); + NetworkError networkError = (NetworkError)error; + if (networkError == NetworkError.Timeout) { - OnClientDisconnect(clientId); + //Client timed out. + if (isServer) + { + OnClientDisconnect(clientId); + return; + } + } + else if (networkError != NetworkError.Ok) + { + Debug.LogWarning("MLAPI: NetworkTransport receive error: " + networkError.ToString()); return; } - } - else if (networkError != NetworkError.Ok) - { - Debug.LogWarning("MLAPI: NetworkTransport receive error: " + networkError.ToString()); - return; - } - switch (eventType) - { - case NetworkEventType.ConnectEvent: - if (isServer) - { - pendingClients.Add(clientId); - StartCoroutine(ApprovalTimeout(clientId)); - } - else - { - int sizeOfStream = 32; - if (NetworkConfig.ConnectionApproval) - sizeOfStream += 2 + NetworkConfig.ConnectionData.Length; - - using (MemoryStream writeStream = new MemoryStream(sizeOfStream)) + switch (eventType) + { + case NetworkEventType.ConnectEvent: + if (isServer) { - using (BinaryWriter writer = new BinaryWriter(writeStream)) - { - writer.Write(NetworkConfig.GetConfig()); - if (NetworkConfig.ConnectionApproval) - { - writer.Write((ushort)NetworkConfig.ConnectionData.Length); - writer.Write(NetworkConfig.ConnectionData); - } - } - Send(clientId, "MLAPI_CONNECTION_REQUEST", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", writeStream.GetBuffer()); + pendingClients.Add(clientId); + StartCoroutine(ApprovalTimeout(clientId)); } - } - break; - case NetworkEventType.DataEvent: - HandleIncomingData(clientId, messageBuffer, channelId); - break; - case NetworkEventType.DisconnectEvent: - if (isServer) - OnClientDisconnect(clientId); - break; - } + else + { + int sizeOfStream = 32; + if (NetworkConfig.ConnectionApproval) + sizeOfStream += 2 + NetworkConfig.ConnectionData.Length; + + using (MemoryStream writeStream = new MemoryStream(sizeOfStream)) + { + using (BinaryWriter writer = new BinaryWriter(writeStream)) + { + writer.Write(NetworkConfig.GetConfig()); + if (NetworkConfig.ConnectionApproval) + { + writer.Write((ushort)NetworkConfig.ConnectionData.Length); + writer.Write(NetworkConfig.ConnectionData); + } + } + Send(clientId, "MLAPI_CONNECTION_REQUEST", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", writeStream.GetBuffer()); + } + } + break; + case NetworkEventType.DataEvent: + HandleIncomingData(clientId, messageBuffer, channelId); + break; + case NetworkEventType.DisconnectEvent: + if (isServer) + OnClientDisconnect(clientId); + break; + } + } while (eventType != NetworkEventType.Nothing); lastReceiveTickTime = Time.time; } - if (isServer && (Time.time - lastEventTickTime >= (1f / NetworkConfig.EventTickrate))) + if (isServer && ((Time.time - lastEventTickTime >= (1f / NetworkConfig.EventTickrate)) || NetworkConfig.EventTickrate <= 0)) { LagCompensationManager.AddFrames(); - NetworkedObject.InvokeSyncvafrUpdate(); + NetworkedObject.InvokeSyncvarUpdate(); lastEventTickTime = Time.time; } } From ae0f5233daff08697ced007125a122397d92af59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Cor=C3=A9n?= Date: Fri, 9 Mar 2018 10:41:58 +0100 Subject: [PATCH 4/5] Renamed internal MLAPI channel --- MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs | 4 ++-- MLAPI/MonoBehaviours/Core/NetworkingManager.cs | 10 +++++----- .../NetworkPoolManager.cs | 4 ++-- .../NetworkSceneManager.cs | 2 +- MLAPI/NetworkingManagerComponents/SpawnManager.cs | 12 ++++++------ 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs b/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs index ea31a8f..3ceb31f 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs @@ -333,7 +333,7 @@ namespace MLAPI } } } - NetworkingManager.singleton.Send(clientId, "MLAPI_SYNC_VAR_UPDATE", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.ToArray()); + NetworkingManager.singleton.Send(clientId, "MLAPI_SYNC_VAR_UPDATE", "MLAPI_INTERNAL", stream.ToArray()); } } @@ -426,7 +426,7 @@ namespace MLAPI } } } - NetworkingManager.singleton.Send("MLAPI_SYNC_VAR_UPDATE", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.ToArray()); + NetworkingManager.singleton.Send("MLAPI_SYNC_VAR_UPDATE", "MLAPI_INTERNAL", stream.ToArray()); } lastSyncTime = Time.time; } diff --git a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs index 8b6820a..32af8f6 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs @@ -108,7 +108,7 @@ namespace MLAPI ConnectionConfig cConfig = new ConnectionConfig(); //MLAPI channels and messageTypes - NetworkConfig.Channels.Add("MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", QosType.ReliableFragmentedSequenced); + NetworkConfig.Channels.Add("MLAPI_INTERNAL", QosType.ReliableFragmentedSequenced); NetworkConfig.Channels.Add("MLAPI_POSITION_UPDATE", QosType.StateUpdate); NetworkConfig.Channels.Add("MLAPI_ANIMATION_UPDATE", QosType.ReliableSequenced); MessageManager.messageTypes.Add("MLAPI_CONNECTION_REQUEST", 0); @@ -356,7 +356,7 @@ namespace MLAPI writer.Write(NetworkConfig.ConnectionData); } } - Send(clientId, "MLAPI_CONNECTION_REQUEST", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", writeStream.GetBuffer()); + Send(clientId, "MLAPI_CONNECTION_REQUEST", "MLAPI_INTERNAL", writeStream.GetBuffer()); } } break; @@ -1087,7 +1087,7 @@ namespace MLAPI { writer.Write(clientId); } - Send("MLAPI_CLIENT_DISCONNECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer(), clientId); + Send("MLAPI_CLIENT_DISCONNECT", "MLAPI_INTERNAL", stream.GetBuffer(), clientId); } } } @@ -1166,7 +1166,7 @@ namespace MLAPI } } } - Send(clientId, "MLAPI_CONNECTION_APPROVED", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", writeStream.GetBuffer()); + Send(clientId, "MLAPI_CONNECTION_APPROVED", "MLAPI_INTERNAL", writeStream.GetBuffer()); } //Inform old clients of the new player @@ -1192,7 +1192,7 @@ namespace MLAPI writer.Write(clientId); } } - Send("MLAPI_ADD_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer(), clientId); + Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer(), clientId); } //Flush syncvars: foreach (KeyValuePair networkedObject in SpawnManager.spawnedObjects) diff --git a/MLAPI/NetworkingManagerComponents/NetworkPoolManager.cs b/MLAPI/NetworkingManagerComponents/NetworkPoolManager.cs index c159b3e..730c691 100644 --- a/MLAPI/NetworkingManagerComponents/NetworkPoolManager.cs +++ b/MLAPI/NetworkingManagerComponents/NetworkPoolManager.cs @@ -58,7 +58,7 @@ namespace MLAPI.NetworkingManagerComponents writer.Write(rotation.eulerAngles.y); writer.Write(rotation.eulerAngles.z); } - NetworkingManager.singleton.Send("MLAPI_SPAWN_POOL_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); + NetworkingManager.singleton.Send("MLAPI_SPAWN_POOL_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); } return go; } @@ -77,7 +77,7 @@ namespace MLAPI.NetworkingManagerComponents { writer.Write(netObject.NetworkId); } - NetworkingManager.singleton.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); + NetworkingManager.singleton.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); } } } diff --git a/MLAPI/NetworkingManagerComponents/NetworkSceneManager.cs b/MLAPI/NetworkingManagerComponents/NetworkSceneManager.cs index 19cdbe9..e971799 100644 --- a/MLAPI/NetworkingManagerComponents/NetworkSceneManager.cs +++ b/MLAPI/NetworkingManagerComponents/NetworkSceneManager.cs @@ -55,7 +55,7 @@ namespace MLAPI.NetworkingManagerComponents { writer.Write(sceneNameToIndex[sceneName]); } - NetworkingManager.singleton.Send("MLAPI_SWITCH_SCENE", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); + NetworkingManager.singleton.Send("MLAPI_SWITCH_SCENE", "MLAPI_INTERNAL", stream.GetBuffer()); } } diff --git a/MLAPI/NetworkingManagerComponents/SpawnManager.cs b/MLAPI/NetworkingManagerComponents/SpawnManager.cs index 57137c2..65cb25b 100644 --- a/MLAPI/NetworkingManagerComponents/SpawnManager.cs +++ b/MLAPI/NetworkingManagerComponents/SpawnManager.cs @@ -42,7 +42,7 @@ namespace MLAPI.NetworkingManagerComponents writer.Write(netId); writer.Write(-2); } - netManager.Send("MLAPI_CHANGE_OWNER", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); + netManager.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", stream.GetBuffer()); } } @@ -59,7 +59,7 @@ namespace MLAPI.NetworkingManagerComponents writer.Write(netId); writer.Write(clientId); } - netManager.Send("MLAPI_CHANGE_OWNER", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); + netManager.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", stream.GetBuffer()); } } @@ -136,9 +136,9 @@ namespace MLAPI.NetworkingManagerComponents } //If we are host, send to everyone except ourselves. Otherwise, send to all if (netManager != null && netManager.isHost) - netManager.Send("MLAPI_DESTROY_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer(), -1); + netManager.Send("MLAPI_DESTROY_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer(), -1); else - netManager.Send("MLAPI_DESTROY_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); + netManager.Send("MLAPI_DESTROY_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); } } } @@ -193,9 +193,9 @@ namespace MLAPI.NetworkingManagerComponents } //If we are host, send to everyone except ourselves. Otherwise, send to all if (netManager.isHost) - netManager.Send("MLAPI_ADD_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer(), -1); + netManager.Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer(), -1); else - netManager.Send("MLAPI_ADD_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); + netManager.Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); } } } From 5a3d065ab48290f175042157fe721ec5d68c35e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Cor=C3=A9n?= Date: Fri, 9 Mar 2018 13:37:39 +0100 Subject: [PATCH 5/5] Added hang/flood prevention to NetworkingManager --- MLAPI/Data/NetworkingConfiguration.cs | 1 + MLAPI/MonoBehaviours/Core/NetworkingManager.cs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/MLAPI/Data/NetworkingConfiguration.cs b/MLAPI/Data/NetworkingConfiguration.cs index 99209cf..fe969cb 100644 --- a/MLAPI/Data/NetworkingConfiguration.cs +++ b/MLAPI/Data/NetworkingConfiguration.cs @@ -16,6 +16,7 @@ namespace MLAPI public List RegisteredScenes = new List(); public int MessageBufferSize = 65535; public int ReceiveTickrate = 64; + public int MaxReceiveEventsPerTickRate = 500; public int SendTickrate = 64; public int EventTickrate = 64; public int MaxConnections = 100; diff --git a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs index 32af8f6..95e1f51 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs @@ -312,8 +312,10 @@ namespace MLAPI if((Time.time - lastReceiveTickTime >= (1f / NetworkConfig.ReceiveTickrate)) || NetworkConfig.ReceiveTickrate <= 0) { NetworkEventType eventType; + int processedEvents = 0; do { + processedEvents++; eventType = NetworkTransport.Receive(out hostId, out clientId, out channelId, messageBuffer, messageBuffer.Length, out receivedSize, out error); NetworkError networkError = (NetworkError)error; if (networkError == NetworkError.Timeout) @@ -368,7 +370,8 @@ namespace MLAPI OnClientDisconnect(clientId); break; } - } while (eventType != NetworkEventType.Nothing); + // Only do another iteration if: there are no more messages AND (there is no limit to max events or we have processed less than the maximum) + } while (eventType != NetworkEventType.Nothing && (NetworkConfig.MaxReceiveEventsPerTickRate <= 0 || processedEvents < NetworkConfig.MaxReceiveEventsPerTickRate)); lastReceiveTickTime = Time.time; } if (isServer && ((Time.time - lastEventTickTime >= (1f / NetworkConfig.EventTickrate)) || NetworkConfig.EventTickrate <= 0))