Esempio n. 1
0
        /// <summary>
        /// Gets a SHA256 hash of parts of the NetworkingConfiguration instance
        /// </summary>
        /// <param name="cache"></param>
        /// <returns></returns>
        public byte[] GetConfig(bool cache = true)
        {
            if (ConfigHash != null && cache)
            {
                return(ConfigHash);
            }

            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUShort(ProtocolVersion);
                for (int i = 0; i < Channels.Count; i++)
                {
                    writer.WriteString(Channels[i].Name);
                    writer.WriteByte((byte)Channels[i].Type);
                    if (EnableEncryption)
                    {
                        writer.WriteBool(Channels[i].Encrypted);
                    }
                }
                for (int i = 0; i < MessageTypes.Count; i++)
                {
                    writer.WriteString(MessageTypes[i].Name);
                    if (AllowPassthroughMessages)
                    {
                        writer.WriteBool(MessageTypes[i].Passthrough);
                    }
                }
                if (EnableSceneSwitching)
                {
                    for (int i = 0; i < RegisteredScenes.Count; i++)
                    {
                        writer.WriteString(RegisteredScenes[i]);
                    }
                }
                if (HandleObjectSpawning)
                {
                    for (int i = 0; i < NetworkedPrefabs.Count; i++)
                    {
                        writer.WriteString(NetworkedPrefabs[i].name);
                    }
                }
                writer.WriteBool(HandleObjectSpawning);
                writer.WriteBool(EnableEncryption);
                writer.WriteBool(AllowPassthroughMessages);
                writer.WriteBool(EnableSceneSwitching);
                writer.WriteBool(SignKeyExchange);

                //using (SHA256Managed sha256 = new SHA256Managed())
                //{
                // Returns a 160 bit / 20 byte / 5 int checksum of the config
                if (cache)
                {
                    ConfigHash = MessageDigest.SHA1_Opt(writer.Finalize()).ToArray();     //sha256.ComputeHash(writer.Finalize());
                    return(ConfigHash);
                }
                return(MessageDigest.SHA1_Opt(writer.Finalize()).ToArray());    //sha256.ComputeHash(writer.Finalize());
                //}
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Gets a SHA256 hash of parts of the NetworkingConfiguration instance
        /// </summary>
        /// <param name="cache"></param>
        /// <returns></returns>
        public ulong GetConfig(bool cache = true)
        {
            if (ConfigHash != null && cache)
            {
                return(ConfigHash.Value);
            }

            using (BitWriter writer = BitWriter.Get())
            {
                writer.WriteUShort(ProtocolVersion);
                for (int i = 0; i < Channels.Count; i++)
                {
                    writer.WriteString(Channels[i].Name);
                    writer.WriteByte((byte)Channels[i].Type);
                    if (EnableEncryption)
                    {
                        writer.WriteBool(Channels[i].Encrypted);
                    }
                }
                for (int i = 0; i < MessageTypes.Count; i++)
                {
                    writer.WriteString(MessageTypes[i].Name);
                    if (AllowPassthroughMessages)
                    {
                        writer.WriteBool(MessageTypes[i].Passthrough);
                    }
                }
                if (EnableSceneSwitching)
                {
                    for (int i = 0; i < RegisteredScenes.Count; i++)
                    {
                        writer.WriteString(RegisteredScenes[i]);
                    }
                }
                if (HandleObjectSpawning)
                {
                    for (int i = 0; i < NetworkedPrefabs.Count; i++)
                    {
                        writer.WriteString(NetworkedPrefabs[i].name);
                    }
                }
                writer.WriteBool(HandleObjectSpawning);
                writer.WriteBool(EnableEncryption);
                writer.WriteBool(AllowPassthroughMessages);
                writer.WriteBool(EnableSceneSwitching);
                writer.WriteBool(SignKeyExchange);
                writer.WriteBits((byte)AttributeMessageMode, 3);

                // Returns a 160 bit / 20 byte / 5 int checksum of the config
                if (cache)
                {
                    ConfigHash = writer.Finalize().GetStableHash64();
                    return(ConfigHash.Value);
                }
                return(writer.Finalize().GetStableHash64());
            }
        }
        /// <summary>
        /// Switches to a scene with a given name. Can only be called from Server
        /// </summary>
        /// <param name="sceneName">The name of the scene to switch to</param>
        public static void SwitchScene(string sceneName)
        {
            if (!NetworkingManager.singleton.NetworkConfig.EnableSceneSwitching)
            {
                Debug.LogWarning("MLAPI: Scene switching is not enabled");
                return;
            }
            else if (isSwitching)
            {
                Debug.LogWarning("MLAPI: Scene switch already in progress");
                return;
            }
            else if (!registeredSceneNames.Contains(sceneName))
            {
                Debug.LogWarning("MLAPI: The scene " + sceneName + " is not registered as a switchable scene.");
                return;
            }
            SpawnManager.DestroySceneObjects(); //Destroy current scene objects before switching.
            CurrentSceneIndex = sceneNameToIndex[sceneName];
            isSwitching       = true;
            lastScene         = SceneManager.GetActiveScene();
            AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);

            sceneLoad.completed += OnSceneLoaded;

            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUInt(sceneNameToIndex[sceneName]);

                InternalMessageHandler.Send("MLAPI_SWITCH_SCENE", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
        }
        internal static void PassthroughSend(uint targetId, uint sourceId, ushort messageType, int channelId, BitReader reader, uint?networkId = null, ushort?orderId = null)
        {
            if (netManager.isHost && targetId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
            {
                //Host trying to send data to it's own client
                return;
            }

            using (BitWriter writer = BitWriter.Get())
            {
                writer.WriteGenericMessageHeader(messageType, networkId != null, networkId.GetValueOrDefault(), orderId.GetValueOrDefault(), true, null, sourceId);

#if !DISABLE_CRYPTOGRAPHY
                if (netManager.NetworkConfig.EncryptedChannelsHashSet.Contains(MessageManager.reverseChannels[channelId]))
                {
                    writer.WriteByteArray(CryptographyHelper.Encrypt(reader.ReadByteArray(), netManager.ConnectedClients[targetId].AesKey));
                }
                else
#endif
                writer.WriteByteArray(reader.ReadByteArray());

                writer.Finalize(ref FinalMessageBuffer);

                netManager.NetworkConfig.NetworkTransport.QueueMessageForSending(targetId, ref FinalMessageBuffer, (int)writer.GetFinalizeSize(), channelId, false, out byte error);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Returns a base64 encoded version of the config
        /// </summary>
        /// <returns></returns>
        public string ToBase64()
        {
            NetworkConfig config = this;

            using (BitWriter writer = BitWriter.Get())
            {
                writer.WriteUShort(config.ProtocolVersion);
                writer.WriteBits((byte)config.Transport, 5);

                writer.WriteUShort((ushort)config.Channels.Count);
                for (int i = 0; i < config.Channels.Count; i++)
                {
                    writer.WriteString(config.Channels[i].Name);
                    writer.WriteBool(config.Channels[i].Encrypted);
                    writer.WriteBits((byte)config.Channels[i].Type, 5);
                }

                writer.WriteUShort((ushort)config.MessageTypes.Count);
                for (int i = 0; i < config.MessageTypes.Count; i++)
                {
                    writer.WriteString(config.MessageTypes[i].Name);
                    writer.WriteBool(config.MessageTypes[i].Passthrough);
                }

                writer.WriteUShort((ushort)config.RegisteredScenes.Count);
                for (int i = 0; i < config.RegisteredScenes.Count; i++)
                {
                    writer.WriteString(config.RegisteredScenes[i]);
                }

                writer.WriteUShort((ushort)config.NetworkedPrefabs.Count);
                for (int i = 0; i < config.NetworkedPrefabs.Count; i++)
                {
                    writer.WriteBool(config.NetworkedPrefabs[i].playerPrefab);
                    writer.WriteString(config.NetworkedPrefabs[i].name);
                }

                writer.WriteInt(config.MessageBufferSize);
                writer.WriteInt(config.ReceiveTickrate);
                writer.WriteInt(config.MaxReceiveEventsPerTickRate);
                writer.WriteInt(config.SendTickrate);
                writer.WriteInt(config.EventTickrate);
                writer.WriteInt(config.MaxConnections);
                writer.WriteInt(config.ConnectPort);
                writer.WriteString(config.ConnectAddress);
                writer.WriteInt(config.ClientConnectionBufferTimeout);
                writer.WriteBool(config.ConnectionApproval);
                writer.WriteInt(config.SecondsHistory);
                writer.WriteBool(config.HandleObjectSpawning);
                writer.WriteBool(config.EnableEncryption);
                writer.WriteBool(config.SignKeyExchange);
                writer.WriteBool(config.AllowPassthroughMessages);
                writer.WriteBool(config.EnableSceneSwitching);
                writer.WriteBool(config.EnableTimeResync);
                writer.WriteBits((byte)config.AttributeMessageMode, 3);

                return(Convert.ToBase64String(writer.Finalize()));
            }
        }
Esempio n. 6
0
 public byte[] GetPublicKey()
 {
     using (BitWriter writer = new BitWriter())
     {
         writer.WriteByteArray(pub.X.ToByteArray());
         writer.WriteByteArray(pub.Y.ToByteArray(), true);
         return(writer.Finalize());
     }
 }
Esempio n. 7
0
        //RETURNS THE CLIENTIDS WHICH WAS NOT BEING OBSERVED
        internal static ref List <uint> Send(string messageType, string channelName, BitWriter messageWriter, uint clientIdToIgnore, uint?fromNetId, uint?networkId = null, ushort?orderId = null)
        {
            failedObservers.Clear();
            if (netManager.NetworkConfig.EncryptedChannels.Contains(channelName))
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Cannot send messages over encrypted channel to multiple clients");
                }
                return(ref failedObservers);
            }

            using (BitWriter writer = BitWriter.Get())
            {
                writer.WriteGenericMessageHeader(MessageManager.messageTypes[messageType], networkId != null, networkId.GetValueOrDefault(), orderId.GetValueOrDefault(), false, 0, 0);

                writer.WriteWriter(messageWriter);

                int channel = MessageManager.channels[channelName];
                foreach (KeyValuePair <uint, NetworkedClient> pair in netManager.connectedClients)
                {
                    if (pair.Key == clientIdToIgnore)
                    {
                        continue;
                    }

                    uint targetClientId = pair.Key;
                    if (netManager.isHost && targetClientId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
                    {
                        //Don't invoke the message on our own machine. Instant stack overflow.
                        continue;
                    }
                    else if (targetClientId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
                    {
                        //Client trying to send data to host
                        targetClientId = netManager.NetworkConfig.NetworkTransport.ServerNetId;
                    }

                    //If we respect the observers, and the message is targeted (networkId != null) and the targetedNetworkId isnt observing the receiver. Then we continue
                    if (netManager.isServer && fromNetId != null && !SpawnManager.spawnedObjects[fromNetId.Value].observers.Contains(pair.Key))
                    {
                        failedObservers.Add(pair.Key);
                        continue;
                    }

                    writer.Finalize(ref FinalMessageBuffer);

                    NetworkProfiler.StartEvent(TickType.Send, (uint)messageWriter.GetFinalizeSize(), channelName, messageType);
                    byte error;
                    int  byteCount = (int)writer.GetFinalizeSize();
                    NetworkProfiler.addBytesSent((uint)byteCount);
                    netManager.NetworkConfig.NetworkTransport.QueueMessageForSending(targetClientId, ref FinalMessageBuffer, byteCount, channel, false, out error);
                    NetworkProfiler.EndEvent();
                }
                return(ref failedObservers);
            }
        }
        internal static void Send(List <uint> clientIds, string messageType, string channelName, byte[] data, uint?fromNetId, 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;
            }

            using (BitWriter writer = new BitWriter())
            {
                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++)
                {
                    uint targetClientId = clientIds[i];
                    if (netManager.isHost && targetClientId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
                    {
                        //Don't invoke the message on our own machine. Instant stack overflow.
                        continue;
                    }
                    else if (targetClientId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
                    {
                        //Client trying to send data to host
                        targetClientId = netManager.NetworkConfig.NetworkTransport.ServerNetId;
                    }

                    //If we respect the observers, and the message is targeted (networkId != null) and the targetedNetworkId isnt observing the receiver. Then we continue
                    if (netManager.isServer && fromNetId != null && !SpawnManager.spawnedObjects[fromNetId.Value].observers.Contains(clientIds[i]))
                    {
                        continue;
                    }

                    writer.Finalize(ref FinalMessageBuffer);

                    byte error;
                    netManager.NetworkConfig.NetworkTransport.QueueMessageForSending(targetClientId, ref FinalMessageBuffer, (int)writer.GetFinalizeSize(), channel, false, out error);
                }
            }
        }
Esempio n. 9
0
        internal string ToBase64()
        {
            using (BitWriter writer = BitWriter.Get())
            {
                writer.WriteUShort(ProtocolVersion);
                writer.WriteBits((byte)Transport, 5);

                writer.WriteUShort((ushort)Channels.Count);
                for (int i = 0; i < Channels.Count; i++)
                {
                    writer.WriteString(Channels[i].Name);
                    writer.WriteBool(Channels[i].Encrypted);
                    writer.WriteBits((byte)Channels[i].Type, 5);
                }

                writer.WriteUShort((ushort)MessageTypes.Count);
                for (int i = 0; i < MessageTypes.Count; i++)
                {
                    writer.WriteString(MessageTypes[i].Name);
                    writer.WriteBool(MessageTypes[i].Passthrough);
                }

                writer.WriteUShort((ushort)RegisteredScenes.Count);
                for (int i = 0; i < RegisteredScenes.Count; i++)
                {
                    writer.WriteString(RegisteredScenes[i]);
                }

                writer.WriteUShort((ushort)NetworkedPrefabs.Count);
                for (int i = 0; i < NetworkedPrefabs.Count; i++)
                {
                    writer.WriteBool(NetworkedPrefabs[i].playerPrefab);
                    writer.WriteString(NetworkedPrefabs[i].name);
                }

                writer.WriteInt(MessageBufferSize);
                writer.WriteInt(ReceiveTickrate);
                writer.WriteInt(MaxReceiveEventsPerTickRate);
                writer.WriteInt(SendTickrate);
                writer.WriteInt(EventTickrate);
                writer.WriteInt(MaxConnections);
                writer.WriteInt(ConnectPort);
                writer.WriteString(ConnectAddress);
                writer.WriteInt(ClientConnectionBufferTimeout);
                writer.WriteBool(ConnectionApproval);
                writer.WriteInt(SecondsHistory);
                writer.WriteBool(HandleObjectSpawning);
                writer.WriteBool(EnableEncryption);
                writer.WriteBool(SignKeyExchange);
                writer.WriteBool(AllowPassthroughMessages);
                writer.WriteBool(EnableSceneSwitching);
                writer.WriteBool(EnableTimeResync);
                writer.WriteBits((byte)AttributeMessageMode, 3);

                return(Convert.ToBase64String(writer.Finalize()));
            }
        }
Esempio n. 10
0
        internal static void SpawnPrefabIndexServer(NetworkedObject netObject, uint?clientOwnerId = null)
        {
            if (netObject.isSpawned)
            {
                Debug.LogWarning("MLAPI: Object already spawned");
                return;
            }
            else if (!netManager.isServer)
            {
                Debug.LogWarning("MLAPI: Only server can spawn objects");
                return;
            }
            else if (!netManager.NetworkConfig.NetworkPrefabIds.ContainsKey(netObject.NetworkedPrefabName))
            {
                Debug.LogWarning("MLAPI: The prefab name " + netObject.NetworkedPrefabName + " does not exist as a networkedPrefab");
                return;
            }
            else if (!netManager.NetworkConfig.HandleObjectSpawning)
            {
                Debug.LogWarning("MLAPI: NetworkConfig is set to not handle object spawning");
                return;
            }
            uint netId = GetNetworkObjectId();

            netObject.networkId = netId;
            spawnedObjects.Add(netId, netObject);
            netObject._isSpawned  = true;
            netObject.sceneObject = false;
            netObject.InvokeBehaviourNetworkSpawn();
            if (clientOwnerId != null)
            {
                netObject.ownerClientId = clientOwnerId.Value;
                NetworkingManager.singleton.connectedClients[clientOwnerId.Value].OwnedObjects.Add(netObject);
            }
            using (BitWriter writer = new BitWriter())
            {
                writer.WriteBool(false);
                writer.WriteUInt(netObject.NetworkId);
                writer.WriteUInt(netObject.OwnerClientId);
                writer.WriteInt(netManager.NetworkConfig.NetworkPrefabIds[netObject.NetworkedPrefabName]);
                writer.WriteBool(netObject.sceneObject == null ? true : netObject.sceneObject.Value);

                writer.WriteFloat(netObject.transform.position.x);
                writer.WriteFloat(netObject.transform.position.y);
                writer.WriteFloat(netObject.transform.position.z);

                writer.WriteFloat(netObject.transform.rotation.eulerAngles.x);
                writer.WriteFloat(netObject.transform.rotation.eulerAngles.y);
                writer.WriteFloat(netObject.transform.rotation.eulerAngles.z);


                InternalMessageHandler.Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
        }
Esempio n. 11
0
        public void TestWritingTrue()
        {
            BitWriter bitWriter = BitWriter.Get();

            bitWriter.WriteBool(true);

            byte[] result = bitWriter.Finalize();

            Assert.That(result.Length, Is.EqualTo(1));
            Assert.That(result[0], Is.EqualTo(1));
        }
Esempio n. 12
0
        internal static void RemoveOwnership(uint netId)
        {
            NetworkedObject netObject = SpawnManager.spawnedObjects[netId];

            NetworkingManager.singleton.connectedClients[netObject.OwnerClientId].OwnedObjects.RemoveAll(x => x.NetworkId == netId);
            netObject.ownerClientId = NetworkingManager.singleton.NetworkConfig.NetworkTransport.InvalidDummyId;

            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUInt(netId);
                writer.WriteUInt(netObject.ownerClientId);

                InternalMessageHandler.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
        }
Esempio n. 13
0
        private static byte[] Compress(byte[] data, Compression method = Compression.int32)
        {
            int       size  = method == Compression.int16 ? 2 : method == Compression.int32 ? 4 : 8;
            int       count = (data.Length / size) + (data.Length % size == 0 ? 0 : 1);
            WriteFunc func  = size == 2 ? func16 : size == 4 ? func32 : func64;

            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUInt((uint)data.Length);
                for (int i = 0; i < count; ++i)
                {
                    func(writer, data, i);
                }
                return(writer.Finalize());
            }
        }
Esempio n. 14
0
        internal static void Send(uint[] clientIds, string messageType, string channelName, BitWriter messageWriter, uint?fromNetId, uint?networkId = null, ushort?orderId = null)
        {
            if (netManager.NetworkConfig.EncryptedChannelsHashSet.Contains(channelName))
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Cannot send messages over encrypted channel to multiple clients");
                }
                return;
            }

            using (BitWriter writer = BitWriter.Get())
            {
                writer.WriteGenericMessageHeader(MessageManager.messageTypes[messageType], networkId != null, networkId.GetValueOrDefault(), orderId.GetValueOrDefault(), false, 0, 0);

                writer.WriteWriter(messageWriter);

                int channel = MessageManager.channels[channelName];
                for (int i = 0; i < clientIds.Length; i++)
                {
                    uint targetClientId = clientIds[i];
                    if (netManager.isHost && targetClientId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
                    {
                        //Don't invoke the message on our own machine. Instant stack overflow.
                        continue;
                    }
                    else if (targetClientId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
                    {
                        //Client trying to send data to host
                        targetClientId = netManager.NetworkConfig.NetworkTransport.ServerNetId;
                    }

                    //If we respect the observers, and the message is targeted (networkId != null) and the targetedNetworkId isnt observing the receiver. Then we continue
                    if (netManager.isServer && fromNetId != null && !SpawnManager.spawnedObjects[fromNetId.Value].observers.Contains(clientIds[i]))
                    {
                        continue;
                    }

                    writer.Finalize(ref FinalMessageBuffer);

                    NetworkProfiler.StartEvent(TickType.Send, (uint)messageWriter.GetFinalizeSize(), channelName, messageType);
                    byte error;
                    netManager.NetworkConfig.NetworkTransport.QueueMessageForSending(targetClientId, ref FinalMessageBuffer, (int)writer.GetFinalizeSize(), channel, false, out error);
                    NetworkProfiler.EndEvent();
                }
            }
        }
        internal static void PassthroughSend(uint targetId, uint sourceId, ushort messageType, int channelId, byte[] data, uint?networkId = null, ushort?orderId = null)
        {
            if (netManager.isHost && targetId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
            {
                //Host trying to send data to it's own client
                Debug.LogWarning("MLAPI: Send method got message aimed at server from the server?");
                return;
            }

            using (BitWriter writer = new BitWriter())
            {
                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);
                }

                writer.Finalize(ref FinalMessageBuffer);

                byte error;
                netManager.NetworkConfig.NetworkTransport.QueueMessageForSending(targetId, ref FinalMessageBuffer, (int)writer.GetFinalizeSize(), channelId, false, out error);
            }
        }
Esempio n. 16
0
    private void OnGUI()
    {
        int y = 25;

        if (isServer && isLocalPlayer)
        {
            y += 25;
            if (GUI.Button(new Rect(200, y, 200, 20), "Change Text with SyncVar"))
            {
                MySyncedName = "SyncVarTest: " + Random.Range(50, 10000);
            }

            y += 25;
            if (GUI.Button(new Rect(200, y, 200, 20), "Spawn cube"))
            {
                GameObject go = Instantiate(cubePrefab);
                go.transform.position = transform.position + new Vector3(0, 3f, 0);
                go.GetComponent <NetworkedObject>().Spawn();
            }

            y += 25;
            if (GUI.Button(new Rect(200, y, 200, 20), "Spawn sphere"))
            {
                GameObject go = Instantiate(spherePrefab);
                go.transform.position = transform.position + new Vector3(0, 3f, 0);
                go.GetComponent <NetworkedObject>().Spawn();
            }

            y += 25;
            if (GUI.Button(new Rect(200, y, 200, 20), "Set random plane color"))
            {
                planeMaterial.color = Random.ColorHSV();
                using (BitWriter writer = new BitWriter())
                {
                    writer.WriteFloat(planeMaterial.color.r);
                    writer.WriteFloat(planeMaterial.color.g);
                    writer.WriteFloat(planeMaterial.color.b);
                    SendToClientsTarget("OnChangeColor", "ColorChannel", writer.Finalize());
                }
            }
        }
    }
Esempio n. 17
0
        internal static void FlushSceneObjects()
        {
            if (!NetworkingManager.singleton.isServer)
            {
                return;
            }

            List <NetworkedObject> sceneObjectsToSync = new List <NetworkedObject>();

            foreach (KeyValuePair <uint, NetworkedObject> pair in SpawnManager.spawnedObjects)
            {
                if (pair.Value.sceneObject == null || pair.Value.sceneObject == true)
                {
                    sceneObjectsToSync.Add(pair.Value);
                }
            }

            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUShort((ushort)sceneObjectsToSync.Count);
                for (int i = 0; i < sceneObjectsToSync.Count; i++)
                {
                    writer.WriteBool(false); //isLocalPlayer
                    writer.WriteUInt(sceneObjectsToSync[i].NetworkId);
                    writer.WriteUInt(sceneObjectsToSync[i].OwnerClientId);
                    writer.WriteInt(NetworkingManager.singleton.NetworkConfig.NetworkPrefabIds[sceneObjectsToSync[i].NetworkedPrefabName]);
                    writer.WriteBool(sceneObjectsToSync[i].sceneObject == null ? true : sceneObjectsToSync[i].sceneObject.Value);

                    writer.WriteFloat(sceneObjectsToSync[i].transform.position.x);
                    writer.WriteFloat(sceneObjectsToSync[i].transform.position.y);
                    writer.WriteFloat(sceneObjectsToSync[i].transform.position.z);

                    writer.WriteFloat(sceneObjectsToSync[i].transform.rotation.eulerAngles.x);
                    writer.WriteFloat(sceneObjectsToSync[i].transform.rotation.eulerAngles.y);
                    writer.WriteFloat(sceneObjectsToSync[i].transform.rotation.eulerAngles.z);
                }

                InternalMessageHandler.Send("MLAPI_ADD_OBJECTS", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
        }
        //RETURNS IF IT SUCCEDED OR FAILED BECAUSE OF NON-OBSERVER. ANY OTHER FAIL WILL RETURN TRUE
        internal static bool Send(uint clientId, string messageType, string channelName, byte[] data, uint?fromNetId, uint?networkId = null, ushort?orderId = null, bool skipQueue = false)
        {
            uint targetClientId = clientId;

            if (netManager.isHost && targetClientId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
            {
                //Don't invoke the message on our own machine. Instant stack overflow.
                Debug.LogWarning("MLAPI: Cannot send message to own client");
                return(true);
            }
            else if (targetClientId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
            {
                //Client trying to send data to host
                targetClientId = netManager.NetworkConfig.NetworkTransport.ServerNetId;
            }
            //If we respect the observers, and the message is targeted (networkId != null) and the targetedNetworkId isnt observing the receiver. Then we return
            if (netManager.isServer && fromNetId != null && !SpawnManager.spawnedObjects[fromNetId.Value].observers.Contains(clientId))
            {
                return(false);
            }

            bool isPassthrough = (!netManager.isServer && clientId != netManager.NetworkConfig.NetworkTransport.ServerNetId && 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(true);
            }

            using (BitWriter writer = new BitWriter())
            {
                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))
                {
                    //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.WriteByteArray(encrypted);
                }
                else
                {
                    writer.WriteByteArray(data);
                }

                if (isPassthrough)
                {
                    targetClientId = netManager.NetworkConfig.NetworkTransport.ServerNetId;
                }

                writer.Finalize(ref FinalMessageBuffer);

                byte error;
                if (skipQueue)
                {
                    netManager.NetworkConfig.NetworkTransport.QueueMessageForSending(targetClientId, ref FinalMessageBuffer, (int)writer.GetFinalizeSize(), MessageManager.channels[channelName], true, out error);
                }
                else
                {
                    netManager.NetworkConfig.NetworkTransport.QueueMessageForSending(targetClientId, ref FinalMessageBuffer, (int)writer.GetFinalizeSize(), MessageManager.channels[channelName], false, out error);
                }

                return(true);
            }
        }
        //RETURNS IF IT SUCCEDED OR FAILED BECAUSE OF NON-OBSERVER. ANY OTHER FAIL WILL RETURN TRUE
        internal static bool Send(uint clientId, string messageType, string channelName, BitWriter messageWriter, uint?fromNetId, uint?networkId = null, ushort?orderId = null, bool skipQueue = false)
        {
            uint targetClientId = clientId;

            if (netManager.isHost && targetClientId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
            {
                //Don't invoke the message on our own machine. Instant stack overflow.
                return(true);
            }
            else if (targetClientId == netManager.NetworkConfig.NetworkTransport.HostDummyId)
            {
                //Client trying to send data to host
                targetClientId = netManager.NetworkConfig.NetworkTransport.ServerNetId;
            }
            //If we respect the observers, and the message is targeted (networkId != null) and the targetedNetworkId isnt observing the receiver. Then we return
            if (netManager.isServer && fromNetId != null && !SpawnManager.spawnedObjects[fromNetId.Value].observers.Contains(clientId))
            {
                return(false);
            }

            bool isPassthrough = (!netManager.isServer && clientId != netManager.NetworkConfig.NetworkTransport.ServerNetId && netManager.NetworkConfig.AllowPassthroughMessages);

            if (isPassthrough && !netManager.NetworkConfig.PassthroughMessageHashSet.Contains(MessageManager.messageTypes[messageType]))
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("The The MessageType " + messageType + " is not registered as an allowed passthrough message type");
                }
                return(true);
            }

            using (BitWriter writer = BitWriter.Get())
            {
                writer.WriteGenericMessageHeader(MessageManager.messageTypes[messageType], networkId != null, networkId.GetValueOrDefault(), orderId.GetValueOrDefault(), isPassthrough, clientId, null);

#if !DISABLE_CRYPTOGRAPHY
                if (netManager.NetworkConfig.EncryptedChannelsHashSet.Contains(channelName))
                {
                    //This is an encrypted message.
                    byte[] encrypted;
                    if (netManager.isServer)
                    {
                        encrypted = CryptographyHelper.Encrypt(messageWriter.Finalize(), netManager.ConnectedClients[clientId].AesKey);
                    }
                    else
                    {
                        encrypted = CryptographyHelper.Encrypt(messageWriter.Finalize(), netManager.clientAesKey);
                    }

                    writer.WriteByteArray(encrypted);
                }
                else
#endif
                writer.WriteWriter(messageWriter);

                if (isPassthrough)
                {
                    targetClientId = netManager.NetworkConfig.NetworkTransport.ServerNetId;
                }

                writer.Finalize(ref FinalMessageBuffer);

                NetworkProfiler.StartEvent(TickType.Send, (uint)messageWriter.GetFinalizeSize(), channelName, messageType);
                byte error;
                if (skipQueue)
                {
                    netManager.NetworkConfig.NetworkTransport.QueueMessageForSending(targetClientId, ref FinalMessageBuffer, (int)writer.GetFinalizeSize(), MessageManager.channels[channelName], true, out error);
                }
                else
                {
                    netManager.NetworkConfig.NetworkTransport.QueueMessageForSending(targetClientId, ref FinalMessageBuffer, (int)writer.GetFinalizeSize(), MessageManager.channels[channelName], false, out error);
                }
                NetworkProfiler.EndEvent();

                return(true);
            }
        }
Esempio n. 20
0
        /// <summary>
        /// Destroys a NetworkedObject if it's part of a pool. Use this instead of the MonoBehaviour Destroy method. Can only be called from Server.
        /// </summary>
        /// <param name="netObject">The NetworkedObject instance to destroy</param>
        public static void DestroyPoolObject(NetworkedObject netObject)
        {
            if (!NetworkingManager.singleton.isServer)
            {
                Debug.LogWarning("MLAPI: Objects can only be destroyed on the server");
                return;
            }
            netObject.gameObject.SetActive(false);
            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUInt(netObject.NetworkId);

                InternalMessageHandler.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
        }
Esempio n. 21
0
        /// <summary>
        /// Spawns a object from the pool at a given position and rotation. Can only be called from server.
        /// </summary>
        /// <param name="poolName">The name of the pool</param>
        /// <param name="position">The position to spawn the object at</param>
        /// <param name="rotation">The rotation to spawn the object at</param>
        /// <returns></returns>
        public static GameObject SpawnPoolObject(string poolName, Vector3 position, Quaternion rotation)
        {
            if (!NetworkingManager.singleton.isServer)
            {
                Debug.LogWarning("MLAPI: Object spawning can only occur on server");
                return(null);
            }
            GameObject go = Pools[PoolNamesToIndexes[poolName]].SpawnObject(position, rotation);

            using (BitWriter writer = new BitWriter())
            {
                writer.WriteUInt(go.GetComponent <NetworkedObject>().NetworkId);

                writer.WriteFloat(position.x);
                writer.WriteFloat(position.y);
                writer.WriteFloat(position.z);

                writer.WriteFloat(rotation.eulerAngles.x);
                writer.WriteFloat(rotation.eulerAngles.y);
                writer.WriteFloat(rotation.eulerAngles.z);

                InternalMessageHandler.Send("MLAPI_SPAWN_POOL_OBJECT", "MLAPI_INTERNAL", writer.Finalize(), null);
            }
            return(go);
        }
Esempio n. 22
0
        internal void RebuildObservers(uint?clientId = null)
        {
            bool initial = clientId != null;

            if (initial)
            {
                bool shouldBeAdded = true;
                for (int i = 0; i < childNetworkedBehaviours.Count; i++)
                {
                    bool state = childNetworkedBehaviours[i].OnCheckObserver(clientId.Value);
                    if (state == false)
                    {
                        shouldBeAdded = false;
                        break;
                    }
                }
                if (shouldBeAdded)
                {
                    observers.Add(clientId.Value);
                }
            }
            else
            {
                HashSet <uint> previousObservers = new HashSet <uint>(observers);
                HashSet <uint> newObservers      = new HashSet <uint>();
                bool           update            = false;
                for (int i = 0; i < childNetworkedBehaviours.Count; i++)
                {
                    bool changed = childNetworkedBehaviours[i].OnRebuildObservers(newObservers);
                    if (changed)
                    {
                        observers = newObservers;
                        update    = true;
                        break;
                    }
                }
                if (update)
                {
                    foreach (KeyValuePair <uint, NetworkedClient> pair in NetworkingManager.singleton.connectedClients)
                    {
                        if (pair.Key == NetworkingManager.singleton.NetworkConfig.NetworkTransport.HostDummyId)
                        {
                            continue;
                        }
                        if ((previousObservers.Contains(pair.Key) && !newObservers.Contains(pair.Key)) ||
                            (!previousObservers.Contains(pair.Key) && newObservers.Contains(pair.Key)))
                        {
                            //Something changed for this client.
                            using (BitWriter writer = new BitWriter())
                            {
                                writer.WriteUInt(networkId);
                                writer.WriteBool(observers.Contains(pair.Key));

                                InternalMessageHandler.Send(pair.Key, "MLAPI_SET_VISIBILITY", "MLAPI_INTERNAL", writer.Finalize(), null);
                            }
                            FlushToClient(pair.Key);
                        }
                    }
                }
            }
        }
Esempio n. 23
0
        internal static void SpawnObject(NetworkedObject netObject, uint?clientOwnerId = null, BitWriter payload = null)
        {
            if (netObject.isSpawned)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Object already spawned");
                }
                return;
            }
            else if (!netManager.isServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Only server can spawn objects");
                }
                return;
            }
            else if (!netManager.NetworkConfig.NetworkPrefabIds.ContainsKey(netObject.NetworkedPrefabName))
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("The prefab name " + netObject.NetworkedPrefabName + " does not exist as a networkedPrefab");
                }
                return;
            }
            else if (!netManager.NetworkConfig.HandleObjectSpawning)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("NetworkConfig is set to not handle object spawning");
                }
                return;
            }
            uint netId = GetNetworkObjectId();

            netObject.networkId = netId;
            spawnedObjects.Add(netId, netObject);
            netObject._isSpawned  = true;
            netObject.sceneObject = false;

            if (clientOwnerId != null)
            {
                netObject.ownerClientId = clientOwnerId.Value;
                NetworkingManager.singleton.connectedClients[clientOwnerId.Value].OwnedObjects.Add(netObject);
            }

            if (payload == null)
            {
                netObject.InvokeBehaviourNetworkSpawn(null);
            }
            else
            {
                using (BitReader payloadReader = BitReader.Get(payload.Finalize())) netObject.InvokeBehaviourNetworkSpawn(payloadReader);
            }

            foreach (var client in netManager.connectedClients)
            {
                netObject.RebuildObservers(client.Key);
                using (BitWriter writer = BitWriter.Get())
                {
                    writer.WriteBool(false);
                    writer.WriteUInt(netObject.NetworkId);
                    writer.WriteUInt(netObject.OwnerClientId);
                    writer.WriteInt(netManager.NetworkConfig.NetworkPrefabIds[netObject.NetworkedPrefabName]);
                    writer.WriteBool(netObject.sceneObject == null ? true : netObject.sceneObject.Value);
                    writer.WriteBool(netObject.observers.Contains(client.Key));

                    writer.WriteFloat(netObject.transform.position.x);
                    writer.WriteFloat(netObject.transform.position.y);
                    writer.WriteFloat(netObject.transform.position.z);

                    writer.WriteFloat(netObject.transform.rotation.eulerAngles.x);
                    writer.WriteFloat(netObject.transform.rotation.eulerAngles.y);
                    writer.WriteFloat(netObject.transform.rotation.eulerAngles.z);

                    writer.WriteBool(payload != null);

                    if (netObject.observers.Contains(client.Key))
                    {
                        netObject.WriteFormattedSyncedVarData(writer);
                    }

                    if (payload != null)
                    {
                        writer.WriteWriter(payload);
                    }

                    InternalMessageHandler.Send(client.Key, "MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", writer, null);
                }
            }
        }
Esempio n. 24
0
        internal static void OnDestroyObject(uint networkId, bool destroyGameObject)
        {
            if (!spawnedObjects.ContainsKey(networkId) || (netManager != null && !netManager.NetworkConfig.HandleObjectSpawning))
            {
                return;
            }
            if (spawnedObjects[networkId].OwnerClientId != NetworkingManager.singleton.NetworkConfig.NetworkTransport.InvalidDummyId && !spawnedObjects[networkId].isPlayerObject)
            {
                //Someone owns it.
                NetworkingManager.singleton.connectedClients[spawnedObjects[networkId].OwnerClientId].OwnedObjects.RemoveAll(x => x.NetworkId == networkId);
            }
            GameObject go = spawnedObjects[networkId].gameObject;

            if (netManager != null && netManager.isServer)
            {
                releasedNetworkObjectIds.Push(networkId);
                if (spawnedObjects[networkId] != null)
                {
                    using (BitWriter writer = new BitWriter())
                    {
                        writer.WriteUInt(networkId);

                        InternalMessageHandler.Send("MLAPI_DESTROY_OBJECT", "MLAPI_INTERNAL", writer.Finalize(), null);
                    }
                }
            }
            if (destroyGameObject && go != null)
            {
                MonoBehaviour.Destroy(go);
            }
            spawnedObjects.Remove(networkId);
        }