internal static void OnFirstSceneSwitchSync(uint sceneIndex, Guid switchSceneGuid)
        {
            if (!SceneIndexToString.ContainsKey(sceneIndex) || !RegisteredSceneNames.Contains(SceneIndexToString[sceneIndex]))
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                {
                    NetworkLog.LogWarning("Server requested a scene switch to a non-registered scene");
                }

                return;
            }

            if (SceneManager.GetActiveScene().name == SceneIndexToString[sceneIndex])
            {
                return; //This scene is already loaded. This usually happends at first load
            }

            s_LastScene = SceneManager.GetActiveScene();
            string sceneName = SceneIndexToString[sceneIndex];

            s_NextSceneName         = sceneName;
            CurrentActiveSceneIndex = SceneNameToIndex[sceneName];

            IsSpawnedObjectsPendingInDontDestroyOnLoad = true;
            SceneManager.LoadScene(sceneName);

            using (var buffer = PooledNetworkBuffer.Get())
                using (var writer = PooledNetworkWriter.Get(buffer))
                {
                    writer.WriteByteArray(switchSceneGuid.ToByteArray());
                    InternalMessageSender.Send(NetworkManager.Singleton.ServerClientId, NetworkConstants.CLIENT_SWITCH_SCENE_COMPLETED, NetworkChannel.Internal, buffer);
                }

            s_IsSwitching = false;
        }
        internal static void HandleConnectionRequest(ulong clientId, Stream stream)
        {
            using (PooledBitReader reader = PooledBitReader.Get(stream))
            {
                ulong configHash = reader.ReadUInt64Packed();
                if (!NetworkingManager.Singleton.NetworkConfig.CompareConfig(configHash))
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("NetworkConfiguration mismatch. The configuration between the server and client does not match");
                    }
                    NetworkingManager.Singleton.DisconnectClient(clientId);
                    return;
                }

                if (NetworkingManager.Singleton.NetworkConfig.ConnectionApproval)
                {
                    byte[] connectionBuffer = reader.ReadByteArray();
                    NetworkingManager.Singleton.InvokeConnectionApproval(connectionBuffer, clientId, (createPlayerObject, playerPrefabHash, approved, position, rotation) =>
                    {
                        NetworkingManager.Singleton.HandleApproval(clientId, createPlayerObject, playerPrefabHash, approved, position, rotation);
                    });
                }
                else
                {
                    NetworkingManager.Singleton.HandleApproval(clientId, NetworkingManager.Singleton.NetworkConfig.CreatePlayerPrefab, null, true, null, null);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Sends unnamed message to a list of clients
        /// </summary>
        /// <param name="clientIds">The clients to send to, sends to everyone if null</param>
        /// <param name="stream">The message stream containing the data</param>
        /// <param name="channel">The channel to send the data on</param>
        /// <param name="security">The security settings to apply to the message</param>
        public static void SendUnnamedMessage(List <ulong> clientIds, BitStream stream, string channel = null, SecuritySendFlags security = SecuritySendFlags.None)
        {
            if (!NetworkingManager.Singleton.IsServer)
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
                {
                    NetworkLog.LogWarning("Can not send unnamed messages to multiple users as a client");
                }
                return;
            }

            if (clientIds == null)
            {
                for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++)
                {
                    InternalMessageSender.Send(NetworkingManager.Singleton.ConnectedClientsList[i].ClientId, MLAPIConstants.MLAPI_UNNAMED_MESSAGE, string.IsNullOrEmpty(channel) ? "MLAPI_DEFAULT_MESSAGE" : channel, stream, security, null);
                }
            }
            else
            {
                for (int i = 0; i < clientIds.Count; i++)
                {
                    InternalMessageSender.Send(clientIds[i], MLAPIConstants.MLAPI_UNNAMED_MESSAGE, string.IsNullOrEmpty(channel) ? "MLAPI_DEFAULT_MESSAGE" : channel, stream, security, null);
                }
            }
        }
        // Called on client
        internal static void OnSceneSwitch(uint sceneIndex, Guid switchSceneGuid, Stream objectStream)
        {
            if (!sceneIndexToString.ContainsKey(sceneIndex) || !registeredSceneNames.Contains(sceneIndexToString[sceneIndex]))
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                {
                    NetworkLog.LogWarning("Server requested a scene switch to a non registered scene");
                }
                return;
            }

            lastScene = SceneManager.GetActiveScene();

            // Move ALL networked objects to the temp scene
            MoveObjectsToDontDestroyOnLoad();

            isSpawnedObjectsPendingInDontDestroyOnLoad = true;

            string sceneName = sceneIndexToString[sceneIndex];

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

            nextSceneName = sceneName;

            sceneLoad.completed += (AsyncOperation asyncOp2) =>
            {
                OnSceneLoaded(switchSceneGuid, objectStream);
            };

            if (OnSceneSwitchStarted != null)
            {
                OnSceneSwitchStarted(sceneLoad);
            }
        }
        internal static void OnFirstSceneSwitchSync(uint sceneIndex, Guid switchSceneGuid)
        {
            if (!sceneIndexToString.ContainsKey(sceneIndex) || !registeredSceneNames.Contains(sceneIndexToString[sceneIndex]))
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                {
                    NetworkLog.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];

            nextSceneName           = sceneName;
            CurrentActiveSceneIndex = sceneNameToIndex[sceneName];

            isSpawnedObjectsPendingInDontDestroyOnLoad = true;
            SceneManager.LoadScene(sceneName);

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

            isSwitching = false;
        }
Beispiel #6
0
        /// <summary>
        /// Sends the named message
        /// </summary>
        /// <param name="name">The message name to send</param>
        /// <param name="clientIds">The clients to send to, sends to everyone if null</param>
        /// <param name="stream">The message stream containing the data</param>
        /// <param name="channel">The channel to send the data on</param>
        /// <param name="security">The security settings to apply to the message</param>
        public static void SendNamedMessage(string name, List <ulong> clientIds, Stream stream, string channel = null, SecuritySendFlags security = SecuritySendFlags.None)
        {
            ulong hash = NetworkedBehaviour.HashMethodName(name);

            using (PooledBitStream messageStream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(messageStream))
                {
                    writer.WriteUInt64Packed(hash);
                }

                messageStream.CopyFrom(stream);

                if (!NetworkingManager.Singleton.IsServer)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
                    {
                        NetworkLog.LogWarning("Can not send named messages to multiple users as a client");
                    }
                    return;
                }

                InternalMessageSender.Send(MLAPIConstants.MLAPI_NAMED_MESSAGE, string.IsNullOrEmpty(channel) ? "MLAPI_DEFAULT_MESSAGE" : channel, clientIds, messageStream, security, null);
            }
        }
        internal static void HandleSyncedVar(ulong clientId, Stream stream)
        {
            using (PooledBitReader reader = PooledBitReader.Get(stream))
            {
                ulong  networkId  = reader.ReadUInt64Packed();
                ushort orderIndex = reader.ReadUInt16Packed();

                if (SpawnManager.SpawnedObjects.ContainsKey(networkId))
                {
                    NetworkedBehaviour instance = SpawnManager.SpawnedObjects[networkId].GetBehaviourAtOrderIndex(orderIndex);
                    if (instance == null)
                    {
                        if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                        {
                            NetworkLog.LogWarning("SyncedVar message received for a non existant behaviour");
                        }
                        return;
                    }
                    NetworkedBehaviour.HandleSyncedVarValue(instance.syncedVars, stream, clientId, instance);
                }
                else
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("SyncedVar message received for a non existant object with id: " + networkId);
                    }
                    return;
                }
            }
        }
        internal static void HandleServerRPCResponse(ulong clientId, Stream stream)
        {
            using (PooledBitReader reader = PooledBitReader.Get(stream))
            {
                ulong responseId = reader.ReadUInt64Packed();

                if (ResponseMessageManager.ContainsKey(responseId))
                {
                    RpcResponseBase responseBase = ResponseMessageManager.GetByKey(responseId);

                    ResponseMessageManager.Remove(responseId);

                    responseBase.IsDone       = true;
                    responseBase.Result       = reader.ReadObjectPacked(responseBase.Type);
                    responseBase.IsSuccessful = true;
                }
                else
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("ServerRPCResponse message received for a non existant responseId: " + responseId + ". This response is lost.");
                    }
                }
            }
        }
        internal static void HandleServerRPC(ulong clientId, Stream stream)
        {
            using (PooledBitReader reader = PooledBitReader.Get(stream))
            {
                ulong  networkId   = reader.ReadUInt64Packed();
                ushort behaviourId = reader.ReadUInt16Packed();
                ulong  hash        = reader.ReadUInt64Packed();

                if (SpawnManager.SpawnedObjects.ContainsKey(networkId))
                {
                    NetworkedBehaviour behaviour = SpawnManager.SpawnedObjects[networkId].GetBehaviourAtOrderIndex(behaviourId);

                    if (behaviour == null)
                    {
                        if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                        {
                            NetworkLog.LogWarning("ServerRPC message received for a non existant behaviour. NetworkId: " + networkId + ", behaviourIndex: " + behaviourId);
                        }
                    }
                    else
                    {
                        behaviour.OnRemoteServerRPC(hash, clientId, stream);
                    }
                }
                else if (NetworkingManager.Singleton.IsServer || !NetworkingManager.Singleton.NetworkConfig.EnableMessageBuffering)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("ServerRPC message received for a non existant object with id: " + networkId + ". This message is lost.");
                    }
                }
            }
        }
Beispiel #10
0
        /// <summary>
        /// Retrieves a PooledBitReader
        /// </summary>
        /// <param name="stream">The stream the reader should read from</param>
        /// <returns>A PooledBitReader</returns>
        public static PooledBitReader GetReader(Stream stream)
        {
            if (readers.Count == 0)
            {
                if (createdReaders == 254)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("255 readers have been created. Did you forget to dispose?");
                    }
                }
                else if (createdReaders < 255)
                {
                    createdReaders++;
                }

                return(new PooledBitReader(stream));
            }

            PooledBitReader reader = readers.Dequeue();

            reader.SetStream(stream);

            return(reader);
        }
Beispiel #11
0
        internal static void Send(ulong clientId, byte messageType, string channelName, BitStream messageStream, SecuritySendFlags flags, NetworkedObject targetObject)
        {
            messageStream.PadStream();

            if (NetworkingManager.Singleton.IsServer && clientId == NetworkingManager.Singleton.ServerClientId)
            {
                return;
            }

            if (targetObject != null && !targetObject.observers.Contains(clientId))
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
                {
                    NetworkLog.LogWarning("Silently suppressed send call because it was directed to an object without visibility");
                }
                return;
            }

            using (BitStream stream = MessagePacker.WrapMessage(messageType, clientId, messageStream, flags))
            {
                NetworkProfiler.StartEvent(TickType.Send, (uint)stream.Length, channelName, MLAPIConstants.MESSAGE_NAMES[messageType]);

                NetworkingManager.Singleton.NetworkConfig.NetworkTransport.Send(clientId, new ArraySegment <byte>(stream.GetBuffer(), 0, (int)stream.Length), channelName);

                NetworkProfiler.EndEvent();
            }
        }
        /// <summary>
        /// Retrieves a PooledNetworkWriter
        /// </summary>
        /// <param name="stream">The stream the writer should write to</param>
        /// <returns>A PooledNetworkWriter</returns>
        public static PooledNetworkWriter GetWriter(Stream stream)
        {
            if (s_Writers.Count == 0)
            {
                if (s_CreatedWriters == 254)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("255 writers have been created. Did you forget to dispose?");
                    }
                }
                else if (s_CreatedWriters < 255)
                {
                    s_CreatedWriters++;
                }

                return(new PooledNetworkWriter(stream));
            }

            PooledNetworkWriter writer = s_Writers.Dequeue();

            writer.SetStream(stream);

            return(writer);
        }
        internal static void HandleConnectionRequest(ulong clientId, Stream stream)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleConnectionRequest.Begin();
#endif
            using (var reader = PooledNetworkReader.Get(stream))
            {
                ulong configHash = reader.ReadUInt64Packed();
                if (!NetworkManager.Singleton.NetworkConfig.CompareConfig(configHash))
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning($"{nameof(NetworkConfig)} mismatch. The configuration between the server and client does not match");
                    }

                    NetworkManager.Singleton.DisconnectClient(clientId);
                    return;
                }

                if (NetworkManager.Singleton.NetworkConfig.ConnectionApproval)
                {
                    byte[] connectionBuffer = reader.ReadByteArray();
                    NetworkManager.Singleton.InvokeConnectionApproval(connectionBuffer, clientId, (createPlayerObject, playerPrefabHash, approved, position, rotation) => { NetworkManager.Singleton.HandleApproval(clientId, createPlayerObject, playerPrefabHash, approved, position, rotation); });
                }
                else
                {
                    NetworkManager.Singleton.HandleApproval(clientId, NetworkManager.Singleton.NetworkConfig.CreatePlayerPrefab, null, true, null, null);
                }
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleConnectionRequest.End();
#endif
        }
        internal static ReflectionMethod Create(MethodInfo method, ParameterInfo[] parameters, int index)
        {
            RPCAttribute[] attributes = (RPCAttribute[])method.GetCustomAttributes(typeof(RPCAttribute), true);

            if (attributes.Length == 0)
            {
                return(null);
            }

            if (attributes.Length > 1)
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                {
                    NetworkLog.LogWarning("Having more than one ServerRPC or ClientRPC attribute per method is not supported.");
                }
            }

            if (method.ReturnType != typeof(void) && !SerializationManager.IsTypeSupported(method.ReturnType))
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
                {
                    NetworkLog.LogWarning("Invalid return type of RPC. Has to be either void or RpcResponse<T> with a serializable type");
                }
            }

            return(new ReflectionMethod(method, parameters, attributes[0], index));
        }
        // Called on client
        internal static void OnSceneSwitch(uint sceneIndex, Guid switchSceneGuid, Stream objectStream)
        {
            if (!SceneIndexToString.ContainsKey(sceneIndex) || !RegisteredSceneNames.Contains(SceneIndexToString[sceneIndex]))
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                {
                    NetworkLog.LogWarning("Server requested a scene switch to a non-registered scene");
                }

                return;
            }

            s_LastScene = SceneManager.GetActiveScene();

            // Move ALL NetworkObjects to the temp scene
            MoveObjectsToDontDestroyOnLoad();

            IsSpawnedObjectsPendingInDontDestroyOnLoad = true;

            string sceneName = SceneIndexToString[sceneIndex];

            var sceneLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single);

            s_NextSceneName = sceneName;

            sceneLoad.completed += asyncOp2 => OnSceneLoaded(switchSceneGuid, objectStream);
            OnSceneSwitchStarted?.Invoke(sceneLoad);
        }
        public static void NotifyProfilerListeners()
        {
            if (!s_FailsafeCheck)
            {
                return;
            }

            s_FailsafeCheck = false;

            var data         = PerformanceDataManager.GetData();
            var eventHandler = OnPerformanceDataEvent;

            if (eventHandler != null)
            {
                if (data != null)
                {
                    var transport = s_ProfilableTransportProvider.Transport;
                    if (transport != null)
                    {
                        var transportProfilerData = transport.GetTransportProfilerData();

                        PerformanceDataManager.AddTransportData(transportProfilerData);
                    }

                    eventHandler.Invoke(data);
                }
                else
                {
                    NetworkLog.LogWarning(
                        "No data available. Did you forget to call PerformanceDataManager.BeginNewTick() first?");
                }
            }
        }
        internal static void HandleNetworkVariableUpdate(ulong clientId, Stream stream, Action <ulong, PreBufferPreset> bufferCallback, PreBufferPreset bufferPreset)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleNetworkVariableUpdate.Begin();
#endif
            if (!NetworkManager.Singleton.NetworkConfig.EnableNetworkVariable)
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                {
                    NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_UPDATE)} update received but {nameof(NetworkConfig.EnableNetworkVariable)} is false");
                }

                return;
            }

            using (var reader = PooledNetworkReader.Get(stream))
            {
                ulong  networkObjectId       = reader.ReadUInt64Packed();
                ushort networkBehaviourIndex = reader.ReadUInt16Packed();

                if (NetworkSpawnManager.SpawnedObjects.ContainsKey(networkObjectId))
                {
                    var networkBehaviour = NetworkSpawnManager.SpawnedObjects[networkObjectId].GetNetworkBehaviourAtOrderIndex(networkBehaviourIndex);

                    if (networkBehaviour == null)
                    {
                        if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                        {
                            NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_UPDATE)} message received for a non-existent behaviour. {nameof(networkObjectId)}: {networkObjectId}, {nameof(networkBehaviourIndex)}: {networkBehaviourIndex}");
                        }
                    }
                    else
                    {
                        NetworkBehaviour.HandleNetworkVariableUpdate(networkBehaviour.NetworkVariableFields, stream, clientId, networkBehaviour);
                    }
                }
                else if (NetworkManager.Singleton.IsServer || !NetworkManager.Singleton.NetworkConfig.EnableMessageBuffering)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_UPDATE)} message received for a non-existent object with {nameof(networkObjectId)}: {networkObjectId}. This delta was lost.");
                    }
                }
                else
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_UPDATE)} message received for a non-existent object with {nameof(networkObjectId)}: {networkObjectId}. This delta will be buffered and might be recovered.");
                    }

                    bufferCallback(networkObjectId, bufferPreset);
                }
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleNetworkVariableUpdate.End();
#endif
        }
        /// <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.IsServer)
            {
                throw new NotServerException("Only server can start a scene switch");
            }
            else if (isSwitching)
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                {
                    NetworkLog.LogWarning("Scene switch already in progress");
                }
                return(null);
            }
            else if (!registeredSceneNames.Contains(sceneName))
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                {
                    NetworkLog.LogWarning("The scene " + sceneName + " is not registered as a switchable scene.");
                }
                return(null);
            }

            SpawnManager.ServerDestroySpawnedSceneObjects(); //Destroy current scene objects before switching.
            isSwitching = true;
            lastScene   = SceneManager.GetActiveScene();

            SceneSwitchProgress switchSceneProgress = new SceneSwitchProgress();

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

            // Move ALL networked objects to the temp scene
            MoveObjectsToDontDestroyOnLoad();

            isSpawnedObjectsPendingInDontDestroyOnLoad = true;

            // Switch scene
            AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single);

            nextSceneName = sceneName;

            sceneLoad.completed += (AsyncOperation asyncOp2) => { OnSceneLoaded(switchSceneProgress.guid, null); };

            switchSceneProgress.SetSceneLoadOperation(sceneLoad);

            if (OnSceneSwitchStarted != null)
            {
                OnSceneSwitchStarted(sceneLoad);
            }

            return(switchSceneProgress);
        }
        internal static void HandleClientRPCRequest(ulong clientId, Stream stream, string channelName, SecuritySendFlags security, Action <ulong, PreBufferPreset> bufferCallback, PreBufferPreset bufferPreset)
        {
            using (PooledBitReader reader = PooledBitReader.Get(stream))
            {
                ulong  networkId   = reader.ReadUInt64Packed();
                ushort behaviourId = reader.ReadUInt16Packed();
                ulong  hash        = reader.ReadUInt64Packed();
                ulong  responseId  = reader.ReadUInt64Packed();

                if (SpawnManager.SpawnedObjects.ContainsKey(networkId))
                {
                    NetworkedBehaviour behaviour = SpawnManager.SpawnedObjects[networkId].GetBehaviourAtOrderIndex(behaviourId);

                    if (behaviour == null)
                    {
                        if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                        {
                            NetworkLog.LogWarning("ClientRPCRequest message received for a non existant behaviour. NetworkId: " + networkId + ", behaviourIndex: " + behaviourId);
                        }
                    }
                    else
                    {
                        object result = behaviour.OnRemoteClientRPC(hash, clientId, stream);

                        using (PooledBitStream responseStream = PooledBitStream.Get())
                        {
                            using (PooledBitWriter responseWriter = PooledBitWriter.Get(responseStream))
                            {
                                responseWriter.WriteUInt64Packed(responseId);
                                responseWriter.WriteObjectPacked(result);
                            }

                            InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_CLIENT_RPC_RESPONSE, channelName, responseStream, security, null);
                        }
                    }
                }
                else if (NetworkingManager.Singleton.IsServer || !NetworkingManager.Singleton.NetworkConfig.EnableMessageBuffering)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("ClientRPCRequest message received for a non existant object with id: " + networkId + ". This message is lost.");
                    }
                }
                else
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("ClientRPCRequest message received for a non existant object with id: " + networkId + ". This message will be buffered and might be recovered.");
                    }
                    bufferCallback(networkId, bufferPreset);
                }
            }
        }
        /// <summary>
        /// Sends unnamed message to a list of clients
        /// </summary>
        /// <param name="clientIds">The clients to send to, sends to everyone if null</param>
        /// <param name="buffer">The message stream containing the data</param>
        /// <param name="networkChannel">The channel to send the data on</param>
        public static void SendUnnamedMessage(List <ulong> clientIds, NetworkBuffer buffer, NetworkChannel networkChannel = NetworkChannel.Internal)
        {
            if (!NetworkManager.Singleton.IsServer)
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
                {
                    NetworkLog.LogWarning("Can not send unnamed messages to multiple users as a client");
                }
                return;
            }

            InternalMessageSender.Send(NetworkConstants.UNNAMED_MESSAGE, networkChannel, clientIds, buffer);
        }
Beispiel #21
0
        /// <summary>
        /// Sends unnamed message to a list of clients
        /// </summary>
        /// <param name="clientIds">The clients to send to, sends to everyone if null</param>
        /// <param name="stream">The message stream containing the data</param>
        /// <param name="channel">The channel to send the data on</param>
        /// <param name="security">The security settings to apply to the message</param>
        public static void SendUnnamedMessage(List <ulong> clientIds, BitStream stream, string channel = null, SecuritySendFlags security = SecuritySendFlags.None)
        {
            if (!NetworkingManager.Singleton.IsServer)
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
                {
                    NetworkLog.LogWarning("Can not send unnamed messages to multiple users as a client");
                }
                return;
            }

            InternalMessageSender.Send(MLAPIConstants.MLAPI_UNNAMED_MESSAGE, string.IsNullOrEmpty(channel) ? "MLAPI_DEFAULT_MESSAGE" : channel, clientIds, stream, security, null);
        }
 internal static void SetCurrentSceneIndex()
 {
     if (!sceneNameToIndex.ContainsKey(SceneManager.GetActiveScene().name))
     {
         if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
         {
             NetworkLog.LogWarning("The current scene (" + SceneManager.GetActiveScene().name + ") is not regisered as a network scene.");
         }
         return;
     }
     currentSceneIndex       = sceneNameToIndex[SceneManager.GetActiveScene().name];
     CurrentActiveSceneIndex = currentSceneIndex;
 }
Beispiel #23
0
        /// <summary>
        /// Retrieves an expandable PooledBitStream from the pool
        /// </summary>
        /// <returns>An expandable PooledBitStream</returns>
        public static PooledBitStream GetStream()
        {
            if (streams.Count == 0)
            {
                if (overflowStreams.Count > 0)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
                    {
                        NetworkLog.LogInfo("Retrieving PooledBitStream from overflow pool. Recent burst?");
                    }

                    object weakStream = null;
                    while (overflowStreams.Count > 0 && ((weakStream = overflowStreams.Dequeue().Target) == null))
                    {
                        ;
                    }

                    if (weakStream != null)
                    {
                        PooledBitStream strongStream = (PooledBitStream)weakStream;

                        strongStream.SetLength(0);
                        strongStream.Position = 0;

                        return(strongStream);
                    }
                }

                if (createdStreams == 254)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("255 streams have been created. Did you forget to dispose?");
                    }
                }
                else if (createdStreams < 255)
                {
                    createdStreams++;
                }

                return(new PooledBitStream());
            }

            PooledBitStream stream = streams.Dequeue();

            stream.SetLength(0);
            stream.Position = 0;

            return(stream);
        }
Beispiel #24
0
        /// <summary>
        /// Retrieves an expandable PooledNetworkBuffer from the pool
        /// </summary>
        /// <returns>An expandable PooledNetworkBuffer</returns>
        public static PooledNetworkBuffer GetBuffer()
        {
            if (s_Buffers.Count == 0)
            {
                if (s_OverflowBuffers.Count > 0)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
                    {
                        NetworkLog.LogInfo($"Retrieving {nameof(PooledNetworkBuffer)} from overflow pool. Recent burst?");
                    }

                    object weakBuffer = null;
                    while (s_OverflowBuffers.Count > 0 && ((weakBuffer = s_OverflowBuffers.Dequeue().Target) == null))
                    {
                        ;
                    }

                    if (weakBuffer != null)
                    {
                        PooledNetworkBuffer strongBuffer = (PooledNetworkBuffer)weakBuffer;

                        strongBuffer.SetLength(0);
                        strongBuffer.Position = 0;

                        return(strongBuffer);
                    }
                }

                if (s_CreatedBuffers == k_MaxBitPoolBuffers)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning($"{k_MaxBitPoolBuffers} buffers have been created. Did you forget to dispose?");
                    }
                }
                else if (s_CreatedBuffers < k_MaxBitPoolBuffers)
                {
                    s_CreatedBuffers++;
                }

                return(new PooledNetworkBuffer());
            }

            PooledNetworkBuffer buffer = s_Buffers.Dequeue();

            buffer.SetLength(0);
            buffer.Position = 0;

            return(buffer);
        }
Beispiel #25
0
        internal void SetCurrentSceneIndex()
        {
            if (!SceneNameToIndex.TryGetValue(SceneManager.GetActiveScene().name, out CurrentSceneIndex))
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                {
                    NetworkLog.LogWarning($"The current scene ({SceneManager.GetActiveScene().name}) is not regisered as a network scene.");
                }

                return;
            }

            CurrentActiveSceneIndex = CurrentSceneIndex;
        }
        internal static void HandleNetworkedVarUpdate(ulong clientId, Stream stream, Action <ulong, PreBufferPreset> bufferCallback, PreBufferPreset bufferPreset)
        {
            if (!NetworkingManager.Singleton.NetworkConfig.EnableNetworkedVar)
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                {
                    NetworkLog.LogWarning("NetworkedVar update received but EnableNetworkedVar is false");
                }
                return;
            }

            using (PooledBitReader reader = PooledBitReader.Get(stream))
            {
                ulong  networkId  = reader.ReadUInt64Packed();
                ushort orderIndex = reader.ReadUInt16Packed();

                if (SpawnManager.SpawnedObjects.ContainsKey(networkId))
                {
                    NetworkedBehaviour instance = SpawnManager.SpawnedObjects[networkId].GetBehaviourAtOrderIndex(orderIndex);

                    if (instance == null)
                    {
                        if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                        {
                            NetworkLog.LogWarning("NetworkedVarUpdate message received for a non existant behaviour. NetworkId: " + networkId + ", behaviourIndex: " + orderIndex);
                        }
                    }
                    else
                    {
                        NetworkedBehaviour.HandleNetworkedVarUpdate(instance.networkedVarFields, stream, clientId, instance);
                    }
                }
                else if (NetworkingManager.Singleton.IsServer || !NetworkingManager.Singleton.NetworkConfig.EnableMessageBuffering)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("NetworkedVarUpdate message received for a non existant object with id: " + networkId + ". This delta was lost.");
                    }
                }
                else
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("NetworkedVarUpdate message received for a non existant object with id: " + networkId + ". This delta will be buffered and might be recovered.");
                    }
                    bufferCallback(networkId, bufferPreset);
                }
            }
        }
        /// <summary>
        /// Sends unnamed message to a list of clients
        /// </summary>
        /// <param name="clientIds">The clients to send to, sends to everyone if null</param>
        /// <param name="buffer">The message stream containing the data</param>
        /// <param name="networkChannel">The channel to send the data on</param>
        public void SendUnnamedMessage(List <ulong> clientIds, NetworkBuffer buffer, NetworkChannel networkChannel = NetworkChannel.Internal)
        {
            if (!m_NetworkManager.IsServer)
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
                {
                    NetworkLog.LogWarning("Can not send unnamed messages to multiple users as a client");
                }

                return;
            }

            m_NetworkManager.MessageSender.Send(NetworkConstants.UNNAMED_MESSAGE, networkChannel, clientIds, buffer);
            PerformanceDataManager.Increment(ProfilerConstants.UnnamedMessageSent);
        }
Beispiel #28
0
        internal static void Send(byte messageType, string channelName, ulong clientIdToIgnore, BitStream messageStream, SecuritySendFlags flags, NetworkedObject targetObject)
        {
            bool encrypted     = ((flags & SecuritySendFlags.Encrypted) == SecuritySendFlags.Encrypted) && NetworkingManager.Singleton.NetworkConfig.EnableEncryption;
            bool authenticated = ((flags & SecuritySendFlags.Authenticated) == SecuritySendFlags.Authenticated) && NetworkingManager.Singleton.NetworkConfig.EnableEncryption;

            if (encrypted || authenticated)
            {
                for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++)
                {
                    if (NetworkingManager.Singleton.ConnectedClientsList[i].ClientId == clientIdToIgnore)
                    {
                        continue;
                    }

                    Send(NetworkingManager.Singleton.ConnectedClientsList[i].ClientId, messageType, channelName, messageStream, flags, targetObject);
                }
            }
            else
            {
                messageStream.PadStream();

                using (BitStream stream = MessagePacker.WrapMessage(messageType, 0, messageStream, flags))
                {
                    NetworkProfiler.StartEvent(TickType.Send, (uint)stream.Length, channelName, MLAPIConstants.MESSAGE_NAMES[messageType]);
                    for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++)
                    {
                        if (NetworkingManager.Singleton.ConnectedClientsList[i].ClientId == clientIdToIgnore ||
                            (NetworkingManager.Singleton.IsServer && NetworkingManager.Singleton.ConnectedClientsList[i].ClientId == NetworkingManager.Singleton.ServerClientId))
                        {
                            continue;
                        }

                        if (targetObject != null && !targetObject.observers.Contains(NetworkingManager.Singleton.ConnectedClientsList[i].ClientId))
                        {
                            if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
                            {
                                NetworkLog.LogWarning("Silently suppressed send(ignore) call because it was directed to an object without visibility");
                            }
                            continue;
                        }

                        NetworkingManager.Singleton.NetworkConfig.NetworkTransport.Send(NetworkingManager.Singleton.ConnectedClientsList[i].ClientId, new ArraySegment <byte>(stream.GetBuffer(), 0, (int)stream.Length), channelName);
                    }
                    NetworkProfiler.EndEvent();
                }
            }
        }
        internal static void HandleServerRPCRequest(ulong clientId, Stream stream, string channelName, SecuritySendFlags security)
        {
            using (PooledBitReader reader = PooledBitReader.Get(stream))
            {
                ulong  networkId   = reader.ReadUInt64Packed();
                ushort behaviourId = reader.ReadUInt16Packed();
                ulong  hash        = reader.ReadUInt64Packed();
                ulong  responseId  = reader.ReadUInt64Packed();

                if (SpawnManager.SpawnedObjects.ContainsKey(networkId))
                {
                    NetworkedBehaviour behaviour = SpawnManager.SpawnedObjects[networkId].GetBehaviourAtOrderIndex(behaviourId);

                    if (behaviour == null)
                    {
                        if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                        {
                            NetworkLog.LogWarning("ServerRPCRequest message received for a non existant behaviour. NetworkId: " + networkId + ", behaviourIndex: " + behaviourId);
                        }
                    }
                    else
                    {
                        object result = behaviour.OnRemoteServerRPC(hash, clientId, stream);

                        using (PooledBitStream responseStream = PooledBitStream.Get())
                        {
                            using (PooledBitWriter responseWriter = PooledBitWriter.Get(responseStream))
                            {
                                responseWriter.WriteUInt64Packed(responseId);
                                responseWriter.WriteObjectPacked(result);
                            }

                            InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_SERVER_RPC_RESPONSE, channelName, responseStream, security, SpawnManager.SpawnedObjects[networkId]);
                        }
                    }
                }
                else
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning("ServerRPCRequest message received for a non existant object with id: " + networkId + ". This message is lost.");
                    }
                }
            }
        }
        internal object Invoke(NetworkedBehaviour target, ulong senderClientId, Stream stream)
        {
            if (requireOwnership == true && senderClientId != target.OwnerClientId)
            {
                if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                {
                    NetworkLog.LogWarning("Only owner can invoke ServerRPC that is marked to require ownership");
                }

                return(null);
            }

            target.executingRpcSender = senderClientId;

            if (stream.Position == 0)
            {
                if (useDelegate)
                {
                    return(InvokeDelegate(target, senderClientId, stream));
                }
                else
                {
                    return(InvokeReflected(target, stream));
                }
            }
            else
            {
                // Create a new stream so that the stream they get ONLY contains user data and not MLAPI headers
                using (PooledBitStream userStream = PooledBitStream.Get())
                {
                    userStream.CopyUnreadFrom(stream);
                    userStream.Position = 0;

                    if (useDelegate)
                    {
                        return(InvokeDelegate(target, senderClientId, userStream));
                    }
                    else
                    {
                        return(InvokeReflected(target, userStream));
                    }
                }
            }
        }