public void ParseStringTable(IBitStream reader, string tableName, DemoParser parser) { int numStrings = (int)reader.ReadInt(16); if (tableName == "modelprecache") { parser.modelprecache.Clear (); } for (int i = 0; i < numStrings; i++) { string stringName = reader.ReadString(); if (stringName.Length >= 100) throw new Exception("Roy said I should throw this."); if (reader.ReadBit()) { int userDataSize = (int)reader.ReadInt(16); byte[] data = reader.ReadBytes(userDataSize); if (tableName == "userinfo") { PlayerInfo info = PlayerInfo.ParseFrom(new BinaryReader(new MemoryStream(data))); parser.RawPlayers[int.Parse(stringName)] = info; } else if (tableName == "instancebaseline") { int classid = int.Parse(stringName); //wtf volvo? parser.instanceBaseline[classid] = data; } else if (tableName == "modelprecache") { parser.modelprecache.Add (stringName); } } } // Client side stuff if ( reader.ReadBit() ) { int numstrings = (int)reader.ReadInt(16); for ( int i = 0 ; i < numstrings; i++ ) { reader.ReadString(); // stringname if ( reader.ReadBit() ) { int userDataSize = ( int )reader.ReadInt(16); reader.ReadBytes( userDataSize ); } else { } } } }
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> /// Reads an update that occures when a new edict enters the PVS (potentially visible system) /// </summary> /// <returns>The new Entity.</returns> private static Entity ReadEnterPVS(IBitStream reader, int id, DemoParser parser) { //What kind of entity? int serverClassID = (int)reader.ReadInt(parser.SendTableParser.ClassBits); //So find the correct server class ServerClass entityClass = parser.SendTableParser.ServerClasses[serverClassID]; reader.ReadInt(10); //Entity serial. //Never used anywhere I guess. Every parser just skips this Entity newEntity = new Entity(id, entityClass); //give people the chance to subscribe to events for this newEntity.ServerClass.AnnounceNewEntity(newEntity); //And then parse the instancebaseline. //basically you could call //newEntity.ApplyUpdate(parser.instanceBaseline[entityClass]; //This code below is just faster, since it only parses stuff once //which is faster. object[] fastBaseline; if (parser.PreprocessedBaselines.TryGetValue(serverClassID, out fastBaseline)) PropertyEntry.Emit(newEntity, fastBaseline); else { var preprocessedBaseline = new List<object>(); if (parser.instanceBaseline.ContainsKey(serverClassID)) using (var collector = new PropertyCollector(newEntity, preprocessedBaseline)) using (var bitStream = BitStreamUtil.Create(parser.instanceBaseline[serverClassID])) newEntity.ApplyUpdate(bitStream); parser.PreprocessedBaselines.Add(serverClassID, preprocessedBaseline.ToArray()); } return newEntity; }
public static int DecodeInt(SendTableProperty prop, IBitStream reader) { if (prop.Flags.HasFlagFast(SendPropertyFlags.VarInt)) { if (prop.Flags.HasFlagFast(SendPropertyFlags.Unsigned)) { return (int)reader.ReadVarInt(); } else { return (int)reader.ReadSignedVarInt(); } } else { if (prop.Flags.HasFlagFast(SendPropertyFlags.Unsigned)) { return (int)reader.ReadInt(prop.NumberOfBits); } else { return reader.ReadSignedInt(prop.NumberOfBits); } } }
public static float DecodeFloat(SendTableProperty prop, IBitStream reader) { float fVal = 0.0f; ulong dwInterp; if (DecodeSpecialFloat(prop, reader, out fVal)) return fVal; //Encoding: The range between lowVal and highVal is splitted into the same steps. //Read an int, fit it into the range. dwInterp = reader.ReadInt(prop.NumberOfBits); fVal = (float)dwInterp / ( ( 1 << prop.NumberOfBits ) - 1 ); fVal = prop.LowValue + ( prop.HighValue - prop.LowValue ) * fVal; return fVal; }
public static int DecodeInt(SendTableProperty prop, IBitStream reader) { if (prop.Flags.HasFlagFast(SendPropertyFlags.VarInt)) { if (prop.Flags.HasFlagFast(SendPropertyFlags.Unsigned)) { return (int)reader.ReadVarInt(); } else { Trace.WriteLine("signed varints are not implemented. BAAAAAAD.", "PropDecoder:DecodeInt()"); return (int)reader.ReadVarInt(); } } else { if (prop.Flags.HasFlagFast(SendPropertyFlags.Unsigned)) { return (int)reader.ReadInt(prop.NumberOfBits); } else { return reader.ReadSignedInt(prop.NumberOfBits); } } }
public static object[] DecodeArray(FlattenedPropEntry flattenedProp, IBitStream reader) { int numElements = flattenedProp.Prop.NumberOfElements; int maxElements = numElements; int numBits = 1; while (( maxElements >>= 1 ) != 0) { numBits++; } int nElements = (int)reader.ReadInt(numBits); object[] result = new object[nElements]; FlattenedPropEntry temp = new FlattenedPropEntry("", flattenedProp.ArrayElementProp, null); for (int i = 0; i < nElements; i++) { result[i] = DecodeProp(temp, reader); } return result; }
static float ReadBitNormal(IBitStream reader) { bool isNegative = reader.ReadBit(); uint fractVal = reader.ReadInt(NORMAL_FRACTIONAL_BITS); float value = (float)fractVal * NORMAL_RESOLUTION; if (isNegative) value *= -1; return value; }
static float ReadBitCoord(IBitStream reader) { int intVal, fractVal; float value = 0; bool isNegative = false; // Read the required integer and fraction flags intVal = (int)reader.ReadInt(1); fractVal = (int)reader.ReadInt(1); // If we got either parse them, otherwise it's a zero. if (( intVal | fractVal ) != 0) { // Read the sign bit isNegative = reader.ReadBit(); // If there's an integer, read it in if (intVal == 1) { // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE] intVal = (int)reader.ReadInt(14) + 1; //14 --> Coord int bits } //If there's a fraction, read it in if (fractVal == 1) { fractVal = (int)reader.ReadInt(COORD_FRACTIONAL_BITS); } value = intVal + ( (float)fractVal * COORD_RESOLUTION ); } if (isNegative) value *= -1; return value; }
static float ReadBitCoordMP(IBitStream reader, bool isIntegral, bool isLowPrecision) { int intval = 0, fractval = 0; float value = 0.0f; bool isNegative = false; bool inBounds = reader.ReadBit(); if (isIntegral) { // Read the required integer and fraction flags intval = reader.ReadBit() ? 1 : 0; // If we got either parse them, otherwise it's a zero. if (intval == 1) { // Read the sign bit isNegative = reader.ReadBit(); // If there's an integer, read it in // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE] if (inBounds) { value = (float)( reader.ReadInt(11) + 1 ); } else { value = (float)( reader.ReadInt(14) + 1 ); } } } else { // Read the required integer and fraction flags intval = reader.ReadBit() ? 1 : 0; // Read the sign bit isNegative = reader.ReadBit(); // If we got either parse them, otherwise it's a zero. if (intval == 1) { // If there's an integer, read it in // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE] if (inBounds) { value = (float)( reader.ReadInt(11) + 1 ); } else { value = (float)( reader.ReadInt(14) + 1 ); } } // If there's a fraction, read it in fractval = (int)reader.ReadInt(isLowPrecision ? 3 : 5); // Calculate the correct floating point value value = intval + ( (float)fractval * ( isLowPrecision ? COORD_RESOLUTION_LOWPRECISION : COORD_RESOLUTION ) ); } if (isNegative) value = -value; return value; }
public static string DecodeString(SendTableProperty prop, IBitStream reader) { return Encoding.Default.GetString(reader.ReadBytes((int)reader.ReadInt(9))); }
static float ReadBitCellCoord(IBitStream reader, int bits, bool lowPrecision, bool integral) { int intval = 0, fractval = 0; float value = 0.0f; if (integral) { value = (float)reader.ReadInt(bits); } else { intval = (int)reader.ReadInt(bits); fractval = (int)reader.ReadInt(lowPrecision ? COORD_FRACTIONAL_BITS_MP_LOWPRECISION : COORD_FRACTIONAL_BITS); value = intval + ( (float)fractval * ( lowPrecision ? COORD_RESOLUTION_LOWPRECISION : COORD_RESOLUTION ) ); } return value; }
public static void Apply(CreateStringTable table, IBitStream reader, DemoParser parser) { if (table.Name == "modelprecache") { while (parser.modelprecache.Count < table.MaxEntries) { parser.modelprecache.Add(null); } } if (reader.ReadBit()) { throw new NotImplementedException("Encoded with dictionaries, unable to decode"); } int nTemp = table.MaxEntries; int nEntryBits = 0; while ((nTemp >>= 1) != 0) { ++nEntryBits; } List <string> history = new List <string>(); int lastEntry = -1; for (int i = 0; i < table.NumEntries; i++) { int entryIndex = lastEntry + 1; // d in the entity-index if (!reader.ReadBit()) { entryIndex = (int)reader.ReadInt(nEntryBits); } lastEntry = entryIndex; // Read the name of the string into entry. string entry = ""; if (entryIndex < 0 || entryIndex >= table.MaxEntries) { throw new Exception("bogus string index"); } if (reader.ReadBit()) { bool substringcheck = reader.ReadBit(); if (substringcheck) { int index = (int)reader.ReadInt(5); int bytestocopy = (int)reader.ReadInt(5); entry = history[index].Substring(0, bytestocopy); entry += reader.ReadString(1024); } else { entry = reader.ReadString(1024); } } if (entry == null) { entry = ""; } if (history.Count > 31) { history.RemoveAt(0); } history.Add(entry); // Read in the user data. byte[] userdata = new byte[0]; if (reader.ReadBit()) { if (table.UserDataFixedSize) { userdata = reader.ReadBits(table.UserDataSizeBits); } else { int bytesToRead = (int)reader.ReadInt(14); userdata = reader.ReadBytes(bytesToRead); } } if (userdata.Length == 0) { break; } if (table.Name == "userinfo") { // Now we'll parse the players out of it. BinaryReader playerReader = new BinaryReader(new MemoryStream(userdata)); PlayerInfo info = PlayerInfo.ParseFrom(playerReader); parser.RawPlayers[entryIndex] = info; } else if (table.Name == "instancebaseline") { int classid = int.Parse(entry); //wtf volvo? parser.instanceBaseline[classid] = userdata; } else if (table.Name == "modelprecache") { parser.modelprecache[entryIndex] = entry; } } parser.stringTables.Add(table); }
public void ParseStringTableMessage(CSVCMsg_CreateStringTable table, DemoParser parser) { using (IBitStream reader = BitStreamUtil.Create(table.string_data)) { if (reader.ReadBit()) { throw new NotImplementedException("Encoded with dictionaries, unable to decode"); } int nTemp = table.max_entries; int nEntryBits = 0; while ((nTemp >>= 1) != 0) { ++nEntryBits; } List <string> history = new List <string>(); int lastEntry = -1; for (int i = 0; i < table.num_entries; i++) { int entryIndex = lastEntry + 1; // read in the entity-index if (!reader.ReadBit()) { entryIndex = (int)reader.ReadInt(nEntryBits); } lastEntry = entryIndex; // Read the name of the string into entry. string entry = ""; if (entryIndex < 0 || entryIndex >= table.max_entries) { throw new InvalidDataException("bogus string index"); } if (reader.ReadBit()) { bool substringcheck = reader.ReadBit(); if (substringcheck) { int index = (int)reader.ReadInt(5); int bytestocopy = (int)reader.ReadInt(5); entry = history[index].Substring(0, bytestocopy); entry += reader.ReadString(1024); } else { entry = reader.ReadString(1024); } } if (entry == null) { entry = ""; } if (history.Count > 31) { history.RemoveAt(0); } // Read in the user data. byte[] userdata = new byte[0]; if (reader.ReadBit()) { if (table.user_data_fixed_size) { userdata = reader.ReadBits(table.user_data_size_bits); } else { int bytesToRead = (int)reader.ReadInt(14); userdata = reader.ReadBytes(bytesToRead); } } if (userdata.Length == 0) { break; } // Now we'll parse the players out of it. BinaryReader playerReader = new BinaryReader(new MemoryStream(userdata)); PlayerInfo info = PlayerInfo.ParseFrom(playerReader); UpdatePlayer(info, parser); } } }
static float ReadBitCoordMP(IBitStream reader, bool isIntegral, bool isLowPrecision) { int intval = 0, fractval = 0; float value = 0.0f; bool isNegative = false; bool inBounds = reader.ReadBit(); if (isIntegral) { // Read the required integer and fraction flags intval = reader.ReadBit() ? 1 : 0; // If we got either parse them, otherwise it's a zero. if (intval == 1) { // Read the sign bit isNegative = reader.ReadBit(); // If there's an integer, read it in // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE] if (inBounds) { value = (float)(reader.ReadInt(11) + 1); } else { value = (float)(reader.ReadInt(14) + 1); } } } else { // Read the required integer and fraction flags intval = reader.ReadBit() ? 1 : 0; // Read the sign bit isNegative = reader.ReadBit(); // If we got either parse them, otherwise it's a zero. if (intval == 1) { // If there's an integer, read it in // Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE] if (inBounds) { value = (float)(reader.ReadInt(11) + 1); } else { value = (float)(reader.ReadInt(14) + 1); } } // If there's a fraction, read it in fractval = (int)reader.ReadInt(isLowPrecision ? 3 : 5); // Calculate the correct floating point value value = intval + ((float)fractval * (isLowPrecision ? COORD_RESOLUTION_LOWPRECISION : COORD_RESOLUTION)); } if (isNegative) { value = -value; } return(value); }
public static string DecodeString(SendTableProperty prop, IBitStream reader) { return(Encoding.Default.GetString(reader.ReadBytes((int)reader.ReadInt(9)))); }
public void ParseStringTable(IBitStream reader, string tableName, DemoParser parser) { int numStrings = (int)reader.ReadInt(16); if (tableName == "modelprecache") { parser.modelprecache.Clear(); } for (int i = 0; i < numStrings; i++) { string stringName = reader.ReadString(); if (stringName.Length >= 100) { throw new Exception("Roy said I should throw this."); } if (reader.ReadBit()) { int userDataSize = (int)reader.ReadInt(16); byte[] data = reader.ReadBytes(userDataSize); if (tableName == "userinfo") { PlayerInfo info = PlayerInfo.ParseFrom(new BinaryReader(new MemoryStream(data))); parser.RawPlayers[int.Parse(stringName)] = info; } else if (tableName == "instancebaseline") { int classid = int.Parse(stringName); //wtf volvo? parser.instanceBaseline[classid] = data; } else if (tableName == "modelprecache") { parser.modelprecache.Add(stringName); } } } // Client side stuff if (reader.ReadBit()) { int numstrings = (int)reader.ReadInt(16); for (int i = 0; i < numstrings; i++) { reader.ReadString(); // stringname if (reader.ReadBit()) { int userDataSize = ( int )reader.ReadInt(16); reader.ReadBytes(userDataSize); } else { } } } }
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 static void Apply(CreateStringTable table, IBitStream reader, DemoParser parser) { if (table.Name == "modelprecache") { while (parser.modelprecache.Count < table.MaxEntries) { parser.modelprecache.Add(null); } } if (reader.ReadBit()) throw new NotImplementedException("Encoded with dictionaries, unable to decode"); int nTemp = table.MaxEntries; int nEntryBits = 0; while ((nTemp >>= 1) != 0) ++nEntryBits; List<string> history = new List<string>(); int lastEntry = -1; for (int i = 0; i < table.NumEntries; i++) { int entryIndex = lastEntry + 1; // d in the entity-index if (!reader.ReadBit()) { entryIndex = (int)reader.ReadInt(nEntryBits); } lastEntry = entryIndex; // Read the name of the string into entry. string entry = ""; if (entryIndex < 0 || entryIndex >= table.MaxEntries) { throw new InvalidDataException("bogus string index"); } if (reader.ReadBit()) { bool substringcheck = reader.ReadBit(); if (substringcheck) { int index = (int)reader.ReadInt(5); int bytestocopy = (int)reader.ReadInt(5); entry = history[index].Substring(0, bytestocopy); entry += reader.ReadString(1024); } else { entry = reader.ReadString(1024); } } if (entry == null) entry = ""; if (history.Count > 31) history.RemoveAt(0); history.Add(entry); // Read in the user data. byte[] userdata = new byte[0]; if (reader.ReadBit()) { if (table.UserDataFixedSize) { userdata = reader.ReadBits(table.UserDataSizeBits); } else { int bytesToRead = (int)reader.ReadInt(14); userdata = reader.ReadBytes(bytesToRead); } } if (userdata.Length == 0) break; if (table.Name == "userinfo") { // Now we'll parse the players out of it. BinaryReader playerReader = new BinaryReader(new MemoryStream(userdata)); PlayerInfo info = PlayerInfo.ParseFrom(playerReader); parser.RawPlayers[entryIndex] = info; } else if (table.Name == "instancebaseline") { int classid = int.Parse(entry); //wtf volvo? parser.instanceBaseline[classid] = userdata; } else if (table.Name == "modelprecache") { parser.modelprecache[entryIndex] = entry; } } parser.stringTables.Add(table); }