Skip to content

Commit

Permalink
0.5.0-pre
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoxue1272 committed Jul 3, 2023
1 parent 1c5ac18 commit 086cc8d
Show file tree
Hide file tree
Showing 17 changed files with 859 additions and 682 deletions.
52 changes: 8 additions & 44 deletions src/main/kotlin/io/tiangou/EventHandler.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
package io.tiangou

import io.tiangou.EventHandleConfig.GroupMessageHandleEnum.*
import io.tiangou.repository.UserCacheRepository
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.data.ReadOnlyPluginConfig
import net.mamoe.mirai.console.data.ValueDescription
import net.mamoe.mirai.console.data.value
import net.mamoe.mirai.event.EventHandler
import net.mamoe.mirai.event.SimpleListenerHost
import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent
Expand Down Expand Up @@ -57,7 +52,7 @@ object EventHandler : SimpleListenerHost() {
log.warning("qq user:[${sender.id}]", it)
reply("${it.message}")
} else {
log.warning("processing valo bot logic throw throwable", it)
log.warning("processing valorant bot logic throw throwable", it)
reply("error: ${it.message}")
}
}
Expand All @@ -79,49 +74,18 @@ object EventHandler : SimpleListenerHost() {
}

private fun GroupMessageEvent.isGroupMessageAllow(): Boolean =
when (EventHandleConfig.config.groupMessageHandleStorage) {
AT_AND_QUOTE_REPLY -> message.firstIsInstanceOrNull<At>()?.target == bot.id
when (Global.eventConfig.groupMessageHandleStorage) {
Global.GroupMessageHandleEnum.AT_AND_QUOTE_REPLY -> message.firstIsInstanceOrNull<At>()?.target == bot.id
|| message.firstIsInstanceOrNull<QuoteReply>()?.source?.fromId == bot.id

AT -> message.firstIsInstanceOrNull<At>()?.target == bot.id
QUOTE_REPLY -> message.firstIsInstanceOrNull<QuoteReply>()?.source?.fromId == bot.id
NONE -> false
ALL -> true
Global.GroupMessageHandleEnum.AT -> message.firstIsInstanceOrNull<At>()?.target == bot.id
Global.GroupMessageHandleEnum.QUOTE_REPLY -> message.firstIsInstanceOrNull<QuoteReply>()?.source?.fromId == bot.id
Global.GroupMessageHandleEnum.NONE -> false
Global.GroupMessageHandleEnum.ALL -> true
}

private suspend fun MessageEvent.inputNotFoundHandle() {
if (EventHandleConfig.config.isWarnOnInputNotFound) reply("未找到对应操作,请检查输入是否正确")
}

}

object EventHandleConfig : ReadOnlyPluginConfig("event-handle-config") {

@ValueDescription("事件监听配置")
val config: EventHandleConfigData by value(EventHandleConfigData())

@Serializable
data class EventHandleConfigData(
@ValueDescription("当输入不正确时发出警告(为true时回复未知操作,false不回复消息)")
val isWarnOnInputNotFound: Boolean = true,
@ValueDescription(
"""
配置群内消息监听策略: AT: 监听AT消息, AT_AND_QUOTE_REPLY: 监听AT和引用回复消息, QUOTE_REPLY: 监听引用回复消息, NONE: 不监听群内消息, ALL: 监听所有消息
默认为: AT_AND_QUOTE_REPLY, 就是监听 AT消息和引用回复消息.
"""
)
val groupMessageHandleStorage: GroupMessageHandleEnum = AT_AND_QUOTE_REPLY,
@ValueDescription("指令等待输入超时时间,请不要设置太短或太长,分为单位,默认5分钟")
val waitTimeoutMinutes: Int = 5
)

@Serializable
enum class GroupMessageHandleEnum {
AT,
QUOTE_REPLY,
AT_AND_QUOTE_REPLY,
NONE,
ALL
if (Global.eventConfig.isWarnOnInputNotFound) reply("未找到对应操作,请检查输入是否正确")
}

}
Expand Down
39 changes: 35 additions & 4 deletions src/main/kotlin/io/tiangou/ValorantBotPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ package io.tiangou
import io.tiangou.cron.CronTaskCommand
import io.tiangou.cron.CronTaskManager
import io.tiangou.cron.StoreCachesCleanTask
import io.tiangou.repository.PersistenceDataInitiator
import io.tiangou.repository.persistnce.PersistenceDataInitiator
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import net.mamoe.mirai.console.command.CommandManager
import net.mamoe.mirai.console.command.CommandSender
import net.mamoe.mirai.console.data.ReadOnlyPluginConfig
import net.mamoe.mirai.console.data.ValueDescription
import net.mamoe.mirai.console.data.value
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import net.mamoe.mirai.contact.Contact
Expand Down Expand Up @@ -75,7 +79,7 @@ object ValorantBotPlugin : KotlinPlugin(
) {

override fun onEnable() {
EventHandleConfig.reload()
Global.reload()
CronTaskManager.reload()
runBlocking { PersistenceDataInitiator.init() }
EventHandler.registerTo(GlobalEventChannel)
Expand All @@ -94,9 +98,9 @@ object ValorantBotPlugin : KotlinPlugin(

}

object Global {
@property:JvmStatic
object Global : ReadOnlyPluginConfig("plugin-config") {

@property:JvmStatic
val json = Json {
encodeDefaults = true
useAlternativeNames = false
Expand All @@ -108,6 +112,33 @@ object Global {
val coroutineScope: CoroutineScope
get() = ValorantBotPlugin

@ValueDescription("事件监听配置")
val eventConfig: EventHandleConfigData by value(EventHandleConfigData())

@Serializable
data class EventHandleConfigData(
@ValueDescription("当输入不正确时发出警告(为true时回复未知操作,false不回复消息)")
val isWarnOnInputNotFound: Boolean = true,
@ValueDescription(
"""
配置群内消息监听策略: AT: 监听AT消息, AT_AND_QUOTE_REPLY: 监听AT和引用回复消息, QUOTE_REPLY: 监听引用回复消息, NONE: 不监听群内消息, ALL: 监听所有群消息
默认为: AT_AND_QUOTE_REPLY, 就是监听 AT消息和引用回复消息.
"""
)
val groupMessageHandleStorage: GroupMessageHandleEnum = GroupMessageHandleEnum.AT_AND_QUOTE_REPLY,
@ValueDescription("指令等待输入超时时间,请不要设置太短或太长,分为单位,默认5分钟")
val waitTimeoutMinutes: Int = 5
)

@Serializable
enum class GroupMessageHandleEnum {
AT,
QUOTE_REPLY,
AT_AND_QUOTE_REPLY,
NONE,
ALL
}

}


Expand Down
6 changes: 4 additions & 2 deletions src/main/kotlin/io/tiangou/api/RiotApi.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@file:JvmName("RiotApiKt")
@file:UseSerializers(AtomicReferenceSerializer::class)

package io.tiangou.api

Expand All @@ -10,6 +11,7 @@ import io.tiangou.api.data.*
import io.tiangou.other.http.ClientData
import io.tiangou.serializer.AtomicReferenceSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import net.mamoe.mirai.console.util.safeCast
import java.util.concurrent.atomic.AtomicReference
import kotlin.coroutines.coroutineContext
Expand Down Expand Up @@ -142,8 +144,8 @@ sealed class RiotApi<in T : Any, out R : Any> : ApiInvoker<T, R> {

@Serializable
class RiotClientData(
private val authToken: @Serializable(AtomicReferenceSerializer::class) AtomicReference<String?> = AtomicReference(),
private val xRiotEntitlementsJwt: @Serializable(AtomicReferenceSerializer::class) AtomicReference<String?> = AtomicReference(),
private val authToken: AtomicReference<String?> = AtomicReference(),
private val xRiotEntitlementsJwt: AtomicReference<String?> = AtomicReference(),
var puuid: String? = null,
var region: String? = null,
var shard: String? = null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.tiangou.cron

import io.tiangou.repository.PersistenceDataInitiator
import io.tiangou.repository.persistnce.PersistenceDataInitiator
import kotlinx.serialization.Serializable

@Serializable
Expand Down
4 changes: 4 additions & 0 deletions src/main/kotlin/io/tiangou/logic/LogicProcessExternal.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ val HELP_LIST_MESSAGE: String by lazy {
3.查询商店
4.更新每日商店推送任务状态
5.自定义商店背景图
6.查询配件商店
""".trimIndent()
}

Expand Down
84 changes: 68 additions & 16 deletions src/main/kotlin/io/tiangou/logic/LogicProcessor.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.tiangou.logic


import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.tiangou.*
import io.tiangou.api.RiotApi
import io.tiangou.api.data.AuthCookiesRequest
Expand All @@ -10,12 +12,17 @@ import io.tiangou.api.data.MultiFactorAuthRequest
import io.tiangou.logic.utils.GenerateImageType
import io.tiangou.logic.utils.StoreImageHelper
import io.tiangou.other.http.actions
import io.tiangou.other.http.client
import io.tiangou.repository.UserCache
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable
import net.mamoe.mirai.console.util.cast
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.file.AbsoluteFileFolder.Companion.extension
import net.mamoe.mirai.event.events.MessageEvent
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.data.Image.Key.isUploaded
import net.mamoe.mirai.message.data.MessageChainBuilder
import net.mamoe.mirai.message.data.Image.Key.queryUrl
import net.mamoe.mirai.utils.ExternalResource.Companion.toExternalResource

@Serializable
Expand Down Expand Up @@ -189,31 +196,35 @@ object CheckIsBotFriendProcessor : LogicProcessor<MessageEvent> {

}

suspend fun MessageEvent.uploadImage(bytes: ByteArray) {
var uploadImage =
getContact().uploadImage(bytes.toExternalResource().toAutoCloseable())
repeat(2) {
if (!uploadImage.isUploaded(bot)) {
uploadImage = getContact()
.uploadImage(bytes.toExternalResource().toAutoCloseable())
}
}
if (uploadImage.isUploaded(bot)) {
reply(MessageChainBuilder().append(uploadImage).build())
} else {
reply("图片上传失败,请稍候重试")
}
}

@Serializable
object QueryPlayerDailyStoreItemProcessor : LogicProcessor<MessageEvent> {
object QueryPlayerDailyStoreProcessor : LogicProcessor<MessageEvent> {

override suspend fun process(event: MessageEvent, userCache: UserCache): Boolean {
event.reply("正在查询每日商店,请稍等")
val skinsPanelLayoutImage = StoreImageHelper.get(userCache, GenerateImageType.SKINS_PANEL_LAYOUT)
var uploadImage =
event.getContact().uploadImage(skinsPanelLayoutImage.toExternalResource().toAutoCloseable())
repeat(2) {
if (!uploadImage.isUploaded(event.bot)) {
uploadImage = event.getContact()
.uploadImage(skinsPanelLayoutImage.toExternalResource().toAutoCloseable())
}
}
if (uploadImage.isUploaded(event.bot)) {
event.reply(MessageChainBuilder().append(uploadImage).build())
} else {
event.reply("图片上传失败,请稍候重试")
}
event.uploadImage(skinsPanelLayoutImage)
return false
}
}

@Serializable
object SubscribeTaskDailyStore : LogicProcessor<MessageEvent> {
object SubscribeTaskDailyStoreProcessor : LogicProcessor<MessageEvent> {
override suspend fun process(event: MessageEvent, userCache: UserCache): Boolean {
userCache.apply {
subscribeDailyStore = !subscribeDailyStore
Expand All @@ -222,4 +233,45 @@ object SubscribeTaskDailyStore : LogicProcessor<MessageEvent> {
}
return false
}
}

@Serializable
object TellCustomBackgroundCanUploadProcessor : LogicProcessor<MessageEvent> {
override suspend fun process(event: MessageEvent, userCache: UserCache): Boolean {
event.reply("请上传背景图片(若要回复为默认背景,请发送\"恢复默认\")")
return false
}
}

@Serializable
object UploadCustomBackgroundProcessor : LogicProcessor<MessageEvent> {
override suspend fun process(event: MessageEvent, userCache: UserCache): Boolean {
if (event.message.toText() == "恢复默认") {
userCache.customBackgroundFile = null
event.reply("已将背景图片恢复至默认")
} else {
val downloadUrl = event.run {
message.firstIsInstanceOrNull<Image>()?.queryUrl()
?: takeIf { it.subject is Group }?.message?.firstIsInstanceOrNull<FileMessage>()
?.toAbsoluteFile(subject.cast())?.takeIf { ImageType.matchOrNull(it.extension) != null }
?.getUrl()
} ?: event.reply("无法解析图片,请确认图片后缀无误,推荐上传PNG或JPG格式的图片").let { return false }
userCache.customBackgroundFile = ValorantBotPlugin.dataFolder.resolve("${event.sender.id}_background.bkg")
.apply { writeBytes(client.get(downloadUrl).readBytes()) }
event.reply("上传成功")
}
StoreImageHelper.clean(userCache)
return false
}
}

@Serializable
object QueryPlayerAccessoryStoreProcessor : LogicProcessor<MessageEvent> {

override suspend fun process(event: MessageEvent, userCache: UserCache): Boolean {
event.reply("正在查询配件商店,请稍等")
val accessoryStoreImage = StoreImageHelper.get(userCache, GenerateImageType.ACCESSORY_STORE)
event.uploadImage(accessoryStoreImage)
return false
}
}
20 changes: 9 additions & 11 deletions src/main/kotlin/io/tiangou/logic/LogicSelector.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.tiangou.logic

import io.ktor.util.date.*
import io.tiangou.EventHandleConfig
import io.tiangou.Global
import io.tiangou.reply
import io.tiangou.repository.LogicRepository
Expand Down Expand Up @@ -31,20 +30,19 @@ class LogicSelector : CoroutineScope {

fun loadLogic(message: String): LogicProcessor<MessageEvent>? {
logicList = logicList ?: LogicRepository.find(message)
timeoutStamp = (getTimeMillis() + EventHandleConfig.config.waitTimeoutMinutes * 60 * 1000L)
timeoutStamp = (getTimeMillis() + Global.eventConfig.waitTimeoutMinutes * 60 * 1000L)
return logicList?.get(index++)
}

fun createTimeoutCancelJob(event: MessageEvent, userCache: UserCache) {
if (timeoutCancelJob == null && isStatusNormal()) {
timeoutCancelJob = launch {
while (true) {
delay(timeoutStamp!! - getTimeMillis())
if (getTimeMillis() >= timeoutStamp!!) {
userCache.clean()
event.reply("等待输入超时,已自动退出,请重新发起")
break
}
(timeoutCancelJob == null && isStatusNormal()) || return
timeoutCancelJob = launch {
while (true) {
delay(timeoutStamp!! - getTimeMillis())
if (getTimeMillis() >= timeoutStamp!!) {
userCache.clean()
event.reply("等待输入超时,已自动退出,请重新发起")
break
}
}
}
Expand Down

0 comments on commit 086cc8d

Please sign in to comment.