private static void LogServer(string message, LogType logType)
        {
            // Get the sender of the local log
            ulong localId = NetworkManager.Singleton != null ? NetworkManager.Singleton.LocalClientId : 0;

            switch (logType)
            {
            case LogType.Info:
                LogInfoServerLocal(message, localId);
                break;

            case LogType.Warning:
                LogWarningServerLocal(message, localId);
                break;

            case LogType.Error:
                LogErrorServerLocal(message, localId);
                break;
            }

            if (NetworkManager.Singleton != null && !NetworkManager.Singleton.IsServer && NetworkManager.Singleton.NetworkConfig.EnableNetworkLogs)
            {
                using (var buffer = PooledNetworkBuffer.Get())
                    using (var writer = PooledNetworkWriter.Get(buffer))
                    {
                        writer.WriteByte((byte)logType);
                        writer.WriteStringPacked(message);

                        NetworkManager.Singleton.MessageSender.Send(NetworkManager.Singleton.ServerClientId, NetworkConstants.SERVER_LOG, NetworkChannel.Internal, buffer);
                    }
            }
        }
        /// <summary>
        /// Sends a named message
        /// </summary>
        /// <param name="name">The message name to send</param>
        /// <param name="clientId">The client to send the message to</param>
        /// <param name="stream">The message stream containing the data</param>
        /// <param name="networkChannel">The channel to send the data on</param>
        public static void SendNamedMessage(string name, ulong clientId, Stream stream, NetworkChannel networkChannel = NetworkChannel.Internal)
        {
            ulong hash = 0;

            switch (NetworkManager.Singleton.NetworkConfig.RpcHashSize)
            {
            case HashSize.VarIntTwoBytes:
                hash = name.GetStableHash16();
                break;

            case HashSize.VarIntFourBytes:
                hash = name.GetStableHash32();
                break;

            case HashSize.VarIntEightBytes:
                hash = name.GetStableHash64();
                break;
            }

            using (var messageBuffer = PooledNetworkBuffer.Get())
                using (var writer = PooledNetworkWriter.Get(messageBuffer))
                {
                    writer.WriteUInt64Packed(hash);

                    messageBuffer.CopyFrom(stream);

                    InternalMessageSender.Send(clientId, NetworkConstants.NAMED_MESSAGE, networkChannel, messageBuffer);
                    PerformanceDataManager.Increment(ProfilerConstants.NamedMessageSent);
                }
        }
示例#3
0
        /// <inheritdoc />
        public void WriteDelta(Stream stream)
        {
            using (var writer = PooledNetworkWriter.Get(stream))
            {
                writer.WriteUInt16Packed((ushort)m_DirtyEvents.Count);
                for (int i = 0; i < m_DirtyEvents.Count; i++)
                {
                    writer.WriteBits((byte)m_DirtyEvents[i].Type, 2);

                    switch (m_DirtyEvents[i].Type)
                    {
                    case NetworkSetEvent <T> .EventType.Add:
                    {
                        writer.WriteObjectPacked(m_DirtyEvents[i].Value);         //BOX
                    }
                    break;

                    case NetworkSetEvent <T> .EventType.Remove:
                    {
                        writer.WriteObjectPacked(m_DirtyEvents[i].Value);         //BOX
                    }
                    break;

                    case NetworkSetEvent <T> .EventType.Clear:
                    {
                        //Nothing has to be written
                    }
                    break;
                    }
                }
            }
        }
        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;
        }
        /// <summary>
        /// Should be called the first time a queue item is pulled from a queue history frame.
        /// This will reset the frame's stream indices and add a new stream and stream writer to the m_CurrentQueueItem instance.
        /// </summary>
        /// <returns>FrameQueueItem</returns>
        internal RpcFrameQueueItem GetFirstQueueItem()
        {
            if (QueueBuffer.Position > 0)
            {
                m_QueueItemOffsetIndex = 0;
                QueueBuffer.Position   = 0;

                if (m_QueueFrameType == QueueFrameType.Inbound)
                {
                    if (m_CurrentQueueItem.NetworkBuffer == null)
                    {
                        m_CurrentQueueItem.NetworkBuffer = PooledNetworkBuffer.Get();
                    }

                    if (m_CurrentQueueItem.NetworkWriter == null)
                    {
                        m_CurrentQueueItem.NetworkWriter = PooledNetworkWriter.Get(m_CurrentQueueItem.NetworkBuffer);
                    }

                    if (m_CurrentQueueItem.NetworkReader == null)
                    {
                        m_CurrentQueueItem.NetworkReader = PooledNetworkReader.Get(m_CurrentQueueItem.NetworkBuffer);
                    }
                }

                return(GetCurrentQueueItem());
            }

            m_CurrentQueueItem.QueueItemType = RpcQueueContainer.QueueItemType.None;
            return(m_CurrentQueueItem);
        }
示例#6
0
        private void OnSceneUnloadClient(Guid switchSceneGuid, Stream objectStream)
        {
            var networkObjects = UnityEngine.Object.FindObjectsOfType <NetworkObject>();

            m_NetworkManager.SpawnManager.ClientCollectSoftSyncSceneObjectSweep(networkObjects);

            using (var reader = PooledNetworkReader.Get(objectStream))
            {
                var newObjectsCount = reader.ReadUInt32Packed();

                for (int i = 0; i < newObjectsCount; i++)
                {
                    NetworkObject.DeserializeSceneObject(objectStream as Serialization.NetworkBuffer, reader, m_NetworkManager);
                }
            }

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

            s_IsSwitching = false;

            OnSceneSwitched?.Invoke();
        }
        internal void RemoveOwnership(NetworkObject networkObject)
        {
            if (!NetworkManager.IsServer)
            {
                throw new NotServerException("Only the server can change ownership");
            }

            if (!networkObject.IsSpawned)
            {
                throw new SpawnStateException("Object is not spawned");
            }

            for (int i = NetworkManager.ConnectedClients[networkObject.OwnerClientId].OwnedObjects.Count - 1; i > -1; i--)
            {
                if (NetworkManager.ConnectedClients[networkObject.OwnerClientId].OwnedObjects[i] == networkObject)
                {
                    NetworkManager.ConnectedClients[networkObject.OwnerClientId].OwnedObjects.RemoveAt(i);
                }
            }

            networkObject.OwnerClientIdInternal = null;

            using (var buffer = PooledNetworkBuffer.Get())
                using (var writer = PooledNetworkWriter.Get(buffer))
                {
                    writer.WriteUInt64Packed(networkObject.NetworkObjectId);
                    writer.WriteUInt64Packed(networkObject.OwnerClientId);

                    NetworkManager.MessageSender.Send(NetworkConstants.CHANGE_OWNER, NetworkChannel.Internal, buffer);
                }
        }
示例#8
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 (!IsSpawned)
            {
                throw new SpawnStateException("Object is not spawned");
            }

            if (!NetworkManager.Singleton.IsServer)
            {
                throw new NotServerException("Only server can change visibility");
            }

            if (!m_Observers.Contains(clientId))
            {
                throw new VisibilityChangeException("The object is already hidden");
            }

            if (clientId == NetworkManager.Singleton.ServerClientId)
            {
                throw new VisibilityChangeException("Cannot hide an object from the server");
            }


            // Send destroy call
            m_Observers.Remove(clientId);

            using (var buffer = PooledNetworkBuffer.Get())
                using (var writer = PooledNetworkWriter.Get(buffer))
                {
                    writer.WriteUInt64Packed(NetworkObjectId);

                    InternalMessageSender.Send(clientId, NetworkConstants.DESTROY_OBJECT, NetworkChannel.Internal, buffer);
                }
        }
示例#9
0
        internal static void ChangeOwnership(NetworkObject networkObject, ulong clientId)
        {
            if (!NetworkManager.Singleton.IsServer)
            {
                throw new NotServerException("Only the server can change ownership");
            }

            if (!networkObject.IsSpawned)
            {
                throw new SpawnStateException("Object is not spawned");
            }

            if (NetworkManager.Singleton.ConnectedClients.ContainsKey(networkObject.OwnerClientId))
            {
                for (int i = NetworkManager.Singleton.ConnectedClients[networkObject.OwnerClientId].OwnedObjects.Count - 1; i >= 0; i--)
                {
                    if (NetworkManager.Singleton.ConnectedClients[networkObject.OwnerClientId].OwnedObjects[i] == networkObject)
                    {
                        NetworkManager.Singleton.ConnectedClients[networkObject.OwnerClientId].OwnedObjects.RemoveAt(i);
                    }
                }
            }

            NetworkManager.Singleton.ConnectedClients[clientId].OwnedObjects.Add(networkObject);
            networkObject.OwnerClientId = clientId;

            using (var buffer = PooledNetworkBuffer.Get())
                using (var writer = PooledNetworkWriter.Get(buffer))
                {
                    writer.WriteUInt64Packed(networkObject.NetworkObjectId);
                    writer.WriteUInt64Packed(clientId);

                    InternalMessageSender.Send(NetworkConstants.CHANGE_OWNER, NetworkChannel.Internal, buffer);
                }
        }
        /// <summary>
        /// Initialize
        /// This should be called during primary initialization period (typically during NetworkManager's Start method)
        /// This will allocate [maxFrameHistory] + [1 currentFrame] number of PooledNetworkBuffers and keep them open until the session ends
        /// Note: For zero frame history set maxFrameHistory to zero
        /// </summary>
        /// <param name="maxFrameHistory"></param>
        public void Initialize(uint maxFrameHistory)
        {
            ClearParameters();

            m_RpcQueueProcessor = new RpcQueueProcessor();
            m_MaxFrameHistory   = maxFrameHistory + k_MinQueueHistory;

            if (!QueueHistory.ContainsKey(RpcQueueHistoryFrame.QueueFrameType.Inbound))
            {
                QueueHistory.Add(RpcQueueHistoryFrame.QueueFrameType.Inbound, new Dictionary <int, Dictionary <NetworkUpdateStage, RpcQueueHistoryFrame> >());
            }

            if (!QueueHistory.ContainsKey(RpcQueueHistoryFrame.QueueFrameType.Outbound))
            {
                QueueHistory.Add(RpcQueueHistoryFrame.QueueFrameType.Outbound, new Dictionary <int, Dictionary <NetworkUpdateStage, RpcQueueHistoryFrame> >());
            }

            for (int i = 0; i < m_MaxFrameHistory; i++)
            {
                if (!QueueHistory[RpcQueueHistoryFrame.QueueFrameType.Outbound].ContainsKey(i))
                {
                    QueueHistory[RpcQueueHistoryFrame.QueueFrameType.Outbound].Add(i, new Dictionary <NetworkUpdateStage, RpcQueueHistoryFrame>());
                    var queueHistoryFrame = new RpcQueueHistoryFrame(RpcQueueHistoryFrame.QueueFrameType.Outbound, NetworkUpdateStage.PostLateUpdate);
                    queueHistoryFrame.QueueBuffer          = PooledNetworkBuffer.Get();
                    queueHistoryFrame.QueueBuffer.Position = 0;
                    queueHistoryFrame.QueueWriter          = PooledNetworkWriter.Get(queueHistoryFrame.QueueBuffer);
                    queueHistoryFrame.QueueReader          = PooledNetworkReader.Get(queueHistoryFrame.QueueBuffer);
                    queueHistoryFrame.QueueItemOffsets     = new List <uint>();

                    //For now all outbound, we will always have a single update in which they are processed (LATEUPDATE)
                    QueueHistory[RpcQueueHistoryFrame.QueueFrameType.Outbound][i].Add(NetworkUpdateStage.PostLateUpdate, queueHistoryFrame);
                }

                if (!QueueHistory[RpcQueueHistoryFrame.QueueFrameType.Inbound].ContainsKey(i))
                {
                    QueueHistory[RpcQueueHistoryFrame.QueueFrameType.Inbound].Add(i, new Dictionary <NetworkUpdateStage, RpcQueueHistoryFrame>());

                    //For inbound, we create a queue history frame per update stage
                    foreach (NetworkUpdateStage netUpdateStage in Enum.GetValues(typeof(NetworkUpdateStage)))
                    {
                        var rpcQueueHistoryFrame = new RpcQueueHistoryFrame(RpcQueueHistoryFrame.QueueFrameType.Inbound, netUpdateStage);
                        rpcQueueHistoryFrame.QueueBuffer          = PooledNetworkBuffer.Get();
                        rpcQueueHistoryFrame.QueueBuffer.Position = 0;
                        rpcQueueHistoryFrame.QueueWriter          = PooledNetworkWriter.Get(rpcQueueHistoryFrame.QueueBuffer);
                        rpcQueueHistoryFrame.QueueReader          = PooledNetworkReader.Get(rpcQueueHistoryFrame.QueueBuffer);
                        rpcQueueHistoryFrame.QueueItemOffsets     = new List <uint>();
                        QueueHistory[RpcQueueHistoryFrame.QueueFrameType.Inbound][i].Add(netUpdateStage, rpcQueueHistoryFrame);
                    }
                }
            }

            //As long as this instance is using the pre-defined update stages
            if (!m_ProcessUpdateStagesExternally)
            {
                //Register with the network update loop system
                this.RegisterAllNetworkUpdates();
            }
        }
 public void SendPlayerEjectionCommand(string userId)
 {
     using (PooledNetworkBuffer stream = PooledNetworkBuffer.Get())
     {
         using (PooledNetworkWriter writer = PooledNetworkWriter.Get(stream))
         {
             writer.WriteStringPacked(userId);
             _Client.SendMessageToServer(GameRoomMessagingHubConstants.SEND_PLAYER_EJECTION_COMMAND, stream);
         }
     }
 }
 public void SendSystemUserIdToServer(string userId)
 {
     using (PooledNetworkBuffer stream = PooledNetworkBuffer.Get())
     {
         using (PooledNetworkWriter writer = PooledNetworkWriter.Get(stream))
         {
             writer.WriteStringPacked(userId);
             _Client.SendMessageToServer(GameRoomMessagingHubConstants.SEND_SYSTEM_USERID_TO_SERVER, stream);
         }
     }
 }
 public void SendServerProcessDownCommand(int timeSeconds)
 {
     using (PooledNetworkBuffer stream = PooledNetworkBuffer.Get())
     {
         using (PooledNetworkWriter writer = PooledNetworkWriter.Get(stream))
         {
             writer.WriteInt32Packed(timeSeconds);
             _Client.SendMessageToServer(GameRoomMessagingHubConstants.SEND_SERVER_PROCESS_DOWN_COMMAND, stream);
         }
     }
 }
        /// <summary>
        /// Hides a list of objects from a client
        /// </summary>
        /// <param name="networkObjects">The objects to hide</param>
        /// <param name="clientId">The client to hide the objects from</param>
        public static void NetworkHide(List <NetworkObject> networkObjects, ulong clientId)
        {
            if (networkObjects == null || networkObjects.Count == 0)
            {
                throw new ArgumentNullException("At least one " + nameof(NetworkObject) + " has to be provided");
            }

            NetworkManager networkManager = networkObjects[0].NetworkManager;

            if (!networkManager.IsServer)
            {
                throw new NotServerException("Only server can change visibility");
            }

            if (clientId == networkManager.ServerClientId)
            {
                throw new VisibilityChangeException("Cannot hide an object from the server");
            }

            // Do the safety loop first to prevent putting the MLAPI in an invalid state.
            for (int i = 0; i < networkObjects.Count; i++)
            {
                if (!networkObjects[i].IsSpawned)
                {
                    throw new SpawnStateException("Object is not spawned");
                }

                if (!networkObjects[i].Observers.Contains(clientId))
                {
                    throw new VisibilityChangeException($"{nameof(NetworkObject)} with {nameof(NetworkObjectId)}: {networkObjects[i].NetworkObjectId} is already hidden");
                }

                if (networkObjects[i].NetworkManager != networkManager)
                {
                    throw new ArgumentNullException("All " + nameof(NetworkObject) + "s must belong to the same " + nameof(NetworkManager));
                }
            }

            using (var buffer = PooledNetworkBuffer.Get())
                using (var writer = PooledNetworkWriter.Get(buffer))
                {
                    writer.WriteUInt16Packed((ushort)networkObjects.Count);

                    for (int i = 0; i < networkObjects.Count; i++)
                    {
                        // Send destroy call
                        networkObjects[i].Observers.Remove(clientId);

                        writer.WriteUInt64Packed(networkObjects[i].NetworkObjectId);
                    }

                    networkManager.MessageSender.Send(clientId, NetworkConstants.DESTROY_OBJECTS, NetworkChannel.Internal, buffer);
                }
        }
示例#15
0
 private void SendNetMessage(string msg_name, string msg)
 {
     print("Sending net message");
     using (var buffer = PooledNetworkBuffer.Get()) {
         using (var writer = PooledNetworkWriter.Get(buffer)) {
             writer.WriteString(msg);
             MLAPI.Messaging.CustomMessagingManager.SendNamedMessage(
                 msg_name, null, buffer);
         }
     }
 }
示例#16
0
 /// <summary>
 /// Writes the TickEvent data to the stream
 /// </summary>
 /// <param name="stream">The stream to write the TickEvent data to</param>
 public void SerializeToStream(Stream stream)
 {
     using (var writer = PooledNetworkWriter.Get(stream))
     {
         writer.WriteByte((byte)EventType);
         writer.WriteUInt32Packed(Bytes);
         writer.WriteStringPacked(ChannelName);
         writer.WriteStringPacked(MessageType);
         writer.WriteBool(Closed);
     }
 }
 /// <summary>
 /// Write the snapshot index to a buffer
 /// </summary>
 /// <param name="buffer">The buffer to write the index to</param>
 private void WriteIndex(NetworkBuffer buffer)
 {
     using (var writer = PooledNetworkWriter.Get(buffer))
     {
         writer.WriteInt16((short)m_Snapshot.LastEntry);
         for (var i = 0; i < m_Snapshot.LastEntry; i++)
         {
             WriteEntry(writer, in m_Snapshot.Entries[i]);
         }
     }
 }
示例#18
0
 /// <summary>
 /// Responsible for the Server->Client RPC's of the connection result.
 /// </summary>
 /// <param name="netId"> id of the client to send to </param>
 /// <param name="status"> the status to pass to the client</param>
 public void S2CConnectResult(ulong netId, ConnectStatus status)
 {
     using (var buffer = PooledNetworkBuffer.Get())
     {
         using (var writer = PooledNetworkWriter.Get(buffer))
         {
             writer.WriteInt32((int)status);
             MLAPI.Messaging.CustomMessagingManager.SendNamedMessage("S2C_ConnectResult", netId, buffer, NetworkChannel.Internal);
         }
     }
 }
示例#19
0
 /// <inheritdoc />
 public void WriteField(Stream stream)
 {
     using (var writer = PooledNetworkWriter.Get(stream))
     {
         writer.WriteUInt16Packed((ushort)m_List.Count);
         for (int i = 0; i < m_List.Count; i++)
         {
             writer.WriteObjectPacked(m_List[i]); //BOX
         }
     }
 }
示例#20
0
        internal static NetworkBuffer WrapMessage(byte messageType, NetworkBuffer messageBody)
        {
            var outStream = PooledNetworkBuffer.Get();

            using (var outWriter = PooledNetworkWriter.Get(outStream))
            {
                outWriter.WriteByte(messageType);
                outStream.Write(messageBody.GetBuffer(), 0, (int)messageBody.Length);
            }

            return(outStream);
        }
示例#21
0
 /// <inheritdoc />
 public void WriteField(Stream stream)
 {
     using (var writer = PooledNetworkWriter.Get(stream))
     {
         writer.WriteUInt16Packed((ushort)m_Dictionary.Count);
         foreach (KeyValuePair <TKey, TValue> pair in m_Dictionary)
         {
             writer.WriteObjectPacked(pair.Key);
             writer.WriteObjectPacked(pair.Value);
         }
     }
 }
示例#22
0
        /// <inheritdoc />
        public void WriteField(Stream stream)
        {
            using (var writer = PooledNetworkWriter.Get(stream))
            {
                writer.WriteUInt16Packed((ushort)m_Set.Count);

                foreach (T value in m_Set)
                {
                    writer.WriteObjectPacked(value); //BOX
                }
            }
        }
示例#23
0
        /// <summary>
        /// Writes the current ProfilerTick to the stream
        /// </summary>
        /// <param name="stream">The stream containing</param>
        public void SerializeToStream(Stream stream)
        {
            using (var writer = PooledNetworkWriter.Get(stream))
            {
                writer.WriteUInt16Packed((ushort)Events.Count);

                for (int i = 0; i < Events.Count; i++)
                {
                    Events[i].SerializeToStream(stream);
                }
            }
        }
        /// <summary>
        /// Shows a list of previously hidden objects to a client
        /// </summary>
        /// <param name="networkObjects">The objects to show</param>
        /// <param name="clientId">The client to show the objects to</param>
        /// <param name="payload">An optional payload to send as part of the spawns</param>
        public static void NetworkShow(List <NetworkObject> networkObjects, ulong clientId, Stream payload = null)
        {
            if (networkObjects == null || networkObjects.Count == 0)
            {
                throw new ArgumentNullException("At least one " + nameof(NetworkObject) + " has to be provided");
            }

            NetworkManager networkManager = networkObjects[0].NetworkManager;

            if (!networkManager.IsServer)
            {
                throw new NotServerException("Only server can change visibility");
            }


            // Do the safety loop first to prevent putting the MLAPI in an invalid state.
            for (int i = 0; i < networkObjects.Count; i++)
            {
                if (!networkObjects[i].IsSpawned)
                {
                    throw new SpawnStateException("Object is not spawned");
                }

                if (networkObjects[i].Observers.Contains(clientId))
                {
                    throw new VisibilityChangeException($"{nameof(NetworkObject)} with NetworkId: {networkObjects[i].NetworkObjectId} is already visible");
                }

                if (networkObjects[i].NetworkManager != networkManager)
                {
                    throw new ArgumentNullException("All " + nameof(NetworkObject) + "s must belong to the same " + nameof(NetworkManager));
                }
            }

            using (var buffer = PooledNetworkBuffer.Get())
                using (var writer = PooledNetworkWriter.Get(buffer))
                {
                    writer.WriteUInt16Packed((ushort)networkObjects.Count);

                    for (int i = 0; i < networkObjects.Count; i++)
                    {
                        // Send spawn call
                        networkObjects[i].Observers.Add(clientId);

                        networkManager.SpawnManager.WriteSpawnCallForObject(buffer, clientId, networkObjects[i], payload);
                    }

                    networkManager.MessageSender.Send(clientId, NetworkConstants.ADD_OBJECTS, NetworkChannel.Internal, buffer);
                }
        }
示例#25
0
        /// <summary>
        /// Gets a SHA256 hash of parts of the NetworkConfig instance
        /// </summary>
        /// <param name="cache"></param>
        /// <returns></returns>
        public ulong GetConfig(bool cache = true)
        {
            if (m_ConfigHash != null && cache)
            {
                return(m_ConfigHash.Value);
            }

            Sort();

            using (var buffer = PooledNetworkBuffer.Get())
                using (var writer = PooledNetworkWriter.Get(buffer))
                {
                    writer.WriteUInt16Packed(ProtocolVersion);
                    writer.WriteString(NetworkConstants.PROTOCOL_VERSION);

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

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

                    writer.WriteBool(EnableNetworkVariable);
                    writer.WriteBool(ForceSamePrefabs);
                    writer.WriteBool(UsePrefabSync);
                    writer.WriteBool(EnableSceneManagement);
                    writer.WriteBool(EnsureNetworkVariableLengthSafety);
                    writer.WriteBits((byte)RpcHashSize, 2);
                    buffer.PadBuffer();

                    if (cache)
                    {
                        m_ConfigHash = buffer.ToArray().GetStableHash64();
                        return(m_ConfigHash.Value);
                    }

                    return(buffer.ToArray().GetStableHash64());
                }
        }
        /// <summary>
        /// Gets a SHA256 hash of parts of the NetworkConfig instance
        /// </summary>
        /// <param name="cache"></param>
        /// <returns></returns>
        public ulong GetConfig(bool cache = true)
        {
            if (m_ConfigHash != null && cache)
            {
                return(m_ConfigHash.Value);
            }

            Sort();

            using (var buffer = PooledNetworkBuffer.Get())
                using (var writer = PooledNetworkWriter.Get(buffer))
                {
                    writer.WriteUInt16Packed(ProtocolVersion);
                    writer.WriteString(NetworkConstants.PROTOCOL_VERSION);

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

                    if (ForceSamePrefabs)
                    {
                        var sortedDictionary = NetworkPrefabOverrideLinks.OrderBy(x => x.Key);
                        foreach (var sortedEntry in sortedDictionary)
                        {
                            writer.WriteUInt32Packed(sortedEntry.Key);
                        }
                    }

                    writer.WriteBool(EnableNetworkVariable);
                    writer.WriteBool(ForceSamePrefabs);
                    writer.WriteBool(EnableSceneManagement);
                    writer.WriteBool(EnsureNetworkVariableLengthSafety);
                    writer.WriteBits((byte)RpcHashSize, 2);
                    buffer.PadBuffer();

                    if (cache)
                    {
                        m_ConfigHash = XXHash.Hash64(buffer.ToArray());
                        return(m_ConfigHash.Value);
                    }

                    return(XXHash.Hash64(buffer.ToArray()));
                }
        }
示例#27
0
        /// <inheritdoc />
        public void WriteDelta(Stream stream)
        {
            using (var writer = PooledNetworkWriter.Get(stream))
            {
                writer.WriteUInt16Packed((ushort)m_DirtyEvents.Count);
                for (int i = 0; i < m_DirtyEvents.Count; i++)
                {
                    writer.WriteBits((byte)m_DirtyEvents[i].Type, 3);
                    switch (m_DirtyEvents[i].Type)
                    {
                    case NetworkDictionaryEvent <TKey, TValue> .EventType.Add:
                    {
                        writer.WriteObjectPacked(m_DirtyEvents[i].Key);
                        writer.WriteObjectPacked(m_DirtyEvents[i].Value);
                    }
                    break;

                    case NetworkDictionaryEvent <TKey, TValue> .EventType.Remove:
                    {
                        writer.WriteObjectPacked(m_DirtyEvents[i].Key);
                    }
                    break;

                    case NetworkDictionaryEvent <TKey, TValue> .EventType.RemovePair:
                    {
                        writer.WriteObjectPacked(m_DirtyEvents[i].Key);
                        writer.WriteObjectPacked(m_DirtyEvents[i].Value);
                    }
                    break;

                    case NetworkDictionaryEvent <TKey, TValue> .EventType.Clear:
                    {
                        //write nothing
                    }
                    break;

                    case NetworkDictionaryEvent <TKey, TValue> .EventType.Value:
                    {
                        writer.WriteObjectPacked(m_DirtyEvents[i].Key);
                        writer.WriteObjectPacked(m_DirtyEvents[i].Value);
                    }
                    break;
                    }
                }
            }
        }
示例#28
0
        internal static void WriteNetworkVariableData(List <INetworkVariable> networkVariableList, Stream stream, ulong clientId, NetworkManager networkManager)
        {
            if (networkVariableList.Count == 0)
            {
                return;
            }

            using (var writer = PooledNetworkWriter.Get(stream))
            {
                for (int j = 0; j < networkVariableList.Count; j++)
                {
                    bool canClientRead = networkVariableList[j].CanClientRead(clientId);

                    if (networkManager.NetworkConfig.EnsureNetworkVariableLengthSafety)
                    {
                        if (!canClientRead)
                        {
                            writer.WriteUInt16Packed(0);
                        }
                    }
                    else
                    {
                        writer.WriteBool(canClientRead);
                    }

                    if (canClientRead)
                    {
                        if (networkManager.NetworkConfig.EnsureNetworkVariableLengthSafety)
                        {
                            using (var varBuffer = PooledNetworkBuffer.Get())
                            {
                                networkVariableList[j].WriteField(varBuffer);
                                varBuffer.PadBuffer();

                                writer.WriteUInt16Packed((ushort)varBuffer.Length);
                                varBuffer.CopyTo(stream);
                            }
                        }
                        else
                        {
                            networkVariableList[j].WriteField(stream);
                        }
                    }
                }
            }
        }
示例#29
0
 public void C2SSceneChanged(int newScene)
 {
     if (NetManager.IsHost)
     {
         ClientSceneChanged?.Invoke(NetManager.ServerClientId, newScene);
     }
     else if (NetManager.IsConnectedClient)
     {
         using (var buffer = PooledNetworkBuffer.Get())
         {
             using (var writer = PooledNetworkWriter.Get(buffer))
             {
                 writer.WriteInt32(newScene);
                 MLAPI.Messaging.CustomMessagingManager.SendNamedMessage("C2S_SceneChanged", NetManager.ServerClientId, buffer, NetworkChannel.Internal);
             }
         }
     }
 }
示例#30
0
        public void StartGame()
        {
            var pts = new HashSet <Transform>(_SpawnPoints.GetComponentsInChildren <Transform>());

            pts.Remove(_SpawnPoints.transform); // Why does unity return parent also ?

            foreach (var(player, point) in _SessionManager.Zip(pts, (player, point) => (player, point.localPosition)))
            {
                var obj = Instantiate(_PlayerPrefab, point, Quaternion.identity);

                using var stream = PooledNetworkBuffer.Get();
                using var writer = PooledNetworkWriter.Get(stream);

                writer.WriteByte((byte)player.Character);
                writer.WritePadBits();

                var net = obj.GetComponent <NetworkObject>();

                net.SpawnAsPlayerObject(player.ID, stream, true);
            }
        }