From 1d4bb9b5343d22d124b843363fec575617c6118d Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Thu, 1 May 2025 12:52:47 -0400 Subject: [PATCH] [+] Minato migration --- src/main/java/ext/Ext.kt | 6 +++-- src/main/java/icu/samnyan/aqua/net/Bot.kt | 20 ++++++++++++++++ .../icu/samnyan/aqua/net/CardController.kt | 3 +-- .../icu/samnyan/aqua/sega/aimedb/AimeDB.kt | 18 ++++++++++----- .../samnyan/aqua/sega/general/model/Card.kt | 23 +++++++++++++++++++ .../aqua/sega/general/service/CardService.kt | 10 -------- .../resources/db/80/V1000_47__net_minato.sql | 1 + 7 files changed, 61 insertions(+), 20 deletions(-) create mode 100644 src/main/resources/db/80/V1000_47__net_minato.sql diff --git a/src/main/java/ext/Ext.kt b/src/main/java/ext/Ext.kt index 9f6e1ca2..3f34367d 100644 --- a/src/main/java/ext/Ext.kt +++ b/src/main/java/ext/Ext.kt @@ -27,6 +27,7 @@ import java.security.MessageDigest import java.time.LocalDate import java.time.LocalDateTime import java.time.ZoneId +import java.time.ZoneOffset.UTC import java.time.format.DateTimeFormatter import java.util.* import java.util.concurrent.locks.Lock @@ -129,11 +130,12 @@ inline fun resJson(name: Str, warn: Boolean = true) = resStr(name)?. val JST_ZONE = ZoneId.of("Asia/Tokyo") fun jstNow() = LocalDateTime.now(JST_ZONE) fun millis() = System.currentTimeMillis() +fun utcNow() = LocalDateTime.now(UTC) val DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd") fun LocalDate.isoDate() = format(DATE_FORMAT) fun String.isoDate() = DATE_FORMAT.parse(this, LocalDate::from) -fun Date.utc() = toInstant().atZone(java.time.ZoneOffset.UTC).toLocalDate() -fun LocalDate.toDate() = Date(atStartOfDay().toInstant(java.time.ZoneOffset.UTC).toEpochMilli()) +fun Date.utc() = toInstant().atZone(UTC).toLocalDate() +fun LocalDate.toDate() = Date(atStartOfDay().toInstant(UTC).toEpochMilli()) fun LocalDateTime.isoDateTime() = format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) fun String.isoDateTime() = LocalDateTime.parse(this, DateTimeFormatter.ISO_LOCAL_DATE_TIME) val URL_SAFE_DT = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss") diff --git a/src/main/java/icu/samnyan/aqua/net/Bot.kt b/src/main/java/icu/samnyan/aqua/net/Bot.kt index 07f451bb..21088b1e 100644 --- a/src/main/java/icu/samnyan/aqua/net/Bot.kt +++ b/src/main/java/icu/samnyan/aqua/net/Bot.kt @@ -4,6 +4,7 @@ import ext.* import icu.samnyan.aqua.net.db.AquaUserServices import icu.samnyan.aqua.net.utils.SUCCESS import icu.samnyan.aqua.sega.chusan.model.Chu3Repos +import icu.samnyan.aqua.sega.general.model.CardStatus import icu.samnyan.aqua.sega.general.model.sensitiveInfo import icu.samnyan.aqua.sega.maimai2.model.Mai2Repos import jakarta.transaction.Transactional @@ -18,6 +19,10 @@ import org.springframework.web.bind.annotation.RestController class BotProps { var enabled: Boolean = false var secret: String = "" + + companion object { + const val MINATO_CARD_EXT: Int = Int.MAX_VALUE - 2; + } } @RestController @@ -46,6 +51,21 @@ class BotController( } } + @API("/migrated-to-minato") + fun migratedToMinato(@RP secret: Str, @RP card: Str): Any { + secret.checkSecret() + + // 1. Find user card + val oc = us.cardRepo.findByLuid(card)() ?: (404 - "Card not found") + + // 2. Change the status to migrated + us.cardRepo.save(oc.apply { + status = CardStatus.MIGRATED_TO_MINATO + accessTime = utcNow() + }) + return SUCCESS + } + @Transactional @PostMapping("/debug-user-profile") @Doc("Obtain debug information for a user card", "User card details") diff --git a/src/main/java/icu/samnyan/aqua/net/CardController.kt b/src/main/java/icu/samnyan/aqua/net/CardController.kt index e2a760ab..68c1de10 100644 --- a/src/main/java/icu/samnyan/aqua/net/CardController.kt +++ b/src/main/java/icu/samnyan/aqua/net/CardController.kt @@ -19,7 +19,6 @@ import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service import org.springframework.web.bind.annotation.RestController import java.time.LocalDateTime -import java.time.ZoneOffset import kotlin.jvm.optionals.getOrNull import kotlin.random.Random @@ -145,7 +144,7 @@ suspend fun migrateCard(repo: GenericUserDataRepo, cardRepo: // Create a new dummy card for deleted data it.card = async { cardRepo.save(Card().apply { - luid = "Migrated data of ghost card ${ghost.id} for user ${card.aquaUser!!.auId} on ${LocalDateTime.now(ZoneOffset.UTC).isoDateTime()}" + luid = "Migrated data of ghost card ${ghost.id} for user ${card.aquaUser!!.auId} on ${utcNow().isoDateTime()}" // Randomize an extId outside the normal range extId = Random.nextLong(0x7FFFFFF7L shl 32, 0x7FFFFFFFL shl 32) registerTime = LocalDateTime.now() diff --git a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDB.kt b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDB.kt index 887138a2..1cdde4f3 100644 --- a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDB.kt +++ b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDB.kt @@ -1,10 +1,11 @@ package icu.samnyan.aqua.sega.aimedb -import ext.logger -import ext.toHex +import ext.* +import icu.samnyan.aqua.net.BotProps import icu.samnyan.aqua.net.db.AquaUserServices import icu.samnyan.aqua.sega.allnet.AllNetProps import icu.samnyan.aqua.sega.general.model.Card +import icu.samnyan.aqua.sega.general.model.CardStatus import icu.samnyan.aqua.sega.general.service.CardService import io.netty.buffer.ByteBuf import io.netty.buffer.ByteBufUtil @@ -124,11 +125,16 @@ class AimeDB( } } - fun getCard(accessCode: String) = cardService.getCardByAccessCode(accessCode).getOrNull()?.let { card -> + fun getCard(accessCode: String) = us.cardRepo.findByLuid(accessCode)()?.let { card -> + // If it's migrated to Minato, return the Minato card for 24 hours + if (card.status == CardStatus.MIGRATED_TO_MINATO && card.accessTime.plusDays(1).isAfter(utcNow())) + return BotProps.MINATO_CARD_EXT.long + // Update card access time - cardService.cardRepo.save(card.apply { accessTime = LocalDateTime.now() }).let { - it.aquaUser?.ghostCard ?: it - }?.extId + us.cardRepo.save(card.apply { accessTime = LocalDateTime.now() }) + + // If it's a ghost card, return the ghost card. Otherwise, return the original card + (card.aquaUser?.ghostCard ?: card).extId } ?: -1 /** diff --git a/src/main/java/icu/samnyan/aqua/sega/general/model/Card.kt b/src/main/java/icu/samnyan/aqua/sega/general/model/Card.kt index 454b1389..303fe445 100644 --- a/src/main/java/icu/samnyan/aqua/sega/general/model/Card.kt +++ b/src/main/java/icu/samnyan/aqua/sega/general/model/Card.kt @@ -5,6 +5,26 @@ import icu.samnyan.aqua.net.db.AquaNetUser import jakarta.persistence.* import java.time.LocalDateTime +enum class CardStatus { + NORMAL, + + // Reserved for future use + NORMAL_RESERVED_1, + NORMAL_RESERVED_2, + NORMAL_RESERVED_3, + NORMAL_RESERVED_4, + NORMAL_RESERVED_5, + NORMAL_RESERVED_6, + NORMAL_RESERVED_7, + NORMAL_RESERVED_8, + NORMAL_RESERVED_9, + + // Deleted statuses + OVERWRITTEN, + DELETED, + MIGRATED_TO_MINATO, +} + /** * @author samnyan (privateamusement@protonmail.com) */ @@ -44,6 +64,9 @@ class Card( // Unfortunately some people decide to cheat and upload all perfect scores :( // This will not affect gameplay behavior, but will hide the user from ranking var rankingBanned: Boolean = false, + + @Enumerated(EnumType.ORDINAL) + var status: CardStatus = CardStatus.NORMAL, ) { @Suppress("unused") // Used by serialization val isLinked get() = aquaUser != null diff --git a/src/main/java/icu/samnyan/aqua/sega/general/service/CardService.kt b/src/main/java/icu/samnyan/aqua/sega/general/service/CardService.kt index ad44336f..7845fd18 100644 --- a/src/main/java/icu/samnyan/aqua/sega/general/service/CardService.kt +++ b/src/main/java/icu/samnyan/aqua/sega/general/service/CardService.kt @@ -31,16 +31,6 @@ class CardService(val cardRepo: CardRepository) */ fun getCardByExtId(extId: Long?): Optional = cardRepo.findByExtId(extId) - /** - * Find a card by its access code - * - * @param accessCode String represent of an access code - * @return Optional of a Card - */ - fun getCardByAccessCode(accessCode: String?): Optional = Optional.ofNullable( - cardRepo.findByLuid(accessCode).getOrNull() - ) - /** * Register a new card with access code * @param accessCode String represent of an access code diff --git a/src/main/resources/db/80/V1000_47__net_minato.sql b/src/main/resources/db/80/V1000_47__net_minato.sql new file mode 100644 index 00000000..d81b496b --- /dev/null +++ b/src/main/resources/db/80/V1000_47__net_minato.sql @@ -0,0 +1 @@ +alter table sega_card add status SMALLINT default 0 not null;