from asyncio import StreamReader, StreamWriter, open_connection from rcon.exceptions import SessionTimeout, WrongPassword from rcon.source.proto import Packet, Type from rcon.source.async_rcon import close, communicate # https://github.com/conqp/rcon/blob/929f358f1a7d155141704866b736c6f9666b4bd1/rcon/source/async_rcon.py#L45 async def rcon( command: str, *arguments: str, host: str, port: int, passwd: str, encoding: str = 'utf-8', frag_threshold: int = 4096, frag_detect_cmd: str = '' ) -> str: """Run a command asynchronously.""" reader, writer = await open_connection(host, port) response = await communicate( reader, writer, Packet.make_login(passwd, encoding=encoding), frag_threshold=frag_threshold, frag_detect_cmd=frag_detect_cmd ) # Wait for SERVERDATA_AUTH_RESPONSE according to: # https://developer.valvesoftware.com/wiki/Source_RCON_Protocol while response.type != Type.SERVERDATA_AUTH_RESPONSE: response = await Packet.aread(reader) if response.id == -1: await close(writer) raise WrongPassword() request = Packet.make_command(command, *arguments, encoding=encoding) response = await communicate(reader, writer, request) await close(writer) if response.id != request.id: raise SessionTimeout() try: return response.payload.decode(encoding) except UnicodeDecodeError: #print(f"[{host}:{port}] Cannot decode response payload, use ignore encoding") return response.payload.decode(encoding, errors="ignore")