集成help以及init到core内,修改baseplugin为plugin
This commit is contained in:
@@ -34,7 +34,7 @@ NEO 框架的设计遵循以下核心理念:
|
|||||||
* **OneBot 11 标准支持**:完整支持 OneBot 11 的消息、通知、请求和元事件。
|
* **OneBot 11 标准支持**:完整支持 OneBot 11 的消息、通知、请求和元事件。
|
||||||
* **类型安全**:基于 `dataclasses` 的强类型事件模型,开发体验更佳。
|
* **类型安全**:基于 `dataclasses` 的强类型事件模型,开发体验更佳。
|
||||||
* **插件系统**:轻量级的装饰器风格插件系统,支持指令 (`@matcher.command`) 和事件监听 (`@matcher.on_notice`, `@matcher.on_request`)。
|
* **插件系统**:轻量级的装饰器风格插件系统,支持指令 (`@matcher.command`) 和事件监听 (`@matcher.on_notice`, `@matcher.on_request`)。
|
||||||
* **插件元数据与自动帮助**:插件可通过 `__plugin_meta__` 变量进行自我描述,框架会自动加载这些信息并生成 `/help` 指令,无需手动维护帮助列表。
|
* **插件元数据与内置帮助**:插件可通过 `__plugin_meta__` 变量进行自我描述。框架核心内置了 `/help` 指令,可自动收集并展示所有插件的帮助信息,无需手动维护。
|
||||||
* **🔥 热重载支持**:内置文件监控,修改 `base_plugins` 下的代码自动重载,无需重启,极大提升调试效率。
|
* **🔥 热重载支持**:内置文件监控,修改 `base_plugins` 下的代码自动重载,无需重启,极大提升调试效率。
|
||||||
* **异步核心**:基于 `asyncio` 和 `websockets` 的高性能异步核心。
|
* **异步核心**:基于 `asyncio` 和 `websockets` 的高性能异步核心。
|
||||||
* **自动重连**:内置 WebSocket 断线重连机制。
|
* **自动重连**:内置 WebSocket 断线重连机制。
|
||||||
@@ -103,9 +103,8 @@ NEO 框架的设计遵循以下核心理念:
|
|||||||
|
|
||||||
```
|
```
|
||||||
NEO/
|
NEO/
|
||||||
├── base_plugins/ # 基础插件目录,新建插件文件即可自动加载(支持热重载)
|
├── plugins/ # 插件目录,新建插件文件即可自动加载(支持热重载)
|
||||||
│ ├── echo.py # 示例插件:实现 /echo 和 /赞我 指令
|
│ └── echo.py # 示例插件:实现 /echo 和 /赞我 指令
|
||||||
│ └── help.py # 帮助插件:自动生成所有插件的帮助信息
|
|
||||||
├── core/ # 核心框架代码
|
├── core/ # 核心框架代码
|
||||||
│ ├── api/ # API 模块抽象层 (MessageAPI, GroupAPI, FriendAPI, AccountAPI)
|
│ ├── api/ # API 模块抽象层 (MessageAPI, GroupAPI, FriendAPI, AccountAPI)
|
||||||
│ │ ├── __init__.py
|
│ │ ├── __init__.py
|
||||||
@@ -117,6 +116,7 @@ NEO/
|
|||||||
│ ├── bot.py # Bot API 封装,提供 send_group_msg 等方法
|
│ ├── bot.py # Bot API 封装,提供 send_group_msg 等方法
|
||||||
│ ├── command_manager.py # 命令与事件分发器
|
│ ├── command_manager.py # 命令与事件分发器
|
||||||
│ ├── config_loader.py # 配置加载器
|
│ ├── config_loader.py # 配置加载器
|
||||||
|
│ ├── plugin_manager.py # 插件加载与管理
|
||||||
│ └── ws.py # WebSocket 客户端核心
|
│ └── ws.py # WebSocket 客户端核心
|
||||||
├── models/ # 数据模型
|
├── models/ # 数据模型
|
||||||
│ ├── events/ # OneBot 事件定义 (Message, Notice, Request, Meta)
|
│ ├── events/ # OneBot 事件定义 (Message, Notice, Request, Meta)
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
"""
|
|
||||||
帮助插件
|
|
||||||
|
|
||||||
提供 /help 指令,用于展示所有已加载插件的帮助信息。
|
|
||||||
"""
|
|
||||||
from core.command_manager import matcher
|
|
||||||
from models.events.message import MessageEvent
|
|
||||||
|
|
||||||
__plugin_meta__ = {
|
|
||||||
"name": "帮助",
|
|
||||||
"description": "显示所有可用指令的帮助信息",
|
|
||||||
"usage": "/help",
|
|
||||||
}
|
|
||||||
|
|
||||||
@matcher.command("help")
|
|
||||||
async def help_command(bot, event: MessageEvent):
|
|
||||||
"""
|
|
||||||
处理 /help 指令,生成并发送帮助信息
|
|
||||||
|
|
||||||
:param bot: Bot 实例
|
|
||||||
:param event: 消息事件对象
|
|
||||||
"""
|
|
||||||
help_text = "--- 可用指令列表 ---\n"
|
|
||||||
|
|
||||||
for plugin_name, meta in matcher.plugins.items():
|
|
||||||
name = meta.get("name", "未命名插件")
|
|
||||||
description = meta.get("description", "暂无描述")
|
|
||||||
usage = meta.get("usage", "暂无用法说明")
|
|
||||||
|
|
||||||
help_text += f"\n{name} ({plugin_name}):\n"
|
|
||||||
help_text += f" 功能: {description}\n"
|
|
||||||
help_text += f" 用法: {usage}\n"
|
|
||||||
|
|
||||||
await bot.send(event, help_text.strip())
|
|
||||||
@@ -29,6 +29,34 @@ class CommandManager:
|
|||||||
self.request_handlers: List[Dict] = [] # 存储请求处理器
|
self.request_handlers: List[Dict] = [] # 存储请求处理器
|
||||||
self.plugins: Dict[str, Dict[str, Any]] = {} # 存储插件元数据
|
self.plugins: Dict[str, Dict[str, Any]] = {} # 存储插件元数据
|
||||||
|
|
||||||
|
# --- 内置 help 指令 ---
|
||||||
|
self.commands["help"] = self._help_command
|
||||||
|
self.plugins["core.help"] = {
|
||||||
|
"name": "帮助",
|
||||||
|
"description": "显示所有可用指令的帮助信息",
|
||||||
|
"usage": "/help",
|
||||||
|
}
|
||||||
|
|
||||||
|
async def _help_command(self, bot, event):
|
||||||
|
"""
|
||||||
|
内置的 /help 指令处理器
|
||||||
|
|
||||||
|
:param bot: Bot 实例
|
||||||
|
:param event: 消息事件对象
|
||||||
|
"""
|
||||||
|
help_text = "--- 可用指令列表 ---\n"
|
||||||
|
|
||||||
|
for plugin_name, meta in self.plugins.items():
|
||||||
|
name = meta.get("name", "未命名插件")
|
||||||
|
description = meta.get("description", "暂无描述")
|
||||||
|
usage = meta.get("usage", "暂无用法说明")
|
||||||
|
|
||||||
|
help_text += f"\n{name}:\n"
|
||||||
|
help_text += f" 功能: {description}\n"
|
||||||
|
help_text += f" 用法: {usage}\n"
|
||||||
|
|
||||||
|
await bot.send(event, help_text.strip())
|
||||||
|
|
||||||
# --- 1. 消息指令装饰器 ---
|
# --- 1. 消息指令装饰器 ---
|
||||||
def command(self, name: str):
|
def command(self, name: str):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,28 +1,32 @@
|
|||||||
|
"""
|
||||||
|
插件管理器模块
|
||||||
|
|
||||||
|
负责扫描、加载和管理 `base_plugins` 目录下的所有插件。
|
||||||
|
"""
|
||||||
import importlib
|
import importlib
|
||||||
import os
|
import os
|
||||||
import pkgutil
|
import pkgutil
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
from core.command_manager import matcher
|
from core.command_manager import matcher
|
||||||
|
|
||||||
|
|
||||||
def load_all_plugins():
|
def load_all_plugins():
|
||||||
"""
|
"""
|
||||||
扫描并加载当前包下所有的插件(支持文件和文件夹)
|
扫描并加载 `plugins` 目录下的所有插件。
|
||||||
|
|
||||||
该函数会遍历当前目录下的所有模块:
|
该函数会遍历 `plugins` 目录下的所有模块:
|
||||||
1. 如果模块已加载,则执行 reload 操作(用于热重载)
|
1. 如果模块已加载,则执行 reload 操作(用于热重载)。
|
||||||
2. 如果模块未加载,则执行 import 操作
|
2. 如果模块未加载,则执行 import 操作。
|
||||||
|
|
||||||
加载过程中会打印详细的日志信息。
|
加载过程中会提取插件元数据 `__plugin_meta__` 并注册到 CommandManager。
|
||||||
"""
|
"""
|
||||||
package_name = __package__
|
plugin_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "plugins")
|
||||||
package_path = [os.path.dirname(__file__)]
|
package_name = "plugins"
|
||||||
|
|
||||||
print(f" 正在从 {package_name} 加载插件...")
|
print(f" 正在从 {package_name} 加载插件...")
|
||||||
|
|
||||||
for loader, module_name, is_pkg in pkgutil.iter_modules(package_path):
|
for loader, module_name, is_pkg in pkgutil.iter_modules([plugin_dir]):
|
||||||
full_module_name = f"{package_name}.{module_name}"
|
full_module_name = f"{package_name}.{module_name}"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -42,6 +46,3 @@ def load_all_plugins():
|
|||||||
print(f" [{type_str}] 成功{action}: {module_name}")
|
print(f" [{type_str}] 成功{action}: {module_name}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f" {action if 'action' in locals() else '加载'}插件 {module_name} 失败: {e}")
|
print(f" {action if 'action' in locals() else '加载'}插件 {module_name} 失败: {e}")
|
||||||
|
|
||||||
|
|
||||||
load_all_plugins()
|
|
||||||
11
main.py
11
main.py
@@ -10,8 +10,8 @@ import time
|
|||||||
from watchdog.observers import Observer
|
from watchdog.observers import Observer
|
||||||
from watchdog.events import FileSystemEventHandler
|
from watchdog.events import FileSystemEventHandler
|
||||||
|
|
||||||
import base_plugins # noqa: F401 别动这里是加载插件的
|
|
||||||
from core import WS
|
from core import WS
|
||||||
|
from core.plugin_manager import load_all_plugins
|
||||||
|
|
||||||
|
|
||||||
class PluginReloadHandler(FileSystemEventHandler):
|
class PluginReloadHandler(FileSystemEventHandler):
|
||||||
@@ -59,7 +59,7 @@ class PluginReloadHandler(FileSystemEventHandler):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# 重新扫描并加载插件
|
# 重新扫描并加载插件
|
||||||
base_plugins.load_all_plugins()
|
load_all_plugins()
|
||||||
print("[HotReload] 插件重载完成")
|
print("[HotReload] 插件重载完成")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[HotReload] 重载失败: {e}")
|
print(f"[HotReload] 重载失败: {e}")
|
||||||
@@ -73,9 +73,12 @@ async def main():
|
|||||||
2. 初始化 WebSocket 客户端
|
2. 初始化 WebSocket 客户端
|
||||||
3. 建立连接并保持运行
|
3. 建立连接并保持运行
|
||||||
"""
|
"""
|
||||||
|
# 首次加载插件
|
||||||
|
load_all_plugins()
|
||||||
|
|
||||||
# 启动文件监控
|
# 启动文件监控
|
||||||
# 监控 base_plugins 目录
|
# 监控 plugins 目录
|
||||||
plugin_path = os.path.join(os.path.dirname(__file__), "base_plugins")
|
plugin_path = os.path.join(os.path.dirname(__file__), "plugins")
|
||||||
|
|
||||||
event_handler = PluginReloadHandler()
|
event_handler = PluginReloadHandler()
|
||||||
observer = Observer()
|
observer = Observer()
|
||||||
|
|||||||
Reference in New Issue
Block a user