from socket import socket import rcon from rcon import login, send_command from utils import parse_args, safe_input, load_script # terminal color codes # the readline module requires \001 and \002 because it counts characters # when displaying, but those color codes are zero-width # also, the libedit library that readline sometimes interfaces with truncates trailing color codes # always end input() prompt strings with a visible character (including a space) RST = '\001\x1b[0m\002' GRN = '\001\x1b[0;32m\002' BLU = '\001\x1b[0;34m\002' GRY = '\001\x1b[0;37m\002' def main(): args = parse_args() RCON_ADDRESS = None if args.host: RCON_ADDRESS = args.host args.port = args.port or 25575 else: RCON_ADDRESS = safe_input(f"{GRN} RCON hostname (IP address)>{RST} ") RCON_PORT = args.port or int(safe_input(f"{GRN} RCON port (default 25575)>{RST} ") or 25575) RCON_PASSWORD = args.password or safe_input(f"{GRN} RCON server password>{RST} ") # open TCP connection to server with socket() as sock: try: sock.connect((RCON_ADDRESS, RCON_PORT)) except: print(f"{GRY} Connection to server failed. {RST}") print(f"{GRY} Please check the server hostname and port, then try again. {RST}") exit(1) sock.settimeout(args.socket_timeout or 30) # login attempts login_success = login(sock, RCON_PASSWORD) while (not login_success): print(f"{GRY} Authentication failed. {RST}") # if not run interactively, quit b/c we don't want to prompt the user for more passwords if args.password: exit(1) login_success = login(sock, safe_input(f"{GRN} Please re-enter the RCON password>{RST} ")) if args.execute_command: if args.echo: rcon.ECHO_COMMANDS = True for command in args.execute_command: print(send_command(sock, command)) exit() elif args.execute_file: if args.echo: rcon.ECHO_COMMANDS = True script = load_script(args.execute_file) # load_script already verifies the user script has a `run` method script.run(sock) exit() else: # command REPL print(f"{GRY} Successfully logged in. Press Ctrl-C for a fresh prompt or Ctrl-D to exit. {RST}") while True: # safe_input will terminate the program when the user pressed Ctrl-D command = safe_input(f"{BLU} RCON@{RCON_ADDRESS} >{RST} ") print(f"{GRY}", send_command(sock, command), f"{RST}") if __name__ == '__main__': main()