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()
inline fun <reified T> arr(vararg args: T) = arrayOf(*args)
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) }
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) }
@ -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
}.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
operator fun <T> Optional<T>.invoke(): T? = orElse(null)
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.findByLuid(cardId)(),
us.cardRepo.findById(cardId.long)(),
).toMutableList()
).mut
cards += cards.flatMap {
(it.aquaUser?.cards ?: emptyList()) + listOfNotNull(it.aquaUser?.ghostCard)
}
cards = cards.distinctBy { it.id }.toMutableList()
cards = cards.distinctBy { it.id }.mut
return cards.map { card ->
// Find all games played by this card

View File

@ -1,6 +1,7 @@
package icu.samnyan.aqua.net
import ext.HTTP
import ext.mut
import ext.toJson
import icu.samnyan.aqua.net.games.BaseEntity
import io.ktor.client.call.*
@ -54,8 +55,8 @@ class AquaNetSafetyService(
*/
suspend fun isSafeBatch(rawContents: List<String>): List<Boolean> {
val contents = rawContents.map { Normalizer.normalize(it, Normalizer.Form.NFKC) }
val origMap = safety.findAll().associateBy { it.content }.toMutableMap()
val map = safety.findAll().associateBy { it.content.lowercase().trim() }.toMutableMap()
val origMap = safety.findAll().associateBy { it.content }.mut
val map = safety.findAll().associateBy { it.content.lowercase().trim() }.mut
// Process unseen content with OpenAI
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 ->
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) ->
val ranks = detailedRanks.getOrPut(lvl.toInt()) { rankMap.toMutableMap() }
val ranks = detailedRanks.getOrPut(lvl.toInt()) { rankMap.mut }
ranks[v] = ranks[v]!! + 1
}
}
// 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 ->
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.minus
import ext.mut
import java.time.LocalDate
const val LETTERS = "" +
@ -60,7 +61,7 @@ fun findTrend(log: List<TrendLog>): List<TrendOut> {
val trend = d.distinctBy { it.date }
.map { TrendOut(it.date, maxRating[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)
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")
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) {
(400 - "Rival list is full")

View File

@ -139,7 +139,7 @@ class AllNet(
val ver = reqMap["ver"] ?: "1.0"
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),
"host" to props.host.ifBlank { localAddr },
)

View File

@ -91,7 +91,7 @@ fun ChusanController.chusanInit() {
data["nextIndex"] = rawIndex % 10000000000L
mapOf("itemKind" to kind) grabs {
// 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
db.userData.findByCard_ExtId(uid)()?.card?.aquaUser?.gameOptions?.let {
@ -146,7 +146,7 @@ fun ChusanController.chusanInit() {
// Compatibility: Older chusan uses boolean for isSuccess
fun checkAncient(d: List<UserMusicDetail>) =
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
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
(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) }
}
fun String.paged(key: String, fn: PagedHandler) = pagedWithKind(key) { PagedProcessor(null, fn) }

View File

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

View File

@ -319,17 +319,17 @@ class Maimai2ServletController(
"GetUserScoreRankingApi", "UpsertClientBookkeepingApi", "UpsertClientSettingApi",
"UpsertClientTestmodeApi", "UpsertClientUploadApi", "Ping", "RemoveTokenApi", "CMLoginApi", "CMLogoutApi",
"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",
"CMLoginApi", "CMLogoutApi", "CMUpsertBuyCardApi", "UserLogoutApi", "GetGameMapAreaConditionApi",
"UpsertUserChargelogApi")
"UpsertUserChargelogApi").also { endpointList.removeAll(it) }
val staticEndpoint = mapOf(
"CreateTokenApi" to """{"Bearer":"meow"}""",
"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 handlers: Map<String, BaseHandler> = endpointList.associateWith { api ->

View File

@ -196,7 +196,7 @@ fun WaccaServer.init() {
"user/status/GetDetail" api@ { _, (uid) ->
val u = user(uid) ?: return@api "[]"
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 scoreMap = scores.associateBy { it.musicId to it.level }
val gates = rp.gate.findByUser(u)
@ -343,7 +343,7 @@ fun WaccaServer.init() {
?: WcUserScore().apply { user = u; musicId = pl.musicId; level = pl.level }).apply {
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)
bestCombo = max(bestCombo, pl.maxCombo)
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) ->
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)
}
@ -462,7 +462,7 @@ fun WaccaServer.init() {
clearStatus = clearType.int() // 0..3: Fail, Blue, Silver, Gold
clearSongCt = clearCt.int()
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)) {

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
@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 lowestMissCt = Int.MAX_VALUE
var rating = 0