[+] Minato migration

This commit is contained in:
Azalea
2025-05-01 12:52:47 -04:00
parent 110a2144fa
commit 1d4bb9b534
7 changed files with 61 additions and 20 deletions

View File

@@ -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 <reified T> 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")

View File

@@ -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")

View File

@@ -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 <T : IUserData> migrateCard(repo: GenericUserDataRepo<T>, 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()

View File

@@ -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
/**

View File

@@ -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

View File

@@ -31,16 +31,6 @@ class CardService(val cardRepo: CardRepository)
*/
fun getCardByExtId(extId: Long?): Optional<Card> = 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<Card> = Optional.ofNullable(
cardRepo.findByLuid(accessCode).getOrNull()
)
/**
* Register a new card with access code
* @param accessCode String represent of an access code

View File

@@ -0,0 +1 @@
alter table sega_card add status SMALLINT default 0 not null;