mirror of
https://github.com/MewoLab/AquaDX.git
synced 2025-12-14 11:56:15 +08:00
Compare commits
4 Commits
5aca650602
...
d996fba291
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d996fba291 | ||
|
|
0cb2a95ff3 | ||
|
|
be5220fd51 | ||
|
|
f23c0d6fe1 |
@@ -1,7 +1,6 @@
|
||||
<script>
|
||||
import { fade } from "svelte/transition";
|
||||
import { FADE_IN, FADE_OUT } from "../../libs/config";
|
||||
import GameSettingFields from "./GameSettingFields.svelte";
|
||||
import { t, ts } from "../../libs/i18n";
|
||||
import useLocalStorage from "../../libs/hooks/useLocalStorage.svelte";
|
||||
import RegionSelector from "./RegionSelector.svelte";
|
||||
@@ -13,7 +12,6 @@
|
||||
<blockquote>
|
||||
{ts("settings.gameNotice")}
|
||||
</blockquote>
|
||||
<GameSettingFields game="general"/>
|
||||
<div class="field">
|
||||
<div class="bool">
|
||||
<input id="rounding" type="checkbox" bind:checked={rounding.value}/>
|
||||
|
||||
@@ -149,18 +149,30 @@ export const EN_REF_SETTINGS = {
|
||||
'settings.tabs.mai2': 'Mai',
|
||||
'settings.tabs.ongeki': 'Ongeki',
|
||||
'settings.tabs.wacca': 'Wacca',
|
||||
'settings.fields.unlockMusic.name': 'Unlock All Music',
|
||||
'settings.fields.unlockMusic.desc': 'Unlock all music and master difficulty in game.',
|
||||
'settings.fields.unlockChara.name': 'Unlock All Characters',
|
||||
'settings.fields.unlockChara.desc': 'Unlock all characters, voices, and partners in game.',
|
||||
'settings.fields.unlockCollectables.name': 'Unlock All Collectables',
|
||||
'settings.fields.unlockCollectables.desc': 'Unlock all collectables (nameplate, title, icon, frame) in game.',
|
||||
'settings.fields.unlockTickets.name': 'Unlock All Tickets',
|
||||
'settings.fields.unlockTickets.desc': 'Infinite map/ex tickets (Note: maimai still limits which tickets can be used).',
|
||||
'settings.fields.waccaInfiniteWp.name': 'Wacca: Infinite WP',
|
||||
'settings.fields.waccaInfiniteWp.desc': 'Set WP to 999999',
|
||||
'settings.fields.waccaAlwaysVip.name': 'Wacca: Always VIP',
|
||||
'settings.fields.waccaAlwaysVip.desc': 'Set VIP expiration date to 2077-01-01',
|
||||
'settings.fields.mai2UnlockMusic.name': 'Unlock All Music',
|
||||
'settings.fields.mai2UnlockMusic.desc': 'Unlock all music and master difficulty.',
|
||||
'settings.fields.mai2UnlockChara.name': 'Unlock All Characters',
|
||||
'settings.fields.mai2UnlockChara.desc': 'Unlock all characters (new characters start at level 1).',
|
||||
'settings.fields.mai2UnlockCharaMaxLevel.name': 'Max Character Level',
|
||||
'settings.fields.mai2UnlockCharaMaxLevel.desc': 'Set all characters to max level.',
|
||||
'settings.fields.mai2UnlockPartners.name': 'Unlock All Partners',
|
||||
'settings.fields.mai2UnlockPartners.desc': 'Unlock all partners.',
|
||||
'settings.fields.mai2UnlockCollectables.name': 'Unlock All Collectables',
|
||||
'settings.fields.mai2UnlockCollectables.desc': 'Unlock all collectables (nameplate, title, icon, frame).',
|
||||
'settings.fields.mai2UnlockTickets.name': 'Unlock All Tickets',
|
||||
'settings.fields.mai2UnlockTickets.desc': 'Infinite tickets (Note: client still limits which tickets can be used).',
|
||||
'settings.fields.waccaUnlockMusic.name': 'Unlock All Music',
|
||||
'settings.fields.waccaUnlockMusic.desc': 'Unlock all music.',
|
||||
'settings.fields.waccaUnlockPlates.name': 'Unlock All Plates',
|
||||
'settings.fields.waccaUnlockPlates.desc': 'Unlock all plates.',
|
||||
'settings.fields.waccaUnlockCollectables.name': 'Unlock All Collectables',
|
||||
'settings.fields.waccaUnlockCollectables.desc': 'Unlock all collectables (icon, trophy).',
|
||||
'settings.fields.waccaUnlockTickets.name': 'Infinite Tickets',
|
||||
'settings.fields.waccaUnlockTickets.desc': 'Infinite tickets.',
|
||||
'settings.fields.waccaInfiniteWp.name': 'Infinite WP',
|
||||
'settings.fields.waccaInfiniteWp.desc': 'Set WP to 999999.',
|
||||
'settings.fields.waccaAlwaysVip.name': 'Always VIP',
|
||||
'settings.fields.waccaAlwaysVip.desc': 'Set VIP expiration date to 2077-01-01.',
|
||||
'settings.fields.chusanTeamName.name': 'Team Name',
|
||||
'settings.fields.chusanTeamName.desc': 'Customize the text displayed on the top of your profile.',
|
||||
'settings.fields.chusanInfinitePenguins.name': 'Infinite Penguins',
|
||||
|
||||
@@ -161,18 +161,30 @@ const zhSettings: typeof EN_REF_SETTINGS = {
|
||||
'settings.tabs.mai2': '舞萌',
|
||||
'settings.tabs.ongeki': '音击',
|
||||
'settings.tabs.wacca': '华卡',
|
||||
'settings.fields.unlockMusic.name': '解锁谱面',
|
||||
'settings.fields.unlockMusic.desc': '在游戏中解锁所有曲目和大师难度谱面。',
|
||||
'settings.fields.unlockChara.name': '解锁角色',
|
||||
'settings.fields.unlockChara.desc': '在游戏中解锁所有角色、语音和伙伴。',
|
||||
'settings.fields.unlockCollectables.name': '解锁收藏品',
|
||||
'settings.fields.unlockCollectables.desc': '在游戏中解锁所有收藏品(名牌、称号、图标、背景图)。',
|
||||
'settings.fields.unlockTickets.name': '解锁游戏券',
|
||||
'settings.fields.unlockTickets.desc': '无限跑图券/解锁券(注:maimai 客户端仍限制一些券不能使用)。',
|
||||
'settings.fields.waccaInfiniteWp.name': '华卡:无限 WP',
|
||||
'settings.fields.waccaInfiniteWp.desc': '将 WP 设置为 999999',
|
||||
'settings.fields.waccaAlwaysVip.name': '华卡:永久会员',
|
||||
'settings.fields.waccaAlwaysVip.desc': '将 VIP 到期时间设置为 2077-01-01',
|
||||
'settings.fields.mai2UnlockMusic.name': '解锁谱面',
|
||||
'settings.fields.mai2UnlockMusic.desc': '解锁所有曲目和大师难度谱面。',
|
||||
'settings.fields.mai2UnlockChara.name': '解锁角色',
|
||||
'settings.fields.mai2UnlockChara.desc': '解锁所有角色(新角色从 1 级开始)。',
|
||||
'settings.fields.mai2UnlockCharaMaxLevel.name': '角色满级',
|
||||
'settings.fields.mai2UnlockCharaMaxLevel.desc': '将所有角色设置为满级。',
|
||||
'settings.fields.mai2UnlockPartners.name': '解锁搭档',
|
||||
'settings.fields.mai2UnlockPartners.desc': '解锁所有搭档。',
|
||||
'settings.fields.mai2UnlockCollectables.name': '解锁收藏品',
|
||||
'settings.fields.mai2UnlockCollectables.desc': '解锁所有收藏品(姓名框、称号、头像、背景)。',
|
||||
'settings.fields.mai2UnlockTickets.name': '解锁功能票',
|
||||
'settings.fields.mai2UnlockTickets.desc': '无限功能票(注:客户端仍限制一些功能票不能使用)。',
|
||||
'settings.fields.waccaUnlockMusic.name': '解锁谱面',
|
||||
'settings.fields.waccaUnlockMusic.desc': '解锁所有曲目。',
|
||||
'settings.fields.waccaUnlockPlates.name': '解锁铭牌',
|
||||
'settings.fields.waccaUnlockPlates.desc': '解锁所有铭牌。',
|
||||
'settings.fields.waccaUnlockCollectables.name': '解锁收藏品',
|
||||
'settings.fields.waccaUnlockCollectables.desc': '解锁所有收藏品。',
|
||||
'settings.fields.waccaUnlockTickets.name': '无限解锁券',
|
||||
'settings.fields.waccaUnlockTickets.desc': '无限解锁券。',
|
||||
'settings.fields.waccaInfiniteWp.name': '无限 WP',
|
||||
'settings.fields.waccaInfiniteWp.desc': '将 WP 设置为 999999。',
|
||||
'settings.fields.waccaAlwaysVip.name': '永久会员',
|
||||
'settings.fields.waccaAlwaysVip.desc': '将 VIP 到期时间设置为 2077-01-01。',
|
||||
'settings.fields.chusanTeamName.name': '队伍名称',
|
||||
'settings.fields.chusanTeamName.desc': '自定义显示在个人资料顶部的文本。',
|
||||
'settings.fields.chusanInfinitePenguins.name': '我是桐谷遥',
|
||||
|
||||
@@ -35,8 +35,10 @@ import java.util.concurrent.locks.Lock
|
||||
import kotlin.reflect.KCallable
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
import kotlin.reflect.full.declaredMemberProperties
|
||||
import kotlin.reflect.full.isSubclassOf
|
||||
import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.jvm.javaField
|
||||
import kotlin.reflect.jvm.jvmErasure
|
||||
|
||||
typealias RP = RequestParam
|
||||
@@ -81,7 +83,9 @@ annotation class SettingField(
|
||||
|
||||
// Reflection
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : Any> KClass<T>.vars() = memberProperties.mapNotNull { it as? Var<T, Any> }
|
||||
fun <T : Any> KClass<T>.ownVars() = declaredMemberProperties.sortedBy { it.javaField?.declaringClass?.declaredFields?.indexOf(it.javaField) ?: Int.MAX_VALUE }.mapNotNull { it as? Var<T, Any> }
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : Any> KClass<T>.vars(): List<Var<T, Any>> = supertypes.mapNotNull { it.classifier as? KClass<*> }.filter { !it.java.isInterface }.flatMap{ it.vars() as List<Var<T, Any>> } + ownVars()
|
||||
fun <T : Any> KClass<T>.varsMap() = vars().associateBy { it.name }
|
||||
fun <T : Any> KClass<T>.getters() = java.methods.filter { it.name.startsWith("get") }
|
||||
fun <T : Any> KClass<T>.gettersMap() = getters().associateBy { it.name.removePrefix("get").firstCharLower() }
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.RestController
|
||||
import java.security.MessageDigest
|
||||
import icu.samnyan.aqua.net.utils.SUCCESS
|
||||
import icu.samnyan.aqua.net.components.JWT
|
||||
import icu.samnyan.aqua.net.db.AquaGameOptions
|
||||
import icu.samnyan.aqua.net.db.AquaNetUser
|
||||
import icu.samnyan.aqua.net.db.AquaUserServices
|
||||
import icu.samnyan.aqua.net.games.mai2.Mai2Import
|
||||
@@ -47,7 +48,7 @@ data class UserProfilePicture(val url: Str, val updatedAtMs: Long)
|
||||
data class UserBasicInfo(
|
||||
val auId: Long, val ghostExtId: Long, val registrationTimeMs: Long,
|
||||
val username: Str, val displayName: Str, val email: Str, val passwordHash: Str, val profileBio: Str,
|
||||
val profilePicture: UserProfilePicture?,
|
||||
val profilePicture: UserProfilePicture?, val gameOptions: Map<Str, Any?>?,
|
||||
)
|
||||
|
||||
private data class UserUpdatedEvent(val user: UserBasicInfo, val isNewlyCreated: Bool)
|
||||
@@ -131,7 +132,7 @@ class Fedy(
|
||||
} caught { UserRegisterRes(error = it) }
|
||||
}
|
||||
|
||||
data class UserUpdateReq(val auId: Long, val fields: Map<Str, Str?>?)
|
||||
data class UserUpdateReq(val auId: Long, val fields: Map<Str, Str?>?, val gameOptions: Map<Str, Any?>?)
|
||||
data class UserUpdateRes(val error: FedyErr? = null, val user: UserBasicInfo? = null)
|
||||
@API("/user/update")
|
||||
fun handleUserUpdate(@RH(KEY_HEADER) key: Str, @RT(REQ_PART) req: UserUpdateReq, @RT(PFP_PART) pfpFile: MultipartFile?): UserUpdateRes = handleFedy(key) {
|
||||
@@ -142,12 +143,16 @@ class Fedy(
|
||||
if (k == "email") { ru.email = us.validateEmail(v) }
|
||||
else us.update(ru, k, v)
|
||||
}
|
||||
pfpFile?.run {
|
||||
pfpFile?.apply {
|
||||
val mime = TIKA.detect(pfpFile.bytes).takeIf { it.startsWith("image/") } ?: (400 - "Invalid file type")
|
||||
val name = "${ru.auId}${MIMES.forName(mime)?.extension ?: ".jpg"}"
|
||||
(paths.aquaNetPortrait.path() / name).writeBytes(bytes)
|
||||
ru.profilePicture = name
|
||||
}
|
||||
req.gameOptions?.apply {
|
||||
val options = ru.gameOptions ?: AquaGameOptions().also { ru.gameOptions = it }
|
||||
forEach { (k, v) -> v?.let { GAME_OPTIONS_FIELDS[k]?.set(options, it) } }
|
||||
}
|
||||
us.userRepo.save(ru)
|
||||
if (fields.containsKey("pwHash") ?: false) { us.clearAllSessions(ru) }
|
||||
UserUpdateRes(user = ru.fedyBasicInfo())
|
||||
@@ -162,7 +167,8 @@ class Fedy(
|
||||
?.let { UserProfilePicture(
|
||||
url = "/uploads/net/portrait/${profilePicture}",
|
||||
updatedAtMs = it.getLastModifiedTime().toMillis()
|
||||
) }
|
||||
) },
|
||||
gameOptions?.let { o -> GAME_OPTIONS_FIELDS.mapValues { it.value.get(o) } }
|
||||
)
|
||||
|
||||
data class DataPullReq(val extId: Long, val game: Str, val createdAtMs: Long, val updatedAtMs: Long, val exportOptions: ExportOptions)
|
||||
@@ -286,17 +292,16 @@ class Fedy(
|
||||
log.info("Fedy /card/unlink : Unlinked card ${card.id} (${card.luid}) from user ${cu.auId} (${cu.username})")
|
||||
}
|
||||
|
||||
fun onUserUpdated(u: AquaNetUser, isNew: Bool = false) = maybeNotifyAsync(FedyEvent(userUpdated = UserUpdatedEvent(u.fedyBasicInfo(), isNew)))
|
||||
fun onCardCreated(luid: Str, extId: Long) = maybeNotifyAsync(FedyEvent(cardCreated = CardCreatedEvent(luid, extId)))
|
||||
fun onCardLinked(luid: Str, oldExtId: Long?, ghostExtId: Long, migratedGames: List<Str>) = maybeNotifyAsync(FedyEvent(cardLinked = CardLinkedEvent(luid, oldExtId, ghostExtId, migratedGames)))
|
||||
fun onCardUnlinked(luid: Str) = maybeNotifyAsync(FedyEvent(cardUnlinked = CardUnlinkedEvent(luid)))
|
||||
fun onDataUpdated(extId: Long, game: Str, removeOldData: Bool) = maybeNotifyAsync({
|
||||
fun onUserUpdated(u: AquaNetUser, isNew: Bool = false) = maybeNotifyAsync { FedyEvent(userUpdated = UserUpdatedEvent(u.fedyBasicInfo(), isNew)) }
|
||||
fun onCardCreated(luid: Str, extId: Long) = maybeNotifyAsync { FedyEvent(cardCreated = CardCreatedEvent(luid, extId)) }
|
||||
fun onCardLinked(luid: Str, oldExtId: Long?, ghostExtId: Long, migratedGames: List<Str>) = maybeNotifyAsync { FedyEvent(cardLinked = CardLinkedEvent(luid, oldExtId, ghostExtId, migratedGames)) }
|
||||
fun onCardUnlinked(luid: Str) = maybeNotifyAsync { FedyEvent(cardUnlinked = CardUnlinkedEvent(luid)) }
|
||||
fun onDataUpdated(extId: Long, game: Str, removeOldData: Bool) = maybeNotifyAsync {
|
||||
val card = cardRepo.findByExtId(extId).orElse(null) ?: return@maybeNotifyAsync null // Card not found, nothing to do
|
||||
FedyEvent(dataUpdated = DataUpdatedEvent(extId, card.isGhost, game, removeOldData))
|
||||
})
|
||||
}
|
||||
|
||||
private fun maybeNotifyAsync(event: FedyEvent) = maybeNotifyAsync({ event })
|
||||
private fun maybeNotifyAsync(getEvent: () -> FedyEvent?) = if (!props.enabled && !suppressEvents.get()) {} else CompletableFuture.runAsync {
|
||||
private fun maybeNotifyAsync(getEvent: () -> FedyEvent?) = if (!props.enabled || suppressEvents.get()) {} else CompletableFuture.runAsync {
|
||||
var event: FedyEvent? = null
|
||||
try {
|
||||
event = getEvent()
|
||||
@@ -355,6 +360,12 @@ class Fedy(
|
||||
const val KEY_HEADER = "X-Fedy-Key"
|
||||
const val REQ_PART = "request"
|
||||
const val PFP_PART = "profilePicture"
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val GAME_OPTIONS_FIELDS = listOf(
|
||||
O::mai2UnlockMusic, O::mai2UnlockChara, O::mai2UnlockCharaMaxLevel, O::mai2UnlockPartners, O::mai2UnlockCollectables, O::mai2UnlockTickets
|
||||
).map { it as Var<O, Any?> }.associateBy { it.name }
|
||||
val log = logger()
|
||||
}
|
||||
}
|
||||
|
||||
typealias O = AquaGameOptions
|
||||
|
||||
@@ -14,7 +14,8 @@ import kotlin.reflect.jvm.jvmErasure
|
||||
class SettingsApi(
|
||||
val us: AquaUserServices,
|
||||
val userRepo: AquaNetUserRepo,
|
||||
val goRepo: AquaGameOptionsRepo
|
||||
val goRepo: AquaGameOptionsRepo,
|
||||
val fedy: Fedy
|
||||
) {
|
||||
// Get all params with SettingField annotation
|
||||
val fields = AquaGameOptions::class.vars()
|
||||
@@ -41,6 +42,6 @@ class SettingsApi(
|
||||
}
|
||||
// Check field type
|
||||
field.setCast(options, value)
|
||||
goRepo.save(options)
|
||||
goRepo.save(options).also { fedy.onUserUpdated(u) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,7 @@ package icu.samnyan.aqua.net.db
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||
import ext.SettingField
|
||||
import jakarta.persistence.Entity
|
||||
import jakarta.persistence.GeneratedValue
|
||||
import jakarta.persistence.GenerationType
|
||||
import jakarta.persistence.Id
|
||||
import jakarta.persistence.*
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
|
||||
@Entity
|
||||
@@ -14,21 +11,29 @@ class AquaGameOptions(
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
var id: Long = 0,
|
||||
|
||||
@SettingField("general")
|
||||
var unlockMusic: Boolean = false,
|
||||
|
||||
@SettingField("general")
|
||||
var unlockChara: Boolean = false,
|
||||
|
||||
@SettingField("general")
|
||||
var unlockCollectables: Boolean = false,
|
||||
|
||||
@SettingField("general")
|
||||
var unlockTickets: Boolean = false,
|
||||
@SettingField("mai2") @Column(name = "mai2_unlock_music")
|
||||
var mai2UnlockMusic: Boolean = false,
|
||||
@SettingField("mai2") @Column(name = "mai2_unlock_chara")
|
||||
var mai2UnlockChara: Boolean = false,
|
||||
@SettingField("mai2") @Column(name = "mai2_unlock_chara_max_level")
|
||||
var mai2UnlockCharaMaxLevel: Boolean = false,
|
||||
@SettingField("mai2") @Column(name = "mai2_unlock_partners")
|
||||
var mai2UnlockPartners: Boolean = false,
|
||||
@SettingField("mai2") @Column(name = "mai2_unlock_collectables")
|
||||
var mai2UnlockCollectables: Boolean = false,
|
||||
@SettingField("mai2") @Column(name = "mai2_unlock_tickets")
|
||||
var mai2UnlockTickets: Boolean = false,
|
||||
|
||||
@SettingField("wacca")
|
||||
var waccaUnlockMusic: Boolean = false,
|
||||
@SettingField("wacca")
|
||||
var waccaUnlockPlates: Boolean = false,
|
||||
@SettingField("wacca")
|
||||
var waccaUnlockCollectables: Boolean = false,
|
||||
@SettingField("wacca")
|
||||
var waccaUnlockTickets: Boolean = false,
|
||||
@SettingField("wacca")
|
||||
var waccaInfiniteWp: Boolean = false,
|
||||
|
||||
@SettingField("wacca")
|
||||
var waccaAlwaysVip: Boolean = false,
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package icu.samnyan.aqua.sega.maimai2.handler
|
||||
|
||||
import ext.int
|
||||
import ext.logger
|
||||
import ext.mapApply
|
||||
import icu.samnyan.aqua.net.games.mai2.Maimai2
|
||||
import icu.samnyan.aqua.sega.general.BaseHandler
|
||||
import icu.samnyan.aqua.sega.general.dao.CardRepository
|
||||
import icu.samnyan.aqua.sega.maimai2.model.Mai2Repos
|
||||
import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2ItemKind
|
||||
import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2UserCharacter
|
||||
import org.springframework.stereotype.Component
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
@@ -15,34 +18,25 @@ class GetUserCharacterHandler(
|
||||
val maimai2: Maimai2,
|
||||
val cardRepo: CardRepository,
|
||||
) : BaseHandler {
|
||||
val itemUnlock = maimai2.itemMapping[Mai2ItemKind.chara.name]?.map { mapOf(
|
||||
"characterId" to it.key,
|
||||
"level" to 9999,
|
||||
"awakening" to 1,
|
||||
"useCount" to 0
|
||||
) }
|
||||
val charaIds = maimai2.itemMapping[Mai2ItemKind.chara.name]?.map { it.key.int() } ?: emptyList()
|
||||
|
||||
init {
|
||||
if (itemUnlock.isNullOrEmpty()) logger.warn("Mai2 item info is empty")
|
||||
if (charaIds.isEmpty()) logger.warn("Mai2 item info is empty")
|
||||
}
|
||||
|
||||
override fun handle(request: Map<String, Any>): Any {
|
||||
val userId = (request["userId"] as Number).toLong()
|
||||
|
||||
// Aqua Net game unlock feature
|
||||
cardRepo.findByExtId(userId).getOrNull()?.aquaUser?.gameOptions?.let { opt ->
|
||||
if (!opt.unlockChara or itemUnlock.isNullOrEmpty()) return@let
|
||||
|
||||
logger.info("Response: ${itemUnlock!!.size} Characters - All unlock")
|
||||
return mapOf(
|
||||
"userId" to userId,
|
||||
"userCharacterList" to itemUnlock
|
||||
)
|
||||
}
|
||||
val gameOptions = cardRepo.findByExtId(userId).getOrNull()?.aquaUser?.gameOptions
|
||||
val userCharacterList = repos.userCharacter.findByUser_Card_ExtId(userId)
|
||||
.let { if (gameOptions?.mai2UnlockChara != true) it else (
|
||||
charaIds.associateWith { Mai2UserCharacter().apply { characterId = it; level = 1 } } +
|
||||
it.associateBy { it.characterId }
|
||||
).values }
|
||||
.let { if (gameOptions?.mai2UnlockCharaMaxLevel != true) it else it.mapApply { level = 9999 } }
|
||||
|
||||
return mapOf(
|
||||
"userId" to userId,
|
||||
"userCharacterList" to repos.userCharacter.findByUser_Card_ExtId(userId)
|
||||
"userCharacterList" to userCharacterList
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -50,10 +50,11 @@ class GetUserItemHandler(
|
||||
// Aqua Net game unlock feature
|
||||
cardRepo.findByExtId(userId).getOrNull()?.aquaUser?.gameOptions?.let { opt ->
|
||||
val items = when {
|
||||
(kind in 5..8) && opt.unlockMusic -> musicUnlock.getValue(kind)
|
||||
(kind in 1..3 || kind == 11) && opt.unlockCollectables -> itemUnlock[kind]
|
||||
(kind == 12) && opt.unlockTickets -> itemUnlock[kind]
|
||||
(kind in 9..10) && opt.unlockChara -> itemUnlock[kind]
|
||||
(kind in 5..8) && opt.mai2UnlockMusic -> musicUnlock.getValue(kind)
|
||||
(kind in 1..3 || kind == 11) && opt.mai2UnlockCollectables -> itemUnlock[kind]
|
||||
(kind == 12) && opt.mai2UnlockTickets -> itemUnlock[kind]
|
||||
(kind == 9) && opt.mai2UnlockChara -> itemUnlock[kind]
|
||||
(kind == 10) && opt.mai2UnlockPartners -> itemUnlock[kind]
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
|
||||
@@ -205,19 +205,19 @@ fun WaccaServer.init() {
|
||||
val go = u.card?.aquaUser?.gameOptions ?: AquaGameOptions()
|
||||
|
||||
// All unlock
|
||||
if (go.unlockMusic && wacca.musicMapping.isNotEmpty()) {
|
||||
if (go.waccaUnlockMusic && wacca.musicMapping.isNotEmpty()) {
|
||||
items[MUSIC_UNLOCK()] = wacca.musicMapping.map { (id, v) -> MUSIC_UNLOCK(u, id, p1 = v.notes.size.long() - 1) }
|
||||
}
|
||||
if (go.unlockTickets) {
|
||||
if (go.waccaUnlockTickets) {
|
||||
var i = 0
|
||||
items[TICKET()] = enabledTickets.flatMap { (1..5).map { TICKET(u, it).apply { id = (i++).toLong() } } }
|
||||
}
|
||||
if (go.unlockChara) {
|
||||
if (go.waccaUnlockPlates) {
|
||||
wacca.itemMapping["plates"]?.let { items[USER_PLATE()] = it.map { (k, _) -> USER_PLATE(u, k.int()) } }
|
||||
}
|
||||
if (go.unlockCollectables) {
|
||||
if (go.waccaUnlockCollectables) {
|
||||
// TODO: Add titles
|
||||
mapOf("icon" to ICON, "plates" to USER_PLATE, "trophy" to TROPHY).map { (name, type) ->
|
||||
mapOf("icon" to ICON, "trophy" to TROPHY).map { (name, type) ->
|
||||
wacca.itemMapping[name]?.let { items[type()] = it.map { (k, _) -> type(u, k.int()) } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
-- Add new unlock columns
|
||||
ALTER TABLE aqua_game_options ADD COLUMN mai2_unlock_music BIT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE aqua_game_options ADD COLUMN mai2_unlock_chara BIT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE aqua_game_options ADD COLUMN mai2_unlock_chara_max_level BIT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE aqua_game_options ADD COLUMN mai2_unlock_partners BIT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE aqua_game_options ADD COLUMN mai2_unlock_collectables BIT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE aqua_game_options ADD COLUMN mai2_unlock_tickets BIT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE aqua_game_options ADD COLUMN wacca_unlock_music BIT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE aqua_game_options ADD COLUMN wacca_unlock_plates BIT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE aqua_game_options ADD COLUMN wacca_unlock_collectables BIT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE aqua_game_options ADD COLUMN wacca_unlock_tickets BIT NOT NULL DEFAULT 0;
|
||||
|
||||
-- Migrate data
|
||||
UPDATE aqua_game_options SET
|
||||
mai2_unlock_music = unlock_music,
|
||||
mai2_unlock_chara = unlock_chara,
|
||||
mai2_unlock_chara_max_level = unlock_chara,
|
||||
mai2_unlock_partners = unlock_chara,
|
||||
mai2_unlock_collectables = unlock_collectables,
|
||||
mai2_unlock_tickets = unlock_tickets,
|
||||
wacca_unlock_music = unlock_music,
|
||||
wacca_unlock_plates = unlock_chara | unlock_collectables,
|
||||
wacca_unlock_collectables = unlock_collectables,
|
||||
wacca_unlock_tickets = unlock_tickets;
|
||||
|
||||
-- Drop old columns
|
||||
ALTER TABLE aqua_game_options DROP COLUMN unlock_music;
|
||||
ALTER TABLE aqua_game_options DROP COLUMN unlock_chara;
|
||||
ALTER TABLE aqua_game_options DROP COLUMN unlock_collectables;
|
||||
ALTER TABLE aqua_game_options DROP COLUMN unlock_tickets;
|
||||
Reference in New Issue
Block a user