private void DoVisibleShowWrite(PooledBitStream stream, Stream spawnPayload) { if (!isServer) { throw new NotServerException("Only the server can change visibility of a Network Behaviour."); } if (!isNetworkSpawned) { throw new NetworkException("This Network Behaviour is not spawned on the network. Make sure this Network Behaviour is spawned using the NetworkBehaviour.SpawnOnNetwork function before changing it's visiblity."); } //Do message using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { //Write behaviour info and type writer.WriteUInt64Packed(networkID); writer.WriteUInt64Packed(ownerID); writer.WriteUInt64Packed(RPCTypeDefinition.GetHashFromType(GetType())); if (string.IsNullOrWhiteSpace(uniqueID)) { writer.WriteBool(false); } else { writer.WriteBool(true); writer.WriteUInt64Packed(m_UniqueHash); } writer.WriteBool(ownerCanUnspawn); writer.WriteBool(destroyOnUnspawn); //Write payload writer.WriteBool(spawnPayload != null); if (spawnPayload != null) { spawnPayload.Position = 0; writer.WriteInt32Packed((int)spawnPayload.Length); stream.CopyFrom(spawnPayload); } if (networkManager.enableLogging) { Debug.Log("Sending to clients the new behaviour " + GetType()); } } }
public void HandleSpawnMessage(ulong clientID, Stream stream, float receiveTime) { using (PooledBitReader reader = PooledBitReader.Get(stream)) { ulong networkID = reader.ReadUInt64Packed(); //Network ID ulong ownerID = reader.ReadUInt64Packed(); //Owner Type behaviourType = RPCTypeDefinition.GetTypeFromHash(reader.ReadUInt64Packed()); bool hasUniqueHash = reader.ReadBool(); ulong uniqueHash = 0; if (hasUniqueHash) { uniqueHash = reader.ReadUInt64Packed(); } bool ownerCanUnspawn = reader.ReadBool(); bool destroyOnUnspawn = reader.ReadBool(); //Read spawn payload PooledBitStream payloadStream = null; if (reader.ReadBool()) { payloadStream = PooledBitStream.Get(); int payloadLength = reader.ReadInt32Packed(); payloadStream.CopyUnreadFrom(stream, payloadLength); stream.Position += payloadLength; payloadStream.Position = 0; } if (networkManager.enableLogging) { string s = "Received add object event from server. Object: " + behaviourType.ToString() + " | Network ID: " + networkID + " | Owner: " + ownerID + " | Has Unique Hash: " + hasUniqueHash + " | "; if (hasUniqueHash) { s += uniqueHash + " | "; } s += "Owner Can Unspawn: " + ownerCanUnspawn + " | Destroy On Unspawn: " + destroyOnUnspawn; Debug.Log(s); } if (hasUniqueHash) { if (m_LocalPendingBehaviours.TryGetValue(uniqueHash, out PendingNetworkBehaviour pendingBehaviour)) { if (pendingBehaviour.reference.networkBehaviour.GetType() != behaviourType) { Debug.LogError("Received add object message where the remote network behaviour type(" + behaviourType.ToString() + ") does not match up with local network behaviour type (" + pendingBehaviour.reference.networkBehaviour.GetType() + ") with same unique ID(" + pendingBehaviour.reference.networkBehaviour.uniqueID + ").", pendingBehaviour.reference.networkBehaviour); return; } //Clean up pending m_LocalPendingBehaviours.Remove(uniqueHash); m_LocalPendingBehavioursList.Remove(pendingBehaviour.reference.networkBehaviour); OnObjectConnectSuccess(pendingBehaviour.reference, networkID, ownerID, ownerCanUnspawn, destroyOnUnspawn, payloadStream); if (payloadStream != null) { payloadStream.Dispose(); } } else if (m_RemotePendingBehavioursHashes.ContainsKey(uniqueHash)) { Debug.LogError("Received duplicate 'add object' message for hash '" + uniqueHash + "'."); return; } else if (m_RemotePendingBehaviours.ContainsKey(networkID)) { Debug.LogError("Recevied duplicate 'add object' message for network ID '" + networkID + "'."); return; } else { PendingNetworkBehaviour pendingBehaviourReference = new PendingNetworkBehaviour() { isRemoteBehaviour = true, uniqueHash = uniqueHash, ownerID = ownerID, networkID = networkID, ownerCanUnspawn = ownerCanUnspawn, destroyOnUnspawn = destroyOnUnspawn, spawnPayload = payloadStream }; m_RemotePendingBehavioursHashes.Add(uniqueHash, pendingBehaviourReference); m_RemotePendingBehaviours.Add(networkID, pendingBehaviourReference); } } else //No unique hash { //Build network behaviour GameObject behaviourObject = new GameObject("Server Network Object"); //All this stuff just in case the instantiate behaviour also instantiates other network behaviours in its awake function m_TrackAwakeSpawns = true; NetworkBehaviour serverBehaviour = (NetworkBehaviour)behaviourObject.AddComponent(behaviourType); m_TrackAwakeSpawns = false; if (m_BehavioursAwaitingSpawn.Count > 0) { while (m_BehavioursAwaitingSpawn.Count > 0) { NetworkBehaviourReference reference = m_BehavioursAwaitingSpawn.Dequeue(); if (reference.networkBehaviour == serverBehaviour) { OnObjectConnectSuccess(reference, networkID, ownerID, ownerCanUnspawn, destroyOnUnspawn, payloadStream); if (payloadStream != null) { payloadStream.Dispose(); } } else { SpawnOnNetworkClient(reference.networkBehaviour, reference.connectedClientCallback, reference.disconnectedDelegate, reference.localRPCDelegate, reference.ownerChangeDelegate); } } } if (!serverBehaviour.isNetworkSpawned) { serverBehaviour.uniqueID = "NETWORK_SERVER_BEHAVIOUR_" + networkID.ToString(); serverBehaviour.SpawnOnNetwork(); ulong hash = serverBehaviour.uniqueID.GetStableHash(networkManager.config.rpcHashSize); PendingNetworkBehaviour pendingBehaviour = m_LocalPendingBehaviours[hash]; //Clean up pending m_LocalPendingBehaviours.Remove(uniqueHash); m_LocalPendingBehavioursList.Remove(serverBehaviour); OnObjectConnectSuccess(pendingBehaviour.reference, networkID, ownerID, ownerCanUnspawn, destroyOnUnspawn, payloadStream); if (payloadStream != null) { payloadStream.Dispose(); } } } } }