コード例 #1
0
        public static SteamGameServerQueryEndPoint[] GetServerList(string gamename,
                                                                   Action <SteamGameServerQueryEndPoint> itemGenerated)
        {
            // https://developer.valvesoftware.com/wiki/Master_Server_Query_Protocol

            var queryEndPoints = new List <SteamGameServerQueryEndPoint>(5000);

            var addressBytes = new byte[4];
            var portBytes    = new byte[2];


            var dnsEntry = System.Net.Dns.GetHostEntry("hl2master.steampowered.com");

            //var ip = dnsEntry.AddressList.Length > 1 ? dnsEntry.AddressList[1] : dnsEntry.AddressList[0];
            foreach (var ip in dnsEntry.AddressList)
            {
                Debug.WriteLine($"Read from  {ip}");
                var        roundtrips   = 0;
                IPEndPoint lastEndPoint = new IPEndPoint(0, 0);
                queryEndPoints.Clear();

                using (System.Net.Sockets.UdpClient udp = new System.Net.Sockets.UdpClient())
                {
                    queryEndPoints.Clear();
                    var hasErros = false;

                    //udp.Connect("208.64.200.52", 27011);
                    while (true)
                    {
                        byte[] buffer = null;
                        try
                        {
                            udp.Connect(ip, 27011);
                            string request = "1ÿ";
                            request += lastEndPoint + "\0";
                            request += "\\gamedir\\" + gamename;
                            //request += "\\empty\\0";

#if DEBUG //request += @"\name_match\*EUTW*";
#endif

                            request += "\0";

                            var bytes = CharEncoding.GetBytes(request);

                            //udp.Connect("146.66.155.8", 27019);
                            IPEndPoint endp = udp.Client.RemoteEndPoint as IPEndPoint;
                            udp.Client.ReceiveTimeout = 900;

                            var sendlen = udp.Send(bytes, bytes.Length);
#if DEBUG
                            if (sendlen != bytes.Length)
                            {
                                Trace.WriteLine("IServerRepository.GetServerList - sendlen != bytes.Length");
                            }
#endif

                            roundtrips++;
                            buffer = udp.Receive(ref endp);
                        }
                        catch (System.Net.Sockets.SocketException)
                        {
                            //hasErros = true;
                            break;
                        }
                        catch (TimeoutException)
                        {
                            hasErros = true;
                            break;
                        }
                        catch (ObjectDisposedException)
                        {
                            hasErros = true;
                            break;
                        }

                        using (var mem = new System.IO.MemoryStream(buffer, false))
                            using (var br = new System.IO.BinaryReader(mem, Encoding.UTF8))
                            {
                                var i = br.ReadUInt32();
                                i = br.ReadUInt16();

                                while (mem.Position < mem.Length)
                                {
                                    addressBytes[0] = br.ReadByte();
                                    addressBytes[1] = br.ReadByte();
                                    addressBytes[2] = br.ReadByte();
                                    addressBytes[3] = br.ReadByte();

                                    portBytes[0] = br.ReadByte();
                                    portBytes[1] = br.ReadByte();

                                    int port = portBytes[0] << 8 | portBytes[1];


                                    if (addressBytes.All(b => b == 0))
                                    {
                                        break;
                                    }

                                    lastEndPoint = new IPEndPoint(new IPAddress(addressBytes), port);

                                    var item = new SteamGameServerQueryEndPoint();
                                    item.Host      = lastEndPoint.Address;
                                    item.QueryPort = lastEndPoint.Port;
                                    queryEndPoints.Add(item);
                                    if (itemGenerated != null)
                                    {
                                        itemGenerated(item);
                                    }
                                }

                                Debug.WriteLine("RoundTrips {0} - {1}", roundtrips, lastEndPoint.ToString());

                                if (addressBytes.All(b => b == 0))
                                {
                                    break;
                                }
                            }
                    }
                    if (!hasErros)
                    {
                        break;
                    }
                }
            }

            return(queryEndPoints.Distinct(new SteamGameServerQueryEndPointComparer()).ToArray());
        }
コード例 #2
0
 public static SteamGameServer GetServerInfo(SteamGameServerQueryEndPoint gameServerQueryEndpoint)
 {
     return(GetServerInfo(new IPEndPoint(gameServerQueryEndpoint.Host, gameServerQueryEndpoint.QueryPort)));
 }