mirror of https://github.com/hykilpikonna/AquaDX
[+] Mut
parent
96fb815bd8
commit
56e424c29b
|
@ -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) }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ->
|
||||||
|
|
|
@ -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 }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
|
const val LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
|
||||||
|
@ -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)) }
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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 },
|
||||||
)
|
)
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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) }
|
||||||
|
|
|
@ -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() }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ->
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue