Black formatting

This commit is contained in:
drmext 2022-11-15 14:03:37 +00:00
parent 44fd2a25b3
commit 532cd3d9b9
No known key found for this signature in database
GPG Key ID: F1ED48FFE79A6961
45 changed files with 4133 additions and 3786 deletions

6
.gitignore vendored
View File

@ -1,3 +1,5 @@
*.pyc *.pyc
db.json /db*.json
*.db /*.db
.venv/
webui/

View File

@ -1,18 +1,21 @@
# MonkeyBusiness # MonkeyBusiness
e-amusement server using FastAPI and TinyDB
for experimental testing and playing e-amusement server using [FastAPI](https://github.com/tiangolo/fastapi) and [TinyDB](https://github.com/msiemens/tinydb)
for experimental local testing and playing
## Instructions: **don't host it publicly as-is**
`pip install -U -r requirements.txt`
`python pyeamu.py` ## Instructions
Edit services url and enable url_slash 1. Install [python](https://www.python.org/ftp/python/3.10.8/python-3.10.8-amd64.exe) with "Add python.exe to PATH" checked
1. Run `start.bat`
1. Edit prop/ea3-config.xml
## Playable Games
## Playable Games:
- DDR A20 PLUS - DDR A20 PLUS
- DDR A3 - DDR A3
- IIDX 18 Resort Anthem - IIDX 18 Resort Anthem
@ -20,4 +23,4 @@ Edit services url and enable url_slash
- IIDX 20 tricoro - IIDX 20 tricoro
- IIDX 29 CastHour - IIDX 29 CastHour
- IIDX 30 RESIDENT - IIDX 30 RESIDENT
- SDVX 6 Exceed Gear - SDVX 6 EXCEED GEAR

View File

@ -5,14 +5,15 @@ def get_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(0) s.settimeout(0)
try: try:
s.connect(('10.254.254.254', 1)) s.connect(("10.254.254.254", 1))
IP = s.getsockname()[0] IP = s.getsockname()[0]
except Exception: except Exception:
IP = '127.0.0.1' IP = "127.0.0.1"
finally: finally:
s.close() s.close()
return IP return IP
ip = get_ip() ip = get_ip()
port = 8000 port = 8000
services_prefix = "/core" services_prefix = "/core"

View File

@ -30,7 +30,7 @@ def _add_list_as_str(elm, vals):
if elm is not None: if elm is not None:
elm.text = new_val elm.text = new_val
elm.attrib['__count'] = str(len(vals)) elm.attrib["__count"] = str(len(vals))
else: else:
return new_val return new_val
@ -50,43 +50,43 @@ async def core_get_game_version_from_software_version(software_version):
_, model, dest, spec, rev, ext = software_version _, model, dest, spec, rev, ext = software_version
ext = int(ext) ext = int(ext)
if model == 'LDJ' and ext >= 2022101700: if model == "LDJ" and ext >= 2022101700:
return 30 return 30
elif model == 'LDJ' and ext in range(2021101300, 2022101500): elif model == "LDJ" and ext in range(2021101300, 2022101500):
return 29 return 29
elif model == 'JDZ' and ext == 2011071200: elif model == "JDZ" and ext == 2011071200:
return 18 return 18
elif model == 'KDZ' and ext == 2012090300: elif model == "KDZ" and ext == 2012090300:
return 19 return 19
elif model == 'LDJ' and ext == 2013090900: elif model == "LDJ" and ext == 2013090900:
return 20 return 20
elif model == 'MDX' and ext >= 2019022600: elif model == "MDX" and ext >= 2019022600:
return 19 return 19
elif model == 'KFC' and ext >= 2020090402: elif model == "KFC" and ext >= 2020090402:
return 6 return 6
else: else:
return 0 return 0
async def core_process_request(request): async def core_process_request(request):
cl = request.headers.get('Content-Length') cl = request.headers.get("Content-Length")
data = await request.body() data = await request.body()
if not cl or not data: if not cl or not data:
return {} return {}
if 'X-Compress' in request.headers: if "X-Compress" in request.headers:
request.compress = request.headers.get('X-Compress') request.compress = request.headers.get("X-Compress")
else: else:
request.compress = None request.compress = None
if 'X-Eamuse-Info' in request.headers: if "X-Eamuse-Info" in request.headers:
xeamuseinfo = request.headers.get('X-Eamuse-Info') xeamuseinfo = request.headers.get("X-Eamuse-Info")
key = bytes.fromhex(xeamuseinfo[2:].replace("-", "")) key = bytes.fromhex(xeamuseinfo[2:].replace("-", ""))
xml_dec = EamuseARC4(key).decrypt(data[:int(cl)]) xml_dec = EamuseARC4(key).decrypt(data[: int(cl)])
request.is_encrypted = True request.is_encrypted = True
else: else:
xml_dec = data[:int(cl)] xml_dec = data[: int(cl)]
request.is_encrypted = False request.is_encrypted = False
if request.compress == "lz77": if request.compress == "lz77":
@ -101,25 +101,24 @@ async def core_process_request(request):
print("Request:") print("Request:")
print(xml_text) print(xml_text)
model_parts = (root.attrib['model'], *root.attrib['model'].split(':')) model_parts = (root.attrib["model"], *root.attrib["model"].split(":"))
module = root[0].tag module = root[0].tag
method = root[0].attrib['method'] if 'method' in root[0].attrib else None 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 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 = await core_get_game_version_from_software_version(model_parts)
return { return {
'root': root, "root": root,
'text': xml_text, "text": xml_text,
'module': module, "module": module,
'method': method, "method": method,
'command': command, "command": command,
"model": model_parts[1],
'model': model_parts[1], "dest": model_parts[2],
'dest': model_parts[2], "spec": model_parts[3],
'spec': model_parts[3], "rev": model_parts[4],
'rev': model_parts[4], "ext": model_parts[5],
'ext': model_parts[5], "game_version": game_version,
'game_version': game_version,
} }
@ -138,7 +137,7 @@ async def core_prepare_response(request, xml):
response_headers = {"User-Agent": "EAMUSE.Httpac/1.0"} response_headers = {"User-Agent": "EAMUSE.Httpac/1.0"}
if request.is_encrypted: if request.is_encrypted:
xeamuseinfo = "1-%08x-%04x" % (int(time.time()), random.randint(0x0000, 0xffff)) xeamuseinfo = "1-%08x-%04x" % (int(time.time()), random.randint(0x0000, 0xFFFF))
response_headers["X-Eamuse-Info"] = xeamuseinfo response_headers["X-Eamuse-Info"] = xeamuseinfo
key = bytes.fromhex(xeamuseinfo[2:].replace("-", "")) key = bytes.fromhex(xeamuseinfo[2:].replace("-", ""))
response = EamuseARC4(key).encrypt(xml_binary) response = EamuseARC4(key).encrypt(xml_binary)

View File

@ -1,6 +1,6 @@
from tinydb import TinyDB from tinydb import TinyDB
db = TinyDB('db.json', indent=4) db = TinyDB("db.json", indent=4)
def get_db(): def get_db():

View File

@ -3,15 +3,15 @@ from os import path
from glob import glob from glob import glob
routers = [] routers = []
for module_path in [f for f in glob(path.join(path.dirname(__file__), '**/*.py'), recursive=True) for module_path in [
if path.basename(f) != "__init__.py"]: f
spec = util.spec_from_file_location('', module_path) 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) module = util.module_from_spec(spec)
spec.loader.exec_module(module) spec.loader.exec_module(module)
router = getattr(module, 'router', None) router = getattr(module, "router", None)
if router is not None: if router is not None:
routers.append(router) routers.append(router)

View File

@ -21,12 +21,12 @@ def get_target_table(game_id):
def get_profile(game_id, cid): def get_profile(game_id, cid):
target_table = get_target_table(game_id) target_table = get_target_table(game_id)
profile = get_db().table(target_table).get(where('card') == cid) profile = get_db().table(target_table).get(where("card") == cid)
if profile is None: if profile is None:
profile = { profile = {
'card': cid, "card": cid,
'version': {}, "version": {},
} }
return profile return profile
@ -35,43 +35,41 @@ def get_profile(game_id, cid):
def get_game_profile(game_id, game_version, cid): def get_game_profile(game_id, game_version, cid):
profile = get_profile(game_id, cid) profile = get_profile(game_id, cid)
if str(game_version) not in profile['version']: if str(game_version) not in profile["version"]:
profile['version'][str(game_version)] = {} profile["version"][str(game_version)] = {}
return profile['version'][str(game_version)] return profile["version"][str(game_version)]
def create_profile(game_id, game_version, cid, pin): def create_profile(game_id, game_version, cid, pin):
target_table = get_target_table(game_id) target_table = get_target_table(game_id)
profile = get_profile(game_id, cid) profile = get_profile(game_id, cid)
profile['pin'] = pin profile["pin"] = pin
get_db().table(target_table).upsert(profile, where('card') == cid) get_db().table(target_table).upsert(profile, where("card") == cid)
@router.post('/{gameinfo}/cardmng/authpass') @router.post("/{gameinfo}/cardmng/authpass")
async def cardmng_authpass(request: Request): async def cardmng_authpass(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
cid = request_info['root'][0].attrib['refid'] cid = request_info["root"][0].attrib["refid"]
passwd = request_info['root'][0].attrib['pass'] passwd = request_info["root"][0].attrib["pass"]
profile = get_profile(request_info['model'], cid) profile = get_profile(request_info["model"], cid)
if profile is None or passwd != profile.get('pin', None): if profile is None or passwd != profile.get("pin", None):
status = 116 status = 116
else: else:
status = 0 status = 0
response = E.response( response = E.response(E.authpass(status=status))
E.authpass(status=status)
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/cardmng/bindmodel') @router.post("/{gameinfo}/cardmng/bindmodel")
async def cardmng_bindmodel(request: Request): async def cardmng_bindmodel(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
@ -85,14 +83,14 @@ async def cardmng_bindmodel(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/cardmng/getrefid') @router.post("/{gameinfo}/cardmng/getrefid")
async def cardmng_getrefid(request: Request): async def cardmng_getrefid(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
cid = request_info['root'][0].attrib['cardid'] cid = request_info["root"][0].attrib["cardid"]
passwd = request_info['root'][0].attrib['passwd'] passwd = request_info["root"][0].attrib["passwd"]
create_profile(request_info['model'], request_info['game_version'], cid, passwd) create_profile(request_info["model"], request_info["game_version"], cid, passwd)
response = E.response( response = E.response(
E.getrefid( E.getrefid(
@ -105,13 +103,13 @@ async def cardmng_getrefid(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/cardmng/inquire') @router.post("/{gameinfo}/cardmng/inquire")
async def cardmng_inquire(request: Request): async def cardmng_inquire(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
cid = request_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(request_info["model"], request_info["game_version"], cid)
if profile: if profile:
binded = 1 binded = 1
newflag = 0 newflag = 0

View File

@ -7,7 +7,7 @@ from core_common import core_process_request, core_prepare_response, E
router = APIRouter(prefix="/core", tags=["eacoin"]) router = APIRouter(prefix="/core", tags=["eacoin"])
@router.post('/{gameinfo}/eacoin/checkin') @router.post("/{gameinfo}/eacoin/checkin")
async def eacoin_checkin(request: Request): async def eacoin_checkin(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
@ -27,7 +27,7 @@ async def eacoin_checkin(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/eacoin/consume') @router.post("/{gameinfo}/eacoin/consume")
async def eacoin_consume(request: Request): async def eacoin_consume(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
@ -43,7 +43,7 @@ async def eacoin_consume(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/eacoin/getbalance') @router.post("/{gameinfo}/eacoin/getbalance")
async def eacoin_getbalance(request: Request): async def eacoin_getbalance(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)

View File

@ -7,33 +7,33 @@ from core_common import core_process_request, core_prepare_response, E
router = APIRouter(prefix="/core", tags=["facility"]) router = APIRouter(prefix="/core", tags=["facility"])
@router.post('/{gameinfo}/facility/get') @router.post("/{gameinfo}/facility/get")
async def facility_get(request: Request): async def facility_get(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(
E.facility( E.facility(
E.location( E.location(
E('id', 'EA000001', __type="str"), E("id", "EA000001", __type="str"),
E.country('JP', __type="str"), E.country("JP", __type="str"),
E.region('JP-13', __type="str"), E.region("JP-13", __type="str"),
E.customercode('X000000001', __type="str"), E.customercode("X000000001", __type="str"),
E.companycode('X000000001', __type="str"), E.companycode("X000000001", __type="str"),
E.latitude(0, __type="s32"), E.latitude(0, __type="s32"),
E.longitude(0, __type="s32"), E.longitude(0, __type="s32"),
E.accuracy(0, __type="u8"), E.accuracy(0, __type="u8"),
E.countryname('Japan', __type="str"), E.countryname("Japan", __type="str"),
E.regionname('Tokyo', __type="str"), E.regionname("Tokyo", __type="str"),
E.countryjname('日本国', __type="str"), E.countryjname("日本国", __type="str"),
E.regionjname('東京都', __type="str"), E.regionjname("東京都", __type="str"),
E.name(config.arcade, __type="str"), E.name(config.arcade, __type="str"),
E('type', 255, __type="u8"), E("type", 255, __type="u8"),
), ),
E.line( E.line(
E('class', 8, __type="u8"), E("class", 8, __type="u8"),
E.rtt(500, __type="u16"), E.rtt(500, __type="u16"),
E.upclass(8, __type="u8"), E.upclass(8, __type="u8"),
E('id', 3, __type="str"), E("id", 3, __type="str"),
), ),
E.portfw( E.portfw(
E.globalip(config.ip, __type="ip4"), E.globalip(config.ip, __type="ip4"),
@ -56,11 +56,11 @@ async def facility_get(request: Request):
E.valid(365, __type="u16"), E.valid(365, __type="u16"),
), ),
E.url( E.url(
E.eapass('www.ea-pass.konami.net', __type="str"), E.eapass("www.ea-pass.konami.net", __type="str"),
E.arcadefan('www.konami.jp/am', __type="str"), E.arcadefan("www.konami.jp/am", __type="str"),
E.konaminetdx('http://am.573.jp', __type="str"), E.konaminetdx("http://am.573.jp", __type="str"),
E.konamiid('https://id.konami.net', __type="str"), E.konamiid("https://id.konami.net", __type="str"),
E.eagate('http://eagate.573.jp', __type="str"), E.eagate("http://eagate.573.jp", __type="str"),
), ),
), ),
expire=10800, expire=10800,

View File

@ -7,18 +7,22 @@ from core_common import core_process_request, core_prepare_response, E
router = APIRouter(prefix="/core", tags=["message"]) router = APIRouter(prefix="/core", tags=["message"])
@router.post('/{gameinfo}/message/get') @router.post("/{gameinfo}/message/get")
async def message_get(request: Request): async def message_get(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(
E.message( E.message(
expire=300, expire=300,
*[E.item( *[
name=s, E.item(
start=0, name=s,
end=604800, start=0,
) for s in ('sys.mainte', 'sys.eacoin.mainte') if config.maintenance_mode] end=604800,
)
for s in ("sys.mainte", "sys.eacoin.mainte")
if config.maintenance_mode
]
) )
) )

View File

@ -5,7 +5,7 @@ from core_common import core_process_request, core_prepare_response, E
router = APIRouter(prefix="/core", tags=["package"]) router = APIRouter(prefix="/core", tags=["package"])
@router.post('/{gameinfo}/package/list') @router.post("/{gameinfo}/package/list")
async def package_list(request: Request): async def package_list(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)

View File

@ -5,7 +5,7 @@ from core_common import core_process_request, core_prepare_response, E
router = APIRouter(prefix="/core", tags=["pcbevent"]) router = APIRouter(prefix="/core", tags=["pcbevent"])
@router.post('/{gameinfo}/pcbevent/put') @router.post("/{gameinfo}/pcbevent/put")
async def pcbevent_put(request: Request): async def pcbevent_put(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)

View File

@ -7,7 +7,7 @@ from core_common import core_process_request, core_prepare_response, E
router = APIRouter(prefix="/core", tags=["pcbtracker"]) router = APIRouter(prefix="/core", tags=["pcbtracker"])
@router.post('/{gameinfo}/pcbtracker/alive') @router.post("/{gameinfo}/pcbtracker/alive")
async def pcbtracker_alive(request: Request): async def pcbtracker_alive(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)

View File

@ -8,8 +8,8 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["MDX"] router.model_whitelist = ["MDX"]
@router.post('/{gameinfo}/eventlog/write') @router.post("/{gameinfo}/eventlog/write")
async def eventlog_write(request: Request): async def ddr_eventlog_write(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(

View File

@ -8,8 +8,8 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["MDX"] router.model_whitelist = ["MDX"]
@router.post('/{gameinfo}/eventlog_2/write') @router.post("/{gameinfo}/eventlog_2/write")
async def eventlog_2_write(request: Request): async def ddr_eventlog_2_write(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(

View File

@ -17,92 +17,98 @@ router.model_whitelist = ["MDX"]
def get_profile(cid): def get_profile(cid):
return get_db().table('ddr_profile').get( return get_db().table("ddr_profile").get(where("card") == cid)
where('card') == cid
)
def get_game_profile(cid, game_version): def get_game_profile(cid, game_version):
profile = get_profile(cid) profile = get_profile(cid)
return profile['version'].get(str(game_version), None) return profile["version"].get(str(game_version), None)
def get_common(ddr_id, game_version, idx): def get_common(ddr_id, game_version, idx):
profile = get_db().table('ddr_profile').get( profile = get_db().table("ddr_profile").get(where("ddr_id") == int(ddr_id))
where('ddr_id') == int(ddr_id)
)
if profile is not None: if profile is not None:
return profile['version'].get(str(game_version), None)['common'].split(',')[idx] return profile["version"].get(str(game_version), None)["common"].split(",")[idx]
else: else:
return 0 return 0
@router.post('/{gameinfo}/playerdata/usergamedata_advanced')
@router.post("/{gameinfo}/playerdata/usergamedata_advanced")
async def usergamedata_advanced(request: Request): async def usergamedata_advanced(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
is_omni = True if request_info['rev'] == 'O' else False is_omni = True if request_info["rev"] == "O" else False
response = None response = None
data = request_info['root'][0].find('data') data = request_info["root"][0].find("data")
mode = data.find('mode').text mode = data.find("mode").text
gamesession = data.find('gamesession').text gamesession = data.find("gamesession").text
refid = data.find('refid').text refid = data.find("refid").text
default = 'X0000000000000000000000000000000'[:-len(gamesession)]+gamesession default = "X0000000000000000000000000000000"[: -len(gamesession)] + gamesession
db = get_db() db = get_db()
all_profiles_for_card = db.table('ddr_profile').get(Query().card == refid) all_profiles_for_card = db.table("ddr_profile").get(Query().card == refid)
if mode == 'usernew': if mode == "usernew":
shoparea = data.find('shoparea').text shoparea = data.find("shoparea").text
if 'ddr_id' not in all_profiles_for_card: if "ddr_id" not in all_profiles_for_card:
ddr_id = random.randint(10000000, 99999999) ddr_id = random.randint(10000000, 99999999)
all_profiles_for_card['ddr_id'] = ddr_id all_profiles_for_card["ddr_id"] = ddr_id
all_profiles_for_card['version'][str(game_version)] = { all_profiles_for_card["version"][str(game_version)] = {
'game_version': game_version, "game_version": game_version,
'calories_disp': "Off", "calories_disp": "Off",
'character': "All Character Random", "character": "All Character Random",
'arrow_skin': "Normal", "arrow_skin": "Normal",
'filter': "Darkest", "filter": "Darkest",
'guideline': "Center", "guideline": "Center",
'priority': "Judgment", "priority": "Judgment",
'timing_disp': "On", "timing_disp": "On",
'rival_1_ddr_id': 0, "rival_1_ddr_id": 0,
'rival_2_ddr_id': 0, "rival_2_ddr_id": 0,
'rival_3_ddr_id': 0, "rival_3_ddr_id": 0,
'single_grade': 0, "single_grade": 0,
'double_grade': 0, "double_grade": 0,
} }
db.table('ddr_profile').upsert(all_profiles_for_card, where('card') == refid) db.table("ddr_profile").upsert(all_profiles_for_card, where("card") == refid)
response = E.response( response = E.response(
E.playerdata( E.playerdata(
E.result(0, __type="s32"), E.result(0, __type="s32"),
E.seq('-'.join([str(ddr_id)[:4], str(ddr_id)[4:]]), __type="str"), E.seq("-".join([str(ddr_id)[:4], str(ddr_id)[4:]]), __type="str"),
E.code(ddr_id, __type="s32"), E.code(ddr_id, __type="s32"),
E.shoparea(shoparea, __type="str") E.shoparea(shoparea, __type="str"),
) )
) )
elif mode == 'userload' and refid != default: elif mode == "userload" and refid != default:
all_scores = {} all_scores = {}
if all_profiles_for_card is not None: if all_profiles_for_card is not None:
ddr_id = all_profiles_for_card['ddr_id'] ddr_id = all_profiles_for_card["ddr_id"]
profile = get_game_profile(refid, game_version) profile = get_game_profile(refid, game_version)
single_grade = profile.get('single_grade', 0) single_grade = profile.get("single_grade", 0)
double_grade = profile.get('double_grade', 0) double_grade = profile.get("double_grade", 0)
for record in db.table('ddr_scores_best').search((where('game_version') == game_version)& (where('ddr_id') == ddr_id)): for record in db.table("ddr_scores_best").search(
mcode = record['mcode'] (where("game_version") == game_version) & (where("ddr_id") == ddr_id)
difficulty = record['difficulty'] ):
mcode = record["mcode"]
difficulty = record["difficulty"]
if mcode not in all_scores: if mcode not in all_scores:
all_scores[mcode] = [[0, 0, 0, 0, 0] for x in range(10)] all_scores[mcode] = [[0, 0, 0, 0, 0] for x in range(10)]
all_scores[mcode][difficulty] = ([1, record['rank'], record['lamp'], record['score'], record['ghostid']]) all_scores[mcode][difficulty] = [
1,
record["rank"],
record["lamp"],
record["score"],
record["ghostid"],
]
response = E.response( response = E.response(
E.playerdata( E.playerdata(
@ -110,25 +116,36 @@ async def usergamedata_advanced(request: Request):
E.is_new(1 if all_profiles_for_card is None else 0, __type="bool"), E.is_new(1 if all_profiles_for_card is None else 0, __type="bool"),
E.is_refid_locked(0, __type="bool"), E.is_refid_locked(0, __type="bool"),
E.eventdata_count_all(1, __type="s16"), E.eventdata_count_all(1, __type="s16"),
*[E.music( *[
E.mcode(int(mcode), __type="u32"), E.music(
*[E.note( E.mcode(int(mcode), __type="u32"),
E.count(s[0], __type="u16"), *[
E.rank(s[1], __type="u8"), E.note(
E.clearkind(s[2], __type="u8"), E.count(s[0], __type="u16"),
E.score(s[3], __type="s32"), E.rank(s[1], __type="u8"),
E.ghostid(s[4], __type="s32"), E.clearkind(s[2], __type="u8"),
) for s in [score for score in all_scores.get(mcode)]], E.score(s[3], __type="s32"),
) for mcode in all_scores.keys()], E.ghostid(s[4], __type="s32"),
*[E.eventdata( )
E.eventid(event, __type="u32"), for s in [score for score in all_scores.get(mcode)]
E.eventtype(9999, __type="s32"), ],
E.eventno(0, __type="u32"), )
E.condition(0, __type="s64"), for mcode in all_scores.keys()
E.reward(0, __type="u32"), ],
E.comptime(1, __type="s32"), *[
E.savedata(0, __type="s64"), E.eventdata(
) for event in [e for e in range(1, 100) if e not in [4, 6, 7, 8, 14, 47]]], E.eventid(event, __type="u32"),
E.eventtype(9999, __type="s32"),
E.eventno(0, __type="u32"),
E.condition(0, __type="s64"),
E.reward(0, __type="u32"),
E.comptime(1, __type="s32"),
E.savedata(0, __type="s64"),
)
for event in [
e for e in range(1, 100) if e not in [4, 6, 7, 8, 14, 47]
]
],
E.grade( E.grade(
E.single_grade(single_grade, __type="u32"), E.single_grade(single_grade, __type="u32"),
E.double_grade(double_grade, __type="u32"), E.double_grade(double_grade, __type="u32"),
@ -165,187 +182,194 @@ async def usergamedata_advanced(request: Request):
E.mcode(0, __type="u32"), E.mcode(0, __type="u32"),
E.notetype(0, __type="s8"), E.notetype(0, __type="s8"),
E.playstyle(0, __type="s32"), E.playstyle(0, __type="s32"),
) ),
), ),
E.preplayable(), E.preplayable(),
) )
) )
elif mode == 'ghostload': elif mode == "ghostload":
ghostid = int(data.find('ghostid').text) ghostid = int(data.find("ghostid").text)
record = db.table('ddr_scores').get(doc_id=ghostid) record = db.table("ddr_scores").get(doc_id=ghostid)
response = E.response( response = E.response(
E.playerdata( E.playerdata(
E.result(0, __type="s32"), E.result(0, __type="s32"),
E.ghostdata( E.ghostdata(
E.code(record['ddr_id'], __type="s32"), E.code(record["ddr_id"], __type="s32"),
E.mcode(record['mcode'], __type="u32"), E.mcode(record["mcode"], __type="u32"),
E.notetype(record['difficulty'], __type="u8"), E.notetype(record["difficulty"], __type="u8"),
E.ghostsize(record['ghostsize'], __type="s32"), E.ghostsize(record["ghostsize"], __type="s32"),
E.ghost(record['ghost'], __type="string"), E.ghost(record["ghost"], __type="string"),
) ),
) )
) )
elif mode == 'usersave' and refid != default: elif mode == "usersave" and refid != default:
timestamp = time.time() timestamp = time.time()
ddr_id = int(data.find('ddrcode').text) ddr_id = int(data.find("ddrcode").text)
playstyle = int(data.find('playstyle').text) playstyle = int(data.find("playstyle").text)
pcbid = data.find('pcbid').text pcbid = data.find("pcbid").text
shoparea = data.find('shoparea').text shoparea = data.find("shoparea").text
note = data.findall('note') note = data.findall("note")
if int(data.find('isgameover').text) == 0: if int(data.find("isgameover").text) == 0:
for n in note: for n in note:
if int(n.find('stagenum').text) != 0: if int(n.find("stagenum").text) != 0:
mcode = int(n.find('mcode').text) mcode = int(n.find("mcode").text)
difficulty = int(n.find('notetype').text) difficulty = int(n.find("notetype").text)
rank = int(n.find('rank').text) rank = int(n.find("rank").text)
lamp = int(n.find('clearkind').text) lamp = int(n.find("clearkind").text)
score = int(n.find('score').text) score = int(n.find("score").text)
exscore = int(n.find('exscore').text) exscore = int(n.find("exscore").text)
maxcombo = int(n.find('maxcombo').text) maxcombo = int(n.find("maxcombo").text)
life = int(n.find('life').text) life = int(n.find("life").text)
fastcount = int(n.find('fastcount').text) fastcount = int(n.find("fastcount").text)
slowcount = int(n.find('slowcount').text) slowcount = int(n.find("slowcount").text)
judge_marvelous = int(n.find('judge_marvelous').text) judge_marvelous = int(n.find("judge_marvelous").text)
judge_perfect = int(n.find('judge_perfect').text) judge_perfect = int(n.find("judge_perfect").text)
judge_great = int(n.find('judge_great').text) judge_great = int(n.find("judge_great").text)
judge_good = int(n.find('judge_good').text) judge_good = int(n.find("judge_good").text)
judge_boo = int(n.find('judge_boo').text) judge_boo = int(n.find("judge_boo").text)
judge_miss = int(n.find('judge_miss').text) judge_miss = int(n.find("judge_miss").text)
judge_ok = int(n.find('judge_ok').text) judge_ok = int(n.find("judge_ok").text)
judge_ng = int(n.find('judge_ng').text) judge_ng = int(n.find("judge_ng").text)
calorie = int(n.find('calorie').text) calorie = int(n.find("calorie").text)
ghostsize = int(n.find('ghostsize').text) ghostsize = int(n.find("ghostsize").text)
ghost = n.find('ghost').text ghost = n.find("ghost").text
opt_speed = int(n.find('opt_speed').text) opt_speed = int(n.find("opt_speed").text)
opt_boost = int(n.find('opt_boost').text) opt_boost = int(n.find("opt_boost").text)
opt_appearance = int(n.find('opt_appearance').text) opt_appearance = int(n.find("opt_appearance").text)
opt_turn = int(n.find('opt_turn').text) opt_turn = int(n.find("opt_turn").text)
opt_dark = int(n.find('opt_dark').text) opt_dark = int(n.find("opt_dark").text)
opt_scroll = int(n.find('opt_scroll').text) opt_scroll = int(n.find("opt_scroll").text)
opt_arrowcolor = int(n.find('opt_arrowcolor').text) opt_arrowcolor = int(n.find("opt_arrowcolor").text)
opt_cut = int(n.find('opt_cut').text) opt_cut = int(n.find("opt_cut").text)
opt_freeze = int(n.find('opt_freeze').text) opt_freeze = int(n.find("opt_freeze").text)
opt_jump = int(n.find('opt_jump').text) opt_jump = int(n.find("opt_jump").text)
opt_arrowshape = int(n.find('opt_arrowshape').text) opt_arrowshape = int(n.find("opt_arrowshape").text)
opt_filter = int(n.find('opt_filter').text) opt_filter = int(n.find("opt_filter").text)
opt_guideline = int(n.find('opt_guideline').text) opt_guideline = int(n.find("opt_guideline").text)
opt_gauge = int(n.find('opt_gauge').text) opt_gauge = int(n.find("opt_gauge").text)
opt_judgepriority = int(n.find('opt_judgepriority').text) opt_judgepriority = int(n.find("opt_judgepriority").text)
opt_timing = int(n.find('opt_timing').text) opt_timing = int(n.find("opt_timing").text)
db.table('ddr_scores').insert( db.table("ddr_scores").insert(
{ {
'timestamp': timestamp, "timestamp": timestamp,
'pcbid': pcbid, "pcbid": pcbid,
'shoparea': shoparea, "shoparea": shoparea,
'game_version': game_version, "game_version": game_version,
'ddr_id': ddr_id, "ddr_id": ddr_id,
'playstyle': playstyle, "playstyle": playstyle,
'mcode': mcode, "mcode": mcode,
'difficulty': difficulty, "difficulty": difficulty,
'rank': rank, "rank": rank,
'lamp': lamp, "lamp": lamp,
'score': score, "score": score,
'exscore': exscore, "exscore": exscore,
'maxcombo': maxcombo, "maxcombo": maxcombo,
'life': life, "life": life,
'fastcount': fastcount, "fastcount": fastcount,
'slowcount': slowcount, "slowcount": slowcount,
'judge_marvelous': judge_marvelous, "judge_marvelous": judge_marvelous,
'judge_perfect': judge_perfect, "judge_perfect": judge_perfect,
'judge_great': judge_great, "judge_great": judge_great,
'judge_good': judge_good, "judge_good": judge_good,
'judge_boo': judge_boo, "judge_boo": judge_boo,
'judge_miss': judge_miss, "judge_miss": judge_miss,
'judge_ok': judge_ok, "judge_ok": judge_ok,
'judge_ng': judge_ng, "judge_ng": judge_ng,
'calorie': calorie, "calorie": calorie,
'ghostsize': ghostsize, "ghostsize": ghostsize,
'ghost': ghost, "ghost": ghost,
'opt_speed': opt_speed, "opt_speed": opt_speed,
'opt_boost': opt_boost, "opt_boost": opt_boost,
'opt_appearance': opt_appearance, "opt_appearance": opt_appearance,
'opt_turn': opt_turn, "opt_turn": opt_turn,
'opt_dark': opt_dark, "opt_dark": opt_dark,
'opt_scroll': opt_scroll, "opt_scroll": opt_scroll,
'opt_arrowcolor': opt_arrowcolor, "opt_arrowcolor": opt_arrowcolor,
'opt_cut': opt_cut, "opt_cut": opt_cut,
'opt_freeze': opt_freeze, "opt_freeze": opt_freeze,
'opt_jump': opt_jump, "opt_jump": opt_jump,
'opt_arrowshape': opt_arrowshape, "opt_arrowshape": opt_arrowshape,
'opt_filter': opt_filter, "opt_filter": opt_filter,
'opt_guideline': opt_guideline, "opt_guideline": opt_guideline,
'opt_gauge': opt_gauge, "opt_gauge": opt_gauge,
'opt_judgepriority': opt_judgepriority, "opt_judgepriority": opt_judgepriority,
'opt_timing': opt_timing, "opt_timing": opt_timing,
}, },
) )
best = db.table('ddr_scores_best').get( best = db.table("ddr_scores_best").get(
(where('ddr_id') == ddr_id) (where("ddr_id") == ddr_id)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('mcode') == mcode) & (where("mcode") == mcode)
& (where('difficulty') == difficulty) & (where("difficulty") == difficulty)
) )
best = {} if best is None else best best = {} if best is None else best
best_score_data = { best_score_data = {
'game_version': game_version, "game_version": game_version,
'ddr_id': ddr_id, "ddr_id": ddr_id,
'playstyle': playstyle, "playstyle": playstyle,
'mcode': mcode, "mcode": mcode,
'difficulty': difficulty, "difficulty": difficulty,
'rank': min(rank, best.get('rank', rank)), "rank": min(rank, best.get("rank", rank)),
'lamp': max(lamp, best.get('lamp', lamp)), "lamp": max(lamp, best.get("lamp", lamp)),
'score': max(score, best.get('score', score)), "score": max(score, best.get("score", score)),
'exscore': max(exscore, best.get('exscore', exscore)), "exscore": max(exscore, best.get("exscore", exscore)),
} }
ghostid = db.table('ddr_scores').get( ghostid = db.table("ddr_scores").get(
(where('ddr_id') == ddr_id) (where("ddr_id") == ddr_id)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('mcode') == mcode) & (where("mcode") == mcode)
& (where('difficulty') == difficulty) & (where("difficulty") == difficulty)
& (where('score') == max(score, best.get('score', score))) & (where("score") == max(score, best.get("score", score)))
) )
best_score_data['ghostid'] = ghostid.doc_id best_score_data["ghostid"] = ghostid.doc_id
db.table('ddr_scores_best').upsert( db.table("ddr_scores_best").upsert(
best_score_data, best_score_data,
(where('ddr_id') == ddr_id) (where("ddr_id") == ddr_id)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('mcode') == mcode) & (where("mcode") == mcode)
& (where('difficulty') == difficulty) & (where("difficulty") == difficulty),
) )
elif int(data.find('isgameover').text) == 1: elif int(data.find("isgameover").text) == 1:
single_grade = int(data.find('grade/single_grade').text) single_grade = int(data.find("grade/single_grade").text)
double_grade = int(data.find('grade/double_grade').text) double_grade = int(data.find("grade/double_grade").text)
profile = get_profile(refid) profile = get_profile(refid)
game_profile = profile['version'].get(str(game_version), {}) game_profile = profile["version"].get(str(game_version), {})
# workaround to save the correct dan grade by using the course mcode # workaround to save the correct dan grade by using the course mcode
# because omnimix force unlocks all dan courses with <grade __type="u8">1</grade> in coursedb.xml # because omnimix force unlocks all dan courses with <grade __type="u8">1</grade> in coursedb.xml
if is_omni: if is_omni:
n = note[0] n = note[0]
mcode = int(n.find('mcode').text) mcode = int(n.find("mcode").text)
if int(n.find('clearkind').text) != 1: if int(n.find("clearkind").text) != 1:
for grade, course_id in enumerate(range(1000, 1011), start=1): for grade, course_id in enumerate(range(1000, 1011), start=1):
if playstyle == 0 and mcode in (course_id, course_id + 11): if playstyle == 0 and mcode in (course_id, course_id + 11):
single_grade = grade single_grade = grade
elif playstyle == 1 and mcode in (course_id + 1000, course_id + 1000 + 11): elif playstyle == 1 and mcode in (
course_id + 1000,
course_id + 1000 + 11,
):
double_grade = grade double_grade = grade
game_profile['single_grade'] = max(single_grade, game_profile.get('single_grade', single_grade)) game_profile["single_grade"] = max(
game_profile['double_grade'] = max(double_grade, game_profile.get('double_grade', double_grade)) single_grade, game_profile.get("single_grade", single_grade)
)
game_profile["double_grade"] = max(
double_grade, game_profile.get("double_grade", double_grade)
)
profile['version'][str(game_version)] = game_profile profile["version"][str(game_version)] = game_profile
db.table('ddr_profile').upsert(profile, where('card') == refid) db.table("ddr_profile").upsert(profile, where("card") == refid)
response = E.response( response = E.response(
E.playerdata( E.playerdata(
@ -353,95 +377,121 @@ async def usergamedata_advanced(request: Request):
) )
) )
elif mode == 'rivalload': elif mode == "rivalload":
loadflag = int(data.find('loadflag').text) loadflag = int(data.find("loadflag").text)
ddrcode = int(data.find('ddrcode').text) ddrcode = int(data.find("ddrcode").text)
pcbid = data.find('pcbid').text pcbid = data.find("pcbid").text
shoparea = data.find('shoparea').text shoparea = data.find("shoparea").text
if loadflag == 1: if loadflag == 1:
all_scores = {} all_scores = {}
for record in db.table('ddr_scores').search( for record in db.table("ddr_scores").search(
(where('game_version') == game_version) (where("game_version") == game_version)
& (where('pcbid') == pcbid) & (where("pcbid") == pcbid)
& (where('ddr_id') != 0) & (where("ddr_id") != 0)
): ):
ddr_id = record['ddr_id'] ddr_id = record["ddr_id"]
playstyle = record['playstyle'] playstyle = record["playstyle"]
mcode = record['mcode'] mcode = record["mcode"]
difficulty = record['difficulty'] difficulty = record["difficulty"]
score = record['score'] score = record["score"]
if (playstyle, mcode, difficulty) not in all_scores or score > all_scores[(playstyle, mcode, difficulty)].get("score"): if (
playstyle,
mcode,
difficulty,
) not in all_scores or score > all_scores[
(playstyle, mcode, difficulty)
].get(
"score"
):
all_scores[playstyle, mcode, difficulty] = { all_scores[playstyle, mcode, difficulty] = {
'game_version': game_version, "game_version": game_version,
'ddr_id': ddr_id, "ddr_id": ddr_id,
'playstyle': playstyle, "playstyle": playstyle,
'mcode': mcode, "mcode": mcode,
'difficulty': difficulty, "difficulty": difficulty,
'rank': record['rank'], "rank": record["rank"],
'lamp': record['lamp'], "lamp": record["lamp"],
'score': score, "score": score,
'exscore': record['exscore'], "exscore": record["exscore"],
'ghostid': record.doc_id "ghostid": record.doc_id,
} }
scores = list(all_scores.values()) scores = list(all_scores.values())
elif loadflag == 2: elif loadflag == 2:
all_scores = {} all_scores = {}
for record in db.table('ddr_scores').search( for record in db.table("ddr_scores").search(
(where('game_version') == game_version) (where("game_version") == game_version)
& (where('shoparea') == shoparea) & (where("shoparea") == shoparea)
& (where('ddr_id') != 0) & (where("ddr_id") != 0)
): ):
ddr_id = record['ddr_id'] ddr_id = record["ddr_id"]
playstyle = record['playstyle'] playstyle = record["playstyle"]
mcode = record['mcode'] mcode = record["mcode"]
difficulty = record['difficulty'] difficulty = record["difficulty"]
score = record['score'] score = record["score"]
if (playstyle, mcode, difficulty) not in all_scores or score > all_scores[(playstyle, mcode, difficulty)].get("score"): if (
playstyle,
mcode,
difficulty,
) not in all_scores or score > all_scores[
(playstyle, mcode, difficulty)
].get(
"score"
):
all_scores[playstyle, mcode, difficulty] = { all_scores[playstyle, mcode, difficulty] = {
'game_version': game_version, "game_version": game_version,
'ddr_id': ddr_id, "ddr_id": ddr_id,
'playstyle': playstyle, "playstyle": playstyle,
'mcode': mcode, "mcode": mcode,
'difficulty': difficulty, "difficulty": difficulty,
'rank': record['rank'], "rank": record["rank"],
'lamp': record['lamp'], "lamp": record["lamp"],
'score': score, "score": score,
'exscore': record['exscore'], "exscore": record["exscore"],
'ghostid': record.doc_id "ghostid": record.doc_id,
} }
scores = list(all_scores.values()) scores = list(all_scores.values())
elif loadflag == 4: elif loadflag == 4:
all_scores = {} all_scores = {}
for record in db.table('ddr_scores').search((where('game_version') == game_version) & (where('ddr_id') != 0)): for record in db.table("ddr_scores").search(
ddr_id = record['ddr_id'] (where("game_version") == game_version) & (where("ddr_id") != 0)
playstyle = record['playstyle'] ):
mcode = record['mcode'] ddr_id = record["ddr_id"]
difficulty = record['difficulty'] playstyle = record["playstyle"]
score = record['score'] mcode = record["mcode"]
difficulty = record["difficulty"]
score = record["score"]
if (playstyle, mcode, difficulty) not in all_scores or score > all_scores[(playstyle, mcode, difficulty)].get("score"): if (
playstyle,
mcode,
difficulty,
) not in all_scores or score > all_scores[
(playstyle, mcode, difficulty)
].get(
"score"
):
all_scores[playstyle, mcode, difficulty] = { all_scores[playstyle, mcode, difficulty] = {
'game_version': game_version, "game_version": game_version,
'ddr_id': ddr_id, "ddr_id": ddr_id,
'playstyle': playstyle, "playstyle": playstyle,
'mcode': mcode, "mcode": mcode,
'difficulty': difficulty, "difficulty": difficulty,
'rank': record['rank'], "rank": record["rank"],
'lamp': record['lamp'], "lamp": record["lamp"],
'score': score, "score": score,
'exscore': record['exscore'], "exscore": record["exscore"],
'ghostid': record.doc_id "ghostid": record.doc_id,
} }
scores = list(all_scores.values()) scores = list(all_scores.values())
elif loadflag in (8, 16, 32): elif loadflag in (8, 16, 32):
scores = [] scores = []
for s in db.table('ddr_scores_best').search(where('ddr_id') == ddrcode): for s in db.table("ddr_scores_best").search(where("ddr_id") == ddrcode):
scores.append(s) scores.append(s)
response = E.response( response = E.response(
@ -449,23 +499,31 @@ async def usergamedata_advanced(request: Request):
E.result(0, __type="s32"), E.result(0, __type="s32"),
E.data( E.data(
E.recordtype(loadflag, __type="s32"), E.recordtype(loadflag, __type="s32"),
*[E.record( *[
E.mcode(s['mcode'], __type="u32"), E.record(
E.notetype(s['difficulty'], __type="u8"), E.mcode(s["mcode"], __type="u32"),
E.rank(s['rank'], __type="u8"), E.notetype(s["difficulty"], __type="u8"),
E.clearkind(s['lamp'], __type="u8"), E.rank(s["rank"], __type="u8"),
E.flagdata(0, __type="u8"), E.clearkind(s["lamp"], __type="u8"),
E.name(get_common(s['ddr_id'], game_version, 27), __type="str"), E.flagdata(0, __type="u8"),
E.area(int(get_common(s['ddr_id'], game_version, 3), 16), __type="s32"), E.name(
E.code(s['ddr_id'], __type="s32"), get_common(s["ddr_id"], game_version, 27), __type="str"
E.score(s['score'], __type="s32"), ),
E.ghostid(s['ghostid'], __type="s32"), E.area(
)for s in scores] int(get_common(s["ddr_id"], game_version, 3), 16),
) __type="s32",
),
E.code(s["ddr_id"], __type="s32"),
E.score(s["score"], __type="s32"),
E.ghostid(s["ghostid"], __type="s32"),
)
for s in scores
],
),
) )
) )
elif mode == 'inheritance': elif mode == "inheritance":
response = E.response( response = E.response(
E.playerdata( E.playerdata(
E.result(0, __type="s32"), E.result(0, __type="s32"),
@ -484,50 +542,87 @@ async def usergamedata_advanced(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/playerdata/usergamedata_recv') @router.post("/{gameinfo}/playerdata/usergamedata_recv")
async def usergamedata_recv(request: Request): async def usergamedata_recv(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
data = request_info['root'][0].find('data') data = request_info["root"][0].find("data")
cid = data.find('refid').text cid = data.find("refid").text
profile = get_game_profile(cid, game_version) profile = get_game_profile(cid, game_version)
db = get_db().table('ddr_profile') db = get_db().table("ddr_profile")
all_profiles_for_card = db.get(Query().card == cid) all_profiles_for_card = db.get(Query().card == cid)
if all_profiles_for_card is None: if all_profiles_for_card is None:
load = [ load = [
b64encode(str.encode('1,d,1111111,1,0,0,0,0,0,ffffffffffffffff,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,1010-1010,,,,,,').decode()), b64encode(
b64encode(str.encode('0,3,0,0,0,0,0,3,0,0,0,0,1,2,0,0,0,10.000000,10.000000,10.000000,10.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,').decode()), str.encode(
b64encode(str.encode('1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,').decode()), "1,d,1111111,1,0,0,0,0,0,ffffffffffffffff,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,1010-1010,,,,,,"
b64encode(str.encode('0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,').decode()), ).decode()
),
b64encode(
str.encode(
"0,3,0,0,0,0,0,3,0,0,0,0,1,2,0,0,0,10.000000,10.000000,10.000000,10.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,"
).decode()
),
b64encode(
str.encode(
"1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,"
).decode()
),
b64encode(
str.encode(
"0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,"
).decode()
),
] ]
else: else:
calories_disp = ["Off", "On"] calories_disp = ["Off", "On"]
character = ["All Character Random", "Man Random", "Female Random", "Yuni", "Rage", "Afro", "Jenny", "Emi", "Baby-Lon", "Gus", "Ruby", "Alice", "Julio", "Bonnie", "Zero", "Rinon"] character = [
"All Character Random",
"Man Random",
"Female Random",
"Yuni",
"Rage",
"Afro",
"Jenny",
"Emi",
"Baby-Lon",
"Gus",
"Ruby",
"Alice",
"Julio",
"Bonnie",
"Zero",
"Rinon",
]
arrow_skin = ["Normal", "X", "Classic", "Cyber", "Medium", "Small", "Dot"] arrow_skin = ["Normal", "X", "Classic", "Cyber", "Medium", "Small", "Dot"]
screen_filter = ["Off", "Dark", "Darker", "Darkest"] screen_filter = ["Off", "Dark", "Darker", "Darkest"]
guideline = ["Off", "Border", "Center"] guideline = ["Off", "Border", "Center"]
priority = ["Judgment", "Arrow"] priority = ["Judgment", "Arrow"]
timing_disp = ["Off", "On"] timing_disp = ["Off", "On"]
common = profile['common'].split(',') common = profile["common"].split(",")
common[5] = calories_disp.index(profile['calories_disp']) common[5] = calories_disp.index(profile["calories_disp"])
common[6] = character.index(profile['character']) common[6] = character.index(profile["character"])
common[9] = 1 # Mobile link common[9] = 1 # Mobile link
common_load = ",".join([str(i) for i in common]) common_load = ",".join([str(i) for i in common])
option = profile['option'].split(',') option = profile["option"].split(",")
option[13] = arrow_skin.index(profile['arrow_skin']) option[13] = arrow_skin.index(profile["arrow_skin"])
option[14] = screen_filter.index(profile['filter']) option[14] = screen_filter.index(profile["filter"])
option[15] = guideline.index(profile['guideline']) option[15] = guideline.index(profile["guideline"])
option[17] = priority.index(profile['priority']) option[17] = priority.index(profile["priority"])
option[18] = timing_disp.index(profile['timing_disp']) option[18] = timing_disp.index(profile["timing_disp"])
option_load = ",".join([str(i) for i in option]) option_load = ",".join([str(i) for i in option])
rival = profile['rival'].split(',') rival = profile["rival"].split(",")
rival_ids = [profile.get('rival_1_ddr_id', 0), profile.get('rival_2_ddr_id', 0), profile.get('rival_3_ddr_id', 0)] rival_ids = [
profile.get("rival_1_ddr_id", 0),
profile.get("rival_2_ddr_id", 0),
profile.get("rival_3_ddr_id", 0),
]
for idx, r in enumerate(rival_ids, start=3): for idx, r in enumerate(rival_ids, start=3):
if r != 0: if r != 0:
rival[idx] = idx - 2 rival[idx] = idx - 2
@ -535,10 +630,10 @@ async def usergamedata_recv(request: Request):
rival_load = ",".join([str(i) for i in rival]) rival_load = ",".join([str(i) for i in rival])
load = [ load = [
b64encode(str.encode(common_load.split('ffffffff,COMMON,')[1])).decode(), b64encode(str.encode(common_load.split("ffffffff,COMMON,")[1])).decode(),
b64encode(str.encode(option_load.split('ffffffff,OPTION,')[1])).decode(), b64encode(str.encode(option_load.split("ffffffff,OPTION,")[1])).decode(),
b64encode(str.encode(profile['last'].split('ffffffff,LAST,')[1])).decode(), b64encode(str.encode(profile["last"].split("ffffffff,LAST,")[1])).decode(),
b64encode(str.encode(rival_load.split('ffffffff,RIVAL,')[1])).decode() b64encode(str.encode(rival_load.split("ffffffff,RIVAL,")[1])).decode(),
] ]
response = E.response( response = E.response(
@ -546,7 +641,7 @@ async def usergamedata_recv(request: Request):
E.result(0, __type="s32"), E.result(0, __type="s32"),
E.player( E.player(
E.record( E.record(
*[E.d(p, __type="str")for p in load], *[E.d(p, __type="str") for p in load],
), ),
E.record_num(4, __type="u32"), E.record_num(4, __type="u32"),
), ),
@ -557,33 +652,43 @@ async def usergamedata_recv(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/playerdata/usergamedata_send') @router.post("/{gameinfo}/playerdata/usergamedata_send")
async def usergamedata_send(request: Request): async def usergamedata_send(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
data = request_info['root'][0].find('data') data = request_info["root"][0].find("data")
cid = data.find('refid').text cid = data.find("refid").text
num = int(data.find('datanum').text) num = int(data.find("datanum").text)
profile = get_profile(cid) profile = get_profile(cid)
game_profile = profile['version'].get(str(game_version), {}) game_profile = profile["version"].get(str(game_version), {})
if num == 1: if num == 1:
game_profile['common'] = b64decode(data.find('record')[0].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore') game_profile["common"] = b64decode(
data.find("record")[0].text.split("<bin1")[0]
).decode(encoding="utf-8", errors="ignore")
elif num == 4: elif num == 4:
game_profile['common'] = b64decode(data.find('record')[0].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore') game_profile["common"] = b64decode(
game_profile['option'] = b64decode(data.find('record')[1].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore') data.find("record")[0].text.split("<bin1")[0]
game_profile['last'] = b64decode(data.find('record')[2].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore') ).decode(encoding="utf-8", errors="ignore")
game_profile['rival'] = b64decode(data.find('record')[3].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore') game_profile["option"] = b64decode(
for r in ('rival_1_ddr_id', 'rival_2_ddr_id', 'rival_3_ddr_id'): data.find("record")[1].text.split("<bin1")[0]
).decode(encoding="utf-8", errors="ignore")
game_profile["last"] = b64decode(
data.find("record")[2].text.split("<bin1")[0]
).decode(encoding="utf-8", errors="ignore")
game_profile["rival"] = b64decode(
data.find("record")[3].text.split("<bin1")[0]
).decode(encoding="utf-8", errors="ignore")
for r in ("rival_1_ddr_id", "rival_2_ddr_id", "rival_3_ddr_id"):
if r not in game_profile: if r not in game_profile:
game_profile[r] = 0 game_profile[r] = 0
profile['version'][str(game_version)] = game_profile profile["version"][str(game_version)] = game_profile
get_db().table('ddr_profile').upsert(profile, where('card') == cid) get_db().table("ddr_profile").upsert(profile, where("card") == cid)
response = E.response( response = E.response(
E.playerdata( E.playerdata(

View File

@ -17,92 +17,98 @@ router.model_whitelist = ["MDX"]
def get_profile(cid): def get_profile(cid):
return get_db().table('ddr_profile').get( return get_db().table("ddr_profile").get(where("card") == cid)
where('card') == cid
)
def get_game_profile(cid, game_version): def get_game_profile(cid, game_version):
profile = get_profile(cid) profile = get_profile(cid)
return profile['version'].get(str(game_version), None) return profile["version"].get(str(game_version), None)
def get_common(ddr_id, game_version, idx): def get_common(ddr_id, game_version, idx):
profile = get_db().table('ddr_profile').get( profile = get_db().table("ddr_profile").get(where("ddr_id") == int(ddr_id))
where('ddr_id') == int(ddr_id)
)
if profile is not None: if profile is not None:
return profile['version'].get(str(game_version), None)['common'].split(',')[idx] return profile["version"].get(str(game_version), None)["common"].split(",")[idx]
else: else:
return 0 return 0
@router.post('/{gameinfo}/playerdata_2/usergamedata_advanced')
@router.post("/{gameinfo}/playerdata_2/usergamedata_advanced")
async def usergamedata_advanced(request: Request): async def usergamedata_advanced(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
is_omni = True if request_info['rev'] == 'O' else False is_omni = True if request_info["rev"] == "O" else False
response = None response = None
data = request_info['root'][0].find('data') data = request_info["root"][0].find("data")
mode = data.find('mode').text mode = data.find("mode").text
gamesession = data.find('gamesession').text gamesession = data.find("gamesession").text
refid = data.find('refid').text refid = data.find("refid").text
default = 'X0000000000000000000000000000000'[:-len(gamesession)]+gamesession default = "X0000000000000000000000000000000"[: -len(gamesession)] + gamesession
db = get_db() db = get_db()
all_profiles_for_card = db.table('ddr_profile').get(Query().card == refid) all_profiles_for_card = db.table("ddr_profile").get(Query().card == refid)
if mode == 'usernew': if mode == "usernew":
shoparea = data.find('shoparea').text shoparea = data.find("shoparea").text
if 'ddr_id' not in all_profiles_for_card: if "ddr_id" not in all_profiles_for_card:
ddr_id = random.randint(10000000, 99999999) ddr_id = random.randint(10000000, 99999999)
all_profiles_for_card['ddr_id'] = ddr_id all_profiles_for_card["ddr_id"] = ddr_id
all_profiles_for_card['version'][str(game_version)] = { all_profiles_for_card["version"][str(game_version)] = {
'game_version': game_version, "game_version": game_version,
'calories_disp': "Off", "calories_disp": "Off",
'character': "All Character Random", "character": "All Character Random",
'arrow_skin': "Normal", "arrow_skin": "Normal",
'filter': "Darkest", "filter": "Darkest",
'guideline': "Center", "guideline": "Center",
'priority': "Judgment", "priority": "Judgment",
'timing_disp': "On", "timing_disp": "On",
'rival_1_ddr_id': 0, "rival_1_ddr_id": 0,
'rival_2_ddr_id': 0, "rival_2_ddr_id": 0,
'rival_3_ddr_id': 0, "rival_3_ddr_id": 0,
'single_grade': 0, "single_grade": 0,
'double_grade': 0, "double_grade": 0,
} }
db.table('ddr_profile').upsert(all_profiles_for_card, where('card') == refid) db.table("ddr_profile").upsert(all_profiles_for_card, where("card") == refid)
response = E.response( response = E.response(
E.playerdata_2( E.playerdata_2(
E.result(0, __type="s32"), E.result(0, __type="s32"),
E.seq('-'.join([str(ddr_id)[:4], str(ddr_id)[4:]]), __type="str"), E.seq("-".join([str(ddr_id)[:4], str(ddr_id)[4:]]), __type="str"),
E.code(ddr_id, __type="s32"), E.code(ddr_id, __type="s32"),
E.shoparea(shoparea, __type="str") E.shoparea(shoparea, __type="str"),
) )
) )
elif mode == 'userload' and refid != default: elif mode == "userload" and refid != default:
all_scores = {} all_scores = {}
if all_profiles_for_card is not None: if all_profiles_for_card is not None:
ddr_id = all_profiles_for_card['ddr_id'] ddr_id = all_profiles_for_card["ddr_id"]
profile = get_game_profile(refid, game_version) profile = get_game_profile(refid, game_version)
single_grade = profile.get('single_grade', 0) single_grade = profile.get("single_grade", 0)
double_grade = profile.get('double_grade', 0) double_grade = profile.get("double_grade", 0)
for record in db.table('ddr_scores_best').search((where('game_version') == game_version)& (where('ddr_id') == ddr_id)): for record in db.table("ddr_scores_best").search(
mcode = record['mcode'] (where("game_version") == game_version) & (where("ddr_id") == ddr_id)
difficulty = record['difficulty'] ):
mcode = record["mcode"]
difficulty = record["difficulty"]
if mcode not in all_scores: if mcode not in all_scores:
all_scores[mcode] = [[0, 0, 0, 0, 0] for x in range(10)] all_scores[mcode] = [[0, 0, 0, 0, 0] for x in range(10)]
all_scores[mcode][difficulty] = ([1, record['rank'], record['lamp'], record['score'], record['ghostid']]) all_scores[mcode][difficulty] = [
1,
record["rank"],
record["lamp"],
record["score"],
record["ghostid"],
]
response = E.response( response = E.response(
E.playerdata_2( E.playerdata_2(
@ -110,25 +116,36 @@ async def usergamedata_advanced(request: Request):
E.is_new(1 if all_profiles_for_card is None else 0, __type="bool"), E.is_new(1 if all_profiles_for_card is None else 0, __type="bool"),
E.is_refid_locked(0, __type="bool"), E.is_refid_locked(0, __type="bool"),
E.eventdata_count_all(1, __type="s16"), E.eventdata_count_all(1, __type="s16"),
*[E.music( *[
E.mcode(int(mcode), __type="u32"), E.music(
*[E.note( E.mcode(int(mcode), __type="u32"),
E.count(s[0], __type="u16"), *[
E.rank(s[1], __type="u8"), E.note(
E.clearkind(s[2], __type="u8"), E.count(s[0], __type="u16"),
E.score(s[3], __type="s32"), E.rank(s[1], __type="u8"),
E.ghostid(s[4], __type="s32"), E.clearkind(s[2], __type="u8"),
) for s in [score for score in all_scores.get(mcode)]], E.score(s[3], __type="s32"),
) for mcode in all_scores.keys()], E.ghostid(s[4], __type="s32"),
*[E.eventdata( )
E.eventid(event, __type="u32"), for s in [score for score in all_scores.get(mcode)]
E.eventtype(9999, __type="s32"), ],
E.eventno(0, __type="u32"), )
E.condition(0, __type="s64"), for mcode in all_scores.keys()
E.reward(0, __type="u32"), ],
E.comptime(1, __type="s32"), *[
E.savedata(0, __type="s64"), E.eventdata(
) for event in [e for e in range(1, 100) if e not in [4, 6, 7, 8, 14, 47]]], E.eventid(event, __type="u32"),
E.eventtype(9999, __type="s32"),
E.eventno(0, __type="u32"),
E.condition(0, __type="s64"),
E.reward(0, __type="u32"),
E.comptime(1, __type="s32"),
E.savedata(0, __type="s64"),
)
for event in [
e for e in range(1, 100) if e not in [4, 6, 7, 8, 14, 47]
]
],
E.grade( E.grade(
E.single_grade(single_grade, __type="u32"), E.single_grade(single_grade, __type="u32"),
E.double_grade(double_grade, __type="u32"), E.double_grade(double_grade, __type="u32"),
@ -165,187 +182,194 @@ async def usergamedata_advanced(request: Request):
E.mcode(0, __type="u32"), E.mcode(0, __type="u32"),
E.notetype(0, __type="s8"), E.notetype(0, __type="s8"),
E.playstyle(0, __type="s32"), E.playstyle(0, __type="s32"),
) ),
), ),
E.preplayable(), E.preplayable(),
) )
) )
elif mode == 'ghostload': elif mode == "ghostload":
ghostid = int(data.find('ghostid').text) ghostid = int(data.find("ghostid").text)
record = db.table('ddr_scores').get(doc_id=ghostid) record = db.table("ddr_scores").get(doc_id=ghostid)
response = E.response( response = E.response(
E.playerdata_2( E.playerdata_2(
E.result(0, __type="s32"), E.result(0, __type="s32"),
E.ghostdata( E.ghostdata(
E.code(record['ddr_id'], __type="s32"), E.code(record["ddr_id"], __type="s32"),
E.mcode(record['mcode'], __type="u32"), E.mcode(record["mcode"], __type="u32"),
E.notetype(record['difficulty'], __type="u8"), E.notetype(record["difficulty"], __type="u8"),
E.ghostsize(record['ghostsize'], __type="s32"), E.ghostsize(record["ghostsize"], __type="s32"),
E.ghost(record['ghost'], __type="string"), E.ghost(record["ghost"], __type="string"),
) ),
) )
) )
elif mode == 'usersave' and refid != default: elif mode == "usersave" and refid != default:
timestamp = time.time() timestamp = time.time()
ddr_id = int(data.find('ddrcode').text) ddr_id = int(data.find("ddrcode").text)
playstyle = int(data.find('playstyle').text) playstyle = int(data.find("playstyle").text)
pcbid = data.find('pcbid').text pcbid = data.find("pcbid").text
shoparea = data.find('shoparea').text shoparea = data.find("shoparea").text
note = data.findall('note') note = data.findall("note")
if int(data.find('isgameover').text) == 0: if int(data.find("isgameover").text) == 0:
for n in note: for n in note:
if int(n.find('stagenum').text) != 0: if int(n.find("stagenum").text) != 0:
mcode = int(n.find('mcode').text) mcode = int(n.find("mcode").text)
difficulty = int(n.find('notetype').text) difficulty = int(n.find("notetype").text)
rank = int(n.find('rank').text) rank = int(n.find("rank").text)
lamp = int(n.find('clearkind').text) lamp = int(n.find("clearkind").text)
score = int(n.find('score').text) score = int(n.find("score").text)
exscore = int(n.find('exscore').text) exscore = int(n.find("exscore").text)
maxcombo = int(n.find('maxcombo').text) maxcombo = int(n.find("maxcombo").text)
life = int(n.find('life').text) life = int(n.find("life").text)
fastcount = int(n.find('fastcount').text) fastcount = int(n.find("fastcount").text)
slowcount = int(n.find('slowcount').text) slowcount = int(n.find("slowcount").text)
judge_marvelous = int(n.find('judge_marvelous').text) judge_marvelous = int(n.find("judge_marvelous").text)
judge_perfect = int(n.find('judge_perfect').text) judge_perfect = int(n.find("judge_perfect").text)
judge_great = int(n.find('judge_great').text) judge_great = int(n.find("judge_great").text)
judge_good = int(n.find('judge_good').text) judge_good = int(n.find("judge_good").text)
judge_boo = int(n.find('judge_boo').text) judge_boo = int(n.find("judge_boo").text)
judge_miss = int(n.find('judge_miss').text) judge_miss = int(n.find("judge_miss").text)
judge_ok = int(n.find('judge_ok').text) judge_ok = int(n.find("judge_ok").text)
judge_ng = int(n.find('judge_ng').text) judge_ng = int(n.find("judge_ng").text)
calorie = int(n.find('calorie').text) calorie = int(n.find("calorie").text)
ghostsize = int(n.find('ghostsize').text) ghostsize = int(n.find("ghostsize").text)
ghost = n.find('ghost').text ghost = n.find("ghost").text
opt_speed = int(n.find('opt_speed').text) opt_speed = int(n.find("opt_speed").text)
opt_boost = int(n.find('opt_boost').text) opt_boost = int(n.find("opt_boost").text)
opt_appearance = int(n.find('opt_appearance').text) opt_appearance = int(n.find("opt_appearance").text)
opt_turn = int(n.find('opt_turn').text) opt_turn = int(n.find("opt_turn").text)
opt_dark = int(n.find('opt_dark').text) opt_dark = int(n.find("opt_dark").text)
opt_scroll = int(n.find('opt_scroll').text) opt_scroll = int(n.find("opt_scroll").text)
opt_arrowcolor = int(n.find('opt_arrowcolor').text) opt_arrowcolor = int(n.find("opt_arrowcolor").text)
opt_cut = int(n.find('opt_cut').text) opt_cut = int(n.find("opt_cut").text)
opt_freeze = int(n.find('opt_freeze').text) opt_freeze = int(n.find("opt_freeze").text)
opt_jump = int(n.find('opt_jump').text) opt_jump = int(n.find("opt_jump").text)
opt_arrowshape = int(n.find('opt_arrowshape').text) opt_arrowshape = int(n.find("opt_arrowshape").text)
opt_filter = int(n.find('opt_filter').text) opt_filter = int(n.find("opt_filter").text)
opt_guideline = int(n.find('opt_guideline').text) opt_guideline = int(n.find("opt_guideline").text)
opt_gauge = int(n.find('opt_gauge').text) opt_gauge = int(n.find("opt_gauge").text)
opt_judgepriority = int(n.find('opt_judgepriority').text) opt_judgepriority = int(n.find("opt_judgepriority").text)
opt_timing = int(n.find('opt_timing').text) opt_timing = int(n.find("opt_timing").text)
db.table('ddr_scores').insert( db.table("ddr_scores").insert(
{ {
'timestamp': timestamp, "timestamp": timestamp,
'pcbid': pcbid, "pcbid": pcbid,
'shoparea': shoparea, "shoparea": shoparea,
'game_version': game_version, "game_version": game_version,
'ddr_id': ddr_id, "ddr_id": ddr_id,
'playstyle': playstyle, "playstyle": playstyle,
'mcode': mcode, "mcode": mcode,
'difficulty': difficulty, "difficulty": difficulty,
'rank': rank, "rank": rank,
'lamp': lamp, "lamp": lamp,
'score': score, "score": score,
'exscore': exscore, "exscore": exscore,
'maxcombo': maxcombo, "maxcombo": maxcombo,
'life': life, "life": life,
'fastcount': fastcount, "fastcount": fastcount,
'slowcount': slowcount, "slowcount": slowcount,
'judge_marvelous': judge_marvelous, "judge_marvelous": judge_marvelous,
'judge_perfect': judge_perfect, "judge_perfect": judge_perfect,
'judge_great': judge_great, "judge_great": judge_great,
'judge_good': judge_good, "judge_good": judge_good,
'judge_boo': judge_boo, "judge_boo": judge_boo,
'judge_miss': judge_miss, "judge_miss": judge_miss,
'judge_ok': judge_ok, "judge_ok": judge_ok,
'judge_ng': judge_ng, "judge_ng": judge_ng,
'calorie': calorie, "calorie": calorie,
'ghostsize': ghostsize, "ghostsize": ghostsize,
'ghost': ghost, "ghost": ghost,
'opt_speed': opt_speed, "opt_speed": opt_speed,
'opt_boost': opt_boost, "opt_boost": opt_boost,
'opt_appearance': opt_appearance, "opt_appearance": opt_appearance,
'opt_turn': opt_turn, "opt_turn": opt_turn,
'opt_dark': opt_dark, "opt_dark": opt_dark,
'opt_scroll': opt_scroll, "opt_scroll": opt_scroll,
'opt_arrowcolor': opt_arrowcolor, "opt_arrowcolor": opt_arrowcolor,
'opt_cut': opt_cut, "opt_cut": opt_cut,
'opt_freeze': opt_freeze, "opt_freeze": opt_freeze,
'opt_jump': opt_jump, "opt_jump": opt_jump,
'opt_arrowshape': opt_arrowshape, "opt_arrowshape": opt_arrowshape,
'opt_filter': opt_filter, "opt_filter": opt_filter,
'opt_guideline': opt_guideline, "opt_guideline": opt_guideline,
'opt_gauge': opt_gauge, "opt_gauge": opt_gauge,
'opt_judgepriority': opt_judgepriority, "opt_judgepriority": opt_judgepriority,
'opt_timing': opt_timing, "opt_timing": opt_timing,
}, },
) )
best = db.table('ddr_scores_best').get( best = db.table("ddr_scores_best").get(
(where('ddr_id') == ddr_id) (where("ddr_id") == ddr_id)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('mcode') == mcode) & (where("mcode") == mcode)
& (where('difficulty') == difficulty) & (where("difficulty") == difficulty)
) )
best = {} if best is None else best best = {} if best is None else best
best_score_data = { best_score_data = {
'game_version': game_version, "game_version": game_version,
'ddr_id': ddr_id, "ddr_id": ddr_id,
'playstyle': playstyle, "playstyle": playstyle,
'mcode': mcode, "mcode": mcode,
'difficulty': difficulty, "difficulty": difficulty,
'rank': min(rank, best.get('rank', rank)), "rank": min(rank, best.get("rank", rank)),
'lamp': max(lamp, best.get('lamp', lamp)), "lamp": max(lamp, best.get("lamp", lamp)),
'score': max(score, best.get('score', score)), "score": max(score, best.get("score", score)),
'exscore': max(exscore, best.get('exscore', exscore)), "exscore": max(exscore, best.get("exscore", exscore)),
} }
ghostid = db.table('ddr_scores').get( ghostid = db.table("ddr_scores").get(
(where('ddr_id') == ddr_id) (where("ddr_id") == ddr_id)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('mcode') == mcode) & (where("mcode") == mcode)
& (where('difficulty') == difficulty) & (where("difficulty") == difficulty)
& (where('score') == max(score, best.get('score', score))) & (where("score") == max(score, best.get("score", score)))
) )
best_score_data['ghostid'] = ghostid.doc_id best_score_data["ghostid"] = ghostid.doc_id
db.table('ddr_scores_best').upsert( db.table("ddr_scores_best").upsert(
best_score_data, best_score_data,
(where('ddr_id') == ddr_id) (where("ddr_id") == ddr_id)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('mcode') == mcode) & (where("mcode") == mcode)
& (where('difficulty') == difficulty) & (where("difficulty") == difficulty),
) )
elif int(data.find('isgameover').text) == 1: elif int(data.find("isgameover").text) == 1:
single_grade = int(data.find('grade/single_grade').text) single_grade = int(data.find("grade/single_grade").text)
double_grade = int(data.find('grade/double_grade').text) double_grade = int(data.find("grade/double_grade").text)
profile = get_profile(refid) profile = get_profile(refid)
game_profile = profile['version'].get(str(game_version), {}) game_profile = profile["version"].get(str(game_version), {})
# workaround to save the correct dan grade by using the course mcode # workaround to save the correct dan grade by using the course mcode
# because omnimix force unlocks all dan courses with <grade __type="u8">1</grade> in coursedb.xml # because omnimix force unlocks all dan courses with <grade __type="u8">1</grade> in coursedb.xml
if is_omni: if is_omni:
n = note[0] n = note[0]
mcode = int(n.find('mcode').text) mcode = int(n.find("mcode").text)
if int(n.find('clearkind').text) != 1: if int(n.find("clearkind").text) != 1:
for grade, course_id in enumerate(range(1000, 1011), start=1): for grade, course_id in enumerate(range(1000, 1011), start=1):
if playstyle == 0 and mcode in (course_id, course_id + 11): if playstyle == 0 and mcode in (course_id, course_id + 11):
single_grade = grade single_grade = grade
elif playstyle == 1 and mcode in (course_id + 1000, course_id + 1000 + 11): elif playstyle == 1 and mcode in (
course_id + 1000,
course_id + 1000 + 11,
):
double_grade = grade double_grade = grade
game_profile['single_grade'] = max(single_grade, game_profile.get('single_grade', single_grade)) game_profile["single_grade"] = max(
game_profile['double_grade'] = max(double_grade, game_profile.get('double_grade', double_grade)) single_grade, game_profile.get("single_grade", single_grade)
)
game_profile["double_grade"] = max(
double_grade, game_profile.get("double_grade", double_grade)
)
profile['version'][str(game_version)] = game_profile profile["version"][str(game_version)] = game_profile
db.table('ddr_profile').upsert(profile, where('card') == refid) db.table("ddr_profile").upsert(profile, where("card") == refid)
response = E.response( response = E.response(
E.playerdata_2( E.playerdata_2(
@ -353,124 +377,153 @@ async def usergamedata_advanced(request: Request):
) )
) )
elif mode == 'rivalload': elif mode == "rivalload":
loadflag = int(data.find('loadflag').text) loadflag = int(data.find("loadflag").text)
ddrcode = int(data.find('ddrcode').text) ddrcode = int(data.find("ddrcode").text)
pcbid = data.find('pcbid').text pcbid = data.find("pcbid").text
shoparea = data.find('shoparea').text shoparea = data.find("shoparea").text
if loadflag == 1: if loadflag == 1:
all_scores = {} all_scores = {}
for record in db.table('ddr_scores').search( for record in db.table("ddr_scores").search(
(where('game_version') == game_version) (where("game_version") == game_version)
& (where('pcbid') == pcbid) & (where("pcbid") == pcbid)
& (where('ddr_id') != 0) & (where("ddr_id") != 0)
): ):
ddr_id = record['ddr_id'] ddr_id = record["ddr_id"]
playstyle = record['playstyle'] playstyle = record["playstyle"]
mcode = record['mcode'] mcode = record["mcode"]
difficulty = record['difficulty'] difficulty = record["difficulty"]
score = record['score'] score = record["score"]
if (playstyle, mcode, difficulty) not in all_scores or score > all_scores[(playstyle, mcode, difficulty)].get("score"): if (
playstyle,
mcode,
difficulty,
) not in all_scores or score > all_scores[
(playstyle, mcode, difficulty)
].get(
"score"
):
all_scores[playstyle, mcode, difficulty] = { all_scores[playstyle, mcode, difficulty] = {
'game_version': game_version, "game_version": game_version,
'ddr_id': ddr_id, "ddr_id": ddr_id,
'playstyle': playstyle, "playstyle": playstyle,
'mcode': mcode, "mcode": mcode,
'difficulty': difficulty, "difficulty": difficulty,
'rank': record['rank'], "rank": record["rank"],
'lamp': record['lamp'], "lamp": record["lamp"],
'score': score, "score": score,
'exscore': record['exscore'], "exscore": record["exscore"],
'ghostid': record.doc_id "ghostid": record.doc_id,
} }
scores = list(all_scores.values()) scores = list(all_scores.values())
elif loadflag == 2: elif loadflag == 2:
all_scores = {} all_scores = {}
for record in db.table('ddr_scores').search( for record in db.table("ddr_scores").search(
(where('game_version') == game_version) (where("game_version") == game_version)
& (where('shoparea') == shoparea) & (where("shoparea") == shoparea)
& (where('ddr_id') != 0) & (where("ddr_id") != 0)
): ):
ddr_id = record['ddr_id'] ddr_id = record["ddr_id"]
playstyle = record['playstyle'] playstyle = record["playstyle"]
mcode = record['mcode'] mcode = record["mcode"]
difficulty = record['difficulty'] difficulty = record["difficulty"]
score = record['score'] score = record["score"]
if (playstyle, mcode, difficulty) not in all_scores or score > all_scores[(playstyle, mcode, difficulty)].get("score"): if (
playstyle,
mcode,
difficulty,
) not in all_scores or score > all_scores[
(playstyle, mcode, difficulty)
].get(
"score"
):
all_scores[playstyle, mcode, difficulty] = { all_scores[playstyle, mcode, difficulty] = {
'game_version': game_version, "game_version": game_version,
'ddr_id': ddr_id, "ddr_id": ddr_id,
'playstyle': playstyle, "playstyle": playstyle,
'mcode': mcode, "mcode": mcode,
'difficulty': difficulty, "difficulty": difficulty,
'rank': record['rank'], "rank": record["rank"],
'lamp': record['lamp'], "lamp": record["lamp"],
'score': score, "score": score,
'exscore': record['exscore'], "exscore": record["exscore"],
'ghostid': record.doc_id "ghostid": record.doc_id,
} }
scores = list(all_scores.values()) scores = list(all_scores.values())
elif loadflag == 4: elif loadflag == 4:
all_scores = {} all_scores = {}
for record in db.table('ddr_scores').search((where('game_version') == game_version) & (where('ddr_id') != 0)): for record in db.table("ddr_scores").search(
ddr_id = record['ddr_id'] (where("game_version") == game_version) & (where("ddr_id") != 0)
playstyle = record['playstyle'] ):
mcode = record['mcode'] ddr_id = record["ddr_id"]
difficulty = record['difficulty'] playstyle = record["playstyle"]
score = record['score'] mcode = record["mcode"]
difficulty = record["difficulty"]
score = record["score"]
if (playstyle, mcode, difficulty) not in all_scores or score > all_scores[(playstyle, mcode, difficulty)].get("score"): if (
playstyle,
mcode,
difficulty,
) not in all_scores or score > all_scores[
(playstyle, mcode, difficulty)
].get(
"score"
):
all_scores[playstyle, mcode, difficulty] = { all_scores[playstyle, mcode, difficulty] = {
'game_version': game_version, "game_version": game_version,
'ddr_id': ddr_id, "ddr_id": ddr_id,
'playstyle': playstyle, "playstyle": playstyle,
'mcode': mcode, "mcode": mcode,
'difficulty': difficulty, "difficulty": difficulty,
'rank': record['rank'], "rank": record["rank"],
'lamp': record['lamp'], "lamp": record["lamp"],
'score': score, "score": score,
'exscore': record['exscore'], "exscore": record["exscore"],
'ghostid': record.doc_id "ghostid": record.doc_id,
} }
scores = list(all_scores.values()) scores = list(all_scores.values())
elif loadflag in (8, 16, 32): elif loadflag in (8, 16, 32):
scores = [] scores = []
for s in db.table('ddr_scores_best').search(where('ddr_id') == ddrcode): for s in db.table("ddr_scores_best").search(where("ddr_id") == ddrcode):
scores.append(s) scores.append(s)
load = [] load = []
for r in scores: for r in scores:
s = [ s = [
r['mcode'], r["mcode"],
r['difficulty'], r["difficulty"],
r['rank'], r["rank"],
r['lamp'], r["lamp"],
get_common(r['ddr_id'], game_version, 27), get_common(r["ddr_id"], game_version, 27),
int(get_common(r['ddr_id'], game_version, 3), 16), int(get_common(r["ddr_id"], game_version, 3), 16),
r['ddr_id'], r["ddr_id"],
r['score'], r["score"],
r['ghostid'], r["ghostid"],
] ]
load.append(b64encode(str.encode(','.join(str(x) for x in s))).decode()) load.append(b64encode(str.encode(",".join(str(x) for x in s))).decode())
response = E.response( response = E.response(
E.playerdata_2( E.playerdata_2(
E.result(0, __type="s32"), E.result(0, __type="s32"),
E.data( E.data(
*[E.record( *[
E.record_csv(s, __type="str"), E.record(
) for s in load] E.record_csv(s, __type="str"),
) )
for s in load
]
),
) )
) )
elif mode == 'inheritance': elif mode == "inheritance":
response = E.response( response = E.response(
E.playerdata_2( E.playerdata_2(
E.result(0, __type="s32"), E.result(0, __type="s32"),
@ -489,50 +542,87 @@ async def usergamedata_advanced(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/playerdata_2/usergamedata_recv') @router.post("/{gameinfo}/playerdata_2/usergamedata_recv")
async def usergamedata_recv(request: Request): async def usergamedata_recv(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
data = request_info['root'][0].find('data') data = request_info["root"][0].find("data")
cid = data.find('refid').text cid = data.find("refid").text
profile = get_game_profile(cid, game_version) profile = get_game_profile(cid, game_version)
db = get_db().table('ddr_profile') db = get_db().table("ddr_profile")
all_profiles_for_card = db.get(Query().card == cid) all_profiles_for_card = db.get(Query().card == cid)
if all_profiles_for_card is None: if all_profiles_for_card is None:
load = [ load = [
b64encode(str.encode('1,d,1111111,1,0,0,0,0,0,ffffffffffffffff,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,1010-1010,,,,,,').decode()), b64encode(
b64encode(str.encode('0,3,0,0,0,0,0,3,0,0,0,0,1,2,0,0,0,10.000000,10.000000,10.000000,10.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,').decode()), str.encode(
b64encode(str.encode('1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,').decode()), "1,d,1111111,1,0,0,0,0,0,ffffffffffffffff,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,1010-1010,,,,,,"
b64encode(str.encode('0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,').decode()), ).decode()
),
b64encode(
str.encode(
"0,3,0,0,0,0,0,3,0,0,0,0,1,2,0,0,0,10.000000,10.000000,10.000000,10.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,"
).decode()
),
b64encode(
str.encode(
"1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,"
).decode()
),
b64encode(
str.encode(
"0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,,,,,,,,"
).decode()
),
] ]
else: else:
calories_disp = ["Off", "On"] calories_disp = ["Off", "On"]
character = ["All Character Random", "Man Random", "Female Random", "Yuni", "Rage", "Afro", "Jenny", "Emi", "Baby-Lon", "Gus", "Ruby", "Alice", "Julio", "Bonnie", "Zero", "Rinon"] character = [
"All Character Random",
"Man Random",
"Female Random",
"Yuni",
"Rage",
"Afro",
"Jenny",
"Emi",
"Baby-Lon",
"Gus",
"Ruby",
"Alice",
"Julio",
"Bonnie",
"Zero",
"Rinon",
]
arrow_skin = ["Normal", "X", "Classic", "Cyber", "Medium", "Small", "Dot"] arrow_skin = ["Normal", "X", "Classic", "Cyber", "Medium", "Small", "Dot"]
screen_filter = ["Off", "Dark", "Darker", "Darkest"] screen_filter = ["Off", "Dark", "Darker", "Darkest"]
guideline = ["Off", "Border", "Center"] guideline = ["Off", "Border", "Center"]
priority = ["Judgment", "Arrow"] priority = ["Judgment", "Arrow"]
timing_disp = ["Off", "On"] timing_disp = ["Off", "On"]
common = profile['common'].split(',') common = profile["common"].split(",")
common[5] = calories_disp.index(profile['calories_disp']) common[5] = calories_disp.index(profile["calories_disp"])
common[6] = character.index(profile['character']) common[6] = character.index(profile["character"])
common[9] = 1 # Mobile link common[9] = 1 # Mobile link
common_load = ",".join([str(i) for i in common]) common_load = ",".join([str(i) for i in common])
option = profile['option'].split(',') option = profile["option"].split(",")
option[13] = arrow_skin.index(profile['arrow_skin']) option[13] = arrow_skin.index(profile["arrow_skin"])
option[14] = screen_filter.index(profile['filter']) option[14] = screen_filter.index(profile["filter"])
option[15] = guideline.index(profile['guideline']) option[15] = guideline.index(profile["guideline"])
option[17] = priority.index(profile['priority']) option[17] = priority.index(profile["priority"])
option[18] = timing_disp.index(profile['timing_disp']) option[18] = timing_disp.index(profile["timing_disp"])
option_load = ",".join([str(i) for i in option]) option_load = ",".join([str(i) for i in option])
rival = profile['rival'].split(',') rival = profile["rival"].split(",")
rival_ids = [profile.get('rival_1_ddr_id', 0), profile.get('rival_2_ddr_id', 0), profile.get('rival_3_ddr_id', 0)] rival_ids = [
profile.get("rival_1_ddr_id", 0),
profile.get("rival_2_ddr_id", 0),
profile.get("rival_3_ddr_id", 0),
]
for idx, r in enumerate(rival_ids, start=3): for idx, r in enumerate(rival_ids, start=3):
if r != 0: if r != 0:
rival[idx] = idx - 2 rival[idx] = idx - 2
@ -540,10 +630,10 @@ async def usergamedata_recv(request: Request):
rival_load = ",".join([str(i) for i in rival]) rival_load = ",".join([str(i) for i in rival])
load = [ load = [
b64encode(str.encode(common_load.split('ffffffff,COMMON,')[1])).decode(), b64encode(str.encode(common_load.split("ffffffff,COMMON,")[1])).decode(),
b64encode(str.encode(option_load.split('ffffffff,OPTION,')[1])).decode(), b64encode(str.encode(option_load.split("ffffffff,OPTION,")[1])).decode(),
b64encode(str.encode(profile['last'].split('ffffffff,LAST,')[1])).decode(), b64encode(str.encode(profile["last"].split("ffffffff,LAST,")[1])).decode(),
b64encode(str.encode(rival_load.split('ffffffff,RIVAL,')[1])).decode() b64encode(str.encode(rival_load.split("ffffffff,RIVAL,")[1])).decode(),
] ]
response = E.response( response = E.response(
@ -551,7 +641,7 @@ async def usergamedata_recv(request: Request):
E.result(0, __type="s32"), E.result(0, __type="s32"),
E.player( E.player(
E.record( E.record(
*[E.d(p, __type="str")for p in load], *[E.d(p, __type="str") for p in load],
), ),
E.record_num(4, __type="u32"), E.record_num(4, __type="u32"),
), ),
@ -562,33 +652,43 @@ async def usergamedata_recv(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/playerdata_2/usergamedata_send') @router.post("/{gameinfo}/playerdata_2/usergamedata_send")
async def usergamedata_send(request: Request): async def usergamedata_send(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
data = request_info['root'][0].find('data') data = request_info["root"][0].find("data")
cid = data.find('refid').text cid = data.find("refid").text
num = int(data.find('datanum').text) num = int(data.find("datanum").text)
profile = get_profile(cid) profile = get_profile(cid)
game_profile = profile['version'].get(str(game_version), {}) game_profile = profile["version"].get(str(game_version), {})
if num == 1: if num == 1:
game_profile['common'] = b64decode(data.find('record')[0].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore') game_profile["common"] = b64decode(
data.find("record")[0].text.split("<bin1")[0]
).decode(encoding="utf-8", errors="ignore")
elif num == 4: elif num == 4:
game_profile['common'] = b64decode(data.find('record')[0].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore') game_profile["common"] = b64decode(
game_profile['option'] = b64decode(data.find('record')[1].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore') data.find("record")[0].text.split("<bin1")[0]
game_profile['last'] = b64decode(data.find('record')[2].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore') ).decode(encoding="utf-8", errors="ignore")
game_profile['rival'] = b64decode(data.find('record')[3].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore') game_profile["option"] = b64decode(
for r in ('rival_1_ddr_id', 'rival_2_ddr_id', 'rival_3_ddr_id'): data.find("record")[1].text.split("<bin1")[0]
).decode(encoding="utf-8", errors="ignore")
game_profile["last"] = b64decode(
data.find("record")[2].text.split("<bin1")[0]
).decode(encoding="utf-8", errors="ignore")
game_profile["rival"] = b64decode(
data.find("record")[3].text.split("<bin1")[0]
).decode(encoding="utf-8", errors="ignore")
for r in ("rival_1_ddr_id", "rival_2_ddr_id", "rival_3_ddr_id"):
if r not in game_profile: if r not in game_profile:
game_profile[r] = 0 game_profile[r] = 0
profile['version'][str(game_version)] = game_profile profile["version"][str(game_version)] = game_profile
get_db().table('ddr_profile').upsert(profile, where('card') == cid) get_db().table("ddr_profile").upsert(profile, where("card") == cid)
response = E.response( response = E.response(
E.playerdata_2( E.playerdata_2(

View File

@ -8,10 +8,10 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["MDX"] router.model_whitelist = ["MDX"]
@router.post('/{gameinfo}/system/convcardnumber') @router.post("/{gameinfo}/system/convcardnumber")
async def system_convcardnumber(request: Request): async def system_convcardnumber(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
cid = request_info['root'][0].find('data/card_id').text cid = request_info["root"][0].find("data/card_id").text
response = E.response( response = E.response(
E.system( E.system(

View File

@ -8,10 +8,10 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["MDX"] router.model_whitelist = ["MDX"]
@router.post('/{gameinfo}/system_2/convcardnumber') @router.post("/{gameinfo}/system_2/convcardnumber")
async def system_2_convcardnumber(request: Request): async def system_2_convcardnumber(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
cid = request_info['root'][0].find('data/card_id').text cid = request_info["root"][0].find("data/card_id").text
response = E.response( response = E.response(
E.system_2( E.system_2(

View File

@ -6,7 +6,7 @@ router = APIRouter(prefix="/local", tags=["local"])
router.model_whitelist = ["MDX"] router.model_whitelist = ["MDX"]
@router.post('/{gameinfo}/tax/get_phase') @router.post("/{gameinfo}/tax/get_phase")
async def tax_get_phase(request: Request): async def tax_get_phase(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)

View File

@ -8,11 +8,11 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["LDJ"] router.model_whitelist = ["LDJ"]
@router.post('/{gameinfo}/IIDX29gameSystem/systemInfo') @router.post("/{gameinfo}/IIDX29gameSystem/systemInfo")
async def iidx29gamesystem_systeminfo(request: Request): async def iidx29gamesystem_systeminfo(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
unlock = () #(28008, 28065, 28073, 28088, 28089, 29027, 29094, 29095) unlock = () # (28008, 28065, 28073, 28088, 28089, 29027, 29094, 29095)
sp_dp = (0, 1) sp_dp = (0, 1)
response = E.response( response = E.response(
@ -30,46 +30,64 @@ async def iidx29gamesystem_systeminfo(request: Request):
E.isEiseiOpenFlg(val=1), E.isEiseiOpenFlg(val=1),
E.WorldTourismOpenList(val=1), E.WorldTourismOpenList(val=1),
E.BPLBattleOpenPhase(val=2), E.BPLBattleOpenPhase(val=2),
*[E.music_open( *[
E.music_id(s, __type="s32"), E.music_open(
E.kind(0, __type="s32"), E.music_id(s, __type="s32"),
) for s in unlock], E.kind(0, __type="s32"),
*[E.arena_reward( )
E.index(unlock.index(s), __type="s32"), for s in unlock
E.cube_num((unlock.index(s) + 1) * 50, __type="s32"), ],
E.kind(0, __type="s32"), *[
E.value(s, __type="str"), E.arena_reward(
) for s in unlock], E.index(unlock.index(s), __type="s32"),
*[E.arena_music_difficult( E.cube_num((unlock.index(s) + 1) * 50, __type="s32"),
E.play_style(s, __type="s32"), E.kind(0, __type="s32"),
E.arena_class(-1, __type="s32"), E.value(s, __type="str"),
E.low_difficult(1, __type="s32"), )
E.high_difficult(12, __type="s32"), for s in unlock
E.is_leggendaria(1, __type="bool"), ],
E.force_music_list_id(0, __type="s32"), *[
) for s in sp_dp], E.arena_music_difficult(
*[E.arena_cpu_define( E.play_style(s, __type="s32"),
E.play_style(s, __type="s32"), E.arena_class(-1, __type="s32"),
E.arena_class(-1, __type="s32"), E.low_difficult(1, __type="s32"),
E.grade_id(18, __type="s32"), E.high_difficult(12, __type="s32"),
E.low_music_difficult(8, __type="s32"), E.is_leggendaria(1, __type="bool"),
E.high_music_difficult(12, __type="s32"), E.force_music_list_id(0, __type="s32"),
E.is_leggendaria(0, __type="bool"), )
) for s in sp_dp], for s in sp_dp
*[E.maching_class_range( ],
E.play_style(s[0], __type="s32"), *[
E.matching_class(s[1], __type="s32"), E.arena_cpu_define(
E.low_arena_class(0, __type="s32"), E.play_style(s, __type="s32"),
E.high_arena_class(19, __type="s32"), E.arena_class(-1, __type="s32"),
) for s in ((0, 2), (0, 1), (1, 2), (1, 1))], E.grade_id(18, __type="s32"),
*[E.arena_force_music( E.low_music_difficult(8, __type="s32"),
E.play_style(s, __type="s32"), E.high_music_difficult(12, __type="s32"),
E.force_music_list_id(0, __type="s32"), E.is_leggendaria(0, __type="bool"),
E.index(0, __type="s32"), )
E.music_id(1000, __type="s32"), for s in sp_dp
E.note_grade(0, __type="s32"), ],
E.is_active(s, __type="bool"), *[
) for s in sp_dp], E.maching_class_range(
E.play_style(s[0], __type="s32"),
E.matching_class(s[1], __type="s32"),
E.low_arena_class(0, __type="s32"),
E.high_arena_class(19, __type="s32"),
)
for s in ((0, 2), (0, 1), (1, 2), (1, 1))
],
*[
E.arena_force_music(
E.play_style(s, __type="s32"),
E.force_music_list_id(0, __type="s32"),
E.index(0, __type="s32"),
E.music_id(1000, __type="s32"),
E.note_grade(0, __type="s32"),
E.is_active(s, __type="bool"),
)
for s in sp_dp
],
) )
) )

View File

@ -10,113 +10,101 @@ from core_database import get_db
router = APIRouter(prefix="/local2", tags=["local2"]) router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["LDJ"] router.model_whitelist = ["LDJ"]
def get_profile(iidx_id):
return get_db().table('iidx_profile').get(
where('iidx_id') == iidx_id
)
@router.post('/{gameinfo}/IIDX29grade/raised') 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): async def iidx29grade_raised(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
timestamp = time.time() timestamp = time.time()
iidx_id = int(request_info['root'][0].attrib['iidxid']) iidx_id = int(request_info["root"][0].attrib["iidxid"])
achi = int(request_info['root'][0].attrib['achi']) achi = int(request_info["root"][0].attrib["achi"])
cstage = int(request_info['root'][0].attrib['cstage']) cstage = int(request_info["root"][0].attrib["cstage"])
gid = int(request_info['root'][0].attrib['gid']) gid = int(request_info["root"][0].attrib["gid"])
gtype = int(request_info['root'][0].attrib['gtype']) gtype = int(request_info["root"][0].attrib["gtype"])
is_ex = int(request_info['root'][0].attrib['is_ex']) is_ex = int(request_info["root"][0].attrib["is_ex"])
is_mirror = int(request_info['root'][0].attrib['is_mirror']) is_mirror = int(request_info["root"][0].attrib["is_mirror"])
db = get_db() db = get_db()
db.table('iidx_class').insert( db.table("iidx_class").insert(
{ {
'timestamp': timestamp, "timestamp": timestamp,
'game_version': game_version, "game_version": game_version,
'iidx_id': iidx_id, "iidx_id": iidx_id,
'achi': achi, "achi": achi,
'cstage': cstage, "cstage": cstage,
'gid': gid, "gid": gid,
'gtype': gtype, "gtype": gtype,
'is_ex': is_ex, "is_ex": is_ex,
'is_mirror': is_mirror, "is_mirror": is_mirror,
}, },
) )
profile = get_profile(iidx_id) profile = get_profile(iidx_id)
game_profile = profile['version'].get(str(game_version), {}) game_profile = profile["version"].get(str(game_version), {})
best_class = db.table('iidx_class_best').get( best_class = db.table("iidx_class_best").get(
(where('iidx_id') == iidx_id) (where("iidx_id") == iidx_id)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('gid') == gid) & (where("gid") == gid)
& (where('gtype') == gtype) & (where("gtype") == gtype)
) )
best_class = {} if best_class is None else best_class best_class = {} if best_class is None else best_class
best_class_data = { best_class_data = {
'game_version': game_version, "game_version": game_version,
'iidx_id': iidx_id, "iidx_id": iidx_id,
'achi': max(achi, best_class.get('achi', achi)), "achi": max(achi, best_class.get("achi", achi)),
'cstage': max(cstage, best_class.get('cstage', cstage)), "cstage": max(cstage, best_class.get("cstage", cstage)),
'gid': gid, "gid": gid,
'gtype': gtype, "gtype": gtype,
'is_ex': is_ex, "is_ex": is_ex,
'is_mirror': is_mirror, "is_mirror": is_mirror,
} }
db.table('iidx_class_best').upsert( db.table("iidx_class_best").upsert(
best_class_data, best_class_data,
(where('iidx_id') == iidx_id) (where("iidx_id") == iidx_id)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('gid') == gid) & (where("gid") == gid)
& (where('gtype') == gtype) & (where("gtype") == gtype),
) )
best_class_plays = db.table('iidx_class_best').search( best_class_plays = db.table("iidx_class_best").search(
(where('game_version') == game_version) (where("game_version") == game_version) & (where("iidx_id") == iidx_id)
& (where('iidx_id') == iidx_id)
) )
grades = [] grades = []
for record in best_class_plays: for record in best_class_plays:
grades.append([ grades.append(
record['gtype'], [record["gtype"], record["gid"], record["cstage"], record["achi"]]
record['gid'],
record['cstage'],
record['achi']
])
game_profile['grade_values'] = grades
grade_sp = db.table('iidx_class_best').search(
(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('iidx_id') == iidx_id)
& (where('gtype') == 1)
& (where('cstage') == 4)
)
game_profile['grade_double'] = max([x['gid'] for x in grade_dp], default=-1)
profile['version'][str(game_version)] = game_profile
db.table('iidx_profile').upsert(profile, where('game_version') == game_version)
response = E.response(
E.IIDX29grade(
pnum=1
) )
game_profile["grade_values"] = grades
grade_sp = db.table("iidx_class_best").search(
(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("iidx_id") == iidx_id) & (where("gtype") == 1) & (where("cstage") == 4)
)
game_profile["grade_double"] = max([x["gid"] for x in grade_dp], default=-1)
profile["version"][str(game_version)] = game_profile
db.table("iidx_profile").upsert(profile, where("game_version") == game_version)
response = E.response(E.IIDX29grade(pnum=1))
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

View File

@ -8,68 +8,61 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["LDJ"] router.model_whitelist = ["LDJ"]
@router.post('/{gameinfo}/IIDX29lobby/entry') @router.post("/{gameinfo}/IIDX29lobby/entry")
async def iidx29lobby_entry(request: Request): async def iidx29lobby_entry(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX29lobby())
E.IIDX29lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29lobby/update')
@router.post("/{gameinfo}/IIDX29lobby/update")
async def iidx29lobby_update(request: Request): async def iidx29lobby_update(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX29lobby())
E.IIDX29lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29lobby/delete')
@router.post("/{gameinfo}/IIDX29lobby/delete")
async def iidx29lobby_delete(request: Request): async def iidx29lobby_delete(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX29lobby())
E.IIDX29lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29lobby/bplbattle_entry')
@router.post("/{gameinfo}/IIDX29lobby/bplbattle_entry")
async def iidx29lobby_bplbattle_entry(request: Request): async def iidx29lobby_bplbattle_entry(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX29lobby())
E.IIDX29lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29lobby/bplbattle_update')
@router.post("/{gameinfo}/IIDX29lobby/bplbattle_update")
async def iidx29lobby_bplbattle_update(request: Request): async def iidx29lobby_bplbattle_update(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX29lobby())
E.IIDX29lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29lobby/bplbattle_delete')
@router.post("/{gameinfo}/IIDX29lobby/bplbattle_delete")
async def iidx29lobby_bplbattle_delete(request: Request): async def iidx29lobby_bplbattle_delete(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX29lobby())
E.IIDX29lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

View File

@ -9,8 +9,8 @@ from core_database import get_db
import config import config
router = APIRouter(prefix='/local2', tags=['local2']) router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ['LDJ'] router.model_whitelist = ["LDJ"]
class ClearFlags(IntEnum): class ClearFlags(IntEnum):
@ -24,22 +24,22 @@ class ClearFlags(IntEnum):
FULL_COMBO = 7 FULL_COMBO = 7
@router.post('/{gameinfo}/IIDX29music/getrank') @router.post("/{gameinfo}/IIDX29music/getrank")
async def iidx29music_getrank(request: Request): async def iidx29music_getrank(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
root = request_info['root'][0] root = request_info["root"][0]
play_style = int(root.attrib['cltype']) play_style = int(root.attrib["cltype"])
requested_ids = [ requested_ids = [
int(root.get('iidxid', 0)), int(root.get("iidxid", 0)),
int(root.get('iidxid0', 0)), int(root.get("iidxid0", 0)),
int(root.get('iidxid1', 0)), int(root.get("iidxid1", 0)),
int(root.get('iidxid2', 0)), int(root.get("iidxid2", 0)),
int(root.get('iidxid3', 0)), int(root.get("iidxid3", 0)),
int(root.get('iidxid4', 0)), int(root.get("iidxid4", 0)),
] ]
all_scores = {} all_scores = {}
@ -49,323 +49,348 @@ async def iidx29music_getrank(request: Request):
if iidxid == 0: if iidxid == 0:
continue continue
profile = db.table('iidx_profile').get(where('iidx_id') == iidxid)['version'][str(game_version)] profile = db.table("iidx_profile").get(where("iidx_id") == iidxid)["version"][
str(game_version)
]
for record in db.table('iidx_scores_best').search( for record in db.table("iidx_scores_best").search(
(where('music_id') < (game_version + 1) * 1000) (where("music_id") < (game_version + 1) * 1000)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('iidx_id') == iidxid) & (where("iidx_id") == iidxid)
): ):
music_id = record['music_id'] music_id = record["music_id"]
clear_flg = record['clear_flg'] clear_flg = record["clear_flg"]
ex_score = record['ex_score'] ex_score = record["ex_score"]
miss_count = record['miss_count'] miss_count = record["miss_count"]
chart_id = record['chart_id'] chart_id = record["chart_id"]
if (rival_idx, music_id) not in all_scores: if (rival_idx, music_id) not in all_scores:
all_scores[rival_idx, music_id] = { all_scores[rival_idx, music_id] = {
0: {'clear_flg': -1, 'ex_score': -1, 'miss_count': -1}, 0: {"clear_flg": -1, "ex_score": -1, "miss_count": -1},
1: {'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}, 2: {"clear_flg": -1, "ex_score": -1, "miss_count": -1},
3: {'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}, 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]["clear_flg"] = clear_flg
all_scores[rival_idx, music_id][chart_id]['ex_score'] = ex_score all_scores[rival_idx, music_id][chart_id]["ex_score"] = ex_score
all_scores[rival_idx, music_id][chart_id]['miss_count'] = miss_count all_scores[rival_idx, music_id][chart_id]["miss_count"] = miss_count
top_scores = {} top_scores = {}
for record in db.table('iidx_scores_best').search( for record in db.table("iidx_scores_best").search(
(where('music_id') < (game_version + 1) * 1000) (where("music_id") < (game_version + 1) * 1000)
& (where('play_style') == play_style) & (where("play_style") == play_style)
): ):
music_id = record['music_id'] music_id = record["music_id"]
ex_score = record['ex_score'] ex_score = record["ex_score"]
chart_id = record['chart_id'] chart_id = record["chart_id"]
iidx_id = record['iidx_id'] iidx_id = record["iidx_id"]
if music_id not in top_scores: if music_id not in top_scores:
top_scores[music_id] = { top_scores[music_id] = {
0: {'djname': "", 'clear_flg': -1, 'ex_score': -1}, 0: {"djname": "", "clear_flg": -1, "ex_score": -1},
1: {'djname': "", 'clear_flg': -1, 'ex_score': -1}, 1: {"djname": "", "clear_flg": -1, "ex_score": -1},
2: {'djname': "", 'clear_flg': -1, 'ex_score': -1}, 2: {"djname": "", "clear_flg": -1, "ex_score": -1},
3: {'djname': "", 'clear_flg': -1, 'ex_score': -1}, 3: {"djname": "", "clear_flg": -1, "ex_score": -1},
4: {'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']: if ex_score > top_scores[music_id][chart_id]["ex_score"]:
top_name = db.table('iidx_profile').get(where('iidx_id') == iidx_id)['version'][str(game_version)]['djname'] top_name = db.table("iidx_profile").get(where("iidx_id") == iidx_id)[
top_scores[music_id][chart_id]['djname'] = top_name "version"
top_scores[music_id][chart_id]['clear_flg'] = 1 ][str(game_version)]["djname"]
top_scores[music_id][chart_id]['ex_score'] = ex_score top_scores[music_id][chart_id]["djname"] = top_name
top_scores[music_id][chart_id]["clear_flg"] = 1
top_scores[music_id][chart_id]["ex_score"] = ex_score
response = E.response( response = E.response(
E.IIDX29music( E.IIDX29music(
E.style(type=play_style), E.style(type=play_style),
*[E.m([ *[
i, E.m(
k, [
*[all_scores[i, k][d]['clear_flg'] for d in range(5)], i,
*[all_scores[i, k][d]['ex_score'] for d in range(5)], k,
*[all_scores[i, k][d]['miss_count'] for d in range(5)], *[all_scores[i, k][d]["clear_flg"] for d in range(5)],
], __type='s16') for i, k in all_scores], *[all_scores[i, k][d]["ex_score"] for d in range(5)],
*[E.top( *[all_scores[i, k][d]["miss_count"] for d in range(5)],
E.detail([ ],
k, __type="s16",
*[top_scores[k][d]['clear_flg'] for d in range(5)], )
*[top_scores[k][d]['ex_score'] for d in range(5)], for i, k in all_scores
], __type='s16'), ],
name0=top_scores[k][0]['djname'], *[
name1=top_scores[k][1]['djname'], E.top(
name2=top_scores[k][2]['djname'], E.detail(
name3=top_scores[k][3]['djname'], [
name4=top_scores[k][4]['djname'] k,
) for k in top_scores] *[top_scores[k][d]["clear_flg"] for d in range(5)],
*[top_scores[k][d]["ex_score"] for d in range(5)],
],
__type="s16",
),
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) assert response is not None
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29music/crate') @router.post("/{gameinfo}/IIDX29music/crate")
async def iidx29music_crate(request: Request): async def iidx29music_crate(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
db = get_db() db = get_db()
all_score_stats = db.table('iidx_score_stats').search( all_score_stats = db.table("iidx_score_stats").search(
(where('music_id') < (game_version + 1) * 1000) (where("music_id") < (game_version + 1) * 1000)
) )
crate = {} crate = {}
fcrate = {} fcrate = {}
for stat in all_score_stats: for stat in all_score_stats:
if stat['music_id'] not in crate: if stat["music_id"] not in crate:
crate[stat['music_id']] = [1001] * 10 crate[stat["music_id"]] = [1001] * 10
if stat['music_id'] not in fcrate: if stat["music_id"] not in fcrate:
fcrate[stat['music_id']] = [1001] * 10 fcrate[stat["music_id"]] = [1001] * 10
if stat['play_style'] == 1: if stat["play_style"] == 1:
dp_idx = 5 dp_idx = 5
else: else:
dp_idx = 0 dp_idx = 0
crate[stat['music_id']][stat['chart_id'] + dp_idx] = int(stat['clear_rate']) 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']) fcrate[stat["music_id"]][stat["chart_id"] + dp_idx] = int(stat["fc_rate"])
response = E.response( response = E.response(
E.IIDX29music( E.IIDX29music(*[E.c(crate[k] + fcrate[k], mid=k, __type="s32") for k in crate])
*[E.c(crate[k] + fcrate[k], mid=k, __type="s32") for k in crate]
)
) )
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29music/reg') @router.post("/{gameinfo}/IIDX29music/reg")
async def iidx29music_reg(request: Request): async def iidx29music_reg(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
timestamp = time.time() timestamp = time.time()
log = request_info['root'][0].find('music_play_log') log = request_info["root"][0].find("music_play_log")
clear_flg = int(request_info['root'][0].attrib['cflg']) clear_flg = int(request_info["root"][0].attrib["cflg"])
clid = int(request_info['root'][0].attrib['clid']) clid = int(request_info["root"][0].attrib["clid"])
is_death = int(request_info['root'][0].attrib['is_death']) is_death = int(request_info["root"][0].attrib["is_death"])
pid = int(request_info['root'][0].attrib['pid']) pid = int(request_info["root"][0].attrib["pid"])
play_style = int(log.attrib['play_style']) play_style = int(log.attrib["play_style"])
ex_score = int(log.attrib['ex_score']) ex_score = int(log.attrib["ex_score"])
folder_type = int(log.attrib['folder_type']) folder_type = int(log.attrib["folder_type"])
gauge_type = int(log.attrib['gauge_type']) gauge_type = int(log.attrib["gauge_type"])
graph_type = int(log.attrib['graph_type']) graph_type = int(log.attrib["graph_type"])
great_num = int(log.attrib['great_num']) great_num = int(log.attrib["great_num"])
iidx_id = int(log.attrib['iidx_id']) iidx_id = int(log.attrib["iidx_id"])
miss_num = int(log.attrib['miss_num']) miss_num = int(log.attrib["miss_num"])
mode_type = int(log.attrib['mode_type']) mode_type = int(log.attrib["mode_type"])
music_id = int(log.attrib['music_id']) music_id = int(log.attrib["music_id"])
note_id = int(log.attrib['note_id']) note_id = int(log.attrib["note_id"])
option1 = int(log.attrib['option1']) option1 = int(log.attrib["option1"])
option2 = int(log.attrib['option2']) option2 = int(log.attrib["option2"])
pgreat_num = int(log.attrib['pgreat_num']) pgreat_num = int(log.attrib["pgreat_num"])
ghost = log.find("ghost").text ghost = log.find("ghost").text
ghost_gauge = log.find("ghost_gauge").text ghost_gauge = log.find("ghost_gauge").text
db = get_db() db = get_db()
db.table('iidx_scores').insert( db.table("iidx_scores").insert(
{ {
'timestamp': timestamp, "timestamp": timestamp,
'game_version': game_version, "game_version": game_version,
'iidx_id': iidx_id, "iidx_id": iidx_id,
'pid': pid, "pid": pid,
'clear_flg': clear_flg, "clear_flg": clear_flg,
'is_death': is_death, "is_death": is_death,
'music_id': music_id, "music_id": music_id,
'play_style': play_style, "play_style": play_style,
'chart_id': note_id, "chart_id": note_id,
'pgreat_num': pgreat_num, "pgreat_num": pgreat_num,
'great_num': great_num, "great_num": great_num,
'ex_score': ex_score, "ex_score": ex_score,
'miss_count': miss_num, "miss_count": miss_num,
'folder_type': folder_type, "folder_type": folder_type,
'gauge_type': gauge_type, "gauge_type": gauge_type,
'graph_type': graph_type, "graph_type": graph_type,
'mode_type': mode_type, "mode_type": mode_type,
'option1': option1, "option1": option1,
'option2': option2, "option2": option2,
'ghost': ghost, "ghost": ghost,
'ghost_gauge': ghost_gauge, "ghost_gauge": ghost_gauge,
}, },
) )
best_score = db.table('iidx_scores_best').get( best_score = db.table("iidx_scores_best").get(
(where('iidx_id') == iidx_id) (where("iidx_id") == iidx_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == note_id) & (where("chart_id") == note_id)
) )
best_score = {} if best_score is None else best_score best_score = {} if best_score is None else best_score
if clear_flg < ClearFlags.EASY_CLEAR: if clear_flg < ClearFlags.EASY_CLEAR:
miss_num = -1 miss_num = -1
best_miss_count = best_score.get('miss_count', miss_num) best_miss_count = best_score.get("miss_count", miss_num)
if best_miss_count == -1: if best_miss_count == -1:
miss_count = max(miss_num, best_miss_count) miss_count = max(miss_num, best_miss_count)
elif clear_flg > ClearFlags.ASSIST_CLEAR: elif clear_flg > ClearFlags.ASSIST_CLEAR:
miss_count = min(miss_num, best_miss_count) miss_count = min(miss_num, best_miss_count)
else: else:
miss_count = best_miss_count miss_count = best_miss_count
best_ex_score = best_score.get('ex_score', ex_score) best_ex_score = best_score.get("ex_score", ex_score)
best_score_data = { best_score_data = {
'game_version': game_version, "game_version": game_version,
'iidx_id': iidx_id, "iidx_id": iidx_id,
'pid': pid, "pid": pid,
'play_style': play_style, "play_style": play_style,
'music_id': music_id, "music_id": music_id,
'chart_id': note_id, "chart_id": note_id,
'miss_count': miss_count, "miss_count": miss_count,
'ex_score': max(ex_score, best_ex_score), "ex_score": max(ex_score, best_ex_score),
'ghost': ghost if ex_score >= best_ex_score else best_score.get('ghost', ghost), "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), "ghost_gauge": ghost_gauge
'clear_flg': max(clear_flg, best_score.get('clear_flg', clear_flg)), if ex_score >= best_ex_score
'gauge_type': gauge_type if ex_score >= best_ex_score else best_score.get('gauge_type', gauge_type), 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( db.table("iidx_scores_best").upsert(
best_score_data, best_score_data,
(where('iidx_id') == iidx_id) (where("iidx_id") == iidx_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == note_id) & (where("chart_id") == note_id),
) )
score_stats = db.table('iidx_score_stats').get( score_stats = db.table("iidx_score_stats").get(
(where('music_id') == music_id) (where("music_id") == music_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('chart_id') == note_id) & (where("chart_id") == note_id)
) )
score_stats = {} if score_stats is None else score_stats score_stats = {} if score_stats is None else score_stats
score_stats['game_version'] = game_version score_stats["game_version"] = game_version
score_stats['play_style'] = play_style score_stats["play_style"] = play_style
score_stats['music_id'] = music_id score_stats["music_id"] = music_id
score_stats['chart_id'] = note_id score_stats["chart_id"] = note_id
score_stats['play_count'] = score_stats.get('play_count', 0) + 1 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["fc_count"] = score_stats.get("fc_count", 0) + (
score_stats['clear_count'] = score_stats.get('clear_count', 0) + (1 if clear_flg >= ClearFlags.EASY_CLEAR else 0) 1 if clear_flg == ClearFlags.FULL_COMBO 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) 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( db.table("iidx_score_stats").upsert(
score_stats, score_stats,
(where('music_id') == music_id) (where("music_id") == music_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('chart_id') == note_id) & (where("chart_id") == note_id),
) )
ranklist_data = [] ranklist_data = []
ranklist_scores = db.table('iidx_scores_best').search( ranklist_scores = db.table("iidx_scores_best").search(
(where('play_style') == play_style) (where("play_style") == play_style)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == note_id) & (where("chart_id") == note_id)
) )
ranklist_scores = [] if ranklist_scores is None else ranklist_scores ranklist_scores = [] if ranklist_scores is None else ranklist_scores
ranklist_scores_ranked = [] ranklist_scores_ranked = []
for score in ranklist_scores: for score in ranklist_scores:
profile = db.table('iidx_profile').get(where('iidx_id') == score['iidx_id']) profile = db.table("iidx_profile").get(where("iidx_id") == score["iidx_id"])
if profile is None or str(game_version) not in profile['version']: if profile is None or str(game_version) not in profile["version"]:
continue continue
game_profile = profile['version'][str(game_version)] game_profile = profile["version"][str(game_version)]
ranklist_scores_ranked.append({ ranklist_scores_ranked.append(
'opname': config.arcade, {
'name': game_profile['djname'], "opname": config.arcade,
'pid': game_profile['region'], "name": game_profile["djname"],
'body': game_profile['body'], "pid": game_profile["region"],
'face': game_profile['face'], "body": game_profile["body"],
'hair': game_profile['hair'], "face": game_profile["face"],
'hand': game_profile['hand'], "hair": game_profile["hair"],
'head': game_profile['head'], "hand": game_profile["hand"],
'dgrade': game_profile['grade_double'], "head": game_profile["head"],
'sgrade': game_profile['grade_single'], "dgrade": game_profile["grade_double"],
'score': score['ex_score'], "sgrade": game_profile["grade_single"],
'iidx_id': score['iidx_id'], "score": score["ex_score"],
'clflg': score['clear_flg'], "iidx_id": score["iidx_id"],
'myFlg': score['iidx_id'] == 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) ranklist_scores_ranked = sorted(
ranklist_scores_ranked, key=lambda x: (x["clflg"], x["score"]), reverse=True
)
myRank = 0 myRank = 0
for rnum, score in enumerate(ranklist_scores_ranked): for rnum, score in enumerate(ranklist_scores_ranked):
r = E.data( r = E.data(
rnum=rnum + 1, rnum=rnum + 1,
opname=score['opname'], opname=score["opname"],
name=score['name'], name=score["name"],
pid=score['pid'], pid=score["pid"],
body=score['body'], body=score["body"],
face=score['face'], face=score["face"],
hair=score['hair'], hair=score["hair"],
hand=score['hand'], hand=score["hand"],
head=score['head'], head=score["head"],
dgrade=score['dgrade'], dgrade=score["dgrade"],
sgrade=score['sgrade'], sgrade=score["sgrade"],
score=score['score'], score=score["score"],
iidx_id=score['iidx_id'], iidx_id=score["iidx_id"],
clflg=score['clflg'], clflg=score["clflg"],
myFlg=score['myFlg'], myFlg=score["myFlg"],
achieve=0, achieve=0,
) )
ranklist_data.append(r) ranklist_data.append(r)
if score['myFlg']: if score["myFlg"]:
myRank = rnum + 1 myRank = rnum + 1
response = E.response( response = E.response(
E.IIDX29music( E.IIDX29music(
E.ranklist( E.ranklist(*ranklist_data, total_user_num=len(ranklist_data)),
*ranklist_data, E.shopdata(rank=myRank),
total_user_num=len(ranklist_data)
),
E.shopdata(
rank=myRank
),
clid=clid, clid=clid,
crate=score_stats['clear_rate'], crate=score_stats["clear_rate"],
frate=score_stats['fc_rate'], frate=score_stats["fc_rate"],
mid=music_id, mid=music_id,
) )
) )
@ -374,78 +399,77 @@ async def iidx29music_reg(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29music/appoint') @router.post("/{gameinfo}/IIDX29music/appoint")
async def iidx29music_appoint(request: Request): async def iidx29music_appoint(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
root = request_info['root'][0] root = request_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']
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() db = get_db()
record = db.table('iidx_scores_best').get( record = db.table("iidx_scores_best").get(
(where('iidx_id') == iidxid) (where("iidx_id") == iidxid)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == chart_id) & (where("chart_id") == chart_id)
) )
vals = [] vals = []
if record is not None: if record is not None:
vals.append(E.mydata( vals.append(
record['ghost'], E.mydata(
score=record['ex_score'], record["ghost"],
__type="bin", score=record["ex_score"],
__size=len(record['ghost']) // 2, __type="bin",
)) __size=len(record["ghost"]) // 2,
)
)
if ctype == 1: if ctype == 1:
sdata = db.table('iidx_scores_best').get( sdata = db.table("iidx_scores_best").get(
(where('iidx_id') == int(subtype)) (where("iidx_id") == int(subtype))
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == chart_id) & (where("chart_id") == chart_id)
) )
elif ctype in (2, 4, 10): elif ctype in (2, 4, 10):
sdata = { sdata = {
'game_version': 29, "game_version": 29,
'ghost': "", "ghost": "",
'ex_score': 0, "ex_score": 0,
'iidx_id': 0, "iidx_id": 0,
'name': "", "name": "",
'pid': 13 "pid": 13,
} }
for record in db.table('iidx_scores_best').search( for record in db.table("iidx_scores_best").search(
(where('music_id') == music_id) (where("music_id") == music_id) & (where("chart_id") == chart_id)
& (where('chart_id') == chart_id)
): ):
if record['ex_score'] > sdata['ex_score']: if record["ex_score"] > sdata["ex_score"]:
sdata['game_version'] = record['game_version'] sdata["game_version"] = record["game_version"]
sdata['ghost'] = record['ghost'] sdata["ghost"] = record["ghost"]
sdata['ex_score'] = record['ex_score'] sdata["ex_score"] = record["ex_score"]
sdata['iidx_id'] = record['iidx_id'] sdata["iidx_id"] = record["iidx_id"]
sdata['pid'] = record['pid'] sdata["pid"] = record["pid"]
if ctype in (1, 2, 4, 10) and sdata['ex_score'] != 0: if ctype in (1, 2, 4, 10) and sdata["ex_score"] != 0:
vals.append(E.sdata( vals.append(
sdata['ghost'], E.sdata(
score=sdata['ex_score'], sdata["ghost"],
name=db.table('iidx_profile').get(where('iidx_id') == sdata['iidx_id'])['version'][str(sdata['game_version'])]['djname'], score=sdata["ex_score"],
pid=sdata['pid'], name=db.table("iidx_profile").get(where("iidx_id") == sdata["iidx_id"])[
__type="bin", "version"
__size=len(sdata['ghost']) // 2, ][str(sdata["game_version"])]["djname"],
)) pid=sdata["pid"],
__type="bin",
__size=len(sdata["ghost"]) // 2,
response = E.response( )
E.IIDX29music(
*vals
) )
)
response = E.response(E.IIDX29music(*vals))
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

File diff suppressed because it is too large Load Diff

View File

@ -8,13 +8,11 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["LDJ"] router.model_whitelist = ["LDJ"]
@router.post('/{gameinfo}/IIDX29ranking/getranker') @router.post("/{gameinfo}/IIDX29ranking/getranker")
async def iidx29ranking_getranker(request: Request): async def iidx29ranking_getranker(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX29ranking())
E.IIDX29ranking()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

View File

@ -8,7 +8,7 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["LDJ"] router.model_whitelist = ["LDJ"]
@router.post('/{gameinfo}/IIDX29shop/getname') @router.post("/{gameinfo}/IIDX29shop/getname")
async def iidx29shop_getname(request: Request): async def iidx29shop_getname(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
@ -24,7 +24,7 @@ async def iidx29shop_getname(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29shop/getconvention') @router.post("/{gameinfo}/IIDX29shop/getconvention")
async def iidx29shop_getconvention(request: Request): async def iidx29shop_getconvention(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
@ -44,26 +44,21 @@ async def iidx29shop_getconvention(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29shop/sentinfo') @router.post("/{gameinfo}/IIDX29shop/sentinfo")
async def iidx29shop_sentinfo(request: Request): async def iidx29shop_sentinfo(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX29shop())
E.IIDX29shop()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29shop/sendescapepackageinfo')
@router.post("/{gameinfo}/IIDX29shop/sendescapepackageinfo")
async def iidx29shop_sendescapepackageinfo(request: Request): async def iidx29shop_sendescapepackageinfo(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX29shop(expire=1200))
E.IIDX29shop(
expire=1200
)
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

View File

@ -8,11 +8,11 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["LDJ"] router.model_whitelist = ["LDJ"]
@router.post('/{gameinfo}/IIDX30gameSystem/systemInfo') @router.post("/{gameinfo}/IIDX30gameSystem/systemInfo")
async def iidx30gamesystem_systeminfo(request: Request): async def iidx30gamesystem_systeminfo(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
unlock = () #(28008, 28065, 28073, 28088, 28089, 29027, 29094, 29095) unlock = () # (28008, 28065, 28073, 28088, 28089, 29027, 29094, 29095)
sp_dp = (0, 1) sp_dp = (0, 1)
response = E.response( response = E.response(
@ -30,46 +30,64 @@ async def iidx30gamesystem_systeminfo(request: Request):
E.isEiseiOpenFlg(val=1), E.isEiseiOpenFlg(val=1),
E.WorldTourismOpenList(val=1), E.WorldTourismOpenList(val=1),
E.BPLBattleOpenPhase(val=2), E.BPLBattleOpenPhase(val=2),
*[E.music_open( *[
E.music_id(s, __type="s32"), E.music_open(
E.kind(0, __type="s32"), E.music_id(s, __type="s32"),
) for s in unlock], E.kind(0, __type="s32"),
*[E.arena_reward( )
E.index(unlock.index(s), __type="s32"), for s in unlock
E.cube_num((unlock.index(s) + 1) * 50, __type="s32"), ],
E.kind(0, __type="s32"), *[
E.value(s, __type="str"), E.arena_reward(
) for s in unlock], E.index(unlock.index(s), __type="s32"),
*[E.arena_music_difficult( E.cube_num((unlock.index(s) + 1) * 50, __type="s32"),
E.play_style(s, __type="s32"), E.kind(0, __type="s32"),
E.arena_class(-1, __type="s32"), E.value(s, __type="str"),
E.low_difficult(1, __type="s32"), )
E.high_difficult(12, __type="s32"), for s in unlock
E.is_leggendaria(1, __type="bool"), ],
E.force_music_list_id(0, __type="s32"), *[
) for s in sp_dp], E.arena_music_difficult(
*[E.arena_cpu_define( E.play_style(s, __type="s32"),
E.play_style(s, __type="s32"), E.arena_class(-1, __type="s32"),
E.arena_class(-1, __type="s32"), E.low_difficult(1, __type="s32"),
E.grade_id(18, __type="s32"), E.high_difficult(12, __type="s32"),
E.low_music_difficult(8, __type="s32"), E.is_leggendaria(1, __type="bool"),
E.high_music_difficult(12, __type="s32"), E.force_music_list_id(0, __type="s32"),
E.is_leggendaria(0, __type="bool"), )
) for s in sp_dp], for s in sp_dp
*[E.maching_class_range( ],
E.play_style(s[0], __type="s32"), *[
E.matching_class(s[1], __type="s32"), E.arena_cpu_define(
E.low_arena_class(0, __type="s32"), E.play_style(s, __type="s32"),
E.high_arena_class(19, __type="s32"), E.arena_class(-1, __type="s32"),
) for s in ((0, 2), (0, 1), (1, 2), (1, 1))], E.grade_id(18, __type="s32"),
*[E.arena_force_music( E.low_music_difficult(8, __type="s32"),
E.play_style(s, __type="s32"), E.high_music_difficult(12, __type="s32"),
E.force_music_list_id(0, __type="s32"), E.is_leggendaria(0, __type="bool"),
E.index(0, __type="s32"), )
E.music_id(1000, __type="s32"), for s in sp_dp
E.note_grade(0, __type="s32"), ],
E.is_active(s, __type="bool"), *[
) for s in sp_dp], E.maching_class_range(
E.play_style(s[0], __type="s32"),
E.matching_class(s[1], __type="s32"),
E.low_arena_class(0, __type="s32"),
E.high_arena_class(19, __type="s32"),
)
for s in ((0, 2), (0, 1), (1, 2), (1, 1))
],
*[
E.arena_force_music(
E.play_style(s, __type="s32"),
E.force_music_list_id(0, __type="s32"),
E.index(0, __type="s32"),
E.music_id(1000, __type="s32"),
E.note_grade(0, __type="s32"),
E.is_active(s, __type="bool"),
)
for s in sp_dp
],
) )
) )

View File

@ -10,113 +10,101 @@ from core_database import get_db
router = APIRouter(prefix="/local2", tags=["local2"]) router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["LDJ"] router.model_whitelist = ["LDJ"]
def get_profile(iidx_id):
return get_db().table('iidx_profile').get(
where('iidx_id') == iidx_id
)
@router.post('/{gameinfo}/IIDX30grade/raised') 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): async def iidx30grade_raised(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
timestamp = time.time() timestamp = time.time()
iidx_id = int(request_info['root'][0].attrib['iidxid']) iidx_id = int(request_info["root"][0].attrib["iidxid"])
achi = int(request_info['root'][0].attrib['achi']) achi = int(request_info["root"][0].attrib["achi"])
cstage = int(request_info['root'][0].attrib['cstage']) cstage = int(request_info["root"][0].attrib["cstage"])
gid = int(request_info['root'][0].attrib['gid']) gid = int(request_info["root"][0].attrib["gid"])
gtype = int(request_info['root'][0].attrib['gtype']) gtype = int(request_info["root"][0].attrib["gtype"])
is_ex = int(request_info['root'][0].attrib['is_ex']) is_ex = int(request_info["root"][0].attrib["is_ex"])
is_mirror = int(request_info['root'][0].attrib['is_mirror']) is_mirror = int(request_info["root"][0].attrib["is_mirror"])
db = get_db() db = get_db()
db.table('iidx_class').insert( db.table("iidx_class").insert(
{ {
'timestamp': timestamp, "timestamp": timestamp,
'game_version': game_version, "game_version": game_version,
'iidx_id': iidx_id, "iidx_id": iidx_id,
'achi': achi, "achi": achi,
'cstage': cstage, "cstage": cstage,
'gid': gid, "gid": gid,
'gtype': gtype, "gtype": gtype,
'is_ex': is_ex, "is_ex": is_ex,
'is_mirror': is_mirror, "is_mirror": is_mirror,
}, },
) )
profile = get_profile(iidx_id) profile = get_profile(iidx_id)
game_profile = profile['version'].get(str(game_version), {}) game_profile = profile["version"].get(str(game_version), {})
best_class = db.table('iidx_class_best').get( best_class = db.table("iidx_class_best").get(
(where('iidx_id') == iidx_id) (where("iidx_id") == iidx_id)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('gid') == gid) & (where("gid") == gid)
& (where('gtype') == gtype) & (where("gtype") == gtype)
) )
best_class = {} if best_class is None else best_class best_class = {} if best_class is None else best_class
best_class_data = { best_class_data = {
'game_version': game_version, "game_version": game_version,
'iidx_id': iidx_id, "iidx_id": iidx_id,
'achi': max(achi, best_class.get('achi', achi)), "achi": max(achi, best_class.get("achi", achi)),
'cstage': max(cstage, best_class.get('cstage', cstage)), "cstage": max(cstage, best_class.get("cstage", cstage)),
'gid': gid, "gid": gid,
'gtype': gtype, "gtype": gtype,
'is_ex': is_ex, "is_ex": is_ex,
'is_mirror': is_mirror, "is_mirror": is_mirror,
} }
db.table('iidx_class_best').upsert( db.table("iidx_class_best").upsert(
best_class_data, best_class_data,
(where('iidx_id') == iidx_id) (where("iidx_id") == iidx_id)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('gid') == gid) & (where("gid") == gid)
& (where('gtype') == gtype) & (where("gtype") == gtype),
) )
best_class_plays = db.table('iidx_class_best').search( best_class_plays = db.table("iidx_class_best").search(
(where('game_version') == game_version) (where("game_version") == game_version) & (where("iidx_id") == iidx_id)
& (where('iidx_id') == iidx_id)
) )
grades = [] grades = []
for record in best_class_plays: for record in best_class_plays:
grades.append([ grades.append(
record['gtype'], [record["gtype"], record["gid"], record["cstage"], record["achi"]]
record['gid'],
record['cstage'],
record['achi']
])
game_profile['grade_values'] = grades
grade_sp = db.table('iidx_class_best').search(
(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('iidx_id') == iidx_id)
& (where('gtype') == 1)
& (where('cstage') == 4)
)
game_profile['grade_double'] = max([x['gid'] for x in grade_dp], default=-1)
profile['version'][str(game_version)] = game_profile
db.table('iidx_profile').upsert(profile, where('game_version') == game_version)
response = E.response(
E.IIDX30grade(
pnum=1
) )
game_profile["grade_values"] = grades
grade_sp = db.table("iidx_class_best").search(
(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("iidx_id") == iidx_id) & (where("gtype") == 1) & (where("cstage") == 4)
)
game_profile["grade_double"] = max([x["gid"] for x in grade_dp], default=-1)
profile["version"][str(game_version)] = game_profile
db.table("iidx_profile").upsert(profile, where("game_version") == game_version)
response = E.response(E.IIDX30grade(pnum=1))
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

View File

@ -8,68 +8,61 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["LDJ"] router.model_whitelist = ["LDJ"]
@router.post('/{gameinfo}/IIDX30lobby/entry') @router.post("/{gameinfo}/IIDX30lobby/entry")
async def iidx30lobby_entry(request: Request): async def iidx30lobby_entry(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX30lobby())
E.IIDX30lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30lobby/update')
@router.post("/{gameinfo}/IIDX30lobby/update")
async def iidx30lobby_update(request: Request): async def iidx30lobby_update(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX30lobby())
E.IIDX30lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30lobby/delete')
@router.post("/{gameinfo}/IIDX30lobby/delete")
async def iidx30lobby_delete(request: Request): async def iidx30lobby_delete(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX30lobby())
E.IIDX30lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30lobby/bplbattle_entry')
@router.post("/{gameinfo}/IIDX30lobby/bplbattle_entry")
async def iidx30lobby_bplbattle_entry(request: Request): async def iidx30lobby_bplbattle_entry(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX30lobby())
E.IIDX30lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30lobby/bplbattle_update')
@router.post("/{gameinfo}/IIDX30lobby/bplbattle_update")
async def iidx30lobby_bplbattle_update(request: Request): async def iidx30lobby_bplbattle_update(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX30lobby())
E.IIDX30lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30lobby/bplbattle_delete')
@router.post("/{gameinfo}/IIDX30lobby/bplbattle_delete")
async def iidx30lobby_bplbattle_delete(request: Request): async def iidx30lobby_bplbattle_delete(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX30lobby())
E.IIDX30lobby()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

View File

@ -9,8 +9,8 @@ from core_database import get_db
import config import config
router = APIRouter(prefix='/local2', tags=['local2']) router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ['LDJ'] router.model_whitelist = ["LDJ"]
class ClearFlags(IntEnum): class ClearFlags(IntEnum):
@ -24,23 +24,23 @@ class ClearFlags(IntEnum):
FULL_COMBO = 7 FULL_COMBO = 7
@router.post('/{gameinfo}/IIDX30music/getrank') @router.post("/{gameinfo}/IIDX30music/getrank")
async def iidx30music_getrank(request: Request): async def iidx30music_getrank(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
root = request_info['root'][0] root = request_info["root"][0]
play_style = int(root.attrib['cltype']) play_style = int(root.attrib["cltype"])
requested_ids = [ requested_ids = [
int(root.get('iidxid', 0)), int(root.get("iidxid", 0)),
int(root.get('iidxid0', 0)), int(root.get("iidxid0", 0)),
int(root.get('iidxid1', 0)), int(root.get("iidxid1", 0)),
int(root.get('iidxid2', 0)), int(root.get("iidxid2", 0)),
int(root.get('iidxid3', 0)), int(root.get("iidxid3", 0)),
int(root.get('iidxid4', 0)), int(root.get("iidxid4", 0)),
int(root.get('iidxid5', 0)), int(root.get("iidxid5", 0)),
] ]
all_scores = {} all_scores = {}
@ -50,323 +50,348 @@ async def iidx30music_getrank(request: Request):
if iidxid == 0: if iidxid == 0:
continue continue
profile = db.table('iidx_profile').get(where('iidx_id') == iidxid)['version'][str(game_version)] profile = db.table("iidx_profile").get(where("iidx_id") == iidxid)["version"][
str(game_version)
]
for record in db.table('iidx_scores_best').search( for record in db.table("iidx_scores_best").search(
(where('music_id') < (game_version + 1) * 1000) (where("music_id") < (game_version + 1) * 1000)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('iidx_id') == iidxid) & (where("iidx_id") == iidxid)
): ):
music_id = record['music_id'] music_id = record["music_id"]
clear_flg = record['clear_flg'] clear_flg = record["clear_flg"]
ex_score = record['ex_score'] ex_score = record["ex_score"]
miss_count = record['miss_count'] miss_count = record["miss_count"]
chart_id = record['chart_id'] chart_id = record["chart_id"]
if (rival_idx, music_id) not in all_scores: if (rival_idx, music_id) not in all_scores:
all_scores[rival_idx, music_id] = { all_scores[rival_idx, music_id] = {
0: {'clear_flg': -1, 'ex_score': -1, 'miss_count': -1}, 0: {"clear_flg": -1, "ex_score": -1, "miss_count": -1},
1: {'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}, 2: {"clear_flg": -1, "ex_score": -1, "miss_count": -1},
3: {'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}, 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]["clear_flg"] = clear_flg
all_scores[rival_idx, music_id][chart_id]['ex_score'] = ex_score all_scores[rival_idx, music_id][chart_id]["ex_score"] = ex_score
all_scores[rival_idx, music_id][chart_id]['miss_count'] = miss_count all_scores[rival_idx, music_id][chart_id]["miss_count"] = miss_count
top_scores = {} top_scores = {}
for record in db.table('iidx_scores_best').search( for record in db.table("iidx_scores_best").search(
(where('music_id') < (game_version + 1) * 1000) (where("music_id") < (game_version + 1) * 1000)
& (where('play_style') == play_style) & (where("play_style") == play_style)
): ):
music_id = record['music_id'] music_id = record["music_id"]
ex_score = record['ex_score'] ex_score = record["ex_score"]
chart_id = record['chart_id'] chart_id = record["chart_id"]
iidx_id = record['iidx_id'] iidx_id = record["iidx_id"]
if music_id not in top_scores: if music_id not in top_scores:
top_scores[music_id] = { top_scores[music_id] = {
0: {'djname': "", 'clear_flg': -1, 'ex_score': -1}, 0: {"djname": "", "clear_flg": -1, "ex_score": -1},
1: {'djname': "", 'clear_flg': -1, 'ex_score': -1}, 1: {"djname": "", "clear_flg": -1, "ex_score": -1},
2: {'djname': "", 'clear_flg': -1, 'ex_score': -1}, 2: {"djname": "", "clear_flg": -1, "ex_score": -1},
3: {'djname': "", 'clear_flg': -1, 'ex_score': -1}, 3: {"djname": "", "clear_flg": -1, "ex_score": -1},
4: {'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']: if ex_score > top_scores[music_id][chart_id]["ex_score"]:
top_name = db.table('iidx_profile').get(where('iidx_id') == iidx_id)['version'][str(game_version)]['djname'] top_name = db.table("iidx_profile").get(where("iidx_id") == iidx_id)[
top_scores[music_id][chart_id]['djname'] = top_name "version"
top_scores[music_id][chart_id]['clear_flg'] = 1 ][str(game_version)]["djname"]
top_scores[music_id][chart_id]['ex_score'] = ex_score top_scores[music_id][chart_id]["djname"] = top_name
top_scores[music_id][chart_id]["clear_flg"] = 1
top_scores[music_id][chart_id]["ex_score"] = ex_score
response = E.response( response = E.response(
E.IIDX30music( E.IIDX30music(
E.style(type=play_style), E.style(type=play_style),
*[E.m([ *[
i, E.m(
k, [
*[all_scores[i, k][d]['clear_flg'] for d in range(5)], i,
*[all_scores[i, k][d]['ex_score'] for d in range(5)], k,
*[all_scores[i, k][d]['miss_count'] for d in range(5)], *[all_scores[i, k][d]["clear_flg"] for d in range(5)],
], __type='s16') for i, k in all_scores], *[all_scores[i, k][d]["ex_score"] for d in range(5)],
*[E.top( *[all_scores[i, k][d]["miss_count"] for d in range(5)],
E.detail([ ],
k, __type="s16",
*[top_scores[k][d]['clear_flg'] for d in range(5)], )
*[top_scores[k][d]['ex_score'] for d in range(5)], for i, k in all_scores
], __type='s16'), ],
name0=top_scores[k][0]['djname'], *[
name1=top_scores[k][1]['djname'], E.top(
name2=top_scores[k][2]['djname'], E.detail(
name3=top_scores[k][3]['djname'], [
name4=top_scores[k][4]['djname'] k,
) for k in top_scores] *[top_scores[k][d]["clear_flg"] for d in range(5)],
*[top_scores[k][d]["ex_score"] for d in range(5)],
],
__type="s16",
),
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) assert response is not None
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30music/crate') @router.post("/{gameinfo}/IIDX30music/crate")
async def iidx30music_crate(request: Request): async def iidx30music_crate(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
db = get_db() db = get_db()
all_score_stats = db.table('iidx_score_stats').search( all_score_stats = db.table("iidx_score_stats").search(
(where('music_id') < (game_version + 1) * 1000) (where("music_id") < (game_version + 1) * 1000)
) )
crate = {} crate = {}
fcrate = {} fcrate = {}
for stat in all_score_stats: for stat in all_score_stats:
if stat['music_id'] not in crate: if stat["music_id"] not in crate:
crate[stat['music_id']] = [1001] * 10 crate[stat["music_id"]] = [1001] * 10
if stat['music_id'] not in fcrate: if stat["music_id"] not in fcrate:
fcrate[stat['music_id']] = [1001] * 10 fcrate[stat["music_id"]] = [1001] * 10
if stat['play_style'] == 1: if stat["play_style"] == 1:
dp_idx = 5 dp_idx = 5
else: else:
dp_idx = 0 dp_idx = 0
crate[stat['music_id']][stat['chart_id'] + dp_idx] = int(stat['clear_rate']) 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']) fcrate[stat["music_id"]][stat["chart_id"] + dp_idx] = int(stat["fc_rate"])
response = E.response( response = E.response(
E.IIDX30music( E.IIDX30music(*[E.c(crate[k] + fcrate[k], mid=k, __type="s32") for k in crate])
*[E.c(crate[k] + fcrate[k], mid=k, __type="s32") for k in crate]
)
) )
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30music/reg') @router.post("/{gameinfo}/IIDX30music/reg")
async def iidx30music_reg(request: Request): async def iidx30music_reg(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
timestamp = time.time() timestamp = time.time()
log = request_info['root'][0].find('music_play_log') log = request_info["root"][0].find("music_play_log")
clear_flg = int(request_info['root'][0].attrib['cflg']) clear_flg = int(request_info["root"][0].attrib["cflg"])
clid = int(request_info['root'][0].attrib['clid']) clid = int(request_info["root"][0].attrib["clid"])
is_death = int(request_info['root'][0].attrib['is_death']) is_death = int(request_info["root"][0].attrib["is_death"])
pid = int(request_info['root'][0].attrib['pid']) pid = int(request_info["root"][0].attrib["pid"])
play_style = int(log.attrib['play_style']) play_style = int(log.attrib["play_style"])
ex_score = int(log.attrib['ex_score']) ex_score = int(log.attrib["ex_score"])
folder_type = int(log.attrib['folder_type']) folder_type = int(log.attrib["folder_type"])
gauge_type = int(log.attrib['gauge_type']) gauge_type = int(log.attrib["gauge_type"])
graph_type = int(log.attrib['graph_type']) graph_type = int(log.attrib["graph_type"])
great_num = int(log.attrib['great_num']) great_num = int(log.attrib["great_num"])
iidx_id = int(log.attrib['iidx_id']) iidx_id = int(log.attrib["iidx_id"])
miss_num = int(log.attrib['miss_num']) miss_num = int(log.attrib["miss_num"])
mode_type = int(log.attrib['mode_type']) mode_type = int(log.attrib["mode_type"])
music_id = int(log.attrib['music_id']) music_id = int(log.attrib["music_id"])
note_id = int(log.attrib['note_id']) note_id = int(log.attrib["note_id"])
option1 = int(log.attrib['option1']) option1 = int(log.attrib["option1"])
option2 = int(log.attrib['option2']) option2 = int(log.attrib["option2"])
pgreat_num = int(log.attrib['pgreat_num']) pgreat_num = int(log.attrib["pgreat_num"])
ghost = log.find("ghost").text ghost = log.find("ghost").text
ghost_gauge = log.find("ghost_gauge").text ghost_gauge = log.find("ghost_gauge").text
db = get_db() db = get_db()
db.table('iidx_scores').insert( db.table("iidx_scores").insert(
{ {
'timestamp': timestamp, "timestamp": timestamp,
'game_version': game_version, "game_version": game_version,
'iidx_id': iidx_id, "iidx_id": iidx_id,
'pid': pid, "pid": pid,
'clear_flg': clear_flg, "clear_flg": clear_flg,
'is_death': is_death, "is_death": is_death,
'music_id': music_id, "music_id": music_id,
'play_style': play_style, "play_style": play_style,
'chart_id': note_id, "chart_id": note_id,
'pgreat_num': pgreat_num, "pgreat_num": pgreat_num,
'great_num': great_num, "great_num": great_num,
'ex_score': ex_score, "ex_score": ex_score,
'miss_count': miss_num, "miss_count": miss_num,
'folder_type': folder_type, "folder_type": folder_type,
'gauge_type': gauge_type, "gauge_type": gauge_type,
'graph_type': graph_type, "graph_type": graph_type,
'mode_type': mode_type, "mode_type": mode_type,
'option1': option1, "option1": option1,
'option2': option2, "option2": option2,
'ghost': ghost, "ghost": ghost,
'ghost_gauge': ghost_gauge, "ghost_gauge": ghost_gauge,
}, },
) )
best_score = db.table('iidx_scores_best').get( best_score = db.table("iidx_scores_best").get(
(where('iidx_id') == iidx_id) (where("iidx_id") == iidx_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == note_id) & (where("chart_id") == note_id)
) )
best_score = {} if best_score is None else best_score best_score = {} if best_score is None else best_score
if clear_flg < ClearFlags.EASY_CLEAR: if clear_flg < ClearFlags.EASY_CLEAR:
miss_num = -1 miss_num = -1
best_miss_count = best_score.get('miss_count', miss_num) best_miss_count = best_score.get("miss_count", miss_num)
if best_miss_count == -1: if best_miss_count == -1:
miss_count = max(miss_num, best_miss_count) miss_count = max(miss_num, best_miss_count)
elif clear_flg > ClearFlags.ASSIST_CLEAR: elif clear_flg > ClearFlags.ASSIST_CLEAR:
miss_count = min(miss_num, best_miss_count) miss_count = min(miss_num, best_miss_count)
else: else:
miss_count = best_miss_count miss_count = best_miss_count
best_ex_score = best_score.get('ex_score', ex_score) best_ex_score = best_score.get("ex_score", ex_score)
best_score_data = { best_score_data = {
'game_version': game_version, "game_version": game_version,
'iidx_id': iidx_id, "iidx_id": iidx_id,
'pid': pid, "pid": pid,
'play_style': play_style, "play_style": play_style,
'music_id': music_id, "music_id": music_id,
'chart_id': note_id, "chart_id": note_id,
'miss_count': miss_count, "miss_count": miss_count,
'ex_score': max(ex_score, best_ex_score), "ex_score": max(ex_score, best_ex_score),
'ghost': ghost if ex_score >= best_ex_score else best_score.get('ghost', ghost), "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), "ghost_gauge": ghost_gauge
'clear_flg': max(clear_flg, best_score.get('clear_flg', clear_flg)), if ex_score >= best_ex_score
'gauge_type': gauge_type if ex_score >= best_ex_score else best_score.get('gauge_type', gauge_type), 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( db.table("iidx_scores_best").upsert(
best_score_data, best_score_data,
(where('iidx_id') == iidx_id) (where("iidx_id") == iidx_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == note_id) & (where("chart_id") == note_id),
) )
score_stats = db.table('iidx_score_stats').get( score_stats = db.table("iidx_score_stats").get(
(where('music_id') == music_id) (where("music_id") == music_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('chart_id') == note_id) & (where("chart_id") == note_id)
) )
score_stats = {} if score_stats is None else score_stats score_stats = {} if score_stats is None else score_stats
score_stats['game_version'] = game_version score_stats["game_version"] = game_version
score_stats['play_style'] = play_style score_stats["play_style"] = play_style
score_stats['music_id'] = music_id score_stats["music_id"] = music_id
score_stats['chart_id'] = note_id score_stats["chart_id"] = note_id
score_stats['play_count'] = score_stats.get('play_count', 0) + 1 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["fc_count"] = score_stats.get("fc_count", 0) + (
score_stats['clear_count'] = score_stats.get('clear_count', 0) + (1 if clear_flg >= ClearFlags.EASY_CLEAR else 0) 1 if clear_flg == ClearFlags.FULL_COMBO 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) 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( db.table("iidx_score_stats").upsert(
score_stats, score_stats,
(where('music_id') == music_id) (where("music_id") == music_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('chart_id') == note_id) & (where("chart_id") == note_id),
) )
ranklist_data = [] ranklist_data = []
ranklist_scores = db.table('iidx_scores_best').search( ranklist_scores = db.table("iidx_scores_best").search(
(where('play_style') == play_style) (where("play_style") == play_style)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == note_id) & (where("chart_id") == note_id)
) )
ranklist_scores = [] if ranklist_scores is None else ranklist_scores ranklist_scores = [] if ranklist_scores is None else ranklist_scores
ranklist_scores_ranked = [] ranklist_scores_ranked = []
for score in ranklist_scores: for score in ranklist_scores:
profile = db.table('iidx_profile').get(where('iidx_id') == score['iidx_id']) profile = db.table("iidx_profile").get(where("iidx_id") == score["iidx_id"])
if profile is None or str(game_version) not in profile['version']: if profile is None or str(game_version) not in profile["version"]:
continue continue
game_profile = profile['version'][str(game_version)] game_profile = profile["version"][str(game_version)]
ranklist_scores_ranked.append({ ranklist_scores_ranked.append(
'opname': config.arcade, {
'name': game_profile['djname'], "opname": config.arcade,
'pid': game_profile['region'], "name": game_profile["djname"],
'body': game_profile['body'], "pid": game_profile["region"],
'face': game_profile['face'], "body": game_profile["body"],
'hair': game_profile['hair'], "face": game_profile["face"],
'hand': game_profile['hand'], "hair": game_profile["hair"],
'head': game_profile['head'], "hand": game_profile["hand"],
'dgrade': game_profile['grade_double'], "head": game_profile["head"],
'sgrade': game_profile['grade_single'], "dgrade": game_profile["grade_double"],
'score': score['ex_score'], "sgrade": game_profile["grade_single"],
'iidx_id': score['iidx_id'], "score": score["ex_score"],
'clflg': score['clear_flg'], "iidx_id": score["iidx_id"],
'myFlg': score['iidx_id'] == 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) ranklist_scores_ranked = sorted(
ranklist_scores_ranked, key=lambda x: (x["clflg"], x["score"]), reverse=True
)
myRank = 0 myRank = 0
for rnum, score in enumerate(ranklist_scores_ranked): for rnum, score in enumerate(ranklist_scores_ranked):
r = E.data( r = E.data(
rnum=rnum + 1, rnum=rnum + 1,
opname=score['opname'], opname=score["opname"],
name=score['name'], name=score["name"],
pid=score['pid'], pid=score["pid"],
body=score['body'], body=score["body"],
face=score['face'], face=score["face"],
hair=score['hair'], hair=score["hair"],
hand=score['hand'], hand=score["hand"],
head=score['head'], head=score["head"],
dgrade=score['dgrade'], dgrade=score["dgrade"],
sgrade=score['sgrade'], sgrade=score["sgrade"],
score=score['score'], score=score["score"],
iidx_id=score['iidx_id'], iidx_id=score["iidx_id"],
clflg=score['clflg'], clflg=score["clflg"],
myFlg=score['myFlg'], myFlg=score["myFlg"],
achieve=0, achieve=0,
) )
ranklist_data.append(r) ranklist_data.append(r)
if score['myFlg']: if score["myFlg"]:
myRank = rnum + 1 myRank = rnum + 1
response = E.response( response = E.response(
E.IIDX30music( E.IIDX30music(
E.ranklist( E.ranklist(*ranklist_data, total_user_num=len(ranklist_data)),
*ranklist_data, E.shopdata(rank=myRank),
total_user_num=len(ranklist_data)
),
E.shopdata(
rank=myRank
),
clid=clid, clid=clid,
crate=score_stats['clear_rate'], crate=score_stats["clear_rate"],
frate=score_stats['fc_rate'], frate=score_stats["fc_rate"],
mid=music_id, mid=music_id,
) )
) )
@ -375,78 +400,77 @@ async def iidx30music_reg(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30music/appoint') @router.post("/{gameinfo}/IIDX30music/appoint")
async def iidx30music_appoint(request: Request): async def iidx30music_appoint(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
root = request_info['root'][0] root = request_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']
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() db = get_db()
record = db.table('iidx_scores_best').get( record = db.table("iidx_scores_best").get(
(where('iidx_id') == iidxid) (where("iidx_id") == iidxid)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == chart_id) & (where("chart_id") == chart_id)
) )
vals = [] vals = []
if record is not None: if record is not None:
vals.append(E.mydata( vals.append(
record['ghost'], E.mydata(
score=record['ex_score'], record["ghost"],
__type="bin", score=record["ex_score"],
__size=len(record['ghost']) // 2, __type="bin",
)) __size=len(record["ghost"]) // 2,
)
)
if ctype == 1: if ctype == 1:
sdata = db.table('iidx_scores_best').get( sdata = db.table("iidx_scores_best").get(
(where('iidx_id') == int(subtype)) (where("iidx_id") == int(subtype))
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == chart_id) & (where("chart_id") == chart_id)
) )
elif ctype in (2, 4, 10): elif ctype in (2, 4, 10):
sdata = { sdata = {
'game_version': 29, "game_version": 29,
'ghost': "", "ghost": "",
'ex_score': 0, "ex_score": 0,
'iidx_id': 0, "iidx_id": 0,
'name': "", "name": "",
'pid': 13 "pid": 13,
} }
for record in db.table('iidx_scores_best').search( for record in db.table("iidx_scores_best").search(
(where('music_id') == music_id) (where("music_id") == music_id) & (where("chart_id") == chart_id)
& (where('chart_id') == chart_id)
): ):
if record['ex_score'] > sdata['ex_score']: if record["ex_score"] > sdata["ex_score"]:
sdata['game_version'] = record['game_version'] sdata["game_version"] = record["game_version"]
sdata['ghost'] = record['ghost'] sdata["ghost"] = record["ghost"]
sdata['ex_score'] = record['ex_score'] sdata["ex_score"] = record["ex_score"]
sdata['iidx_id'] = record['iidx_id'] sdata["iidx_id"] = record["iidx_id"]
sdata['pid'] = record['pid'] sdata["pid"] = record["pid"]
if ctype in (1, 2, 4, 10) and sdata['ex_score'] != 0: if ctype in (1, 2, 4, 10) and sdata["ex_score"] != 0:
vals.append(E.sdata( vals.append(
sdata['ghost'], E.sdata(
score=sdata['ex_score'], sdata["ghost"],
name=db.table('iidx_profile').get(where('iidx_id') == sdata['iidx_id'])['version'][str(sdata['game_version'])]['djname'], score=sdata["ex_score"],
pid=sdata['pid'], name=db.table("iidx_profile").get(where("iidx_id") == sdata["iidx_id"])[
__type="bin", "version"
__size=len(sdata['ghost']) // 2, ][str(sdata["game_version"])]["djname"],
)) pid=sdata["pid"],
__type="bin",
__size=len(sdata["ghost"]) // 2,
response = E.response( )
E.IIDX30music(
*vals
) )
)
response = E.response(E.IIDX30music(*vals))
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

File diff suppressed because it is too large Load Diff

View File

@ -8,13 +8,11 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["LDJ"] router.model_whitelist = ["LDJ"]
@router.post('/{gameinfo}/IIDX30ranking/getranker') @router.post("/{gameinfo}/IIDX30ranking/getranker")
async def iidx30ranking_getranker(request: Request): async def iidx30ranking_getranker(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX30ranking())
E.IIDX30ranking()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

View File

@ -8,7 +8,7 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["LDJ"] router.model_whitelist = ["LDJ"]
@router.post('/{gameinfo}/IIDX30shop/getname') @router.post("/{gameinfo}/IIDX30shop/getname")
async def iidx30shop_getname(request: Request): async def iidx30shop_getname(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
@ -24,7 +24,7 @@ async def iidx30shop_getname(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30shop/getconvention') @router.post("/{gameinfo}/IIDX30shop/getconvention")
async def iidx30shop_getconvention(request: Request): async def iidx30shop_getconvention(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
@ -44,26 +44,21 @@ async def iidx30shop_getconvention(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30shop/sentinfo') @router.post("/{gameinfo}/IIDX30shop/sentinfo")
async def iidx30shop_sentinfo(request: Request): async def iidx30shop_sentinfo(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX30shop())
E.IIDX30shop()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30shop/sendescapepackageinfo')
@router.post("/{gameinfo}/IIDX30shop/sendescapepackageinfo")
async def iidx30shop_sendescapepackageinfo(request: Request): async def iidx30shop_sendescapepackageinfo(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.IIDX30shop(expire=1200))
E.IIDX30shop(
expire=1200
)
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

View File

@ -9,8 +9,8 @@ from core_database import get_db
import config import config
router = APIRouter(prefix='/local', tags=['local']) router = APIRouter(prefix="/local", tags=["local"])
router.model_whitelist = ['LDJ', 'KDZ', 'JDZ'] router.model_whitelist = ["LDJ", "KDZ", "JDZ"]
class ClearFlags(IntEnum): class ClearFlags(IntEnum):
@ -24,129 +24,137 @@ class ClearFlags(IntEnum):
FULL_COMBO = 7 FULL_COMBO = 7
@router.post('/{gameinfo}/music/getrank') @router.post("/{gameinfo}/music/getrank")
async def music_getrank(request: Request): async def music_getrank(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
iidxid = int(request_info['root'][0].attrib['iidxid']) iidxid = int(request_info["root"][0].attrib["iidxid"])
play_style = int(request_info['root'][0].attrib['cltype']) play_style = int(request_info["root"][0].attrib["cltype"])
all_scores = {} all_scores = {}
db = get_db() db = get_db()
for record in db.table('iidx_scores_best').search( for record in db.table("iidx_scores_best").search(
(where('music_id') < (game_version + 1) * 1000) (where("music_id") < (game_version + 1) * 1000)
& (where('iidx_id') == iidxid) & (where("iidx_id") == iidxid)
& (where('play_style') == play_style) & (where("play_style") == play_style)
): ):
music_id = record['music_id'] music_id = record["music_id"]
clear_flg = record['clear_flg'] clear_flg = record["clear_flg"]
if game_version < 20: if game_version < 20:
m = str(music_id) m = str(music_id)
music_id = int(''.join([m[:len(m)-3], m[-2:]])) music_id = int("".join([m[: len(m) - 3], m[-2:]]))
if clear_flg == ClearFlags.FULL_COMBO and game_version < 19: if clear_flg == ClearFlags.FULL_COMBO and game_version < 19:
clear_flg = 6 clear_flg = 6
ex_score = record['ex_score'] ex_score = record["ex_score"]
miss_count = record['miss_count'] miss_count = record["miss_count"]
cid = record['chart_id'] cid = record["chart_id"]
if cid in (0, 4, 5, 9): if cid in (0, 4, 5, 9):
continue continue
chart_id = cid - 1 chart_id = cid - 1
if music_id not in all_scores: if music_id not in all_scores:
all_scores[music_id] = { all_scores[music_id] = {
0: {'clear_flg': -1, 'ex_score': -1, 'miss_count': -1}, 0: {"clear_flg": -1, "ex_score": -1, "miss_count": -1},
1: {'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}, 2: {"clear_flg": -1, "ex_score": -1, "miss_count": -1},
} }
all_scores[music_id][chart_id]['clear_flg'] = clear_flg all_scores[music_id][chart_id]["clear_flg"] = clear_flg
all_scores[music_id][chart_id]['ex_score'] = ex_score all_scores[music_id][chart_id]["ex_score"] = ex_score
all_scores[music_id][chart_id]['miss_count'] = miss_count all_scores[music_id][chart_id]["miss_count"] = miss_count
response = E.response( response = E.response(
E.music( E.music(
E.style(type=play_style), E.style(type=play_style),
*[E.m([ *[
-1, E.m(
k, [
*[all_scores[k][d]['clear_flg'] for d in range(3)], -1,
*[all_scores[k][d]['ex_score'] for d in range(3)], k,
*[all_scores[k][d]['miss_count'] for d in range(3)], *[all_scores[k][d]["clear_flg"] for d in range(3)],
], __type='s16') for k in all_scores] *[all_scores[k][d]["ex_score"] for d in range(3)],
*[all_scores[k][d]["miss_count"] for d in range(3)],
],
__type="s16",
)
for k in all_scores
]
) )
) )
assert (response is not None) assert response is not None
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/music/crate') @router.post("/{gameinfo}/music/crate")
async def music_crate(request: Request): async def music_crate(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
db = get_db() db = get_db()
all_score_stats = db.table('iidx_score_stats').search( all_score_stats = db.table("iidx_score_stats").search(
(where('music_id') < (game_version + 1) * 1000) (where("music_id") < (game_version + 1) * 1000)
) )
crate = {} crate = {}
fcrate = {} fcrate = {}
for stat in all_score_stats: for stat in all_score_stats:
if game_version < 20: if game_version < 20:
m = str(stat['music_id']) m = str(stat["music_id"])
stat['music_id'] = int(''.join([m[:len(m)-3], m[-2:]])) stat["music_id"] = int("".join([m[: len(m) - 3], m[-2:]]))
if stat['music_id'] not in crate: if stat["music_id"] not in crate:
crate[stat['music_id']] = [101] * 6 crate[stat["music_id"]] = [101] * 6
if stat['music_id'] not in fcrate: if stat["music_id"] not in fcrate:
fcrate[stat['music_id']] = [101] * 6 fcrate[stat["music_id"]] = [101] * 6
if stat['play_style'] == 0: if stat["play_style"] == 0:
old_to_new_adjust = -1 old_to_new_adjust = -1
elif stat['play_style'] == 1: elif stat["play_style"] == 1:
old_to_new_adjust = 2 old_to_new_adjust = 2
crate[stat['music_id']][stat['chart_id'] + old_to_new_adjust] = int(stat['clear_rate']) // 10 crate[stat["music_id"]][stat["chart_id"] + old_to_new_adjust] = (
fcrate[stat['music_id']][stat['chart_id'] + old_to_new_adjust] = int(stat['fc_rate']) // 10 int(stat["clear_rate"]) // 10
)
fcrate[stat["music_id"]][stat["chart_id"] + old_to_new_adjust] = (
int(stat["fc_rate"]) // 10
)
response = E.response( response = E.response(
E.music( E.music(*[E.c(crate[k] + fcrate[k], mid=k, __type="u8") for k in crate])
*[E.c(crate[k] + fcrate[k], mid=k, __type="u8") for k in crate]
)
) )
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/music/reg') @router.post("/{gameinfo}/music/reg")
async def music_reg(request: Request): async def music_reg(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
timestamp = time.time() timestamp = time.time()
root = request_info['root'][0] root = request_info["root"][0]
clear_flg = int(root.attrib['cflg']) clear_flg = int(root.attrib["cflg"])
clid = int(root.attrib['clid']) clid = int(root.attrib["clid"])
great_num = int(root.attrib['gnum']) great_num = int(root.attrib["gnum"])
iidx_id = int(root.attrib['iidxid']) iidx_id = int(root.attrib["iidxid"])
miss_num = int(root.attrib['mnum']) miss_num = int(root.attrib["mnum"])
pgreat_num = int(root.attrib['pgnum']) pgreat_num = int(root.attrib["pgnum"])
pid = int(root.attrib['pid']) pid = int(root.attrib["pid"])
ex_score = (pgreat_num * 2) + great_num ex_score = (pgreat_num * 2) + great_num
if game_version == 20: if game_version == 20:
is_death = int(root.attrib['is_death']) is_death = int(root.attrib["is_death"])
music_id = int(root.attrib['mid']) music_id = int(root.attrib["mid"])
else: else:
is_death = 1 if clear_flg < ClearFlags.ASSIST_CLEAR else 0 is_death = 1 if clear_flg < ClearFlags.ASSIST_CLEAR else 0
m = str(root.attrib['mid']) m = str(root.attrib["mid"])
music_id = int('0'.join([m[:len(m)-2], m[-2:]])) music_id = int("0".join([m[: len(m) - 2], m[-2:]]))
if clear_flg == 6 and game_version < 19: if clear_flg == 6 and game_version < 19:
clear_flg = ClearFlags.FULL_COMBO clear_flg = ClearFlags.FULL_COMBO
@ -160,164 +168,171 @@ async def music_reg(request: Request):
ghost = root.find("ghost").text ghost = root.find("ghost").text
db = get_db() db = get_db()
db.table('iidx_scores').insert( db.table("iidx_scores").insert(
{ {
'timestamp': timestamp, "timestamp": timestamp,
'game_version': game_version, "game_version": game_version,
'iidx_id': iidx_id, "iidx_id": iidx_id,
'pid': pid, "pid": pid,
'clear_flg': clear_flg, "clear_flg": clear_flg,
'is_death': is_death, "is_death": is_death,
'music_id': music_id, "music_id": music_id,
'play_style': play_style, "play_style": play_style,
'chart_id': note_id, "chart_id": note_id,
'pgreat_num': pgreat_num, "pgreat_num": pgreat_num,
'great_num': great_num, "great_num": great_num,
'ex_score': ex_score, "ex_score": ex_score,
'miss_count': miss_num, "miss_count": miss_num,
'ghost': ghost, "ghost": ghost,
}, },
) )
best_score = db.table('iidx_scores_best').get( best_score = db.table("iidx_scores_best").get(
(where('iidx_id') == iidx_id) (where("iidx_id") == iidx_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == note_id) & (where("chart_id") == note_id)
) )
best_score = {} if best_score is None else best_score best_score = {} if best_score is None else best_score
if clear_flg < ClearFlags.EASY_CLEAR: if clear_flg < ClearFlags.EASY_CLEAR:
miss_num = -1 miss_num = -1
best_miss_count = best_score.get('miss_count', miss_num) best_miss_count = best_score.get("miss_count", miss_num)
if best_miss_count == -1: if best_miss_count == -1:
miss_count = max(miss_num, best_miss_count) miss_count = max(miss_num, best_miss_count)
elif clear_flg > ClearFlags.ASSIST_CLEAR: elif clear_flg > ClearFlags.ASSIST_CLEAR:
miss_count = min(miss_num, best_miss_count) miss_count = min(miss_num, best_miss_count)
else: else:
miss_count = best_miss_count miss_count = best_miss_count
best_ex_score = best_score.get('ex_score', ex_score) best_ex_score = best_score.get("ex_score", ex_score)
best_score_data = { best_score_data = {
'game_version': game_version, "game_version": game_version,
'iidx_id': iidx_id, "iidx_id": iidx_id,
'pid': pid, "pid": pid,
'play_style': play_style, "play_style": play_style,
'music_id': music_id, "music_id": music_id,
'chart_id': note_id, "chart_id": note_id,
'miss_count': miss_count, "miss_count": miss_count,
'ex_score': max(ex_score, best_ex_score), "ex_score": max(ex_score, best_ex_score),
'ghost': ghost if ex_score >= best_ex_score else best_score.get('ghost', ghost), "ghost": ghost if ex_score >= best_ex_score else best_score.get("ghost", ghost),
'ghost_gauge': best_score.get('ghost_gauge', 0), "ghost_gauge": best_score.get("ghost_gauge", 0),
'clear_flg': max(clear_flg, best_score.get('clear_flg', clear_flg)), "clear_flg": max(clear_flg, best_score.get("clear_flg", clear_flg)),
'gauge_type': best_score.get('gauge_type', 0), "gauge_type": best_score.get("gauge_type", 0),
} }
db.table('iidx_scores_best').upsert( db.table("iidx_scores_best").upsert(
best_score_data, best_score_data,
(where('iidx_id') == iidx_id) (where("iidx_id") == iidx_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == note_id) & (where("chart_id") == note_id),
) )
score_stats = db.table('iidx_score_stats').get( score_stats = db.table("iidx_score_stats").get(
(where('music_id') == music_id) (where("music_id") == music_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('chart_id') == note_id) & (where("chart_id") == note_id)
) )
score_stats = {} if score_stats is None else score_stats score_stats = {} if score_stats is None else score_stats
score_stats['game_version'] = game_version score_stats["game_version"] = game_version
score_stats['play_style'] = play_style score_stats["play_style"] = play_style
score_stats['music_id'] = music_id score_stats["music_id"] = music_id
score_stats['chart_id'] = note_id score_stats["chart_id"] = note_id
score_stats['play_count'] = score_stats.get('play_count', 0) + 1 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["fc_count"] = score_stats.get("fc_count", 0) + (
score_stats['clear_count'] = score_stats.get('clear_count', 0) + (1 if clear_flg >= ClearFlags.EASY_CLEAR else 0) 1 if clear_flg == ClearFlags.FULL_COMBO 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) 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( db.table("iidx_score_stats").upsert(
score_stats, score_stats,
(where('music_id') == music_id) (where("music_id") == music_id)
& (where('play_style') == play_style) & (where("play_style") == play_style)
& (where('chart_id') == note_id) & (where("chart_id") == note_id),
) )
ranklist_data = [] ranklist_data = []
ranklist_scores = db.table('iidx_scores_best').search( ranklist_scores = db.table("iidx_scores_best").search(
(where('play_style') == play_style) (where("play_style") == play_style)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == note_id) & (where("chart_id") == note_id)
) )
ranklist_scores = [] if ranklist_scores is None else ranklist_scores ranklist_scores = [] if ranklist_scores is None else ranklist_scores
ranklist_scores_ranked = [] ranklist_scores_ranked = []
for score in ranklist_scores: for score in ranklist_scores:
profile = db.table('iidx_profile').get(where('iidx_id') == score['iidx_id']) profile = db.table("iidx_profile").get(where("iidx_id") == score["iidx_id"])
if profile is None or str(game_version) not in profile['version']: if profile is None or str(game_version) not in profile["version"]:
continue continue
game_profile = profile['version'][str(game_version)] game_profile = profile["version"][str(game_version)]
ranklist_scores_ranked.append({ ranklist_scores_ranked.append(
'opname': config.arcade, {
'name': game_profile['djname'], "opname": config.arcade,
'pid': game_profile['region'], "name": game_profile["djname"],
'body': game_profile.get('body', 0), "pid": game_profile["region"],
'face': game_profile.get('face', 0), "body": game_profile.get("body", 0),
'hair': game_profile.get('hair', 0), "face": game_profile.get("face", 0),
'hand': game_profile.get('hand', 0), "hair": game_profile.get("hair", 0),
'head': game_profile.get('head', 0), "hand": game_profile.get("hand", 0),
'dgrade': game_profile['grade_double'], "head": game_profile.get("head", 0),
'sgrade': game_profile['grade_single'], "dgrade": game_profile["grade_double"],
'score': score['ex_score'], "sgrade": game_profile["grade_single"],
'iidx_id': score['iidx_id'], "score": score["ex_score"],
'clflg': score['clear_flg'], "iidx_id": score["iidx_id"],
'myFlg': score['iidx_id'] == 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) ranklist_scores_ranked = sorted(
ranklist_scores_ranked, key=lambda x: (x["clflg"], x["score"]), reverse=True
)
myRank = 0 myRank = 0
for rnum, score in enumerate(ranklist_scores_ranked): for rnum, score in enumerate(ranklist_scores_ranked):
r = E.data( r = E.data(
rnum=rnum + 1, rnum=rnum + 1,
opname=score['opname'], opname=score["opname"],
name=score['name'], name=score["name"],
pid=score['pid'], pid=score["pid"],
body=score['body'], body=score["body"],
face=score['face'], face=score["face"],
hair=score['hair'], hair=score["hair"],
hand=score['hand'], hand=score["hand"],
head=score['head'], head=score["head"],
dgrade=score['dgrade'], dgrade=score["dgrade"],
sgrade=score['sgrade'], sgrade=score["sgrade"],
score=score['score'], score=score["score"],
iidx_id=score['iidx_id'], iidx_id=score["iidx_id"],
clflg=score['clflg'], clflg=score["clflg"],
myFlg=score['myFlg'], myFlg=score["myFlg"],
achieve=0, achieve=0,
) )
ranklist_data.append(r) ranklist_data.append(r)
if score['myFlg']: if score["myFlg"]:
myRank = rnum + 1 myRank = rnum + 1
response = E.response( response = E.response(
E.music( E.music(
E.ranklist( E.ranklist(*ranklist_data, total_user_num=len(ranklist_data)),
*ranklist_data, E.shopdata(rank=myRank),
total_user_num=len(ranklist_data)
),
E.shopdata(
rank=myRank
),
clid=clid, clid=clid,
crate=score_stats['clear_rate'] // 10, crate=score_stats["clear_rate"] // 10,
frate=score_stats['fc_rate'] // 10, frate=score_stats["fc_rate"] // 10,
mid=music_id, mid=music_id,
) )
) )
@ -326,35 +341,33 @@ async def music_reg(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/music/appoint') @router.post("/{gameinfo}/music/appoint")
async def music_appoint(request: Request): async def music_appoint(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
iidxid = int(request_info['root'][0].attrib['iidxid']) iidxid = int(request_info["root"][0].attrib["iidxid"])
music_id = int(request_info['root'][0].attrib['mid']) music_id = int(request_info["root"][0].attrib["mid"])
chart_id = int(request_info['root'][0].attrib['clid']) chart_id = int(request_info["root"][0].attrib["clid"])
db = get_db() db = get_db()
record = db.table('iidx_scores_best').get( record = db.table("iidx_scores_best").get(
(where('iidx_id') == iidxid) (where("iidx_id") == iidxid)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('chart_id') == chart_id) & (where("chart_id") == chart_id)
) )
vals = [] vals = []
if record is not None: if record is not None:
vals.append(E.mydata( vals.append(
record['ghost'], E.mydata(
score=record['ex_score'], record["ghost"],
__type="bin", score=record["ex_score"],
__size=len(record['ghost']) // 2, __type="bin",
)) __size=len(record["ghost"]) // 2,
)
response = E.response(
E.music(
*vals
) )
)
response = E.response(E.music(*vals))
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

File diff suppressed because it is too large Load Diff

View File

@ -8,13 +8,11 @@ router = APIRouter(prefix="/local", tags=["local"])
router.model_whitelist = ["LDJ", "KDZ", "JDZ"] router.model_whitelist = ["LDJ", "KDZ", "JDZ"]
@router.post('/{gameinfo}/ranking/getranker') @router.post("/{gameinfo}/ranking/getranker")
async def ranking_getranker(request: Request): async def ranking_getranker(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.ranking())
E.ranking()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

View File

@ -8,7 +8,7 @@ router = APIRouter(prefix="/local", tags=["local"])
router.model_whitelist = ["LDJ", "KDZ", "JDZ"] router.model_whitelist = ["LDJ", "KDZ", "JDZ"]
@router.post('/{gameinfo}/shop/getname') @router.post("/{gameinfo}/shop/getname")
async def shop_getname(request: Request): async def shop_getname(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
@ -24,7 +24,7 @@ async def shop_getname(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/shop/getconvention') @router.post("/{gameinfo}/shop/getconvention")
async def shop_getconvention(request: Request): async def shop_getconvention(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
@ -44,26 +44,21 @@ async def shop_getconvention(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/shop/sentinfo') @router.post("/{gameinfo}/shop/sentinfo")
async def shop_sentinfo(request: Request): async def shop_sentinfo(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.shop())
E.shop()
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/shop/sendescapepackageinfo')
@router.post("/{gameinfo}/shop/sendescapepackageinfo")
async def shop_sendescapepackageinfo(request: Request): async def shop_sendescapepackageinfo(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(E.shop(expire=1200))
E.shop(
expire=1200
)
)
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)

View File

@ -8,8 +8,8 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["KFC"] router.model_whitelist = ["KFC"]
@router.post('/{gameinfo}/eventlog/write') @router.post("/{gameinfo}/eventlog/write")
async def eventlog_write(request: Request): async def sdvx_eventlog_write(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(

View File

@ -14,71 +14,67 @@ router.model_whitelist = ["KFC"]
def get_profile(cid): def get_profile(cid):
return get_db().table('sdvx_profile').get( return get_db().table("sdvx_profile").get(where("card") == cid)
where('card') == cid
)
def get_game_profile(cid, game_version): def get_game_profile(cid, game_version):
profile = get_profile(cid) profile = get_profile(cid)
return profile['version'].get(str(game_version), None) return profile["version"].get(str(game_version), None)
def get_id_from_profile(cid): def get_id_from_profile(cid):
profile = get_db().table('sdvx_profile').get( profile = get_db().table("sdvx_profile").get(where("card") == cid)
where('card') == cid
)
djid = "%08d" % profile['sdvx_id'] djid = "%08d" % profile["sdvx_id"]
djid_split = '-'.join([djid[:4], djid[4:]]) djid_split = "-".join([djid[:4], djid[4:]])
return profile['sdvx_id'], djid_split return profile["sdvx_id"], djid_split
@router.post('/{gameinfo}/game/sv6_common') @router.post("/{gameinfo}/game/sv6_common")
async def game_sv6_common(request: Request): async def game_sv6_common(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
event = [ event = [
'DEMOGAME_PLAY', "DEMOGAME_PLAY",
'MATCHING_MODE', "MATCHING_MODE",
'MATCHING_MODE_FREE_IP', "MATCHING_MODE_FREE_IP",
'LEVEL_LIMIT_EASING', "LEVEL_LIMIT_EASING",
'ACHIEVEMENT_ENABLE', "ACHIEVEMENT_ENABLE",
'APICAGACHADRAW\t30', "APICAGACHADRAW\t30",
'VOLFORCE_ENABLE', "VOLFORCE_ENABLE",
'AKANAME_ENABLE', "AKANAME_ENABLE",
'PAUSE_ONLINEUPDATE', "PAUSE_ONLINEUPDATE",
'CONTINUATION', "CONTINUATION",
'TENKAICHI_MODE', "TENKAICHI_MODE",
'QC_MODE', "QC_MODE",
'KAC_MODE', "KAC_MODE",
'APPEAL_CARD_GEN_PRICE\t100', # "APPEAL_CARD_GEN_PRICE\t100",
'APPEAL_CARD_GEN_NEW_PRICE\t200', # "APPEAL_CARD_GEN_NEW_PRICE\t200",
'APPEAL_CARD_UNLOCK\t0,20170914,0,20171014,0,20171116,0,20180201,0,20180607,0,20181206,0,20200326,0,20200611,4,10140732,6,10150431', # "APPEAL_CARD_UNLOCK\t0,20170914,0,20171014,0,20171116,0,20180201,0,20180607,0,20181206,0,20200326,0,20200611,4,10140732,6,10150431",
'FAVORITE_APPEALCARD_MAX\t200', "FAVORITE_APPEALCARD_MAX\t200",
'FAVORITE_MUSIC_MAX\t200', "FAVORITE_MUSIC_MAX\t200",
'EVENTDATE_APRILFOOL', "EVENTDATE_APRILFOOL",
'KONAMI_50TH_LOGO', "KONAMI_50TH_LOGO",
'OMEGA_ARS_ENABLE', "OMEGA_ARS_ENABLE",
'DISABLE_MONITOR_ID_CHECK', "DISABLE_MONITOR_ID_CHECK",
'SKILL_ANALYZER_ABLE', "SKILL_ANALYZER_ABLE",
'BLASTER_ABLE', "BLASTER_ABLE",
'STANDARD_UNLOCK_ENABLE', "STANDARD_UNLOCK_ENABLE",
'PLAYERJUDGEADJ_ENABLE', "PLAYERJUDGEADJ_ENABLE",
'MIXID_INPUT_ENABLE', "MIXID_INPUT_ENABLE",
'EVENTDATE_ONIGO', "EVENTDATE_ONIGO",
'EVENTDATE_GOTT', "EVENTDATE_GOTT",
'GENERATOR_ABLE', "GENERATOR_ABLE",
'CREW_SELECT_ABLE', "CREW_SELECT_ABLE",
'PREMIUM_TIME_ENABLE', "PREMIUM_TIME_ENABLE",
'OMEGA_ENABLE\t1,2,3,4,5,6,7,8,9', "OMEGA_ENABLE\t1,2,3,4,5,6,7,8,9",
'HEXA_ENABLE\t1,2,3,4,5', "HEXA_ENABLE\t1,2,3,4,5",
'MEGAMIX_ENABLE', "MEGAMIX_ENABLE",
'VALGENE_ENABLE', "VALGENE_ENABLE",
'ARENA_ENABLE', "ARENA_ENABLE",
'DISP_PASELI_BANNER', "DISP_PASELI_BANNER",
] ]
unlock = [] unlock = []
@ -89,16 +85,22 @@ async def game_sv6_common(request: Request):
response = E.response( response = E.response(
E.game( E.game(
E.event( E.event(
*[E.info( *[
E.event_id(s, __type="str"), E.info(
)for s in event], E.event_id(s, __type="str"),
)
for s in event
],
), ),
E.music_limited( E.music_limited(
*[E.info( *[
E.music_id(s[0], __type="s32"), E.info(
E.music_type(s[1], __type="u8"), E.music_id(s[0], __type="s32"),
E.limited(3, __type="u8"), E.music_type(s[1], __type="u8"),
)for s in unlock], E.limited(3, __type="u8"),
)
for s in unlock
],
), ),
) )
) )
@ -107,71 +109,68 @@ async def game_sv6_common(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/game/sv6_new') @router.post("/{gameinfo}/game/sv6_new")
async def game_sv6_new(request: Request): async def game_sv6_new(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
root = request_info['root'][0] root = request_info["root"][0]
dataid = root.find("dataid").text dataid = root.find("dataid").text
cardno = root.find("cardno").text cardno = root.find("cardno").text
name = root.find("name").text name = root.find("name").text
db = get_db().table('sdvx_profile') db = get_db().table("sdvx_profile")
all_profiles_for_card = db.get(Query().card == dataid) all_profiles_for_card = db.get(Query().card == dataid)
if all_profiles_for_card is None: if all_profiles_for_card is None:
all_profiles_for_card = { all_profiles_for_card = {"card": dataid, "version": {}}
'card': dataid,
'version': {}
}
if 'sdvx_id' not in all_profiles_for_card: if "sdvx_id" not in all_profiles_for_card:
sdvx_id = random.randint(10000000, 99999999) sdvx_id = random.randint(10000000, 99999999)
all_profiles_for_card['sdvx_id'] = sdvx_id all_profiles_for_card["sdvx_id"] = sdvx_id
all_profiles_for_card['version'][str(game_version)] = { all_profiles_for_card["version"][str(game_version)] = {
'game_version': game_version, "game_version": game_version,
'name': name, "name": name,
'appeal_id': 0, "appeal_id": 0,
'skill_level': 0, "skill_level": 0,
'skill_base_id': 0, "skill_base_id": 0,
'skill_name_id': 0, "skill_name_id": 0,
'earned_gamecoin_packet': 0, "earned_gamecoin_packet": 0,
'earned_gamecoin_block': 0, "earned_gamecoin_block": 0,
'earned_blaster_energy': 0, "earned_blaster_energy": 0,
'earned_extrack_energy': 0, "earned_extrack_energy": 0,
'used_packet_booster': 0, "used_packet_booster": 0,
'used_block_booster': 0, "used_block_booster": 0,
'hispeed': 0, "hispeed": 0,
'lanespeed': 0, "lanespeed": 0,
'gauge_option': 0, "gauge_option": 0,
'ars_option': 0, "ars_option": 0,
'notes_option': 0, "notes_option": 0,
'early_late_disp': 0, "early_late_disp": 0,
'draw_adjust': 0, "draw_adjust": 0,
'eff_c_left': 0, "eff_c_left": 0,
'eff_c_right': 1, "eff_c_right": 1,
'music_id': 0, "music_id": 0,
'music_type': 0, "music_type": 0,
'sort_type': 0, "sort_type": 0,
'narrow_down': 0, "narrow_down": 0,
'headphone': 1, "headphone": 1,
'print_count': 0, "print_count": 0,
'start_option': 0, "start_option": 0,
'bgm': 0, "bgm": 0,
'submonitor': 0, "submonitor": 0,
'nemsys': 0, "nemsys": 0,
'stampA': 0, "stampA": 0,
'stampB': 0, "stampB": 0,
'stampC': 0, "stampC": 0,
'stampD': 0, "stampD": 0,
'items': [], "items": [],
'params': [], "params": [],
} }
db.upsert(all_profiles_for_card, where('card') == dataid) db.upsert(all_profiles_for_card, where("card") == dataid)
response = E.response( response = E.response(
E.game( E.game(
@ -183,12 +182,12 @@ async def game_sv6_new(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/game/sv6_load') @router.post("/{gameinfo}/game/sv6_load")
async def game_sv6_load(request: Request): async def game_sv6_load(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
dataid = request_info['root'][0].find("dataid").text dataid = request_info["root"][0].find("dataid").text
profile = get_game_profile(dataid, game_version) profile = get_game_profile(dataid, game_version)
if profile: if profile:
@ -200,28 +199,42 @@ async def game_sv6_load(request: Request):
for i in range(6001): for i in range(6001):
unlock.append([i, 1, 1]) unlock.append([i, 1, 1])
unlock.append([599, 4, 10]) unlock.append([599, 4, 10])
for item in profile['items']: for item in profile["items"]:
unlock.append(item) unlock.append(item)
customize = [[2, 2, [profile['bgm'], profile['submonitor'], profile['nemsys'], profile['stampA'], profile['stampB'], profile['stampC'], profile['stampD']]]] customize = [
for item in profile['params']: [
2,
2,
[
profile["bgm"],
profile["submonitor"],
profile["nemsys"],
profile["stampA"],
profile["stampB"],
profile["stampC"],
profile["stampD"],
],
]
]
for item in profile["params"]:
customize.append(item) customize.append(item)
response = E.response( response = E.response(
E.game( E.game(
E.result(0, __type="u8"), E.result(0, __type="u8"),
E.name(profile['name'], __type="str"), E.name(profile["name"], __type="str"),
E.code(djid_split, __type="str"), E.code(djid_split, __type="str"),
E.sdvx_id(djid_split, __type="str"), E.sdvx_id(djid_split, __type="str"),
E.appeal_id(profile['appeal_id'], __type="u16"), E.appeal_id(profile["appeal_id"], __type="u16"),
E.skill_level(profile['skill_level'], __type="s16"), E.skill_level(profile["skill_level"], __type="s16"),
E.skill_base_id(profile['skill_base_id'], __type="s16"), E.skill_base_id(profile["skill_base_id"], __type="s16"),
E.skill_name_id(profile['skill_name_id'], __type="s16"), E.skill_name_id(profile["skill_name_id"], __type="s16"),
E.gamecoin_packet(profile['earned_gamecoin_packet'], __type="u32"), E.gamecoin_packet(profile["earned_gamecoin_packet"], __type="u32"),
E.gamecoin_block(profile['earned_gamecoin_block'], __type="u32"), E.gamecoin_block(profile["earned_gamecoin_block"], __type="u32"),
E.blaster_energy(profile['earned_blaster_energy'], __type="u32"), E.blaster_energy(profile["earned_blaster_energy"], __type="u32"),
E.blaster_count(9999, __type="u32"), E.blaster_count(9999, __type="u32"),
E.extrack_energy(profile['earned_extrack_energy'], __type="u16"), E.extrack_energy(profile["earned_extrack_energy"], __type="u16"),
E.play_count(1001, __type="u32"), E.play_count(1001, __type="u32"),
E.day_count(301, __type="u32"), E.day_count(301, __type="u32"),
E.today_count(21, __type="u32"), E.today_count(21, __type="u32"),
@ -232,41 +245,49 @@ async def game_sv6_load(request: Request):
E.week_chain(31, __type="u32"), E.week_chain(31, __type="u32"),
E.max_week_chain(1001, __type="u32"), E.max_week_chain(1001, __type="u32"),
E.creator_id(1, __type="u32"), E.creator_id(1, __type="u32"),
E.eaappli( E.eaappli(E.relation(1, __type="s8")),
E.relation(1, __type="s8")
),
E.ea_shop( E.ea_shop(
E.blaster_pass_enable(1, __type="bool"), E.blaster_pass_enable(1, __type="bool"),
E.blaster_pass_limit_date(1605871200, __type="u64"), E.blaster_pass_limit_date(1605871200, __type="u64"),
), ),
E.kac_id(profile['name'], __type="str"), E.kac_id(profile["name"], __type="str"),
E.block_no(0, __type="s32"), E.block_no(0, __type="s32"),
E.volte_factory( E.volte_factory(
*[E.info( *[
E.goods_id(s, __type="s32"), E.info(
E.status(1, __type="s32"), E.goods_id(s, __type="s32"),
)for s in range(1, 999)], E.status(1, __type="s32"),
), )
*[E.campaign( for s in range(1, 999)
E.campaign_id(s, __type="s32"), ],
E.jackpot_flg(1, __type="bool"),
)for s in range(99)],
E.cloud(
E.relation(1, __type="s8")
), ),
*[
E.campaign(
E.campaign_id(s, __type="s32"),
E.jackpot_flg(1, __type="bool"),
)
for s in range(99)
],
E.cloud(E.relation(1, __type="s8")),
E.something( E.something(
*[E.info( *[
E.ranking_id(s[0], __type="s32"), E.info(
E.value(s[1], __type="s64"), E.ranking_id(s[0], __type="s32"),
)for s in [[1402, 20000]]], E.value(s[1], __type="s64"),
)
for s in [[1402, 20000]]
],
), ),
E.festival( E.festival(
E.fes_id(1, __type="s32"), E.fes_id(1, __type="s32"),
E.live_energy(1000000, __type="s32"), E.live_energy(1000000, __type="s32"),
*[E.bonus( *[
E.energy_type(s, __type="s32"), E.bonus(
E.live_energy(1000000, __type="s32"), E.energy_type(s, __type="s32"),
)for s in range(1, 6)], E.live_energy(1000000, __type="s32"),
)
for s in range(1, 6)
],
), ),
E.valgene_ticket( E.valgene_ticket(
E.ticket_num(0, __type="s32"), E.ticket_num(0, __type="s32"),
@ -281,33 +302,39 @@ async def game_sv6_load(request: Request):
E.rank_play_cnt(0, __type="s32"), E.rank_play_cnt(0, __type="s32"),
E.ultimate_play_cnt(0, __type="s32"), E.ultimate_play_cnt(0, __type="s32"),
), ),
E.hispeed(profile['hispeed'], __type="s32"), E.hispeed(profile["hispeed"], __type="s32"),
E.lanespeed(profile['lanespeed'], __type="u32"), E.lanespeed(profile["lanespeed"], __type="u32"),
E.gauge_option(profile['gauge_option'], __type="u8"), E.gauge_option(profile["gauge_option"], __type="u8"),
E.ars_option(profile['ars_option'], __type="u8"), E.ars_option(profile["ars_option"], __type="u8"),
E.notes_option(profile['notes_option'], __type="u8"), E.notes_option(profile["notes_option"], __type="u8"),
E.early_late_disp(profile['early_late_disp'], __type="u8"), E.early_late_disp(profile["early_late_disp"], __type="u8"),
E.draw_adjust(profile['draw_adjust'], __type="s32"), E.draw_adjust(profile["draw_adjust"], __type="s32"),
E.eff_c_left(profile['eff_c_left'], __type="u8"), E.eff_c_left(profile["eff_c_left"], __type="u8"),
E.eff_c_right(profile['eff_c_right'], __type="u8"), E.eff_c_right(profile["eff_c_right"], __type="u8"),
E.last_music_id(profile['music_id'], __type="s32"), E.last_music_id(profile["music_id"], __type="s32"),
E.last_music_type(profile['music_type'], __type="u8"), E.last_music_type(profile["music_type"], __type="u8"),
E.sort_type(profile['sort_type'], __type="u8"), E.sort_type(profile["sort_type"], __type="u8"),
E.narrow_down(profile['narrow_down'], __type="u8"), E.narrow_down(profile["narrow_down"], __type="u8"),
E.headphone(profile['headphone'], __type="u8"), E.headphone(profile["headphone"], __type="u8"),
E.item( E.item(
*[E.info( *[
E.id(s[0], __type="u32"), E.info(
E.type(s[1], __type="u8"), E.id(s[0], __type="u32"),
E.param(s[2], __type="u32"), E.type(s[1], __type="u8"),
)for s in unlock], E.param(s[2], __type="u32"),
)
for s in unlock
],
), ),
E.param( E.param(
*[E.info( *[
E.type(s[0], __type="s32"), E.info(
E.id(s[1], __type="s32"), E.type(s[0], __type="s32"),
E.param(s[2], __type="s32", __count=len(s[2])), E.id(s[1], __type="s32"),
)for s in customize], E.param(s[2], __type="s32", __count=len(s[2])),
)
for s in customize
],
), ),
), ),
) )
@ -323,51 +350,55 @@ async def game_sv6_load(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/game/sv6_load_m') @router.post("/{gameinfo}/game/sv6_load_m")
async def game_sv6_load_m(request: Request): async def game_sv6_load_m(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
dataid = request_info['root'][0].find("refid").text dataid = request_info["root"][0].find("refid").text
profile = get_game_profile(dataid, game_version) profile = get_game_profile(dataid, game_version)
djid, djid_split = get_id_from_profile(dataid) djid, djid_split = get_id_from_profile(dataid)
best_scores = [] best_scores = []
db = get_db() db = get_db()
for record in db.table('sdvx_scores_best').search( for record in db.table("sdvx_scores_best").search(
(where('game_version') == game_version) (where("game_version") == game_version) & (where("sdvx_id") == djid)
& (where('sdvx_id') == djid)
): ):
best_scores.append([ best_scores.append(
record['music_id'], [
record['music_type'], record["music_id"],
record['score'], record["music_type"],
record['exscore'], record["score"],
record['clear_type'], record["exscore"],
record['score_grade'], record["clear_type"],
0, record["score_grade"],
0, 0,
record['btn_rate'], 0,
record['long_rate'], record["btn_rate"],
record['vol_rate'], record["long_rate"],
0, record["vol_rate"],
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
]) 0,
]
)
response = E.response( response = E.response(
E.game( E.game(
E.music( E.music(
*[E.info( *[
E.param(x, __type="u32"), E.info(
)for x in best_scores], E.param(x, __type="u32"),
)
for x in best_scores
],
), ),
), ),
) )
@ -376,67 +407,79 @@ async def game_sv6_load_m(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/game/sv6_save') @router.post("/{gameinfo}/game/sv6_save")
async def game_sv6_save(request: Request): async def game_sv6_save(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
dataid = request_info['root'][0].find("refid").text dataid = request_info["root"][0].find("refid").text
profile = get_profile(dataid) profile = get_profile(dataid)
game_profile = profile['version'].get(str(game_version), {}) game_profile = profile["version"].get(str(game_version), {})
root = request_info['root'][0] root = request_info["root"][0]
game_profile['appeal_id'] = int(root.find('appeal_id').text) game_profile["appeal_id"] = int(root.find("appeal_id").text)
nodes = [ nodes = [
'appeal_id', "appeal_id",
'skill_level', "skill_level",
'skill_base_id', "skill_base_id",
'skill_name_id', "skill_name_id",
'earned_gamecoin_packet', "earned_gamecoin_packet",
'earned_gamecoin_block', "earned_gamecoin_block",
'earned_blaster_energy', "earned_blaster_energy",
'earned_extrack_energy', "earned_extrack_energy",
'hispeed', "hispeed",
'lanespeed', "lanespeed",
'gauge_option', "gauge_option",
'ars_option', "ars_option",
'notes_option', "notes_option",
'early_late_disp', "early_late_disp",
'draw_adjust', "draw_adjust",
'eff_c_left', "eff_c_left",
'eff_c_right', "eff_c_right",
'music_id', "music_id",
'music_type', "music_type",
'sort_type', "sort_type",
'narrow_down', "narrow_down",
'headphone', "headphone",
'start_option', "start_option",
] ]
for node in nodes: for node in nodes:
game_profile[node] = int(root.find(node).text) game_profile[node] = int(root.find(node).text)
game_profile['used_packet_booster'] = int(root.find('ea_shop')[0].text) game_profile["used_packet_booster"] = int(root.find("ea_shop")[0].text)
game_profile['used_block_booster'] = int(root.find('ea_shop')[1].text) game_profile["used_block_booster"] = int(root.find("ea_shop")[1].text)
game_profile['print_count'] = int(root.find('print')[0].text) game_profile["print_count"] = int(root.find("print")[0].text)
items = [] items = []
for info in root.find('item'): for info in root.find("item"):
items.append([int(info.find('id').text), int(info.find('type').text), int(info.find('param').text)]) items.append(
game_profile['items'] = items [
int(info.find("id").text),
int(info.find("type").text),
int(info.find("param").text),
]
)
game_profile["items"] = items
params = [] params = []
for info in root.find('param'): for info in root.find("param"):
p = info.find('param') p = info.find("param")
params.append([int(info.find('type').text), int(info.find('id').text), [int(x) for x in p.text.split(' ')]]) params.append(
game_profile['params'] = params [
int(info.find("type").text),
int(info.find("id").text),
[int(x) for x in p.text.split(" ")],
]
)
game_profile["params"] = params
profile['version'][str(game_version)] = game_profile profile["version"][str(game_version)] = game_profile
get_db().table('sdvx_profile').upsert(profile, where('card') == dataid) get_db().table("sdvx_profile").upsert(profile, where("card") == dataid)
response = E.response( response = E.response(
E.game(), E.game(),
@ -446,20 +489,19 @@ async def game_sv6_save(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/game/sv6_save_m') @router.post("/{gameinfo}/game/sv6_save_m")
async def game_sv6_save_m(request: Request): async def game_sv6_save_m(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
timestamp = time.time() timestamp = time.time()
root = request_info['root'][0] root = request_info["root"][0]
dataid = root.find("dataid").text dataid = root.find("dataid").text
profile = get_game_profile(dataid, game_version) profile = get_game_profile(dataid, game_version)
djid, djid_split = get_id_from_profile(dataid) djid, djid_split = get_id_from_profile(dataid)
track = root.find("track") track = root.find("track")
play_id = int(track.find("play_id").text) play_id = int(track.find("play_id").text)
music_id = int(track.find("music_id").text) music_id = int(track.find("music_id").text)
@ -484,70 +526,70 @@ async def game_sv6_save_m(request: Request):
local_num = int(track.find("local_num").text) local_num = int(track.find("local_num").text)
challenge_type = int(track.find("challenge_type").text) challenge_type = int(track.find("challenge_type").text)
retry_cnt = int(track.find("retry_cnt").text) retry_cnt = int(track.find("retry_cnt").text)
judge = [int(x) for x in track.find("judge").text.split(' ')] judge = [int(x) for x in track.find("judge").text.split(" ")]
db = get_db() db = get_db()
db.table('sdvx_scores').insert( db.table("sdvx_scores").insert(
{ {
'timestamp': timestamp, "timestamp": timestamp,
'game_version': game_version, "game_version": game_version,
'sdvx_id': djid, "sdvx_id": djid,
'play_id': play_id, "play_id": play_id,
'music_id': music_id, "music_id": music_id,
'music_type': music_type, "music_type": music_type,
'score': score, "score": score,
'exscore': exscore, "exscore": exscore,
'clear_type': clear_type, "clear_type": clear_type,
'score_grade': score_grade, "score_grade": score_grade,
'max_chain': max_chain, "max_chain": max_chain,
'just': just, "just": just,
'critical': critical, "critical": critical,
'near': near, "near": near,
'error': error, "error": error,
'effective_rate': effective_rate, "effective_rate": effective_rate,
'btn_rate': btn_rate, "btn_rate": btn_rate,
'long_rate': long_rate, "long_rate": long_rate,
'vol_rate': vol_rate, "vol_rate": vol_rate,
'mode': mode, "mode": mode,
'gauge_type': gauge_type, "gauge_type": gauge_type,
'notes_option': notes_option, "notes_option": notes_option,
'online_num': online_num, "online_num": online_num,
'local_num': local_num, "local_num": local_num,
'challenge_type': challenge_type, "challenge_type": challenge_type,
'retry_cnt': retry_cnt, "retry_cnt": retry_cnt,
'judge': judge, "judge": judge,
}, },
) )
best = db.table('sdvx_scores_best').get( best = db.table("sdvx_scores_best").get(
(where('sdvx_id') == djid) (where("sdvx_id") == djid)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('music_type') == music_type) & (where("music_type") == music_type)
) )
best = {} if best is None else best best = {} if best is None else best
best_score_data = { best_score_data = {
'game_version': game_version, "game_version": game_version,
'sdvx_id': djid, "sdvx_id": djid,
'name': profile['name'], "name": profile["name"],
'music_id': music_id, "music_id": music_id,
'music_type': music_type, "music_type": music_type,
'score': max(score, best.get('score', score)), "score": max(score, best.get("score", score)),
'exscore': max(exscore, best.get('exscore', exscore)), "exscore": max(exscore, best.get("exscore", exscore)),
'clear_type': max(clear_type, best.get('clear_type', clear_type)), "clear_type": max(clear_type, best.get("clear_type", clear_type)),
'score_grade': max(score_grade, best.get('score_grade', score_grade)), "score_grade": max(score_grade, best.get("score_grade", score_grade)),
'btn_rate': max(btn_rate, best.get('btn_rate', btn_rate)), "btn_rate": max(btn_rate, best.get("btn_rate", btn_rate)),
'long_rate': max(long_rate, best.get('long_rate', long_rate)), "long_rate": max(long_rate, best.get("long_rate", long_rate)),
'vol_rate': max(vol_rate, best.get('vol_rate', vol_rate)), "vol_rate": max(vol_rate, best.get("vol_rate", vol_rate)),
} }
db.table('sdvx_scores_best').upsert( db.table("sdvx_scores_best").upsert(
best_score_data, best_score_data,
(where('sdvx_id') == djid) (where("sdvx_id") == djid)
& (where('game_version') == game_version) & (where("game_version") == game_version)
& (where('music_id') == music_id) & (where("music_id") == music_id)
& (where('music_type') == music_type) & (where("music_type") == music_type),
) )
response = E.response( response = E.response(
@ -558,37 +600,42 @@ async def game_sv6_save_m(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/game/sv6_hiscore') @router.post("/{gameinfo}/game/sv6_hiscore")
async def game_sv6_hiscore(request: Request): async def game_sv6_hiscore(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
game_version = request_info['game_version'] game_version = request_info["game_version"]
best_scores = [] best_scores = []
db = get_db() db = get_db()
for record in db.table('sdvx_scores_best').search( for record in db.table("sdvx_scores_best").search(
(where('game_version') == game_version) (where("game_version") == game_version)
): ):
best_scores.append([ best_scores.append(
record['music_id'], [
record['music_type'], record["music_id"],
record['sdvx_id'], record["music_type"],
record['name'], record["sdvx_id"],
record['score'], record["name"],
]) record["score"],
]
)
response = E.response( response = E.response(
E.game( E.game(
E.sc( E.sc(
*[E.d( *[
E.id(s[0], __type="u32"), E.d(
E.ty(s[1], __type="u32"), E.id(s[0], __type="u32"),
E.a_sq(s[2], __type="str"), E.ty(s[1], __type="u32"),
E.a_nm(s[3], __type="str"), E.a_sq(s[2], __type="str"),
E.a_sc(s[4], __type="u32"), E.a_nm(s[3], __type="str"),
E.l_sq(s[2], __type="str"), E.a_sc(s[4], __type="u32"),
E.l_nm(s[3], __type="str"), E.l_sq(s[2], __type="str"),
E.l_sc(s[4], __type="u32"), E.l_nm(s[3], __type="str"),
)for s in best_scores], E.l_sc(s[4], __type="u32"),
)
for s in best_scores
],
), ),
), ),
) )
@ -597,28 +644,24 @@ async def game_sv6_hiscore(request: Request):
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/game/sv6_lounge') @router.post("/{gameinfo}/game/sv6_lounge")
async def game_sv6_lounge(request: Request): async def game_sv6_lounge(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(
E.game( E.game(E.interval(30, __type="u32")),
E.interval(30, __type="u32")
),
) )
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers) return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/game/sv6_shop') @router.post("/{gameinfo}/game/sv6_shop")
async def game_sv6_shop(request: Request): async def game_sv6_shop(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)
response = E.response( response = E.response(
E.game( E.game(E.nxt_time(1000 * 5 * 60, __type="u32")),
E.nxt_time(1000 * 5 * 60, __type="u32")
),
) )
response_body, response_headers = await core_prepare_response(request, response) response_body, response_headers = await core_prepare_response(request, response)
@ -626,17 +669,18 @@ async def game_sv6_shop(request: Request):
for stub in [ for stub in [
'load_r', "load_r",
'frozen', "frozen",
'save_e', "save_e",
'save_mega', "save_mega",
'play_e', "play_e",
'play_s', "play_s",
'entry_s', "entry_s",
'entry_e', "entry_e",
'log' "log",
]: ]:
@router.post(f'/{{gameinfo}}/game/sv6_{stub}')
@router.post(f"/{{gameinfo}}/game/sv6_{stub}")
async def game_sv6_stub(request: Request): async def game_sv6_stub(request: Request):
request_info = await core_process_request(request) request_info = await core_process_request(request)

View File

@ -10,12 +10,14 @@ import modules
from core_common import core_process_request, core_prepare_response, E from core_common import core_process_request, core_prepare_response, E
def urlpathjoin(parts, sep='/'): def urlpathjoin(parts, sep="/"):
return sep + sep.join([x.lstrip(sep) for x in parts]) return sep + sep.join([x.lstrip(sep) for x in parts])
server_address = f"{config.ip}:{config.port}" server_address = f"{config.ip}:{config.port}"
server_services_url = urlunparse(('http', server_address, config.services_prefix, None, None, None)) server_services_url = urlunparse(
("http", server_address, config.services_prefix, None, None, None)
)
keepalive_address = "127.0.0.1" keepalive_address = "127.0.0.1"
app = FastAPI() app = FastAPI()
@ -38,7 +40,7 @@ if __name__ == "__main__":
print("|____/ \__,_|___/_|_| |_|\___||___/___/") print("|____/ \__,_|___/_|_| |_|\___||___/___/")
print() print()
print(f"<services>{server_services_url}</services>") print(f"<services>{server_services_url}</services>")
print("<url_slash __type=\"bool\">1</url_slash>") print('<url_slash __type="bool">1</url_slash>')
print() print()
uvicorn.run("pyeamu:app", host=config.ip, port=config.port, reload=True) uvicorn.run("pyeamu:app", host=config.ip, port=config.port, reload=True)
@ -50,18 +52,20 @@ async def services_get(request: Request):
services = {} services = {}
for service in modules.routers: for service in modules.routers:
model_blacklist = services.get('model_blacklist', []) model_blacklist = services.get("model_blacklist", [])
model_whitelist = services.get('model_whitelist', []) model_whitelist = services.get("model_whitelist", [])
if request_info['model'] in model_blacklist: if request_info["model"] in model_blacklist:
continue continue
if model_whitelist and request_info['model'] not in model_whitelist: if model_whitelist and request_info["model"] not in model_whitelist:
continue continue
k = (service.tags[0] if service.tags else service.prefix).strip('/') k = (service.tags[0] if service.tags else service.prefix).strip("/")
if k not in services: if k not in services:
services[k] = urlunparse(('http', server_address, service.prefix, None, None, None)) services[k] = urlunparse(
("http", server_address, service.prefix, None, None, None)
)
keepalive_params = { keepalive_params = {
"pa": keepalive_address, "pa": keepalive_address,
@ -71,19 +75,27 @@ async def services_get(request: Request):
"t1": 2, "t1": 2,
"t2": 10, "t2": 10,
} }
services["keepalive"] = urlunparse(('http', keepalive_address, "/keepalive", None, urlencode(keepalive_params), None)) services["keepalive"] = urlunparse(
services["ntp"] = urlunparse(('ntp', "pool.ntp.org", "/", None, None, None)) (
services["services"] = urlunparse(('http', server_address, "/core", None, None, None)) "http",
keepalive_address,
"/keepalive",
None,
urlencode(keepalive_params),
None,
)
)
services["ntp"] = urlunparse(("ntp", "pool.ntp.org", "/", None, None, None))
services["services"] = urlunparse(
("http", server_address, "/core", None, None, None)
)
response = E.response( response = E.response(
E.services( E.services(
expire=10800, expire=10800,
mode='operation', mode="operation",
product_domain=1, product_domain=1,
*[E.item( *[E.item(name=k, url=services[k]) for k in services],
name=k,
url=services[k]
) for k in services]
) )
) )

View File

@ -1,16 +1,18 @@
anyio anyio==3.6.2
asgiref asgiref==3.5.2
click click==8.1.3
colorama colorama==0.4.6
fastapi fastapi==0.86.0
h11 h11==0.14.0
idna idna==3.4
kbinxml kbinxml==1.7
lxml lxml==4.9.1
pycryptodomex pycryptodomex==3.15.0
pydantic pydantic==1.10.2
sniffio python-multipart==0.0.5
starlette six==1.16.0
tinydb sniffio==1.3.0
typing_extensions starlette==0.20.4
uvicorn tinydb==4.7.0
typing_extensions==4.4.0
uvicorn==0.19.0

View File

@ -3,9 +3,10 @@ from Cryptodome.Hash import MD5
class EamuseARC4: class EamuseARC4:
def __init__(self, eamuseKey): def __init__(self, eamuseKey):
self.internal_key = bytearray.fromhex("69D74627D985EE2187161570D08D93B12455035B6DF0D8205DF5") self.internal_key = bytearray.fromhex(
"69D74627D985EE2187161570D08D93B12455035B6DF0D8205DF5"
)
self.key = MD5.new(eamuseKey + self.internal_key).digest() self.key = MD5.new(eamuseKey + self.internal_key).digest()
def decrypt(self, data): def decrypt(self, data):

View File

@ -30,14 +30,14 @@ def pack_5(data):
data = "".join(f"{i:05b}" for i in data) data = "".join(f"{i:05b}" for i in data)
if len(data) % 8 != 0: if len(data) % 8 != 0:
data += "0" * (8 - (len(data) % 8)) data += "0" * (8 - (len(data) % 8))
return bytes(int(data[i:i+8], 2) for i in range(0, len(data), 8)) return bytes(int(data[i : i + 8], 2) for i in range(0, len(data), 8))
def unpack_5(data): def unpack_5(data):
data = "".join(f"{i:08b}" for i in data) data = "".join(f"{i:08b}" for i in data)
if len(data) % 5 != 0: if len(data) % 5 != 0:
data += "0" * (5 - (len(data) % 5)) data += "0" * (5 - (len(data) % 5))
return bytes(int(data[i:i+5], 2) for i in range(0, len(data), 5)) return bytes(int(data[i : i + 5], 2) for i in range(0, len(data), 5))
def to_konami_id(uid): def to_konami_id(uid):
@ -74,7 +74,9 @@ def to_uid(konami_id):
raise ValueError("Invalid ID") raise ValueError("Invalid ID")
assert len(konami_id) == 16, f"ID must be 16 characters" assert len(konami_id) == 16, f"ID must be 16 characters"
assert all(i in valid_characters for i in konami_id), "ID contains invalid characters" assert all(
i in valid_characters for i in konami_id
), "ID contains invalid characters"
card = [valid_characters.index(i) for i in konami_id] card = [valid_characters.index(i) for i in konami_id]
assert card[11] % 2 == card[12] % 2, "Parity check failed" assert card[11] % 2 == card[12] % 2, "Parity check failed"
assert card[13] == card[12] ^ 1, "Card invalid" assert card[13] == card[12] ^ 1, "Card invalid"
@ -98,4 +100,6 @@ def to_uid(konami_id):
if __name__ == "__main__": if __name__ == "__main__":
assert to_konami_id("0000000000000000") == "007TUT8XJNSSPN2P", "To KID failed" assert to_konami_id("0000000000000000") == "007TUT8XJNSSPN2P", "To KID failed"
assert to_uid("007TUT8XJNSSPN2P") == "0000000000000000", "From KID failed" assert to_uid("007TUT8XJNSSPN2P") == "0000000000000000", "From KID failed"
assert to_uid(to_konami_id("000000100200F000")) == "000000100200F000", "Roundtrip failed" assert (
to_uid(to_konami_id("000000100200F000")) == "000000100200F000"
), "Roundtrip failed"

View File

@ -14,8 +14,8 @@ class EamuseLZ77:
else: else:
if offset >= data_length: if offset >= data_length:
break break
lookback_flag = int.from_bytes(data[offset:offset+2], 'big') lookback_flag = int.from_bytes(data[offset : offset + 2], "big")
lookback_length = (lookback_flag & 0x000f) + 3 lookback_length = (lookback_flag & 0x000F) + 3
lookback_offset = lookback_flag >> 4 lookback_offset = lookback_flag >> 4
offset += 2 offset += 2
if lookback_flag == 0: if lookback_flag == 0: