[+] Maimai export

This commit is contained in:
Azalea
2024-03-17 00:12:02 -04:00
parent 0f1d6c0984
commit 25f5f6e1f7
6 changed files with 123 additions and 31 deletions

View File

@@ -5,6 +5,8 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
/**
@@ -14,24 +16,22 @@ import java.util.List;
@AllArgsConstructor
@NoArgsConstructor
public class Maimai2DataExport {
private String gameId = "SDEZ";
private UserDetail userData;
private UserExtend userExtend;
private UserOption userOption;
private List<MapEncountNpc> mapEncountNpcList;
private List<UserAct> userActList;
private List<UserCharacter> userCharacterList;
private List<UserCharge> userChargeList;
private List<UserCourse> userCourseList;
private List<UserFavorite> userFavoriteList;
private List<UserFriendSeasonRanking> userFriendSeasonRankingList;
private List<UserGeneralData> userGeneralDataList;
private List<UserGhost> userGhostList;
private List<UserItem> userItemList;
private List<UserLoginBonus> userLoginBonusList;
private List<UserMap> userMapList;
private List<UserMusicDetail> userMusicDetailList;
private List<UserPlaylog> userPlaylogList;
private List<UserRate> userRateList;
private UserUdemae userUdemae;
public String gameId = "SDEZ";
public UserDetail userData;
public UserExtend userExtend;
public UserOption userOption;
public List<MapEncountNpc> mapEncountNpcList;
public List<UserAct> userActList;
public List<UserCharacter> userCharacterList;
public List<UserCharge> userChargeList;
public List<UserCourse> userCourseList;
public List<UserFavorite> userFavoriteList;
public List<UserFriendSeasonRanking> userFriendSeasonRankingList;
public List<UserGeneralData> userGeneralDataList;
public List<UserItem> userItemList;
public List<UserLoginBonus> userLoginBonusList;
public List<UserMap> userMapList;
public List<UserMusicDetail> userMusicDetailList;
public List<UserPlaylog> userPlaylogList;
public UserUdemae userUdemae;
}

View File

@@ -2,6 +2,7 @@ package icu.samnyan.aqua.net.db
import com.fasterxml.jackson.annotation.JsonIgnore
import ext.*
import icu.samnyan.aqua.net.components.JWT
import icu.samnyan.aqua.sega.allnet.AllNetProps
import icu.samnyan.aqua.sega.allnet.KeyChipRepo
import icu.samnyan.aqua.sega.allnet.KeychipSession
@@ -112,7 +113,8 @@ class AquaUserServices(
val cardRepo: CardRepository,
val hasher: PasswordEncoder,
val keyChipRepo: KeyChipRepo,
val allNetProps: AllNetProps
val allNetProps: AllNetProps,
val jwt: JWT
) {
companion object {
val SETTING_FIELDS = AquaUserServices::class.functions

View File

@@ -3,13 +3,17 @@ package icu.samnyan.aqua.net.games
import ext.API
import ext.RP
import ext.Str
import ext.minus
import icu.samnyan.aqua.api.model.resp.sega.maimai2.external.Maimai2DataExport
import icu.samnyan.aqua.net.db.AquaUserServices
import icu.samnyan.aqua.net.utils.*
import icu.samnyan.aqua.sega.maimai2.model.*
import icu.samnyan.aqua.sega.maimai2.model.Mai2UserDataRepo
import icu.samnyan.aqua.sega.maimai2.model.Mai2UserGeneralDataRepo
import icu.samnyan.aqua.sega.maimai2.model.Mai2UserPlaylogRepo
import org.springframework.web.bind.annotation.RestController
import java.lang.reflect.Field
import java.util.*
import kotlin.reflect.full.declaredMembers
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.jvm.jvmErasure
@RestController
@API("api/v2/game/mai2")
@@ -17,7 +21,8 @@ class Maimai2(
override val us: AquaUserServices,
override val playlogRepo: Mai2UserPlaylogRepo,
override val userDataRepo: Mai2UserDataRepo,
val userGeneralDataRepository: Mai2UserGeneralDataRepo
val userGeneralDataRepository: Mai2UserGeneralDataRepo,
val repos: Mai2Repos
): GameApiController("mai2")
{
override suspend fun trend(@RP username: Str): List<TrendOut> = us.cardByName(username) { card ->
@@ -39,4 +44,27 @@ class Maimai2(
genericUserSummary(card, ratingComposition)
}
// Use reflection to get all properties in Mai2Repos with matching names in Maimai2DataExport
var exportFields: Map<Field, UserLinked<*>> = listOf(*Maimai2DataExport::class.java.declaredFields)
.filter { it.name !in arrayOf("gameId", "userData") }
.associateWith { Mai2Repos::class.declaredMembers
.filter { f -> f.returnType.jvmErasure.isSubclassOf(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}")
}
@API("export")
fun exportAllUserData(@RP token: Str) = us.jwt.auth(token) { u ->
try {
Maimai2DataExport().apply {
gameId = "SDEZ"
userData = repos.userData.findByCard(u.ghostCard) ?: (404 - "User not found")
exportFields.forEach { (f, u) ->
f.set(this, if (f.type == List::class.java) u.findByUser(userData)
else u.findSingleByUser(userData).orElse(null))
}
}
} catch (e: Exception) { 500 - "Error during data export. Reason: ${e.message}" }
}
}

View File

@@ -11,6 +11,7 @@ import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.NoRepositoryBean
import org.springframework.stereotype.Component
import java.util.*
@@ -154,4 +155,37 @@ interface Chu3GameNamePlateRepo : JpaRepository<NamePlate, Long>
interface Chu3GameSystemVoiceRepo : JpaRepository<SystemVoice, Long>
interface Chu3GameTrophyRepo : JpaRepository<Trophy, Long>
interface Chu3GameTrophyRepo : JpaRepository<Trophy, Long>
@Component
class Chu3Repos(
val userLoginBonus: Chu3UserLoginBonusRepo,
val userActivity: Chu3UserActivityRepo,
val userCardPrintState: Chu3UserCardPrintStateRepo,
val userCharacter: Chu3UserCharacterRepo,
val userCharge: Chu3UserChargeRepo,
val userCourse: Chu3UserCourseRepo,
val userData: Chu3UserDataRepo,
val userDuel: Chu3UserDuelRepo,
val userGacha: Chu3UserGachaRepo,
val userGameOption: Chu3UserGameOptionRepo,
val userGeneralData: Chu3UserGeneralDataRepo,
val userItem: Chu3UserItemRepo,
val userMapArea: Chu3UserMapAreaRepo,
val userMusicDetail: Chu3UserMusicDetailRepo,
val userPlaylog: Chu3UserPlaylogRepo,
val gameAvatarAcc: Chu3GameAvatarAccRepo,
val gameCharacter: Chu3GameCharacterRepo,
val gameCharge: Chu3GameChargeRepo,
val gameEvent: Chu3GameEventRepo,
val gameFrame: Chu3GameFrameRepo,
val gameGachaCard: Chu3GameGachaCardRepo,
val gameGacha: Chu3GameGachaRepo,
val gameLoginBonusPresets: Chu3GameLoginBonusPresetsRepo,
val gameLoginBonus: Chu3GameLoginBonusRepo,
val gameMapIcon: Chu3GameMapIconRepo,
val gameMusic: Chu3GameMusicRepo,
val gameNamePlate: Chu3GameNamePlateRepo,
val gameSystemVoice: Chu3GameSystemVoiceRepo,
val gameTrophy: Chu3GameTrophyRepo
)

View File

@@ -103,7 +103,7 @@ public class UpsertUserAllHandler implements BaseHandler {
if (userAll.getUserExtend() != null) {
UserExtend newUserExtend = userAll.getUserExtend().get(0);
Optional<UserExtend> userExtendOptional = userExtendRepository.findByUser(newUserData);
Optional<UserExtend> userExtendOptional = userExtendRepository.findSingleByUser(newUserData);
UserExtend userExtend = userExtendOptional.orElseGet(() -> new UserExtend(newUserData));
newUserExtend.setId(userExtend.getId());
@@ -116,7 +116,7 @@ public class UpsertUserAllHandler implements BaseHandler {
if (userAll.getUserOption() != null) {
UserOption newUserOption = userAll.getUserOption().get(0);
Optional<UserOption> userOptionOptional = userOptionRepository.findByUser(newUserData);
Optional<UserOption> userOptionOptional = userOptionRepository.findSingleByUser(newUserData);
UserOption userOption = userOptionOptional.orElseGet(() -> new UserOption(newUserData));
newUserOption.setId(userOption.getId());
@@ -185,7 +185,7 @@ public class UpsertUserAllHandler implements BaseHandler {
//Udemae
UserUdemae newUserUdemae = userRating.getUdemae();
Optional<UserUdemae> udemaeOptional = userUdemaeRepository.findByUser(newUserData);
Optional<UserUdemae> udemaeOptional = userUdemaeRepository.findSingleByUser(newUserData);
UserUdemae userUdemae = udemaeOptional.orElseGet(() -> new UserUdemae(newUserData));
newUserUdemae.setId(userUdemae.getId());

View File

@@ -13,12 +13,14 @@ import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.repository.NoRepositoryBean
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import java.util.*
@NoRepositoryBean
interface UserLinked<T>: JpaRepository<T, Long> {
fun findByUser(user: UserDetail): Optional<T>
fun findByUser(user: UserDetail): List<T>
fun findSingleByUser(user: UserDetail): Optional<T>
fun findByUser_Card_ExtId(userId: Long): List<T>
fun findByUser_Card_ExtId(userId: Long, page: Pageable): Page<T>
fun findSingleByUser_Card_ExtId(userId: Long): Optional<T>
@@ -109,4 +111,30 @@ interface Mai2GameEventRepo : JpaRepository<GameEvent, Int> {
fun findByTypeAndEnable(type: Int, enable: Boolean): List<GameEvent>
}
interface Mai2GameSellingCardRepo : JpaRepository<GameSellingCard, Long>
interface Mai2GameSellingCardRepo : JpaRepository<GameSellingCard, Long>
@Component
class Mai2Repos(
val mapEncountNpc: Mai2MapEncountNpcRepo,
val userAct: Mai2UserActRepo,
val userCard: Mai2UserCardRepo,
val userCharacter: Mai2UserCharacterRepo,
val userCharge: Mai2UserChargeRepo,
val userCourse: Mai2UserCourseRepo,
val userData: Mai2UserDataRepo,
val userExtend: Mai2UserExtendRepo,
val userFavorite: Mai2UserFavoriteRepo,
val userFriendSeasonRanking: Mai2UserFriendSeasonRankingRepo,
val userGeneralData: Mai2UserGeneralDataRepo,
val userItem: Mai2UserItemRepo,
val userLoginBonus: Mai2UserLoginBonusRepo,
val userMap: Mai2UserMapRepo,
val userMusicDetail: Mai2UserMusicDetailRepo,
val userOption: Mai2UserOptionRepo,
val userPlaylog: Mai2UserPlaylogRepo,
val userPrintDetail: Mai2UserPrintDetailRepo,
val userUdemae: Mai2UserUdemaeRepo,
val gameCharge: Mai2GameChargeRepo,
val gameEvent: Mai2GameEventRepo,
val gameSellingCard: Mai2GameSellingCardRepo
)