コード例 #1
0
        //Client only
        public void SpawnOnNetworkClient(NetworkBehaviour behaviour, ClientBehaviourConnectedDelegate connectedCallback, BehaviourDisconnectedDelegate disconnectedCallback, NetworkBehaviourRPCDelegate localRPCCallback, OwnerChangeDelegate ownerChangeCallback)
        {
            if (behaviour == null || !behaviour.isNetworkSpawned || behaviour.isNetworkReady || m_LocalPendingBehavioursList.Contains(behaviour) || string.IsNullOrWhiteSpace(behaviour.uniqueID))
            {
                throw new InvalidOperationException("NetworkBehaviourManager.SpawnNetworkClient is only allowed to be called internally by a Network Behaviour.");
            }

            //Check if this is the Unique Behaviour being spawned in HandleAddObjectMessage where the Unique ID is blank and SpawnOnNetwork is called in Awake.
            if (m_TrackAwakeSpawns)
            {
                m_BehavioursAwaitingSpawn.Enqueue(new NetworkBehaviourReference()
                {
                    networkBehaviour = behaviour, connectedClientCallback = connectedCallback, disconnectedDelegate = disconnectedCallback, localRPCDelegate = localRPCCallback, ownerChangeDelegate = ownerChangeCallback
                });
                return;
            }

            ulong uniqueHash = behaviour.uniqueID.GetStableHash(networkManager.config.rpcHashSize);

            if (m_RemotePendingBehavioursHashes.TryGetValue(uniqueHash, out PendingNetworkBehaviour pendingBehaviour))
            {
                m_RemotePendingBehavioursHashes.Remove(uniqueHash);
                m_RemotePendingBehaviours.Remove(pendingBehaviour.networkID);
                OnObjectConnectSuccess(new NetworkBehaviourReference()
                {
                    networkBehaviour = behaviour, connectedClientCallback = connectedCallback, disconnectedDelegate = disconnectedCallback, localRPCDelegate = localRPCCallback, ownerChangeDelegate = ownerChangeCallback
                }, pendingBehaviour.networkID, pendingBehaviour.ownerID, pendingBehaviour.ownerCanUnspawn, pendingBehaviour.destroyOnUnspawn, pendingBehaviour.spawnPayload);
                pendingBehaviour.spawnPayload?.Dispose();
            }
            else if (m_LocalPendingBehaviours.TryGetValue(uniqueHash, out pendingBehaviour))
            {
                //Check if the unique hash has already been added by this client
                if (m_BehaviourByHashedID.TryGetValue(uniqueHash, out NetworkBehaviour otherBehaviour))
                {
                    if (!BehaviourWasDestroyed(otherBehaviour))
                    {
                        throw new NetworkException("A Network Behaviour already has the unique ID '" + behaviour.uniqueID + "'.");
                    }
                }

                if (m_HashedStrings.TryGetValue(uniqueHash, out string otherUniqueID))
                {
                    if (otherUniqueID == behaviour.uniqueID)
                    {
                        throw new NetworkException("A Network Behaviour already has the unique ID '" + behaviour.uniqueID + "'.");
                    }
                    else
                    {
                        //This occurs when 2 different strings hash to the same value from MLAPI.Hashing.GetStableHash.
                        throw new NetworkException("A hash collision occurred. Either change the unique ID or increase the hash size in the config. '" + behaviour.uniqueID + "' and '" + otherUniqueID + "' both hashed to '" + uniqueHash + "'.");
                    }
                }
            }
            else
            {
                if (m_BehaviourByHashedID.TryGetValue(uniqueHash, out NetworkBehaviour otherBehaviour))
                {
                    if (!BehaviourWasDestroyed(otherBehaviour))
                    {
                        throw new NetworkException("A Network Behaviour already has the unique ID '" + behaviour.uniqueID + "'.");
                    }
                }

                if (m_HashedStrings.TryGetValue(uniqueHash, out string otherUniqueID))
                {
                    if (otherUniqueID == behaviour.uniqueID)
                    {
                        throw new NetworkException("A Network Behaviour already has the unique ID '" + behaviour.uniqueID + "'.");
                    }
                    else
                    {
                        //This occurs when 2 different strings hash to the same value from MLAPI.Hashing.GetStableHash.
                        throw new NetworkException("A hash collision occurred. Either change the unique ID or increase the hash size in the config. '" + behaviour.uniqueID + "' and '" + otherUniqueID + "' both hashed to '" + uniqueHash + "'.");
                    }
                }

                //Add to pending
                pendingBehaviour = new PendingNetworkBehaviour()
                {
                    isRemoteBehaviour = false, uniqueHash = uniqueHash, ownerID = networkManager.serverID, networkID = 0, reference = new NetworkBehaviourReference {
                        networkBehaviour = behaviour, connectedClientCallback = connectedCallback, disconnectedDelegate = disconnectedCallback, localRPCDelegate = localRPCCallback, ownerChangeDelegate = ownerChangeCallback
                    }
                };
                m_LocalPendingBehavioursList.Add(pendingBehaviour.reference.networkBehaviour);
                m_LocalPendingBehaviours.Add(uniqueHash, pendingBehaviour);
                m_HashedStrings.Add(uniqueHash, behaviour.uniqueID);
                m_BehaviourByHashedID.Add(uniqueHash, behaviour);
            }
        }
コード例 #2
0
        //Server only
        public void SpawnOnNetworkServer(NetworkBehaviour behaviour, ServerBehaviourConnectedDelegate connectedCallback, BehaviourDisconnectedDelegate disconnectCallback, NetworkBehaviourRPCDelegate localRPCCallback, OwnerChangeDelegate ownerChangeCallback, ulong owner, List <ulong> observers, Stream spawnPayload)
        {
            if (behaviour == null || !behaviour.isNetworkSpawned || behaviour.isNetworkReady)
            {
                throw new InvalidOperationException("NetworkBehaviourManager.SpawnOnNetworkServer is only allowed to be called internally by a Network Behaviour.");
            }

            ulong newNetworkID = GetNewNetworkID();

            if (!string.IsNullOrWhiteSpace(behaviour.uniqueID))
            {
                ulong uniqueHash = behaviour.uniqueID.GetStableHash(networkManager.config.rpcHashSize);
                if (m_BehaviourByHashedID.TryGetValue(uniqueHash, out NetworkBehaviour otherBehaviour))
                {
                    if (!BehaviourWasDestroyed(otherBehaviour))
                    {
                        throw new NetworkException("A Network Behaviour already has the unique ID '" + behaviour.uniqueID + "'.");
                    }
                }

                if (m_HashedStrings.TryGetValue(uniqueHash, out string otherUniqueID))
                {
                    if (otherUniqueID == behaviour.uniqueID)
                    {
                        throw new NetworkException("A Network Behaviour already has the unique ID '" + behaviour.uniqueID + "'.");
                    }
                    else
                    {
                        //This occurs when 2 different strings hash to the same value from MLAPI.Hashing.GetStableHash.
                        throw new NetworkException("A hash collision occurred. Either change the unique ID or increase the hash size in the config. '" + behaviour.uniqueID + "' and '" + otherUniqueID + "' both hashed to '" + uniqueHash + "'.");
                    }
                }
                m_HashedStrings.Add(uniqueHash, behaviour.uniqueID);
                m_BehaviourByHashedID.Add(uniqueHash, behaviour);
            }

            m_NetworkBehaviours.Add(new NetworkBehaviourReference()
            {
                networkBehaviour = behaviour, connectedServerCallback = connectedCallback, disconnectedDelegate = disconnectCallback, localRPCDelegate = localRPCCallback, ownerChangeDelegate = ownerChangeCallback
            });
            m_NetworkBehaviourDictionary.Add(newNetworkID, m_NetworkBehaviours[m_NetworkBehaviours.Count - 1]);

            //Spawn payload
            if (spawnPayload == null)
            {
                connectedCallback.Invoke(newNetworkID, owner, networkManager.serverID, observers, null);
            }
            else
            {
                using (PooledBitStream payloadStream = PooledBitStream.Get())
                {
                    payloadStream.CopyFrom(spawnPayload);
                    payloadStream.Position = 0;
                    connectedCallback.Invoke(newNetworkID, owner, networkManager.serverID, observers, payloadStream);
                }
            }
        }