pull/99/head^2
Azalea 2025-01-05 02:13:55 -05:00
parent 96fb815bd8
commit 56e424c29b
13 changed files with 31 additions and 24 deletions

View File

@ -190,7 +190,7 @@ val Any?.truthy get() = when (this) {
fun <T> ls(vararg args: T) = args.toList() fun <T> ls(vararg args: T) = args.toList()
inline fun <reified T> arr(vararg args: T) = arrayOf(*args) inline fun <reified T> arr(vararg args: T) = arrayOf(*args)
operator fun <K, V> Map<K, V>.plus(map: Map<K, V>) = operator fun <K, V> Map<K, V>.plus(map: Map<K, V>) =
(if (this is MutableMap) this else toMutableMap()).apply { putAll(map) } (if (this is MutableMap) this else mut).apply { putAll(map) }
operator fun <K, V> MutableMap<K, V>.plusAssign(map: Map<K, V>) { putAll(map) } operator fun <K, V> MutableMap<K, V>.plusAssign(map: Map<K, V>) { putAll(map) }
fun <K, V: Any> Map<K, V?>.vNotNull(): Map<K, V> = filterValues { it != null }.mapValues { it.value!! } fun <K, V: Any> Map<K, V?>.vNotNull(): Map<K, V> = filterValues { it != null }.mapValues { it.value!! }
fun <T> MutableList<T>.popAll(list: List<T>) = list.also { removeAll(it) } fun <T> MutableList<T>.popAll(list: List<T>) = list.also { removeAll(it) }
@ -201,6 +201,10 @@ fun <K, V: Any> Map<K, V?>.recursiveNotNull(): Map<K, V> = mapNotNull { (k, v) -
k to if (v is Map<*, *>) (v as Map<Any?, Any?>).recursiveNotNull() else v k to if (v is Map<*, *>) (v as Map<Any?, Any?>).recursiveNotNull() else v
}.toMap() as Map<K, V> }.toMap() as Map<K, V>
val <T> List<T>.mut get() = toMutableList()
val <K, V> Map<K, V>.mut get() = toMutableMap()
val <T> Set<T>.mut get() = toMutableSet()
// Optionals // Optionals
operator fun <T> Optional<T>.invoke(): T? = orElse(null) operator fun <T> Optional<T>.invoke(): T? = orElse(null)
fun <T> Optional<T>.expect(message: Str = "Value is not present") = orElseGet { (400 - message) } fun <T> Optional<T>.expect(message: Str = "Value is not present") = orElseGet { (400 - message) }

View File

@ -57,11 +57,11 @@ class BotController(
us.cardRepo.findByExtId(cardId.long)(), us.cardRepo.findByExtId(cardId.long)(),
us.cardRepo.findByLuid(cardId)(), us.cardRepo.findByLuid(cardId)(),
us.cardRepo.findById(cardId.long)(), us.cardRepo.findById(cardId.long)(),
).toMutableList() ).mut
cards += cards.flatMap { cards += cards.flatMap {
(it.aquaUser?.cards ?: emptyList()) + listOfNotNull(it.aquaUser?.ghostCard) (it.aquaUser?.cards ?: emptyList()) + listOfNotNull(it.aquaUser?.ghostCard)
} }
cards = cards.distinctBy { it.id }.toMutableList() cards = cards.distinctBy { it.id }.mut
return cards.map { card -> return cards.map { card ->
// Find all games played by this card // Find all games played by this card

View File

@ -1,6 +1,7 @@
package icu.samnyan.aqua.net package icu.samnyan.aqua.net
import ext.HTTP import ext.HTTP
import ext.mut
import ext.toJson import ext.toJson
import icu.samnyan.aqua.net.games.BaseEntity import icu.samnyan.aqua.net.games.BaseEntity
import io.ktor.client.call.* import io.ktor.client.call.*
@ -54,8 +55,8 @@ class AquaNetSafetyService(
*/ */
suspend fun isSafeBatch(rawContents: List<String>): List<Boolean> { suspend fun isSafeBatch(rawContents: List<String>): List<Boolean> {
val contents = rawContents.map { Normalizer.normalize(it, Normalizer.Form.NFKC) } val contents = rawContents.map { Normalizer.normalize(it, Normalizer.Form.NFKC) }
val origMap = safety.findAll().associateBy { it.content }.toMutableMap() val origMap = safety.findAll().associateBy { it.content }.mut
val map = safety.findAll().associateBy { it.content.lowercase().trim() }.toMutableMap() val map = safety.findAll().associateBy { it.content.lowercase().trim() }.mut
// Process unseen content with OpenAI // Process unseen content with OpenAI
val news = contents.filter { it.lowercase().trim() !in map && it !in contents }.map { inp -> val news = contents.filter { it.lowercase().trim() !in map && it !in contents }.map { inp ->

View File

@ -146,13 +146,13 @@ abstract class GameApiController<T : IUserData>(val name: String, userDataClass:
plays.forEach { play -> plays.forEach { play ->
val lvl = musicMapping[play.musicId]?.notes?.getOrNull(if (play.level == 10) 0 else play.level)?.lv ?: return@forEach val lvl = musicMapping[play.musicId]?.notes?.getOrNull(if (play.level == 10) 0 else play.level)?.lv ?: return@forEach
shownRanks.find { (s, _) -> play.achievement > s }?.let { (_, v) -> shownRanks.find { (s, _) -> play.achievement > s }?.let { (_, v) ->
val ranks = detailedRanks.getOrPut(lvl.toInt()) { rankMap.toMutableMap() } val ranks = detailedRanks.getOrPut(lvl.toInt()) { rankMap.mut }
ranks[v] = ranks[v]!! + 1 ranks[v] = ranks[v]!! + 1
} }
} }
// Collapse detailed ranks to get non-detailed ranks map<rank, count> // Collapse detailed ranks to get non-detailed ranks map<rank, count>
val ranks = shownRanks.associate { (_, v) -> v to 0 }.toMutableMap().also { ranks -> val ranks = shownRanks.associate { (_, v) -> v to 0 }.mut.also { ranks ->
plays.forEach { play -> plays.forEach { play ->
shownRanks.find { (s, _) -> play.achievement > s }?.let { (_, v) -> ranks[v] = ranks[v]!! + 1 } shownRanks.find { (s, _) -> play.achievement > s }?.let { (_, v) -> ranks[v] = ranks[v]!! + 1 }
} }

View File

@ -2,6 +2,7 @@ package icu.samnyan.aqua.net.games
import ext.isoDate import ext.isoDate
import ext.minus import ext.minus
import ext.mut
import java.time.LocalDate import java.time.LocalDate
const val LETTERS = "" + const val LETTERS = "" +
@ -60,7 +61,7 @@ fun findTrend(log: List<TrendLog>): List<TrendOut> {
val trend = d.distinctBy { it.date } val trend = d.distinctBy { it.date }
.map { TrendOut(it.date, maxRating[it.date] ?: 0, .map { TrendOut(it.date, maxRating[it.date] ?: 0,
playCounts[it.date] ?: 0) } playCounts[it.date] ?: 0) }
.sortedBy { it.date }.toMutableList() .sortedBy { it.date }.mut
// Fill in the missing dates (min date and current date) // Fill in the missing dates (min date and current date)
trend[0].let { if (it.date > minDate) trend.add(0, TrendOut(minDate, 0, 0)) } trend[0].let { if (it.date > minDate) trend.add(0, TrendOut(minDate, 0, 0)) }

View File

@ -127,7 +127,7 @@ class Maimai2(
user = repos.userData.findByCardExtId(myCard.extId).orElse(null) ?: (404 - "User not found") user = repos.userData.findByCardExtId(myCard.extId).orElse(null) ?: (404 - "User not found")
propertyKey = "favorite_rival" propertyKey = "favorite_rival"
} }
val myRivalList = myRival.propertyValue.split(',').filter { it.isNotEmpty() }.toMutableSet() val myRivalList = myRival.propertyValue.split(',').filter { it.isNotEmpty() }.mut
if (isAdd && myRivalList.size >= 4) { if (isAdd && myRivalList.size >= 4) {
(400 - "Rival list is full") (400 - "Rival list is full")

View File

@ -139,7 +139,7 @@ class AllNet(
val ver = reqMap["ver"] ?: "1.0" val ver = reqMap["ver"] ?: "1.0"
val formatVer = reqMap["format_ver"] ?: "" val formatVer = reqMap["format_ver"] ?: ""
val resp = props.map.toMutableMap() + mapOf( val resp = props.map.mut + mapOf(
"uri" to switchUri(localAddr, localPort, gameId, ver, session), "uri" to switchUri(localAddr, localPort, gameId, ver, session),
"host" to props.host.ifBlank { localAddr }, "host" to props.host.ifBlank { localAddr },
) )

View File

@ -91,7 +91,7 @@ fun ChusanController.chusanInit() {
data["nextIndex"] = rawIndex % 10000000000L data["nextIndex"] = rawIndex % 10000000000L
mapOf("itemKind" to kind) grabs { mapOf("itemKind" to kind) grabs {
// TODO: All unlock // TODO: All unlock
val items = db.userItem.findAllByUser_Card_ExtIdAndItemKind(uid, kind).toMutableList() val items = db.userItem.findAllByUser_Card_ExtIdAndItemKind(uid, kind).mut
// Check game options // Check game options
db.userData.findByCard_ExtId(uid)()?.card?.aquaUser?.gameOptions?.let { db.userData.findByCard_ExtId(uid)()?.card?.aquaUser?.gameOptions?.let {
@ -146,7 +146,7 @@ fun ChusanController.chusanInit() {
// Compatibility: Older chusan uses boolean for isSuccess // Compatibility: Older chusan uses boolean for isSuccess
fun checkAncient(d: List<UserMusicDetail>) = fun checkAncient(d: List<UserMusicDetail>) =
data["version"]?.double?.let { if (it >= 2.15) d else d.map { data["version"]?.double?.let { if (it >= 2.15) d else d.map {
d.toJson().jsonMap().toMutableMap().apply { this["isSuccess"] = this["isSuccess"].truthy } d.toJson().jsonMap().mut.apply { this["isSuccess"] = this["isSuccess"].truthy }
} } ?: d } } ?: d
db.userMusicDetail.findByUser_Card_ExtId(uid).groupBy { it.musicId } db.userMusicDetail.findByUser_Card_ExtId(uid).groupBy { it.musicId }

View File

@ -62,7 +62,7 @@ abstract class MeowApi(val serialize: (String, Any?) -> String) {
} }
else pageCache[cacheKey] = millis() to list else pageCache[cacheKey] = millis() to list
(mapOf("userId" to uid, "length" to lst.size, "nextIndex" to iAfter, key to lst) + add).toMutableMap() (mapOf("userId" to uid, "length" to lst.size, "nextIndex" to iAfter, key to lst) + add).mut
.also { p.post?.invoke(it) } .also { p.post?.invoke(it) }
} }
fun String.paged(key: String, fn: PagedHandler) = pagedWithKind(key) { PagedProcessor(null, fn) } fun String.paged(key: String, fn: PagedHandler) = pagedWithKind(key) { PagedProcessor(null, fn) }

View File

@ -1,11 +1,12 @@
package icu.samnyan.aqua.sega.general package icu.samnyan.aqua.sega.general
import ext.ls
import jakarta.persistence.AttributeConverter import jakarta.persistence.AttributeConverter
import jakarta.persistence.Converter import jakarta.persistence.Converter
@Converter @Converter
class IntegerListConverter : AttributeConverter<List<Int>, String> { class IntegerListConverter : AttributeConverter<List<Int>, String> {
override fun convertToDatabaseColumn(lst: List<Int>?) = lst?.joinToString(";") ?: "" override fun convertToDatabaseColumn(lst: List<Int>?) = lst?.joinToString(";") ?: ""
override fun convertToEntityAttribute(str: String?) = if (str.isNullOrBlank()) mutableListOf() else override fun convertToEntityAttribute(str: String?) = if (str.isNullOrBlank()) ls() else
str.split(';').map { it.toInt() }.toMutableList() str.split(';').map { it.toInt() }
} }

View File

@ -319,17 +319,17 @@ class Maimai2ServletController(
"GetUserScoreRankingApi", "UpsertClientBookkeepingApi", "UpsertClientSettingApi", "GetUserScoreRankingApi", "UpsertClientBookkeepingApi", "UpsertClientSettingApi",
"UpsertClientTestmodeApi", "UpsertClientUploadApi", "Ping", "RemoveTokenApi", "CMLoginApi", "CMLogoutApi", "UpsertClientTestmodeApi", "UpsertClientUploadApi", "Ping", "RemoveTokenApi", "CMLoginApi", "CMLogoutApi",
"CMUpsertBuyCardApi", "GetGameSettingApi", "GetGameKaleidxScopeApi", "GetGameMusicScoreApi", "CMUpsertBuyCardApi", "GetGameSettingApi", "GetGameKaleidxScopeApi", "GetGameMusicScoreApi",
"GetUserKaleidxScopeApi", "GetUserNewItemApi", "GetUserNewItemListApi").toMutableList() "GetUserKaleidxScopeApi", "GetUserNewItemApi", "GetUserNewItemListApi").mut
val noopEndpoint = endpointList.popAll("GetUserScoreRankingApi", "UpsertClientBookkeepingApi", val noopEndpoint = setOf("GetUserScoreRankingApi", "UpsertClientBookkeepingApi",
"UpsertClientSettingApi", "UpsertClientTestmodeApi", "UpsertClientUploadApi", "Ping", "RemoveTokenApi", "UpsertClientSettingApi", "UpsertClientTestmodeApi", "UpsertClientUploadApi", "Ping", "RemoveTokenApi",
"CMLoginApi", "CMLogoutApi", "CMUpsertBuyCardApi", "UserLogoutApi", "GetGameMapAreaConditionApi", "CMLoginApi", "CMLogoutApi", "CMUpsertBuyCardApi", "UserLogoutApi", "GetGameMapAreaConditionApi",
"UpsertUserChargelogApi") "UpsertUserChargelogApi").also { endpointList.removeAll(it) }
val staticEndpoint = mapOf( val staticEndpoint = mapOf(
"CreateTokenApi" to """{"Bearer":"meow"}""", "CreateTokenApi" to """{"Bearer":"meow"}""",
"CMUpsertUserPrintlogApi" to """{"returnCode":1,"orderId":"0","serialId":"FAKECARDIMAG12345678"}""", "CMUpsertUserPrintlogApi" to """{"returnCode":1,"orderId":"0","serialId":"FAKECARDIMAG12345678"}""",
).also { endpointList.popAll(it.keys.toList()) } ).also { endpointList.removeAll(it.keys.toSet()) }
val members = this::class.declaredMemberProperties val members = this::class.declaredMemberProperties
val handlers: Map<String, BaseHandler> = endpointList.associateWith { api -> val handlers: Map<String, BaseHandler> = endpointList.associateWith { api ->

View File

@ -196,7 +196,7 @@ fun WaccaServer.init() {
"user/status/GetDetail" api@ { _, (uid) -> "user/status/GetDetail" api@ { _, (uid) ->
val u = user(uid) ?: return@api "[]" val u = user(uid) ?: return@api "[]"
val o = options(u) val o = options(u)
val items = rp.item.findByUser(u).groupBy { it.type }.toMutableMap() val items = rp.item.findByUser(u).groupBy { it.type }.mut
val scores = rp.bestScore.findByUser(u) val scores = rp.bestScore.findByUser(u)
val scoreMap = scores.associateBy { it.musicId to it.level } val scoreMap = scores.associateBy { it.musicId to it.level }
val gates = rp.gate.findByUser(u) val gates = rp.gate.findByUser(u)
@ -343,7 +343,7 @@ fun WaccaServer.init() {
?: WcUserScore().apply { user = u; musicId = pl.musicId; level = pl.level }).apply { ?: WcUserScore().apply { user = u; musicId = pl.musicId; level = pl.level }).apply {
grades[WaccaGrades.valueMap[pl.grade]?.ordinal ?: (400 - "Grade ${pl.grade} invalid")]++ grades[WaccaGrades.valueMap[pl.grade]?.ordinal ?: (400 - "Grade ${pl.grade} invalid")]++
clears = clears.zip(pl.clears()) { a, b -> a + b }.toMutableList() clears = clears.zip(pl.clears()) { a, b -> a + b }.mut
achievement = max(achievement, pl.achievement) achievement = max(achievement, pl.achievement)
bestCombo = max(bestCombo, pl.maxCombo) bestCombo = max(bestCombo, pl.maxCombo)
lowestMissCt = min(lowestMissCt, pl.judgements[3]) lowestMissCt = min(lowestMissCt, pl.judgements[3])
@ -425,7 +425,7 @@ fun WaccaServer.init() {
"user/status/update" empty { req, (uid, playType, items, isContinue, isFirstPlayFree, itemsUsed, lastSong) -> "user/status/update" empty { req, (uid, playType, items, isContinue, isFirstPlayFree, itemsUsed, lastSong) ->
val u = user(uid) ?: (404 - "User not found") val u = user(uid) ?: (404 - "User not found")
u.lastSongInfo = (lastSong as List<Int>).toMutableList() u.lastSongInfo = (lastSong as List<Int>).mut
afterPlay(u, items as List<List<Int>>, playType.int(), req.appVersion) afterPlay(u, items as List<List<Int>>, playType.int(), req.appVersion)
} }
@ -462,7 +462,7 @@ fun WaccaServer.init() {
clearStatus = clearType.int() // 0..3: Fail, Blue, Silver, Gold clearStatus = clearType.int() // 0..3: Fail, Blue, Silver, Gold
clearSongCt = clearCt.int() clearSongCt = clearCt.int()
playCt++ playCt++
if (scores.sum() > s.songScores.sum()) songScores = scores.toMutableList() if (scores.sum() > s.songScores.sum()) songScores = scores.mut
}) })
if (dan.int() > u.danLevel || (dan.int() == u.danLevel && clearType.int() > u.danType)) { if (dan.int() > u.danLevel || (dan.int() == u.danLevel && clearType.int() > u.danType)) {

View File

@ -101,7 +101,7 @@ class WcUserScore : WaccaUserEntity() {
var clears: MutableList<Int> = mutableListOf(0, 0, 0, 0, 0) // Played, Clear, Full Combo, Missless, All Marv var clears: MutableList<Int> = mutableListOf(0, 0, 0, 0, 0) // Played, Clear, Full Combo, Missless, All Marv
@Convert(converter = IntegerListConverter::class) @Convert(converter = IntegerListConverter::class)
var grades: MutableList<Int> = (1..13).map { 0 }.toMutableList() // From D to SSS+ var grades: MutableList<Int> = (1..13).map { 0 }.mut // From D to SSS+
var bestCombo = 0 var bestCombo = 0
var lowestMissCt = Int.MAX_VALUE var lowestMissCt = Int.MAX_VALUE
var rating = 0 var rating = 0