Browse Source

Rewrite battleye client

pull/20/head
Richard Neumann 2 years ago
parent
commit
1552a58e84
  1. 54
      rcon/battleye/client.py

54
rcon/battleye/client.py

@ -1,6 +1,6 @@
"""BattlEye RCon client.""" """BattlEye RCon client."""
from io import BufferedWriter from collections import defaultdict
from logging import getLogger from logging import getLogger
from socket import SOCK_DGRAM from socket import SOCK_DGRAM
from typing import Callable from typing import Callable
@ -43,39 +43,45 @@ class Client(BaseClient, socket_type=SOCK_DGRAM):
self.max_length = max_length self.max_length = max_length
self._handle_server_message = message_handler self._handle_server_message = message_handler
def _receive(self, max_length: int) -> Response: def receive(self) -> Response:
"""Receive a packet.""" """Receive a packet."""
return RESPONSE_TYPES[ return RESPONSE_TYPES[
(header := Header.from_bytes( (header := Header.from_bytes(
(data := self._socket.recv(max_length))[:8] (data := self._socket.recv(self.max_length))[:8]
)).type )).type
].from_bytes(header, data[8:]) ].from_bytes(header, data[8:])
def receive(self, file: BufferedWriter) -> Response | str: def communicate(self, request: Request) -> Response | str:
"""Receive a message.""" """Send a request and receive a response."""
server_messages = set() acknowledged = defaultdict(set)
messages = []
while isinstance( while True:
response := self._receive(self.max_length), with self._socket.makefile('wb') as file:
ServerMessage file.write(bytes(request))
):
server_messages.add(response)
file.write(bytes(ServerMessageAck(response.seq)))
self._handle_server_message(response)
if not server_messages: response = self.receive()
return response
return ''.join( try:
msg.message for msg in seq = response.seq
sorted(server_messages, key=lambda msg: msg.seq) except AttributeError:
) return response
def communicate(self, request: Request) -> Response | str: if seq in acknowledged[msg_type := type(response)]:
"""Send a request and receive a response.""" break
with self._socket.makefile('wb') as file: else:
file.write(bytes(request)) acknowledged[msg_type].add(seq)
return self.receive(file)
if isinstance(response, ServerMessage):
self._handle_server_message(response)
with self._socket.makefile('wb') as file:
file.write(bytes(ServerMessageAck(response.seq)))
else:
messages.append(response)
return ''.join(msg.message for msg in sorted(messages, key=lambda msg: msg.seq))
def login(self, passwd: str) -> bool: def login(self, passwd: str) -> bool:
"""Log-in the user.""" """Log-in the user."""

Loading…
Cancel
Save