diff options
| author | Pinapelz <yukais@pinapelz.com> | 2025-05-12 15:04:41 -0700 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2025-05-12 15:06:36 -0700 |
| commit | 56239d76b13081aa9f7d50e555198597fc1979dc (patch) | |
| tree | abe6244e3065004711759f986d968789eb858aa9 | |
| parent | 32a90095610afe49403f85d430b7bf5c1ad4c1a9 (diff) | |
sdvx_asphyxia: add 22vv0 asphyxia
| -rw-r--r-- | jubeat/asphyxia/czeave_to_tachi.py | 2 | ||||
| -rw-r--r-- | sdvx/asphyxia/22vv0_kfc_to_tachi.py | 120 | ||||
| -rw-r--r-- | sdvx/asphyxia/README.md | 7 |
3 files changed, 128 insertions, 1 deletions
diff --git a/jubeat/asphyxia/czeave_to_tachi.py b/jubeat/asphyxia/czeave_to_tachi.py index e06b396..9038b24 100644 --- a/jubeat/asphyxia/czeave_to_tachi.py +++ b/jubeat/asphyxia/czeave_to_tachi.py @@ -65,7 +65,7 @@ if __name__ == "__main__": parser.add_argument( "-o", "--output", help="Output filename", default="czeave_asphyxia_batch_manual.json" ) - parser.add_argument("-p", "--profile", help="Asphyxia Profile ID to export for") + parser.add_argument("-p", "--profile", help="Asphyxia Profile ID to export for", required=True) args = parser.parse_args() if args.file is None: print("ERROR: Please specify Asphyxia DB file (from savedata folder)") diff --git a/sdvx/asphyxia/22vv0_kfc_to_tachi.py b/sdvx/asphyxia/22vv0_kfc_to_tachi.py new file mode 100644 index 0000000..58ecc22 --- /dev/null +++ b/sdvx/asphyxia/22vv0_kfc_to_tachi.py @@ -0,0 +1,120 @@ +import argparse +import json +import os +import requests + + +LAMP_MAP = { + 1: "FAILED", + 2: "CLEAR", + 3: "EXCESSIVE CLEAR", + 4: "ULTIMATE CHAIN", + 5: "PERFECT ULTIMATE CHAIN" +} + +DIFFICULTY_MAP = { + 0: "NOV", + 1: "ADV", + 2: "EXH", + 3: "GAME_SPECIFIC", + 4: "MXM" +} + + +def load_seeds(url: str = "https://raw.githubusercontent.com/zkrising/Tachi/refs/heads/main/seeds/collections/charts-sdvx.json") -> dict: + print("Loading seeds from:", url) + response = requests.get(url) + response.raise_for_status() + return response.json() + +def find_chart_difficulties(in_game_id: int, seeds: dict = None): + low, high = 0, len(seeds) - 1 + results = [] + while low <= high: + mid = (low + high) // 2 + chart = seeds[mid] + if chart["data"]["inGameID"] == in_game_id: + results.append(chart) + left, right = mid - 1, mid + 1 + while left >= 0 and seeds[left]["data"]["inGameID"] == in_game_id: + results.append(seeds[left]) + left -= 1 + while right < len(seeds) and seeds[right]["data"]["inGameID"] == in_game_id: + results.append(seeds[right]) + right += 1 + break + elif chart["data"]["inGameID"] < in_game_id: + low = mid + 1 + else: + high = mid - 1 + for result in results: + if result["difficulty"] not in DIFFICULTY_MAP.values(): + return result["difficulty"] + return None + + +def convert_22vv0_sdvx_to_tachi_json(file: str, output_path: str, service: str, profile_id: str): + seeds = load_seeds() + with open(file, "r", encoding="utf-8") as infile: + batch_manual = { + "meta": {"game": "sdvx", "playtype": "Single", "service": service}, + } + scores = [] + for line in infile: + data = json.loads(line) + if "collection" not in data.keys(): + continue + if data["collection"] == "music": + music_id = data["mid"] + difficulty = DIFFICULTY_MAP[data["type"]] + if difficulty == "GAME_SPECIFIC": + difficulty = find_chart_difficulties(music_id, seeds) + if difficulty is None: + print("[ERROR] -> Difficulty for", music_id, " was not found in Tachi seeds") + continue + score = data["score"] + exscore = data["exscore"] + lamp = LAMP_MAP[data["clear"]] + timestamp = data["updatedAt"]["$$date"] + scores.append({ + "score": score, + "lamp": lamp, + "matchType": "sdvxInGameID", + "identifier": str(data["mid"]), + "difficulty": difficulty, + "timeAchieved": timestamp, + "optional": { + "exScore": exscore + } + }) + batch_manual["scores"] = scores + with open(output_path, "w", encoding="utf-8") as outfile: + json.dump(batch_manual, outfile, indent=4, ensure_ascii=False) + print(f"Output saved to {output_path}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + prog="22vv0_kfc_to_tachi.py", + description="Converts 22vv0 Asphyxia SDVX (KFC) 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="SOUND VOLTEX Asphyxia (22vv0)", + ) + parser.add_argument("-f", "--file", help="AsphyxiaCORE SOND VOLREX .db file (sdvx@asphyxia.db)", required=True) + parser.add_argument( + "-o", "--output", help="Output filename", default="sdvx_asphyxia_batch_manual.json" + ) + parser.add_argument("-p", "--profile", help="Asphyxia Profile ID to export for") + args = parser.parse_args() + if args.file is None: + print("ERROR: Please specify Asphyxia DB file (from savedata folder)") + exit(1) + if not os.path.exists(args.file): + print(f"ERROR: The file {args.file} does not exist.") + exit(1) + + convert_22vv0_sdvx_to_tachi_json(args.file, args.output, args.service, args.profile) diff --git a/sdvx/asphyxia/README.md b/sdvx/asphyxia/README.md new file mode 100644 index 0000000..6e2d4ac --- /dev/null +++ b/sdvx/asphyxia/README.md @@ -0,0 +1,7 @@ +# 22vv0 Asphyxia SOUND VOLTEX to Batch Manual + +[Plugin Repo](https://github.com/22vv0/asphyxia_plugins) + +Pass in your `sdvx@asphyxia.db` as `-f` or `--file`, this can be found in the `savedata` folder of wherever your Asphyxia executable is. + +Your Profile ID can be found by going to `Asphyxia WebUI -> Profile` and copy the ID there for the appropriate profile |
