示例#1
0
        internal static void OnFirstSceneSwitchSync(uint sceneIndex, Guid switchSceneGuid)
        {
            if (!sceneIndexToString.ContainsKey(sceneIndex) || !registeredSceneNames.Contains(sceneIndexToString[sceneIndex]))
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Server requested a scene switch to a non registered scene");
                }
                return;
            }
            else if (SceneManager.GetActiveScene().name == sceneIndexToString[sceneIndex])
            {
                return; //This scene is already loaded. This usually happends at first load
            }

            lastScene = SceneManager.GetActiveScene();
            string sceneName = sceneIndexToString[sceneIndex];

            nextScene = SceneManager.GetSceneByName(sceneName);
            CurrentActiveSceneIndex = sceneNameToIndex[sceneName];

            SceneManager.LoadScene(sceneName);

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteByteArray(switchSceneGuid.ToByteArray());
                    InternalMessageHandler.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_CLIENT_SWITCH_SCENE_COMPLETED, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null);
                }
            }

            isSwitching = false;
        }
示例#2
0
        internal static void ChangeOwnership(uint netId, uint clientId)
        {
            if (!netManager.isServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("You can only change ownership from Server");
                }
                return;
            }
            NetworkedObject netObject = SpawnManager.SpawnedObjects[netId];

            for (int i = NetworkingManager.singleton.ConnectedClients[netObject.OwnerClientId].OwnedObjects.Count - 1; i > -1; i--)
            {
                if (NetworkingManager.singleton.ConnectedClients[netObject.OwnerClientId].OwnedObjects[i].NetworkId == netId)
                {
                    NetworkingManager.singleton.ConnectedClients[netObject.OwnerClientId].OwnedObjects.RemoveAt(i);
                }
            }
            NetworkingManager.singleton.ConnectedClients[clientId].OwnedObjects.Add(netObject);
            netObject.OwnerClientId = clientId;

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteUInt32Packed(netId);
                    writer.WriteUInt32Packed(clientId);

                    InternalMessageHandler.Send(MLAPIConstants.MLAPI_CHANGE_OWNER, "MLAPI_INTERNAL", stream, SecuritySendFlags.None);
                }
            }
        }
示例#3
0
        internal void SendClientRPCPerformance(ulong hash, uint clientId, Stream messageStream, string channel, SecuritySendFlags security)
        {
            if (!IsServer && IsRunning)
            {
                //We are NOT a server.
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Only clients and host can invoke ClientRPC");
                }
                return;
            }

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteUInt32Packed(NetworkId);
                    writer.WriteUInt16Packed(NetworkedObject.GetOrderIndex(this));
                    writer.WriteUInt64Packed(hash);

                    stream.CopyFrom(messageStream);

                    if (IsHost && clientId == NetworkingManager.Singleton.LocalClientId)
                    {
                        messageStream.Position = 0;
                        InvokeClientRPCLocal(hash, NetworkingManager.Singleton.LocalClientId, messageStream);
                    }
                    else
                    {
                        InternalMessageHandler.Send(clientId, MLAPIConstants.MLAPI_CLIENT_RPC, string.IsNullOrEmpty(channel) ? "MLAPI_DEFAULT_MESSAGE" : channel, stream, security);
                    }
                }
            }
        }
示例#4
0
        /// <summary>
        /// Hides a object from a specific client
        /// </summary>
        /// <param name="clientId">The client to hide the object for</param>
        public void NetworkHide(ulong clientId)
        {
            if (!NetworkingManager.Singleton.IsServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Error)
                {
                    LogHelper.LogError("Can only call NetworkHide on the server");
                }
                return;
            }

            if (observers.Contains(clientId) && clientId != NetworkingManager.Singleton.ServerClientId)
            {
                // Send destroy call
                observers.Remove(clientId);

                using (PooledBitStream stream = PooledBitStream.Get())
                {
                    using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                    {
                        writer.WriteUInt64Packed(NetworkId);

                        InternalMessageHandler.Send(MLAPIConstants.MLAPI_DESTROY_OBJECT, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null);
                    }
                }
            }
        }
示例#5
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 NetworkedObject SpawnPoolObject(string poolName, Vector3 position, Quaternion rotation)
        {
            if (!NetworkingManager.singleton.isServer)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Object spawning can only occur on server");
                }
                return(null);
            }
            NetworkedObject netObject = Pools[PoolNamesToIndexes[poolName]].SpawnObject(position, rotation);

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteUInt32Packed(netObject.NetworkId);

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

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

                    InternalMessageHandler.Send(MLAPIConstants.MLAPI_SPAWN_POOL_OBJECT, "MLAPI_INTERNAL", stream);
                }
            }
            return(netObject);
        }
示例#6
0
        internal static void SendSpawnCallForObject(ulong clientId, NetworkedObject netObject, Stream payload)
        {
            using (PooledBitStream stream = PooledBitStream.Get())
            {
                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.WriteBool(netObject.DestroyWithScene);

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

                InternalMessageHandler.Send(clientId, MLAPIConstants.MLAPI_ADD_OBJECT, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null);
            }
        }
示例#7
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 SceneSwitchProgress SwitchScene(string sceneName)
        {
            if (!NetworkingManager.singleton.NetworkConfig.EnableSceneSwitching)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Scene switching is not enabled");
                }
                return(null);
            }
            else if (isSwitching)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Scene switch already in progress");
                }
                return(null);
            }
            else if (!registeredSceneNames.Contains(sceneName))
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("The scene " + sceneName + " is not registered as a switchable scene.");
                }
                return(null);
            }
            SpawnManager.DestroySceneObjects(); //Destroy current scene objects before switching.
            currentSceneIndex = sceneNameToIndex[sceneName];
            isSwitching       = true;
            lastScene         = SceneManager.GetActiveScene();

            SceneSwitchProgress switchSceneProgress = new SceneSwitchProgress();

            sceneSwitchProgresses.Add(switchSceneProgress.guid, switchSceneProgress);
            currentSceneSwitchProgressGuid = switchSceneProgress.guid;

            AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);

            nextScene            = SceneManager.GetSceneByName(sceneName);
            sceneLoad.completed += (AsyncOperation AsyncOp) => { OnSceneLoaded(AsyncOp, switchSceneProgress.guid); };

            switchSceneProgress.SetSceneLoadOperation(sceneLoad);

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteUInt32Packed(sceneNameToIndex[sceneName]);
                    writer.WriteByteArray(switchSceneProgress.guid.ToByteArray());

                    InternalMessageHandler.Send(MLAPIConstants.MLAPI_SWITCH_SCENE, "MLAPI_INTERNAL", stream, SecuritySendFlags.None);
                }
            }
            return(switchSceneProgress);
        }
示例#8
0
        internal static void OnDestroyObject(uint networkId, bool destroyGameObject)
        {
            if (!SpawnedObjects.ContainsKey(networkId) || (netManager != null && !netManager.NetworkConfig.HandleObjectSpawning))
            {
                return;
            }
            if (!SpawnedObjects[networkId].isOwnedByServer && !SpawnedObjects[networkId].isPlayerObject &&
                netManager.ConnectedClients.ContainsKey(SpawnedObjects[networkId].OwnerClientId))
            {
                //Someone owns it.
                for (int i = NetworkingManager.singleton.ConnectedClients[SpawnedObjects[networkId].OwnerClientId].OwnedObjects.Count - 1; i > -1; i--)
                {
                    if (NetworkingManager.singleton.ConnectedClients[SpawnedObjects[networkId].OwnerClientId].OwnedObjects[i].NetworkId == networkId)
                    {
                        NetworkingManager.singleton.ConnectedClients[SpawnedObjects[networkId].OwnerClientId].OwnedObjects.RemoveAt(i);
                    }
                }
            }
            SpawnedObjects[networkId].isSpawned = false;

            if (netManager != null && netManager.isServer)
            {
                releasedNetworkObjectIds.Push(networkId);
                if (SpawnedObjects[networkId] != null)
                {
                    using (PooledBitStream stream = PooledBitStream.Get())
                    {
                        using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                        {
                            writer.WriteUInt32Packed(networkId);

                            InternalMessageHandler.Send(MLAPIConstants.MLAPI_DESTROY_OBJECT, "MLAPI_INTERNAL", stream);
                        }
                    }
                }
            }

            GameObject go = SpawnedObjects[networkId].gameObject;

            if (destroyGameObject && go != null)
            {
                MonoBehaviour.Destroy(go);
            }
            SpawnedObjects.Remove(networkId);
            for (int i = SpawnedObjectsList.Count - 1; i > -1; i--)
            {
                if (SpawnedObjectsList[i].NetworkId == networkId)
                {
                    SpawnedObjectsList.RemoveAt(i);
                }
            }
        }
示例#9
0
        private static void OnSceneUnload(AsyncOperation operation, Guid switchSceneGuid)
        {
            if (NetworkingManager.singleton.isServer)
            {
                SpawnManager.MarkSceneObjects();
                NetworkedObject[] networkedObjects = MonoBehaviour.FindObjectsOfType <NetworkedObject>();
                for (int i = 0; i < networkedObjects.Length; i++)
                {
                    if (!networkedObjects[i].isSpawned && networkedObjects[i].destroyWithScene == true)
                    {
                        networkedObjects[i].Spawn(null, true);
                    }
                }
            }
            else
            {
                SpawnManager.SpawnPendingObjectsForScene(CurrentActiveSceneIndex);

                NetworkedObject[] netObjects = MonoBehaviour.FindObjectsOfType <NetworkedObject>();
                for (int i = 0; i < netObjects.Length; i++)
                {
                    if (netObjects[i].destroyWithScene == null)
                    {
                        MonoBehaviour.Destroy(netObjects[i].gameObject);
                    }
                }
            }

            //Tell server that scene load is completed
            if (NetworkingManager.singleton.isHost)
            {
                OnClientSwitchSceneCompleted(NetworkingManager.singleton.LocalClientId, switchSceneGuid);
            }
            else if (NetworkingManager.singleton.isClient)
            {
                using (PooledBitStream stream = PooledBitStream.Get())
                {
                    using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                    {
                        writer.WriteByteArray(switchSceneGuid.ToByteArray());
                        InternalMessageHandler.Send(NetworkingManager.singleton.ServerClientId, MLAPIConstants.MLAPI_CLIENT_SWITCH_SCENE_COMPLETED, "MLAPI_INTERNAL", stream, SecuritySendFlags.None);
                    }
                }
            }

            isSwitching = false;
        }
示例#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);

            nextScene            = SceneManager.GetSceneByName(sceneName);
            sceneLoad.completed += OnSceneLoaded;

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteUInt32Packed(sceneNameToIndex[sceneName]);

                    InternalMessageHandler.Send(MLAPIConstants.MLAPI_SWITCH_SCENE, "MLAPI_INTERNAL", stream);
                }
            }
        }
示例#11
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 (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteUInt32Packed(netObject.NetworkId);

                    InternalMessageHandler.Send(MLAPIConstants.MLAPI_DESTROY_POOL_OBJECT, "MLAPI_INTERNAL", stream);
                }
            }
        }
示例#12
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
            {
                previousObservers.Clear();
                foreach (var item in observers)
                {
                    previousObservers.Add(item);
                }
                bool update = false;
                for (int i = 0; i < childNetworkedBehaviours.Count; i++)
                {
                    bool changed = childNetworkedBehaviours[i].OnRebuildObservers(observers);
                    if (changed)
                    {
                        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) && !observers.Contains(pair.Key)) ||
                            (!previousObservers.Contains(pair.Key) && observers.Contains(pair.Key)))
                        {
                            //Something changed for this client.
                            using (BitWriter writer = BitWriter.Get())
                            {
                                writer.WriteUInt(networkId);
                                writer.WriteBool(observers.Contains(pair.Key));

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

                                InternalMessageHandler.Send(pair.Key, "MLAPI_SET_VISIBILITY", "MLAPI_INTERNAL", writer, null);
                            }
                        }
                    }
                }
                else
                {
                    foreach (var item in previousObservers)
                    {
                        observers.Add(item);
                    }
                }
                previousObservers.Clear();
            }
        }
示例#13
0
        internal void NetworkedVarUpdate()
        {
            if (!networkedVarInit)
            {
                NetworkedVarInit();
            }

            //TODO: Do this efficiently.

            if (!CouldHaveDirtyVars())
            {
                return;
            }

            networkedVarIndexesToReset.Clear();
            networkedVarIndexesToResetSet.Clear();

            for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++)
            {
                //This iterates over every "channel group".
                for (int j = 0; j < channelMappedVarIndexes.Count; j++)
                {
                    using (PooledBitStream stream = PooledBitStream.Get())
                    {
                        using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                        {
                            writer.WriteUInt32Packed(NetworkId);
                            writer.WriteUInt16Packed(NetworkedObject.GetOrderIndex(this));

                            uint clientId   = NetworkingManager.Singleton.ConnectedClientsList[i].ClientId;
                            bool writtenAny = false;
                            for (int k = 0; k < networkedVarFields.Count; k++)
                            {
                                if (!channelMappedVarIndexes[j].Contains(k))
                                {
                                    //This var does not belong to the currently iterating channel group.
                                    writer.WriteBool(false);
                                    continue;
                                }

                                bool isDirty = networkedVarFields[k].IsDirty(); //cache this here. You never know what operations users will do in the dirty methods
                                writer.WriteBool(isDirty);

                                if (isDirty && (!IsServer || networkedVarFields[k].CanClientRead(clientId)))
                                {
                                    writtenAny = true;
                                    networkedVarFields[k].WriteDelta(stream);
                                    if (!networkedVarIndexesToResetSet.Contains(k))
                                    {
                                        networkedVarIndexesToResetSet.Add(k);
                                        networkedVarIndexesToReset.Add(k);
                                    }
                                }
                            }

                            if (writtenAny)
                            {
                                if (IsServer)
                                {
                                    InternalMessageHandler.Send(clientId, MLAPIConstants.MLAPI_NETWORKED_VAR_DELTA, channelsForVarGroups[j], stream, SecuritySendFlags.None);
                                }
                                else
                                {
                                    InternalMessageHandler.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_NETWORKED_VAR_DELTA, channelsForVarGroups[j], stream, SecuritySendFlags.None);
                                }
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < networkedVarIndexesToReset.Count; i++)
            {
                networkedVarFields[networkedVarIndexesToReset[i]].ResetDirty();
            }
        }
示例#14
0
        private static void OnSceneUnloadClient(Guid switchSceneGuid, Stream objectStream)
        {
            if (NetworkingManager.Singleton.NetworkConfig.UsePrefabSync)
            {
                SpawnManager.DestroySceneObjects();

                using (PooledBitReader reader = PooledBitReader.Get(objectStream))
                {
                    uint newObjectsCount = reader.ReadUInt32Packed();

                    for (int i = 0; i < newObjectsCount; i++)
                    {
                        bool  isPlayerObject = reader.ReadBool();
                        ulong networkId      = reader.ReadUInt64Packed();
                        ulong owner          = reader.ReadUInt64Packed();

                        ulong prefabHash = reader.ReadUInt64Packed();

                        bool destroyWithScene = reader.ReadBool();

                        Vector3    position = new Vector3(reader.ReadSinglePacked(), reader.ReadSinglePacked(), reader.ReadSinglePacked());
                        Quaternion rotation = Quaternion.Euler(reader.ReadSinglePacked(), reader.ReadSinglePacked(), reader.ReadSinglePacked());

                        NetworkedObject networkedObject = SpawnManager.CreateLocalNetworkedObject(false, 0, prefabHash, position, rotation);
                        SpawnManager.SpawnNetworkedObjectLocally(networkedObject, networkId, true, isPlayerObject, owner, objectStream, false, 0, true, destroyWithScene);
                    }
                }
            }
            else
            {
                NetworkedObject[] networkedObjects = MonoBehaviour.FindObjectsOfType <NetworkedObject>();

                SpawnManager.ClientCollectSoftSyncSceneObjectSweep(networkedObjects);

                using (PooledBitReader reader = PooledBitReader.Get(objectStream))
                {
                    uint newObjectsCount = reader.ReadUInt32Packed();

                    for (int i = 0; i < newObjectsCount; i++)
                    {
                        bool  isPlayerObject = reader.ReadBool();
                        ulong networkId      = reader.ReadUInt64Packed();
                        ulong owner          = reader.ReadUInt64Packed();

                        ulong instanceId = reader.ReadUInt64Packed();

                        bool destroyWithScene = reader.ReadBool();

                        NetworkedObject networkedObject = SpawnManager.CreateLocalNetworkedObject(true, instanceId, 0, null, null);
                        SpawnManager.SpawnNetworkedObjectLocally(networkedObject, networkId, true, isPlayerObject, owner, objectStream, false, 0, true, destroyWithScene);
                    }
                }
            }

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteByteArray(switchSceneGuid.ToByteArray());
                    InternalMessageHandler.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_CLIENT_SWITCH_SCENE_COMPLETED, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null);
                }
            }

            isSwitching = false;

            if (OnSceneSwitched != null)
            {
                OnSceneSwitched();
            }
        }
示例#15
0
        internal static void SpawnObject(NetworkedObject netObject, uint?clientOwnerId = null, Stream payload = null, bool destroyWithScene = false)
        {
            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 (SpawnManager.GetNetworkedPrefabIndexOfName(netObject.NetworkedPrefabName) == -1)
            {
                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);
            SpawnedObjectsList.Add(netObject);
            netObject.isSpawned           = true;
            netObject.destroyWithScene    = destroyWithScene;
            netObject.sceneSpawnedInIndex = NetworkSceneManager.CurrentActiveSceneIndex;

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

            if (payload == null)
            {
                netObject.InvokeBehaviourNetworkSpawn(null);
            }
            else
            {
                netObject.InvokeBehaviourNetworkSpawn(payload);
            }

            foreach (var client in netManager.ConnectedClients)
            {
                using (PooledBitStream stream = PooledBitStream.Get())
                {
                    using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                    {
                        writer.WriteBool(false);
                        writer.WriteUInt32Packed(netObject.NetworkId);
                        writer.WriteUInt32Packed(netObject.OwnerClientId);
                        writer.WriteUInt64Packed(netObject.NetworkedPrefabHash);

                        writer.WriteBool(netObject.destroyWithScene == null ? true : netObject.destroyWithScene.Value);
                        writer.WriteBool(netObject.SceneDelayedSpawn);
                        writer.WriteUInt32Packed(netObject.sceneSpawnedInIndex);

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

                        netObject.WriteNetworkedVarData(stream, client.Key);

                        if (payload != null)
                        {
                            stream.CopyFrom(payload);
                        }

                        InternalMessageHandler.Send(client.Key, MLAPIConstants.MLAPI_ADD_OBJECT, "MLAPI_INTERNAL", stream, SecuritySendFlags.None);
                    }
                }
            }
        }
示例#16
0
        internal static void OnDestroyObject(ulong networkId, bool destroyGameObject)
        {
            if (NetworkingManager.Singleton == null)
            {
                return;
            }

            //Removal of spawned object
            if (!SpawnedObjects.ContainsKey(networkId))
            {
                return;
            }

            if (!SpawnedObjects[networkId].IsOwnedByServer && !SpawnedObjects[networkId].IsPlayerObject &&
                NetworkingManager.Singleton.ConnectedClients.ContainsKey(SpawnedObjects[networkId].OwnerClientId))
            {
                //Someone owns it.
                for (int i = NetworkingManager.Singleton.ConnectedClients[SpawnedObjects[networkId].OwnerClientId].OwnedObjects.Count - 1; i > -1; i--)
                {
                    if (NetworkingManager.Singleton.ConnectedClients[SpawnedObjects[networkId].OwnerClientId].OwnedObjects[i].NetworkId == networkId)
                    {
                        NetworkingManager.Singleton.ConnectedClients[SpawnedObjects[networkId].OwnerClientId].OwnedObjects.RemoveAt(i);
                    }
                }
            }
            SpawnedObjects[networkId].IsSpawned = false;

            if (NetworkingManager.Singleton != null && NetworkingManager.Singleton.IsServer)
            {
                releasedNetworkObjectIds.Push(networkId);

                if (SpawnedObjects[networkId] != null)
                {
                    using (PooledBitStream stream = PooledBitStream.Get())
                    {
                        using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                        {
                            writer.WriteUInt64Packed(networkId);

                            InternalMessageHandler.Send(MLAPIConstants.MLAPI_DESTROY_OBJECT, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, SpawnedObjects[networkId]);
                        }
                    }
                }
            }

            GameObject go = SpawnedObjects[networkId].gameObject;

            if (destroyGameObject && go != null)
            {
                if (customDestroyHandlers.ContainsKey(SpawnedObjects[networkId].PrefabHash))
                {
                    customDestroyHandlers[SpawnedObjects[networkId].PrefabHash](SpawnedObjects[networkId]);
                    SpawnManager.OnDestroyObject(networkId, false);
                }
                else
                {
                    MonoBehaviour.Destroy(go);
                }
            }

            SpawnedObjects.Remove(networkId);

            for (int i = SpawnedObjectsList.Count - 1; i > -1; i--)
            {
                if (SpawnedObjectsList[i].NetworkId == networkId)
                {
                    SpawnedObjectsList.RemoveAt(i);
                }
            }
        }
示例#17
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);
                        }
                    }
                }
            }
        }
示例#18
0
        //Server only
        internal static void SpawnPlayerObject(NetworkedObject netObject, uint clientId, Stream 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;
            }
            else if (netManager.ConnectedClients[clientId].PlayerObject != null)
            {
                if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                {
                    LogHelper.LogWarning("Client already have a player object");
                }
                return;
            }
            uint netId = GetNetworkObjectId();

            netObject.NetworkId = netId;
            SpawnedObjects.Add(netId, netObject);
            SpawnedObjectsList.Add(netObject);
            netObject.isSpawned      = true;
            netObject.sceneObject    = false;
            netObject.isPlayerObject = true;
            netManager.ConnectedClients[clientId].PlayerObject = netObject;

            if (payload == null)
            {
                netObject.InvokeBehaviourNetworkSpawn(null);
            }
            else
            {
                netObject.InvokeBehaviourNetworkSpawn(payload);
            }

            foreach (var client in netManager.ConnectedClients)
            {
                using (PooledBitStream stream = PooledBitStream.Get())
                {
                    using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                    {
                        writer.WriteBool(true);
                        writer.WriteUInt32Packed(netObject.NetworkId);
                        writer.WriteUInt32Packed(netObject.OwnerClientId);
                        writer.WriteInt32Packed(netManager.NetworkConfig.NetworkPrefabIds[netObject.NetworkedPrefabName]);
                        writer.WriteBool(netObject.sceneObject == null ? true : netObject.sceneObject.Value);

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

                        netObject.WriteNetworkedVarData(stream, client.Key);

                        if (payload != null)
                        {
                            stream.CopyFrom(payload);
                        }

                        InternalMessageHandler.Send(client.Key, MLAPIConstants.MLAPI_ADD_OBJECT, "MLAPI_INTERNAL", stream);
                    }
                }
            }
        }
示例#19
0
        internal static void OnDestroyObject(uint networkId, bool destroyGameObject)
        {
            if ((netManager == null || !netManager.NetworkConfig.HandleObjectSpawning))
            {
                return;
            }

            //Removal of pending object
            //Even though pending objects is marked with DontDestroyOnLoad, the OnDestroy method is invoked on pending objects. They are however not
            //destroyed (probably a unity bug for having an gameobject spawned as inactive). Therefore we only actual remove it from the list if
            //destroyGameObject is set to true, meaning MLAPI decided to destroy it, not unity.
            if (destroyGameObject == true && PendingSpawnObjects.ContainsKey(networkId))
            {
                if (!PendingSpawnObjects[networkId].netObject.isOwnedByServer && !PendingSpawnObjects[networkId].netObject.isPlayerObject &&
                    netManager.ConnectedClients.ContainsKey(PendingSpawnObjects[networkId].netObject.OwnerClientId))
                {
                    //Someone owns it.
                    for (int i = NetworkingManager.singleton.ConnectedClients[PendingSpawnObjects[networkId].netObject.OwnerClientId].OwnedObjects.Count - 1; i > -1; i--)
                    {
                        if (NetworkingManager.singleton.ConnectedClients[PendingSpawnObjects[networkId].netObject.OwnerClientId].OwnedObjects[i].NetworkId == networkId)
                        {
                            NetworkingManager.singleton.ConnectedClients[PendingSpawnObjects[networkId].netObject.OwnerClientId].OwnedObjects.RemoveAt(i);
                        }
                    }
                }

                GameObject pendingGameObject = PendingSpawnObjects[networkId].netObject.gameObject;
                if (pendingGameObject != null)
                {
                    MonoBehaviour.Destroy(pendingGameObject);
                }
                PendingSpawnObjects.Remove(networkId);
            }

            //Removal of spawned object
            if (!SpawnedObjects.ContainsKey(networkId))
            {
                return;
            }
            if (!SpawnedObjects[networkId].isOwnedByServer && !SpawnedObjects[networkId].isPlayerObject &&
                netManager.ConnectedClients.ContainsKey(SpawnedObjects[networkId].OwnerClientId))
            {
                //Someone owns it.
                for (int i = NetworkingManager.singleton.ConnectedClients[SpawnedObjects[networkId].OwnerClientId].OwnedObjects.Count - 1; i > -1; i--)
                {
                    if (NetworkingManager.singleton.ConnectedClients[SpawnedObjects[networkId].OwnerClientId].OwnedObjects[i].NetworkId == networkId)
                    {
                        NetworkingManager.singleton.ConnectedClients[SpawnedObjects[networkId].OwnerClientId].OwnedObjects.RemoveAt(i);
                    }
                }
            }
            SpawnedObjects[networkId].isSpawned = false;

            if (netManager != null && netManager.isServer)
            {
                releasedNetworkObjectIds.Push(networkId);
                if (SpawnedObjects[networkId] != null)
                {
                    using (PooledBitStream stream = PooledBitStream.Get())
                    {
                        using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                        {
                            writer.WriteUInt32Packed(networkId);

                            InternalMessageHandler.Send(MLAPIConstants.MLAPI_DESTROY_OBJECT, "MLAPI_INTERNAL", stream, SecuritySendFlags.None);
                        }
                    }
                }
            }

            GameObject go = SpawnedObjects[networkId].gameObject;

            if (destroyGameObject && go != null)
            {
                MonoBehaviour.Destroy(go);
            }
            SpawnedObjects.Remove(networkId);
            for (int i = SpawnedObjectsList.Count - 1; i > -1; i--)
            {
                if (SpawnedObjectsList[i].NetworkId == networkId)
                {
                    SpawnedObjectsList.RemoveAt(i);
                }
            }
        }
示例#20
0
        private static void OnSceneUnloadServer(Guid switchSceneGuid)
        {
            // Justification: Rare alloc, could(should?) reuse
            List <NetworkedObject> newSceneObjects = new List <NetworkedObject>();

            {
                NetworkedObject[] networkedObjects = MonoBehaviour.FindObjectsOfType <NetworkedObject>();

                for (int i = 0; i < networkedObjects.Length; i++)
                {
                    if (networkedObjects[i].IsSceneObject == null)
                    {
                        SpawnManager.SpawnNetworkedObjectLocally(networkedObjects[i], SpawnManager.GetNetworkObjectId(), true, false, null, null, false, 0, false, true);

                        newSceneObjects.Add(networkedObjects[i]);
                    }
                }
            }


            for (int j = 0; j < NetworkingManager.Singleton.ConnectedClientsList.Count; j++)
            {
                if (NetworkingManager.Singleton.ConnectedClientsList[j].ClientId != NetworkingManager.Singleton.ServerClientId)
                {
                    using (PooledBitStream stream = PooledBitStream.Get())
                    {
                        using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                        {
                            writer.WriteUInt32Packed(CurrentActiveSceneIndex);
                            writer.WriteByteArray(switchSceneGuid.ToByteArray());

                            uint sceneObjectsToSpawn = 0;
                            for (int i = 0; i < newSceneObjects.Count; i++)
                            {
                                if (newSceneObjects[i].observers.Contains(NetworkingManager.Singleton.ConnectedClientsList[j].ClientId))
                                {
                                    sceneObjectsToSpawn++;
                                }
                            }

                            writer.WriteUInt32Packed(sceneObjectsToSpawn);

                            for (int i = 0; i < newSceneObjects.Count; i++)
                            {
                                if (newSceneObjects[i].observers.Contains(NetworkingManager.Singleton.ConnectedClientsList[j].ClientId))
                                {
                                    if (NetworkingManager.Singleton.NetworkConfig.UsePrefabSync)
                                    {
                                        writer.WriteBool(newSceneObjects[i].IsPlayerObject);
                                        writer.WriteUInt64Packed(newSceneObjects[i].NetworkId);
                                        writer.WriteUInt64Packed(newSceneObjects[i].OwnerClientId);

                                        writer.WriteUInt64Packed(newSceneObjects[i].PrefabHash);

                                        writer.WriteBool(newSceneObjects[i].DestroyWithScene);

                                        writer.WriteSinglePacked(newSceneObjects[i].transform.position.x);
                                        writer.WriteSinglePacked(newSceneObjects[i].transform.position.y);
                                        writer.WriteSinglePacked(newSceneObjects[i].transform.position.z);

                                        writer.WriteSinglePacked(newSceneObjects[i].transform.rotation.eulerAngles.x);
                                        writer.WriteSinglePacked(newSceneObjects[i].transform.rotation.eulerAngles.y);
                                        writer.WriteSinglePacked(newSceneObjects[i].transform.rotation.eulerAngles.z);

                                        if (NetworkingManager.Singleton.NetworkConfig.EnableNetworkedVar)
                                        {
                                            newSceneObjects[i].WriteNetworkedVarData(stream, NetworkingManager.Singleton.ConnectedClientsList[j].ClientId);
                                        }
                                    }
                                    else
                                    {
                                        writer.WriteBool(newSceneObjects[i].IsPlayerObject);
                                        writer.WriteUInt64Packed(newSceneObjects[i].NetworkId);
                                        writer.WriteUInt64Packed(newSceneObjects[i].OwnerClientId);

                                        writer.WriteUInt64Packed(newSceneObjects[i].NetworkedInstanceId);

                                        writer.WriteBool(newSceneObjects[i].DestroyWithScene);

                                        if (NetworkingManager.Singleton.NetworkConfig.EnableNetworkedVar)
                                        {
                                            newSceneObjects[i].WriteNetworkedVarData(stream, NetworkingManager.Singleton.ConnectedClientsList[j].ClientId);
                                        }
                                    }
                                }
                            }
                        }

                        InternalMessageHandler.Send(NetworkingManager.Singleton.ConnectedClientsList[j].ClientId, MLAPIConstants.MLAPI_SWITCH_SCENE, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null);
                    }
                }
            }

            //Tell server that scene load is completed
            if (NetworkingManager.Singleton.IsHost)
            {
                OnClientSwitchSceneCompleted(NetworkingManager.Singleton.LocalClientId, switchSceneGuid);
            }

            isSwitching = false;

            if (OnSceneSwitched != null)
            {
                OnSceneSwitched();
            }
        }