1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
import argparse
import json
import os
from datetime import datetime
LAMP_MAP = {
1: "FAILED",
2: "ASSIST CLEAR",
3: "EASY CLEAR",
4: "CLEAR",
5: "HARD CLEAR",
6: "EX HARD CLEAR",
7: "FULL COMBO"
}
DIFFICULTY_MAP = { # Beginner difficulty not supported
1: "NORMAL",
2: "HYPER",
3: "ANOTHER",
4: "LEGGENDARIA",
6: "DP NORMAL",
7: "DP HYPER",
8: "DP ANOTHER",
9: "DP LEGGENDARIA"
}
def convert_duel0213_to_tachi(file: str, single_output_path: str, double_output_path: str, service: str):
with open(file, "r", encoding="utf-8") as infile:
sp_scores = []
dp_scores = []
export_data = json.load(infile)
data_sect = export_data["data"]
for score_id in data_sect:
data = data_sect[score_id]
if data["collection"] != "score":
continue
music_id = str(data["mid"])
cArray = data["cArray"]
played_levels = []
for i in range(10):
if i == 0 or i == 5: # skip BEGINNER
continue
if cArray[i] != 0:
played_levels.append((i, cArray[i]))
for diff, lamp_val in played_levels:
score = data["esArray"][diff]
difficulty = DIFFICULTY_MAP[diff]
pgreat = data["pgArray"][diff]
great = data["gArray"][diff]
lamp = LAMP_MAP[lamp_val]
timestamp_str = data["updatedAt"]
timestamp = int(datetime.fromisoformat(timestamp_str.replace('Z', '+00:00')).timestamp() * 1000)
judgements = {
"pgreat": pgreat,
"great": great,
}
score_obj = {
"score": score,
"timeAchieved": timestamp,
"matchType": "inGameID",
"identifier": music_id,
"lamp": lamp,
"difficulty": difficulty,
"judgements": judgements
}
if diff <= 4: # SP
sp_scores.append(score_obj)
else:
dp_scores.append(score_obj)
batch_manual_single = {"meta": {"game": "iidx", "playtype": "SP", "service": service}, "scores": sp_scores}
batch_manual_double = {"meta": {"game": "iidx", "playtype": "DP", "service": service}, "scores": dp_scores}
with open(single_output_path, "w", encoding="utf-8") as spoutfile:
json.dump(batch_manual_single, spoutfile, indent=4, ensure_ascii=False)
print(f"SP Output saved to {single_output_path}")
with open(double_output_path, "w", encoding="utf-8") as dpoutfile:
json.dump(batch_manual_double, dpoutfile, indent=4, ensure_ascii=False)
print(f"DP Output saved to {double_output_path}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog="iidx_duel0213_to_tachi.py",
description="Converts duel0213 Asphyxia IIDX save data to Tachi compatible JSON",
)
parser.add_argument(
"-s",
"--service",
help="Service description to be shown on Tachi (Note for where this score came from)",
default="beatmania IIDX Asphyxia Export",
)
parser.add_argument("-f", "--file", help="Score Export JSON Get this by going to the WebUI -> Profiles -> Detail -> Data -> Score Export", required=True)
parser.add_argument(
"-so", "--sp-output", help="Output filename for SP scores", default="iidx_scores_sp.json"
)
parser.add_argument(
"-do", "--dp-output", help="Output filename for DP scores", default="iidx_scores_dp.json"
)
args = parser.parse_args()
if args.file is None:
print("ERROR: Please specify score JSON. Get this by going to the WebUI -> Profiles -> Detail -> Data -> Score Export")
exit(1)
if not os.path.exists(args.file):
print(f"ERROR: The file {args.file} does not exist.")
exit(1)
convert_duel0213_to_tachi(args.file, args.sp_output, args.dp_output, args.service)
|