From 46526f8a13f9f8ca27ab103e6b607ed67528a7ba Mon Sep 17 00:00:00 2001 From: drmext <71258889+drmext@users.noreply.github.com> Date: Sun, 27 Sep 2026 18:25:42 +0000 Subject: [PATCH] Fix --- README.md | 4 - config.py | 1 + core_common.py | 312 ++++++++++++++++--------- modules/__init__.py | 82 ++----- modules/core/apsmanager.py | 15 +- modules/core/cardmng.py | 62 ++--- modules/core/dlstatus.py | 24 +- modules/core/eacoin.py | 60 ++--- modules/core/facility.py | 19 +- modules/core/ins.py | 24 +- modules/core/message.py | 16 +- modules/core/package.py | 24 +- modules/core/package2.py | 15 +- modules/core/pcbevent.py | 15 +- modules/core/pcbtracker.py | 16 +- modules/ddr/api.py | 118 ++++++---- modules/ddr/eventlog.py | 19 +- modules/ddr/eventlog_2.py | 19 +- modules/ddr/eventlog_3.py | 19 +- modules/ddr/playdata_3.py | 94 +++----- modules/ddr/playerdata.py | 53 ++--- modules/ddr/playerdata_2.py | 52 ++--- modules/ddr/system.py | 18 +- modules/ddr/system_2.py | 18 +- modules/ddr/system_3.py | 18 +- modules/ddr/tax.py | 36 ++- modules/ddr/wordcheck_3.py | 17 +- modules/drs/eventlog.py | 19 +- modules/drs/game.py | 92 +++----- modules/gitadora/api.py | 136 +++++++---- modules/gitadora/cardutil.py | 38 ++-- modules/gitadora/gameend.py | 25 +- modules/gitadora/gameinfo.py | 19 +- modules/gitadora/gametop.py | 26 +-- modules/gitadora/lobby.py | 19 +- modules/gitadora/playablemusic.py | 19 +- modules/gitadora/shopinfo.py | 16 +- modules/iidx/api.py | 136 ++++++----- modules/iidx/iidx29gamesystem.py | 17 +- modules/iidx/iidx29grade.py | 34 ++- modules/iidx/iidx29lobby.py | 62 ++--- modules/iidx/iidx29music.py | 64 ++---- modules/iidx/iidx29pc.py | 147 +++++------- modules/iidx/iidx29ranking.py | 17 +- modules/iidx/iidx29shop.py | 44 ++-- modules/iidx/iidx30gamesystem.py | 17 +- modules/iidx/iidx30grade.py | 34 ++- modules/iidx/iidx30lobby.py | 69 ++---- modules/iidx/iidx30music.py | 110 ++++----- modules/iidx/iidx30pc.py | 188 ++++++--------- modules/iidx/iidx30ranking.py | 17 +- modules/iidx/iidx30shop.py | 44 ++-- modules/iidx/iidx31gamesystem.py | 17 +- modules/iidx/iidx31grade.py | 34 ++- modules/iidx/iidx31lobby.py | 69 ++---- modules/iidx/iidx31music.py | 110 ++++----- modules/iidx/iidx31pc.py | 208 +++++++---------- modules/iidx/iidx31ranking.py | 17 +- modules/iidx/iidx31shop.py | 44 ++-- modules/iidx/iidx31streaming.py | 26 +-- modules/iidx/iidx32gamesystem.py | 17 +- modules/iidx/iidx32grade.py | 34 ++- modules/iidx/iidx32lobby.py | 69 ++---- modules/iidx/iidx32music.py | 119 ++++------ modules/iidx/iidx32pc.py | 208 +++++++---------- modules/iidx/iidx32ranking.py | 17 +- modules/iidx/iidx32shop.py | 44 ++-- modules/iidx/iidx32streaming.py | 26 +-- modules/iidx/iidx33gamesystem.py | 17 +- modules/iidx/iidx33grade.py | 34 ++- modules/iidx/iidx33lobby.py | 69 ++---- modules/iidx/iidx33music.py | 119 ++++------ modules/iidx/iidx33pc.py | 208 +++++++---------- modules/iidx/iidx33ranking.py | 17 +- modules/iidx/iidx33shop.py | 74 +++--- modules/iidx/iidx33streaming.py | 26 +-- modules/iidx/music.py | 62 ++--- modules/iidx/pc.py | 87 +++---- modules/iidx/ranking.py | 17 +- modules/iidx/shop.py | 44 ++-- modules/nostalgia/op3_common.py | 26 +-- modules/nostalgia/op3_player.py | 75 +++--- modules/registry.py | 274 ++++++++++++++++++++++ modules/sdvx/eventlog.py | 17 +- modules/sdvx/game.py | 198 ++++++---------- modules/webapi.py | 33 +++ pyeamu.py | 367 +++++++++++++++++------------- requirements.txt | 5 +- start.bat | 4 +- start.sh | 2 +- 90 files changed, 2444 insertions(+), 2969 deletions(-) create mode 100644 modules/registry.py create mode 100644 modules/webapi.py diff --git a/README.md b/README.md index 66e5058..03d97da 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,4 @@ Run [start.bat (Windows)](start.bat) or [start.sh (Linux, MacOS)](start.sh) - DRS, GD, NOST, and SDVX require mdb xml files copied to the server folder -- **URL Slash 1 (On)** [may still be required in rare cases](modules/__init__.py#L46) - -- **URL Slash 0 (Off)** may be required in other cases - - When initially creating a DDR profile, complete an entire credit without pfree hacks diff --git a/config.py b/config.py index d5d01ef..d63be04 100644 --- a/config.py +++ b/config.py @@ -18,6 +18,7 @@ ip = get_ip() port = 8000 response_compression = True verbose_log = False +dev_reload = False arcade = "M0NKYBUS1N3Z" paseli = 10000 diff --git a/core_common.py b/core_common.py index 4dd963d..52518e8 100644 --- a/core_common.py +++ b/core_common.py @@ -1,10 +1,11 @@ import config +import re import threading import time +from functools import partial -from fastapi import HTTPException -from lxml.builder import ElementMaker +from lxml.etree import Element, iselement, tostring from kbinxml import KBinXML @@ -14,30 +15,133 @@ from utils.lz77 import lz77_decode, lz77_encode # Skip LZ77 for tiny bodies that always expand under AVS framing overhead. LZ77_MIN_RAW_BYTES = 256 +# XML declaration charset aliases -> kbinxml / binary codec name (xrpc-go EncodingByName). +_ENCODING_ALIASES = { + "UTF-8": "UTF-8", + "UTF8": "UTF-8", + "SHIFT_JIS": "cp932", + "SHIFT-JIS": "cp932", + "SJIS": "cp932", + "CP932": "cp932", + "EUC-JP": "EUC_JP", + "EUC_JP": "EUC_JP", + "EUCJP": "EUC_JP", + "ISO-8859-1": "ISO-8859-1", + "ISO_8859-1": "ISO-8859-1", + "ASCII": "ASCII", +} -def _add_val_as_str(elm, val): - new_val = str(val) +# kbinxml codec -> AVS XML declaration / lxml tostring encoding name. +_XML_DECL_NAMES = { + "UTF-8": "UTF-8", + "cp932": "SHIFT_JIS", + "EUC_JP": "EUC-JP", + "ISO-8859-1": "ISO-8859-1", + "ASCII": "ASCII", +} - if elm is not None: - elm.text = new_val - - else: - return new_val +_XML_DECL_ENCODING_RE = re.compile( + br"""encoding\s*=\s*["']([^"']+)["']""", re.IGNORECASE +) -def _add_bool_as_str(elm, val): - return _add_val_as_str(elm, 1 if val else 0) +class EamuseError(Exception): + """Bad e-amuse request; caught by the bare ASGI app and turned into an HTTP status.""" + + __slots__ = ("status_code", "detail") + + def __init__(self, status_code: int = 400, detail: str | bytes = ""): + self.status_code = status_code + self.detail = detail + super().__init__(detail if detail else status_code) -def _add_list_as_str(elm, vals): - new_val = " ".join([str(val) for val in vals]) +def _normalize_xml_encoding(name: str | None) -> str: + """Map a declaration / alias to a kbinxml codec name; default UTF-8.""" + if not name: + return "UTF-8" + return _ENCODING_ALIASES.get(name.upper().replace(" ", ""), "UTF-8") - if elm is not None: - elm.text = new_val - elm.attrib["__count"] = str(len(vals)) - else: - return new_val +def _xml_decl_name(codec: str) -> str: + """AVS / lxml declaration name for a kbinxml codec.""" + return _XML_DECL_NAMES.get(codec, "UTF-8") + + +def _detect_text_xml_encoding(data: bytes) -> str: + """Read charset from ; default UTF-8.""" + head = data[:200] + m = _XML_DECL_ENCODING_RE.search(head) + if not m: + return "UTF-8" + try: + return _normalize_xml_encoding(m.group(1).decode("ascii", errors="ignore")) + except Exception: + return "UTF-8" + + +def _attr_str(val): + """Convert a keyword argument to an XML attribute string.""" + t = type(val) + if t is str: + return val + if t is bool: + return "1" if val else "0" + if t is int or t is float: + return str(val) + if t is list: + return " ".join(str(v) for v in val) + raise TypeError(f"bad attribute type: {t.__name__}({val!r})") + + +class _ElementFactory: + """Drop-in replacement for lxml.builder.ElementMaker with our typemap. + + Supports ``E.tag(...)`` and ``E("tag", ...)``. Hot tags are cached on the + instance after the first ``__getattr__`` so loops do not allocate a fresh + ``partial`` on every access. + """ + + __slots__ = ("__dict__",) + + def __call__(self, tag, *children, **attrib): + elem = Element(tag) + if attrib: + for k, v in attrib.items(): + elem.attrib[k] = _attr_str(v) + + for item in children: + t = type(item) + if t is str: + try: + last = elem[-1] + except IndexError: + elem.text = (elem.text or "") + item + else: + last.tail = (last.tail or "") + item + elif t is bool: + elem.text = "1" if item else "0" + elif t is int or t is float: + elem.text = str(item) + elif t is list: + elem.text = " ".join(str(v) for v in item) + elem.attrib["__count"] = str(len(item)) + elif iselement(item): + elem.append(item) + else: + raise TypeError(f"bad argument type: {t.__name__}({item!r})") + + return elem + + def __getattr__(self, tag): + if tag.startswith("_"): + raise AttributeError(tag) + fn = partial(self, tag) + setattr(self, tag, fn) + return fn + + +E = _ElementFactory() _AVS_DEFAULT_SEED = 0x41C64E6D @@ -75,110 +179,88 @@ def avs_prng_uint16(): def _parse_eamuse_info(header): - """Return (unix_bytes, prng_bytes) or raise HTTPException(400).""" + """Return (unix_bytes, prng_bytes) or raise EamuseError(400).""" parts = header.split("-") if len(parts) != 3 or parts[0] != "1": - raise HTTPException(status_code=400, detail="malformed X-Eamuse-Info") + raise EamuseError(400, "malformed X-Eamuse-Info") unix_hex, prng_hex = parts[1], parts[2] if len(unix_hex) != 8 or len(prng_hex) != 4: - raise HTTPException(status_code=400, detail="malformed X-Eamuse-Info") + raise EamuseError(400, "malformed X-Eamuse-Info") try: return bytes.fromhex(unix_hex), bytes.fromhex(prng_hex) except ValueError: - raise HTTPException(status_code=400, detail="malformed X-Eamuse-Info") from None + raise EamuseError(400, "malformed X-Eamuse-Info") from None -E = ElementMaker( - typemap={ - int: _add_val_as_str, - bool: _add_bool_as_str, - list: _add_list_as_str, - float: _add_val_as_str, - } +# (min_ext, version) newest-first; first match with ext >= min_ext wins. +_LDJ_VERSIONS = ( + (2025091700, 33), + (2024100900, 32), + (2023101800, 31), + (2022101700, 30), + (2021101300, 29), + # TODO: Consolidate IIDX modules to easily support versions 21-28 (probably never) + (2020102800, 28), + (2019101600, 27), + (2018110700, 26), + (2017122100, 25), + (2016102400, 24), + (2015111100, 23), + (2014091700, 22), + (2013100200, 21), + (2012010100, 20), +) + +_M32_VERSIONS = ( + (2024031300, 10), + (2022121400, 9), + (2021042100, 8), + (2019100200, 7), + (2018072700, 6), + # TODO: Support versions 1-5 (never) + (2017090600, 5), + (2017011800, 4), + (2015042100, 3), + (2014021400, 2), + (2013012400, 1), ) -async def core_get_game_version_from_software_version(software_version): +def _version_from_thresholds(ext, thresholds): + for min_ext, ver in thresholds: + if ext >= min_ext: + return ver + return 0 + + +def core_get_game_version_from_software_version(software_version): _, model, dest, spec, rev, ext = software_version ext = int(ext) if model == "LDJ": - if ext >= 2025091700: - return 33 - elif ext >= 2024100900: - return 32 - elif ext >= 2023101800: - return 31 - elif ext >= 2022101700: - return 30 - elif ext >= 2021101300: - return 29 - # TODO: Consolidate IIDX modules to easily support versions 21-28 (probably never) - elif ext >= 2020102800: - return 28 - elif ext >= 2019101600: - return 27 - elif ext >= 2018110700: - return 26 - elif ext >= 2017122100: - return 25 - elif ext >= 2016102400: - return 24 - elif ext >= 2015111100: - return 23 - elif ext >= 2014091700: - return 22 - elif ext >= 2013100200: - return 21 - elif ext >= 2012010100: - return 20 - elif model == "KDZ": + return _version_from_thresholds(ext, _LDJ_VERSIONS) + if model == "KDZ": return 19 - elif model == "JDZ": + if model == "JDZ": return 18 - - elif model == "M32": - if ext >= 2024031300: - return 10 - elif ext >= 2022121400: - return 9 - elif ext >= 2021042100: - return 8 - elif ext >= 2019100200: - return 7 - elif ext >= 2018072700: - return 6 - # TODO: Support versions 1-5 (never) - elif ext >= 2017090600: - return 5 - elif ext >= 2017011800: - return 4 - elif ext >= 2015042100: - return 3 - elif ext >= 2014021400: - return 2 - elif ext >= 2013012400: - return 1 - - elif model == "MDX": - if ext >= 2024061200 and ext not in (2024042069, 2025042069): # GF + if model == "M32": + return _version_from_thresholds(ext, _M32_VERSIONS) + if model == "MDX": + if ext >= 2024061200 and ext not in (2024042069, 2025042069): # GF return 20 if ext >= 2019022600: # ??? return 19 - - elif model == "KFC": + return 0 + if model == "KFC": if ext >= 2020090402: # ??? return 6 - - elif model == "REC": - return 1 - - # TODO: ??? - # elif model == "PAN": - # return 0 - - else: return 0 + if model == "REC": + return 1 + # TODO: ??? + # if model == "PAN": + # return 0 + return 0 async def core_process_request(request): @@ -186,11 +268,11 @@ async def core_process_request(request): data = await request.body() if not cl or not data: - raise HTTPException(status_code=400) + raise EamuseError(400) request.compress = request.headers.get("X-Compress", "none") # intentionally lowercase 'none' (NOT None) if request.compress not in ("none", "lz77"): - raise HTTPException(status_code=400, detail="unsupported X-Compress value") + raise EamuseError(400, "unsupported X-Compress value") if "X-Eamuse-Info" in request.headers: unix_bytes, prng_bytes = _parse_eamuse_info(request.headers.get("X-Eamuse-Info")) @@ -203,9 +285,14 @@ async def core_process_request(request): if request.compress == "lz77": xml_dec = lz77_decode(xml_dec) + # Signature byte distinguishes binary; KBinXML.__init__ peeks the same way once. + request.is_binxml = bool(xml_dec) and xml_dec[0] == 0xA0 xml = KBinXML(xml_dec, convert_illegal_things=True) root = xml.xml_doc - request.is_binxml = KBinXML.is_binary_xml(xml_dec) + if request.is_binxml: + request.xml_encoding = _normalize_xml_encoding(xml.encoding) + else: + request.xml_encoding = _detect_text_xml_encoding(xml_dec) xml_text = None if config.verbose_log: @@ -217,13 +304,17 @@ async def core_process_request(request): print("\033[94mREQUEST\033[0m:") print(f"X-Eamuse-Info: {eamuse_info}") print(f"X-Compress: {request.compress}") + print( + f"Encoding: {_xml_decl_name(request.xml_encoding)}" + f" ({'binary' if request.is_binxml else 'text'})" + ) print(xml_text) model_parts = (root.attrib["model"], *root.attrib["model"].split(":")) module = root[0].tag method = root[0].attrib["method"] if "method" in root[0].attrib else None command = root[0].attrib["command"] if "command" in root[0].attrib else None - game_version = await core_get_game_version_from_software_version(model_parts) + game_version = core_get_game_version_from_software_version(model_parts) return { "root": root, @@ -240,13 +331,20 @@ async def core_process_request(request): } -async def core_prepare_response(request, xml): +def core_prepare_response(request, xml): + enc = getattr(request, "xml_encoding", None) or "UTF-8" binxml = KBinXML(xml) if request.is_binxml: - xml_binary = binxml.to_binary() + xml_binary = binxml.to_binary(encoding=enc) else: - xml_binary = binxml.to_text().encode("utf-8") # TODO: Proper encoding + # Compact on the wire; verbose_log pretty-prints separately via to_text(). + xml_binary = tostring( + binxml.xml_doc, + encoding=_xml_decl_name(enc), + xml_declaration=True, + pretty_print=False, + ) response_headers = {"User-Agent": "EAMUSE.Httpac/1.0"} @@ -279,6 +377,10 @@ async def core_prepare_response(request, xml): print("\033[91mRESPONSE\033[0m:") print(f"X-Eamuse-Info: {response_headers.get('X-Eamuse-Info', 'none')}") print(f"X-Compress: {response_headers['X-Compress']}") + print( + f"Encoding: {_xml_decl_name(enc)}" + f" ({'binary' if request.is_binxml else 'text'})" + ) print(binxml.to_text()) return response, response_headers diff --git a/modules/__init__.py b/modules/__init__.py index 3d22bed..c0c1d94 100644 --- a/modules/__init__.py +++ b/modules/__init__.py @@ -1,71 +1,23 @@ -from importlib import util -from os import path -from glob import glob +import importlib +import pkgutil -from fastapi import APIRouter, Request -from typing import Optional +from . import registry # noqa: F401 -routers = [] -for module_path in [ - f - for f in glob(path.join(path.dirname(__file__), "**/*.py"), recursive=True) - if path.basename(f) != "__init__.py" -]: - spec = util.spec_from_file_location("", module_path) - module = util.module_from_spec(spec) - spec.loader.exec_module(module) +webui_routers = [] - router = getattr(module, "router", None) - if router is not None: - routers.append(router) +_SKIP = {"registry", "webapi"} - if path.basename(module_path) != "api.py": - for obj in dir(module): - globals()[obj] = module.__dict__[obj] +for modinfo in pkgutil.walk_packages(__path__, __name__ + "."): + short = modinfo.name.rsplit(".", 1)[-1] + if short in _SKIP or short.startswith("_"): + continue -router = APIRouter(tags=["slashless_forwarder"]) + module = importlib.import_module(modinfo.name) - -@router.post("/fwdr") -async def forward_slashless( - request: Request, - model: Optional[str] = None, - f: Optional[str] = None, - module: Optional[str] = None, - method: Optional[str] = None, -): - if f != None: - module, method = f.split(".") - - try: - find_response = globals()[f"{module}_{method}".lower()] - return await find_response(request) - except KeyError: - try: - game_code = model.split(":")[0] - # TODO: check for more edge cases - if game_code == "MDX" and module.startswith("eventlo"): - find_response = globals()[f"ddr_{module}_{method}"] - elif game_code == "REC": - find_response = globals()[f"drs_{module}_{method}"] - elif game_code == "KFC": - if module == "eventlog": - find_response = globals()[f"sdvx_{module}_{method}"] - else: - sdvx_ver = "".join(filter(str.isdigit, method)) - find_response = globals()[f"{module}_{"".join([i for i in method if not i.isdigit()])}"] - return await find_response(sdvx_ver, request) - elif game_code == "M32": - if module == "lobby": - find_response = globals()[f"gitadora_{module}_{method}"] - else: - gd_module = module.split("_") - find_response = globals()[f"gitadora_{gd_module[-1]}_{method}"] - return await find_response(gd_module[0], request) - return await find_response(request) - except (KeyError, UnboundLocalError): - print("Try URL Slash 1 (On) if this game is supported.") - return Response(status_code=404) - - -routers.append(router) + if short == "api": + api_router = getattr(module, "router", None) + if api_router is not None: + pkg = modinfo.name.split(".")[-2] # modules.ddr.api -> ddr + mount = {"ddr": "/ddr", "iidx": "/iidx", "gitadora": "/gfdm"}.get(pkg) + if mount: + webui_routers.append((mount, api_router)) diff --git a/modules/core/apsmanager.py b/modules/core/apsmanager.py index 812bd7a..8eecf8a 100644 --- a/modules/core/apsmanager.py +++ b/modules/core/apsmanager.py @@ -1,15 +1,12 @@ -from fastapi import APIRouter, Request, Response +from modules.registry import Ctx, set_xrpc_defaults, xrpc -from core_common import core_process_request, core_prepare_response, E +from core_common import E -router = APIRouter(prefix="/core", tags=["apsmanager"]) +set_xrpc_defaults(service="apsmanager") - -@router.post("/{gameinfo}/apsmanager/getstat") -async def apsmanager_getstat(request: Request): - request_info = await core_process_request(request) +@xrpc("apsmanager/getstat") +async def apsmanager_getstat(ctx: Ctx): response = E.response(E.apsmanager(expire=600)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/core/cardmng.py b/modules/core/cardmng.py index 7090d7b..d43fa39 100644 --- a/modules/core/cardmng.py +++ b/modules/core/cardmng.py @@ -1,11 +1,10 @@ -from fastapi import APIRouter, Request, Response +from modules.registry import Ctx, set_xrpc_defaults, xrpc from tinydb import Query, where -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/core", tags=["cardmng"]) - +set_xrpc_defaults(service="cardmng") def get_target_table(game_id): target_table = { @@ -21,7 +20,6 @@ def get_target_table(game_id): return target_table[game_id] - def get_profile(game_id, cid): target_table = get_target_table(game_id) profile = get_db().table(target_table).get(where("card") == cid) @@ -34,7 +32,6 @@ def get_profile(game_id, cid): return profile - def get_game_profile(game_id, game_version, cid): profile = get_profile(game_id, cid) @@ -43,7 +40,6 @@ def get_game_profile(game_id, game_version, cid): return profile["version"][str(game_version)] - def create_profile(game_id, game_version, cid, pin): target_table = get_target_table(game_id) profile = get_profile(game_id, cid) @@ -52,15 +48,13 @@ def create_profile(game_id, game_version, cid, pin): get_db().table(target_table).upsert(profile, where("card") == cid) +@xrpc("cardmng/authpass") +async def cardmng_authpass(ctx: Ctx): -@router.post("/{gameinfo}/cardmng/authpass") -async def cardmng_authpass(request: Request): - request_info = await core_process_request(request) + cid = ctx.info["root"][0].attrib["refid"] + passwd = ctx.info["root"][0].attrib["pass"] - cid = request_info["root"][0].attrib["refid"] - passwd = request_info["root"][0].attrib["pass"] - - target_table = get_target_table(request_info["model"]) + target_table = get_target_table(ctx.info["model"]) profile = get_db().table(target_table).get(where("card") == cid) if profile is None or passwd != profile.get("pin", None): status = 116 @@ -69,28 +63,22 @@ async def cardmng_authpass(request: Request): response = E.response(E.authpass(status=status)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/cardmng/bindmodel") -async def cardmng_bindmodel(request: Request): - request_info = await core_process_request(request) +@xrpc("cardmng/bindmodel") +async def cardmng_bindmodel(ctx: Ctx): response = E.response(E.bindmodel(dataid=1)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("cardmng/getrefid") +async def cardmng_getrefid(ctx: Ctx): -@router.post("/{gameinfo}/cardmng/getrefid") -async def cardmng_getrefid(request: Request): - request_info = await core_process_request(request) + cid = ctx.info["root"][0].attrib["cardid"] + passwd = ctx.info["root"][0].attrib["passwd"] - cid = request_info["root"][0].attrib["cardid"] - passwd = request_info["root"][0].attrib["passwd"] - - create_profile(request_info["model"], request_info["game_version"], cid, passwd) + create_profile(ctx.info["model"], ctx.info["game_version"], cid, passwd) response = E.response( E.getrefid( @@ -99,17 +87,14 @@ async def cardmng_getrefid(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("cardmng/inquire") +async def cardmng_inquire(ctx: Ctx): -@router.post("/{gameinfo}/cardmng/inquire") -async def cardmng_inquire(request: Request): - request_info = await core_process_request(request) + cid = ctx.info["root"][0].attrib["cardid"] - cid = request_info["root"][0].attrib["cardid"] - - profile = get_game_profile(request_info["model"], request_info["game_version"], cid) + profile = get_game_profile(ctx.info["model"], ctx.info["game_version"], cid) if profile: binded = 1 newflag = 0 @@ -131,5 +116,4 @@ async def cardmng_inquire(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/core/dlstatus.py b/modules/core/dlstatus.py index db92a4c..968c346 100644 --- a/modules/core/dlstatus.py +++ b/modules/core/dlstatus.py @@ -1,25 +1,19 @@ -from fastapi import APIRouter, Request, Response +from modules.registry import Ctx, set_xrpc_defaults, xrpc -from core_common import core_process_request, core_prepare_response, E +from core_common import E -router = APIRouter(prefix="/core", tags=["dlstatus"]) +set_xrpc_defaults(service="dlstatus") - -@router.post("/{gameinfo}/dlstatus/done") -async def dlstatus_done(request: Request): - request_info = await core_process_request(request) +@xrpc("dlstatus/done") +async def dlstatus_done(ctx: Ctx): response = E.response(E.dlstatus(status=0)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/dlstatus/progress") -async def dlstatus_progress(request: Request): - request_info = await core_process_request(request) +@xrpc("dlstatus/progress") +async def dlstatus_progress(ctx: Ctx): response = E.response(E.dlstatus(status=0)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/core/eacoin.py b/modules/core/eacoin.py index d2ca8d6..c6064ac 100644 --- a/modules/core/eacoin.py +++ b/modules/core/eacoin.py @@ -1,21 +1,20 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response from tinydb import where -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/core", tags=["eacoin"]) - sessid = 0 payments = {} -@router.post("/{gameinfo}/eacoin/checkin") -async def eacoin_checkin(request: Request): - request_info = await core_process_request(request) - pcbid = request_info["root"].attrib["srcid"] - cardid = request_info["root"][0].find("cardid").text +set_xrpc_defaults(service="eacoin") + +@xrpc("eacoin/checkin") +async def eacoin_checkin(ctx: Ctx): + pcbid = ctx.info["root"].attrib["srcid"] + cardid = ctx.info["root"][0].find("cardid").text op = get_db().table("shop").get(where("pcbid") == pcbid) op = {} if op is None else op @@ -39,31 +38,25 @@ async def eacoin_checkin(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/eacoin/checkout") -async def eacoin_checkout(request: Request): - request_info = await core_process_request(request) +@xrpc("eacoin/checkout") +async def eacoin_checkout(ctx: Ctx): response = E.response(E.eacoin()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/eacoin/consume") -async def eacoin_consume(request: Request): - request_info = await core_process_request(request) - sessid = int(request_info["root"][0].find("sessid").text) - payment = int(request_info["root"][0].find("payment").text) +@xrpc("eacoin/consume") +async def eacoin_consume(ctx: Ctx): + sessid = int(ctx.info["root"][0].find("sessid").text) + payment = int(ctx.info["root"][0].find("payment").text) cardid = payments.get(sessid, None) # fallback if server is restarted mid-round for IIDX movie or gacha purchases - if cardid == None: - response = E.response( + if cardid is None: + return E.response( E.eacoin( E.acstatus(0, __type="u8"), E.autocharge(0, __type="u8"), @@ -71,11 +64,8 @@ async def eacoin_consume(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) - bal = get_db().table("paseli").get(where("cardid") == cardid) - if bal == None: + if bal is None: bal = { "cardid": cardid, "balance": config.paseli, @@ -105,13 +95,10 @@ async def eacoin_consume(request: Request): # del payments[sessid] - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/eacoin/getbalance") -async def eacoin_getbalance(request: Request): - request_info = await core_process_request(request) +@xrpc("eacoin/getbalance") +async def eacoin_getbalance(ctx: Ctx): response = E.response( E.eacoin( @@ -120,5 +107,4 @@ async def eacoin_getbalance(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/core/facility.py b/modules/core/facility.py index 8bc381d..4f475c2 100644 --- a/modules/core/facility.py +++ b/modules/core/facility.py @@ -1,18 +1,16 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response from tinydb import where -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/core", tags=["facility"]) +set_xrpc_defaults(service="facility") - -@router.post("/{gameinfo}/facility/get") -async def facility_get(request: Request): - request_info = await core_process_request(request) - pcbid = request_info["root"].attrib["srcid"] +@xrpc("facility/get") +async def facility_get(ctx: Ctx): + pcbid = ctx.info["root"].attrib["srcid"] op = get_db().table("shop").get(where("pcbid") == pcbid) op = {} if op is None else op @@ -42,7 +40,7 @@ async def facility_get(request: Request): E("id", 3, __type="str"), ), E.portfw( - E.globalip(request.client.host, __type="ip4"), + E.globalip(ctx.request.client.host, __type="ip4"), E.globalport(5700, __type="u16"), E.privateport(5700, __type="u16"), ), @@ -73,5 +71,4 @@ async def facility_get(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/core/ins.py b/modules/core/ins.py index 697233d..f0d8e82 100644 --- a/modules/core/ins.py +++ b/modules/core/ins.py @@ -1,25 +1,19 @@ -from fastapi import APIRouter, Request, Response +from modules.registry import Ctx, set_xrpc_defaults, xrpc -from core_common import core_process_request, core_prepare_response, E +from core_common import E -router = APIRouter(prefix="/core", tags=["ins"]) +set_xrpc_defaults(service="ins") - -@router.post("/{gameinfo}/ins/netlog") -async def ins_netlog(request: Request): - request_info = await core_process_request(request) +@xrpc("ins/netlog") +async def ins_netlog(ctx: Ctx): response = E.response(E.netlog(status=0)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/ins/send") -async def ins_send(request: Request): - request_info = await core_process_request(request) +@xrpc("ins/send") +async def ins_send(ctx: Ctx): response = E.response(E.netlog(status=0)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/core/message.py b/modules/core/message.py index b3b70a6..0ff58a9 100644 --- a/modules/core/message.py +++ b/modules/core/message.py @@ -1,15 +1,12 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="message") -router = APIRouter(prefix="/core", tags=["message"]) - - -@router.post("/{gameinfo}/message/get") -async def message_get(request: Request): - request_info = await core_process_request(request) +@xrpc("message/get") +async def message_get(ctx: Ctx): response = E.response( E.message( @@ -26,5 +23,4 @@ async def message_get(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/core/package.py b/modules/core/package.py index c24be9d..3c29065 100644 --- a/modules/core/package.py +++ b/modules/core/package.py @@ -1,25 +1,19 @@ -from fastapi import APIRouter, Request, Response +from modules.registry import Ctx, set_xrpc_defaults, xrpc -from core_common import core_process_request, core_prepare_response, E +from core_common import E -router = APIRouter(prefix="/core", tags=["package"]) +set_xrpc_defaults(service="package") - -@router.post("/{gameinfo}/package/list") -async def package_list(request: Request): - request_info = await core_process_request(request) +@xrpc("package/list") +async def package_list(ctx: Ctx): response = E.response(E.package(expire=1200, status=0)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/package/intend") -async def package_intend(request: Request): - request_info = await core_process_request(request) +@xrpc("package/intend") +async def package_intend(ctx: Ctx): response = E.response(E.package(status=0)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/core/package2.py b/modules/core/package2.py index 4ba8054..b0f1084 100644 --- a/modules/core/package2.py +++ b/modules/core/package2.py @@ -1,15 +1,12 @@ -from fastapi import APIRouter, Request, Response +from modules.registry import Ctx, set_xrpc_defaults, xrpc -from core_common import core_process_request, core_prepare_response, E +from core_common import E -router = APIRouter(prefix="/core", tags=["package2"]) +set_xrpc_defaults(service="package2") - -@router.post("/{gameinfo}/package2/list") -async def package2_list(request: Request): - request_info = await core_process_request(request) +@xrpc("package2/list") +async def package2_list(ctx: Ctx): response = E.response(E.package2(expire=1200, status=0)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/core/pcbevent.py b/modules/core/pcbevent.py index 3d47caf..e544ac4 100644 --- a/modules/core/pcbevent.py +++ b/modules/core/pcbevent.py @@ -1,15 +1,12 @@ -from fastapi import APIRouter, Request, Response +from modules.registry import Ctx, set_xrpc_defaults, xrpc -from core_common import core_process_request, core_prepare_response, E +from core_common import E -router = APIRouter(prefix="/core", tags=["pcbevent"]) +set_xrpc_defaults(service="pcbevent") - -@router.post("/{gameinfo}/pcbevent/put") -async def pcbevent_put(request: Request): - request_info = await core_process_request(request) +@xrpc("pcbevent/put") +async def pcbevent_put(ctx: Ctx): response = E.response(E.pcbevent(expire=600)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/core/pcbtracker.py b/modules/core/pcbtracker.py index 51f8cf9..dc86c5b 100644 --- a/modules/core/pcbtracker.py +++ b/modules/core/pcbtracker.py @@ -1,17 +1,14 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config from time import time -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="pcbtracker") -router = APIRouter(prefix="/core", tags=["pcbtracker"]) - - -@router.post("/{gameinfo}/pcbtracker/alive") -async def pcbtracker_alive(request: Request): - request_info = await core_process_request(request) +@xrpc("pcbtracker/alive") +async def pcbtracker_alive(ctx: Ctx): response = E.response( E.pcbtracker( @@ -24,5 +21,4 @@ async def pcbtracker_alive(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/ddr/api.py b/modules/ddr/api.py index 202d449..cabc9b9 100644 --- a/modules/ddr/api.py +++ b/modules/ddr/api.py @@ -1,23 +1,19 @@ -from fastapi import APIRouter, Request, Response, File, UploadFile - -from core_common import core_process_request, core_prepare_response, E - -from tinydb import Query, where -from core_database import get_db -from pydantic import BaseModel - -import config -import utils.card as conv -from utils.lz77 import lz77_decode - -import lxml.etree as ET -import json -import struct from typing import Optional, Dict, List, Tuple from os import path +import json +import struct +import lxml.etree as ET +from pydantic import BaseModel +from starlette.requests import Request +from starlette.responses import Response +from starlette.routing import Route, Router +from tinydb import where -router = APIRouter(prefix="/ddr", tags=["api_ddr"]) +import utils.card as conv +from core_database import get_db +from modules.webapi import endpoint, read_model +from utils.lz77 import lz77_decode class DDR_Profile_Main_Items(BaseModel): @@ -54,19 +50,23 @@ class DDR_Profile_20_Items(BaseModel): rival_3_ddr_id: Optional[int] customize: Optional[dict] -@router.get("/profiles") -async def ddr_profiles(): + +@endpoint +async def ddr_profiles(request: Request): return get_db().table("ddr_profile").all() -@router.get("/profiles/{ddr_id}") -async def ddr_profile_id(ddr_id: str): +@endpoint +async def ddr_profile_id(request: Request): + ddr_id = request.path_params["ddr_id"] ddr_id = int("".join([i for i in ddr_id if i.isnumeric()])) return get_db().table("ddr_profile").get(where("ddr_id") == ddr_id) -@router.patch("/profiles/{ddr_id}") -async def ddr_profile_id_patch(ddr_id: str, item: DDR_Profile_Main_Items): +@endpoint +async def ddr_profile_id_patch(request: Request): + ddr_id = request.path_params["ddr_id"] + item = await read_model(request, DDR_Profile_Main_Items) ddr_id = int("".join([i for i in ddr_id if i.isnumeric()])) profile = get_db().table("ddr_profile").get(where("ddr_id") == ddr_id) @@ -77,8 +77,10 @@ async def ddr_profile_id_patch(ddr_id: str, item: DDR_Profile_Main_Items): return Response(status_code=204) -@router.patch("/profiles/{ddr_id}/19") -async def ddr_profile_id_19_patch(ddr_id: str, item: DDR_Profile_19_Items): +@endpoint +async def ddr_profile_id_19_patch(request: Request): + ddr_id = request.path_params["ddr_id"] + item = await read_model(request, DDR_Profile_19_Items) ddr_id = int("".join([i for i in ddr_id if i.isnumeric()])) profile = get_db().table("ddr_profile").get(where("ddr_id") == ddr_id) game_profile = profile["version"].get("19", {}) @@ -104,8 +106,10 @@ async def ddr_profile_id_19_patch(ddr_id: str, item: DDR_Profile_19_Items): return Response(status_code=204) -@router.patch("/profiles/{ddr_id}/20") -async def ddr_profile_id_20_patch(ddr_id: str, item: DDR_Profile_20_Items): +@endpoint +async def ddr_profile_id_20_patch(request: Request): + ddr_id = request.path_params["ddr_id"] + item = await read_model(request, DDR_Profile_20_Items) ddr_id = int("".join([i for i in ddr_id if i.isnumeric()])) profile = get_db().table("ddr_profile").get(where("ddr_id") == ddr_id) game_profile = profile["version"].get("20", {}) @@ -123,8 +127,9 @@ async def ddr_profile_id_20_patch(ddr_id: str, item: DDR_Profile_20_Items): return Response(status_code=204) -@router.get("/card/{card}") -async def ddr_card_to_profile(card: str): +@endpoint +async def ddr_card_to_profile(request: Request): + card = request.path_params["card"] card = card.upper() lookalike = { "I": "1", @@ -137,44 +142,46 @@ async def ddr_card_to_profile(card: str): if card.startswith("E004") or card.startswith("012E"): card = "".join([c for c in card if c in "0123456789ABCDEF"]) uid = card - kid = conv.to_konami_id(card) else: card = "".join([c for c in card if c in conv.valid_characters]) uid = conv.to_uid(card) - kid = card profile = get_db().table("ddr_profile").get(where("card") == uid) return profile -@router.get("/scores") -async def ddr_scores(): +@endpoint +async def ddr_scores(request: Request): return get_db().table("ddr_scores").all() -@router.get("/scores/{ddr_id}") -async def ddr_scores_id(ddr_id: str): +@endpoint +async def ddr_scores_id(request: Request): + ddr_id = request.path_params["ddr_id"] ddr_id = int("".join([i for i in ddr_id if i.isnumeric()])) return get_db().table("ddr_scores").search((where("ddr_id") == ddr_id)) -@router.get("/scores_best") -async def ddr_scores_best(): +@endpoint +async def ddr_scores_best(request: Request): return get_db().table("ddr_scores_best").all() -@router.get("/scores_best/{ddr_id}") -async def ddr_scores_best_id(ddr_id: str): +@endpoint +async def ddr_scores_best_id(request: Request): + ddr_id = request.path_params["ddr_id"] ddr_id = int("".join([i for i in ddr_id if i.isnumeric()])) return get_db().table("ddr_scores_best").search((where("ddr_id") == ddr_id)) -@router.get("/mcode/{mcode}/all") -async def ddr_scores_id(mcode: int): +@endpoint +async def ddr_scores_mcode_all(request: Request): + mcode = int(request.path_params["mcode"]) return get_db().table("ddr_scores").search((where("mcode") == mcode)) -@router.get("/mcode/{mcode}/best") -async def ddr_scores_id_best(mcode: int): +@endpoint +async def ddr_scores_mcode_best(request: Request): + mcode = int(request.path_params["mcode"]) return get_db().table("ddr_scores_best").search((where("mcode") == mcode)) @@ -232,9 +239,11 @@ class ARC: ) -@router.post("/parse_mdb/upload") -async def ddr_receive_mdb(file: UploadFile = File(...)) -> bytes: - data = await file.read() +@endpoint +async def ddr_receive_mdb(request: Request): + form = await request.form() + upload = form["file"] + data = await upload.read() arc = ARC(data) try: mdb_new = ET.fromstring( @@ -287,3 +296,22 @@ async def ddr_receive_mdb(file: UploadFile = File(...)) -> bytes: json.dump(mdb, fp, indent=4, ensure_ascii=False) return Response(status_code=201) + + +router = Router( + routes=[ + Route("/profiles", ddr_profiles, methods=["GET"]), + Route("/profiles/{ddr_id}", ddr_profile_id, methods=["GET"]), + Route("/profiles/{ddr_id}", ddr_profile_id_patch, methods=["PATCH"]), + Route("/profiles/{ddr_id}/19", ddr_profile_id_19_patch, methods=["PATCH"]), + Route("/profiles/{ddr_id}/20", ddr_profile_id_20_patch, methods=["PATCH"]), + Route("/card/{card}", ddr_card_to_profile, methods=["GET"]), + Route("/scores", ddr_scores, methods=["GET"]), + Route("/scores/{ddr_id}", ddr_scores_id, methods=["GET"]), + Route("/scores_best", ddr_scores_best, methods=["GET"]), + Route("/scores_best/{ddr_id}", ddr_scores_best_id, methods=["GET"]), + Route("/mcode/{mcode}/all", ddr_scores_mcode_all, methods=["GET"]), + Route("/mcode/{mcode}/best", ddr_scores_mcode_best, methods=["GET"]), + Route("/parse_mdb/upload", ddr_receive_mdb, methods=["POST"]), + ] +) diff --git a/modules/ddr/eventlog.py b/modules/ddr/eventlog.py index c7f2e9a..30dbf30 100644 --- a/modules/ddr/eventlog.py +++ b/modules/ddr/eventlog.py @@ -1,25 +1,20 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["MDX"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["MDX"] - - -@router.post("/{gameinfo}/eventlog/write") -async def ddr_eventlog_write(request: Request): - request_info = await core_process_request(request) +@xrpc("eventlog/write") +async def ddr_eventlog_write(ctx: Ctx): response = E.response( E.eventlog( E.gamesession(9999999, __type="s64"), - E.logsendflg(0, __type="s32"), + E.logsendflg(1 if config.maintenance_mode else 0, __type="s32"), E.logerrlevel(0, __type="s32"), E.evtidnosendflg(0, __type="s32"), ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/ddr/eventlog_2.py b/modules/ddr/eventlog_2.py index 9a48a99..1b1b4ce 100644 --- a/modules/ddr/eventlog_2.py +++ b/modules/ddr/eventlog_2.py @@ -1,25 +1,20 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["MDX"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["MDX"] - - -@router.post("/{gameinfo}/eventlog_2/write") -async def ddr_eventlog_2_write(request: Request): - request_info = await core_process_request(request) +@xrpc("eventlog_2/write") +async def ddr_eventlog_2_write(ctx: Ctx): response = E.response( E.eventlog_2( E.gamesession(9999999, __type="s64"), - E.logsendflg(0, __type="s32"), + E.logsendflg(1 if config.maintenance_mode else 0, __type="s32"), E.logerrlevel(0, __type="s32"), E.evtidnosendflg(0, __type="s32"), ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/ddr/eventlog_3.py b/modules/ddr/eventlog_3.py index 1a792f7..2d01877 100644 --- a/modules/ddr/eventlog_3.py +++ b/modules/ddr/eventlog_3.py @@ -1,25 +1,20 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["MDX"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["MDX"] - - -@router.post("/{gameinfo}/eventlog_3/write") -async def ddr_eventlog_3_write(request: Request): - request_info = await core_process_request(request) +@xrpc("eventlog_3/write") +async def ddr_eventlog_3_write(ctx: Ctx): response = E.response( E.eventlog_3( E.gamesession(9999999, __type="s64"), - E.logsendflg(0, __type="s32"), + E.logsendflg(1 if config.maintenance_mode else 0, __type="s32"), E.logerrlevel(0, __type="s32"), E.evtidnosendflg(0, __type="s32"), ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/ddr/playdata_3.py b/modules/ddr/playdata_3.py index 6a7902a..688455c 100644 --- a/modules/ddr/playdata_3.py +++ b/modules/ddr/playdata_3.py @@ -1,3 +1,4 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import random import time @@ -5,28 +6,22 @@ from tinydb import Query, where import config -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db from os import path import json -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["MDX"] - +set_xrpc_defaults(service="local2", models=["MDX"]) def get_profile(cid): return get_db().table("ddr_profile").get(where("card") == cid) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - mdb = {} ddr_metadata = path.join("webui", "ddr.json") if path.exists(ddr_metadata): @@ -176,9 +171,8 @@ flares = [ (800000, 1), ] -@router.post("/{gameinfo}/playdata_3/musicdata_load") -async def playdata_3_musicdata_load(request: Request): - request_info = await core_process_request(request) +@xrpc("playdata_3/musicdata_load") +async def playdata_3_musicdata_load(ctx: Ctx): if mdb: response = E.response( @@ -194,7 +188,6 @@ async def playdata_3_musicdata_load(request: Request): ) ) - else: response = E.response( E.playdata_3( @@ -206,15 +199,13 @@ async def playdata_3_musicdata_load(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response -@router.post("/{gameinfo}/playdata_3/playerdata_load") -async def playdata_3_playerdata_load(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("playdata_3/playerdata_load") +async def playdata_3_playerdata_load(ctx: Ctx): + game_version = ctx.info["game_version"] - data = request_info["root"][0].find("data") + data = ctx.info["root"][0].find("data") #mode = data.find("mode").text #gamesession = data.find("gamesession").text refid = data.find("refid").text @@ -332,15 +323,13 @@ async def playdata_3_playerdata_load(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response -@router.post("/{gameinfo}/playdata_3/rivaldata_load") -async def playdata_3_rivaldata_load(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("playdata_3/rivaldata_load") +async def playdata_3_rivaldata_load(ctx: Ctx): + game_version = ctx.info["game_version"] - data = request_info["root"][0].find("data") + data = ctx.info["root"][0].find("data") loadflag = int(data.find("loadkind").text) country = data.find("country").text region = data.find("region").text @@ -474,16 +463,13 @@ async def playdata_3_rivaldata_load(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("playdata_3/playerdata_new") +async def playdata_3_playerdata_new(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/playdata_3/playerdata_new") -async def playdata_3_playerdata_new(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - data = request_info["root"][0].find("data") + data = ctx.info["root"][0].find("data") refid = data.find("refid").text db = get_db() @@ -505,7 +491,6 @@ async def playdata_3_playerdata_new(request: Request): db.table("ddr_profile").upsert(all_profiles_for_card, where("card") == refid) - response = E.response( E.playdata_3( E.result(0, __type="s32"), @@ -515,17 +500,14 @@ async def playdata_3_playerdata_new(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("playdata_3/playerdata_save") +async def playdata_3_playerdata_save(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/playdata_3/playerdata_save") -async def playdata_3_playerdata_save(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - retrycnt = int(request_info["root"][0].find("retrycnt").text) - data = request_info["root"][0].find("data") + retrycnt = int(ctx.info["root"][0].find("retrycnt").text) + data = ctx.info["root"][0].find("data") refid = data.find("refid").text savekind = int(data.find("savekind").text) @@ -669,16 +651,12 @@ async def playdata_3_playerdata_save(request: Request): ) ) + return response - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) +@xrpc("playdata_3/ghostdata_load") +async def playdata_3_ghostdata_load(ctx: Ctx): - -@router.post("/{gameinfo}/playdata_3/ghostdata_load") -async def playdata_3_ghostdata_load(request: Request): - request_info = await core_process_request(request) - - data = request_info["root"][0].find("data") + data = ctx.info["root"][0].find("data") ghostid = int(data.find("ghostid").text) record = get_db().table("ddr_scores").get(doc_id=ghostid) @@ -691,13 +669,10 @@ async def playdata_3_ghostdata_load(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/playdata_3/mergeddata_load") -async def playdata_3_mergeddata_load(request: Request): - request_info = await core_process_request(request) +@xrpc("playdata_3/mergeddata_load") +async def playdata_3_mergeddata_load(ctx: Ctx): response = E.response( E.playdata_3( @@ -708,5 +683,4 @@ async def playdata_3_mergeddata_load(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/ddr/playerdata.py b/modules/ddr/playerdata.py index adc52ca..107c1c9 100644 --- a/modules/ddr/playerdata.py +++ b/modules/ddr/playerdata.py @@ -1,3 +1,4 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import random import time @@ -5,27 +6,21 @@ from tinydb import Query, where import config -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db from base64 import b64decode, b64encode -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["MDX"] - +set_xrpc_defaults(service="local2", models=["MDX"]) def get_profile(cid): return get_db().table("ddr_profile").get(where("card") == cid) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - def get_common(ddr_id, game_version, idx): profile = get_db().table("ddr_profile").get(where("ddr_id") == int(ddr_id)) if profile is not None: @@ -33,15 +28,13 @@ def get_common(ddr_id, game_version, idx): else: return 0 - -@router.post("/{gameinfo}/playerdata/usergamedata_advanced") -async def playerdata_usergamedata_advanced(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - is_omni = True if request_info["rev"] == "O" else False +@xrpc("playerdata/usergamedata_advanced") +async def playerdata_usergamedata_advanced(ctx: Ctx): + game_version = ctx.info["game_version"] + is_omni = True if ctx.info["rev"] == "O" else False response = None - data = request_info["root"][0].find("data") + data = ctx.info["root"][0].find("data") mode = data.find("mode").text gamesession = data.find("gamesession").text refid = data.find("refid").text @@ -110,7 +103,6 @@ async def playerdata_usergamedata_advanced(request: Request): record["ghostid"], ] - f = {} for mcode in all_scores.keys(): if mcode not in f: @@ -544,16 +536,13 @@ async def playerdata_usergamedata_advanced(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("playerdata/usergamedata_recv") +async def playerdata_usergamedata_recv(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/playerdata/usergamedata_recv") -async def playerdata_usergamedata_recv(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - data = request_info["root"][0].find("data") + data = ctx.info["root"][0].find("data") cid = data.find("refid").text profile = get_game_profile(cid, game_version) @@ -654,16 +643,13 @@ async def playerdata_usergamedata_recv(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("playerdata/usergamedata_send") +async def playerdata_usergamedata_send(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/playerdata/usergamedata_send") -async def playerdata_usergamedata_send(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - data = request_info["root"][0].find("data") + data = ctx.info["root"][0].find("data") cid = data.find("refid").text num = int(data.find("datanum").text) @@ -702,5 +688,4 @@ async def playerdata_usergamedata_send(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/ddr/playerdata_2.py b/modules/ddr/playerdata_2.py index 7645069..e97bbc8 100644 --- a/modules/ddr/playerdata_2.py +++ b/modules/ddr/playerdata_2.py @@ -1,3 +1,4 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import random import time @@ -5,27 +6,21 @@ from tinydb import Query, where import config -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db from base64 import b64decode, b64encode -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["MDX"] - +set_xrpc_defaults(service="local2", models=["MDX"]) def get_profile(cid): return get_db().table("ddr_profile").get(where("card") == cid) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - def get_common(ddr_id, game_version, idx): profile = get_db().table("ddr_profile").get(where("ddr_id") == int(ddr_id)) if profile is not None: @@ -33,15 +28,13 @@ def get_common(ddr_id, game_version, idx): else: return 0 - -@router.post("/{gameinfo}/playerdata_2/usergamedata_advanced") -async def playerdata_2_usergamedata_advanced(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - is_omni = True if request_info["rev"] == "O" else False +@xrpc("playerdata_2/usergamedata_advanced") +async def playerdata_2_usergamedata_advanced(ctx: Ctx): + game_version = ctx.info["game_version"] + is_omni = True if ctx.info["rev"] == "O" else False response = None - data = request_info["root"][0].find("data") + data = ctx.info["root"][0].find("data") mode = data.find("mode").text gamesession = data.find("gamesession").text refid = data.find("refid").text @@ -615,16 +608,13 @@ async def playerdata_2_usergamedata_advanced(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("playerdata_2/usergamedata_recv") +async def playerdata_2_usergamedata_recv(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/playerdata_2/usergamedata_recv") -async def playerdata_2_usergamedata_recv(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - data = request_info["root"][0].find("data") + data = ctx.info["root"][0].find("data") cid = data.find("refid").text profile = get_game_profile(cid, game_version) @@ -725,16 +715,13 @@ async def playerdata_2_usergamedata_recv(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("playerdata_2/usergamedata_send") +async def playerdata_2_usergamedata_send(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/playerdata_2/usergamedata_send") -async def playerdata_2_usergamedata_send(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - data = request_info["root"][0].find("data") + data = ctx.info["root"][0].find("data") cid = data.find("refid").text num = int(data.find("datanum").text) @@ -773,5 +760,4 @@ async def playerdata_2_usergamedata_send(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/ddr/system.py b/modules/ddr/system.py index 66ae0ee..636e043 100644 --- a/modules/ddr/system.py +++ b/modules/ddr/system.py @@ -1,17 +1,14 @@ -from fastapi import APIRouter, Request, Response +from modules.registry import Ctx, set_xrpc_defaults, xrpc -from core_common import core_process_request, core_prepare_response, E +from core_common import E import utils.card as conv -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["MDX"] +set_xrpc_defaults(service="local2", models=["MDX"]) - -@router.post("/{gameinfo}/system/convcardnumber") -async def system_convcardnumber(request: Request): - request_info = await core_process_request(request) - cid = request_info["root"][0].find("data/card_id").text +@xrpc("system/convcardnumber") +async def system_convcardnumber(ctx: Ctx): + cid = ctx.info["root"][0].find("data/card_id").text response = E.response( E.system( @@ -20,5 +17,4 @@ async def system_convcardnumber(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/ddr/system_2.py b/modules/ddr/system_2.py index 75716a6..96061e8 100644 --- a/modules/ddr/system_2.py +++ b/modules/ddr/system_2.py @@ -1,17 +1,14 @@ -from fastapi import APIRouter, Request, Response +from modules.registry import Ctx, set_xrpc_defaults, xrpc -from core_common import core_process_request, core_prepare_response, E +from core_common import E import utils.card as conv -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["MDX"] +set_xrpc_defaults(service="local2", models=["MDX"]) - -@router.post("/{gameinfo}/system_2/convcardnumber") -async def system_2_convcardnumber(request: Request): - request_info = await core_process_request(request) - cid = request_info["root"][0].find("data/card_id").text +@xrpc("system_2/convcardnumber") +async def system_2_convcardnumber(ctx: Ctx): + cid = ctx.info["root"][0].find("data/card_id").text response = E.response( E.system_2( @@ -20,5 +17,4 @@ async def system_2_convcardnumber(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/ddr/system_3.py b/modules/ddr/system_3.py index 08acce0..5117fb1 100644 --- a/modules/ddr/system_3.py +++ b/modules/ddr/system_3.py @@ -1,17 +1,14 @@ -from fastapi import APIRouter, Request, Response +from modules.registry import Ctx, set_xrpc_defaults, xrpc -from core_common import core_process_request, core_prepare_response, E +from core_common import E import utils.card as conv -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["MDX"] +set_xrpc_defaults(service="local2", models=["MDX"]) - -@router.post("/{gameinfo}/system_3/convcardnumber") -async def system_3_convcardnumber(request: Request): - request_info = await core_process_request(request) - cid = request_info["root"][0].find("data/card_id").text +@xrpc("system_3/convcardnumber") +async def system_3_convcardnumber(ctx: Ctx): + cid = ctx.info["root"][0].find("data/card_id").text response = E.response( E.system_3( @@ -20,5 +17,4 @@ async def system_3_convcardnumber(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/ddr/tax.py b/modules/ddr/tax.py index cd78b6c..fea81f7 100644 --- a/modules/ddr/tax.py +++ b/modules/ddr/tax.py @@ -1,20 +1,16 @@ -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E - -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["MDX"] - - -@router.post("/{gameinfo}/tax/get_phase") -async def tax_get_phase(request: Request): - request_info = await core_process_request(request) - - response = E.response( - E.tax( - E.phase(0, __type="s32"), - ) - ) - - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) +from modules.registry import Ctx, set_xrpc_defaults, xrpc + +from core_common import E + +set_xrpc_defaults(service="local", models=["MDX"]) + +@xrpc("tax/get_phase") +async def tax_get_phase(ctx: Ctx): + + response = E.response( + E.tax( + E.phase(0, __type="s32"), + ) + ) + + return response diff --git a/modules/ddr/wordcheck_3.py b/modules/ddr/wordcheck_3.py index 42f9f08..d2ce23c 100644 --- a/modules/ddr/wordcheck_3.py +++ b/modules/ddr/wordcheck_3.py @@ -1,16 +1,12 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["MDX"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["MDX"] - - -@router.post("/{gameinfo}/wordcheck_3/tabooword_check") -async def wordcheck_3_tabooword_check(request: Request): - request_info = await core_process_request(request) +@xrpc("wordcheck_3/tabooword_check") +async def wordcheck_3_tabooword_check(ctx: Ctx): response = E.response( E.wordcheck_3( @@ -19,5 +15,4 @@ async def wordcheck_3_tabooword_check(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/drs/eventlog.py b/modules/drs/eventlog.py index 9da0d4a..31d4510 100644 --- a/modules/drs/eventlog.py +++ b/modules/drs/eventlog.py @@ -1,25 +1,20 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local", models=["REC"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["REC"] - - -@router.post("/{gameinfo}/eventlog/write") -async def drs_eventlog_write(request: Request): - request_info = await core_process_request(request) +@xrpc("eventlog/write") +async def drs_eventlog_write(ctx: Ctx): response = E.response( E.eventlog( E.gamesession(9999999, __type="s64"), - E.logsendflg(0, __type="s32"), + E.logsendflg(1 if config.maintenance_mode else 0, __type="s32"), E.logerrlevel(0, __type="s32"), E.evtidnosendflg(0, __type="s32"), ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/drs/game.py b/modules/drs/game.py index ee72a44..e34adc4 100644 --- a/modules/drs/game.py +++ b/modules/drs/game.py @@ -1,3 +1,4 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import xml.etree.ElementTree as ET from os import path @@ -7,25 +8,19 @@ import config import random import time -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["REC"] - +set_xrpc_defaults(service="local", models=["REC"]) def get_profile(cid): return get_db().table("dancerush_profile").get(where("card") == cid) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - def get_id_from_profile(cid): profile = get_db().table("dancerush_profile").get(where("card") == cid) @@ -34,10 +29,8 @@ def get_id_from_profile(cid): return profile["drs_id"], djid_split - -@router.post("/{gameinfo}/game/get_common") -async def drs_game_get_common(request: Request): - request_info = await core_process_request(request) +@xrpc("game/get_common") +async def drs_game_get_common(ctx: Ctx): songs = {} @@ -190,16 +183,13 @@ async def drs_game_get_common(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("game/get_playdata_{player}") +async def drs_game_get_playdata(player: str, ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/game/get_playdata_{player}") -async def drs_game_get_playdata(player: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - dataid = request_info["root"][0].find("userid/refid").text + dataid = ctx.info["root"][0].find("userid/refid").text profile = get_game_profile(dataid, game_version) if profile: @@ -247,26 +237,20 @@ async def drs_game_get_playdata(player: str, request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/lock_multi_login_{player}") -async def drs_game_lock_multi_login(player: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/lock_multi_login_{player}") +async def drs_game_lock_multi_login(player: str, ctx: Ctx): response = E.response(E.game()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("game/sign_up_{player}") +async def drs_game_sign_up(player: str, ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/game/sign_up_{player}") -async def drs_game_sign_up(player: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - root = request_info["root"][0] + root = ctx.info["root"][0] dataid = root.find("userid/dataid").text cardno = root.find("userid/cardno").text @@ -295,14 +279,11 @@ async def drs_game_sign_up(player: str, request: Request): response = E.response(E.game()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/get_musicscore_{player}") -async def drs_get_musicscore(player: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("game/get_musicscore_{player}") +async def drs_get_musicscore(player: str, ctx: Ctx): + game_version = ctx.info["game_version"] scores = [] db = get_db() @@ -341,18 +322,15 @@ async def drs_get_musicscore(player: str, request: Request): ), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/save_musicscore") -async def drs_save_musicscore(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("game/save_musicscore") +async def drs_save_musicscore(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - root = request_info["root"][0][0] + root = ctx.info["root"][0][0] dataid = root.find("userid/refid").text profile = get_game_profile(dataid, game_version) @@ -420,16 +398,13 @@ async def drs_save_musicscore(request: Request): response = E.response(E.game()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("game/save_playdata") +async def drs_save_musicscore(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/game/save_playdata") -async def drs_save_musicscore(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - root = request_info["root"][0][0] + root = ctx.info["root"][0][0] dataid = root.find("userid/refid").text @@ -478,5 +453,4 @@ async def drs_save_musicscore(request: Request): response = E.response(E.game()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/gitadora/api.py b/modules/gitadora/api.py index 12f8051..2294595 100644 --- a/modules/gitadora/api.py +++ b/modules/gitadora/api.py @@ -1,16 +1,14 @@ -from fastapi import APIRouter, Request, Response +from typing import Optional -from core_common import core_process_request, core_prepare_response, E - -from tinydb import Query, where -from core_database import get_db from pydantic import BaseModel +from starlette.requests import Request +from starlette.responses import Response +from starlette.routing import Route, Router +from tinydb import where -import config import utils.card as conv - - -router = APIRouter(prefix="/gfdm", tags=["api_gfdm"]) +from core_database import get_db +from modules.webapi import endpoint, read_model class GFDM_Profile_Main_Items(BaseModel): @@ -25,19 +23,22 @@ class GFDM_Profile_Version_Items(BaseModel): rival_card_ids: list = [] -@router.get("/profiles") -async def gfdm_profiles(): +@endpoint +async def gfdm_profiles(request: Request): return get_db().table("gitadora_profile").all() -@router.get("/profiles/{gitadora_id}") -async def gfdm_profile_id(gitadora_id: str): +@endpoint +async def gfdm_profile_id(request: Request): + gitadora_id = request.path_params["gitadora_id"] gitadora_id = int("".join([i for i in gitadora_id if i.isnumeric()])) return get_db().table("gitadora_profile").get(where("gitadora_id") == gitadora_id) -@router.patch("/profiles/{gitadora_id}") -async def gfdm_profile_id_patch(gitadora_id: str, item: GFDM_Profile_Main_Items): +@endpoint +async def gfdm_profile_id_patch(request: Request): + gitadora_id = request.path_params["gitadora_id"] + item = await read_model(request, GFDM_Profile_Main_Items) gitadora_id = int("".join([i for i in gitadora_id if i.isnumeric()])) profile = ( get_db().table("gitadora_profile").get(where("gitadora_id") == gitadora_id) @@ -52,10 +53,11 @@ async def gfdm_profile_id_patch(gitadora_id: str, item: GFDM_Profile_Main_Items) return Response(status_code=204) -@router.patch("/profiles/{gitadora_id}/{version}") -async def gfdm_profile_id_version_patch( - gitadora_id: str, version: int, item: GFDM_Profile_Version_Items -): +@endpoint +async def gfdm_profile_id_version_patch(request: Request): + gitadora_id = request.path_params["gitadora_id"] + version = int(request.path_params["version"]) + item = await read_model(request, GFDM_Profile_Version_Items) gitadora_id = int("".join([i for i in gitadora_id if i.isnumeric()])) profile = ( get_db().table("gitadora_profile").get(where("gitadora_id") == gitadora_id) @@ -74,8 +76,9 @@ async def gfdm_profile_id_version_patch( return Response(status_code=204) -@router.get("/card/{card}") -async def gfdm_card_to_profile(card: str): +@endpoint +async def gfdm_card_to_profile(request: Request): + card = request.path_params["card"] card = card.upper() lookalike = { "I": "1", @@ -97,26 +100,28 @@ async def gfdm_card_to_profile(card: str): return profile -@router.get("/drummania/scores") -async def dm_scores(): +@endpoint +async def dm_scores(request: Request): return get_db().table("drummania_scores").all() -@router.get("/guitarfreaks/scores") -async def gf_scores(): +@endpoint +async def gf_scores(request: Request): return get_db().table("guitarfreaks_scores").all() -@router.get("/drummania/scores/{gitadora_id}") -async def dm_scores_id(gitadora_id: str): +@endpoint +async def dm_scores_id(request: Request): + gitadora_id = request.path_params["gitadora_id"] gitadora_id = int("".join([i for i in gitadora_id if i.isnumeric()])) return ( get_db().table("drummania_scores").search((where("gitadora_id") == gitadora_id)) ) -@router.get("/guitarfreaks/scores/{gitadora_id}") -async def gf_scores_id(gitadora_id: str): +@endpoint +async def gf_scores_id(request: Request): + gitadora_id = request.path_params["gitadora_id"] gitadora_id = int("".join([i for i in gitadora_id if i.isnumeric()])) return ( get_db() @@ -125,18 +130,19 @@ async def gf_scores_id(gitadora_id: str): ) -@router.get("/drummania/scores_best") -async def dm_scores_best(): +@endpoint +async def dm_scores_best(request: Request): return get_db().table("drummania_scores_best").all() -@router.get("/guitarfreaks/scores_best") -async def gf_scores_best(): +@endpoint +async def gf_scores_best(request: Request): return get_db().table("guitarfreaks_scores_best").all() -@router.get("/drummania/scores_best/{gitadora_id}") -async def dm_scores_best_id(gitadora_id: str): +@endpoint +async def dm_scores_best_id(request: Request): + gitadora_id = request.path_params["gitadora_id"] gitadora_id = int("".join([i for i in gitadora_id if i.isnumeric()])) return ( get_db() @@ -145,8 +151,9 @@ async def dm_scores_best_id(gitadora_id: str): ) -@router.get("/guitarfreaks/scores_best/{gitadora_id}") -async def gf_scores_best_id(gitadora_id: str): +@endpoint +async def gf_scores_best_id(request: Request): + gitadora_id = request.path_params["gitadora_id"] gitadora_id = int("".join([i for i in gitadora_id if i.isnumeric()])) return ( get_db() @@ -155,21 +162,60 @@ async def gf_scores_best_id(gitadora_id: str): ) -@router.get("/drummania/mcode/{mcode}/all") -async def dm_scores_id(mcode: int): +@endpoint +async def dm_scores_mcode_all(request: Request): + mcode = int(request.path_params["mcode"]) return get_db().table("drummania_scores").search((where("mcode") == mcode)) -@router.get("/guitarfreaks/mcode/{mcode}/all") -async def gf_scores_id(mcode: int): +@endpoint +async def gf_scores_mcode_all(request: Request): + mcode = int(request.path_params["mcode"]) return get_db().table("guitarfreaks_scores").search((where("mcode") == mcode)) -@router.get("/drummania/mcode/{mcode}/best") -async def dm_scores_id_best(mcode: int): +@endpoint +async def dm_scores_mcode_best(request: Request): + mcode = int(request.path_params["mcode"]) return get_db().table("drummania_scores_best").search((where("mcode") == mcode)) -@router.get("/guitarfreaks/mcode/{mcode}/best") -async def gf_scores_id_best(mcode: int): +@endpoint +async def gf_scores_mcode_best(request: Request): + mcode = int(request.path_params["mcode"]) return get_db().table("guitarfreaks_scores_best").search((where("mcode") == mcode)) + + +router = Router( + routes=[ + Route("/profiles", gfdm_profiles, methods=["GET"]), + Route("/profiles/{gitadora_id}", gfdm_profile_id, methods=["GET"]), + Route("/profiles/{gitadora_id}", gfdm_profile_id_patch, methods=["PATCH"]), + Route( + "/profiles/{gitadora_id}/{version}", + gfdm_profile_id_version_patch, + methods=["PATCH"], + ), + Route("/card/{card}", gfdm_card_to_profile, methods=["GET"]), + Route("/drummania/scores", dm_scores, methods=["GET"]), + Route("/guitarfreaks/scores", gf_scores, methods=["GET"]), + Route("/drummania/scores/{gitadora_id}", dm_scores_id, methods=["GET"]), + Route("/guitarfreaks/scores/{gitadora_id}", gf_scores_id, methods=["GET"]), + Route("/drummania/scores_best", dm_scores_best, methods=["GET"]), + Route("/guitarfreaks/scores_best", gf_scores_best, methods=["GET"]), + Route( + "/drummania/scores_best/{gitadora_id}", + dm_scores_best_id, + methods=["GET"], + ), + Route( + "/guitarfreaks/scores_best/{gitadora_id}", + gf_scores_best_id, + methods=["GET"], + ), + Route("/drummania/mcode/{mcode}/all", dm_scores_mcode_all, methods=["GET"]), + Route("/guitarfreaks/mcode/{mcode}/all", gf_scores_mcode_all, methods=["GET"]), + Route("/drummania/mcode/{mcode}/best", dm_scores_mcode_best, methods=["GET"]), + Route("/guitarfreaks/mcode/{mcode}/best", gf_scores_mcode_best, methods=["GET"]), + ] +) diff --git a/modules/gitadora/cardutil.py b/modules/gitadora/cardutil.py index c18277a..ced7ce3 100644 --- a/modules/gitadora/cardutil.py +++ b/modules/gitadora/cardutil.py @@ -1,32 +1,26 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from tinydb import Query, where import random -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["M32"] - +set_xrpc_defaults(service=("local", "local2"), models=["M32"]) def get_profile(cid): return get_db().table("gitadora_profile").get(where("card") == cid) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) +@xrpc("{ver}_cardutil/check") +async def gitadora_cardutil_check(ver: str, ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/{ver}_cardutil/check") -async def gitadora_cardutil_check(ver: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - data = request_info["root"][0].find("player") + data = ctx.info["root"][0].find("player") no = int(data.attrib["no"]) @@ -62,17 +56,14 @@ async def gitadora_cardutil_check(ver: str, request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("{ver}_cardutil/regist") +async def gitadora_cardutil_regist(ver: str, ctx: Ctx): + game_version = ctx.info["game_version"] + spec = ctx.info["spec"] -@router.post("/{gameinfo}/{ver}_cardutil/regist") -async def gitadora_cardutil_regist(ver: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - spec = request_info["spec"] - - data = request_info["root"][0].find("player") + data = ctx.info["root"][0].find("player") no = int(data.attrib["no"]) @@ -260,5 +251,4 @@ async def gitadora_cardutil_regist(ver: str, request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/gitadora/gameend.py b/modules/gitadora/gameend.py index ac33a97..c5ce8bf 100644 --- a/modules/gitadora/gameend.py +++ b/modules/gitadora/gameend.py @@ -1,36 +1,30 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from tinydb import Query, where -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["M32"] - +set_xrpc_defaults(service=("local", "local2"), models=["M32"]) def get_profile(cid): return get_db().table("gitadora_profile").get(where("card") == cid) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - -@router.post("/{gameinfo}/{ver}_gameend/regist") -async def gitadora_gameend_regist(ver: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - spec = request_info["spec"] +@xrpc("{ver}_gameend/regist") +async def gitadora_gameend_regist(ver: str, ctx: Ctx): + game_version = ctx.info["game_version"] + spec = ctx.info["spec"] if spec in ("A", "C"): g = "guitarfreaks" elif spec in ("B", "D"): g = "drummania" - root = request_info["root"][0] + root = ctx.info["root"][0] players = root.findall("player") @@ -341,5 +335,4 @@ async def gitadora_gameend_regist(ver: str, request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/gitadora/gameinfo.py b/modules/gitadora/gameinfo.py index 3de6aba..f63fe89 100644 --- a/modules/gitadora/gameinfo.py +++ b/modules/gitadora/gameinfo.py @@ -1,17 +1,13 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service=("local", "local2"), models=["M32"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["M32"] - - -@router.post("/{gameinfo}/{ver}_gameinfo/get") -async def gitadora_gameinfo_get(ver: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("{ver}_gameinfo/get") +async def gitadora_gameinfo_get(ver: str, ctx: Ctx): + game_version = ctx.info["game_version"] response = E.response( E( @@ -237,5 +233,4 @@ async def gitadora_gameinfo_get(ver: str, request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/gitadora/gametop.py b/modules/gitadora/gametop.py index 99d940b..306b13a 100644 --- a/modules/gitadora/gametop.py +++ b/modules/gitadora/gametop.py @@ -1,39 +1,32 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from tinydb import Query, where import time -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db - -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["M32"] - +set_xrpc_defaults(service=("local", "local2"), models=["M32"]) def get_profile(cid): return get_db().table("gitadora_profile").get(where("card") == cid) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - -@router.post("/{gameinfo}/{ver}_gametop/get") -async def gitadora_gametop_get(ver: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - spec = request_info["spec"] +@xrpc("{ver}_gametop/get") +async def gitadora_gametop_get(ver: str, ctx: Ctx): + game_version = ctx.info["game_version"] + spec = ctx.info["spec"] if spec in ("A", "C"): g = "guitarfreaks" elif spec in ("B", "D"): g = "drummania" - data = request_info["root"][0].find("player") + data = ctx.info["root"][0].find("player") no = int(data.attrib["no"]) dataid = data.find("refid").text profile = get_game_profile(dataid, game_version) @@ -638,5 +631,4 @@ async def gitadora_gametop_get(ver: str, request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/gitadora/lobby.py b/modules/gitadora/lobby.py index 6ebef62..6f454ff 100644 --- a/modules/gitadora/lobby.py +++ b/modules/gitadora/lobby.py @@ -1,19 +1,15 @@ -from fastapi import APIRouter, Request, Response - -from core_common import E, core_prepare_response, core_process_request - -router = APIRouter(prefix="/lobby", tags=["lobby"]) -router.model_whitelist = ["M32"] +from modules.registry import Ctx, set_xrpc_defaults, xrpc +from core_common import E host = {} +set_xrpc_defaults(service="lobby", models=["M32"]) -@router.post("/{gameinfo}/lobby/request") -async def gitadora_lobby_request(request: Request): - request_info = await core_process_request(request) +@xrpc("lobby/request") +async def gitadora_lobby_request(ctx: Ctx): - root = request_info["root"][0][0] + root = ctx.info["root"][0][0] address_ip = root.find("address/ip").text check_attestid = root.find("check/attestid").text @@ -45,5 +41,4 @@ async def gitadora_lobby_request(request: Request): host["attestid"] = check_attestid response = E.response(E.lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/gitadora/playablemusic.py b/modules/gitadora/playablemusic.py index a423fce..4b38ba8 100644 --- a/modules/gitadora/playablemusic.py +++ b/modules/gitadora/playablemusic.py @@ -1,18 +1,14 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import lxml.etree as ET from os import path -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service=("local", "local2"), models=["M32"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["M32"] - - -@router.post("/{gameinfo}/{ver}_playablemusic/get") -async def gitadora_playablemusic_get(ver: str, request: Request): - request_info = await core_process_request(request) - spec = request_info["spec"] +@xrpc("{ver}_playablemusic/get") +async def gitadora_playablemusic_get(ver: str, ctx: Ctx): + spec = ctx.info["spec"] if spec in ("A", "B"): is_delta = False @@ -135,5 +131,4 @@ async def gitadora_playablemusic_get(ver: str, request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/gitadora/shopinfo.py b/modules/gitadora/shopinfo.py index 0e41687..bd27853 100644 --- a/modules/gitadora/shopinfo.py +++ b/modules/gitadora/shopinfo.py @@ -1,14 +1,11 @@ -from fastapi import APIRouter, Request, Response +from modules.registry import Ctx, set_xrpc_defaults, xrpc -from core_common import core_process_request, core_prepare_response, E +from core_common import E -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["M32"] +set_xrpc_defaults(service=("local", "local2"), models=["M32"]) - -@router.post("/{gameinfo}/{ver}_shopinfo/regist") -async def gitadora_shopinfo_regist(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("{ver}_shopinfo/regist") +async def gitadora_shopinfo_regist(ver: str, ctx: Ctx): response = E.response( E( @@ -27,5 +24,4 @@ async def gitadora_shopinfo_regist(ver: str, request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/api.py b/modules/iidx/api.py index 30f3246..cdd4772 100644 --- a/modules/iidx/api.py +++ b/modules/iidx/api.py @@ -1,22 +1,18 @@ -from fastapi import APIRouter, Request, Response, File, UploadFile - -from core_common import core_process_request, core_prepare_response, E - -from tinydb import Query, where -from core_database import get_db -from pydantic import BaseModel from typing import Optional +from os import path +import json +import xml.etree.ElementTree as ET + +from pydantic import BaseModel +from starlette.requests import Request +from starlette.responses import Response +from starlette.routing import Route, Router +from tinydb import where -import config import utils.card as conv import utils.musicdata_tool as mdt - -import xml.etree.ElementTree as ET -import json -from os import path - - -router = APIRouter(prefix="/iidx", tags=["api_iidx"]) +from core_database import get_db +from modules.webapi import endpoint, read_model class IIDX_Profile_Main_Items(BaseModel): @@ -81,19 +77,22 @@ class IIDX_Profile_Version_Items(BaseModel): dp_rival_6_iidx_id: Optional[int] = 0 -@router.get("/profiles") -async def iidx_profiles(): +@endpoint +async def iidx_profiles(request: Request): return get_db().table("iidx_profile").all() -@router.get("/profiles/{iidx_id}") -async def iidx_profile_id(iidx_id: str): +@endpoint +async def iidx_profile_id(request: Request): + iidx_id = request.path_params["iidx_id"] iidx_id = int("".join([i for i in iidx_id if i.isnumeric()])) return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) -@router.patch("/profiles/{iidx_id}") -async def iidx_profile_id_patch(iidx_id: str, item: IIDX_Profile_Main_Items): +@endpoint +async def iidx_profile_id_patch(request: Request): + iidx_id = request.path_params["iidx_id"] + item = await read_model(request, IIDX_Profile_Main_Items) iidx_id = int("".join([i for i in iidx_id if i.isnumeric()])) profile = get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) @@ -104,12 +103,13 @@ async def iidx_profile_id_patch(iidx_id: str, item: IIDX_Profile_Main_Items): return Response(status_code=204) -@router.patch("/profiles/{iidx_id}/{version}") -async def iidx_profile_id_version_patch( - iidx_id: str, version: int, item: IIDX_Profile_Version_Items -): +@endpoint +async def iidx_profile_id_version_patch(request: Request): + iidx_id = request.path_params["iidx_id"] + version = int(request.path_params["version"]) + item = await read_model(request, IIDX_Profile_Version_Items) + if version < 30: - # TODO: differentiate 18, 19, 20, 29, 30 return Response(status_code=406) iidx_id = int("".join([i for i in iidx_id if i.isnumeric()])) profile = get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) @@ -177,8 +177,10 @@ async def iidx_profile_id_version_patch( return Response(status_code=204) -@router.get("/card/{card}") -async def iidx_card_to_profile(card: str): + +@endpoint +async def iidx_card_to_profile(request: Request): + card = request.path_params["card"] card = card.upper() lookalike = { "I": "1", @@ -191,66 +193,72 @@ async def iidx_card_to_profile(card: str): if card.startswith("E004") or card.startswith("012E"): card = "".join([c for c in card if c in "0123456789ABCDEF"]) uid = card - kid = conv.to_konami_id(card) else: card = "".join([c for c in card if c in conv.valid_characters]) uid = conv.to_uid(card) - kid = card profile = get_db().table("iidx_profile").get(where("card") == uid) return profile -@router.get("/scores") -async def iidx_scores(): +@endpoint +async def iidx_scores(request: Request): return get_db().table("iidx_scores").all() -@router.get("/scores/{iidx_id}") -async def iidx_scores_id(iidx_id: str): +@endpoint +async def iidx_scores_id(request: Request): + iidx_id = request.path_params["iidx_id"] iidx_id = int("".join([i for i in iidx_id if i.isnumeric()])) return get_db().table("iidx_scores").search((where("iidx_id") == iidx_id)) -@router.get("/scores_best") -async def iidx_scores_best(): +@endpoint +async def iidx_scores_best(request: Request): return get_db().table("iidx_scores_best").all() -@router.get("/scores_best/{iidx_id}") -async def iidx_scores_best_id(iidx_id: str): +@endpoint +async def iidx_scores_best_id(request: Request): + iidx_id = request.path_params["iidx_id"] iidx_id = int("".join([i for i in iidx_id if i.isnumeric()])) return get_db().table("iidx_scores_best").search((where("iidx_id") == iidx_id)) -@router.get("/music_id/{music_id}/all") -async def iidx_scores_id(music_id: int): +@endpoint +async def iidx_scores_music_all(request: Request): + music_id = int(request.path_params["music_id"]) return get_db().table("iidx_scores").search((where("music_id") == music_id)) -@router.get("/music_id/{music_id}/best") -async def iidx_scores_id_best(music_id: int): +@endpoint +async def iidx_scores_music_best(request: Request): + music_id = int(request.path_params["music_id"]) return get_db().table("iidx_scores_best").search((where("music_id") == music_id)) -@router.get("/class_best/{iidx_id}") -async def iidx_class_best(iidx_id: str): +@endpoint +async def iidx_class_best(request: Request): + iidx_id = request.path_params["iidx_id"] iidx_id = int("".join([i for i in iidx_id if i.isnumeric()])) return get_db().table("iidx_class_best").search((where("iidx_id") == iidx_id)) -@router.get("/score_stats/all") -async def iidx_score_stats(): +@endpoint +async def iidx_score_stats(request: Request): return get_db().table("iidx_score_stats").all() -@router.get("/score_stats/{music_id}") -async def iidx_score_stats_song(music_id: int): +@endpoint +async def iidx_score_stats_song(request: Request): + music_id = int(request.path_params["music_id"]) return get_db().table("iidx_score_stats").search((where("music_id") == music_id)) -@router.post("/parse_mdb/upload") -async def iidx_receive_mdb(file: UploadFile = File(...)) -> bytes: - data = await file.read() +@endpoint +async def iidx_receive_mdb(request: Request): + form = await request.form() + upload = form["file"] + data = await upload.read() iidx_bin = path.join("webui", "music_data.bin") iidx_vid = path.join("webui", "video_music_list.xml") @@ -315,3 +323,29 @@ async def iidx_receive_mdb(file: UploadFile = File(...)) -> bytes: return Response(status_code=422) return Response(status_code=406) + + + +router = Router( + routes=[ + Route("/profiles", iidx_profiles, methods=["GET"]), + Route("/profiles/{iidx_id}", iidx_profile_id, methods=["GET"]), + Route("/profiles/{iidx_id}", iidx_profile_id_patch, methods=["PATCH"]), + Route( + "/profiles/{iidx_id}/{version}", + iidx_profile_id_version_patch, + methods=["PATCH"], + ), + Route("/card/{card}", iidx_card_to_profile, methods=["GET"]), + Route("/scores", iidx_scores, methods=["GET"]), + Route("/scores/{iidx_id}", iidx_scores_id, methods=["GET"]), + Route("/scores_best", iidx_scores_best, methods=["GET"]), + Route("/scores_best/{iidx_id}", iidx_scores_best_id, methods=["GET"]), + Route("/music_id/{music_id}/all", iidx_scores_music_all, methods=["GET"]), + Route("/music_id/{music_id}/best", iidx_scores_music_best, methods=["GET"]), + Route("/class_best/{iidx_id}", iidx_class_best, methods=["GET"]), + Route("/score_stats/all", iidx_score_stats, methods=["GET"]), + Route("/score_stats/{music_id}", iidx_score_stats_song, methods=["GET"]), + Route("/parse_mdb/upload", iidx_receive_mdb, methods=["POST"]), + ] +) diff --git a/modules/iidx/iidx29gamesystem.py b/modules/iidx/iidx29gamesystem.py index c3673b6..b5bd895 100644 --- a/modules/iidx/iidx29gamesystem.py +++ b/modules/iidx/iidx29gamesystem.py @@ -1,16 +1,12 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["LDJ"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX29gameSystem/systemInfo") -async def iidx29gamesystem_systeminfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29gameSystem/systemInfo") +async def iidx29gamesystem_systeminfo(ctx: Ctx): unlock = () # (28008, 28065, 28073, 28088, 28089, 29027, 29094, 29095) sp_dp = (0, 1) @@ -91,5 +87,4 @@ async def iidx29gamesystem_systeminfo(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx29grade.py b/modules/iidx/iidx29grade.py index 85692c2..ea5771d 100644 --- a/modules/iidx/iidx29grade.py +++ b/modules/iidx/iidx29grade.py @@ -1,34 +1,29 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time from tinydb import Query, where -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - +set_xrpc_defaults(service="local2", models=["LDJ"]) def get_profile(iidx_id): return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) - -@router.post("/{gameinfo}/IIDX29grade/raised") -async def iidx29grade_raised(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX29grade/raised") +async def iidx29grade_raised(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - iidx_id = int(request_info["root"][0].attrib["iidxid"]) - achi = int(request_info["root"][0].attrib["achi"]) - cstage = int(request_info["root"][0].attrib["cstage"]) - gid = int(request_info["root"][0].attrib["gid"]) - gtype = int(request_info["root"][0].attrib["gtype"]) - is_ex = int(request_info["root"][0].attrib["is_ex"]) - is_mirror = int(request_info["root"][0].attrib["is_mirror"]) + iidx_id = int(ctx.info["root"][0].attrib["iidxid"]) + achi = int(ctx.info["root"][0].attrib["achi"]) + cstage = int(ctx.info["root"][0].attrib["cstage"]) + gid = int(ctx.info["root"][0].attrib["gid"]) + gtype = int(ctx.info["root"][0].attrib["gtype"]) + is_ex = int(ctx.info["root"][0].attrib["is_ex"]) + is_mirror = int(ctx.info["root"][0].attrib["is_mirror"]) db = get_db() db.table("iidx_class").insert( @@ -106,5 +101,4 @@ async def iidx29grade_raised(request: Request): response = E.response(E.IIDX29grade(pnum=1)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx29lobby.py b/modules/iidx/iidx29lobby.py index c823f97..2f92821 100644 --- a/modules/iidx/iidx29lobby.py +++ b/modules/iidx/iidx29lobby.py @@ -1,68 +1,48 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["LDJ"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX29lobby/entry") -async def iidx29lobby_entry(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29lobby/entry") +async def iidx29lobby_entry(ctx: Ctx): response = E.response(E.IIDX29lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29lobby/update") -async def iidx29lobby_update(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29lobby/update") +async def iidx29lobby_update(ctx: Ctx): response = E.response(E.IIDX29lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29lobby/delete") -async def iidx29lobby_delete(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29lobby/delete") +async def iidx29lobby_delete(ctx: Ctx): response = E.response(E.IIDX29lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29lobby/bplbattle_entry") -async def iidx29lobby_bplbattle_entry(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29lobby/bplbattle_entry") +async def iidx29lobby_bplbattle_entry(ctx: Ctx): response = E.response(E.IIDX29lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29lobby/bplbattle_update") -async def iidx29lobby_bplbattle_update(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29lobby/bplbattle_update") +async def iidx29lobby_bplbattle_update(ctx: Ctx): response = E.response(E.IIDX29lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29lobby/bplbattle_delete") -async def iidx29lobby_bplbattle_delete(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29lobby/bplbattle_delete") +async def iidx29lobby_bplbattle_delete(ctx: Ctx): response = E.response(E.IIDX29lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx29music.py b/modules/iidx/iidx29music.py index 407d144..3160072 100644 --- a/modules/iidx/iidx29music.py +++ b/modules/iidx/iidx29music.py @@ -1,18 +1,14 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time from enum import IntEnum -from fastapi import APIRouter, Request, Response from tinydb import where -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db import config -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - class ClearFlags(IntEnum): NO_PLAY = 0 FAILED = 1 @@ -23,13 +19,13 @@ class ClearFlags(IntEnum): EX_HARD_CLEAR = 6 FULL_COMBO = 7 +set_xrpc_defaults(service="local2", models=["LDJ"]) -@router.post("/{gameinfo}/IIDX29music/getrank") -async def iidx29music_getrank(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX29music/getrank") +async def iidx29music_getrank(ctx: Ctx): + game_version = ctx.info["game_version"] - root = request_info["root"][0] + root = ctx.info["root"][0] play_style = int(root.attrib["cltype"]) @@ -149,14 +145,11 @@ async def iidx29music_getrank(request: Request): assert response is not None - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29music/crate") -async def iidx29music_crate(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX29music/crate") +async def iidx29music_crate(ctx: Ctx): + game_version = ctx.info["game_version"] db = get_db() all_score_stats = db.table("iidx_score_stats").search( @@ -183,23 +176,20 @@ async def iidx29music_crate(request: Request): E.IIDX29music(*[E.c(crate[k] + fcrate[k], mid=k, __type="s32") for k in crate]) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29music/reg") -async def iidx29music_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX29music/reg") +async def iidx29music_reg(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - log = request_info["root"][0].find("music_play_log") + log = ctx.info["root"][0].find("music_play_log") - clear_flg = int(request_info["root"][0].attrib["cflg"]) - clid = int(request_info["root"][0].attrib["clid"]) - is_death = int(request_info["root"][0].attrib["is_death"]) - pid = int(request_info["root"][0].attrib["pid"]) + clear_flg = int(ctx.info["root"][0].attrib["cflg"]) + clid = int(ctx.info["root"][0].attrib["clid"]) + is_death = int(ctx.info["root"][0].attrib["is_death"]) + pid = int(ctx.info["root"][0].attrib["pid"]) play_style = int(log.attrib["play_style"]) ex_score = int(log.attrib["ex_score"]) @@ -396,15 +386,12 @@ async def iidx29music_reg(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX29music/appoint") +async def iidx29music_appoint(ctx: Ctx): -@router.post("/{gameinfo}/IIDX29music/appoint") -async def iidx29music_appoint(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] iidxid = int(root.attrib["iidxid"]) music_id = int(root.attrib["mid"]) @@ -472,5 +459,4 @@ async def iidx29music_appoint(request: Request): response = E.response(E.IIDX29music(*vals)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx29pc.py b/modules/iidx/iidx29pc.py index e1315fd..e90d4d6 100644 --- a/modules/iidx/iidx29pc.py +++ b/modules/iidx/iidx29pc.py @@ -1,37 +1,30 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from tinydb import Query, where import config import random -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - +set_xrpc_defaults(service="local2", models=["LDJ"]) def get_profile(cid): return get_db().table("iidx_profile").get(where("card") == cid) - def get_profile_by_id(iidx_id): return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - def get_game_profile_by_id(iidx_id, game_version): profile = get_profile_by_id(iidx_id) return profile["version"].get(str(game_version), None) - def get_id_from_profile(cid): profile = get_db().table("iidx_profile").get(where("card") == cid) @@ -40,7 +33,6 @@ def get_id_from_profile(cid): return profile["iidx_id"], djid_split - def calculate_folder_mask(profile): return ( profile.get("_show_category_grade", 0) << 0 @@ -56,13 +48,11 @@ def calculate_folder_mask(profile): | (profile.get("_hide_iidx_id", 0) << 12) ) +@xrpc("IIDX29pc/get") +async def iidx29pc_get(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX29pc/get") -async def iidx29pc_get(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - cid = request_info["root"][0].attrib["cid"] + cid = ctx.info["root"][0].attrib["cid"] profile = get_game_profile(cid, game_version) djid, djid_split = get_id_from_profile(cid) @@ -443,13 +433,10 @@ async def iidx29pc_get(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29pc/common") -async def iidx29pc_common(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29pc/common") +async def iidx29pc_common(ctx: Ctx): response = E.response( E.IIDX29pc( @@ -519,18 +506,15 @@ async def iidx29pc_common(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX29pc/save") +async def iidx29pc_save(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX29pc/save") -async def iidx29pc_save(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - xid = int(request_info["root"][0].attrib["iidxid"]) - cid = request_info["root"][0].attrib["cid"] - clt = int(request_info["root"][0].attrib["cltype"]) + xid = int(ctx.info["root"][0].attrib["iidxid"]) + cid = ctx.info["root"][0].attrib["cid"] + clt = int(ctx.info["root"][0].attrib["cltype"]) profile = get_profile(cid) game_profile = profile["version"].get(str(game_version), {}) @@ -589,8 +573,8 @@ async def iidx29pc_save(request: Request): "s_tsujigiri_disp", "sp_opt", ]: - if k in request_info["root"][0].attrib: - game_profile[k] = request_info["root"][0].attrib[k] + if k in ctx.info["root"][0].attrib: + game_profile[k] = ctx.info["root"][0].attrib[k] for k in [ ("d_liflen", "d_lift"), @@ -598,10 +582,10 @@ async def iidx29pc_save(request: Request): ("s_liflen", "s_lift"), ("sach", "s_achi"), ]: - if k[1] in request_info["root"][0].attrib: - game_profile[k[0]] = request_info["root"][0].attrib[k[1]] + if k[1] in ctx.info["root"][0].attrib: + game_profile[k[0]] = ctx.info["root"][0].attrib[k[1]] - lightning_setting = request_info["root"][0].find("lightning_setting") + lightning_setting = ctx.info["root"][0].find("lightning_setting") if lightning_setting is not None: for k in [ "headphone_vol", @@ -628,7 +612,7 @@ async def iidx29pc_save(request: Request): if concentration is not None: game_profile["lightning_setting_concentration"] = int(concentration.text) - lightning_customize_flg = request_info["root"][0].find("lightning_customize_flg") + lightning_customize_flg = ctx.info["root"][0].find("lightning_customize_flg") if lightning_customize_flg is not None: for k in [ "flg_skin_0", @@ -637,21 +621,21 @@ async def iidx29pc_save(request: Request): lightning_customize_flg.attrib[k] ) - secret = request_info["root"][0].find("secret") + secret = ctx.info["root"][0].find("secret") if secret is not None: for k in ["flg1", "flg2", "flg3", "flg4"]: flg = secret.find(k) if flg is not None: game_profile["secret_" + k] = [int(x) for x in flg.text.split(" ")] - leggendaria = request_info["root"][0].find("leggendaria") + leggendaria = ctx.info["root"][0].find("leggendaria") if leggendaria is not None: for k in ["flg1"]: flg = leggendaria.find(k) if flg is not None: game_profile["leggendaria_" + k] = [int(x) for x in flg.text.split(" ")] - step = request_info["root"][0].find("step") + step = ctx.info["root"][0].find("step") if step is not None: for k in [ "dp_level", @@ -671,7 +655,7 @@ async def iidx29pc_save(request: Request): if is_track_ticket is not None: game_profile["stepup_is_track_ticket"] = int(is_track_ticket.text) - dj_ranks = request_info["root"][0].findall("dj_rank") + dj_ranks = ctx.info["root"][0].findall("dj_rank") dj_ranks = [] if dj_ranks is None else dj_ranks for dj_rank in dj_ranks: style = int(dj_rank.attrib["style"]) @@ -686,7 +670,7 @@ async def iidx29pc_save(request: Request): int(x) for x in point.text.split(" ") ] - notes_radars = request_info["root"][0].findall("notes_radar") + notes_radars = ctx.info["root"][0].findall("notes_radar") notes_radars = [] if notes_radars is None else notes_radars for notes_radar in notes_radars: style = int(notes_radar.attrib["style"]) @@ -695,7 +679,7 @@ async def iidx29pc_save(request: Request): int(x) for x in score.text.split(" ") ] - achievements = request_info["root"][0].find("achievements") + achievements = ctx.info["root"][0].find("achievements") if achievements is not None: for k in [ "last_weekly", @@ -714,7 +698,7 @@ async def iidx29pc_save(request: Request): int(x) for x in trophy.text.split(" ") ] - grade = request_info["root"][0].find("grade") + grade = ctx.info["root"][0].find("grade") if grade is not None: grade_values = [] for g in grade.findall("g"): @@ -725,12 +709,12 @@ async def iidx29pc_save(request: Request): profile["grade_values"] = grade_values deller_amount = game_profile.get("deller", 0) - deller = request_info["root"][0].find("deller") + deller = ctx.info["root"][0].find("deller") if deller is not None: deller_amount = int(deller.attrib["deller"]) game_profile["deller"] = deller_amount - language = request_info["root"][0].find("language_setting") + language = ctx.info["root"][0].find("language_setting") if language is not None: language_value = int(language.attrib["language"]) game_profile["language_setting"] = language_value @@ -738,7 +722,7 @@ async def iidx29pc_save(request: Request): game_profile["spnum"] = game_profile.get("spnum", 0) + (1 if clt == 0 else 0) game_profile["dpnum"] = game_profile.get("dpnum", 0) + (1 if clt == 1 else 0) - if request_info["model"] == "TDJ": + if ctx.info["model"] == "TDJ": game_profile["lightning_play_data_spnum"] = game_profile.get( "lightning_play_data_spnum", 0 ) + (1 if clt == 0 else 0) @@ -752,13 +736,10 @@ async def iidx29pc_save(request: Request): response = E.response(E.IIDX29pc(iidxid=xid, cltype=clt)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29pc/visit") -async def iidx29pc_visit(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29pc/visit") +async def iidx29pc_visit(ctx: Ctx): response = E.response( E.IIDX29pc( @@ -771,18 +752,15 @@ async def iidx29pc_visit(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX29pc/reg") +async def iidx29pc_reg(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX29pc/reg") -async def iidx29pc_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - cid = request_info["root"][0].attrib["cid"] - name = request_info["root"][0].attrib["name"] - pid = request_info["root"][0].attrib["pid"] + cid = ctx.info["root"][0].attrib["cid"] + name = ctx.info["root"][0].attrib["name"] + pid = ctx.info["root"][0].attrib["pid"] db = get_db().table("iidx_profile") all_profiles_for_card = db.get(Query().card == cid) @@ -979,13 +957,10 @@ async def iidx29pc_reg(request: Request): response = E.response(E.IIDX29pc(id=card, id_str=card_split)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29pc/getLaneGachaTicket") -async def iidx29pc_getlanegachaticket(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29pc/getLaneGachaTicket") +async def iidx29pc_getlanegachaticket(ctx: Ctx): response = E.response( E.IIDX29pc( @@ -1011,13 +986,10 @@ async def iidx29pc_getlanegachaticket(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29pc/drawLaneGacha") -async def iidx29pc_drawlanegacha(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29pc/drawLaneGacha") +async def iidx29pc_drawlanegacha(ctx: Ctx): response = E.response( E.IIDX29pc( @@ -1031,25 +1003,18 @@ async def iidx29pc_drawlanegacha(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29pc/eaappliresult") -async def iidx29pc_eaappliresult(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29pc/eaappliresult") +async def iidx29pc_eaappliresult(ctx: Ctx): response = E.response(E.IIDX29pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29pc/logout") -async def iidx29pc_logout(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29pc/logout") +async def iidx29pc_logout(ctx: Ctx): response = E.response(E.IIDX29pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx29ranking.py b/modules/iidx/iidx29ranking.py index 8f3f9a3..084c0c5 100644 --- a/modules/iidx/iidx29ranking.py +++ b/modules/iidx/iidx29ranking.py @@ -1,18 +1,13 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["LDJ"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX29ranking/getranker") -async def iidx29ranking_getranker(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29ranking/getranker") +async def iidx29ranking_getranker(ctx: Ctx): response = E.response(E.IIDX29ranking()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx29shop.py b/modules/iidx/iidx29shop.py index 4d8c0a7..9266f0a 100644 --- a/modules/iidx/iidx29shop.py +++ b/modules/iidx/iidx29shop.py @@ -1,16 +1,12 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["LDJ"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX29shop/getname") -async def iidx29shop_getname(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29shop/getname") +async def iidx29shop_getname(ctx: Ctx): response = E.response( E.IIDX29shop( @@ -20,13 +16,10 @@ async def iidx29shop_getname(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29shop/getconvention") -async def iidx29shop_getconvention(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29shop/getconvention") +async def iidx29shop_getconvention(ctx: Ctx): response = E.response( E.IIDX29shop( @@ -40,25 +33,18 @@ async def iidx29shop_getconvention(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29shop/sentinfo") -async def iidx29shop_sentinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29shop/sentinfo") +async def iidx29shop_sentinfo(ctx: Ctx): response = E.response(E.IIDX29shop()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX29shop/sendescapepackageinfo") -async def iidx29shop_sendescapepackageinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX29shop/sendescapepackageinfo") +async def iidx29shop_sendescapepackageinfo(ctx: Ctx): response = E.response(E.IIDX29shop(expire=1200)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx30gamesystem.py b/modules/iidx/iidx30gamesystem.py index 190b81a..8fe0271 100644 --- a/modules/iidx/iidx30gamesystem.py +++ b/modules/iidx/iidx30gamesystem.py @@ -1,18 +1,14 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from time import time import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["LDJ"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX30gameSystem/systemInfo") -async def iidx30gamesystem_systeminfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30gameSystem/systemInfo") +async def iidx30gamesystem_systeminfo(ctx: Ctx): unlock = () # force unlock LM exclusives to complete unlock all songs server side @@ -89,5 +85,4 @@ async def iidx30gamesystem_systeminfo(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx30grade.py b/modules/iidx/iidx30grade.py index 6eaa720..023835f 100644 --- a/modules/iidx/iidx30grade.py +++ b/modules/iidx/iidx30grade.py @@ -1,34 +1,29 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time from tinydb import Query, where -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - +set_xrpc_defaults(service="local2", models=["LDJ"]) def get_profile(iidx_id): return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) - -@router.post("/{gameinfo}/IIDX30grade/raised") -async def iidx30grade_raised(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX30grade/raised") +async def iidx30grade_raised(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - iidx_id = int(request_info["root"][0].attrib["iidxid"]) - achi = int(request_info["root"][0].attrib["achi"]) - cstage = int(request_info["root"][0].attrib["cstage"]) - gid = int(request_info["root"][0].attrib["gid"]) - gtype = int(request_info["root"][0].attrib["gtype"]) - is_ex = int(request_info["root"][0].attrib["is_ex"]) - is_mirror = int(request_info["root"][0].attrib["is_mirror"]) + iidx_id = int(ctx.info["root"][0].attrib["iidxid"]) + achi = int(ctx.info["root"][0].attrib["achi"]) + cstage = int(ctx.info["root"][0].attrib["cstage"]) + gid = int(ctx.info["root"][0].attrib["gid"]) + gtype = int(ctx.info["root"][0].attrib["gtype"]) + is_ex = int(ctx.info["root"][0].attrib["is_ex"]) + is_mirror = int(ctx.info["root"][0].attrib["is_mirror"]) db = get_db() db.table("iidx_class").insert( @@ -112,5 +107,4 @@ async def iidx30grade_raised(request: Request): response = E.response(E.IIDX30grade(pnum=1)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx30lobby.py b/modules/iidx/iidx30lobby.py index 78e48c2..908a374 100644 --- a/modules/iidx/iidx30lobby.py +++ b/modules/iidx/iidx30lobby.py @@ -1,24 +1,19 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from time import time import config -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E - -router = APIRouter(prefix="/lobby", tags=["lobby"]) -router.model_whitelist = ["LDJ"] - +from core_common import E arena_host = {} bpl_host = {} +set_xrpc_defaults(service="lobby", models=["LDJ"]) -@router.post("/{gameinfo}/IIDX30lobby/entry") -async def iidx30lobby_entry(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30lobby/entry") +async def iidx30lobby_entry(ctx: Ctx): - root = request_info["root"][0] + root = ctx.info["root"][0] sp_dp = root.find("play_style").text arena_class = root.find("arena_class").text ga = root.find("address/ga").text.split() @@ -60,23 +55,17 @@ async def iidx30lobby_entry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30lobby/update") -async def iidx30lobby_update(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30lobby/update") +async def iidx30lobby_update(ctx: Ctx): response = E.response(E.IIDX30lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30lobby/delete") -async def iidx30lobby_delete(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30lobby/delete") +async def iidx30lobby_delete(ctx: Ctx): # normal reset del arena_host["ga"] @@ -85,15 +74,12 @@ async def iidx30lobby_delete(request: Request): del arena_host["time"] response = E.response(E.IIDX30lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX30lobby/bplbattle_entry") +async def iidx30lobby_bplbattle_entry(ctx: Ctx): -@router.post("/{gameinfo}/IIDX30lobby/bplbattle_entry") -async def iidx30lobby_bplbattle_entry(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] sp_dp = root.find("play_style").text arena_class = root.find("arena_class").text password = root.find("passward").text # passward @@ -137,25 +123,19 @@ async def iidx30lobby_bplbattle_entry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30lobby/bplbattle_update") -async def iidx30lobby_bplbattle_update(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30lobby/bplbattle_update") +async def iidx30lobby_bplbattle_update(ctx: Ctx): response = E.response(E.IIDX30lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX30lobby/bplbattle_delete") +async def iidx30lobby_bplbattle_delete(ctx: Ctx): -@router.post("/{gameinfo}/IIDX30lobby/bplbattle_delete") -async def iidx30lobby_bplbattle_delete(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] ga = root.find("address/ga").text.split() # normal reset @@ -165,5 +145,4 @@ async def iidx30lobby_bplbattle_delete(request: Request): break response = E.response(E.IIDX30lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx30music.py b/modules/iidx/iidx30music.py index 28be389..0f852da 100644 --- a/modules/iidx/iidx30music.py +++ b/modules/iidx/iidx30music.py @@ -1,19 +1,15 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time import random from enum import IntEnum -from fastapi import APIRouter, Request, Response from tinydb import where -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db import config -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - class ClearFlags(IntEnum): NO_PLAY = 0 FAILED = 1 @@ -24,13 +20,13 @@ class ClearFlags(IntEnum): EX_HARD_CLEAR = 6 FULL_COMBO = 7 +set_xrpc_defaults(service="local2", models=["LDJ"]) -@router.post("/{gameinfo}/IIDX30music/getrank") -async def iidx30music_getrank(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX30music/getrank") +async def iidx30music_getrank(ctx: Ctx): + game_version = ctx.info["game_version"] - root = request_info["root"][0] + root = ctx.info["root"][0] play_style = int(root.attrib["cltype"]) @@ -151,14 +147,11 @@ async def iidx30music_getrank(request: Request): assert response is not None - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30music/crate") -async def iidx30music_crate(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX30music/crate") +async def iidx30music_crate(ctx: Ctx): + game_version = ctx.info["game_version"] db = get_db() all_score_stats = db.table("iidx_score_stats").search( @@ -185,23 +178,20 @@ async def iidx30music_crate(request: Request): E.IIDX30music(*[E.c(crate[k] + fcrate[k], mid=k, __type="s32") for k in crate]) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30music/reg") -async def iidx30music_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX30music/reg") +async def iidx30music_reg(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - log = request_info["root"][0].find("music_play_log") + log = ctx.info["root"][0].find("music_play_log") - clear_flg = int(request_info["root"][0].attrib["cflg"]) - clid = int(request_info["root"][0].attrib["clid"]) - is_death = int(request_info["root"][0].attrib["is_death"]) - pid = int(request_info["root"][0].attrib["pid"]) + clear_flg = int(ctx.info["root"][0].attrib["cflg"]) + clid = int(ctx.info["root"][0].attrib["clid"]) + is_death = int(ctx.info["root"][0].attrib["is_death"]) + pid = int(ctx.info["root"][0].attrib["pid"]) play_style = int(log.attrib["play_style"]) ex_score = int(log.attrib["ex_score"]) @@ -398,15 +388,12 @@ async def iidx30music_reg(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX30music/appoint") +async def iidx30music_appoint(ctx: Ctx): -@router.post("/{gameinfo}/IIDX30music/appoint") -async def iidx30music_appoint(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] iidxid = int(root.attrib["iidxid"]) music_id = int(root.attrib["mid"]) @@ -474,15 +461,12 @@ async def iidx30music_appoint(request: Request): response = E.response(E.IIDX30music(*vals)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX30music/arenaCPU") +async def iidx30music_arenacpu(ctx: Ctx): -@router.post("/{gameinfo}/IIDX30music/arenaCPU") -async def iidx30music_arenacpu(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] music_list = root.findall("music_list") music_count = len(music_list) cpu_list = root.findall("cpu_list") @@ -533,13 +517,10 @@ async def iidx30music_arenacpu(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30music/retry") -async def iidx30music_retry(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30music/retry") +async def iidx30music_retry(ctx: Ctx): response = E.response( E.IIDX30music( @@ -548,32 +529,24 @@ async def iidx30music_retry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30music/play") -async def iidx30music_play(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30music/play") +async def iidx30music_play(ctx: Ctx): response = E.response(E.IIDX30music()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30music/nosave") -async def iidx30music_nosave(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30music/nosave") +async def iidx30music_nosave(ctx: Ctx): response = E.response(E.IIDX30music()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response -@router.post("/{gameinfo}/IIDX30music/movieinfo") -async def iidx30music_movieinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30music/movieinfo") +async def iidx30music_movieinfo(ctx: Ctx): response = E.response( E.IIDX30music( @@ -581,5 +554,4 @@ async def iidx30music_movieinfo(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx30pc.py b/modules/iidx/iidx30pc.py index 62282b8..3e91ab9 100644 --- a/modules/iidx/iidx30pc.py +++ b/modules/iidx/iidx30pc.py @@ -1,38 +1,31 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from tinydb import Query, where from time import time import config import random -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - +set_xrpc_defaults(service="local2", models=["LDJ"]) def get_profile(cid): return get_db().table("iidx_profile").get(where("card") == cid) - def get_profile_by_id(iidx_id): return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - def get_game_profile_by_id(iidx_id, game_version): profile = get_profile_by_id(iidx_id) return profile["version"].get(str(game_version), None) - def get_id_from_profile(cid): profile = get_db().table("iidx_profile").get(where("card") == cid) @@ -41,7 +34,6 @@ def get_id_from_profile(cid): return profile["iidx_id"], djid_split - def calculate_folder_mask(profile): return ( profile.get("_show_category_grade", 0) << 0 @@ -57,13 +49,11 @@ def calculate_folder_mask(profile): | (profile.get("_hide_iidx_id", 0) << 12) ) +@xrpc("IIDX30pc/get") +async def iidx30pc_get(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX30pc/get") -async def iidx30pc_get(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - cid = request_info["root"][0].attrib["cid"] + cid = ctx.info["root"][0].attrib["cid"] profile = get_game_profile(cid, game_version) djid, djid_split = get_id_from_profile(cid) @@ -716,13 +706,10 @@ async def iidx30pc_get(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30pc/common") -async def iidx30pc_common(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30pc/common") +async def iidx30pc_common(ctx: Ctx): response = E.response( E.IIDX30pc( @@ -758,7 +745,7 @@ async def iidx30pc_common(request: Request): E.movie_agreement(version=1), E.license("None", __type="str"), E.file_recovery(url=str(config.ip)), - E.movie_upload(url=f"http://{str(request.client.host)}:4399/movie/"), # use https://github.com/bookqaq/010-record-api + E.movie_upload(url=f"http://{str(ctx.request.client.host)}:4399/movie/"), # use https://github.com/bookqaq/010-record-api # E.button_release_frame(frame=''), # E.trigger_logic_type(type=''), # E.cm_movie_info(type=''), @@ -794,18 +781,15 @@ async def iidx30pc_common(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX30pc/save") +async def iidx30pc_save(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX30pc/save") -async def iidx30pc_save(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - xid = int(request_info["root"][0].attrib["iidxid"]) - cid = request_info["root"][0].attrib["cid"] - clt = int(request_info["root"][0].attrib["cltype"]) + xid = int(ctx.info["root"][0].attrib["iidxid"]) + cid = ctx.info["root"][0].attrib["cid"] + clt = int(ctx.info["root"][0].attrib["cltype"]) profile = get_profile(cid) game_profile = profile["version"].get(str(game_version), {}) @@ -868,8 +852,8 @@ async def iidx30pc_save(request: Request): "s_visualization", "sp_opt", ]: - if k in request_info["root"][0].attrib: - game_profile[k] = request_info["root"][0].attrib[k] + if k in ctx.info["root"][0].attrib: + game_profile[k] = ctx.info["root"][0].attrib[k] for k in [ ("d_liflen", "d_lift"), @@ -877,10 +861,10 @@ async def iidx30pc_save(request: Request): ("s_liflen", "s_lift"), ("sach", "s_achi"), ]: - if k[1] in request_info["root"][0].attrib: - game_profile[k[0]] = request_info["root"][0].attrib[k[1]] + if k[1] in ctx.info["root"][0].attrib: + game_profile[k[0]] = ctx.info["root"][0].attrib[k[1]] - lightning_setting = request_info["root"][0].find("lightning_setting") + lightning_setting = ctx.info["root"][0].find("lightning_setting") if lightning_setting is not None: for k in [ "headphone_vol", @@ -907,17 +891,17 @@ async def iidx30pc_save(request: Request): if concentration is not None: game_profile["lightning_setting_concentration"] = int(concentration.text) - movie_agreement = request_info["root"][0].find("movie_agreement") + movie_agreement = ctx.info["root"][0].find("movie_agreement") if movie_agreement is not None and "agreement_version" in movie_agreement.attrib: game_profile["movie_agreement"] = int( movie_agreement.attrib["agreement_version"] ) - hide_name = request_info["root"][0].find("movie_setting/hide_name") + hide_name = ctx.info["root"][0].find("movie_setting/hide_name") if hide_name is not None: game_profile["hide_name"] = int(hide_name.text) - lightning_customize_flg = request_info["root"][0].find("lightning_customize_flg") + lightning_customize_flg = ctx.info["root"][0].find("lightning_customize_flg") if lightning_customize_flg is not None: for k in [ "flg_skin_0", @@ -926,21 +910,21 @@ async def iidx30pc_save(request: Request): lightning_customize_flg.attrib[k] ) - secret = request_info["root"][0].find("secret") + secret = ctx.info["root"][0].find("secret") if secret is not None: for k in ["flg1", "flg2", "flg3", "flg4"]: flg = secret.find(k) if flg is not None: game_profile["secret_" + k] = [int(x) for x in flg.text.split(" ")] - leggendaria = request_info["root"][0].find("leggendaria") + leggendaria = ctx.info["root"][0].find("leggendaria") if leggendaria is not None: for k in ["flg1"]: flg = leggendaria.find(k) if flg is not None: game_profile["leggendaria_" + k] = [int(x) for x in flg.text.split(" ")] - step = request_info["root"][0].find("step") + step = ctx.info["root"][0].find("step") if step is not None: for k in [ "dp_fluctuation", @@ -962,7 +946,7 @@ async def iidx30pc_save(request: Request): if is_track_ticket is not None: game_profile["stepup_is_track_ticket"] = int(is_track_ticket.text) - dj_ranks = request_info["root"][0].findall("dj_rank") + dj_ranks = ctx.info["root"][0].findall("dj_rank") dj_ranks = [] if dj_ranks is None else dj_ranks for dj_rank in dj_ranks: style = int(dj_rank.attrib["style"]) @@ -977,7 +961,7 @@ async def iidx30pc_save(request: Request): int(x) for x in point.text.split(" ") ] - notes_radars = request_info["root"][0].findall("notes_radar") + notes_radars = ctx.info["root"][0].findall("notes_radar") notes_radars = [] if notes_radars is None else notes_radars for notes_radar in notes_radars: style = int(notes_radar.attrib["style"]) @@ -986,7 +970,7 @@ async def iidx30pc_save(request: Request): int(x) for x in score.text.split(" ") ] - achievements = request_info["root"][0].find("achievements") + achievements = ctx.info["root"][0].find("achievements") if achievements is not None: for k in [ "last_weekly", @@ -1005,7 +989,7 @@ async def iidx30pc_save(request: Request): int(x) for x in trophy.text.split(" ") ] - grade = request_info["root"][0].find("grade") + grade = ctx.info["root"][0].find("grade") if grade is not None: grade_values = [] for g in grade.findall("g"): @@ -1016,12 +1000,12 @@ async def iidx30pc_save(request: Request): profile["grade_values"] = grade_values deller_amount = game_profile.get("deller", 0) - deller = request_info["root"][0].find("deller") + deller = ctx.info["root"][0].find("deller") if deller is not None: deller_amount = int(deller.attrib["deller"]) game_profile["deller"] = deller_amount - language = request_info["root"][0].find("language_setting") + language = ctx.info["root"][0].find("language_setting") if language is not None: language_value = int(language.attrib["language"]) game_profile["language_setting"] = language_value @@ -1029,7 +1013,7 @@ async def iidx30pc_save(request: Request): game_profile["spnum"] = game_profile.get("spnum", 0) + (1 if clt == 0 else 0) game_profile["dpnum"] = game_profile.get("dpnum", 0) + (1 if clt == 1 else 0) - if request_info["model"] == "TDJ": + if ctx.info["model"] == "TDJ": game_profile["lightning_play_data_spnum"] = game_profile.get( "lightning_play_data_spnum", 0 ) + (1 if clt == 0 else 0) @@ -1043,13 +1027,10 @@ async def iidx30pc_save(request: Request): response = E.response(E.IIDX30pc(iidxid=xid, cltype=clt)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30pc/visit") -async def iidx30pc_visit(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30pc/visit") +async def iidx30pc_visit(ctx: Ctx): response = E.response( E.IIDX30pc( @@ -1062,18 +1043,15 @@ async def iidx30pc_visit(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX30pc/reg") +async def iidx30pc_reg(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX30pc/reg") -async def iidx30pc_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - cid = request_info["root"][0].attrib["cid"] - name = request_info["root"][0].attrib["name"] - pid = request_info["root"][0].attrib["pid"] + cid = ctx.info["root"][0].attrib["cid"] + name = ctx.info["root"][0].attrib["name"] + pid = ctx.info["root"][0].attrib["pid"] db = get_db().table("iidx_profile") all_profiles_for_card = db.get(Query().card == cid) @@ -1270,13 +1248,10 @@ async def iidx30pc_reg(request: Request): response = E.response(E.IIDX30pc(id=card, id_str=card_split)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30pc/getLaneGachaTicket") -async def iidx30pc_getlanegachaticket(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30pc/getLaneGachaTicket") +async def iidx30pc_getlanegachaticket(ctx: Ctx): response = E.response( E.IIDX30pc( @@ -1305,23 +1280,17 @@ async def iidx30pc_getlanegachaticket(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30pc/consumeLaneGachaTicket") -async def iidx30pc_consumelanegachaticket(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30pc/consumeLaneGachaTicket") +async def iidx30pc_consumelanegachaticket(ctx: Ctx): response = E.response(E.IIDX30pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30pc/drawLaneGacha") -async def iidx30pc_drawlanegacha(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30pc/drawLaneGacha") +async def iidx30pc_drawlanegacha(ctx: Ctx): response = E.response( E.IIDX30pc( @@ -1335,54 +1304,39 @@ async def iidx30pc_drawlanegacha(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30pc/eaappliresult") -async def iidx30pc_eaappliresult(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30pc/eaappliresult") +async def iidx30pc_eaappliresult(ctx: Ctx): response = E.response(E.IIDX30pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30pc/playstart") -async def iidx30pc_playstart(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30pc/playstart") +async def iidx30pc_playstart(ctx: Ctx): response = E.response(E.IIDX30pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30pc/playend") -async def iidx30pc_playend(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30pc/playend") +async def iidx30pc_playend(ctx: Ctx): response = E.response(E.IIDX30pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30pc/delete") -async def iidx30pc_delete(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30pc/delete") +async def iidx30pc_delete(ctx: Ctx): response = E.response(E.IIDX30pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response -@router.post("/{gameinfo}/IIDX30pc/logout") -async def iidx30pc_logout(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30pc/logout") +async def iidx30pc_logout(ctx: Ctx): response = E.response(E.IIDX30pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx30ranking.py b/modules/iidx/iidx30ranking.py index aaed077..ebd3479 100644 --- a/modules/iidx/iidx30ranking.py +++ b/modules/iidx/iidx30ranking.py @@ -1,18 +1,13 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["LDJ"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX30ranking/getranker") -async def iidx30ranking_getranker(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30ranking/getranker") +async def iidx30ranking_getranker(ctx: Ctx): response = E.response(E.IIDX30ranking()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx30shop.py b/modules/iidx/iidx30shop.py index a60d6bc..259baa1 100644 --- a/modules/iidx/iidx30shop.py +++ b/modules/iidx/iidx30shop.py @@ -1,16 +1,12 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["LDJ"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX30shop/getname") -async def iidx30shop_getname(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30shop/getname") +async def iidx30shop_getname(ctx: Ctx): response = E.response( E.IIDX30shop( @@ -20,13 +16,10 @@ async def iidx30shop_getname(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30shop/getconvention") -async def iidx30shop_getconvention(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30shop/getconvention") +async def iidx30shop_getconvention(ctx: Ctx): response = E.response( E.IIDX30shop( @@ -40,25 +33,18 @@ async def iidx30shop_getconvention(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30shop/sentinfo") -async def iidx30shop_sentinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30shop/sentinfo") +async def iidx30shop_sentinfo(ctx: Ctx): response = E.response(E.IIDX30shop()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX30shop/sendescapepackageinfo") -async def iidx30shop_sendescapepackageinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX30shop/sendescapepackageinfo") +async def iidx30shop_sendescapepackageinfo(ctx: Ctx): response = E.response(E.IIDX30shop(expire=1200)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx31gamesystem.py b/modules/iidx/iidx31gamesystem.py index d3f8f46..8ac0a01 100644 --- a/modules/iidx/iidx31gamesystem.py +++ b/modules/iidx/iidx31gamesystem.py @@ -1,18 +1,14 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from time import time import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["LDJ"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX31gameSystem/systemInfo") -async def iidx31gamesystem_systeminfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31gameSystem/systemInfo") +async def iidx31gamesystem_systeminfo(ctx: Ctx): unlock = () # force unlock LM exclusives to complete unlock all songs server side @@ -198,5 +194,4 @@ async def iidx31gamesystem_systeminfo(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx31grade.py b/modules/iidx/iidx31grade.py index 6e87262..9491bf9 100644 --- a/modules/iidx/iidx31grade.py +++ b/modules/iidx/iidx31grade.py @@ -1,34 +1,29 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time from tinydb import Query, where -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - +set_xrpc_defaults(service="local2", models=["LDJ"]) def get_profile(iidx_id): return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) - -@router.post("/{gameinfo}/IIDX31grade/raised") -async def iidx31grade_raised(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX31grade/raised") +async def iidx31grade_raised(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - iidx_id = int(request_info["root"][0].attrib["iidxid"]) - achi = int(request_info["root"][0].attrib["achi"]) - cstage = int(request_info["root"][0].attrib["cstage"]) - gid = int(request_info["root"][0].attrib["gid"]) - gtype = int(request_info["root"][0].attrib["gtype"]) - is_ex = int(request_info["root"][0].attrib["is_ex"]) - is_mirror = int(request_info["root"][0].attrib["is_mirror"]) + iidx_id = int(ctx.info["root"][0].attrib["iidxid"]) + achi = int(ctx.info["root"][0].attrib["achi"]) + cstage = int(ctx.info["root"][0].attrib["cstage"]) + gid = int(ctx.info["root"][0].attrib["gid"]) + gtype = int(ctx.info["root"][0].attrib["gtype"]) + is_ex = int(ctx.info["root"][0].attrib["is_ex"]) + is_mirror = int(ctx.info["root"][0].attrib["is_mirror"]) db = get_db() db.table("iidx_class").insert( @@ -112,5 +107,4 @@ async def iidx31grade_raised(request: Request): response = E.response(E.IIDX31grade(pnum=1)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx31lobby.py b/modules/iidx/iidx31lobby.py index 7e897e0..d3d37e3 100644 --- a/modules/iidx/iidx31lobby.py +++ b/modules/iidx/iidx31lobby.py @@ -1,24 +1,19 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from time import time import config -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E - -router = APIRouter(prefix="/lobby", tags=["lobby"]) -router.model_whitelist = ["LDJ"] - +from core_common import E arena_host = {} bpl_host = {} +set_xrpc_defaults(service="lobby", models=["LDJ"]) -@router.post("/{gameinfo}/IIDX31lobby/entry") -async def iidx31lobby_entry(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31lobby/entry") +async def iidx31lobby_entry(ctx: Ctx): - root = request_info["root"][0] + root = ctx.info["root"][0] sp_dp = root.find("play_style").text arena_class = root.find("arena_class").text ga = root.find("address/ga").text.split() @@ -60,23 +55,17 @@ async def iidx31lobby_entry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31lobby/update") -async def iidx31lobby_update(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31lobby/update") +async def iidx31lobby_update(ctx: Ctx): response = E.response(E.IIDX31lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31lobby/delete") -async def iidx31lobby_delete(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31lobby/delete") +async def iidx31lobby_delete(ctx: Ctx): # normal reset del arena_host["ga"] @@ -85,15 +74,12 @@ async def iidx31lobby_delete(request: Request): del arena_host["time"] response = E.response(E.IIDX31lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX31lobby/bplbattle_entry") +async def iidx31lobby_bplbattle_entry(ctx: Ctx): -@router.post("/{gameinfo}/IIDX31lobby/bplbattle_entry") -async def iidx31lobby_bplbattle_entry(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] sp_dp = root.find("play_style").text arena_class = root.find("arena_class").text password = root.find("passward").text # passward @@ -137,25 +123,19 @@ async def iidx31lobby_bplbattle_entry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31lobby/bplbattle_update") -async def iidx31lobby_bplbattle_update(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31lobby/bplbattle_update") +async def iidx31lobby_bplbattle_update(ctx: Ctx): response = E.response(E.IIDX31lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX31lobby/bplbattle_delete") +async def iidx31lobby_bplbattle_delete(ctx: Ctx): -@router.post("/{gameinfo}/IIDX31lobby/bplbattle_delete") -async def iidx31lobby_bplbattle_delete(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] ga = root.find("address/ga").text.split() # normal reset @@ -165,5 +145,4 @@ async def iidx31lobby_bplbattle_delete(request: Request): break response = E.response(E.IIDX31lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx31music.py b/modules/iidx/iidx31music.py index ecb2d97..fcde8e3 100644 --- a/modules/iidx/iidx31music.py +++ b/modules/iidx/iidx31music.py @@ -1,19 +1,15 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time import random from enum import IntEnum -from fastapi import APIRouter, Request, Response from tinydb import where -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db import config -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - class ClearFlags(IntEnum): NO_PLAY = 0 FAILED = 1 @@ -24,13 +20,13 @@ class ClearFlags(IntEnum): EX_HARD_CLEAR = 6 FULL_COMBO = 7 +set_xrpc_defaults(service="local2", models=["LDJ"]) -@router.post("/{gameinfo}/IIDX31music/getrank") -async def iidx31music_getrank(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX31music/getrank") +async def iidx31music_getrank(ctx: Ctx): + game_version = ctx.info["game_version"] - root = request_info["root"][0] + root = ctx.info["root"][0] play_style = int(root.attrib["cltype"]) @@ -151,14 +147,11 @@ async def iidx31music_getrank(request: Request): assert response is not None - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31music/crate") -async def iidx31music_crate(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX31music/crate") +async def iidx31music_crate(ctx: Ctx): + game_version = ctx.info["game_version"] db = get_db() all_score_stats = db.table("iidx_score_stats").search( @@ -185,23 +178,20 @@ async def iidx31music_crate(request: Request): E.IIDX31music(*[E.c(crate[k] + fcrate[k], mid=k, __type="s32") for k in crate]) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31music/reg") -async def iidx31music_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX31music/reg") +async def iidx31music_reg(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - log = request_info["root"][0].find("music_play_log") + log = ctx.info["root"][0].find("music_play_log") - clear_flg = int(request_info["root"][0].attrib["cflg"]) - clid = int(request_info["root"][0].attrib["clid"]) - is_death = int(request_info["root"][0].attrib["is_death"]) - pid = int(request_info["root"][0].attrib["pid"]) + clear_flg = int(ctx.info["root"][0].attrib["cflg"]) + clid = int(ctx.info["root"][0].attrib["clid"]) + is_death = int(ctx.info["root"][0].attrib["is_death"]) + pid = int(ctx.info["root"][0].attrib["pid"]) play_style = int(log.attrib["play_style"]) ex_score = int(log.attrib["ex_score"]) @@ -400,15 +390,12 @@ async def iidx31music_reg(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX31music/appoint") +async def iidx31music_appoint(ctx: Ctx): -@router.post("/{gameinfo}/IIDX31music/appoint") -async def iidx31music_appoint(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] iidxid = int(root.attrib["iidxid"]) music_id = int(root.attrib["mid"]) @@ -476,15 +463,12 @@ async def iidx31music_appoint(request: Request): response = E.response(E.IIDX31music(*vals)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX31music/arenaCPU") +async def iidx31music_arenacpu(ctx: Ctx): -@router.post("/{gameinfo}/IIDX31music/arenaCPU") -async def iidx31music_arenacpu(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] music_list = root.findall("music_list") music_count = len(music_list) cpu_list = root.findall("cpu_list") @@ -535,13 +519,10 @@ async def iidx31music_arenacpu(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31music/retry") -async def iidx31music_retry(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31music/retry") +async def iidx31music_retry(ctx: Ctx): response = E.response( E.IIDX31music( @@ -550,32 +531,24 @@ async def iidx31music_retry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31music/play") -async def iidx31music_play(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31music/play") +async def iidx31music_play(ctx: Ctx): response = E.response(E.IIDX31music()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31music/nosave") -async def iidx31music_nosave(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31music/nosave") +async def iidx31music_nosave(ctx: Ctx): response = E.response(E.IIDX31music()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response -@router.post("/{gameinfo}/IIDX31music/movieinfo") -async def iidx31music_movieinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31music/movieinfo") +async def iidx31music_movieinfo(ctx: Ctx): response = E.response( E.IIDX31music( @@ -583,5 +556,4 @@ async def iidx31music_movieinfo(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx31pc.py b/modules/iidx/iidx31pc.py index 33932cf..acc408c 100644 --- a/modules/iidx/iidx31pc.py +++ b/modules/iidx/iidx31pc.py @@ -1,38 +1,31 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from tinydb import Query, where from time import time import config import random -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - +set_xrpc_defaults(service="local2", models=["LDJ"]) def get_profile(cid): return get_db().table("iidx_profile").get(where("card") == cid) - def get_profile_by_id(iidx_id): return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - def get_game_profile_by_id(iidx_id, game_version): profile = get_profile_by_id(iidx_id) return profile["version"].get(str(game_version), None) - def get_id_from_profile(cid): profile = get_db().table("iidx_profile").get(where("card") == cid) @@ -41,7 +34,6 @@ def get_id_from_profile(cid): return profile["iidx_id"], djid_split - def calculate_folder_mask(profile): return ( profile.get("_show_category_grade", 0) << 0 @@ -57,14 +49,12 @@ def calculate_folder_mask(profile): | (profile.get("_hide_iidx_id", 0) << 12) ) +@xrpc("IIDX31pc/get") +async def iidx31pc_get(ctx: Ctx): + game_version = ctx.info["game_version"] + date_code = int(ctx.info["ext"]) -@router.post("/{gameinfo}/IIDX31pc/get") -async def iidx31pc_get(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - date_code = int(request_info["ext"]) - - cid = request_info["root"][0].attrib["cid"] + cid = ctx.info["root"][0].attrib["cid"] profile = get_game_profile(cid, game_version) djid, djid_split = get_id_from_profile(cid) @@ -767,14 +757,11 @@ async def iidx31pc_get(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31pc/common") -async def iidx31pc_common(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX31pc/common") +async def iidx31pc_common(ctx: Ctx): + game_version = ctx.info["game_version"] db = get_db() all_score_stats = db.table("iidx_score_stats").search( @@ -809,7 +796,7 @@ async def iidx31pc_common(request: Request): E.movie_agreement(version=1), E.license("None", __type="str"), E.file_recovery(url=str(config.ip)), - E.movie_upload(url=f"http://{str(request.client.host)}:4399/movie/"), # use https://github.com/bookqaq/010-record-api + E.movie_upload(url=f"http://{str(ctx.request.client.host)}:4399/movie/"), # use https://github.com/bookqaq/010-record-api # E.button_release_frame(frame=''), # E.trigger_logic_type(type=''), # E.cm_movie_info(type=''), @@ -850,18 +837,15 @@ async def iidx31pc_common(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX31pc/save") +async def iidx31pc_save(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX31pc/save") -async def iidx31pc_save(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - xid = int(request_info["root"][0].attrib["iidxid"]) - cid = request_info["root"][0].attrib["cid"] - clt = int(request_info["root"][0].attrib["cltype"]) + xid = int(ctx.info["root"][0].attrib["iidxid"]) + cid = ctx.info["root"][0].attrib["cid"] + clt = int(ctx.info["root"][0].attrib["cltype"]) profile = get_profile(cid) game_profile = profile["version"].get(str(game_version), {}) @@ -926,8 +910,8 @@ async def iidx31pc_save(request: Request): "s_visualization", "sp_opt", ]: - if k in request_info["root"][0].attrib: - game_profile[k] = request_info["root"][0].attrib[k] + if k in ctx.info["root"][0].attrib: + game_profile[k] = ctx.info["root"][0].attrib[k] for k in [ ("d_liflen", "d_lift"), @@ -935,10 +919,10 @@ async def iidx31pc_save(request: Request): ("s_liflen", "s_lift"), ("sach", "s_achi"), ]: - if k[1] in request_info["root"][0].attrib: - game_profile[k[0]] = request_info["root"][0].attrib[k[1]] + if k[1] in ctx.info["root"][0].attrib: + game_profile[k[0]] = ctx.info["root"][0].attrib[k[1]] - lightning_setting = request_info["root"][0].find("lightning_setting") + lightning_setting = ctx.info["root"][0].find("lightning_setting") if lightning_setting is not None: for k in [ "headphone_vol", @@ -970,7 +954,7 @@ async def iidx31pc_save(request: Request): if concentration is not None: game_profile["lightning_setting_concentration"] = int(concentration.text) - music_memo = request_info["root"][0].find("music_memo") + music_memo = ctx.info["root"][0].find("music_memo") if music_memo is not None: folders = music_memo.findall("folder") for f in folders: @@ -981,17 +965,17 @@ async def iidx31pc_save(request: Request): game_profile[f"music_memo_{fi}_{ps}_name"] = fn game_profile[f"music_memo_{fi}_{ps}_mids"] = mids - movie_agreement = request_info["root"][0].find("movie_agreement") + movie_agreement = ctx.info["root"][0].find("movie_agreement") if movie_agreement is not None and "agreement_version" in movie_agreement.attrib: game_profile["movie_agreement"] = int( movie_agreement.attrib["agreement_version"] ) - hide_name = request_info["root"][0].find("movie_setting/hide_name") + hide_name = ctx.info["root"][0].find("movie_setting/hide_name") if hide_name is not None: game_profile["hide_name"] = int(hide_name.text) - # lightning_customize_flg = request_info["root"][0].find("lightning_customize_flg") + # lightning_customize_flg = ctx.info["root"][0].find("lightning_customize_flg") # if lightning_customize_flg is not None: # for k in [ # "flg_skin_0", @@ -1000,21 +984,21 @@ async def iidx31pc_save(request: Request): # lightning_customize_flg.attrib[k] # ) - secret = request_info["root"][0].find("secret") + secret = ctx.info["root"][0].find("secret") if secret is not None: for k in ["flg1", "flg2", "flg3", "flg4"]: flg = secret.find(k) if flg is not None: game_profile["secret_" + k] = [int(x) for x in flg.text.split(" ")] - leggendaria = request_info["root"][0].find("leggendaria") + leggendaria = ctx.info["root"][0].find("leggendaria") if leggendaria is not None: for k in ["flg1"]: flg = leggendaria.find(k) if flg is not None: game_profile["leggendaria_" + k] = [int(x) for x in flg.text.split(" ")] - step = request_info["root"][0].find("step") + step = ctx.info["root"][0].find("step") if step is not None: for k in [ "dp_fluctuation", @@ -1036,7 +1020,7 @@ async def iidx31pc_save(request: Request): if is_track_ticket is not None: game_profile["stepup_is_track_ticket"] = int(is_track_ticket.text) - dj_ranks = request_info["root"][0].findall("dj_rank") + dj_ranks = ctx.info["root"][0].findall("dj_rank") dj_ranks = [] if dj_ranks is None else dj_ranks for dj_rank in dj_ranks: style = int(dj_rank.attrib["style"]) @@ -1051,7 +1035,7 @@ async def iidx31pc_save(request: Request): int(x) for x in point.text.split(" ") ] - skin_equips = request_info["root"][0].findall("skin_equip") + skin_equips = ctx.info["root"][0].findall("skin_equip") skin_equips = [] if skin_equips is None else skin_equips skin = { 1: "explosion", @@ -1072,7 +1056,7 @@ async def iidx31pc_save(request: Request): if skin_id in skin: game_profile[skin[skin_id]] = int(skin_equip.attrib["skin_no"]) - tdjskin_equips = request_info["root"][0].findall("tdjskin_equip") + tdjskin_equips = ctx.info["root"][0].findall("tdjskin_equip") tdjskin_equips = [] if tdjskin_equips is None else tdjskin_equips tdjskin = { 0: "submonitor", @@ -1083,7 +1067,7 @@ async def iidx31pc_save(request: Request): if skin_id in tdjskin: game_profile[tdjskin[skin_id]] = int(tdjskin_equip.attrib["skin_no"]) - notes_radars = request_info["root"][0].findall("notes_radar") + notes_radars = ctx.info["root"][0].findall("notes_radar") notes_radars = [] if notes_radars is None else notes_radars for notes_radar in notes_radars: style = int(notes_radar.attrib["style"]) @@ -1092,7 +1076,7 @@ async def iidx31pc_save(request: Request): int(x) for x in score.text.split(" ") ] - achievements = request_info["root"][0].find("achievements") + achievements = ctx.info["root"][0].find("achievements") if achievements is not None: for k in [ "last_weekly", @@ -1111,7 +1095,7 @@ async def iidx31pc_save(request: Request): int(x) for x in trophy.text.split(" ") ] - grade = request_info["root"][0].find("grade") + grade = ctx.info["root"][0].find("grade") if grade is not None: grade_values = [] for g in grade.findall("g"): @@ -1122,12 +1106,12 @@ async def iidx31pc_save(request: Request): profile["grade_values"] = grade_values deller_amount = game_profile.get("deller", 0) - deller = request_info["root"][0].find("deller") + deller = ctx.info["root"][0].find("deller") if deller is not None: deller_amount = int(deller.attrib["deller"]) game_profile["deller"] = deller_amount - language = request_info["root"][0].find("language_setting") + language = ctx.info["root"][0].find("language_setting") if language is not None: language_value = int(language.attrib["language"]) game_profile["language_setting"] = language_value @@ -1135,7 +1119,7 @@ async def iidx31pc_save(request: Request): game_profile["spnum"] = game_profile.get("spnum", 0) + (1 if clt == 0 else 0) game_profile["dpnum"] = game_profile.get("dpnum", 0) + (1 if clt == 1 else 0) - if request_info["model"] == "TDJ": + if ctx.info["model"] == "TDJ": game_profile["lightning_play_data_spnum"] = game_profile.get( "lightning_play_data_spnum", 0 ) + (1 if clt == 0 else 0) @@ -1149,13 +1133,10 @@ async def iidx31pc_save(request: Request): response = E.response(E.IIDX31pc(iidxid=xid, cltype=clt)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31pc/visit") -async def iidx31pc_visit(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31pc/visit") +async def iidx31pc_visit(ctx: Ctx): response = E.response( E.IIDX31pc( @@ -1168,18 +1149,15 @@ async def iidx31pc_visit(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX31pc/reg") +async def iidx31pc_reg(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX31pc/reg") -async def iidx31pc_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - cid = request_info["root"][0].attrib["cid"] - name = request_info["root"][0].attrib["name"] - pid = request_info["root"][0].attrib["pid"] + cid = ctx.info["root"][0].attrib["cid"] + name = ctx.info["root"][0].attrib["name"] + pid = ctx.info["root"][0].attrib["pid"] db = get_db().table("iidx_profile") all_profiles_for_card = db.get(Query().card == cid) @@ -1400,13 +1378,10 @@ async def iidx31pc_reg(request: Request): response = E.response(E.IIDX31pc(id=card, id_str=card_split)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31pc/getLaneGachaTicket") -async def iidx31pc_getlanegachaticket(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31pc/getLaneGachaTicket") +async def iidx31pc_getlanegachaticket(ctx: Ctx): response = E.response( E.IIDX31pc( @@ -1435,23 +1410,17 @@ async def iidx31pc_getlanegachaticket(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31pc/consumeLaneGachaTicket") -async def iidx31pc_consumelanegachaticket(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31pc/consumeLaneGachaTicket") +async def iidx31pc_consumelanegachaticket(ctx: Ctx): response = E.response(E.IIDX31pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31pc/drawLaneGacha") -async def iidx31pc_drawlanegacha(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31pc/drawLaneGacha") +async def iidx31pc_drawlanegacha(ctx: Ctx): response = E.response( E.IIDX31pc( @@ -1465,65 +1434,46 @@ async def iidx31pc_drawlanegacha(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31pc/eaappliresult") -async def iidx31pc_eaappliresult(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31pc/eaappliresult") +async def iidx31pc_eaappliresult(ctx: Ctx): response = E.response(E.IIDX31pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31pc/playstart") -async def iidx31pc_playstart(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31pc/playstart") +async def iidx31pc_playstart(ctx: Ctx): response = E.response(E.IIDX31pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31pc/playend") -async def iidx31pc_playend(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31pc/playend") +async def iidx31pc_playend(ctx: Ctx): response = E.response(E.IIDX31pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31pc/delete") -async def iidx31pc_delete(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31pc/delete") +async def iidx31pc_delete(ctx: Ctx): response = E.response(E.IIDX31pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31pc/logout") -async def iidx31pc_logout(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31pc/logout") +async def iidx31pc_logout(ctx: Ctx): response = E.response(E.IIDX31pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31pc/getCompeInfo") -async def iidx31pc_getcompeinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31pc/getCompeInfo") +async def iidx31pc_getcompeinfo(ctx: Ctx): response = E.response(E.IIDX31pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx31ranking.py b/modules/iidx/iidx31ranking.py index c1f2270..35deb7f 100644 --- a/modules/iidx/iidx31ranking.py +++ b/modules/iidx/iidx31ranking.py @@ -1,18 +1,13 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["LDJ"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX31ranking/getranker") -async def iidx31ranking_getranker(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31ranking/getranker") +async def iidx31ranking_getranker(ctx: Ctx): response = E.response(E.IIDX31ranking()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx31shop.py b/modules/iidx/iidx31shop.py index 06742e3..f76e51d 100644 --- a/modules/iidx/iidx31shop.py +++ b/modules/iidx/iidx31shop.py @@ -1,16 +1,12 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["LDJ"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX31shop/getname") -async def iidx31shop_getname(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31shop/getname") +async def iidx31shop_getname(ctx: Ctx): response = E.response( E.IIDX31shop( @@ -20,13 +16,10 @@ async def iidx31shop_getname(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31shop/getconvention") -async def iidx31shop_getconvention(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31shop/getconvention") +async def iidx31shop_getconvention(ctx: Ctx): response = E.response( E.IIDX31shop( @@ -40,25 +33,18 @@ async def iidx31shop_getconvention(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31shop/sentinfo") -async def iidx31shop_sentinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31shop/sentinfo") +async def iidx31shop_sentinfo(ctx: Ctx): response = E.response(E.IIDX31shop()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31shop/sendescapepackageinfo") -async def iidx31shop_sendescapepackageinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31shop/sendescapepackageinfo") +async def iidx31shop_sendescapepackageinfo(ctx: Ctx): response = E.response(E.IIDX31shop(expire=1200)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx31streaming.py b/modules/iidx/iidx31streaming.py index 1918caf..1879601 100644 --- a/modules/iidx/iidx31streaming.py +++ b/modules/iidx/iidx31streaming.py @@ -1,28 +1,20 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local2", models=["LDJ"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX31streaming/common") -async def iidx31streaming_common(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31streaming/common") +async def iidx31streaming_common(ctx: Ctx): response = E.response(E.IIDX31streaming()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX31streaming/getcm") -async def iidx31streaming_getcm(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX31streaming/getcm") +async def iidx31streaming_getcm(ctx: Ctx): response = E.response(E.IIDX31streaming()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx32gamesystem.py b/modules/iidx/iidx32gamesystem.py index b8a94ab..3133885 100644 --- a/modules/iidx/iidx32gamesystem.py +++ b/modules/iidx/iidx32gamesystem.py @@ -1,18 +1,14 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from time import time import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local", models=["LDJ"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX32gameSystem/systemInfo") -async def iidx32gamesystem_systeminfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32gameSystem/systemInfo") +async def iidx32gamesystem_systeminfo(ctx: Ctx): unlock = () # force unlock LM exclusives to complete unlock all songs server side @@ -194,5 +190,4 @@ async def iidx32gamesystem_systeminfo(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx32grade.py b/modules/iidx/iidx32grade.py index fb507b1..2cbf792 100644 --- a/modules/iidx/iidx32grade.py +++ b/modules/iidx/iidx32grade.py @@ -1,34 +1,29 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time from tinydb import Query, where -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - +set_xrpc_defaults(service="local", models=["LDJ"]) def get_profile(iidx_id): return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) - -@router.post("/{gameinfo}/IIDX32grade/raised") -async def iidx32grade_raised(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX32grade/raised") +async def iidx32grade_raised(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - iidx_id = int(request_info["root"][0].attrib["iidxid"]) - achi = int(request_info["root"][0].attrib["achi"]) - cstage = int(request_info["root"][0].attrib["cstage"]) - gid = int(request_info["root"][0].attrib["gid"]) - gtype = int(request_info["root"][0].attrib["gtype"]) - is_ex = int(request_info["root"][0].attrib["is_ex"]) - is_mirror = int(request_info["root"][0].attrib["is_mirror"]) + iidx_id = int(ctx.info["root"][0].attrib["iidxid"]) + achi = int(ctx.info["root"][0].attrib["achi"]) + cstage = int(ctx.info["root"][0].attrib["cstage"]) + gid = int(ctx.info["root"][0].attrib["gid"]) + gtype = int(ctx.info["root"][0].attrib["gtype"]) + is_ex = int(ctx.info["root"][0].attrib["is_ex"]) + is_mirror = int(ctx.info["root"][0].attrib["is_mirror"]) db = get_db() db.table("iidx_class").insert( @@ -112,5 +107,4 @@ async def iidx32grade_raised(request: Request): response = E.response(E.IIDX32grade(pnum=1)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx32lobby.py b/modules/iidx/iidx32lobby.py index aaacd06..01c1401 100644 --- a/modules/iidx/iidx32lobby.py +++ b/modules/iidx/iidx32lobby.py @@ -1,24 +1,19 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from time import time import config -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E - -router = APIRouter(prefix="/lobby2", tags=["lobby2"]) -router.model_whitelist = ["LDJ"] - +from core_common import E arena_host = {} bpl_host = {} +set_xrpc_defaults(service="lobby2", models=["LDJ"]) -@router.post("/{gameinfo}/IIDX32lobby/entry") -async def iidx32lobby_entry(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32lobby/entry") +async def iidx32lobby_entry(ctx: Ctx): - root = request_info["root"][0] + root = ctx.info["root"][0] sp_dp = root.find("play_style").text arena_class = root.find("arena_class").text ga = root.find("address/ga").text.split() @@ -60,23 +55,17 @@ async def iidx32lobby_entry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32lobby/update") -async def iidx32lobby_update(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32lobby/update") +async def iidx32lobby_update(ctx: Ctx): response = E.response(E.IIDX32lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32lobby/delete") -async def iidx32lobby_delete(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32lobby/delete") +async def iidx32lobby_delete(ctx: Ctx): # normal reset del arena_host["ga"] @@ -85,15 +74,12 @@ async def iidx32lobby_delete(request: Request): del arena_host["time"] response = E.response(E.IIDX32lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX32lobby/bplbattle_entry") +async def iidx32lobby_bplbattle_entry(ctx: Ctx): -@router.post("/{gameinfo}/IIDX32lobby/bplbattle_entry") -async def iidx32lobby_bplbattle_entry(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] sp_dp = root.find("play_style").text arena_class = root.find("arena_class").text password = root.find("passward").text # passward @@ -137,25 +123,19 @@ async def iidx32lobby_bplbattle_entry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32lobby/bplbattle_update") -async def iidx32lobby_bplbattle_update(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32lobby/bplbattle_update") +async def iidx32lobby_bplbattle_update(ctx: Ctx): response = E.response(E.IIDX32lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX32lobby/bplbattle_delete") +async def iidx32lobby_bplbattle_delete(ctx: Ctx): -@router.post("/{gameinfo}/IIDX32lobby/bplbattle_delete") -async def iidx32lobby_bplbattle_delete(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] ga = root.find("address/ga").text.split() # normal reset @@ -165,5 +145,4 @@ async def iidx32lobby_bplbattle_delete(request: Request): break response = E.response(E.IIDX32lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx32music.py b/modules/iidx/iidx32music.py index d425d83..33bf1a4 100644 --- a/modules/iidx/iidx32music.py +++ b/modules/iidx/iidx32music.py @@ -1,19 +1,15 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time import random from enum import IntEnum -from fastapi import APIRouter, Request, Response from tinydb import where -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db import config -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - - class ClearFlags(IntEnum): NO_PLAY = 0 FAILED = 1 @@ -24,13 +20,13 @@ class ClearFlags(IntEnum): EX_HARD_CLEAR = 6 FULL_COMBO = 7 +set_xrpc_defaults(service="local", models=["LDJ"]) -@router.post("/{gameinfo}/IIDX32music/getrank") -async def iidx32music_getrank(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX32music/getrank") +async def iidx32music_getrank(ctx: Ctx): + game_version = ctx.info["game_version"] - root = request_info["root"][0] + root = ctx.info["root"][0] play_style = int(root.attrib["cltype"]) @@ -151,14 +147,11 @@ async def iidx32music_getrank(request: Request): assert response is not None - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32music/crate") -async def iidx32music_crate(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX32music/crate") +async def iidx32music_crate(ctx: Ctx): + game_version = ctx.info["game_version"] db = get_db() all_score_stats = db.table("iidx_score_stats").search( @@ -185,23 +178,20 @@ async def iidx32music_crate(request: Request): E.IIDX32music(*[E.c(crate[k] + fcrate[k], mid=k, __type="s32") for k in crate]) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32music/reg") -async def iidx32music_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX32music/reg") +async def iidx32music_reg(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - log = request_info["root"][0].find("music_play_log") + log = ctx.info["root"][0].find("music_play_log") - clear_flg = int(request_info["root"][0].attrib["cflg"]) - clid = int(request_info["root"][0].attrib["clid"]) - is_death = int(request_info["root"][0].attrib["is_death"]) - pid = int(request_info["root"][0].attrib["pid"]) + clear_flg = int(ctx.info["root"][0].attrib["cflg"]) + clid = int(ctx.info["root"][0].attrib["clid"]) + is_death = int(ctx.info["root"][0].attrib["is_death"]) + pid = int(ctx.info["root"][0].attrib["pid"]) play_style = int(log.attrib["play_style"]) ex_score = int(log.attrib["ex_score"]) @@ -404,15 +394,12 @@ async def iidx32music_reg(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX32music/appoint") +async def iidx32music_appoint(ctx: Ctx): -@router.post("/{gameinfo}/IIDX32music/appoint") -async def iidx32music_appoint(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] iidxid = int(root.attrib["iidxid"]) music_id = int(root.attrib["mid"]) @@ -480,15 +467,12 @@ async def iidx32music_appoint(request: Request): response = E.response(E.IIDX32music(*vals)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX32music/arenaCPU") +async def iidx32music_arenacpu(ctx: Ctx): -@router.post("/{gameinfo}/IIDX32music/arenaCPU") -async def iidx32music_arenacpu(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] music_list = root.findall("music_list") music_count = len(music_list) cpu_list = root.findall("cpu_list") @@ -539,13 +523,10 @@ async def iidx32music_arenacpu(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32music/retry") -async def iidx32music_retry(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32music/retry") +async def iidx32music_retry(ctx: Ctx): response = E.response( E.IIDX32music( @@ -554,42 +535,31 @@ async def iidx32music_retry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32music/play") -async def iidx32music_play(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32music/play") +async def iidx32music_play(ctx: Ctx): response = E.response(E.IIDX32music()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32music/nosave") -async def iidx32music_nosave(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32music/nosave") +async def iidx32music_nosave(ctx: Ctx): response = E.response(E.IIDX32music()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32music/getranksub") -async def iidx32music_getranksub(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32music/getranksub") +async def iidx32music_getranksub(ctx: Ctx): response = E.response(E.IIDX32music()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response -@router.post("/{gameinfo}/IIDX32music/movieinfo") -async def iidx32music_movieinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32music/movieinfo") +async def iidx32music_movieinfo(ctx: Ctx): response = E.response( E.IIDX32music( @@ -597,6 +567,5 @@ async def iidx32music_movieinfo(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx32pc.py b/modules/iidx/iidx32pc.py index 47b6783..ea25d41 100644 --- a/modules/iidx/iidx32pc.py +++ b/modules/iidx/iidx32pc.py @@ -1,38 +1,31 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from tinydb import Query, where from time import time import config import random -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - +set_xrpc_defaults(service="local", models=["LDJ"]) def get_profile(cid): return get_db().table("iidx_profile").get(where("card") == cid) - def get_profile_by_id(iidx_id): return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - def get_game_profile_by_id(iidx_id, game_version): profile = get_profile_by_id(iidx_id) return profile["version"].get(str(game_version), None) - def get_id_from_profile(cid): profile = get_db().table("iidx_profile").get(where("card") == cid) @@ -41,7 +34,6 @@ def get_id_from_profile(cid): return profile["iidx_id"], djid_split - def calculate_folder_mask(profile): return ( profile.get("_show_category_grade", 0) << 0 @@ -57,14 +49,12 @@ def calculate_folder_mask(profile): | (profile.get("_hide_iidx_id", 0) << 12) ) +@xrpc("IIDX32pc/get") +async def iidx32pc_get(ctx: Ctx): + game_version = ctx.info["game_version"] + date_code = int(ctx.info["ext"]) -@router.post("/{gameinfo}/IIDX32pc/get") -async def iidx32pc_get(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - date_code = int(request_info["ext"]) - - cid = request_info["root"][0].attrib["cid"] + cid = ctx.info["root"][0].attrib["cid"] profile = get_game_profile(cid, game_version) djid, djid_split = get_id_from_profile(cid) @@ -715,14 +705,11 @@ async def iidx32pc_get(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32pc/common") -async def iidx32pc_common(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX32pc/common") +async def iidx32pc_common(ctx: Ctx): + game_version = ctx.info["game_version"] db = get_db() all_score_stats = db.table("iidx_score_stats").search( @@ -757,7 +744,7 @@ async def iidx32pc_common(request: Request): E.movie_agreement(version=1), E.license("None", __type="str"), E.file_recovery(url=str(config.ip)), - E.movie_upload(url=f"http://{str(request.client.host)}:4399/movie/"), # use https://github.com/bookqaq/010-record-api + E.movie_upload(url=f"http://{str(ctx.request.client.host)}:4399/movie/"), # use https://github.com/bookqaq/010-record-api # E.button_release_frame(frame=''), # E.trigger_logic_type(type=''), # E.cm_movie_info(type=''), @@ -798,18 +785,15 @@ async def iidx32pc_common(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX32pc/save") +async def iidx32pc_save(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX32pc/save") -async def iidx32pc_save(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - xid = int(request_info["root"][0].attrib["iidxid"]) - cid = request_info["root"][0].attrib["cid"] - clt = int(request_info["root"][0].attrib["cltype"]) + xid = int(ctx.info["root"][0].attrib["iidxid"]) + cid = ctx.info["root"][0].attrib["cid"] + clt = int(ctx.info["root"][0].attrib["cltype"]) profile = get_profile(cid) game_profile = profile["version"].get(str(game_version), {}) @@ -877,8 +861,8 @@ async def iidx32pc_save(request: Request): "s_visualization", "sp_opt", ]: - if k in request_info["root"][0].attrib: - game_profile[k] = request_info["root"][0].attrib[k] + if k in ctx.info["root"][0].attrib: + game_profile[k] = ctx.info["root"][0].attrib[k] for k in [ ("d_liflen", "d_lift"), @@ -886,10 +870,10 @@ async def iidx32pc_save(request: Request): ("s_liflen", "s_lift"), ("sach", "s_achi"), ]: - if k[1] in request_info["root"][0].attrib: - game_profile[k[0]] = request_info["root"][0].attrib[k[1]] + if k[1] in ctx.info["root"][0].attrib: + game_profile[k[0]] = ctx.info["root"][0].attrib[k[1]] - lightning_setting = request_info["root"][0].find("lightning_setting") + lightning_setting = ctx.info["root"][0].find("lightning_setting") if lightning_setting is not None: for k in [ "headphone_vol", @@ -921,7 +905,7 @@ async def iidx32pc_save(request: Request): if concentration is not None: game_profile["lightning_setting_concentration"] = int(concentration.text) - music_memo = request_info["root"][0].find("music_memo") + music_memo = ctx.info["root"][0].find("music_memo") if music_memo is not None: folders = music_memo.findall("folder") for f in folders: @@ -932,17 +916,17 @@ async def iidx32pc_save(request: Request): game_profile[f"music_memo_{fi}_{ps}_name"] = fn game_profile[f"music_memo_{fi}_{ps}_mids"] = mids - movie_agreement = request_info["root"][0].find("movie_agreement") + movie_agreement = ctx.info["root"][0].find("movie_agreement") if movie_agreement is not None and "agreement_version" in movie_agreement.attrib: game_profile["movie_agreement"] = int( movie_agreement.attrib["agreement_version"] ) - hide_name = request_info["root"][0].find("movie_setting/hide_name") + hide_name = ctx.info["root"][0].find("movie_setting/hide_name") if hide_name is not None: game_profile["hide_name"] = int(hide_name.text) - # lightning_customize_flg = request_info["root"][0].find("lightning_customize_flg") + # lightning_customize_flg = ctx.info["root"][0].find("lightning_customize_flg") # if lightning_customize_flg is not None: # for k in [ # "flg_skin_0", @@ -951,21 +935,21 @@ async def iidx32pc_save(request: Request): # lightning_customize_flg.attrib[k] # ) - secret = request_info["root"][0].find("secret") + secret = ctx.info["root"][0].find("secret") if secret is not None: for k in ["flg1", "flg2", "flg3", "flg4"]: flg = secret.find(k) if flg is not None: game_profile["secret_" + k] = [int(x) for x in flg.text.split(" ")] - leggendaria = request_info["root"][0].find("leggendaria") + leggendaria = ctx.info["root"][0].find("leggendaria") if leggendaria is not None: for k in ["flg1"]: flg = leggendaria.find(k) if flg is not None: game_profile["leggendaria_" + k] = [int(x) for x in flg.text.split(" ")] - step = request_info["root"][0].find("step") + step = ctx.info["root"][0].find("step") if step is not None: for k in [ "dp_fluctuation", @@ -992,7 +976,7 @@ async def iidx32pc_save(request: Request): if is_track_ticket is not None: game_profile["stepup_is_track_ticket"] = int(is_track_ticket.text) - dj_ranks = request_info["root"][0].findall("dj_rank") + dj_ranks = ctx.info["root"][0].findall("dj_rank") dj_ranks = [] if dj_ranks is None else dj_ranks for dj_rank in dj_ranks: style = int(dj_rank.attrib["style"]) @@ -1007,7 +991,7 @@ async def iidx32pc_save(request: Request): int(x) for x in point.text.split(" ") ] - skin_equips = request_info["root"][0].findall("skin_equip") + skin_equips = ctx.info["root"][0].findall("skin_equip") skin_equips = [] if skin_equips is None else skin_equips skin = { 1: "explosion", @@ -1028,7 +1012,7 @@ async def iidx32pc_save(request: Request): if skin_id in skin: game_profile[skin[skin_id]] = int(skin_equip.attrib["skin_no"]) - tdjskin_equips = request_info["root"][0].findall("tdjskin_equip") + tdjskin_equips = ctx.info["root"][0].findall("tdjskin_equip") tdjskin_equips = [] if tdjskin_equips is None else tdjskin_equips tdjskin = { 0: "submonitor", @@ -1039,7 +1023,7 @@ async def iidx32pc_save(request: Request): if skin_id in tdjskin: game_profile[tdjskin[skin_id]] = int(tdjskin_equip.attrib["skin_no"]) - notes_radars = request_info["root"][0].findall("notes_radar") + notes_radars = ctx.info["root"][0].findall("notes_radar") notes_radars = [] if notes_radars is None else notes_radars for notes_radar in notes_radars: style = int(notes_radar.attrib["style"]) @@ -1048,7 +1032,7 @@ async def iidx32pc_save(request: Request): int(x) for x in score.text.split(" ") ] - achievements = request_info["root"][0].find("achievements") + achievements = ctx.info["root"][0].find("achievements") if achievements is not None: for k in [ "last_weekly", @@ -1067,7 +1051,7 @@ async def iidx32pc_save(request: Request): int(x) for x in trophy.text.split(" ") ] - grade = request_info["root"][0].find("grade") + grade = ctx.info["root"][0].find("grade") if grade is not None: grade_values = [] for g in grade.findall("g"): @@ -1078,12 +1062,12 @@ async def iidx32pc_save(request: Request): profile["grade_values"] = grade_values deller_amount = game_profile.get("deller", 0) - deller = request_info["root"][0].find("deller") + deller = ctx.info["root"][0].find("deller") if deller is not None: deller_amount = int(deller.attrib["deller"]) game_profile["deller"] = deller_amount - language = request_info["root"][0].find("language_setting") + language = ctx.info["root"][0].find("language_setting") if language is not None: language_value = int(language.attrib["language"]) game_profile["language_setting"] = language_value @@ -1091,7 +1075,7 @@ async def iidx32pc_save(request: Request): game_profile["spnum"] = game_profile.get("spnum", 0) + (1 if clt == 0 else 0) game_profile["dpnum"] = game_profile.get("dpnum", 0) + (1 if clt == 1 else 0) - if request_info["model"] == "TDJ": + if ctx.info["model"] == "TDJ": game_profile["lightning_play_data_spnum"] = game_profile.get( "lightning_play_data_spnum", 0 ) + (1 if clt == 0 else 0) @@ -1105,13 +1089,10 @@ async def iidx32pc_save(request: Request): response = E.response(E.IIDX32pc(iidxid=xid, cltype=clt)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32pc/visit") -async def iidx32pc_visit(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32pc/visit") +async def iidx32pc_visit(ctx: Ctx): response = E.response( E.IIDX32pc( @@ -1124,18 +1105,15 @@ async def iidx32pc_visit(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX32pc/reg") +async def iidx32pc_reg(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX32pc/reg") -async def iidx32pc_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - cid = request_info["root"][0].attrib["cid"] - name = request_info["root"][0].attrib["name"] - pid = request_info["root"][0].attrib["pid"] + cid = ctx.info["root"][0].attrib["cid"] + name = ctx.info["root"][0].attrib["name"] + pid = ctx.info["root"][0].attrib["pid"] db = get_db().table("iidx_profile") all_profiles_for_card = db.get(Query().card == cid) @@ -1363,13 +1341,10 @@ async def iidx32pc_reg(request: Request): response = E.response(E.IIDX32pc(id=card, id_str=card_split)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32pc/getLaneGachaTicket") -async def iidx32pc_getlanegachaticket(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32pc/getLaneGachaTicket") +async def iidx32pc_getlanegachaticket(ctx: Ctx): response = E.response( E.IIDX32pc( @@ -1398,23 +1373,17 @@ async def iidx32pc_getlanegachaticket(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32pc/consumeLaneGachaTicket") -async def iidx32pc_consumelanegachaticket(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32pc/consumeLaneGachaTicket") +async def iidx32pc_consumelanegachaticket(ctx: Ctx): response = E.response(E.IIDX32pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32pc/drawLaneGacha") -async def iidx32pc_drawlanegacha(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32pc/drawLaneGacha") +async def iidx32pc_drawlanegacha(ctx: Ctx): response = E.response( E.IIDX32pc( @@ -1428,65 +1397,46 @@ async def iidx32pc_drawlanegacha(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32pc/eaappliresult") -async def iidx32pc_eaappliresult(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32pc/eaappliresult") +async def iidx32pc_eaappliresult(ctx: Ctx): response = E.response(E.IIDX32pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32pc/playstart") -async def iidx32pc_playstart(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32pc/playstart") +async def iidx32pc_playstart(ctx: Ctx): response = E.response(E.IIDX32pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32pc/playend") -async def iidx32pc_playend(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32pc/playend") +async def iidx32pc_playend(ctx: Ctx): response = E.response(E.IIDX32pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32pc/delete") -async def iidx32pc_delete(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32pc/delete") +async def iidx32pc_delete(ctx: Ctx): response = E.response(E.IIDX32pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32pc/logout") -async def iidx32pc_logout(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32pc/logout") +async def iidx32pc_logout(ctx: Ctx): response = E.response(E.IIDX32pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32pc/getCompeInfo") -async def iidx32pc_getcompeinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32pc/getCompeInfo") +async def iidx32pc_getcompeinfo(ctx: Ctx): response = E.response(E.IIDX32pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx32ranking.py b/modules/iidx/iidx32ranking.py index 5cf14c0..361d5b7 100644 --- a/modules/iidx/iidx32ranking.py +++ b/modules/iidx/iidx32ranking.py @@ -1,18 +1,13 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local", models=["LDJ"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX32ranking/getranker") -async def iidx32ranking_getranker(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32ranking/getranker") +async def iidx32ranking_getranker(ctx: Ctx): response = E.response(E.IIDX32ranking()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx32shop.py b/modules/iidx/iidx32shop.py index 133c546..3bdc7f0 100644 --- a/modules/iidx/iidx32shop.py +++ b/modules/iidx/iidx32shop.py @@ -1,16 +1,12 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local", models=["LDJ"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX32shop/getname") -async def iidx32shop_getname(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32shop/getname") +async def iidx32shop_getname(ctx: Ctx): response = E.response( E.IIDX32shop( @@ -20,13 +16,10 @@ async def iidx32shop_getname(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32shop/getconvention") -async def iidx32shop_getconvention(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32shop/getconvention") +async def iidx32shop_getconvention(ctx: Ctx): response = E.response( E.IIDX32shop( @@ -40,25 +33,18 @@ async def iidx32shop_getconvention(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32shop/sentinfo") -async def iidx32shop_sentinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32shop/sentinfo") +async def iidx32shop_sentinfo(ctx: Ctx): response = E.response(E.IIDX32shop()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32shop/sendescapepackageinfo") -async def iidx32shop_sendescapepackageinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32shop/sendescapepackageinfo") +async def iidx32shop_sendescapepackageinfo(ctx: Ctx): response = E.response(E.IIDX32shop(expire=1200)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx32streaming.py b/modules/iidx/iidx32streaming.py index 5ebd35b..155e21d 100644 --- a/modules/iidx/iidx32streaming.py +++ b/modules/iidx/iidx32streaming.py @@ -1,28 +1,20 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local", models=["LDJ"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX32streaming/common") -async def iidx32streaming_common(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32streaming/common") +async def iidx32streaming_common(ctx: Ctx): response = E.response(E.IIDX32streaming()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX32streaming/getcm") -async def iidx32streaming_getcm(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX32streaming/getcm") +async def iidx32streaming_getcm(ctx: Ctx): response = E.response(E.IIDX32streaming()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx33gamesystem.py b/modules/iidx/iidx33gamesystem.py index 7573e30..676c474 100644 --- a/modules/iidx/iidx33gamesystem.py +++ b/modules/iidx/iidx33gamesystem.py @@ -1,18 +1,14 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from time import time import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local", models=["LDJ"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX33gameSystem/systemInfo") -async def iidx33gamesystem_systeminfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33gameSystem/systemInfo") +async def iidx33gamesystem_systeminfo(ctx: Ctx): unlock = () # force unlock LM exclusives to complete unlock all songs server side @@ -196,5 +192,4 @@ async def iidx33gamesystem_systeminfo(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx33grade.py b/modules/iidx/iidx33grade.py index 87b53f0..bda5b59 100644 --- a/modules/iidx/iidx33grade.py +++ b/modules/iidx/iidx33grade.py @@ -1,34 +1,29 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time from tinydb import Query, where -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - +set_xrpc_defaults(service="local", models=["LDJ"]) def get_profile(iidx_id): return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) - -@router.post("/{gameinfo}/IIDX33grade/raised") -async def iidx33grade_raised(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX33grade/raised") +async def iidx33grade_raised(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - iidx_id = int(request_info["root"][0].attrib["iidxid"]) - achi = int(request_info["root"][0].attrib["achi"]) - cstage = int(request_info["root"][0].attrib["cstage"]) - gid = int(request_info["root"][0].attrib["gid"]) - gtype = int(request_info["root"][0].attrib["gtype"]) - is_ex = int(request_info["root"][0].attrib["is_ex"]) - is_mirror = int(request_info["root"][0].attrib["is_mirror"]) + iidx_id = int(ctx.info["root"][0].attrib["iidxid"]) + achi = int(ctx.info["root"][0].attrib["achi"]) + cstage = int(ctx.info["root"][0].attrib["cstage"]) + gid = int(ctx.info["root"][0].attrib["gid"]) + gtype = int(ctx.info["root"][0].attrib["gtype"]) + is_ex = int(ctx.info["root"][0].attrib["is_ex"]) + is_mirror = int(ctx.info["root"][0].attrib["is_mirror"]) db = get_db() db.table("iidx_class").insert( @@ -112,5 +107,4 @@ async def iidx33grade_raised(request: Request): response = E.response(E.IIDX33grade(pnum=1)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx33lobby.py b/modules/iidx/iidx33lobby.py index c43f8a0..f5cf057 100644 --- a/modules/iidx/iidx33lobby.py +++ b/modules/iidx/iidx33lobby.py @@ -1,24 +1,19 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from time import time import config -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E - -router = APIRouter(prefix="/lobby2", tags=["lobby2"]) -router.model_whitelist = ["LDJ"] - +from core_common import E arena_host = {} bpl_host = {} +set_xrpc_defaults(service="lobby2", models=["LDJ"]) -@router.post("/{gameinfo}/IIDX33lobby/entry") -async def iidx33lobby_entry(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33lobby/entry") +async def iidx33lobby_entry(ctx: Ctx): - root = request_info["root"][0] + root = ctx.info["root"][0] sp_dp = root.find("play_style").text arena_class = root.find("arena_class").text ga = root.find("address/ga").text.split() @@ -60,23 +55,17 @@ async def iidx33lobby_entry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33lobby/update") -async def iidx33lobby_update(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33lobby/update") +async def iidx33lobby_update(ctx: Ctx): response = E.response(E.IIDX33lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33lobby/delete") -async def iidx33lobby_delete(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33lobby/delete") +async def iidx33lobby_delete(ctx: Ctx): # normal reset del arena_host["ga"] @@ -85,15 +74,12 @@ async def iidx33lobby_delete(request: Request): del arena_host["time"] response = E.response(E.IIDX33lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX33lobby/bplbattle_entry") +async def iidx33lobby_bplbattle_entry(ctx: Ctx): -@router.post("/{gameinfo}/IIDX33lobby/bplbattle_entry") -async def iidx33lobby_bplbattle_entry(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] sp_dp = root.find("play_style").text arena_class = root.find("arena_class").text password = root.find("passward").text # passward @@ -137,25 +123,19 @@ async def iidx33lobby_bplbattle_entry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33lobby/bplbattle_update") -async def iidx33lobby_bplbattle_update(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33lobby/bplbattle_update") +async def iidx33lobby_bplbattle_update(ctx: Ctx): response = E.response(E.IIDX33lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX33lobby/bplbattle_delete") +async def iidx33lobby_bplbattle_delete(ctx: Ctx): -@router.post("/{gameinfo}/IIDX33lobby/bplbattle_delete") -async def iidx33lobby_bplbattle_delete(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] ga = root.find("address/ga").text.split() # normal reset @@ -165,5 +145,4 @@ async def iidx33lobby_bplbattle_delete(request: Request): break response = E.response(E.IIDX33lobby()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx33music.py b/modules/iidx/iidx33music.py index 24da0a6..6b9cc1d 100644 --- a/modules/iidx/iidx33music.py +++ b/modules/iidx/iidx33music.py @@ -1,19 +1,15 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time import random from enum import IntEnum -from fastapi import APIRouter, Request, Response from tinydb import where -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db import config -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - - class ClearFlags(IntEnum): NO_PLAY = 0 FAILED = 1 @@ -24,13 +20,13 @@ class ClearFlags(IntEnum): EX_HARD_CLEAR = 6 FULL_COMBO = 7 +set_xrpc_defaults(service="local", models=["LDJ"]) -@router.post("/{gameinfo}/IIDX33music/getrank") -async def iidx33music_getrank(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX33music/getrank") +async def iidx33music_getrank(ctx: Ctx): + game_version = ctx.info["game_version"] - root = request_info["root"][0] + root = ctx.info["root"][0] play_style = int(root.attrib["cltype"]) @@ -151,14 +147,11 @@ async def iidx33music_getrank(request: Request): assert response is not None - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33music/crate") -async def iidx33music_crate(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX33music/crate") +async def iidx33music_crate(ctx: Ctx): + game_version = ctx.info["game_version"] db = get_db() all_score_stats = db.table("iidx_score_stats").search( @@ -185,23 +178,20 @@ async def iidx33music_crate(request: Request): E.IIDX33music(*[E.c(crate[k] + fcrate[k], mid=k, __type="s32") for k in crate]) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33music/reg") -async def iidx33music_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX33music/reg") +async def iidx33music_reg(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - log = request_info["root"][0].find("music_play_log") + log = ctx.info["root"][0].find("music_play_log") - clear_flg = int(request_info["root"][0].attrib["cflg"]) - clid = int(request_info["root"][0].attrib["clid"]) - is_death = int(request_info["root"][0].attrib["is_death"]) - pid = int(request_info["root"][0].attrib["pid"]) + clear_flg = int(ctx.info["root"][0].attrib["cflg"]) + clid = int(ctx.info["root"][0].attrib["clid"]) + is_death = int(ctx.info["root"][0].attrib["is_death"]) + pid = int(ctx.info["root"][0].attrib["pid"]) play_style = int(log.attrib["play_style"]) ex_score = int(log.attrib["ex_score"]) @@ -404,15 +394,12 @@ async def iidx33music_reg(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX33music/appoint") +async def iidx33music_appoint(ctx: Ctx): -@router.post("/{gameinfo}/IIDX33music/appoint") -async def iidx33music_appoint(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] iidxid = int(root.attrib["iidxid"]) music_id = int(root.attrib["mid"]) @@ -480,15 +467,12 @@ async def iidx33music_appoint(request: Request): response = E.response(E.IIDX33music(*vals)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX33music/arenaCPU") +async def iidx33music_arenacpu(ctx: Ctx): -@router.post("/{gameinfo}/IIDX33music/arenaCPU") -async def iidx33music_arenacpu(request: Request): - request_info = await core_process_request(request) - - root = request_info["root"][0] + root = ctx.info["root"][0] music_list = root.findall("music_list") music_count = len(music_list) cpu_list = root.findall("cpu_list") @@ -539,13 +523,10 @@ async def iidx33music_arenacpu(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33music/retry") -async def iidx33music_retry(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33music/retry") +async def iidx33music_retry(ctx: Ctx): response = E.response( E.IIDX33music( @@ -554,42 +535,31 @@ async def iidx33music_retry(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33music/play") -async def iidx33music_play(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33music/play") +async def iidx33music_play(ctx: Ctx): response = E.response(E.IIDX33music()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33music/nosave") -async def iidx33music_nosave(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33music/nosave") +async def iidx33music_nosave(ctx: Ctx): response = E.response(E.IIDX33music()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33music/getranksub") -async def iidx33music_getranksub(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33music/getranksub") +async def iidx33music_getranksub(ctx: Ctx): response = E.response(E.IIDX33music()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response -@router.post("/{gameinfo}/IIDX33music/movieinfo") -async def iidx33music_movieinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33music/movieinfo") +async def iidx33music_movieinfo(ctx: Ctx): response = E.response( E.IIDX33music( @@ -597,6 +567,5 @@ async def iidx33music_movieinfo(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx33pc.py b/modules/iidx/iidx33pc.py index 5e83f90..a0a4dd4 100644 --- a/modules/iidx/iidx33pc.py +++ b/modules/iidx/iidx33pc.py @@ -1,38 +1,31 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from tinydb import Query, where from time import time import config import random -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - +set_xrpc_defaults(service="local", models=["LDJ"]) def get_profile(cid): return get_db().table("iidx_profile").get(where("card") == cid) - def get_profile_by_id(iidx_id): return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - def get_game_profile_by_id(iidx_id, game_version): profile = get_profile_by_id(iidx_id) return profile["version"].get(str(game_version), None) - def get_id_from_profile(cid): profile = get_db().table("iidx_profile").get(where("card") == cid) @@ -41,7 +34,6 @@ def get_id_from_profile(cid): return profile["iidx_id"], djid_split - def calculate_folder_mask(profile): return ( profile.get("_show_category_grade", 0) << 0 @@ -57,14 +49,12 @@ def calculate_folder_mask(profile): | (profile.get("_hide_iidx_id", 0) << 12) ) +@xrpc("IIDX33pc/get") +async def iidx33pc_get(ctx: Ctx): + game_version = ctx.info["game_version"] + date_code = int(ctx.info["ext"]) -@router.post("/{gameinfo}/IIDX33pc/get") -async def iidx33pc_get(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - date_code = int(request_info["ext"]) - - cid = request_info["root"][0].attrib["cid"] + cid = ctx.info["root"][0].attrib["cid"] profile = get_game_profile(cid, game_version) djid, djid_split = get_id_from_profile(cid) @@ -729,14 +719,11 @@ async def iidx33pc_get(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33pc/common") -async def iidx33pc_common(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("IIDX33pc/common") +async def iidx33pc_common(ctx: Ctx): + game_version = ctx.info["game_version"] db = get_db() all_score_stats = db.table("iidx_score_stats").search( @@ -771,7 +758,7 @@ async def iidx33pc_common(request: Request): E.movie_agreement(version=1), E.license("None", __type="str"), E.file_recovery(url=str(config.ip)), - E.movie_upload(url=f"http://{str(request.client.host)}:4399/movie/"), # use https://github.com/bookqaq/010-record-api + E.movie_upload(url=f"http://{str(ctx.request.client.host)}:4399/movie/"), # use https://github.com/bookqaq/010-record-api # E.button_release_frame(frame=''), # E.trigger_logic_type(type=''), # E.cm_movie_info(type=''), @@ -812,18 +799,15 @@ async def iidx33pc_common(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX33pc/save") +async def iidx33pc_save(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX33pc/save") -async def iidx33pc_save(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - xid = int(request_info["root"][0].attrib["iidxid"]) - cid = request_info["root"][0].attrib["cid"] - clt = int(request_info["root"][0].attrib["cltype"]) + xid = int(ctx.info["root"][0].attrib["iidxid"]) + cid = ctx.info["root"][0].attrib["cid"] + clt = int(ctx.info["root"][0].attrib["cltype"]) profile = get_profile(cid) game_profile = profile["version"].get(str(game_version), {}) @@ -894,8 +878,8 @@ async def iidx33pc_save(request: Request): "s_visualization", "sp_opt", ]: - if k in request_info["root"][0].attrib: - game_profile[k] = request_info["root"][0].attrib[k] + if k in ctx.info["root"][0].attrib: + game_profile[k] = ctx.info["root"][0].attrib[k] for k in [ ("d_liflen", "d_lift"), @@ -904,10 +888,10 @@ async def iidx33pc_save(request: Request): ("sach", "s_achi"), ("bgnflg", "bgnasst"), ]: - if k[1] in request_info["root"][0].attrib: - game_profile[k[0]] = request_info["root"][0].attrib[k[1]] + if k[1] in ctx.info["root"][0].attrib: + game_profile[k[0]] = ctx.info["root"][0].attrib[k[1]] - lightning_setting = request_info["root"][0].find("lightning_setting") + lightning_setting = ctx.info["root"][0].find("lightning_setting") if lightning_setting is not None: for k in [ "headphone_vol", @@ -943,7 +927,7 @@ async def iidx33pc_save(request: Request): if concentration is not None: game_profile["lightning_setting_concentration"] = int(concentration.text) - music_memo = request_info["root"][0].find("music_memo") + music_memo = ctx.info["root"][0].find("music_memo") if music_memo is not None: folders = music_memo.findall("folder") for f in folders: @@ -954,17 +938,17 @@ async def iidx33pc_save(request: Request): game_profile[f"music_memo_{fi}_{ps}_name"] = fn game_profile[f"music_memo_{fi}_{ps}_mids"] = mids - movie_agreement = request_info["root"][0].find("movie_agreement") + movie_agreement = ctx.info["root"][0].find("movie_agreement") if movie_agreement is not None and "agreement_version" in movie_agreement.attrib: game_profile["movie_agreement"] = int( movie_agreement.attrib["agreement_version"] ) - hide_name = request_info["root"][0].find("movie_setting/hide_name") + hide_name = ctx.info["root"][0].find("movie_setting/hide_name") if hide_name is not None: game_profile["hide_name"] = int(hide_name.text) - # lightning_customize_flg = request_info["root"][0].find("lightning_customize_flg") + # lightning_customize_flg = ctx.info["root"][0].find("lightning_customize_flg") # if lightning_customize_flg is not None: # for k in [ # "flg_skin_0", @@ -973,21 +957,21 @@ async def iidx33pc_save(request: Request): # lightning_customize_flg.attrib[k] # ) - secret = request_info["root"][0].find("secret") + secret = ctx.info["root"][0].find("secret") if secret is not None: for k in ["flg1", "flg2", "flg3", "flg4"]: flg = secret.find(k) if flg is not None: game_profile["secret_" + k] = [int(x) for x in flg.text.split(" ")] - leggendaria = request_info["root"][0].find("leggendaria") + leggendaria = ctx.info["root"][0].find("leggendaria") if leggendaria is not None: for k in ["flg1"]: flg = leggendaria.find(k) if flg is not None: game_profile["leggendaria_" + k] = [int(x) for x in flg.text.split(" ")] - step = request_info["root"][0].find("step") + step = ctx.info["root"][0].find("step") if step is not None: for k in [ "dp_fluctuation", @@ -1014,7 +998,7 @@ async def iidx33pc_save(request: Request): if is_track_ticket is not None: game_profile["stepup_is_track_ticket"] = int(is_track_ticket.text) - dj_ranks = request_info["root"][0].findall("dj_rank") + dj_ranks = ctx.info["root"][0].findall("dj_rank") dj_ranks = [] if dj_ranks is None else dj_ranks for dj_rank in dj_ranks: style = int(dj_rank.attrib["style"]) @@ -1029,7 +1013,7 @@ async def iidx33pc_save(request: Request): int(x) for x in point.text.split(" ") ] - skin_equips = request_info["root"][0].findall("pskin_equip") + skin_equips = ctx.info["root"][0].findall("pskin_equip") skin_equips = [] if skin_equips is None else skin_equips skin = { 1: "explosion", @@ -1053,7 +1037,7 @@ async def iidx33pc_save(request: Request): if skin_id in skin: game_profile[skin[skin_id]] = int(skin_equip.attrib["skin_no"]) - tdjskin_equips = request_info["root"][0].findall("vskin_equip") + tdjskin_equips = ctx.info["root"][0].findall("vskin_equip") tdjskin_equips = [] if tdjskin_equips is None else tdjskin_equips tdjskin = { 0: "submonitor", @@ -1066,7 +1050,7 @@ async def iidx33pc_save(request: Request): if skin_id in tdjskin: game_profile[tdjskin[skin_id]] = int(tdjskin_equip.attrib["skin_no"]) - notes_radars = request_info["root"][0].findall("notes_radar") + notes_radars = ctx.info["root"][0].findall("notes_radar") notes_radars = [] if notes_radars is None else notes_radars for notes_radar in notes_radars: style = int(notes_radar.attrib["style"]) @@ -1075,7 +1059,7 @@ async def iidx33pc_save(request: Request): int(x) for x in score.text.split(" ") ] - achievements = request_info["root"][0].find("achievements") + achievements = ctx.info["root"][0].find("achievements") if achievements is not None: for k in [ "last_weekly", @@ -1094,7 +1078,7 @@ async def iidx33pc_save(request: Request): int(x) for x in trophy.text.split(" ") ] - grade = request_info["root"][0].find("grade") + grade = ctx.info["root"][0].find("grade") if grade is not None: grade_values = [] for g in grade.findall("g"): @@ -1105,12 +1089,12 @@ async def iidx33pc_save(request: Request): profile["grade_values"] = grade_values deller_amount = game_profile.get("deller", 0) - deller = request_info["root"][0].find("deller") + deller = ctx.info["root"][0].find("deller") if deller is not None: deller_amount = int(deller.attrib["deller"]) game_profile["deller"] = deller_amount - language = request_info["root"][0].find("language_setting") + language = ctx.info["root"][0].find("language_setting") if language is not None: language_value = int(language.attrib["language"]) game_profile["language_setting"] = language_value @@ -1118,7 +1102,7 @@ async def iidx33pc_save(request: Request): game_profile["spnum"] = game_profile.get("spnum", 0) + (1 if clt == 0 else 0) game_profile["dpnum"] = game_profile.get("dpnum", 0) + (1 if clt == 1 else 0) - if request_info["model"] == "TDJ": + if ctx.info["model"] == "TDJ": game_profile["lightning_play_data_spnum"] = game_profile.get( "lightning_play_data_spnum", 0 ) + (1 if clt == 0 else 0) @@ -1132,13 +1116,10 @@ async def iidx33pc_save(request: Request): response = E.response(E.IIDX33pc(iidxid=xid, cltype=clt)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33pc/visit") -async def iidx33pc_visit(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33pc/visit") +async def iidx33pc_visit(ctx: Ctx): response = E.response( E.IIDX33pc( @@ -1151,18 +1132,15 @@ async def iidx33pc_visit(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("IIDX33pc/reg") +async def iidx33pc_reg(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/IIDX33pc/reg") -async def iidx33pc_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - cid = request_info["root"][0].attrib["cid"] - name = request_info["root"][0].attrib["name"] - pid = request_info["root"][0].attrib["pid"] + cid = ctx.info["root"][0].attrib["cid"] + name = ctx.info["root"][0].attrib["name"] + pid = ctx.info["root"][0].attrib["pid"] db = get_db().table("iidx_profile") all_profiles_for_card = db.get(Query().card == cid) @@ -1402,13 +1380,10 @@ async def iidx33pc_reg(request: Request): response = E.response(E.IIDX33pc(id=card, id_str=card_split)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33pc/getLaneGachaTicket") -async def iidx33pc_getlanegachaticket(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33pc/getLaneGachaTicket") +async def iidx33pc_getlanegachaticket(ctx: Ctx): response = E.response( E.IIDX33pc( @@ -1437,23 +1412,17 @@ async def iidx33pc_getlanegachaticket(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33pc/consumeLaneGachaTicket") -async def iidx33pc_consumelanegachaticket(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33pc/consumeLaneGachaTicket") +async def iidx33pc_consumelanegachaticket(ctx: Ctx): response = E.response(E.IIDX33pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33pc/drawLaneGacha") -async def iidx33pc_drawlanegacha(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33pc/drawLaneGacha") +async def iidx33pc_drawlanegacha(ctx: Ctx): response = E.response( E.IIDX33pc( @@ -1467,65 +1436,46 @@ async def iidx33pc_drawlanegacha(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33pc/eaappliresult") -async def iidx33pc_eaappliresult(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33pc/eaappliresult") +async def iidx33pc_eaappliresult(ctx: Ctx): response = E.response(E.IIDX33pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33pc/playstart") -async def iidx33pc_playstart(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33pc/playstart") +async def iidx33pc_playstart(ctx: Ctx): response = E.response(E.IIDX33pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33pc/playend") -async def iidx33pc_playend(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33pc/playend") +async def iidx33pc_playend(ctx: Ctx): response = E.response(E.IIDX33pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33pc/delete") -async def iidx33pc_delete(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33pc/delete") +async def iidx33pc_delete(ctx: Ctx): response = E.response(E.IIDX33pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33pc/logout") -async def iidx33pc_logout(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33pc/logout") +async def iidx33pc_logout(ctx: Ctx): response = E.response(E.IIDX33pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33pc/getCompeInfo") -async def iidx33pc_getcompeinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33pc/getCompeInfo") +async def iidx33pc_getcompeinfo(ctx: Ctx): response = E.response(E.IIDX33pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx33ranking.py b/modules/iidx/iidx33ranking.py index 5a31687..284cecd 100644 --- a/modules/iidx/iidx33ranking.py +++ b/modules/iidx/iidx33ranking.py @@ -1,18 +1,13 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local", models=["LDJ"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX33ranking/getranker") -async def iidx33ranking_getranker(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33ranking/getranker") +async def iidx33ranking_getranker(ctx: Ctx): response = E.response(E.IIDX33ranking()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx33shop.py b/modules/iidx/iidx33shop.py index fcf9520..3dfd260 100644 --- a/modules/iidx/iidx33shop.py +++ b/modules/iidx/iidx33shop.py @@ -1,19 +1,16 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response from tinydb import Query, where -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] +set_xrpc_defaults(service="local", models=["LDJ"]) - -@router.post("/{gameinfo}/IIDX33shop/getname") -async def iidx33shop_getname(request: Request): - request_info = await core_process_request(request) - pcbid = request_info["root"].attrib["srcid"] +@xrpc("IIDX33shop/getname") +async def iidx33shop_getname(ctx: Ctx): + pcbid = ctx.info["root"].attrib["srcid"] op = get_db().table("shop").get(where("pcbid") == pcbid) op = {} if op is None else op @@ -26,15 +23,12 @@ async def iidx33shop_getname(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33shop/savename") -async def iidx33shop_savename(request: Request): - request_info = await core_process_request(request) - pcbid = request_info["root"].attrib["srcid"] - opname = request_info["root"][0].attrib["opname"] +@xrpc("IIDX33shop/savename") +async def iidx33shop_savename(ctx: Ctx): + pcbid = ctx.info["root"].attrib["srcid"] + opname = ctx.info["root"][0].attrib["opname"] shop_info = { "pcbid": pcbid, @@ -45,13 +39,10 @@ async def iidx33shop_savename(request: Request): response = E.response(E.IIDX33shop()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33shop/getconvention") -async def iidx33shop_getconvention(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33shop/getconvention") +async def iidx33shop_getconvention(ctx: Ctx): response = E.response( E.IIDX33shop( @@ -65,32 +56,24 @@ async def iidx33shop_getconvention(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33shop/sentinfo") -async def iidx33shop_sentinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33shop/sentinfo") +async def iidx33shop_sentinfo(ctx: Ctx): response = E.response(E.IIDX33shop()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33shop/sendescapepackageinfo") -async def iidx33shop_sendescapepackageinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33shop/sendescapepackageinfo") +async def iidx33shop_sendescapepackageinfo(ctx: Ctx): response = E.response(E.IIDX33shop(expire=1200)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response -@router.post("/{gameinfo}/IIDX33shop/getclosingtime") -async def iidx33shop_getclosingtime(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33shop/getclosingtime") +async def iidx33shop_getclosingtime(ctx: Ctx): response = E.response( E.IIDX33shop( @@ -99,14 +82,11 @@ async def iidx33shop_getclosingtime(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response -@router.post("/{gameinfo}/IIDX33shop/saveclosingtime") -async def iidx33shop_saveclosingtime(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33shop/saveclosingtime") +async def iidx33shop_saveclosingtime(ctx: Ctx): response = E.response(E.IIDX33shop()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/iidx33streaming.py b/modules/iidx/iidx33streaming.py index 614393e..df0328d 100644 --- a/modules/iidx/iidx33streaming.py +++ b/modules/iidx/iidx33streaming.py @@ -1,28 +1,20 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local", models=["LDJ"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ"] - - -@router.post("/{gameinfo}/IIDX33streaming/common") -async def iidx33streaming_common(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33streaming/common") +async def iidx33streaming_common(ctx: Ctx): response = E.response(E.IIDX33streaming()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/IIDX33streaming/getcm") -async def iidx33streaming_getcm(request: Request): - request_info = await core_process_request(request) +@xrpc("IIDX33streaming/getcm") +async def iidx33streaming_getcm(ctx: Ctx): response = E.response(E.IIDX33streaming()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/music.py b/modules/iidx/music.py index 5bc1a9e..7f4399a 100644 --- a/modules/iidx/music.py +++ b/modules/iidx/music.py @@ -1,18 +1,14 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import time from enum import IntEnum -from fastapi import APIRouter, Request, Response from tinydb import where -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db import config -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ", "KDZ", "JDZ"] - - class ClearFlags(IntEnum): NO_PLAY = 0 FAILED = 1 @@ -23,14 +19,14 @@ class ClearFlags(IntEnum): EX_HARD_CLEAR = 6 FULL_COMBO = 7 +set_xrpc_defaults(service="local", models=["LDJ", "KDZ", "JDZ"]) -@router.post("/{gameinfo}/music/getrank") -async def music_getrank(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("music/getrank") +async def music_getrank(ctx: Ctx): + game_version = ctx.info["game_version"] - iidxid = int(request_info["root"][0].attrib["iidxid"]) - play_style = int(request_info["root"][0].attrib["cltype"]) + iidxid = int(ctx.info["root"][0].attrib["iidxid"]) + play_style = int(ctx.info["root"][0].attrib["cltype"]) all_scores = {} db = get_db() @@ -85,14 +81,11 @@ async def music_getrank(request: Request): assert response is not None - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/music/crate") -async def music_crate(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("music/crate") +async def music_crate(ctx: Ctx): + game_version = ctx.info["game_version"] db = get_db() all_score_stats = db.table("iidx_score_stats").search( @@ -127,18 +120,15 @@ async def music_crate(request: Request): E.music(*[E.c(crate[k] + fcrate[k], mid=k, __type="u8") for k in crate]) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/music/reg") -async def music_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("music/reg") +async def music_reg(ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - root = request_info["root"][0] + root = ctx.info["root"][0] clear_flg = int(root.attrib["cflg"]) clid = int(root.attrib["clid"]) @@ -337,17 +327,14 @@ async def music_reg(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("music/appoint") +async def music_appoint(ctx: Ctx): -@router.post("/{gameinfo}/music/appoint") -async def music_appoint(request: Request): - request_info = await core_process_request(request) - - iidxid = int(request_info["root"][0].attrib["iidxid"]) - music_id = int(request_info["root"][0].attrib["mid"]) - chart_id = int(request_info["root"][0].attrib["clid"]) + iidxid = int(ctx.info["root"][0].attrib["iidxid"]) + music_id = int(ctx.info["root"][0].attrib["mid"]) + chart_id = int(ctx.info["root"][0].attrib["clid"]) db = get_db() record = db.table("iidx_scores_best").get( @@ -369,5 +356,4 @@ async def music_appoint(request: Request): response = E.response(E.music(*vals)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/pc.py b/modules/iidx/pc.py index 2b5ce77..06e130f 100644 --- a/modules/iidx/pc.py +++ b/modules/iidx/pc.py @@ -1,31 +1,25 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from tinydb import Query, where import config import random -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ", "KDZ", "JDZ"] - +set_xrpc_defaults(service="local", models=["LDJ", "KDZ", "JDZ"]) def get_profile(cid): return get_db().table("iidx_profile").get(where("card") == cid) - def get_profile_by_id(iidx_id): return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - def get_id_from_profile(cid): profile = get_db().table("iidx_profile").get(where("card") == cid) @@ -34,7 +28,6 @@ def get_id_from_profile(cid): return profile["iidx_id"], djid_split - def calculate_folder_mask(profile): return ( profile.get("_show_category_grade", 0) << 0 @@ -48,13 +41,11 @@ def calculate_folder_mask(profile): | (profile.get("_hide_rival_info", 0) << 9) ) +@xrpc("pc/get") +async def pc_get(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/pc/get") -async def pc_get(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - cid = request_info["root"][0].attrib["rid"] + cid = ctx.info["root"][0].attrib["rid"] profile = get_game_profile(cid, game_version) djid, djid_split = get_id_from_profile(cid) @@ -440,14 +431,11 @@ async def pc_get(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/pc/common") -async def pc_common(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("pc/common") +async def pc_common(ctx: Ctx): + game_version = ctx.info["game_version"] if game_version == 20: response = E.response( @@ -526,16 +514,13 @@ async def pc_common(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("pc/save") +async def pc_save(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/pc/save") -async def pc_save(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - root = request_info["root"][0] + root = ctx.info["root"][0] xid = int(root.attrib["iidxid"]) clt = int(root.attrib["cltype"]) @@ -616,7 +601,7 @@ async def pc_save(request: Request): int(x) for x in trophy.text.split(" ") ] - grade = request_info["root"][0].find("grade") + grade = ctx.info["root"][0].find("grade") if grade is not None: grade_values = [] for g in grade.findall("g"): @@ -641,13 +626,10 @@ async def pc_save(request: Request): response = E.response(E.pc(iidxid=xid, cltype=clt)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/pc/visit") -async def pc_visit(request: Request): - request_info = await core_process_request(request) +@xrpc("pc/visit") +async def pc_visit(ctx: Ctx): response = E.response( E.pc( @@ -660,18 +642,15 @@ async def pc_visit(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("pc/reg") +async def pc_reg(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/pc/reg") -async def pc_reg(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - cid = request_info["root"][0].attrib["cid"] - name = request_info["root"][0].attrib["name"] - pid = request_info["root"][0].attrib["pid"] + cid = ctx.info["root"][0].attrib["cid"] + name = ctx.info["root"][0].attrib["name"] + pid = ctx.info["root"][0].attrib["pid"] db = get_db().table("iidx_profile") all_profiles_for_card = db.get(Query().card == cid) @@ -864,15 +843,11 @@ async def pc_reg(request: Request): response = E.response(E.pc(id=card, id_str=card_split)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/pc/logout") -async def pc_logout(request: Request): - request_info = await core_process_request(request) +@xrpc("pc/logout") +async def pc_logout(ctx: Ctx): response = E.response(E.pc()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/ranking.py b/modules/iidx/ranking.py index 844ca24..a9f2eb8 100644 --- a/modules/iidx/ranking.py +++ b/modules/iidx/ranking.py @@ -1,18 +1,13 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local", models=["LDJ", "KDZ", "JDZ"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ", "KDZ", "JDZ"] - - -@router.post("/{gameinfo}/ranking/getranker") -async def ranking_getranker(request: Request): - request_info = await core_process_request(request) +@xrpc("ranking/getranker") +async def ranking_getranker(ctx: Ctx): response = E.response(E.ranking()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/iidx/shop.py b/modules/iidx/shop.py index 75177f9..deb24b8 100644 --- a/modules/iidx/shop.py +++ b/modules/iidx/shop.py @@ -1,16 +1,12 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local", models=["LDJ", "KDZ", "JDZ"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["LDJ", "KDZ", "JDZ"] - - -@router.post("/{gameinfo}/shop/getname") -async def shop_getname(request: Request): - request_info = await core_process_request(request) +@xrpc("shop/getname") +async def shop_getname(ctx: Ctx): response = E.response( E.shop( @@ -20,13 +16,10 @@ async def shop_getname(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/shop/getconvention") -async def shop_getconvention(request: Request): - request_info = await core_process_request(request) +@xrpc("shop/getconvention") +async def shop_getconvention(ctx: Ctx): response = E.response( E.shop( @@ -40,25 +33,18 @@ async def shop_getconvention(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/shop/sentinfo") -async def shop_sentinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("shop/sentinfo") +async def shop_sentinfo(ctx: Ctx): response = E.response(E.shop()) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/shop/sendescapepackageinfo") -async def shop_sendescapepackageinfo(request: Request): - request_info = await core_process_request(request) +@xrpc("shop/sendescapepackageinfo") +async def shop_sendescapepackageinfo(ctx: Ctx): response = E.response(E.shop(expire=1200)) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/nostalgia/op3_common.py b/modules/nostalgia/op3_common.py index 4d9e9c8..e789609 100644 --- a/modules/nostalgia/op3_common.py +++ b/modules/nostalgia/op3_common.py @@ -1,29 +1,22 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import xml.etree.ElementTree as ET from os import path -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service="local", models=["PAN"]) -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["PAN"] - - -@router.post("/{gameinfo}/op3_common/get_common_info") -async def op3_common_get_common_info(request: Request): - request_info = await core_process_request(request) +@xrpc("op3_common/get_common_info") +async def op3_common_get_common_info(ctx: Ctx): response = E.response( E.get_common_info(E.olupdate(E.delete_flag(0, __type="bool"))) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/op3_common/get_music_info") -async def op3_common_get_music_info(request: Request): - request_info = await core_process_request(request) +@xrpc("op3_common/get_music_info") +async def op3_common_get_music_info(ctx: Ctx): songs = {} @@ -150,5 +143,4 @@ async def op3_common_get_music_info(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/nostalgia/op3_player.py b/modules/nostalgia/op3_player.py index 6533a8f..091cb33 100644 --- a/modules/nostalgia/op3_player.py +++ b/modules/nostalgia/op3_player.py @@ -1,32 +1,26 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc from tinydb import Query, where import random -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local", tags=["local"]) -router.model_whitelist = ["PAN"] - +set_xrpc_defaults(service="local", models=["PAN"]) def get_profile(cid): return get_db().table("nostalgia_profile").get(where("card") == cid) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) +@xrpc("op3_player/regist_playdata") +async def op3_player_regist_playdata(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/op3_player/regist_playdata") -async def op3_player_regist_playdata(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - root = request_info["root"][0] + root = ctx.info["root"][0] dataid = root.find("dataid").text refid = root.find("refid").text @@ -158,16 +152,13 @@ async def op3_player_regist_playdata(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("op3_player/get_musicdata") +async def op3_player_get_musicdata(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/op3_player/get_musicdata") -async def op3_player_get_musicdata(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - refid = request_info["root"][0].find("refid").text + refid = ctx.info["root"][0].find("refid").text profile = get_game_profile(refid, game_version) nostalgia_id = get_profile(refid)["nostalgia_id"] @@ -214,16 +205,13 @@ async def op3_player_get_musicdata(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("op3_player/get_playdata") +async def op3_player_get_playdata(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/op3_player/get_playdata") -async def op3_player_get_playdata(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - refid = request_info["root"][0].find("refid").text + refid = ctx.info["root"][0].find("refid").text profile = get_game_profile(refid, game_version) response = E.response( @@ -326,16 +314,13 @@ async def op3_player_get_playdata(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("op3_player/set_stage_result") +async def op3_player_set_stage_result(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/op3_player/set_stage_result") -async def op3_player_set_stage_result(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - root = request_info["root"][0] + root = ctx.info["root"][0] refid = root.find("refid").text profile = get_profile(refid) @@ -481,16 +466,13 @@ async def op3_player_set_stage_result(request: Request): response = E.response(E.set_stage_result(E.player())) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("op3_player/set_total_result") +async def op3_player_set_total_result(ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/op3_player/set_total_result") -async def op3_player_set_total_result(request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - root = request_info["root"][0] + root = ctx.info["root"][0] refid = root.find("refid").text profile = get_profile(refid) @@ -555,5 +537,4 @@ async def op3_player_set_total_result(request: Request): response = E.response(E.set_total_result(E.player())) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/registry.py b/modules/registry.py new file mode 100644 index 0000000..922f537 --- /dev/null +++ b/modules/registry.py @@ -0,0 +1,274 @@ +"""Unified xrpc route registry for slash and slashless dispatch.""" + +from __future__ import annotations + +import inspect +import re +from dataclasses import dataclass, field +from typing import Any, Callable, Optional, Sequence, Union + +from starlette.requests import Request +from starlette.responses import Response + +from core_common import core_prepare_response, core_process_request + +ServiceArg = Union[str, Sequence[str]] + +DEFAULT_PREFIX: dict[str, str] = { + "local": "/local", + "local2": "/local2", + "lobby": "/lobby", + "lobby2": "/lobby2", + "apsmanager": "/core", + "cardmng": "/core", + "dlstatus": "/core", + "eacoin": "/core", + "facility": "/core", + "ins": "/core", + "message": "/core", + "package": "/core", + "package2": "/core", + "pcbevent": "/core", + "pcbtracker": "/core", +} + +_PARAM_RE = re.compile(r"\{([^}/]+)\}") + + +@dataclass +class Ctx: + """Per-request context passed to xrpc handlers.""" + + request: Request + info: dict + + +@dataclass +class RouteEntry: + regex: Optional[re.Pattern] + template: str + endpoint: Callable + param_names: list[str] + whitelist: Optional[frozenset] + blacklist: frozenset + services: list[tuple[str, str]] = field(default_factory=list) + + +_module_defaults: dict[str, dict[str, Any]] = {} +_static: dict[str, list[RouteEntry]] = {} +_param: list[RouteEntry] = [] +_services: list[tuple[str, str, Optional[frozenset], frozenset]] = [] + + +def set_xrpc_defaults( + *, + service: Optional[ServiceArg] = None, + prefix: Optional[Union[str, Sequence[str]]] = None, + models: Optional[Sequence[str]] = None, + model_blacklist: Optional[Sequence[str]] = None, +) -> None: + """Set default @xrpc kwargs for the calling module.""" + modname = inspect.currentframe().f_back.f_globals.get("__name__", "") + defaults: dict[str, Any] = {} + if service is not None: + defaults["service"] = service + if prefix is not None: + defaults["prefix"] = prefix + if models is not None: + defaults["models"] = models + if model_blacklist is not None: + defaults["model_blacklist"] = model_blacklist + _module_defaults[modname] = defaults + + +def _path_template_regex(template: str) -> re.Pattern: + parts = [] + last = 0 + for param in _PARAM_RE.finditer(template): + parts.append(re.escape(template[last : param.start()])) + parts.append(f"(?P<{param.group(1)}>[^/]+)") + last = param.end() + parts.append(re.escape(template[last:])) + return re.compile("^" + "".join(parts) + "$", re.IGNORECASE) + + +def _normalize_services( + service: ServiceArg, prefix: Optional[Union[str, Sequence[str]]] +) -> list[tuple[str, str]]: + if isinstance(service, str): + names = [service] + else: + names = list(service) + + if prefix is None: + prefixes = [DEFAULT_PREFIX.get(n, f"/{n}") for n in names] + elif isinstance(prefix, str): + prefixes = [prefix] * len(names) + else: + prefixes = list(prefix) + if len(prefixes) != len(names): + raise ValueError("prefix sequence must match service names") + + return list(zip(names, prefixes)) + + +def _model_allowed( + model_code: str, whitelist: Optional[frozenset], blacklist: frozenset +) -> bool: + if model_code in blacklist: + return False + if whitelist is not None and model_code not in whitelist: + return False + return True + + +async def _finish(request: Request, result: Any) -> Response: + if isinstance(result, Response): + return result + body, headers = core_prepare_response(request, result) + return Response(content=body, headers=headers) + + +def _make_endpoint(fn: Callable, user_params: list[str]) -> Callable: + """Build a process/prepare wrapper specialized for common handler shapes.""" + + # Most handlers: async def handler(ctx: Ctx) + if user_params == ["ctx"]: + + async def endpoint_ctx(request: Request, **_captures: str) -> Response: + info = await core_process_request(request) + return await _finish( + request, await fn(Ctx(request=request, info=info)) + ) + + return endpoint_ctx + + # Parameterized: async def handler(ver|player|..., ctx: Ctx) + if len(user_params) == 2 and user_params[1] == "ctx": + cap_name = user_params[0] + + async def endpoint_cap(request: Request, **captures: str) -> Response: + info = await core_process_request(request) + return await _finish( + request, + await fn(captures[cap_name], Ctx(request=request, info=info)), + ) + + return endpoint_cap + + async def endpoint_general(request: Request, **captures: str) -> Response: + info = await core_process_request(request) + ctx = Ctx(request=request, info=info) + kwargs: dict[str, Any] = {} + for name in user_params: + if name == "ctx": + kwargs["ctx"] = ctx + elif name in captures: + kwargs[name] = captures[name] + return await _finish(request, await fn(**kwargs)) + + return endpoint_general + + +def xrpc( + template: str, + *, + service: Optional[ServiceArg] = None, + prefix: Optional[Union[str, Sequence[str]]] = None, + models: Optional[Sequence[str]] = None, + model_blacklist: Optional[Sequence[str]] = None, +) -> Callable: + """Register an e-amuse handler; wraps process/prepare around the function.""" + + modname = inspect.currentframe().f_back.f_globals.get("__name__", "") + defaults = _module_defaults.get(modname, {}) + if service is None: + service = defaults.get("service") + if service is None: + raise TypeError("@xrpc requires service= or set_xrpc_defaults(service=...)") + if prefix is None: + prefix = defaults.get("prefix") + if models is None and "models" in defaults: + models = defaults["models"] + if model_blacklist is None and "model_blacklist" in defaults: + model_blacklist = defaults["model_blacklist"] + + template = template.lstrip("/") + pairs = _normalize_services(service, prefix) + whitelist = frozenset(models) if models is not None else None + blacklist = frozenset(model_blacklist) if model_blacklist else frozenset() + parameterized = "{" in template + + def decorator(fn: Callable) -> Callable: + user_params = list(inspect.signature(fn).parameters.keys()) + endpoint = _make_endpoint(fn, user_params) + + entry = RouteEntry( + regex=_path_template_regex(template) if parameterized else None, + template=template, + endpoint=endpoint, + param_names=user_params, + whitelist=whitelist, + blacklist=blacklist, + services=pairs, + ) + if parameterized: + _param.append(entry) + else: + _static.setdefault(template.lower(), []).append(entry) + for name, pref in pairs: + _services.append((name, pref, whitelist, blacklist)) + return fn + + return decorator + + +def clear() -> None: + _static.clear() + _param.clear() + _services.clear() + _module_defaults.clear() + + +def routes() -> list[RouteEntry]: + out: list[RouteEntry] = [] + for entries in _static.values(): + out.extend(entries) + out.extend(_param) + return out + + +async def dispatch( + request: Request, model: Optional[str], path_key: str +) -> Response: + model_code = (model or "").split(":")[0] + path_key = path_key.lstrip("/") + + for entry in _static.get(path_key.lower(), ()): + if not _model_allowed(model_code, entry.whitelist, entry.blacklist): + continue + return await entry.endpoint(request) + + for entry in _param: + if not _model_allowed(model_code, entry.whitelist, entry.blacklist): + continue + match = entry.regex.match(path_key) + if not match: + continue + return await entry.endpoint(request, **match.groupdict()) + + return Response(status_code=404) + + +def iter_services(model_code: str) -> list[tuple[str, str]]: + """Unique (service_name, prefix) advertised for this game model code.""" + seen: set[str] = set() + out: list[tuple[str, str]] = [] + for name, pref, whitelist, blacklist in _services: + if not _model_allowed(model_code, whitelist, blacklist): + continue + if name in seen: + continue + seen.add(name) + out.append((name, pref)) + return out diff --git a/modules/sdvx/eventlog.py b/modules/sdvx/eventlog.py index 4f533c7..3630f1e 100644 --- a/modules/sdvx/eventlog.py +++ b/modules/sdvx/eventlog.py @@ -1,16 +1,12 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import config -from fastapi import APIRouter, Request, Response +from core_common import E -from core_common import core_process_request, core_prepare_response, E +set_xrpc_defaults(service=("local", "local2"), models=["KFC"]) -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["KFC"] - - -@router.post("/{gameinfo}/eventlog/write") -async def sdvx_eventlog_write(request: Request): - request_info = await core_process_request(request) +@xrpc("eventlog/write") +async def sdvx_eventlog_write(ctx: Ctx): response = E.response( E.eventlog( @@ -21,5 +17,4 @@ async def sdvx_eventlog_write(request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/sdvx/game.py b/modules/sdvx/game.py index 669107e..fd720ed 100644 --- a/modules/sdvx/game.py +++ b/modules/sdvx/game.py @@ -1,3 +1,4 @@ +from modules.registry import Ctx, set_xrpc_defaults, xrpc import xml.etree.ElementTree as ET from os import path @@ -7,25 +8,19 @@ import config import random import time -from fastapi import APIRouter, Request, Response - -from core_common import core_process_request, core_prepare_response, E +from core_common import E from core_database import get_db -router = APIRouter(prefix="/local2", tags=["local2"]) -router.model_whitelist = ["KFC"] - +set_xrpc_defaults(service=("local", "local2"), models=["KFC"]) def get_profile(cid): return get_db().table("sdvx_profile").get(where("card") == cid) - def get_game_profile(cid, game_version): profile = get_profile(cid) return profile["version"].get(str(game_version), None) - def get_id_from_profile(cid): profile = get_db().table("sdvx_profile").get(where("card") == cid) @@ -34,10 +29,8 @@ def get_id_from_profile(cid): return profile["sdvx_id"], djid_split - -@router.post("/{gameinfo}/game/sv{ver}_common") -async def game_sv_common(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_common") +async def game_sv_common(ver: str, ctx: Ctx): event = [ "DEMOGAME_PLAY", @@ -132,7 +125,6 @@ async def game_sv_common(ver: str, request: Request): for j in range(0, 5): unlock.append([i, j]) - response = E.response( E.game( E.event( @@ -156,16 +148,13 @@ async def game_sv_common(ver: str, request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("game/sv{ver}_new") +async def game_sv_new(ver: str, ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/game/sv{ver}_new") -async def game_sv_new(ver: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - root = request_info["root"][0] + root = ctx.info["root"][0] dataid = root.find("dataid").text cardno = root.find("cardno").text @@ -229,16 +218,13 @@ async def game_sv_new(ver: str, request: Request): ), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("game/sv{ver}_load") +async def game_sv_load(ver: str, ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/game/sv{ver}_load") -async def game_sv_load(ver: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - dataid = request_info["root"][0].find("dataid").text + dataid = ctx.info["root"][0].find("dataid").text profile = get_game_profile(dataid, game_version) if profile: @@ -397,16 +383,13 @@ async def game_sv_load(ver: str, request: Request): ) ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("game/sv{ver}_load_m") +async def game_sv_load_m(ver: str, ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/game/sv{ver}_load_m") -async def game_sv_load_m(ver: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - dataid = request_info["root"][0].find("refid").text + dataid = ctx.info["root"][0].find("refid").text profile = get_game_profile(dataid, game_version) djid, djid_split = get_id_from_profile(dataid) @@ -457,21 +440,18 @@ async def game_sv_load_m(ver: str, request: Request): ), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response +@xrpc("game/sv{ver}_save") +async def game_sv_save(ver: str, ctx: Ctx): + game_version = ctx.info["game_version"] -@router.post("/{gameinfo}/game/sv{ver}_save") -async def game_sv_save(ver: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] - - dataid = request_info["root"][0].find("refid").text + dataid = ctx.info["root"][0].find("refid").text profile = get_profile(dataid) game_profile = profile["version"].get(str(game_version), {}) - root = request_info["root"][0] + root = ctx.info["root"][0] game_profile["appeal_id"] = int(root.find("appeal_id").text) @@ -588,18 +568,15 @@ async def game_sv_save(ver: str, request: Request): E.game(), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_save_m") -async def game_sv_save_m(ver: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("game/sv{ver}_save_m") +async def game_sv_save_m(ver: str, ctx: Ctx): + game_version = ctx.info["game_version"] timestamp = time.time() - root = request_info["root"][0] + root = ctx.info["root"][0] dataid = root.find("dataid").text profile = get_game_profile(dataid, game_version) @@ -699,14 +676,11 @@ async def game_sv_save_m(ver: str, request: Request): E.game(), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_hiscore") -async def game_sv_hiscore(ver: str, request: Request): - request_info = await core_process_request(request) - game_version = request_info["game_version"] +@xrpc("game/sv{ver}_hiscore") +async def game_sv_hiscore(ver: str, ctx: Ctx): + game_version = ctx.info["game_version"] best_scores = [] db = get_db() @@ -743,137 +717,103 @@ async def game_sv_hiscore(ver: str, request: Request): ), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_lounge") -async def game_sv_lounge(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_lounge") +async def game_sv_lounge(ver: str, ctx: Ctx): response = E.response( E.game(E.interval(30, __type="u32")), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_shop") -async def game_sv_shop(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_shop") +async def game_sv_shop(ver: str, ctx: Ctx): response = E.response( E.game(E.nxt_time(1000 * 5 * 60, __type="u32")), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_load_r") -async def game_sv_load_r(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_load_r") +async def game_sv_load_r(ver: str, ctx: Ctx): response = E.response( E.game(), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_frozen") -async def game_sv_frozen(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_frozen") +async def game_sv_frozen(ver: str, ctx: Ctx): response = E.response( E.game(), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_save_e") -async def game_sv_save_e(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_save_e") +async def game_sv_save_e(ver: str, ctx: Ctx): response = E.response( E.game(), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_save_mega") -async def game_sv_save_mega(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_save_mega") +async def game_sv_save_mega(ver: str, ctx: Ctx): response = E.response( E.game(), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_play_e") -async def game_sv_play_e(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_play_e") +async def game_sv_play_e(ver: str, ctx: Ctx): response = E.response( E.game(), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_play_s") -async def game_sv_play_s(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_play_s") +async def game_sv_play_s(ver: str, ctx: Ctx): response = E.response( E.game(), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_entry_s") -async def game_sv_entry_s(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_entry_s") +async def game_sv_entry_s(ver: str, ctx: Ctx): response = E.response( E.game(), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_entry_e") -async def game_sv_entry_e(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_entry_e") +async def game_sv_entry_e(ver: str, ctx: Ctx): response = E.response( E.game(), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response - -@router.post("/{gameinfo}/game/sv{ver}_log") -async def game_sv_log(ver: str, request: Request): - request_info = await core_process_request(request) +@xrpc("game/sv{ver}_log") +async def game_sv_log(ver: str, ctx: Ctx): response = E.response( E.game(), ) - response_body, response_headers = await core_prepare_response(request, response) - return Response(content=response_body, headers=response_headers) + return response diff --git a/modules/webapi.py b/modules/webapi.py new file mode 100644 index 0000000..cc0e354 --- /dev/null +++ b/modules/webapi.py @@ -0,0 +1,33 @@ +"""Helpers for Starlette WebUI JSON APIs.""" + +from __future__ import annotations + +import json +from typing import Any, Callable, Type + +from pydantic import BaseModel +from starlette.requests import Request +from starlette.responses import JSONResponse, Response + + +async def read_model(request: Request, model: Type[BaseModel]) -> BaseModel: + body = await request.body() + data = json.loads(body) if body else {} + return model.model_validate(data) + + +def as_response(value: Any) -> Response: + if isinstance(value, Response): + return value + return JSONResponse(value) + + +def endpoint(fn: Callable) -> Callable: + """Wrap an async handler so plain dict/list returns become JSON.""" + + async def wrapper(request: Request) -> Response: + result = await fn(request) + return as_response(result) + + wrapper.__name__ = getattr(fn, "__name__", "endpoint") + return wrapper diff --git a/pyeamu.py b/pyeamu.py index ee9a901..c1d03ba 100644 --- a/pyeamu.py +++ b/pyeamu.py @@ -1,126 +1,123 @@ -from urllib.parse import urlparse, urlunparse, urlencode +"""Compose outer bare ASGI (e-amuse) with Starlette WebUI sub-app.""" -import uvicorn +from __future__ import annotations import json -from os import name, path -from typing import Optional - -from fastapi import FastAPI, Request, Response -from fastapi.middleware.cors import CORSMiddleware -from fastapi.staticfiles import StaticFiles -from starlette.responses import RedirectResponse +import re +from os import path +from urllib.parse import unquote, urlencode, urlparse, urlunparse +from starlette.applications import Starlette +from starlette.middleware import Middleware +from starlette.middleware.cors import CORSMiddleware +from starlette.requests import Request +from starlette.responses import JSONResponse, RedirectResponse, Response +from starlette.routing import Mount, Route +from starlette.staticfiles import StaticFiles +from starlette.types import ASGIApp, Receive, Scope, Send import config import modules import utils.card as conv - -from core_common import core_process_request, core_prepare_response, E - -import socket - - -def urlpathjoin(parts, sep="/"): - return sep + sep.join([x.lstrip(sep) for x in parts]) - +from core_common import E, EamuseError, core_prepare_response, core_process_request +from modules.registry import dispatch, iter_services loopback = "127.0.0.1" -server_addresses = [] -for host in ("localhost", config.ip, socket.gethostname()): - server_addresses.append(f"{host}:{config.port}") - -server_services_urls = [] -for server_address in server_addresses: - server_services_urls.append( - urlunparse(("http", server_address, "/core", None, None, None)) +settings = { + s: getattr(config, s) + for s in ( + "ip", + "port", + "response_compression", + "verbose_log", + "arcade", + "paseli", + "maintenance_mode", ) +} -settings = {} -for s in ( - "ip", - "port", - "response_compression", - "verbose_log", - "arcade", - "paseli", - "maintenance_mode", -): - settings[s] = getattr(config, s) +# Paths handled by the Starlette WebUI / static sub-app +_WEBUI_PREFIXES = ("/webui", "/ddr", "/iidx", "/gfdm", "/config", "/conv") -app = FastAPI() -for router in modules.routers: - app.include_router(router) - -app.add_middleware( - CORSMiddleware, - allow_origins=["*"], - allow_credentials=True, - allow_methods=["*"], - allow_headers=["*"], +_CORE_SERVICES_GET = re.compile( + r"^/core/[^/]+/services/get/?$", re.IGNORECASE ) +# (model, slashless, request_address) -> service name -> url +_services_url_cache: dict[tuple[str, bool, str], dict[str, str]] = {} -if path.exists("webui"): - webui = True - with open(path.join("webui", "monkey.json"), "w") as f: - json.dump(settings, f, indent=2) - app.mount("/webui", StaticFiles(directory="webui", html=True), name="webui") -else: - webui = False - - @app.get("/webui") - async def redirect_to_config(): - return RedirectResponse(url="/config") - - -# Enable ANSI escape sequences -if name == "nt": - import ctypes - - kernel32 = ctypes.windll.kernel32 - kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7) - - -if __name__ == "__main__": - print( - """ - █▄ ▄█ █▀█ █▄ █ █▄▀ ▀██ ▀▄▀ - █ ▀ █ █▄█ █ ▀█ █ █ ▄▄█ █ - - ██▄ █ █ ▄▀▀ ▄█ █▄ █ ▀██ ▀█▀ - █▄█ ▀▄█ ▄██ █ █ ▀█ ▄▄█ █▄▄ -""" +_KEEPALIVE_URL = urlunparse( + ( + "http", + loopback, + "/keepalive", + None, + urlencode( + { + "pa": loopback, + "ia": loopback, + "ga": loopback, + "ma": loopback, + "t1": 2, + "t2": 10, + } + ), + None, ) - print() - print("\033[1mGame Config\033[0m:") - for server_services_url in server_services_urls: - print(f"\033[92m{server_services_url}\033[0m") - print("") - print() - print("\033[1mWeb Interface\033[0m:") - if webui: - for server_address in server_addresses: - print(f"http://{server_address}/webui/") - else: - print("/webui missing") - print("download it here: https://github.com/drmext/BounceTrippy/releases") - print() - print("\033[1mSource Repository\033[0m:") - print("https://github.com/drmext/MonkeyBusiness") - print() - uvicorn.run("pyeamu:app", host="0.0.0.0", port=config.port, reload=True) +) +_NTP_URL = urlunparse(("ntp", "pool.ntp.org", "/", None, None, None)) -@app.post("/core") -@app.post("/core/{gameinfo}/services/get") -async def services_get( - request: Request, - model: Optional[str] = None, - f: Optional[str] = None, - module: Optional[str] = None, - method: Optional[str] = None, -): +def _resolve_path_key(request: Request) -> str | None: + """Slashless (?f= / module+method) or slashed ({path}) -> module/method key.""" + qp = request.query_params + f = qp.get("f") + module = qp.get("module") + method = qp.get("method") + + if f is not None: + module, method = f.split(".", 1) + + if module and method: + return f"{module}/{method}" + + path_params = request.scope.get("path_params") or {} + if "path" in path_params: + return path_params["path"] + + return None + + +async def handle_xrpc(request: Request, *, model: str | None = None) -> Response: + if model is None: + model = request.query_params.get("model") + path_key = _resolve_path_key(request) + if not path_key: + return Response(status_code=404) + return await dispatch(request, model, path_key) + + +def _services_for(model: str, slashless: bool, request_address: str) -> dict[str, str]: + key = (model, slashless, request_address) + cached = _services_url_cache.get(key) + if cached is not None: + return cached + + services: dict[str, str] = {} + for service_name, prefix in iter_services(model): + if service_name in services: + continue + pre = "/fwdr" if slashless else prefix + services[service_name] = urlunparse( + ("http", request_address, pre, None, None, None) + ) + services["keepalive"] = _KEEPALIVE_URL + services["ntp"] = _NTP_URL + _services_url_cache[key] = services + return services + + +async def services_get(request: Request) -> Response: request_info = await core_process_request(request) parsed = urlparse(str(request.url)) @@ -129,51 +126,13 @@ async def services_get( else: request_address = f"{parsed.netloc}:{config.port}" - services = {} + qp = request.query_params + f = qp.get("f") + module = qp.get("module") + method = qp.get("method") + slashless = f == "services.get" or (module == "services" and method == "get") - for service in modules.routers: - model_blacklist = services.get("model_blacklist", []) - model_whitelist = services.get("model_whitelist", []) - - if request_info["model"] in model_blacklist: - continue - - if model_whitelist and request_info["model"] not in model_whitelist: - continue - - tag = service.tags[0] if service.tags else "" - if tag.startswith("api_") or tag == "slashless_forwarder": - continue - - k = (tag if tag else service.prefix).strip("/") - if f == "services.get" or module == "services" and method == "get": - # url_slash 0 - pre = "/fwdr" - else: - # url_slash 1 - pre = service.prefix - if k not in services: - services[k] = urlunparse(("http", request_address, pre, None, None, None)) - - keepalive_params = { - "pa": loopback, - "ia": loopback, - "ga": loopback, - "ma": loopback, - "t1": 2, - "t2": 10, - } - services["keepalive"] = urlunparse( - ( - "http", - loopback, - "/keepalive", - None, - urlencode(keepalive_params), - None, - ) - ) - services["ntp"] = urlunparse(("ntp", "pool.ntp.org", "/", None, None, None)) + services = _services_for(request_info["model"], slashless, request_address) response = E.response( E.services( @@ -184,29 +143,21 @@ async def services_get( ) ) - response_body, response_headers = await core_prepare_response(request, response) + response_body, response_headers = core_prepare_response(request, response) return Response(content=response_body, headers=response_headers) -@app.get("/") -async def redirect_to_webui(): +async def redirect_to_webui(request: Request) -> Response: return RedirectResponse(url="/webui") -@app.get("/config") -async def get_config(): - return settings +async def get_config(request: Request) -> Response: + return JSONResponse(settings) -@app.get("/conv/{card}") -async def card_conv(card: str): - card = card.upper() - lookalike = { - "I": "1", - "O": "0", - "Q": "0", - "V": "U", - } +async def card_conv(request: Request) -> Response: + card = request.path_params["card"].upper() + lookalike = {"I": "1", "O": "0", "Q": "0", "V": "U"} for k, v in lookalike.items(): card = card.replace(k, v) if card.startswith("E004") or card.startswith("012E"): @@ -217,4 +168,92 @@ async def card_conv(card: str): card = "".join([c for c in card if c in conv.valid_characters]) uid = conv.to_uid(card) kid = card - return {"uid": uid, "konami_id": kid} + return JSONResponse({"uid": uid, "konami_id": kid}) + + +async def redirect_webui_missing(request: Request) -> Response: + return RedirectResponse(url="/config") + + +def _build_webui() -> Starlette: + routes: list = [ + Route("/", redirect_to_webui, methods=["GET"]), + Route("/config", get_config, methods=["GET"]), + Route("/conv/{card}", card_conv, methods=["GET"]), + ] + + for mount_path, api_router in modules.webui_routers: + routes.insert(0, Mount(mount_path, app=api_router)) + + if path.exists("webui"): + with open(path.join("webui", "monkey.json"), "w") as f: + json.dump(settings, f, indent=2) + routes.insert(0, Mount("/webui", app=StaticFiles(directory="webui", html=True))) + else: + routes.insert(0, Route("/webui", redirect_webui_missing, methods=["GET"])) + + middleware = [ + Middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) + ] + return Starlette(routes=routes, middleware=middleware) + + +webui_app: ASGIApp = _build_webui() +has_webui = path.exists("webui") + + +async def _send_response(response: Response, scope: Scope, receive: Receive, send: Send) -> None: + await response(scope, receive, send) + + +async def app(scope: Scope, receive: Receive, send: Send) -> None: + if scope["type"] == "lifespan": + await webui_app(scope, receive, send) + return + + if scope["type"] != "http": + return + + raw_path = unquote(scope.get("path") or "") + method = scope.get("method", "GET").upper() + + # WebUI / static / config / card converter + if raw_path == "/" or any( + raw_path == p or raw_path.startswith(p + "/") for p in _WEBUI_PREFIXES + ): + await webui_app(scope, receive, send) + return + + if method != "POST": + await _send_response(Response(status_code=404), scope, receive, send) + return + + request = Request(scope, receive) + + try: + # services.get + if raw_path.rstrip("/") == "/core" or _CORE_SERVICES_GET.match(raw_path): + response = await services_get(request) + elif raw_path.rstrip("/") == "/fwdr": + response = await handle_xrpc(request) + else: + # slashed: /{svc}/{gameinfo}/{path...} — model is the gameinfo segment + parts = [p for p in raw_path.strip("/").split("/") if p] + if len(parts) >= 3: + scope = dict(scope) + scope["path_params"] = {"path": "/".join(parts[2:])} + request = Request(scope, receive) + model = request.query_params.get("model") or parts[1] + response = await handle_xrpc(request, model=model) + else: + response = Response(status_code=404) + except EamuseError as exc: + response = Response(status_code=exc.status_code, content=exc.detail or b"") + + await _send_response(response, scope, receive, send) diff --git a/requirements.txt b/requirements.txt index 382736d..07d7df4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ -fastapi +starlette +uvicorn[standard] kbinxml>=2.0 pycryptodomex python-multipart +pydantic tinydb -uvicorn[standard] diff --git a/start.bat b/start.bat index e0c69ae..b3cf146 100644 --- a/start.bat +++ b/start.bat @@ -11,10 +11,10 @@ if not exist .venv\Scripts\activate.bat ( py -m venv .venv .venv\Scripts\activate.bat py -m pip install -r requirements.txt - py pyeamu.py + py main.py ) else ( .venv\Scripts\activate.bat - py pyeamu.py + py main.py ) goto :EOF diff --git a/start.sh b/start.sh index aef882f..c3591c5 100644 --- a/start.sh +++ b/start.sh @@ -16,4 +16,4 @@ fi source .venv/bin/activate $py -m pip install -r requirements.txt -$py pyeamu.py +$py main.py