Ejemplo n.º 1
0
        public IEnumerable <IGameServer> GetServersLazy(MasterServerRequest masterServerRequest)
        {
            var        packet       = 0;
            IPEndPoint lastEndPoint = null;

            using (var client = SteamAgent.GetUdpClient(_endpoint))
            {
                while (!masterServerRequest.MaximumPackets.HasValue || packet < masterServerRequest.MaximumPackets.Value)
                {
                    var request  = GetRequest(lastEndPoint, masterServerRequest.Region, masterServerRequest.Filters);
                    var response = AsyncHelper.RunSync(() => SteamAgent.RequestResponseAsync(client, request, IpEndPointLength));

                    packet++;

                    var packetEndPoints = ReadEndPointsFromPacket(response);
                    foreach (var endPoint in packetEndPoints)
                    {
                        if (endPoint.IsEmpty())
                        {
                            yield break;
                        }
                        yield return(new GameServer(endPoint));

                        lastEndPoint = endPoint;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public async Task <IEnumerable <IGameServer> > GetServersAsync(MasterServerRequest masterServerRequest)
        {
            var endPoints = new List <IPEndPoint>();

            var packet = 0;

            using (var client = SteamAgent.GetUdpClient(_endpoint))
            {
                while (!masterServerRequest.MaximumPackets.HasValue || packet < masterServerRequest.MaximumPackets.Value)
                {
                    var request  = GetRequest(endPoints.LastOrDefault(), masterServerRequest.Region, masterServerRequest.Filters);
                    var response = await SteamAgent.RequestResponseAsync(client, request, IpEndPointLength);

                    packet++;

                    var packetEndPoints = ReadEndPointsFromPacket(response);
                    endPoints.AddRange(packetEndPoints);

                    if (endPoints.Last().IsEmpty())
                    {
                        break;
                    }
                }
            }

            return(endPoints.Take(endPoints.Count - 1).Select(e => new GameServer(e)));
        }
Ejemplo n.º 3
0
        private async Task <GameServerInfo> QueryServerInfoAsync(TimeSpan timeout)
        {
            var task = Task.Run(async() =>
            {
                using (var client = SteamAgent.GetUdpClient(EndPoint))
                {
                    var requestPacket = GetRequestPacket(GameServerQueryPacketType.InfoRequest);
                    requestPacket.WriteString("Source Engine Query");

                    var pingTask     = SendPing();
                    var responseTask = SteamAgent.RequestResponseAsync(client, requestPacket.ToArray(), 4);

                    await Task.WhenAll(pingTask, responseTask);

                    var response = await responseTask;
                    var ping     = await pingTask;

                    var responseType = response.ReadEnum <GameServerQueryPacketType>();

                    if (responseType != GameServerQueryPacketType.InfoResponse)
                    {
                        throw new ProtocolViolationException();
                    }

                    _info = GameServerInfo.Parse(this, ping, response);
                    return(_info);
                }
            });

            return(await task.TimeoutAfter(timeout));
        }
Ejemplo n.º 4
0
        private async Task <IGameServerRules> QueryServerRulesAsync(TimeSpan timeout)
        {
            var task = Task.Run(async() =>
            {
                using (var client = SteamAgent.GetUdpClient(EndPoint))
                {
                    var requestPacket = GetRequestPacket(GameServerQueryPacketType.RulesRequest);
                    requestPacket.WriteLong(-1);

                    var reader = await SteamAgent.RequestResponseAsync(client, requestPacket.ToArray(), 4);

                    var responseType = reader.ReadEnum <GameServerQueryPacketType>();

                    if (responseType == GameServerQueryPacketType.RulesResponse)
                    {
                        throw new NotImplementedException();
                    }

                    if (responseType != GameServerQueryPacketType.RequestChallenge)
                    {
                        throw new ProtocolViolationException();
                    }

                    var challengeNumber = reader.ReadLong();
                    requestPacket       = GetRequestPacket(GameServerQueryPacketType.RulesRequest);
                    requestPacket.WriteLong(challengeNumber);

                    reader = await SteamAgent.RequestResponseAsync(client, requestPacket.ToArray(), 16); //seems not to agree with protocol, would expect this 11 bytes earlier...

                    responseType = reader.ReadEnum <GameServerQueryPacketType>();

                    if (responseType != GameServerQueryPacketType.RulesResponse)
                    {
                        throw new ProtocolViolationException();
                    }

                    var ruleCount = reader.ReadShort();
                    var rules     = new List <GameServerRule>(ruleCount);

                    var packetsReceived = 1;
                    Func <Task <BufferReader> > sequelRequestAsyncFunc = async() =>
                    {
                        var next = await SteamAgent.ReceiveBufferReaderAsync(client, 12); //protocol unclear, header size determined manually
                        packetsReceived++;
                        return(next);
                    };

                    var multiPacketStringReader = new MultiPacketStringReader(reader, sequelRequestAsyncFunc);

                    for (var i = 0; i < ruleCount; i++)
                    {
                        var key   = await multiPacketStringReader.ReadStringAsync();
                        var value = await multiPacketStringReader.ReadStringAsync();

                        rules.Add(new GameServerRule(key, value));
                    }

                    _rules = new GameServerRules(rules);
                    return(_rules);
                }
            });

            return(await task.TimeoutAfter(timeout));
        }
Ejemplo n.º 5
0
        private async Task <IEnumerable <IGameServerPlayer> > QueryServerPlayersAsync(TimeSpan timeout)
        {
            var task = Task.Run(async() =>
            {
                using (var client = SteamAgent.GetUdpClient(EndPoint))
                {
                    var requestPacket = GetRequestPacket(GameServerQueryPacketType.PlayersRequest);
                    requestPacket.WriteLong(-1);

                    var reader = await SteamAgent.RequestResponseAsync(client, requestPacket.ToArray(), 4);

                    var responseType = reader.ReadEnum <GameServerQueryPacketType>();

                    if (responseType != GameServerQueryPacketType.RequestChallenge)
                    {
                        throw new ProtocolViolationException();
                    }

                    var challengeNumber = reader.ReadLong();
                    requestPacket       = GetRequestPacket(GameServerQueryPacketType.PlayersRequest);
                    requestPacket.WriteLong(challengeNumber);

                    reader         = await SteamAgent.RequestResponseAsync(client, requestPacket.ToArray(), 4); //seems not to agree with protocol, would expect this 11 bytes earlier...
                    var receivedAt = DateTime.Now;

                    responseType = reader.ReadEnum <GameServerQueryPacketType>();

                    if (responseType != GameServerQueryPacketType.PlayersResponse)
                    {
                        throw new ProtocolViolationException();
                    }

                    var playerCount = reader.ReadByte();
                    var players     = new List <GameServerPlayer>(playerCount);

                    //var packetsReceived = 1;
                    //Func<Task<BufferReader>> sequelRequestAsyncFunc = async () =>
                    //{
                    //    var next = await SteamAgent.ReceiveBufferReaderAsync(client, 12); //protocol unclear, header size determined manually
                    //    packetsReceived++;
                    //    return next;
                    //};

                    //var multiPacketStringReader = new MultiPacketStringReader(reader, sequelRequestAsyncFunc);

                    for (var i = 0; i < playerCount; i++)
                    {
                        var position = reader.ReadByte();
                        //if (position != i)
                        //    throw new ProtocolViolationException($"Expected literal byte {i}, got {position} (player index)");

                        var name     = reader.ReadString();
                        var score    = reader.ReadLong();
                        var duration = reader.ReadFloat();

                        var connectedAt = receivedAt.Subtract(TimeSpan.FromSeconds(duration));

                        players.Add(new GameServerPlayer(name, score, connectedAt));
                    }

                    if (players.Count != playerCount)
                    {
                        throw new ArgumentOutOfRangeException($"Expected {playerCount} player blocks, got {players.Count}");
                    }

                    _players = players;
                    return(_players);
                }
            });

            return(await task.TimeoutAfter(timeout));
        }