diff --git a/pkg/plugin/host.py b/pkg/plugin/host.py index 0961a1e..ed9f5c3 100644 --- a/pkg/plugin/host.py +++ b/pkg/plugin/host.py @@ -7,7 +7,11 @@ import sys import pkg.utils.context as context __plugins__ = {} -"""{ +""" +插件列表 + +示例: +{ "example": { "name": "example", "description": "example", @@ -68,15 +72,42 @@ def unload_plugins(): logging.error("插件{}卸载时发生错误: {}".format(plugin['name'], sys.exc_info())) -def emit(event: str, **kwargs): +class EventContext: + """ 事件上下文 """ + eid = 0 + + name = "" + + __prevent_default__ = False + """ 是否阻止默认行为 """ + + __prevent_postorder__ = False + """ 是否阻止后续插件的执行 """ + + def prevent_default(self): + """阻止默认行为""" + self.__prevent_default__ = True + + def prevent_postorder(self): + """阻止后续插件执行""" + self.__prevent_postorder__ = True + + def is_prevented_default(self): + return self.__prevent_default__ + + def is_prevented_postorder(self): + return self.__prevent_postorder__ + + def __init__(self, name: str): + self.name = name + self.eid = EventContext.eid + EventContext.eid += 1 + + +def emit(event_name: str, **kwargs) -> EventContext: """ 触发事件 """ - for plugin in __plugins__.values(): - for hook in plugin['hooks'].get(event, []): - try: - kwargs['plugin_host'] = context.get_plugin_host() - hook(plugin['instance'], **kwargs) - except: - logging.error("插件{}触发事件{}时发生错误: {}".format(plugin['name'], event, sys.exc_info())) + import pkg.utils.context as context + return context.get_plugin_host().emit(event_name, **kwargs) class PluginHost: @@ -85,9 +116,6 @@ class PluginHost: def __init__(self): context.set_plugin_host(self) - def prevent_default(self): - """阻止默认行为""" - def get_runtime_context(self) -> context: """获取运行时上下文""" return context @@ -99,3 +127,25 @@ class PluginHost: def notify_admin(self, message): """通知管理员""" context.get_qqbot_manager().notify_admin(message) + + def emit(self, event_name: str, **kwargs) -> EventContext: + """ 触发事件 """ + event_context = EventContext(event_name) + for plugin in __plugins__.values(): + for hook in plugin['hooks'].get(event_name, []): + try: + kwargs['host'] = context.get_plugin_host() + kwargs['event'] = event_context + hook(plugin['instance'], **kwargs) + + if event_context.is_prevented_default(): + logging.debug("插件 {} 要求阻止事件{}的默认行为".format(plugin['name'], event_name)) + + if event_context.is_prevented_postorder(): + logging.debug("插件 {} 阻止了后序插件的执行".format(plugin['name'])) + break + + except: + logging.error("插件{}触发事件{}时发生错误: {}".format(plugin['name'], event_name, sys.exc_info())) + + return event_context diff --git a/pkg/qqbot/manager.py b/pkg/qqbot/manager.py index 54b5cb4..79bebfc 100644 --- a/pkg/qqbot/manager.py +++ b/pkg/qqbot/manager.py @@ -98,14 +98,50 @@ class QQBotManager: # Caution: 注册新的事件处理器之后,请务必在unsubscribe_all中编写相应的取消订阅代码 @self.bot.on(FriendMessage) async def on_friend_message(event: FriendMessage): + # 触发事件 + args = { + "launcher_type": "person", + "launcher_id": event.sender.id, + "sender_id": event.sender.id, + "message_chain": event.message_chain, + } + event = plugin_host.emit(plugin_models.PersonMessage, **args) + + if event.is_prevented_default(): + return + go(self.on_person_message, (event,)) @self.bot.on(StrangerMessage) async def on_stranger_message(event: StrangerMessage): + # 触发事件 + args = { + "launcher_type": "person", + "launcher_id": event.sender.id, + "sender_id": event.sender.id, + "message_chain": event.message_chain, + } + event = plugin_host.emit(plugin_models.PersonMessage, **args) + + if event.is_prevented_default(): + return + go(self.on_person_message, (event,)) @self.bot.on(GroupMessage) async def on_group_message(event: GroupMessage): + # 触发事件 + args = { + "launcher_type": "group", + "launcher_id": event.group.id, + "sender_id": event.sender.id, + "message_chain": event.message_chain, + } + event = plugin_host.emit(plugin_models.GroupMessage, **args) + + if event.is_prevented_default(): + return + go(self.on_group_message, (event,)) def unsubscribe_all(): @@ -159,15 +195,6 @@ class QQBotManager: # 私聊消息处理 def on_person_message(self, event: MessageEvent): - # 触发事件 - args = { - "launcher_type": "person", - "launcher_id": event.sender.id, - "sender_id": event.sender.id, - "message_chain": event.message_chain, - } - plugin_host.emit(plugin_models.PersonMessage, **args) - reply = '' if event.sender.id == self.bot.qq: @@ -203,15 +230,6 @@ class QQBotManager: # 群消息处理 def on_group_message(self, event: GroupMessage): - # 触发事件 - args = { - "launcher_type": "group", - "launcher_id": event.group.id, - "sender_id": event.sender.id, - "message_chain": event.message_chain, - } - plugin_host.emit(plugin_models.GroupMessage, **args) - reply = '' def process(text=None) -> str: diff --git a/plugins/example/__init__.py b/plugins/example/__init__.py new file mode 100644 index 0000000..1acb9b4 --- /dev/null +++ b/plugins/example/__init__.py @@ -0,0 +1,22 @@ +from pkg.plugin.models import Plugin, PersonMessage, GroupMessage, register +from pkg.plugin.host import EventContext + + +@register(name="ExamplePlugin", description="用于展示QChatGPT插件支持功能的插件", version="0.0.1", author="RockChinQ") +class ExamplePlugin(Plugin): + + def __init__(self): + pass + + @Plugin.on(PersonMessage) + def person_message(self, event: EventContext, **kwargs): + print("person_message", kwargs) + event.prevent_default() + + @Plugin.on(GroupMessage) + def group_message(self, **kwargs): + print("group_message", kwargs) + self.host.notify_admin("group_message") + + def __del__(self): + pass