Skip to content
This repository has been archived by the owner on Oct 20, 2023. It is now read-only.

Commit

Permalink
REFACTOR(pjsk): remove specific pjsk feature (see #556)
Browse files Browse the repository at this point in the history
  • Loading branch information
StarWishsama committed Feb 22, 2023
1 parent c6f2342 commit e79754f
Show file tree
Hide file tree
Showing 16 changed files with 130 additions and 1,558 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ package ren.natsuyuk1.comet.commands
import moe.sdl.yac.core.subcommands
import moe.sdl.yac.parameters.arguments.argument
import moe.sdl.yac.parameters.arguments.default
import moe.sdl.yac.parameters.options.flag
import moe.sdl.yac.parameters.options.option
import moe.sdl.yac.parameters.types.int
import moe.sdl.yac.parameters.types.long
import ren.natsuyuk1.comet.api.Comet
import ren.natsuyuk1.comet.api.command.*
Expand All @@ -14,21 +12,16 @@ import ren.natsuyuk1.comet.api.message.asImage
import ren.natsuyuk1.comet.api.message.buildMessageWrapper
import ren.natsuyuk1.comet.api.user.CometUser
import ren.natsuyuk1.comet.commands.service.ProjectSekaiService
import ren.natsuyuk1.comet.consts.cometClient
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.ProjectSekaiAPI.getCheerPredictData
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.objects.MusicDifficulty
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.objects.kit33.toMessageWrapper
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.toMessageWrapper
import ren.natsuyuk1.comet.objects.config.FeatureConfig
import ren.natsuyuk1.comet.objects.pjsk.ProjectSekaiUserData
import ren.natsuyuk1.comet.objects.pjsk.local.PJSKProfileMusic
import ren.natsuyuk1.comet.objects.pjsk.local.ProjectSekaiMusic
import ren.natsuyuk1.comet.service.image.ProjectSekaiImageService
import ren.natsuyuk1.comet.util.pjsk.pjskFolder
import ren.natsuyuk1.comet.util.toMessageWrapper
import ren.natsuyuk1.comet.utils.file.isBlank
import ren.natsuyuk1.comet.utils.file.isType
import ren.natsuyuk1.comet.utils.math.NumberUtil.formatDigests
import java.io.File

val PROJECTSEKAI by lazy {
Expand All @@ -37,7 +30,6 @@ val PROJECTSEKAI by lazy {
listOf("pjsk", "啤酒烧烤"),
"查询 Project Sekai: Colorful Stage 相关信息",
" /pjsk bind -i [账号 ID] - 绑定账号\n" +
"/pjsk event (排名) 查询当前活动信息\n" +
"/pjsk pred 查询当前活动结束预测分数\n" +
"/pjsk info 查询账号信息\n" +
"/pjsk chart 查询歌曲谱面\n" +
Expand All @@ -57,10 +49,7 @@ class ProjectSekaiCommand(
if (FeatureConfig.data.projectSekaiSetting.enable) {
subcommands(
Bind(subject, sender, user),
Event(subject, sender, user),
Prediction(subject, sender, user),
Info(subject, sender, user),
Best30(subject, sender, user),
Chart(subject, sender, user),
Music(subject, sender, user),
)
Expand All @@ -74,11 +63,7 @@ class ProjectSekaiCommand(
}

if (currentContext.invokedSubcommand == null) {
if (ProjectSekaiUserData.isBound(user.id.value)) {
subject.sendMessage(ProjectSekaiService.queryUserEventInfo(user, 0))
} else {
subject.sendMessage(property.helpText.toMessageWrapper())
}
subject.sendMessage(property.helpText.toMessageWrapper())
}
}

Expand Down Expand Up @@ -144,75 +129,6 @@ class ProjectSekaiCommand(
}
}

class Event(
override val subject: PlatformCommandSender,
override val sender: PlatformCommandSender,
override val user: CometUser,
) : CometSubCommand(subject, sender, user, EVENT) {

companion object {
val EVENT = SubCommandProperty(
"event",
listOf("活动排名", "活排"),
PROJECTSEKAI,
)
}

private val position by argument("排名位置", "欲查询的指定排名").int().default(0)

override suspend fun run() {
subject.sendMessage(ProjectSekaiService.queryUserEventInfo(user, position))
}
}

class Prediction(
override val subject: PlatformCommandSender,
override val sender: PlatformCommandSender,
override val user: CometUser,
) : CometSubCommand(subject, sender, user, PREDICTION) {

companion object {
val PREDICTION = SubCommandProperty(
"pred",
listOf("prediction", "预测", "预测线"),
PROJECTSEKAI,
)
}

private val event by option("-e", "--event").flag(default = false)

override suspend fun run() {
if (event) {
cometClient.getCheerPredictData().toMessageWrapper().takeIf {
!it.isEmpty()
}?.let {
subject.sendMessage(it)
}
} else {
subject.sendMessage(ProjectSekaiService.fetchPrediction())
}
}
}

class Best30(
override val subject: PlatformCommandSender,
override val sender: PlatformCommandSender,
override val user: CometUser,
) : CometSubCommand(subject, sender, user, BEST30) {

companion object {
val BEST30 = SubCommandProperty(
"best30",
listOf("b30"),
PROJECTSEKAI,
)
}

override suspend fun run() {
subject.sendMessage(ProjectSekaiService.b30(user))
}
}

class Chart(
override val subject: PlatformCommandSender,
override val sender: PlatformCommandSender,
Expand Down Expand Up @@ -249,8 +165,6 @@ class ProjectSekaiCommand(
FeatureConfig.data.projectSekaiSetting.minSimilarity,
)

val extraInfo = musicInfo?.id?.let { PJSKProfileMusic.getMusicInfo(it) }

if (musicInfo == null) {
subject.sendMessage("找不到你想要搜索的歌曲哦".toMessageWrapper())
return
Expand All @@ -273,18 +187,6 @@ class ProjectSekaiCommand(
subject.sendMessage(
buildMessageWrapper {
appendTextln("搜索准确度: $sim")
if (extraInfo != null) {
val bpmText = if (!extraInfo.bpms.isNullOrEmpty()) {
buildString {
extraInfo.bpms.forEach { bi ->
append("${bi.bpm.formatDigests(0)} - ")
}
}.removeSuffix(" - ")
} else {
extraInfo.bpm.formatDigests(0)
}
appendTextln("BPM: $bpmText")
}
appendElement(chartFile.asImage())
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,17 @@ package ren.natsuyuk1.comet.commands.service
import ren.natsuyuk1.comet.api.message.MessageWrapper
import ren.natsuyuk1.comet.api.user.CometUser
import ren.natsuyuk1.comet.consts.cometClient
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.ProjectSekaiAPI.getRankSeasonInfo
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.ProjectSekaiAPI.getSpecificRankInfo
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.ProjectSekaiAPI.getUserEventInfo
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.ProjectSekaiAPI.getUserInfo
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.objects.SekaiEventStatus
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.objects.kit33.toMessageWrapper
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.objects.toMessageWrapper
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.toMessageWrapper
import ren.natsuyuk1.comet.service.ProjectSekaiManager
import ren.natsuyuk1.comet.service.image.ProjectSekaiImageService.drawEventInfo
import ren.natsuyuk1.comet.util.toMessageWrapper
import ren.natsuyuk1.comet.utils.skiko.SkikoHelper
import ren.natsuyuk1.comet.objects.pjsk.ProjectSekaiData as pjskData
import ren.natsuyuk1.comet.objects.pjsk.ProjectSekaiUserData as pjskUserData
import ren.natsuyuk1.comet.service.ProjectSekaiManager as pjskHelper

object ProjectSekaiService {
fun bindAccount(user: CometUser, userID: Long): MessageWrapper {
if (pjskUserData.hasUserID(userID)) {
return "该账号已被绑定,如果是你的账号被错误绑定请联系管理员".toMessageWrapper()
}

return if (pjskUserData.isBound(user.id.value)) {
pjskUserData.updateID(user.id.value, userID)
"已更改你绑定的账号 ID!".toMessageWrapper()
Expand All @@ -30,75 +23,10 @@ object ProjectSekaiService {
}
}

suspend fun queryUserEventInfo(user: CometUser, position: Int): MessageWrapper {
val userData = pjskUserData.getUserPJSKData(user.id.value)
val currentEventId = pjskData.getEventId() ?: return "获取当前活动信息失败, 请稍后再试".toMessageWrapper()

if (position == 0 && userData == null) {
return "你还没有绑定过世界计划账号, 使用 /pjsk bind -i [你的ID] 绑定".toMessageWrapper()
}

return when (pjskHelper.getCurrentEventStatus()) {
SekaiEventStatus.ONGOING, SekaiEventStatus.END -> {
if (position == 0 && userData != null) {
val cur = cometClient.getUserEventInfo(currentEventId, userData.userID)
if (SkikoHelper.isSkikoLoaded()) {
cur.drawEventInfo(currentEventId, userData)
} else {
cur.toMessageWrapper(userData, currentEventId)
}
} else {
val cur = cometClient.getSpecificRankInfo(currentEventId, position)

if (SkikoHelper.isSkikoLoaded()) {
cur.drawEventInfo(currentEventId)
} else {
cur.toMessageWrapper(null, currentEventId)
}
}
}

SekaiEventStatus.COUNTING -> {
"活动数据统计中, 请耐心等待~".toMessageWrapper()
}

else -> {
"获取当前活动信息失败, 请稍后再试".toMessageWrapper()
}
}
}

fun fetchPrediction(): MessageWrapper {
val pred = pjskData.getCurrentPredictionInfo()
val predUpdateTime = pjskData.getPredictionInfoTime()

if (pred == null || predUpdateTime == null) {
return "活动预测线信息暂未获取, 稍等片刻哦~".toMessageWrapper()
}

return pred.toMessageWrapper(predUpdateTime)
}

suspend fun queryUserInfo(userID: Long): MessageWrapper {
val rankSeason = ProjectSekaiManager.getLatestRankSeason() ?: return "查询排位数据时出现异常".toMessageWrapper()

val rankInfo = cometClient.getRankSeasonInfo(userID, rankSeason)

return cometClient.getUserInfo(userID).toMessageWrapper().apply {
appendLine()
appendLine()
appendText(rankInfo.getRankInfo())
}
}

suspend fun b30(user: CometUser): MessageWrapper {
if (!SkikoHelper.isSkikoLoaded()) {
return "Comet 的图像生成库还没加载, 生成不了图片捏".toMessageWrapper()
}

val userData = pjskUserData.getUserPJSKData(user.id.value)
?: return "你还没有绑定过世界计划账号, 使用 /pjsk bind -i [你的ID] 绑定".toMessageWrapper()

return cometClient.getUserInfo(userData.userID).generateBest30()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ val defaultCommands: List<AbstractCommandNode<*>> =
PROJECTSEKAI,
listOf(
ProjectSekaiCommand.Bind.BIND,
ProjectSekaiCommand.Event.EVENT,
ProjectSekaiCommand.Prediction.PREDICTION,
ProjectSekaiCommand.Info.INFO,
ProjectSekaiCommand.Chart.CHART,
ProjectSekaiCommand.Music.MUSIC,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ import ren.natsuyuk1.comet.network.CometClient
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.objects.ProjectSekaiEventList
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.objects.ProjectSekaiRankSeasonInfo
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.objects.ProjectSekaiUserInfo
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.objects.SekaiProfileEventInfo
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.objects.kit33.PJSKCheerfulPreditionInfo
import ren.natsuyuk1.comet.network.thirdparty.projectsekai.objects.kit33.PJSKEventPredictionInfo
import ren.natsuyuk1.comet.utils.json.serializeTo

private val logger = mu.KotlinLogging.logger {}
Expand All @@ -48,12 +45,6 @@ object ProjectSekaiAPI {
*/
private const val PJSEKAI_URL = "https://api.pjsek.ai/database/master"

/**
* 33 Kit
* https://3-3.dev/
*/
private const val THREE3KIT_URL = "https://33.dsml.hk/pred"

private suspend fun CometClient.profileRequest(
param: String,
builder: URLBuilder.(URLBuilder) -> Unit = {},
Expand All @@ -79,34 +70,6 @@ object ProjectSekaiAPI {
}
}

suspend fun CometClient.getUserEventInfo(eventID: Int, userID: Long): SekaiProfileEventInfo {
logger.debug { "Fetching project sekai event $eventID rank for user $userID" }

val resp = profileRequest("/api/user/%7Buser_id%7D/event/$eventID/ranking") {
parameters.append("targetUserId", userID.toString())
}

if (resp.status != HttpStatusCode.OK) {
error("API return code isn't OK (${resp.status}), raw request url: ${resp.call.request.url}")
}

return json.decodeFromString(resp.bodyAsText().also { logger.debug { "Raw content: $it" } })
}

suspend fun CometClient.getSpecificRankInfo(eventID: Int, rankPosition: Int): SekaiProfileEventInfo {
logger.debug { "Fetching project sekai event $eventID rank position at $rankPosition" }

val resp = profileRequest("/api/user/%7Buser_id%7D/event/$eventID/ranking") {
parameters.append("targetRank", rankPosition.toString())
}

if (resp.status != HttpStatusCode.OK) {
error("API return code isn't OK (${resp.status}), raw request url: ${resp.call.request.url}")
}

return json.decodeFromString(resp.bodyAsText().also { logger.debug { "Raw content: $it" } })
}

suspend fun CometClient.getEventList(limit: Int = 12, startAt: Int = -1, skip: Int = 0): ProjectSekaiEventList {
logger.debug { "Fetching project sekai event list" }

Expand All @@ -121,12 +84,6 @@ object ProjectSekaiAPI {
}.bodyAsText().serializeTo(json)
}

suspend fun CometClient.getRankPredictionInfo(): PJSKEventPredictionInfo {
logger.debug { "Fetching project sekai rank prediction info" }

return client.get(THREE3KIT_URL).bodyAsText().serializeTo(json)
}

suspend fun CometClient.getUserInfo(id: Long): ProjectSekaiUserInfo {
logger.debug { "Fetching project sekai user info for $id" }

Expand All @@ -152,16 +109,4 @@ object ProjectSekaiAPI {

return json.decodeFromString(resp.bodyAsText().also { logger.debug { "Raw content: $it" } })
}

suspend fun CometClient.getCheerPredictData(): PJSKCheerfulPreditionInfo {
logger.debug { "Fetching project sekai cheerful event predict info" }

val resp = client.get("https://33.dsml.hk/cheer-pred")

if (resp.status != HttpStatusCode.OK) {
error("API return code isn't OK (${resp.status}), raw request url: ${resp.call.request.url}")
}

return json.decodeFromString(resp.bodyAsText().also { logger.debug { "Raw content: $it" } })
}
}
Loading

0 comments on commit e79754f

Please sign in to comment.