예제 #1
0
        /// <summary>
        /// Parses the embedded message from within a base message
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static object[] ParseEmbeddedMessages(byte[] data)
        {
            var fs       = new MemoryStream(data);
            var messages = new LinkedList <object>();

            while (fs.Position < fs.Length)
            {
                ulong kind = DemParser.ReadVarInt(fs);
                ulong size = DemParser.ReadVarInt(fs);
                var   buf  = new byte[size];
                fs.Read(buf, 0, (int)size);

                object message = RuntimeTypeModel.Default.Deserialize(new MemoryStream(buf), null, DemParser.EmbeddedTypeMap[kind]);

                messages.AddLast(message);
            }

            var array = new object[messages.Count];

            messages.CopyTo(array, 0);
            return(array);
        }
예제 #2
0
        /// <summary>
        /// Parses a base message and its embedded message (if required)
        /// </summary>
        /// <param name="fs"></param>
        /// <returns></returns>
        public static object ParseMessage(Stream fs)
        {
            ulong kind = DemParser.ReadVarInt(fs);
            ulong tick = DemParser.ReadVarInt(fs);
            ulong size = DemParser.ReadVarInt(fs);
            var   buf  = new byte[size];

            fs.Read(buf, 0, (int)size);

            // decompress if needed
            bool isCompressed = (kind & DemParser.CompressedKindMask) != 0;

            if (isCompressed)
            {
                kind = kind - DemParser.CompressedKindMask;
                buf  = Snappy.SnappyCodec.Uncompress(buf);
            }

            object message = RuntimeTypeModel.Default.Deserialize(new MemoryStream(buf), null, DemParser.BaseTypeMap[kind]);

            DemParser.PrintMessage(message, kind, tick, size, buf, isCompressed);
            return(message);
        }
예제 #3
0
        public Dictionary <ParserPhase, LinkedList <object> > Read(string fileName)
        {
            using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                var buf = new byte[8];
                fs.Read(buf, 0, 8);
                if (System.Text.Encoding.UTF8.GetString(buf) != "PBUFDEM\0")
                {
                    throw new InvalidDataException("Invalid Header");
                }

                buf = new byte[4];
                fs.Read(buf, 0, 4);
                if (BitConverter.IsLittleEndian != true) // the bit converter requires the bytes in the computer's endian-ness
                {
                    Array.Reverse(buf);
                }
                //int summaryOffset = BitConverter.ToInt32(buf, 0);

                this.Phase = ParserPhase.Prologue;
                this._messages[this.Phase] = new LinkedList <object>();

                while (fs.Position < fs.Length)
                {
                    object msg = DemParser.ParseMessage(fs);

                    // special message handling
                    if (msg is dota2.CDemoSyncTick)
                    {
                        this.Phase = ParserPhase.Match;
                        this._messages[this.Phase] = new LinkedList <object>();
                    }
                    else if (msg is dota2.CDemoStop)
                    {
                        this.Phase = ParserPhase.Epilogue;
                        this._messages[this.Phase] = new LinkedList <object>();
                    }
                    else if (msg is dota2.IBaseWithEmbedded)
                    {
                        var msgBase = msg as dota2.IBaseWithEmbedded;
                        foreach (object inner in msgBase.EmbeddedMessages)
                        {
                            StringTable t;
                            if (inner is dota2.CSVCMsg_CreateStringTable)
                            {
                                t = new StringTable((dota2.CSVCMsg_CreateStringTable)inner);
                                this._stringTables.Add(t.Name, t);
                                this.HandleTable(t);
                            }
                            else if (inner is dota2.CSVCMsg_UpdateStringTable)
                            {
                                var ust = (dota2.CSVCMsg_UpdateStringTable)inner;
                                t = this._stringTables[ust.table_id];
                                t.Update(ust);
                                this.HandleTable(t);
                            }
                        }
                    }

                    this._messages[this.Phase].AddLast(msg);
                }
            }

            return(this._messages);
        }