You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

51 lines
1.6 KiB

import io
from a2s.exceptions import BrokenMessageError
from a2s.defaults import DEFAULT_TIMEOUT, DEFAULT_ENCODING
from a2s.a2sstream import request
from a2s.byteio import ByteReader
A2S_RULES_RESPONSE = 0x45
A2S_CHALLENGE_RESPONSE = 0x41
def rules(address, timeout=DEFAULT_TIMEOUT, encoding=DEFAULT_ENCODING):
return rules_impl(address, timeout, encoding)
def rules_impl(address, timeout, encoding, challenge=0):
resp_data = request(
address, b"\x56" + challenge.to_bytes(4, "little"), timeout)
reader = ByteReader(
io.BytesIO(resp_data), endian="<", encoding=encoding)
# A2S_RESPONSE misteriously seems to add a FF FF FF FF
# long to the beginning of the response which isn't
# mentioned on the wiki.
#
# Behaviour witnessed with TF2 server 94.23.226.200:2045
# As of 2015-11-22, Quake Live servers on steam do not
# Source: valve-python messages.py
if reader.peek(4) == b"\xFF\xFF\xFF\xFF":
reader.read(4)
response_type = reader.read_uint8()
if response_type == A2S_CHALLENGE_RESPONSE:
if challenge != 0:
raise BrokenMessageError(
"Server keeps sending challenge responses")
challenge = reader.read_int32()
return rules_impl(address, timeout, encoding, challenge)
if response_type != A2S_RULES_RESPONSE:
raise BrokenMessageError(
"Invalid response type: " + str(response_type))
rule_count = reader.read_int16()
# Have to use tuples to preserve evaluation order
resp = dict(
(reader.read_cstring(), reader.read_cstring())
for rule_num in range(rule_count)
)
return resp