Ejemplo n.º 1
0
        protected async Task <List <ServerAddress> > RetrieveAsync(int limit, IPEndPoint remote = null, int tried = -1)
        {
            var cur     = -1;
            var servers = new List <ServerAddress>();

            if (remote == null)
            {
                var hosts = Dns.GetHostAddresses("hl2master.steampowered.com");
                if (tried == -1)
                {
                    cur = new Random().Next(hosts.Length);
                }
                else
                {
                    cur = (tried + 1) % hosts.Length;
                }
                var       host = hosts[cur];
                const int port = 27011;
#if DEBUG
                this.Logger().Debug("Contacting master server {0}:{1}", host, port);
#endif
                remote = new IPEndPoint(host, port); //TODO: alternate ip and ports availability
            }
            var e         = new IPEndPoint(IPAddress.Any, 0);
            var udpClient = new UdpClient(e)
            {
                Client = { ReceiveTimeout = DefaultReceiveTimeout, SendTimeout = DefaultSendTimeout }
            };
            udpClient.Connect(remote);

            var       i             = 0;
            const int maxIterations = 30;
            string    lastSeed;
            var       seed = "0.0.0.0:0";
            do
            {
                lastSeed = seed;
                var msg = BuildMessage(seed);

                if (await udpClient.SendAsync(msg, msg.Length).ConfigureAwait(false) != msg.Length)
                {
                    throw new Exception("Send failed.");
                }
                byte[] response = null;
                var    timedOut = false;
                try {
                    response =
                        (await udpClient.ReceiveWithTimeoutAfter(DefaultReceiveTimeout).ConfigureAwait(false)).Buffer;
                } catch (TimeoutException) {
                    timedOut = true;
                    if (cur == -1 || tried != -1 || i != 0)
                    {
                        throw new TimeoutException($"Received timeout on try: {(tried == -1 ? 1 : 2)} packet: {i}");
                    }
                }
                //only retries when remote was not passed in, on the first try, and when the first packet was never received
                if (timedOut)
                {
                    return(await RetrieveAsync(limit, null, cur));
                }
                seed = ParseResponse(servers, response, limit);
                if (seed == null)
                {
                    throw new Exception("Bad packet recieved.");
                }
                i++;
            } while (i < maxIterations && !seed.Equals("0.0.0.0:0") && !seed.Equals(lastSeed));
#if DEBUG
            this.Logger().Debug("Found {0} servers in {1} packets.", servers.Count, i);
#endif
            return(servers);
        }
Ejemplo n.º 2
0
        public async Task <List <IPEndPoint> > GetParsedServers(CancellationToken cancelToken, int limit = -1,
                                                                IPEndPoint remote = null, int tried = -1)
        {
            var cur     = -1;
            var servers = new List <IPEndPoint>();

            if (remote == null)
            {
                var hosts = await Dns.GetHostAddressesAsync("hl2master.steampowered.com").ConfigureAwait(false);

                if (tried == -1)
                {
                    cur = new Random().Next(hosts.Length);
                }
                else
                {
                    cur = (tried + 1) % hosts.Length;
                }
                var       host = hosts[cur];
                const int port = 27011;

                remote = new IPEndPoint(host, port); //TODO: alternate ip and ports availability
            }
            var e         = new IPEndPoint(IPAddress.Any, 0);
            var udpClient = new UdpClient(e)
            {
                Client = { ReceiveTimeout = Consts.DefaultReceiveTimeout, SendTimeout = Consts.DefaultSendTimeout }
            };

            var       i             = 0;
            const int maxIterations = 30;
            string    lastSeed;
            var       seed = "0.0.0.0:0";

            do
            {
                cancelToken.ThrowIfCancellationRequested();
                lastSeed = seed;
                var msg = BuildMessage(seed);

                if (await udpClient.SendAsync(msg, msg.Length, remote).ConfigureAwait(false) != msg.Length)
                {
                    throw new Exception("Send failed.");
                }
                byte[] response = null;
                var    timedOut = false;
                try {
                    response =
                        (await
                         udpClient.ReceiveWithTimeoutAfter(Consts.DefaultReceiveTimeout, cancelToken).ConfigureAwait(false))
                        .Buffer;
                } catch (TimeoutException) {
                    timedOut = true;
                    if ((cur == -1) || (tried != -1) || (i != 0))
                    {
                        throw new TimeoutException(string.Format("Received timeout on try: {0} packet: {1}",
                                                                 tried == -1 ? 1 : 2, i));
                    }
                }
                //only retries when remote was not passed in, on the first try, and when the first packet was never received
                if (timedOut)
                {
                    return(await GetParsedServers(cancelToken, limit, null, cur).ConfigureAwait(false));
                }
                seed = ParseResponse(servers, response, limit);
                if (seed == null)
                {
                    throw new Exception("Bad packet recieved.");
                }
                i++;
            } while ((i < maxIterations) && !seed.Equals("0.0.0.0:0") && !seed.Equals(lastSeed));
            return(servers);
        }