From 4d28f3420e9927e93128ee42917e93912c1ccf84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Cor=C3=A9n?= <2108U9@gmail.com> Date: Tue, 17 Apr 2018 21:38:08 +0200 Subject: [PATCH] Switched the Generic MLAPI message layer to BitWriter & BitReader --- .../MonoBehaviours/Core/NetworkingManager.cs | 369 +++++++++--------- .../Core/InternalMessageHandler.Send.cs | 284 ++++++-------- 2 files changed, 305 insertions(+), 348 deletions(-) diff --git a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs index 8d8c465..f415288 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs @@ -10,6 +10,7 @@ using System.Security.Cryptography; using MLAPI.NetworkingManagerComponents.Cryptography; using MLAPI.NetworkingManagerComponents.Core; using UnityEngine.SceneManagement; +using MLAPI.NetworkingManagerComponents.Binary; namespace MLAPI.MonoBehaviours.Core { @@ -821,200 +822,198 @@ namespace MLAPI.MonoBehaviours.Core private void HandleIncomingData(uint clientId, byte[] data, int channelId) { - using(MemoryStream readStream = new MemoryStream(data)) + BitReader reader = new BitReader(data); + + ushort messageType = reader.ReadUShort(); + bool targeted = reader.ReadBool(); + uint targetNetworkId = 0; + ushort networkOrderId = 0; + if (targeted) { - using (BinaryReader reader = new BinaryReader(readStream)) + targetNetworkId = reader.ReadUInt(); + networkOrderId = reader.ReadUShort(); + } + bool isPassthrough = reader.ReadBool(); + + uint passthroughOrigin = 0; + uint passthroughTarget = 0; + + if (isPassthrough && isServer) + passthroughTarget = reader.ReadUInt(); + else if (isPassthrough && !isServer) + passthroughOrigin = reader.ReadUInt(); + + + //Client tried to send a network message that was not the connection request before he was accepted. + if (isServer && pendingClients.Contains(clientId) && messageType != 0) + { + Debug.LogWarning("MLAPI: Message recieved from clientId " + clientId + " before it has been accepted"); + return; + } + + + //ushort bytesToRead = reader.ReadUShort(); + reader.SkipPadded(); + + byte[] incommingData = reader.ReadByteArray(); + if (NetworkConfig.EncryptedChannelsHashSet.Contains(MessageManager.reverseChannels[channelId])) + { + //Encrypted message + if (isServer) + incommingData = CryptographyHelper.Decrypt(incommingData, connectedClients[clientId].AesKey); + else + incommingData = CryptographyHelper.Decrypt(incommingData, clientAesKey); + } + + if (isServer && isPassthrough && !NetworkConfig.PassthroughMessageHashSet.Contains(messageType)) + { + Debug.LogWarning("MLAPI: Client " + clientId + " tried to send a passthrough message for a messageType not registered as passthrough"); + return; + } + else if (isClient && isPassthrough && !NetworkConfig.PassthroughMessageHashSet.Contains(messageType)) + { + Debug.LogWarning("MLAPI: Server tried to send a passthrough message for a messageType not registered as passthrough"); + return; + } + else if (isServer && isPassthrough) + { + if (!connectedClients.ContainsKey(passthroughTarget)) { - ushort messageType = reader.ReadUInt16(); - bool targeted = reader.ReadBoolean(); - uint targetNetworkId = 0; - ushort networkOrderId = 0; - if(targeted) + Debug.LogWarning("MLAPI: Passthrough message was sent with invalid target: " + passthroughTarget + " from client " + clientId); + return; + } + uint? netIdTarget = null; + ushort? netOrderId = null; + if (targeted) + { + netIdTarget = targetNetworkId; + netOrderId = networkOrderId; + } + InternalMessageHandler.PassthroughSend(passthroughTarget, clientId, messageType, channelId, incommingData, netIdTarget, netOrderId); + return; + } + + if (messageType >= 32) + { + #region CUSTOM MESSAGE + //Custom message, invoke all message handlers + if (targeted) + { + if (!SpawnManager.spawnedObjects.ContainsKey(targetNetworkId)) { - targetNetworkId = reader.ReadUInt32(); - networkOrderId = reader.ReadUInt16(); - } - bool isPassthrough = reader.ReadBoolean(); - - uint passthroughOrigin = 0; - uint passthroughTarget = 0; - - if (isPassthrough && isServer) - passthroughTarget = reader.ReadUInt32(); - else if (isPassthrough && !isServer) - passthroughOrigin = reader.ReadUInt32(); - - - //Client tried to send a network message that was not the connection request before he was accepted. - if (isServer && pendingClients.Contains(clientId) && messageType != 0) - { - Debug.LogWarning("MLAPI: Message recieved from clientId " + clientId + " before it has been accepted"); + Debug.LogWarning("MLAPI: No target for message found"); return; } - - - ushort bytesToRead = reader.ReadUInt16(); - byte[] incommingData = reader.ReadBytes(bytesToRead); - if(NetworkConfig.EncryptedChannelsHashSet.Contains(MessageManager.reverseChannels[channelId])) + else if (!SpawnManager.spawnedObjects[targetNetworkId].targetMessageActions.ContainsKey(networkOrderId)) { - //Encrypted message - if (isServer) - incommingData = CryptographyHelper.Decrypt(incommingData, connectedClients[clientId].AesKey); + Debug.LogWarning("MLAPI: No target messageType for message found"); + return; + } + else if (!SpawnManager.spawnedObjects[targetNetworkId].targetMessageActions[networkOrderId].ContainsKey(messageType)) + { + Debug.LogWarning("MLAPI: No target found with the given messageType"); + return; + } + SpawnManager.spawnedObjects[targetNetworkId].targetMessageActions[networkOrderId][messageType].Invoke(clientId, incommingData); + } + else + { + foreach (KeyValuePair> pair in MessageManager.messageCallbacks[messageType]) + { + if (isPassthrough) + pair.Value(passthroughOrigin, incommingData); else - incommingData = CryptographyHelper.Decrypt(incommingData, clientAesKey); - } - - if (isServer && isPassthrough && !NetworkConfig.PassthroughMessageHashSet.Contains(messageType)) - { - Debug.LogWarning("MLAPI: Client " + clientId + " tried to send a passthrough message for a messageType not registered as passthrough"); - return; - } - else if(isClient && isPassthrough && !NetworkConfig.PassthroughMessageHashSet.Contains(messageType)) - { - Debug.LogWarning("MLAPI: Server tried to send a passthrough message for a messageType not registered as passthrough"); - return; - } - else if(isServer && isPassthrough) - { - if (!connectedClients.ContainsKey(passthroughTarget)) - { - Debug.LogWarning("MLAPI: Passthrough message was sent with invalid target: " + passthroughTarget + " from client " + clientId); - return; - } - uint? netIdTarget = null; - ushort? netOrderId = null; - if (targeted) - { - netIdTarget = targetNetworkId; - netOrderId = networkOrderId; - } - InternalMessageHandler.PassthroughSend(passthroughTarget, clientId, messageType, channelId, incommingData, netIdTarget, netOrderId); - return; - } - - if (messageType >= 32) - { - #region CUSTOM MESSAGE - //Custom message, invoke all message handlers - if(targeted) - { - if (!SpawnManager.spawnedObjects.ContainsKey(targetNetworkId)) - { - Debug.LogWarning("MLAPI: No target for message found"); - return; - } - else if (!SpawnManager.spawnedObjects[targetNetworkId].targetMessageActions.ContainsKey(networkOrderId)) - { - Debug.LogWarning("MLAPI: No target messageType for message found"); - return; - } - else if (!SpawnManager.spawnedObjects[targetNetworkId].targetMessageActions[networkOrderId].ContainsKey(messageType)) - { - Debug.LogWarning("MLAPI: No target found with the given messageType"); - return; - } - SpawnManager.spawnedObjects[targetNetworkId].targetMessageActions[networkOrderId][messageType].Invoke(clientId, incommingData); - } - else - { - foreach (KeyValuePair> pair in MessageManager.messageCallbacks[messageType]) - { - if (isPassthrough) - pair.Value(passthroughOrigin, incommingData); - else - pair.Value(clientId, incommingData); - } - } - #endregion - } - else - { - #region INTERNAL MESSAGE - //MLAPI message - switch (messageType) - { - case 0: //Client to server > sends connection buffer - if (isServer) - { - InternalMessageHandler.HandleConnectionRequest(clientId, incommingData, channelId); - } - break; - case 1: //Server informs client it has been approved: - if (isClient) - { - InternalMessageHandler.HandleConnectionApproved(clientId, incommingData, channelId); - } - break; - case 2: - //Server informs client another client connected - //MLAPI_ADD_OBJECT - if (isClient) - { - InternalMessageHandler.HandleAddObject(clientId, incommingData, channelId); - } - break; - case 3: - //Server informs client another client disconnected - //MLAPI_CLIENT_DISCONNECT - if (isClient) - { - InternalMessageHandler.HandleClientDisconnect(clientId, incommingData, channelId); - } - break; - case 4: - //Server infroms clients to destroy an object - if (isClient) - { - InternalMessageHandler.HandleDestroyObject(clientId, incommingData, channelId); - } - break; - case 5: - //Scene switch - if (isClient) - { - InternalMessageHandler.HandleSwitchScene(clientId, incommingData, channelId); - } - break; - case 6: //Spawn pool object - if (isClient) - { - InternalMessageHandler.HandleSpawnPoolObject(clientId, incommingData, channelId); - } - break; - case 7: //Destroy pool object - if (isClient) - { - InternalMessageHandler.HandleDestroyPoolObject(clientId, incommingData, channelId); - } - break; - case 8: //Change owner - if (isClient) - { - InternalMessageHandler.HandleChangeOwner(clientId, incommingData, channelId); - } - break; - case 9: //Syncvar - if (isClient) - { - InternalMessageHandler.HandleSyncVarUpdate(clientId, incommingData, channelId); - } - break; - case 10: - if (isClient) //MLAPI_ADD_OBJECTS (plural) - { - InternalMessageHandler.HandleAddObjects(clientId, incommingData, channelId); - } - break; - case 11: - if (isClient) - { - InternalMessageHandler.HandleTimeSync(clientId, incommingData, channelId); - } - break; - } - #endregion + pair.Value(clientId, incommingData); } } + #endregion + } + else + { + #region INTERNAL MESSAGE + //MLAPI message + switch (messageType) + { + case 0: //Client to server > sends connection buffer + if (isServer) + { + InternalMessageHandler.HandleConnectionRequest(clientId, incommingData, channelId); + } + break; + case 1: //Server informs client it has been approved: + if (isClient) + { + InternalMessageHandler.HandleConnectionApproved(clientId, incommingData, channelId); + } + break; + case 2: + //Server informs client another client connected + //MLAPI_ADD_OBJECT + if (isClient) + { + InternalMessageHandler.HandleAddObject(clientId, incommingData, channelId); + } + break; + case 3: + //Server informs client another client disconnected + //MLAPI_CLIENT_DISCONNECT + if (isClient) + { + InternalMessageHandler.HandleClientDisconnect(clientId, incommingData, channelId); + } + break; + case 4: + //Server infroms clients to destroy an object + if (isClient) + { + InternalMessageHandler.HandleDestroyObject(clientId, incommingData, channelId); + } + break; + case 5: + //Scene switch + if (isClient) + { + InternalMessageHandler.HandleSwitchScene(clientId, incommingData, channelId); + } + break; + case 6: //Spawn pool object + if (isClient) + { + InternalMessageHandler.HandleSpawnPoolObject(clientId, incommingData, channelId); + } + break; + case 7: //Destroy pool object + if (isClient) + { + InternalMessageHandler.HandleDestroyPoolObject(clientId, incommingData, channelId); + } + break; + case 8: //Change owner + if (isClient) + { + InternalMessageHandler.HandleChangeOwner(clientId, incommingData, channelId); + } + break; + case 9: //Syncvar + if (isClient) + { + InternalMessageHandler.HandleSyncVarUpdate(clientId, incommingData, channelId); + } + break; + case 10: + if (isClient) //MLAPI_ADD_OBJECTS (plural) + { + InternalMessageHandler.HandleAddObjects(clientId, incommingData, channelId); + } + break; + case 11: + if (isClient) + { + InternalMessageHandler.HandleTimeSync(clientId, incommingData, channelId); + } + break; + } + #endregion } } diff --git a/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Send.cs b/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Send.cs index 118725d..362c902 100644 --- a/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Send.cs +++ b/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Send.cs @@ -1,7 +1,7 @@ -using System.Collections.Generic; -using System.IO; +using System; +using System.Collections.Generic; using MLAPI.Data; -using MLAPI.MonoBehaviours.Core; +using MLAPI.NetworkingManagerComponents.Binary; using MLAPI.NetworkingManagerComponents.Cryptography; using UnityEngine; using UnityEngine.Networking; @@ -20,41 +20,29 @@ namespace MLAPI.NetworkingManagerComponents.Core return; } - int sizeOfStream = 10; - if (networkId != null) - sizeOfStream += 4; - if (orderId != null) - sizeOfStream += 2; - sizeOfStream += data.Length; - - using (MemoryStream stream = new MemoryStream(sizeOfStream)) + using (BitWriter writer = new BitWriter()) { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Write(messageType); - writer.Write(networkId != null); - if (networkId != null) - writer.Write(networkId.Value); - if (orderId != null) - writer.Write(orderId.Value); - writer.Write(true); - writer.Write(sourceId); - if (netManager.NetworkConfig.EncryptedChannelsHashSet.Contains(MessageManager.reverseChannels[channelId])) - { - //Encrypted message - byte[] encrypted = CryptographyHelper.Encrypt(data, netManager.connectedClients[targetId].AesKey); - writer.Write((ushort)encrypted.Length); - writer.Write(encrypted); - } - else - { - writer.Write((ushort)data.Length); - writer.Write(data); - } - } + writer.WriteUShort(messageType); + writer.WriteBool(networkId != null); + + if (networkId != null) + writer.WriteUInt(networkId.Value); + + if (orderId != null) + writer.WriteUShort(orderId.Value); + + writer.WriteBool(true); + writer.WriteUInt(sourceId); + + writer.WriteAlignBits(); + + if (netManager.NetworkConfig.EncryptedChannelsHashSet.Contains(MessageManager.reverseChannels[channelId])) + writer.WriteByteArray(CryptographyHelper.Encrypt(data, netManager.connectedClients[targetId].AesKey)); + else + writer.WriteByteArray(data); byte error; - NetworkTransport.QueueMessageForSending(targetNetId.HostId, targetNetId.ConnectionId, channelId, stream.GetBuffer(), sizeOfStream, out error); + NetworkTransport.QueueMessageForSending(targetNetId.HostId, targetNetId.ConnectionId, channelId, writer.Finalize(), (int)writer.GetFinalizeSize(), out error); } } @@ -80,55 +68,45 @@ namespace MLAPI.NetworkingManagerComponents.Core return; } - int sizeOfStream = 6; - if (networkId != null) - sizeOfStream += 4; - if (orderId != null) - sizeOfStream += 2; - if (isPassthrough) - sizeOfStream += 4; - sizeOfStream += data.Length; - - using (MemoryStream stream = new MemoryStream(sizeOfStream)) + using (BitWriter writer = new BitWriter()) { - using (BinaryWriter writer = new BinaryWriter(stream)) + writer.WriteUShort(MessageManager.messageTypes[messageType]); + writer.WriteBool(networkId != null); + + if (networkId != null) + writer.WriteUInt(networkId.Value); + + if (orderId != null) + writer.WriteUShort(orderId.Value); + + writer.WriteBool(isPassthrough); + + if (isPassthrough) + writer.WriteUInt(clientId); + + writer.WriteAlignBits(); + + if (netManager.NetworkConfig.EncryptedChannelsHashSet.Contains(channelName)) { - writer.Write(MessageManager.messageTypes[messageType]); - writer.Write(networkId != null); - if (networkId != null) - writer.Write(networkId.Value); - if (orderId != null) - writer.Write(orderId.Value); - writer.Write(isPassthrough); - if (isPassthrough) - writer.Write(clientId); - - if (netManager.NetworkConfig.EncryptedChannelsHashSet.Contains(channelName)) - { - //This is an encrypted message. - byte[] encrypted; - if (netManager.isServer) - encrypted = CryptographyHelper.Encrypt(data, netManager.connectedClients[clientId].AesKey); - else - encrypted = CryptographyHelper.Encrypt(data, netManager.clientAesKey); - - writer.Write((ushort)encrypted.Length); - writer.Write(encrypted); - } + //This is an encrypted message. + byte[] encrypted; + if (netManager.isServer) + encrypted = CryptographyHelper.Encrypt(data, netManager.connectedClients[clientId].AesKey); else - { - //Send in plaintext. - writer.Write((ushort)data.Length); - writer.Write(data); - } + encrypted = CryptographyHelper.Encrypt(data, netManager.clientAesKey); + + writer.WriteByteArray(encrypted); } + else + writer.WriteByteArray(data); + byte error; if (isPassthrough) netId = NetId.ServerNetId; if (skipQueue) - NetworkTransport.Send(netId.HostId, netId.ConnectionId, MessageManager.channels[channelName], stream.GetBuffer(), sizeOfStream, out error); + NetworkTransport.Send(netId.HostId, netId.ConnectionId, MessageManager.channels[channelName], writer.Finalize(), (int)writer.GetFinalizeSize(), out error); else - NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, MessageManager.channels[channelName], stream.GetBuffer(), sizeOfStream, out error); + NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, MessageManager.channels[channelName], writer.Finalize(), (int)writer.GetFinalizeSize(), out error); } } @@ -140,27 +118,23 @@ namespace MLAPI.NetworkingManagerComponents.Core return; } - int sizeOfStream = 6; - if (networkId != null) - sizeOfStream += 4; - if (orderId != null) - sizeOfStream += 2; - sizeOfStream += data.Length; - - using (MemoryStream stream = new MemoryStream(sizeOfStream)) + using (BitWriter writer = new BitWriter()) { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Write(MessageManager.messageTypes[messageType]); - writer.Write(networkId != null); - if (networkId != null) - writer.Write(networkId.Value); - if (orderId != null) - writer.Write(orderId.Value); - writer.Write(false); - writer.Write((ushort)data.Length); - writer.Write(data); - } + writer.WriteUShort(MessageManager.messageTypes[messageType]); + writer.WriteBool(networkId != null); + + if (networkId != null) + writer.WriteUInt(networkId.Value); + + if (orderId != null) + writer.WriteUShort(orderId.Value); + + writer.WriteBool(false); + + writer.WriteAlignBits(); + + writer.WriteByteArray(data); + int channel = MessageManager.channels[channelName]; for (int i = 0; i < clientIds.Length; i++) { @@ -176,7 +150,7 @@ namespace MLAPI.NetworkingManagerComponents.Core netId = NetId.ServerNetId; } byte error; - NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); + NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, writer.Finalize(), (int)writer.GetFinalizeSize(), out error); } } } @@ -189,28 +163,23 @@ namespace MLAPI.NetworkingManagerComponents.Core return; } - //2 bytes for messageType, 2 bytes for buffer length and one byte for target bool - int sizeOfStream = 6; - if (networkId != null) - sizeOfStream += 4; - if (orderId != null) - sizeOfStream += 2; - sizeOfStream += data.Length; - - using (MemoryStream stream = new MemoryStream(sizeOfStream)) + using (BitWriter writer = new BitWriter()) { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Write(MessageManager.messageTypes[messageType]); - writer.Write(networkId != null); - if (networkId != null) - writer.Write(networkId.Value); - if (orderId != null) - writer.Write(orderId.Value); - writer.Write(false); - writer.Write((ushort)data.Length); - writer.Write(data); - } + writer.WriteUShort(MessageManager.messageTypes[messageType]); + writer.WriteBool(networkId != null); + + if (networkId != null) + writer.WriteUInt(networkId.Value); + + if (orderId != null) + writer.WriteUShort(orderId.Value); + + writer.WriteBool(false); + + writer.WriteAlignBits(); + + writer.WriteByteArray(data); + int channel = MessageManager.channels[channelName]; for (int i = 0; i < clientIds.Count; i++) { @@ -226,7 +195,7 @@ namespace MLAPI.NetworkingManagerComponents.Core netId = NetId.ServerNetId; } byte error; - NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); + NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, writer.Finalize(), (int)writer.GetFinalizeSize(), out error); } } } @@ -240,29 +209,23 @@ namespace MLAPI.NetworkingManagerComponents.Core Debug.LogWarning("MLAPI: Cannot send messages over encrypted channel to multiple clients."); return; } - - //2 bytes for messageType, 2 bytes for buffer length and one byte for target bool - int sizeOfStream = 6; - if (networkId != null) - sizeOfStream += 4; - if (orderId != null) - sizeOfStream += 2; - sizeOfStream += data.Length; - - using (MemoryStream stream = new MemoryStream(sizeOfStream)) + using (BitWriter writer = new BitWriter()) { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Write(MessageManager.messageTypes[messageType]); - writer.Write(networkId != null); - if (networkId != null) - writer.Write(networkId.Value); - if (orderId != null) - writer.Write(orderId.Value); - writer.Write(false); - writer.Write((ushort)data.Length); - writer.Write(data); - } + writer.WriteUShort(MessageManager.messageTypes[messageType]); + writer.WriteBool(networkId != null); + + if (networkId != null) + writer.WriteUInt(networkId.Value); + + if (orderId != null) + writer.WriteUShort(orderId.Value); + + writer.WriteBool(false); + + writer.WriteAlignBits(); + + writer.WriteByteArray(data); + int channel = MessageManager.channels[channelName]; foreach (KeyValuePair pair in netManager.connectedClients) { @@ -278,7 +241,7 @@ namespace MLAPI.NetworkingManagerComponents.Core netId = NetId.ServerNetId; } byte error; - NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); + NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, writer.Finalize(), (int)writer.GetFinalizeSize(), out error); } } } @@ -291,28 +254,23 @@ namespace MLAPI.NetworkingManagerComponents.Core return; } - //2 bytes for messageType, 2 bytes for buffer length and one byte for target bool - int sizeOfStream = 5; - if (networkId != null) - sizeOfStream += 4; - if (orderId != null) - sizeOfStream += 2; - sizeOfStream += data.Length; - - using (MemoryStream stream = new MemoryStream(sizeOfStream)) + using (BitWriter writer = new BitWriter()) { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Write(MessageManager.messageTypes[messageType]); - writer.Write(networkId != null); - if (networkId != null) - writer.Write(networkId.Value); - if (orderId != null) - writer.Write(orderId.Value); - writer.Write(false); - writer.Write((ushort)data.Length); - writer.Write(data); - } + writer.WriteUShort(MessageManager.messageTypes[messageType]); + writer.WriteBool(networkId != null); + + if (networkId != null) + writer.WriteUInt(networkId.Value); + + if (orderId != null) + writer.WriteUShort(orderId.Value); + + writer.WriteBool(false); + + writer.WriteAlignBits(); + + writer.WriteByteArray(data); + int channel = MessageManager.channels[channelName]; foreach (KeyValuePair pair in netManager.connectedClients) { @@ -331,7 +289,7 @@ namespace MLAPI.NetworkingManagerComponents.Core netId = NetId.ServerNetId; } byte error; - NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); + NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, writer.Finalize(), (int)writer.GetFinalizeSize(), out error); } } }