68 lines
2.4 KiB
Python
68 lines
2.4 KiB
Python
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
|
|
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):
|
|
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))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main(parse_args())
|
|
|