mirror of
https://github.com/drmext/MonkeyBusiness.git
synced 2026-10-26 09:10:18 -05:00
Fix
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@
|
||||
/*.db
|
||||
.venv/
|
||||
webui/
|
||||
MonkeyBusiness.log
|
||||
|
||||
@@ -9,8 +9,8 @@ Run [start.bat (Windows)](start.bat) or [start.sh (Linux, MacOS)](start.sh)
|
||||
[web interface](https://github.com/drmext/BounceTrippy/releases), [score import](utils/db)
|
||||
|
||||
## Playable Games
|
||||
- IIDX 18-20, 29-33 (Online Arena/BPL support)
|
||||
- DDR A20P, A3, WORLD (OmniMIX/GF, BPL, and [Fake PFREE](https://github.com/drmext/BemaniPatcher/blob/nopr/ddra3.html#L133) support)
|
||||
- IIDX 18-20, 29-34 (Online Arena/BPL support)
|
||||
- DDR A20P, A3, WORLD (OmniMIX/GF, BPL, and Fake PFREE support)
|
||||
- GD 6-10 DELTA (Battle Mode support)
|
||||
- DRS
|
||||
- NOST 3
|
||||
@@ -20,8 +20,10 @@ Run [start.bat (Windows)](start.bat) or [start.sh (Linux, MacOS)](start.sh)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Delete [or fix](start.bat#L9) `/.venv` if the server folder is moved or python is upgraded
|
||||
- Delete [or fix](make_venv_portable.bat) `/.venv` if the server folder is moved or python is upgraded
|
||||
|
||||
- DRS, GD, NOST, and SDVX require mdb xml files copied to the server folder
|
||||
|
||||
- When initially creating a DDR profile, complete an entire credit without pfree hacks
|
||||
|
||||
- Update the webui
|
||||
|
||||
@@ -18,6 +18,7 @@ ip = get_ip()
|
||||
port = 8000
|
||||
response_compression = False
|
||||
verbose_log = False
|
||||
log_to_file = False
|
||||
dev_reload = False
|
||||
|
||||
arcade = "M0NKYBUS1N3Z"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import config
|
||||
|
||||
import os
|
||||
import re
|
||||
import threading
|
||||
import time
|
||||
@@ -15,6 +16,24 @@ 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
|
||||
|
||||
_ANSI_RE = re.compile(r"\033\[[0-9;]*m")
|
||||
_LOG_PATH = os.path.join(os.path.dirname(os.path.abspath(config.__file__)), "MonkeyBusiness.log")
|
||||
_LOG_LOCK = threading.Lock()
|
||||
|
||||
|
||||
def _verbose_log(*lines: str) -> None:
|
||||
"""Print and/or append dump lines; destinations controlled independently."""
|
||||
if config.verbose_log:
|
||||
for line in lines:
|
||||
print(line)
|
||||
if not config.log_to_file:
|
||||
return
|
||||
plain = "\n".join(_ANSI_RE.sub("", line) for line in lines) + "\n"
|
||||
with _LOG_LOCK:
|
||||
with open(_LOG_PATH, "a", encoding="utf-8") as f:
|
||||
f.write(plain)
|
||||
f.flush()
|
||||
|
||||
# XML declaration charset aliases -> kbinxml / binary codec name (xrpc-go EncodingByName).
|
||||
_ENCODING_ALIASES = {
|
||||
"UTF-8": "UTF-8",
|
||||
@@ -194,6 +213,7 @@ def _parse_eamuse_info(header):
|
||||
|
||||
# (min_ext, version) newest-first; first match with ext >= min_ext wins.
|
||||
_LDJ_VERSIONS = (
|
||||
(2026091600, 34),
|
||||
(2025091700, 33),
|
||||
(2024100900, 32),
|
||||
(2023101800, 31),
|
||||
@@ -295,20 +315,22 @@ async def core_process_request(request):
|
||||
request.xml_encoding = _detect_text_xml_encoding(xml_dec)
|
||||
|
||||
xml_text = None
|
||||
if config.verbose_log:
|
||||
if config.verbose_log or config.log_to_file:
|
||||
xml_text = xml.to_text()
|
||||
eamuse_info = (
|
||||
request.headers.get("X-Eamuse-Info") if request.is_encrypted else "none"
|
||||
)
|
||||
print()
|
||||
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'})"
|
||||
_verbose_log(
|
||||
"",
|
||||
"\033[94mREQUEST\033[0m:",
|
||||
f"X-Eamuse-Info: {eamuse_info}",
|
||||
f"X-Compress: {request.compress}",
|
||||
(
|
||||
f"Encoding: {_xml_decl_name(request.xml_encoding)}"
|
||||
f" ({'binary' if request.is_binxml else 'text'})"
|
||||
),
|
||||
xml_text,
|
||||
)
|
||||
print(xml_text)
|
||||
|
||||
model_parts = (root.attrib["model"], *root.attrib["model"].split(":"))
|
||||
module = root[0].tag
|
||||
@@ -373,14 +395,16 @@ def core_prepare_response(request, xml):
|
||||
else:
|
||||
response = bytes(response)
|
||||
|
||||
if config.verbose_log:
|
||||
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'})"
|
||||
if config.verbose_log or config.log_to_file:
|
||||
_verbose_log(
|
||||
"\033[91mRESPONSE\033[0m:",
|
||||
f"X-Eamuse-Info: {response_headers.get('X-Eamuse-Info', 'none')}",
|
||||
f"X-Compress: {response_headers['X-Compress']}",
|
||||
(
|
||||
f"Encoding: {_xml_decl_name(enc)}"
|
||||
f" ({'binary' if request.is_binxml else 'text'})"
|
||||
),
|
||||
binxml.to_text(),
|
||||
)
|
||||
print(binxml.to_text())
|
||||
|
||||
return response, response_headers
|
||||
|
||||
195
modules/iidx/iidx34gamesystem.py
Normal file
195
modules/iidx/iidx34gamesystem.py
Normal file
@@ -0,0 +1,195 @@
|
||||
from modules.registry import Ctx, set_xrpc_defaults, xrpc
|
||||
from time import time
|
||||
|
||||
import config
|
||||
|
||||
from core_common import E
|
||||
|
||||
set_xrpc_defaults(service="local", models=["LDJ"])
|
||||
|
||||
@xrpc("IIDX34gameSystem/systemInfo")
|
||||
async def iidx34gamesystem_systeminfo(ctx: Ctx):
|
||||
|
||||
unlock = ()
|
||||
# force unlock LM exclusives to complete unlock all songs server side
|
||||
# this makes LM exclusive folder disappear, so just use hex edits
|
||||
# unlock = (30106, 31084, 30077, 31085, 30107, 30028, 30076, 31083, 30098)
|
||||
|
||||
current_time = round(time())
|
||||
|
||||
response = E.response(
|
||||
E.IIDX34gameSystem(
|
||||
# E.option_2pp(),
|
||||
*[
|
||||
E.music_open(
|
||||
E.music_id(mid, __type="s32"),
|
||||
E.kind(0, __type="s32"),
|
||||
)
|
||||
for mid in unlock
|
||||
],
|
||||
E.grade_course(
|
||||
E.play_style(0, __type="s32"),
|
||||
E.grade_id(15, __type="s32"),
|
||||
E.music_id_0(19022, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(23068, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(27013, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(29045, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
E.is_valid(1, __type="bool"),
|
||||
),
|
||||
E.grade_course(
|
||||
E.play_style(0, __type="s32"),
|
||||
E.grade_id(16, __type="s32"),
|
||||
E.music_id_0(27034, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(24023, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(16009, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(25085, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
E.is_valid(1, __type="bool"),
|
||||
),
|
||||
E.grade_course(
|
||||
E.play_style(0, __type="s32"),
|
||||
E.grade_id(17, __type="s32"),
|
||||
E.music_id_0(26087, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(19002, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(29050, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(30024, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
E.is_valid(1, __type="bool"),
|
||||
),
|
||||
E.grade_course(
|
||||
E.play_style(0, __type="s32"),
|
||||
E.grade_id(18, __type="s32"),
|
||||
E.music_id_0(30052, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(18032, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(16020, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(12004, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
E.is_valid(1, __type="bool"),
|
||||
),
|
||||
E.grade_course(
|
||||
E.play_style(1, __type="s32"),
|
||||
E.grade_id(15, __type="s32"),
|
||||
E.music_id_0(12002, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(31063, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(23046, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(30020, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
E.is_valid(1, __type="bool"),
|
||||
),
|
||||
E.grade_course(
|
||||
E.play_style(1, __type="s32"),
|
||||
E.grade_id(16, __type="s32"),
|
||||
E.music_id_0(26106, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(14021, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(29052, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(23075, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
E.is_valid(1, __type="bool"),
|
||||
),
|
||||
E.grade_course(
|
||||
E.play_style(1, __type="s32"),
|
||||
E.grade_id(17, __type="s32"),
|
||||
E.music_id_0(29042, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(26043, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(17017, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(28005, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
E.is_valid(1, __type="bool"),
|
||||
),
|
||||
E.grade_course(
|
||||
E.play_style(1, __type="s32"),
|
||||
E.grade_id(18, __type="s32"),
|
||||
E.music_id_0(25007, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(29017, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(19002, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(9028, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
E.is_valid(1, __type="bool"),
|
||||
),
|
||||
E.arena_schedule(
|
||||
E.season(1, __type="u8"),
|
||||
E.phase(4, __type="u8"),
|
||||
E.rule_type(0, __type="u8"),
|
||||
E.start(current_time - 600, __type="u32"),
|
||||
E.end(current_time + 600, __type="u32"),
|
||||
),
|
||||
*[
|
||||
E.arena_reward(
|
||||
E.index(unlock.index(mid), __type="s32"),
|
||||
E.cube_num((unlock.index(mid) + 1) * 50, __type="s32"),
|
||||
E.kind(0, __type="s32"),
|
||||
E.value(mid, __type="str"),
|
||||
)
|
||||
for mid in unlock
|
||||
],
|
||||
*[
|
||||
E.arena_music_difficult(
|
||||
E.play_style(sp_dp, __type="s32"),
|
||||
E.arena_class(arena_class, __type="s32"),
|
||||
E.low_difficult(8, __type="s32"),
|
||||
E.high_difficult(12, __type="s32"),
|
||||
E.is_leggendaria(1, __type="bool"),
|
||||
E.force_music_list_id(0, __type="s32"),
|
||||
)
|
||||
for sp_dp in (0, 1)
|
||||
for arena_class in range(20)
|
||||
],
|
||||
*[
|
||||
E.arena_cpu_define(
|
||||
E.play_style(sp_dp, __type="s32"),
|
||||
E.arena_class(arena_class, __type="s32"),
|
||||
E.grade_id(18, __type="s32"),
|
||||
E.low_music_difficult(8, __type="s32"),
|
||||
E.high_music_difficult(12, __type="s32"),
|
||||
E.is_leggendaria(0, __type="bool"),
|
||||
)
|
||||
for sp_dp in (0, 1)
|
||||
for arena_class in range(20)
|
||||
],
|
||||
*[
|
||||
E.maching_class_range(
|
||||
E.play_style(sp_dp, __type="s32"),
|
||||
E.matching_class(arena_class, __type="s32"),
|
||||
E.low_arena_class(arena_class, __type="s32"),
|
||||
E.high_arena_class(arena_class, __type="s32"),
|
||||
)
|
||||
for sp_dp in (0, 1)
|
||||
for arena_class in range(20)
|
||||
],
|
||||
E.Event1Phase(val=0),
|
||||
E.isNewSongAnother12OpenFlg(val=1),
|
||||
E.isKiwamiOpenFlg(val=1),
|
||||
E.WorldTourismOpenList(val=-1),
|
||||
E.OldBPLBattleOpenPhase(val=1),
|
||||
E.BPLBattleOpenPhase(val=3),
|
||||
E.VocaloidEvent(val=1),
|
||||
# E.beat(val=5293),
|
||||
)
|
||||
)
|
||||
|
||||
return response
|
||||
113
modules/iidx/iidx34grade.py
Normal file
113
modules/iidx/iidx34grade.py
Normal file
@@ -0,0 +1,113 @@
|
||||
from modules.registry import Ctx, set_xrpc_defaults, xrpc
|
||||
import time
|
||||
|
||||
from tinydb import Query, where
|
||||
|
||||
from core_common import E
|
||||
from core_database import get_db
|
||||
from modules.iidx.iidx34pc import apply_badge_attribs
|
||||
|
||||
set_xrpc_defaults(service="local", models=["LDJ"])
|
||||
|
||||
def get_profile(iidx_id):
|
||||
return get_db().table("iidx_profile").get(where("iidx_id") == iidx_id)
|
||||
|
||||
@xrpc("IIDX34grade/raised")
|
||||
async def iidx34grade_raised(ctx: Ctx):
|
||||
game_version = ctx.info["game_version"]
|
||||
|
||||
timestamp = time.time()
|
||||
|
||||
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(
|
||||
{
|
||||
"timestamp": timestamp,
|
||||
"game_version": game_version,
|
||||
"iidx_id": iidx_id,
|
||||
"achi": achi,
|
||||
"cstage": cstage,
|
||||
"gid": gid,
|
||||
"gtype": gtype,
|
||||
"is_ex": is_ex,
|
||||
"is_mirror": is_mirror,
|
||||
},
|
||||
)
|
||||
|
||||
profile = get_profile(iidx_id)
|
||||
game_profile = profile["version"].get(str(game_version), {})
|
||||
|
||||
best_class = db.table("iidx_class_best").get(
|
||||
(where("iidx_id") == iidx_id)
|
||||
& (where("game_version") == game_version)
|
||||
& (where("gid") == gid)
|
||||
& (where("gtype") == gtype)
|
||||
)
|
||||
|
||||
best_class = {} if best_class is None else best_class
|
||||
|
||||
best_class_data = {
|
||||
"game_version": game_version,
|
||||
"iidx_id": iidx_id,
|
||||
"achi": max(achi, best_class.get("achi", achi)),
|
||||
"cstage": max(cstage, best_class.get("cstage", cstage)),
|
||||
"gid": gid,
|
||||
"gtype": gtype,
|
||||
"is_ex": is_ex,
|
||||
"is_mirror": is_mirror,
|
||||
}
|
||||
|
||||
db.table("iidx_class_best").upsert(
|
||||
best_class_data,
|
||||
(where("iidx_id") == iidx_id)
|
||||
& (where("game_version") == game_version)
|
||||
& (where("gid") == gid)
|
||||
& (where("gtype") == gtype),
|
||||
)
|
||||
|
||||
best_class_plays = db.table("iidx_class_best").search(
|
||||
(where("game_version") == game_version) & (where("iidx_id") == iidx_id)
|
||||
)
|
||||
|
||||
grades = []
|
||||
for record in best_class_plays:
|
||||
grades.append(
|
||||
[record["gtype"], record["gid"], record["cstage"], record["achi"]]
|
||||
)
|
||||
|
||||
game_profile["grade_values"] = grades
|
||||
|
||||
grade_sp = db.table("iidx_class_best").search(
|
||||
(where("game_version") == game_version)
|
||||
& (where("iidx_id") == iidx_id)
|
||||
& (where("gtype") == 0)
|
||||
& (where("cstage") == 4)
|
||||
)
|
||||
|
||||
game_profile["grade_single"] = max([x["gid"] for x in grade_sp], default=-1)
|
||||
|
||||
grade_dp = db.table("iidx_class_best").search(
|
||||
(where("game_version") == game_version)
|
||||
& (where("iidx_id") == iidx_id)
|
||||
& (where("gtype") == 1)
|
||||
& (where("cstage") == 4)
|
||||
)
|
||||
|
||||
game_profile["grade_double"] = max([x["gid"] for x in grade_dp], default=-1)
|
||||
|
||||
apply_badge_attribs(game_profile, ctx.info["root"][0].find("badge"))
|
||||
|
||||
profile["version"][str(game_version)] = game_profile
|
||||
|
||||
db.table("iidx_profile").upsert(profile, where("game_version") == game_version)
|
||||
|
||||
response = E.response(E.IIDX34grade(pnum=1))
|
||||
|
||||
return response
|
||||
148
modules/iidx/iidx34lobby.py
Normal file
148
modules/iidx/iidx34lobby.py
Normal file
@@ -0,0 +1,148 @@
|
||||
from modules.registry import Ctx, set_xrpc_defaults, xrpc
|
||||
from time import time
|
||||
|
||||
import config
|
||||
|
||||
from core_common import E
|
||||
|
||||
arena_host = {}
|
||||
bpl_host = {}
|
||||
|
||||
set_xrpc_defaults(service="lobby2", models=["LDJ"])
|
||||
|
||||
@xrpc("IIDX34lobby/entry")
|
||||
async def iidx34lobby_entry(ctx: Ctx):
|
||||
|
||||
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()
|
||||
gp = root.find("address/gp").text
|
||||
la = root.find("address/la").text.split()
|
||||
|
||||
if arena_host and time() < arena_host["time"]:
|
||||
# test menu reset
|
||||
if arena_host["ga"] == ga:
|
||||
is_arena_host = 1
|
||||
arena_host["time"] = time() + 30
|
||||
else:
|
||||
is_arena_host = 0
|
||||
response = E.response(
|
||||
E.IIDX34lobby(
|
||||
E.host(is_arena_host, __type="bool"),
|
||||
E.matching_class(arena_class, __type="s32"),
|
||||
E.address(
|
||||
E.ga(arena_host["ga"], __type="u8"),
|
||||
E.gp(arena_host["gp"], __type="u16"),
|
||||
E.la(arena_host["la"], __type="u8"),
|
||||
),
|
||||
)
|
||||
)
|
||||
else:
|
||||
arena_host["ga"] = ga
|
||||
arena_host["gp"] = gp
|
||||
arena_host["la"] = la
|
||||
arena_host["time"] = time() + 30
|
||||
response = E.response(
|
||||
E.IIDX34lobby(
|
||||
E.host(1, __type="bool"),
|
||||
E.matching_class(arena_class, __type="s32"),
|
||||
E.address(
|
||||
E.ga(ga, __type="u8"),
|
||||
E.gp(gp, __type="u16"),
|
||||
E.la(la, __type="u8"),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34lobby/update")
|
||||
async def iidx34lobby_update(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34lobby())
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34lobby/delete")
|
||||
async def iidx34lobby_delete(ctx: Ctx):
|
||||
|
||||
# normal reset
|
||||
del arena_host["ga"]
|
||||
del arena_host["gp"]
|
||||
del arena_host["la"]
|
||||
del arena_host["time"]
|
||||
response = E.response(E.IIDX34lobby())
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34lobby/bplbattle_entry")
|
||||
async def iidx34lobby_bplbattle_entry(ctx: Ctx):
|
||||
|
||||
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
|
||||
ga = root.find("address/ga").text.split()
|
||||
gp = root.find("address/gp").text
|
||||
la = root.find("address/la").text.split()
|
||||
|
||||
if bpl_host and password in bpl_host and time() < bpl_host[password]["time"]:
|
||||
# test menu reset
|
||||
if bpl_host[password]["ga"] == ga:
|
||||
is_bpl_host = 1
|
||||
bpl_host[password]["time"] = time() + 30
|
||||
else:
|
||||
is_bpl_host = 0
|
||||
response = E.response(
|
||||
E.IIDX34lobby(
|
||||
E.host(is_bpl_host, __type="bool"),
|
||||
E.matching_class(arena_class, __type="s32"),
|
||||
E.address(
|
||||
E.ga(bpl_host[password]["ga"], __type="u8"),
|
||||
E.gp(bpl_host[password]["gp"], __type="u16"),
|
||||
E.la(bpl_host[password]["la"], __type="u8"),
|
||||
),
|
||||
)
|
||||
)
|
||||
else:
|
||||
bpl_host[password] = {}
|
||||
bpl_host[password]["ga"] = ga
|
||||
bpl_host[password]["gp"] = gp
|
||||
bpl_host[password]["la"] = la
|
||||
bpl_host[password]["time"] = time() + 30
|
||||
response = E.response(
|
||||
E.IIDX34lobby(
|
||||
E.host(1, __type="bool"),
|
||||
E.matching_class(arena_class, __type="s32"),
|
||||
E.address(
|
||||
E.ga(ga, __type="u8"),
|
||||
E.gp(gp, __type="u16"),
|
||||
E.la(la, __type="u8"),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34lobby/bplbattle_update")
|
||||
async def iidx34lobby_bplbattle_update(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34lobby())
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34lobby/bplbattle_delete")
|
||||
async def iidx34lobby_bplbattle_delete(ctx: Ctx):
|
||||
|
||||
root = ctx.info["root"][0]
|
||||
ga = root.find("address/ga").text.split()
|
||||
|
||||
# normal reset
|
||||
for host in bpl_host:
|
||||
if bpl_host[host]["ga"] == ga:
|
||||
del bpl_host[host]
|
||||
break
|
||||
response = E.response(E.IIDX34lobby())
|
||||
|
||||
return response
|
||||
585
modules/iidx/iidx34music.py
Normal file
585
modules/iidx/iidx34music.py
Normal file
@@ -0,0 +1,585 @@
|
||||
from modules.registry import Ctx, set_xrpc_defaults, xrpc
|
||||
import time
|
||||
import random
|
||||
from enum import IntEnum
|
||||
|
||||
from tinydb import where
|
||||
|
||||
from core_common import E
|
||||
from core_database import get_db
|
||||
from modules.iidx.iidx34pc import apply_badge_attribs
|
||||
|
||||
import config
|
||||
|
||||
class ClearFlags(IntEnum):
|
||||
NO_PLAY = 0
|
||||
FAILED = 1
|
||||
ASSIST_CLEAR = 2
|
||||
EASY_CLEAR = 3
|
||||
CLEAR = 4
|
||||
HARD_CLEAR = 5
|
||||
EX_HARD_CLEAR = 6
|
||||
FULL_COMBO = 7
|
||||
|
||||
set_xrpc_defaults(service="local", models=["LDJ"])
|
||||
|
||||
@xrpc("IIDX34music/getrank")
|
||||
async def iidx34music_getrank(ctx: Ctx):
|
||||
game_version = ctx.info["game_version"]
|
||||
|
||||
root = ctx.info["root"][0]
|
||||
|
||||
play_style = int(root.attrib["cltype"])
|
||||
|
||||
requested_ids = [
|
||||
int(root.get("iidxid", 0)),
|
||||
int(root.get("iidxid0", 0)),
|
||||
int(root.get("iidxid1", 0)),
|
||||
int(root.get("iidxid2", 0)),
|
||||
int(root.get("iidxid3", 0)),
|
||||
int(root.get("iidxid4", 0)),
|
||||
int(root.get("iidxid5", 0)),
|
||||
]
|
||||
|
||||
all_scores = {}
|
||||
db = get_db()
|
||||
|
||||
for rival_idx, iidxid in enumerate(requested_ids, -1):
|
||||
if iidxid == 0:
|
||||
continue
|
||||
|
||||
profile = db.table("iidx_profile").get(where("iidx_id") == iidxid)["version"][
|
||||
str(game_version)
|
||||
]
|
||||
|
||||
for record in db.table("iidx_scores_best").search(
|
||||
(where("music_id") < (game_version + 1) * 1000)
|
||||
& (where("play_style") == play_style)
|
||||
& (where("iidx_id") == iidxid)
|
||||
):
|
||||
music_id = record["music_id"]
|
||||
clear_flg = record["clear_flg"]
|
||||
ex_score = record["ex_score"]
|
||||
miss_count = record["miss_count"]
|
||||
chart_id = record["chart_id"]
|
||||
|
||||
if (rival_idx, music_id) not in all_scores:
|
||||
all_scores[rival_idx, music_id] = {
|
||||
0: {"clear_flg": -1, "ex_score": -1, "miss_count": -1},
|
||||
1: {"clear_flg": -1, "ex_score": -1, "miss_count": -1},
|
||||
2: {"clear_flg": -1, "ex_score": -1, "miss_count": -1},
|
||||
3: {"clear_flg": -1, "ex_score": -1, "miss_count": -1},
|
||||
4: {"clear_flg": -1, "ex_score": -1, "miss_count": -1},
|
||||
}
|
||||
|
||||
all_scores[rival_idx, music_id][chart_id]["clear_flg"] = clear_flg
|
||||
all_scores[rival_idx, music_id][chart_id]["ex_score"] = ex_score
|
||||
all_scores[rival_idx, music_id][chart_id]["miss_count"] = miss_count
|
||||
|
||||
names = {}
|
||||
profiles = get_db().table("iidx_profile")
|
||||
for p in profiles:
|
||||
names[p["iidx_id"]] = {}
|
||||
try:
|
||||
names[p["iidx_id"]]["name"] = p["version"][str(game_version)]["djname"]
|
||||
except KeyError:
|
||||
names[p["iidx_id"]]["name"] = "UNK"
|
||||
|
||||
top_scores = {}
|
||||
for record in db.table("iidx_scores_best").search(
|
||||
(where("music_id") < (game_version + 1) * 1000)
|
||||
& (where("play_style") == play_style)
|
||||
):
|
||||
music_id = record["music_id"]
|
||||
ex_score = record["ex_score"]
|
||||
chart_id = record["chart_id"]
|
||||
iidx_id = record["iidx_id"]
|
||||
|
||||
if music_id not in top_scores:
|
||||
top_scores[music_id] = {
|
||||
0: {"djname": "", "clear_flg": -1, "ex_score": -1},
|
||||
1: {"djname": "", "clear_flg": -1, "ex_score": -1},
|
||||
2: {"djname": "", "clear_flg": -1, "ex_score": -1},
|
||||
3: {"djname": "", "clear_flg": -1, "ex_score": -1},
|
||||
4: {"djname": "", "clear_flg": -1, "ex_score": -1},
|
||||
}
|
||||
|
||||
if ex_score > top_scores[music_id][chart_id]["ex_score"]:
|
||||
top_scores[music_id][chart_id]["djname"] = names[iidx_id]["name"]
|
||||
top_scores[music_id][chart_id]["clear_flg"] = 1
|
||||
top_scores[music_id][chart_id]["ex_score"] = ex_score
|
||||
|
||||
response = E.response(
|
||||
E.IIDX34music(
|
||||
E.style(type=play_style),
|
||||
*[
|
||||
E.m(
|
||||
[
|
||||
i,
|
||||
k,
|
||||
*[all_scores[i, k][d]["clear_flg"] for d in range(5)],
|
||||
*[all_scores[i, k][d]["ex_score"] for d in range(5)],
|
||||
*[all_scores[i, k][d]["miss_count"] for d in range(5)],
|
||||
],
|
||||
__type="s32",
|
||||
)
|
||||
for i, k in all_scores
|
||||
],
|
||||
*[
|
||||
E.top(
|
||||
E.detail(
|
||||
[
|
||||
k,
|
||||
*[top_scores[k][d]["clear_flg"] for d in range(5)],
|
||||
*[top_scores[k][d]["ex_score"] for d in range(5)],
|
||||
],
|
||||
__type="s32",
|
||||
),
|
||||
name0=top_scores[k][0]["djname"],
|
||||
name1=top_scores[k][1]["djname"],
|
||||
name2=top_scores[k][2]["djname"],
|
||||
name3=top_scores[k][3]["djname"],
|
||||
name4=top_scores[k][4]["djname"],
|
||||
)
|
||||
for k in top_scores
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
assert response is not None
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34music/crate")
|
||||
async def iidx34music_crate(ctx: Ctx):
|
||||
game_version = ctx.info["game_version"]
|
||||
|
||||
db = get_db()
|
||||
all_score_stats = db.table("iidx_score_stats").search(
|
||||
(where("music_id") < (game_version + 1) * 1000)
|
||||
)
|
||||
|
||||
crate = {}
|
||||
fcrate = {}
|
||||
for stat in all_score_stats:
|
||||
if stat["music_id"] not in crate:
|
||||
crate[stat["music_id"]] = [1001] * 10
|
||||
if stat["music_id"] not in fcrate:
|
||||
fcrate[stat["music_id"]] = [1001] * 10
|
||||
|
||||
if stat["play_style"] == 1:
|
||||
dp_idx = 5
|
||||
else:
|
||||
dp_idx = 0
|
||||
|
||||
crate[stat["music_id"]][stat["chart_id"] + dp_idx] = int(stat["clear_rate"])
|
||||
fcrate[stat["music_id"]][stat["chart_id"] + dp_idx] = int(stat["fc_rate"])
|
||||
|
||||
response = E.response(
|
||||
E.IIDX34music(*[E.c(crate[k] + fcrate[k], mid=k, __type="s32") for k in crate])
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34music/reg")
|
||||
async def iidx34music_reg(ctx: Ctx):
|
||||
game_version = ctx.info["game_version"]
|
||||
|
||||
timestamp = time.time()
|
||||
|
||||
log = ctx.info["root"][0].find("music_play_log")
|
||||
|
||||
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"])
|
||||
folder_type = int(log.attrib["folder_type"])
|
||||
gauge_type = int(log.attrib["gauge_type"])
|
||||
graph_type = int(log.attrib["graph_type"])
|
||||
great_num = int(log.attrib["great_num"])
|
||||
iidx_id = int(log.attrib["iidx_id"])
|
||||
miss_num = int(log.attrib["miss_num"]) if is_death == 0 else -1
|
||||
mode_type = int(log.attrib["mode_type"])
|
||||
music_id = int(log.attrib["music_id"])
|
||||
note_id = int(log.attrib["note_id"])
|
||||
option1 = int(log.attrib["option1"])
|
||||
option2 = int(log.attrib["option2"])
|
||||
pgreat_num = int(log.attrib["pgreat_num"])
|
||||
|
||||
ghost = log.find("ghost").text
|
||||
ghost_gauge = log.find("ghost_gauge").text
|
||||
|
||||
db = get_db()
|
||||
db.table("iidx_scores").insert(
|
||||
{
|
||||
"timestamp": timestamp,
|
||||
"game_version": game_version,
|
||||
"iidx_id": iidx_id,
|
||||
"pid": pid,
|
||||
"clear_flg": clear_flg,
|
||||
"is_death": is_death,
|
||||
"music_id": music_id,
|
||||
"play_style": play_style,
|
||||
"chart_id": note_id,
|
||||
"pgreat_num": pgreat_num,
|
||||
"great_num": great_num,
|
||||
"ex_score": ex_score,
|
||||
"miss_count": miss_num,
|
||||
"folder_type": folder_type,
|
||||
"gauge_type": gauge_type,
|
||||
"graph_type": graph_type,
|
||||
"mode_type": mode_type,
|
||||
"option1": option1,
|
||||
"option2": option2,
|
||||
"ghost": ghost,
|
||||
"ghost_gauge": ghost_gauge,
|
||||
},
|
||||
)
|
||||
|
||||
best_score = db.table("iidx_scores_best").get(
|
||||
(where("iidx_id") == iidx_id)
|
||||
& (where("play_style") == play_style)
|
||||
& (where("music_id") == music_id)
|
||||
& (where("chart_id") == note_id)
|
||||
)
|
||||
best_score = {} if best_score is None else best_score
|
||||
|
||||
best_miss_count = best_score.get("miss_count", miss_num)
|
||||
if best_miss_count == -1 or miss_num ==-1:
|
||||
miss_count = max(miss_num, best_miss_count)
|
||||
else:
|
||||
miss_count = min(miss_num, best_miss_count)
|
||||
best_ex_score = best_score.get("ex_score", ex_score)
|
||||
best_score_data = {
|
||||
"game_version": game_version,
|
||||
"iidx_id": iidx_id,
|
||||
"pid": pid,
|
||||
"play_style": play_style,
|
||||
"music_id": music_id,
|
||||
"chart_id": note_id,
|
||||
"miss_count": miss_count,
|
||||
"ex_score": max(ex_score, best_ex_score),
|
||||
"ghost": ghost if ex_score >= best_ex_score else best_score.get("ghost", ghost),
|
||||
"ghost_gauge": (
|
||||
ghost_gauge
|
||||
if ex_score >= best_ex_score
|
||||
else best_score.get("ghost_gauge", ghost_gauge)
|
||||
),
|
||||
"clear_flg": max(clear_flg, best_score.get("clear_flg", clear_flg)),
|
||||
"gauge_type": (
|
||||
gauge_type
|
||||
if ex_score >= best_ex_score
|
||||
else best_score.get("gauge_type", gauge_type)
|
||||
),
|
||||
}
|
||||
|
||||
db.table("iidx_scores_best").upsert(
|
||||
best_score_data,
|
||||
(where("iidx_id") == iidx_id)
|
||||
& (where("play_style") == play_style)
|
||||
& (where("music_id") == music_id)
|
||||
& (where("chart_id") == note_id),
|
||||
)
|
||||
|
||||
score_stats = db.table("iidx_score_stats").get(
|
||||
(where("music_id") == music_id)
|
||||
& (where("play_style") == play_style)
|
||||
& (where("chart_id") == note_id)
|
||||
)
|
||||
score_stats = {} if score_stats is None else score_stats
|
||||
|
||||
score_stats["game_version"] = game_version
|
||||
score_stats["play_style"] = play_style
|
||||
score_stats["music_id"] = music_id
|
||||
score_stats["chart_id"] = note_id
|
||||
score_stats["play_count"] = score_stats.get("play_count", 0) + 1
|
||||
score_stats["fc_count"] = score_stats.get("fc_count", 0) + (
|
||||
1 if clear_flg == ClearFlags.FULL_COMBO else 0
|
||||
)
|
||||
score_stats["clear_count"] = score_stats.get("clear_count", 0) + (
|
||||
1 if clear_flg >= ClearFlags.EASY_CLEAR else 0
|
||||
)
|
||||
score_stats["fc_rate"] = int(
|
||||
(score_stats["fc_count"] / score_stats["play_count"]) * 1000
|
||||
)
|
||||
score_stats["clear_rate"] = int(
|
||||
(score_stats["clear_count"] / score_stats["play_count"]) * 1000
|
||||
)
|
||||
|
||||
db.table("iidx_score_stats").upsert(
|
||||
score_stats,
|
||||
(where("music_id") == music_id)
|
||||
& (where("play_style") == play_style)
|
||||
& (where("chart_id") == note_id),
|
||||
)
|
||||
|
||||
profile = db.table("iidx_profile").get(where("iidx_id") == iidx_id)
|
||||
if profile is not None and str(game_version) in profile["version"]:
|
||||
game_profile = profile["version"][str(game_version)]
|
||||
apply_badge_attribs(game_profile, ctx.info["root"][0].find("badge"))
|
||||
profile["version"][str(game_version)] = game_profile
|
||||
db.table("iidx_profile").upsert(profile, where("iidx_id") == iidx_id)
|
||||
|
||||
ranklist_data = []
|
||||
ranklist_scores = db.table("iidx_scores_best").search(
|
||||
(where("play_style") == play_style)
|
||||
& (where("music_id") == music_id)
|
||||
& (where("chart_id") == note_id)
|
||||
)
|
||||
ranklist_scores = [] if ranklist_scores is None else ranklist_scores
|
||||
|
||||
ranklist_scores_ranked = []
|
||||
|
||||
for score in ranklist_scores:
|
||||
profile = db.table("iidx_profile").get(where("iidx_id") == score["iidx_id"])
|
||||
|
||||
if profile is None or str(game_version) not in profile["version"]:
|
||||
continue
|
||||
|
||||
game_profile = profile["version"][str(game_version)]
|
||||
|
||||
ranklist_scores_ranked.append(
|
||||
{
|
||||
"opname": config.arcade,
|
||||
"name": game_profile["djname"],
|
||||
"pid": game_profile["region"],
|
||||
"back": game_profile.get("back", 0),
|
||||
"body": game_profile["body"],
|
||||
"face": game_profile["face"],
|
||||
"hair": game_profile["hair"],
|
||||
"hand": game_profile["hand"],
|
||||
"head": game_profile["head"],
|
||||
"dgrade": game_profile["grade_double"],
|
||||
"sgrade": game_profile["grade_single"],
|
||||
"score": score["ex_score"],
|
||||
"iidx_id": score["iidx_id"],
|
||||
"clflg": score["clear_flg"],
|
||||
"myFlg": score["iidx_id"] == iidx_id,
|
||||
}
|
||||
)
|
||||
|
||||
ranklist_scores_ranked = sorted(
|
||||
ranklist_scores_ranked, key=lambda x: (x["clflg"], x["score"]), reverse=True
|
||||
)
|
||||
|
||||
myRank = 0
|
||||
for rnum, score in enumerate(ranklist_scores_ranked):
|
||||
r = E.data(
|
||||
rnum=rnum + 1,
|
||||
opname=score["opname"],
|
||||
name=score["name"],
|
||||
pid=score["pid"],
|
||||
back=score["back"],
|
||||
body=score["body"],
|
||||
face=score["face"],
|
||||
hair=score["hair"],
|
||||
hand=score["hand"],
|
||||
head=score["head"],
|
||||
dgrade=score["dgrade"],
|
||||
sgrade=score["sgrade"],
|
||||
score=score["score"],
|
||||
iidx_id=score["iidx_id"],
|
||||
clflg=score["clflg"],
|
||||
myFlg=score["myFlg"],
|
||||
achieve=0,
|
||||
)
|
||||
ranklist_data.append(r)
|
||||
|
||||
if score["myFlg"]:
|
||||
myRank = rnum + 1
|
||||
|
||||
response = E.response(
|
||||
E.IIDX34music(
|
||||
E.ranklist(*ranklist_data, total_user_num=len(ranklist_data)),
|
||||
E.shopdata(rank=myRank),
|
||||
clid=clid,
|
||||
crate=score_stats["clear_rate"],
|
||||
frate=score_stats["fc_rate"],
|
||||
mid=music_id,
|
||||
)
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34music/appoint")
|
||||
async def iidx34music_appoint(ctx: Ctx):
|
||||
|
||||
root = ctx.info["root"][0]
|
||||
|
||||
iidxid = int(root.attrib["iidxid"])
|
||||
music_id = int(root.attrib["mid"])
|
||||
chart_id = int(root.attrib["clid"])
|
||||
ctype = int(root.attrib["ctype"])
|
||||
subtype = root.attrib["subtype"]
|
||||
|
||||
db = get_db()
|
||||
record = db.table("iidx_scores_best").get(
|
||||
(where("iidx_id") == iidxid)
|
||||
& (where("music_id") == music_id)
|
||||
& (where("chart_id") == chart_id)
|
||||
)
|
||||
|
||||
vals = []
|
||||
if record is not None:
|
||||
vals.append(
|
||||
E.mydata(
|
||||
record["ghost"],
|
||||
score=record["ex_score"],
|
||||
__type="bin",
|
||||
__size=len(record["ghost"]) // 2,
|
||||
)
|
||||
)
|
||||
|
||||
if ctype == 1:
|
||||
sdata = db.table("iidx_scores_best").get(
|
||||
(where("iidx_id") == int(subtype))
|
||||
& (where("music_id") == music_id)
|
||||
& (where("chart_id") == chart_id)
|
||||
)
|
||||
elif ctype in (2, 4, 10):
|
||||
sdata = {
|
||||
"game_version": 29,
|
||||
"ghost": "",
|
||||
"ex_score": 0,
|
||||
"iidx_id": 0,
|
||||
"name": "",
|
||||
"pid": 13,
|
||||
}
|
||||
|
||||
for record in db.table("iidx_scores_best").search(
|
||||
(where("music_id") == music_id) & (where("chart_id") == chart_id)
|
||||
):
|
||||
if record["ex_score"] > sdata["ex_score"]:
|
||||
sdata["game_version"] = record["game_version"]
|
||||
sdata["ghost"] = record["ghost"]
|
||||
sdata["ex_score"] = record["ex_score"]
|
||||
sdata["iidx_id"] = record["iidx_id"]
|
||||
sdata["pid"] = record["pid"]
|
||||
|
||||
if ctype in (1, 2, 4, 10) and sdata["ex_score"] != 0:
|
||||
vals.append(
|
||||
E.sdata(
|
||||
sdata["ghost"],
|
||||
score=sdata["ex_score"],
|
||||
name=db.table("iidx_profile").get(where("iidx_id") == sdata["iidx_id"])[
|
||||
"version"
|
||||
][str(sdata["game_version"])]["djname"],
|
||||
pid=sdata["pid"],
|
||||
__type="bin",
|
||||
__size=len(sdata["ghost"]) // 2,
|
||||
)
|
||||
)
|
||||
|
||||
response = E.response(E.IIDX34music(*vals))
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34music/arenaCPU")
|
||||
async def iidx34music_arenacpu(ctx: Ctx):
|
||||
|
||||
root = ctx.info["root"][0]
|
||||
music_list = root.findall("music_list")
|
||||
music_count = len(music_list)
|
||||
cpu_list = root.findall("cpu_list")
|
||||
cpu_count = len(cpu_list)
|
||||
|
||||
cpu = {}
|
||||
|
||||
for music in music_list:
|
||||
music_idx = int(music.find("index").text)
|
||||
exscore_max = int(music.find("total_notes").text) * 2
|
||||
|
||||
cpu[music_idx] = {}
|
||||
|
||||
for bot_idx in range(cpu_count):
|
||||
cpu[music_idx][bot_idx] = {}
|
||||
|
||||
exscore = round(exscore_max * random.uniform(0.77, 0.93))
|
||||
cpu[music_idx][bot_idx]["exscore"] = exscore
|
||||
|
||||
ghost_len = 64
|
||||
ghost_data = [0] * ghost_len
|
||||
for x in range(ghost_len):
|
||||
ghost_data[x] = exscore // ghost_len
|
||||
if (exscore % ghost_len) > x:
|
||||
ghost_data[x] += 1
|
||||
|
||||
cpu[music_idx][bot_idx]["ghost_data"] = ghost_data
|
||||
|
||||
response = E.response(
|
||||
E.IIDX34music(
|
||||
*[
|
||||
E.cpu_score_list(
|
||||
E.index(bot_idx, __type="s32"),
|
||||
*[
|
||||
E.score_list(
|
||||
E.index(music_idx, __type="s32"),
|
||||
E.score(cpu[music_idx][bot_idx]["exscore"], __type="s32"),
|
||||
E.ghost(cpu[music_idx][bot_idx]["ghost_data"], __type="s8"),
|
||||
E.enable_score(1, __type="bool"),
|
||||
E.enable_ghost(1, __type="bool"),
|
||||
E.location_id("X000000001", __type="str"),
|
||||
)
|
||||
for music_idx in range(music_count)
|
||||
],
|
||||
)
|
||||
for bot_idx in range(cpu_count)
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34music/retry")
|
||||
async def iidx34music_retry(ctx: Ctx):
|
||||
|
||||
response = E.response(
|
||||
E.IIDX34music(
|
||||
E.session(session_id=1),
|
||||
status=0,
|
||||
)
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34music/play")
|
||||
async def iidx34music_play(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34music())
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34music/nosave")
|
||||
async def iidx34music_nosave(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34music())
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34music/getranksub")
|
||||
async def iidx34music_getranksub(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34music())
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34music/movieinfo")
|
||||
async def iidx34music_movieinfo(ctx: Ctx):
|
||||
|
||||
response = E.response(
|
||||
E.IIDX34music(
|
||||
status=0,
|
||||
)
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34music/sc")
|
||||
async def iidx34music_sc(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34music())
|
||||
|
||||
return response
|
||||
1540
modules/iidx/iidx34pc.py
Normal file
1540
modules/iidx/iidx34pc.py
Normal file
File diff suppressed because it is too large
Load Diff
13
modules/iidx/iidx34ranking.py
Normal file
13
modules/iidx/iidx34ranking.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from modules.registry import Ctx, set_xrpc_defaults, xrpc
|
||||
import config
|
||||
|
||||
from core_common import E
|
||||
|
||||
set_xrpc_defaults(service="local", models=["LDJ"])
|
||||
|
||||
@xrpc("IIDX34ranking/getranker")
|
||||
async def iidx34ranking_getranker(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34ranking())
|
||||
|
||||
return response
|
||||
92
modules/iidx/iidx34shop.py
Normal file
92
modules/iidx/iidx34shop.py
Normal file
@@ -0,0 +1,92 @@
|
||||
from modules.registry import Ctx, set_xrpc_defaults, xrpc
|
||||
import config
|
||||
|
||||
from tinydb import Query, where
|
||||
|
||||
from core_common import E
|
||||
from core_database import get_db
|
||||
|
||||
set_xrpc_defaults(service="local", models=["LDJ"])
|
||||
|
||||
@xrpc("IIDX34shop/getname")
|
||||
async def iidx34shop_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
|
||||
|
||||
response = E.response(
|
||||
E.IIDX34shop(
|
||||
cls_opt=0,
|
||||
opname=op.get("opname", config.arcade),
|
||||
pid=13,
|
||||
)
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34shop/savename")
|
||||
async def iidx34shop_savename(ctx: Ctx):
|
||||
pcbid = ctx.info["root"].attrib["srcid"]
|
||||
opname = ctx.info["root"][0].attrib["opname"]
|
||||
|
||||
shop_info = {
|
||||
"pcbid": pcbid,
|
||||
"opname": opname,
|
||||
}
|
||||
|
||||
get_db().table("shop").upsert(shop_info, where("pcbid") == pcbid)
|
||||
|
||||
response = E.response(E.IIDX34shop())
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34shop/getconvention")
|
||||
async def iidx34shop_getconvention(ctx: Ctx):
|
||||
|
||||
response = E.response(
|
||||
E.IIDX34shop(
|
||||
E.valid(1, __type="bool"),
|
||||
music_0=-1,
|
||||
music_1=-1,
|
||||
music_2=-1,
|
||||
music_3=-1,
|
||||
start_time=0,
|
||||
end_time=0,
|
||||
)
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34shop/sentinfo")
|
||||
async def iidx34shop_sentinfo(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34shop())
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34shop/sendescapepackageinfo")
|
||||
async def iidx34shop_sendescapepackageinfo(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34shop(expire=1200))
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34shop/getclosingtime")
|
||||
async def iidx34shop_getclosingtime(ctx: Ctx):
|
||||
|
||||
response = E.response(
|
||||
E.IIDX34shop(
|
||||
E.exist(1, __type="bool"),
|
||||
*[E.week(cls_opt=0, week=i) for i in range(7)]
|
||||
)
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34shop/saveclosingtime")
|
||||
async def iidx34shop_saveclosingtime(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34shop())
|
||||
|
||||
return response
|
||||
20
modules/iidx/iidx34streaming.py
Normal file
20
modules/iidx/iidx34streaming.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from modules.registry import Ctx, set_xrpc_defaults, xrpc
|
||||
import config
|
||||
|
||||
from core_common import E
|
||||
|
||||
set_xrpc_defaults(service="local", models=["LDJ"])
|
||||
|
||||
@xrpc("IIDX34streaming/common")
|
||||
async def iidx34streaming_common(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34streaming())
|
||||
|
||||
return response
|
||||
|
||||
@xrpc("IIDX34streaming/getcm")
|
||||
async def iidx34streaming_getcm(ctx: Ctx):
|
||||
|
||||
response = E.response(E.IIDX34streaming())
|
||||
|
||||
return response
|
||||
Reference in New Issue
Block a user