コード例 #1
0
        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];
コード例 #2
0
 protected override void Parse(ref BitStreamReader bsr)
 {
     if ((DemoParseResult & DemoParseResult.DataTooLong) != 0)
     {
         throw new InvalidDataException("data too long");
     }
     // make sure we set the demo settings first
     Header = new DemoHeader(this);
     Header.ParseStream(ref bsr);
     DemoInfo = new DemoInfo(this);
     // it might be worth it to implement updating helper classes with listeners, but it's not a huge deal atm
     StringTablesManager = new StringTablesManager(this);
     ErrorList           = new List <string>();
     DecompressedLookup  = new List <byte[]>();
     Frames    = new List <PacketFrame>();
     StartTick = 0;
     try {
         PacketFrame frame;
         do
         {
             frame = new PacketFrame(this);
             Frames.Add(frame);
             frame.ParseStream(ref bsr);
             _parseProgress?.Report((double)bsr.CurrentBitIndex / bsr.BitLength);
         } while (frame.Type != PacketType.Stop && bsr.BitsRemaining >= 24);                 // would be 32 but the last byte is often cut off
         StartAdjustmentTick ??= 0;
         EndTick = this.FilterForPacket <Packet>().Select(packet => packet.Tick).Where(i => i >= 0).Max();
     }
     catch (Exception e) {
         _exceptionDuringParsing = true;
         Debug.WriteLine($"Exception after parsing {Frames.Count - 1} packets");
         LogError($"Exception after parsing {Frames.Count - 1} packets: {e.Message}");
         throw;
     }
     EndAdjustmentTick ??= EndTick;
     DemoParseResult |= DemoParseResult.Success;
 }