protected override void Parse(ref BitStreamReader bsr)
        {
            StringTablesManager manager = DemoRef.StringTablesManager;

            if (!manager.TableReadable.GetValueOrDefault(_tableName))
            {
                DemoRef.LogError($"{_tableName} table is marked as non-readable, can't update :/");
                _exceptionWhileParsing = true;
                bsr.SkipToEnd();
                return;
            }

            if (manager.CreationLookup.Single(table => table.TableName == _tableName).Flags == StringTableFlags.Fake)
            {
                DemoRef.LogError($"{_tableName} table was created manually - not parsed in SvcServerInfo");
                _exceptionWhileParsing = true;
                bsr.SkipToEnd();
                return;
            }

            try {             // se2007/engine/networkstringtable.cpp  line 595
                MutableStringTable tableToUpdate = manager.Tables[_tableName];

                int?decompressedIndex = null;
                if (tableToUpdate.Flags.HasValue && (tableToUpdate.Flags & StringTableFlags.DataCompressed) != 0 && _canCompress)
                {
                    // decompress the data - engine/baseclientstate.cpp (hl2_src) line 1364
                    int    uncompressedSize = bsr.ReadSInt();
                    int    compressedSize   = bsr.ReadSInt();
                    byte[] data             = Compression.Decompress(ref bsr, compressedSize - 8); // -8 to ignore header
                    decompressedIndex = DemoRef.DecompressedLookup.Count;
                    DemoRef.DecompressedLookup.Add(data);                                          // so that we can access the reader for the entries later
                    if (data.Length != uncompressedSize)
                    {
                        throw new Exception("could not decompress data in string table update");
                    }
                    bsr = new BitStreamReader(data);
                }

                int entryIndex = -1;
                var history    = new C5.CircularQueue <string>(32);

                for (int i = 0; i < _numUpdatedEntries; i++)
                {
                    entryIndex++;
                    if (!bsr.ReadBool())
                    {
                        entryIndex = (int)bsr.ReadUInt(BitUtils.HighestBitIndex(tableToUpdate.MaxEntries));
                    }

                    string?entryName = null;
                    if (bsr.ReadBool())
                    {
                        if (bsr.ReadBool())                           // the first part of the string may be the same as for other entries
                        {
                            int index     = (int)bsr.ReadUInt(5);
                            int subStrLen = (int)bsr.ReadUInt(SubStringBits);
                            entryName  = history[index][..subStrLen];
Example #2
0
 protected override void Parse(ref BitStreamReader bsr)
 {
     PlayerMasks = new PlayerMask[VoiceMaxPlayers];
     for (int i = 0; i < VoiceMaxPlayers; i++)
     {
         PlayerMasks[i] = new PlayerMask {
             GameRulesMask = bsr.ReadSInt(), BanMask = bsr.ReadSInt()
         }
     }
     ;
     PlayerModEnable = bsr.ReadByte() != 0;
 }
Example #3
0
 protected override void Parse(ref BitStreamReader bsr)
 {
     FileStamp       = bsr.ReadStringOfLength(8);
     DemoProtocol    = bsr.ReadUInt();
     NetworkProtocol = bsr.ReadUInt();
     ServerName      = bsr.ReadStringOfLength(260);
     ClientName      = bsr.ReadStringOfLength(260);
     MapName         = bsr.ReadStringOfLength(260);
     GameDirectory   = bsr.ReadStringOfLength(260);
     PlaybackTime    = bsr.ReadFloat();
     TickCount       = bsr.ReadSInt();
     FrameCount      = bsr.ReadSInt();
     SignOnLength    = bsr.ReadUInt();
 }
        public static unsafe byte[] Decompress(ref BitStreamReader bsr, int compSize)
        {
            uint type       = bsr.ReadUInt();
            int  decompSize = bsr.ReadSInt();

            switch (type)
            {
            case LZSS_ID:
                Span <byte> dataIn = compSize < 100000 ? stackalloc byte[compSize] : new byte[compSize];
                bsr.ReadToSpan(dataIn);
                byte[] arrOut = new byte[decompSize];

                fixed(byte *pDataIn = dataIn)
                fixed(byte *pDataOut = arrOut)
                DecompressLZSS(pDataIn, pDataOut);

                return(arrOut);

            case SNAPPY_ID:
                Debug.Assert(false);
                throw new NotImplementedException("snappy decompression not implemented");

            default:
                throw new InvalidOperationException("unknown compression method");
            }
        }
        // src_main/common/netmessages.cpp  SVC_ServerInfo::WriteToBuffer
        protected override void Parse(ref BitStreamReader bsr)
        {
            NetworkProtocol = bsr.ReadUShort();
            ServerCount     = bsr.ReadUInt();
            IsHltv          = bsr.ReadBool();
            IsDedicated     = bsr.ReadBool();
            if (DemoInfo.IsLeft4Dead() && DemoInfo.Game >= SourceGame.L4D2_2147)
            {
                UnknownBit = bsr.ReadBool();
            }
            ClientCrc = bsr.ReadSInt();
            if (DemoInfo.NewDemoProtocol)             // unknown field, could be before ClientCrc
            {
                Unknown = bsr.ReadUInt();
            }
            MaxServerClasses = bsr.ReadUShort();
            if (NetworkProtocol == 24)
            {
                MapMD5 = bsr.ReadBytes(16);
            }
            else
            {
                MapCrc = bsr.ReadUInt();                 // network protocol < 18 according to p2 leak, but doesn't add up for l4d2 and p2
            }
            PlayerCount     = bsr.ReadByte();
            MaxClients      = bsr.ReadByte();
            TickInterval    = bsr.ReadFloat();
            Platform        = (char)bsr.ReadByte();
            GameDirBitIndex = bsr.AbsoluteBitIndex;
            GameDir         = bsr.ReadNullTerminatedString();
            MapName         = bsr.ReadNullTerminatedString();
            SkyName         = bsr.ReadNullTerminatedString();
            HostName        = bsr.ReadNullTerminatedString();
            if (DemoInfo.IsLeft4Dead() && DemoInfo.Game >= SourceGame.L4D2_2147)
            {
                MissionName  = bsr.ReadNullTerminatedString();
                MutationName = bsr.ReadNullTerminatedString();
            }
            if (NetworkProtocol == 24)
            {
                HasReplay = bsr.ReadBool();                 // protocol version >= 16
            }
            // there's a good change that the first SvcServerInfo parsed is parsed correctly
            // prevent the interval from being overwritten by subsequent, incorrectly detected, SvcServerInfo messages
            // TODO: check if changing tickrate mid game sends another SvcServerInfo
            if (!DemoInfo.HasParsedTickInterval)
            {
                DemoInfo.TickInterval          = TickInterval;
                DemoInfo.HasParsedTickInterval = true;
            }
            // this packet always(?) appears before the creation of any tables

            DemoRef.StringTablesManager.ClearCurrentTables();

            // init baselines here
            DemoRef.EntBaseLines = new EntityBaseLines(DemoRef, MaxServerClasses);
        }
Example #6
0
        protected override void Parse(ref BitStreamReader bsr)
        {
            Armor       = bsr.ReadByte();
            DamageTaken = bsr.ReadByte();
            BitsDamage  = bsr.ReadSInt();
            bsr.ReadVector3(out VecFrom);

            /*VecFrom = new Vector3 {       old engine?
             *      X = bsr.ReadCoord(),
             *      Y = bsr.ReadCoord(),
             *      Z = bsr.ReadCoord()
             * };*/
        }
        protected override void Parse(ref BitStreamReader bsr)
        {
            DataType = (CustomDataType)bsr.ReadSInt();
            uint size = bsr.ReadUInt();

            DataMessage = CustomDataFactory.CreateCustomDataMessage(DemoRef, DataType);
            try {
                DataMessage.ParseStream(bsr.SplitAndSkip(size * 8));
            } catch (Exception e) {
                DemoRef.LogError($"error while parsing custom data of type: {DataType}... {e.Message}");
                DataMessage = new UnknownCustomDataMessage(DemoRef);
            }
        }
Example #8
0
        protected override void Parse(ref BitStreamReader bsr)
        {
            Command = bsr.ReadStringOfLength(bsr.ReadSInt());
            TimingAdjustment.AdjustFromConsoleCmd(this);
            Match match = KeyPressRegex.Match(Command);

            if (match.Success)
            {
                int val = int.Parse(match.Groups[1].Value);
                if (val >= 0 && val < (int)Packets.ButtonCode.LAST)
                {
                    ButtonCode = (ButtonCode)val;
                }
            }
        }
Example #9
0
        protected override void Parse(ref BitStreamReader bsr)
        {
            int  byteLen           = bsr.ReadSInt();
            int  indexBeforeTables = bsr.CurrentBitIndex;
            byte tableCount        = bsr.ReadByte();

            Tables = new List <StringTable>(tableCount);
            for (int i = 0; i < tableCount; i++)
            {
                var table = new StringTable(DemoRef);
                Tables.Add(table);
                table.ParseStream(ref bsr);
            }
            bsr.CurrentBitIndex = indexBeforeTables + byteLen * 8;

            // if this packet exists make sure to create the tables manager after we parse this
            DemoRef.StringTablesManager.CreateTablesFromPacket(this);
        }
Example #10
0
        protected override void Parse(ref BitStreamReader bsr)
        {
            byte typeVal = bsr.ReadByte();

            Type = DemoPacket.ByteToPacketType(DemoInfo, typeVal);

            if (Type == PacketType.Unknown)
            {
                throw new ArgumentException("no byte->packet mapper found for this game!");
            }
            else if (Type == PacketType.Invalid)
            {
                throw new ArgumentException($"Illegal packet type: {typeVal}");
            }

            // very last byte is cut off in (all?) demos, copy data from the previous frame if this is the case

            Tick = bsr.BitsRemaining >= 32
                                ? bsr.ReadSInt()
                                : (int)bsr.ReadUInt(24) | (DemoRef.Frames[^ 2].Tick & (0xff << 24));
Example #11
0
 // we're reading a player_info_t, so take alignment into account
 protected override void Parse(ref BitStreamReader bsr)
 {
     if (DemoInfo.NewDemoProtocol && !DemoInfo.IsLeft4Dead1())
     {
         SteamId = (CSteamId)bsr.ReadULong();
     }
     Name   = bsr.ReadStringOfLength(MaxPlayerNameLength);
     UserId = bsr.ReadSInt();
     Guid   = bsr.ReadStringOfLength(SignedGuidLen + 1);
     bsr.SkipBytes(3);
     FriendsId   = bsr.ReadUInt();
     FriendsName = bsr.ReadStringOfLength(MaxPlayerNameLength);
     FakePlayer  = bsr.ReadByte() != 0;
     IsHlTv      = bsr.ReadByte() != 0;
     bsr.SkipBytes(2);
     CustomFiles     = new[] { bsr.ReadUInt(), bsr.ReadUInt(), bsr.ReadUInt(), bsr.ReadUInt() };
     FilesDownloaded = bsr.ReadByte();
     bsr.SkipBytes(3);
     // for demo protocol 4 there's 4 additional bytes somewhere for some reason
 }
        protected override void Parse(ref BitStreamReader bsr)
        {
            // first, we read the main message info here
            MaxEntries     = (ushort)bsr.ReadUInt(11);
            IsDelta        = bsr.ReadBool();
            DeltaFrom      = IsDelta ? bsr.ReadSInt() : -1;
            BaseLine       = bsr.ReadUInt(1);
            UpdatedEntries = (ushort)bsr.ReadUInt(11);
            uint dataLen = bsr.ReadUInt(20);

            UpdateBaseline = bsr.ReadBool();
            _entBsr        = bsr.SplitAndSkip(dataLen);

#if !FORCE_PROCESS_ENTS
            if ((DemoRef.DemoParseResult & DemoParseResult.EntParsingEnabled) == 0 ||
                (DemoRef.DemoParseResult & DemoParseResult.EntParsingFailed) != 0)
            {
                return;
            }
#endif
            // now, we do some setup for ent parsing
            ref EntitySnapshot?snapshot = ref DemoRef.EntitySnapshot;
Example #13
0
 protected override void Parse(ref BitStreamReader bsr)
 {
     SignOnState = (SignOnState)bsr.ReadByte();
     SpawnCount  = bsr.ReadSInt();
     if (DemoInfo.NewDemoProtocol)
     {
         NumServerPlayers = bsr.ReadUInt();
         int length = (int)bsr.ReadUInt();
         if (length > 0)
         {
             PlayerNetworkIds = bsr.ReadBytes(length);
         }
         length = (int)bsr.ReadUInt();
         if (length > 0)                 // the string still seams to be null terminated (sometimes?)
         {
             MapName = bsr.ReadStringOfLength(length).Split(new char[] { '\0' }, 2)[0];
         }
     }
     if (SignOnState == SignOnState.PreSpawn)
     {
         DemoRef.ClientSoundSequence = 1;                 // reset sound sequence number after receiving SignOn sounds
     }
 }
Example #14
0
        public void WriteSInts()
        {
            var                        random = new Random(0);
            BitStreamWriter            bsw    = new BitStreamWriter();
            List <(int val, int size)> bits   = new List <(int val, int size)>();

            for (int _ = 0; _ < Iterations; _++)
            {
                (int val, int size)r = (random.Next(), random.Next(1, 33));
                r.val &= int.MaxValue >> (32 - r.size);
                if ((r.val & (1 << (r.size - 1))) != 0)                 // sign extend, not necessary for primitive types
                {
                    r.val |= int.MaxValue << r.size;                    // can use int here since the leftmost 0 will get shifted away anyway
                }
                bits.Add(r);
                bsw.WriteBitsFromSInt(r.val, r.size);
            }
            BitStreamReader bsr = new BitStreamReader(bsw);

            for (int i = 0; i < Iterations; i++)
            {
                Assert.AreEqual(bits[i].val, bsr.ReadSInt(bits[i].size), $"index: {i}");
            }
        }
 protected override void Parse(ref BitStreamReader bsr)
 {
     Unk = bsr.ReadSInt();
 }
Example #16
0
        protected override void Parse(ref BitStreamReader bsr)
        {
            EntityIndex = bsr.ReadBool() ? bsr.ReadUInt(bsr.ReadBool() ? 5 : DemoInfo.MaxEdictBits) : _deltaTmp.EntityIndex;

#pragma warning disable 8629
            if (DemoInfo.NewDemoProtocol)
            {
                Flags = (SoundFlags?)bsr.ReadUIntIfExists(DemoInfo.SoundFlagBitsEncode) ?? _deltaTmp.Flags;
                if ((Flags & SoundFlags.IsScriptHandle) != 0)
                {
                    ScriptHash = bsr.ReadUInt();
                }
                else
                {
                    SoundNum = (int?)bsr.ReadUIntIfExists(DemoInfo.MaxSndIndexBits) ?? _deltaTmp.SoundNum;
                }
            }
            else
            {
                SoundNum = (int?)bsr.ReadUIntIfExists(DemoInfo.MaxSndIndexBits) ?? _deltaTmp.SoundNum;
                Flags    = (SoundFlags?)bsr.ReadUIntIfExists(DemoInfo.SoundFlagBitsEncode) ?? _deltaTmp.Flags;
            }
            Chan = (Channel?)bsr.ReadUIntIfExists(3) ?? _deltaTmp.Chan;
#pragma warning restore 8629

            #region get sound name

            if (SoundNum.HasValue)
            {
                var mgr = DemoRef.StringTablesManager;

                if (mgr.TableReadable.GetValueOrDefault(TableNames.SoundPreCache))
                {
                    _soundTableReadable = true;
                    if (SoundNum >= mgr.Tables[TableNames.SoundPreCache].Entries.Count)
                    {
                        DemoRef.LogError($"{GetType().Name} - sound index out of range: {SoundNum}");
                    }
                    else if (SoundNum != 0)
                    {
                        SoundName = mgr.Tables[TableNames.SoundPreCache].Entries[SoundNum.Value].EntryName;
                    }
                }
            }

            #endregion

            IsAmbient  = bsr.ReadBool();
            IsSentence = bsr.ReadBool();

            if (Flags != SoundFlags.Stop)
            {
                if (bsr.ReadBool())
                {
                    SequenceNumber = _deltaTmp.SequenceNumber;
                }
                else if (bsr.ReadBool())
                {
                    SequenceNumber = _deltaTmp.SequenceNumber + 1;
                }
                else
                {
                    SequenceNumber = bsr.ReadUInt(SndSeqNumberBits);
                }

                Volume     = bsr.ReadUIntIfExists(7) / 127.0f ?? _deltaTmp.Volume;
                SoundLevel = bsr.ReadUIntIfExists(MaxSndLvlBits) ?? _deltaTmp.SoundLevel;
                Pitch      = bsr.ReadUIntIfExists(8) ?? _deltaTmp.Pitch;
                if (!DemoInfo.NewDemoProtocol && DemoRef.Header.NetworkProtocol > 21)
                {
                    SpecialDspCount = bsr.ReadByteIfExists() ?? _deltaTmp.SpecialDspCount;
                }

                if (DemoInfo.NewDemoProtocol)
                {
                    RandomSeed = bsr.ReadSIntIfExists(6) ?? _deltaTmp.RandomSeed;                     // 6, 18, or 29
                    Delay      = bsr.ReadFloatIfExists() ?? _deltaTmp.Delay;
                }
                else
                {
                    if (bsr.ReadBool())
                    {
                        Delay = bsr.ReadSInt(MaxSndDelayMSecEncodeBits) / 1000.0f;
                        if (Delay < 0)
                        {
                            Delay *= 10.0f;
                        }
                        Delay -= SndDelayOffset;
                    }
                    else
                    {
                        Delay = _deltaTmp.Delay;
                    }
                }

                Origin = new Vector3 {
                    X = bsr.ReadSIntIfExists(PropDecodeConsts.CoordIntBits - 2) * 8 ?? _deltaTmp.Origin.X,
                    Y = bsr.ReadSIntIfExists(PropDecodeConsts.CoordIntBits - 2) * 8 ?? _deltaTmp.Origin.Y,
                    Z = bsr.ReadSIntIfExists(PropDecodeConsts.CoordIntBits - 2) * 8 ?? _deltaTmp.Origin.Z
                };
                SpeakerEntity = bsr.ReadSIntIfExists(DemoInfo.MaxEdictBits + 1) ?? _deltaTmp.SpeakerEntity;
            }
            else
            {
                ClearStopFields();
            }
        }
Example #17
0
 protected override void Parse(ref BitStreamReader bsr)
 {
     Unknown     = bsr.ReadSInt();
     CallbackStr = bsr.ReadNullTerminatedString();
 }
Example #18
0
 protected override void Parse(ref BitStreamReader bsr)
 {
     Cookie   = bsr.ReadSInt();
     CvarName = bsr.ReadNullTerminatedString();
 }