Пример #1
0
		/// <summary>
		/// Returns a base64 encoded version of the config
		/// </summary>
		/// <returns></returns>
		public string ToBase64()
		{
			NetworkConfig config = this;
			using (PooledBitStream stream = PooledBitStream.Get())
			{
				using (PooledBitWriter writer = PooledBitWriter.Get(stream))
				{
					writer.WriteString(config.protocalVersion);

					writer.WriteInt32Packed(config.receiveTickrate);
					writer.WriteInt32Packed(config.maxReceiveEventsPerTickRate);
					writer.WriteInt32Packed(config.eventTickrate);
					writer.WriteInt32Packed(config.clientConnectionBufferTimeout);
					writer.WriteInt32Packed(config.secondsHistory);
					writer.WriteBool(config.enableTimeResync);
					writer.WriteBool(config.ensureNetworkedVarLengthSafety);
					writer.WriteBits((byte)config.rpcHashSize, 3);
					writer.WriteBool(recycleNetworkIDs);
					writer.WriteSinglePacked(networkIDRecycleDelay);
					writer.WriteBool(enableNetworkedVar);
                    writer.WriteBool(clientSendSceneEvents);
                    writer.WriteBool(serverSendSceneEvents);
                    stream.PadStream();

					return Convert.ToBase64String(stream.ToArray());
				}
			}
		}
        /// <summary>
        /// Hides an object from all clients.
        /// Server only.
        /// </summary>
        public void NetworkHideAll()
        {
            //A faster message send bypassing MessageSender completely

            using (PooledBitStream baseStream = PooledBitStream.Get())
            {
                DoVisibleHideWrite(baseStream);
                baseStream.PadStream();

                using (BitStream stream = MessagePacker.WrapMessage(networkBehaviourManager.unspawnMessageType, 0, baseStream, SecuritySendFlags.None))
                {
                    using (List <ulong> .Enumerator clients = networkManager.clients)
                    {
                        while (clients.MoveNext())
                        {
                            if (clients.Current == networkManager.serverID)
                            {
                                continue;
                            }
                            if (!m_PendingObservers.Remove(clients.Current) && !m_Observers.Remove(clients.Current))
                            {
                                continue;
                            }

                            networkManager.transport.Send(clients.Current, new ArraySegment <byte>(stream.GetBuffer(), 0, (int)stream.Length), networkManager.networkInternalChannel);
                        }
                    }
                }
            }
        }
Пример #3
0
		/// <summary>
		/// Gets a SHA256 hash of parts of the NetworkingConfiguration instance
		/// </summary>
		/// <param name="cache"></param>
		/// <returns></returns>
		public ulong GetConfig(bool cache = true)
		{
			if (ConfigHash != null && cache)
				return ConfigHash.Value;

			using (PooledBitStream stream = PooledBitStream.Get())
			{
				using (PooledBitWriter writer = PooledBitWriter.Get(stream))
				{
					writer.WriteString(protocalVersion);

					writer.WriteBool(enableNetworkedVar);
					writer.WriteBool(ensureNetworkedVarLengthSafety);
					writer.WriteBits((byte)rpcHashSize, 3);
					stream.PadStream();

					if (cache)
					{
						ConfigHash = stream.ToArray().GetStableHash64();
						return ConfigHash.Value;
					}

					return stream.ToArray().GetStableHash64();
				}
			}
		}
Пример #4
0
        /// <summary>
        /// Removes all ownership of an object from any client and returns ownership to the server. Can only be called by the server or the owner of this Network Behaviour.
        /// </summary>
        public void RemoveOwnership()
        {
            if (!networkManager.isRunning)
            {
                Debug.LogError("Cannot remove ownership. The network is not running.");
                return;
            }


            if (!isNetworkSpawned)
            {
                throw new NetworkException("Cannot change ownership. This Network Behaviour is not spawned.");
            }

            if (!isServer && !isOwner)
            {
                throw new NotServerException("Only the server can call NetworkBehaviour.RemoveOwnership when they are not the owner of the Network Behaviour.");
            }

            //Owner does not change
            if (isOwnedByServer)
            {
                return;
            }

            if (isServer)
            {
                m_OwnerClientID = networkManager.serverID;
                OnGainedOwnership();
            }

            using (PooledBitStream baseStream = PooledBitStream.Get())
            {
                DoOwnershipWrite(baseStream, networkManager.serverID);
                if (isServer)
                {
                    baseStream.PadStream();

                    using (BitStream stream = MessagePacker.WrapMessage(networkBehaviourManager.ownerChangeMessageType, 0, baseStream, SecuritySendFlags.None))
                    {
                        using (HashSet <ulong> .Enumerator observers = GetObservers())
                        {
                            while (observers.MoveNext())
                            {
                                if (observers.Current == NetworkManager.Get().serverID)
                                {
                                    continue;
                                }

                                NetworkManager.Get().transport.Send(observers.Current, new ArraySegment <byte>(stream.GetBuffer(), 0, (int)stream.Length), networkManager.networkInternalChannel);
                            }
                        }
                    }
                }
                else
                {
                    MessageSender.Send(networkManager.serverID, networkBehaviourManager.ownerChangeMessageType, networkManager.networkInternalChannel, baseStream);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Gets a SHA256 hash of parts of the NetworkingConfiguration instance
        /// </summary>
        /// <param name="cache"></param>
        /// <returns></returns>
        public ulong GetConfig(bool cache = true)
        {
            if (ConfigHash != null && cache)
            {
                return(ConfigHash.Value);
            }

            Sort();

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteUInt16Packed(ProtocolVersion);
                    writer.WriteString(MLAPIConstants.MLAPI_PROTOCOL_VERSION);

                    for (int i = 0; i < Channels.Count; i++)
                    {
                        writer.WriteString(Channels[i].Name);
                        writer.WriteByte((byte)Channels[i].Type);
                    }

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

                    if (HandleObjectSpawning && ForceSamePrefabs)
                    {
                        List <NetworkedPrefab> sortedPrefabList = NetworkedPrefabs.OrderBy(x => x.hash).ToList();
                        for (int i = 0; i < sortedPrefabList.Count; i++)
                        {
                            writer.WriteUInt64Packed(sortedPrefabList[i].hash);
                        }
                    }

                    writer.WriteBool(ForceSamePrefabs);
                    writer.WriteBool(HandleObjectSpawning);
                    writer.WriteBool(EnableEncryption);
                    writer.WriteBool(EnableSceneSwitching);
                    writer.WriteBool(SignKeyExchange);
                    writer.WriteBits((byte)RpcHashSize, 3);
                    writer.WriteBits((byte)PrefabHashSize, 3);
                    stream.PadStream();

                    if (cache)
                    {
                        ConfigHash = stream.ToArray().GetStableHash64();
                        return(ConfigHash.Value);
                    }

                    return(stream.ToArray().GetStableHash64());
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Returns a base64 encoded version of the config
        /// </summary>
        /// <returns></returns>
        public string ToBase64()
        {
            NetworkConfig config = this;

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteUInt16Packed(config.ProtocolVersion);
                    writer.WriteBits((byte)config.Transport, 5);

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

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

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

                    writer.WriteInt32Packed(config.MessageBufferSize);
                    writer.WriteInt32Packed(config.ReceiveTickrate);
                    writer.WriteInt32Packed(config.MaxReceiveEventsPerTickRate);
                    writer.WriteInt32Packed(config.SendTickrate);
                    writer.WriteInt32Packed(config.EventTickrate);
                    writer.WriteInt32Packed(config.MaxConnections);
                    writer.WriteInt32Packed(config.ConnectPort);
                    writer.WriteString(config.ConnectAddress);
                    writer.WriteInt32Packed(config.ClientConnectionBufferTimeout);
                    writer.WriteBool(config.ConnectionApproval);
                    writer.WriteInt32Packed(config.SecondsHistory);
                    writer.WriteBool(config.HandleObjectSpawning);
                    writer.WriteBool(config.EnableEncryption);
                    writer.WriteBool(config.SignKeyExchange);
                    writer.WriteBool(config.EnableSceneSwitching);
                    writer.WriteInt32Packed(config.LoadSceneTimeOut);
                    writer.WriteBool(config.EnableTimeResync);
                    writer.WriteBits((byte)config.RpcHashSize, 3);
                    stream.PadStream();

                    return(Convert.ToBase64String(stream.ToArray()));
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Gets a SHA256 hash of parts of the NetworkingConfiguration instance
        /// </summary>
        /// <param name="cache"></param>
        /// <returns></returns>
        public ulong GetConfig(bool cache = true)
        {
            if (ConfigHash != null && cache)
            {
                return(ConfigHash.Value);
            }

            Sort();

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteUInt16Packed(ProtocolVersion);
                    writer.WriteString(MLAPIConstants.MLAPI_PROTOCOL_VERSION);

                    if (EnableSceneManagement && !AllowRuntimeSceneChanges)
                    {
                        for (int i = 0; i < RegisteredScenes.Count; i++)
                        {
                            writer.WriteString(RegisteredScenes[i]);
                        }
                    }

                    if (ForceSamePrefabs)
                    {
                        List <NetworkedPrefab> sortedPrefabList = NetworkedPrefabs.OrderBy(x => x.Hash).ToList();
                        for (int i = 0; i < sortedPrefabList.Count; i++)
                        {
                            writer.WriteUInt64Packed(sortedPrefabList[i].Hash);
                        }
                    }

                    writer.WriteBool(EnableNetworkedVar);
                    writer.WriteBool(ForceSamePrefabs);
                    writer.WriteBool(UsePrefabSync);
                    writer.WriteBool(EnableSceneManagement);
                    writer.WriteBool(EnsureNetworkedVarLengthSafety);
                    writer.WriteBool(EnableEncryption);
                    writer.WriteBool(SignKeyExchange);
                    writer.WriteBits((byte)RpcHashSize, 2);
                    stream.PadStream();

                    if (cache)
                    {
                        ConfigHash = stream.ToArray().GetStableHash64();
                        return(ConfigHash.Value);
                    }

                    return(stream.ToArray().GetStableHash64());
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Returns a base64 encoded version of the config
        /// </summary>
        /// <returns></returns>
        public string ToBase64()
        {
            NetworkConfig config = this;

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteUInt16Packed(config.ProtocolVersion);

                    writer.WriteUInt16Packed((ushort)config.RegisteredScenes.Count);

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

                    writer.WriteInt32Packed(config.ServerTargetFramerate);
                    writer.WriteInt32Packed(config.NetworkedTransformTickrate);
                    writer.WriteInt32Packed(config.ClientCommandTickrate);
                    writer.WriteInt32Packed(config.MaxReceiveEventsPerTickRate);
                    writer.WriteInt32Packed(config.LagCompensationTickRate);
                    writer.WriteInt32Packed(config.EventTickrate);
                    writer.WriteInt32Packed(config.ClientConnectionBufferTimeout);
                    writer.WriteBool(config.ConnectionApproval);
                    writer.WriteInt32Packed(config.SecondsHistory);
                    writer.WriteBool(config.EnableEncryption);
                    writer.WriteBool(config.SignKeyExchange);
                    writer.WriteInt32Packed(config.LoadSceneTimeOut);
                    writer.WriteBool(config.EnableTimeResync);
                    writer.WriteBool(config.EnsureNetworkedVarLengthSafety);
                    writer.WriteBits((byte)config.RpcHashSize, 2);
                    writer.WriteBool(ForceSamePrefabs);
                    writer.WriteBool(UsePrefabSync);
                    writer.WriteBool(EnableSceneManagement);
                    writer.WriteBool(RecycleNetworkIds);
                    writer.WriteSinglePacked(NetworkIdRecycleDelay);
                    writer.WriteBool(EnableNetworkedVar);
                    writer.WriteBool(AllowRuntimeSceneChanges);
                    writer.WriteBool(EnableNetworkLogs);
                    stream.PadStream();

                    return(Convert.ToBase64String(stream.ToArray()));
                }
            }
        }
        /// <summary>
        /// Does not supress errors invloving clients that already have visibility of this Network Behaviour.
        /// Server only.
        /// </summary>
        /// <param name="clientIDs"></param>
        public void NetworkShow(List <ulong> clientIDs, Stream spawnPayload = null)
        {
            //A faster message send bypassing MessageSender completely

            if (clientIDs == null)
            {
                throw new ArgumentNullException(nameof(clientIDs));
            }

            using (PooledBitStream baseStream = PooledBitStream.Get())
            {
                DoVisibleShowWrite(baseStream, spawnPayload);
                baseStream.PadStream();
                if (clientIDs.Count == 0)
                {
                    return;                      //No one to send to.
                }
                using (BitStream stream = MessagePacker.WrapMessage(networkBehaviourManager.spawnMessageType, 0, baseStream, SecuritySendFlags.None))
                {
                    for (int i = 0; i < clientIDs.Count; i++)
                    {
                        if (clientIDs[i] == NetworkManager.Get().serverID)
                        {
                            continue;
                        }
                        if (m_PendingObservers.Contains(clientIDs[i]))
                        {
                            Debug.LogError("This Network Behaviour is already pending visibility to client '" + clientIDs[i] + "'. Watch for a call to NetworkStart for when it successfully connects.", this);
                            continue;
                        }
                        if (m_Observers.Contains(clientIDs[i]))
                        {
                            Debug.LogError("This Network Behaviour is already pending visibility to client '" + clientIDs[i] + "'. Watch for a call to NetworkStart for when it successfully connects.", this);
                            continue;
                        }
                        m_PendingObservers.Add(clientIDs[i]);

                        NetworkManager.Get().transport.Send(clientIDs[i], new ArraySegment <byte>(stream.GetBuffer(), 0, (int)stream.Length), networkManager.networkInternalChannel);
                    }
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Returns a base64 encoded version of the config
        /// </summary>
        /// <returns></returns>
        public string ToBase64()
        {
            NetworkConfig config = this;

            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteUInt16Packed(config.ProtocolVersion);

                    writer.WriteUInt16Packed((ushort)config.RegisteredScenes.Count);

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

                    writer.WriteInt32Packed(config.ReceiveTickrate);
                    writer.WriteInt32Packed(config.MaxReceiveEventsPerTickRate);
                    writer.WriteInt32Packed(config.SendTickrate);
                    writer.WriteInt32Packed(config.EventTickrate);
                    writer.WriteInt32Packed(config.ClientConnectionBufferTimeout);
                    writer.WriteBool(config.ConnectionApproval);
                    writer.WriteInt32Packed(config.SecondsHistory);
                    writer.WriteBool(config.EnableEncryption);
                    writer.WriteBool(config.SignKeyExchange);
                    writer.WriteInt32Packed(config.LoadSceneTimeOut);
                    writer.WriteBool(config.EnableTimeResync);
                    writer.WriteBits((byte)config.RpcHashSize, 3);
                    writer.WriteBool(ForceSamePrefabs);
                    writer.WriteBool(UsePrefabSync);
                    writer.WriteBool(EnableNetworkedVar);
                    stream.PadStream();

                    return(Convert.ToBase64String(stream.ToArray()));
                }
            }
        }
        /// <summary>
        /// Hides an object from a specific clients.
        /// Server only.
        /// </summary>
        /// <param name="clientIDs">The clients to hide the object from.</param>
        public void NetworkHide(List <ulong> clientIDs)
        {
            //A faster message send bypassing MessageSender completely

            if (clientIDs == null)
            {
                throw new ArgumentNullException(nameof(clientIDs));
            }

            using (PooledBitStream baseStream = PooledBitStream.Get())
            {
                DoVisibleHideWrite(baseStream);
                baseStream.PadStream();
                if (clientIDs.Count == 0)
                {
                    return;                      //No one to send to.
                }
                using (BitStream stream = MessagePacker.WrapMessage(networkBehaviourManager.unspawnMessageType, 0, baseStream, SecuritySendFlags.None))
                {
                    for (int i = 0; i < clientIDs.Count; i++)
                    {
                        if (clientIDs[i] == networkManager.serverID)
                        {
                            continue;
                        }
                        if (!m_PendingObservers.Remove(clientIDs[i]) && !m_Observers.Remove(clientIDs[i]))
                        {
                            Debug.LogError("This Network Behaviour is already not visible to client '" + clientIDs[i] + "'.", this);
                            continue;
                        }

                        networkManager.transport.Send(clientIDs[i], new ArraySegment <byte>(stream.GetBuffer(), 0, (int)stream.Length), networkManager.networkInternalChannel);
                    }
                }
            }
        }
Пример #12
0
        /// <summary>
        /// Changes the owner of the object. Can only be called from the server or the owner of this Network Behaviour.
        /// </summary>
        /// <param name="targetClientID">The new owner clientId</param>
        public void SetOwner(ulong targetClientID)
        {
            if (!networkManager.isRunning)
            {
                Debug.LogError("Cannot set ownership. The network is not running.");
                return;
            }

            if (!isServer)
            {
                if (isOwner && targetClientID == networkManager.serverID)
                {
                    RemoveOwnership();
                    return;
                }
                throw new NotServerException("Only the server can call NetworkBehaviour.SetOwner to target anything but the server.");
            }

            if (!isNetworkSpawned)
            {
                throw new NetworkException("Cannot change ownership. This Network Behaviour is not spawned.");
            }

            if (!IsNetworkVisibleTo(targetClientID))
            {
                throw new NetworkException("Cannot change ownership to a client that does not have visibility of this Network Behaviour.");
            }

            //Owner does not change
            if (targetClientID == ownerID)
            {
                return;
            }

            if (targetClientID == networkManager.serverID)
            {
                RemoveOwnership();
                return;
            }

            if (isOwner)
            {
                m_OwnerClientID = targetClientID;
                OnLostOwnership();
            }
            else //This may seem redundant but we want ownership changes to be set before the OnLostOwnership call
            {
                m_OwnerClientID = targetClientID;
            }

            //Send to all (not pending)observers
            using (PooledBitStream baseStream = PooledBitStream.Get())
            {
                DoOwnershipWrite(baseStream, targetClientID);
                baseStream.PadStream();

                using (BitStream stream = MessagePacker.WrapMessage(networkBehaviourManager.ownerChangeMessageType, 0, baseStream, SecuritySendFlags.None))
                {
                    using (HashSet <ulong> .Enumerator observers = GetObservers())
                    {
                        while (observers.MoveNext())
                        {
                            if (observers.Current == NetworkManager.Get().serverID)
                            {
                                continue;
                            }

                            NetworkManager.Get().transport.Send(observers.Current, new ArraySegment <byte>(stream.GetBuffer(), 0, (int)stream.Length), networkManager.networkInternalChannel);
                        }
                    }
                }
            }
        }