Ejemplo n.º 1
0
        /*
         * internal static void FlushSceneObjects()
         * {
         *  if (!NetworkingManager.singleton.isServer)
         *      return;
         *
         *  //This loop is bad. For each client, we loop over every object twice.
         *  foreach (KeyValuePair<uint, NetworkedClient> client in netManager.connectedClients)
         *  {
         *      int sceneObjects = 0;
         *      foreach (var netObject in SpawnManager.spawnedObjects)
         *          if (netObject.Value.sceneObject == null || netObject.Value.sceneObject == true)
         *              sceneObjects++;
         *
         *      using (BitWriter writer = BitWriter.Get())
         *      {
         *          writer.WriteUShort((ushort)sceneObjects);
         *          foreach (var netObject in SpawnManager.spawnedObjects)
         *          {
         *              if (netObject.Value.sceneObject == null || netObject.Value.sceneObject == true)
         *              {
         *                  writer.WriteBool(false); //isLocalPlayer
         *                  writer.WriteUInt(netObject.Value.NetworkId);
         *                  writer.WriteUInt(netObject.Value.OwnerClientId);
         *                  writer.WriteInt(NetworkingManager.singleton.NetworkConfig.NetworkPrefabIds[netObject.Value.NetworkedPrefabName]);
         *                  writer.WriteBool(netObject.Value.sceneObject == null ? true : netObject.Value.sceneObject.Value);
         *                  writer.WriteBool(netObject.Value.observers.Contains(client.Key));
         *
         *                  writer.WriteFloat(netObject.Value.transform.position.x);
         *                  writer.WriteFloat(netObject.Value.transform.position.y);
         *                  writer.WriteFloat(netObject.Value.transform.position.z);
         *
         *                  writer.WriteFloat(netObject.Value.transform.rotation.eulerAngles.x);
         *                  writer.WriteFloat(netObject.Value.transform.rotation.eulerAngles.y);
         *                  writer.WriteFloat(netObject.Value.transform.rotation.eulerAngles.z);
         *
         *                  if (netObject.Value.observers.Contains(client.Key))
         *                      netObject.Value.WriteFormattedSyncedVarData(writer);
         *              }
         *          }
         *          InternalMessageHandler.Send(client.Key, "MLAPI_ADD_OBJECTS", "MLAPI_INTERNAL", writer, null);
         *      }
         *  }
         * }
         */

        internal static NetworkedObject CreateSpawnedObject(int networkedPrefabId, uint networkId, uint owner, bool playerObject, Vector3 position, Quaternion rotation, BitReader reader, bool readSyncedVar, bool readPayload)
        {
            if (!netManager.NetworkConfig.NetworkPrefabNames.ContainsKey(networkedPrefabId))
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Cannot spawn the object, invalid prefabIndex");
                }
                return(null);
            }

            GameObject      go        = MonoBehaviour.Instantiate(netManager.NetworkConfig.NetworkedPrefabs[networkedPrefabId].prefab, position, rotation);
            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 (readSyncedVar)
            {
                netObject.SetFormattedSyncedVarData(reader);
            }

            netObject.NetworkedPrefabName = netManager.NetworkConfig.NetworkPrefabNames[networkedPrefabId];
            netObject.isSpawned           = true;
            netObject.isPooledObject      = false;

            if (netManager.isServer)
            {
                netObject.NetworkId = GetNetworkObjectId();
            }
            else
            {
                netObject.NetworkId = networkId;
            }

            netObject.sceneObject        = false;
            netObject.OwnerClientId      = owner;
            netObject.isPlayerObject     = playerObject;
            netObject.transform.position = position;
            netObject.transform.rotation = rotation;
            spawnedObjects.Add(netObject.NetworkId, netObject);
            if (playerObject)
            {
                NetworkingManager.singleton.ConnectedClients[owner].PlayerObject = netObject;
            }
            netObject.InvokeBehaviourNetworkSpawn(reader);
            return(netObject);
        }
Ejemplo n.º 2
0
        //RETURNS THE CLIENTIDS WHICH WAS NOT BEING OBSERVED
        internal static ref List <uint> Send(string messageType, string channelName, BitWriter messageWriter, uint?fromNetId, uint?networkId = null, ushort?orderId = null)
        {
            failedObservers.Clear();
            if (netManager.connectedClients.Count == 0)
            {
                return(ref failedObservers);
            }
            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)
                {
                    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;
                    netManager.NetworkConfig.NetworkTransport.QueueMessageForSending(targetClientId, ref FinalMessageBuffer, (int)writer.GetFinalizeSize(), channel, false, out error);
                    NetworkProfiler.EndEvent();
                }
                return(ref failedObservers);
            }
        }
Ejemplo n.º 3
0
 internal static void SetCurrentSceneIndex()
 {
     if (!sceneNameToIndex.ContainsKey(SceneManager.GetActiveScene().name))
     {
         if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
         {
             LogHelper.LogWarning("Scene switching is enabled but the current scene (" + SceneManager.GetActiveScene().name + ") is not regisered as a network scene.");
         }
         return;
     }
     CurrentSceneIndex = sceneNameToIndex[SceneManager.GetActiveScene().name];
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Turns time back a given amount of seconds, invokes an action and turns it back. The time is based on the estimated RTT of a clientId
        /// </summary>
        /// <param name="clientId">The clientId's RTT to use</param>
        /// <param name="action">The action to invoke when time is turned back</param>
        public static void Simulate(uint clientId, Action action)
        {
            if (!NetworkingManager.singleton.isServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Lag compensation simulations are only to be ran on the server");
                }
                return;
            }
            float milisecondsDelay = NetworkingManager.singleton.NetworkConfig.NetworkTransport.GetCurrentRTT(clientId, out error) / 2f;

            Simulate(milisecondsDelay * 1000f, action);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Creates a networked object pool. Can only be called from the server
        /// </summary>
        /// <param name="poolName">Name of the pool</param>
        /// <param name="spawnablePrefabIndex">The index of the prefab to use in the spawnablePrefabs array</param>
        /// <param name="size">The amount of objects in the pool</param>
        public static void CreatePool(string poolName, int spawnablePrefabIndex, uint size = 16)
        {
            if (!NetworkingManager.singleton.isServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Pools can only be created on the server");
                }
                return;
            }
            NetworkPool pool = new NetworkPool(spawnablePrefabIndex, size, PoolIndex);

            PoolNamesToIndexes.Add(poolName, PoolIndex);
            PoolIndex++;
        }
Ejemplo n.º 6
0
        internal static int AddIncomingMessageHandler(string name, Action <uint, BitReader> action)
        {
            if (messageTypes.ContainsKey(name))
            {
                if (messageCallbacks.ContainsKey(messageTypes[name]))
                {
                    int handlerId = 0;
                    if (messageHandlerCounter.ContainsKey(messageTypes[name]))
                    {
                        if (!releasedMessageHandlerCounters.ContainsKey(messageTypes[name]))
                        {
                            releasedMessageHandlerCounters.Add(messageTypes[name], new Stack <int>());
                        }

                        if (releasedMessageHandlerCounters[messageTypes[name]].Count == 0)
                        {
                            handlerId = messageHandlerCounter[messageTypes[name]];
                            messageHandlerCounter[messageTypes[name]]++;
                        }
                        else
                        {
                            handlerId = releasedMessageHandlerCounters[messageTypes[name]].Pop();
                        }
                    }
                    else
                    {
                        messageHandlerCounter.Add(messageTypes[name], handlerId + 1);
                    }
                    messageCallbacks[messageTypes[name]].Add(handlerId, action);
                    return(handlerId);
                }
                else
                {
                    messageCallbacks.Add(messageTypes[name], new Dictionary <int, Action <uint, BitReader> >());
                    messageHandlerCounter.Add(messageTypes[name], 1);
                    messageCallbacks[messageTypes[name]].Add(0, action);
                    return(0);
                }
            }
            else
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("The message type " + name + " has not been registered. Please define it in the netConfig");
                }
                return(-1);
            }
        }
Ejemplo n.º 7
0
 /// <summary>
 /// This destroys an object pool and all of it's objects. Can only be called from the server
 /// </summary>
 /// <param name="poolName">The name of the pool</param>
 public static void DestroyPool(string poolName)
 {
     if (!NetworkingManager.singleton.isServer)
     {
         if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
         {
             LogHelper.LogWarning("Pools can only be destroyed on the server");
         }
         return;
     }
     for (int i = 0; i < Pools[PoolNamesToIndexes[poolName]].objects.Length; i++)
     {
         MonoBehaviour.Destroy(Pools[PoolNamesToIndexes[poolName]].objects[i]);
     }
     Pools.Remove(PoolNamesToIndexes[poolName]);
 }
Ejemplo n.º 8
0
        internal static GameObject SpawnPlayerObject(uint clientId, uint networkId, Vector3 position, Quaternion rotation, BitReader reader = null)
        {
            if (string.IsNullOrEmpty(netManager.NetworkConfig.PlayerPrefabName) || !netManager.NetworkConfig.NetworkPrefabIds.ContainsKey(netManager.NetworkConfig.PlayerPrefabName))
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("There is no player prefab in the NetworkConfig, or it's not registered at as a spawnable prefab");
                }
                return(null);
            }
            GameObject      go        = MonoBehaviour.Instantiate(netManager.NetworkConfig.NetworkedPrefabs[netManager.NetworkConfig.NetworkPrefabIds[netManager.NetworkConfig.PlayerPrefabName]].prefab, position, rotation);
            NetworkedObject netObject = go.GetComponent <NetworkedObject>();

            if (netObject == null)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Please add a NetworkedObject component to the root of the player prefab");
                }
                netObject = go.AddComponent <NetworkedObject>();
            }

            if (NetworkingManager.singleton.isServer)
            {
                netObject.networkId = GetNetworkObjectId();
            }
            else
            {
                netObject.networkId = networkId;
            }

            if (reader != null)
            {
                netObject.SetFormattedSyncedVarData(reader);
            }

            netObject._isPooledObject = false;
            netObject.ownerClientId   = clientId;
            netObject._isPlayerObject = true;
            netObject._isSpawned      = true;
            netObject.sceneObject     = false;
            netManager.connectedClients[clientId].PlayerObject = go;
            spawnedObjects.Add(netObject.NetworkId, netObject);
            netObject.InvokeBehaviourNetworkSpawn();
            return(go);
        }
Ejemplo n.º 9
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)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Objects can only be destroyed on the server");
                }
                return;
            }
            netObject.gameObject.SetActive(false);
            using (BitWriter writer = BitWriter.Get())
            {
                writer.WriteUInt(netObject.NetworkId);

                InternalMessageHandler.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_INTERNAL", writer, null);
            }
        }
Ejemplo n.º 10
0
        /// <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)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Scene switching is not enabled");
                }
                return;
            }
            else if (isSwitching)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Scene switch already in progress");
                }
                return;
            }
            else if (!registeredSceneNames.Contains(sceneName))
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("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 = BitWriter.Get())
            {
                writer.WriteUInt(sceneNameToIndex[sceneName]);

                InternalMessageHandler.Send("MLAPI_SWITCH_SCENE", "MLAPI_INTERNAL", writer, null);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Turns time back a given amount of seconds, invokes an action and turns it back
        /// </summary>
        /// <param name="secondsAgo">The amount of seconds</param>
        /// <param name="action">The action to invoke when time is turned back</param>
        public static void Simulate(float secondsAgo, Action action)
        {
            if (!NetworkingManager.singleton.isServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Lag compensation simulations are only to be ran on the server");
                }
                return;
            }
            for (int i = 0; i < simulationObjects.Count; i++)
            {
                simulationObjects[i].ReverseTransform(secondsAgo);
            }

            action.Invoke();

            for (int i = 0; i < simulationObjects.Count; i++)
            {
                simulationObjects[i].ResetStateTransform();
            }
        }
Ejemplo n.º 12
0
        internal static GameObject SpawnPrefabIndexClient(int networkedPrefabId, uint networkId, uint owner, Vector3 position, Quaternion rotation, BitReader reader = null)
        {
            if (!netManager.NetworkConfig.NetworkPrefabNames.ContainsKey(networkedPrefabId))
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Cannot spawn the object, invalid prefabIndex");
                }
                return(null);
            }

            GameObject      go        = MonoBehaviour.Instantiate(netManager.NetworkConfig.NetworkedPrefabs[networkedPrefabId].prefab, position, rotation);
            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 (reader != null)
            {
                netObject.SetFormattedSyncedVarData(reader);
            }

            netObject.NetworkedPrefabName = netManager.NetworkConfig.NetworkPrefabNames[networkedPrefabId];
            netObject._isSpawned          = true;
            netObject._isPooledObject     = false;
            netObject.networkId           = networkId;
            netObject.ownerClientId       = owner;
            netObject.transform.position  = position;
            netObject.transform.rotation  = rotation;
            spawnedObjects.Add(netObject.NetworkId, netObject);
            netObject.InvokeBehaviourNetworkSpawn();
            return(go);
        }
Ejemplo n.º 13
0
        internal static void RemoveOwnership(uint netId)
        {
            if (!netManager.isServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("You can only remove ownership from Server");
                }
                return;
            }
            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 = BitWriter.Get())
            {
                writer.WriteUInt(netId);
                writer.WriteUInt(netObject.ownerClientId);

                InternalMessageHandler.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", writer, null);
            }
        }
Ejemplo n.º 14
0
        internal static void Send(List <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.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.WriteWriter(messageWriter);

                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);

                    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 HandleConnectionApproved(uint clientId, BitReader reader, int channelId)
        {
            netManager.LocalClientId = reader.ReadUInt();
            uint sceneIndex = 0;

            if (netManager.NetworkConfig.EnableSceneSwitching)
            {
                sceneIndex = reader.ReadUInt();
            }

#if !DISABLE_CRYPTOGRAPHY
            if (netManager.NetworkConfig.EnableEncryption)
            {
                byte[] serverPublicKey = reader.ReadByteArray();
                netManager.clientAesKey = netManager.clientDiffieHellman.GetSharedSecret(serverPublicKey);
                if (netManager.NetworkConfig.SignKeyExchange)
                {
                    byte[] publicKeySignature = reader.ReadByteArray();
                    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                    {
                        rsa.PersistKeyInCsp = false;
                        rsa.FromXmlString(netManager.NetworkConfig.RSAPublicKey);
                        if (!rsa.VerifyData(serverPublicKey, new SHA512CryptoServiceProvider(), publicKeySignature))
                        {
                            //Man in the middle.
                            if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                            {
                                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                                {
                                    LogHelper.LogWarning("Signature doesnt match for the key exchange public part. Disconnecting");
                                }
                            }
                            netManager.StopClient();
                            return;
                        }
                    }
                }
            }
#endif

            float netTime     = reader.ReadFloat();
            int   remoteStamp = reader.ReadInt();
            int   msDelay     = NetworkingManager.singleton.NetworkConfig.NetworkTransport.GetRemoteDelayTimeMS(clientId, remoteStamp, out byte error);
            netManager.NetworkTime = netTime + (msDelay / 1000f);

            netManager.ConnectedClients.Add(netManager.LocalClientId, new NetworkedClient()
            {
                ClientId = netManager.LocalClientId
            });
            int clientCount = reader.ReadInt();
            for (int i = 0; i < clientCount; i++)
            {
                uint _clientId = reader.ReadUInt();
                netManager.ConnectedClients.Add(_clientId, new NetworkedClient()
                {
                    ClientId = _clientId
                });
                netManager.ConnectedClientsList.Add(netManager.ConnectedClients[_clientId]);
            }
            if (netManager.NetworkConfig.HandleObjectSpawning)
            {
                SpawnManager.DestroySceneObjects();
                int objectCount = reader.ReadInt();
                for (int i = 0; i < objectCount; i++)
                {
                    bool isPlayerObject = reader.ReadBool();
                    uint networkId      = reader.ReadUInt();
                    uint ownerId        = reader.ReadUInt();
                    int  prefabId       = reader.ReadInt();
                    bool isActive       = reader.ReadBool();
                    bool sceneObject    = reader.ReadBool();
                    bool visible        = reader.ReadBool();

                    float xPos = reader.ReadFloat();
                    float yPos = reader.ReadFloat();
                    float zPos = reader.ReadFloat();

                    float xRot = reader.ReadFloat();
                    float yRot = reader.ReadFloat();
                    float zRot = reader.ReadFloat();

                    NetworkedObject netObject = SpawnManager.CreateSpawnedObject(prefabId, networkId, ownerId, isPlayerObject,
                                                                                 new Vector3(xPos, yPos, zPos), Quaternion.Euler(xRot, yRot, zRot), reader, visible, false);
                    netObject.SetLocalVisibility(visible);
                    netObject.sceneObject = sceneObject;
                    netObject.gameObject.SetActive(isActive);
                }
            }

            if (netManager.NetworkConfig.EnableSceneSwitching)
            {
                NetworkSceneManager.OnSceneSwitch(sceneIndex);
            }

            netManager.isConnectedClients = true;
            if (netManager.OnClientConnectedCallback != null)
            {
                netManager.OnClientConnectedCallback.Invoke(netManager.LocalClientId);
            }
        }
Ejemplo n.º 16
0
        //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);
            }
        }
Ejemplo n.º 17
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);
                }
            }
        }