From fa1ed52c3291685ad74a79e8b99e7671c8fc6daf Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:06:46 -0500 Subject: [PATCH] [+] Bind card --- .../icu/samnyan/aqua/net/CardController.kt | 71 ++++++++++++++++--- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/src/main/java/icu/samnyan/aqua/net/CardController.kt b/src/main/java/icu/samnyan/aqua/net/CardController.kt index 19504bf9..55bfc516 100644 --- a/src/main/java/icu/samnyan/aqua/net/CardController.kt +++ b/src/main/java/icu/samnyan/aqua/net/CardController.kt @@ -1,15 +1,14 @@ package icu.samnyan.aqua.net -import ext.RP -import ext.Str -import ext.async -import ext.minus +import ext.* import icu.samnyan.aqua.net.components.JWT +import icu.samnyan.aqua.net.db.AquaNetUser import icu.samnyan.aqua.net.db.AquaNetUserRepo +import icu.samnyan.aqua.net.utils.SUCCESS +import icu.samnyan.aqua.sega.general.dao.CardRepository import icu.samnyan.aqua.sega.general.model.Card import icu.samnyan.aqua.sega.general.service.CardService import org.springframework.stereotype.Service -import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController import kotlin.jvm.optionals.getOrNull @@ -19,7 +18,8 @@ class CardController( val userRepo: AquaNetUserRepo, val jwt: JWT, val cardService: CardService, - val cardSummary: CardSummary, + val cardGameService: CardGameService, + val cardRepository: CardRepository, ) { @API("/summary") suspend fun summary(@RP cardId: Str): Any @@ -28,17 +28,42 @@ class CardController( // Lookup data for each game return mapOf( - "id" to card.extId, "accessCode" to card.luid, "registerTime" to card.registerTime, "accessTime" to card.accessTime, - "summary" to cardSummary.getSummary(card), + "summary" to cardGameService.getSummary(card), ) } + + /** + * Bind a card to the user. This action will migrate selected data from the card to the user's ghost card. + * + * Non-migrated data will not be lost, but will be inaccessible from the card until the card is unbound. + * + * @param token JWT token + * @param cardId Card ID + * @param migrate Things to migrate, stored as a comma-separated list of game IDs (e.g. "maimai2,chusan") + */ + @API("/bind") + suspend fun bind(@RP token: Str, @RP cardId: Str, @RP migrate: Str) = jwt.auth(token) { u -> + // Check if the card is already bound + val card = cardService.tryLookup(cardId) ?: (404 - "Card not found") + if (card.aquaUser != null) 400 - "Card already bound to another user (@${card.aquaUser?.username})" + + // Bind the card + card.aquaUser = u + async { cardRepository.save(card) } + + // Migrate selected data to the new user + val games = migrate.split(',') + cardGameService.migrate(card, games) + + SUCCESS + } } @Service -class CardSummary( +class CardGameService( val maimai: icu.samnyan.aqua.sega.maimai.dao.userdata.UserDataRepository, val maimai2: icu.samnyan.aqua.sega.maimai2.dao.userdata.UserDataRepository, val chusan: icu.samnyan.aqua.sega.chusan.dao.userdata.UserDataRepository, @@ -46,6 +71,34 @@ class CardSummary( val ongeki: icu.samnyan.aqua.sega.ongeki.dao.userdata.UserDataRepository, val diva: icu.samnyan.aqua.sega.diva.dao.userdata.PlayerProfileRepository, ) { + suspend fun migrate(card: Card, games: List) = async { + // Migrate data from the card to the user's ghost card + // An easy migration is to change the UserData card field to the user's ghost card + games.forEach { game -> + when (game) { + "maimai" -> maimai.findByCard_ExtId(card.extId).getOrNull()?.let { + it.card = card.aquaUser!!.ghostCard + } + "maimai2" -> maimai2.findByCard_ExtId(card.extId).getOrNull()?.let { + it.card = card.aquaUser!!.ghostCard + } + "chusan" -> chusan.findByCard_ExtId(card.extId).getOrNull()?.let { + it.card = card.aquaUser!!.ghostCard + } + "chunithm" -> chunithm.findByCard_ExtId(card.extId).getOrNull()?.let { + it.card = card.aquaUser!!.ghostCard + } + "ongeki" -> ongeki.findByCard_ExtId(card.extId).getOrNull()?.let { + it.card = card.aquaUser!!.ghostCard + } + // TODO: diva +// "diva" -> diva.findByPdId(card.extId.toInt()).getOrNull()?.let { +// it.pdId = card.aquaUser!!.ghostCard +// } + } + } + } + suspend fun getSummary(card: Card) = async { mapOf( "maimai" to maimai.findByCard_ExtId(card.extId).getOrNull()?.let { mapOf(