From 32e8f08398cab6a6346a16608a1c413c787ddfcf Mon Sep 17 00:00:00 2001 From: Rock Chin <1010553892@qq.com> Date: Mon, 16 Jan 2023 23:40:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/plugin/host.py | 17 +++++++++ pkg/plugin/models.py | 11 ++++-- pkg/plugin/switch.py | 86 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 pkg/plugin/switch.py diff --git a/pkg/plugin/host.py b/pkg/plugin/host.py index 598512aa..a8332ced 100644 --- a/pkg/plugin/host.py +++ b/pkg/plugin/host.py @@ -7,6 +7,7 @@ import sys import traceback import pkg.utils.context as context +import pkg.plugin.switch as switch from mirai import Mirai @@ -17,6 +18,8 @@ __plugins__ = {} 示例: { "example": { + "path": "plugins/example/main.py", + "enabled: True, "name": "example", "description": "example", "version": "0.0.1", @@ -58,6 +61,8 @@ def initialize_plugins(): """ 初始化插件 """ logging.info("初始化插件") for plugin in __plugins__.values(): + if not plugin['enabled']: + continue try: plugin['instance'] = plugin["class"]() except: @@ -195,6 +200,18 @@ class PluginHost: event_context = EventContext(event_name) logging.debug("触发事件: {} ({})".format(event_name, event_context.eid)) for plugin in __plugins__.values(): + + if not plugin['enabled']: + continue + + if plugin['instance'] is None: + # 从关闭状态切到开启状态之后,重新加载插件 + try: + plugin['instance'] = plugin["class"]() + except: + logging.error("插件{}初始化时发生错误: {}".format(plugin['name'], sys.exc_info())) + continue + for hook in plugin['hooks'].get(event_name, []): try: already_prevented_default = event_context.is_prevented_default() diff --git a/pkg/plugin/models.py b/pkg/plugin/models.py index da99bdcc..53b13581 100644 --- a/pkg/plugin/models.py +++ b/pkg/plugin/models.py @@ -3,8 +3,6 @@ import logging import pkg.plugin.host as host import pkg.utils.context -__current_registering_plugin__ = "" - PersonMessageReceived = "person_message_received" """收到私聊消息时,在判断是否应该响应前触发 kwargs: @@ -143,6 +141,9 @@ def on(event: str): return Plugin.on(event) +__current_registering_plugin__ = "" + + class Plugin: host: host.PluginHost @@ -193,7 +194,9 @@ def register(name: str, description: str, version: str, author: str): "description": description, "version": version, "author": author, - "hooks": {} + "hooks": {}, + "path": host.__current_module_path__, + "enabled": True, } def wrapper(cls: Plugin): @@ -202,6 +205,8 @@ def register(name: str, description: str, version: str, author: str): cls.version = version cls.author = author cls.host = pkg.utils.context.get_plugin_host() + cls.enabled = True + cls.path = host.__current_module_path__ # 存到插件列表 host.__plugins__[name]["class"] = cls diff --git a/pkg/plugin/switch.py b/pkg/plugin/switch.py new file mode 100644 index 00000000..5dfc41b8 --- /dev/null +++ b/pkg/plugin/switch.py @@ -0,0 +1,86 @@ +# 控制插件的开关 +import json +import logging +import os + +import pkg.plugin.host as host + + +def wrapper_dict_from_plugin_list() -> dict: + """ 将插件列表转换为开关json """ + switch = {} + + for plugin_name in host.__plugins__: + plugin = host.__plugins__[plugin_name] + + switch[plugin_name] = { + "path": plugin["path"], + "enabled": plugin["enabled"], + } + + return switch + + +def apply_switch(switch: dict): + """将开关数据应用到插件列表中""" + for plugin_name in switch: + host.__plugins__[plugin_name]["enabled"] = switch[plugin_name]["enabled"] + + +def dump_switch(): + """ 保存开关数据 """ + logging.debug("保存开关数据") + # 将开关数据写入plugins/switch.json + + switch = wrapper_dict_from_plugin_list() + + with open("plugins/switch.json", "w", encoding="utf-8") as f: + json.dump(switch, f, indent=4, ensure_ascii=False) + + +def load_switch(): + """ 加载开关数据 """ + logging.debug("加载开关数据") + # 读取plugins/switch.json + + switch = {} + + # 检查文件是否存在 + if not os.path.exists("plugins/switch.json"): + # 不存在则创建 + with open("plugins/switch.json", "w", encoding="utf-8") as f: + json.dump(switch, f, indent=4, ensure_ascii=False) + + with open("plugins/switch.json", "r", encoding="utf-8") as f: + switch = json.load(f) + + if switch is None: + switch = {} + + switch_modified = False + + # 检查switch中多余的和path不相符的 + for plugin_name in switch: + if plugin_name not in host.__plugins__: + del switch[plugin_name] + switch_modified = True + elif switch[plugin_name]["path"] != host.__plugins__[plugin_name]["path"]: + # 删除此不相符的 + del switch[plugin_name] + switch_modified = True + + # 检查plugin中多余的 + for plugin_name in host.__plugins__: + if plugin_name not in switch: + switch[plugin_name] = { + "path": host.__plugins__[plugin_name]["path"], + "enabled": host.__plugins__[plugin_name]["enabled"], + } + switch_modified = True + + # 如果switch有修改,保存 + if switch_modified: + dump_switch() + + # 应用开关数据 + apply_switch(switch)