internal static ReadOnlyCollection <IPEndPoint> ProcessPacket(byte[] packet) { Parser parser = new Parser(packet); List <IPEndPoint> endPoints = new List <IPEndPoint>(); parser.Skip(6); int counter = 6; string ip = string.Empty;; int port = 0; while (counter != packet.Length) { ip = parser.ReadByte() + "." + parser.ReadByte() + "." + parser.ReadByte() + "." + parser.ReadByte(); byte portByte1 = parser.ReadByte(); byte portByte2 = parser.ReadByte(); if (BitConverter.IsLittleEndian) { port = BitConverter.ToUInt16(new byte[] { portByte2, portByte1 }, 0); } else { port = BitConverter.ToUInt16(new byte[] { portByte1, portByte2 }, 0); } endPoints.Add(new IPEndPoint(IPAddress.Parse(ip), port)); counter += 6; } return(endPoints.AsReadOnly()); }
/// <summary> /// Retrieves information about the players currently on the server /// </summary> /// <returns>ReadOnlyCollection of Player instances</returns> public virtual ReadOnlyCollection <Player> GetPlayers() { byte[] recvData = null; if (IsObsolete) { recvData = socket.GetResponse(QueryMsg.ObsoletePlayerQuery, Type); } else { if (PlayerChallengeId == null) { recvData = GetPlayerChallengeId(); if (IsPlayerChallengeId) { PlayerChallengeId = recvData; } } if (IsPlayerChallengeId) { recvData = socket.GetResponse(Util.MergeByteArrays(QueryMsg.PlayerQuery, PlayerChallengeId), Type); } } try { Parser parser = new Parser(recvData); if (parser.ReadByte() != (byte)ResponseMsgHeader.A2S_PLAYER) { throw new InvalidHeaderException("A2S_PLAYER message header is not valid"); } int playerCount = parser.ReadByte(); List <Player> players = new List <Player>(playerCount); for (int i = 0; i < playerCount; i++) { parser.ReadByte();//index,always equal to 0 players.Add(new Player() { Name = parser.ReadString(), Score = parser.ReadInt(), Time = TimeSpan.FromSeconds(parser.ReadFloat()) }); } if (playerCount == 1 && players[0].Name == "Max Players") { return(null); } return(players.AsReadOnly()); } catch (Exception e) { e.Data.Add("ReceivedData", recvData); throw; } }
private byte[] SourcePackets(byte[] data) { byte pktCount = data[8]; List <KeyValuePair <byte, byte[]> > pktList = new List <KeyValuePair <byte, byte[]> >(pktCount); pktList.Add(new KeyValuePair <byte, byte[]>(data[9], data)); byte[] recvData; for (int i = 1; i < pktCount; i++) { recvData = ReceiveData(); pktList.Add(new KeyValuePair <byte, byte[]>(recvData[9], recvData)); } pktList.Sort((x, y) => x.Key.CompareTo(y.Key)); Parser parser = null; bool isCompressed = false; int checksum = 0; List <byte> recvList = new List <byte>(); parser = new Parser(pktList[0].Value); parser.Skip(4); //header if (parser.ReadInt() < 0) //ID { isCompressed = true; } parser.ReadByte(); //total int pktId = parser.ReadByte(); // packet id parser.ReadShort(); //size if (isCompressed) { parser.Skip(2); //[this is not equal to decompressed length of data] checksum = parser.ReadInt(); //Checksum } recvList.AddRange(parser.GetUnParsedData()); for (int i = 1; i < pktList.Count; i++) { parser = new Parser(pktList[i].Value); parser.Skip(12);//multipacket header only recvList.AddRange(parser.GetUnParsedData()); } recvData = recvList.ToArray <byte>(); if (isCompressed) { recvData = Decompress(recvData); if (!IsValid(recvData, checksum)) { throw new InvalidPacketException("packet's checksum value does not match with the calculated checksum"); } } return(recvData.Skip(4).ToArray <byte>()); }
protected virtual ReadOnlyCollection <Player> GetPlayersCore(Stopwatch sw = null) { byte[] recvData = null; if (IsObsolete) { recvData = socket.GetResponse(QueryMsg.ObsoletePlayerQuery, Type); } else { if (PlayerChallengeId == null) { recvData = GetPlayerChallengeId(sw); if (IsPlayerChallengeId) { PlayerChallengeId = recvData; } } if (IsPlayerChallengeId) { recvData = socket.GetResponse(Util.MergeByteArrays(QueryMsg.PlayerQuery, PlayerChallengeId), Type); } } try { var parser = new Parser(recvData); if (parser.ReadByte() != (byte)ResponseMsgHeader.A2S_PLAYER) { throw new InvalidHeaderException("A2S_PLAYER message header is not valid"); } int playerCount = parser.ReadByte(); var players = new List <Player>(); for (var i = 0; i < playerCount && parser.HasMore; i++) { parser.ReadByte(); //index,always equal to 0 players.Add(new Player { Name = parser.ReadString(), Score = parser.ReadInt(), Time = TimeSpan.FromSeconds(parser.ReadFloat()) }); } //playerCount = players.Count; // some servers report more players than it really returns //if (playerCount == 1 && players[0].Name == "Max Players") // return null; return(players.AsReadOnly()); } catch (Exception e) { e.Data.Add("ReceivedData", recvData); throw; } }
private byte[] GetPlayerChallengeId(Stopwatch sw = null) { var recvBytes = socket.GetResponse(QueryMsg.PlayerChallengeQuery, Type, sw); try { var parser = new Parser(recvBytes); var header = parser.ReadByte(); switch (header) { case (byte)ResponseMsgHeader.A2S_SERVERQUERY_GETCHALLENGE: IsPlayerChallengeId = true; return(parser.GetUnParsedData()); case (byte)ResponseMsgHeader.A2S_PLAYER: IsPlayerChallengeId = false; return(recvBytes); default: throw new InvalidHeaderException("A2S_SERVERQUERY_GETCHALLENGE message header is not valid"); } } catch (Exception e) { e.Data.Add("ReceivedData", recvBytes); throw; } }
private byte[] GetRuleChallengeId() { var recvBytes = socket.GetResponse(QueryMsg.RuleChallengeQuery, Type); try { var parser = new Parser(recvBytes); var header = parser.ReadByte(); switch (header) { case (byte)ResponseMsgHeader.A2S_SERVERQUERY_GETCHALLENGE: IsRuleChallengeId = true; return(BitConverter.GetBytes(parser.ReadInt())); case (byte)ResponseMsgHeader.A2S_RULES: IsRuleChallengeId = false; return(recvBytes); default: throw new InvalidHeaderException("A2S_SERVERQUERY_GETCHALLENGE message header is not valid"); } } catch (Exception e) { e.Data.Add("ReceivedData", recvBytes); throw; } }
/// <summary> /// Retrieves server rules /// </summary> /// <returns>ReadOnlyCollection of Rule instances</returns> public ReadOnlyCollection <Rule> GetRules() { byte[] recvData = null; if (IsObsolete) { recvData = socket.GetResponse(QueryMsg.ObsoleteRuleQuery, Type); } else { if (RuleChallengeId == null) { recvData = GetRuleChallengeId(); if (IsRuleChallengeId) { RuleChallengeId = recvData; } } if (IsRuleChallengeId) { recvData = socket.GetResponse(Util.MergeByteArrays(QueryMsg.RuleQuery, RuleChallengeId), Type); } } try { Parser parser = new Parser(recvData); if (parser.ReadByte() != (byte)ResponseMsgHeader.A2S_RULES) { throw new InvalidHeaderException("A2S_RULES message header is not valid"); } int count = parser.ReadShort();//number of rules List <Rule> rules = new List <Rule>(count); for (int i = 0; i < count; i++) { rules.Add(new Rule() { Name = parser.ReadString(), Value = parser.ReadString() }); } return(rules.AsReadOnly()); } catch (Exception e) { e.Data.Add("ReceivedData", recvData); throw; } }
private ServerInfo Obsolete(byte[] data) { var parser = new Parser(data); if (parser.ReadByte() != (byte) ResponseMsgHeader.A2S_INFO_Obsolete) throw new InvalidHeaderException("A2S_INFO(obsolete) message header is not valid"); var server = new ServerInfo(); server.IsObsolete = true; server.Address = parser.ReadString(); server.Name = parser.ReadString(); server.Map = parser.ReadString(); server.Directory = parser.ReadString(); server.Id = Util.GetGameId(parser.ReadString()); server.Players = parser.ReadByte(); server.MaxPlayers = parser.ReadByte(); server.Protocol = parser.ReadByte(); server.ServerType = (new Func<string>(() => { switch ((char) parser.ReadByte()) { case 'L': return "non-dedicated server"; case 'D': return "dedicated"; case 'P': return "HLTV server"; } return ""; }))(); server.Environment = (new Func<string>(() => { switch ((char) parser.ReadByte()) { case 'L': return "Linux"; case 'W': return "Windows"; } return ""; }))(); server.IsPrivate = Convert.ToBoolean(parser.ReadByte()); var mod = parser.ReadByte(); server.IsModded = mod > 0; if (server.IsModded) { var modinfo = new Mod(); modinfo.Link = parser.ReadString(); modinfo.DownloadLink = parser.ReadString(); parser.ReadByte(); //0x00 modinfo.Version = parser.ReadInt(); modinfo.Size = parser.ReadInt(); modinfo.IsOnlyMultiPlayer = parser.ReadByte() > 0; modinfo.IsHalfLifeDll = parser.ReadByte() == 0; server.ModInfo = modinfo; } server.IsSecure = Convert.ToBoolean(parser.ReadByte()); server.Bots = parser.ReadByte(); server.GameVersion = "server is obsolete,does not provide this information"; server.Ping = Latency; return server; }
private byte[] GetRuleChallengeId() { var recvBytes = socket.GetResponse(QueryMsg.RuleChallengeQuery, Type); try { var parser = new Parser(recvBytes); var header = parser.ReadByte(); switch (header) { case (byte) ResponseMsgHeader.A2S_SERVERQUERY_GETCHALLENGE: IsRuleChallengeId = true; return BitConverter.GetBytes(parser.ReadInt()); case (byte) ResponseMsgHeader.A2S_RULES: IsRuleChallengeId = false; return recvBytes; default: throw new InvalidHeaderException("A2S_SERVERQUERY_GETCHALLENGE message header is not valid"); } } catch (Exception e) { e.Data.Add("ReceivedData", recvBytes); throw; } }
private ServerInfo Current(byte[] data) { var parser = new Parser(data); if (parser.ReadByte() != (byte) ResponseMsgHeader.A2S_INFO) throw new InvalidHeaderException("A2S_INFO message header is not valid"); var server = new ServerInfo(); server.IsObsolete = false; server.Protocol = parser.ReadByte(); server.Name = parser.ReadString(); server.Map = parser.ReadString(); server.Directory = parser.ReadString(); server.Description = parser.ReadString(); server.Id = parser.ReadShort(); server.Players = parser.ReadByte(); server.MaxPlayers = parser.ReadByte(); server.Bots = parser.ReadByte(); server.ServerType = (new Func<string>(() => { switch ((char) parser.ReadByte()) { case 'l': return "Listen"; case 'd': return "Dedicated"; case 'p': return "SourceTV"; } return ""; }))(); server.Environment = (new Func<string>(() => { switch ((char) parser.ReadByte()) { case 'l': return "Linux"; case 'w': return "Windows"; case 'm': return "Mac"; } return ""; }))(); server.IsPrivate = Convert.ToBoolean(parser.ReadByte()); server.IsSecure = Convert.ToBoolean(parser.ReadByte()); if (server.Id >= 2400 && server.Id <= 2412) { var ship = new TheShip(); switch (parser.ReadByte()) { case 0: ship.Mode = "Hunt"; break; case 1: ship.Mode = "Elimination"; break; case 2: ship.Mode = "Duel"; break; case 3: ship.Mode = "Deathmatch"; break; case 4: ship.Mode = "VIP Team"; break; case 5: ship.Mode = "Team Elimination"; break; default: ship.Mode = ""; break; } ship.Witnesses = parser.ReadByte(); ship.Duration = parser.ReadByte(); server.ShipInfo = ship; } server.GameVersion = parser.ReadString(); if (parser.HasMore) { var edf = parser.ReadByte(); var info = new ExtraInfo(); info.Port = (edf & 0x80) > 0 ? parser.ReadShort() : (ushort)0; info.SteamID = (edf & 0x10) > 0 ? parser.ReadLong() : 0; if ((edf & 0x40) > 0) info.SpecInfo = new SourceTVInfo {Port = parser.ReadShort(), Name = parser.ReadString()}; info.Keywords = (edf & 0x20) > 0 ? parser.ReadString() : string.Empty; info.GameId = (edf & 0x01) > 0 ? parser.ReadLong() : 0; server.Extra = info; } server.Address = socket.Address.Address + ":" + socket.Address.Port; server.Ping = Latency; return server; }
protected virtual ReadOnlyCollection<Rule> GetRulesCore() { byte[] recvData = null; if (IsObsolete) { recvData = socket.GetResponse(QueryMsg.ObsoleteRuleQuery, Type); } else { if (RuleChallengeId == null) { recvData = GetRuleChallengeId(); if (IsRuleChallengeId) RuleChallengeId = recvData; } if (IsRuleChallengeId) recvData = socket.GetResponse(Util.MergeByteArrays(QueryMsg.RuleQuery, RuleChallengeId), Type); } try { var parser = new Parser(recvData); if (parser.ReadByte() != (byte) ResponseMsgHeader.A2S_RULES) throw new InvalidHeaderException("A2S_RULES message header is not valid"); int count = parser.ReadShort(); //number of rules var rules = new List<Rule>(count); for (var i = 0; i < count; i++) { rules.Add(new Rule {Name = parser.ReadString(), Value = parser.ReadString()}); } return rules.AsReadOnly(); } catch (Exception e) { e.Data.Add("ReceivedData", recvData); throw; } }
protected virtual ReadOnlyCollection<Player> GetPlayersCore() { byte[] recvData = null; if (IsObsolete) { recvData = socket.GetResponse(QueryMsg.ObsoletePlayerQuery, Type); } else { if (PlayerChallengeId == null) { recvData = GetPlayerChallengeId(); if (IsPlayerChallengeId) PlayerChallengeId = recvData; } if (IsPlayerChallengeId) recvData = socket.GetResponse(Util.MergeByteArrays(QueryMsg.PlayerQuery, PlayerChallengeId), Type); } try { var parser = new Parser(recvData); if (parser.ReadByte() != (byte) ResponseMsgHeader.A2S_PLAYER) throw new InvalidHeaderException("A2S_PLAYER message header is not valid"); int playerCount = parser.ReadByte(); var players = new List<Player>(); for (var i = 0; i < playerCount && parser.HasMore; i++) { parser.ReadByte(); //index,always equal to 0 players.Add(new Player { Name = parser.ReadString(), Score = parser.ReadInt(), Time = TimeSpan.FromSeconds(parser.ReadFloat()) }); } //playerCount = players.Count; // some servers report more players than it really returns //if (playerCount == 1 && players[0].Name == "Max Players") // return null; return players.AsReadOnly(); } catch (Exception e) { e.Data.Add("ReceivedData", recvData); throw; } }
internal static ReadOnlyCollection<IPEndPoint> ProcessPacket(byte[] packet) { Parser parser = new Parser(packet); List<IPEndPoint> endPoints = new List<IPEndPoint>(); parser.Skip(6); int counter = 6; string ip = string.Empty; ; int port = 0; while (counter != packet.Length) { ip = parser.ReadByte() + "." + parser.ReadByte() + "." + parser.ReadByte() + "." + parser.ReadByte(); byte portByte1 = parser.ReadByte(); byte portByte2 = parser.ReadByte(); if (BitConverter.IsLittleEndian) { port = BitConverter.ToUInt16(new byte[] { portByte2, portByte1 }, 0); } else { port = BitConverter.ToUInt16(new byte[] { portByte1, portByte2 }, 0); } endPoints.Add(new IPEndPoint(IPAddress.Parse(ip), port)); counter += 6; } return endPoints.AsReadOnly(); }
private ServerInfo Obsolete(byte[] data) { var parser = new Parser(data); if (parser.ReadByte() != (byte)ResponseMsgHeader.A2S_INFO_Obsolete) { throw new InvalidHeaderException("A2S_INFO(obsolete) message header is not valid"); } var server = new ServerInfo(); server.IsObsolete = true; server.Address = parser.ReadString(); server.Name = parser.ReadString(); server.Map = parser.ReadString(); server.Directory = parser.ReadString(); server.Id = Util.GetGameId(parser.ReadString()); server.Players = parser.ReadByte(); server.MaxPlayers = parser.ReadByte(); server.Protocol = parser.ReadByte(); server.ServerType = (new Func <string>(() => { switch ((char)parser.ReadByte()) { case 'L': return("non-dedicated server"); case 'D': return("dedicated"); case 'P': return("HLTV server"); } return(""); }))(); server.Environment = (new Func <string>(() => { switch ((char)parser.ReadByte()) { case 'L': return("Linux"); case 'W': return("Windows"); } return(""); }))(); server.IsPrivate = Convert.ToBoolean(parser.ReadByte()); var mod = parser.ReadByte(); server.IsModded = mod > 0; if (server.IsModded) { var modinfo = new Mod(); modinfo.Link = parser.ReadString(); modinfo.DownloadLink = parser.ReadString(); parser.ReadByte(); //0x00 modinfo.Version = parser.ReadInt(); modinfo.Size = parser.ReadInt(); modinfo.IsOnlyMultiPlayer = parser.ReadByte() > 0; modinfo.IsHalfLifeDll = parser.ReadByte() == 0; server.ModInfo = modinfo; } server.IsSecure = Convert.ToBoolean(parser.ReadByte()); server.Bots = parser.ReadByte(); server.GameVersion = "server is obsolete,does not provide this information"; server.Ping = Latency; return(server); }
private ServerInfo Current(byte[] data) { var parser = new Parser(data); if (parser.ReadByte() != (byte)ResponseMsgHeader.A2S_INFO) { throw new InvalidHeaderException("A2S_INFO message header is not valid"); } var server = new ServerInfo(); server.IsObsolete = false; server.Protocol = parser.ReadByte(); server.Name = parser.ReadString(); server.Map = parser.ReadString(); server.Directory = parser.ReadString(); server.Description = parser.ReadString(); server.Id = parser.ReadShort(); server.Players = parser.ReadByte(); server.MaxPlayers = parser.ReadByte(); server.Bots = parser.ReadByte(); server.ServerType = (new Func <string>(() => { switch ((char)parser.ReadByte()) { case 'l': return("Listen"); case 'd': return("Dedicated"); case 'p': return("SourceTV"); } return(""); }))(); server.Environment = (new Func <string>(() => { switch ((char)parser.ReadByte()) { case 'l': return("Linux"); case 'w': return("Windows"); case 'm': return("Mac"); } return(""); }))(); server.IsPrivate = Convert.ToBoolean(parser.ReadByte()); server.IsSecure = Convert.ToBoolean(parser.ReadByte()); if (server.Id >= 2400 && server.Id <= 2412) { var ship = new TheShip(); switch (parser.ReadByte()) { case 0: ship.Mode = "Hunt"; break; case 1: ship.Mode = "Elimination"; break; case 2: ship.Mode = "Duel"; break; case 3: ship.Mode = "Deathmatch"; break; case 4: ship.Mode = "VIP Team"; break; case 5: ship.Mode = "Team Elimination"; break; default: ship.Mode = ""; break; } ship.Witnesses = parser.ReadByte(); ship.Duration = parser.ReadByte(); server.ShipInfo = ship; } server.GameVersion = parser.ReadString(); if (parser.HasMore) { var edf = parser.ReadByte(); var info = new ExtraInfo(); info.Port = (edf & 0x80) > 0 ? parser.ReadShort() : (ushort)0; info.SteamID = (edf & 0x10) > 0 ? parser.ReadLong() : 0; if ((edf & 0x40) > 0) { info.SpecInfo = new SourceTVInfo { Port = parser.ReadShort(), Name = parser.ReadString() } } ; info.Keywords = (edf & 0x20) > 0 ? parser.ReadString() : string.Empty; info.GameId = (edf & 0x01) > 0 ? parser.ReadLong() : 0; server.Extra = info; } server.Address = socket.Address.Address + ":" + socket.Address.Port; server.Ping = Latency; return(server); }
private byte[] GetPlayerChallengeId() { byte[] recvBytes = null; byte header = 0; Parser parser = null; recvBytes = socket.GetResponse(QueryMsg.PlayerChallengeQuery, Type); try { parser = new Parser(recvBytes); header = parser.ReadByte(); switch (header) { case (byte)ResponseMsgHeader.A2S_SERVERQUERY_GETCHALLENGE: IsPlayerChallengeId = true; return parser.GetUnParsedData(); case (byte)ResponseMsgHeader.A2S_PLAYER: IsPlayerChallengeId = false; return recvBytes; default: throw new InvalidHeaderException("A2S_SERVERQUERY_GETCHALLENGE message header is not valid"); } } catch (Exception e) { e.Data.Add("ReceivedData", recvBytes); throw; } }
private byte[] SourcePackets(byte[] data) { byte pktCount = data[8]; List<KeyValuePair<byte, byte[]>> pktList = new List<KeyValuePair<byte, byte[]>>(pktCount); pktList.Add(new KeyValuePair<byte, byte[]>(data[9], data)); byte[] recvData; for (int i = 1; i < pktCount; i++) { recvData = ReceiveData(); pktList.Add(new KeyValuePair<byte, byte[]>(recvData[9], recvData)); } pktList.Sort((x, y) => x.Key.CompareTo(y.Key)); Parser parser = null; bool isCompressed = false; int checksum = 0; List<byte> recvList = new List<byte>(); parser = new Parser(pktList[0].Value); parser.Skip(4);//header if (parser.ReadInt() < 0)//ID isCompressed = true; parser.ReadByte();//total int pktId = parser.ReadByte();// packet id parser.ReadShort();//size if (isCompressed) { parser.Skip(2);//[this is not equal to decompressed length of data] checksum = parser.ReadInt();//Checksum } recvList.AddRange(parser.GetUnParsedData()); for (int i = 1; i < pktList.Count; i++) { parser = new Parser(pktList[i].Value); parser.Skip(12);//multipacket header only recvList.AddRange(parser.GetUnParsedData()); } recvData = recvList.ToArray<byte>(); if (isCompressed) { recvData = Decompress(recvData); if (!IsValid(recvData, checksum)) throw new InvalidPacketException("packet's checksum value does not match with the calculated checksum"); } return recvData.Skip(4).ToArray<byte>(); }