Esempio n. 1
0
		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
			        {
			        }
		        }
	        }
        }
Esempio n. 2
0
		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;
        }
Esempio n. 4
0
		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);
				}
			}
		}
Esempio n. 5
0
        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;
        }
Esempio n. 6
0
 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);
         }
     }
 }
Esempio n. 7
0
        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;
        }
Esempio n. 8
0
        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;
        }
Esempio n. 9
0
        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;
        }
Esempio n. 10
0
        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;
        }
Esempio n. 11
0
 public static string DecodeString(SendTableProperty prop, IBitStream reader)
 {
     return Encoding.Default.GetString(reader.ReadBytes((int)reader.ReadInt(9)));
 }
Esempio n. 12
0
        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;
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        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);
                }
            }
        }
Esempio n. 15
0
        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);
        }
Esempio n. 16
0
 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
                    {
                    }
                }
            }
        }
Esempio n. 18
0
        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);
        }