aboutsummaryrefslogtreecommitdiffstats
path: root/sdvx
diff options
context:
space:
mode:
authorPinapelz <yukais@pinapelz.com>2025-05-12 15:04:41 -0700
committerPinapelz <yukais@pinapelz.com>2025-05-12 15:06:36 -0700
commit56239d76b13081aa9f7d50e555198597fc1979dc (patch)
treeabe6244e3065004711759f986d968789eb858aa9 /sdvx
parent32a90095610afe49403f85d430b7bf5c1ad4c1a9 (diff)
sdvx_asphyxia: add 22vv0 asphyxia
Diffstat (limited to 'sdvx')
-rw-r--r--sdvx/asphyxia/22vv0_kfc_to_tachi.py120
-rw-r--r--sdvx/asphyxia/README.md7
2 files changed, 127 insertions, 0 deletions
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
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage