internal static void HandleNetworkVariableUpdate(List <INetworkVariable> networkVariableList, Stream stream, ulong clientId, NetworkBehaviour logInstance)
        {
            using (var reader = PooledNetworkReader.Get(stream))
            {
                for (int i = 0; i < networkVariableList.Count; i++)
                {
                    ushort varSize = 0;

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

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

                    if (IsServer && !networkVariableList[i].CanClientWrite(clientId))
                    {
                        if (NetworkManager.Singleton.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.Singleton.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;
                        }
                    }
                }
            }
        }
        internal static void SetNetworkVariableData(List <INetworkVariable> networkVariableList, Stream stream)
        {
            if (networkVariableList.Count == 0)
            {
                return;
            }

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

                    if (NetworkManager.Singleton.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.Singleton.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;
                        }
                    }
                }
            }
        }
Example #3
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++)
                {
                    NetworkSetEvent <T> .EventType eventType = (NetworkSetEvent <T> .EventType)reader.ReadBits(2);
                    switch (eventType)
                    {
                    case NetworkSetEvent <T> .EventType.Add:
                    {
                        T 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:
                    {
                        T 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;
                    }
                }
            }
        }