Browse Source

Acknowledge server messages

pull/20/head
Richard Neumann 2 years ago
parent
commit
5ed3572080
  1. 18
      rcon/battleye/client.py
  2. 17
      rcon/battleye/proto.py

18
rcon/battleye/client.py

@ -1,5 +1,6 @@
"""BattlEye RCon client.""" """BattlEye RCon client."""
from io import BufferedWriter
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
@ -11,6 +12,7 @@ from rcon.battleye.proto import LoginRequest
from rcon.battleye.proto import Request from rcon.battleye.proto import Request
from rcon.battleye.proto import Response from rcon.battleye.proto import Response
from rcon.battleye.proto import ServerMessage from rcon.battleye.proto import ServerMessage
from rcon.battleye.proto import ServerMessageAck
from rcon.client import BaseClient from rcon.client import BaseClient
from rcon.exceptions import WrongPassword from rcon.exceptions import WrongPassword
@ -31,11 +33,14 @@ class Client(BaseClient, socket_type=SOCK_DGRAM):
"""BattlEye RCon client.""" """BattlEye RCon client."""
def __init__( def __init__(
self, *args, self,
*args,
max_length: int = 4096,
message_handler: MessageHandler = log_message, message_handler: MessageHandler = log_message,
**kwargs **kwargs
): ):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
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, max_length: int) -> Response:
@ -46,9 +51,13 @@ class Client(BaseClient, socket_type=SOCK_DGRAM):
)).type )).type
].from_bytes(header, data[8:]) ].from_bytes(header, data[8:])
def receive(self, max_length: int = 4096) -> Response: def receive(self, file: BufferedWriter) -> Response:
"""Receive a message.""" """Receive a message."""
while isinstance(response := self._receive(max_length), ServerMessage): while isinstance(
response := self._receive(self.max_length),
ServerMessage
):
file.write(bytes(ServerMessageAck(response.seq)))
self._handle_server_message(response) self._handle_server_message(response)
return response return response
@ -57,8 +66,7 @@ class Client(BaseClient, socket_type=SOCK_DGRAM):
"""Send a request and receive a response.""" """Send a request and receive a response."""
with self._socket.makefile('wb') as file: with self._socket.makefile('wb') as file:
file.write(bytes(request)) file.write(bytes(request))
return self.receive(file)
return self.receive()
def login(self, passwd: str) -> bool: def login(self, passwd: str) -> bool:
"""Log-in the user.""" """Log-in the user."""

17
rcon/battleye/proto.py

@ -13,6 +13,7 @@ __all__ = [
'CommandRequest', 'CommandRequest',
'CommandResponse', 'CommandResponse',
'ServerMessage', 'ServerMessage',
'ServerMessageAck',
'Request', 'Request',
'Response' 'Response'
] ]
@ -172,7 +173,21 @@ class ServerMessage(NamedTuple):
return self.payload.decode('ascii') return self.payload.decode('ascii')
Request = LoginRequest | CommandRequest class ServerMessageAck(NamedTuple):
"""An acknowledgement of a message from the server."""
seq: int
def __bytes__(self):
return (0x02).to_bytes(1, 'little') + self.payload
@property
def payload(self) -> bytes:
"""Return the payload."""
return self.seq.to_bytes(1, 'little')
Request = LoginRequest | CommandRequest | ServerMessageAck
Response = LoginResponse | CommandResponse | ServerMessage Response = LoginResponse | CommandResponse | ServerMessage
RESPONSE_TYPES = { RESPONSE_TYPES = {

Loading…
Cancel
Save