diff --git a/src/admin.html b/src/admin.html new file mode 100644 index 0000000..d18ef0b --- /dev/null +++ b/src/admin.html @@ -0,0 +1,79 @@ + + + + + Admin + + + + + + + +
+ + +
+ +
+ + +
+ + + + + diff --git a/src/emulator.py b/src/emulator.py index af41c08..debde8d 100644 --- a/src/emulator.py +++ b/src/emulator.py @@ -1,6 +1,7 @@ import asyncio import json import logging +import time import mgba.core import mgba.image @@ -10,8 +11,8 @@ import pyvirtualcam import websockets from mgba._pylib import ffi -WIDTH = 240 -HEIGHT = 160 +WIDTH: int = 240 +HEIGHT: int = 160 URI: str = "ws://127.0.0.1:6789/" FPS: int = 60 HZ: int = 10 @@ -36,7 +37,7 @@ core.set_video_buffer(screen) core.reset() mgba.log.silence() -logging.basicConfig(level=logging.DEBUG) +# logging.basicConfig(level=logging.DEBUG) def parse_message(message: dict[str, str]): @@ -60,7 +61,7 @@ def parse_message(message: dict[str, str]): data = message["admin"] if data == "save": # voodoo magic incomming state = core.save_raw_state() - with open("states/test.state", "wb") as state_file: + with open(f"states/{time.strftime('%Y-%m-%dT%H:%M:%S')}.state", "wb") as state_file: for byte in state: state_file.write(byte.to_bytes(4, byteorder="big", signed=False)) elif data == "load": # black magic incomming @@ -78,7 +79,7 @@ async def main(): with pyvirtualcam.Camera(width=WIDTH, height=HEIGHT, fps=FPS) as cam: logging.debug(f"Using virtual camera: {cam.device}") async with websockets.connect(URI) as websocket: - await websocket.send('{"auth":"password"}') + await websocket.send('{"auth":"emulator_password"}') logging.debug(f"connected to: {websocket}") while True: diff --git a/src/server.py b/src/server.py index 593291f..04cb30a 100644 --- a/src/server.py +++ b/src/server.py @@ -1,6 +1,7 @@ import asyncio import json import logging +import os import time from typing import Any @@ -8,15 +9,22 @@ import websockets from utils import User, Users, Votes -logging.basicConfig(level=logging.DEBUG) +# logging.basicConfig(level=logging.DEBUG) -PASSWORD_ADMIN: str = "password" -PASSWORD_EMU: str = "password" +PASSWORD_ADMIN: str = "admin_password" +PASSWORD_EMU: str = "emulator_password" VOTES: Votes = Votes() USERS: Users = Users() -async def parse_message(user: User, message: dict[str, str]): +async def send_states(user: User) -> None: + files = os.listdir("states") + states = list(filter(lambda x: x.endswith(".state"), files)) + message = json.dumps({"state": states}) + await user.send(message) + + +async def parse_message(user: User, message: dict[str, str]) -> None: """Parse the user's message. Args: @@ -25,12 +33,14 @@ async def parse_message(user: User, message: dict[str, str]): """ if "auth" in message: data = message["auth"] - if USERS.emulator is None and data == PASSWORD_EMU: + if USERS.emulator is None and data == PASSWORD_EMU and user != USERS.admin: USERS.emulator = user logging.debug(f"emulator authenticated: {user}") - elif USERS.admin is None and data == PASSWORD_ADMIN: + await user.send('{"auth":"success"}') + elif USERS.admin is None and data == PASSWORD_ADMIN and user != USERS.emulator: USERS.admin = user logging.debug(f"admin authenticated: {user}") + await user.send('{"auth":"success"}') if "action" in message: data = message["action"] @@ -65,6 +75,16 @@ async def parse_message(user: User, message: dict[str, str]): else: logging.error(f"user is not emulator: {user}") + if "state" in message: + data = message["state"] + if user == USERS.admin: + if data == "get": + await send_states(user) + else: + logging.error(f"unsupported state action: {data}") + else: + logging.error(f"user is not admin: {user}") + async def handler(websocket: Any, path: str): """Handle the messages sent by a user. @@ -84,6 +104,12 @@ async def handler(websocket: Any, path: str): finally: # Unregister user USERS.unregister(user) + if user == USERS.admin: + USERS.admin = None + logging.debug(f"admin disconnected: {user}") + elif user == USERS.emulator: + logging.debug(f"emulator disconnected: {user}") + USERS.emulator = None async def main():