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()); }
public static SteamGameServer GetServerInfo(SteamGameServerQueryEndPoint gameServerQueryEndpoint) { return(GetServerInfo(new IPEndPoint(gameServerQueryEndpoint.Host, gameServerQueryEndpoint.QueryPort))); }