跳到主要内容

钩子能更好实现扩展功能,以及自定义行为

系统内置的钩子


//接收到了消息时
com.blr19c.falowp.bot.system.listener.hooks.ReceiveMessageHook

//消息类插件执行时
com.blr19c.falowp.bot.system.listener.hooks.MessagePluginExecutionHook

//事件类插件执行时
com.blr19c.falowp.bot.system.listener.hooks.EventPluginExecutionHook

//任务类插件执行时
com.blr19c.falowp.bot.system.listener.hooks.TaskPluginExecutionHook

//帮助事件执行时(用于修改插件信息)
com.blr19c.falowp.bot.system.listener.hooks.HelpEventHook

提示

如果你想要更多的系统内置钩子,你可以提出issues

钩子的使用

import com.blr19c.falowp.bot.system.Log
import com.blr19c.falowp.bot.system.listener.hooks.MessagePluginExecutionHook
import com.blr19c.falowp.bot.system.plugin.Plugin
import com.blr19c.falowp.bot.system.plugin.Plugin.Listener.Hook.Companion.beforeHook

@Plugin(name = "test")
class Test : Log {

private val test = beforeHook<MessagePluginExecutionHook> { (receiveMessage, register) ->
log().info("当前发送人权限为:" + receiveMessage.sender.auth.name)
this.process()
}

init {
test.register()
}
}

创建支持钩子的作用域

import com.blr19c.falowp.bot.system.Log
import com.blr19c.falowp.bot.system.plugin.Plugin
import com.blr19c.falowp.bot.system.plugin.Plugin.Listener.Hook.Companion.beforeHook
import com.blr19c.falowp.bot.system.plugin.Plugin.Message.message
import com.blr19c.falowp.bot.system.plugin.hook.withPluginHook

@Plugin(name = "test")
class Test : Log {

private val test = message(Regex("你好")) {
//在发送"你好"之前,允许TestHook钩子进行操作
withPluginHook(this, TestHook()) {
this.sendReply("你好")
}
}

private val testHook = beforeHook<TestHook> {
//在发送"你好"之前,先发送"你好hook"
this.botApi().sendReply("你好hook")
//不执行 this.process() 代表不允许withPluginHook块中间的代码执行
this.process()
}

init {
test.register()
testHook.register()
}
}

class TestHook : Plugin.Listener.Hook

钩子的种类

//前置钩子
com.blr19c.falowp.bot.system.plugin.Plugin.Listener.Hook.Companion.beforeHook
//后置钩子
com.blr19c.falowp.bot.system.plugin.Plugin.Listener.Hook.Companion.afterReturningHook
//异常通知
com.blr19c.falowp.bot.system.plugin.Plugin.Listener.Hook.Companion.afterThrowingHook
//最终通知
com.blr19c.falowp.bot.system.plugin.Plugin.Listener.Hook.Companion.afterFinallyHook
//环绕
com.blr19c.falowp.bot.system.plugin.Plugin.Listener.Hook.Companion.aroundHook

运行时钩子(beta)

在你使用其他机器人框架时,是不是会遇到这种情况

比如: 你发送一个选项,想让用户在此选择其中一个,这个时候你需要创建两个消息监听

//监听message1

//监听选项选择(但是问题在于这个选项选择在没有触发第一个监听时是没有任何意义的)

//为此你要声明上下文参数获取当前用户的当前状态是不是已经触发了监听1

但是有了运行时钩子,你可以这样写

import com.blr19c.falowp.bot.system.Log
import com.blr19c.falowp.bot.system.listener.hooks.ReceiveMessageHook
import com.blr19c.falowp.bot.system.plugin.Plugin
import com.blr19c.falowp.bot.system.plugin.Plugin.Message.message
import com.blr19c.falowp.bot.system.plugin.UnRegister
import com.blr19c.falowp.bot.system.plugin.hook.HookTypeEnum

@Plugin(name = "test")
class Test : Log {

private val test = message(Regex("你好")) {

//发送选项
this.sendReply("请在以下选项中选择一个, 1.你好, 2.你不好")

//你的数据
val data = Any()

//创建hook监听选项被选择
this.runtimeHook<ReceiveMessageHook>(HookTypeEnum.BEFORE) { (message), unRegister ->
//养成在hook中保持第一句话获取this.botApi()的好习惯(在你需要使用botApi的时候)
val botApi = this.botApi()
log().info("在这里也能获取到你的数据$data")
if (message.content.message == "1") {
botApi.sendReply("你好")
//在不需要的时候手动取消
unRegister.unregister()
return@runtimeHook
}
if (message.content.message == "2") {
botApi.sendReply("你不好")
//在不需要的时候手动取消
unRegister.unregister()
return@runtimeHook
}
botApi.sendReply("选项错误,请继续输入1或者2")
}
}

init {
test.register()
}
}

简单场景下你也可以这样写

@Plugin(name = "test")
class Test : Log {

private val test = message(Regex("你好")) {

//发送选项
this.sendReply("请在以下选项中选择一个, 1.你好, 2.你不好")

//监听回复内容
//awaitReply最好搭配 `withTimeout` `withTimeoutOrNull` 等超时机制使用
val replyMessage = this.awaitReply(MessagePluginRegisterMatch(Regex("([12])"))) { (reply) -> reply }
if (replyMessage == "1") {
this.sendReply("你好")
}
if (replyMessage == "2") {
this.sendReply("你不好")
}
}

init {
test.register()
}
}

不用声明其他的消息类型,也不需要在上下文中配置数据,看起来是不是好了很多

钩子虽好也不要贪杯哦

过度使用可能会让你的代码难以理解