From 89e666d09ae5a1b8cd0b22e9c131ef06297196ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Cor=C3=A9n?= Date: Tue, 17 Apr 2018 14:47:08 +0200 Subject: [PATCH] Moved send and message handle methods to own class --- MLAPI/MLAPI.csproj | 3 + .../MonoBehaviours/Core/NetworkedBehaviour.cs | 32 +- .../MonoBehaviours/Core/NetworkingManager.cs | 747 +----------------- .../Core/InternalMessageHandler.Receive.cs | 445 +++++++++++ .../Core/InternalMessageHandler.Send.cs | 339 ++++++++ .../Core/InternalMessageHandler.cs | 16 + .../Core/NetworkPoolManager.cs | 4 +- .../Core/NetworkSceneManager.cs | 2 +- .../Core/SpawnManager.cs | 10 +- 9 files changed, 851 insertions(+), 747 deletions(-) create mode 100644 MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Receive.cs create mode 100644 MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Send.cs create mode 100644 MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.cs diff --git a/MLAPI/MLAPI.csproj b/MLAPI/MLAPI.csproj index f0b660f..8507873 100644 --- a/MLAPI/MLAPI.csproj +++ b/MLAPI/MLAPI.csproj @@ -97,6 +97,9 @@ + + + diff --git a/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs b/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs index 4d97a46..e8840ff 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs @@ -450,7 +450,7 @@ namespace MLAPI.MonoBehaviours.Core } } } - NetworkingManager.singleton.Send(clientId, "MLAPI_SYNC_VAR_UPDATE", "MLAPI_INTERNAL", stream.ToArray()); + InternalMessageHandler.Send(clientId, "MLAPI_SYNC_VAR_UPDATE", "MLAPI_INTERNAL", stream.ToArray()); } } @@ -555,7 +555,7 @@ namespace MLAPI.MonoBehaviours.Core } } } - NetworkingManager.singleton.Send("MLAPI_SYNC_VAR_UPDATE", "MLAPI_INTERNAL", stream.ToArray()); + InternalMessageHandler.Send("MLAPI_SYNC_VAR_UPDATE", "MLAPI_INTERNAL", stream.ToArray()); } lastSyncTime = NetworkingManager.singleton.NetworkTime; } @@ -695,7 +695,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Server can not send messages to server."); return; } - NetworkingManager.singleton.Send(NetId.ServerNetId.GetClientId(), messageType, channelName, data); + InternalMessageHandler.Send(NetId.ServerNetId.GetClientId(), messageType, channelName, data); } /// @@ -728,7 +728,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Server can not send messages to server."); return; } - NetworkingManager.singleton.Send(NetId.ServerNetId.GetClientId(), messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); + InternalMessageHandler.Send(NetId.ServerNetId.GetClientId(), messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); } /// @@ -761,7 +761,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Invalid Passthrough send. Ensure AllowPassthroughMessages are turned on and that the MessageType " + messageType + " is registered as a passthroughMessageType"); return; } - NetworkingManager.singleton.Send(ownerClientId, messageType, channelName, data); + InternalMessageHandler.Send(ownerClientId, messageType, channelName, data); } /// @@ -794,7 +794,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Invalid Passthrough send. Ensure AllowPassthroughMessages are turned on and that the MessageType " + messageType + " is registered as a passthroughMessageType"); return; } - NetworkingManager.singleton.Send(ownerClientId, messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); + InternalMessageHandler.Send(ownerClientId, messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); } /// @@ -827,7 +827,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported"); return; } - NetworkingManager.singleton.Send(messageType, channelName, data, ownerClientId); + InternalMessageHandler.Send(messageType, channelName, data, ownerClientId); } /// @@ -860,7 +860,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported"); return; } - NetworkingManager.singleton.Send(messageType, channelName, data, ownerClientId, networkId, networkedObject.GetOrderIndex(this)); + InternalMessageHandler.Send(messageType, channelName, data, ownerClientId, networkId, networkedObject.GetOrderIndex(this)); } /// @@ -894,7 +894,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Invalid Passthrough send. Ensure AllowPassthroughMessages are turned on and that the MessageType " + messageType + " is registered as a passthroughMessageType"); return; } - NetworkingManager.singleton.Send(clientId, messageType, channelName, data); + InternalMessageHandler.Send(clientId, messageType, channelName, data); } /// @@ -929,7 +929,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Invalid Passthrough send. Ensure AllowPassthroughMessages are turned on and that the MessageType " + messageType + " is registered as a passthroughMessageType"); return; } - NetworkingManager.singleton.Send(clientId, messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); + InternalMessageHandler.Send(clientId, messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); } /// @@ -964,7 +964,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported"); return; } - NetworkingManager.singleton.Send(clientIds, messageType, channelName, data); + InternalMessageHandler.Send(clientIds, messageType, channelName, data); } /// @@ -999,7 +999,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported"); return; } - NetworkingManager.singleton.Send(clientIds, messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); + InternalMessageHandler.Send(clientIds, messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); } /// @@ -1034,7 +1034,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported"); return; } - NetworkingManager.singleton.Send(clientIds, messageType, channelName, data); + InternalMessageHandler.Send(clientIds, messageType, channelName, data); } /// @@ -1069,7 +1069,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported"); return; } - NetworkingManager.singleton.Send(clientIds, messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); + InternalMessageHandler.Send(clientIds, messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); } /// @@ -1103,7 +1103,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported"); return; } - NetworkingManager.singleton.Send(messageType, channelName, data); + InternalMessageHandler.Send(messageType, channelName, data); } /// @@ -1136,7 +1136,7 @@ namespace MLAPI.MonoBehaviours.Core Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported"); return; } - NetworkingManager.singleton.Send(messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); + InternalMessageHandler.Send(messageType, channelName, data, networkId, networkedObject.GetOrderIndex(this)); } /// diff --git a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs index f8e8cdb..20df98f 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs @@ -142,9 +142,9 @@ namespace MLAPI.MonoBehaviours.Core /// public NetworkConfig NetworkConfig; - private EllipticDiffieHellman clientDiffieHellman; - private Dictionary diffieHellmanPublicKeys; - private byte[] clientAesKey; + internal EllipticDiffieHellman clientDiffieHellman; + internal Dictionary diffieHellmanPublicKeys; + internal byte[] clientAesKey; /// /// An inspector bool that acts as a Trigger for regenerating RSA keys. Should not be used outside Unity editor. @@ -778,7 +778,7 @@ namespace MLAPI.MonoBehaviours.Core writer.Write(NetworkConfig.ConnectionData); } } - Send(netId.GetClientId(), "MLAPI_CONNECTION_REQUEST", "MLAPI_INTERNAL", writeStream.GetBuffer(), null, null, true); + InternalMessageHandler.Send(netId.GetClientId(), "MLAPI_CONNECTION_REQUEST", "MLAPI_INTERNAL", writeStream.GetBuffer(), null, null, true); } } break; @@ -901,7 +901,7 @@ namespace MLAPI.MonoBehaviours.Core netIdTarget = targetNetworkId; netOrderId = networkOrderId; } - PassthroughSend(passthroughTarget, clientId, messageType, channelId, incommingData, netIdTarget, netOrderId); + InternalMessageHandler.PassthroughSend(passthroughTarget, clientId, messageType, channelId, incommingData, netIdTarget, netOrderId); return; } @@ -949,137 +949,13 @@ namespace MLAPI.MonoBehaviours.Core case 0: //Client to server > sends connection buffer if (isServer) { - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - byte[] configHash = messageReader.ReadBytes(32); - if (!NetworkConfig.CompareConfig(configHash)) - { - Debug.LogWarning("MLAPI: NetworkConfiguration missmatch. The configuration between the server and client does not match."); - DisconnectClient(clientId); - return; - } - byte[] aesKey = new byte[0]; - if (NetworkConfig.EnableEncryption) - { - ushort diffiePublicSize = messageReader.ReadUInt16(); - byte[] diffiePublic = messageReader.ReadBytes(diffiePublicSize); - diffieHellmanPublicKeys.Add(clientId, diffiePublic); - - } - if (NetworkConfig.ConnectionApproval) - { - ushort bufferSize = messageReader.ReadUInt16(); - byte[] connectionBuffer = messageReader.ReadBytes(bufferSize); - ConnectionApprovalCallback(connectionBuffer, clientId, HandleApproval); - } - else - { - HandleApproval(clientId, true, Vector3.zero, Quaternion.identity); - } - } - } + InternalMessageHandler.HandleConnectionRequest(clientId, incommingData, channelId); } break; case 1: //Server informs client it has been approved: if (isClient) { - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - myClientId = messageReader.ReadUInt32(); - uint sceneIndex = 0; - if (NetworkConfig.EnableSceneSwitching) - { - sceneIndex = messageReader.ReadUInt32(); - } - - if (NetworkConfig.EnableEncryption) - { - ushort keyLength = messageReader.ReadUInt16(); - byte[] serverPublicKey = messageReader.ReadBytes(keyLength); - clientAesKey = clientDiffieHellman.GetSharedSecret(serverPublicKey); - if (NetworkConfig.SignKeyExchange) - { - ushort signatureLength = messageReader.ReadUInt16(); - byte[] publicKeySignature = messageReader.ReadBytes(signatureLength); - using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) - { - rsa.PersistKeyInCsp = false; - rsa.FromXmlString(NetworkConfig.RSAPublicKey); - if (!rsa.VerifyData(serverPublicKey, new SHA512CryptoServiceProvider(), publicKeySignature)) - { - //Man in the middle. - Debug.LogWarning("MLAPI: Signature doesnt match for the key exchange public part. Disconnecting"); - StopClient(); - return; - } - } - } - } - - float netTime = messageReader.ReadSingle(); - int remoteStamp = messageReader.ReadInt32(); - byte error; - NetId netId = new NetId(clientId); - int msDelay = NetworkTransport.GetRemoteDelayTimeMS(netId.HostId, netId.ConnectionId, remoteStamp, out error); - if ((NetworkError)error != NetworkError.Ok) - msDelay = 0; - networkTime = netTime + (msDelay / 1000f); - - connectedClients.Add(clientId, new NetworkedClient() { ClientId = clientId }); - int clientCount = messageReader.ReadInt32(); - for (int i = 0; i < clientCount; i++) - { - uint _clientId = messageReader.ReadUInt32(); - connectedClients.Add(_clientId, new NetworkedClient() { ClientId = _clientId }); - } - if (NetworkConfig.HandleObjectSpawning) - { - SpawnManager.DestroySceneObjects(); - int objectCount = messageReader.ReadInt32(); - for (int i = 0; i < objectCount; i++) - { - bool isPlayerObject = messageReader.ReadBoolean(); - uint networkId = messageReader.ReadUInt32(); - uint ownerId = messageReader.ReadUInt32(); - int prefabId = messageReader.ReadInt32(); - bool isActive = messageReader.ReadBoolean(); - bool sceneObject = messageReader.ReadBoolean(); - - float xPos = messageReader.ReadSingle(); - float yPos = messageReader.ReadSingle(); - float zPos = messageReader.ReadSingle(); - - float xRot = messageReader.ReadSingle(); - float yRot = messageReader.ReadSingle(); - float zRot = messageReader.ReadSingle(); - - if (isPlayerObject) - { - SpawnManager.SpawnPlayerObject(ownerId, networkId, new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); - } - else - { - GameObject go = SpawnManager.SpawnPrefabIndexClient(prefabId, networkId, ownerId, - new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); - - go.GetComponent().sceneObject = sceneObject; - go.SetActive(isActive); - } - } - } - if (NetworkConfig.EnableSceneSwitching) - { - NetworkSceneManager.OnSceneSwitch(sceneIndex); - } - } - } - _isClientConnected = true; - if (OnClientConnectedCallback != null) - OnClientConnectedCallback.Invoke(clientId); + InternalMessageHandler.HandleConnectionApproved(clientId, incommingData, channelId); } break; case 2: @@ -1087,45 +963,7 @@ namespace MLAPI.MonoBehaviours.Core //MLAPI_ADD_OBJECT if (isClient) { - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - if (NetworkConfig.HandleObjectSpawning) - { - bool isPlayerObject = messageReader.ReadBoolean(); - uint networkId = messageReader.ReadUInt32(); - uint ownerId = messageReader.ReadUInt32(); - int prefabId = messageReader.ReadInt32(); - bool sceneObject = messageReader.ReadBoolean(); - - float xPos = messageReader.ReadSingle(); - float yPos = messageReader.ReadSingle(); - float zPos = messageReader.ReadSingle(); - - float xRot = messageReader.ReadSingle(); - float yRot = messageReader.ReadSingle(); - float zRot = messageReader.ReadSingle(); - - if (isPlayerObject) - { - connectedClients.Add(ownerId, new NetworkedClient() { ClientId = ownerId }); - SpawnManager.SpawnPlayerObject(ownerId, networkId, new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); - } - else - { - GameObject go = SpawnManager.SpawnPrefabIndexClient(prefabId, networkId, ownerId, - new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); - go.GetComponent().sceneObject = sceneObject; - } - } - else - { - uint ownerId = messageReader.ReadUInt32(); - connectedClients.Add(ownerId, new NetworkedClient() { ClientId = ownerId }); - } - } - } + InternalMessageHandler.HandleAddObject(clientId, incommingData, channelId); } break; case 3: @@ -1133,266 +971,57 @@ namespace MLAPI.MonoBehaviours.Core //MLAPI_CLIENT_DISCONNECT if (isClient) { - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - uint disconnectedClientId = messageReader.ReadUInt32(); - OnClientDisconnect(disconnectedClientId); - } - } + InternalMessageHandler.HandleClientDisconnect(clientId, incommingData, channelId); } break; case 4: //Server infroms clients to destroy an object if (isClient) { - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - uint netId = messageReader.ReadUInt32(); - SpawnManager.OnDestroyObject(netId, true); - } - } + InternalMessageHandler.HandleDestroyObject(clientId, incommingData, channelId); } break; case 5: //Scene switch if (isClient) { - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - NetworkSceneManager.OnSceneSwitch(messageReader.ReadUInt32()); - } - } + InternalMessageHandler.HandleSwitchScene(clientId, incommingData, channelId); } break; case 6: //Spawn pool object if (isClient) { - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - uint netId = messageReader.ReadUInt32(); - float xPos = messageReader.ReadSingle(); - float yPos = messageReader.ReadSingle(); - float zPos = messageReader.ReadSingle(); - float xRot = messageReader.ReadSingle(); - float yRot = messageReader.ReadSingle(); - float zRot = messageReader.ReadSingle(); - SpawnManager.spawnedObjects[netId].transform.position = new Vector3(xPos, yPos, zPos); - SpawnManager.spawnedObjects[netId].transform.rotation = Quaternion.Euler(xRot, yRot, zRot); - SpawnManager.spawnedObjects[netId].gameObject.SetActive(true); - } - } + InternalMessageHandler.HandleSpawnPoolObject(clientId, incommingData, channelId); } break; case 7: //Destroy pool object if (isClient) { - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - uint netId = messageReader.ReadUInt32(); - SpawnManager.spawnedObjects[netId].gameObject.SetActive(false); - } - } + InternalMessageHandler.HandleDestroyPoolObject(clientId, incommingData, channelId); } break; case 8: //Change owner if (isClient) { - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - uint netId = messageReader.ReadUInt32(); - uint ownerClientId = messageReader.ReadUInt32(); - if (SpawnManager.spawnedObjects[netId].OwnerClientId == MyClientId) - { - //We are current owner. - SpawnManager.spawnedObjects[netId].InvokeBehaviourOnLostOwnership(); - } - if (ownerClientId == MyClientId) - { - //We are new owner. - SpawnManager.spawnedObjects[netId].InvokeBehaviourOnGainedOwnership(); - } - SpawnManager.spawnedObjects[netId].ownerClientId = ownerClientId; - } - } + InternalMessageHandler.HandleChangeOwner(clientId, incommingData, channelId); } break; case 9: //Syncvar if (isClient) { - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - byte dirtyCount = messageReader.ReadByte(); - uint netId = messageReader.ReadUInt32(); - ushort orderIndex = messageReader.ReadUInt16(); - if (dirtyCount > 0) - { - for (int i = 0; i < dirtyCount; i++) - { - byte fieldIndex = messageReader.ReadByte(); - if (!SpawnManager.spawnedObjects.ContainsKey(netId)) - { - Debug.LogWarning("MLAPI: Sync message recieved for a non existant object with id: " + netId); - return; - } - else if (SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex) == null) - { - Debug.LogWarning("MLAPI: Sync message recieved for a non existant behaviour"); - return; - } - else if (fieldIndex > (SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).syncedFieldTypes.Count - 1)) - { - Debug.LogWarning("MLAPI: Sync message recieved for field out of bounds"); - return; - } - FieldType type = SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).syncedFieldTypes[fieldIndex]; - switch (type) - { - case FieldType.Bool: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadBoolean(), fieldIndex); - break; - case FieldType.Byte: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadByte(), fieldIndex); - break; - case FieldType.Char: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadChar(), fieldIndex); - break; - case FieldType.Double: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadDouble(), fieldIndex); - break; - case FieldType.Single: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadSingle(), fieldIndex); - break; - case FieldType.Int: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadInt32(), fieldIndex); - break; - case FieldType.Long: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadInt64(), fieldIndex); - break; - case FieldType.SByte: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadSByte(), fieldIndex); - break; - case FieldType.Short: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadInt16(), fieldIndex); - break; - case FieldType.UInt: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadUInt32(), fieldIndex); - break; - case FieldType.ULong: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadUInt64(), fieldIndex); - break; - case FieldType.UShort: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadUInt16(), fieldIndex); - break; - case FieldType.String: - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadString(), fieldIndex); - break; - case FieldType.Vector3: - { //Cases aren't their own scope. Therefor we create a scope for them as they share the X,Y,Z local variables otherwise. - float x = messageReader.ReadSingle(); - float y = messageReader.ReadSingle(); - float z = messageReader.ReadSingle(); - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(new Vector3(x, y, z), fieldIndex); - } - break; - case FieldType.Vector2: - { - float x = messageReader.ReadSingle(); - float y = messageReader.ReadSingle(); - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(new Vector2(x, y), fieldIndex); - } - break; - case FieldType.Quaternion: - { - float x = messageReader.ReadSingle(); - float y = messageReader.ReadSingle(); - float z = messageReader.ReadSingle(); - SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(Quaternion.Euler(x, y, z), fieldIndex); - } - break; - } - } - } - } - } + InternalMessageHandler.HandleSyncVarUpdate(clientId, incommingData, channelId); } break; case 10: if (isClient) //MLAPI_ADD_OBJECTS (plural) { - Debug.LogError("AddObjects"); - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - if (NetworkConfig.HandleObjectSpawning) - { - ushort objectCount = messageReader.ReadUInt16(); - for (int i = 0; i < objectCount; i++) - { - bool isPlayerObject = messageReader.ReadBoolean(); - uint networkId = messageReader.ReadUInt32(); - uint ownerId = messageReader.ReadUInt32(); - int prefabId = messageReader.ReadInt32(); - bool sceneObject = messageReader.ReadBoolean(); - - float xPos = messageReader.ReadSingle(); - float yPos = messageReader.ReadSingle(); - float zPos = messageReader.ReadSingle(); - - float xRot = messageReader.ReadSingle(); - float yRot = messageReader.ReadSingle(); - float zRot = messageReader.ReadSingle(); - - if (isPlayerObject) - { - connectedClients.Add(ownerId, new NetworkedClient() { ClientId = ownerId }); - SpawnManager.SpawnPlayerObject(ownerId, networkId, new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); - } - else - { - GameObject go = SpawnManager.SpawnPrefabIndexClient(prefabId, networkId, ownerId, - new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); - go.GetComponent().sceneObject = sceneObject; - } - } - } - } - } + InternalMessageHandler.HandleAddObjects(clientId, incommingData, channelId); } - break; case 11: if (isClient) { - using (MemoryStream messageReadStream = new MemoryStream(incommingData)) - { - using (BinaryReader messageReader = new BinaryReader(messageReadStream)) - { - float netTime = messageReader.ReadSingle(); - int timestamp = messageReader.ReadInt32(); - - NetId netId = new NetId(clientId); - byte error; - int msDelay = NetworkTransport.GetRemoteDelayTimeMS(netId.HostId, netId.ConnectionId, timestamp, out error); - if ((NetworkError)error != NetworkError.Ok) - msDelay = 0; - networkTime = netTime + (msDelay / 1000f); - } - } + InternalMessageHandler.HandleTimeSync(clientId, incommingData, channelId); } break; } @@ -1402,335 +1031,7 @@ namespace MLAPI.MonoBehaviours.Core } } - #region SEND METHODS - internal void PassthroughSend(uint targetId, uint sourceId, ushort messageType, int channelId, byte[] data, uint? networkId = null, ushort? orderId = null) - { - NetId targetNetId = new NetId(targetId); - if (isHost && targetNetId.IsHost()) - { - //Host trying to send data to it's own client - Debug.LogWarning("MLAPI: Send method got message aimed at server from the server?"); - return; - } - - int sizeOfStream = 10; - if (networkId != null) - sizeOfStream += 4; - if (orderId != null) - sizeOfStream += 2; - sizeOfStream += data.Length; - - using (MemoryStream stream = new MemoryStream(sizeOfStream)) - { - 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(NetworkConfig.EncryptedChannelsHashSet.Contains(MessageManager.reverseChannels[channelId])) - { - //Encrypted message - byte[] encrypted = CryptographyHelper.Encrypt(data, connectedClients[targetId].AesKey); - writer.Write((ushort)encrypted.Length); - writer.Write(encrypted); - } - else - { - writer.Write((ushort)data.Length); - writer.Write(data); - } - } - - byte error; - NetworkTransport.QueueMessageForSending(targetNetId.HostId, targetNetId.ConnectionId, channelId, stream.GetBuffer(), sizeOfStream, out error); - } - } - - internal void Send(uint clientId, string messageType, string channelName, byte[] data, uint? networkId = null, ushort? orderId = null, bool skipQueue = false) - { - NetId netId = new NetId(clientId); - if(isHost && netId.IsHost()) - { - //Don't invoke the message on our own machine. Instant stack overflow. - Debug.LogWarning("MLAPI: Cannot send message to own client"); - return; - } - else if(netId.IsHost()) - { - //Client trying to send data to host - netId = NetId.ServerNetId; - } - - bool isPassthrough = (!isServer && clientId != NetId.ServerNetId.GetClientId() && NetworkConfig.AllowPassthroughMessages); - if (isPassthrough && !NetworkConfig.PassthroughMessageHashSet.Contains(MessageManager.messageTypes[messageType])) - { - Debug.LogWarning("MLAPI: The The MessageType " + messageType + " is not registered as an allowed passthrough message type."); - 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 (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(isPassthrough); - if (isPassthrough) - writer.Write(clientId); - - if (NetworkConfig.EncryptedChannelsHashSet.Contains(channelName)) - { - //This is an encrypted message. - byte[] encrypted; - if (isServer) - encrypted = CryptographyHelper.Encrypt(data, connectedClients[clientId].AesKey); - else - encrypted = CryptographyHelper.Encrypt(data, clientAesKey); - - writer.Write((ushort)encrypted.Length); - writer.Write(encrypted); - } - else - { - //Send in plaintext. - writer.Write((ushort)data.Length); - writer.Write(data); - } - } - byte error; - if (isPassthrough) - netId = NetId.ServerNetId; - if (skipQueue) - NetworkTransport.Send(netId.HostId, netId.ConnectionId, MessageManager.channels[channelName], stream.GetBuffer(), sizeOfStream, out error); - else - NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, MessageManager.channels[channelName], stream.GetBuffer(), sizeOfStream, out error); - } - } - - internal void Send(uint[] clientIds, string messageType, string channelName, byte[] data, uint? networkId = null, ushort? orderId = null) - { - if (NetworkConfig.EncryptedChannelsHashSet.Contains(channelName)) - { - Debug.LogWarning("MLAPI: Cannot send messages over encrypted channel to multiple clients."); - return; - } - - int sizeOfStream = 6; - if (networkId != null) - sizeOfStream += 4; - if (orderId != null) - sizeOfStream += 2; - sizeOfStream += data.Length; - - using (MemoryStream stream = new MemoryStream(sizeOfStream)) - { - 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); - } - int channel = MessageManager.channels[channelName]; - for (int i = 0; i < clientIds.Length; i++) - { - NetId netId = new NetId(clientIds[i]); - if (isHost && netId.IsHost()) - { - //Don't invoke the message on our own machine. Instant stack overflow. - continue; - } - else if (netId.IsHost()) - { - //Client trying to send data to host - netId = NetId.ServerNetId; - } - byte error; - NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); - } - } - } - - internal void Send(List clientIds, string messageType, string channelName, byte[] data, uint? networkId = null, ushort? orderId = null) - { - if (NetworkConfig.EncryptedChannelsHashSet.Contains(channelName)) - { - 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 (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); - } - int channel = MessageManager.channels[channelName]; - for (int i = 0; i < clientIds.Count; i++) - { - NetId netId = new NetId(clientIds[i]); - if (isHost && netId.IsHost()) - { - //Don't invoke the message on our own machine. Instant stack overflow. - continue; - } - else if (netId.IsHost()) - { - //Client trying to send data to host - netId = NetId.ServerNetId; - } - byte error; - NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); - } - } - } - - internal void Send(string messageType, string channelName, byte[] data, uint? networkId = null, ushort? orderId = null) - { - if (connectedClients.Count == 0) - return; - if (NetworkConfig.EncryptedChannels.Contains(channelName)) - { - 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 (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); - } - int channel = MessageManager.channels[channelName]; - foreach (KeyValuePair pair in connectedClients) - { - NetId netId = new NetId(pair.Key); - if(isHost && netId.IsHost()) - { - //Don't invoke the message on our own machine. Instant stack overflow. - continue; - } - else if (netId.IsHost()) - { - //Client trying to send data to host - netId = NetId.ServerNetId; - } - byte error; - NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); - } - } - } - - internal void Send(string messageType, string channelName, byte[] data, uint clientIdToIgnore, uint? networkId = null, ushort? orderId = null) - { - if (NetworkConfig.EncryptedChannels.Contains(channelName)) - { - 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 = 5; - if (networkId != null) - sizeOfStream += 4; - if (orderId != null) - sizeOfStream += 2; - sizeOfStream += data.Length; - - using (MemoryStream stream = new MemoryStream(sizeOfStream)) - { - 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); - } - int channel = MessageManager.channels[channelName]; - foreach (KeyValuePair pair in connectedClients) - { - if (pair.Key == clientIdToIgnore) - continue; - - NetId netId = new NetId(pair.Key); - if (isHost && netId.IsHost()) - { - //Don't invoke the message on our own machine. Instant stack overflow. - continue; - } - else if (netId.IsHost()) - { - //Client trying to send data to host - netId = NetId.ServerNetId; - } - byte error; - NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); - } - } - } - #endregion - - private void DisconnectClient(uint clientId) + internal void DisconnectClient(uint clientId) { if (!isServer) return; @@ -1752,7 +1053,7 @@ namespace MLAPI.MonoBehaviours.Core NetworkTransport.Disconnect(netId.HostId, netId.ConnectionId, out error); } - private void OnClientDisconnect(uint clientId) + internal void OnClientDisconnect(uint clientId) { if (pendingClients.Contains(clientId)) pendingClients.Remove(clientId); @@ -1779,7 +1080,7 @@ namespace MLAPI.MonoBehaviours.Core { writer.Write(clientId); } - Send("MLAPI_CLIENT_DISCONNECT", "MLAPI_INTERNAL", stream.GetBuffer(), clientId); + InternalMessageHandler.Send("MLAPI_CLIENT_DISCONNECT", "MLAPI_INTERNAL", stream.GetBuffer(), clientId); } } } @@ -1797,12 +1098,12 @@ namespace MLAPI.MonoBehaviours.Core foreach (KeyValuePair pair in connectedClients) { - Send("MLAPI_TIME_SYNC", "MLAPI_TIME_SYNC", stream.GetBuffer()); + InternalMessageHandler.Send("MLAPI_TIME_SYNC", "MLAPI_TIME_SYNC", stream.GetBuffer()); } } } - private void HandleApproval(uint clientId, bool approved, Vector3 position, Quaternion rotation) + internal void HandleApproval(uint clientId, bool approved, Vector3 position, Quaternion rotation) { if(approved) { @@ -1925,7 +1226,7 @@ namespace MLAPI.MonoBehaviours.Core } } } - Send(clientId, "MLAPI_CONNECTION_APPROVED", "MLAPI_INTERNAL", writeStream.GetBuffer(), null, null, true); + InternalMessageHandler.Send(clientId, "MLAPI_CONNECTION_APPROVED", "MLAPI_INTERNAL", writeStream.GetBuffer(), null, null, true); if (OnClientConnectedCallback != null) OnClientConnectedCallback.Invoke(clientId); @@ -1963,7 +1264,7 @@ namespace MLAPI.MonoBehaviours.Core writer.Write(clientId); } } - Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer(), clientId); + InternalMessageHandler.Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer(), clientId); } //Flush syncvars: foreach (KeyValuePair networkedObject in SpawnManager.spawnedObjects) diff --git a/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Receive.cs b/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Receive.cs new file mode 100644 index 0000000..9d0dcd0 --- /dev/null +++ b/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Receive.cs @@ -0,0 +1,445 @@ +using System; +using System.IO; +using System.Security.Cryptography; +using MLAPI.Data; +using MLAPI.MonoBehaviours.Core; +using UnityEngine; +using UnityEngine.Networking; + +namespace MLAPI.NetworkingManagerComponents.Core +{ + internal static partial class InternalMessageHandler + { + internal static void HandleConnectionRequest(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + byte[] configHash = messageReader.ReadBytes(32); + if (!netManager.NetworkConfig.CompareConfig(configHash)) + { + Debug.LogWarning("MLAPI: NetworkConfiguration missmatch. The configuration between the server and client does not match."); + netManager.DisconnectClient(clientId); + return; + } + byte[] aesKey = new byte[0]; + if (netManager.NetworkConfig.EnableEncryption) + { + ushort diffiePublicSize = messageReader.ReadUInt16(); + byte[] diffiePublic = messageReader.ReadBytes(diffiePublicSize); + netManager.diffieHellmanPublicKeys.Add(clientId, diffiePublic); + + } + if (netManager.NetworkConfig.ConnectionApproval) + { + ushort bufferSize = messageReader.ReadUInt16(); + byte[] connectionBuffer = messageReader.ReadBytes(bufferSize); + netManager.ConnectionApprovalCallback(connectionBuffer, clientId, netManager.HandleApproval); + } + else + { + netManager.HandleApproval(clientId, true, Vector3.zero, Quaternion.identity); + } + } + } + } + + internal static void HandleConnectionApproved(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + netManager.myClientId = messageReader.ReadUInt32(); + uint sceneIndex = 0; + if (netManager.NetworkConfig.EnableSceneSwitching) + { + sceneIndex = messageReader.ReadUInt32(); + } + + if (netManager.NetworkConfig.EnableEncryption) + { + ushort keyLength = messageReader.ReadUInt16(); + byte[] serverPublicKey = messageReader.ReadBytes(keyLength); + netManager.clientAesKey = netManager.clientDiffieHellman.GetSharedSecret(serverPublicKey); + if (netManager.NetworkConfig.SignKeyExchange) + { + ushort signatureLength = messageReader.ReadUInt16(); + byte[] publicKeySignature = messageReader.ReadBytes(signatureLength); + using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) + { + rsa.PersistKeyInCsp = false; + rsa.FromXmlString(netManager.NetworkConfig.RSAPublicKey); + if (!rsa.VerifyData(serverPublicKey, new SHA512CryptoServiceProvider(), publicKeySignature)) + { + //Man in the middle. + Debug.LogWarning("MLAPI: Signature doesnt match for the key exchange public part. Disconnecting"); + netManager.StopClient(); + return; + } + } + } + } + + float netTime = messageReader.ReadSingle(); + int remoteStamp = messageReader.ReadInt32(); + byte error; + NetId netId = new NetId(clientId); + int msDelay = NetworkTransport.GetRemoteDelayTimeMS(netId.HostId, netId.ConnectionId, remoteStamp, out error); + if ((NetworkError)error != NetworkError.Ok) + msDelay = 0; + netManager.networkTime = netTime + (msDelay / 1000f); + + netManager.connectedClients.Add(clientId, new NetworkedClient() { ClientId = clientId }); + int clientCount = messageReader.ReadInt32(); + for (int i = 0; i < clientCount; i++) + { + uint _clientId = messageReader.ReadUInt32(); + netManager.connectedClients.Add(_clientId, new NetworkedClient() { ClientId = _clientId }); + } + if (netManager.NetworkConfig.HandleObjectSpawning) + { + SpawnManager.DestroySceneObjects(); + int objectCount = messageReader.ReadInt32(); + for (int i = 0; i < objectCount; i++) + { + bool isPlayerObject = messageReader.ReadBoolean(); + uint networkId = messageReader.ReadUInt32(); + uint ownerId = messageReader.ReadUInt32(); + int prefabId = messageReader.ReadInt32(); + bool isActive = messageReader.ReadBoolean(); + bool sceneObject = messageReader.ReadBoolean(); + + float xPos = messageReader.ReadSingle(); + float yPos = messageReader.ReadSingle(); + float zPos = messageReader.ReadSingle(); + + float xRot = messageReader.ReadSingle(); + float yRot = messageReader.ReadSingle(); + float zRot = messageReader.ReadSingle(); + + if (isPlayerObject) + { + SpawnManager.SpawnPlayerObject(ownerId, networkId, new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); + } + else + { + GameObject go = SpawnManager.SpawnPrefabIndexClient(prefabId, networkId, ownerId, + new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); + + go.GetComponent().sceneObject = sceneObject; + go.SetActive(isActive); + } + } + } + if (netManager.NetworkConfig.EnableSceneSwitching) + { + NetworkSceneManager.OnSceneSwitch(sceneIndex); + } + } + } + netManager._isClientConnected = true; + if (netManager.OnClientConnectedCallback != null) + netManager.OnClientConnectedCallback.Invoke(clientId); + } + + internal static void HandleAddObject(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + if (netManager.NetworkConfig.HandleObjectSpawning) + { + bool isPlayerObject = messageReader.ReadBoolean(); + uint networkId = messageReader.ReadUInt32(); + uint ownerId = messageReader.ReadUInt32(); + int prefabId = messageReader.ReadInt32(); + bool sceneObject = messageReader.ReadBoolean(); + + float xPos = messageReader.ReadSingle(); + float yPos = messageReader.ReadSingle(); + float zPos = messageReader.ReadSingle(); + + float xRot = messageReader.ReadSingle(); + float yRot = messageReader.ReadSingle(); + float zRot = messageReader.ReadSingle(); + + if (isPlayerObject) + { + netManager.connectedClients.Add(ownerId, new NetworkedClient() { ClientId = ownerId }); + SpawnManager.SpawnPlayerObject(ownerId, networkId, new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); + } + else + { + GameObject go = SpawnManager.SpawnPrefabIndexClient(prefabId, networkId, ownerId, + new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); + go.GetComponent().sceneObject = sceneObject; + } + } + else + { + uint ownerId = messageReader.ReadUInt32(); + netManager.connectedClients.Add(ownerId, new NetworkedClient() { ClientId = ownerId }); + } + } + } + } + + internal static void HandleClientDisconnect(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + uint disconnectedClientId = messageReader.ReadUInt32(); + netManager.OnClientDisconnect(disconnectedClientId); + } + } + } + + internal static void HandleDestroyObject(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + uint netId = messageReader.ReadUInt32(); + SpawnManager.OnDestroyObject(netId, true); + } + } + } + + internal static void HandleSwitchScene(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + NetworkSceneManager.OnSceneSwitch(messageReader.ReadUInt32()); + } + } + } + + internal static void HandleSpawnPoolObject(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + uint netId = messageReader.ReadUInt32(); + + float xPos = messageReader.ReadSingle(); + float yPos = messageReader.ReadSingle(); + float zPos = messageReader.ReadSingle(); + + float xRot = messageReader.ReadSingle(); + float yRot = messageReader.ReadSingle(); + float zRot = messageReader.ReadSingle(); + + SpawnManager.spawnedObjects[netId].transform.position = new Vector3(xPos, yPos, zPos); + SpawnManager.spawnedObjects[netId].transform.rotation = Quaternion.Euler(xRot, yRot, zRot); + SpawnManager.spawnedObjects[netId].gameObject.SetActive(true); + } + } + } + + internal static void HandleDestroyPoolObject(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + uint netId = messageReader.ReadUInt32(); + SpawnManager.spawnedObjects[netId].gameObject.SetActive(false); + } + } + } + + internal static void HandleChangeOwner(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + uint netId = messageReader.ReadUInt32(); + uint ownerClientId = messageReader.ReadUInt32(); + if (SpawnManager.spawnedObjects[netId].OwnerClientId == netManager.MyClientId) + { + //We are current owner. + SpawnManager.spawnedObjects[netId].InvokeBehaviourOnLostOwnership(); + } + if (ownerClientId == netManager.MyClientId) + { + //We are new owner. + SpawnManager.spawnedObjects[netId].InvokeBehaviourOnGainedOwnership(); + } + SpawnManager.spawnedObjects[netId].ownerClientId = ownerClientId; + } + } + } + + internal static void HandleSyncVarUpdate(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + byte dirtyCount = messageReader.ReadByte(); + uint netId = messageReader.ReadUInt32(); + ushort orderIndex = messageReader.ReadUInt16(); + if (dirtyCount > 0) + { + for (int i = 0; i < dirtyCount; i++) + { + byte fieldIndex = messageReader.ReadByte(); + if (!SpawnManager.spawnedObjects.ContainsKey(netId)) + { + Debug.LogWarning("MLAPI: Sync message recieved for a non existant object with id: " + netId); + return; + } + else if (SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex) == null) + { + Debug.LogWarning("MLAPI: Sync message recieved for a non existant behaviour"); + return; + } + else if (fieldIndex > (SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).syncedFieldTypes.Count - 1)) + { + Debug.LogWarning("MLAPI: Sync message recieved for field out of bounds"); + return; + } + FieldType type = SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).syncedFieldTypes[fieldIndex]; + switch (type) + { + case FieldType.Bool: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadBoolean(), fieldIndex); + break; + case FieldType.Byte: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadByte(), fieldIndex); + break; + case FieldType.Char: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadChar(), fieldIndex); + break; + case FieldType.Double: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadDouble(), fieldIndex); + break; + case FieldType.Single: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadSingle(), fieldIndex); + break; + case FieldType.Int: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadInt32(), fieldIndex); + break; + case FieldType.Long: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadInt64(), fieldIndex); + break; + case FieldType.SByte: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadSByte(), fieldIndex); + break; + case FieldType.Short: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadInt16(), fieldIndex); + break; + case FieldType.UInt: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadUInt32(), fieldIndex); + break; + case FieldType.ULong: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadUInt64(), fieldIndex); + break; + case FieldType.UShort: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadUInt16(), fieldIndex); + break; + case FieldType.String: + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadString(), fieldIndex); + break; + case FieldType.Vector3: + { //Cases aren't their own scope. Therefor we create a scope for them as they share the X,Y,Z local variables otherwise. + float x = messageReader.ReadSingle(); + float y = messageReader.ReadSingle(); + float z = messageReader.ReadSingle(); + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(new Vector3(x, y, z), fieldIndex); + } + break; + case FieldType.Vector2: + { + float x = messageReader.ReadSingle(); + float y = messageReader.ReadSingle(); + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(new Vector2(x, y), fieldIndex); + } + break; + case FieldType.Quaternion: + { + float x = messageReader.ReadSingle(); + float y = messageReader.ReadSingle(); + float z = messageReader.ReadSingle(); + SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(Quaternion.Euler(x, y, z), fieldIndex); + } + break; + } + } + } + } + } + } + + internal static void HandleAddObjects(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + if (netManager.NetworkConfig.HandleObjectSpawning) + { + ushort objectCount = messageReader.ReadUInt16(); + for (int i = 0; i < objectCount; i++) + { + bool isPlayerObject = messageReader.ReadBoolean(); + uint networkId = messageReader.ReadUInt32(); + uint ownerId = messageReader.ReadUInt32(); + int prefabId = messageReader.ReadInt32(); + bool sceneObject = messageReader.ReadBoolean(); + + float xPos = messageReader.ReadSingle(); + float yPos = messageReader.ReadSingle(); + float zPos = messageReader.ReadSingle(); + + float xRot = messageReader.ReadSingle(); + float yRot = messageReader.ReadSingle(); + float zRot = messageReader.ReadSingle(); + + if (isPlayerObject) + { + netManager.connectedClients.Add(ownerId, new NetworkedClient() { ClientId = ownerId }); + SpawnManager.SpawnPlayerObject(ownerId, networkId, new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); + } + else + { + GameObject go = SpawnManager.SpawnPrefabIndexClient(prefabId, networkId, ownerId, + new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot)); + go.GetComponent().sceneObject = sceneObject; + } + } + } + } + } + } + + internal static void HandleTimeSync(uint clientId, byte[] incommingData, int channelId) + { + using (MemoryStream messageReadStream = new MemoryStream(incommingData)) + { + using (BinaryReader messageReader = new BinaryReader(messageReadStream)) + { + float netTime = messageReader.ReadSingle(); + int timestamp = messageReader.ReadInt32(); + + NetId netId = new NetId(clientId); + byte error; + int msDelay = NetworkTransport.GetRemoteDelayTimeMS(netId.HostId, netId.ConnectionId, timestamp, out error); + if ((NetworkError)error != NetworkError.Ok) + msDelay = 0; + netManager.networkTime = netTime + (msDelay / 1000f); + } + } + } + } +} diff --git a/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Send.cs b/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Send.cs new file mode 100644 index 0000000..118725d --- /dev/null +++ b/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Send.cs @@ -0,0 +1,339 @@ +using System.Collections.Generic; +using System.IO; +using MLAPI.Data; +using MLAPI.MonoBehaviours.Core; +using MLAPI.NetworkingManagerComponents.Cryptography; +using UnityEngine; +using UnityEngine.Networking; + +namespace MLAPI.NetworkingManagerComponents.Core +{ + internal static partial class InternalMessageHandler + { + internal static void PassthroughSend(uint targetId, uint sourceId, ushort messageType, int channelId, byte[] data, uint? networkId = null, ushort? orderId = null) + { + NetId targetNetId = new NetId(targetId); + if (netManager.isHost && targetNetId.IsHost()) + { + //Host trying to send data to it's own client + Debug.LogWarning("MLAPI: Send method got message aimed at server from the server?"); + return; + } + + int sizeOfStream = 10; + if (networkId != null) + sizeOfStream += 4; + if (orderId != null) + sizeOfStream += 2; + sizeOfStream += data.Length; + + using (MemoryStream stream = new MemoryStream(sizeOfStream)) + { + 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); + } + } + + byte error; + NetworkTransport.QueueMessageForSending(targetNetId.HostId, targetNetId.ConnectionId, channelId, stream.GetBuffer(), sizeOfStream, out error); + } + } + + internal static void Send(uint clientId, string messageType, string channelName, byte[] data, uint? networkId = null, ushort? orderId = null, bool skipQueue = false) + { + NetId netId = new NetId(clientId); + if (netManager.isHost && netId.IsHost()) + { + //Don't invoke the message on our own machine. Instant stack overflow. + Debug.LogWarning("MLAPI: Cannot send message to own client"); + return; + } + else if (netId.IsHost()) + { + //Client trying to send data to host + netId = NetId.ServerNetId; + } + + bool isPassthrough = (!netManager.isServer && clientId != NetId.ServerNetId.GetClientId() && netManager.NetworkConfig.AllowPassthroughMessages); + if (isPassthrough && !netManager.NetworkConfig.PassthroughMessageHashSet.Contains(MessageManager.messageTypes[messageType])) + { + Debug.LogWarning("MLAPI: The The MessageType " + messageType + " is not registered as an allowed passthrough message type."); + 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 (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(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); + } + else + { + //Send in plaintext. + writer.Write((ushort)data.Length); + writer.Write(data); + } + } + byte error; + if (isPassthrough) + netId = NetId.ServerNetId; + if (skipQueue) + NetworkTransport.Send(netId.HostId, netId.ConnectionId, MessageManager.channels[channelName], stream.GetBuffer(), sizeOfStream, out error); + else + NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, MessageManager.channels[channelName], stream.GetBuffer(), sizeOfStream, out error); + } + } + + internal static void Send(uint[] clientIds, string messageType, string channelName, byte[] data, uint? networkId = null, ushort? orderId = null) + { + if (netManager.NetworkConfig.EncryptedChannelsHashSet.Contains(channelName)) + { + Debug.LogWarning("MLAPI: Cannot send messages over encrypted channel to multiple clients."); + return; + } + + int sizeOfStream = 6; + if (networkId != null) + sizeOfStream += 4; + if (orderId != null) + sizeOfStream += 2; + sizeOfStream += data.Length; + + using (MemoryStream stream = new MemoryStream(sizeOfStream)) + { + 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); + } + int channel = MessageManager.channels[channelName]; + for (int i = 0; i < clientIds.Length; i++) + { + NetId netId = new NetId(clientIds[i]); + if (netManager.isHost && netId.IsHost()) + { + //Don't invoke the message on our own machine. Instant stack overflow. + continue; + } + else if (netId.IsHost()) + { + //Client trying to send data to host + netId = NetId.ServerNetId; + } + byte error; + NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); + } + } + } + + internal static void Send(List clientIds, string messageType, string channelName, byte[] data, uint? networkId = null, ushort? orderId = null) + { + if (netManager.NetworkConfig.EncryptedChannelsHashSet.Contains(channelName)) + { + 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 (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); + } + int channel = MessageManager.channels[channelName]; + for (int i = 0; i < clientIds.Count; i++) + { + NetId netId = new NetId(clientIds[i]); + if (netManager.isHost && netId.IsHost()) + { + //Don't invoke the message on our own machine. Instant stack overflow. + continue; + } + else if (netId.IsHost()) + { + //Client trying to send data to host + netId = NetId.ServerNetId; + } + byte error; + NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); + } + } + } + + internal static void Send(string messageType, string channelName, byte[] data, uint? networkId = null, ushort? orderId = null) + { + if (netManager.connectedClients.Count == 0) + return; + if (netManager.NetworkConfig.EncryptedChannels.Contains(channelName)) + { + 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 (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); + } + int channel = MessageManager.channels[channelName]; + foreach (KeyValuePair pair in netManager.connectedClients) + { + NetId netId = new NetId(pair.Key); + if (netManager.isHost && netId.IsHost()) + { + //Don't invoke the message on our own machine. Instant stack overflow. + continue; + } + else if (netId.IsHost()) + { + //Client trying to send data to host + netId = NetId.ServerNetId; + } + byte error; + NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); + } + } + } + + internal static void Send(string messageType, string channelName, byte[] data, uint clientIdToIgnore, uint? networkId = null, ushort? orderId = null) + { + if (netManager.NetworkConfig.EncryptedChannels.Contains(channelName)) + { + 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 = 5; + if (networkId != null) + sizeOfStream += 4; + if (orderId != null) + sizeOfStream += 2; + sizeOfStream += data.Length; + + using (MemoryStream stream = new MemoryStream(sizeOfStream)) + { + 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); + } + int channel = MessageManager.channels[channelName]; + foreach (KeyValuePair pair in netManager.connectedClients) + { + if (pair.Key == clientIdToIgnore) + continue; + + NetId netId = new NetId(pair.Key); + if (netManager.isHost && netId.IsHost()) + { + //Don't invoke the message on our own machine. Instant stack overflow. + continue; + } + else if (netId.IsHost()) + { + //Client trying to send data to host + netId = NetId.ServerNetId; + } + byte error; + NetworkTransport.QueueMessageForSending(netId.HostId, netId.ConnectionId, channel, stream.GetBuffer(), sizeOfStream, out error); + } + } + } + } +} diff --git a/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.cs b/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.cs new file mode 100644 index 0000000..adff8dc --- /dev/null +++ b/MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.cs @@ -0,0 +1,16 @@ +using System; +using MLAPI.MonoBehaviours.Core; + +namespace MLAPI.NetworkingManagerComponents.Core +{ + internal static partial class InternalMessageHandler + { + private static NetworkingManager netManager + { + get + { + return NetworkingManager.singleton; + } + } + } +} diff --git a/MLAPI/NetworkingManagerComponents/Core/NetworkPoolManager.cs b/MLAPI/NetworkingManagerComponents/Core/NetworkPoolManager.cs index c3e9c63..a4df814 100644 --- a/MLAPI/NetworkingManagerComponents/Core/NetworkPoolManager.cs +++ b/MLAPI/NetworkingManagerComponents/Core/NetworkPoolManager.cs @@ -78,7 +78,7 @@ namespace MLAPI.NetworkingManagerComponents.Core writer.Write(rotation.eulerAngles.y); writer.Write(rotation.eulerAngles.z); } - NetworkingManager.singleton.Send("MLAPI_SPAWN_POOL_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); + InternalMessageHandler.Send("MLAPI_SPAWN_POOL_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); } return go; } @@ -101,7 +101,7 @@ namespace MLAPI.NetworkingManagerComponents.Core { writer.Write(netObject.NetworkId); } - NetworkingManager.singleton.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); + InternalMessageHandler.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); } } } diff --git a/MLAPI/NetworkingManagerComponents/Core/NetworkSceneManager.cs b/MLAPI/NetworkingManagerComponents/Core/NetworkSceneManager.cs index eb5078f..ea80aeb 100644 --- a/MLAPI/NetworkingManagerComponents/Core/NetworkSceneManager.cs +++ b/MLAPI/NetworkingManagerComponents/Core/NetworkSceneManager.cs @@ -64,7 +64,7 @@ namespace MLAPI.NetworkingManagerComponents.Core { writer.Write(sceneNameToIndex[sceneName]); } - NetworkingManager.singleton.Send("MLAPI_SWITCH_SCENE", "MLAPI_INTERNAL", stream.GetBuffer()); + InternalMessageHandler.Send("MLAPI_SWITCH_SCENE", "MLAPI_INTERNAL", stream.GetBuffer()); } } diff --git a/MLAPI/NetworkingManagerComponents/Core/SpawnManager.cs b/MLAPI/NetworkingManagerComponents/Core/SpawnManager.cs index 7b9e06b..114d75b 100644 --- a/MLAPI/NetworkingManagerComponents/Core/SpawnManager.cs +++ b/MLAPI/NetworkingManagerComponents/Core/SpawnManager.cs @@ -45,7 +45,7 @@ namespace MLAPI.NetworkingManagerComponents.Core writer.Write(netId); writer.Write(netObject.ownerClientId); } - netManager.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", stream.GetBuffer()); + InternalMessageHandler.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", stream.GetBuffer()); } } @@ -62,7 +62,7 @@ namespace MLAPI.NetworkingManagerComponents.Core writer.Write(netId); writer.Write(clientId); } - netManager.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", stream.GetBuffer()); + InternalMessageHandler.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", stream.GetBuffer()); } } @@ -131,7 +131,7 @@ namespace MLAPI.NetworkingManagerComponents.Core writer.Write(sceneObjectsToSync[i].transform.rotation.eulerAngles.z); } } - NetworkingManager.singleton.Send("MLAPI_ADD_OBJECTS", "MLAPI_INTERNAL", stream.GetBuffer()); + InternalMessageHandler.Send("MLAPI_ADD_OBJECTS", "MLAPI_INTERNAL", stream.GetBuffer()); } } @@ -213,7 +213,7 @@ namespace MLAPI.NetworkingManagerComponents.Core writer.Write(netObject.transform.rotation.eulerAngles.z); } - netManager.Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); + InternalMessageHandler.Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); } } @@ -269,7 +269,7 @@ namespace MLAPI.NetworkingManagerComponents.Core { writer.Write(networkId); } - netManager.Send("MLAPI_DESTROY_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); + InternalMessageHandler.Send("MLAPI_DESTROY_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer()); } } }