104 lines
2.7 KiB
Python
104 lines
2.7 KiB
Python
|
import argparse
|
||
|
import logging
|
||
|
import re
|
||
|
import subprocess
|
||
|
import threading
|
||
|
from typing import List
|
||
|
|
||
|
import message_queue
|
||
|
|
||
|
|
||
|
LOG = logging.getLogger(__name__)
|
||
|
|
||
|
|
||
|
class ProcessWrapper:
|
||
|
"""Iterator that spawns a process and yields lines from its stdout."""
|
||
|
|
||
|
def __init__(self, command: List[str], queue: message_queue.MessageQueue):
|
||
|
self.proc = subprocess.Popen(
|
||
|
" ".join(command),
|
||
|
shell=True,
|
||
|
stdout=subprocess.PIPE,
|
||
|
stdin=subprocess.PIPE,
|
||
|
universal_newlines=True,
|
||
|
)
|
||
|
|
||
|
def __iter__(self):
|
||
|
return iter(self.proc.stdout.readline, "")
|
||
|
|
||
|
def send(self, msg):
|
||
|
self.proc.stdin.write(msg)
|
||
|
|
||
|
def wait(self):
|
||
|
return self.proc.wait()
|
||
|
|
||
|
|
||
|
def send_process_output(
|
||
|
process: ProcessWrapper, msg_queue: message_queue.MessageQueue
|
||
|
):
|
||
|
# "[07:36:28] [Server thread/INFO] [minecraft/DedicatedServer]: <khr_> test"
|
||
|
prog = re.compile(r"\[.*\] \[(.*)\] \[(.*)\]: <(.*)> (.*)")
|
||
|
for line in process:
|
||
|
LOG.info(line.rstrip("\n"))
|
||
|
result = prog.search(line)
|
||
|
if result:
|
||
|
LOG.info("user: {} msg: {}".format(
|
||
|
result.group(3),
|
||
|
result.group(4).rstrip("\n"),
|
||
|
))
|
||
|
msg_queue.add(
|
||
|
{
|
||
|
"user": result.group(3),
|
||
|
"msg": result.group(4).rstrip("\n"),
|
||
|
},
|
||
|
)
|
||
|
|
||
|
|
||
|
def relay_queue_input(
|
||
|
process: ProcessWrapper, msg_queue: message_queue.MessageQueue
|
||
|
):
|
||
|
for message in msg_queue:
|
||
|
if "command" in message:
|
||
|
process.send(message["command"])
|
||
|
else:
|
||
|
LOG.debug(message)
|
||
|
|
||
|
|
||
|
def main():
|
||
|
logging.basicConfig(level=logging.DEBUG)
|
||
|
parser = argparse.ArgumentParser()
|
||
|
parser.add_argument("--matrix_server")
|
||
|
parser.add_argument("--matrix_server_port", type=int, default=5001)
|
||
|
parser.add_argument("command", nargs=argparse.REMAINDER)
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
LOG.info("Running Minecraft Server Wrapper")
|
||
|
wrapper = ProcessWrapper(args.command)
|
||
|
queue = message_queue.MessageQueue(
|
||
|
host=args.matrix_server,
|
||
|
port=args.matrix_server_port,
|
||
|
side=message_queue.Side.CLIENT,
|
||
|
)
|
||
|
send_worker = threading.Thread(
|
||
|
target=send_process_output,
|
||
|
args=(wrapper, queue),
|
||
|
daemon=True,
|
||
|
)
|
||
|
receive_worker = threading.Thread(
|
||
|
target=relay_queue_input,
|
||
|
args=(wrapper, queue),
|
||
|
daemon=True,
|
||
|
)
|
||
|
send_worker.start()
|
||
|
receive_worker.start()
|
||
|
LOG.info("All threads created")
|
||
|
send_worker.join()
|
||
|
receive_worker.join()
|
||
|
queue.close()
|
||
|
LOG.info("All threads terminated")
|
||
|
return wrapper.wait()
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|