```实现BotFunction注解的服务发现机制

机器人框架已更新,支持通过BotFunction注解进行服务发现。注解现包含target和retention元数据,支持在运行时使用反射进行处理。服务实现现在 suspend 函数,以支持异步行为。此外,引入了新的配置属性来定义机器人管理员ID。```
This commit is contained in:
Grand-cocoa 2024-08-30 13:50:01 +08:00
parent fe1d7a2368
commit ae3213dc63
9 changed files with 92 additions and 44 deletions

View File

@ -11,4 +11,7 @@ import kotlin.reflect.KClass
* @since 2024/8/29 下午3:48
* @see Service
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@org.springframework.stereotype.Service
annotation class BotFunction(vararg val value: KClass<out Event>)

View File

@ -1,22 +1,34 @@
package info.alinadace.miraibot.bean
import info.alinadace.miraibot.annotation.BotFunction
import info.alinadace.miraibot.config.BotConfig
import info.alinadace.miraibot.enum.LoginType
import info.alinadace.miraibot.enums.LoginType
import info.alinadace.miraibot.service.Service
import jakarta.annotation.Resource
import net.mamoe.mirai.Bot
import net.mamoe.mirai.BotFactory
import net.mamoe.mirai.auth.BotAuthorization
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.utils.BotConfiguration
import org.springframework.boot.autoconfigure.AutoConfiguration
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean
import java.util.Collections
import java.util.HashMap
import kotlin.reflect.KClass
/**
* 机器人配置
* @author Kane
* @since 2024/8/29 下午2:47
*/
@AutoConfiguration
@EnableConfigurationProperties(BotConfig::class)
class BotConfiguration {
@Resource
private val services: List<Service<Event>> = Collections.emptyList();
@Bean(initMethod = "login")
fun bot(config: BotConfig): Bot{
return when (config.type) {
@ -29,6 +41,30 @@ class BotConfiguration {
}
}
@Bean
fun botFunctionMap(): HashMap<KClass<out Event>, MutableList<Service<Event>>>{
val eventMap = HashMap<KClass<out Event>, MutableList<Service<Event>>>();
for (service in services) {
val clazz = service::class
val annotations = clazz.annotations
if (annotations.isEmpty()) continue
var function: BotFunction? = null
for (annotation in annotations) {
if (annotation is BotFunction){
function = annotation
}
}
if (function == null){
continue
}
for (kClass in function.value) {
val serviceList = eventMap.getOrPut(kClass) { mutableListOf() }
serviceList.add(service)
}
}
return eventMap
}
private fun BotConfiguration.extracted() {
fileBasedDeviceInfo()
protocol = BotConfiguration.MiraiProtocol.ANDROID_WATCH

View File

@ -1,6 +1,7 @@
package info.alinadace.miraibot.config
import info.alinadace.miraibot.enum.LoginType
import info.alinadace.miraibot.enums.LoginType
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.context.properties.ConfigurationProperties
/**
@ -12,4 +13,14 @@ import org.springframework.boot.context.properties.ConfigurationProperties
*/
@ConfigurationProperties("bot")
class BotConfig(val id: Long, val password: String, val type: LoginType) {
companion object {
@JvmStatic
val NULL_INSTANCE = BotConfig(0, "", LoginType.PASSWORD)
@JvmStatic
@Value("\${bot.admin}")
val ADMIN_ID: Long = 0;
}
fun isNull(config: BotConfig): Boolean {
return config == NULL_INSTANCE
}
}

View File

@ -1,11 +0,0 @@
package info.alinadace.miraibot.enum
import net.mamoe.mirai.event.Event
/**
* @author Kane
* @since 2024/8/29 下午3:56
*/
enum class EventType(val event: Event) {
}

View File

@ -1,4 +1,4 @@
package info.alinadace.miraibot.enum
package info.alinadace.miraibot.enums
/**
* 登录方式

View File

@ -1,28 +0,0 @@
package info.alinadace.miraibot.service
import info.alinadace.miraibot.annotation.BotFunction
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.events.GroupMessageEvent
import net.mamoe.mirai.event.events.MessageEvent
/**
* @author Kane
* @since 2024/8/29 下午3:47
*/
@BotFunction(MessageEvent::class, GroupMessageEvent::class)
class Constellation: Service<MessageEvent>{
/**
* 服务入口
*/
override fun entrance(event: MessageEvent): Boolean {
TODO("Not yet implemented")
}
/**
* 服务行为
*/
override fun active(event: MessageEvent) {
TODO("Not yet implemented")
}
}

View File

@ -0,0 +1,36 @@
package info.alinadace.miraibot.service
import info.alinadace.miraibot.annotation.BotFunction
import info.alinadace.miraibot.config.BotConfig
import net.mamoe.mirai.event.events.GroupMessageEvent
import net.mamoe.mirai.event.events.MessageEvent
import net.mamoe.mirai.message.data.PlainText
/**
* @author Kane
* @since 2024/8/29 下午3:47
*/
@BotFunction(MessageEvent::class, GroupMessageEvent::class)
class ExampleService: Service<MessageEvent>{
/**
* 服务入口
*/
override fun entrance(event: MessageEvent): Boolean {
val chain = event.message
if (chain.size == 1 && chain[0] is PlainText){
if (chain[0].contentToString() == "测试" && event.sender.id == BotConfig.ADMIN_ID) {
return true
}
}
return false
}
/**
* 服务行为
*/
override suspend fun active(event: MessageEvent) {
event.subject.sendMessage("测试成功")
}
}

View File

@ -16,5 +16,5 @@ interface Service<E: Event> {
/**
* 服务行为
*/
fun active(event: E)
suspend fun active(event: E)
}

View File

@ -5,3 +5,4 @@ spring:
active: @profiles.active@
bot:
type: qrcode
admin: 1075576561