mirror of
https://github.com/drmext/MonkeyBusiness.git
synced 2024-12-18 18:35:53 +01:00
Partially implement IIDX 20 tricoro
This commit is contained in:
parent
31abc27cca
commit
75dd75bb05
12
README.md
12
README.md
@ -1,12 +1,20 @@
|
|||||||
# MonkeyBusiness
|
# MonkeyBusiness
|
||||||
e-amusement server using FastAPI and TinyDB
|
e-amusement server using FastAPI and TinyDB
|
||||||
|
|
||||||
for experimental testing
|
for experimental testing and playing
|
||||||
|
|
||||||
|
|
||||||
# Instructions
|
## Instructions:
|
||||||
`pip install -U -r requirements.txt`
|
`pip install -U -r requirements.txt`
|
||||||
|
|
||||||
`python pyeamu.py`
|
`python pyeamu.py`
|
||||||
|
|
||||||
Edit services url and enable url_slash
|
Edit services url and enable url_slash
|
||||||
|
|
||||||
|
|
||||||
|
## Playable Games:
|
||||||
|
- `DDR A20 PLUS`
|
||||||
|
- `DDR A3`
|
||||||
|
- `IIDX 20 tricoro`
|
||||||
|
- `IIDX 29 CastHour`
|
||||||
|
- `SDVX 6 Exceed Gear`
|
||||||
|
@ -56,6 +56,8 @@ async def core_get_game_version_from_software_version(software_version):
|
|||||||
return 19
|
return 19
|
||||||
elif model == 'KFC' and ext >= 2020090402:
|
elif model == 'KFC' and ext >= 2020090402:
|
||||||
return 6
|
return 6
|
||||||
|
elif model == 'LDJ' and ext == 2013090900:
|
||||||
|
return 20
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
343
modules/iidx/music.py
Normal file
343
modules/iidx/music.py
Normal file
@ -0,0 +1,343 @@
|
|||||||
|
import time
|
||||||
|
from enum import IntEnum
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Request, Response
|
||||||
|
from tinydb import where
|
||||||
|
|
||||||
|
from core_common import core_process_request, core_prepare_response, E
|
||||||
|
from core_database import get_db
|
||||||
|
|
||||||
|
import config
|
||||||
|
|
||||||
|
router = APIRouter(prefix='/local', tags=['local'])
|
||||||
|
router.model_whitelist = ['LDJ']
|
||||||
|
|
||||||
|
|
||||||
|
class ClearFlags(IntEnum):
|
||||||
|
NO_PLAY = 0
|
||||||
|
FAILED = 1
|
||||||
|
ASSIST_CLEAR = 2
|
||||||
|
EASY_CLEAR = 3
|
||||||
|
CLEAR = 4
|
||||||
|
HARD_CLEAR = 5
|
||||||
|
EX_HARD_CLEAR = 6
|
||||||
|
FULL_COMBO = 7
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/{gameinfo}/music/getrank')
|
||||||
|
async def music_getrank(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
game_version = request_info['game_version']
|
||||||
|
|
||||||
|
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)
|
||||||
|
):
|
||||||
|
music_id = record['music_id']
|
||||||
|
clear_flg = record['clear_flg']
|
||||||
|
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},
|
||||||
|
}
|
||||||
|
|
||||||
|
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]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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')
|
||||||
|
async def music_crate(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
|
||||||
|
crate = {}
|
||||||
|
fcrate = {}
|
||||||
|
for stat in all_score_stats:
|
||||||
|
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:
|
||||||
|
old_to_new_adjust = -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
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
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')
|
||||||
|
async def music_reg(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
game_version = request_info['game_version']
|
||||||
|
|
||||||
|
timestamp = time.time()
|
||||||
|
|
||||||
|
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'])
|
||||||
|
is_death = int(root.attrib['is_death'])
|
||||||
|
music_id = int(root.attrib['mid'])
|
||||||
|
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 clid < 3:
|
||||||
|
note_id = clid + 1
|
||||||
|
play_style = 0
|
||||||
|
else:
|
||||||
|
note_id = clid - 2
|
||||||
|
play_style = 1
|
||||||
|
|
||||||
|
ghost = root.find("ghost").text
|
||||||
|
|
||||||
|
db = get_db()
|
||||||
|
db.table('iidx_scores').insert(
|
||||||
|
{
|
||||||
|
'timestamp': timestamp,
|
||||||
|
'game_version': game_version,
|
||||||
|
'iidx_id': iidx_id,
|
||||||
|
'pid': pid,
|
||||||
|
'clear_flg': clear_flg,
|
||||||
|
'is_death': is_death,
|
||||||
|
'music_id': music_id,
|
||||||
|
'play_style': play_style,
|
||||||
|
'chart_id': note_id,
|
||||||
|
'pgreat_num': pgreat_num,
|
||||||
|
'great_num': great_num,
|
||||||
|
'ex_score': ex_score,
|
||||||
|
'miss_count': miss_num,
|
||||||
|
'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 = {} 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)
|
||||||
|
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_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),
|
||||||
|
}
|
||||||
|
|
||||||
|
db.table('iidx_scores_best').upsert(
|
||||||
|
best_score_data,
|
||||||
|
(where('iidx_id') == iidx_id)
|
||||||
|
& (where('play_style') == play_style)
|
||||||
|
& (where('music_id') == music_id)
|
||||||
|
& (where('chart_id') == note_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
score_stats = db.table('iidx_score_stats').get(
|
||||||
|
(where('music_id') == music_id)
|
||||||
|
& (where('play_style') == play_style)
|
||||||
|
& (where('chart_id') == note_id)
|
||||||
|
)
|
||||||
|
score_stats = {} if score_stats is None else score_stats
|
||||||
|
|
||||||
|
score_stats['game_version'] = game_version
|
||||||
|
score_stats['play_style'] = play_style
|
||||||
|
score_stats['music_id'] = music_id
|
||||||
|
score_stats['chart_id'] = note_id
|
||||||
|
score_stats['play_count'] = score_stats.get('play_count', 0) + 1
|
||||||
|
score_stats['fc_count'] = score_stats.get('fc_count', 0) + (1 if clear_flg == ClearFlags.FULL_COMBO else 0)
|
||||||
|
score_stats['clear_count'] = score_stats.get('clear_count', 0) + (1 if clear_flg >= ClearFlags.EASY_CLEAR else 0)
|
||||||
|
score_stats['fc_rate'] = int((score_stats['fc_count'] / score_stats['play_count']) * 1000)
|
||||||
|
score_stats['clear_rate'] = int((score_stats['clear_count'] / score_stats['play_count']) * 1000)
|
||||||
|
|
||||||
|
db.table('iidx_score_stats').upsert(
|
||||||
|
score_stats,
|
||||||
|
(where('music_id') == music_id)
|
||||||
|
& (where('play_style') == play_style)
|
||||||
|
& (where('chart_id') == note_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
ranklist_data = []
|
||||||
|
ranklist_scores = db.table('iidx_scores_best').search(
|
||||||
|
(where('play_style') == play_style)
|
||||||
|
& (where('music_id') == music_id)
|
||||||
|
& (where('chart_id') == note_id)
|
||||||
|
)
|
||||||
|
ranklist_scores = [] if ranklist_scores is None else ranklist_scores
|
||||||
|
|
||||||
|
ranklist_scores_ranked = []
|
||||||
|
|
||||||
|
for score in ranklist_scores:
|
||||||
|
profile = db.table('iidx_profile').get(where('iidx_id') == score['iidx_id'])
|
||||||
|
|
||||||
|
if profile is None or str(game_version) not in profile['version']:
|
||||||
|
continue
|
||||||
|
|
||||||
|
game_profile = profile['version'][str(game_version)]
|
||||||
|
|
||||||
|
ranklist_scores_ranked.append({
|
||||||
|
'opname': config.arcade,
|
||||||
|
'name': game_profile['djname'],
|
||||||
|
'pid': game_profile['region'],
|
||||||
|
'body': game_profile['body'],
|
||||||
|
'face': game_profile['face'],
|
||||||
|
'hair': game_profile['hair'],
|
||||||
|
'hand': game_profile['hand'],
|
||||||
|
'head': game_profile['head'],
|
||||||
|
'dgrade': game_profile['grade_double'],
|
||||||
|
'sgrade': game_profile['grade_single'],
|
||||||
|
'score': score['ex_score'],
|
||||||
|
'iidx_id': score['iidx_id'],
|
||||||
|
'clflg': score['clear_flg'],
|
||||||
|
'myFlg': score['iidx_id'] == iidx_id
|
||||||
|
})
|
||||||
|
|
||||||
|
ranklist_scores_ranked = sorted(ranklist_scores_ranked, key=lambda x: (x['clflg'], x['score']), reverse=True)
|
||||||
|
|
||||||
|
myRank = 0
|
||||||
|
for rnum, score in enumerate(ranklist_scores_ranked):
|
||||||
|
r = E.data(
|
||||||
|
rnum=rnum + 1,
|
||||||
|
opname=score['opname'],
|
||||||
|
name=score['name'],
|
||||||
|
pid=score['pid'],
|
||||||
|
body=score['body'],
|
||||||
|
face=score['face'],
|
||||||
|
hair=score['hair'],
|
||||||
|
hand=score['hand'],
|
||||||
|
head=score['head'],
|
||||||
|
dgrade=score['dgrade'],
|
||||||
|
sgrade=score['sgrade'],
|
||||||
|
score=score['score'],
|
||||||
|
iidx_id=score['iidx_id'],
|
||||||
|
clflg=score['clflg'],
|
||||||
|
myFlg=score['myFlg'],
|
||||||
|
achieve=0,
|
||||||
|
)
|
||||||
|
ranklist_data.append(r)
|
||||||
|
|
||||||
|
if score['myFlg']:
|
||||||
|
myRank = rnum + 1
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
E.music(
|
||||||
|
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,
|
||||||
|
mid=music_id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
response_body, response_headers = await core_prepare_response(request, response)
|
||||||
|
return Response(content=response_body, headers=response_headers)
|
||||||
|
|
||||||
|
|
||||||
|
@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'])
|
||||||
|
|
||||||
|
db = get_db()
|
||||||
|
record = db.table('iidx_scores_best').get(
|
||||||
|
(where('iidx_id') == iidxid)
|
||||||
|
& (where('music_id') == music_id)
|
||||||
|
& (where('chart_id') == chart_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
vals = []
|
||||||
|
if record is not None:
|
||||||
|
vals.append(E.mydata(
|
||||||
|
record['ghost'],
|
||||||
|
score=record['ex_score'],
|
||||||
|
__type="bin",
|
||||||
|
__size=len(record['ghost']) // 2,
|
||||||
|
))
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
E.music(
|
||||||
|
*vals
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
response_body, response_headers = await core_prepare_response(request, response)
|
||||||
|
return Response(content=response_body, headers=response_headers)
|
581
modules/iidx/pc.py
Normal file
581
modules/iidx/pc.py
Normal file
@ -0,0 +1,581 @@
|
|||||||
|
from tinydb import Query, where
|
||||||
|
|
||||||
|
import config
|
||||||
|
import random
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Request, Response
|
||||||
|
|
||||||
|
from core_common import core_process_request, core_prepare_response, E
|
||||||
|
from core_database import get_db
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/local", tags=["local"])
|
||||||
|
router.model_whitelist = ["LDJ"]
|
||||||
|
|
||||||
|
|
||||||
|
def get_profile(cid):
|
||||||
|
return get_db().table('iidx_profile').get(
|
||||||
|
where('card') == cid
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_profile_by_id(iidx_id):
|
||||||
|
return get_db().table('iidx_profile').get(
|
||||||
|
where('iidx_id') == iidx_id
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_game_profile(cid, game_version):
|
||||||
|
profile = get_profile(cid)
|
||||||
|
|
||||||
|
return profile['version'].get(str(game_version), None)
|
||||||
|
|
||||||
|
|
||||||
|
def get_id_from_profile(cid):
|
||||||
|
profile = get_db().table('iidx_profile').get(
|
||||||
|
where('card') == cid
|
||||||
|
)
|
||||||
|
|
||||||
|
djid = "%08d" % profile['iidx_id']
|
||||||
|
djid_split = '-'.join([djid[:4], djid[4:]])
|
||||||
|
|
||||||
|
return profile['iidx_id'], djid_split
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_folder_mask(profile):
|
||||||
|
return profile.get('_show_category_grade', 0) << 0 \
|
||||||
|
| (profile.get('_show_category_status', 0) << 1) \
|
||||||
|
| (profile.get('_show_category_difficulty', 0) << 2) \
|
||||||
|
| (profile.get('_show_category_alphabet', 0) << 3) \
|
||||||
|
| (profile.get('_show_category_rival_play', 0) << 4) \
|
||||||
|
| (profile.get('_show_category_rival_winlose', 0) << 6) \
|
||||||
|
| (profile.get('_show_rival_shop_info', 0) << 7) \
|
||||||
|
| (profile.get('_hide_play_count', 0) << 8) \
|
||||||
|
| (profile.get('_hide_rival_info', 0) << 9) \
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/{gameinfo}/pc/get')
|
||||||
|
async def pc_get(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
game_version = request_info['game_version']
|
||||||
|
|
||||||
|
cid = request_info['root'][0].attrib['did']
|
||||||
|
profile = get_game_profile(cid, game_version)
|
||||||
|
djid, djid_split = get_id_from_profile(cid)
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
E.pc(
|
||||||
|
E.pcdata(
|
||||||
|
dach=profile['dach'],
|
||||||
|
dp_opt=profile['dp_opt'],
|
||||||
|
dp_opt2=profile['dp_opt2'],
|
||||||
|
dpnum=profile["dpnum"],
|
||||||
|
gno=profile['gno'],
|
||||||
|
gpos=profile['gpos'],
|
||||||
|
help=profile['help'],
|
||||||
|
hispeed=profile['hispeed'],
|
||||||
|
id=djid,
|
||||||
|
idstr=djid_split,
|
||||||
|
judge=profile['judge'],
|
||||||
|
judgeAdj=profile['judgeAdj'],
|
||||||
|
liflen=profile['lift'],
|
||||||
|
mode=profile['mode'],
|
||||||
|
name=profile['djname'],
|
||||||
|
notes=profile['notes'],
|
||||||
|
opstyle=profile['opstyle'],
|
||||||
|
pase=profile['pase'],
|
||||||
|
pid=profile['region'],
|
||||||
|
pmode=profile['pmode'],
|
||||||
|
sach=profile['sach'],
|
||||||
|
sdhd=profile['sdhd'],
|
||||||
|
sdtype=profile['sdtype'],
|
||||||
|
sp_opt=profile['sp_opt'],
|
||||||
|
spnum=profile["spnum"],
|
||||||
|
timing=profile['timing'],
|
||||||
|
),
|
||||||
|
E.qprodata([profile["head"], profile["hair"], profile["face"], profile["hand"], profile["body"]],
|
||||||
|
__type="u32", __size=5 * 4),
|
||||||
|
E.skin(
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
profile["turntable"],
|
||||||
|
profile["explosion"],
|
||||||
|
profile["bgm"],
|
||||||
|
calculate_folder_mask(profile),
|
||||||
|
profile["sudden"],
|
||||||
|
0,
|
||||||
|
profile["categoryvoice"],
|
||||||
|
profile["note"],
|
||||||
|
profile["fullcombo"],
|
||||||
|
profile["keybeam"],
|
||||||
|
profile["judgestring"],
|
||||||
|
-1,
|
||||||
|
profile["soundpreview"],
|
||||||
|
],
|
||||||
|
__type="s16"),
|
||||||
|
E.rlist(),
|
||||||
|
E.commonboss(baron=0, deller=profile['deller'], orb=0),
|
||||||
|
E.secret(
|
||||||
|
E.flg1(profile.get('secret_flg1', [-1]), __type="s64"),
|
||||||
|
E.flg2(profile.get('secret_flg2', [-1]), __type="s64"),
|
||||||
|
E.flg3(profile.get('secret_flg3', [-1]), __type="s64"),
|
||||||
|
),
|
||||||
|
E.join_shop(join_cflg=1, join_id=10, join_name=config.arcade, joinflg=1),
|
||||||
|
E.grade(
|
||||||
|
*[E.g(x, __type="u8") for x in profile['grade_values']],
|
||||||
|
dgid=profile['grade_double'],
|
||||||
|
sgid=profile['grade_single'],
|
||||||
|
),
|
||||||
|
E.redboss(
|
||||||
|
crush=profile.get('redboss_crush', 0),
|
||||||
|
open=profile.get('redboss_open', 0),
|
||||||
|
progress=profile.get('redboss_progress', 0),
|
||||||
|
),
|
||||||
|
E.blueboss(
|
||||||
|
column0=profile.get('blueboss_column0', 0),
|
||||||
|
column1=profile.get('blueboss_column1', 0),
|
||||||
|
first_flg=profile.get('blueboss_first_flg', 0),
|
||||||
|
gauge=profile.get('blueboss_gauge', 0),
|
||||||
|
general=profile.get('blueboss_general', 0),
|
||||||
|
item=profile.get('blueboss_item', 0),
|
||||||
|
item_flg=profile.get('blueboss_item_flg', 0),
|
||||||
|
level=profile.get('blueboss_level', 0),
|
||||||
|
row0=profile.get('blueboss_row0', 0),
|
||||||
|
row1=profile.get('blueboss_row1', 0),
|
||||||
|
sector=profile.get('blueboss_sector', 0),
|
||||||
|
),
|
||||||
|
E.yellowboss(
|
||||||
|
E.p_attack(profile.get('yellowboss_p_attack', [0] * 7), __type="s32"),
|
||||||
|
E.pbest_attack(profile.get('yellowboss_pbest_attack', [0] * 7), __type="s32"),
|
||||||
|
E.defeat(profile.get('yellowboss_defeat', [0] * 7), __type="bool"),
|
||||||
|
E.shop_damage(profile.get('yellowboss_shop_damage', [0] * 7), __type="s32"),
|
||||||
|
critical=profile.get('yellowboss_critical', 0),
|
||||||
|
destiny=profile.get('yellowboss_destiny', 0),
|
||||||
|
first_flg=profile.get('yellowboss_first_flg', 1),
|
||||||
|
heroic0=profile.get('yellowboss_heroic0', 0),
|
||||||
|
heroic1=profile.get('yellowboss_heroic1', 0),
|
||||||
|
join_num=profile.get('yellowboss_join_num', 0),
|
||||||
|
last_select=profile.get('yellowboss_last_select', 0),
|
||||||
|
level=profile.get('yellowboss_level', 1),
|
||||||
|
shop_message=profile.get('yellowboss_shop_message', ""),
|
||||||
|
special_move=profile.get('yellowboss_special_move', ""),
|
||||||
|
),
|
||||||
|
E.link5(
|
||||||
|
anisakis=1,
|
||||||
|
bad=1,
|
||||||
|
beachside=1,
|
||||||
|
beautiful=1,
|
||||||
|
broken=1,
|
||||||
|
castle=1,
|
||||||
|
china=1,
|
||||||
|
cuvelia=1,
|
||||||
|
exusia=1,
|
||||||
|
fallen=1,
|
||||||
|
flip=1,
|
||||||
|
glass=1,
|
||||||
|
glassflg=1,
|
||||||
|
qpro=1,
|
||||||
|
qproflg=1,
|
||||||
|
quaver=1,
|
||||||
|
reflec_data=1,
|
||||||
|
reunion=1,
|
||||||
|
sakura=1,
|
||||||
|
sampling=1,
|
||||||
|
second=1,
|
||||||
|
summer=1,
|
||||||
|
survival=1,
|
||||||
|
thunder=1,
|
||||||
|
titans=1,
|
||||||
|
treasure=1,
|
||||||
|
turii=1,
|
||||||
|
waxing=1,
|
||||||
|
whydidyou=1,
|
||||||
|
wuv=1,
|
||||||
|
),
|
||||||
|
E.cafe(
|
||||||
|
astraia=1,
|
||||||
|
bastie=1,
|
||||||
|
beachimp=1,
|
||||||
|
food=0,
|
||||||
|
holysnow=1,
|
||||||
|
is_first=0,
|
||||||
|
ledvsscu=1,
|
||||||
|
pastry=0,
|
||||||
|
rainbow=1,
|
||||||
|
service=0,
|
||||||
|
trueblue=1,
|
||||||
|
),
|
||||||
|
E.tricolettepark(
|
||||||
|
attack_rate=0,
|
||||||
|
boss0_damage=0,
|
||||||
|
boss0_stun=0,
|
||||||
|
boss1_damage=0,
|
||||||
|
boss1_stun=0,
|
||||||
|
boss2_damage=0,
|
||||||
|
boss2_stun=0,
|
||||||
|
boss3_damage=0,
|
||||||
|
boss3_stun=0,
|
||||||
|
is_union=0,
|
||||||
|
magic_gauge=0,
|
||||||
|
open_music=-1,
|
||||||
|
party=0,
|
||||||
|
),
|
||||||
|
E.weekly(
|
||||||
|
mid=-1,
|
||||||
|
wid=1,
|
||||||
|
),
|
||||||
|
E.packinfo(
|
||||||
|
music_0=-1,
|
||||||
|
music_1=-1,
|
||||||
|
music_2=-1,
|
||||||
|
pack_id=1,
|
||||||
|
),
|
||||||
|
E.visitor(anum=1, pnum=2, snum=1, vs_flg=1),
|
||||||
|
E.gakuen(music_list=-1),
|
||||||
|
E.achievements(
|
||||||
|
E.trophy(
|
||||||
|
profile.get('achievements_trophy', [])[:10],
|
||||||
|
__type="s64"
|
||||||
|
),
|
||||||
|
last_weekly=profile.get('achievements_last_weekly', 0),
|
||||||
|
pack=profile.get('achievements_pack_id', 0),
|
||||||
|
pack_comp=profile.get('achievements_pack_comp', 0),
|
||||||
|
rival_crush=0,
|
||||||
|
visit_flg=profile.get('achievements_visit_flg', 0),
|
||||||
|
weekly_num=profile.get('achievements_weekly_num', 0),
|
||||||
|
),
|
||||||
|
E.step(
|
||||||
|
E.stamp("", __type="bin"),
|
||||||
|
E.help("", __type="bin"),
|
||||||
|
dp_ach=0,
|
||||||
|
dp_hdpt=0,
|
||||||
|
dp_level=0,
|
||||||
|
dp_mplay=0,
|
||||||
|
dp_round=0,
|
||||||
|
review=0,
|
||||||
|
sp_ach=0,
|
||||||
|
sp_hdpt=0,
|
||||||
|
sp_level=0,
|
||||||
|
sp_mplay=0,
|
||||||
|
sp_round=0,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
response_body, response_headers = await core_prepare_response(request, response)
|
||||||
|
return Response(content=response_body, headers=response_headers)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/{gameinfo}/pc/common')
|
||||||
|
async def pc_common(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
E.pc(
|
||||||
|
E.mranking(
|
||||||
|
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
__type="u16"),
|
||||||
|
E.ir(beat=2),
|
||||||
|
E.boss(phase=0),
|
||||||
|
E.red(phase=2),
|
||||||
|
E.yellow(phase=4),
|
||||||
|
E.limit(phase=25),
|
||||||
|
E.cafe(open=1),
|
||||||
|
E.yellow_correct(
|
||||||
|
*[E.detail(
|
||||||
|
avg_shop=7,
|
||||||
|
critical=2,
|
||||||
|
max_condition=18,
|
||||||
|
max_member=20,
|
||||||
|
max_resist=1,
|
||||||
|
min_condition=10,
|
||||||
|
min_member=1,
|
||||||
|
min_resist=1,
|
||||||
|
rival=2
|
||||||
|
)for detail in range(6)],
|
||||||
|
E.detail(
|
||||||
|
avg_shop=7,
|
||||||
|
critical=2,
|
||||||
|
max_condition=144,
|
||||||
|
max_member=20,
|
||||||
|
max_resist=1,
|
||||||
|
min_condition=80,
|
||||||
|
min_member=1,
|
||||||
|
min_resist=1,
|
||||||
|
rival=2
|
||||||
|
),
|
||||||
|
avg_shop=7,
|
||||||
|
),
|
||||||
|
expire=600
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
response_body, response_headers = await core_prepare_response(request, response)
|
||||||
|
return Response(content=response_body, headers=response_headers)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/{gameinfo}/pc/save')
|
||||||
|
async def pc_save(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
game_version = request_info['game_version']
|
||||||
|
|
||||||
|
root = request_info['root'][0]
|
||||||
|
|
||||||
|
xid = int(root.attrib['iidxid'])
|
||||||
|
clt = int(root.attrib['cltype'])
|
||||||
|
|
||||||
|
profile = get_profile_by_id(xid)
|
||||||
|
game_profile = profile['version'].get(str(game_version), {})
|
||||||
|
|
||||||
|
if clt == 0:
|
||||||
|
game_profile['sach'] = root.attrib['achi']
|
||||||
|
game_profile['sp_opt'] = root.attrib['opt']
|
||||||
|
elif clt == 1:
|
||||||
|
game_profile['dach'] = root.attrib['achi']
|
||||||
|
game_profile['dp_opt'] = root.attrib['opt']
|
||||||
|
game_profile['dp_opt2'] = root.attrib['opt2']
|
||||||
|
|
||||||
|
for k in [
|
||||||
|
'gno',
|
||||||
|
'gpos',
|
||||||
|
'help',
|
||||||
|
'hispeed',
|
||||||
|
'judge',
|
||||||
|
'judgeAdj',
|
||||||
|
'lift',
|
||||||
|
'mode',
|
||||||
|
'notes',
|
||||||
|
'opstyle',
|
||||||
|
'pnum',
|
||||||
|
'sdhd',
|
||||||
|
'sdtype',
|
||||||
|
'timing',
|
||||||
|
]:
|
||||||
|
if k in root.attrib:
|
||||||
|
game_profile[k] = root.attrib[k]
|
||||||
|
|
||||||
|
secret = root.find('secret')
|
||||||
|
if secret is not None:
|
||||||
|
for k in ['flg1', 'flg2', 'flg3', 'flg4']:
|
||||||
|
flg = secret.find(k)
|
||||||
|
if flg is not None:
|
||||||
|
game_profile['secret_' + k] = [int(x) for x in flg.text.split(' ')]
|
||||||
|
|
||||||
|
step = root.find('step')
|
||||||
|
if step is not None:
|
||||||
|
for k in [
|
||||||
|
'dp_level',
|
||||||
|
'dp_mplay',
|
||||||
|
'enemy_damage',
|
||||||
|
'enemy_defeat_flg',
|
||||||
|
'mission_clear_num',
|
||||||
|
'progress',
|
||||||
|
'sp_level',
|
||||||
|
'sp_mplay',
|
||||||
|
'tips_read_list',
|
||||||
|
'total_point',
|
||||||
|
]:
|
||||||
|
game_profile['stepup_' + k] = int(step.attrib[k])
|
||||||
|
|
||||||
|
is_track_ticket = step.find('is_track_ticket')
|
||||||
|
if is_track_ticket is not None:
|
||||||
|
game_profile['stepup_is_track_ticket'] = int(is_track_ticket.text)
|
||||||
|
|
||||||
|
|
||||||
|
achievements = root.find('achievements')
|
||||||
|
if achievements is not None:
|
||||||
|
for k in [
|
||||||
|
'last_weekly',
|
||||||
|
'pack_comp',
|
||||||
|
'pack_flg',
|
||||||
|
'pack_id',
|
||||||
|
'play_pack',
|
||||||
|
'visit_flg',
|
||||||
|
'weekly_num',
|
||||||
|
]:
|
||||||
|
game_profile['achievements_' + k] = int(achievements.attrib[k])
|
||||||
|
|
||||||
|
trophy = achievements.find('trophy')
|
||||||
|
if trophy is not None:
|
||||||
|
game_profile['achievements_trophy'] = [int(x) for x in trophy.text.split(' ')]
|
||||||
|
|
||||||
|
grade = request_info['root'][0].find('grade')
|
||||||
|
if grade is not None:
|
||||||
|
grade_values = []
|
||||||
|
for g in grade.findall('g'):
|
||||||
|
grade_values.append([int(x) for x in g.text.split(' ')])
|
||||||
|
|
||||||
|
profile['grade_single'] = int(grade.attrib['sgid'])
|
||||||
|
profile['grade_double'] = int(grade.attrib['dgid'])
|
||||||
|
profile['grade_values'] = grade_values
|
||||||
|
|
||||||
|
deller_amount = game_profile.get('deller', 0)
|
||||||
|
commonboss = root.find('commonboss')
|
||||||
|
if commonboss is not None:
|
||||||
|
deller_amount = int(commonboss.attrib['deller'])
|
||||||
|
game_profile['deller'] = deller_amount
|
||||||
|
|
||||||
|
game_profile['spnum'] = game_profile.get('spnum', 0) + (1 if clt == 0 else 0)
|
||||||
|
game_profile['dpnum'] = game_profile.get('dpnum', 0) + (1 if clt == 1 else 0)
|
||||||
|
|
||||||
|
profile['version'][str(game_version)] = game_profile
|
||||||
|
|
||||||
|
get_db().table('iidx_profile').upsert(profile, where('iidx_id') == xid)
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
E.pc(
|
||||||
|
iidxid=xid,
|
||||||
|
cltype=clt
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
response_body, response_headers = await core_prepare_response(request, response)
|
||||||
|
return Response(content=response_body, headers=response_headers)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/{gameinfo}/pc/visit')
|
||||||
|
async def pc_visit(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
E.pc(
|
||||||
|
aflg=1,
|
||||||
|
anum=1,
|
||||||
|
pflg=1,
|
||||||
|
pnum=1,
|
||||||
|
sflg=1,
|
||||||
|
snum=1,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
response_body, response_headers = await core_prepare_response(request, response)
|
||||||
|
return Response(content=response_body, headers=response_headers)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/{gameinfo}/pc/reg')
|
||||||
|
async def pc_reg(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
game_version = request_info['game_version']
|
||||||
|
|
||||||
|
cid = request_info['root'][0].attrib['cid']
|
||||||
|
name = request_info['root'][0].attrib['name']
|
||||||
|
pid = request_info['root'][0].attrib['pid']
|
||||||
|
|
||||||
|
db = get_db().table('iidx_profile')
|
||||||
|
all_profiles_for_card = db.get(Query().card == cid)
|
||||||
|
|
||||||
|
if all_profiles_for_card is None:
|
||||||
|
all_profiles_for_card = {
|
||||||
|
'card': cid,
|
||||||
|
'version': {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if 'iidx_id' not in all_profiles_for_card:
|
||||||
|
iidx_id = random.randint(10000000, 99999999)
|
||||||
|
all_profiles_for_card['iidx_id'] = iidx_id
|
||||||
|
|
||||||
|
all_profiles_for_card['version'][str(game_version)] = {
|
||||||
|
'game_version': game_version,
|
||||||
|
'djname': name,
|
||||||
|
'region': int(pid),
|
||||||
|
'head': 0,
|
||||||
|
'hair': 0,
|
||||||
|
'face': 0,
|
||||||
|
'hand': 0,
|
||||||
|
'body': 0,
|
||||||
|
'turntable': 0,
|
||||||
|
'explosion': 0,
|
||||||
|
'bgm': 0,
|
||||||
|
'folder_mask': 0,
|
||||||
|
'sudden': 0,
|
||||||
|
'categoryvoice': 0,
|
||||||
|
'note': 0,
|
||||||
|
'fullcombo': 0,
|
||||||
|
'keybeam': 0,
|
||||||
|
'judgestring': 0,
|
||||||
|
'soundpreview': 0,
|
||||||
|
'dach': 0,
|
||||||
|
'dp_opt': 0,
|
||||||
|
'dp_opt2': 0,
|
||||||
|
'dpnum': 0,
|
||||||
|
'gno': 0,
|
||||||
|
'gpos': 0,
|
||||||
|
'help': 0,
|
||||||
|
'hispeed': 0,
|
||||||
|
'judge': 0,
|
||||||
|
'judgeAdj': 0,
|
||||||
|
'lift': 0,
|
||||||
|
'mode': 0,
|
||||||
|
'notes': 0,
|
||||||
|
'opstyle': 0,
|
||||||
|
'pase': 0,
|
||||||
|
'pmode': 0,
|
||||||
|
'sach': 0,
|
||||||
|
'sdhd': 50,
|
||||||
|
'sdtype': 0,
|
||||||
|
'sp_opt': 0,
|
||||||
|
'spnum': 0,
|
||||||
|
'timing': 0,
|
||||||
|
'deller': 0,
|
||||||
|
|
||||||
|
# Step up mode
|
||||||
|
'stepup_dp_level': 0,
|
||||||
|
'stepup_dp_mplay': 0,
|
||||||
|
'stepup_enemy_damage': 0,
|
||||||
|
'stepup_enemy_defeat_flg': 0,
|
||||||
|
'stepup_mission_clear_num': 0,
|
||||||
|
'stepup_progress': 0,
|
||||||
|
'stepup_sp_level': 0,
|
||||||
|
'stepup_sp_mplay': 0,
|
||||||
|
'stepup_tips_read_list': 0,
|
||||||
|
'stepup_total_point': 0,
|
||||||
|
'stepup_is_track_ticket': 0,
|
||||||
|
|
||||||
|
# Grades
|
||||||
|
'grade_single': -1,
|
||||||
|
'grade_double': -1,
|
||||||
|
'grade_values': [],
|
||||||
|
|
||||||
|
# Achievements
|
||||||
|
'achievements_trophy': [0] * 80,
|
||||||
|
'achievements_last_weekly': 0,
|
||||||
|
'achievements_pack_comp': 0,
|
||||||
|
'achievements_pack_flg': 0,
|
||||||
|
'achievements_pack_id': 0,
|
||||||
|
'achievements_play_pack': 0,
|
||||||
|
'achievements_visit_flg': 0,
|
||||||
|
'achievements_weekly_num': 0,
|
||||||
|
|
||||||
|
# Web UI/Other options
|
||||||
|
'_show_category_grade': 0,
|
||||||
|
'_show_category_status': 1,
|
||||||
|
'_show_category_difficulty': 1,
|
||||||
|
'_show_category_alphabet': 1,
|
||||||
|
'_show_category_rival_play': 0,
|
||||||
|
'_show_category_rival_winlose': 0,
|
||||||
|
'_show_rival_shop_info': 0,
|
||||||
|
'_hide_play_count': 0,
|
||||||
|
'_hide_rival_info': 1,
|
||||||
|
}
|
||||||
|
db.upsert(all_profiles_for_card, where('card') == cid)
|
||||||
|
|
||||||
|
card, card_split = get_id_from_profile(cid)
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
E.pc(
|
||||||
|
id=card,
|
||||||
|
id_str=card_split
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
response_body, response_headers = await core_prepare_response(request, response)
|
||||||
|
return Response(content=response_body, headers=response_headers)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/{gameinfo}/pc/logout')
|
||||||
|
async def pc_logout(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
E.pc()
|
||||||
|
)
|
||||||
|
|
||||||
|
response_body, response_headers = await core_prepare_response(request, response)
|
||||||
|
return Response(content=response_body, headers=response_headers)
|
20
modules/iidx/ranking.py
Normal file
20
modules/iidx/ranking.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import config
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Request, Response
|
||||||
|
|
||||||
|
from core_common import core_process_request, core_prepare_response, E
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/local2", tags=["local2"])
|
||||||
|
router.model_whitelist = ["LDJ"]
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/{gameinfo}/ranking/getranker')
|
||||||
|
async def ranking_getranker(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
E.ranking()
|
||||||
|
)
|
||||||
|
|
||||||
|
response_body, response_headers = await core_prepare_response(request, response)
|
||||||
|
return Response(content=response_body, headers=response_headers)
|
69
modules/iidx/shop.py
Normal file
69
modules/iidx/shop.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import config
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Request, Response
|
||||||
|
|
||||||
|
from core_common import core_process_request, core_prepare_response, E
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/local", tags=["local"])
|
||||||
|
router.model_whitelist = ["LDJ"]
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/{gameinfo}/shop/getname')
|
||||||
|
async def shop_getname(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
E.shop(
|
||||||
|
cls_opt=0,
|
||||||
|
opname=config.arcade,
|
||||||
|
pid=13,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
response_body, response_headers = await core_prepare_response(request, response)
|
||||||
|
return Response(content=response_body, headers=response_headers)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/{gameinfo}/shop/getconvention')
|
||||||
|
async def shop_getconvention(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
|
||||||
|
response = E.response(
|
||||||
|
E.shop(
|
||||||
|
E.valid(1, __type="bool"),
|
||||||
|
music_0=-1,
|
||||||
|
music_1=-1,
|
||||||
|
music_2=-1,
|
||||||
|
music_3=-1,
|
||||||
|
start_time=0,
|
||||||
|
end_time=0,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
response_body, response_headers = await core_prepare_response(request, response)
|
||||||
|
return Response(content=response_body, headers=response_headers)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/{gameinfo}/shop/sentinfo')
|
||||||
|
async def shop_sentinfo(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
|
||||||
|
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')
|
||||||
|
async def shop_sendescapepackageinfo(request: Request):
|
||||||
|
request_info = await core_process_request(request)
|
||||||
|
|
||||||
|
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)
|
Loading…
Reference in New Issue
Block a user