/// <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); }
/// <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); }
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); }