[+] Generalize data import for chusan

pull/29/head
Azalea 2024-03-30 23:52:29 -04:00
parent d4178c85a9
commit 3a8616e225
59 changed files with 390 additions and 333 deletions

View File

@ -33,6 +33,7 @@ typealias RB = RequestBody
typealias RH = RequestHeader typealias RH = RequestHeader
typealias PV = PathVariable typealias PV = PathVariable
typealias API = RequestMapping typealias API = RequestMapping
typealias Var<T, V> = KMutableProperty1<T, V>
typealias Str = String typealias Str = String
typealias Bool = Boolean typealias Bool = Boolean
typealias JavaSerializable = java.io.Serializable typealias JavaSerializable = java.io.Serializable
@ -50,13 +51,13 @@ annotation class SettingField(val name: Str, val desc: Str)
// Reflection // Reflection
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
fun <T : Any> KClass<T>.vars() = memberProperties.mapNotNull { it as? KMutableProperty1<T, Any> } fun <T : Any> KClass<T>.vars() = memberProperties.mapNotNull { it as? Var<T, Any> }
fun <T : Any> KClass<T>.varsMap() = vars().associateBy { it.name } fun <T : Any> KClass<T>.varsMap() = vars().associateBy { it.name }
fun <T : Any> KClass<T>.getters() = java.methods.filter { it.name.startsWith("get") } fun <T : Any> KClass<T>.getters() = java.methods.filter { it.name.startsWith("get") }
fun <T : Any> KClass<T>.gettersMap() = getters().associateBy { it.name.removePrefix("get").decapitalize() } fun <T : Any> KClass<T>.gettersMap() = getters().associateBy { it.name.removePrefix("get").decapitalize() }
infix fun KCallable<*>.returns(type: KClass<*>) = returnType.jvmErasure.isSubclassOf(type) infix fun KCallable<*>.returns(type: KClass<*>) = returnType.jvmErasure.isSubclassOf(type)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
fun <C, T: Any> KMutableProperty1<C, T>.setCast(obj: C, value: String) = set(obj, when (returnType.classifier) { fun <C, T: Any> Var<C, T>.setCast(obj: C, value: String) = set(obj, when (returnType.classifier) {
String::class -> value String::class -> value
Int::class -> value.toInt() Int::class -> value.toInt()
Boolean::class -> value.toBoolean() Boolean::class -> value.toBoolean()

View File

@ -35,11 +35,11 @@ val JACKSON = jacksonObjectMapper().apply {
inline fun <reified T> ObjectMapper.parse(str: Str) = readValue(str, T::class.java) inline fun <reified T> ObjectMapper.parse(str: Str) = readValue(str, T::class.java)
inline fun <reified T> ObjectMapper.parse(map: Map<*, *>) = convertValue(map, T::class.java) inline fun <reified T> ObjectMapper.parse(map: Map<*, *>) = convertValue(map, T::class.java)
// TODO: https://stackoverflow.com/q/78197784/7346633 // TODO: https://stackoverflow.com/q/78197784/7346633
inline fun <reified T> Str.parseJackson() = if (contains("null")) { fun <T> Str.parseJackson(cls: Class<T>) = if (contains("null")) {
val map = JACKSON.parse<MutableMap<String, Any>>(this) val map = JACKSON.parse<MutableMap<String, Any>>(this)
JACKSON.convertValue(map.recursiveNotNull(), T::class.java) JACKSON.convertValue(map.recursiveNotNull(), cls)
} }
else JACKSON.readValue(this, T::class.java) else JACKSON.readValue(this, cls)
fun <T> T.toJson() = JACKSON.writeValueAsString(this) fun <T> T.toJson() = JACKSON.writeValueAsString(this)
inline fun <reified T> String.json() = try { inline fun <reified T> String.json() = try {

View File

@ -81,64 +81,64 @@ public class ApiChuniV2PlayerDataController {
} }
@PutMapping("profile/username") @PutMapping("profile/username")
public UserData updateName(@RequestBody Map<String, Object> request) { public Chu3UserData updateName(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
profile.setUserName((String) request.get("userName")); profile.setUserName((String) request.get("userName"));
return userDataService.saveUserData(profile); return userDataService.saveUserData(profile);
} }
@PutMapping("profile/romversion") @PutMapping("profile/romversion")
public UserData updateRomVersion(@RequestBody Map<String, Object> request) { public Chu3UserData updateRomVersion(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
profile.setLastRomVersion((String) request.get("romVersion")); profile.setLastRomVersion((String) request.get("romVersion"));
return userDataService.saveUserData(profile); return userDataService.saveUserData(profile);
} }
@PutMapping("profile/dataversion") @PutMapping("profile/dataversion")
public UserData updateDataVersion(@RequestBody Map<String, Object> request) { public Chu3UserData updateDataVersion(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
profile.setLastDataVersion((String) request.get("dataVersion")); profile.setLastDataVersion((String) request.get("dataVersion"));
return userDataService.saveUserData(profile); return userDataService.saveUserData(profile);
} }
@PutMapping("profile/plate") @PutMapping("profile/plate")
public UserData updatePlate(@RequestBody Map<String, Object> request) { public Chu3UserData updatePlate(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
profile.setNameplateId((Integer) request.get("nameplateId")); profile.setNameplateId((Integer) request.get("nameplateId"));
return userDataService.saveUserData(profile); return userDataService.saveUserData(profile);
} }
@PutMapping("profile/frame") @PutMapping("profile/frame")
public UserData updateFrame(@RequestBody Map<String, Object> request) { public Chu3UserData updateFrame(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
profile.setFrameId((Integer) request.get("frameId")); profile.setFrameId((Integer) request.get("frameId"));
return userDataService.saveUserData(profile); return userDataService.saveUserData(profile);
} }
@PutMapping("profile/trophy") @PutMapping("profile/trophy")
public UserData updateTrophy(@RequestBody Map<String, Object> request) { public Chu3UserData updateTrophy(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
profile.setTrophyId((Integer) request.get("trophyId")); profile.setTrophyId((Integer) request.get("trophyId"));
return userDataService.saveUserData(profile); return userDataService.saveUserData(profile);
} }
@PutMapping("profile/mapicon") @PutMapping("profile/mapicon")
public UserData updateMapIcon(@RequestBody Map<String, Object> request) { public Chu3UserData updateMapIcon(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
profile.setMapIconId((Integer) request.get("mapiconId")); profile.setMapIconId((Integer) request.get("mapiconId"));
return userDataService.saveUserData(profile); return userDataService.saveUserData(profile);
} }
@PutMapping("profile/sysvoice") @PutMapping("profile/sysvoice")
public UserData updateSystemVoice(@RequestBody Map<String, Object> request) { public Chu3UserData updateSystemVoice(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
profile.setVoiceId((Integer) request.get("voiceId")); profile.setVoiceId((Integer) request.get("voiceId"));
return userDataService.saveUserData(profile); return userDataService.saveUserData(profile);
} }
@PutMapping("profile/avatar") @PutMapping("profile/avatar")
public UserData updateAvatar(@RequestBody Map<String, Object> request) { public Chu3UserData updateAvatar(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
int category = (Integer) request.get("category"); int category = (Integer) request.get("category");
switch (category) { switch (category) {
case 1: case 1:
@ -169,7 +169,7 @@ public class ApiChuniV2PlayerDataController {
@PutMapping("profile/privacy") @PutMapping("profile/privacy")
public ResponseEntity<Object> updatePrivacy(@RequestBody Map<String, Object> request) { public ResponseEntity<Object> updatePrivacy(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
UserGameOption option = userGameOptionService.getByUser(profile).orElseThrow(); UserGameOption option = userGameOptionService.getByUser(profile).orElseThrow();
int privacy = (Integer) request.get("privacy"); int privacy = (Integer) request.get("privacy");
if (privacy != 1 && privacy != 0) { if (privacy != 1 && privacy != 0) {
@ -300,7 +300,7 @@ public class ApiChuniV2PlayerDataController {
@PutMapping("song/{id}/favorite") @PutMapping("song/{id}/favorite")
public void updateSongFavorite(@RequestParam String aimeId, @PathVariable String id) { public void updateSongFavorite(@RequestParam String aimeId, @PathVariable String id) {
UserData profile = userDataService.getUserByExtId(aimeId).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId(aimeId).orElseThrow();
UserGeneralData userGeneralData = userGeneralDataService.getByUserAndKey(profile, "favorite_music") UserGeneralData userGeneralData = userGeneralDataService.getByUserAndKey(profile, "favorite_music")
.orElseGet(() -> new UserGeneralData(profile, "favorite_music")); .orElseGet(() -> new UserGeneralData(profile, "favorite_music"));
List<String> favoriteSongs = new LinkedList<String>(Arrays.asList(userGeneralData.getPropertyValue().split(","))); List<String> favoriteSongs = new LinkedList<String>(Arrays.asList(userGeneralData.getPropertyValue().split(",")));
@ -329,7 +329,7 @@ public class ApiChuniV2PlayerDataController {
@PostMapping("character") @PostMapping("character")
public ResponseEntity<Object> updateCharacter(@RequestBody Map<String, Object> request) { public ResponseEntity<Object> updateCharacter(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
Integer characterId = (Integer) request.get("characterId"); Integer characterId = (Integer) request.get("characterId");
Optional<UserCharacter> characterOptional = userCharacterService.getByUserAndCharacterId(profile, characterId); Optional<UserCharacter> characterOptional = userCharacterService.getByUserAndCharacterId(profile, characterId);
UserCharacter character; UserCharacter character;
@ -371,7 +371,7 @@ public class ApiChuniV2PlayerDataController {
@PostMapping("item") @PostMapping("item")
public ResponseEntity<Object> updateItem(@RequestBody Map<String, Object> request) { public ResponseEntity<Object> updateItem(@RequestBody Map<String, Object> request) {
UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow(); Chu3UserData profile = userDataService.getUserByExtId((String) request.get("aimeId")).orElseThrow();
Integer itemId = (Integer) request.get("itemId"); Integer itemId = (Integer) request.get("itemId");
Integer itemKind = (Integer) request.get("itemKind"); Integer itemKind = (Integer) request.get("itemKind");
Optional<UserItem> itemOptional = userItemService.getByUserAndItemIdAndKind(profile, itemId,itemKind); Optional<UserItem> itemOptional = userItemService.getByUserAndItemIdAndKind(profile, itemId,itemKind);
@ -446,7 +446,7 @@ public class ApiChuniV2PlayerDataController {
card = cardService.registerByAccessCode(exUser.getAccessCode()); card = cardService.registerByAccessCode(exUser.getAccessCode());
} }
UserData userData = mapper.convert(exUser, new TypeReference<>() { Chu3UserData userData = mapper.convert(exUser, new TypeReference<>() {
}); });
userData.setCard(card); userData.setCard(card);
userDataService.saveAndFlushUserData(userData); userDataService.saveAndFlushUserData(userData);

View File

@ -1,10 +1,11 @@
package icu.samnyan.aqua.api.model.resp.sega.chuni.v2.external package icu.samnyan.aqua.api.model.resp.sega.chuni.v2.external
import icu.samnyan.aqua.net.games.IExportClass
import icu.samnyan.aqua.sega.chusan.model.userdata.* import icu.samnyan.aqua.sega.chusan.model.userdata.*
data class Chu3DataExport( data class Chu3DataExport(
var gameId: String = "SDHD", override var gameId: String = "SDHD",
var userData: UserData, override var userData: Chu3UserData,
var userGameOption: UserGameOption, var userGameOption: UserGameOption,
var userActivityList: List<UserActivity>, var userActivityList: List<UserActivity>,
var userCharacterList: List<UserCharacter>, var userCharacterList: List<UserCharacter>,
@ -16,7 +17,8 @@ data class Chu3DataExport(
var userMusicDetailList: List<UserMusicDetail>, var userMusicDetailList: List<UserMusicDetail>,
var userPlaylogList: List<UserPlaylog>, var userPlaylogList: List<UserPlaylog>,
var userLoginBonusList: List<UserLoginBonus>, var userLoginBonusList: List<UserLoginBonus>,
) { ): IExportClass<Chu3UserData> {
constructor() : this("SDHD", UserData(), UserGameOption(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList()) constructor() : this("SDHD",
Chu3UserData(), UserGameOption(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList())
} }

View File

@ -1,9 +1,10 @@
package icu.samnyan.aqua.api.model.resp.sega.maimai2.external package icu.samnyan.aqua.api.model.resp.sega.maimai2.external
import icu.samnyan.aqua.net.games.IExportClass
import icu.samnyan.aqua.sega.maimai2.model.userdata.* import icu.samnyan.aqua.sega.maimai2.model.userdata.*
data class Maimai2DataExport( data class Maimai2DataExport(
var userData: Mai2UserDetail, override var userData: Mai2UserDetail,
var userExtend: Mai2UserExtend, var userExtend: Mai2UserExtend,
var userOption: Mai2UserOption, var userOption: Mai2UserOption,
var userUdemae: Mai2UserUdemae, var userUdemae: Mai2UserUdemae,
@ -20,8 +21,8 @@ data class Maimai2DataExport(
var userMapList: List<Mai2UserMap>, var userMapList: List<Mai2UserMap>,
var userMusicDetailList: List<Mai2UserMusicDetail>, var userMusicDetailList: List<Mai2UserMusicDetail>,
var userPlaylogList: List<Mai2UserPlaylog>, var userPlaylogList: List<Mai2UserPlaylog>,
var gameId: String = "SDEZ", override var gameId: String = "SDEZ",
) { ): IExportClass<Mai2UserDetail> {
constructor() : this(Mai2UserDetail(), Mai2UserExtend(), Mai2UserOption(), Mai2UserUdemae(), constructor() : this(Mai2UserDetail(), Mai2UserExtend(), Mai2UserOption(), Mai2UserUdemae(),
mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(),
mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(), mutableListOf(),

View File

@ -4,7 +4,7 @@ import ext.*
import icu.samnyan.aqua.net.components.JWT import icu.samnyan.aqua.net.components.JWT
import icu.samnyan.aqua.net.db.AquaUserServices import icu.samnyan.aqua.net.db.AquaUserServices
import icu.samnyan.aqua.net.games.GenericUserDataRepo import icu.samnyan.aqua.net.games.GenericUserDataRepo
import icu.samnyan.aqua.net.games.IGenericUserData import icu.samnyan.aqua.net.games.IUserData
import icu.samnyan.aqua.net.utils.AquaNetProps import icu.samnyan.aqua.net.utils.AquaNetProps
import icu.samnyan.aqua.net.utils.SUCCESS import icu.samnyan.aqua.net.utils.SUCCESS
import icu.samnyan.aqua.sega.chusan.model.Chu3UserDataRepo import icu.samnyan.aqua.sega.chusan.model.Chu3UserDataRepo
@ -116,7 +116,7 @@ class CardController(
* *
* Assumption: The card is already linked to the user. * Assumption: The card is already linked to the user.
*/ */
suspend fun <T : IGenericUserData> migrateCard(repo: GenericUserDataRepo<T>, card: Card): Bool suspend fun <T : IUserData> migrateCard(repo: GenericUserDataRepo<T>, card: Card): Bool
{ {
// Check if data already exists in the user's ghost card // Check if data already exists in the user's ghost card
async { repo.findByCard(card.aquaUser!!.ghostCard) }?.let { async { repo.findByCard(card.aquaUser!!.ghostCard) }?.let {

View File

@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory
import kotlin.jvm.optionals.getOrNull import kotlin.jvm.optionals.getOrNull
import kotlin.reflect.KClass import kotlin.reflect.KClass
abstract class GameApiController<T : IGenericUserData>(name: String, userDataClass: KClass<T>) { abstract class GameApiController<T : IUserData>(name: String, userDataClass: KClass<T>) {
val musicMapping = resJson<Map<String, GenericMusicMeta>>("/meta/$name/music.json") val musicMapping = resJson<Map<String, GenericMusicMeta>>("/meta/$name/music.json")
?.mapKeys { it.key.toInt() } ?: emptyMap() ?.mapKeys { it.key.toInt() } ?: emptyMap()
val logger = LoggerFactory.getLogger(javaClass) val logger = LoggerFactory.getLogger(javaClass)

View File

@ -1,14 +1,20 @@
package icu.samnyan.aqua.net.games package icu.samnyan.aqua.net.games
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.module.SimpleModule
import ext.* import ext.*
import java.lang.reflect.Field import icu.samnyan.aqua.net.db.AquaNetUser
import icu.samnyan.aqua.net.db.AquaUserServices
import icu.samnyan.aqua.net.utils.AquaNetProps
import icu.samnyan.aqua.net.utils.SUCCESS
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.repository.NoRepositoryBean
import org.springframework.transaction.PlatformTransactionManager
import org.springframework.transaction.support.TransactionTemplate
import java.time.LocalDateTime
import java.util.*
import kotlin.io.path.Path
import kotlin.io.path.writeText
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty1
// Import class with renaming // Import class with renaming
data class ImportClass<T : Any>( data class ImportClass<T : Any>(
@ -17,18 +23,114 @@ data class ImportClass<T : Any>(
val name: String = type.simpleName!!.removePrefix("Mai2").lowercase() val name: String = type.simpleName!!.removePrefix("Mai2").lowercase()
) )
abstract class ImportController<T: Any>( interface IUserEntity<UserModel: IUserData> {
val exportFields: Map<String, KMutableProperty1<T, Any>>, var id: Long
val renameTable: Map<String, ImportClass<*>> var user: UserModel
}
interface IExportClass<UserModel: IUserData> {
var gameId: String
var userData: UserModel
}
@NoRepositoryBean
interface IUserRepo<UserModel, ThisModel>: JpaRepository<ThisModel, Long> {
fun findByUser(user: UserModel): List<ThisModel>
fun findSingleByUser(user: UserModel): Optional<ThisModel>
}
/**
* Import controller for a game
*
* @param game: 4-letter Game ID
* @param exportFields: Mapping of type names to variables in the export model
* (e.g. "Mai2UserCharacter" -> Mai2DataExport::userCharacterList)
* @param exportRepos: Mapping of variables to repositories that can be used to find the data
* @param artemisRenames: Mapping of Artemis table names to import classes
*/
abstract class ImportController<ExportModel: IExportClass<UserModel>, UserModel: IUserData>(
val game: String,
val exportClass: KClass<ExportModel>,
val exportFields: Map<String, Var<ExportModel, Any>>,
val exportRepos: Map<Var<ExportModel, Any>, IUserRepo<UserModel, *>>,
val artemisRenames: Map<String, ImportClass<*>>,
) { ) {
abstract fun createEmpty(): T abstract fun createEmpty(): ExportModel
abstract val userDataRepo: GenericUserDataRepo<UserModel>
@Autowired lateinit var us: AquaUserServices
@Autowired lateinit var netProps: AquaNetProps
@Autowired lateinit var transManager: PlatformTransactionManager
val trans by lazy { TransactionTemplate(transManager) }
init { init {
renameTable.values.forEach { artemisRenames.values.forEach {
if (it.name !in exportFields) error("Code error! Export fields incomplete: missing ${it.name}") if (it.name !in exportFields) error("Code error! Export fields incomplete: missing ${it.name}")
} }
} }
val listRepos = exportRepos.filter { it.key returns List::class }
val singleRepos = exportRepos.filter { !(it.key returns List::class) }
fun export(u: AquaNetUser) = createEmpty().apply {
gameId = game
userData = userDataRepo.findByCard(u.ghostCard) ?: (404 - "User not found")
exportRepos.forEach { (f, u) ->
if (f returns List::class) f.set(this, u.findByUser(userData))
else u.findSingleByUser(userData)()?.let { f.set(this, it) }
}
}
@API("export")
fun exportUserData(@RP token: Str) = us.jwt.auth(token) { u ->
log.info("Exporting user data for ${u.auId}")
export(u)
}
@Suppress("UNCHECKED_CAST")
@API("import")
fun importUserData(@RP token: Str, @RB json: Str) = us.jwt.auth(token) { u ->
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<IUserEntity<UserModel>> }.vNotNull()
val singles = singleRepos.toList().associate { (f, r) -> r to f.get(export) as IUserEntity<UserModel> }.vNotNull()
// Validate new user data
// Check that all ids are 0 (this should be true since all ids are @JsonIgnore)
if (export.userData.id != 0L) 400 - "User ID must be 0"
lists.values.flatten().forEach { if (it.id != 0L) 400 - "ID must be 0" }
singles.values.forEach { if (it.id != 0L) 400 - "ID must be 0" }
// Set user card
export.userData.card = u.ghostCard
// Check existing data
userDataRepo.findByCard(u.ghostCard)?.also { gu ->
// Store a backup of the old data
val fl = "mai2-backup-${u.auId}-${LocalDateTime.now().urlSafeStr()}.json"
(Path(netProps.importBackupPath) / fl).writeText(export(u).toJson())
// Delete the old data (After migration v1000.7, all user-linked entities have ON DELETE CASCADE)
log.info("Mai2 Import: Deleting old data for user ${u.auId}")
userDataRepo.delete(gu)
userDataRepo.flush()
}
trans.execute {
// Insert new data
val nu = userDataRepo.save(export.userData)
// Set user fields
lists.values.flatten().forEach { it.user = nu }
singles.values.forEach { it.user = nu }
// Save new data
singles.forEach { (repo, single) -> (repo as IUserRepo<UserModel, Any>).save(single) }
lists.forEach { (repo, list) -> (repo as IUserRepo<UserModel, Any>).saveAll(list) }
}
SUCCESS
}
/** /**
* Read an artemis SQL dump file and return Aqua JSON * Read an artemis SQL dump file and return Aqua JSON
*/ */
@ -52,7 +154,7 @@ abstract class ImportController<T: Any>(
// For each insert statement, we will try to parse the values // For each insert statement, we will try to parse the values
statements.forEachIndexed fi@{ i, insert -> statements.forEachIndexed fi@{ i, insert ->
// Try to map tables // Try to map tables
val tb = renameTable[insert.table] ?: return@fi warn("Unknown table ${insert.table} in insert $i") val tb = artemisRenames[insert.table] ?: return@fi warn("Unknown table ${insert.table} in insert $i")
val field = exportFields[tb.name]!! val field = exportFields[tb.name]!!
val obj = tb.mapTo(insert.mapping) val obj = tb.mapTo(insert.mapping)
@ -77,43 +179,7 @@ abstract class ImportController<T: Any>(
return JACKSON_ARTEMIS.convertValue(dict, type.java) return JACKSON_ARTEMIS.convertValue(dict, type.java)
} }
val log = logger()
} }
} }
// Read SQL dump and convert to dictionary
val insertPattern = """INSERT INTO\s+(\w+)\s*\(([^)]+)\)\s*VALUES\s*\(([^)]+)\);""".toRegex()
data class SqlInsert(val table: String, val mapping: Map<String, String>)
fun String.asSqlInsert(): SqlInsert {
val match = insertPattern.matchEntire(this) ?: error("Does not match insert pattern")
val (table, rawCols, rawVals) = match.destructured
val cols = rawCols.split(',').map { it.trim(' ', '"') }
// Parse values with proper quote handling
val vals = mutableListOf<String>()
var startI = 0
var insideQuote = false
rawVals.forEachIndexed { i, c ->
if (c == ',' && !insideQuote) {
vals.add(rawVals.substring(startI, i).trim(' ', '"'))
startI = i + 1
} else if (c == '"') insideQuote = !insideQuote
}
assert(cols.size == vals.size) { "Column and value count mismatch" }
return SqlInsert(table, cols.zip(vals).toMap())
}
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
val JSON_INT_LIST_STR = SimpleModule().addDeserializer(List::class.java, object : JsonDeserializer<List<Integer>>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext) =
try {
val text = parser.text.trim('[', ']')
if (text.isEmpty()) emptyList()
else text.split(',').map { it.trim().toInt() } as List<Integer>
} catch (e: Exception) {
400 - "Invalid list value ${parser.text}: $e" }
})
val JACKSON_ARTEMIS = JACKSON.copy().apply {
registerModule(JSON_INT_LIST_STR)
}

View File

@ -0,0 +1,46 @@
package icu.samnyan.aqua.net.games
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.module.SimpleModule
import ext.JACKSON
import ext.minus
// Read SQL dump and convert to dictionary
val insertPattern = """INSERT INTO\s+(\w+)\s*\(([^)]+)\)\s*VALUES\s*\(([^)]+)\);""".toRegex()
data class SqlInsert(val table: String, val mapping: Map<String, String>)
fun String.asSqlInsert(): SqlInsert {
val match = insertPattern.matchEntire(this) ?: error("Does not match insert pattern")
val (table, rawCols, rawVals) = match.destructured
val cols = rawCols.split(',').map { it.trim(' ', '"') }
// Parse values with proper quote handling
val vals = mutableListOf<String>()
var startI = 0
var insideQuote = false
rawVals.forEachIndexed { i, c ->
if (c == ',' && !insideQuote) {
vals.add(rawVals.substring(startI, i).trim(' ', '"'))
startI = i + 1
} else if (c == '"') insideQuote = !insideQuote
}
assert(cols.size == vals.size) { "Column and value count mismatch" }
return SqlInsert(table, cols.zip(vals).toMap())
}
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
val JSON_INT_LIST_STR = SimpleModule().addDeserializer(List::class.java, object : JsonDeserializer<List<Integer>>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext) =
try {
val text = parser.text.trim('[', ']')
if (text.isEmpty()) emptyList()
else text.split(',').map { it.trim().toInt() } as List<Integer>
} catch (e: Exception) {
400 - "Invalid list value ${parser.text}: $e" }
})
val JACKSON_ARTEMIS = JACKSON.copy().apply {
registerModule(JSON_INT_LIST_STR)
}

View File

@ -1,7 +1,6 @@
package icu.samnyan.aqua.net.games package icu.samnyan.aqua.net.games
import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.databind.annotation.JsonSerialize
import ext.JACKSON import ext.JACKSON
@ -16,8 +15,6 @@ import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.NoRepositoryBean import org.springframework.data.repository.NoRepositoryBean
import java.util.* import java.util.*
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
data class TrendOut(val date: String, val rating: Int, val plays: Int) data class TrendOut(val date: String, val rating: Int, val plays: Int)
@ -81,7 +78,8 @@ data class GenericItemMeta(
) )
// Here are some interfaces to generalize across multiple games // Here are some interfaces to generalize across multiple games
interface IGenericUserData { interface IUserData {
val id: Long
val userName: String val userName: String
val playerRating: Int val playerRating: Int
val highestRating: Int val highestRating: Int
@ -124,7 +122,7 @@ open class UserDataEntity : BaseEntity() {
} }
@NoRepositoryBean @NoRepositoryBean
interface GenericUserDataRepo<T : IGenericUserData> : JpaRepository<T, Long> { interface GenericUserDataRepo<T : IUserData> : JpaRepository<T, Long> {
fun findByCard(card: Card): T? fun findByCard(card: Card): T?
fun findByCard_ExtId(extId: Long): Optional<T> fun findByCard_ExtId(extId: Long): Optional<T>
@Query("select count(*) from #{#entityName} where playerRating > :rating") @Query("select count(*) from #{#entityName} where playerRating > :rating")

View File

@ -1,22 +1,36 @@
package icu.samnyan.aqua.net.games.chu3 package icu.samnyan.aqua.net.games.chu3
import ext.API import ext.API
import ext.returns
import ext.vars import ext.vars
import icu.samnyan.aqua.api.model.resp.sega.chuni.v2.external.Chu3DataExport import icu.samnyan.aqua.api.model.resp.sega.chuni.v2.external.Chu3DataExport
import icu.samnyan.aqua.net.games.ImportClass import icu.samnyan.aqua.net.games.ImportClass
import icu.samnyan.aqua.net.games.ImportController import icu.samnyan.aqua.net.games.ImportController
import icu.samnyan.aqua.sega.chusan.model.Chu3Repos
import icu.samnyan.aqua.sega.chusan.model.Chu3UserLinked
import icu.samnyan.aqua.sega.chusan.model.userdata.* import icu.samnyan.aqua.sega.chusan.model.userdata.*
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
import kotlin.reflect.full.declaredMembers
@RestController @RestController
@API("api/v2/game/chu3") @API("api/v2/game/chu3")
class Chu3Import : ImportController<Chu3DataExport>( class Chu3Import(
val repos: Chu3Repos,
) : ImportController<Chu3DataExport, Chu3UserData>(
"SDHD", Chu3DataExport::class,
exportFields = Chu3DataExport::class.vars().associateBy { exportFields = Chu3DataExport::class.vars().associateBy {
var name = it.name var name = it.name
if (name == "userMapList") name = "userMapAreaList" if (name == "userMapList") name = "userMapAreaList"
name.replace("List", "").lowercase() name.replace("List", "").lowercase()
}, },
renameTable = mapOf( exportRepos = Chu3DataExport::class.vars()
.filter { f -> f.name !in setOf("gameId", "userData") }
.associateWith { Chu3Repos::class.declaredMembers
.filter { f -> f returns Chu3UserLinked::class }
.firstOrNull { f -> f.name == it.name || f.name == it.name.replace("List", "") }
?.call(repos) as Chu3UserLinked<*>? ?: error("No matching field found for ${it.name}")
},
artemisRenames = mapOf(
"chuni_item_character" to ImportClass(UserCharacter::class), "chuni_item_character" to ImportClass(UserCharacter::class),
"chuni_item_duel" to ImportClass(UserDuel::class), "chuni_item_duel" to ImportClass(UserDuel::class),
"chuni_item_item" to ImportClass(UserItem::class, mapOf("isValid" to "valid")), "chuni_item_item" to ImportClass(UserItem::class, mapOf("isValid" to "valid")),
@ -24,7 +38,7 @@ class Chu3Import : ImportController<Chu3DataExport>(
"chuni_item_map_area" to ImportClass(UserMapArea::class), "chuni_item_map_area" to ImportClass(UserMapArea::class),
"chuni_profile_activity" to ImportClass(UserActivity::class, mapOf("activityId" to "id")), "chuni_profile_activity" to ImportClass(UserActivity::class, mapOf("activityId" to "id")),
"chuni_profile_charge" to ImportClass(UserCharge::class), "chuni_profile_charge" to ImportClass(UserCharge::class),
"chuni_profile_data" to ImportClass(UserData::class, mapOf("user" to null, "version" to null, "isNetMember" to null)), "chuni_profile_data" to ImportClass(Chu3UserData::class, mapOf("user" to null, "version" to null, "isNetMember" to null)),
"chuni_profile_option" to ImportClass(UserGameOption::class, mapOf("version" to null)), "chuni_profile_option" to ImportClass(UserGameOption::class, mapOf("version" to null)),
"chuni_score_best" to ImportClass(UserMusicDetail::class), "chuni_score_best" to ImportClass(UserMusicDetail::class),
"chuni_score_playlog" to ImportClass(UserPlaylog::class), "chuni_score_playlog" to ImportClass(UserPlaylog::class),
@ -35,4 +49,5 @@ class Chu3Import : ImportController<Chu3DataExport>(
) )
) { ) {
override fun createEmpty() = Chu3DataExport() override fun createEmpty() = Chu3DataExport()
override val userDataRepo = repos.userData
} }

View File

@ -8,7 +8,7 @@ import icu.samnyan.aqua.net.db.AquaUserServices
import icu.samnyan.aqua.net.games.* import icu.samnyan.aqua.net.games.*
import icu.samnyan.aqua.net.utils.* import icu.samnyan.aqua.net.utils.*
import icu.samnyan.aqua.sega.chusan.model.* import icu.samnyan.aqua.sega.chusan.model.*
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
@RestController @RestController
@ -18,7 +18,7 @@ class Chusan(
override val playlogRepo: Chu3UserPlaylogRepo, override val playlogRepo: Chu3UserPlaylogRepo,
override val userDataRepo: Chu3UserDataRepo, override val userDataRepo: Chu3UserDataRepo,
val userGeneralDataRepository: Chu3UserGeneralDataRepo, val userGeneralDataRepository: Chu3UserGeneralDataRepo,
): GameApiController<UserData>("chu3", UserData::class) { ): GameApiController<Chu3UserData>("chu3", Chu3UserData::class) {
override suspend fun trend(@RP username: Str): List<TrendOut> = us.cardByName(username) { card -> override suspend fun trend(@RP username: Str): List<TrendOut> = us.cardByName(username) { card ->
findTrend(playlogRepo.findByUserCardExtId(card.extId) findTrend(playlogRepo.findByUserCardExtId(card.extId)
.map { TrendLog(it.playDate.toString(), it.playerRating) }) .map { TrendLog(it.playDate.toString(), it.playerRating) })
@ -27,7 +27,7 @@ class Chusan(
// Only show > AAA rank // Only show > AAA rank
override val shownRanks = chu3Scores.filter { it.first >= 95 * 10000 } override val shownRanks = chu3Scores.filter { it.first >= 95 * 10000 }
override val settableFields: Map<String, (UserData, String) -> Unit> by lazy { mapOf( override val settableFields: Map<String, (Chu3UserData, String) -> Unit> by lazy { mapOf(
"userName" to { u, v -> u.setUserName(v) "userName" to { u, v -> u.setUserName(v)
if (!v.all { it in USERNAME_CHARS }) { 400 - "Invalid character in username" } if (!v.all { it in USERNAME_CHARS }) { 400 - "Invalid character in username" }
}, },

View File

@ -1,20 +1,34 @@
package icu.samnyan.aqua.net.games.mai2 package icu.samnyan.aqua.net.games.mai2
import ext.API import ext.API
import ext.returns
import ext.vars import ext.vars
import icu.samnyan.aqua.api.model.resp.sega.maimai2.external.Maimai2DataExport import icu.samnyan.aqua.api.model.resp.sega.maimai2.external.Maimai2DataExport
import icu.samnyan.aqua.net.games.ImportClass import icu.samnyan.aqua.net.games.ImportClass
import icu.samnyan.aqua.net.games.ImportController 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.userdata.* import icu.samnyan.aqua.sega.maimai2.model.userdata.*
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
import kotlin.reflect.full.declaredMembers
@RestController @RestController
@API("api/v2/game/mai2") @API("api/v2/game/mai2")
class Mai2Import : ImportController<Maimai2DataExport>( class Mai2Import(
val repos: Mai2Repos,
) : ImportController<Maimai2DataExport, Mai2UserDetail>(
"SDEZ", Maimai2DataExport::class,
exportFields = Maimai2DataExport::class.vars().associateBy { exportFields = Maimai2DataExport::class.vars().associateBy {
it.name.replace("List", "").lowercase() it.name.replace("List", "").lowercase()
}, },
renameTable = mapOf( 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}")
},
artemisRenames = mapOf(
"mai2_item_character" to ImportClass(Mai2UserCharacter::class), "mai2_item_character" to ImportClass(Mai2UserCharacter::class),
"mai2_item_charge" to ImportClass(Mai2UserCharge::class), "mai2_item_charge" to ImportClass(Mai2UserCharge::class),
"mai2_item_friend_season_ranking" to ImportClass(Mai2UserFriendSeasonRanking::class), "mai2_item_friend_season_ranking" to ImportClass(Mai2UserFriendSeasonRanking::class),
@ -30,10 +44,8 @@ class Mai2Import : ImportController<Maimai2DataExport>(
"mai2_profile_option" to ImportClass(Mai2UserOption::class, mapOf("version" to null)), "mai2_profile_option" to ImportClass(Mai2UserOption::class, mapOf("version" to null)),
"mai2_score_best" to ImportClass(Mai2UserMusicDetail::class), "mai2_score_best" to ImportClass(Mai2UserMusicDetail::class),
"mai2_score_course" to ImportClass(Mai2UserCourse::class), "mai2_score_course" to ImportClass(Mai2UserCourse::class),
// "mai2_profile_ghost" to ImportClass(UserGhost::class),
// "mai2_profile_rating" to ImportClass(UserRating::class),
// "mai2_profile_region" to ImportClass(UserRegion::class),
) )
) { ) {
override fun createEmpty() = Maimai2DataExport() override fun createEmpty() = Maimai2DataExport()
override val userDataRepo = repos.userData
} }

View File

@ -1,23 +1,13 @@
package icu.samnyan.aqua.net.games.mai2 package icu.samnyan.aqua.net.games.mai2
import ext.* import ext.*
import icu.samnyan.aqua.api.model.resp.sega.maimai2.external.Maimai2DataExport
import icu.samnyan.aqua.net.db.AquaNetUser
import icu.samnyan.aqua.net.db.AquaUserServices import icu.samnyan.aqua.net.db.AquaUserServices
import icu.samnyan.aqua.net.games.* import icu.samnyan.aqua.net.games.*
import icu.samnyan.aqua.net.utils.* import icu.samnyan.aqua.net.utils.*
import icu.samnyan.aqua.sega.maimai2.model.* import icu.samnyan.aqua.sega.maimai2.model.*
import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2UserDetail import icu.samnyan.aqua.sega.maimai2.model.userdata.*
import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2UserEntity
import org.springframework.transaction.PlatformTransactionManager
import org.springframework.transaction.support.TransactionTemplate
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
import java.time.LocalDateTime
import java.util.* import java.util.*
import kotlin.io.path.Path
import kotlin.io.path.writeText
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.full.declaredMembers
@RestController @RestController
@API("api/v2/game/mai2") @API("api/v2/game/mai2")
@ -25,13 +15,8 @@ class Maimai2(
override val us: AquaUserServices, override val us: AquaUserServices,
override val playlogRepo: Mai2UserPlaylogRepo, override val playlogRepo: Mai2UserPlaylogRepo,
override val userDataRepo: Mai2UserDataRepo, override val userDataRepo: Mai2UserDataRepo,
val userGeneralDataRepository: Mai2UserGeneralDataRepo,
val repos: Mai2Repos, val repos: Mai2Repos,
val netProps: AquaNetProps,
transManager: PlatformTransactionManager
): GameApiController<Mai2UserDetail>("mai2", Mai2UserDetail::class) { ): GameApiController<Mai2UserDetail>("mai2", Mai2UserDetail::class) {
val trans = TransactionTemplate(transManager)
override suspend fun trend(@RP username: Str): List<TrendOut> = us.cardByName(username) { card -> override suspend fun trend(@RP username: Str): List<TrendOut> = us.cardByName(username) { card ->
findTrend(playlogRepo.findByUserCardExtId(card.extId) findTrend(playlogRepo.findByUserCardExtId(card.extId)
.map { TrendLog(it.playDate, it.afterRating) }) .map { TrendLog(it.playDate, it.afterRating) })
@ -46,7 +31,7 @@ class Maimai2(
) } ) }
override suspend fun userSummary(@RP username: Str) = us.cardByName(username) { card -> override suspend fun userSummary(@RP username: Str) = us.cardByName(username) { card ->
val extra = userGeneralDataRepository.findByUser_Card_ExtId(card.extId) val extra = repos.userGeneralData.findByUser_Card_ExtId(card.extId)
.associate { it.propertyKey to it.propertyValue } .associate { it.propertyKey to it.propertyValue }
val ratingComposition = mapOf( val ratingComposition = mapOf(
@ -56,72 +41,4 @@ class Maimai2(
genericUserSummary(card, ratingComposition) genericUserSummary(card, ratingComposition)
} }
// Use reflection to get all properties in Mai2Repos with matching names in Maimai2DataExport
val exportFields: Map<KMutableProperty1<Maimai2DataExport, Any>, UserLinked<*>> = Maimai2DataExport::class.vars()
.filter { f -> f.name !in setOf("gameId", "userData") }
.associateWith { Mai2Repos::class.declaredMembers
.filter { f -> f returns UserLinked::class }
.firstOrNull { f -> f.name == it.name || f.name == it.name.replace("List", "") }
?.call(repos) as UserLinked<*>? ?: error("No matching field found for ${it.name}")
}
val listFields = exportFields.filter { it.key returns List::class }
val singleFields = exportFields.filter { !(it.key returns List::class) }
fun export(u: AquaNetUser) = Maimai2DataExport().apply {
gameId = "SDEZ"
userData = repos.userData.findByCard(u.ghostCard) ?: (404 - "User not found")
exportFields.forEach { (f, u) ->
if (f returns List::class) f.set(this, u.findByUser(userData))
else u.findSingleByUser(userData)()?.let { f.set(this, it) }
}
}
@API("export")
fun exportAllUserData(@RP token: Str) = us.jwt.auth(token) { u -> export(u) }
@Suppress("UNCHECKED_CAST")
@API("import")
fun importUserData(@RP token: Str, @RB json: Str) = us.jwt.auth(token) { u ->
val export = json.parseJackson<Maimai2DataExport>()
if (!export.gameId.equals("SDEZ", true)) 400 - "Invalid game ID"
val lists = listFields.toList().associate { (f, r) -> r to f.get(export) as List<Mai2UserEntity> }.vNotNull()
val singles = singleFields.toList().associate { (f, r) -> r to f.get(export) as Mai2UserEntity }.vNotNull()
// Validate new user data
// Check that all ids are 0 (this should be true since all ids are @JsonIgnore)
if (export.userData.id != 0L) 400 - "User ID must be 0"
lists.values.flatten().forEach { if (it.id != 0L) 400 - "ID must be 0" }
singles.values.forEach { if (it.id != 0L) 400 - "ID must be 0" }
// Set user card
export.userData.card = u.ghostCard
// Check existing data
repos.userData.findByCard(u.ghostCard)?.also { gu ->
// Store a backup of the old data
val fl = "mai2-backup-${u.auId}-${LocalDateTime.now().urlSafeStr()}.json"
(Path(netProps.importBackupPath) / fl).writeText(export(u).toJson())
// Delete the old data (After migration v1000.7, all user-linked entities have ON DELETE CASCADE)
logger.info("Mai2 Import: Deleting old data for user ${u.auId}")
repos.userData.delete(gu)
repos.userData.flush()
}
trans.execute {
// Insert new data
val nu = repos.userData.save(export.userData)
// Set user fields
lists.values.flatten().forEach { it.user = nu }
singles.values.forEach { it.user = nu }
// Save new data
singles.forEach { (repo, single) -> (repo as UserLinked<Any>).save(single) }
lists.forEach { (repo, list) -> (repo as UserLinked<Any>).saveAll(list) }
}
SUCCESS
}
} }

View File

@ -3,7 +3,7 @@ package icu.samnyan.aqua.sega.chusan.handler;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.general.BaseHandler; import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.chusan.model.response.data.UserEmoney; import icu.samnyan.aqua.sega.chusan.model.response.data.UserEmoney;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.service.UserDataService; import icu.samnyan.aqua.sega.chusan.service.UserDataService;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper; import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -36,12 +36,12 @@ public class CMGetUserDataHandler implements BaseHandler {
@Override @Override
public String handle(Map<String, Object> request) throws JsonProcessingException { public String handle(Map<String, Object> request) throws JsonProcessingException {
String userId = String.valueOf(request.get("userId")); String userId = String.valueOf(request.get("userId"));
Optional<UserData> userDataOptional = userDataService.getUserByExtId(userId); Optional<Chu3UserData> userDataOptional = userDataService.getUserByExtId(userId);
if (userDataOptional.isPresent()) { if (userDataOptional.isPresent()) {
Map<String, Object> resultMap = new LinkedHashMap<>(); Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("userId", userId); resultMap.put("userId", userId);
UserData user = userDataOptional.get(); Chu3UserData user = userDataOptional.get();
UserEmoney userEmoney = new UserEmoney(); UserEmoney userEmoney = new UserEmoney();
user.setUserEmoney(userEmoney); user.setUserEmoney(userEmoney);

View File

@ -2,7 +2,7 @@ package icu.samnyan.aqua.sega.chusan.handler;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.general.BaseHandler; import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.service.UserDataService; import icu.samnyan.aqua.sega.chusan.service.UserDataService;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper; import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -38,11 +38,11 @@ public class CMGetUserPreviewHandler implements BaseHandler {
String userId = String.valueOf(request.get("userId")); String userId = String.valueOf(request.get("userId"));
String segaIdAuthKey = String.valueOf(request.get("segaIdAuthKey")); String segaIdAuthKey = String.valueOf(request.get("segaIdAuthKey"));
Optional<UserData> userDataOptional = userDataService.getUserByExtId(userId); Optional<Chu3UserData> userDataOptional = userDataService.getUserByExtId(userId);
if (userDataOptional.isPresent()) { if (userDataOptional.isPresent()) {
Map<String, Object> resultMap = new LinkedHashMap<>(); Map<String, Object> resultMap = new LinkedHashMap<>();
UserData user = userDataOptional.get(); Chu3UserData user = userDataOptional.get();
resultMap.put("userName", user.getUserName()); resultMap.put("userName", user.getUserName());
resultMap.put("level", user.getLevel()); resultMap.put("level", user.getLevel());

View File

@ -7,7 +7,7 @@ import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.chusan.model.gamedata.GameGachaCard; import icu.samnyan.aqua.sega.chusan.model.gamedata.GameGachaCard;
import icu.samnyan.aqua.sega.chusan.model.request.UpsertUserGacha; import icu.samnyan.aqua.sega.chusan.model.request.UpsertUserGacha;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserCardPrintState; import icu.samnyan.aqua.sega.chusan.model.userdata.UserCardPrintState;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserGacha; import icu.samnyan.aqua.sega.chusan.model.userdata.UserGacha;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserItem; import icu.samnyan.aqua.sega.chusan.model.userdata.UserItem;
import icu.samnyan.aqua.sega.chusan.service.UserDataService; import icu.samnyan.aqua.sega.chusan.service.UserDataService;
@ -53,9 +53,9 @@ public class CMUpsertUserGachaHandler implements BaseHandler {
UpsertUserGacha upsertUserGacha = mapper.convert(request.get("cmUpsertUserGacha"), UpsertUserGacha.class); UpsertUserGacha upsertUserGacha = mapper.convert(request.get("cmUpsertUserGacha"), UpsertUserGacha.class);
List<UserCardPrintState> userCardPrintStateList = new ArrayList<>(); List<UserCardPrintState> userCardPrintStateList = new ArrayList<>();
UserData userData; Chu3UserData userData;
Optional<UserData> userOptional = userDataService.getUserByExtId(userId); Optional<Chu3UserData> userOptional = userDataService.getUserByExtId(userId);
if (userOptional.isPresent()) { if (userOptional.isPresent()) {
userData = userOptional.get(); userData = userOptional.get();
} else { } else {

View File

@ -5,7 +5,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserCardPrintStateRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserCardPrintStateRepo;
import icu.samnyan.aqua.sega.general.BaseHandler; import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserCardPrintState; import icu.samnyan.aqua.sega.chusan.model.userdata.UserCardPrintState;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserItem; import icu.samnyan.aqua.sega.chusan.model.userdata.UserItem;
import icu.samnyan.aqua.sega.chusan.service.UserDataService; import icu.samnyan.aqua.sega.chusan.service.UserDataService;
import icu.samnyan.aqua.sega.chusan.service.UserItemService; import icu.samnyan.aqua.sega.chusan.service.UserItemService;
@ -43,9 +43,9 @@ public class CMUpsertUserPrintSubtractHandler implements BaseHandler {
UserCardPrintState userCardPrintState = mapper.convert(request.get("userCardPrintState"), UserCardPrintState.class); UserCardPrintState userCardPrintState = mapper.convert(request.get("userCardPrintState"), UserCardPrintState.class);
List<UserItem> userItemList = mapper.convert(request.get("userItemList"), new TypeReference<List<UserItem>>() {}); List<UserItem> userItemList = mapper.convert(request.get("userItemList"), new TypeReference<List<UserItem>>() {});
UserData userData; Chu3UserData userData;
Optional<UserData> userOptional = userDataService.getUserByExtId(userId); Optional<Chu3UserData> userOptional = userDataService.getUserByExtId(userId);
if (userOptional.isPresent()) { if (userOptional.isPresent()) {
userData = userOptional.get(); userData = userOptional.get();
} else { } else {

View File

@ -5,7 +5,7 @@ import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.chusan.model.gamedata.GameLoginBonus; import icu.samnyan.aqua.sega.chusan.model.gamedata.GameLoginBonus;
import icu.samnyan.aqua.sega.chusan.model.gamedata.GameLoginBonusPreset; import icu.samnyan.aqua.sega.chusan.model.gamedata.GameLoginBonusPreset;
import icu.samnyan.aqua.sega.chusan.model.response.CodeResp; import icu.samnyan.aqua.sega.chusan.model.response.CodeResp;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserItem; import icu.samnyan.aqua.sega.chusan.model.userdata.UserItem;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserLoginBonus; import icu.samnyan.aqua.sega.chusan.model.userdata.UserLoginBonus;
import icu.samnyan.aqua.sega.chusan.service.*; import icu.samnyan.aqua.sega.chusan.service.*;
@ -63,7 +63,7 @@ public class GameLoginHandler implements BaseHandler {
@Override @Override
public String handle(Map<String, Object> request) throws JsonProcessingException { public String handle(Map<String, Object> request) throws JsonProcessingException {
String userId = (String) request.get("userId"); String userId = (String) request.get("userId");
Optional<UserData> userDataOptional = userDataService.getUserByExtId(userId); Optional<Chu3UserData> userDataOptional = userDataService.getUserByExtId(userId);
boolean userPresent = userDataOptional.isPresent(); boolean userPresent = userDataOptional.isPresent();
if (userPresent){ if (userPresent){
userDataService.updateLoginTime(userDataOptional.get()); userDataService.updateLoginTime(userDataOptional.get());
@ -105,7 +105,7 @@ public class GameLoginHandler implements BaseHandler {
Optional<GameLoginBonus> gameLoginBonus = this.gameLoginBonusService.getGameLoginBonusByDay(preset.getId(), bonusCount); Optional<GameLoginBonus> gameLoginBonus = this.gameLoginBonusService.getGameLoginBonusByDay(preset.getId(), bonusCount);
if(gameLoginBonus.isPresent()){ if(gameLoginBonus.isPresent()){
GameLoginBonus gameLoginBonusResult = gameLoginBonus.get(); GameLoginBonus gameLoginBonusResult = gameLoginBonus.get();
UserData userData = this.userDataService.getUserByExtId(userId).orElseThrow(); Chu3UserData userData = this.userDataService.getUserByExtId(userId).orElseThrow();
UserItem userItem = new UserItem(userData); UserItem userItem = new UserItem(userData);
userItem.setItemId(gameLoginBonusResult.getPresentId()); userItem.setItemId(gameLoginBonusResult.getPresentId());
userItem.setItemKind(6); userItem.setItemKind(6);

View File

@ -2,7 +2,7 @@ package icu.samnyan.aqua.sega.chusan.handler;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.general.BaseHandler; import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.service.UserDataService; import icu.samnyan.aqua.sega.chusan.service.UserDataService;
import icu.samnyan.aqua.sega.util.jackson.StringMapper; import icu.samnyan.aqua.sega.util.jackson.StringMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -35,12 +35,12 @@ public class GetUserDataHandler implements BaseHandler {
@Override @Override
public String handle(Map<String, Object> request) throws JsonProcessingException { public String handle(Map<String, Object> request) throws JsonProcessingException {
String userId = (String) request.get("userId"); String userId = (String) request.get("userId");
Optional<UserData> userDataOptional = userDataService.getUserByExtId(userId); Optional<Chu3UserData> userDataOptional = userDataService.getUserByExtId(userId);
if (userDataOptional.isPresent()) { if (userDataOptional.isPresent()) {
Map<String, Object> resultMap = new LinkedHashMap<>(); Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("userId", userId); resultMap.put("userId", userId);
UserData user = userDataOptional.get(); Chu3UserData user = userDataOptional.get();
resultMap.put("userData", user); resultMap.put("userData", user);
String json = mapper.write(resultMap); String json = mapper.write(resultMap);

View File

@ -4,7 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.general.BaseHandler; import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.chusan.model.response.GetUserPreviewResp; import icu.samnyan.aqua.sega.chusan.model.response.GetUserPreviewResp;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserCharacter; import icu.samnyan.aqua.sega.chusan.model.userdata.UserCharacter;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserGameOption; import icu.samnyan.aqua.sega.chusan.model.userdata.UserGameOption;
import icu.samnyan.aqua.sega.chusan.service.UserCharacterService; import icu.samnyan.aqua.sega.chusan.service.UserCharacterService;
import icu.samnyan.aqua.sega.chusan.service.UserDataService; import icu.samnyan.aqua.sega.chusan.service.UserDataService;
@ -53,13 +53,13 @@ public class GetUserPreviewHandler implements BaseHandler {
public String handle(Map<String, Object> request) throws JsonProcessingException { public String handle(Map<String, Object> request) throws JsonProcessingException {
String userId = (String) request.get("userId"); String userId = (String) request.get("userId");
Optional<UserData> userData = userDataService.getUserByExtId(userId); Optional<Chu3UserData> userData = userDataService.getUserByExtId(userId);
if (userData.isEmpty()) { if (userData.isEmpty()) {
return null; return null;
} }
UserData user = userData.get(); Chu3UserData user = userData.get();
GetUserPreviewResp resp = new GetUserPreviewResp(); GetUserPreviewResp resp = new GetUserPreviewResp();
resp.setUserId(userId); resp.setUserId(userId);

View File

@ -15,7 +15,6 @@ import icu.samnyan.aqua.sega.util.jackson.StringMapper;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -61,15 +60,15 @@ public class UpsertUserAllHandler implements BaseHandler {
// Not all field will be sent. Check if they are exist first. // Not all field will be sent. Check if they are exist first.
UserData newUserData; Chu3UserData newUserData;
// UserData // UserData
if (upsertUserAll.getUserData() == null) { if (upsertUserAll.getUserData() == null) {
return null; return null;
} else { } else {
newUserData = upsertUserAll.getUserData().get(0); newUserData = upsertUserAll.getUserData().get(0);
UserData userData = userDataService.getUserByExtId(userId).orElseGet(() -> { Chu3UserData userData = userDataService.getUserByExtId(userId).orElseGet(() -> {
var data = new UserData(); var data = new Chu3UserData();
Card card = cardService.getCardByExtId(userId).orElseThrow(); Card card = cardService.getCardByExtId(userId).orElseThrow();
data.setCard(card); data.setCard(card);
return data; return data;

View File

@ -4,7 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.general.BaseHandler; import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.chusan.model.response.CodeResp; import icu.samnyan.aqua.sega.chusan.model.response.CodeResp;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserCharge; import icu.samnyan.aqua.sega.chusan.model.userdata.UserCharge;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.service.UserChargeService; import icu.samnyan.aqua.sega.chusan.service.UserChargeService;
import icu.samnyan.aqua.sega.chusan.service.UserDataService; import icu.samnyan.aqua.sega.chusan.service.UserDataService;
import icu.samnyan.aqua.sega.util.jackson.StringMapper; import icu.samnyan.aqua.sega.util.jackson.StringMapper;
@ -36,7 +36,7 @@ public class UpsertUserChargelogHandler implements BaseHandler {
@Override @Override
public String handle(Map<String, Object> request) throws JsonProcessingException { public String handle(Map<String, Object> request) throws JsonProcessingException {
String userId = (String) request.get("userId"); String userId = (String) request.get("userId");
UserData user = userDataService.getUserByExtId(userId).orElseThrow(); Chu3UserData user = userDataService.getUserByExtId(userId).orElseThrow();
Map<String, Object> userChargeMap = (Map<String, Object>) request.get("userCharge"); Map<String, Object> userChargeMap = (Map<String, Object>) request.get("userCharge");
String chargeId = (String) userChargeMap.get("chargeId"); String chargeId = (String) userChargeMap.get("chargeId");

View File

@ -4,6 +4,7 @@ package icu.samnyan.aqua.sega.chusan.model
import icu.samnyan.aqua.net.games.GenericPlaylogRepo import icu.samnyan.aqua.net.games.GenericPlaylogRepo
import icu.samnyan.aqua.net.games.GenericUserDataRepo import icu.samnyan.aqua.net.games.GenericUserDataRepo
import icu.samnyan.aqua.net.games.IUserRepo
import icu.samnyan.aqua.sega.chusan.model.gamedata.* import icu.samnyan.aqua.sega.chusan.model.gamedata.*
import icu.samnyan.aqua.sega.chusan.model.userdata.* import icu.samnyan.aqua.sega.chusan.model.userdata.*
import org.springframework.data.domain.Page import org.springframework.data.domain.Page
@ -16,12 +17,10 @@ import java.util.*
@NoRepositoryBean @NoRepositoryBean
interface UserLinked<T, ID> : JpaRepository<T, ID> { interface Chu3UserLinked<T> : IUserRepo<Chu3UserData, T> {
fun findByUser_Card_ExtId(extId: Long): List<T> fun findByUser_Card_ExtId(extId: Long): List<T>
fun findSingleByUser_Card_ExtId(extId: Long): Optional<T> fun findSingleByUser_Card_ExtId(extId: Long): Optional<T>
fun findByUser_Card_ExtId(extId: Long, pageable: Pageable): Page<T> fun findByUser_Card_ExtId(extId: Long, pageable: Pageable): Page<T>
fun findByUser(user: UserData): List<T>
fun findSingleByUser(user: UserData): Optional<T>
} }
@ -39,62 +38,62 @@ interface Chu3UserLoginBonusRepo : JpaRepository<UserLoginBonus, Int> {
fun findLoginBonus(userId: Int, version: Int, presetId: Int): Optional<UserLoginBonus> fun findLoginBonus(userId: Int, version: Int, presetId: Int): Optional<UserLoginBonus>
} }
interface Chu3UserActivityRepo : UserLinked<UserActivity, Long> { interface Chu3UserActivityRepo : Chu3UserLinked<UserActivity> {
fun findTopByUserAndActivityIdAndKindOrderByIdDesc(user: UserData, activityId: Int, kind: Int): Optional<UserActivity> fun findTopByUserAndActivityIdAndKindOrderByIdDesc(user: Chu3UserData, activityId: Int, kind: Int): Optional<UserActivity>
fun findAllByUser_Card_ExtIdAndKindOrderBySortNumberDesc(extId: Long, kind: Int): List<UserActivity> fun findAllByUser_Card_ExtIdAndKindOrderBySortNumberDesc(extId: Long, kind: Int): List<UserActivity>
} }
interface Chu3UserCardPrintStateRepo : UserLinked<UserCardPrintState, Long> { interface Chu3UserCardPrintStateRepo : Chu3UserLinked<UserCardPrintState> {
fun findByUser_Card_ExtIdAndHasCompleted(extId: Long, hasCompleted: Boolean): List<UserCardPrintState> fun findByUser_Card_ExtIdAndHasCompleted(extId: Long, hasCompleted: Boolean): List<UserCardPrintState>
fun findByUserAndGachaIdAndHasCompleted(userData: UserData, gachaId: Int, hasCompleted: Boolean): List<UserCardPrintState> fun findByUserAndGachaIdAndHasCompleted(userData: Chu3UserData, gachaId: Int, hasCompleted: Boolean): List<UserCardPrintState>
} }
interface Chu3UserCharacterRepo : UserLinked<UserCharacter, Long> { interface Chu3UserCharacterRepo : Chu3UserLinked<UserCharacter> {
fun findTopByUserAndCharacterIdOrderByIdDesc(user: UserData, characterId: Int): Optional<UserCharacter> fun findTopByUserAndCharacterIdOrderByIdDesc(user: Chu3UserData, characterId: Int): Optional<UserCharacter>
} }
interface Chu3UserChargeRepo : UserLinked<UserCharge, Long> { interface Chu3UserChargeRepo : Chu3UserLinked<UserCharge> {
fun findByUserAndChargeId(extId: UserData, chargeId: Int): Optional<UserCharge> fun findByUserAndChargeId(extId: Chu3UserData, chargeId: Int): Optional<UserCharge>
} }
interface Chu3UserCourseRepo : UserLinked<UserCourse, Long> { interface Chu3UserCourseRepo : Chu3UserLinked<UserCourse> {
fun findTopByUserAndCourseIdOrderByIdDesc(user: UserData, courseId: Int): Optional<UserCourse> fun findTopByUserAndCourseIdOrderByIdDesc(user: Chu3UserData, courseId: Int): Optional<UserCourse>
} }
interface Chu3UserDataRepo : GenericUserDataRepo<UserData> interface Chu3UserDataRepo : GenericUserDataRepo<Chu3UserData>
interface Chu3UserDuelRepo : UserLinked<UserDuel, Long> { interface Chu3UserDuelRepo : Chu3UserLinked<UserDuel> {
fun findTopByUserAndDuelIdOrderByIdDesc(user: UserData, duelId: Int): Optional<UserDuel> fun findTopByUserAndDuelIdOrderByIdDesc(user: Chu3UserData, duelId: Int): Optional<UserDuel>
} }
interface Chu3UserGachaRepo : UserLinked<UserGacha, Long> { interface Chu3UserGachaRepo : Chu3UserLinked<UserGacha> {
fun findByUserAndGachaId(extId: UserData, gachaId: Int): Optional<UserGacha> fun findByUserAndGachaId(extId: Chu3UserData, gachaId: Int): Optional<UserGacha>
} }
interface Chu3UserGameOptionRepo : UserLinked<UserGameOption, Long> interface Chu3UserGameOptionRepo : Chu3UserLinked<UserGameOption>
interface Chu3UserGeneralDataRepo : UserLinked<UserGeneralData, Long> { interface Chu3UserGeneralDataRepo : Chu3UserLinked<UserGeneralData> {
fun findByUserAndPropertyKey(user: UserData, key: String): Optional<UserGeneralData> fun findByUserAndPropertyKey(user: Chu3UserData, key: String): Optional<UserGeneralData>
fun findByUser_Card_ExtIdAndPropertyKey(extId: Long, key: String): Optional<UserGeneralData> fun findByUser_Card_ExtIdAndPropertyKey(extId: Long, key: String): Optional<UserGeneralData>
} }
interface Chu3UserItemRepo : UserLinked<UserItem, Long> { interface Chu3UserItemRepo : Chu3UserLinked<UserItem> {
fun findTopByUserAndItemIdAndItemKindOrderByIdDesc(user: UserData, itemId: Int, itemKind: Int): Optional<UserItem> fun findTopByUserAndItemIdAndItemKindOrderByIdDesc(user: Chu3UserData, itemId: Int, itemKind: Int): Optional<UserItem>
fun findAllByUser_Card_ExtIdAndItemKind(extId: Long, itemKind: Int, pageable: Pageable): Page<UserItem> fun findAllByUser_Card_ExtIdAndItemKind(extId: Long, itemKind: Int, pageable: Pageable): Page<UserItem>
fun findAllByUser_Card_ExtIdAndItemKind(extId: Long, itemKind: Int): List<UserItem> fun findAllByUser_Card_ExtIdAndItemKind(extId: Long, itemKind: Int): List<UserItem>
} }
interface Chu3UserMapAreaRepo : UserLinked<UserMapArea, Long> { interface Chu3UserMapAreaRepo : Chu3UserLinked<UserMapArea> {
fun findTopByUserAndMapAreaIdOrderByIdDesc(user: UserData, mapAreaId: Int): Optional<UserMapArea> fun findTopByUserAndMapAreaIdOrderByIdDesc(user: Chu3UserData, mapAreaId: Int): Optional<UserMapArea>
} }
interface Chu3UserMusicDetailRepo : UserLinked<UserMusicDetail, Long> { interface Chu3UserMusicDetailRepo : Chu3UserLinked<UserMusicDetail> {
fun findTopByUserAndMusicIdAndLevelOrderByIdDesc(user: UserData, musicId: Int, level: Int): Optional<UserMusicDetail> fun findTopByUserAndMusicIdAndLevelOrderByIdDesc(user: Chu3UserData, musicId: Int, level: Int): Optional<UserMusicDetail>
fun findByUser_Card_ExtIdAndMusicId(extId: Long, musicId: Int): List<UserMusicDetail> fun findByUser_Card_ExtIdAndMusicId(extId: Long, musicId: Int): List<UserMusicDetail>
} }

View File

@ -21,7 +21,7 @@ import java.util.Map;
public class UpsertUserAll implements Serializable { public class UpsertUserAll implements Serializable {
@Nullable @Nullable
private List<UserData> userData; private List<Chu3UserData> userData;
@Nullable @Nullable
private List<UserGameOption> userGameOption; private List<UserGameOption> userGameOption;

View File

@ -2,7 +2,7 @@ package icu.samnyan.aqua.sega.chusan.model.request;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import icu.samnyan.aqua.sega.chusan.model.gamedata.GameGachaCard; import icu.samnyan.aqua.sega.chusan.model.gamedata.GameGachaCard;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserGacha; import icu.samnyan.aqua.sega.chusan.model.userdata.UserGacha;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserItem; import icu.samnyan.aqua.sega.chusan.model.userdata.UserItem;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -22,7 +22,7 @@ import java.util.List;
public class UpsertUserGacha implements Serializable { public class UpsertUserGacha implements Serializable {
@Nullable @Nullable
private UserData userData; private Chu3UserData userData;
@Nullable @Nullable
private UserGacha userGacha; private UserGacha userGacha;

View File

@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import icu.samnyan.aqua.net.games.IGenericUserData; import icu.samnyan.aqua.net.games.IUserData;
import icu.samnyan.aqua.sega.chusan.model.response.data.UserEmoney; import icu.samnyan.aqua.sega.chusan.model.response.data.UserEmoney;
import icu.samnyan.aqua.sega.general.model.Card; import icu.samnyan.aqua.sega.general.model.Card;
import icu.samnyan.aqua.sega.util.jackson.AccessCodeSerializer; import icu.samnyan.aqua.sega.util.jackson.AccessCodeSerializer;
@ -126,7 +126,7 @@ import java.util.List;
"rankUpChallengeResults", "rankUpChallengeResults",
"isNetBattleHost", "isNetBattleHost",
"netBattleEndState" }) "netBattleEndState" })
public class UserData implements Serializable, IGenericUserData { public class Chu3UserData implements Serializable, IUserData {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -31,7 +31,7 @@ public class UserActivity implements Serializable {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
private int kind; private int kind;
@ -49,7 +49,7 @@ public class UserActivity implements Serializable {
private int param4; private int param4;
public UserActivity(UserData userData) { public UserActivity(Chu3UserData userData) {
user = userData; user = userData;
} }
} }

View File

@ -20,7 +20,7 @@ public class UserCMission {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
@Column(name = "mission_id") @Column(name = "mission_id")
private int missionId; private int missionId;

View File

@ -20,7 +20,7 @@ public class UserCMissionProgress {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
@Column(name = "mission_id") @Column(name = "mission_id")
private int missionId; private int missionId;

View File

@ -30,7 +30,7 @@ public class UserCardPrintState implements Serializable {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
private boolean hasCompleted; private boolean hasCompleted;
private LocalDateTime limitDate; private LocalDateTime limitDate;
@ -38,7 +38,7 @@ public class UserCardPrintState implements Serializable {
private int cardId; private int cardId;
private int gachaId; private int gachaId;
public UserCardPrintState(UserData user) { public UserCardPrintState(Chu3UserData user) {
this.user = user; this.user = user;
} }
} }

View File

@ -31,7 +31,7 @@ public class UserCharacter implements Serializable {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
@Column(name = "character_id") @Column(name = "character_id")
private int characterId; private int characterId;
@ -56,7 +56,7 @@ public class UserCharacter implements Serializable {
private int param2 = 0; private int param2 = 0;
public UserCharacter(UserData userData) { public UserCharacter(Chu3UserData userData) {
user = userData; user = userData;
} }
} }

View File

@ -31,7 +31,7 @@ public class UserCharge implements Serializable {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
@Column(name = "charge_id") @Column(name = "charge_id")
private int chargeId; private int chargeId;
@ -48,7 +48,7 @@ public class UserCharge implements Serializable {
private LocalDateTime paramDate; private LocalDateTime paramDate;
public UserCharge(UserData user) { public UserCharge(Chu3UserData user) {
this.user = user; this.user = user;
} }
} }

View File

@ -27,7 +27,7 @@ public class UserCourse {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
@Column(name = "course_id") @Column(name = "course_id")
private int courseId; private int courseId;
@ -70,7 +70,7 @@ public class UserCourse {
@JsonProperty("isClear") @JsonProperty("isClear")
private boolean isClear; private boolean isClear;
public UserCourse(UserData userData) { public UserCourse(Chu3UserData userData) {
user = userData; user = userData;
} }

View File

@ -27,7 +27,7 @@ public class UserDuel {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
@Column(name = "duel_id") @Column(name = "duel_id")
private int duelId; private int duelId;
@ -49,7 +49,7 @@ public class UserDuel {
private int param4; private int param4;
public UserDuel(UserData userData) { public UserDuel(Chu3UserData userData) {
user = userData; user = userData;
} }
} }

View File

@ -29,7 +29,7 @@ public class UserGacha implements Serializable {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
@Column(name = "gacha_id") @Column(name = "gacha_id")
private int gachaId; private int gachaId;
@ -46,7 +46,7 @@ public class UserGacha implements Serializable {
private LocalDateTime dailyGachaDate; private LocalDateTime dailyGachaDate;
public UserGacha(UserData user) { public UserGacha(Chu3UserData user) {
this.user = user; this.user = user;
} }
} }

View File

@ -81,7 +81,7 @@ public class UserGameOption implements Serializable {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
private int bgInfo; private int bgInfo;
@ -183,7 +183,7 @@ public class UserGameOption implements Serializable {
private int ext10; private int ext10;
public UserGameOption(UserData userData) { public UserGameOption(Chu3UserData userData) {
user = userData; user = userData;
} }
} }

View File

@ -29,14 +29,14 @@ public class UserGeneralData implements Serializable {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
private String propertyKey; private String propertyKey;
@Column(columnDefinition = "TEXT") @Column(columnDefinition = "TEXT")
private String propertyValue; private String propertyValue;
public UserGeneralData(UserData userData, String key) { public UserGeneralData(Chu3UserData userData, String key) {
this.user = userData; this.user = userData;
this.propertyKey = key; this.propertyKey = key;
this.propertyValue = ""; this.propertyValue = "";

View File

@ -31,7 +31,7 @@ public class UserItem implements Serializable {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
// Kind ,Type // Kind ,Type
@Column(name = "item_kind") @Column(name = "item_kind")
@ -45,7 +45,7 @@ public class UserItem implements Serializable {
@JsonProperty("isValid") @JsonProperty("isValid")
private boolean isValid = true; private boolean isValid = true;
public UserItem(UserData userData) { public UserItem(Chu3UserData userData) {
user = userData; user = userData;
} }
} }

View File

@ -39,7 +39,7 @@ public class UserMapArea implements Serializable {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
@Column(name = "map_area_id") @Column(name = "map_area_id")
private int mapAreaId; private int mapAreaId;
@ -58,7 +58,7 @@ public class UserMapArea implements Serializable {
@JsonProperty("isLocked") @JsonProperty("isLocked")
private boolean isLocked; private boolean isLocked;
public UserMapArea(UserData userData) { public UserMapArea(Chu3UserData userData) {
user = userData; user = userData;
} }
} }

View File

@ -48,7 +48,7 @@ public class UserMusicDetail implements Serializable {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
@Column(name = "music_id") @Column(name = "music_id")
private int musicId; private int musicId;
@ -86,7 +86,7 @@ public class UserMusicDetail implements Serializable {
private int ext1; private int ext1;
public UserMusicDetail(UserData userData) { public UserMusicDetail(Chu3UserData userData) {
user = userData; user = userData;
} }

View File

@ -32,7 +32,7 @@ public class UserPlaylog implements Serializable, IGenericGamePlaylog {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private UserData user; private Chu3UserData user;
private String romVersion; private String romVersion;
@ -155,7 +155,7 @@ public class UserPlaylog implements Serializable, IGenericGamePlaylog {
// SUN PLUS // SUN PLUS
private int ticketId; private int ticketId;
public UserPlaylog(UserData userData) { public UserPlaylog(Chu3UserData userData) {
user = userData; user = userData;
} }

View File

@ -2,7 +2,7 @@ package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserActivityRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserActivityRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserActivity; import icu.samnyan.aqua.sega.chusan.model.userdata.UserActivity;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -30,7 +30,7 @@ public class UserActivityService {
return userActivityRepository.saveAll(userActivityList); return userActivityRepository.saveAll(userActivityList);
} }
public Optional<UserActivity> getByUserAndActivityIdAndKind(UserData user, int activityId, int kind) { public Optional<UserActivity> getByUserAndActivityIdAndKind(Chu3UserData user, int activityId, int kind) {
return userActivityRepository.findTopByUserAndActivityIdAndKindOrderByIdDesc(user, activityId, kind); return userActivityRepository.findTopByUserAndActivityIdAndKindOrderByIdDesc(user, activityId, kind);
} }

View File

@ -2,7 +2,7 @@ package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserCharacterRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserCharacterRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserCharacter; import icu.samnyan.aqua.sega.chusan.model.userdata.UserCharacter;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
@ -42,7 +42,7 @@ public class UserCharacterService {
return userCharacterRepository.findByUser_Card_ExtId(Long.parseLong(userId), pageable); return userCharacterRepository.findByUser_Card_ExtId(Long.parseLong(userId), pageable);
} }
public Optional<UserCharacter> getByUserAndCharacterId(UserData user, int characterId) { public Optional<UserCharacter> getByUserAndCharacterId(Chu3UserData user, int characterId) {
return userCharacterRepository.findTopByUserAndCharacterIdOrderByIdDesc(user, characterId); return userCharacterRepository.findTopByUserAndCharacterIdOrderByIdDesc(user, characterId);
} }

View File

@ -2,7 +2,7 @@ package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserChargeRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserChargeRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserCharge; import icu.samnyan.aqua.sega.chusan.model.userdata.UserCharge;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
@ -32,7 +32,7 @@ public class UserChargeService {
return userChargeRepository.findByUser_Card_ExtId(Long.parseLong(userId)); return userChargeRepository.findByUser_Card_ExtId(Long.parseLong(userId));
} }
public Optional<UserCharge> getByUserAndChargeId(UserData user, int chargeId) { public Optional<UserCharge> getByUserAndChargeId(Chu3UserData user, int chargeId) {
return userChargeRepository.findByUserAndChargeId(user, chargeId); return userChargeRepository.findByUserAndChargeId(user, chargeId);
} }

View File

@ -2,7 +2,7 @@ package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserCourseRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserCourseRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserCourse; import icu.samnyan.aqua.sega.chusan.model.userdata.UserCourse;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
@ -42,7 +42,7 @@ public class UserCourseService {
return userCourseRepository.findByUser_Card_ExtId(Long.parseLong(userId), page); return userCourseRepository.findByUser_Card_ExtId(Long.parseLong(userId), page);
} }
public Optional<UserCourse> getByUserAndCourseId(UserData user, int courseId) { public Optional<UserCourse> getByUserAndCourseId(Chu3UserData user, int courseId) {
return userCourseRepository.findTopByUserAndCourseIdOrderByIdDesc(user, courseId); return userCourseRepository.findTopByUserAndCourseIdOrderByIdDesc(user, courseId);
} }
} }

View File

@ -1,7 +1,7 @@
package icu.samnyan.aqua.sega.chusan.service; package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserDataRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserDataRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.general.model.Card; import icu.samnyan.aqua.sega.general.model.Card;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -22,23 +22,23 @@ public class UserDataService {
this.userDataRepository = userDataRepository; this.userDataRepository = userDataRepository;
} }
public UserData saveUserData(UserData userData) { public Chu3UserData saveUserData(Chu3UserData userData) {
return userDataRepository.save(userData); return userDataRepository.save(userData);
} }
public UserData saveAndFlushUserData(UserData userData) { public Chu3UserData saveAndFlushUserData(Chu3UserData userData) {
return userDataRepository.saveAndFlush(userData); return userDataRepository.saveAndFlush(userData);
} }
public Optional<UserData> getUserByExtId(String aimeId) { public Optional<Chu3UserData> getUserByExtId(String aimeId) {
return userDataRepository.findByCard_ExtId(Long.parseLong(aimeId)); return userDataRepository.findByCard_ExtId(Long.parseLong(aimeId));
} }
public Optional<UserData> getUserByCard(Card card) { public Optional<Chu3UserData> getUserByCard(Card card) {
return Optional.ofNullable(userDataRepository.findByCard(card)); return Optional.ofNullable(userDataRepository.findByCard(card));
} }
public void updateLoginTime(UserData userData) { public void updateLoginTime(Chu3UserData userData) {
userData.setLastLoginDate(LocalDateTime.now()); userData.setLastLoginDate(LocalDateTime.now());
userDataRepository.save(userData); userDataRepository.save(userData);
} }

View File

@ -1,7 +1,7 @@
package icu.samnyan.aqua.sega.chusan.service; package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserDuelRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserDuelRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserDuel; import icu.samnyan.aqua.sega.chusan.model.userdata.UserDuel;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -22,7 +22,7 @@ public class UserDuelService {
this.userDuelRepository = userDuelRepository; this.userDuelRepository = userDuelRepository;
} }
public Optional<UserDuel> getByUserAndDuelId(UserData user, int duelId) { public Optional<UserDuel> getByUserAndDuelId(Chu3UserData user, int duelId) {
return userDuelRepository.findTopByUserAndDuelIdOrderByIdDesc(user, duelId); return userDuelRepository.findTopByUserAndDuelIdOrderByIdDesc(user, duelId);
} }

View File

@ -1,7 +1,7 @@
package icu.samnyan.aqua.sega.chusan.service; package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserGachaRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserGachaRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserGacha; import icu.samnyan.aqua.sega.chusan.model.userdata.UserGacha;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -32,7 +32,7 @@ public class UserGachaService {
return userGachaRepository.findByUser_Card_ExtId(Long.parseLong(userId)); return userGachaRepository.findByUser_Card_ExtId(Long.parseLong(userId));
} }
public Optional<UserGacha> getByUserAndGachaId(UserData user, int gachaId) { public Optional<UserGacha> getByUserAndGachaId(Chu3UserData user, int gachaId) {
return userGachaRepository.findByUserAndGachaId(user, gachaId); return userGachaRepository.findByUserAndGachaId(user, gachaId);
} }

View File

@ -1,7 +1,7 @@
package icu.samnyan.aqua.sega.chusan.service; package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserGameOptionRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserGameOptionRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserGameOption; import icu.samnyan.aqua.sega.chusan.model.userdata.UserGameOption;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -25,7 +25,7 @@ public class UserGameOptionService {
return userGameOptionRepository.save(userGameOption); return userGameOptionRepository.save(userGameOption);
} }
public Optional<UserGameOption> getByUser(UserData user) { public Optional<UserGameOption> getByUser(Chu3UserData user) {
return userGameOptionRepository.findSingleByUser(user); return userGameOptionRepository.findSingleByUser(user);
} }

View File

@ -1,7 +1,7 @@
package icu.samnyan.aqua.sega.chusan.service; package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserGeneralDataRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserGeneralDataRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserGeneralData; import icu.samnyan.aqua.sega.chusan.model.userdata.UserGeneralData;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -23,7 +23,7 @@ public class UserGeneralDataService {
return userGeneralDataRepository.save(userGeneralData); return userGeneralDataRepository.save(userGeneralData);
} }
public Optional<UserGeneralData> getByUserAndKey(UserData user, String key) { public Optional<UserGeneralData> getByUserAndKey(Chu3UserData user, String key) {
return userGeneralDataRepository.findByUserAndPropertyKey(user, key); return userGeneralDataRepository.findByUserAndPropertyKey(user, key);
} }

View File

@ -1,7 +1,7 @@
package icu.samnyan.aqua.sega.chusan.service; package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserItemRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserItemRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserItem; import icu.samnyan.aqua.sega.chusan.model.userdata.UserItem;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@ -39,7 +39,7 @@ public class UserItemService {
return userItemList; return userItemList;
} }
public Optional<UserItem> getByUserAndItemIdAndKind(UserData user, int itemId, int itemKind) { public Optional<UserItem> getByUserAndItemIdAndKind(Chu3UserData user, int itemId, int itemKind) {
return userItemRepository.findTopByUserAndItemIdAndItemKindOrderByIdDesc(user, itemId, itemKind); return userItemRepository.findTopByUserAndItemIdAndItemKindOrderByIdDesc(user, itemId, itemKind);
} }

View File

@ -1,7 +1,7 @@
package icu.samnyan.aqua.sega.chusan.service; package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserMapAreaRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserMapAreaRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserMapArea; import icu.samnyan.aqua.sega.chusan.model.userdata.UserMapArea;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -30,7 +30,7 @@ public class UserMapAreaService {
return userMapRepository.saveAll(userMap); return userMapRepository.saveAll(userMap);
} }
public List<UserMapArea> getByUser(UserData user) { public List<UserMapArea> getByUser(Chu3UserData user) {
return userMapRepository.findByUser(user); return userMapRepository.findByUser(user);
} }
@ -38,7 +38,7 @@ public class UserMapAreaService {
return userMapRepository.findByUser_Card_ExtId(Long.parseLong(userId)); return userMapRepository.findByUser_Card_ExtId(Long.parseLong(userId));
} }
public Optional<UserMapArea> getByUserAndMapAreaId(UserData user, int mapId) { public Optional<UserMapArea> getByUserAndMapAreaId(Chu3UserData user, int mapId) {
return userMapRepository.findTopByUserAndMapAreaIdOrderByIdDesc(user, mapId); return userMapRepository.findTopByUserAndMapAreaIdOrderByIdDesc(user, mapId);
} }
} }

View File

@ -1,7 +1,7 @@
package icu.samnyan.aqua.sega.chusan.service; package icu.samnyan.aqua.sega.chusan.service;
import icu.samnyan.aqua.sega.chusan.model.Chu3UserMusicDetailRepo; import icu.samnyan.aqua.sega.chusan.model.Chu3UserMusicDetailRepo;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserData; import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3UserData;
import icu.samnyan.aqua.sega.chusan.model.userdata.UserMusicDetail; import icu.samnyan.aqua.sega.chusan.model.userdata.UserMusicDetail;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@ -44,7 +44,7 @@ public class UserMusicDetailService {
return userMusicDetailRepository.findByUser_Card_ExtIdAndMusicId(Long.parseLong(userId), musicId); return userMusicDetailRepository.findByUser_Card_ExtIdAndMusicId(Long.parseLong(userId), musicId);
} }
public Optional<UserMusicDetail> getByUserAndMusicIdAndLevel(UserData user, int musicId, int level) { public Optional<UserMusicDetail> getByUserAndMusicIdAndLevel(Chu3UserData user, int musicId, int level) {
return userMusicDetailRepository.findTopByUserAndMusicIdAndLevelOrderByIdDesc(user, musicId, level); return userMusicDetailRepository.findTopByUserAndMusicIdAndLevelOrderByIdDesc(user, musicId, level);
} }
} }

View File

@ -4,6 +4,7 @@ package icu.samnyan.aqua.sega.maimai2.model
import icu.samnyan.aqua.net.games.GenericPlaylogRepo import icu.samnyan.aqua.net.games.GenericPlaylogRepo
import icu.samnyan.aqua.net.games.GenericUserDataRepo import icu.samnyan.aqua.net.games.GenericUserDataRepo
import icu.samnyan.aqua.net.games.IUserRepo
import icu.samnyan.aqua.sega.general.model.Card import icu.samnyan.aqua.sega.general.model.Card
import icu.samnyan.aqua.sega.maimai2.model.userdata.* import icu.samnyan.aqua.sega.maimai2.model.userdata.*
import org.springframework.data.domain.Page import org.springframework.data.domain.Page
@ -16,8 +17,7 @@ import org.springframework.transaction.annotation.Transactional
import java.util.* import java.util.*
@NoRepositoryBean @NoRepositoryBean
interface UserLinked<T>: JpaRepository<T, Long> { interface Mai2UserLinked<T>: JpaRepository<T, Long>, IUserRepo<Mai2UserDetail, T> {
fun findByUser(user: Mai2UserDetail): List<T>
fun findSingleByUser(user: Mai2UserDetail): Optional<T> fun findSingleByUser(user: Mai2UserDetail): Optional<T>
fun findByUser_Card_ExtId(userId: Long): List<T> fun findByUser_Card_ExtId(userId: Long): List<T>
fun findByUser_Card_ExtId(userId: Long, page: Pageable): Page<T> fun findByUser_Card_ExtId(userId: Long, page: Pageable): Page<T>
@ -26,25 +26,25 @@ interface UserLinked<T>: JpaRepository<T, Long> {
fun deleteByUser(user: Mai2UserDetail) fun deleteByUser(user: Mai2UserDetail)
} }
interface Mai2MapEncountNpcRepo : UserLinked<Mai2MapEncountNpc> interface Mai2MapEncountNpcRepo : Mai2UserLinked<Mai2MapEncountNpc>
interface Mai2UserActRepo : UserLinked<Mai2UserAct> { interface Mai2UserActRepo : Mai2UserLinked<Mai2UserAct> {
fun findByUserAndKindAndActivityId(user: Mai2UserDetail, kind: Int, id: Int): Optional<Mai2UserAct> fun findByUserAndKindAndActivityId(user: Mai2UserDetail, kind: Int, id: Int): Optional<Mai2UserAct>
fun findByUser_Card_ExtIdAndKind(userId: Long, kind: Int): List<Mai2UserAct> fun findByUser_Card_ExtIdAndKind(userId: Long, kind: Int): List<Mai2UserAct>
} }
interface Mai2UserCardRepo : UserLinked<Mai2UserCard> { interface Mai2UserCardRepo : Mai2UserLinked<Mai2UserCard> {
fun findByUserAndCardId(user: Mai2UserDetail, cardId: Int): Optional<Mai2UserCard> fun findByUserAndCardId(user: Mai2UserDetail, cardId: Int): Optional<Mai2UserCard>
} }
interface Mai2UserCharacterRepo : UserLinked<Mai2UserCharacter> { interface Mai2UserCharacterRepo : Mai2UserLinked<Mai2UserCharacter> {
fun findByUserAndCharacterId(user: Mai2UserDetail, characterId: Int): Optional<Mai2UserCharacter> fun findByUserAndCharacterId(user: Mai2UserDetail, characterId: Int): Optional<Mai2UserCharacter>
} }
interface Mai2UserChargeRepo : UserLinked<Mai2UserCharge> interface Mai2UserChargeRepo : Mai2UserLinked<Mai2UserCharge>
interface Mai2UserCourseRepo : UserLinked<Mai2UserCourse> { interface Mai2UserCourseRepo : Mai2UserLinked<Mai2UserCourse> {
fun findByUserAndCourseId(user: Mai2UserDetail, courseId: Int): Optional<Mai2UserCourse> fun findByUserAndCourseId(user: Mai2UserDetail, courseId: Int): Optional<Mai2UserCourse>
} }
@ -56,54 +56,54 @@ interface Mai2UserDataRepo : GenericUserDataRepo<Mai2UserDetail> {
fun deleteByCard(card: Card): Void fun deleteByCard(card: Card): Void
} }
interface Mai2UserExtendRepo : UserLinked<Mai2UserExtend> interface Mai2UserExtendRepo : Mai2UserLinked<Mai2UserExtend>
interface Mai2UserFavoriteRepo : UserLinked<Mai2UserFavorite> { interface Mai2UserFavoriteRepo : Mai2UserLinked<Mai2UserFavorite> {
fun findByUserAndItemKind(user: Mai2UserDetail, kind: Int): Optional<Mai2UserFavorite> fun findByUserAndItemKind(user: Mai2UserDetail, kind: Int): Optional<Mai2UserFavorite>
fun findByUserIdAndItemKind(userId: Long, kind: Int): List<Mai2UserFavorite> fun findByUserIdAndItemKind(userId: Long, kind: Int): List<Mai2UserFavorite>
} }
interface Mai2UserFriendSeasonRankingRepo : UserLinked<Mai2UserFriendSeasonRanking> { interface Mai2UserFriendSeasonRankingRepo : Mai2UserLinked<Mai2UserFriendSeasonRanking> {
fun findByUserAndSeasonId(user: Mai2UserDetail, seasonId: Int): Optional<Mai2UserFriendSeasonRanking> fun findByUserAndSeasonId(user: Mai2UserDetail, seasonId: Int): Optional<Mai2UserFriendSeasonRanking>
} }
interface Mai2UserGeneralDataRepo : UserLinked<Mai2UserGeneralData> { interface Mai2UserGeneralDataRepo : Mai2UserLinked<Mai2UserGeneralData> {
fun findByUserAndPropertyKey(user: Mai2UserDetail, key: String): Optional<Mai2UserGeneralData> fun findByUserAndPropertyKey(user: Mai2UserDetail, key: String): Optional<Mai2UserGeneralData>
fun findByUser_Card_ExtIdAndPropertyKey(userId: Long, key: String): Optional<Mai2UserGeneralData> fun findByUser_Card_ExtIdAndPropertyKey(userId: Long, key: String): Optional<Mai2UserGeneralData>
} }
interface Mai2UserItemRepo : UserLinked<Mai2UserItem> { interface Mai2UserItemRepo : Mai2UserLinked<Mai2UserItem> {
fun findByUserCardExtIdAndItemKind(userId: Long, kind: Int): List<Mai2UserItem> fun findByUserCardExtIdAndItemKind(userId: Long, kind: Int): List<Mai2UserItem>
fun findByUserAndItemKindAndItemId(user: Mai2UserDetail, itemKind: Int, itemId: Int): Optional<Mai2UserItem> fun findByUserAndItemKindAndItemId(user: Mai2UserDetail, itemKind: Int, itemId: Int): Optional<Mai2UserItem>
fun findByUser_Card_ExtIdAndItemKind(userId: Long, kind: Int, page: Pageable): Page<Mai2UserItem> fun findByUser_Card_ExtIdAndItemKind(userId: Long, kind: Int, page: Pageable): Page<Mai2UserItem>
} }
interface Mai2UserLoginBonusRepo : UserLinked<Mai2UserLoginBonus> { interface Mai2UserLoginBonusRepo : Mai2UserLinked<Mai2UserLoginBonus> {
fun findByUserAndBonusId(user: Mai2UserDetail, bonusId: Int): Optional<Mai2UserLoginBonus> fun findByUserAndBonusId(user: Mai2UserDetail, bonusId: Int): Optional<Mai2UserLoginBonus>
} }
interface Mai2UserMapRepo : UserLinked<Mai2UserMap> { interface Mai2UserMapRepo : Mai2UserLinked<Mai2UserMap> {
fun findByUserAndMapId(user: Mai2UserDetail, mapId: Int): Optional<Mai2UserMap> fun findByUserAndMapId(user: Mai2UserDetail, mapId: Int): Optional<Mai2UserMap>
} }
interface Mai2UserMusicDetailRepo : UserLinked<Mai2UserMusicDetail> { interface Mai2UserMusicDetailRepo : Mai2UserLinked<Mai2UserMusicDetail> {
fun findByUser_Card_ExtIdAndMusicId(userId: Long, id: Int): List<Mai2UserMusicDetail> fun findByUser_Card_ExtIdAndMusicId(userId: Long, id: Int): List<Mai2UserMusicDetail>
fun findByUserAndMusicIdAndLevel(user: Mai2UserDetail, musicId: Int, level: Int): Optional<Mai2UserMusicDetail> fun findByUserAndMusicIdAndLevel(user: Mai2UserDetail, musicId: Int, level: Int): Optional<Mai2UserMusicDetail>
} }
interface Mai2UserOptionRepo : UserLinked<Mai2UserOption> interface Mai2UserOptionRepo : Mai2UserLinked<Mai2UserOption>
interface Mai2UserPlaylogRepo : GenericPlaylogRepo<Mai2UserPlaylog>, UserLinked<Mai2UserPlaylog> { interface Mai2UserPlaylogRepo : GenericPlaylogRepo<Mai2UserPlaylog>, Mai2UserLinked<Mai2UserPlaylog> {
fun findByUser_Card_ExtIdAndMusicIdAndLevel(userId: Long, musicId: Int, level: Int): List<Mai2UserPlaylog> fun findByUser_Card_ExtIdAndMusicIdAndLevel(userId: Long, musicId: Int, level: Int): List<Mai2UserPlaylog>
} }
interface Mai2UserPrintDetailRepo : JpaRepository<Mai2UserPrintDetail, Long> interface Mai2UserPrintDetailRepo : JpaRepository<Mai2UserPrintDetail, Long>
interface Mai2UserUdemaeRepo : UserLinked<Mai2UserUdemae> interface Mai2UserUdemaeRepo : Mai2UserLinked<Mai2UserUdemae>
interface Mai2GameChargeRepo : JpaRepository<Mai2GameCharge, Long> interface Mai2GameChargeRepo : JpaRepository<Mai2GameCharge, Long>

View File

@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.databind.annotation.JsonSerialize
import icu.samnyan.aqua.net.games.BaseEntity import icu.samnyan.aqua.net.games.BaseEntity
import icu.samnyan.aqua.net.games.IGenericUserData import icu.samnyan.aqua.net.games.IUserData
import icu.samnyan.aqua.sega.general.IntegerListConverter import icu.samnyan.aqua.sega.general.IntegerListConverter
import icu.samnyan.aqua.sega.general.model.Card import icu.samnyan.aqua.sega.general.model.Card
import icu.samnyan.aqua.sega.util.jackson.AccessCodeSerializer import icu.samnyan.aqua.sega.util.jackson.AccessCodeSerializer
@ -149,7 +149,7 @@ class Mai2UserDetail(
// TODO: Make these non-nullable with default value // TODO: Make these non-nullable with default value
var currentPlayCount: Int? = 0, var currentPlayCount: Int? = 0,
var renameCredit: Int? = 0 var renameCredit: Int? = 0
) : BaseEntity(), IGenericUserData { ) : BaseEntity(), IUserData {
@get:JsonIgnore @get:JsonIgnore
override val totalScore: Long override val totalScore: Long
get() = totalDeluxscore get() = totalDeluxscore

View File

@ -8,6 +8,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.annotation.JsonPropertyOrder import com.fasterxml.jackson.annotation.JsonPropertyOrder
import icu.samnyan.aqua.net.games.BaseEntity import icu.samnyan.aqua.net.games.BaseEntity
import icu.samnyan.aqua.net.games.IGenericGamePlaylog import icu.samnyan.aqua.net.games.IGenericGamePlaylog
import icu.samnyan.aqua.net.games.IUserEntity
import icu.samnyan.aqua.sega.general.IntegerListConverter import icu.samnyan.aqua.sega.general.IntegerListConverter
import jakarta.persistence.* import jakarta.persistence.*
import lombok.AllArgsConstructor import lombok.AllArgsConstructor
@ -15,11 +16,11 @@ import lombok.Data
import lombok.NoArgsConstructor import lombok.NoArgsConstructor
@MappedSuperclass @MappedSuperclass
open class Mai2UserEntity : BaseEntity() { open class Mai2UserEntity : BaseEntity(), IUserEntity<Mai2UserDetail> {
@JsonIgnore @JsonIgnore
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
open var user: Mai2UserDetail = Mai2UserDetail() override var user: Mai2UserDetail = Mai2UserDetail()
} }

View File

@ -3,7 +3,7 @@ package icu.samnyan.aqua.sega.ongeki.model.userdata;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import icu.samnyan.aqua.net.games.IGenericUserData; import icu.samnyan.aqua.net.games.IUserData;
import icu.samnyan.aqua.sega.general.model.Card; import icu.samnyan.aqua.sega.general.model.Card;
import icu.samnyan.aqua.sega.util.jackson.AccessCodeSerializer; import icu.samnyan.aqua.sega.util.jackson.AccessCodeSerializer;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -21,7 +21,7 @@ import java.io.Serializable;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class UserData implements Serializable, IGenericUserData { public class UserData implements Serializable, IUserData {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -5,7 +5,7 @@ import ext.ls
import ext.sec import ext.sec
import ext.toDate import ext.toDate
import icu.samnyan.aqua.net.games.BaseEntity import icu.samnyan.aqua.net.games.BaseEntity
import icu.samnyan.aqua.net.games.IGenericUserData import icu.samnyan.aqua.net.games.IUserData
import icu.samnyan.aqua.sega.general.IntegerListConverter import icu.samnyan.aqua.sega.general.IntegerListConverter
import icu.samnyan.aqua.sega.general.model.Card import icu.samnyan.aqua.sega.general.model.Card
import jakarta.persistence.* import jakarta.persistence.*
@ -15,7 +15,7 @@ import java.util.*
* General user information * General user information
*/ */
@Entity @Table(name = "wacca_user") @Entity @Table(name = "wacca_user")
class WaccaUser : BaseEntity(), IGenericUserData { class WaccaUser : BaseEntity(), IUserData {
@OneToOne @OneToOne
@JoinColumn(name = "aime_card_id", unique = true) @JoinColumn(name = "aime_card_id", unique = true)
override var card: Card? = Card() override var card: Card? = Card()