#!/usr/bin/env python3 """Minimal Minecraft RCON client (stdlib only). Usage: python3 rcon.py [command ...] Exit non-zero if the server reports a failure. """ import socket import struct import sys class Rcon: def __init__(self, host: str, port: int, password: str, timeout: float = 10.0): self.host, self.port, self.password = host, port, password self.timeout = timeout self._id = 0 def _send(self, sock: socket.socket, ptype: int, body: str) -> int: self._id += 1 rid = self._id payload = struct.pack(" str: with socket.create_connection((self.host, self.port), timeout=self.timeout) as sock: sock.settimeout(self.timeout) rid = self._send(sock, 3, self.password) rid2, _, _ = self._recv(sock) if rid2 == -1: raise PermissionError("RCON auth failed") self._send(sock, 2, cmd) _, _, text = self._recv(sock) return text def main(argv): if len(argv) < 5: print(__doc__) return 2 host, port, password = argv[1], int(argv[2]), argv[3] rc = 0 for cmd in argv[4:]: try: out = Rcon(host, port, password).command(cmd) except Exception as exc: # noqa: BLE001 - CLI surface print(f"! {cmd}: {exc}", file=sys.stderr) rc = 1 continue if out.strip(): print(out.strip()) lowered = out.lower() if "unknown" in lowered or "failed" in lowered or "error" in lowered: rc = 1 return rc if __name__ == "__main__": raise SystemExit(main(sys.argv))