Пример #1
0
        private void MessageHandler_Server_SendPlayerEjectionCommand(ulong senderClientId, Stream dataStream)
        {
            using (PooledNetworkReader reader = PooledNetworkReader.Get(dataStream))
            {
                string userId = reader.ReadStringPacked().ToString();

                MLAPIExtension.NetworkClientUser networkClientUser = new MLAPIExtension.NetworkClientUser();
                networkClientUser.ClientId = 0;
                networkClientUser.UserId   = userId;

                _OnReceivedSystemUserIdSubject.OnNext(networkClientUser);
            }
        }
Пример #2
0
        /// <inheritdoc />
        public void ReadField(Stream stream, ushort localTick, ushort remoteTick)
        {
            using (var reader = PooledNetworkReader.Get(stream))
            {
                m_Set.Clear();
                ushort count = reader.ReadUInt16Packed();

                for (int i = 0; i < count; i++)
                {
                    m_Set.Add((T)reader.ReadObjectPacked(typeof(T))); //BOX
                }
            }
        }
Пример #3
0
        internal static void HandleTimeSync(ulong clientId, Stream stream, float receiveTime)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleTimeSync.Begin();
#endif
            using (var reader = PooledNetworkReader.Get(stream))
            {
                float netTime = reader.ReadSinglePacked();
                NetworkManager.Singleton.UpdateNetworkTime(clientId, netTime, receiveTime);
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleTimeSync.End();
#endif
        }
Пример #4
0
 /// <inheritdoc />
 public void ReadField(Stream stream, ushort localTick, ushort remoteTick)
 {
     using (var reader = PooledNetworkReader.Get(stream))
     {
         m_Dictionary.Clear();
         ushort entryCount = reader.ReadUInt16Packed();
         for (int i = 0; i < entryCount; i++)
         {
             var key   = (TKey)reader.ReadObjectPacked(typeof(TKey));
             var value = (TValue)reader.ReadObjectPacked(typeof(TValue));
             m_Dictionary.Add(key, value);
         }
     }
 }
Пример #5
0
        internal static void HandleDestroyObject(ulong clientId, Stream stream)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleDestroyObject.Begin();
#endif
            using (var reader = PooledNetworkReader.Get(stream))
            {
                ulong networkId = reader.ReadUInt64Packed();
                NetworkSpawnManager.OnDestroyObject(networkId, true);
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleDestroyObject.End();
#endif
        }
        public void HandleAllClientsSwitchSceneCompleted(ulong clientId, Stream stream)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleAllClientsSwitchSceneCompleted.Begin();
#endif
            using (var reader = PooledNetworkReader.Get(stream))
            {
                var clientIds         = reader.ReadULongArray();
                var timedOutClientIds = reader.ReadULongArray();
                NetworkManager.SceneManager.AllClientsReady(clientIds, timedOutClientIds);
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleAllClientsSwitchSceneCompleted.End();
#endif
        }
Пример #7
0
        /// <summary>
        /// Creates a ProfilerTick from data in the provided stream
        /// </summary>
        /// <param name="stream">The stream containing the ProfilerTick data</param>
        /// <returns>The ProfilerTick with data read from the stream</returns>
        public static ProfilerTick FromStream(Stream stream)
        {
            var tick = new ProfilerTick();

            using (var reader = PooledNetworkReader.Get(stream))
            {
                ushort count = reader.ReadUInt16Packed();
                for (int i = 0; i < count; i++)
                {
                    tick.Events.Add(TickEvent.FromStream(stream));
                }

                return(tick);
            }
        }
Пример #8
0
        /// <summary>
        /// Creates a TickEvent from data in the provided stream
        /// </summary>
        /// <param name="stream">The stream containing the TickEvent data</param>
        /// <returns>The TickEvent with data read from the stream</returns>
        public static TickEvent FromStream(Stream stream)
        {
            using (var reader = PooledNetworkReader.Get(stream))
            {
                var tickEvent = new TickEvent
                {
                    EventType   = (TickType)reader.ReadByte(),
                    Bytes       = reader.ReadUInt32Packed(),
                    ChannelName = reader.ReadStringPacked(),
                    MessageType = reader.ReadStringPacked(),
                    Closed      = reader.ReadBool()
                };

                return(tickEvent);
            }
        }
Пример #9
0
        internal static void HandleNamedMessage(ulong clientId, Stream stream)
        {
            PerformanceDataManager.Increment(ProfilerConstants.NumberOfNamedMessages);
            ProfilerStatManager.NamedMessage.Record();
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleNamedMessage.Begin();
#endif
            using (var reader = PooledNetworkReader.Get(stream))
            {
                ulong hash = reader.ReadUInt64Packed();

                CustomMessagingManager.InvokeNamedMessage(hash, clientId, stream);
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleNamedMessage.End();
#endif
        }
Пример #10
0
        internal static void HandleDestroyObjects(ulong clientId, Stream stream)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleDestroyObjects.Begin();
#endif
            using (var reader = PooledNetworkReader.Get(stream))
            {
                ushort objectCount = reader.ReadUInt16Packed();

                for (int i = 0; i < objectCount; i++)
                {
                    HandleDestroyObject(clientId, stream);
                }
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleDestroyObjects.End();
#endif
        }
Пример #11
0
        internal static void HandleSwitchScene(ulong clientId, Stream stream)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleSwitchScene.Begin();
#endif
            using (var reader = PooledNetworkReader.Get(stream))
            {
                uint sceneIndex      = reader.ReadUInt32Packed();
                Guid switchSceneGuid = new Guid(reader.ReadByteArray());

                var objectBuffer = new NetworkBuffer();
                objectBuffer.CopyUnreadFrom(stream);
                objectBuffer.Position = 0;

                NetworkSceneManager.OnSceneSwitch(sceneIndex, switchSceneGuid, objectBuffer);
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleSwitchScene.End();
#endif
        }
        public void HandleConnectionRequest(ulong clientId, Stream stream)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleConnectionRequest.Begin();
#endif
            if (NetworkManager.PendingClients.TryGetValue(clientId, out PendingClient client))
            {
                // Set to pending approval to prevent future connection requests from being approved
                client.ConnectionState = PendingClient.State.PendingApproval;
            }

            using (var reader = PooledNetworkReader.Get(stream))
            {
                ulong configHash = reader.ReadUInt64Packed();
                if (!NetworkManager.NetworkConfig.CompareConfig(configHash))
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogWarning($"{nameof(NetworkConfig)} mismatch. The configuration between the server and client does not match");
                    }

                    NetworkManager.DisconnectClient(clientId);
                    return;
                }

                if (NetworkManager.NetworkConfig.ConnectionApproval)
                {
                    byte[] connectionBuffer = reader.ReadByteArray();
                    NetworkManager.InvokeConnectionApproval(connectionBuffer, clientId,
                                                            (createPlayerObject, playerPrefabHash, approved, position, rotation) =>
                                                            NetworkManager.HandleApproval(clientId, createPlayerObject, playerPrefabHash, approved, position, rotation));
                }
                else
                {
                    NetworkManager.HandleApproval(clientId, NetworkManager.NetworkConfig.PlayerPrefab != null, null, true, null, null);
                }
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleConnectionRequest.End();
#endif
        }
Пример #13
0
        // This method is responsible for unwrapping a message, that is extracting the messagebody.
        internal static NetworkBuffer UnwrapMessage(NetworkBuffer inputBuffer, out byte messageType)
        {
            using (var inputHeaderReader = PooledNetworkReader.Get(inputBuffer))
            {
                if (inputBuffer.Length < 1)
                {
                    if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                    {
                        NetworkLog.LogError("The incoming message was too small");
                    }
                    messageType = NetworkConstants.INVALID;

                    return(null);
                }

                messageType = inputHeaderReader.ReadByteDirect();

                // The input stream is now ready to be read from. It's "safe" and has the correct position
                return(inputBuffer);
            }
        }
Пример #14
0
        /// <summary>
        /// Sets the NetworkConfig data with that from a base64 encoded version
        /// </summary>
        /// <param name="base64">The base64 encoded version</param>
        public void FromBase64(string base64)
        {
            NetworkConfig config = this;

            byte[] binary = Convert.FromBase64String(base64);
            using (var buffer = new NetworkBuffer(binary))
                using (var reader = PooledNetworkReader.Get(buffer))
                {
                    config.ProtocolVersion = reader.ReadUInt16Packed();

                    ushort sceneCount = reader.ReadUInt16Packed();
                    config.RegisteredScenes.Clear();

                    for (int i = 0; i < sceneCount; i++)
                    {
                        config.RegisteredScenes.Add(reader.ReadString().ToString());
                    }

                    config.ReceiveTickrate             = reader.ReadInt32Packed();
                    config.MaxReceiveEventsPerTickRate = reader.ReadInt32Packed();
                    config.EventTickrate = reader.ReadInt32Packed();
                    config.ClientConnectionBufferTimeout = reader.ReadInt32Packed();
                    config.ConnectionApproval            = reader.ReadBool();
                    config.SecondsHistory   = reader.ReadInt32Packed();
                    config.LoadSceneTimeOut = reader.ReadInt32Packed();
                    config.EnableTimeResync = reader.ReadBool();
                    config.EnsureNetworkVariableLengthSafety = reader.ReadBool();
                    config.RpcHashSize              = (HashSize)reader.ReadBits(2);
                    config.ForceSamePrefabs         = reader.ReadBool();
                    config.UsePrefabSync            = reader.ReadBool();
                    config.EnableSceneManagement    = reader.ReadBool();
                    config.RecycleNetworkIds        = reader.ReadBool();
                    config.NetworkIdRecycleDelay    = reader.ReadSinglePacked();
                    config.EnableNetworkVariable    = reader.ReadBool();
                    config.AllowRuntimeSceneChanges = reader.ReadBool();
                    config.EnableNetworkLogs        = reader.ReadBool();
                }
        }
        /// <summary>
        /// AddQueueItemToInboundFrame
        /// Adds an RPC queue item to the outbound frame
        /// </summary>
        /// <param name="qItemType">type of rpc (client or server)</param>
        /// <param name="timeStamp">when it was received</param>
        /// <param name="sourceNetworkId">who sent the rpc</param>
        /// <param name="message">the message being received</param>
        internal void AddQueueItemToInboundFrame(QueueItemType qItemType, float timeStamp, ulong sourceNetworkId, NetworkBuffer message)
        {
            long originalPosition = message.Position;

            NetworkUpdateStage updateStage;

            using (var reader = PooledNetworkReader.Get(message))
            {
                var longValue  = reader.ReadUInt64Packed(); // NetworkObjectId (temporary, we reset position just below)
                var shortValue = reader.ReadUInt16Packed(); // NetworkBehaviourId (temporary, we reset position just below)
                updateStage = (NetworkUpdateStage)reader.ReadByteDirect();
            }

            message.Position = originalPosition;
            var rpcQueueHistoryItem = GetQueueHistoryFrame(RpcQueueHistoryFrame.QueueFrameType.Inbound, updateStage);

            rpcQueueHistoryItem.IsDirty = true;

            long StartPosition = rpcQueueHistoryItem.QueueBuffer.Position;

            //Write the packed version of the queueItem to our current queue history buffer
            rpcQueueHistoryItem.QueueWriter.WriteUInt16((ushort)qItemType);
            rpcQueueHistoryItem.QueueWriter.WriteSingle(timeStamp);
            rpcQueueHistoryItem.QueueWriter.WriteUInt64(sourceNetworkId);

            //Inbound we copy the entire packet and store the position offset
            long streamSize = message.Length;

            rpcQueueHistoryItem.QueueWriter.WriteInt64(streamSize);
            rpcQueueHistoryItem.QueueWriter.WriteInt64(message.Position);
            rpcQueueHistoryItem.QueueWriter.WriteBytes(message.GetBuffer(), streamSize);

            //Add the packed size to the offsets for parsing over various entries
            rpcQueueHistoryItem.QueueItemOffsets.Add((uint)rpcQueueHistoryItem.QueueBuffer.Position);

            //Calculate the packed size based on stream progression
            rpcQueueHistoryItem.TotalSize += (uint)(rpcQueueHistoryItem.QueueBuffer.Position - StartPosition);
        }
        public void HandleConnectionApproved(ulong clientId, Stream stream, float receiveTime)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleConnectionApproved.Begin();
#endif
            using (var reader = PooledNetworkReader.Get(stream))
            {
                NetworkManager.LocalClientId = reader.ReadUInt64Packed();

                uint sceneIndex = 0;
                var  sceneSwitchProgressGuid = new Guid();

                if (NetworkManager.NetworkConfig.EnableSceneManagement)
                {
                    sceneIndex = reader.ReadUInt32Packed();
                    sceneSwitchProgressGuid = new Guid(reader.ReadByteArray());
                }

                bool sceneSwitch = NetworkManager.NetworkConfig.EnableSceneManagement && NetworkManager.SceneManager.HasSceneMismatch(sceneIndex);

                float netTime = reader.ReadSinglePacked();
                NetworkManager.UpdateNetworkTime(clientId, netTime, receiveTime, true);

                NetworkManager.ConnectedClients.Add(NetworkManager.LocalClientId, new NetworkClient {
                    ClientId = NetworkManager.LocalClientId
                });


                void DelayedSpawnAction(Stream continuationStream)
                {
                    using (var continuationReader = PooledNetworkReader.Get(continuationStream))
                    {
                        if (!NetworkManager.NetworkConfig.EnableSceneManagement)
                        {
                            NetworkManager.SpawnManager.DestroySceneObjects();
                        }
                        else
                        {
                            NetworkManager.SpawnManager.ClientCollectSoftSyncSceneObjectSweep(null);
                        }

                        var objectCount = continuationReader.ReadUInt32Packed();
                        for (int i = 0; i < objectCount; i++)
                        {
                            NetworkObject.DeserializeSceneObject(continuationStream as NetworkBuffer, continuationReader, m_NetworkManager);
                        }

                        NetworkManager.SpawnManager.CleanDiffedSceneObjects();
                        NetworkManager.IsConnectedClient = true;
                        NetworkManager.InvokeOnClientConnectedCallback(NetworkManager.LocalClientId);
                    }
                }

                if (sceneSwitch)
                {
                    UnityAction <Scene, Scene> onSceneLoaded = null;

                    var continuationBuffer = new NetworkBuffer();
                    continuationBuffer.CopyUnreadFrom(stream);
                    continuationBuffer.Position = 0;

                    void OnSceneLoadComplete()
                    {
                        SceneManager.activeSceneChanged -= onSceneLoaded;
                        NetworkSceneManager.IsSpawnedObjectsPendingInDontDestroyOnLoad = false;
                        DelayedSpawnAction(continuationBuffer);
                    }

                    onSceneLoaded = (oldScene, newScene) => { OnSceneLoadComplete(); };
                    SceneManager.activeSceneChanged += onSceneLoaded;
                    m_NetworkManager.SceneManager.OnFirstSceneSwitchSync(sceneIndex, sceneSwitchProgressGuid);
                }
                else
                {
                    DelayedSpawnAction(stream);
                }
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleConnectionApproved.End();
#endif
        }
Пример #17
0
        /// <inheritdoc />
        public void ReadDelta(Stream stream, bool keepDirtyDelta, ushort localTick, ushort remoteTick)
        {
            using (var reader = PooledNetworkReader.Get(stream))
            {
                ushort deltaCount = reader.ReadUInt16Packed();
                for (int i = 0; i < deltaCount; i++)
                {
                    var eventType = (NetworkSetEvent <T> .EventType)reader.ReadBits(2);
                    switch (eventType)
                    {
                    case NetworkSetEvent <T> .EventType.Add:
                    {
                        var value = (T)reader.ReadObjectPacked(typeof(T));         //BOX
                        m_Set.Add(value);

                        if (OnSetChanged != null)
                        {
                            OnSetChanged(new NetworkSetEvent <T>
                                {
                                    Type  = eventType,
                                    Value = value
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkSetEvent <T>()
                                {
                                    Type  = eventType,
                                    Value = value
                                });
                        }
                    }
                    break;

                    case NetworkSetEvent <T> .EventType.Remove:
                    {
                        var value = (T)reader.ReadObjectPacked(typeof(T));         //BOX
                        m_Set.Remove(value);

                        if (OnSetChanged != null)
                        {
                            OnSetChanged(new NetworkSetEvent <T>
                                {
                                    Type  = eventType,
                                    Value = value
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkSetEvent <T>()
                                {
                                    Type  = eventType,
                                    Value = value
                                });
                        }
                    }
                    break;

                    case NetworkSetEvent <T> .EventType.Clear:
                    {
                        //Read nothing
                        m_Set.Clear();

                        if (OnSetChanged != null)
                        {
                            OnSetChanged(new NetworkSetEvent <T>
                                {
                                    Type = eventType,
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkSetEvent <T>()
                                {
                                    Type = eventType
                                });
                        }
                    }
                    break;
                    }
                }
            }
        }
Пример #18
0
        internal static void HandleAddObject(ulong clientId, Stream stream)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleAddObject.Begin();
#endif
            using (var reader = PooledNetworkReader.Get(stream))
            {
                bool  isPlayerObject  = reader.ReadBool();
                ulong networkId       = reader.ReadUInt64Packed();
                ulong ownerId         = reader.ReadUInt64Packed();
                bool  hasParent       = reader.ReadBool();
                ulong?parentNetworkId = null;

                if (hasParent)
                {
                    parentNetworkId = reader.ReadUInt64Packed();
                }

                ulong prefabHash;
                ulong instanceId;
                bool  softSync;

                if (!NetworkManager.Singleton.NetworkConfig.EnableSceneManagement || NetworkManager.Singleton.NetworkConfig.UsePrefabSync)
                {
                    softSync   = false;
                    instanceId = 0;
                    prefabHash = reader.ReadUInt64Packed();
                }
                else
                {
                    softSync = reader.ReadBool();

                    if (softSync)
                    {
                        instanceId = reader.ReadUInt64Packed();
                        prefabHash = 0;
                    }
                    else
                    {
                        prefabHash = reader.ReadUInt64Packed();
                        instanceId = 0;
                    }
                }

                Vector3?   pos = null;
                Quaternion?rot = null;
                if (reader.ReadBool())
                {
                    pos = new Vector3(reader.ReadSinglePacked(), reader.ReadSinglePacked(), reader.ReadSinglePacked());
                    rot = Quaternion.Euler(reader.ReadSinglePacked(), reader.ReadSinglePacked(), reader.ReadSinglePacked());
                }

                bool hasPayload    = reader.ReadBool();
                int  payLoadLength = hasPayload ? reader.ReadInt32Packed() : 0;

                var networkObject = NetworkSpawnManager.CreateLocalNetworkObject(softSync, instanceId, prefabHash, parentNetworkId, pos, rot);
                NetworkSpawnManager.SpawnNetworkObjectLocally(networkObject, networkId, softSync, isPlayerObject, ownerId, stream, hasPayload, payLoadLength, true, false);

                Queue <BufferManager.BufferedMessage> bufferQueue = BufferManager.ConsumeBuffersForNetworkId(networkId);

                // Apply buffered messages
                if (bufferQueue != null)
                {
                    while (bufferQueue.Count > 0)
                    {
                        BufferManager.BufferedMessage message = bufferQueue.Dequeue();
                        NetworkManager.Singleton.HandleIncomingData(message.SenderClientId, message.NetworkChannel, new ArraySegment <byte>(message.NetworkBuffer.GetBuffer(), (int)message.NetworkBuffer.Position, (int)message.NetworkBuffer.Length), message.ReceiveTime, false);
                        BufferManager.RecycleConsumedBufferedMessage(message);
                    }
                }
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleAddObject.End();
#endif
        }
Пример #19
0
        /// <inheritdoc />
        public void ReadDelta(Stream stream, bool keepDirtyDelta, ushort localTick, ushort remoteTick)
        {
            using (var reader = PooledNetworkReader.Get(stream))
            {
                ushort deltaCount = reader.ReadUInt16Packed();
                for (int i = 0; i < deltaCount; i++)
                {
                    var eventType = (NetworkDictionaryEvent <TKey, TValue> .EventType)reader.ReadBits(3);
                    switch (eventType)
                    {
                    case NetworkDictionaryEvent <TKey, TValue> .EventType.Add:
                    {
                        var key   = (TKey)reader.ReadObjectPacked(typeof(TKey));
                        var value = (TValue)reader.ReadObjectPacked(typeof(TValue));
                        m_Dictionary.Add(key, value);

                        if (OnDictionaryChanged != null)
                        {
                            OnDictionaryChanged(new NetworkDictionaryEvent <TKey, TValue>
                                {
                                    Type  = eventType,
                                    Key   = key,
                                    Value = value
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkDictionaryEvent <TKey, TValue>()
                                {
                                    Type  = eventType,
                                    Key   = key,
                                    Value = value
                                });
                        }
                    }
                    break;

                    case NetworkDictionaryEvent <TKey, TValue> .EventType.Remove:
                    {
                        var    key = (TKey)reader.ReadObjectPacked(typeof(TKey));
                        TValue value;
                        m_Dictionary.TryGetValue(key, out value);
                        m_Dictionary.Remove(key);

                        if (OnDictionaryChanged != null)
                        {
                            OnDictionaryChanged(new NetworkDictionaryEvent <TKey, TValue>
                                {
                                    Type  = eventType,
                                    Key   = key,
                                    Value = value
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkDictionaryEvent <TKey, TValue>()
                                {
                                    Type  = eventType,
                                    Key   = key,
                                    Value = value
                                });
                        }
                    }
                    break;

                    case NetworkDictionaryEvent <TKey, TValue> .EventType.RemovePair:
                    {
                        var key   = (TKey)reader.ReadObjectPacked(typeof(TKey));
                        var value = (TValue)reader.ReadObjectPacked(typeof(TValue));
                        m_Dictionary.Remove(new KeyValuePair <TKey, TValue>(key, value));

                        if (OnDictionaryChanged != null)
                        {
                            OnDictionaryChanged(new NetworkDictionaryEvent <TKey, TValue>
                                {
                                    Type  = eventType,
                                    Key   = key,
                                    Value = value
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkDictionaryEvent <TKey, TValue>()
                                {
                                    Type  = eventType,
                                    Key   = key,
                                    Value = value
                                });
                        }
                    }
                    break;

                    case NetworkDictionaryEvent <TKey, TValue> .EventType.Clear:
                    {
                        //read nothing
                        m_Dictionary.Clear();

                        if (OnDictionaryChanged != null)
                        {
                            OnDictionaryChanged(new NetworkDictionaryEvent <TKey, TValue>
                                {
                                    Type = eventType
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkDictionaryEvent <TKey, TValue>
                                {
                                    Type = eventType
                                });
                        }
                    }
                    break;

                    case NetworkDictionaryEvent <TKey, TValue> .EventType.Value:
                    {
                        var key   = (TKey)reader.ReadObjectPacked(typeof(TKey));
                        var value = (TValue)reader.ReadObjectPacked(typeof(TValue));

                        m_Dictionary[key] = value;

                        if (OnDictionaryChanged != null)
                        {
                            OnDictionaryChanged(new NetworkDictionaryEvent <TKey, TValue>
                                {
                                    Type  = eventType,
                                    Key   = key,
                                    Value = value
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkDictionaryEvent <TKey, TValue>()
                                {
                                    Type  = eventType,
                                    Key   = key,
                                    Value = value
                                });
                        }
                    }
                    break;
                    }
                }
            }
        }
        private static void OnSceneUnloadClient(Guid switchSceneGuid, Stream objectStream)
        {
            if (!NetworkManager.Singleton.NetworkConfig.EnableSceneManagement || NetworkManager.Singleton.NetworkConfig.UsePrefabSync)
            {
                NetworkSpawnManager.DestroySceneObjects();

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

                    for (int i = 0; i < newObjectsCount; i++)
                    {
                        bool  isPlayerObject  = reader.ReadBool();
                        ulong networkId       = reader.ReadUInt64Packed();
                        ulong owner           = reader.ReadUInt64Packed();
                        bool  hasParent       = reader.ReadBool();
                        ulong?parentNetworkId = null;

                        if (hasParent)
                        {
                            parentNetworkId = reader.ReadUInt64Packed();
                        }

                        ulong prefabHash = reader.ReadUInt64Packed();

                        Vector3?   position = null;
                        Quaternion?rotation = null;
                        if (reader.ReadBool())
                        {
                            position = new Vector3(reader.ReadSinglePacked(), reader.ReadSinglePacked(), reader.ReadSinglePacked());
                            rotation = Quaternion.Euler(reader.ReadSinglePacked(), reader.ReadSinglePacked(), reader.ReadSinglePacked());
                        }

                        var networkObject = NetworkSpawnManager.CreateLocalNetworkObject(false, 0, prefabHash, parentNetworkId, position, rotation);
                        NetworkSpawnManager.SpawnNetworkObjectLocally(networkObject, networkId, true, isPlayerObject, owner, objectStream, false, 0, true, false);

                        var bufferQueue = BufferManager.ConsumeBuffersForNetworkId(networkId);

                        // Apply buffered messages
                        if (bufferQueue != null)
                        {
                            while (bufferQueue.Count > 0)
                            {
                                BufferManager.BufferedMessage message = bufferQueue.Dequeue();
                                NetworkManager.Singleton.HandleIncomingData(message.SenderClientId, message.NetworkChannel, new ArraySegment <byte>(message.NetworkBuffer.GetBuffer(), (int)message.NetworkBuffer.Position, (int)message.NetworkBuffer.Length), message.ReceiveTime, false);
                                BufferManager.RecycleConsumedBufferedMessage(message);
                            }
                        }
                    }
                }
            }
            else
            {
                var networkObjects = MonoBehaviour.FindObjectsOfType <NetworkObject>();
                NetworkSpawnManager.ClientCollectSoftSyncSceneObjectSweep(networkObjects);

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

                    for (int i = 0; i < newObjectsCount; i++)
                    {
                        bool  isPlayerObject  = reader.ReadBool();
                        ulong networkId       = reader.ReadUInt64Packed();
                        ulong owner           = reader.ReadUInt64Packed();
                        bool  hasParent       = reader.ReadBool();
                        ulong?parentNetworkId = null;

                        if (hasParent)
                        {
                            parentNetworkId = reader.ReadUInt64Packed();
                        }

                        ulong instanceId = reader.ReadUInt64Packed();

                        var networkObject = NetworkSpawnManager.CreateLocalNetworkObject(true, instanceId, 0, parentNetworkId, null, null);
                        NetworkSpawnManager.SpawnNetworkObjectLocally(networkObject, networkId, true, isPlayerObject, owner, objectStream, false, 0, true, false);

                        var bufferQueue = BufferManager.ConsumeBuffersForNetworkId(networkId);

                        // Apply buffered messages
                        if (bufferQueue != null)
                        {
                            while (bufferQueue.Count > 0)
                            {
                                BufferManager.BufferedMessage message = bufferQueue.Dequeue();
                                NetworkManager.Singleton.HandleIncomingData(message.SenderClientId, message.NetworkChannel, new ArraySegment <byte>(message.NetworkBuffer.GetBuffer(), (int)message.NetworkBuffer.Position, (int)message.NetworkBuffer.Length), message.ReceiveTime, false);
                                BufferManager.RecycleConsumedBufferedMessage(message);
                            }
                        }
                    }
                }
            }

            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;

            OnSceneSwitched?.Invoke();
        }
        public void NetworkObjectSceneSerializationFailure()
        {
            var networkObjectsToTest = new List <GameObject>();

            var pooledBuffer = PooledNetworkBuffer.Get();
            var writer       = PooledNetworkWriter.Get(pooledBuffer);
            var reader       = PooledNetworkReader.Get(pooledBuffer);
            var invalidNetworkObjectOffsets   = new List <long>();
            var invalidNetworkObjectIdCount   = new List <int>();
            var invalidNetworkObjects         = new List <GameObject>();
            var invalidNetworkObjectFrequency = 3;

            // Construct 50 NetworkObjects
            for (int i = 0; i < 50; i++)
            {
                // Inject an invalid NetworkObject every [invalidNetworkObjectFrequency] entry
                if ((i % invalidNetworkObjectFrequency) == 0)
                {
                    // Create the invalid NetworkObject
                    var gameObject = new GameObject($"InvalidTestObject{i}");

                    Assert.IsNotNull(gameObject);

                    var networkObject = gameObject.AddComponent <NetworkObject>();

                    Assert.IsNotNull(networkObject);

                    var networkVariableComponent = gameObject.AddComponent <NetworkBehaviourWithNetworkVariables>();
                    Assert.IsNotNull(networkVariableComponent);

                    // Add invalid NetworkObject's starting position before serialization to handle trapping for the Debug.LogError message
                    // that we know will be thrown
                    invalidNetworkObjectOffsets.Add(pooledBuffer.Position);

                    networkObject.GlobalObjectIdHash = (uint)(i);
                    invalidNetworkObjectIdCount.Add(i);

                    invalidNetworkObjects.Add(gameObject);

                    // Serialize the invalid NetworkObject
                    networkObject.SerializeSceneObject(writer, 0);

                    Debug.Log($"Invalid {nameof(NetworkObject)} Size {pooledBuffer.Position - invalidNetworkObjectOffsets[invalidNetworkObjectOffsets.Count - 1]}");

                    // Now adjust how frequent we will inject invalid NetworkObjects
                    invalidNetworkObjectFrequency = Random.Range(2, 5);
                }
                else
                {
                    // Create a valid NetworkObject
                    var gameObject = new GameObject($"TestObject{i}");

                    Assert.IsNotNull(gameObject);

                    var networkObject = gameObject.AddComponent <NetworkObject>();

                    var networkVariableComponent = gameObject.AddComponent <NetworkBehaviourWithNetworkVariables>();
                    Assert.IsNotNull(networkVariableComponent);

                    Assert.IsNotNull(networkObject);

                    networkObject.GlobalObjectIdHash = (uint)(i + 4096);

                    networkObjectsToTest.Add(gameObject);

                    // Serialize the valid NetworkObject
                    networkObject.SerializeSceneObject(writer, 0);

                    // Add this valid NetworkObject into the PendinigSoftSyncObjects list
                    NetworkManagerHelper.NetworkManagerObject.SpawnManager.PendingSoftSyncObjects.Add(networkObject.GlobalObjectIdHash, networkObject);
                }
            }

            var totalBufferSize = pooledBuffer.Position;

            // Reset the position for reading this information
            pooledBuffer.Position = 0;

            var networkObjectsDeSerialized = new List <NetworkObject>();
            var currentLogLevel            = NetworkManager.Singleton.LogLevel;
            var invalidNetworkObjectCount  = 0;

            while (pooledBuffer.Position != totalBufferSize)
            {
                // If we reach the point where we expect it to fail, then make sure we let TestRunner know it should expect this log error message
                if (invalidNetworkObjectOffsets.Count > 0 && pooledBuffer.Position == invalidNetworkObjectOffsets[0])
                {
                    invalidNetworkObjectOffsets.RemoveAt(0);

                    // Turn off Network Logging to avoid other errors that we know will happen after the below LogAssert.Expect message occurs.
                    NetworkManager.Singleton.LogLevel = Logging.LogLevel.Nothing;

                    // Trap for this specific error message so we don't make Test Runner think we failed (it will fail on Debug.LogError)
                    UnityEngine.TestTools.LogAssert.Expect(LogType.Error, $"Failed to spawn {nameof(NetworkObject)} for Hash {invalidNetworkObjectIdCount[invalidNetworkObjectCount]}.");

                    invalidNetworkObjectCount++;
                }
                var deserializedNetworkObject = NetworkObject.DeserializeSceneObject(pooledBuffer, reader, NetworkManagerHelper.NetworkManagerObject);
                if (deserializedNetworkObject != null)
                {
                    networkObjectsDeSerialized.Add(deserializedNetworkObject);
                }
                else
                {
                    // Under this condition, we are expecting null (i.e. no NetworkObject instantiated)
                    // and will set our log level back to the original value to assure the valid NetworkObjects
                    // aren't causing any log Errors to occur
                    NetworkManager.Singleton.LogLevel = currentLogLevel;
                }
            }

            reader.Dispose();
            writer.Dispose();
            NetworkBufferPool.PutBackInPool(pooledBuffer);

            // Now validate all NetworkObjects returned against the original NetworkObjects we created
            // after they validate, destroy the objects
            foreach (var entry in networkObjectsToTest)
            {
                var entryNetworkObject = entry.GetComponent <NetworkObject>();
                Assert.IsTrue(networkObjectsDeSerialized.Contains(entryNetworkObject));
                Object.Destroy(entry);
            }

            // Destroy the invalid network objects
            foreach (var entry in invalidNetworkObjects)
            {
                Object.Destroy(entry);
            }
        }
        /// <summary>
        /// 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>
        private void Initialize(uint maxFrameHistory)
        {
            //This makes sure that we don't exceed a ridiculous value by capping the number of queue history frames to ushort.MaxValue
            //If this value is exceeded, then it will be kept at the ceiling of ushort.Maxvalue.
            //Note: If running at a 60pps rate (16ms update frequency) this would yield 17.47 minutes worth of queue frame history.
            if (maxFrameHistory > ushort.MaxValue)
            {
                if (NetworkLog.CurrentLogLevel == LogLevel.Developer)
                {
                    NetworkLog.LogWarning($"The {nameof(RpcQueueHistoryFrame)} size cannot exceed {ushort.MaxValue} {nameof(RpcQueueHistoryFrame)}s! Capping at {ushort.MaxValue} {nameof(RpcQueueHistoryFrame)}s.");
                }
                maxFrameHistory = ushort.MaxValue;
            }

            ClearParameters();

            m_RpcQueueProcessor = new RpcQueueProcessor(this, NetworkManager);
            m_MaxFrameHistory   = maxFrameHistory + k_MinQueueHistory;

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

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

            for (int i = 0; i < m_MaxFrameHistory; i++)
            {
                if (!m_QueueHistory[RpcQueueHistoryFrame.QueueFrameType.Outbound].ContainsKey(i))
                {
                    m_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)
                    m_QueueHistory[RpcQueueHistoryFrame.QueueFrameType.Outbound][i].Add(NetworkUpdateStage.PostLateUpdate, queueHistoryFrame);
                }

                if (!m_QueueHistory[RpcQueueHistoryFrame.QueueFrameType.Inbound].ContainsKey(i))
                {
                    m_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>();
                        m_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();
            }
        }
Пример #23
0
        internal static void SetNetworkVariableData(List <INetworkVariable> networkVariableList, Stream stream, NetworkManager networkManager)
        {
            if (networkVariableList.Count == 0)
            {
                return;
            }

            using (var reader = PooledNetworkReader.Get(stream))
            {
                for (int j = 0; j < networkVariableList.Count; j++)
                {
                    ushort varSize = 0;

                    if (networkManager.NetworkConfig.EnsureNetworkVariableLengthSafety)
                    {
                        varSize = reader.ReadUInt16Packed();

                        if (varSize == 0)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (!reader.ReadBool())
                        {
                            continue;
                        }
                    }

                    long readStartPos = stream.Position;

                    networkVariableList[j].ReadField(stream, NetworkTickSystem.NoTick, NetworkTickSystem.NoTick);

                    if (networkManager.NetworkConfig.EnsureNetworkVariableLengthSafety)
                    {
                        if (stream is NetworkBuffer networkBuffer)
                        {
                            networkBuffer.SkipPadBits();
                        }

                        if (stream.Position > (readStartPos + varSize))
                        {
                            if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                            {
                                NetworkLog.LogWarning($"Var data read too far. {stream.Position - (readStartPos + varSize)} bytes.");
                            }

                            stream.Position = readStartPos + varSize;
                        }
                        else if (stream.Position < (readStartPos + varSize))
                        {
                            if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                            {
                                NetworkLog.LogWarning($"Var data read too little. {(readStartPos + varSize) - stream.Position} bytes.");
                            }

                            stream.Position = readStartPos + varSize;
                        }
                    }
                }
            }
        }
Пример #24
0
        internal static void HandleNetworkVariableUpdate(List <INetworkVariable> networkVariableList, Stream stream, ulong clientId, NetworkBehaviour logInstance, NetworkManager networkManager)
        {
            using (var reader = PooledNetworkReader.Get(stream))
            {
                for (int i = 0; i < networkVariableList.Count; i++)
                {
                    ushort varSize = 0;

                    if (networkManager.NetworkConfig.EnsureNetworkVariableLengthSafety)
                    {
                        varSize = reader.ReadUInt16Packed();

                        if (varSize == 0)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (!reader.ReadBool())
                        {
                            continue;
                        }
                    }

                    if (networkManager.IsServer && !networkVariableList[i].CanClientWrite(clientId))
                    {
                        if (networkManager.NetworkConfig.EnsureNetworkVariableLengthSafety)
                        {
                            if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                            {
                                NetworkLog.LogWarning($"Client wrote to {nameof(NetworkVariable)} without permission. => {(logInstance != null ? ($"{nameof(NetworkObjectId)}: {logInstance.NetworkObjectId} - {nameof(NetworkObject.GetNetworkBehaviourOrderIndex)}(): {logInstance.NetworkObject.GetNetworkBehaviourOrderIndex(logInstance)} - VariableIndex: {i}") : string.Empty)}");
                            }

                            stream.Position += varSize;
                            continue;
                        }

                        //This client wrote somewhere they are not allowed. This is critical
                        //We can't just skip this field. Because we don't actually know how to dummy read
                        //That is, we don't know how many bytes to skip. Because the interface doesn't have a
                        //Read that gives us the value. Only a Read that applies the value straight away
                        //A dummy read COULD be added to the interface for this situation, but it's just being too nice.
                        //This is after all a developer fault. A critical error should be fine.
                        // - TwoTen
                        if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
                        {
                            NetworkLog.LogError($"Client wrote to {nameof(NetworkVariable)} without permission. No more variables can be read. This is critical. => {(logInstance != null ? ($"{nameof(NetworkObjectId)}: {logInstance.NetworkObjectId} - {nameof(NetworkObject.GetNetworkBehaviourOrderIndex)}(): {logInstance.NetworkObject.GetNetworkBehaviourOrderIndex(logInstance)} - VariableIndex: {i}") : string.Empty)}");
                        }

                        return;
                    }

                    long readStartPos = stream.Position;

                    networkVariableList[i].ReadField(stream, NetworkTickSystem.NoTick, NetworkTickSystem.NoTick);
                    PerformanceDataManager.Increment(ProfilerConstants.NetworkVarUpdates);

                    ProfilerStatManager.NetworkVarsRcvd.Record();

                    if (networkManager.NetworkConfig.EnsureNetworkVariableLengthSafety)
                    {
                        if (stream is NetworkBuffer networkBuffer)
                        {
                            networkBuffer.SkipPadBits();
                        }

                        if (stream.Position > (readStartPos + varSize))
                        {
                            if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                            {
                                NetworkLog.LogWarning($"Var update read too far. {stream.Position - (readStartPos + varSize)} bytes. => {(logInstance != null ? ($"{nameof(NetworkObjectId)}: {logInstance.NetworkObjectId} - {nameof(NetworkObject.GetNetworkBehaviourOrderIndex)}(): {logInstance.NetworkObject.GetNetworkBehaviourOrderIndex(logInstance)} - VariableIndex: {i}") : string.Empty)}");
                            }

                            stream.Position = readStartPos + varSize;
                        }
                        else if (stream.Position < (readStartPos + varSize))
                        {
                            if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
                            {
                                NetworkLog.LogWarning($"Var update read too little. {(readStartPos + varSize) - stream.Position} bytes. => {(logInstance != null ? ($"{nameof(NetworkObjectId)}: {logInstance.NetworkObjectId} - {nameof(NetworkObject.GetNetworkBehaviourOrderIndex)}(): {logInstance.NetworkObject.GetNetworkBehaviourOrderIndex(logInstance)} - VariableIndex: {i}") : string.Empty)}");
                            }

                            stream.Position = readStartPos + varSize;
                        }
                    }
                }
            }
        }
Пример #25
0
        internal static void HandleConnectionApproved(ulong clientId, Stream stream, float receiveTime)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleConnectionApproved.Begin();
#endif
            using (var reader = PooledNetworkReader.Get(stream))
            {
                NetworkManager.Singleton.LocalClientId = reader.ReadUInt64Packed();

                uint sceneIndex = 0;
                Guid sceneSwitchProgressGuid = new Guid();

                if (NetworkManager.Singleton.NetworkConfig.EnableSceneManagement)
                {
                    sceneIndex = reader.ReadUInt32Packed();
                    sceneSwitchProgressGuid = new Guid(reader.ReadByteArray());
                }

                bool sceneSwitch = NetworkManager.Singleton.NetworkConfig.EnableSceneManagement && NetworkSceneManager.HasSceneMismatch(sceneIndex);

                float netTime = reader.ReadSinglePacked();
                NetworkManager.Singleton.UpdateNetworkTime(clientId, netTime, receiveTime, true);

                NetworkManager.Singleton.ConnectedClients.Add(NetworkManager.Singleton.LocalClientId, new NetworkClient {
                    ClientId = NetworkManager.Singleton.LocalClientId
                });


                void DelayedSpawnAction(Stream continuationStream)
                {
                    using (var continuationReader = PooledNetworkReader.Get(continuationStream))
                    {
                        if (!NetworkManager.Singleton.NetworkConfig.EnableSceneManagement || NetworkManager.Singleton.NetworkConfig.UsePrefabSync)
                        {
                            NetworkSpawnManager.DestroySceneObjects();
                        }
                        else
                        {
                            NetworkSpawnManager.ClientCollectSoftSyncSceneObjectSweep(null);
                        }

                        uint objectCount = continuationReader.ReadUInt32Packed();
                        for (int i = 0; i < objectCount; i++)
                        {
                            bool  isPlayerObject  = continuationReader.ReadBool();
                            ulong networkId       = continuationReader.ReadUInt64Packed();
                            ulong ownerId         = continuationReader.ReadUInt64Packed();
                            bool  hasParent       = continuationReader.ReadBool();
                            ulong?parentNetworkId = null;

                            if (hasParent)
                            {
                                parentNetworkId = continuationReader.ReadUInt64Packed();
                            }

                            ulong prefabHash;
                            ulong instanceId;
                            bool  softSync;

                            if (!NetworkManager.Singleton.NetworkConfig.EnableSceneManagement || NetworkManager.Singleton.NetworkConfig.UsePrefabSync)
                            {
                                softSync   = false;
                                instanceId = 0;
                                prefabHash = continuationReader.ReadUInt64Packed();
                            }
                            else
                            {
                                softSync = continuationReader.ReadBool();

                                if (softSync)
                                {
                                    instanceId = continuationReader.ReadUInt64Packed();
                                    prefabHash = 0;
                                }
                                else
                                {
                                    prefabHash = continuationReader.ReadUInt64Packed();
                                    instanceId = 0;
                                }
                            }

                            Vector3?   pos = null;
                            Quaternion?rot = null;
                            if (continuationReader.ReadBool())
                            {
                                pos = new Vector3(continuationReader.ReadSinglePacked(), continuationReader.ReadSinglePacked(), continuationReader.ReadSinglePacked());
                                rot = Quaternion.Euler(continuationReader.ReadSinglePacked(), continuationReader.ReadSinglePacked(), continuationReader.ReadSinglePacked());
                            }

                            var networkObject = NetworkSpawnManager.CreateLocalNetworkObject(softSync, instanceId, prefabHash, parentNetworkId, pos, rot);
                            NetworkSpawnManager.SpawnNetworkObjectLocally(networkObject, networkId, softSync, isPlayerObject, ownerId, continuationStream, false, 0, true, false);

                            Queue <BufferManager.BufferedMessage> bufferQueue = BufferManager.ConsumeBuffersForNetworkId(networkId);

                            // Apply buffered messages
                            if (bufferQueue != null)
                            {
                                while (bufferQueue.Count > 0)
                                {
                                    BufferManager.BufferedMessage message = bufferQueue.Dequeue();
                                    NetworkManager.Singleton.HandleIncomingData(message.SenderClientId, message.NetworkChannel, new ArraySegment <byte>(message.NetworkBuffer.GetBuffer(), (int)message.NetworkBuffer.Position, (int)message.NetworkBuffer.Length), message.ReceiveTime, false);
                                    BufferManager.RecycleConsumedBufferedMessage(message);
                                }
                            }
                        }

                        NetworkSpawnManager.CleanDiffedSceneObjects();
                        NetworkManager.Singleton.IsConnectedClient = true;
                        NetworkManager.Singleton.InvokeOnClientConnectedCallback(NetworkManager.Singleton.LocalClientId);
                    }
                }

                if (sceneSwitch)
                {
                    UnityAction <Scene, Scene> onSceneLoaded = null;

                    var continuationBuffer = new NetworkBuffer();
                    continuationBuffer.CopyUnreadFrom(stream);
                    continuationBuffer.Position = 0;

                    void OnSceneLoadComplete()
                    {
                        SceneManager.activeSceneChanged -= onSceneLoaded;
                        NetworkSceneManager.IsSpawnedObjectsPendingInDontDestroyOnLoad = false;
                        DelayedSpawnAction(continuationBuffer);
                    }

                    onSceneLoaded = (oldScene, newScene) => { OnSceneLoadComplete(); };
                    SceneManager.activeSceneChanged += onSceneLoaded;
                    NetworkSceneManager.OnFirstSceneSwitchSync(sceneIndex, sceneSwitchProgressGuid);
                }
                else
                {
                    DelayedSpawnAction(stream);
                }
            }
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            s_HandleConnectionApproved.End();
#endif
        }
Пример #26
0
        /// <inheritdoc />
        public void ReadDelta(Stream stream, bool keepDirtyDelta, ushort localTick, ushort remoteTick)
        {
            using (var reader = PooledNetworkReader.Get(stream))
            {
                ushort deltaCount = reader.ReadUInt16Packed();
                for (int i = 0; i < deltaCount; i++)
                {
                    NetworkListEvent <T> .EventType eventType = (NetworkListEvent <T> .EventType)reader.ReadBits(3);
                    switch (eventType)
                    {
                    case NetworkListEvent <T> .EventType.Add:
                    {
                        m_List.Add((T)reader.ReadObjectPacked(typeof(T)));     //BOX

                        if (OnListChanged != null)
                        {
                            OnListChanged(new NetworkListEvent <T>
                                {
                                    Type  = eventType,
                                    Index = m_List.Count - 1,
                                    Value = m_List[m_List.Count - 1]
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkListEvent <T>()
                                {
                                    Type  = eventType,
                                    Index = m_List.Count - 1,
                                    Value = m_List[m_List.Count - 1]
                                });
                        }
                    }
                    break;

                    case NetworkListEvent <T> .EventType.Insert:
                    {
                        int index = reader.ReadInt32Packed();
                        m_List.Insert(index, (T)reader.ReadObjectPacked(typeof(T)));     //BOX

                        if (OnListChanged != null)
                        {
                            OnListChanged(new NetworkListEvent <T>
                                {
                                    Type  = eventType,
                                    Index = index,
                                    Value = m_List[index]
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkListEvent <T>()
                                {
                                    Type  = eventType,
                                    Index = index,
                                    Value = m_List[index]
                                });
                        }
                    }
                    break;

                    case NetworkListEvent <T> .EventType.Remove:
                    {
                        T   value = (T)reader.ReadObjectPacked(typeof(T));   //BOX
                        int index = m_List.IndexOf(value);
                        m_List.RemoveAt(index);

                        if (OnListChanged != null)
                        {
                            OnListChanged(new NetworkListEvent <T>
                                {
                                    Type  = eventType,
                                    Index = index,
                                    Value = value
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkListEvent <T>()
                                {
                                    Type  = eventType,
                                    Index = index,
                                    Value = value
                                });
                        }
                    }
                    break;

                    case NetworkListEvent <T> .EventType.RemoveAt:
                    {
                        int index = reader.ReadInt32Packed();
                        T   value = m_List[index];
                        m_List.RemoveAt(index);

                        if (OnListChanged != null)
                        {
                            OnListChanged(new NetworkListEvent <T>
                                {
                                    Type  = eventType,
                                    Index = index,
                                    Value = value
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkListEvent <T>()
                                {
                                    Type  = eventType,
                                    Index = index,
                                    Value = value
                                });
                        }
                    }
                    break;

                    case NetworkListEvent <T> .EventType.Value:
                    {
                        int index = reader.ReadInt32Packed();
                        T   value = (T)reader.ReadObjectPacked(typeof(T));   //BOX
                        if (index < m_List.Count)
                        {
                            m_List[index] = value;
                        }

                        if (OnListChanged != null)
                        {
                            OnListChanged(new NetworkListEvent <T>
                                {
                                    Type  = eventType,
                                    Index = index,
                                    Value = value
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkListEvent <T>()
                                {
                                    Type  = eventType,
                                    Index = index,
                                    Value = value
                                });
                        }
                    }
                    break;

                    case NetworkListEvent <T> .EventType.Clear:
                    {
                        //Read nothing
                        m_List.Clear();

                        if (OnListChanged != null)
                        {
                            OnListChanged(new NetworkListEvent <T>
                                {
                                    Type = eventType,
                                });
                        }

                        if (keepDirtyDelta)
                        {
                            m_DirtyEvents.Add(new NetworkListEvent <T>()
                                {
                                    Type = eventType
                                });
                        }
                    }
                    break;
                    }
                }
            }
        }