7 HEADER = b"\xFF\xFF\xFF\xFF"
10 @attr.s(auto_attribs=True, frozen=True, slots=True)
11 class CLGetInfo(Writable):
12 def encode(self) -> bytes:
13 return HEADER + f"getinfo {uuid.uuid4()}".encode(UTF_8)
16 @attr.s(auto_attribs=True, frozen=True, slots=True)
17 class SVGetInfoResponse(Readable):
27 qcstatus: Optional[str]
28 challenge: Optional[str]
29 d0_blind_id: Optional[str] = None
33 def decode(cls) -> Generator[Optional["SVGetInfoResponse"], bytes, None]:
34 ret: Optional[SVGetInfoResponse] = None
38 parts = buf.decode(UTF_8).split("\\")[1:]
39 pairs = zip(*[iter(parts)] * 2)
41 for k in ("gameversion", "sv_maxclients", "clients", "bots", "protocol"):
42 args[k] = int(args[k])
43 ret = SVGetInfoResponse(**args)
46 SVMessage = Union[SVGetInfoResponse]
50 def sv_parse() -> Generator[Optional[SVMessage], bytes, None]:
51 getinfo_response = b"infoResponse\n"
52 ret: Optional[SVMessage] = None
57 if buf.startswith(HEADER):
58 buf = buf[len(HEADER):]
59 if buf.startswith(getinfo_response):
60 buf = buf[len(getinfo_response):]
61 ret = SVGetInfoResponse.decode().send(buf)