فهرست منبع

plugin: godcmd support manage plugins

lanvent 3 سال پیش
والد
کامیت
cb7bf446e3
2فایلهای تغییر یافته به همراه118 افزوده شده و 20 حذف شده
  1. 56 0
      plugins/godcmd/godcmd.py
  2. 62 20
      plugins/plugin_manager.py

+ 56 - 0
plugins/godcmd/godcmd.py

@@ -48,6 +48,24 @@ ADMIN_COMMANDS = {
         "alias": ["resetall", "重置所有会话"],
         "desc": "重置所有会话",
     },
+    "scanp": {
+        "alias": ["scanp", "扫描插件"],
+        "desc": "扫描插件目录是否有新插件",
+    },
+    "plist": {
+        "alias": ["plist", "插件"],
+        "desc": "打印当前插件列表",
+    },
+    "enablep": {
+        "alias": ["enablep", "启用插件"],
+        "args": ["插件名"],
+        "desc": "启用指定插件",
+    },
+    "disablep": {
+        "alias": ["disablep", "禁用插件"],
+        "args": ["插件名"],
+        "desc": "禁用指定插件",
+    },
     "debug": {
         "alias": ["debug", "调试模式", "DEBUG"],
         "desc": "开启机器调试日志",
@@ -163,6 +181,44 @@ class Godcmd(Plugin):
                         elif cmd == "debug":
                             logger.setLevel('DEBUG')
                             ok, result = True, "DEBUG模式已开启"
+                        elif cmd == "plist":
+                            plugins = PluginManager().list_plugins()
+                            ok = True
+                            result = "插件列表:\n"
+                            for name,plugincls in plugins.items():
+                                result += f"{name}_v{plugincls.version} - "
+                                if plugincls.enabled:
+                                    result += "已启用\n"
+                                else:
+                                    result += "未启用\n"
+                        elif cmd == "scanp":
+                            new_plugins = PluginManager().scan_plugins()
+                            ok, result = True, "插件扫描完成"
+                            if len(new_plugins) >0 :
+                                PluginManager().activate_plugins()
+                                result += "\n发现新插件:\n"
+                                result += "\n".join([f"{p.name}_v{p.version}" for p in new_plugins])
+                            else :
+                                result +=", 未发现新插件"
+                        elif cmd == "enablep":
+                            if len(args) != 1:
+                                ok, result = False, "请提供插件名"
+                            else:
+                                ok = PluginManager().enable_plugin(args[0])
+                                if ok:
+                                    result = "插件已启用"
+                                else:
+                                    result = "插件不存在"
+                        elif cmd == "disablep":
+                            if len(args) != 1:
+                                ok, result = False, "请提供插件名"
+                            else:
+                                ok = PluginManager().disable_plugin(args[0])
+                                if ok:
+                                    result = "插件已禁用"
+                                else:
+                                    result = "插件不存在"
+
                         logger.debug("[Godcmd] admin command: %s by %s" % (cmd, user))
                 else:
                     ok, result = False, "需要管理员权限才能执行该指令"

+ 62 - 20
plugins/plugin_manager.py

@@ -15,6 +15,7 @@ class PluginManager:
         self.plugins = {}
         self.listening_plugins = {}
         self.instances = {}
+        self.pconf = {}
 
     def register(self, name: str, desc: str, version: str, author: str):
         def wrapper(plugincls):
@@ -28,12 +29,27 @@ class PluginManager:
             return plugincls
         return wrapper
 
-    def save_config(self, pconf):
+    def save_config(self):
         with open("plugins/plugins.json", "w", encoding="utf-8") as f:
-            json.dump(pconf, f, indent=4, ensure_ascii=False)
+            json.dump(self.pconf, f, indent=4, ensure_ascii=False)
 
     def load_config(self):
         logger.info("Loading plugins config...")
+
+        modified = False
+        if os.path.exists("plugins/plugins.json"):
+            with open("plugins/plugins.json", "r", encoding="utf-8") as f:
+                pconf = json.load(f)
+        else:
+            modified = True
+            pconf = {"plugins": []}
+        self.pconf = pconf
+        if modified:
+            self.save_config()
+        return pconf
+
+    def scan_plugins(self):
+        logger.info("Scaning plugins ...")
         plugins_dir = "plugins"
         for plugin_name in os.listdir(plugins_dir):
             plugin_path = os.path.join(plugins_dir, plugin_name)
@@ -44,31 +60,20 @@ class PluginManager:
                     # 导入插件
                     import_path = "{}.{}.{}".format(plugins_dir, plugin_name, plugin_name)
                     main_module = importlib.import_module(import_path)
-
+        pconf = self.pconf
+        new_plugins = []
         modified = False
-        if os.path.exists("plugins/plugins.json"):
-            with open("plugins/plugins.json", "r", encoding="utf-8") as f:
-                pconf = json.load(f)
-        else:
-            modified = True
-            pconf = {"plugins": []}
         for name, plugincls in self.plugins.items():
             if name not in [plugin["name"] for plugin in pconf["plugins"]]:
+                new_plugins.append(plugincls)
                 modified = True
                 logger.info("Plugin %s not found in pconfig, adding to pconfig..." % name)
                 pconf["plugins"].append({"name": name, "enabled": True})
         if modified:
-            self.save_config(pconf)
-        return pconf
-
-    def load_plugins(self):
-        pconf = self.load_config()
-        logger.debug("plugins.json config={}".format(pconf))
-        for plugin in pconf["plugins"]:
-            name = plugin["name"]
-            enabled = plugin["enabled"]
-            self.plugins[name].enabled = enabled
+            self.save_config()
+        return new_plugins
 
+    def activate_plugins(self):
         for name, plugincls in self.plugins.items():
             if plugincls.enabled:
                 if name not in self.instances:
@@ -79,11 +84,48 @@ class PluginManager:
                             self.listening_plugins[event] = []
                         self.listening_plugins[event].append(name)
 
+    def load_plugins(self):
+        self.load_config()
+        self.scan_plugins()
+        pconf = self.pconf
+        logger.debug("plugins.json config={}".format(pconf))
+        for plugin in pconf["plugins"]:
+            name = plugin["name"]
+            enabled = plugin["enabled"]
+            self.plugins[name].enabled = enabled
+        self.activate_plugins()
+
     def emit_event(self, e_context: EventContext, *args, **kwargs):
         if e_context.event in self.listening_plugins:
             for name in self.listening_plugins[e_context.event]:
-                if e_context.action == EventAction.CONTINUE:
+                if self.plugins[name].enabled and e_context.action == EventAction.CONTINUE:
                     logger.debug("Plugin %s triggered by event %s" % (name,e_context.event))
                     instance = self.instances[name]
                     instance.handlers[e_context.event](e_context, *args, **kwargs)
         return e_context
+
+    def enable_plugin(self,name):
+        if name not in self.plugins:
+            return False
+        if not self.plugins[name].enabled :
+            self.plugins[name].enabled = True
+            idx = next(i for i in range(len(self.pconf['plugins'])) if self.pconf["plugins"][i]['name'] == name)
+            self.pconf["plugins"][idx]["enabled"] = True
+            self.save_config()
+            self.activate_plugins()
+            return True
+        return True
+    
+    def disable_plugin(self,name):
+        if name not in self.plugins:
+            return False
+        if self.plugins[name].enabled :
+            self.plugins[name].enabled = False
+            idx = next(i for i in range(len(self.pconf['plugins'])) if self.pconf["plugins"][i]['name'] == name)
+            self.pconf["plugins"][idx]["enabled"] = False
+            self.save_config()
+            return True
+        return True
+    
+    def list_plugins(self):
+        return self.plugins