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; } } } }
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))); }
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)); }
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)); }
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)); }