mirror of
https://github.com/MewoLab/AquaDX.git
synced 2026-09-29 02:07:57 +03:00
feat: ongeki 1.60 support (#240)
Co-authored-by: Raymond <101374892+raymonable@users.noreply.github.com>
This commit is contained in:
@@ -32,6 +32,7 @@ import java.time.ZoneOffset.UTC
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.*
|
||||
import java.util.concurrent.locks.Lock
|
||||
import kotlin.math.floor
|
||||
import kotlin.reflect.KCallable
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
@@ -199,6 +200,10 @@ val Any?.truthy get() = when (this) {
|
||||
}
|
||||
val Any?.str get() = toString()
|
||||
|
||||
fun truncateVersion(version: Number): Number {
|
||||
return (floor(version.toFloat() / 5.0) * 5).toInt();
|
||||
}
|
||||
|
||||
// Collections
|
||||
fun <T> ls(vararg args: T) = args.toList()
|
||||
inline fun <reified T> arr(vararg args: T) = arrayOf(*args)
|
||||
@@ -277,4 +282,4 @@ fun List<List<Any?>>.numCsv(vararg head: Str) = head.joinToString(",") + "\n" +
|
||||
joinToString("\n") { it.joinToString(",") }
|
||||
|
||||
// DI
|
||||
inline fun <reified T : Any> ApplicationContext.lazy() = kotlin.lazy { getBean(T::class.java) }
|
||||
inline fun <reified T : Any> ApplicationContext.lazy() = kotlin.lazy { getBean(T::class.java) }
|
||||
|
||||
@@ -3,6 +3,7 @@ package icu.samnyan.aqua.sega.general.filter
|
||||
import ext.details
|
||||
import ext.logger
|
||||
import ext.toJson
|
||||
import ext.truncateVersion
|
||||
import icu.samnyan.aqua.net.components.GeoIP
|
||||
import icu.samnyan.aqua.sega.allnet.TokenChecker
|
||||
import icu.samnyan.aqua.sega.general.model.GameEncryptionKey
|
||||
@@ -36,9 +37,6 @@ class CompressionFilter(
|
||||
|
||||
}
|
||||
|
||||
fun truncateVersion(version: Number): Number {
|
||||
return (floor(version.toFloat() / 5.0) * 5).toInt();
|
||||
}
|
||||
fun getVersion(req: HttpServletRequest, game: String): Int {
|
||||
// NOTE: this should help with some issues regarding mismatched data
|
||||
val expectedVersion = (req.getHeader("Mai-Encoding") ?:
|
||||
|
||||
@@ -4,6 +4,8 @@ import ext.empty
|
||||
import ext.int
|
||||
import ext.parsing
|
||||
import ext.plus
|
||||
import ext.str
|
||||
import ext.truncateVersion
|
||||
|
||||
fun OngekiController.ongekiInit() {
|
||||
fun <T> List<T>.staticLst(key: String) = mapOf("length" to size, key to this)
|
||||
@@ -13,18 +15,21 @@ fun OngekiController.ongekiInit() {
|
||||
initUpsertAll()
|
||||
|
||||
// Has type, but type is always 1
|
||||
"GetGameEvent".static {
|
||||
gdb.event.findAll().map {
|
||||
mapOf("id" to it.id, "type" to 1, "startDate" to "2005-01-01 00:00:00.0", "endDate" to "2099-01-01 05:00:00.0")
|
||||
}.staticLst("gameEventList") + mapOf("type" to 1)
|
||||
"GetGameEvent" {
|
||||
// val trunkVer = truncateVersion((data["version"] ?: "1.50.00").str.split(".").take(2).joinToString("").int)
|
||||
val events = gdb.event.findAll()
|
||||
// .filter{ it.id.str.startsWith(trunkVer.str) }
|
||||
.map {
|
||||
mapOf("id" to it.id, "type" to 1, "startDate" to "2005-01-01 00:00:00.0", "endDate" to "2099-01-01 05:00:00.0")
|
||||
}
|
||||
mapOf("gameEventList" to events, "length" to events.size, "type" to 1)
|
||||
}
|
||||
|
||||
"GetGamePoint".static { gdb.point.findAll().staticLst("gamePointList") }
|
||||
"GetGamePresent".static { gdb.present.findAll().staticLst("gamePresentList") }
|
||||
"GetGameReward".static { gdb.reward.findAll().staticLst("gameRewardList") }
|
||||
|
||||
// Dummy endpoints
|
||||
"GetGameTechMusic".static { empty.staticLst("gameTechMusicList") }
|
||||
"GetGameTechMusic".static { gdb.gameData.ogkGameTechMusics.staticLst("gameTechMusicList") }
|
||||
"GetGameMessage" { mapOf("type" to data["type"], "length" to 0, "gameMessageList" to empty) }
|
||||
"GetGameMusicReleaseState".static { mapOf("techScore" to 0, "cardNum" to 0) }
|
||||
|
||||
@@ -82,4 +87,4 @@ fun OngekiController.ongekiInit() {
|
||||
"UpsertClientTestmode" static { """{"returnCode":1, "apiName":"UpsertClientTestmodeApi"}""" }
|
||||
"UpsertUserGplog" static { """{"returnCode":1, "apiName":"UpsertUserGplogApi"}""" }
|
||||
"Ping" static { """{"returnCode":1, "apiName":"Ping"}""" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,11 +54,12 @@ interface OgkUserDeckRepo : OngekiUserLinked<UserDeck> {
|
||||
}
|
||||
|
||||
interface OgkUserEventMusicRepo : OngekiUserLinked<UserEventMusic> {
|
||||
fun findByUserAndEventIdAndTypeAndMusicId(
|
||||
fun findByUserAndEventIdAndTypeAndMusicIdAndLevel(
|
||||
userData: UserData,
|
||||
eventId: Int,
|
||||
type: Int,
|
||||
musicId: Int
|
||||
musicId: Int,
|
||||
level: Int
|
||||
): UserEventMusic?
|
||||
}
|
||||
|
||||
@@ -162,7 +163,10 @@ interface OgkUserGachaRepo : OngekiUserLinked<UserGacha> {
|
||||
}
|
||||
|
||||
// Re:Fresh
|
||||
interface OgkUserEventMapRepo : OngekiUserLinked<UserEventMap>
|
||||
interface OgkUserEventMapRepo : OngekiUserLinked<UserEventMap> {
|
||||
fun findByUserAndEventIdAndMapId(user: UserData, eventId: Int, mapId: Int): UserEventMap?
|
||||
fun findByUser_Card_ExtIdAndEventIdAndMapId(extId: Long, eventId: Int, mapId: Int): UserEventMap?
|
||||
}
|
||||
interface OgkUserSkinRepo : OngekiUserLinked<UserSkin>
|
||||
|
||||
|
||||
|
||||
@@ -74,7 +74,9 @@ fun OngekiController.initUpsertAll() {
|
||||
// UserEventMap
|
||||
userEventMap?.let {
|
||||
db.eventMap.save(it.apply {
|
||||
id = db.eventMap.findSingleByUser(u)?.id ?: 0 }) }
|
||||
id = db.eventMap.findByUserAndEventIdAndMapId(u, it.eventId, it.mapId)?.id ?: 0
|
||||
})
|
||||
}
|
||||
|
||||
// UserPlaylogList
|
||||
userPlaylogList?.let { db.playlog.saveAll(it) }
|
||||
@@ -195,8 +197,9 @@ fun OngekiController.initUpsertAll() {
|
||||
|
||||
// UserEventMusicList
|
||||
userEventMusicList?.let { list ->
|
||||
db.eventMusic.saveAll(list.distinctBy { it.eventId to it.type to it.musicId }.mapApply {
|
||||
id = db.eventMusic.findByUserAndEventIdAndTypeAndMusicId(u, eventId, type, musicId)?.id ?: 0 }) }
|
||||
db.eventMusic.saveAll(list.distinctBy { it.eventId to it.type to it.musicId to it.level }.mapApply {
|
||||
id = db.eventMusic.findByUserAndEventIdAndTypeAndMusicIdAndLevel(u, eventId, type, musicId, level)?.id ?: 0
|
||||
}) }
|
||||
|
||||
// UserTechEventList
|
||||
userTechEventList?.let { list ->
|
||||
|
||||
@@ -7,6 +7,7 @@ import icu.samnyan.aqua.sega.general.model.CardStatus
|
||||
import icu.samnyan.aqua.sega.general.model.UserRecentRating
|
||||
import icu.samnyan.aqua.sega.ongeki.model.OgkItemType
|
||||
import icu.samnyan.aqua.sega.ongeki.model.UserItem
|
||||
import icu.samnyan.aqua.sega.ongeki.model.UserEventMap
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.data.domain.Sort
|
||||
import java.time.LocalDateTime
|
||||
@@ -14,10 +15,25 @@ import java.time.format.DateTimeFormatter
|
||||
|
||||
|
||||
fun OngekiController.initUser() {
|
||||
val emptyEventMapData = """{"unlockPoints":0,"_unlockedTileIDs":[1],"_rewardScenarioIDs":[],"_rewardRewardKeyIDs":[],"endless":false,"loopCount":0}"""
|
||||
|
||||
"GetUserData" { mapOf("userId" to uid, "userData" to db.data.findByCard_ExtId(uid)) }
|
||||
|
||||
"GetUserOption" { mapOf("userId" to uid, "userOption" to db.option.findSingleByUser_Card_ExtId(uid)) }
|
||||
"GetUserEventMap" { mapOf("userId" to uid, "userEventMap" to db.eventMap.findSingleByUser_Card_ExtId(uid)) }
|
||||
"GetUserEventMap" {
|
||||
val eventId = data["eventId"]?.int ?: 0
|
||||
val mapId = data["mapId"]?.int ?: 0
|
||||
val userEventMap = db.eventMap.findByUser_Card_ExtIdAndEventIdAndMapId(uid, eventId, mapId)
|
||||
?: UserEventMap().apply {
|
||||
this.eventId = eventId
|
||||
this.mapId = mapId
|
||||
this.mapData = emptyEventMapData
|
||||
}
|
||||
mapOf(
|
||||
"userId" to uid,
|
||||
"userEventMap" to userEventMap
|
||||
)
|
||||
}
|
||||
|
||||
"GetUserTechEvent".unpaged { db.techEvent.findByUser_Card_ExtId(uid) }
|
||||
"GetUserBoss".unpaged { db.boss.findByUser_Card_ExtId(uid) }
|
||||
|
||||
@@ -29,6 +29,12 @@ class GameEvent {
|
||||
var id: Long = 0
|
||||
}
|
||||
|
||||
class GameTechMusic {
|
||||
var eventId = 0
|
||||
var musicId = 0
|
||||
var level = 0
|
||||
}
|
||||
|
||||
class GameMusic {
|
||||
var id: Long = 0
|
||||
var name: String = ""
|
||||
@@ -105,4 +111,4 @@ class GameGacha {
|
||||
|
||||
@JsonProperty("isCeiling")
|
||||
var isCeiling: Boolean = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,6 +166,7 @@ class UserChapter : OngekiUserEntity() {
|
||||
var jewelCount = 0
|
||||
var lastPlayMusicCategory = 0
|
||||
var lastPlayMusicId = 0
|
||||
var lastPlayMusicMinorCategory: String = ""
|
||||
var lastPlayMusicLevel = 0
|
||||
var isStoryWatched = false
|
||||
var isClear = false
|
||||
@@ -197,7 +198,10 @@ class UserDeck : OngekiUserEntity() {
|
||||
}
|
||||
|
||||
@Entity(name = "OngekiUserEventMusic")
|
||||
@Table(name = "ongeki_user_event_music")
|
||||
@Table(
|
||||
name = "ongeki_user_event_music",
|
||||
uniqueConstraints = [UniqueConstraint(columnNames = ["user_id", "event_id", "type", "music_id", "level"])]
|
||||
)
|
||||
class UserEventMusic : OngekiUserEntity() {
|
||||
var eventId = 0
|
||||
var type = 0
|
||||
@@ -318,6 +322,7 @@ class UserMusicItem : OngekiUserEntity() {
|
||||
class UserOption : OngekiUserEntity() {
|
||||
var optionSet = 0
|
||||
var speed = 0
|
||||
var fieldWall = 0
|
||||
var mirror = 0
|
||||
var judgeTiming = 0
|
||||
var judgeAdjustment = 0
|
||||
@@ -342,20 +347,19 @@ class UserOption : OngekiUserEntity() {
|
||||
var colorSide = 0
|
||||
var effectDamage = 0
|
||||
var effectPos = 0
|
||||
var effectAttack = 0
|
||||
var judgeDisp = 0
|
||||
var judgePos = 0
|
||||
var judgeBreak = 0
|
||||
var judgeHit = 0
|
||||
var platinumBreakDisp = 0
|
||||
var judgeCriticalBreak = 0
|
||||
var platinumBreakDisp = 0
|
||||
var matching = 0
|
||||
var dispPlayerLv = 0
|
||||
var dispRating = 0
|
||||
var dispBP = 0
|
||||
var headphone = 0
|
||||
|
||||
// Re:Fresh
|
||||
var effectAttack = 0
|
||||
}
|
||||
|
||||
|
||||
@@ -457,6 +461,7 @@ class UserStory : OngekiUserEntity() {
|
||||
var jewelCount = 0
|
||||
var lastPlayMusicId = 0
|
||||
var lastPlayMusicCategory = 0
|
||||
var lastPlayMusicMinorCategory: String = ""
|
||||
var lastPlayMusicLevel = 0
|
||||
}
|
||||
|
||||
@@ -498,7 +503,10 @@ class UserTrainingRoom : OngekiUserEntity() {
|
||||
|
||||
// Re:Fresh
|
||||
@Entity(name = "OngekiUserEventMap")
|
||||
@Table(name = "ongeki_user_event_map")
|
||||
@Table(
|
||||
name = "ongeki_user_event_map",
|
||||
uniqueConstraints = [UniqueConstraint(columnNames = ["user_id", "event_id", "map_id"])]
|
||||
)
|
||||
class UserEventMap : OngekiUserEntity() {
|
||||
var eventId = 0
|
||||
var mapId = 0
|
||||
|
||||
@@ -19,6 +19,7 @@ import icu.samnyan.aqua.sega.ongeki.model.GameChara as OgkGameChara
|
||||
import icu.samnyan.aqua.sega.ongeki.model.GameEvent as OgkGameEvent
|
||||
import icu.samnyan.aqua.sega.ongeki.model.GameGacha as OgkGameGacha
|
||||
import icu.samnyan.aqua.sega.ongeki.model.GameGachaCard as OgkGameGachaCard
|
||||
import icu.samnyan.aqua.sega.ongeki.model.GameTechMusic as OgkGameTechMusic
|
||||
import icu.samnyan.aqua.sega.ongeki.model.GameMusic as OgkGameMusic
|
||||
import icu.samnyan.aqua.sega.ongeki.model.GamePoint as OgkGamePoint
|
||||
import icu.samnyan.aqua.sega.ongeki.model.GamePresent as OgkGamePresent
|
||||
@@ -50,6 +51,7 @@ class GameDataService() {
|
||||
log.warn("Game data file $f or resource $resPath not found, using empty list")
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// maimai2
|
||||
@@ -72,6 +74,7 @@ class GameDataService() {
|
||||
lateinit var ogkGameCards: List<OgkGameCard>
|
||||
lateinit var ogkGameCharas: List<OgkGameChara>
|
||||
lateinit var ogkGameEvents: List<OgkGameEvent>
|
||||
lateinit var ogkGameTechMusics: List<OgkGameTechMusic>
|
||||
lateinit var ogkGameMusics: List<OgkGameMusic>
|
||||
lateinit var ogkGamePoints: List<OgkGamePoint>
|
||||
lateinit var ogkGamePresents: List<OgkGamePresent>
|
||||
@@ -103,6 +106,7 @@ class GameDataService() {
|
||||
ogkGameCards = load("ongeki", "game_card.json")
|
||||
ogkGameCharas = load("ongeki", "game_chara.json")
|
||||
ogkGameEvents = load("ongeki", "game_event.json")
|
||||
ogkGameTechMusics = load("ongeki", "game_tech_music.json")
|
||||
ogkGameMusics = load("ongeki", "game_music.json")
|
||||
ogkGamePoints = load("ongeki", "game_point.json")
|
||||
ogkGamePresents = load("ongeki", "game_present.json")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
-- should have been not nullable in the first place smh
|
||||
DELETE FROM ongeki_user_event_map
|
||||
WHERE user_id IS NULL;
|
||||
|
||||
ALTER TABLE ongeki_user_event_map
|
||||
MODIFY user_id BIGINT NOT NULL;
|
||||
|
||||
-- dedupe before adding new constraint just in case
|
||||
DELETE FROM ongeki_user_event_map
|
||||
WHERE id NOT IN (
|
||||
SELECT id
|
||||
FROM (
|
||||
SELECT MAX(id) AS id
|
||||
FROM ongeki_user_event_map
|
||||
GROUP BY user_id, event_id, map_id
|
||||
) AS rows_to_keep
|
||||
);
|
||||
|
||||
ALTER TABLE ongeki_user_event_map
|
||||
ADD UNIQUE KEY uniq_ongeki_user_event_map (user_id, event_id, map_id);
|
||||
@@ -0,0 +1,23 @@
|
||||
-- allow separate Technical Challenge records for each chart difficulty
|
||||
-- drop the old constraint and dedupe with the new constraint just in case again
|
||||
ALTER TABLE ongeki_user_event_music
|
||||
DROP INDEX IF EXISTS UKo5PU3BgZeTKB8SNykq9U7xjfshp;
|
||||
|
||||
DELETE FROM ongeki_user_event_music
|
||||
WHERE user_id IS NULL;
|
||||
|
||||
ALTER TABLE ongeki_user_event_music
|
||||
MODIFY user_id BIGINT NOT NULL;
|
||||
|
||||
DELETE FROM ongeki_user_event_music
|
||||
WHERE id NOT IN (
|
||||
SELECT id
|
||||
FROM (
|
||||
SELECT MAX(id) AS id
|
||||
FROM ongeki_user_event_music
|
||||
GROUP BY user_id, event_id, type, music_id, level
|
||||
) AS rows_to_keep
|
||||
);
|
||||
|
||||
ALTER TABLE ongeki_user_event_music
|
||||
ADD UNIQUE KEY uniq_ongeki_user_event_music (user_id, event_id, type, music_id, level);
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE ongeki_user_chapter
|
||||
ADD COLUMN last_play_music_minor_category VARCHAR(255) NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE ongeki_user_story
|
||||
ADD COLUMN last_play_music_minor_category VARCHAR(255) NOT NULL DEFAULT '';
|
||||
@@ -0,0 +1,7 @@
|
||||
-- new field wall option field
|
||||
ALTER TABLE ongeki_user_option
|
||||
ADD COLUMN field_wall INT NOT NULL DEFAULT 0;
|
||||
|
||||
-- varchar(255) not enough for event map storage
|
||||
ALTER TABLE ongeki_user_event_map
|
||||
MODIFY COLUMN map_data TEXT NULL;
|
||||
Reference in New Issue
Block a user