From b2feb9a130c2693447de41ff8f9be473d4fce5c3 Mon Sep 17 00:00:00 2001
From: Raymond <101374892+raymonable@users.noreply.github.com>
Date: Sat, 6 Jun 2026 22:19:12 -0400
Subject: [PATCH] feat: [ongeki] data export/import
---
.../components/settings/OngekiSettings.svelte | 12 +++
.../src/pages/Home/ImportDataAction.svelte | 2 +
.../aqua/net/games/ongeki/OngekiImport.kt | 73 +++++++++++++++++++
3 files changed, 87 insertions(+)
create mode 100644 src/main/java/icu/samnyan/aqua/net/games/ongeki/OngekiImport.kt
diff --git a/AquaNet/src/components/settings/OngekiSettings.svelte b/AquaNet/src/components/settings/OngekiSettings.svelte
index 110f5ae7..ebf87977 100644
--- a/AquaNet/src/components/settings/OngekiSettings.svelte
+++ b/AquaNet/src/components/settings/OngekiSettings.svelte
@@ -2,8 +2,20 @@
import { fade } from "svelte/transition";
import { FADE_IN, FADE_OUT } from "../../libs/config";
import GameSettingFields from "./GameSettingFields.svelte";
+
+ function exportData() {
+ submitting = "export"
+ GAME.export('ongeki')
+ .then(data => download(JSON.stringify(data), `AquaDX_ongeki_export_${values[0]}.json`))
+ .catch(e => error = e.message)
+ .finally(() => submitting = "")
+ }
+
diff --git a/AquaNet/src/pages/Home/ImportDataAction.svelte b/AquaNet/src/pages/Home/ImportDataAction.svelte
index 52f44bb6..e4115f40 100644
--- a/AquaNet/src/pages/Home/ImportDataAction.svelte
+++ b/AquaNet/src/pages/Home/ImportDataAction.svelte
@@ -69,6 +69,8 @@
return 'mai2';
case 'SDHD':
return 'chu3';
+ case 'SDDT':
+ return 'ongeki';
default:
throw new Error(t('home.import.unknown-game'));
}
diff --git a/src/main/java/icu/samnyan/aqua/net/games/ongeki/OngekiImport.kt b/src/main/java/icu/samnyan/aqua/net/games/ongeki/OngekiImport.kt
new file mode 100644
index 00000000..47208444
--- /dev/null
+++ b/src/main/java/icu/samnyan/aqua/net/games/ongeki/OngekiImport.kt
@@ -0,0 +1,73 @@
+package icu.samnyan.aqua.net.games.ongeki
+
+import ext.API
+import ext.returns
+import ext.vars
+import icu.samnyan.aqua.net.games.IExportClass
+import icu.samnyan.aqua.net.games.ImportClass
+import icu.samnyan.aqua.net.games.ImportController
+import icu.samnyan.aqua.sega.ongeki.model.*
+import icu.samnyan.aqua.sega.ongeki.OngekiRepos
+import icu.samnyan.aqua.sega.ongeki.OngekiUserLinked
+import icu.samnyan.aqua.sega.ongeki.OngekiUserRepos
+import org.springframework.web.bind.annotation.RestController
+import kotlin.reflect.full.declaredMembers
+
+@RestController
+@API("api/v2/game/ongeki")
+class OngekiImport(
+ val repos: OngekiRepos,
+) : ImportController(
+ "SDDT", "ongeki", OngekiDataExport::class,
+ exportFields = OngekiDataExport::class.vars().associateBy {
+ it.name.replace("List", "").lowercase()
+ },
+ exportRepos = OngekiDataExport::class.vars()
+ .filter { f -> f.name !in setOf("gameId", "userData") }
+ .associateWith { OngekiUserRepos::class.declaredMembers
+ .filter { f -> f returns OngekiUserLinked::class }
+ .firstOrNull { f -> f.name == it.name || f.name == it.name.replace("List", "") }
+ ?.call(repos) as OngekiUserLinked<*>? ?: error("No matching field found for ${it.name}")
+ },
+ artemisRenames = mapOf() // TODO (almost nobody uses this so it's very low priority)
+) {
+ override fun createEmpty() = OngekiDataExport()
+ override val userDataRepo = repos.u.data
+}
+
+
+data class OngekiDataExport(
+ override var gameId: String = "SDDT",
+ override var userData: UserData,
+ var userActivity: List,
+ var userBoss: List,
+ var userCard: List,
+ var userChapter: List,
+ var userCharacter: List,
+ var userDeck: List,
+ var userEventMusic: List,
+ var userEventPoint: List,
+ var userGeneralData: List,
+ var userItem: List,
+ var userKop: List,
+ var userLoginBonus: List,
+ var userMemoryChapter: List,
+ var userMissionPoint: List,
+ var userMusicDetail: List,
+ var userMusicItem: List,
+ var userOption: UserOption,
+ var userPlaylog: List,
+ var userRivalData: List,
+ var userScenario: List,
+ var userStory: List,
+ var userTechCount: List,
+ var userTechEvent: List,
+ var userTradeItem: List,
+ var userTrainingRoom: List,
+ var userEventMap: List,
+ var userSkin: List,
+ var userRegions: List,
+ var userGacha: List,
+): IExportClass {
+ constructor() : this("SDDT", UserData(), ArrayList(), ArrayList(), ArrayList(), ArrayList(),ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(),ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(),ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(),ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(),ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList())
+}