diff --git a/src/main/java/icu/samnyan/aqua/net/games/ImportController.kt b/src/main/java/icu/samnyan/aqua/net/games/ImportController.kt index e17ebb0a..27a452be 100644 --- a/src/main/java/icu/samnyan/aqua/net/games/ImportController.kt +++ b/src/main/java/icu/samnyan/aqua/net/games/ImportController.kt @@ -58,7 +58,8 @@ abstract class ImportController, UserModel: val exportFields: Map>, val exportRepos: Map, IUserRepo>, val artemisRenames: Map>, - val customExporters: Map, (UserModel, ExportOptions) -> Any?> = emptyMap() + val customExporters: Map, (UserModel, ExportOptions) -> Any?> = emptyMap(), + val customImporters: Map, (ExportModel, UserModel) -> Unit> = emptyMap() ) { abstract fun createEmpty(): ExportModel abstract val userDataRepo: GenericUserDataRepo @@ -105,8 +106,8 @@ abstract class ImportController, UserModel: val export = json.parseJackson(exportClass.java) if (!export.gameId.equals(game, true)) 400 - "Invalid game ID" - val lists = listRepos.toList().associate { (f, r) -> r to f.get(export) as List> }.vNotNull() - val singles = singleRepos.toList().associate { (f, r) -> r to f.get(export) as IUserEntity }.vNotNull() + val lists = listRepos.toList().filter { (f, _) -> f !in customImporters }.associate { (f, r) -> r to f.get(export) as List> }.vNotNull() + val singles = singleRepos.toList().filter { (f, _) -> f !in customImporters }.associate { (f, r) -> r to f.get(export) as IUserEntity }.vNotNull() // Validate new user data // Check that all ids are 0 (this should be true since all ids are @JsonIgnore) @@ -138,6 +139,10 @@ abstract class ImportController, UserModel: // Save new data singles.forEach { (repo, single) -> (repo as IUserRepo).save(single) } lists.forEach { (repo, list) -> (repo as IUserRepo).saveAll(list) } + // Handle custom importers + customImporters.forEach { (field, importer) -> + importer(export, nu) + } } SUCCESS diff --git a/src/main/java/icu/samnyan/aqua/net/games/mai2/Mai2Import.kt b/src/main/java/icu/samnyan/aqua/net/games/mai2/Mai2Import.kt index 90f83f1c..03da745c 100644 --- a/src/main/java/icu/samnyan/aqua/net/games/mai2/Mai2Import.kt +++ b/src/main/java/icu/samnyan/aqua/net/games/mai2/Mai2Import.kt @@ -9,6 +9,7 @@ import icu.samnyan.aqua.net.games.ImportClass import icu.samnyan.aqua.net.games.ImportController import icu.samnyan.aqua.sega.maimai2.model.Mai2Repos import icu.samnyan.aqua.sega.maimai2.model.Mai2UserLinked +import icu.samnyan.aqua.sega.maimai2.model.request.Mai2UserFavoriteItem import icu.samnyan.aqua.sega.maimai2.model.userdata.* import org.springframework.web.bind.annotation.RestController import kotlin.reflect.full.declaredMembers @@ -24,10 +25,15 @@ class Mai2Import( }, exportRepos = Maimai2DataExport::class.vars() .filter { f -> f.name !in setOf("gameId", "userData") } - .associateWith { Mai2Repos::class.declaredMembers - .filter { f -> f returns Mai2UserLinked::class } - .firstOrNull { f -> f.name == it.name || f.name == it.name.replace("List", "") } - ?.call(repos) as Mai2UserLinked<*>? ?: error("No matching field found for ${it.name}") + .associateWith { field -> + val repoName = when (field.name) { + "userKaleidxScopeList" -> "userKaleidx" + else -> field.name.replace("List", "") + } + Mai2Repos::class.declaredMembers + .filter { f -> f returns Mai2UserLinked::class } + .firstOrNull { f -> f.name == repoName } + ?.call(repos) as Mai2UserLinked<*>? ?: error("No matching field found for ${field.name}") }, artemisRenames = mapOf( "mai2_item_character" to ImportClass(Mai2UserCharacter::class), @@ -46,17 +52,36 @@ class Mai2Import( "mai2_score_best" to ImportClass(Mai2UserMusicDetail::class), "mai2_score_course" to ImportClass(Mai2UserCourse::class), ), - customExporters = run { - mapOf( - Maimai2DataExport::userPlaylogList to { user: Mai2UserDetail, options: ExportOptions -> - if (options.playlogSince != null) { - repos.userPlaylog.findByUserAndUserPlayDateAfter(user, options.playlogSince) - } else { - repos.userPlaylog.findByUser(user) - } + customExporters = mapOf( + Maimai2DataExport::userPlaylogList to { user: Mai2UserDetail, options: ExportOptions -> + if (options.playlogSince != null) { + repos.userPlaylog.findByUserAndUserPlayDateAfter(user, options.playlogSince) + } else { + repos.userPlaylog.findByUser(user) } - ) as Map, (Mai2UserDetail, ExportOptions) -> Any?> - } + }, + Maimai2DataExport::userFavoriteMusicList to { user: Mai2UserDetail, _: ExportOptions -> + repos.userGeneralData.findByUserAndPropertyKey(user, "favorite_music").orElse(null) + ?.propertyValue + ?.takeIf { it.isNotEmpty() } + ?.split(",") + ?.mapIndexed { index, id -> Mai2UserFavoriteItem().apply { orderId = index; this.id = id.toInt() } } + ?: emptyList() + } + ) as Map, (Mai2UserDetail, ExportOptions) -> Any?>, + customImporters = mapOf( + Maimai2DataExport::userFavoriteMusicList to { export: Maimai2DataExport, user: Mai2UserDetail -> + val favoriteMusicList = export.userFavoriteMusicList + if (favoriteMusicList.isNotEmpty()) { + val key = "favorite_music" + val data = repos.userGeneralData.findByUserAndPropertyKey(user, key).orElse(null) + ?: Mai2UserGeneralData().apply { this.user = user; propertyKey = key } + repos.userGeneralData.save(data.apply { + propertyValue = favoriteMusicList.map { it.id }.joinToString(",") + }) + } + } + ) as Map, (Maimai2DataExport, Mai2UserDetail) -> Unit> ) { override fun createEmpty() = Maimai2DataExport() override val userDataRepo = repos.userData @@ -79,11 +104,14 @@ data class Maimai2DataExport( var userLoginBonusList: List, var userMapList: List, var userMusicDetailList: List, + var userIntimateList: List, + var userFavoriteMusicList: List, + var userKaleidxScopeList: List, var userPlaylogList: List, override var gameId: String = "SDEZ", ): IExportClass { constructor() : this(Mai2UserDetail(), Mai2UserExtend(), Mai2UserOption(), Mai2UserUdemae(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), - mutableListOf()) + mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf()) }