feat: now possible to load and save data through redis "messages"

This commit is contained in:
Laureηt 2021-11-14 22:07:47 +01:00
parent 5ccbd3d8e4
commit 73abc7a981
No known key found for this signature in database
GPG key ID: D88C6B294FD40994
4 changed files with 34 additions and 28 deletions

View file

@ -27,6 +27,7 @@ from settings import (
REDIS_PORT, REDIS_PORT,
RTMP_STREAM_URI, RTMP_STREAM_URI,
) )
from utils import States
core = mgba.core.load_path(EMULATOR_ROM_PATH) core = mgba.core.load_path(EMULATOR_ROM_PATH)
screen = mgba.image.Image(EMULATOR_WIDTH, EMULATOR_HEIGHT) screen = mgba.image.Image(EMULATOR_WIDTH, EMULATOR_HEIGHT)
@ -37,6 +38,8 @@ logging.basicConfig(level=logging.DEBUG)
mgba.log.silence() mgba.log.silence()
r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0) r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0)
states: States = States()
def next_action(): def next_action():
"""Select the next key from the redis database. """Select the next key from the redis database.
@ -94,12 +97,13 @@ def state_manager(loop):
ps.subscribe("admin") ps.subscribe("admin")
while True: while True:
for message in ps.listen(): for message in ps.listen():
print(message) logging.debug(message)
asyncio.ensure_future(save(), loop=loop) if message["type"] == "message":
data = message["data"].decode("utf-8")
if data == "save":
async def save(): asyncio.ensure_future(states.save(core), loop=loop)
print("saving") elif data.startswith("load:"):
asyncio.ensure_future(states.load(core, data.removeprefix("load:")), loop=loop)
async def emulator(): async def emulator():
@ -129,7 +133,6 @@ async def main(loop):
task_emulator = loop.create_task(emulator()) task_emulator = loop.create_task(emulator())
await task_emulator await task_emulator
thread.join()
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -61,7 +61,6 @@ async def parse_message(user: User, message: dict[str, str]) -> None:
elif data in KEYS_ID: elif data in KEYS_ID:
r.incr(data) r.incr(data)
user.last_message = time.time() user.last_message = time.time()
user.has_voted = True
else: else:
logging.error(f"unsupported action: {data}") logging.error(f"unsupported action: {data}")

View file

@ -30,7 +30,7 @@ FFMPEG_BITRATE: str = getenv("FFMPEG_BIRATE", "2M")
PASSWORD_ADMIN: str = getenv("PASSWORD_ADMIN", "password_admin") 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] = { KEYMAP: dict[str, int] = {
"a": 0, "a": 0,

View file

@ -1,15 +1,17 @@
import logging import logging
import os
import time import time
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Optional from typing import Any, Optional
from mgba._pylib import ffi
class User: class User:
"""Store infos related to a connected user.""" """Store infos related to a connected user."""
websocket: Any websocket: Any
last_message: float last_message: float
has_voted: bool
def __init__(self, websocket: Any) -> None: def __init__(self, websocket: Any) -> None:
"""Construct a User object. """Construct a User object.
@ -19,7 +21,6 @@ class User:
""" """
self.websocket = websocket self.websocket = websocket
self.last_message = time.time() self.last_message = time.time()
self.has_voted = False
async def send(self, data: str): async def send(self, data: str):
"""Send data through the user's websocket. """Send data through the user's websocket.
@ -42,7 +43,6 @@ class User:
class Users(set): class Users(set):
"""Store `User`s connected to the server.""" """Store `User`s connected to the server."""
emulator: Optional[User] = None
admin: Optional[User] = None admin: Optional[User] = None
def register(self, user: User): def register(self, user: User):
@ -63,22 +63,26 @@ class Users(set):
self.remove(user) self.remove(user)
logging.debug(f"user unregistered: {self}") 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 __init__(self) -> None:
# def save(self, core): """Construct a `States` object."""
# state = core.save_raw_state() files = os.listdir("states")
# with open(f"states/{time.strftime('%Y-%m-%dT%H:%M:%S')}.state", "wb") as state_file: states = list(filter(lambda x: x.endswith(".state"), files))
# for byte in state: self.update(states)
# state_file.write(byte.to_bytes(4, byteorder="big", signed=False))
# def load(self, core, state): async def save(self, core):
# state = ffi.new("unsigned char[397312]") state = core.save_raw_state()
# with open("states/test.state", "rb") as state_file: with open(f"states/{time.strftime('%Y-%m-%dT%H:%M:%S')}.state", "wb") as state_file:
# for i in range(len(state)): for byte in state:
# state[i] = int.from_bytes(state_file.read(4), byteorder="big", signed=False) state_file.write(byte.to_bytes(4, byteorder="big", signed=False))
# core.load_raw_state(state) 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)