internal static BitStream WrapMessage(byte messageType, ulong clientID, BitStream messageBody, SecuritySendFlags flags) { try { bool encrypted = ((flags & SecuritySendFlags.Encrypted) == SecuritySendFlags.Encrypted) && false; //NetworkManager.Get().NetworkConfig.EnableEncryption; bool authenticated = (flags & SecuritySendFlags.Authenticated) == SecuritySendFlags.Authenticated && false; //NetworkManager.Get().NetworkConfig.EnableEncryption; PooledBitStream outStream = PooledBitStream.Get(); using (PooledBitWriter outWriter = PooledBitWriter.Get(outStream)) { outWriter.WriteBit(encrypted); outWriter.WriteBit(authenticated); outWriter.WriteBits(messageType, 6); outStream.Write(messageBody.GetBuffer(), 0, (int)messageBody.Length); } return(outStream); } catch (Exception e) { Debug.LogError("Error while wrapping headers"); Debug.LogError(e.ToString()); return(null); } }
internal static void WriteSpawnCallForObject(MLAPI.Serialization.BitStream stream, ulong clientId, NetworkedObject netObject, Stream payload) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteBool(netObject.IsPlayerObject); writer.WriteUInt64Packed(netObject.NetworkId); writer.WriteUInt64Packed(netObject.OwnerClientId); if (NetworkingManager.Singleton.NetworkConfig.UsePrefabSync) { writer.WriteUInt64Packed(netObject.PrefabHash); } else { writer.WriteBool(netObject.IsSceneObject == null ? true : netObject.IsSceneObject.Value); if (netObject.IsSceneObject == null || netObject.IsSceneObject.Value) { writer.WriteUInt64Packed(netObject.NetworkedInstanceId); } else { writer.WriteUInt64Packed(netObject.PrefabHash); } } writer.WriteSinglePacked(netObject.transform.position.x); writer.WriteSinglePacked(netObject.transform.position.y); writer.WriteSinglePacked(netObject.transform.position.z); writer.WriteSinglePacked(netObject.transform.rotation.eulerAngles.x); writer.WriteSinglePacked(netObject.transform.rotation.eulerAngles.y); writer.WriteSinglePacked(netObject.transform.rotation.eulerAngles.z); writer.WriteBool(payload != null); if (payload != null) { writer.WriteInt32Packed((int)payload.Length); } if (NetworkingManager.Singleton.NetworkConfig.EnableNetworkedVar) { netObject.WriteNetworkedVarData(stream, clientId); } if (payload != null) { stream.CopyFrom(payload); } } }
public byte[] ToBytes() { BitStream stream = new BitStream(); BitWriter writer = new BitWriter(stream); writer.WriteUInt16Packed((ushort)ticks.Length); for (int i = 0; i < ticks.Length; i++) { ticks[i].SerializeToStream(stream); } return(stream.ToArray()); }
/// <summary> /// Handle the valid messages received from NetworkManager.HandleIncomingData(). /// </summary> /// <param name="sendingClientID"></param> /// <param name="messageType"></param> /// <param name="messageStream"></param> /// <param name="receiveTime"></param> public void HandleMessage(ulong sendingClientID, byte messageType, BitStream messageStream, float receiveTime) { if (messageType >= m_FirstFreeIndex) { if (messageType == (byte)MessageType.INVALID) { Debug.LogWarning("Received invalid message."); return; } Debug.LogError("Received unknown message type. Message type: " + messageType.ToString()); return; } NetworkMessageReceiver receiver = m_Receivers[messageType]; switch (receiver) { case NetworkMessageReceiver.Both: m_Callbacks[messageType].Invoke(sendingClientID, messageStream, receiveTime); break; case NetworkMessageReceiver.Client: if (networkManager.isClient) { m_Callbacks[messageType].Invoke(sendingClientID, messageStream, receiveTime); } #if DEVELOPMENT_BUILD || UNITY_EDITOR if (!networkManager.isClient) { Debug.LogError("Client '" + sendingClientID + "' sent message type " + GetMessageName(messageType) + "(" + messageType.ToString() + ") when the Network Message Receiver for this message type is set to Client."); } #endif break; case NetworkMessageReceiver.Server: if (networkManager.isServer) { m_Callbacks[messageType].Invoke(sendingClientID, messageStream, receiveTime); } #if DEVELOPMENT_BUILD || UNITY_EDITOR if (!networkManager.isServer) { Debug.LogError("Server sent message type '" + GetMessageName(messageType) + "(" + messageType.ToString() + ")' when the Network Message Receiver for this message type is set to Server."); } #endif break; } }
// This method is responsible for unwrapping a message, that is extracting the messagebody. // Could include decrypting and/or authentication. internal static BitStream UnwrapMessage(BitStream inputStream, ulong clientID, out byte messageType, out SecuritySendFlags security) { using (PooledBitReader inputHeaderReader = PooledBitReader.Get(inputStream)) { try { if (inputStream.Length < 1) { Debug.LogError("The incoming message was too small"); messageType = (byte)MessageType.INVALID; security = SecuritySendFlags.None; return(null); } bool isEncrypted = inputHeaderReader.ReadBit(); bool isAuthenticated = inputHeaderReader.ReadBit(); if (isEncrypted && isAuthenticated) { security = SecuritySendFlags.Encrypted | SecuritySendFlags.Authenticated; } else if (isEncrypted) { security = SecuritySendFlags.Encrypted; } else if (isAuthenticated) { security = SecuritySendFlags.Authenticated; } else { security = SecuritySendFlags.None; } messageType = inputHeaderReader.ReadByteBits(6); // The input stream is now ready to be read from. It's "safe" and has the correct position return(inputStream); } catch (Exception e) { Debug.LogError("Error while unwrapping headers"); Debug.LogError(e.ToString()); security = SecuritySendFlags.None; messageType = (byte)MessageType.INVALID; return(null); } } }
public static ProfilerContainer FromBytes(byte[] bytes) { ProfilerContainer container = new ProfilerContainer(); BitStream stream = new BitStream(bytes); BitReader reader = new BitReader(stream); ushort count = reader.ReadUInt16Packed(); container.ticks = new ProfilerTick[count]; for (int i = 0; i < count; i++) { container.ticks[i] = ProfilerTick.FromStream(stream); } return(container); }
private void HandleIncomingData(ulong sendingClientID, byte channel, ArraySegment <byte> data, float receiveTime) { if (enableLogging) { Debug.Log("Unwrapping Data Header"); } inputStreamWrapper.SetTarget(data.Array); inputStreamWrapper.SetLength(data.Count + data.Offset); inputStreamWrapper.Position = data.Offset; using (BitStream messageStream = MessagePacker.UnwrapMessage(inputStreamWrapper, sendingClientID, out byte messageType, out SecuritySendFlags security)) { if (messageStream == null) { Debug.LogError("Message unwrap could not be completed. Was the header corrupt? Crypto error?"); return; } else if (messageType == (byte)MessageType.INVALID) { Debug.LogError("Message unwrap read an invalid messageType"); return; } uint headerByteSize = (uint)Arithmetic.VarIntSize(messageType); //if(enableLogging) //Debug.Log("Data Header: messageType=" + m_MessageHandler.GetMessageName(messageType) + "(" + messageType + ")"); // Client tried to send a network message that was not the connection request before they were accepted if (m_PendingClientsDictionary.ContainsKey(sendingClientID) && m_PendingClientsDictionary[sendingClientID].connectionState == PendingClient.State.PendingConnection && messageType != (byte)MessageType.NETWORK_CONNECTION_REQUEST) { Debug.LogWarning("Message received from clientID " + sendingClientID + " before it has been accepted. Message type: (" + messageType.ToString() + ") " + m_MessageHandler.GetMessageName(messageType)); return; } //Handle Message m_MessageHandler.HandleMessage(sendingClientID, messageType, messageStream, receiveTime); } }
/// <summary> /// Sets the NetworkConfig data with that from a base64 encoded version /// </summary> /// <param name="base64">The base64 encoded version</param> public void FromBase64(string base64) { NetworkConfig config = this; byte[] binary = Convert.FromBase64String(base64); using (BitStream stream = new BitStream(binary)) { using (PooledBitReader reader = PooledBitReader.Get(stream)) { config.ProtocolVersion = reader.ReadUInt16Packed(); ushort sceneCount = reader.ReadUInt16Packed(); config.RegisteredScenes.Clear(); for (int i = 0; i < sceneCount; i++) { config.RegisteredScenes.Add(reader.ReadString().ToString()); } config.ReceiveTickrate = reader.ReadInt32Packed(); config.MaxReceiveEventsPerTickRate = reader.ReadInt32Packed(); config.SendTickrate = reader.ReadInt32Packed(); config.EventTickrate = reader.ReadInt32Packed(); config.ClientConnectionBufferTimeout = reader.ReadInt32Packed(); config.ConnectionApproval = reader.ReadBool(); config.SecondsHistory = reader.ReadInt32Packed(); config.EnableEncryption = reader.ReadBool(); config.SignKeyExchange = reader.ReadBool(); config.LoadSceneTimeOut = reader.ReadInt32Packed(); config.EnableTimeResync = reader.ReadBool(); config.RpcHashSize = (HashSize)reader.ReadBits(3); config.ForceSamePrefabs = reader.ReadBool(); config.UsePrefabSync = reader.ReadBool(); config.EnableNetworkedVar = reader.ReadBool(); } } }
internal static NetworkedObject CreateSpawnedObject(int networkedPrefabId, uint networkId, uint owner, bool playerObject, uint sceneSpawnedInIndex, bool sceneDelayedSpawn, bool destroyWithScene, Vector3?position, Quaternion?rotation, bool isActive, Stream stream, bool readPayload, int payloadLength, bool readNetworkedVar) { if (networkedPrefabId >= netManager.NetworkConfig.NetworkedPrefabs.Count || networkedPrefabId < 0) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("Cannot spawn the object, invalid prefabIndex: " + networkedPrefabId); } return(null); } //Delayed spawning if (sceneDelayedSpawn && sceneSpawnedInIndex != NetworkSceneManager.CurrentActiveSceneIndex) { GameObject prefab = netManager.NetworkConfig.NetworkedPrefabs[networkedPrefabId].prefab; bool prefabActive = prefab.activeSelf; prefab.SetActive(false); GameObject go = (position == null && rotation == null) ? MonoBehaviour.Instantiate(prefab) : MonoBehaviour.Instantiate(prefab, position.GetValueOrDefault(Vector3.zero), rotation.GetValueOrDefault(Quaternion.identity)); prefab.SetActive(prefabActive); //Appearantly some wierd behavior when switching scenes can occur that destroys this object even though the scene is //not destroyed, therefor we set it to DontDestroyOnLoad here, to prevent that problem. MonoBehaviour.DontDestroyOnLoad(go); NetworkedObject netObject = go.GetComponent <NetworkedObject>(); if (netObject == null) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("Please add a NetworkedObject component to the root of all spawnable objects"); } netObject = go.AddComponent <NetworkedObject>(); } netObject.NetworkedPrefabName = netManager.NetworkConfig.NetworkedPrefabs[networkedPrefabId].name; netObject.isSpawned = false; netObject.isPooledObject = false; if (netManager.isServer) { netObject.NetworkId = GetNetworkObjectId(); } else { netObject.NetworkId = networkId; } netObject.destroyWithScene = destroyWithScene; netObject.OwnerClientId = owner; netObject.isPlayerObject = playerObject; netObject.SceneDelayedSpawn = sceneDelayedSpawn; netObject.sceneSpawnedInIndex = sceneSpawnedInIndex; Dictionary <ushort, List <INetworkedVar> > dummyNetworkedVars = new Dictionary <ushort, List <INetworkedVar> >(); List <NetworkedBehaviour> networkedBehaviours = new List <NetworkedBehaviour>(netObject.GetComponentsInChildren <NetworkedBehaviour>()); for (ushort i = 0; i < networkedBehaviours.Count; i++) { dummyNetworkedVars.Add(i, networkedBehaviours[i].GetDummyNetworkedVars()); } PendingSpawnObject pso = new PendingSpawnObject() { netObject = netObject, dummyNetworkedVars = dummyNetworkedVars, sceneSpawnedInIndex = sceneSpawnedInIndex, playerObject = playerObject, owner = owner, isActive = isActive, payload = null }; PendingSpawnObjects.Add(netObject.NetworkId, pso); pso.SetNetworkedVarData(stream); if (readPayload) { MLAPI.Serialization.BitStream payloadStream = new MLAPI.Serialization.BitStream(); payloadStream.CopyUnreadFrom(stream, payloadLength); stream.Position += payloadLength; pso.payload = payloadStream; } return(netObject); } //Normal spawning { GameObject prefab = netManager.NetworkConfig.NetworkedPrefabs[networkedPrefabId].prefab; GameObject go = (position == null && rotation == null) ? MonoBehaviour.Instantiate(prefab) : MonoBehaviour.Instantiate(prefab, position.GetValueOrDefault(Vector3.zero), rotation.GetValueOrDefault(Quaternion.identity)); NetworkedObject netObject = go.GetComponent <NetworkedObject>(); if (netObject == null) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("Please add a NetworkedObject component to the root of all spawnable objects"); } netObject = go.AddComponent <NetworkedObject>(); } if (readNetworkedVar) { netObject.SetNetworkedVarData(stream); } netObject.NetworkedPrefabName = netManager.NetworkConfig.NetworkedPrefabs[networkedPrefabId].name; netObject.isSpawned = true; netObject.isPooledObject = false; if (netManager.isServer) { netObject.NetworkId = GetNetworkObjectId(); } else { netObject.NetworkId = networkId; } netObject.destroyWithScene = destroyWithScene; netObject.OwnerClientId = owner; netObject.isPlayerObject = playerObject; netObject.SceneDelayedSpawn = sceneDelayedSpawn; netObject.sceneSpawnedInIndex = sceneSpawnedInIndex; SpawnedObjects.Add(netObject.NetworkId, netObject); SpawnedObjectsList.Add(netObject); if (playerObject) { NetworkingManager.singleton.ConnectedClients[owner].PlayerObject = netObject; } if (readPayload) { using (PooledBitStream payloadStream = PooledBitStream.Get()) { payloadStream.CopyUnreadFrom(stream, payloadLength); stream.Position += payloadLength; netObject.InvokeBehaviourNetworkSpawn(payloadStream); } } else { netObject.InvokeBehaviourNetworkSpawn(null); } netObject.gameObject.SetActive(isActive); return(netObject); } }
/// <summary> /// Sets the NetworkConfig data with that from a base64 encoded version /// </summary> /// <param name="base64">The base64 encoded version</param> /// <param name="createDummyObject">Wheter or not to create dummy objects for NetworkedPrefabs</param> public void FromBase64(string base64, bool createDummyObject = false) { NetworkConfig config = this; byte[] binary = Convert.FromBase64String(base64); using (BitStream stream = new BitStream(binary)) { using (PooledBitReader reader = PooledBitReader.Get(stream)) { config.ProtocolVersion = reader.ReadUInt16Packed(); config.Transport = (DefaultTransport)reader.ReadBits(5); ushort channelCount = reader.ReadUInt16Packed(); config.Channels.Clear(); for (int i = 0; i < channelCount; i++) { Channel channel = new Channel() { Name = reader.ReadString().ToString(), Type = (ChannelType)reader.ReadBits(5) }; config.Channels.Add(channel); } ushort sceneCount = reader.ReadUInt16Packed(); config.RegisteredScenes.Clear(); for (int i = 0; i < sceneCount; i++) { config.RegisteredScenes.Add(reader.ReadString().ToString()); } ushort networkedPrefabsCount = reader.ReadUInt16Packed(); config.NetworkedPrefabs.Clear(); GameObject root = createDummyObject ? new GameObject("MLAPI: Dummy prefabs") : null; for (int i = 0; i < networkedPrefabsCount; i++) { bool playerPrefab = reader.ReadBool(); string prefabName = reader.ReadString().ToString(); GameObject dummyPrefab = createDummyObject ? new GameObject("REPLACEME: " + prefabName + "(Dummy prefab)", typeof(NetworkedObject)) : null; if (dummyPrefab != null) { dummyPrefab.GetComponent <NetworkedObject>().NetworkedPrefabName = prefabName; dummyPrefab.transform.SetParent(root.transform); //This is just here to not ruin your hierarchy } NetworkedPrefab networkedPrefab = new NetworkedPrefab() { playerPrefab = playerPrefab, prefab = dummyPrefab }; config.NetworkedPrefabs.Add(networkedPrefab); } config.MessageBufferSize = reader.ReadInt32Packed(); config.ReceiveTickrate = reader.ReadInt32Packed(); config.MaxReceiveEventsPerTickRate = reader.ReadInt32Packed(); config.SendTickrate = reader.ReadInt32Packed(); config.EventTickrate = reader.ReadInt32Packed(); config.MaxConnections = reader.ReadInt32Packed(); config.ConnectPort = reader.ReadInt32Packed(); config.ConnectAddress = reader.ReadString().ToString(); config.ClientConnectionBufferTimeout = reader.ReadInt32Packed(); config.ConnectionApproval = reader.ReadBool(); config.SecondsHistory = reader.ReadInt32Packed(); config.HandleObjectSpawning = reader.ReadBool(); config.EnableEncryption = reader.ReadBool(); config.SignKeyExchange = reader.ReadBool(); config.EnableSceneSwitching = reader.ReadBool(); config.EnableTimeResync = reader.ReadBool(); config.AttributeMessageMode = (AttributeMessageMode)reader.ReadBits(3); } } }