mirror of
https://github.com/MewoLab/AquaDX.git
synced 2025-10-25 20:12:39 +00:00
[F] Data import fix (#153)
This commit is contained in:
parent
d79a4e5499
commit
e3486042a5
@ -8,6 +8,8 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
|||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonNamingStrategy
|
import kotlinx.serialization.json.JsonNamingStrategy
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
// Jackson
|
// Jackson
|
||||||
val ACCEPTABLE_FALSE = setOf("0", "false", "no", "off", "False", "None", "null")
|
val ACCEPTABLE_FALSE = setOf("0", "false", "no", "off", "False", "None", "null")
|
||||||
@ -21,7 +23,13 @@ val JSON_FUZZY_BOOLEAN = SimpleModule().addDeserializer(Boolean::class.java, obj
|
|||||||
})
|
})
|
||||||
val JSON_DATETIME = SimpleModule().addDeserializer(java.time.LocalDateTime::class.java, object : JsonDeserializer<java.time.LocalDateTime>() {
|
val JSON_DATETIME = SimpleModule().addDeserializer(java.time.LocalDateTime::class.java, object : JsonDeserializer<java.time.LocalDateTime>() {
|
||||||
override fun deserialize(parser: JsonParser, context: DeserializationContext) =
|
override fun deserialize(parser: JsonParser, context: DeserializationContext) =
|
||||||
parser.text.asDateTime() ?: (400 - "Invalid date time value ${parser.text}")
|
// First try standard formats via asDateTime() method
|
||||||
|
parser.text.asDateTime() ?: try {
|
||||||
|
// Try maimai2 format (yyyy-MM-dd HH:mm:ss.0)
|
||||||
|
LocalDateTime.parse(parser.text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.0"))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
400 - "Invalid date time value ${parser.text}"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
val JACKSON = jacksonObjectMapper().apply {
|
val JACKSON = jacksonObjectMapper().apply {
|
||||||
setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||||
@ -73,4 +81,4 @@ val JSON = Json {
|
|||||||
// fun objectMapper(): ObjectMapper {
|
// fun objectMapper(): ObjectMapper {
|
||||||
// return JACKSON
|
// return JACKSON
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import org.springframework.transaction.support.TransactionTemplate
|
|||||||
import icu.samnyan.aqua.sega.maimai2.model.Mai2UserDataRepo
|
import icu.samnyan.aqua.sega.maimai2.model.Mai2UserDataRepo
|
||||||
import icu.samnyan.aqua.net.games.GenericUserDataRepo
|
import icu.samnyan.aqua.net.games.GenericUserDataRepo
|
||||||
import icu.samnyan.aqua.net.games.IUserData
|
import icu.samnyan.aqua.net.games.IUserData
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConfigurationProperties(prefix = "aqua-net.fedy")
|
@ConfigurationProperties(prefix = "aqua-net.fedy")
|
||||||
@ -43,7 +44,6 @@ enum class FedyEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@ConditionalOnProperty("aqua-net.fedy.enabled", havingValue = "true")
|
|
||||||
@API("/api/v2/fedy")
|
@API("/api/v2/fedy")
|
||||||
class Fedy(
|
class Fedy(
|
||||||
val jwt: JWT,
|
val jwt: JWT,
|
||||||
@ -59,6 +59,7 @@ class Fedy(
|
|||||||
val transaction by lazy { TransactionTemplate(transactionManager) }
|
val transaction by lazy { TransactionTemplate(transactionManager) }
|
||||||
|
|
||||||
private fun Str.checkKey() {
|
private fun Str.checkKey() {
|
||||||
|
if (!props.enabled) 403 - "Fedy is disabled"
|
||||||
if (!MessageDigest.isEqual(this.toByteArray(), props.key.toByteArray())) 403 - "Invalid Key"
|
if (!MessageDigest.isEqual(this.toByteArray(), props.key.toByteArray())) 403 - "Invalid Key"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ class Fedy(
|
|||||||
val userFedy = AquaNetUserFedy(aquaNetUser = user)
|
val userFedy = AquaNetUserFedy(aquaNetUser = user)
|
||||||
userFedyRepo.save(userFedy)
|
userFedyRepo.save(userFedy)
|
||||||
|
|
||||||
notifyRemote(FedyEvent.Linked, mapOf("auId" to user.auId, "nonce" to nonce))
|
notify(FedyEvent.Linked, mapOf("auId" to user.auId, "nonce" to nonce))
|
||||||
return mapOf("linkedAt" to userFedy.createdAt.toEpochMilli())
|
return mapOf("linkedAt" to userFedy.createdAt.toEpochMilli())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ class Fedy(
|
|||||||
val userFedy = userFedyRepo.findByAquaNetUserAuId(user.auId) ?: 412 - "User not linked"
|
val userFedy = userFedyRepo.findByAquaNetUserAuId(user.auId) ?: 412 - "User not linked"
|
||||||
userFedyRepo.delete(userFedy)
|
userFedyRepo.delete(userFedy)
|
||||||
|
|
||||||
notifyRemote(FedyEvent.Unlinked, mapOf("auId" to user.auId))
|
notify(FedyEvent.Unlinked, mapOf("auId" to user.auId))
|
||||||
return SUCCESS
|
return SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,10 +141,10 @@ class Fedy(
|
|||||||
transaction.execute { when (req.game) {
|
transaction.execute { when (req.game) {
|
||||||
"mai2" -> {
|
"mai2" -> {
|
||||||
if (req.removeOldData) { removeOldData(mai2UserDataRepo) }
|
if (req.removeOldData) { removeOldData(mai2UserDataRepo) }
|
||||||
|
val userAll = req.data["upsertUserAll"] as JDict // UserAll first, prevent using backlog
|
||||||
|
mai2UpsertUserAll.handle(mapOf("userId" to extId, "upsertUserAll" to userAll))
|
||||||
val playlogs = req.data["userPlaylogList"] as List<JDict>
|
val playlogs = req.data["userPlaylogList"] as List<JDict>
|
||||||
playlogs.forEach { mai2UploadUserPlaylog.handle(mapOf("userId" to extId, "userPlaylog" to it)) }
|
playlogs.forEach { mai2UploadUserPlaylog.handle(mapOf("userId" to extId, "userPlaylog" to it)) }
|
||||||
val userAll = req.data["upsertUserAll"] as JDict
|
|
||||||
mai2UpsertUserAll.handle(mapOf("userId" to extId, "upsertUserAll" to userAll))
|
|
||||||
}
|
}
|
||||||
else -> 406 - "Unsupported game"
|
else -> 406 - "Unsupported game"
|
||||||
} }
|
} }
|
||||||
@ -151,19 +152,19 @@ class Fedy(
|
|||||||
return SUCCESS
|
return SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onUpserted(game: Str, maybeExtId: Any?) = notifyRemote(FedyEvent.Upserted, game, maybeExtId)
|
fun onUpserted(game: Str, maybeExtId: Any?) = maybeNotifyAsync(FedyEvent.Upserted, game, maybeExtId)
|
||||||
fun onImported(game: Str, maybeExtId: Any?) = notifyRemote(FedyEvent.Imported, game, maybeExtId)
|
fun onImported(game: Str, maybeExtId: Any?) = maybeNotifyAsync(FedyEvent.Imported, game, maybeExtId)
|
||||||
|
|
||||||
private fun notifyRemote(event: FedyEvent, game: Str, maybeExtId: Any?) { try {
|
private fun maybeNotifyAsync(event: FedyEvent, game: Str, maybeExtId: Any?) = if (!props.enabled) {} else CompletableFuture.runAsync { try {
|
||||||
val extId = maybeExtId?.long ?: return
|
val extId = maybeExtId?.long ?: return@runAsync
|
||||||
val user = userRepo.findByGhostCardExtId(extId) ?: return
|
val user = userRepo.findByGhostCardExtId(extId) ?: return@runAsync
|
||||||
val userFedy = userFedyRepo.findByAquaNetUserAuId(user.auId) ?: return
|
val userFedy = userFedyRepo.findByAquaNetUserAuId(user.auId) ?: return@runAsync
|
||||||
notifyRemote(event, mapOf("auId" to user.auId, "game" to game))
|
notify(event, mapOf("auId" to user.auId, "game" to game))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error("Error handling Fedy on notifyRemote($event, $game, $maybeExtId)", e)
|
log.error("Error handling Fedy on maybeNotifyAsync($event, $game, $maybeExtId)", e)
|
||||||
} }
|
} }
|
||||||
|
|
||||||
private fun notifyRemote(event: FedyEvent, body: Any?) {
|
private fun notify(event: FedyEvent, body: Any?) {
|
||||||
val MAX_RETRY = 3
|
val MAX_RETRY = 3
|
||||||
val body = body?.toJson() ?: "{}"
|
val body = body?.toJson() ?: "{}"
|
||||||
var retry = 0
|
var retry = 0
|
||||||
|
|||||||
@ -70,7 +70,7 @@ abstract class ImportController<ExportModel: IExportClass<UserModel>, UserModel:
|
|||||||
@Autowired lateinit var netProps: AquaNetProps
|
@Autowired lateinit var netProps: AquaNetProps
|
||||||
@Autowired lateinit var transManager: PlatformTransactionManager
|
@Autowired lateinit var transManager: PlatformTransactionManager
|
||||||
val trans by lazy { TransactionTemplate(transManager) }
|
val trans by lazy { TransactionTemplate(transManager) }
|
||||||
@Autowired(required = false) @Lazy var fedy: Fedy? = null
|
@Autowired @Lazy lateinit var fedy: Fedy
|
||||||
|
|
||||||
init {
|
init {
|
||||||
artemisRenames.values.forEach {
|
artemisRenames.values.forEach {
|
||||||
@ -147,7 +147,7 @@ abstract class ImportController<ExportModel: IExportClass<UserModel>, UserModel:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Fedy.getGameName(game)?.let { fedy?.onImported(it, u.ghostCard.extId) }
|
Fedy.getGameName(game)?.let { fedy.onImported(it, u.ghostCard.extId) }
|
||||||
|
|
||||||
SUCCESS
|
SUCCESS
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import kotlin.reflect.full.declaredMemberProperties
|
|||||||
import icu.samnyan.aqua.net.Fedy
|
import icu.samnyan.aqua.net.Fedy
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.context.annotation.Lazy
|
import org.springframework.context.annotation.Lazy
|
||||||
|
import org.springframework.beans.factory.ObjectProvider
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
* @author samnyan (privateamusement@protonmail.com)
|
||||||
@ -40,7 +41,7 @@ class Maimai2ServletController(
|
|||||||
val net: Maimai2,
|
val net: Maimai2,
|
||||||
): MeowApi(serialize = { _, resp -> if (resp is String) resp else resp.toJson() }) {
|
): MeowApi(serialize = { _, resp -> if (resp is String) resp else resp.toJson() }) {
|
||||||
|
|
||||||
@Autowired(required = false) @Lazy var fedy: Fedy? = null
|
@Autowired @Lazy lateinit var fedy: Fedy
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = logger()
|
private val log = logger()
|
||||||
@ -94,9 +95,7 @@ class Maimai2ServletController(
|
|||||||
val ctx = RequestContext(req, data.mut)
|
val ctx = RequestContext(req, data.mut)
|
||||||
serialize(api, handlers[api]!!(ctx) ?: noop).also {
|
serialize(api, handlers[api]!!(ctx) ?: noop).also {
|
||||||
log.info("$token : $api > ${it.truncate(500)}")
|
log.info("$token : $api > ${it.truncate(500)}")
|
||||||
if (api == "UpsertUserAllApi") {
|
if (api == "UpsertUserAllApi") { fedy.onUpserted("mai2", data["userId"]) }
|
||||||
fedy?.onUpserted("mai2", data["userId"])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user