Browse Source

Fixed a typo and added support for new A2S Info challenge #298

pull/341/head
philippj 4 years ago
committed by Rossen
parent
commit
2c608af8bd
  1. 27
      steam/game_servers.py

27
steam/game_servers.py

@ -242,7 +242,7 @@ def _handle_a2s_response(sock):
sock.settimeout(0.3)
return _handle_a2s_multi_packet_response(sock, packet)
else:
raise RuntimeError("Invalid reponse header - %d" % header)
raise RuntimeError("Invalid response header - %d" % header)
def _handle_a2s_multi_packet_response(sock, packet):
@ -305,7 +305,7 @@ def _unpack_multipacket_header(payload_offset, packet):
raise RuntimeError("Unexpected payload_offset - %d" % payload_offset)
def a2s_info(server_addr, timeout=2, force_goldsrc=False):
def a2s_info(server_addr, timeout=2, force_goldsrc=False, challenge=0):
"""Get information from a server
.. note::
@ -320,6 +320,8 @@ def a2s_info(server_addr, timeout=2, force_goldsrc=False):
:type force_goldsrc: :class:`bool`
:param timeout: (optional) timeout in seconds
:type timeout: float
:param challenge: (optional) optionally supply a challenge in accordance to a2s protocol changes from December 2020
:type challenge: int
:raises: :class:`RuntimeError`, :class:`socket.timeout`
:returns: a dict with information or `None` on timeout
:rtype: :class:`dict`
@ -329,7 +331,11 @@ def a2s_info(server_addr, timeout=2, force_goldsrc=False):
ss.settimeout(timeout)
# request server info
ss.send(_pack('<lc', -1, b'T') + b'Source Engine Query\x00')
payload = _pack('<lc', -1, b'T') + b'Source Engine Query\x00'
if challenge not in (-1, 0): # If a valid challenge was supplied, append it to the payload
payload += challenge.to_bytes(4, 'little', signed = True)
ss.send(payload)
start = _time()
# handle response(s)
@ -359,8 +365,8 @@ def a2s_info(server_addr, timeout=2, force_goldsrc=False):
header, = data.unpack('<4xc')
# invalid header
if header not in b'mI':
raise RuntimeError("Invalid reponse header - %s" % repr(header))
if header not in b'mIA':
raise RuntimeError("Invalid response header - %s" % repr(header))
# GoldSrc response
elif header == b'm':
info = {
@ -445,6 +451,13 @@ def a2s_info(server_addr, timeout=2, force_goldsrc=False):
if edf & 0x01:
info['game_id'], = data.unpack('<Q')
info['app_id'] = info['game_id'] & 0xFFFFFF
# Challenge response
elif header == b'A':
if challenge not in (-1, 0):
raise RuntimeError("Invalid response header for request containing challenge answer - %s" % repr(header))
challenge = data.unpack('<l')
return a2s_info(server_addr = server_addr, timeout = timeout, force_goldsrc = force_goldsrc, challenge = challenge[0])
return info
@ -495,7 +508,7 @@ def a2s_players(server_addr, timeout=2, challenge=0):
header, num_players = data.unpack('<4xcB')
if header != b'D':
raise RuntimeError("Invalid reponse header - %s" % repr(header))
raise RuntimeError("Invalid response header - %s" % repr(header))
players = []
@ -553,7 +566,7 @@ def a2s_rules(server_addr, timeout=2, challenge=0):
header, num_rules = data.unpack('<4xcH')
if header != b'E':
raise RuntimeError("Invalid reponse header - %s" % repr(header))
raise RuntimeError("Invalid response header - %s" % repr(header))
rules = {}

Loading…
Cancel
Save