diff --git a/README.md b/README.md index 0ff2486..fa775ab 100644 --- a/README.md +++ b/README.md @@ -19,12 +19,16 @@ pip install --user git+https://github.com/christofsteel/pyautosplit.git ## Usage +### LiveSplit First you should start LiveSplit, and start the LiveSplit server component. After that you can launch PyAutoSplit with ``` pyautosplit routefile.json ``` +### LiveSplit One +Start PyAutoSplit with `--livesplitone` and it'll tell you the address LiveSplit One can connect to. + ## Configuration To use PyAutoSplit for a game, you have to have it installed and two files. One specific for the game you are playing and one specific for your route. In this repository, there is an example for the game VVVVVV and a route for glitchless 100%. diff --git a/pyautosplit/callbacks.py b/pyautosplit/callbacks.py index a9dacbb..4778703 100644 --- a/pyautosplit/callbacks.py +++ b/pyautosplit/callbacks.py @@ -2,6 +2,12 @@ import time import socket from copy import deepcopy +from flask import Flask +from flask_sockets import Sockets +from gevent import monkey +from gevent import pywsgi +from geventwebsocket.handler import WebSocketHandler +from threading import Thread from simpleeval import simple_eval @@ -125,7 +131,6 @@ def start(self): class LiveSplitServer(CallbackHandler): - def __init__(self, host="localhost", port=16834): super().__init__() self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -150,3 +155,57 @@ def update_time(self): def split(self, split): self.socket.send(b"split\r\n") + + +class LiveSplitOne(CallbackHandler): + def __init__(self, port=5000): + super().__init__() + + monkey.patch_all() + + self.app = Flask(__name__) + self.app.config['SECRET_KEY'] = 'secret!' + self.sockets = Sockets(self.app) + self.ws_list = [] + + @self.sockets.route('/') + def echo_socket(ws): + self.ws_list.append(ws) + while not ws.closed: + message = ws.receive() + ws.send(message) + + self.server = pywsgi.WSGIServer( + ('', port), self.app, handler_class=WebSocketHandler) + + self.thread = Thread(target=self._start_server, daemon=True) + print(f"Connect LiveSplitOne to ws://localhost:{port}") + self.thread.start() + + def init(self, *args, **kwargs): + super().init(*args, **kwargs) + + def reset(self): + self._send_command("reset") + + def start(self): + self._send_command("start") + + def split(self, split): + self._send_command("split") + + def pause(self): + self._send_command("togglepause") + + def resume(self): + self._send_command("togglepause") + + def _send_command(self, name): + for ws in self.ws_list: + if not ws.closed: + ws.send(name) + else: + self.ws_list.remove(ws) + + def _start_server(self): + self.server.start() diff --git a/pyautosplit/main.py b/pyautosplit/main.py index 41e1192..ed782ae 100644 --- a/pyautosplit/main.py +++ b/pyautosplit/main.py @@ -4,12 +4,13 @@ from collections import OrderedDict from .game import Game -from .callbacks import ConsoleOut, LiveSplitServer +from .callbacks import ConsoleOut, LiveSplitServer, LiveSplitOne def main(): parser = ArgumentParser() parser.add_argument("--no-livesplit", "-L", action="store_true") + parser.add_argument("--livesplitone", "-O", action="store_true") parser.add_argument("--console-out", "-c", action="store_true") parser.add_argument("--livesplit-port", "-p", type=int, default=16834) parser.add_argument("--livesplit-host", "-H", default="localhost") @@ -32,10 +33,14 @@ def main(): callback_handlers = [] if not args.no_livesplit: - callback_handlers.append( - LiveSplitServer( - args.livesplit_host, - args.livesplit_port)) + if args.livesplitone: + callback_handlers.append( + LiveSplitOne(args.livesplit_port)) + else: + callback_handlers.append( + LiveSplitServer( + args.livesplit_host, + args.livesplit_port)) if args.console_out: callback_handlers.append(ConsoleOut()) diff --git a/setup.py b/setup.py index 9a70a2b..6b51a04 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ description="A python autosplit module for linux and the livesplit server module", url="https://github.com/christofsteel/pyautosplit.git", packages=setuptools.find_packages(), - install_requires=["python-ptrace", "simpleeval"], + install_requires=["flask-sockets", "python-ptrace", "simpleeval"], classifiers=[ "Development Status :: 4 - Beta", "Programming Language :: Python :: 3", @@ -19,7 +19,7 @@ "Topic :: Software Development :: Debuggers", ], python_requires='>=3.7', - entry_points = { + entry_points={ 'console_scripts': ['pyautosplit=pyautosplit.main:main'] } )