MonkeyBusiness/modules/gitadora/gameend.py
2023-01-04 07:13:45 +00:00

346 lines
12 KiB
Python

from tinydb import Query, where
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 = ["M32"]
def get_profile(cid):
return get_db().table("gitadora_profile").get(where("card") == cid)
def get_game_profile(cid, game_version):
profile = get_profile(cid)
return profile["version"].get(str(game_version), None)
@router.post("/{gameinfo}/{ver}_gameend/regist")
async def gitadora_gameend_regist(ver: str, request: Request):
request_info = await core_process_request(request)
game_version = request_info["game_version"]
spec = request_info["spec"]
if spec == "A":
g = "guitarfreaks"
elif spec == "B":
g = "drummania"
root = request_info["root"][0]
players = root.findall("player")
for player in players:
no = int(player.attrib["no"])
if player.attrib["card"] != "use":
continue
dataid = player.find("refid").text
profile = get_profile(dataid)
gitadora_id = profile["gitadora_id"]
game_profile = profile["version"].get(str(game_version), {})
game_profile[g]["customdata_playstyle"] = [
int(x) for x in player.find("customdata/playstyle").text.split(" ")
]
game_profile[g]["customdata_custom"] = [
int(x) for x in player.find("customdata/custom").text.split(" ")
]
for k in [
"cabid",
"play",
"playtime",
"playterm",
"session_cnt",
"matching_num",
"extra_stage",
"extra_play",
"extra_clear",
"encore_play",
"encore_clear",
"pencore_play",
"pencore_clear",
"max_clear_diff",
"max_full_diff",
"max_exce_diff",
"clear_num",
"full_num",
"exce_num",
"no_num",
"e_num",
"d_num",
"c_num",
"b_num",
"a_num",
"s_num",
"ss_num",
"last_category",
"last_musicid",
"last_seq",
"disp_level",
]:
game_profile[g]["playinfo_" + k] = int(player.find(f"playinfo/{k}").text)
game_profile[g]["tutorial_progress"] = int(
player.find("tutorial/progress").text
)
game_profile[g]["tutorial_disp_state"] = int(
player.find("tutorial/disp_state").text
)
game_profile[g]["information"] = [
int(x) for x in player.find("information/info").text.split(" ")
]
game_profile[g]["reward"] = [
int(x) for x in player.find("reward/status").text.split(" ")
]
game_profile[g]["skilldata_skill"] = int(player.find("skilldata/skill").text)
game_profile[g]["skilldata_allskill"] = int(
player.find("skilldata/all_skill").text
)
groove = [
"extra_gauge",
"encore_gauge",
"encore_cnt",
"encore_success",
]
if game_version > 6:
groove.append("unlock_point")
for k in groove:
game_profile[g]["groove_" + k] = int(player.find(f"groove/{k}").text)
record_max = [
"skill",
"all_skill",
"clear_diff",
"full_diff",
"exce_diff",
"clear_music_num",
"full_music_num",
"exce_music_num",
"clear_seq_num",
]
if game_version > 6:
record_max.append("classic_all_skill")
for k in record_max:
game_profile[g]["record_max_" + k] = int(
player.find(f"record/max/{k}").text
)
for k in [
"diff_100_nr",
"diff_150_nr",
"diff_200_nr",
"diff_250_nr",
"diff_300_nr",
"diff_350_nr",
"diff_400_nr",
"diff_450_nr",
"diff_500_nr",
"diff_550_nr",
"diff_600_nr",
"diff_650_nr",
"diff_700_nr",
"diff_750_nr",
"diff_800_nr",
"diff_850_nr",
"diff_900_nr",
"diff_950_nr",
]:
game_profile[g]["record_" + k] = int(player.find(f"record/diff/{k}").text)
for k in [
"diff_100_clear",
"diff_150_clear",
"diff_200_clear",
"diff_250_clear",
"diff_300_clear",
"diff_350_clear",
"diff_400_clear",
"diff_450_clear",
"diff_500_clear",
"diff_550_clear",
"diff_600_clear",
"diff_650_clear",
"diff_700_clear",
"diff_750_clear",
"diff_800_clear",
"diff_850_clear",
"diff_900_clear",
"diff_950_clear",
]:
game_profile[g]["record_" + k] = [
int(x) for x in player.find(f"record/diff/{k}").text.split(" ")
]
for k in [
"music_list_1",
"music_list_2",
"music_list_3",
]:
game_profile[g]["favorite_" + k] = [
int(x) for x in player.find(f"favoritemusic/{k}").text.split(" ")
]
profile["version"][str(game_version)] = game_profile
get_db().table("gitadora_profile").upsert(profile, where("card") == dataid)
stage = player.findall("stage")
for s in stage:
data_version = root.find("data_version").text
timestamp = int(s.find("date_ms").text)
musicid = int(s.find("musicid").text)
seq = int(s.find("seq").text)
skill = int(s.find("skill").text)
new_skill = int(s.find("new_skill").text)
clear = int(s.find("clear").text)
auto_clear = int(s.find("auto_clear").text)
fullcombo = int(s.find("fullcombo").text)
excellent = int(s.find("excellent").text)
medal = int(s.find("medal").text)
perc = int(s.find("perc").text)
new_perc = int(s.find("new_perc").text)
rank = int(s.find("rank").text)
score = int(s.find("score").text)
combo = int(s.find("combo").text)
max_combo_perc = int(s.find("max_combo_perc").text)
flags = int(s.find("flags").text)
phrase_combo_perc = int(s.find("phrase_combo_perc").text)
perfect = int(s.find("perfect").text)
great = int(s.find("great").text)
good = int(s.find("good").text)
ok = int(s.find("ok").text)
miss = int(s.find("miss").text)
perfect_perc = int(s.find("perfect_perc").text)
great_perc = int(s.find("great_perc").text)
good_perc = int(s.find("good_perc").text)
ok_perc = int(s.find("ok_perc").text)
miss_perc = int(s.find("miss_perc").text)
meter = int(s.find("meter").text)
meter_prog = int(s.find("meter_prog").text)
before_meter = int(s.find("before_meter").text)
before_meter_prog = int(s.find("before_meter_prog").text)
is_new_meter = int(s.find("is_new_meter").text)
phrase_data_num = int(s.find("phrase_data_num").text)
phrase_addr = [int(x) for x in s.find("phrase_addr").text.split(" ")]
phrase_type = [int(x) for x in s.find("phrase_type").text.split(" ")]
phrase_status = [int(x) for x in s.find("phrase_status").text.split(" ")]
phrase_end_addr = int(s.find("phrase_end_addr").text)
get_db().table(f"{g}_scores").insert(
{
"timestamp": timestamp,
"game_version": game_version,
"gitadora_id": gitadora_id,
"data_version": data_version,
"musicid": musicid,
"seq": seq,
"skill": skill,
"new_skill": new_skill,
"clear": clear,
"auto_clear": auto_clear,
"fullcombo": fullcombo,
"excellent": excellent,
"medal": medal,
"perc": perc,
"new_perc": new_perc,
"rank": rank,
"score": score,
"combo": combo,
"max_combo_perc": max_combo_perc,
"flags": flags,
"phrase_combo_perc": phrase_combo_perc,
"perfect": perfect,
"great": great,
"good": good,
"ok": ok,
"miss": miss,
"perfect_perc": perfect_perc,
"great_perc": great_perc,
"good_perc": good_perc,
"ok_perc": ok_perc,
"miss_perc": miss_perc,
"meter": meter,
"meter_prog": meter_prog,
"before_meter": before_meter,
"before_meter_prog": before_meter_prog,
"is_new_meter": is_new_meter,
"phrase_data_num": phrase_data_num,
"phrase_addr": phrase_addr,
"phrase_type": phrase_type,
"phrase_status": phrase_status,
"phrase_end_addr": phrase_end_addr,
},
)
best_score = (
get_db()
.table(f"{g}_scores_best")
.get(
(where("gitadora_id") == gitadora_id)
& (where("musicid") == musicid)
& (where("seq") == seq)
)
)
best_score = {} if best_score is None else best_score
best_perc = best_score.get("perc", perc)
best_score_data = {
"gitadora_id": gitadora_id,
"musicid": musicid,
"seq": seq,
"skill": max(skill, best_score.get("skill", skill)),
"clear": max(clear, best_score.get("clear", clear)),
"fullcombo": max(fullcombo, best_score.get("fullcombo", fullcombo)),
"excellent": max(excellent, best_score.get("excellent", excellent)),
"perc": max(perc, best_score.get("perc", perc)),
"rank": max(rank, best_score.get("rank", rank)),
"meter": meter
if perc >= best_perc
else best_score.get("meter", meter),
"meter_prog": meter_prog
if perc >= best_perc
else best_score.get("meter_prog", meter_prog),
}
get_db().table(f"{g}_scores_best").upsert(
best_score_data,
(where("gitadora_id") == gitadora_id)
& (where("musicid") == musicid)
& (where("seq") == seq),
)
response = E.response(
E(
f"{ver}_gameend",
E.gamemode(mode="game_mode"),
E.player(
E.skill(
E.rank(1, __type="s32"),
E.total_nr(1, __type="s32"),
),
E.all_skill(
E.rank(1, __type="s32"),
E.total_nr(1, __type="s32"),
),
no=no,
state=0,
),
)
)
response_body, response_headers = await core_prepare_response(request, response)
return Response(content=response_body, headers=response_headers)