[F] Wacca fix impl details

This commit is contained in:
Azalea
2024-03-28 20:17:33 -04:00
parent 4ebddf78ed
commit 56ce7f9696
5 changed files with 64 additions and 43 deletions

View File

@@ -11,12 +11,16 @@ enum class WaccaGrades(val value: Int) {
AA(5),
AAA(6),
S(7),
SS(8),
SSS(9),
MASTER(10),
S_PLUS(11),
SS(8),
SS_PLUS(12),
SSS(9),
SSS_PLUS(13),
MASTER(10);
companion object {
val valueMap = entries.associateBy { it.value }
}
}
enum class WaccaDifficulty(val value: Int) {
@@ -90,7 +94,7 @@ enum class WaccaOptionType(val id: Int, val default: Int) {
MASTER_VOL(1001, 3), // 0
SET_TITLE_ID(1002, 104001), // ID
SET_ICON_ID(1003, 102001), // ID
SET_NAV_ID(1004, 210001), // ID
SET_NAV_ID(1004, 310001), // ID
SET_PLATE_ID(1005, 211001), // ID
}

View File

@@ -4,8 +4,10 @@ import ext.*
import icu.samnyan.aqua.net.utils.ApiException
import icu.samnyan.aqua.sega.general.dao.CardRepository
import icu.samnyan.aqua.sega.wacca.WaccaItemType.*
import icu.samnyan.aqua.sega.wacca.WaccaOptionType.SET_ICON_ID
import icu.samnyan.aqua.sega.wacca.WaccaOptionType.SET_TITLE_ID
import icu.samnyan.aqua.sega.wacca.WaccaItemType.NOTE_COLOR
import icu.samnyan.aqua.sega.wacca.WaccaItemType.NOTE_SOUND
import icu.samnyan.aqua.sega.wacca.WaccaItemType.TOUCH_EFFECT
import icu.samnyan.aqua.sega.wacca.WaccaOptionType.*
import icu.samnyan.aqua.sega.wacca.model.BaseRequest
import icu.samnyan.aqua.sega.wacca.model.db.*
import io.ktor.client.utils.*
@@ -168,33 +170,37 @@ fun WaccaServer.init() {
// TODO: make this and vip configurable
// u.wp = 999999
u.run {
ls("status" - lStatus(),
"options" - o.map { (k, v) -> ls(k, v) },
"seasonalPlayModeCounts" - (playCounts.mapIndexed { i, it -> ls(season, i + 1, it) } + ls(ls(0, 1, 1))),
"items" - ls(MUSIC_UNLOCK, TITLE, ICON, TROPHY, SKILL, TICKET, NOTE_COLOR, NOTE_SOUND, NAVIGATOR, USER_PLATE, TOUCH_EFFECT).map {
if (it == TICKET && go?.unlockTickets == true) (0..4).map { ls(it, 106002, 0) }
u.run { ls(
"0 status" - lStatus(),
"1 options" - o.map { (k, v) -> ls(k, v) },
"2 seasonalPlayModeCounts" - (playCounts.mapIndexed { i, it -> ls(season, i + 1, it) } + ls(ls(0, 1, 1))),
"3 items" - ls(MUSIC_UNLOCK, TITLE, ICON, TROPHY, SKILL, TICKET, NOTE_COLOR, NOTE_SOUND, NAVIGATOR, USER_PLATE, TOUCH_EFFECT).map {
if (it == MUSIC_UNLOCK) items[it()]?.flatMap { song ->
// Add all difficulties up to the highest unlocked
(1..song.p1).map { diff -> ls(song.itemId, diff, 0, song.acquiredDate.sec) }
} ?: empty
else if (it == TICKET && go?.unlockTickets == true) (0..4).map { ls(it, 106002, 0) }
else items[it()]?.map { it.ls() } ?: empty
},
"scores" - scores.map { it.ls() },
"songPlayStatus" - ls(lastSongInfo[0], 1),
"seasonInfo" - ls(xp, wpTotal, wpSpent, scores.sumOf { it.score },
"4 scores" - scores.map { it.ls() },
"5 songPlayStatus" - ls(lastSongInfo[0], 1),
"6 seasonInfo" - ls(xp, wpTotal, wpSpent, scores.sumOf { it.score },
items[TITLE()]?.size ?: 0, items[ICON()]?.size ?: 0, 0,
items[NOTE_COLOR()]?.size ?: 0, items[NOTE_SOUND()]?.size ?: 0, items[USER_PLATE()]?.size ?: 0,
gates.sumOf { it.totalPoints }),
"playAreaList" - "[[0],[0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0],[0,0,0,0],[0,0,0,0,0,0,0],[0]]".jsonArray(),
"songUpdateTime" - lastLoginDate.time / 1000,
"favorites" - u.favoriteSongs,
"stoppedSongIds" - empty,
"events" - empty,
"gate" - gates.associateBy { it.gateId }.let { gateMap -> enabledGates.map {
"7 playAreaList" - "[[0],[0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0],[0,0,0,0],[0,0,0,0,0,0,0],[0]]".jsonArray(),
"8 songUpdateTime" - lastLoginDate.time / 1000,
"9 favorites" - u.favoriteSongs,
"10 stoppedSongIds" - empty,
"11 events" - empty,
"12 gate" - gates.associateBy { it.gateId }.let { gateMap -> enabledGates.map {
gateMap[it]?.ls() ?: WcUserGate().apply { gateId = it }.ls()
} },
"lastSongInfo" - lastSongInfo,
"gateTutorialFlags" - gateTutorialFlags.jsonArray(),
"gatchaInfo" - empty,
"friendList" - empty,
"bingoStatus" - ls(
"13 lastSongInfo" - lastSongInfo,
"14 gateTutorialFlags" - gateTutorialFlags.jsonArray(),
"15 gatchaInfo" - empty,
"16 friendList" - empty,
"17 bingoStatus" - ls(
"pageNumber" - (bingo?.pageNumber ?: 0),
"pageStatus" - (bingo?.pageProgress?.jsonArray() ?: empty)
)
@@ -210,8 +216,8 @@ fun WaccaServer.init() {
WP() -> { u.wp += param; u.wpTotal += param }
XP() -> u.xp += param
MUSIC_DIFFICULTY_UNLOCK(),
MUSIC_UNLOCK() -> newItems += (ex ?: WcUserItem(type, id))
.apply { user = u; p1 = min(max(param.long(), p1), WaccaDifficulty.HARD.value.long()) }
MUSIC_UNLOCK() -> newItems += (ex ?: WcUserItem(MUSIC_UNLOCK(), id))
.apply { user = u; p1 = max(param.long(), p1).coerceAtLeast(WaccaDifficulty.HARD.value.long()) }
TROPHY() -> newItems += (ex ?: TROPHY(u, id)).apply { p1 = season.long(); p2 = param.long() }
else -> newItems += (ex ?: WcUserItem(type, id)).apply { user = u }
}
@@ -242,14 +248,15 @@ fun WaccaServer.init() {
empty
}
"user/mission/update" { _, (uid, bingoDetail, items, gateTutorialFlags) ->
"user/mission/update" { _, (uid, bingoDetail, items, tutFlags) ->
val u = user(uid) ?: (404 - "User not found")
u.gateTutorialFlags = gateTutorialFlags.toJson()
rp.user.save(u.apply { gateTutorialFlags = tutFlags.toJson() })
addItems(items as List<List<Int>>, u, itmGrp(u))
// Update bingo
val (page, prog) = bingoDetail as List<Any>
rp.bingo.findByUser(u).firstOrNull() ?: WcUserBingo().apply { user = u; pageNumber = page.int(); pageProgress = prog.toJson() }
val bingo = rp.bingo.findByUser(u).firstOrNull() ?: WcUserBingo().apply { user = u; pageNumber = page.int() }
rp.bingo.save(bingo.apply { pageProgress = prog.toJson() })
empty
}
@@ -266,7 +273,7 @@ fun WaccaServer.init() {
val best = rp.bestScore.findByUserAndSongIdAndDifficulty(u, song.songId, song.difficulty)
?: WcUserScore().apply { user = u; songId = song.songId; difficulty = song.difficulty }
best.grades[song.grade - 1]++
best.grades[WaccaGrades.valueMap[song.grade]?.ordinal ?: (400 - "Grade ${song.grade} invalid")]++
best.clears = best.clears.zip(song.clears()) { a, b -> a + b }.toMutableList()
best.score = max(best.score, song.score)
best.bestCombo = max(best.bestCombo, song.maxCombo)
@@ -275,7 +282,7 @@ fun WaccaServer.init() {
rp.bestScore.save(best)
ls(best.ls(), ls(song.songId, best.clears[0]), "seasonalInfo" - (1..11).map { 0 }, "rankingInfo" - empty)
ls(best.lsMusicUpdate(), ls(song.songId, best.clears[0]), "seasonalInfo" - (1..11).map { 0 }, "rankingInfo" - empty)
}
"user/music/UpdateCoop" redirect "user/music/update"
"user/music/UpdateVersus" redirect "user/music/update"
@@ -295,6 +302,13 @@ fun WaccaServer.init() {
empty
}
fun incrUses(u: WaccaUser, opts: Map<Int, Int>) {
rp.item.findByUserAndItemIdAndType(u, opts[SET_ICON_ID], ICON())
?.let { rp.item.save(it.apply { p1++ }) }
rp.item.findByUserAndItemIdAndType(u, opts[SET_NAV_ID], NAVIGATOR())
?.let { rp.item.save(it.apply { p1++ }) }
}
"user/status/update" { req, (uid, playType, items, isContinue, isFirstPlayFree, itemsUsed, lastSong) ->
val u = user(uid) ?: (404 - "User not found")
rp.user.save(u.apply {
@@ -305,7 +319,7 @@ fun WaccaServer.init() {
lastSongInfo = (lastSong as List<Int>).toMutableList()
lastGameVer = req.appVersion
// TODO: Add icon and nav items
incrUses(u, options(u))
})
empty

View File

@@ -25,7 +25,9 @@ interface WcUserFriendRepo : IWaccaUserLinked<WcUserFriend>
interface WcUserGateRepo : IWaccaUserLinked<WcUserGate> {
fun findByUserAndGateId(user: WaccaUser, gateId: Int): WcUserGate?
}
interface WcUserItemRepo : IWaccaUserLinked<WcUserItem>
interface WcUserItemRepo : IWaccaUserLinked<WcUserItem> {
fun findByUserAndItemIdAndType(user: WaccaUser, itemId: Int, type: Int): WcUserItem?
}
interface WcUserBestScoreRepo : IWaccaUserLinked<WcUserScore> {
fun findByUserAndSongIdAndDifficulty(user: WaccaUser, songId: Int, difficulty: Int): WcUserScore?
}

View File

@@ -76,12 +76,12 @@ class WcUserItem(
var acquiredDate: Date = Date(),
) : WaccaUserEntity() {
fun ls() = when (type) {
MUSIC_UNLOCK() -> ls(itemId, p1, acquiredDate.sec, acquiredDate.sec) // songId, diff, acquireDate, unlockDate
MUSIC_UNLOCK() -> ls(itemId, p1, 0, acquiredDate.sec) // songId, diff, acquireDate, unlockDate
ICON() -> ls(itemId, 1, p1, acquiredDate.sec) // id, type, uses, acquiredDate
TROPHY() -> ls(itemId, p1, p2, p3) // id, season, progress, badgeType
SKILL() -> ls(itemId, p1, p2, p3) // skillType, level, flag, badge
TICKET() -> ls(id, itemId, p1) // userTicketId, ticketId, expire
NAVIGATOR() -> ls(itemId, 1, acquiredDate.sec, p1, p2) // id, type, acquiredDate, uses, usesToday
NAVIGATOR() -> ls(itemId, 1, acquiredDate.sec, p1, p1) // id, type, acquiredDate, uses, usesToday
// Generic: title, note colors, note sounds, plates, touch effects
else -> ls(itemId, 1, acquiredDate.sec) // id, type, acquireDate
@@ -105,7 +105,8 @@ class WcUserScore : WaccaUserEntity() {
var lowestMissCt = Int.MAX_VALUE
var rating = 0
fun ls() = ls(songId, difficulty, clears, clears, grades, score, lowestMissCt, 0, 1, rating)
fun ls() = ls(songId, difficulty, clears, clears, grades, score, bestCombo, lowestMissCt, 1, rating)
fun lsMusicUpdate() = ls(songId, difficulty, clears, clears, grades, score, lowestMissCt, 0, 1, rating)
}
@Entity @Table(name = "wacca_user_playlog", uniqueConstraints = [UC("", ["user_id", "song_id", "chart_id", "date_scored"])])