/// <summary> /// Parses the tick internally /// </summary> /// <returns><c>true</c>, if tick was parsed, <c>false</c> otherwise.</returns> private bool ParseTick() { DemoCommand command = (DemoCommand)BitStream.ReadByte(); BitStream.ReadInt(32); // tick number BitStream.ReadByte(); // player slot this.CurrentTick++; // = TickNum; switch (command) { case DemoCommand.Synctick: break; case DemoCommand.Stop: return(false); case DemoCommand.ConsoleCommand: BitStream.BeginChunk(BitStream.ReadSignedInt(32) * 8); BitStream.EndChunk(); break; case DemoCommand.DataTables: BitStream.BeginChunk(BitStream.ReadSignedInt(32) * 8); SendTableParser.ParsePacket(BitStream); BitStream.EndChunk(); //Map the weapons in the equipmentMapping-Dictionary. MapEquipment(); //And now we have the entities, we can bind events on them. BindEntites(); break; case DemoCommand.StringTables: BitStream.BeginChunk(BitStream.ReadSignedInt(32) * 8); StringTables.ParsePacket(BitStream, this); BitStream.EndChunk(); break; case DemoCommand.UserCommand: BitStream.ReadInt(32); BitStream.BeginChunk(BitStream.ReadSignedInt(32) * 8); BitStream.EndChunk(); break; case DemoCommand.Signon: case DemoCommand.Packet: ParseDemoPacket(); break; default: throw new Exception("Can't handle Demo-Command " + command); } return(true); }
public void Parse(IBitStream bitstream) { var keys = new List <Key>(); while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if (wireType == 0 && fieldnum == 1) { EventId = bitstream.ReadProtobufVarInt(); } else if (wireType == 2 && fieldnum == 2) { Name = bitstream.ReadProtobufString(); } else if (wireType == 2 && fieldnum == 3) { var length = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(length * 8); var key = new Key(); key.Parse(bitstream); keys.Add(key); bitstream.EndChunk(); } else { throw new InvalidDataException(); } } Keys = keys.ToArray(); }
public void Parse(IBitStream bitstream, DemoParser parser) { while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if (wireType == 2) { if (fieldnum == 1) { Name = bitstream.ReadProtobufString(); continue; } else if (fieldnum == 8) { // String data is special. // We'll simply hope that gaben is nice and sends // string_data last, just like he should. var len = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(len * 8); DemoInfo.DP.Handler.CreateStringTableUserInfoHandler.Apply(this, bitstream, parser); bitstream.EndChunk(); if (!bitstream.ChunkFinished) throw new NotImplementedException("Lord Gaben wasn't nice to us :/"); break; } else throw new InvalidDataException("yes I know we should drop this but we" + "probably want to know that they added a new big field"); } if (wireType != 0) throw new InvalidDataException(); var val = bitstream.ReadProtobufVarInt(); switch (fieldnum) { case 2: MaxEntries = val; break; case 3: NumEntries = val; break; case 4: _UserDataFixedSize = val; break; case 5: UserDataSize = val; break; case 6: UserDataSizeBits = val; break; case 7: Flags = val; break; default: // silently drop break; } } }
public IEnumerable <SendProp> Parse(IBitStream bitstream) { var sendprops = new List <SendProp>(); while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if (wireType == 2) { if (fieldnum == 2) { NetTableName = bitstream.ReadProtobufString(); } else if (fieldnum == 4) { // Props are special. // We'll simply hope that gaben is nice and sends // props last, just like he should. var len = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(len * 8); var sendprop = new SendProp(); sendprop.Parse(bitstream); sendprops.Add(sendprop); bitstream.EndChunk(); } else { throw new InvalidDataException("yes I know we should drop this" + "but we probably want to know that they added a new big field"); } } else if (wireType == 0) { var val = bitstream.ReadProtobufVarInt(); switch (fieldnum) { case 1: _IsEnd = val; break; case 3: _NeedsDecoder = val; break; } } else { throw new InvalidDataException(); } } return(sendprops); }
/// <summary> /// Parses a demo-packet. /// </summary> /// <param name="bitstream">Bitstream.</param> /// <param name="demo">Demo.</param> public static void ParsePacket(IBitStream bitstream, DemoParser demo) { //As long as there is stuff to read while (!bitstream.ChunkFinished) { int cmd = bitstream.ReadProtobufVarInt(); //What type of packet is this? int length = bitstream.ReadProtobufVarInt(); //And how long is it? bitstream.BeginChunk(length * 8); //read length bytes if (cmd == (int)SVC_Messages.svc_PacketEntities) { //Parse packet entities new PacketEntities().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_GameEventList) { //and all this other stuff new GameEventList().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_GameEvent) { new GameEvent().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_CreateStringTable) { new CreateStringTable().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_UpdateStringTable) { new UpdateStringTable().Parse(bitstream, demo); } else if (cmd == (int)NET_Messages.net_Tick) { //and all this other stuff new NETTick().Parse(bitstream, demo); } else { //You can use this flag to see what information the other packets contain, //if you want. Then you can look into the objects. Has some advnatages, and some disdavantages (mostly speed), //so we use our own lightning-fast parsing code. #if SLOW_PROTOBUF Type toParse = null; if (Enum.IsDefined(typeof(SVC_Messages), cmd)) { SVC_Messages msg = (SVC_Messages)cmd; toParse = Assembly.GetExecutingAssembly().GetType("DemoInfo.Messages.CSVCMsg_" + msg.ToString().Substring(4)); } else if (Enum.IsDefined(typeof(NET_Messages), cmd)) { NET_Messages msg = (NET_Messages)cmd; toParse = Assembly.GetExecutingAssembly().GetType("DemoInfo.Messages.CNETMsg_" + msg.ToString().Substring(4)); } var data = bitstream.ReadBytes(length); if (toParse == null) continue; ProtoBuf.IExtensible result; using (var memstream = new MemoryStream(data)) result = memstream.ReadProtobufMessage(toParse); foreach (var parser in Parsers) if (parser.TryApplyMessage(result, demo) && (parser.Priority > 0)) break; #endif } bitstream.EndChunk(); } }
public void ParsePacket(IBitStream bitstream) { while (true) { var type = (SVC_Messages)bitstream.ReadProtobufVarInt(); if (type != SVC_Messages.svc_SendTable) { throw new Exception("Expected SendTable, got " + type); } var size = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(size * 8); var sendTable = new SendTable(bitstream); bitstream.EndChunk(); if (sendTable.IsEnd) { break; } DataTables.Add(sendTable); } int serverClassCount = checked ((int)bitstream.ReadInt(16)); for (int i = 0; i < serverClassCount; i++) { ServerClass entry = new ServerClass(); entry.ClassID = checked ((int)bitstream.ReadInt(16)); if (entry.ClassID > serverClassCount) { throw new Exception("Invalid class index"); } entry.Name = bitstream.ReadDataTableString(); entry.DTName = bitstream.ReadDataTableString(); entry.DataTableID = DataTables.FindIndex(a => a.Name == entry.DTName); if (ServerClasses.FirstOrDefault(sc => sc.Name == entry.Name && sc.DTName == entry.DTName) == null) { ServerClasses.Add(entry); } } for (int i = 0; i < serverClassCount; i++) { FlattenDataTable(i); } }
public void Parse(IBitStream bitstream, DemoParser parser) { while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if ((fieldnum == 7) && (wireType == 2)) { // Entity data is special. // We'll simply hope that gaben is nice and sends // entity_data last, just like he should. var len = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(len * 8); DemoInfo.DP.Handler.PacketEntitesHandler.Apply(this, bitstream, parser); bitstream.EndChunk(); if (!bitstream.ChunkFinished) throw new NotImplementedException("Lord Gaben wasn't nice to us :/"); break; } if (wireType != 0) throw new InvalidDataException(); var val = bitstream.ReadProtobufVarInt(); switch (fieldnum) { case 1: MaxEntries = val; break; case 2: UpdatedEntries = val; break; case 3: _IsDelta = val; break; case 4: _UpdateBaseline = val; break; case 5: Baseline = val; break; case 6: DeltaFrom = val; break; default: // silently drop break; } } }
public void Parse(IBitStream bitstream, DemoParser parser) { while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if ((wireType == 2) && (fieldnum == 3)) { // String data is special. // We'll simply hope that gaben is nice and sends // string_data last, just like he should. var len = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(len * 8); DemoInfo.DP.Handler.UpdateStringTableUserInfoHandler.Apply(this, bitstream, parser); bitstream.EndChunk(); if (!bitstream.ChunkFinished) { throw new NotImplementedException("Lord Gaben wasn't nice to us :/"); } break; } if (wireType != 0) { throw new Exception(); } var val = bitstream.ReadProtobufVarInt(); switch (fieldnum) { case 1: TableId = val; break; case 2: NumChangedEntries = val; break; default: // silently drop break; } } }
public void Parse(IBitStream bitstream, DemoParser parser) { while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if (wireType == 0 && fieldnum == 1) { MsgType = bitstream.ReadProtobufVarInt(); } else if (wireType == 0 && fieldnum == 3) { PassThrough = bitstream.ReadProtobufVarInt(); } else if (fieldnum == 2) { // msg data if (wireType == 2) { bitstream.BeginChunk(bitstream.ReadProtobufVarInt() * 8); switch (MsgType) { // This is where you can add others UserMessage parsing logic case (int)User_Messages.um_SayText: new SayText().Parse(bitstream, parser); break; case (int)User_Messages.um_SayText2: new SayText2().Parse(bitstream, parser); break; case (int)User_Messages.um_ServerRankUpdate: new ServerRankUpdate().Parse(bitstream, parser); break; } bitstream.EndChunk(); if (!bitstream.ChunkFinished) { throw new NotImplementedException("Lord Gaben wasn't nice to us :/"); } } } } }
private IEnumerable<Descriptor> ReadDescriptors(IBitStream bitstream) { while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if ((wireType != 2) || (fieldnum != 1)) throw new InvalidDataException(); var length = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(length * 8); var descriptor = new Descriptor(); descriptor.Parse(bitstream); yield return descriptor; bitstream.EndChunk(); } }
public void Parse(IBitStream bitstream, DemoParser parser) { while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if (wireType == 2 && fieldnum == 1) { bitstream.BeginChunk(bitstream.ReadProtobufVarInt() * 8); new RankUpdate().Parse(bitstream, parser); bitstream.EndChunk(); } else { throw new InvalidDataException(); } } }
private IEnumerable <Descriptor> ReadDescriptors(IBitStream bitstream) { while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if (wireType != 2 || fieldnum != 1) { throw new InvalidDataException(); } var length = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(length * 8); var descriptor = new Descriptor(); descriptor.Parse(bitstream); yield return(descriptor); bitstream.EndChunk(); } }
public void ParsePacket(IBitStream bitstream) { while (true) { var type = (SVC_Messages)bitstream.ReadProtobufVarInt(); if (type != SVC_Messages.svc_SendTable) throw new Exception("Expected SendTable, got " + type); var size = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(size * 8); var sendTable = new SendTable(bitstream); bitstream.EndChunk(); if (sendTable.IsEnd) break; DataTables.Add(sendTable); } int serverClassCount = checked((int)bitstream.ReadInt(16)); for (int i = 0; i < serverClassCount; i++) { ServerClass entry = new ServerClass(); entry.ClassID = checked((int)bitstream.ReadInt(16)); if (entry.ClassID > serverClassCount) throw new Exception("Invalid class index"); entry.Name = bitstream.ReadDataTableString(); entry.DTName = bitstream.ReadDataTableString(); entry.DataTableID = DataTables.FindIndex(a => a.Name == entry.DTName); ServerClasses.Add(entry); } for (int i = 0; i < serverClassCount; i++) FlattenDataTable(i); }
/// <summary> /// Parses a demo-packet. /// </summary> /// <param name="bitstream">Bitstream.</param> /// <param name="demo">Demo.</param> public static void ParsePacket(IBitStream bitstream, DemoParser demo) { //As long as there is stuff to read while (!bitstream.ChunkFinished) { var cmd = bitstream.ReadProtobufVarInt(); //What type of packet is this? var length = bitstream.ReadProtobufVarInt(); //And how long is it? bitstream.BeginChunk(length * 8); //read length bytes if (cmd == (int)SVC_Messages.svc_PacketEntities) { //Parse packet entities new PacketEntities().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_GameEventList) { //and all this other stuff new GameEventList().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_GameEvent) { new GameEvent().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_CreateStringTable) { new CreateStringTable().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_UpdateStringTable) { new UpdateStringTable().Parse(bitstream, demo); } else if (cmd == (int)NET_Messages.net_Tick) { //and all this other stuff new NETTick().Parse(bitstream, demo); } bitstream.EndChunk(); } }
public void Parse(IBitStream bitstream) { var keys = new List<Key>(); while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if ((wireType == 0) && (fieldnum == 1)) { EventId = bitstream.ReadProtobufVarInt(); } else if ((wireType == 2) && (fieldnum == 2)) { Name = bitstream.ReadProtobufString(); } else if ((wireType == 2) && (fieldnum == 3)) { var length = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(length * 8); var key = new Key(); key.Parse(bitstream); keys.Add(key); bitstream.EndChunk(); } else throw new InvalidDataException(); } Keys = keys.ToArray(); }
public static void ParsePacket(IBitStream bitstream, DemoParser demo) { while (!bitstream.ChunkFinished) { int cmd = bitstream.ReadProtobufVarInt(); int length = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(length * 8); if (cmd == (int)NET_Messages.net_Tick) { new NETTick().Parse(bitstream); } else if (cmd == (int)SVC_Messages.svc_PacketEntities) { new PacketEntities().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_EncryptedData) { // TODO: maybe one day find the key for this? } else if (cmd == (int)SVC_Messages.svc_GameEventList) { new GameEventList().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_GameEvent) { new GameEvent().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_CreateStringTable) { new CreateStringTable().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_UpdateStringTable) { new UpdateStringTable().Parse(bitstream, demo); } else { #if SLOW_PROTOBUF Type toParse = null; if (Enum.IsDefined(typeof(SVC_Messages), cmd)) { SVC_Messages msg = (SVC_Messages)cmd; toParse = Assembly.GetExecutingAssembly().GetType("DemoInfo.Messages.CSVCMsg_" + msg.ToString().Substring(4)); } else if (Enum.IsDefined(typeof(NET_Messages), cmd)) { NET_Messages msg = (NET_Messages)cmd; toParse = Assembly.GetExecutingAssembly().GetType("DemoInfo.Messages.CNETMsg_" + msg.ToString().Substring(4)); } var data = bitstream.ReadBytes(length); if (toParse == null) { continue; } ProtoBuf.IExtensible result; using (var memstream = new MemoryStream(data)) result = memstream.ReadProtobufMessage(toParse); foreach (var parser in Parsers) { if (parser.TryApplyMessage(result, demo) && (parser.Priority > 0)) { break; } } #endif } bitstream.EndChunk(); } }
public void Parse(IBitStream bitstream, DemoParser parser) { while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if ((fieldnum == 7) && (wireType == 2)) { // Entity data is special. // We'll simply hope that gaben is nice and sends // entity_data last, just like he should. var len = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(len * 8); DemoInfo.DP.Handler.PacketEntitesHandler.Apply(this, bitstream, parser); bitstream.EndChunk(); if (!bitstream.ChunkFinished) { throw new NotImplementedException("Lord Gaben wasn't nice to us :/"); } break; } if (wireType != 0) { throw new Exception(); } var val = bitstream.ReadProtobufVarInt(); switch (fieldnum) { case 1: MaxEntries = val; break; case 2: UpdatedEntries = val; break; case 3: _IsDelta = val; break; case 4: _UpdateBaseline = val; break; case 5: Baseline = val; break; case 6: DeltaFrom = val; break; default: // silently drop break; } } }
public IEnumerable<SendProp> Parse(IBitStream bitstream) { var sendprops = new List<SendProp>(); while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if (wireType == 2) { if (fieldnum == 2) { NetTableName = bitstream.ReadProtobufString(); } else if (fieldnum == 4) { // Props are special. // We'll simply hope that gaben is nice and sends // props last, just like he should. var len = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(len * 8); var sendprop = new SendProp(); sendprop.Parse(bitstream); sendprops.Add(sendprop); bitstream.EndChunk(); } else throw new InvalidDataException("yes I know we should drop this" + "but we probably want to know that they added a new big field"); } else if (wireType == 0) { var val = bitstream.ReadProtobufVarInt(); switch (fieldnum) { case 1: _IsEnd = val; break; case 3: _NeedsDecoder = val; break; default: // silently drop break; } } else throw new InvalidDataException(); } return sendprops; }
public void Parse(IBitStream bitstream, DemoParser parser) { while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if (wireType == 2) { if (fieldnum == 1) { Name = bitstream.ReadProtobufString(); continue; } else if (fieldnum == 8) { // String data is special. // We'll simply hope that gaben is nice and sends // string_data last, just like he should. var len = bitstream.ReadProtobufVarInt(); bitstream.BeginChunk(len * 8); DemoInfo.DP.Handler.CreateStringTableUserInfoHandler.Apply(this, bitstream, parser); bitstream.EndChunk(); if (!bitstream.ChunkFinished) { throw new NotImplementedException("Lord Gaben wasn't nice to us :/"); } break; } else { throw new Exception("yes I know we should drop this but we" + "probably want to know that they added a new big field"); } } if (wireType != 0) { throw new Exception(); } var val = bitstream.ReadProtobufVarInt(); switch (fieldnum) { case 2: MaxEntries = val; break; case 3: NumEntries = val; break; case 4: _UserDataFixedSize = val; break; case 5: UserDataSize = val; break; case 6: UserDataSizeBits = val; break; case 7: Flags = val; break; default: // silently drop break; } } }
private bool ParseTick() { DemoCommand command = (DemoCommand)BitStream.ReadByte(); BitStream.ReadInt(32); // tick number BitStream.ReadByte(); // player slot this.CurrentTick++; // = TickNum; switch (command) { case DemoCommand.Synctick: break; case DemoCommand.Stop: return(false); case DemoCommand.ConsoleCommand: BitStream.BeginChunk(BitStream.ReadSignedInt(32) * 8); BitStream.EndChunk(); break; case DemoCommand.DataTables: BitStream.BeginChunk(BitStream.ReadSignedInt(32) * 8); SendTableParser.ParsePacket(BitStream); BitStream.EndChunk(); for (int i = 0; i < SendTableParser.ServerClasses.Count; i++) { var sc = SendTableParser.ServerClasses[i]; if (sc.BaseClasses.Count > 6 && sc.BaseClasses [6].Name == "CWeaponCSBase") { //It is a "weapon" (Gun, C4, ... (...is the cz still a "weapon" after the nerf?)) if (sc.BaseClasses.Count > 7) { if (sc.BaseClasses [7].Name == "CWeaponCSBaseGun") { //it is a ratatatata-weapon. var s = sc.DTName.Substring(9).ToLower(); equipmentMapping.Add(sc, Equipment.MapEquipment(s)); } else if (sc.BaseClasses [7].Name == "CBaseCSGrenade") { //"boom"-weapon. equipmentMapping.Add(sc, Equipment.MapEquipment(sc.DTName.Substring(3).ToLower())); } } else if (sc.Name == "CC4") { //Bomb is neither "ratatata" nor "boom", its "booooooom". equipmentMapping.Add(sc, EquipmentElement.Bomb); } else if (sc.Name == "CKnife" || (sc.BaseClasses.Count > 6 && sc.BaseClasses [6].Name == "CKnife")) { //tsching weapon equipmentMapping.Add(sc, EquipmentElement.Knife); } else if (sc.Name == "CWeaponNOVA" || sc.Name == "CWeaponSawedoff" || sc.Name == "CWeaponXM1014") { equipmentMapping.Add(sc, Equipment.MapEquipment(sc.Name.Substring(7).ToLower())); } } } BindEntites(); break; case DemoCommand.StringTables: BitStream.BeginChunk(BitStream.ReadSignedInt(32) * 8); StringTables.ParsePacket(BitStream, this); BitStream.EndChunk(); break; case DemoCommand.UserCommand: BitStream.ReadInt(32); BitStream.BeginChunk(BitStream.ReadSignedInt(32) * 8); BitStream.EndChunk(); break; case DemoCommand.Signon: case DemoCommand.Packet: ParseDemoPacket(); break; default: throw new Exception("Can't handle Demo-Command " + command); } return(true); }
public void TestBasicChunking() { Assert.AreEqual(data.First(), dbgAll.ReadByte()); dbgAll.BeginChunk((128 * 1024 - 2) * 8); Assert.IsFalse(dbgAll.ChunkFinished); dbgAll.ReadBytes(128 * 1024 - 2); Assert.IsTrue(dbgAll.ChunkFinished); dbgAll.EndChunk(); Assert.AreEqual(data.Last(), dbgAll.ReadByte()); }
public void Parse(IBitStream bitstream, DemoParser parser) { Keys = new List <object>(); while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if (wireType == 2 && fieldnum == 1) { EventName = bitstream.ReadProtobufString(); } else if (wireType == 0 && fieldnum == 2) { EventId = bitstream.ReadProtobufVarInt(); } else if (wireType == 2 && fieldnum == 3) { bitstream.BeginChunk(bitstream.ReadProtobufVarInt() * 8); /* * Hope and pray that gaben is once again nice to us and * sends 'type' first, then the respective member, then NOTHING. */ desc = bitstream.ReadProtobufVarInt(); wireType = desc & 7; fieldnum = desc >> 3; if (wireType != 0 || fieldnum != 1) { throw new InvalidDataException("Lord Gaben wasn't nice to us :/"); } var typeMember = bitstream.ReadProtobufVarInt(); desc = bitstream.ReadProtobufVarInt(); wireType = desc & 7; fieldnum = desc >> 3; if (fieldnum != typeMember + 1) { throw new InvalidDataException("Lord Gaben wasn't nice to us :/ (srsly wtf!?)"); } switch (typeMember) { case 1: // string if (wireType != 2) { throw new InvalidDataException("proto definition differs"); } Keys.Add(bitstream.ReadProtobufString()); break; case 2: // float if (wireType != 5) { throw new InvalidDataException("proto definition differs"); } Keys.Add(bitstream.ReadFloat()); break; case 3: // long case 4: // short case 5: // byte if (wireType != 0) { throw new InvalidDataException("proto definition differs"); } Keys.Add(bitstream.ReadProtobufVarInt()); break; case 6: // bool if (wireType != 0) { throw new InvalidDataException("proto definition differs"); } Keys.Add(bitstream.ReadProtobufVarInt() != 0); break; default: throw new InvalidDataException("Looks like they introduced a new type"); } if (!bitstream.ChunkFinished) { throw new InvalidDataException("Lord Gaben tricked us! D:"); } bitstream.EndChunk(); } else { throw new InvalidDataException(); } } GameEventHandler.Apply(this, parser); }
public void Parse(IBitStream bitstream, DemoParser parser) { Keys = new List<object>(); while (!bitstream.ChunkFinished) { var desc = bitstream.ReadProtobufVarInt(); var wireType = desc & 7; var fieldnum = desc >> 3; if ((wireType == 2) && (fieldnum == 1)) { EventName = bitstream.ReadProtobufString(); } else if ((wireType == 0) && (fieldnum == 2)) { EventId = bitstream.ReadProtobufVarInt(); } else if ((wireType == 2) && (fieldnum == 3)) { bitstream.BeginChunk(bitstream.ReadProtobufVarInt() * 8); /* * Hope and pray that gaben is once again nice to us and * sends 'type' first, then the respective member, then NOTHING. */ desc = bitstream.ReadProtobufVarInt(); wireType = desc & 7; fieldnum = desc >> 3; if ((wireType != 0) || (fieldnum != 1)) throw new InvalidDataException("Lord Gaben wasn't nice to us :/"); var typeMember = bitstream.ReadProtobufVarInt(); desc = bitstream.ReadProtobufVarInt(); wireType = desc & 7; fieldnum = desc >> 3; if (fieldnum != (typeMember + 1)) throw new InvalidDataException("Lord Gaben wasn't nice to us :/ (srsly wtf!?)"); switch (typeMember) { case 1: // string if (wireType != 2) throw new InvalidDataException("proto definition differs"); Keys.Add(bitstream.ReadProtobufString()); break; case 2: // float if (wireType != 5) throw new InvalidDataException("proto definition differs"); Keys.Add(bitstream.ReadFloat()); break; case 3: // long case 4: // short case 5: // byte if (wireType != 0) throw new InvalidDataException("proto definition differs"); Keys.Add(bitstream.ReadProtobufVarInt()); break; case 6: // bool if (wireType != 0) throw new InvalidDataException("proto definition differs"); Keys.Add(bitstream.ReadProtobufVarInt() != 0); break; default: throw new InvalidDataException("Looks like they introduced a new type"); } if (!bitstream.ChunkFinished) throw new InvalidDataException("Lord Gaben tricked us! D:"); bitstream.EndChunk(); } else throw new InvalidDataException(); } GameEventHandler.Apply(this, parser); }
/// <summary> /// Parses a demo-packet. /// </summary> /// <param name="bitstream">Bitstream.</param> /// <param name="demo">Demo.</param> public static void ParsePacket(IBitStream bitstream, DemoParser demo) { //As long as there is stuff to read while (!bitstream.ChunkFinished) { int cmd = bitstream.ReadProtobufVarInt(); //What type of packet is this? int length = bitstream.ReadProtobufVarInt(); //And how long is it? bitstream.BeginChunk(length * 8); //read length bytes if (cmd == (int)SVC_Messages.svc_PacketEntities) //Parse packet entities { new PacketEntities().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_GameEventList) //and all this other stuff { new GameEventList().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_GameEvent) { new GameEvent().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_CreateStringTable) { new CreateStringTable().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_UpdateStringTable) { new UpdateStringTable().Parse(bitstream, demo); } else if (cmd == (int)NET_Messages.net_Tick) //and all this other stuff { new NETTick().Parse(bitstream, demo); } else if (cmd == (int)SVC_Messages.svc_UserMessage) { new UserMessage().Parse(bitstream, demo); } else { //You can use this flag to see what information the other packets contain, //if you want. Then you can look into the objects. Has some advnatages, and some disdavantages (mostly speed), //so we use our own lightning-fast parsing code. #if SLOW_PROTOBUF Type toParse = null; if (Enum.IsDefined(typeof(SVC_Messages), cmd)) { SVC_Messages msg = (SVC_Messages)cmd; toParse = Assembly.GetExecutingAssembly().GetType("DemoInfo.Messages.CSVCMsg_" + msg.ToString().Substring(4)); } else if (Enum.IsDefined(typeof(NET_Messages), cmd)) { NET_Messages msg = (NET_Messages)cmd; toParse = Assembly.GetExecutingAssembly().GetType("DemoInfo.Messages.CNETMsg_" + msg.ToString().Substring(4)); } var data = bitstream.ReadBytes(length); if (toParse == null) { continue; } ProtoBuf.IExtensible result; using (var memstream = new MemoryStream(data)) result = memstream.ReadProtobufMessage(toParse); foreach (var parser in Parsers) { if (parser.TryApplyMessage(result, demo) && (parser.Priority > 0)) { break; } } #endif } bitstream.EndChunk(); } }
public void BeginChunk(int bits) { A.BeginChunk(bits); B.BeginChunk(bits); }