mirror of
https://github.com/MewoLab/AquaDX.git
synced 2026-02-09 14:57:59 +08:00
[+] Maimai item unlock
This commit is contained in:
@@ -12,6 +12,7 @@ import kotlinx.serialization.json.Json
|
|||||||
import kotlinx.serialization.json.JsonNamingStrategy
|
import kotlinx.serialization.json.JsonNamingStrategy
|
||||||
import org.apache.tika.Tika
|
import org.apache.tika.Tika
|
||||||
import org.apache.tika.mime.MimeTypes
|
import org.apache.tika.mime.MimeTypes
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.http.HttpStatus
|
import org.springframework.http.HttpStatus
|
||||||
import org.springframework.web.bind.annotation.RequestBody
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
import org.springframework.web.bind.annotation.RequestHeader
|
import org.springframework.web.bind.annotation.RequestHeader
|
||||||
@@ -67,6 +68,16 @@ val HTTP = HttpClient(CIO) {
|
|||||||
val TIKA = Tika()
|
val TIKA = Tika()
|
||||||
val MIMES = MimeTypes.getDefaultMimeTypes()
|
val MIMES = MimeTypes.getDefaultMimeTypes()
|
||||||
|
|
||||||
|
// Class resource
|
||||||
|
object Ext {
|
||||||
|
val log = LoggerFactory.getLogger(Ext::class.java)
|
||||||
|
}
|
||||||
|
fun res(name: Str) = Ext::class.java.getResourceAsStream(name)
|
||||||
|
fun resStr(name: Str) = res(name)?.reader()?.readText()
|
||||||
|
inline fun <reified T> resJson(name: Str, warn: Boolean = true) = resStr(name)?.let {
|
||||||
|
JSON.decodeFromString<T>(it)
|
||||||
|
} ?: run { if (warn) Ext.log.warn("Resource $name is not found"); null }
|
||||||
|
|
||||||
// Date and time
|
// Date and time
|
||||||
fun millis() = System.currentTimeMillis()
|
fun millis() = System.currentTimeMillis()
|
||||||
val DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
val DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
||||||
|
|||||||
@@ -68,7 +68,13 @@ data class GenericMusicMeta(
|
|||||||
@Serializable
|
@Serializable
|
||||||
data class GenericNoteMeta(
|
data class GenericNoteMeta(
|
||||||
val lv: Double,
|
val lv: Double,
|
||||||
val lvId: Int
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class GenericItemMeta(
|
||||||
|
val name: String? = null,
|
||||||
|
val disable: Boolean? = null,
|
||||||
|
val ver: String? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
// Here are some interfaces to generalize across multiple games
|
// Here are some interfaces to generalize across multiple games
|
||||||
@@ -111,12 +117,10 @@ interface GenericPlaylogRepo<T: IGenericGamePlaylog> : JpaRepository<T, Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class GameApiController(name: String) {
|
abstract class GameApiController(name: String) {
|
||||||
val musicMapping: Map<Int, GenericMusicMeta> = GameApiController::class.java
|
val musicMapping = resJson<Map<String, GenericMusicMeta>>("/meta/$name/music.json")
|
||||||
.getResourceAsStream("/meta/$name/music.json")
|
?.mapKeys { it.key.toInt() } ?: emptyMap()
|
||||||
.use { it?.reader()?.readText() }
|
|
||||||
?.let { JSON.decodeFromString<Map<String, GenericMusicMeta>>(it) }
|
val itemMapping = resJson<Map<String, Map<String, GenericItemMeta>>>("/meta/$name/items.json") ?: emptyMap()
|
||||||
?.mapKeys { it.key.toInt() }
|
|
||||||
?: emptyMap()
|
|
||||||
|
|
||||||
abstract val us: AquaUserServices
|
abstract val us: AquaUserServices
|
||||||
abstract val userDataRepo: GenericUserDataRepo<*>
|
abstract val userDataRepo: GenericUserDataRepo<*>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import icu.samnyan.aqua.net.games.Maimai2
|
|||||||
import icu.samnyan.aqua.sega.general.dao.CardRepository
|
import icu.samnyan.aqua.sega.general.dao.CardRepository
|
||||||
import icu.samnyan.aqua.sega.maimai2.handler.BaseHandler
|
import icu.samnyan.aqua.sega.maimai2.handler.BaseHandler
|
||||||
import icu.samnyan.aqua.sega.maimai2.model.Mai2Repos
|
import icu.samnyan.aqua.sega.maimai2.model.Mai2Repos
|
||||||
|
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserItem.Mai2ItemKind
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.data.domain.PageRequest
|
import org.springframework.data.domain.PageRequest
|
||||||
@@ -25,7 +26,21 @@ class GetUserItemHandler(
|
|||||||
"itemId" to it.key,
|
"itemId" to it.key,
|
||||||
"stock" to 1,
|
"stock" to 1,
|
||||||
"isValid" to true,
|
"isValid" to true,
|
||||||
).toMap() } }
|
) } }
|
||||||
|
|
||||||
|
val itemUnlock = Mai2ItemKind.ALL.filter { it.key in 1..3 || it.key in 9..12 }
|
||||||
|
.mapValues { (kind, kindEnum) -> maimai2.itemMapping[kindEnum.name]?.map { (id, item) ->
|
||||||
|
mapOf(
|
||||||
|
"itemKind" to kind,
|
||||||
|
"itemId" to id,
|
||||||
|
"stock" to 1,
|
||||||
|
"isValid" to true,
|
||||||
|
) } ?: emptyList() }
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (musicUnlock[5].isNullOrEmpty()) logger.warn("Mai2 music info is empty")
|
||||||
|
if (itemUnlock[1].isNullOrEmpty()) logger.warn("Mai2 item info is empty")
|
||||||
|
}
|
||||||
|
|
||||||
override fun handle(request: Map<String, Any>): Any {
|
override fun handle(request: Map<String, Any>): Any {
|
||||||
val userId = (request["userId"] as Number).toLong()
|
val userId = (request["userId"] as Number).toLong()
|
||||||
@@ -35,19 +50,28 @@ class GetUserItemHandler(
|
|||||||
val kind = (nextIndexVal / MULT).toInt()
|
val kind = (nextIndexVal / MULT).toInt()
|
||||||
val nextIndex = (nextIndexVal % MULT).toInt()
|
val nextIndex = (nextIndexVal % MULT).toInt()
|
||||||
val pageNum = nextIndex / maxCount
|
val pageNum = nextIndex / maxCount
|
||||||
|
val kindType = Mai2ItemKind.ALL[kind]?.name
|
||||||
|
|
||||||
// Aqua Net game unlock feature
|
// Aqua Net game unlock feature
|
||||||
cardRepo.findByExtId(userId).getOrNull()?.aquaUser?.gameOptions?.let { opt ->
|
cardRepo.findByExtId(userId).getOrNull()?.aquaUser?.gameOptions?.let { opt ->
|
||||||
// All Music unlock
|
val items = when {
|
||||||
if (kind in 5..8 && opt.unlockMusic) {
|
(kind in 5..8) && opt.unlockMusic -> musicUnlock.getValue(kind)
|
||||||
logger.info("Response: ${maimai2.musicMapping.size} items - Music unlock")
|
(kind in 1..3 || kind == 11) && opt.unlockCollectables -> itemUnlock[kind]
|
||||||
return mapOf(
|
(kind == 12) && opt.unlockTickets -> itemUnlock[kind]
|
||||||
"userId" to userId,
|
(kind in 9..10) && opt.unlockChara -> itemUnlock[kind]
|
||||||
"nextIndex" to 0,
|
else -> emptyList()
|
||||||
"itemKind" to kind,
|
|
||||||
"userItemList" to musicUnlock.getValue(kind)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no items are found, disable the unlock feature
|
||||||
|
if (items.isNullOrEmpty()) return@let
|
||||||
|
|
||||||
|
logger.info("Response: ${items.size} $kindType items - All unlock")
|
||||||
|
return mapOf(
|
||||||
|
"userId" to userId,
|
||||||
|
"nextIndex" to 0,
|
||||||
|
"itemKind" to kind,
|
||||||
|
"userItemList" to items
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val dbPage = repos.userItem.findByUser_Card_ExtIdAndItemKind(userId, kind, PageRequest.of(pageNum, maxCount))
|
val dbPage = repos.userItem.findByUser_Card_ExtIdAndItemKind(userId, kind, PageRequest.of(pageNum, maxCount))
|
||||||
@@ -60,7 +84,7 @@ class GetUserItemHandler(
|
|||||||
"userItemList" to dbPage.content
|
"userItemList" to dbPage.content
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info("Response: ${dbPage.numberOfElements} items")
|
logger.info("Response: ${dbPage.numberOfElements} $kindType items")
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
package icu.samnyan.aqua.sega.maimai2.model.userdata;
|
package icu.samnyan.aqua.sega.maimai2.model.userdata;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
@@ -40,15 +42,26 @@ public class UserItem implements Serializable {
|
|||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int KIND_NAMEPLATE = 1;
|
public enum Mai2ItemKind {
|
||||||
public static final int KIND_TITLE = 2;
|
plate(1),
|
||||||
public static final int KIND_ICON = 3;
|
title(2),
|
||||||
public static final int KIND_MUSIC_UNLOCK = 5;
|
icon(3),
|
||||||
public static final int KIND_MUSIC_MASTER_UNLOCK = 6;
|
musicUnlock(5),
|
||||||
public static final int KIND_MUSIC_REMASTER_UNLOCK = 7;
|
musicMasterUnlock(6),
|
||||||
public static final int KIND_MUSIC_STRONG_UNLOCK = 8;
|
musicRemasterUnlock(7),
|
||||||
public static final int KIND_CHARACTER = 9;
|
musicStrongUnlock(8),
|
||||||
public static final int KIND_PARTNER = 10;
|
chara(9),
|
||||||
public static final int KIND_FRAME = 11;
|
partner(10),
|
||||||
public static final int KIND_TICKETS = 12;
|
frame(11),
|
||||||
|
ticket(12);
|
||||||
|
|
||||||
|
public final int value;
|
||||||
|
|
||||||
|
Mai2ItemKind(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Map<Integer, Mai2ItemKind> ALL = Arrays.stream(Mai2ItemKind.class.getEnumConstants())
|
||||||
|
.map(k -> Map.entry(k.value, k)).collect(HashMap::new, (m, v) -> m.put(v.getKey(), v.getValue()), Map::putAll);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package icu.samnyan.aqua.spring
|
|||||||
|
|
||||||
import ch.qos.logback.classic.spi.ILoggingEvent
|
import ch.qos.logback.classic.spi.ILoggingEvent
|
||||||
import ch.qos.logback.core.pattern.CompositeConverter
|
import ch.qos.logback.core.pattern.CompositeConverter
|
||||||
import ext.center
|
|
||||||
import ext.get
|
import ext.get
|
||||||
import org.springframework.boot.ansi.AnsiColor
|
import org.springframework.boot.ansi.AnsiColor
|
||||||
import org.springframework.boot.ansi.AnsiOutput
|
import org.springframework.boot.ansi.AnsiOutput
|
||||||
@@ -10,7 +9,7 @@ import org.springframework.boot.ansi.AnsiOutput
|
|||||||
private const val PROJECT_PACKAGE_PREFIX = "icu.samnyan.aqua"
|
private const val PROJECT_PACKAGE_PREFIX = "icu.samnyan.aqua"
|
||||||
private const val SEGA_PACKAGE_PREFIX = "icu.samnyan.aqua.sega"
|
private const val SEGA_PACKAGE_PREFIX = "icu.samnyan.aqua.sega"
|
||||||
private val SYSTEM_COLOR = AnsiColor.WHITE
|
private val SYSTEM_COLOR = AnsiColor.WHITE
|
||||||
private val SEGA_COLOR = AnsiColor.MAGENTA
|
private val SEGA_COLOR = AnsiColor.BRIGHT_CYAN
|
||||||
private val MISC_COLOR = AnsiColor.BRIGHT_BLUE
|
private val MISC_COLOR = AnsiColor.BRIGHT_BLUE
|
||||||
|
|
||||||
class LoggerComponent : CompositeConverter<ILoggingEvent>() {
|
class LoggerComponent : CompositeConverter<ILoggingEvent>() {
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ mkdir -p "$DIR/ongeki" "$DIR/mai2" "$DIR/chu3"
|
|||||||
|
|
||||||
curl "https://aquadx.net/d/ongeki/00/all-music.json" -o "$DIR/ongeki/music.json"
|
curl "https://aquadx.net/d/ongeki/00/all-music.json" -o "$DIR/ongeki/music.json"
|
||||||
curl "https://aquadx.net/d/mai2/00/all-music.json" -o "$DIR/mai2/music.json"
|
curl "https://aquadx.net/d/mai2/00/all-music.json" -o "$DIR/mai2/music.json"
|
||||||
|
curl "https://aquadx.net/d/mai2/00/all-items.json" -o "$DIR/mai2/items.json"
|
||||||
curl "https://aquadx.net/d/chu3/00/all-music.json" -o "$DIR/chu3/music.json"
|
curl "https://aquadx.net/d/chu3/00/all-music.json" -o "$DIR/chu3/music.json"
|
||||||
|
|||||||
Reference in New Issue
Block a user