コード例 #1
0
 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();
 }
コード例 #2
0
 private void GetChallengeId()
 {
     byte[] recvData=null;
     try
     {
         recvData = socket.GetResponse(RconChIdQuery, EngineType.GoldSource);
         Parser parser = new Parser(recvData);
         ChallengeId = parser.ReadString().Split(' ')[2].Trim();
     }
     catch (Exception e)
     {
         e.Data.Add("ReceivedData", recvData);
         throw;
     }
 }
コード例 #3
0
ファイル: RconUtil.cs プロジェクト: exelv1/SteamServerBrowser
 internal static RconSrcPacket ProcessPacket(byte[] data)
 {
     RconSrcPacket packet = new RconSrcPacket();
     try
     {
         Parser parser = new Parser(data);
         packet.Size = parser.ReadInt();
         packet.Id = parser.ReadInt();
         packet.Type = parser.ReadInt();
         byte[] body = parser.GetUnParsedData();
         if (body.Length == 2)
             packet.Body = string.Empty;
         else
             packet.Body = Util.BytesToString(body, 0, body.Length - 3);
     }
     catch (Exception e)
     {
         e.Data.Add("ReceivedData", data);
         throw;
     }
     return packet;
 }
コード例 #4
0
ファイル: Server.cs プロジェクト: vtchill/SteamServerBrowser
 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;
 }
コード例 #5
0
ファイル: Server.cs プロジェクト: vtchill/SteamServerBrowser
        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;
              }
        }
コード例 #6
0
ファイル: Server.cs プロジェクト: vtchill/SteamServerBrowser
        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;
        }
コード例 #7
0
ファイル: Server.cs プロジェクト: vtchill/SteamServerBrowser
        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;
              }
        }
コード例 #8
0
ファイル: Server.cs プロジェクト: vtchill/SteamServerBrowser
        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;
              }
        }
コード例 #9
0
 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;
     }
 }
コード例 #10
0
ファイル: UdpQuery.cs プロジェクト: exelv1/SteamServerBrowser
        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>();
        }