aboutsummaryrefslogtreecommitdiffstats
path: root/chuni/aquadx/chuni_aquadx_to_tachi.py
blob: 4063ac22d1882e9a656fca318093d453aa7cee4d (plain) (blame)
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
import argparse
import json

DIFFICULTY_MAPPING = {
    0: "BASIC",
    1: "ADVANCED",
    2: "EXPERT",
    3: "MASTER",
    4: "ULTIMA",
    5: "WORLD'S END",
}

def convert_chuni_aquadx_json_to_tachi_json(input_json: str, output_file: str, service: str):
    with open(input_json, "r", encoding="utf-8") as f:
        raw_data = json.load(f)

    batch_manual = {
        "meta": {"game": "chunithm", "playtype": "Single", "service": service},
        "scores": [],
    }

    processed_count = 0
    skipped_count = 0

    if "userPlaylogList" in raw_data:
        for entry in raw_data["userPlaylogList"]:
            level = entry.get("level", 0)

            # Skip World's End, Unsupported by Tachi
            if level == 5 or level not in DIFFICULTY_MAPPING:
                skipped_count += 1
                continue

            processed_count += 1
            music_id = entry["musicId"]

            score_value = entry.get("score", 0)
            is_clear = entry.get("isClear", False)
            is_full_combo = entry.get("isFullCombo", False)
            is_all_justice = entry.get("isAllJustice", False)
            is_all_perfect = entry.get("isAllPerfect", False)
            lamp = "FAILED"
            if is_all_perfect:
                lamp = "ALL JUSTICE CRITICAL"
            elif is_all_justice:
                lamp = "ALL JUSTICE"
            elif is_full_combo:
                lamp = "FULL COMBO"
            elif is_clear:
                lamp = "CLEAR"
            timestamp = entry.get("sortNumber", None)

            jcrit = entry.get("judgeHeaven", 0) + entry.get("judgeCritical", 0)
            justice = entry.get("judgeJustice", 0)
            attack = entry.get("judgeAttack", 0)
            miss = entry.get("judgeGuilty", 0)
            combo = entry.get("maxCombo", 0)

            score_entry = {
                "score": score_value,
                "lamp": lamp,
                "matchType": "inGameID",
                "identifier": str(music_id),
                "difficulty": DIFFICULTY_MAPPING[level],
                "timeAchieved": timestamp * 1000 if timestamp else None,
                "judgements": {
                    "jcrit": jcrit,
                    "justice": justice,
                    "attack": attack,
                    "miss": miss,
                },
                "optional": {"maxCombo": combo},
            }

            batch_manual["scores"].append(score_entry)

    with open(output_file, "w", encoding="utf-8") as f:
        print("--- Processing Summary ---")
        print(f"Total scores processed: {processed_count}")
        print(f"Scores skipped (level 5 or invalid): {skipped_count}")
        print(f"Output saved to {output_file}")
        json.dump(batch_manual, f, indent=4, ensure_ascii=False)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        prog="chuni_aquadx_to_tachi",
        description="Converts AquaDX score data for Chuni to Tachi compatible JSON",
        epilog="Fast/Slow can't be derived (I think)",
    )
    parser.add_argument("input_file", help="Path to the input JSON file exported from AquaDX")
    parser.add_argument(
        "-s",
        "--service",
        help="Service description to be shown on Tachi (Note for where this score came from)",
        default="AquaDX Chuni Import",
    )
    parser.add_argument(
        "-o", "--output", help="Output filename", default="aquadx_chuni_tachi.json"
    )
    args = parser.parse_args()
    convert_chuni_aquadx_json_to_tachi_json(args.input_file, args.output, args.service)
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage