feat: now possible to load and save data through redis "messages"
This commit is contained in:
parent
5ccbd3d8e4
commit
73abc7a981
|
@ -27,6 +27,7 @@ from settings import (
|
|||
REDIS_PORT,
|
||||
RTMP_STREAM_URI,
|
||||
)
|
||||
from utils import States
|
||||
|
||||
core = mgba.core.load_path(EMULATOR_ROM_PATH)
|
||||
screen = mgba.image.Image(EMULATOR_WIDTH, EMULATOR_HEIGHT)
|
||||
|
@ -37,6 +38,8 @@ logging.basicConfig(level=logging.DEBUG)
|
|||
mgba.log.silence()
|
||||
r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0)
|
||||
|
||||
states: States = States()
|
||||
|
||||
|
||||
def next_action():
|
||||
"""Select the next key from the redis database.
|
||||
|
@ -94,12 +97,13 @@ def state_manager(loop):
|
|||
ps.subscribe("admin")
|
||||
while True:
|
||||
for message in ps.listen():
|
||||
print(message)
|
||||
asyncio.ensure_future(save(), loop=loop)
|
||||
|
||||
|
||||
async def save():
|
||||
print("saving")
|
||||
logging.debug(message)
|
||||
if message["type"] == "message":
|
||||
data = message["data"].decode("utf-8")
|
||||
if data == "save":
|
||||
asyncio.ensure_future(states.save(core), loop=loop)
|
||||
elif data.startswith("load:"):
|
||||
asyncio.ensure_future(states.load(core, data.removeprefix("load:")), loop=loop)
|
||||
|
||||
|
||||
async def emulator():
|
||||
|
@ -129,7 +133,6 @@ async def main(loop):
|
|||
|
||||
task_emulator = loop.create_task(emulator())
|
||||
await task_emulator
|
||||
thread.join()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -61,7 +61,6 @@ async def parse_message(user: User, message: dict[str, str]) -> None:
|
|||
elif data in KEYS_ID:
|
||||
r.incr(data)
|
||||
user.last_message = time.time()
|
||||
user.has_voted = True
|
||||
else:
|
||||
logging.error(f"unsupported action: {data}")
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ FFMPEG_BITRATE: str = getenv("FFMPEG_BIRATE", "2M")
|
|||
|
||||
PASSWORD_ADMIN: str = getenv("PASSWORD_ADMIN", "password_admin")
|
||||
|
||||
USER_TIMEOUT: float = 0.5
|
||||
USER_TIMEOUT: float = float(getenv("USER_TIMEOUT", 0.5))
|
||||
|
||||
KEYMAP: dict[str, int] = {
|
||||
"a": 0,
|
||||
|
|
42
src/utils.py
42
src/utils.py
|
@ -1,15 +1,17 @@
|
|||
import logging
|
||||
import os
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Optional
|
||||
|
||||
from mgba._pylib import ffi
|
||||
|
||||
|
||||
class User:
|
||||
"""Store infos related to a connected user."""
|
||||
|
||||
websocket: Any
|
||||
last_message: float
|
||||
has_voted: bool
|
||||
|
||||
def __init__(self, websocket: Any) -> None:
|
||||
"""Construct a User object.
|
||||
|
@ -19,7 +21,6 @@ class User:
|
|||
"""
|
||||
self.websocket = websocket
|
||||
self.last_message = time.time()
|
||||
self.has_voted = False
|
||||
|
||||
async def send(self, data: str):
|
||||
"""Send data through the user's websocket.
|
||||
|
@ -42,7 +43,6 @@ class User:
|
|||
class Users(set):
|
||||
"""Store `User`s connected to the server."""
|
||||
|
||||
emulator: Optional[User] = None
|
||||
admin: Optional[User] = None
|
||||
|
||||
def register(self, user: User):
|
||||
|
@ -63,22 +63,26 @@ class Users(set):
|
|||
self.remove(user)
|
||||
logging.debug(f"user unregistered: {self}")
|
||||
|
||||
def clear(self) -> None:
|
||||
"""Clear the `has_voted` of each user in the set."""
|
||||
for user in self:
|
||||
user.has_voted = False
|
||||
|
||||
class States(set):
|
||||
"""Save and load states from files."""
|
||||
|
||||
# class States(set):
|
||||
# def save(self, core):
|
||||
# state = core.save_raw_state()
|
||||
# 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))
|
||||
def __init__(self) -> None:
|
||||
"""Construct a `States` object."""
|
||||
files = os.listdir("states")
|
||||
states = list(filter(lambda x: x.endswith(".state"), files))
|
||||
self.update(states)
|
||||
|
||||
# def load(self, core, state):
|
||||
# state = ffi.new("unsigned char[397312]")
|
||||
# with open("states/test.state", "rb") as state_file:
|
||||
# for i in range(len(state)):
|
||||
# state[i] = int.from_bytes(state_file.read(4), byteorder="big", signed=False)
|
||||
# core.load_raw_state(state)
|
||||
async def save(self, core):
|
||||
state = core.save_raw_state()
|
||||
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))
|
||||
self.add(state)
|
||||
|
||||
async def load(self, core, filename):
|
||||
state = ffi.new("unsigned char[397312]") # pulled 397312 from my ass
|
||||
with open(f"states/{filename}.state", "rb") as state_file:
|
||||
for i in range(len(state)):
|
||||
state[i] = int.from_bytes(state_file.read(4), byteorder="big", signed=False)
|
||||
core.load_raw_state(state)
|
||||
|
|
Loading…
Reference in a new issue