MonkeyBusiness/utils/db/import_ddr_spice_automap.py
2023-06-10 13:17:40 +00:00

141 lines
4.8 KiB
Python

import argparse
import xml.etree.ElementTree as ET
from tinydb import TinyDB, where
from tinydb.middlewares import CachingMiddleware
from tinydb.storages import JSONStorage
def main(automap_xml, version, monkey_db, ddr_id):
storage = CachingMiddleware(JSONStorage)
storage.WRITE_CACHE_SIZE = 5000
db = TinyDB(
monkey_db,
indent=2,
encoding="utf-8",
ensure_ascii=False,
storage=storage,
)
ddr_id = int(ddr_id.replace("-", ""))
profile = db.table("ddr_profile").get(where("ddr_id") == ddr_id)
if profile == None:
raise SystemExit(f"ERROR: DDR profile {ddr_id} not in {monkey_db}")
game_version = 19
if profile["version"].get(str(game_version), None) == None:
raise SystemExit(
f"ERROR: DDR profile {ddr_id} version {game_version} not in {monkey_db}"
)
scores = []
with open(automap_xml, "rb") as fp:
automap_0 = fp.read().split(b"\n\n")
if version == 19:
playerdata = "playerdata"
else:
playerdata = "playerdata_2"
scores_xml = False
for xml in automap_0:
tree = ET.ElementTree(ET.fromstring(xml.decode(encoding="shift-jis")))
root = tree.getroot()
if scores_xml:
for music in root.findall(f"{playerdata}/music"):
mcode = int(music.find("mcode").text)
for difficulty, chart in enumerate(music.findall("note")):
if int(chart.find("count").text) > 0:
rank = int(chart.find("rank").text)
clearkind = int(chart.find("clearkind").text)
score = int(chart.find("score").text)
scores.append([mcode, difficulty, rank, clearkind, score])
break
else:
try:
if root.find(f"{playerdata}/data/mode").text == "userload":
if len(root.find(f"{playerdata}/data/refid").text) == 16:
scores_xml = True
except AttributeError:
continue
total_count = len(scores)
if total_count == 0:
raise SystemExit("ERROR: No scores to import")
for s in scores:
mcode = s[0]
difficulty = s[1]
rank = s[2]
lamp = s[3]
score = s[4]
exscore = 0
print(
f"mcode: {mcode}, difficulty: {difficulty}, rank: {rank}, score: {score}, lamp: {lamp}"
)
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": 0 if difficulty < 5 else 1,
"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("exscore") == best.get("exscore", exscore))
)
if ghostid:
best_score_data["ghostid"] = ghostid.doc_id
else:
best_score_data["ghostid"] = -1
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),
)
db.close()
print()
print(f"{total_count} scores imported to DDR profile {ddr_id} in {monkey_db}")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--automap_xml", help="Input xml file", required=True)
parser.add_argument(
"--version",
help="19 is A20P, 20 is A3",
default=19,
type=int,
)
parser.add_argument("--monkey_db", help="Output json file", required=True)
parser.add_argument("--ddr_id", help="12345678", required=True)
args = parser.parse_args()
main(args.automap_xml, args.version, args.monkey_db, args.ddr_id)