private void CalculateProtocol15Hack(Int32 dataLength) { /* * Valve broke network protocol 15 by changing the protocol without incrementing the protocol number. * * The change adds an extra bit after each message ID, so the only thing that's guaranteed to read correctly with every protocol 15 demo now if the header. * * The first message in the first sigon frame is always svc_print or svc_serverinfo, so if either of those are invalid, odds are that the demo uses the changed protocol. * */ // read in data block Byte[] frameData = parser.Reader.ReadBytes(dataLength); BitBuffer bitBuffer = new BitBuffer(frameData); // parse messages SourceDemoParser.MessageId messageId = (SourceDemoParser.MessageId)bitBuffer.ReadUnsignedBits(5); if (messageId == SourceDemoParser.MessageId.SVC_Print) { String s = bitBuffer.ReadString(); if (s.Contains("Map") || s.Contains("Build") || s.Contains("Players")) { // Looks like a valid svc_print string. return; } Protocol15Hack = true; } else if (messageId == SourceDemoParser.MessageId.SVC_ServerInfo) { UInt32 networkProtocol = bitBuffer.ReadUnsignedBits(16); if (networkProtocol != this.networkProtocol) { // Should match header, must be invalid. Protocol15Hack = true; } } }
/// <summary> /// Parses S2C_PLAYER. /// </summary> /// <param name="data"></param> /// <param name="si"></param> private void ParsePlayerQueryReply(BitBuffer bitBuffer) { Int32 nPlayers = bitBuffer.ReadByte(); for (Int32 i = 0; i < nPlayers; i++) { bitBuffer.SeekBytes(1); // skip index Player player = new Player(); player.Name = bitBuffer.ReadString(); player.Score = bitBuffer.ReadInt32(); Single time = bitBuffer.ReadSingle(); player.Time = (time == -1 ? "BOT" : Common.DurationString(time)); mainWindowInterface.AddPlayerToServer(this, player); } }
/// <summary> /// Parses S2C_INFO. /// </summary> /// <param name="data"></param> /// <param name="si"></param> private void ParseInfoQueryReply(Byte[] data) { BitBuffer bitBuffer = new BitBuffer(data); if (bitBuffer.ReadInt32() != -1) { throw new ApplicationException("Bad A2S_INFO reply"); } // read reply type Byte type = bitBuffer.ReadByte(); Boolean sourceEngine; if (type == S2C_INFO_SOURCE) { sourceEngine = true; } else if (type == S2C_INFO_GOLDSRC) { sourceEngine = false; } else { throw new ApplicationException(String.Format("Bad A2S_INFO type: {0}", type)); } mainWindowInterface.SetServerProperty(this, "SourceEngine", sourceEngine); // read the rest if (!sourceEngine) { bitBuffer.ReadString(); //si.Address = bitBuffer.ReadString(); // resolved hostname } else { bitBuffer.SeekBytes(1); // network version } mainWindowInterface.SetServerProperty(this, "Title", bitBuffer.ReadString()); // server name mainWindowInterface.SetServerProperty(this, "Map", bitBuffer.ReadString()); // map String gameFolder = bitBuffer.ReadString(); mainWindowInterface.SetServerProperty(this, "GameFolder", gameFolder); // game folder String gameName = bitBuffer.ReadString(); // game name if (sourceEngine) { bitBuffer.SeekBytes(2); // app id } mainWindowInterface.SetServerProperty(this, "NumSpectators", bitBuffer.ReadByte()); // num spectators mainWindowInterface.SetServerProperty(this, "MaxSpectators", bitBuffer.ReadByte()); // max spectators bitBuffer.SeekBytes(1); // goldsrc: network version, source: num bots bitBuffer.SeekBytes(1); // dedicated bitBuffer.SeekBytes(1); // os mainWindowInterface.SetServerProperty(this, "PasswordProtected", (bitBuffer.ReadByte() == 1)); // determine game name Game game = GameManager.Find((sourceEngine ? Game.Engines.Source : Game.Engines.HalfLife), gameFolder); if (game == null) { mainWindowInterface.SetServerProperty(this, "GameName", gameName); } else { mainWindowInterface.SetServerProperty(this, "GameName", game.Name); } }
private Object ParseEntry(BitBuffer bitBuffer, Entry e) { Boolean signed = ((e.Flags & EntryFlags.Signed) != 0); if ((e.Flags & EntryFlags.Byte) != 0) { if (signed) { return((SByte)ParseInt(bitBuffer, e)); } else { return((Byte)ParseUnsignedInt(bitBuffer, e)); } } if ((e.Flags & EntryFlags.Short) != 0) { if (signed) { return((Int16)ParseInt(bitBuffer, e)); } else { return((UInt16)ParseUnsignedInt(bitBuffer, e)); } } if ((e.Flags & EntryFlags.Integer) != 0) { if (signed) { return((Int32)ParseInt(bitBuffer, e)); } else { return((UInt32)ParseUnsignedInt(bitBuffer, e)); } } if ((e.Flags & EntryFlags.Float) != 0 || (e.Flags & EntryFlags.TimeWindow8) != 0 || (e.Flags & EntryFlags.TimeWindowBig) != 0) { Boolean negative = false; Int32 bitsToRead = (Int32)e.nBits; if (signed) { negative = bitBuffer.ReadBoolean(); bitsToRead--; } return((Single)bitBuffer.ReadUnsignedBits(bitsToRead) / e.Divisor * (negative ? -1.0f : 1.0f)); } if ((e.Flags & EntryFlags.Angle) != 0) { return((Single)(bitBuffer.ReadUnsignedBits((Int32)e.nBits) * (360.0f / (Single)(1 << (Int32)e.nBits)))); } if ((e.Flags & EntryFlags.String) != 0) { return(bitBuffer.ReadString()); } throw new ApplicationException(String.Format("Unknown delta entry type {0}.", e.Flags)); }
private Object ParseEntry(BitBuffer bitBuffer, Entry e) { Boolean signed = ((e.Flags & EntryFlags.Signed) != 0); if ((e.Flags & EntryFlags.Byte) != 0) { if (signed) { return (SByte)ParseInt(bitBuffer, e); } else { return (Byte)ParseUnsignedInt(bitBuffer, e); } } if ((e.Flags & EntryFlags.Short) != 0) { if (signed) { return (Int16)ParseInt(bitBuffer, e); } else { return (UInt16)ParseUnsignedInt(bitBuffer, e); } } if ((e.Flags & EntryFlags.Integer) != 0) { if (signed) { return (Int32)ParseInt(bitBuffer, e); } else { return (UInt32)ParseUnsignedInt(bitBuffer, e); } } if ((e.Flags & EntryFlags.Float) != 0 || (e.Flags & EntryFlags.TimeWindow8) != 0 || (e.Flags & EntryFlags.TimeWindowBig) != 0) { Boolean negative = false; Int32 bitsToRead = (Int32)e.nBits; if (signed) { negative = bitBuffer.ReadBoolean(); bitsToRead--; } return (Single)bitBuffer.ReadUnsignedBits(bitsToRead) / e.Divisor * (negative ? -1.0f : 1.0f); } if ((e.Flags & EntryFlags.Angle) != 0) { return (Single)(bitBuffer.ReadUnsignedBits((Int32)e.nBits) * (360.0f / (Single)(1 << (Int32)e.nBits))); } if ((e.Flags & EntryFlags.String) != 0) { return bitBuffer.ReadString(); } throw new ApplicationException(String.Format("Unknown delta entry type {0}.", e.Flags)); }
private void MessageDisconnect() { bitBuffer.ReadString(); // Disconnect reason? }
public void MessageDownload() { bitBuffer.SeekBits(32); bitBuffer.ReadString(); bitBuffer.SeekBits(1); }