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
db.json
*.db
/db*.json
/*.db
.venv/
webui/

View File

@ -1,18 +1,21 @@
# 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:
`pip install -U -r requirements.txt`
**don't host it publicly as-is**
`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 A3
- IIDX 18 Resort Anthem
@ -20,4 +23,4 @@ Edit services url and enable url_slash
- IIDX 20 tricoro
- IIDX 29 CastHour
- 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.settimeout(0)
try:
s.connect(('10.254.254.254', 1))
s.connect(("10.254.254.254", 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
IP = "127.0.0.1"
finally:
s.close()
return IP
ip = get_ip()
port = 8000
services_prefix = "/core"

View File

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

View File

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

View File

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

View File

@ -21,12 +21,12 @@ def get_target_table(game_id):
def get_profile(game_id, cid):
target_table = get_target_table(game_id)
profile = get_db().table(target_table).get(where('card') == cid)
profile = get_db().table(target_table).get(where("card") == cid)
if profile is None:
profile = {
'card': cid,
'version': {},
"card": cid,
"version": {},
}
return profile
@ -35,43 +35,41 @@ def get_profile(game_id, cid):
def get_game_profile(game_id, game_version, cid):
profile = get_profile(game_id, cid)
if str(game_version) not in profile['version']:
profile['version'][str(game_version)] = {}
if str(game_version) not in profile["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):
target_table = get_target_table(game_id)
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):
request_info = await core_process_request(request)
cid = request_info['root'][0].attrib['refid']
passwd = request_info['root'][0].attrib['pass']
cid = request_info["root"][0].attrib["refid"]
passwd = request_info["root"][0].attrib["pass"]
profile = get_profile(request_info['model'], cid)
if profile is None or passwd != profile.get('pin', None):
profile = get_profile(request_info["model"], cid)
if profile is None or passwd != profile.get("pin", None):
status = 116
else:
status = 0
response = E.response(
E.authpass(status=status)
)
response = E.response(E.authpass(status=status))
response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/cardmng/bindmodel')
@router.post("/{gameinfo}/cardmng/bindmodel")
async def cardmng_bindmodel(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)
@router.post('/{gameinfo}/cardmng/getrefid')
@router.post("/{gameinfo}/cardmng/getrefid")
async def cardmng_getrefid(request: Request):
request_info = await core_process_request(request)
cid = request_info['root'][0].attrib['cardid']
passwd = request_info['root'][0].attrib['passwd']
cid = request_info["root"][0].attrib["cardid"]
passwd = request_info["root"][0].attrib["passwd"]
create_profile(request_info['model'], request_info['game_version'], cid, passwd)
create_profile(request_info["model"], request_info["game_version"], cid, passwd)
response = E.response(
E.getrefid(
@ -105,13 +103,13 @@ async def cardmng_getrefid(request: Request):
return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/cardmng/inquire')
@router.post("/{gameinfo}/cardmng/inquire")
async def cardmng_inquire(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:
binded = 1
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.post('/{gameinfo}/eacoin/checkin')
@router.post("/{gameinfo}/eacoin/checkin")
async def eacoin_checkin(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)
@router.post('/{gameinfo}/eacoin/consume')
@router.post("/{gameinfo}/eacoin/consume")
async def eacoin_consume(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)
@router.post('/{gameinfo}/eacoin/getbalance')
@router.post("/{gameinfo}/eacoin/getbalance")
async def eacoin_getbalance(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.post('/{gameinfo}/facility/get')
@router.post("/{gameinfo}/facility/get")
async def facility_get(request: Request):
request_info = await core_process_request(request)
response = E.response(
E.facility(
E.location(
E('id', 'EA000001', __type="str"),
E.country('JP', __type="str"),
E.region('JP-13', __type="str"),
E.customercode('X000000001', __type="str"),
E.companycode('X000000001', __type="str"),
E("id", "EA000001", __type="str"),
E.country("JP", __type="str"),
E.region("JP-13", __type="str"),
E.customercode("X000000001", __type="str"),
E.companycode("X000000001", __type="str"),
E.latitude(0, __type="s32"),
E.longitude(0, __type="s32"),
E.accuracy(0, __type="u8"),
E.countryname('Japan', __type="str"),
E.regionname('Tokyo', __type="str"),
E.countryjname('日本国', __type="str"),
E.regionjname('東京都', __type="str"),
E.countryname("Japan", __type="str"),
E.regionname("Tokyo", __type="str"),
E.countryjname("日本国", __type="str"),
E.regionjname("東京都", __type="str"),
E.name(config.arcade, __type="str"),
E('type', 255, __type="u8"),
E("type", 255, __type="u8"),
),
E.line(
E('class', 8, __type="u8"),
E("class", 8, __type="u8"),
E.rtt(500, __type="u16"),
E.upclass(8, __type="u8"),
E('id', 3, __type="str"),
E("id", 3, __type="str"),
),
E.portfw(
E.globalip(config.ip, __type="ip4"),
@ -56,11 +56,11 @@ async def facility_get(request: Request):
E.valid(365, __type="u16"),
),
E.url(
E.eapass('www.ea-pass.konami.net', __type="str"),
E.arcadefan('www.konami.jp/am', __type="str"),
E.konaminetdx('http://am.573.jp', __type="str"),
E.konamiid('https://id.konami.net', __type="str"),
E.eagate('http://eagate.573.jp', __type="str"),
E.eapass("www.ea-pass.konami.net", __type="str"),
E.arcadefan("www.konami.jp/am", __type="str"),
E.konaminetdx("http://am.573.jp", __type="str"),
E.konamiid("https://id.konami.net", __type="str"),
E.eagate("http://eagate.573.jp", __type="str"),
),
),
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.post('/{gameinfo}/message/get')
@router.post("/{gameinfo}/message/get")
async def message_get(request: Request):
request_info = await core_process_request(request)
response = E.response(
E.message(
expire=300,
*[E.item(
name=s,
start=0,
end=604800,
) for s in ('sys.mainte', 'sys.eacoin.mainte') if config.maintenance_mode]
*[
E.item(
name=s,
start=0,
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.post('/{gameinfo}/package/list')
@router.post("/{gameinfo}/package/list")
async def package_list(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.post('/{gameinfo}/pcbevent/put')
@router.post("/{gameinfo}/pcbevent/put")
async def pcbevent_put(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.post('/{gameinfo}/pcbtracker/alive')
@router.post("/{gameinfo}/pcbtracker/alive")
async def pcbtracker_alive(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.post('/{gameinfo}/eventlog/write')
async def eventlog_write(request: Request):
@router.post("/{gameinfo}/eventlog/write")
async def ddr_eventlog_write(request: Request):
request_info = await core_process_request(request)
response = E.response(

View File

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

View File

@ -17,92 +17,98 @@ router.model_whitelist = ["MDX"]
def get_profile(cid):
return get_db().table('ddr_profile').get(
where('card') == cid
)
return get_db().table("ddr_profile").get(where("card") == cid)
def get_game_profile(cid, game_version):
profile = get_profile(cid)
return profile['version'].get(str(game_version), None)
return profile["version"].get(str(game_version), None)
def get_common(ddr_id, game_version, idx):
profile = get_db().table('ddr_profile').get(
where('ddr_id') == int(ddr_id)
)
profile = get_db().table("ddr_profile").get(where("ddr_id") == int(ddr_id))
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:
return 0
@router.post('/{gameinfo}/playerdata/usergamedata_advanced')
@router.post("/{gameinfo}/playerdata/usergamedata_advanced")
async def usergamedata_advanced(request: Request):
request_info = await core_process_request(request)
game_version = request_info['game_version']
is_omni = True if request_info['rev'] == 'O' else False
game_version = request_info["game_version"]
is_omni = True if request_info["rev"] == "O" else False
response = None
data = request_info['root'][0].find('data')
mode = data.find('mode').text
gamesession = data.find('gamesession').text
refid = data.find('refid').text
default = 'X0000000000000000000000000000000'[:-len(gamesession)]+gamesession
data = request_info["root"][0].find("data")
mode = data.find("mode").text
gamesession = data.find("gamesession").text
refid = data.find("refid").text
default = "X0000000000000000000000000000000"[: -len(gamesession)] + gamesession
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':
shoparea = data.find('shoparea').text
if mode == "usernew":
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)
all_profiles_for_card['ddr_id'] = ddr_id
all_profiles_for_card["ddr_id"] = ddr_id
all_profiles_for_card['version'][str(game_version)] = {
'game_version': game_version,
'calories_disp': "Off",
'character': "All Character Random",
'arrow_skin': "Normal",
'filter': "Darkest",
'guideline': "Center",
'priority': "Judgment",
'timing_disp': "On",
'rival_1_ddr_id': 0,
'rival_2_ddr_id': 0,
'rival_3_ddr_id': 0,
'single_grade': 0,
'double_grade': 0,
all_profiles_for_card["version"][str(game_version)] = {
"game_version": game_version,
"calories_disp": "Off",
"character": "All Character Random",
"arrow_skin": "Normal",
"filter": "Darkest",
"guideline": "Center",
"priority": "Judgment",
"timing_disp": "On",
"rival_1_ddr_id": 0,
"rival_2_ddr_id": 0,
"rival_3_ddr_id": 0,
"single_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(
E.playerdata(
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.shoparea(shoparea, __type="str")
E.shoparea(shoparea, __type="str"),
)
)
elif mode == 'userload' and refid != default:
elif mode == "userload" and refid != default:
all_scores = {}
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)
single_grade = profile.get('single_grade', 0)
double_grade = profile.get('double_grade', 0)
single_grade = profile.get("single_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)):
mcode = record['mcode']
difficulty = record['difficulty']
for record in db.table("ddr_scores_best").search(
(where("game_version") == game_version) & (where("ddr_id") == ddr_id)
):
mcode = record["mcode"]
difficulty = record["difficulty"]
if mcode not in all_scores:
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(
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_refid_locked(0, __type="bool"),
E.eventdata_count_all(1, __type="s16"),
*[E.music(
E.mcode(int(mcode), __type="u32"),
*[E.note(
E.count(s[0], __type="u16"),
E.rank(s[1], __type="u8"),
E.clearkind(s[2], __type="u8"),
E.score(s[3], __type="s32"),
E.ghostid(s[4], __type="s32"),
) for s in [score for score in all_scores.get(mcode)]],
) for mcode in all_scores.keys()],
*[E.eventdata(
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.music(
E.mcode(int(mcode), __type="u32"),
*[
E.note(
E.count(s[0], __type="u16"),
E.rank(s[1], __type="u8"),
E.clearkind(s[2], __type="u8"),
E.score(s[3], __type="s32"),
E.ghostid(s[4], __type="s32"),
)
for s in [score for score in all_scores.get(mcode)]
],
)
for mcode in all_scores.keys()
],
*[
E.eventdata(
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.single_grade(single_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.notetype(0, __type="s8"),
E.playstyle(0, __type="s32"),
)
),
),
E.preplayable(),
)
)
elif mode == 'ghostload':
ghostid = int(data.find('ghostid').text)
record = db.table('ddr_scores').get(doc_id=ghostid)
elif mode == "ghostload":
ghostid = int(data.find("ghostid").text)
record = db.table("ddr_scores").get(doc_id=ghostid)
response = E.response(
E.playerdata(
E.result(0, __type="s32"),
E.ghostdata(
E.code(record['ddr_id'], __type="s32"),
E.mcode(record['mcode'], __type="u32"),
E.notetype(record['difficulty'], __type="u8"),
E.ghostsize(record['ghostsize'], __type="s32"),
E.ghost(record['ghost'], __type="string"),
)
E.code(record["ddr_id"], __type="s32"),
E.mcode(record["mcode"], __type="u32"),
E.notetype(record["difficulty"], __type="u8"),
E.ghostsize(record["ghostsize"], __type="s32"),
E.ghost(record["ghost"], __type="string"),
),
)
)
elif mode == 'usersave' and refid != default:
elif mode == "usersave" and refid != default:
timestamp = time.time()
ddr_id = int(data.find('ddrcode').text)
playstyle = int(data.find('playstyle').text)
pcbid = data.find('pcbid').text
shoparea = data.find('shoparea').text
note = data.findall('note')
ddr_id = int(data.find("ddrcode").text)
playstyle = int(data.find("playstyle").text)
pcbid = data.find("pcbid").text
shoparea = data.find("shoparea").text
if int(data.find('isgameover').text) == 0:
note = data.findall("note")
if int(data.find("isgameover").text) == 0:
for n in note:
if int(n.find('stagenum').text) != 0:
mcode = int(n.find('mcode').text)
difficulty = int(n.find('notetype').text)
rank = int(n.find('rank').text)
lamp = int(n.find('clearkind').text)
score = int(n.find('score').text)
exscore = int(n.find('exscore').text)
maxcombo = int(n.find('maxcombo').text)
life = int(n.find('life').text)
fastcount = int(n.find('fastcount').text)
slowcount = int(n.find('slowcount').text)
judge_marvelous = int(n.find('judge_marvelous').text)
judge_perfect = int(n.find('judge_perfect').text)
judge_great = int(n.find('judge_great').text)
judge_good = int(n.find('judge_good').text)
judge_boo = int(n.find('judge_boo').text)
judge_miss = int(n.find('judge_miss').text)
judge_ok = int(n.find('judge_ok').text)
judge_ng = int(n.find('judge_ng').text)
calorie = int(n.find('calorie').text)
ghostsize = int(n.find('ghostsize').text)
ghost = n.find('ghost').text
opt_speed = int(n.find('opt_speed').text)
opt_boost = int(n.find('opt_boost').text)
opt_appearance = int(n.find('opt_appearance').text)
opt_turn = int(n.find('opt_turn').text)
opt_dark = int(n.find('opt_dark').text)
opt_scroll = int(n.find('opt_scroll').text)
opt_arrowcolor = int(n.find('opt_arrowcolor').text)
opt_cut = int(n.find('opt_cut').text)
opt_freeze = int(n.find('opt_freeze').text)
opt_jump = int(n.find('opt_jump').text)
opt_arrowshape = int(n.find('opt_arrowshape').text)
opt_filter = int(n.find('opt_filter').text)
opt_guideline = int(n.find('opt_guideline').text)
opt_gauge = int(n.find('opt_gauge').text)
opt_judgepriority = int(n.find('opt_judgepriority').text)
opt_timing = int(n.find('opt_timing').text)
if int(n.find("stagenum").text) != 0:
mcode = int(n.find("mcode").text)
difficulty = int(n.find("notetype").text)
rank = int(n.find("rank").text)
lamp = int(n.find("clearkind").text)
score = int(n.find("score").text)
exscore = int(n.find("exscore").text)
maxcombo = int(n.find("maxcombo").text)
life = int(n.find("life").text)
fastcount = int(n.find("fastcount").text)
slowcount = int(n.find("slowcount").text)
judge_marvelous = int(n.find("judge_marvelous").text)
judge_perfect = int(n.find("judge_perfect").text)
judge_great = int(n.find("judge_great").text)
judge_good = int(n.find("judge_good").text)
judge_boo = int(n.find("judge_boo").text)
judge_miss = int(n.find("judge_miss").text)
judge_ok = int(n.find("judge_ok").text)
judge_ng = int(n.find("judge_ng").text)
calorie = int(n.find("calorie").text)
ghostsize = int(n.find("ghostsize").text)
ghost = n.find("ghost").text
opt_speed = int(n.find("opt_speed").text)
opt_boost = int(n.find("opt_boost").text)
opt_appearance = int(n.find("opt_appearance").text)
opt_turn = int(n.find("opt_turn").text)
opt_dark = int(n.find("opt_dark").text)
opt_scroll = int(n.find("opt_scroll").text)
opt_arrowcolor = int(n.find("opt_arrowcolor").text)
opt_cut = int(n.find("opt_cut").text)
opt_freeze = int(n.find("opt_freeze").text)
opt_jump = int(n.find("opt_jump").text)
opt_arrowshape = int(n.find("opt_arrowshape").text)
opt_filter = int(n.find("opt_filter").text)
opt_guideline = int(n.find("opt_guideline").text)
opt_gauge = int(n.find("opt_gauge").text)
opt_judgepriority = int(n.find("opt_judgepriority").text)
opt_timing = int(n.find("opt_timing").text)
db.table('ddr_scores').insert(
db.table("ddr_scores").insert(
{
'timestamp': timestamp,
'pcbid': pcbid,
'shoparea': shoparea,
'game_version': game_version,
'ddr_id': ddr_id,
'playstyle': playstyle,
'mcode': mcode,
'difficulty': difficulty,
'rank': rank,
'lamp': lamp,
'score': score,
'exscore': exscore,
'maxcombo': maxcombo,
'life': life,
'fastcount': fastcount,
'slowcount': slowcount,
'judge_marvelous': judge_marvelous,
'judge_perfect': judge_perfect,
'judge_great': judge_great,
'judge_good': judge_good,
'judge_boo': judge_boo,
'judge_miss': judge_miss,
'judge_ok': judge_ok,
'judge_ng': judge_ng,
'calorie': calorie,
'ghostsize': ghostsize,
'ghost': ghost,
'opt_speed': opt_speed,
'opt_boost': opt_boost,
'opt_appearance': opt_appearance,
'opt_turn': opt_turn,
'opt_dark': opt_dark,
'opt_scroll': opt_scroll,
'opt_arrowcolor': opt_arrowcolor,
'opt_cut': opt_cut,
'opt_freeze': opt_freeze,
'opt_jump': opt_jump,
'opt_arrowshape': opt_arrowshape,
'opt_filter': opt_filter,
'opt_guideline': opt_guideline,
'opt_gauge': opt_gauge,
'opt_judgepriority': opt_judgepriority,
'opt_timing': opt_timing,
"timestamp": timestamp,
"pcbid": pcbid,
"shoparea": shoparea,
"game_version": game_version,
"ddr_id": ddr_id,
"playstyle": playstyle,
"mcode": mcode,
"difficulty": difficulty,
"rank": rank,
"lamp": lamp,
"score": score,
"exscore": exscore,
"maxcombo": maxcombo,
"life": life,
"fastcount": fastcount,
"slowcount": slowcount,
"judge_marvelous": judge_marvelous,
"judge_perfect": judge_perfect,
"judge_great": judge_great,
"judge_good": judge_good,
"judge_boo": judge_boo,
"judge_miss": judge_miss,
"judge_ok": judge_ok,
"judge_ng": judge_ng,
"calorie": calorie,
"ghostsize": ghostsize,
"ghost": ghost,
"opt_speed": opt_speed,
"opt_boost": opt_boost,
"opt_appearance": opt_appearance,
"opt_turn": opt_turn,
"opt_dark": opt_dark,
"opt_scroll": opt_scroll,
"opt_arrowcolor": opt_arrowcolor,
"opt_cut": opt_cut,
"opt_freeze": opt_freeze,
"opt_jump": opt_jump,
"opt_arrowshape": opt_arrowshape,
"opt_filter": opt_filter,
"opt_guideline": opt_guideline,
"opt_gauge": opt_gauge,
"opt_judgepriority": opt_judgepriority,
"opt_timing": opt_timing,
},
)
best = db.table('ddr_scores_best').get(
(where('ddr_id') == ddr_id)
& (where('game_version') == game_version)
& (where('mcode') == mcode)
& (where('difficulty') == difficulty)
best = db.table("ddr_scores_best").get(
(where("ddr_id") == ddr_id)
& (where("game_version") == game_version)
& (where("mcode") == mcode)
& (where("difficulty") == difficulty)
)
best = {} if best is None else best
best_score_data = {
'game_version': game_version,
'ddr_id': ddr_id,
'playstyle': playstyle,
'mcode': mcode,
'difficulty': difficulty,
'rank': min(rank, best.get('rank', rank)),
'lamp': max(lamp, best.get('lamp', lamp)),
'score': max(score, best.get('score', score)),
'exscore': max(exscore, best.get('exscore', exscore)),
"game_version": game_version,
"ddr_id": ddr_id,
"playstyle": playstyle,
"mcode": mcode,
"difficulty": difficulty,
"rank": min(rank, best.get("rank", rank)),
"lamp": max(lamp, best.get("lamp", lamp)),
"score": max(score, best.get("score", score)),
"exscore": max(exscore, best.get("exscore", exscore)),
}
ghostid = db.table('ddr_scores').get(
(where('ddr_id') == ddr_id)
& (where('game_version') == game_version)
& (where('mcode') == mcode)
& (where('difficulty') == difficulty)
& (where('score') == max(score, best.get('score', score)))
ghostid = db.table("ddr_scores").get(
(where("ddr_id") == ddr_id)
& (where("game_version") == game_version)
& (where("mcode") == mcode)
& (where("difficulty") == difficulty)
& (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,
(where('ddr_id') == ddr_id)
& (where('game_version') == game_version)
& (where('mcode') == mcode)
& (where('difficulty') == difficulty)
(where("ddr_id") == ddr_id)
& (where("game_version") == game_version)
& (where("mcode") == mcode)
& (where("difficulty") == difficulty),
)
elif int(data.find('isgameover').text) == 1:
single_grade = int(data.find('grade/single_grade').text)
double_grade = int(data.find('grade/double_grade').text)
elif int(data.find("isgameover").text) == 1:
single_grade = int(data.find("grade/single_grade").text)
double_grade = int(data.find("grade/double_grade").text)
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
# 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:
n = note[0]
mcode = int(n.find('mcode').text)
if int(n.find('clearkind').text) != 1:
mcode = int(n.find("mcode").text)
if int(n.find("clearkind").text) != 1:
for grade, course_id in enumerate(range(1000, 1011), start=1):
if playstyle == 0 and mcode in (course_id, course_id + 11):
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
game_profile['single_grade'] = max(single_grade, game_profile.get('single_grade', single_grade))
game_profile['double_grade'] = max(double_grade, game_profile.get('double_grade', double_grade))
game_profile["single_grade"] = max(
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
db.table('ddr_profile').upsert(profile, where('card') == refid)
profile["version"][str(game_version)] = game_profile
db.table("ddr_profile").upsert(profile, where("card") == refid)
response = E.response(
E.playerdata(
@ -353,95 +377,121 @@ async def usergamedata_advanced(request: Request):
)
)
elif mode == 'rivalload':
loadflag = int(data.find('loadflag').text)
ddrcode = int(data.find('ddrcode').text)
pcbid = data.find('pcbid').text
shoparea = data.find('shoparea').text
elif mode == "rivalload":
loadflag = int(data.find("loadflag").text)
ddrcode = int(data.find("ddrcode").text)
pcbid = data.find("pcbid").text
shoparea = data.find("shoparea").text
if loadflag == 1:
all_scores = {}
for record in db.table('ddr_scores').search(
(where('game_version') == game_version)
& (where('pcbid') == pcbid)
& (where('ddr_id') != 0)
for record in db.table("ddr_scores").search(
(where("game_version") == game_version)
& (where("pcbid") == pcbid)
& (where("ddr_id") != 0)
):
ddr_id = record['ddr_id']
playstyle = record['playstyle']
mcode = record['mcode']
difficulty = record['difficulty']
score = record['score']
ddr_id = record["ddr_id"]
playstyle = record["playstyle"]
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] = {
'game_version': game_version,
'ddr_id': ddr_id,
'playstyle': playstyle,
'mcode': mcode,
'difficulty': difficulty,
'rank': record['rank'],
'lamp': record['lamp'],
'score': score,
'exscore': record['exscore'],
'ghostid': record.doc_id
}
"game_version": game_version,
"ddr_id": ddr_id,
"playstyle": playstyle,
"mcode": mcode,
"difficulty": difficulty,
"rank": record["rank"],
"lamp": record["lamp"],
"score": score,
"exscore": record["exscore"],
"ghostid": record.doc_id,
}
scores = list(all_scores.values())
elif loadflag == 2:
all_scores = {}
for record in db.table('ddr_scores').search(
(where('game_version') == game_version)
& (where('shoparea') == shoparea)
& (where('ddr_id') != 0)
for record in db.table("ddr_scores").search(
(where("game_version") == game_version)
& (where("shoparea") == shoparea)
& (where("ddr_id") != 0)
):
ddr_id = record['ddr_id']
playstyle = record['playstyle']
mcode = record['mcode']
difficulty = record['difficulty']
score = record['score']
ddr_id = record["ddr_id"]
playstyle = record["playstyle"]
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] = {
'game_version': game_version,
'ddr_id': ddr_id,
'playstyle': playstyle,
'mcode': mcode,
'difficulty': difficulty,
'rank': record['rank'],
'lamp': record['lamp'],
'score': score,
'exscore': record['exscore'],
'ghostid': record.doc_id
}
"game_version": game_version,
"ddr_id": ddr_id,
"playstyle": playstyle,
"mcode": mcode,
"difficulty": difficulty,
"rank": record["rank"],
"lamp": record["lamp"],
"score": score,
"exscore": record["exscore"],
"ghostid": record.doc_id,
}
scores = list(all_scores.values())
elif loadflag == 4:
all_scores = {}
for record in db.table('ddr_scores').search((where('game_version') == game_version) & (where('ddr_id') != 0)):
ddr_id = record['ddr_id']
playstyle = record['playstyle']
mcode = record['mcode']
difficulty = record['difficulty']
score = record['score']
for record in db.table("ddr_scores").search(
(where("game_version") == game_version) & (where("ddr_id") != 0)
):
ddr_id = record["ddr_id"]
playstyle = record["playstyle"]
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] = {
'game_version': game_version,
'ddr_id': ddr_id,
'playstyle': playstyle,
'mcode': mcode,
'difficulty': difficulty,
'rank': record['rank'],
'lamp': record['lamp'],
'score': score,
'exscore': record['exscore'],
'ghostid': record.doc_id
}
"game_version": game_version,
"ddr_id": ddr_id,
"playstyle": playstyle,
"mcode": mcode,
"difficulty": difficulty,
"rank": record["rank"],
"lamp": record["lamp"],
"score": score,
"exscore": record["exscore"],
"ghostid": record.doc_id,
}
scores = list(all_scores.values())
elif loadflag in (8, 16, 32):
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)
response = E.response(
@ -449,23 +499,31 @@ async def usergamedata_advanced(request: Request):
E.result(0, __type="s32"),
E.data(
E.recordtype(loadflag, __type="s32"),
*[E.record(
E.mcode(s['mcode'], __type="u32"),
E.notetype(s['difficulty'], __type="u8"),
E.rank(s['rank'], __type="u8"),
E.clearkind(s['lamp'], __type="u8"),
E.flagdata(0, __type="u8"),
E.name(get_common(s['ddr_id'], game_version, 27), __type="str"),
E.area(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]
)
*[
E.record(
E.mcode(s["mcode"], __type="u32"),
E.notetype(s["difficulty"], __type="u8"),
E.rank(s["rank"], __type="u8"),
E.clearkind(s["lamp"], __type="u8"),
E.flagdata(0, __type="u8"),
E.name(
get_common(s["ddr_id"], game_version, 27), __type="str"
),
E.area(
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(
E.playerdata(
E.result(0, __type="s32"),
@ -484,50 +542,87 @@ async def usergamedata_advanced(request: Request):
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):
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')
cid = data.find('refid').text
data = request_info["root"][0].find("data")
cid = data.find("refid").text
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)
if all_profiles_for_card is None:
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(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()),
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(
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:
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"]
screen_filter = ["Off", "Dark", "Darker", "Darkest"]
guideline = ["Off", "Border", "Center"]
priority = ["Judgment", "Arrow"]
timing_disp = ["Off", "On"]
common = profile['common'].split(',')
common[5] = calories_disp.index(profile['calories_disp'])
common[6] = character.index(profile['character'])
common[9] = 1 # Mobile link
common = profile["common"].split(",")
common[5] = calories_disp.index(profile["calories_disp"])
common[6] = character.index(profile["character"])
common[9] = 1 # Mobile link
common_load = ",".join([str(i) for i in common])
option = profile['option'].split(',')
option[13] = arrow_skin.index(profile['arrow_skin'])
option[14] = screen_filter.index(profile['filter'])
option[15] = guideline.index(profile['guideline'])
option[17] = priority.index(profile['priority'])
option[18] = timing_disp.index(profile['timing_disp'])
option = profile["option"].split(",")
option[13] = arrow_skin.index(profile["arrow_skin"])
option[14] = screen_filter.index(profile["filter"])
option[15] = guideline.index(profile["guideline"])
option[17] = priority.index(profile["priority"])
option[18] = timing_disp.index(profile["timing_disp"])
option_load = ",".join([str(i) for i in option])
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 = 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),
]
for idx, r in enumerate(rival_ids, start=3):
if r != 0:
rival[idx] = idx - 2
@ -535,10 +630,10 @@ async def usergamedata_recv(request: Request):
rival_load = ",".join([str(i) for i in rival])
load = [
b64encode(str.encode(common_load.split('ffffffff,COMMON,')[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(rival_load.split('ffffffff,RIVAL,')[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(profile["last"].split("ffffffff,LAST,")[1])).decode(),
b64encode(str.encode(rival_load.split("ffffffff,RIVAL,")[1])).decode(),
]
response = E.response(
@ -546,7 +641,7 @@ async def usergamedata_recv(request: Request):
E.result(0, __type="s32"),
E.player(
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"),
),
@ -557,33 +652,43 @@ async def usergamedata_recv(request: Request):
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):
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')
cid = data.find('refid').text
num = int(data.find('datanum').text)
data = request_info["root"][0].find("data")
cid = data.find("refid").text
num = int(data.find("datanum").text)
profile = get_profile(cid)
game_profile = profile['version'].get(str(game_version), {})
game_profile = profile["version"].get(str(game_version), {})
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:
game_profile['common'] = b64decode(data.find('record')[0].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore')
game_profile['option'] = b64decode(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'):
game_profile["common"] = b64decode(
data.find("record")[0].text.split("<bin1")[0]
).decode(encoding="utf-8", errors="ignore")
game_profile["option"] = b64decode(
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:
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(
E.playerdata(

View File

@ -17,92 +17,98 @@ router.model_whitelist = ["MDX"]
def get_profile(cid):
return get_db().table('ddr_profile').get(
where('card') == cid
)
return get_db().table("ddr_profile").get(where("card") == cid)
def get_game_profile(cid, game_version):
profile = get_profile(cid)
return profile['version'].get(str(game_version), None)
return profile["version"].get(str(game_version), None)
def get_common(ddr_id, game_version, idx):
profile = get_db().table('ddr_profile').get(
where('ddr_id') == int(ddr_id)
)
profile = get_db().table("ddr_profile").get(where("ddr_id") == int(ddr_id))
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:
return 0
@router.post('/{gameinfo}/playerdata_2/usergamedata_advanced')
@router.post("/{gameinfo}/playerdata_2/usergamedata_advanced")
async def usergamedata_advanced(request: Request):
request_info = await core_process_request(request)
game_version = request_info['game_version']
is_omni = True if request_info['rev'] == 'O' else False
game_version = request_info["game_version"]
is_omni = True if request_info["rev"] == "O" else False
response = None
data = request_info['root'][0].find('data')
mode = data.find('mode').text
gamesession = data.find('gamesession').text
refid = data.find('refid').text
default = 'X0000000000000000000000000000000'[:-len(gamesession)]+gamesession
data = request_info["root"][0].find("data")
mode = data.find("mode").text
gamesession = data.find("gamesession").text
refid = data.find("refid").text
default = "X0000000000000000000000000000000"[: -len(gamesession)] + gamesession
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':
shoparea = data.find('shoparea').text
if mode == "usernew":
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)
all_profiles_for_card['ddr_id'] = ddr_id
all_profiles_for_card["ddr_id"] = ddr_id
all_profiles_for_card['version'][str(game_version)] = {
'game_version': game_version,
'calories_disp': "Off",
'character': "All Character Random",
'arrow_skin': "Normal",
'filter': "Darkest",
'guideline': "Center",
'priority': "Judgment",
'timing_disp': "On",
'rival_1_ddr_id': 0,
'rival_2_ddr_id': 0,
'rival_3_ddr_id': 0,
'single_grade': 0,
'double_grade': 0,
all_profiles_for_card["version"][str(game_version)] = {
"game_version": game_version,
"calories_disp": "Off",
"character": "All Character Random",
"arrow_skin": "Normal",
"filter": "Darkest",
"guideline": "Center",
"priority": "Judgment",
"timing_disp": "On",
"rival_1_ddr_id": 0,
"rival_2_ddr_id": 0,
"rival_3_ddr_id": 0,
"single_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(
E.playerdata_2(
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.shoparea(shoparea, __type="str")
E.shoparea(shoparea, __type="str"),
)
)
elif mode == 'userload' and refid != default:
elif mode == "userload" and refid != default:
all_scores = {}
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)
single_grade = profile.get('single_grade', 0)
double_grade = profile.get('double_grade', 0)
single_grade = profile.get("single_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)):
mcode = record['mcode']
difficulty = record['difficulty']
for record in db.table("ddr_scores_best").search(
(where("game_version") == game_version) & (where("ddr_id") == ddr_id)
):
mcode = record["mcode"]
difficulty = record["difficulty"]
if mcode not in all_scores:
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(
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_refid_locked(0, __type="bool"),
E.eventdata_count_all(1, __type="s16"),
*[E.music(
E.mcode(int(mcode), __type="u32"),
*[E.note(
E.count(s[0], __type="u16"),
E.rank(s[1], __type="u8"),
E.clearkind(s[2], __type="u8"),
E.score(s[3], __type="s32"),
E.ghostid(s[4], __type="s32"),
) for s in [score for score in all_scores.get(mcode)]],
) for mcode in all_scores.keys()],
*[E.eventdata(
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.music(
E.mcode(int(mcode), __type="u32"),
*[
E.note(
E.count(s[0], __type="u16"),
E.rank(s[1], __type="u8"),
E.clearkind(s[2], __type="u8"),
E.score(s[3], __type="s32"),
E.ghostid(s[4], __type="s32"),
)
for s in [score for score in all_scores.get(mcode)]
],
)
for mcode in all_scores.keys()
],
*[
E.eventdata(
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.single_grade(single_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.notetype(0, __type="s8"),
E.playstyle(0, __type="s32"),
)
),
),
E.preplayable(),
)
)
elif mode == 'ghostload':
ghostid = int(data.find('ghostid').text)
record = db.table('ddr_scores').get(doc_id=ghostid)
elif mode == "ghostload":
ghostid = int(data.find("ghostid").text)
record = db.table("ddr_scores").get(doc_id=ghostid)
response = E.response(
E.playerdata_2(
E.result(0, __type="s32"),
E.ghostdata(
E.code(record['ddr_id'], __type="s32"),
E.mcode(record['mcode'], __type="u32"),
E.notetype(record['difficulty'], __type="u8"),
E.ghostsize(record['ghostsize'], __type="s32"),
E.ghost(record['ghost'], __type="string"),
)
E.code(record["ddr_id"], __type="s32"),
E.mcode(record["mcode"], __type="u32"),
E.notetype(record["difficulty"], __type="u8"),
E.ghostsize(record["ghostsize"], __type="s32"),
E.ghost(record["ghost"], __type="string"),
),
)
)
elif mode == 'usersave' and refid != default:
elif mode == "usersave" and refid != default:
timestamp = time.time()
ddr_id = int(data.find('ddrcode').text)
playstyle = int(data.find('playstyle').text)
pcbid = data.find('pcbid').text
shoparea = data.find('shoparea').text
note = data.findall('note')
ddr_id = int(data.find("ddrcode").text)
playstyle = int(data.find("playstyle").text)
pcbid = data.find("pcbid").text
shoparea = data.find("shoparea").text
if int(data.find('isgameover').text) == 0:
note = data.findall("note")
if int(data.find("isgameover").text) == 0:
for n in note:
if int(n.find('stagenum').text) != 0:
mcode = int(n.find('mcode').text)
difficulty = int(n.find('notetype').text)
rank = int(n.find('rank').text)
lamp = int(n.find('clearkind').text)
score = int(n.find('score').text)
exscore = int(n.find('exscore').text)
maxcombo = int(n.find('maxcombo').text)
life = int(n.find('life').text)
fastcount = int(n.find('fastcount').text)
slowcount = int(n.find('slowcount').text)
judge_marvelous = int(n.find('judge_marvelous').text)
judge_perfect = int(n.find('judge_perfect').text)
judge_great = int(n.find('judge_great').text)
judge_good = int(n.find('judge_good').text)
judge_boo = int(n.find('judge_boo').text)
judge_miss = int(n.find('judge_miss').text)
judge_ok = int(n.find('judge_ok').text)
judge_ng = int(n.find('judge_ng').text)
calorie = int(n.find('calorie').text)
ghostsize = int(n.find('ghostsize').text)
ghost = n.find('ghost').text
opt_speed = int(n.find('opt_speed').text)
opt_boost = int(n.find('opt_boost').text)
opt_appearance = int(n.find('opt_appearance').text)
opt_turn = int(n.find('opt_turn').text)
opt_dark = int(n.find('opt_dark').text)
opt_scroll = int(n.find('opt_scroll').text)
opt_arrowcolor = int(n.find('opt_arrowcolor').text)
opt_cut = int(n.find('opt_cut').text)
opt_freeze = int(n.find('opt_freeze').text)
opt_jump = int(n.find('opt_jump').text)
opt_arrowshape = int(n.find('opt_arrowshape').text)
opt_filter = int(n.find('opt_filter').text)
opt_guideline = int(n.find('opt_guideline').text)
opt_gauge = int(n.find('opt_gauge').text)
opt_judgepriority = int(n.find('opt_judgepriority').text)
opt_timing = int(n.find('opt_timing').text)
if int(n.find("stagenum").text) != 0:
mcode = int(n.find("mcode").text)
difficulty = int(n.find("notetype").text)
rank = int(n.find("rank").text)
lamp = int(n.find("clearkind").text)
score = int(n.find("score").text)
exscore = int(n.find("exscore").text)
maxcombo = int(n.find("maxcombo").text)
life = int(n.find("life").text)
fastcount = int(n.find("fastcount").text)
slowcount = int(n.find("slowcount").text)
judge_marvelous = int(n.find("judge_marvelous").text)
judge_perfect = int(n.find("judge_perfect").text)
judge_great = int(n.find("judge_great").text)
judge_good = int(n.find("judge_good").text)
judge_boo = int(n.find("judge_boo").text)
judge_miss = int(n.find("judge_miss").text)
judge_ok = int(n.find("judge_ok").text)
judge_ng = int(n.find("judge_ng").text)
calorie = int(n.find("calorie").text)
ghostsize = int(n.find("ghostsize").text)
ghost = n.find("ghost").text
opt_speed = int(n.find("opt_speed").text)
opt_boost = int(n.find("opt_boost").text)
opt_appearance = int(n.find("opt_appearance").text)
opt_turn = int(n.find("opt_turn").text)
opt_dark = int(n.find("opt_dark").text)
opt_scroll = int(n.find("opt_scroll").text)
opt_arrowcolor = int(n.find("opt_arrowcolor").text)
opt_cut = int(n.find("opt_cut").text)
opt_freeze = int(n.find("opt_freeze").text)
opt_jump = int(n.find("opt_jump").text)
opt_arrowshape = int(n.find("opt_arrowshape").text)
opt_filter = int(n.find("opt_filter").text)
opt_guideline = int(n.find("opt_guideline").text)
opt_gauge = int(n.find("opt_gauge").text)
opt_judgepriority = int(n.find("opt_judgepriority").text)
opt_timing = int(n.find("opt_timing").text)
db.table('ddr_scores').insert(
db.table("ddr_scores").insert(
{
'timestamp': timestamp,
'pcbid': pcbid,
'shoparea': shoparea,
'game_version': game_version,
'ddr_id': ddr_id,
'playstyle': playstyle,
'mcode': mcode,
'difficulty': difficulty,
'rank': rank,
'lamp': lamp,
'score': score,
'exscore': exscore,
'maxcombo': maxcombo,
'life': life,
'fastcount': fastcount,
'slowcount': slowcount,
'judge_marvelous': judge_marvelous,
'judge_perfect': judge_perfect,
'judge_great': judge_great,
'judge_good': judge_good,
'judge_boo': judge_boo,
'judge_miss': judge_miss,
'judge_ok': judge_ok,
'judge_ng': judge_ng,
'calorie': calorie,
'ghostsize': ghostsize,
'ghost': ghost,
'opt_speed': opt_speed,
'opt_boost': opt_boost,
'opt_appearance': opt_appearance,
'opt_turn': opt_turn,
'opt_dark': opt_dark,
'opt_scroll': opt_scroll,
'opt_arrowcolor': opt_arrowcolor,
'opt_cut': opt_cut,
'opt_freeze': opt_freeze,
'opt_jump': opt_jump,
'opt_arrowshape': opt_arrowshape,
'opt_filter': opt_filter,
'opt_guideline': opt_guideline,
'opt_gauge': opt_gauge,
'opt_judgepriority': opt_judgepriority,
'opt_timing': opt_timing,
"timestamp": timestamp,
"pcbid": pcbid,
"shoparea": shoparea,
"game_version": game_version,
"ddr_id": ddr_id,
"playstyle": playstyle,
"mcode": mcode,
"difficulty": difficulty,
"rank": rank,
"lamp": lamp,
"score": score,
"exscore": exscore,
"maxcombo": maxcombo,
"life": life,
"fastcount": fastcount,
"slowcount": slowcount,
"judge_marvelous": judge_marvelous,
"judge_perfect": judge_perfect,
"judge_great": judge_great,
"judge_good": judge_good,
"judge_boo": judge_boo,
"judge_miss": judge_miss,
"judge_ok": judge_ok,
"judge_ng": judge_ng,
"calorie": calorie,
"ghostsize": ghostsize,
"ghost": ghost,
"opt_speed": opt_speed,
"opt_boost": opt_boost,
"opt_appearance": opt_appearance,
"opt_turn": opt_turn,
"opt_dark": opt_dark,
"opt_scroll": opt_scroll,
"opt_arrowcolor": opt_arrowcolor,
"opt_cut": opt_cut,
"opt_freeze": opt_freeze,
"opt_jump": opt_jump,
"opt_arrowshape": opt_arrowshape,
"opt_filter": opt_filter,
"opt_guideline": opt_guideline,
"opt_gauge": opt_gauge,
"opt_judgepriority": opt_judgepriority,
"opt_timing": opt_timing,
},
)
best = db.table('ddr_scores_best').get(
(where('ddr_id') == ddr_id)
& (where('game_version') == game_version)
& (where('mcode') == mcode)
& (where('difficulty') == difficulty)
best = db.table("ddr_scores_best").get(
(where("ddr_id") == ddr_id)
& (where("game_version") == game_version)
& (where("mcode") == mcode)
& (where("difficulty") == difficulty)
)
best = {} if best is None else best
best_score_data = {
'game_version': game_version,
'ddr_id': ddr_id,
'playstyle': playstyle,
'mcode': mcode,
'difficulty': difficulty,
'rank': min(rank, best.get('rank', rank)),
'lamp': max(lamp, best.get('lamp', lamp)),
'score': max(score, best.get('score', score)),
'exscore': max(exscore, best.get('exscore', exscore)),
"game_version": game_version,
"ddr_id": ddr_id,
"playstyle": playstyle,
"mcode": mcode,
"difficulty": difficulty,
"rank": min(rank, best.get("rank", rank)),
"lamp": max(lamp, best.get("lamp", lamp)),
"score": max(score, best.get("score", score)),
"exscore": max(exscore, best.get("exscore", exscore)),
}
ghostid = db.table('ddr_scores').get(
(where('ddr_id') == ddr_id)
& (where('game_version') == game_version)
& (where('mcode') == mcode)
& (where('difficulty') == difficulty)
& (where('score') == max(score, best.get('score', score)))
ghostid = db.table("ddr_scores").get(
(where("ddr_id") == ddr_id)
& (where("game_version") == game_version)
& (where("mcode") == mcode)
& (where("difficulty") == difficulty)
& (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,
(where('ddr_id') == ddr_id)
& (where('game_version') == game_version)
& (where('mcode') == mcode)
& (where('difficulty') == difficulty)
(where("ddr_id") == ddr_id)
& (where("game_version") == game_version)
& (where("mcode") == mcode)
& (where("difficulty") == difficulty),
)
elif int(data.find('isgameover').text) == 1:
single_grade = int(data.find('grade/single_grade').text)
double_grade = int(data.find('grade/double_grade').text)
elif int(data.find("isgameover").text) == 1:
single_grade = int(data.find("grade/single_grade").text)
double_grade = int(data.find("grade/double_grade").text)
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
# 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:
n = note[0]
mcode = int(n.find('mcode').text)
if int(n.find('clearkind').text) != 1:
mcode = int(n.find("mcode").text)
if int(n.find("clearkind").text) != 1:
for grade, course_id in enumerate(range(1000, 1011), start=1):
if playstyle == 0 and mcode in (course_id, course_id + 11):
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
game_profile['single_grade'] = max(single_grade, game_profile.get('single_grade', single_grade))
game_profile['double_grade'] = max(double_grade, game_profile.get('double_grade', double_grade))
game_profile["single_grade"] = max(
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
db.table('ddr_profile').upsert(profile, where('card') == refid)
profile["version"][str(game_version)] = game_profile
db.table("ddr_profile").upsert(profile, where("card") == refid)
response = E.response(
E.playerdata_2(
@ -353,124 +377,153 @@ async def usergamedata_advanced(request: Request):
)
)
elif mode == 'rivalload':
loadflag = int(data.find('loadflag').text)
ddrcode = int(data.find('ddrcode').text)
pcbid = data.find('pcbid').text
shoparea = data.find('shoparea').text
elif mode == "rivalload":
loadflag = int(data.find("loadflag").text)
ddrcode = int(data.find("ddrcode").text)
pcbid = data.find("pcbid").text
shoparea = data.find("shoparea").text
if loadflag == 1:
all_scores = {}
for record in db.table('ddr_scores').search(
(where('game_version') == game_version)
& (where('pcbid') == pcbid)
& (where('ddr_id') != 0)
for record in db.table("ddr_scores").search(
(where("game_version") == game_version)
& (where("pcbid") == pcbid)
& (where("ddr_id") != 0)
):
ddr_id = record['ddr_id']
playstyle = record['playstyle']
mcode = record['mcode']
difficulty = record['difficulty']
score = record['score']
ddr_id = record["ddr_id"]
playstyle = record["playstyle"]
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] = {
'game_version': game_version,
'ddr_id': ddr_id,
'playstyle': playstyle,
'mcode': mcode,
'difficulty': difficulty,
'rank': record['rank'],
'lamp': record['lamp'],
'score': score,
'exscore': record['exscore'],
'ghostid': record.doc_id
}
"game_version": game_version,
"ddr_id": ddr_id,
"playstyle": playstyle,
"mcode": mcode,
"difficulty": difficulty,
"rank": record["rank"],
"lamp": record["lamp"],
"score": score,
"exscore": record["exscore"],
"ghostid": record.doc_id,
}
scores = list(all_scores.values())
elif loadflag == 2:
all_scores = {}
for record in db.table('ddr_scores').search(
(where('game_version') == game_version)
& (where('shoparea') == shoparea)
& (where('ddr_id') != 0)
for record in db.table("ddr_scores").search(
(where("game_version") == game_version)
& (where("shoparea") == shoparea)
& (where("ddr_id") != 0)
):
ddr_id = record['ddr_id']
playstyle = record['playstyle']
mcode = record['mcode']
difficulty = record['difficulty']
score = record['score']
ddr_id = record["ddr_id"]
playstyle = record["playstyle"]
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] = {
'game_version': game_version,
'ddr_id': ddr_id,
'playstyle': playstyle,
'mcode': mcode,
'difficulty': difficulty,
'rank': record['rank'],
'lamp': record['lamp'],
'score': score,
'exscore': record['exscore'],
'ghostid': record.doc_id
}
"game_version": game_version,
"ddr_id": ddr_id,
"playstyle": playstyle,
"mcode": mcode,
"difficulty": difficulty,
"rank": record["rank"],
"lamp": record["lamp"],
"score": score,
"exscore": record["exscore"],
"ghostid": record.doc_id,
}
scores = list(all_scores.values())
elif loadflag == 4:
all_scores = {}
for record in db.table('ddr_scores').search((where('game_version') == game_version) & (where('ddr_id') != 0)):
ddr_id = record['ddr_id']
playstyle = record['playstyle']
mcode = record['mcode']
difficulty = record['difficulty']
score = record['score']
for record in db.table("ddr_scores").search(
(where("game_version") == game_version) & (where("ddr_id") != 0)
):
ddr_id = record["ddr_id"]
playstyle = record["playstyle"]
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] = {
'game_version': game_version,
'ddr_id': ddr_id,
'playstyle': playstyle,
'mcode': mcode,
'difficulty': difficulty,
'rank': record['rank'],
'lamp': record['lamp'],
'score': score,
'exscore': record['exscore'],
'ghostid': record.doc_id
}
"game_version": game_version,
"ddr_id": ddr_id,
"playstyle": playstyle,
"mcode": mcode,
"difficulty": difficulty,
"rank": record["rank"],
"lamp": record["lamp"],
"score": score,
"exscore": record["exscore"],
"ghostid": record.doc_id,
}
scores = list(all_scores.values())
elif loadflag in (8, 16, 32):
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)
load = []
for r in scores:
s = [
r['mcode'],
r['difficulty'],
r['rank'],
r['lamp'],
get_common(r['ddr_id'], game_version, 27),
int(get_common(r['ddr_id'], game_version, 3), 16),
r['ddr_id'],
r['score'],
r['ghostid'],
r["mcode"],
r["difficulty"],
r["rank"],
r["lamp"],
get_common(r["ddr_id"], game_version, 27),
int(get_common(r["ddr_id"], game_version, 3), 16),
r["ddr_id"],
r["score"],
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(
E.playerdata_2(
E.result(0, __type="s32"),
E.data(
*[E.record(
E.record_csv(s, __type="str"),
) for s in load]
)
*[
E.record(
E.record_csv(s, __type="str"),
)
for s in load
]
),
)
)
elif mode == 'inheritance':
elif mode == "inheritance":
response = E.response(
E.playerdata_2(
E.result(0, __type="s32"),
@ -489,50 +542,87 @@ async def usergamedata_advanced(request: Request):
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):
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')
cid = data.find('refid').text
data = request_info["root"][0].find("data")
cid = data.find("refid").text
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)
if all_profiles_for_card is None:
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(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()),
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(
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:
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"]
screen_filter = ["Off", "Dark", "Darker", "Darkest"]
guideline = ["Off", "Border", "Center"]
priority = ["Judgment", "Arrow"]
timing_disp = ["Off", "On"]
common = profile['common'].split(',')
common[5] = calories_disp.index(profile['calories_disp'])
common[6] = character.index(profile['character'])
common[9] = 1 # Mobile link
common = profile["common"].split(",")
common[5] = calories_disp.index(profile["calories_disp"])
common[6] = character.index(profile["character"])
common[9] = 1 # Mobile link
common_load = ",".join([str(i) for i in common])
option = profile['option'].split(',')
option[13] = arrow_skin.index(profile['arrow_skin'])
option[14] = screen_filter.index(profile['filter'])
option[15] = guideline.index(profile['guideline'])
option[17] = priority.index(profile['priority'])
option[18] = timing_disp.index(profile['timing_disp'])
option = profile["option"].split(",")
option[13] = arrow_skin.index(profile["arrow_skin"])
option[14] = screen_filter.index(profile["filter"])
option[15] = guideline.index(profile["guideline"])
option[17] = priority.index(profile["priority"])
option[18] = timing_disp.index(profile["timing_disp"])
option_load = ",".join([str(i) for i in option])
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 = 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),
]
for idx, r in enumerate(rival_ids, start=3):
if r != 0:
rival[idx] = idx - 2
@ -540,10 +630,10 @@ async def usergamedata_recv(request: Request):
rival_load = ",".join([str(i) for i in rival])
load = [
b64encode(str.encode(common_load.split('ffffffff,COMMON,')[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(rival_load.split('ffffffff,RIVAL,')[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(profile["last"].split("ffffffff,LAST,")[1])).decode(),
b64encode(str.encode(rival_load.split("ffffffff,RIVAL,")[1])).decode(),
]
response = E.response(
@ -551,7 +641,7 @@ async def usergamedata_recv(request: Request):
E.result(0, __type="s32"),
E.player(
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"),
),
@ -562,33 +652,43 @@ async def usergamedata_recv(request: Request):
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):
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')
cid = data.find('refid').text
num = int(data.find('datanum').text)
data = request_info["root"][0].find("data")
cid = data.find("refid").text
num = int(data.find("datanum").text)
profile = get_profile(cid)
game_profile = profile['version'].get(str(game_version), {})
game_profile = profile["version"].get(str(game_version), {})
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:
game_profile['common'] = b64decode(data.find('record')[0].text.split('<bin1')[0]).decode(encoding='utf-8', errors='ignore')
game_profile['option'] = b64decode(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'):
game_profile["common"] = b64decode(
data.find("record")[0].text.split("<bin1")[0]
).decode(encoding="utf-8", errors="ignore")
game_profile["option"] = b64decode(
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:
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(
E.playerdata_2(

View File

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

View File

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

View File

@ -6,7 +6,7 @@ router = APIRouter(prefix="/local", tags=["local"])
router.model_whitelist = ["MDX"]
@router.post('/{gameinfo}/tax/get_phase')
@router.post("/{gameinfo}/tax/get_phase")
async def tax_get_phase(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.post('/{gameinfo}/IIDX29gameSystem/systemInfo')
@router.post("/{gameinfo}/IIDX29gameSystem/systemInfo")
async def iidx29gamesystem_systeminfo(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)
response = E.response(
@ -30,46 +30,64 @@ async def iidx29gamesystem_systeminfo(request: Request):
E.isEiseiOpenFlg(val=1),
E.WorldTourismOpenList(val=1),
E.BPLBattleOpenPhase(val=2),
*[E.music_open(
E.music_id(s, __type="s32"),
E.kind(0, __type="s32"),
) for s in unlock],
*[E.arena_reward(
E.index(unlock.index(s), __type="s32"),
E.cube_num((unlock.index(s) + 1) * 50, __type="s32"),
E.kind(0, __type="s32"),
E.value(s, __type="str"),
) for s in unlock],
*[E.arena_music_difficult(
E.play_style(s, __type="s32"),
E.arena_class(-1, __type="s32"),
E.low_difficult(1, __type="s32"),
E.high_difficult(12, __type="s32"),
E.is_leggendaria(1, __type="bool"),
E.force_music_list_id(0, __type="s32"),
) for s in sp_dp],
*[E.arena_cpu_define(
E.play_style(s, __type="s32"),
E.arena_class(-1, __type="s32"),
E.grade_id(18, __type="s32"),
E.low_music_difficult(8, __type="s32"),
E.high_music_difficult(12, __type="s32"),
E.is_leggendaria(0, __type="bool"),
) for 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],
*[
E.music_open(
E.music_id(s, __type="s32"),
E.kind(0, __type="s32"),
)
for s in unlock
],
*[
E.arena_reward(
E.index(unlock.index(s), __type="s32"),
E.cube_num((unlock.index(s) + 1) * 50, __type="s32"),
E.kind(0, __type="s32"),
E.value(s, __type="str"),
)
for s in unlock
],
*[
E.arena_music_difficult(
E.play_style(s, __type="s32"),
E.arena_class(-1, __type="s32"),
E.low_difficult(1, __type="s32"),
E.high_difficult(12, __type="s32"),
E.is_leggendaria(1, __type="bool"),
E.force_music_list_id(0, __type="s32"),
)
for s in sp_dp
],
*[
E.arena_cpu_define(
E.play_style(s, __type="s32"),
E.arena_class(-1, __type="s32"),
E.grade_id(18, __type="s32"),
E.low_music_difficult(8, __type="s32"),
E.high_music_difficult(12, __type="s32"),
E.is_leggendaria(0, __type="bool"),
)
for 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.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):
request_info = await core_process_request(request)
game_version = request_info['game_version']
game_version = request_info["game_version"]
timestamp = time.time()
iidx_id = int(request_info['root'][0].attrib['iidxid'])
achi = int(request_info['root'][0].attrib['achi'])
cstage = int(request_info['root'][0].attrib['cstage'])
gid = int(request_info['root'][0].attrib['gid'])
gtype = int(request_info['root'][0].attrib['gtype'])
is_ex = int(request_info['root'][0].attrib['is_ex'])
is_mirror = int(request_info['root'][0].attrib['is_mirror'])
iidx_id = int(request_info["root"][0].attrib["iidxid"])
achi = int(request_info["root"][0].attrib["achi"])
cstage = int(request_info["root"][0].attrib["cstage"])
gid = int(request_info["root"][0].attrib["gid"])
gtype = int(request_info["root"][0].attrib["gtype"])
is_ex = int(request_info["root"][0].attrib["is_ex"])
is_mirror = int(request_info["root"][0].attrib["is_mirror"])
db = get_db()
db.table('iidx_class').insert(
db.table("iidx_class").insert(
{
'timestamp': timestamp,
'game_version': game_version,
'iidx_id': iidx_id,
'achi': achi,
'cstage': cstage,
'gid': gid,
'gtype': gtype,
'is_ex': is_ex,
'is_mirror': is_mirror,
"timestamp": timestamp,
"game_version": game_version,
"iidx_id": iidx_id,
"achi": achi,
"cstage": cstage,
"gid": gid,
"gtype": gtype,
"is_ex": is_ex,
"is_mirror": is_mirror,
},
)
profile = get_profile(iidx_id)
game_profile = profile['version'].get(str(game_version), {})
game_profile = profile["version"].get(str(game_version), {})
best_class = db.table('iidx_class_best').get(
(where('iidx_id') == iidx_id)
& (where('game_version') == game_version)
& (where('gid') == gid)
& (where('gtype') == gtype)
best_class = db.table("iidx_class_best").get(
(where("iidx_id") == iidx_id)
& (where("game_version") == game_version)
& (where("gid") == gid)
& (where("gtype") == gtype)
)
best_class = {} if best_class is None else best_class
best_class_data = {
'game_version': game_version,
'iidx_id': iidx_id,
'achi': max(achi, best_class.get('achi', achi)),
'cstage': max(cstage, best_class.get('cstage', cstage)),
'gid': gid,
'gtype': gtype,
'is_ex': is_ex,
'is_mirror': is_mirror,
"game_version": game_version,
"iidx_id": iidx_id,
"achi": max(achi, best_class.get("achi", achi)),
"cstage": max(cstage, best_class.get("cstage", cstage)),
"gid": gid,
"gtype": gtype,
"is_ex": is_ex,
"is_mirror": is_mirror,
}
db.table('iidx_class_best').upsert(
db.table("iidx_class_best").upsert(
best_class_data,
(where('iidx_id') == iidx_id)
& (where('game_version') == game_version)
& (where('gid') == gid)
& (where('gtype') == gtype)
(where("iidx_id") == iidx_id)
& (where("game_version") == game_version)
& (where("gid") == gid)
& (where("gtype") == gtype),
)
best_class_plays = db.table('iidx_class_best').search(
(where('game_version') == game_version)
& (where('iidx_id') == iidx_id)
best_class_plays = db.table("iidx_class_best").search(
(where("game_version") == game_version) & (where("iidx_id") == iidx_id)
)
grades = []
for record in best_class_plays:
grades.append([
record['gtype'],
record['gid'],
record['cstage'],
record['achi']
])
game_profile['grade_values'] = grades
grade_sp = db.table('iidx_class_best').search(
(where('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
grades.append(
[record["gtype"], 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))
response_body, response_headers = await core_prepare_response(request, response)
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.post('/{gameinfo}/IIDX29lobby/entry')
@router.post("/{gameinfo}/IIDX29lobby/entry")
async def iidx29lobby_entry(request: Request):
request_info = await core_process_request(request)
response = E.response(
E.IIDX29lobby()
)
response = E.response(E.IIDX29lobby())
response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29lobby/update')
@router.post("/{gameinfo}/IIDX29lobby/update")
async def iidx29lobby_update(request: Request):
request_info = await core_process_request(request)
response = E.response(
E.IIDX29lobby()
)
response = E.response(E.IIDX29lobby())
response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX29lobby/delete')
@router.post("/{gameinfo}/IIDX29lobby/delete")
async def iidx29lobby_delete(request: Request):
request_info = await core_process_request(request)
response = E.response(
E.IIDX29lobby()
)
response = E.response(E.IIDX29lobby())
response_body, response_headers = await core_prepare_response(request, response)
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):
request_info = await core_process_request(request)
response = E.response(
E.IIDX29lobby()
)
response = E.response(E.IIDX29lobby())
response_body, response_headers = await core_prepare_response(request, response)
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):
request_info = await core_process_request(request)
response = E.response(
E.IIDX29lobby()
)
response = E.response(E.IIDX29lobby())
response_body, response_headers = await core_prepare_response(request, response)
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):
request_info = await core_process_request(request)
response = E.response(
E.IIDX29lobby()
)
response = E.response(E.IIDX29lobby())
response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers)

View File

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

View File

@ -8,11 +8,11 @@ router = APIRouter(prefix="/local2", tags=["local2"])
router.model_whitelist = ["LDJ"]
@router.post('/{gameinfo}/IIDX30gameSystem/systemInfo')
@router.post("/{gameinfo}/IIDX30gameSystem/systemInfo")
async def iidx30gamesystem_systeminfo(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)
response = E.response(
@ -30,46 +30,64 @@ async def iidx30gamesystem_systeminfo(request: Request):
E.isEiseiOpenFlg(val=1),
E.WorldTourismOpenList(val=1),
E.BPLBattleOpenPhase(val=2),
*[E.music_open(
E.music_id(s, __type="s32"),
E.kind(0, __type="s32"),
) for s in unlock],
*[E.arena_reward(
E.index(unlock.index(s), __type="s32"),
E.cube_num((unlock.index(s) + 1) * 50, __type="s32"),
E.kind(0, __type="s32"),
E.value(s, __type="str"),
) for s in unlock],
*[E.arena_music_difficult(
E.play_style(s, __type="s32"),
E.arena_class(-1, __type="s32"),
E.low_difficult(1, __type="s32"),
E.high_difficult(12, __type="s32"),
E.is_leggendaria(1, __type="bool"),
E.force_music_list_id(0, __type="s32"),
) for s in sp_dp],
*[E.arena_cpu_define(
E.play_style(s, __type="s32"),
E.arena_class(-1, __type="s32"),
E.grade_id(18, __type="s32"),
E.low_music_difficult(8, __type="s32"),
E.high_music_difficult(12, __type="s32"),
E.is_leggendaria(0, __type="bool"),
) for 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],
*[
E.music_open(
E.music_id(s, __type="s32"),
E.kind(0, __type="s32"),
)
for s in unlock
],
*[
E.arena_reward(
E.index(unlock.index(s), __type="s32"),
E.cube_num((unlock.index(s) + 1) * 50, __type="s32"),
E.kind(0, __type="s32"),
E.value(s, __type="str"),
)
for s in unlock
],
*[
E.arena_music_difficult(
E.play_style(s, __type="s32"),
E.arena_class(-1, __type="s32"),
E.low_difficult(1, __type="s32"),
E.high_difficult(12, __type="s32"),
E.is_leggendaria(1, __type="bool"),
E.force_music_list_id(0, __type="s32"),
)
for s in sp_dp
],
*[
E.arena_cpu_define(
E.play_style(s, __type="s32"),
E.arena_class(-1, __type="s32"),
E.grade_id(18, __type="s32"),
E.low_music_difficult(8, __type="s32"),
E.high_music_difficult(12, __type="s32"),
E.is_leggendaria(0, __type="bool"),
)
for 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.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):
request_info = await core_process_request(request)
game_version = request_info['game_version']
game_version = request_info["game_version"]
timestamp = time.time()
iidx_id = int(request_info['root'][0].attrib['iidxid'])
achi = int(request_info['root'][0].attrib['achi'])
cstage = int(request_info['root'][0].attrib['cstage'])
gid = int(request_info['root'][0].attrib['gid'])
gtype = int(request_info['root'][0].attrib['gtype'])
is_ex = int(request_info['root'][0].attrib['is_ex'])
is_mirror = int(request_info['root'][0].attrib['is_mirror'])
iidx_id = int(request_info["root"][0].attrib["iidxid"])
achi = int(request_info["root"][0].attrib["achi"])
cstage = int(request_info["root"][0].attrib["cstage"])
gid = int(request_info["root"][0].attrib["gid"])
gtype = int(request_info["root"][0].attrib["gtype"])
is_ex = int(request_info["root"][0].attrib["is_ex"])
is_mirror = int(request_info["root"][0].attrib["is_mirror"])
db = get_db()
db.table('iidx_class').insert(
db.table("iidx_class").insert(
{
'timestamp': timestamp,
'game_version': game_version,
'iidx_id': iidx_id,
'achi': achi,
'cstage': cstage,
'gid': gid,
'gtype': gtype,
'is_ex': is_ex,
'is_mirror': is_mirror,
"timestamp": timestamp,
"game_version": game_version,
"iidx_id": iidx_id,
"achi": achi,
"cstage": cstage,
"gid": gid,
"gtype": gtype,
"is_ex": is_ex,
"is_mirror": is_mirror,
},
)
profile = get_profile(iidx_id)
game_profile = profile['version'].get(str(game_version), {})
game_profile = profile["version"].get(str(game_version), {})
best_class = db.table('iidx_class_best').get(
(where('iidx_id') == iidx_id)
& (where('game_version') == game_version)
& (where('gid') == gid)
& (where('gtype') == gtype)
best_class = db.table("iidx_class_best").get(
(where("iidx_id") == iidx_id)
& (where("game_version") == game_version)
& (where("gid") == gid)
& (where("gtype") == gtype)
)
best_class = {} if best_class is None else best_class
best_class_data = {
'game_version': game_version,
'iidx_id': iidx_id,
'achi': max(achi, best_class.get('achi', achi)),
'cstage': max(cstage, best_class.get('cstage', cstage)),
'gid': gid,
'gtype': gtype,
'is_ex': is_ex,
'is_mirror': is_mirror,
"game_version": game_version,
"iidx_id": iidx_id,
"achi": max(achi, best_class.get("achi", achi)),
"cstage": max(cstage, best_class.get("cstage", cstage)),
"gid": gid,
"gtype": gtype,
"is_ex": is_ex,
"is_mirror": is_mirror,
}
db.table('iidx_class_best').upsert(
db.table("iidx_class_best").upsert(
best_class_data,
(where('iidx_id') == iidx_id)
& (where('game_version') == game_version)
& (where('gid') == gid)
& (where('gtype') == gtype)
(where("iidx_id") == iidx_id)
& (where("game_version") == game_version)
& (where("gid") == gid)
& (where("gtype") == gtype),
)
best_class_plays = db.table('iidx_class_best').search(
(where('game_version') == game_version)
& (where('iidx_id') == iidx_id)
best_class_plays = db.table("iidx_class_best").search(
(where("game_version") == game_version) & (where("iidx_id") == iidx_id)
)
grades = []
for record in best_class_plays:
grades.append([
record['gtype'],
record['gid'],
record['cstage'],
record['achi']
])
game_profile['grade_values'] = grades
grade_sp = db.table('iidx_class_best').search(
(where('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
grades.append(
[record["gtype"], 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))
response_body, response_headers = await core_prepare_response(request, response)
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.post('/{gameinfo}/IIDX30lobby/entry')
@router.post("/{gameinfo}/IIDX30lobby/entry")
async def iidx30lobby_entry(request: Request):
request_info = await core_process_request(request)
response = E.response(
E.IIDX30lobby()
)
response = E.response(E.IIDX30lobby())
response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30lobby/update')
@router.post("/{gameinfo}/IIDX30lobby/update")
async def iidx30lobby_update(request: Request):
request_info = await core_process_request(request)
response = E.response(
E.IIDX30lobby()
)
response = E.response(E.IIDX30lobby())
response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/IIDX30lobby/delete')
@router.post("/{gameinfo}/IIDX30lobby/delete")
async def iidx30lobby_delete(request: Request):
request_info = await core_process_request(request)
response = E.response(
E.IIDX30lobby()
)
response = E.response(E.IIDX30lobby())
response_body, response_headers = await core_prepare_response(request, response)
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):
request_info = await core_process_request(request)
response = E.response(
E.IIDX30lobby()
)
response = E.response(E.IIDX30lobby())
response_body, response_headers = await core_prepare_response(request, response)
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):
request_info = await core_process_request(request)
response = E.response(
E.IIDX30lobby()
)
response = E.response(E.IIDX30lobby())
response_body, response_headers = await core_prepare_response(request, response)
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):
request_info = await core_process_request(request)
response = E.response(
E.IIDX30lobby()
)
response = E.response(E.IIDX30lobby())
response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers)

View File

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

View File

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

View File

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

View File

@ -14,71 +14,67 @@ router.model_whitelist = ["KFC"]
def get_profile(cid):
return get_db().table('sdvx_profile').get(
where('card') == cid
)
return get_db().table("sdvx_profile").get(where("card") == cid)
def get_game_profile(cid, game_version):
profile = get_profile(cid)
return profile['version'].get(str(game_version), None)
return profile["version"].get(str(game_version), None)
def get_id_from_profile(cid):
profile = get_db().table('sdvx_profile').get(
where('card') == cid
)
profile = get_db().table("sdvx_profile").get(where("card") == cid)
djid = "%08d" % profile['sdvx_id']
djid_split = '-'.join([djid[:4], djid[4:]])
djid = "%08d" % profile["sdvx_id"]
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):
request_info = await core_process_request(request)
event = [
'DEMOGAME_PLAY',
'MATCHING_MODE',
'MATCHING_MODE_FREE_IP',
'LEVEL_LIMIT_EASING',
'ACHIEVEMENT_ENABLE',
'APICAGACHADRAW\t30',
'VOLFORCE_ENABLE',
'AKANAME_ENABLE',
'PAUSE_ONLINEUPDATE',
'CONTINUATION',
'TENKAICHI_MODE',
'QC_MODE',
'KAC_MODE',
'APPEAL_CARD_GEN_PRICE\t100',
'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',
'FAVORITE_APPEALCARD_MAX\t200',
'FAVORITE_MUSIC_MAX\t200',
'EVENTDATE_APRILFOOL',
'KONAMI_50TH_LOGO',
'OMEGA_ARS_ENABLE',
'DISABLE_MONITOR_ID_CHECK',
'SKILL_ANALYZER_ABLE',
'BLASTER_ABLE',
'STANDARD_UNLOCK_ENABLE',
'PLAYERJUDGEADJ_ENABLE',
'MIXID_INPUT_ENABLE',
'EVENTDATE_ONIGO',
'EVENTDATE_GOTT',
'GENERATOR_ABLE',
'CREW_SELECT_ABLE',
'PREMIUM_TIME_ENABLE',
'OMEGA_ENABLE\t1,2,3,4,5,6,7,8,9',
'HEXA_ENABLE\t1,2,3,4,5',
'MEGAMIX_ENABLE',
'VALGENE_ENABLE',
'ARENA_ENABLE',
'DISP_PASELI_BANNER',
"DEMOGAME_PLAY",
"MATCHING_MODE",
"MATCHING_MODE_FREE_IP",
"LEVEL_LIMIT_EASING",
"ACHIEVEMENT_ENABLE",
"APICAGACHADRAW\t30",
"VOLFORCE_ENABLE",
"AKANAME_ENABLE",
"PAUSE_ONLINEUPDATE",
"CONTINUATION",
"TENKAICHI_MODE",
"QC_MODE",
"KAC_MODE",
# "APPEAL_CARD_GEN_PRICE\t100",
# "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",
"FAVORITE_APPEALCARD_MAX\t200",
"FAVORITE_MUSIC_MAX\t200",
"EVENTDATE_APRILFOOL",
"KONAMI_50TH_LOGO",
"OMEGA_ARS_ENABLE",
"DISABLE_MONITOR_ID_CHECK",
"SKILL_ANALYZER_ABLE",
"BLASTER_ABLE",
"STANDARD_UNLOCK_ENABLE",
"PLAYERJUDGEADJ_ENABLE",
"MIXID_INPUT_ENABLE",
"EVENTDATE_ONIGO",
"EVENTDATE_GOTT",
"GENERATOR_ABLE",
"CREW_SELECT_ABLE",
"PREMIUM_TIME_ENABLE",
"OMEGA_ENABLE\t1,2,3,4,5,6,7,8,9",
"HEXA_ENABLE\t1,2,3,4,5",
"MEGAMIX_ENABLE",
"VALGENE_ENABLE",
"ARENA_ENABLE",
"DISP_PASELI_BANNER",
]
unlock = []
@ -89,16 +85,22 @@ async def game_sv6_common(request: Request):
response = E.response(
E.game(
E.event(
*[E.info(
E.event_id(s, __type="str"),
)for s in event],
*[
E.info(
E.event_id(s, __type="str"),
)
for s in event
],
),
E.music_limited(
*[E.info(
E.music_id(s[0], __type="s32"),
E.music_type(s[1], __type="u8"),
E.limited(3, __type="u8"),
)for s in unlock],
*[
E.info(
E.music_id(s[0], __type="s32"),
E.music_type(s[1], __type="u8"),
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)
@router.post('/{gameinfo}/game/sv6_new')
@router.post("/{gameinfo}/game/sv6_new")
async def game_sv6_new(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
cardno = root.find("cardno").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)
if all_profiles_for_card is None:
all_profiles_for_card = {
'card': dataid,
'version': {}
}
all_profiles_for_card = {"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)
all_profiles_for_card['sdvx_id'] = sdvx_id
all_profiles_for_card["sdvx_id"] = sdvx_id
all_profiles_for_card['version'][str(game_version)] = {
'game_version': game_version,
'name': name,
'appeal_id': 0,
'skill_level': 0,
'skill_base_id': 0,
'skill_name_id': 0,
'earned_gamecoin_packet': 0,
'earned_gamecoin_block': 0,
'earned_blaster_energy': 0,
'earned_extrack_energy': 0,
'used_packet_booster': 0,
'used_block_booster': 0,
'hispeed': 0,
'lanespeed': 0,
'gauge_option': 0,
'ars_option': 0,
'notes_option': 0,
'early_late_disp': 0,
'draw_adjust': 0,
'eff_c_left': 0,
'eff_c_right': 1,
'music_id': 0,
'music_type': 0,
'sort_type': 0,
'narrow_down': 0,
'headphone': 1,
'print_count': 0,
'start_option': 0,
'bgm': 0,
'submonitor': 0,
'nemsys': 0,
'stampA': 0,
'stampB': 0,
'stampC': 0,
'stampD': 0,
'items': [],
'params': [],
all_profiles_for_card["version"][str(game_version)] = {
"game_version": game_version,
"name": name,
"appeal_id": 0,
"skill_level": 0,
"skill_base_id": 0,
"skill_name_id": 0,
"earned_gamecoin_packet": 0,
"earned_gamecoin_block": 0,
"earned_blaster_energy": 0,
"earned_extrack_energy": 0,
"used_packet_booster": 0,
"used_block_booster": 0,
"hispeed": 0,
"lanespeed": 0,
"gauge_option": 0,
"ars_option": 0,
"notes_option": 0,
"early_late_disp": 0,
"draw_adjust": 0,
"eff_c_left": 0,
"eff_c_right": 1,
"music_id": 0,
"music_type": 0,
"sort_type": 0,
"narrow_down": 0,
"headphone": 1,
"print_count": 0,
"start_option": 0,
"bgm": 0,
"submonitor": 0,
"nemsys": 0,
"stampA": 0,
"stampB": 0,
"stampC": 0,
"stampD": 0,
"items": [],
"params": [],
}
db.upsert(all_profiles_for_card, where('card') == dataid)
db.upsert(all_profiles_for_card, where("card") == dataid)
response = E.response(
E.game(
@ -183,12 +182,12 @@ async def game_sv6_new(request: Request):
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):
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)
if profile:
@ -200,28 +199,42 @@ async def game_sv6_load(request: Request):
for i in range(6001):
unlock.append([i, 1, 1])
unlock.append([599, 4, 10])
for item in profile['items']:
for item in profile["items"]:
unlock.append(item)
customize = [[2, 2, [profile['bgm'], profile['submonitor'], profile['nemsys'], profile['stampA'], profile['stampB'], profile['stampC'], profile['stampD']]]]
for item in profile['params']:
customize = [
[
2,
2,
[
profile["bgm"],
profile["submonitor"],
profile["nemsys"],
profile["stampA"],
profile["stampB"],
profile["stampC"],
profile["stampD"],
],
]
]
for item in profile["params"]:
customize.append(item)
response = E.response(
E.game(
E.result(0, __type="u8"),
E.name(profile['name'], __type="str"),
E.name(profile["name"], __type="str"),
E.code(djid_split, __type="str"),
E.sdvx_id(djid_split, __type="str"),
E.appeal_id(profile['appeal_id'], __type="u16"),
E.skill_level(profile['skill_level'], __type="s16"),
E.skill_base_id(profile['skill_base_id'], __type="s16"),
E.skill_name_id(profile['skill_name_id'], __type="s16"),
E.gamecoin_packet(profile['earned_gamecoin_packet'], __type="u32"),
E.gamecoin_block(profile['earned_gamecoin_block'], __type="u32"),
E.blaster_energy(profile['earned_blaster_energy'], __type="u32"),
E.appeal_id(profile["appeal_id"], __type="u16"),
E.skill_level(profile["skill_level"], __type="s16"),
E.skill_base_id(profile["skill_base_id"], __type="s16"),
E.skill_name_id(profile["skill_name_id"], __type="s16"),
E.gamecoin_packet(profile["earned_gamecoin_packet"], __type="u32"),
E.gamecoin_block(profile["earned_gamecoin_block"], __type="u32"),
E.blaster_energy(profile["earned_blaster_energy"], __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.day_count(301, __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.max_week_chain(1001, __type="u32"),
E.creator_id(1, __type="u32"),
E.eaappli(
E.relation(1, __type="s8")
),
E.eaappli(E.relation(1, __type="s8")),
E.ea_shop(
E.blaster_pass_enable(1, __type="bool"),
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.volte_factory(
*[E.info(
E.goods_id(s, __type="s32"),
E.status(1, __type="s32"),
)for s in range(1, 999)],
),
*[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.info(
E.goods_id(s, __type="s32"),
E.status(1, __type="s32"),
)
for s in range(1, 999)
],
),
*[
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.info(
E.ranking_id(s[0], __type="s32"),
E.value(s[1], __type="s64"),
)for s in [[1402, 20000]]],
*[
E.info(
E.ranking_id(s[0], __type="s32"),
E.value(s[1], __type="s64"),
)
for s in [[1402, 20000]]
],
),
E.festival(
E.fes_id(1, __type="s32"),
E.live_energy(1000000, __type="s32"),
*[E.bonus(
E.energy_type(s, __type="s32"),
E.live_energy(1000000, __type="s32"),
)for s in range(1, 6)],
*[
E.bonus(
E.energy_type(s, __type="s32"),
E.live_energy(1000000, __type="s32"),
)
for s in range(1, 6)
],
),
E.valgene_ticket(
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.ultimate_play_cnt(0, __type="s32"),
),
E.hispeed(profile['hispeed'], __type="s32"),
E.lanespeed(profile['lanespeed'], __type="u32"),
E.gauge_option(profile['gauge_option'], __type="u8"),
E.ars_option(profile['ars_option'], __type="u8"),
E.notes_option(profile['notes_option'], __type="u8"),
E.early_late_disp(profile['early_late_disp'], __type="u8"),
E.draw_adjust(profile['draw_adjust'], __type="s32"),
E.eff_c_left(profile['eff_c_left'], __type="u8"),
E.eff_c_right(profile['eff_c_right'], __type="u8"),
E.last_music_id(profile['music_id'], __type="s32"),
E.last_music_type(profile['music_type'], __type="u8"),
E.sort_type(profile['sort_type'], __type="u8"),
E.narrow_down(profile['narrow_down'], __type="u8"),
E.headphone(profile['headphone'], __type="u8"),
E.hispeed(profile["hispeed"], __type="s32"),
E.lanespeed(profile["lanespeed"], __type="u32"),
E.gauge_option(profile["gauge_option"], __type="u8"),
E.ars_option(profile["ars_option"], __type="u8"),
E.notes_option(profile["notes_option"], __type="u8"),
E.early_late_disp(profile["early_late_disp"], __type="u8"),
E.draw_adjust(profile["draw_adjust"], __type="s32"),
E.eff_c_left(profile["eff_c_left"], __type="u8"),
E.eff_c_right(profile["eff_c_right"], __type="u8"),
E.last_music_id(profile["music_id"], __type="s32"),
E.last_music_type(profile["music_type"], __type="u8"),
E.sort_type(profile["sort_type"], __type="u8"),
E.narrow_down(profile["narrow_down"], __type="u8"),
E.headphone(profile["headphone"], __type="u8"),
E.item(
*[E.info(
E.id(s[0], __type="u32"),
E.type(s[1], __type="u8"),
E.param(s[2], __type="u32"),
)for s in unlock],
*[
E.info(
E.id(s[0], __type="u32"),
E.type(s[1], __type="u8"),
E.param(s[2], __type="u32"),
)
for s in unlock
],
),
E.param(
*[E.info(
E.type(s[0], __type="s32"),
E.id(s[1], __type="s32"),
E.param(s[2], __type="s32", __count=len(s[2])),
)for s in customize],
*[
E.info(
E.type(s[0], __type="s32"),
E.id(s[1], __type="s32"),
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)
@router.post('/{gameinfo}/game/sv6_load_m')
@router.post("/{gameinfo}/game/sv6_load_m")
async def game_sv6_load_m(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)
djid, djid_split = get_id_from_profile(dataid)
best_scores = []
db = get_db()
for record in db.table('sdvx_scores_best').search(
(where('game_version') == game_version)
& (where('sdvx_id') == djid)
for record in db.table("sdvx_scores_best").search(
(where("game_version") == game_version) & (where("sdvx_id") == djid)
):
best_scores.append([
record['music_id'],
record['music_type'],
record['score'],
record['exscore'],
record['clear_type'],
record['score_grade'],
0,
0,
record['btn_rate'],
record['long_rate'],
record['vol_rate'],
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
])
best_scores.append(
[
record["music_id"],
record["music_type"],
record["score"],
record["exscore"],
record["clear_type"],
record["score_grade"],
0,
0,
record["btn_rate"],
record["long_rate"],
record["vol_rate"],
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]
)
response = E.response(
E.game(
E.music(
*[E.info(
E.param(x, __type="u32"),
)for x in best_scores],
*[
E.info(
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)
@router.post('/{gameinfo}/game/sv6_save')
@router.post("/{gameinfo}/game/sv6_save")
async def game_sv6_save(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)
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 = [
'appeal_id',
'skill_level',
'skill_base_id',
'skill_name_id',
'earned_gamecoin_packet',
'earned_gamecoin_block',
'earned_blaster_energy',
'earned_extrack_energy',
'hispeed',
'lanespeed',
'gauge_option',
'ars_option',
'notes_option',
'early_late_disp',
'draw_adjust',
'eff_c_left',
'eff_c_right',
'music_id',
'music_type',
'sort_type',
'narrow_down',
'headphone',
'start_option',
"appeal_id",
"skill_level",
"skill_base_id",
"skill_name_id",
"earned_gamecoin_packet",
"earned_gamecoin_block",
"earned_blaster_energy",
"earned_extrack_energy",
"hispeed",
"lanespeed",
"gauge_option",
"ars_option",
"notes_option",
"early_late_disp",
"draw_adjust",
"eff_c_left",
"eff_c_right",
"music_id",
"music_type",
"sort_type",
"narrow_down",
"headphone",
"start_option",
]
for node in nodes:
game_profile[node] = int(root.find(node).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['print_count'] = int(root.find('print')[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["print_count"] = int(root.find("print")[0].text)
items = []
for info in root.find('item'):
items.append([int(info.find('id').text), int(info.find('type').text), int(info.find('param').text)])
game_profile['items'] = items
for info in root.find("item"):
items.append(
[
int(info.find("id").text),
int(info.find("type").text),
int(info.find("param").text),
]
)
game_profile["items"] = items
params = []
for info in root.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(' ')]])
game_profile['params'] = params
for info in root.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(" ")],
]
)
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(
E.game(),
@ -446,20 +489,19 @@ async def game_sv6_save(request: Request):
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):
request_info = await core_process_request(request)
game_version = request_info['game_version']
game_version = request_info["game_version"]
timestamp = time.time()
root = request_info['root'][0]
root = request_info["root"][0]
dataid = root.find("dataid").text
profile = get_game_profile(dataid, game_version)
djid, djid_split = get_id_from_profile(dataid)
track = root.find("track")
play_id = int(track.find("play_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)
challenge_type = int(track.find("challenge_type").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.table('sdvx_scores').insert(
db.table("sdvx_scores").insert(
{
'timestamp': timestamp,
'game_version': game_version,
'sdvx_id': djid,
'play_id': play_id,
'music_id': music_id,
'music_type': music_type,
'score': score,
'exscore': exscore,
'clear_type': clear_type,
'score_grade': score_grade,
'max_chain': max_chain,
'just': just,
'critical': critical,
'near': near,
'error': error,
'effective_rate': effective_rate,
'btn_rate': btn_rate,
'long_rate': long_rate,
'vol_rate': vol_rate,
'mode': mode,
'gauge_type': gauge_type,
'notes_option': notes_option,
'online_num': online_num,
'local_num': local_num,
'challenge_type': challenge_type,
'retry_cnt': retry_cnt,
'judge': judge,
"timestamp": timestamp,
"game_version": game_version,
"sdvx_id": djid,
"play_id": play_id,
"music_id": music_id,
"music_type": music_type,
"score": score,
"exscore": exscore,
"clear_type": clear_type,
"score_grade": score_grade,
"max_chain": max_chain,
"just": just,
"critical": critical,
"near": near,
"error": error,
"effective_rate": effective_rate,
"btn_rate": btn_rate,
"long_rate": long_rate,
"vol_rate": vol_rate,
"mode": mode,
"gauge_type": gauge_type,
"notes_option": notes_option,
"online_num": online_num,
"local_num": local_num,
"challenge_type": challenge_type,
"retry_cnt": retry_cnt,
"judge": judge,
},
)
best = db.table('sdvx_scores_best').get(
(where('sdvx_id') == djid)
& (where('game_version') == game_version)
& (where('music_id') == music_id)
& (where('music_type') == music_type)
best = db.table("sdvx_scores_best").get(
(where("sdvx_id") == djid)
& (where("game_version") == game_version)
& (where("music_id") == music_id)
& (where("music_type") == music_type)
)
best = {} if best is None else best
best_score_data = {
'game_version': game_version,
'sdvx_id': djid,
'name': profile['name'],
'music_id': music_id,
'music_type': music_type,
'score': max(score, best.get('score', score)),
'exscore': max(exscore, best.get('exscore', exscore)),
'clear_type': max(clear_type, best.get('clear_type', clear_type)),
'score_grade': max(score_grade, best.get('score_grade', score_grade)),
'btn_rate': max(btn_rate, best.get('btn_rate', btn_rate)),
'long_rate': max(long_rate, best.get('long_rate', long_rate)),
'vol_rate': max(vol_rate, best.get('vol_rate', vol_rate)),
"game_version": game_version,
"sdvx_id": djid,
"name": profile["name"],
"music_id": music_id,
"music_type": music_type,
"score": max(score, best.get("score", score)),
"exscore": max(exscore, best.get("exscore", exscore)),
"clear_type": max(clear_type, best.get("clear_type", clear_type)),
"score_grade": max(score_grade, best.get("score_grade", score_grade)),
"btn_rate": max(btn_rate, best.get("btn_rate", btn_rate)),
"long_rate": max(long_rate, best.get("long_rate", long_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,
(where('sdvx_id') == djid)
& (where('game_version') == game_version)
& (where('music_id') == music_id)
& (where('music_type') == music_type)
(where("sdvx_id") == djid)
& (where("game_version") == game_version)
& (where("music_id") == music_id)
& (where("music_type") == music_type),
)
response = E.response(
@ -558,37 +600,42 @@ async def game_sv6_save_m(request: Request):
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):
request_info = await core_process_request(request)
game_version = request_info['game_version']
game_version = request_info["game_version"]
best_scores = []
db = get_db()
for record in db.table('sdvx_scores_best').search(
(where('game_version') == game_version)
for record in db.table("sdvx_scores_best").search(
(where("game_version") == game_version)
):
best_scores.append([
record['music_id'],
record['music_type'],
record['sdvx_id'],
record['name'],
record['score'],
])
best_scores.append(
[
record["music_id"],
record["music_type"],
record["sdvx_id"],
record["name"],
record["score"],
]
)
response = E.response(
E.game(
E.sc(
*[E.d(
E.id(s[0], __type="u32"),
E.ty(s[1], __type="u32"),
E.a_sq(s[2], __type="str"),
E.a_nm(s[3], __type="str"),
E.a_sc(s[4], __type="u32"),
E.l_sq(s[2], __type="str"),
E.l_nm(s[3], __type="str"),
E.l_sc(s[4], __type="u32"),
)for s in best_scores],
*[
E.d(
E.id(s[0], __type="u32"),
E.ty(s[1], __type="u32"),
E.a_sq(s[2], __type="str"),
E.a_nm(s[3], __type="str"),
E.a_sc(s[4], __type="u32"),
E.l_sq(s[2], __type="str"),
E.l_nm(s[3], __type="str"),
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)
@router.post('/{gameinfo}/game/sv6_lounge')
@router.post("/{gameinfo}/game/sv6_lounge")
async def game_sv6_lounge(request: Request):
request_info = await core_process_request(request)
response = E.response(
E.game(
E.interval(30, __type="u32")
),
E.game(E.interval(30, __type="u32")),
)
response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers)
@router.post('/{gameinfo}/game/sv6_shop')
@router.post("/{gameinfo}/game/sv6_shop")
async def game_sv6_shop(request: Request):
request_info = await core_process_request(request)
response = E.response(
E.game(
E.nxt_time(1000 * 5 * 60, __type="u32")
),
E.game(E.nxt_time(1000 * 5 * 60, __type="u32")),
)
response_body, response_headers = await core_prepare_response(request, response)
@ -626,17 +669,18 @@ async def game_sv6_shop(request: Request):
for stub in [
'load_r',
'frozen',
'save_e',
'save_mega',
'play_e',
'play_s',
'entry_s',
'entry_e',
'log'
"load_r",
"frozen",
"save_e",
"save_mega",
"play_e",
"play_s",
"entry_s",
"entry_e",
"log",
]:
@router.post(f'/{{gameinfo}}/game/sv6_{stub}')
@router.post(f"/{{gameinfo}}/game/sv6_{stub}")
async def game_sv6_stub(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
def urlpathjoin(parts, sep='/'):
def urlpathjoin(parts, sep="/"):
return sep + sep.join([x.lstrip(sep) for x in parts])
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"
app = FastAPI()
@ -38,7 +40,7 @@ if __name__ == "__main__":
print("|____/ \__,_|___/_|_| |_|\___||___/___/")
print()
print(f"<services>{server_services_url}</services>")
print("<url_slash __type=\"bool\">1</url_slash>")
print('<url_slash __type="bool">1</url_slash>')
print()
uvicorn.run("pyeamu:app", host=config.ip, port=config.port, reload=True)
@ -50,18 +52,20 @@ async def services_get(request: Request):
services = {}
for service in modules.routers:
model_blacklist = services.get('model_blacklist', [])
model_whitelist = services.get('model_whitelist', [])
model_blacklist = services.get("model_blacklist", [])
model_whitelist = services.get("model_whitelist", [])
if request_info['model'] in model_blacklist:
if request_info["model"] in model_blacklist:
continue
if model_whitelist and request_info['model'] not in model_whitelist:
if model_whitelist and request_info["model"] not in model_whitelist:
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:
services[k] = urlunparse(('http', server_address, service.prefix, None, None, None))
services[k] = urlunparse(
("http", server_address, service.prefix, None, None, None)
)
keepalive_params = {
"pa": keepalive_address,
@ -71,19 +75,27 @@ async def services_get(request: Request):
"t1": 2,
"t2": 10,
}
services["keepalive"] = urlunparse(('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))
services["keepalive"] = urlunparse(
(
"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(
E.services(
expire=10800,
mode='operation',
mode="operation",
product_domain=1,
*[E.item(
name=k,
url=services[k]
) for k in services]
*[E.item(name=k, url=services[k]) for k in services],
)
)

View File

@ -1,16 +1,18 @@
anyio
asgiref
click
colorama
fastapi
h11
idna
kbinxml
lxml
pycryptodomex
pydantic
sniffio
starlette
tinydb
typing_extensions
uvicorn
anyio==3.6.2
asgiref==3.5.2
click==8.1.3
colorama==0.4.6
fastapi==0.86.0
h11==0.14.0
idna==3.4
kbinxml==1.7
lxml==4.9.1
pycryptodomex==3.15.0
pydantic==1.10.2
python-multipart==0.0.5
six==1.16.0
sniffio==1.3.0
starlette==0.20.4
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:
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()
def decrypt(self, data):

View File

@ -30,14 +30,14 @@ def pack_5(data):
data = "".join(f"{i:05b}" for i in data)
if len(data) % 8 != 0:
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):
data = "".join(f"{i:08b}" for i in data)
if len(data) % 5 != 0:
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):
@ -74,7 +74,9 @@ def to_uid(konami_id):
raise ValueError("Invalid ID")
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]
assert card[11] % 2 == card[12] % 2, "Parity check failed"
assert card[13] == card[12] ^ 1, "Card invalid"
@ -98,4 +100,6 @@ def to_uid(konami_id):
if __name__ == "__main__":
assert to_konami_id("0000000000000000") == "007TUT8XJNSSPN2P", "To 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:
if offset >= data_length:
break
lookback_flag = int.from_bytes(data[offset:offset+2], 'big')
lookback_length = (lookback_flag & 0x000f) + 3
lookback_flag = int.from_bytes(data[offset : offset + 2], "big")
lookback_length = (lookback_flag & 0x000F) + 3
lookback_offset = lookback_flag >> 4
offset += 2
if lookback_flag == 0: