合并BaseEventPlugin到BasePlugin,重写了components_registry,修正了统计输出
This commit is contained in:
21
changes.md
21
changes.md
@@ -15,21 +15,23 @@
|
|||||||
- `python_dependencies`: 插件依赖的Python包列表,默认为空。**现在并不检查**
|
- `python_dependencies`: 插件依赖的Python包列表,默认为空。**现在并不检查**
|
||||||
- `config_file_name`: 插件配置文件名,默认为`config.toml`。
|
- `config_file_name`: 插件配置文件名,默认为`config.toml`。
|
||||||
- `config_schema`: 插件配置文件的schema,用于自动生成配置文件。
|
- `config_schema`: 插件配置文件的schema,用于自动生成配置文件。
|
||||||
|
4. 部分API的参数类型和返回值进行了调整
|
||||||
|
- `chat_api.py`中获取流的参数中可以使用一个特殊的枚举类型来获得所有平台的 ChatStream 了。
|
||||||
|
- `config_api.py`中的`get_global_config`和`get_plugin_config`方法现在支持嵌套访问的配置键名。
|
||||||
|
- `database_api.py`中的`db_query`方法调整了参数顺序以增强参数限制的同时,保证了typing正确;`db_get`方法增加了`single_result`参数,与`db_query`保持一致。
|
||||||
|
5. 增加了`logging_api`,可以用`get_logger`来获取日志记录器。
|
||||||
|
|
||||||
# 插件系统修改
|
# 插件系统修改
|
||||||
1. 现在所有的匹配模式不再是关键字了,而是枚举类。**(可能有遗漏)**
|
1. 现在所有的匹配模式不再是关键字了,而是枚举类。**(可能有遗漏)**
|
||||||
2. 修复了一下显示插件信息不显示的问题。同时精简了一下显示内容
|
2. 修复了一下显示插件信息不显示的问题。同时精简了一下显示内容
|
||||||
3. 修复了插件系统混用了`plugin_name`和`display_name`的问题。现在所有的插件信息都使用`display_name`来显示,而内部标识仍然使用`plugin_name`。**(可能有遗漏)**
|
3. 修复了插件系统混用了`plugin_name`和`display_name`的问题。现在所有的插件信息都使用`display_name`来显示,而内部标识仍然使用`plugin_name`。
|
||||||
3. 部分API的参数类型和返回值进行了调整
|
|
||||||
- `chat_api.py`中获取流的参数中可以使用一个特殊的枚举类型来获得所有平台的 ChatStream 了。
|
|
||||||
- `config_api.py`中的`get_global_config`和`get_plugin_config`方法现在支持嵌套访问的配置键名。
|
|
||||||
- `database_api.py`中的`db_query`方法调整了参数顺序以增强参数限制的同时,保证了typing正确;`db_get`方法增加了`single_result`参数,与`db_query`保持一致。
|
|
||||||
4. 现在增加了参数类型检查,完善了对应注释
|
4. 现在增加了参数类型检查,完善了对应注释
|
||||||
5. 现在插件抽象出了总基类 `PluginBase`
|
5. 现在插件抽象出了总基类 `PluginBase`
|
||||||
- 基于`Action`和`Command`的插件基类现在为`BasePlugin`。
|
- <del>基于`Action`和`Command`的插件基类现在为`BasePlugin`。</del>
|
||||||
- 基于`Event`的插件基类现在为`BaseEventPlugin`。
|
- <del>基于`Event`的插件基类现在为`BaseEventPlugin`。</del>
|
||||||
- 所有的插件都继承自`PluginBase`。
|
- 基于`Action`,`Command`和`Event`的插件基类现在为`BasePlugin`,所有插件都应该继承此基类。
|
||||||
- 所有的插件都由`register_plugin`装饰器注册。
|
- `BasePlugin`继承自`PluginBase`。
|
||||||
|
- 所有的插件类都由`register_plugin`装饰器注册。
|
||||||
6. 现在我们终于可以让插件有自定义的名字了!
|
6. 现在我们终于可以让插件有自定义的名字了!
|
||||||
- 真正实现了插件的`plugin_name`**不受文件夹名称限制**的功能。(吐槽:可乐你的某个小小细节导致我搞了好久……)
|
- 真正实现了插件的`plugin_name`**不受文件夹名称限制**的功能。(吐槽:可乐你的某个小小细节导致我搞了好久……)
|
||||||
- 通过在插件类中定义`plugin_name`属性来指定插件内部标识符。
|
- 通过在插件类中定义`plugin_name`属性来指定插件内部标识符。
|
||||||
@@ -38,6 +40,7 @@
|
|||||||
- 例如:`MaiMBot.plugins.example_plugin`而不是`example_plugin`。
|
- 例如:`MaiMBot.plugins.example_plugin`而不是`example_plugin`。
|
||||||
- 仅在插件 import 失败时会如此,正常注册过程中失败的插件不会显示包名,而是显示插件内部标识符。(这是特性,但是基本上不可能出现这个情况)
|
- 仅在插件 import 失败时会如此,正常注册过程中失败的插件不会显示包名,而是显示插件内部标识符。(这是特性,但是基本上不可能出现这个情况)
|
||||||
7. 现在不支持单文件插件了,加载方式已经完全删除。
|
7. 现在不支持单文件插件了,加载方式已经完全删除。
|
||||||
|
8. 把`BaseEventPlugin`合并到了`BasePlugin`中,所有插件都应该继承自`BasePlugin`。
|
||||||
|
|
||||||
|
|
||||||
# 吐槽
|
# 吐槽
|
||||||
|
|||||||
@@ -7,15 +7,13 @@ from src.plugin_system import (
|
|||||||
ComponentInfo,
|
ComponentInfo,
|
||||||
ActionActivationType,
|
ActionActivationType,
|
||||||
ConfigField,
|
ConfigField,
|
||||||
BaseEventPlugin,
|
|
||||||
BaseEventHandler,
|
BaseEventHandler,
|
||||||
EventType,
|
EventType,
|
||||||
|
MaiMessages,
|
||||||
)
|
)
|
||||||
from src.plugin_system.base.component_types import MaiMessages
|
|
||||||
|
|
||||||
# ===== Action组件 =====
|
# ===== Action组件 =====
|
||||||
|
|
||||||
|
|
||||||
class HelloAction(BaseAction):
|
class HelloAction(BaseAction):
|
||||||
"""问候Action - 简单的问候动作"""
|
"""问候Action - 简单的问候动作"""
|
||||||
|
|
||||||
@@ -86,7 +84,7 @@ class TimeCommand(BaseCommand):
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
# 获取当前时间
|
# 获取当前时间
|
||||||
time_format = self.get_config("time.format", "%Y-%m-%d %H:%M:%S")
|
time_format: str = self.get_config("time.format", "%Y-%m-%d %H:%M:%S") # type: ignore
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
time_str = now.strftime(time_format)
|
time_str = now.strftime(time_format)
|
||||||
|
|
||||||
@@ -140,6 +138,7 @@ class HelloWorldPlugin(BasePlugin):
|
|||||||
"enable_emoji": ConfigField(type=bool, default=True, description="是否启用表情符号"),
|
"enable_emoji": ConfigField(type=bool, default=True, description="是否启用表情符号"),
|
||||||
},
|
},
|
||||||
"time": {"format": ConfigField(type=str, default="%Y-%m-%d %H:%M:%S", description="时间显示格式")},
|
"time": {"format": ConfigField(type=str, default="%Y-%m-%d %H:%M:%S", description="时间显示格式")},
|
||||||
|
"print_message": {"enabled": ConfigField(type=bool, default=True, description="是否启用打印")},
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_plugin_components(self) -> List[Tuple[ComponentInfo, Type]]:
|
def get_plugin_components(self) -> List[Tuple[ComponentInfo, Type]]:
|
||||||
@@ -147,26 +146,27 @@ class HelloWorldPlugin(BasePlugin):
|
|||||||
(HelloAction.get_action_info(), HelloAction),
|
(HelloAction.get_action_info(), HelloAction),
|
||||||
(ByeAction.get_action_info(), ByeAction), # 添加告别Action
|
(ByeAction.get_action_info(), ByeAction), # 添加告别Action
|
||||||
(TimeCommand.get_command_info(), TimeCommand),
|
(TimeCommand.get_command_info(), TimeCommand),
|
||||||
|
(PrintMessage.get_handler_info(), PrintMessage),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@register_plugin
|
# @register_plugin
|
||||||
class HelloWorldEventPlugin(BaseEventPlugin):
|
# class HelloWorldEventPlugin(BaseEPlugin):
|
||||||
"""Hello World事件插件 - 处理问候和告别事件"""
|
# """Hello World事件插件 - 处理问候和告别事件"""
|
||||||
|
|
||||||
plugin_name = "hello_world_event_plugin"
|
# plugin_name = "hello_world_event_plugin"
|
||||||
enable_plugin = False
|
# enable_plugin = False
|
||||||
dependencies = []
|
# dependencies = []
|
||||||
python_dependencies = []
|
# python_dependencies = []
|
||||||
config_file_name = "event_config.toml"
|
# config_file_name = "event_config.toml"
|
||||||
|
|
||||||
config_schema = {
|
|
||||||
"plugin": {
|
|
||||||
"name": ConfigField(type=str, default="hello_world_event_plugin", description="插件名称"),
|
|
||||||
"version": ConfigField(type=str, default="1.0.0", description="插件版本"),
|
|
||||||
"enabled": ConfigField(type=bool, default=True, description="是否启用插件"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_plugin_components(self) -> List[Tuple[ComponentInfo, Type]]:
|
# config_schema = {
|
||||||
return [(PrintMessage.get_handler_info(), PrintMessage)]
|
# "plugin": {
|
||||||
|
# "name": ConfigField(type=str, default="hello_world_event_plugin", description="插件名称"),
|
||||||
|
# "version": ConfigField(type=str, default="1.0.0", description="插件版本"),
|
||||||
|
# "enabled": ConfigField(type=bool, default=True, description="是否启用插件"),
|
||||||
|
# },
|
||||||
|
# }
|
||||||
|
|
||||||
|
# def get_plugin_components(self) -> List[Tuple[ComponentInfo, Type]]:
|
||||||
|
# return [(PrintMessage.get_handler_info(), PrintMessage)]
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ from .base import (
|
|||||||
BaseEventHandler,
|
BaseEventHandler,
|
||||||
EventHandlerInfo,
|
EventHandlerInfo,
|
||||||
EventType,
|
EventType,
|
||||||
BaseEventPlugin,
|
|
||||||
MaiMessages,
|
MaiMessages,
|
||||||
)
|
)
|
||||||
from .core import (
|
from .core import (
|
||||||
@@ -49,7 +48,6 @@ __all__ = [
|
|||||||
"BasePlugin",
|
"BasePlugin",
|
||||||
"BaseAction",
|
"BaseAction",
|
||||||
"BaseCommand",
|
"BaseCommand",
|
||||||
"BaseEventPlugin",
|
|
||||||
"BaseEventHandler",
|
"BaseEventHandler",
|
||||||
# 类型定义
|
# 类型定义
|
||||||
"ComponentType",
|
"ComponentType",
|
||||||
|
|||||||
@@ -2,13 +2,12 @@ from pathlib import Path
|
|||||||
|
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
|
|
||||||
logger = get_logger("plugin_register")
|
logger = get_logger("plugin_manager") # 复用plugin_manager名称
|
||||||
|
|
||||||
|
|
||||||
def register_plugin(cls):
|
def register_plugin(cls):
|
||||||
from src.plugin_system.core.plugin_manager import plugin_manager
|
from src.plugin_system.core.plugin_manager import plugin_manager
|
||||||
from src.plugin_system.base.base_plugin import BasePlugin
|
from src.plugin_system.base.base_plugin import BasePlugin
|
||||||
from src.plugin_system.base.base_event_plugin import BaseEventPlugin
|
|
||||||
|
|
||||||
"""插件注册装饰器
|
"""插件注册装饰器
|
||||||
|
|
||||||
@@ -19,13 +18,16 @@ def register_plugin(cls):
|
|||||||
plugin_description = "我的插件"
|
plugin_description = "我的插件"
|
||||||
...
|
...
|
||||||
"""
|
"""
|
||||||
if not issubclass(cls, BasePlugin) and not issubclass(cls, BaseEventPlugin):
|
if not issubclass(cls, BasePlugin):
|
||||||
logger.error(f"类 {cls.__name__} 不是 BasePlugin 的子类")
|
logger.error(f"类 {cls.__name__} 不是 BasePlugin 的子类")
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
# 只是注册插件类,不立即实例化
|
# 只是注册插件类,不立即实例化
|
||||||
# 插件管理器会负责实例化和注册
|
# 插件管理器会负责实例化和注册
|
||||||
plugin_name: str = cls.plugin_name # type: ignore
|
plugin_name: str = cls.plugin_name # type: ignore
|
||||||
|
if "." in plugin_name:
|
||||||
|
logger.error(f"插件名称 '{plugin_name}' 包含非法字符 '.',请使用下划线替代")
|
||||||
|
raise ValueError(f"插件名称 '{plugin_name}' 包含非法字符 '.',请使用下划线替代")
|
||||||
plugin_manager.plugin_classes[plugin_name] = cls
|
plugin_manager.plugin_classes[plugin_name] = cls
|
||||||
splitted_name = cls.__module__.split(".")
|
splitted_name = cls.__module__.split(".")
|
||||||
root_path = Path(__file__)
|
root_path = Path(__file__)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
from .base_plugin import BasePlugin
|
from .base_plugin import BasePlugin
|
||||||
from .base_action import BaseAction
|
from .base_action import BaseAction
|
||||||
from .base_command import BaseCommand
|
from .base_command import BaseCommand
|
||||||
from .base_event_plugin import BaseEventPlugin
|
|
||||||
from .base_events_handler import BaseEventHandler
|
from .base_events_handler import BaseEventHandler
|
||||||
from .component_types import (
|
from .component_types import (
|
||||||
ComponentType,
|
ComponentType,
|
||||||
@@ -39,7 +38,6 @@ __all__ = [
|
|||||||
"ConfigField",
|
"ConfigField",
|
||||||
"EventHandlerInfo",
|
"EventHandlerInfo",
|
||||||
"EventType",
|
"EventType",
|
||||||
"BaseEventPlugin",
|
|
||||||
"BaseEventHandler",
|
"BaseEventHandler",
|
||||||
"MaiMessages",
|
"MaiMessages",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class BaseAction(ABC):
|
|||||||
action_message: Optional[dict] = None,
|
action_message: Optional[dict] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
|
# sourcery skip: hoist-similar-statement-from-if, merge-else-if-into-elif, move-assign-in-block, swap-if-else-branches, swap-nested-ifs
|
||||||
"""初始化Action组件
|
"""初始化Action组件
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -355,7 +356,9 @@ class BaseAction(ABC):
|
|||||||
|
|
||||||
# 从类属性读取名称,如果没有定义则使用类名自动生成
|
# 从类属性读取名称,如果没有定义则使用类名自动生成
|
||||||
name = getattr(cls, "action_name", cls.__name__.lower().replace("action", ""))
|
name = getattr(cls, "action_name", cls.__name__.lower().replace("action", ""))
|
||||||
|
if "." in name:
|
||||||
|
logger.error(f"Action名称 '{name}' 包含非法字符 '.',请使用下划线替代")
|
||||||
|
raise ValueError(f"Action名称 '{name}' 包含非法字符 '.',请使用下划线替代")
|
||||||
# 获取focus_activation_type和normal_activation_type
|
# 获取focus_activation_type和normal_activation_type
|
||||||
focus_activation_type = getattr(cls, "focus_activation_type", ActionActivationType.ALWAYS)
|
focus_activation_type = getattr(cls, "focus_activation_type", ActionActivationType.ALWAYS)
|
||||||
normal_activation_type = getattr(cls, "normal_activation_type", ActionActivationType.ALWAYS)
|
normal_activation_type = getattr(cls, "normal_activation_type", ActionActivationType.ALWAYS)
|
||||||
|
|||||||
@@ -219,7 +219,9 @@ class BaseCommand(ABC):
|
|||||||
Returns:
|
Returns:
|
||||||
CommandInfo: 生成的Command信息对象
|
CommandInfo: 生成的Command信息对象
|
||||||
"""
|
"""
|
||||||
|
if "." in cls.command_name:
|
||||||
|
logger.error(f"Command名称 '{cls.command_name}' 包含非法字符 '.',请使用下划线替代")
|
||||||
|
raise ValueError(f"Command名称 '{cls.command_name}' 包含非法字符 '.',请使用下划线替代")
|
||||||
return CommandInfo(
|
return CommandInfo(
|
||||||
name=cls.command_name,
|
name=cls.command_name,
|
||||||
component_type=ComponentType.COMMAND,
|
component_type=ComponentType.COMMAND,
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
from abc import abstractmethod
|
|
||||||
from typing import List, Tuple, Type
|
|
||||||
|
|
||||||
from src.common.logger import get_logger
|
|
||||||
from .plugin_base import PluginBase
|
|
||||||
from .component_types import EventHandlerInfo
|
|
||||||
from .base_events_handler import BaseEventHandler
|
|
||||||
|
|
||||||
logger = get_logger("base_event_plugin")
|
|
||||||
|
|
||||||
class BaseEventPlugin(PluginBase):
|
|
||||||
"""基于事件的插件基类
|
|
||||||
|
|
||||||
所有事件类型的插件都应该继承这个基类
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_plugin_components(self) -> List[Tuple[EventHandlerInfo, Type[BaseEventHandler]]]:
|
|
||||||
"""获取插件包含的事件组件
|
|
||||||
|
|
||||||
子类必须实现此方法,返回事件组件
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
List[Tuple[ComponentInfo, Type]]: [(组件信息, 组件类), ...]
|
|
||||||
"""
|
|
||||||
raise NotImplementedError("子类必须实现 get_plugin_components 方法")
|
|
||||||
|
|
||||||
def register_plugin(self) -> bool:
|
|
||||||
"""注册事件插件"""
|
|
||||||
from src.plugin_system.core.events_manager import events_manager
|
|
||||||
|
|
||||||
components = self.get_plugin_components()
|
|
||||||
|
|
||||||
# 检查依赖
|
|
||||||
if not self._check_dependencies():
|
|
||||||
logger.error(f"{self.log_prefix} 依赖检查失败,跳过注册")
|
|
||||||
return False
|
|
||||||
|
|
||||||
registered_components = []
|
|
||||||
for handler_info, handler_class in components:
|
|
||||||
handler_info.plugin_name = self.plugin_name
|
|
||||||
if events_manager.register_event_subscriber(handler_info, handler_class):
|
|
||||||
registered_components.append(handler_info)
|
|
||||||
else:
|
|
||||||
logger.error(f"{self.log_prefix} 事件处理器 {handler_info.name} 注册失败")
|
|
||||||
|
|
||||||
self.plugin_info.components = registered_components
|
|
||||||
|
|
||||||
if events_manager.register_plugins(self.plugin_info):
|
|
||||||
logger.debug(f"{self.log_prefix} 插件注册成功,包含 {len(registered_components)} 个事件处理器")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
logger.error(f"{self.log_prefix} 插件注册失败")
|
|
||||||
return False
|
|
||||||
@@ -38,9 +38,12 @@ class BaseEventHandler(ABC):
|
|||||||
"""获取事件处理器的信息"""
|
"""获取事件处理器的信息"""
|
||||||
# 从类属性读取名称,如果没有定义则使用类名自动生成
|
# 从类属性读取名称,如果没有定义则使用类名自动生成
|
||||||
name: str = getattr(cls, "handler_name", cls.__name__.lower().replace("handler", ""))
|
name: str = getattr(cls, "handler_name", cls.__name__.lower().replace("handler", ""))
|
||||||
|
if "." in name:
|
||||||
|
logger.error(f"事件处理器名称 '{name}' 包含非法字符 '.',请使用下划线替代")
|
||||||
|
raise ValueError(f"事件处理器名称 '{name}' 包含非法字符 '.',请使用下划线替代")
|
||||||
return EventHandlerInfo(
|
return EventHandlerInfo(
|
||||||
name=name,
|
name=name,
|
||||||
component_type=ComponentType.LISTENER,
|
component_type=ComponentType.EVENT_HANDLER,
|
||||||
description=getattr(cls, "handler_description", "events处理器"),
|
description=getattr(cls, "handler_description", "events处理器"),
|
||||||
event_type=cls.event_type,
|
event_type=cls.event_type,
|
||||||
weight=cls.weight,
|
weight=cls.weight,
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import List, Type
|
from typing import List, Type, Tuple, Union
|
||||||
from .plugin_base import PluginBase
|
from .plugin_base import PluginBase
|
||||||
|
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.plugin_system.base.component_types import ComponentInfo
|
from src.plugin_system.base.component_types import ComponentInfo, ActionInfo, CommandInfo, EventHandlerInfo
|
||||||
|
from .base_action import BaseAction
|
||||||
|
from .base_command import BaseCommand
|
||||||
|
from .base_events_handler import BaseEventHandler
|
||||||
|
|
||||||
logger = get_logger("base_plugin")
|
logger = get_logger("base_plugin")
|
||||||
|
|
||||||
@@ -21,7 +24,15 @@ class BasePlugin(PluginBase):
|
|||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_plugin_components(self) -> List[tuple[ComponentInfo, Type]]:
|
def get_plugin_components(
|
||||||
|
self,
|
||||||
|
) -> List[
|
||||||
|
Union[
|
||||||
|
Tuple[ActionInfo, Type[BaseAction]],
|
||||||
|
Tuple[CommandInfo, Type[BaseCommand]],
|
||||||
|
Tuple[EventHandlerInfo, Type[BaseEventHandler]],
|
||||||
|
]
|
||||||
|
]:
|
||||||
"""获取插件包含的组件列表
|
"""获取插件包含的组件列表
|
||||||
|
|
||||||
子类必须实现此方法,返回组件信息和组件类的列表
|
子类必须实现此方法,返回组件信息和组件类的列表
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class ComponentType(Enum):
|
|||||||
ACTION = "action" # 动作组件
|
ACTION = "action" # 动作组件
|
||||||
COMMAND = "command" # 命令组件
|
COMMAND = "command" # 命令组件
|
||||||
SCHEDULER = "scheduler" # 定时任务组件(预留)
|
SCHEDULER = "scheduler" # 定时任务组件(预留)
|
||||||
LISTENER = "listener" # 事件监听组件(预留)
|
EVENT_HANDLER = "event_handler" # 事件处理组件(预留)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return self.value
|
return self.value
|
||||||
@@ -161,7 +161,7 @@ class EventHandlerInfo(ComponentInfo):
|
|||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
super().__post_init__()
|
super().__post_init__()
|
||||||
self.component_type = ComponentType.LISTENER
|
self.component_type = ComponentType.EVENT_HANDLER
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
from typing import Dict, List, Optional, Any, Pattern, Tuple, Union, Type
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from typing import Dict, List, Optional, Any, Pattern, Tuple, Union, Type
|
||||||
|
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.plugin_system.base.component_types import (
|
from src.plugin_system.base.component_types import (
|
||||||
ComponentInfo,
|
ComponentInfo,
|
||||||
ActionInfo,
|
ActionInfo,
|
||||||
CommandInfo,
|
CommandInfo,
|
||||||
|
EventHandlerInfo,
|
||||||
PluginInfo,
|
PluginInfo,
|
||||||
ComponentType,
|
ComponentType,
|
||||||
)
|
)
|
||||||
|
|
||||||
from src.plugin_system.base.base_command import BaseCommand
|
from src.plugin_system.base.base_command import BaseCommand
|
||||||
from src.plugin_system.base.base_action import BaseAction
|
from src.plugin_system.base.base_action import BaseAction
|
||||||
|
from src.plugin_system.base.base_events_handler import BaseEventHandler
|
||||||
|
|
||||||
logger = get_logger("component_registry")
|
logger = get_logger("component_registry")
|
||||||
|
|
||||||
@@ -23,12 +26,11 @@ class ComponentRegistry:
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# 组件注册表
|
# 组件注册表
|
||||||
self._components: Dict[str, ComponentInfo] = {} # 组件名 -> 组件信息
|
self._components: Dict[str, ComponentInfo] = {} # 命名空间式组件名 -> 组件信息
|
||||||
self._components_by_type: Dict[ComponentType, Dict[str, ComponentInfo]] = {
|
# 类型 -> 命名空间式名称 -> 组件信息
|
||||||
ComponentType.ACTION: {},
|
self._components_by_type: Dict[ComponentType, Dict[str, ComponentInfo]] = {types: {} for types in ComponentType}
|
||||||
ComponentType.COMMAND: {},
|
# 命名空间式组件名 -> 组件类
|
||||||
}
|
self._components_classes: Dict[str, Type[Union[BaseCommand, BaseAction, BaseEventHandler]]] = {}
|
||||||
self._component_classes: Dict[str, Union[Type[BaseCommand], Type[BaseAction]]] = {} # 组件名 -> 组件类
|
|
||||||
|
|
||||||
# 插件注册表
|
# 插件注册表
|
||||||
self._plugins: Dict[str, PluginInfo] = {} # 插件名 -> 插件信息
|
self._plugins: Dict[str, PluginInfo] = {} # 插件名 -> 插件信息
|
||||||
@@ -39,20 +41,43 @@ class ComponentRegistry:
|
|||||||
|
|
||||||
# Command特定注册表
|
# Command特定注册表
|
||||||
self._command_registry: Dict[str, Type[BaseCommand]] = {} # command名 -> command类
|
self._command_registry: Dict[str, Type[BaseCommand]] = {} # command名 -> command类
|
||||||
self._command_patterns: Dict[Pattern, Type[BaseCommand]] = {} # 编译后的正则 -> command类
|
self._command_patterns: Dict[Pattern, str] = {} # 编译后的正则 -> command名
|
||||||
|
|
||||||
|
# EventHandler特定注册表
|
||||||
|
self._event_handler_registry: Dict[str, Type[BaseEventHandler]] = {} # event_handler名 -> event_handler类
|
||||||
|
self._enabled_event_handlers: Dict[str, Type[BaseEventHandler]] = {} # 启用的事件处理器
|
||||||
|
|
||||||
logger.info("组件注册中心初始化完成")
|
logger.info("组件注册中心初始化完成")
|
||||||
|
|
||||||
# === 通用组件注册方法 ===
|
# == 注册方法 ==
|
||||||
|
|
||||||
|
def register_plugin(self, plugin_info: PluginInfo) -> bool:
|
||||||
|
"""注册插件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
plugin_info: 插件信息
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: 是否注册成功
|
||||||
|
"""
|
||||||
|
plugin_name = plugin_info.name
|
||||||
|
|
||||||
|
if plugin_name in self._plugins:
|
||||||
|
logger.warning(f"插件 {plugin_name} 已存在,跳过注册")
|
||||||
|
return False
|
||||||
|
|
||||||
|
self._plugins[plugin_name] = plugin_info
|
||||||
|
logger.debug(f"已注册插件: {plugin_name} (组件数量: {len(plugin_info.components)})")
|
||||||
|
return True
|
||||||
|
|
||||||
def register_component(
|
def register_component(
|
||||||
self, component_info: ComponentInfo, component_class: Union[Type[BaseCommand], Type[BaseAction]]
|
self, component_info: ComponentInfo, component_class: Type[Union[BaseCommand, BaseAction, BaseEventHandler]]
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""注册组件
|
"""注册组件
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
component_info: 组件信息
|
component_info (ComponentInfo): 组件信息
|
||||||
component_class: 组件类
|
component_class (Type[Union[BaseCommand, BaseAction, BaseEventHandler]]): 组件类
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: 是否注册成功
|
bool: 是否注册成功
|
||||||
@@ -60,68 +85,110 @@ class ComponentRegistry:
|
|||||||
component_name = component_info.name
|
component_name = component_info.name
|
||||||
component_type = component_info.component_type
|
component_type = component_info.component_type
|
||||||
plugin_name = getattr(component_info, "plugin_name", "unknown")
|
plugin_name = getattr(component_info, "plugin_name", "unknown")
|
||||||
|
if "." in component_name:
|
||||||
|
logger.error(f"组件名称 '{component_name}' 包含非法字符 '.',请使用下划线替代")
|
||||||
|
return False
|
||||||
|
if "." in plugin_name:
|
||||||
|
logger.error(f"插件名称 '{plugin_name}' 包含非法字符 '.',请使用下划线替代")
|
||||||
|
return False
|
||||||
|
|
||||||
# 🔥 系统级别自动区分:为不同类型的组件添加命名空间前缀
|
namespaced_name = f"{component_type}.{component_name}"
|
||||||
if component_type == ComponentType.ACTION:
|
|
||||||
namespaced_name = f"action.{component_name}"
|
|
||||||
elif component_type == ComponentType.COMMAND:
|
|
||||||
namespaced_name = f"command.{component_name}"
|
|
||||||
else:
|
|
||||||
# 未来扩展的组件类型
|
|
||||||
namespaced_name = f"{component_type.value}.{component_name}"
|
|
||||||
|
|
||||||
# 检查命名空间化的名称是否冲突
|
|
||||||
if namespaced_name in self._components:
|
if namespaced_name in self._components:
|
||||||
existing_info = self._components[namespaced_name]
|
existing_info = self._components[namespaced_name]
|
||||||
existing_plugin = getattr(existing_info, "plugin_name", "unknown")
|
existing_plugin = getattr(existing_info, "plugin_name", "unknown")
|
||||||
|
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"组件冲突: {component_type.value}组件 '{component_name}' "
|
f"组件名冲突: '{plugin_name}' 插件的 {component_type} 类型组件 '{component_name}' 已被插件 '{existing_plugin}' 注册,跳过此组件注册"
|
||||||
f"已被插件 '{existing_plugin}' 注册,跳过插件 '{plugin_name}' 的注册"
|
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 注册到通用注册表(使用命名空间化的名称)
|
self._components[namespaced_name] = component_info # 注册到通用注册表(使用命名空间化的名称)
|
||||||
self._components[namespaced_name] = component_info
|
|
||||||
self._components_by_type[component_type][component_name] = component_info # 类型内部仍使用原名
|
self._components_by_type[component_type][component_name] = component_info # 类型内部仍使用原名
|
||||||
self._component_classes[namespaced_name] = component_class
|
self._components_classes[namespaced_name] = component_class
|
||||||
|
|
||||||
# 根据组件类型进行特定注册(使用原始名称)
|
# 根据组件类型进行特定注册(使用原始名称)
|
||||||
if component_type == ComponentType.ACTION:
|
match component_type:
|
||||||
self._register_action_component(component_info, component_class) # type: ignore
|
case ComponentType.ACTION:
|
||||||
elif component_type == ComponentType.COMMAND:
|
ret = self._register_action_component(component_info, component_class) # type: ignore
|
||||||
self._register_command_component(component_info, component_class) # type: ignore
|
case ComponentType.COMMAND:
|
||||||
|
ret = self._register_command_component(component_info, component_class) # type: ignore
|
||||||
|
case ComponentType.EVENT_HANDLER:
|
||||||
|
ret = self._register_event_handler_component(component_info, component_class) # type: ignore
|
||||||
|
case _:
|
||||||
|
logger.warning(f"未知组件类型: {component_type}")
|
||||||
|
|
||||||
|
if not ret:
|
||||||
|
return False
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"已注册{component_type.value}组件: '{component_name}' -> '{namespaced_name}' "
|
f"已注册{component_type}组件: '{component_name}' -> '{namespaced_name}' "
|
||||||
f"({component_class.__name__}) [插件: {plugin_name}]"
|
f"({component_class.__name__}) [插件: {plugin_name}]"
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _register_action_component(self, action_info: ActionInfo, action_class: Type[BaseAction]):
|
def _register_action_component(self, action_info: ActionInfo, action_class: Type[BaseAction]) -> bool:
|
||||||
# -------------------------------- NEED REFACTORING --------------------------------
|
|
||||||
# -------------------------------- LOGIC ERROR -------------------------------------
|
|
||||||
"""注册Action组件到Action特定注册表"""
|
"""注册Action组件到Action特定注册表"""
|
||||||
action_name = action_info.name
|
if not (action_name := action_info.name):
|
||||||
|
logger.error(f"Action组件 {action_class.__name__} 必须指定名称")
|
||||||
|
return False
|
||||||
|
if not isinstance(action_info, ActionInfo) or not issubclass(action_class, BaseAction):
|
||||||
|
logger.error(f"注册失败: {action_name} 不是有效的Action")
|
||||||
|
return False
|
||||||
|
|
||||||
self._action_registry[action_name] = action_class
|
self._action_registry[action_name] = action_class
|
||||||
|
|
||||||
# 如果启用,添加到默认动作集
|
# 如果启用,添加到默认动作集
|
||||||
if action_info.enabled:
|
if action_info.enabled:
|
||||||
self._default_actions[action_name] = action_info
|
self._default_actions[action_name] = action_info
|
||||||
|
|
||||||
def _register_command_component(self, command_info: CommandInfo, command_class: Type[BaseCommand]):
|
return True
|
||||||
|
|
||||||
|
def _register_command_component(self, command_info: CommandInfo, command_class: Type[BaseCommand]) -> bool:
|
||||||
"""注册Command组件到Command特定注册表"""
|
"""注册Command组件到Command特定注册表"""
|
||||||
command_name = command_info.name
|
if not (command_name := command_info.name):
|
||||||
|
logger.error(f"Command组件 {command_class.__name__} 必须指定名称")
|
||||||
|
return False
|
||||||
|
if not isinstance(command_info, CommandInfo) or not issubclass(command_class, BaseCommand):
|
||||||
|
logger.error(f"注册失败: {command_name} 不是有效的Command")
|
||||||
|
return False
|
||||||
|
|
||||||
self._command_registry[command_name] = command_class
|
self._command_registry[command_name] = command_class
|
||||||
|
|
||||||
# 编译正则表达式并注册
|
# 如果启用了且有匹配模式
|
||||||
if command_info.command_pattern:
|
if command_info.enabled and command_info.command_pattern:
|
||||||
pattern = re.compile(command_info.command_pattern, re.IGNORECASE | re.DOTALL)
|
pattern = re.compile(command_info.command_pattern, re.IGNORECASE | re.DOTALL)
|
||||||
self._command_patterns[pattern] = command_class
|
if pattern not in self._command_patterns:
|
||||||
|
self._command_patterns[pattern] = command_name
|
||||||
|
|
||||||
|
logger.warning(f"'{command_name}' 对应的命令模式与 '{self._command_patterns[pattern]}' 重复,忽略此命令")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _register_event_handler_component(
|
||||||
|
self, handler_info: EventHandlerInfo, handler_class: Type[BaseEventHandler]
|
||||||
|
) -> bool:
|
||||||
|
if not (handler_name := handler_info.name):
|
||||||
|
logger.error(f"EventHandler组件 {handler_class.__name__} 必须指定名称")
|
||||||
|
return False
|
||||||
|
if not isinstance(handler_info, EventHandlerInfo) or not issubclass(handler_class, BaseEventHandler):
|
||||||
|
logger.error(f"注册失败: {handler_name} 不是有效的EventHandler")
|
||||||
|
return False
|
||||||
|
|
||||||
|
self._event_handler_registry[handler_name] = handler_class
|
||||||
|
|
||||||
|
from .events_manager import events_manager # 延迟导入防止循环导入问题
|
||||||
|
|
||||||
|
if events_manager.register_event_subscriber(handler_info, handler_class):
|
||||||
|
self._enabled_event_handlers[handler_name] = handler_class
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.error(f"注册事件处理器 {handler_name} 失败")
|
||||||
|
return False
|
||||||
|
|
||||||
# === 组件查询方法 ===
|
# === 组件查询方法 ===
|
||||||
|
def get_component_info(
|
||||||
def get_component_info(self, component_name: str, component_type: ComponentType = None) -> Optional[ComponentInfo]: # type: ignore
|
self, component_name: str, component_type: Optional[ComponentType] = None
|
||||||
|
) -> Optional[ComponentInfo]:
|
||||||
# sourcery skip: class-extract-method
|
# sourcery skip: class-extract-method
|
||||||
"""获取组件信息,支持自动命名空间解析
|
"""获取组件信息,支持自动命名空间解析
|
||||||
|
|
||||||
@@ -138,18 +205,12 @@ class ComponentRegistry:
|
|||||||
|
|
||||||
# 2. 如果指定了组件类型,构造命名空间化的名称查找
|
# 2. 如果指定了组件类型,构造命名空间化的名称查找
|
||||||
if component_type:
|
if component_type:
|
||||||
if component_type == ComponentType.ACTION:
|
namespaced_name = f"{component_type}.{component_name}"
|
||||||
namespaced_name = f"action.{component_name}"
|
|
||||||
elif component_type == ComponentType.COMMAND:
|
|
||||||
namespaced_name = f"command.{component_name}"
|
|
||||||
else:
|
|
||||||
namespaced_name = f"{component_type.value}.{component_name}"
|
|
||||||
|
|
||||||
return self._components.get(namespaced_name)
|
return self._components.get(namespaced_name)
|
||||||
|
|
||||||
# 3. 如果没有指定类型,尝试在所有命名空间中查找
|
# 3. 如果没有指定类型,尝试在所有命名空间中查找
|
||||||
candidates = []
|
candidates = []
|
||||||
for namespace_prefix in ["action", "command"]:
|
for namespace_prefix in [types.value for types in ComponentType]:
|
||||||
namespaced_name = f"{namespace_prefix}.{component_name}"
|
namespaced_name = f"{namespace_prefix}.{component_name}"
|
||||||
if component_info := self._components.get(namespaced_name):
|
if component_info := self._components.get(namespaced_name):
|
||||||
candidates.append((namespace_prefix, namespaced_name, component_info))
|
candidates.append((namespace_prefix, namespaced_name, component_info))
|
||||||
@@ -171,8 +232,8 @@ class ComponentRegistry:
|
|||||||
def get_component_class(
|
def get_component_class(
|
||||||
self,
|
self,
|
||||||
component_name: str,
|
component_name: str,
|
||||||
component_type: ComponentType = None, # type: ignore
|
component_type: Optional[ComponentType] = None,
|
||||||
) -> Optional[Union[Type[BaseCommand], Type[BaseAction]]]:
|
) -> Optional[Union[Type[BaseCommand], Type[BaseAction], Type[BaseEventHandler]]]:
|
||||||
"""获取组件类,支持自动命名空间解析
|
"""获取组件类,支持自动命名空间解析
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -184,29 +245,23 @@ class ComponentRegistry:
|
|||||||
"""
|
"""
|
||||||
# 1. 如果已经是命名空间化的名称,直接查找
|
# 1. 如果已经是命名空间化的名称,直接查找
|
||||||
if "." in component_name:
|
if "." in component_name:
|
||||||
return self._component_classes.get(component_name)
|
return self._components_classes.get(component_name)
|
||||||
|
|
||||||
# 2. 如果指定了组件类型,构造命名空间化的名称查找
|
# 2. 如果指定了组件类型,构造命名空间化的名称查找
|
||||||
if component_type:
|
if component_type:
|
||||||
if component_type == ComponentType.ACTION:
|
namespaced_name = f"{component_type.value}.{component_name}"
|
||||||
namespaced_name = f"action.{component_name}"
|
return self._components_classes.get(namespaced_name)
|
||||||
elif component_type == ComponentType.COMMAND:
|
|
||||||
namespaced_name = f"command.{component_name}"
|
|
||||||
else:
|
|
||||||
namespaced_name = f"{component_type.value}.{component_name}"
|
|
||||||
|
|
||||||
return self._component_classes.get(namespaced_name)
|
|
||||||
|
|
||||||
# 3. 如果没有指定类型,尝试在所有命名空间中查找
|
# 3. 如果没有指定类型,尝试在所有命名空间中查找
|
||||||
candidates = []
|
candidates = []
|
||||||
for namespace_prefix in ["action", "command"]:
|
for namespace_prefix in [types.value for types in ComponentType]:
|
||||||
namespaced_name = f"{namespace_prefix}.{component_name}"
|
namespaced_name = f"{namespace_prefix}.{component_name}"
|
||||||
if component_class := self._component_classes.get(namespaced_name):
|
if component_class := self._components_classes.get(namespaced_name):
|
||||||
candidates.append((namespace_prefix, namespaced_name, component_class))
|
candidates.append((namespace_prefix, namespaced_name, component_class))
|
||||||
|
|
||||||
if len(candidates) == 1:
|
if len(candidates) == 1:
|
||||||
# 只有一个匹配,直接返回
|
# 只有一个匹配,直接返回
|
||||||
namespace, full_name, cls = candidates[0]
|
_, full_name, cls = candidates[0]
|
||||||
logger.debug(f"自动解析组件: '{component_name}' -> '{full_name}'")
|
logger.debug(f"自动解析组件: '{component_name}' -> '{full_name}'")
|
||||||
return cls
|
return cls
|
||||||
elif len(candidates) > 1:
|
elif len(candidates) > 1:
|
||||||
@@ -235,7 +290,7 @@ class ComponentRegistry:
|
|||||||
"""获取Action注册表(用于兼容现有系统)"""
|
"""获取Action注册表(用于兼容现有系统)"""
|
||||||
return self._action_registry.copy()
|
return self._action_registry.copy()
|
||||||
|
|
||||||
def get_action_info(self, action_name: str) -> Optional[ActionInfo]:
|
def get_registered_action_info(self, action_name: str) -> Optional[ActionInfo]:
|
||||||
"""获取Action信息"""
|
"""获取Action信息"""
|
||||||
info = self.get_component_info(action_name, ComponentType.ACTION)
|
info = self.get_component_info(action_name, ComponentType.ACTION)
|
||||||
return info if isinstance(info, ActionInfo) else None
|
return info if isinstance(info, ActionInfo) else None
|
||||||
@@ -247,18 +302,18 @@ class ComponentRegistry:
|
|||||||
# === Command特定查询方法 ===
|
# === Command特定查询方法 ===
|
||||||
|
|
||||||
def get_command_registry(self) -> Dict[str, Type[BaseCommand]]:
|
def get_command_registry(self) -> Dict[str, Type[BaseCommand]]:
|
||||||
"""获取Command注册表(用于兼容现有系统)"""
|
"""获取Command注册表"""
|
||||||
return self._command_registry.copy()
|
return self._command_registry.copy()
|
||||||
|
|
||||||
def get_command_patterns(self) -> Dict[Pattern, Type[BaseCommand]]:
|
def get_registered_command_info(self, command_name: str) -> Optional[CommandInfo]:
|
||||||
"""获取Command模式注册表(用于兼容现有系统)"""
|
|
||||||
return self._command_patterns.copy()
|
|
||||||
|
|
||||||
def get_command_info(self, command_name: str) -> Optional[CommandInfo]:
|
|
||||||
"""获取Command信息"""
|
"""获取Command信息"""
|
||||||
info = self.get_component_info(command_name, ComponentType.COMMAND)
|
info = self.get_component_info(command_name, ComponentType.COMMAND)
|
||||||
return info if isinstance(info, CommandInfo) else None
|
return info if isinstance(info, CommandInfo) else None
|
||||||
|
|
||||||
|
def get_command_patterns(self) -> Dict[Pattern, str]:
|
||||||
|
"""获取Command模式注册表"""
|
||||||
|
return self._command_patterns.copy()
|
||||||
|
|
||||||
def find_command_by_text(self, text: str) -> Optional[Tuple[Type[BaseCommand], dict, bool, str]]:
|
def find_command_by_text(self, text: str) -> Optional[Tuple[Type[BaseCommand], dict, bool, str]]:
|
||||||
# sourcery skip: use-named-expression, use-next
|
# sourcery skip: use-named-expression, use-next
|
||||||
"""根据文本查找匹配的命令
|
"""根据文本查找匹配的命令
|
||||||
@@ -270,47 +325,36 @@ class ComponentRegistry:
|
|||||||
Tuple: (命令类, 匹配的命名组, 是否拦截消息, 插件名) 或 None
|
Tuple: (命令类, 匹配的命名组, 是否拦截消息, 插件名) 或 None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for pattern, command_class in self._command_patterns.items():
|
candidates = [pattern for pattern in self._command_patterns if pattern.match(text)]
|
||||||
if match := pattern.match(text):
|
if not candidates:
|
||||||
command_name = None
|
return None
|
||||||
# 查找对应的组件信息
|
if len(candidates) > 1:
|
||||||
for name, cls in self._command_registry.items():
|
logger.warning(f"文本 '{text}' 匹配到多个命令模式: {candidates},使用第一个匹配")
|
||||||
if cls == command_class:
|
command_name = self._command_patterns[candidates[0]]
|
||||||
command_name = name
|
command_info: CommandInfo = self.get_registered_command_info(command_name) # type: ignore
|
||||||
break
|
return (
|
||||||
|
self._command_registry[command_name],
|
||||||
|
candidates[0].match(text).groupdict(), # type: ignore
|
||||||
|
command_info.intercept_message,
|
||||||
|
command_info.plugin_name,
|
||||||
|
)
|
||||||
|
|
||||||
# 检查命令是否启用
|
# === 事件处理器特定查询方法 ===
|
||||||
if command_name:
|
|
||||||
command_info = self.get_command_info(command_name)
|
|
||||||
if command_info and command_info.enabled:
|
|
||||||
return (
|
|
||||||
command_class,
|
|
||||||
match.groupdict(),
|
|
||||||
command_info.intercept_message,
|
|
||||||
command_info.plugin_name,
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
|
|
||||||
# === 插件管理方法 ===
|
def get_event_handler_registry(self) -> Dict[str, Type[BaseEventHandler]]:
|
||||||
|
"""获取事件处理器注册表"""
|
||||||
|
return self._event_handler_registry.copy()
|
||||||
|
|
||||||
def register_plugin(self, plugin_info: PluginInfo) -> bool:
|
def get_registered_event_handler_info(self, handler_name: str) -> Optional[EventHandlerInfo]:
|
||||||
"""注册插件
|
"""获取事件处理器信息"""
|
||||||
|
info = self.get_component_info(handler_name, ComponentType.EVENT_HANDLER)
|
||||||
|
return info if isinstance(info, EventHandlerInfo) else None
|
||||||
|
|
||||||
Args:
|
def get_enabled_event_handlers(self) -> Dict[str, Type[BaseEventHandler]]:
|
||||||
plugin_info: 插件信息
|
"""获取启用的事件处理器"""
|
||||||
|
return self._enabled_event_handlers.copy()
|
||||||
|
|
||||||
Returns:
|
# === 插件查询方法 ===
|
||||||
bool: 是否注册成功
|
|
||||||
"""
|
|
||||||
plugin_name = plugin_info.name
|
|
||||||
|
|
||||||
if plugin_name in self._plugins:
|
|
||||||
logger.warning(f"插件 {plugin_name} 已存在,跳过注册")
|
|
||||||
return False
|
|
||||||
|
|
||||||
self._plugins[plugin_name] = plugin_info
|
|
||||||
logger.debug(f"已注册插件: {plugin_name} (组件数量: {len(plugin_info.components)})")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_plugin_info(self, plugin_name: str) -> Optional[PluginInfo]:
|
def get_plugin_info(self, plugin_name: str) -> Optional[PluginInfo]:
|
||||||
"""获取插件信息"""
|
"""获取插件信息"""
|
||||||
@@ -344,82 +388,22 @@ class ComponentRegistry:
|
|||||||
plugin_instance = plugin_manager.get_plugin_instance(plugin_name)
|
plugin_instance = plugin_manager.get_plugin_instance(plugin_name)
|
||||||
return plugin_instance.config if plugin_instance else None
|
return plugin_instance.config if plugin_instance else None
|
||||||
|
|
||||||
# === 状态管理方法 ===
|
|
||||||
|
|
||||||
# def enable_component(self, component_name: str, component_type: ComponentType = None) -> bool:
|
|
||||||
# # -------------------------------- NEED REFACTORING --------------------------------
|
|
||||||
# # -------------------------------- LOGIC ERROR -------------------------------------
|
|
||||||
# """启用组件,支持命名空间解析"""
|
|
||||||
# # 首先尝试找到正确的命名空间化名称
|
|
||||||
# component_info = self.get_component_info(component_name, component_type)
|
|
||||||
# if not component_info:
|
|
||||||
# return False
|
|
||||||
|
|
||||||
# # 根据组件类型构造正确的命名空间化名称
|
|
||||||
# if component_info.component_type == ComponentType.ACTION:
|
|
||||||
# namespaced_name = f"action.{component_name}" if "." not in component_name else component_name
|
|
||||||
# elif component_info.component_type == ComponentType.COMMAND:
|
|
||||||
# namespaced_name = f"command.{component_name}" if "." not in component_name else component_name
|
|
||||||
# else:
|
|
||||||
# namespaced_name = (
|
|
||||||
# f"{component_info.component_type.value}.{component_name}"
|
|
||||||
# if "." not in component_name
|
|
||||||
# else component_name
|
|
||||||
# )
|
|
||||||
|
|
||||||
# if namespaced_name in self._components:
|
|
||||||
# self._components[namespaced_name].enabled = True
|
|
||||||
# # 如果是Action,更新默认动作集
|
|
||||||
# # ---- HERE ----
|
|
||||||
# # if isinstance(component_info, ActionInfo):
|
|
||||||
# # self._action_descriptions[component_name] = component_info.description
|
|
||||||
# logger.debug(f"已启用组件: {component_name} -> {namespaced_name}")
|
|
||||||
# return True
|
|
||||||
# return False
|
|
||||||
|
|
||||||
# def disable_component(self, component_name: str, component_type: ComponentType = None) -> bool:
|
|
||||||
# # -------------------------------- NEED REFACTORING --------------------------------
|
|
||||||
# # -------------------------------- LOGIC ERROR -------------------------------------
|
|
||||||
# """禁用组件,支持命名空间解析"""
|
|
||||||
# # 首先尝试找到正确的命名空间化名称
|
|
||||||
# component_info = self.get_component_info(component_name, component_type)
|
|
||||||
# if not component_info:
|
|
||||||
# return False
|
|
||||||
|
|
||||||
# # 根据组件类型构造正确的命名空间化名称
|
|
||||||
# if component_info.component_type == ComponentType.ACTION:
|
|
||||||
# namespaced_name = f"action.{component_name}" if "." not in component_name else component_name
|
|
||||||
# elif component_info.component_type == ComponentType.COMMAND:
|
|
||||||
# namespaced_name = f"command.{component_name}" if "." not in component_name else component_name
|
|
||||||
# else:
|
|
||||||
# namespaced_name = (
|
|
||||||
# f"{component_info.component_type.value}.{component_name}"
|
|
||||||
# if "." not in component_name
|
|
||||||
# else component_name
|
|
||||||
# )
|
|
||||||
|
|
||||||
# if namespaced_name in self._components:
|
|
||||||
# self._components[namespaced_name].enabled = False
|
|
||||||
# # 如果是Action,从默认动作集中移除
|
|
||||||
# # ---- HERE ----
|
|
||||||
# # if component_name in self._action_descriptions:
|
|
||||||
# # del self._action_descriptions[component_name]
|
|
||||||
# logger.debug(f"已禁用组件: {component_name} -> {namespaced_name}")
|
|
||||||
# return True
|
|
||||||
# return False
|
|
||||||
|
|
||||||
def get_registry_stats(self) -> Dict[str, Any]:
|
def get_registry_stats(self) -> Dict[str, Any]:
|
||||||
"""获取注册中心统计信息"""
|
"""获取注册中心统计信息"""
|
||||||
action_components: int = 0
|
action_components: int = 0
|
||||||
command_components: int = 0
|
command_components: int = 0
|
||||||
|
events_handlers: int = 0
|
||||||
for component in self._components.values():
|
for component in self._components.values():
|
||||||
if component.component_type == ComponentType.ACTION:
|
if component.component_type == ComponentType.ACTION:
|
||||||
action_components += 1
|
action_components += 1
|
||||||
elif component.component_type == ComponentType.COMMAND:
|
elif component.component_type == ComponentType.COMMAND:
|
||||||
command_components += 1
|
command_components += 1
|
||||||
|
elif component.component_type == ComponentType.EVENT_HANDLER:
|
||||||
|
events_handlers += 1
|
||||||
return {
|
return {
|
||||||
"action_components": action_components,
|
"action_components": action_components,
|
||||||
"command_components": command_components,
|
"command_components": command_components,
|
||||||
|
"event_handlers": events_handlers,
|
||||||
"total_components": len(self._components),
|
"total_components": len(self._components),
|
||||||
"total_plugins": len(self._plugins),
|
"total_plugins": len(self._plugins),
|
||||||
"components_by_type": {
|
"components_by_type": {
|
||||||
@@ -430,5 +414,4 @@ class ComponentRegistry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# 全局组件注册中心实例
|
|
||||||
component_registry = ComponentRegistry()
|
component_registry = ComponentRegistry()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from typing import List, Dict, Optional, Type
|
|||||||
|
|
||||||
from src.chat.message_receive.message import MessageRecv
|
from src.chat.message_receive.message import MessageRecv
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.plugin_system.base.component_types import EventType, EventHandlerInfo, MaiMessages, PluginInfo
|
from src.plugin_system.base.component_types import EventType, EventHandlerInfo, MaiMessages
|
||||||
from src.plugin_system.base.base_events_handler import BaseEventHandler
|
from src.plugin_system.base.base_events_handler import BaseEventHandler
|
||||||
|
|
||||||
logger = get_logger("events_manager")
|
logger = get_logger("events_manager")
|
||||||
@@ -14,7 +14,6 @@ class EventsManager:
|
|||||||
# 有权重的 events 订阅者注册表
|
# 有权重的 events 订阅者注册表
|
||||||
self.events_subscribers: Dict[EventType, List[BaseEventHandler]] = {event: [] for event in EventType}
|
self.events_subscribers: Dict[EventType, List[BaseEventHandler]] = {event: [] for event in EventType}
|
||||||
self.handler_mapping: Dict[str, Type[BaseEventHandler]] = {} # 事件处理器映射表
|
self.handler_mapping: Dict[str, Type[BaseEventHandler]] = {} # 事件处理器映射表
|
||||||
self._plugins: Dict[str, PluginInfo] = {} # 插件注册表
|
|
||||||
|
|
||||||
def register_event_subscriber(self, handler_info: EventHandlerInfo, handler_class: Type[BaseEventHandler]) -> bool:
|
def register_event_subscriber(self, handler_info: EventHandlerInfo, handler_class: Type[BaseEventHandler]) -> bool:
|
||||||
"""注册事件处理器
|
"""注册事件处理器
|
||||||
@@ -42,23 +41,6 @@ class EventsManager:
|
|||||||
|
|
||||||
return self._insert_event_handler(handler_class)
|
return self._insert_event_handler(handler_class)
|
||||||
|
|
||||||
def register_plugins(self, plugin_info: PluginInfo) -> bool:
|
|
||||||
"""注册插件
|
|
||||||
|
|
||||||
Args:
|
|
||||||
plugin_info (PluginInfo): 插件信息
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: 是否注册成功
|
|
||||||
"""
|
|
||||||
if plugin_info.name in self._plugins:
|
|
||||||
logger.warning(f"插件 {plugin_info.name} 已存在,跳过注册")
|
|
||||||
return False
|
|
||||||
|
|
||||||
self._plugins[plugin_info.name] = plugin_info
|
|
||||||
logger.debug(f"插件 {plugin_info.name} 注册成功")
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def handler_mai_events(
|
async def handler_mai_events(
|
||||||
self,
|
self,
|
||||||
event_type: EventType,
|
event_type: EventType,
|
||||||
|
|||||||
@@ -457,13 +457,14 @@ class PluginManager:
|
|||||||
stats = component_registry.get_registry_stats()
|
stats = component_registry.get_registry_stats()
|
||||||
action_count = stats.get("action_components", 0)
|
action_count = stats.get("action_components", 0)
|
||||||
command_count = stats.get("command_components", 0)
|
command_count = stats.get("command_components", 0)
|
||||||
|
event_handler_count = stats.get("event_handlers", 0)
|
||||||
total_components = stats.get("total_components", 0)
|
total_components = stats.get("total_components", 0)
|
||||||
|
|
||||||
# 📋 显示插件加载总览
|
# 📋 显示插件加载总览
|
||||||
if total_registered > 0:
|
if total_registered > 0:
|
||||||
logger.info("🎉 插件系统加载完成!")
|
logger.info("🎉 插件系统加载完成!")
|
||||||
logger.info(
|
logger.info(
|
||||||
f"📊 总览: {total_registered}个插件, {total_components}个组件 (Action: {action_count}, Command: {command_count})"
|
f"📊 总览: {total_registered}个插件, {total_components}个组件 (Action: {action_count}, Command: {command_count}, EventHandler: {event_handler_count})"
|
||||||
)
|
)
|
||||||
|
|
||||||
# 显示详细的插件列表
|
# 显示详细的插件列表
|
||||||
@@ -492,8 +493,9 @@ class PluginManager:
|
|||||||
|
|
||||||
# 组件列表
|
# 组件列表
|
||||||
if plugin_info.components:
|
if plugin_info.components:
|
||||||
action_components = [c for c in plugin_info.components if c.component_type.name == "ACTION"]
|
action_components = [c for c in plugin_info.components if c.component_type == ComponentType.ACTION]
|
||||||
command_components = [c for c in plugin_info.components if c.component_type.name == "COMMAND"]
|
command_components = [c for c in plugin_info.components if c.component_type == ComponentType.COMMAND]
|
||||||
|
event_handler_components = [c for c in plugin_info.components if c.component_type == ComponentType.EVENT_HANDLER]
|
||||||
|
|
||||||
if action_components:
|
if action_components:
|
||||||
action_names = [c.name for c in action_components]
|
action_names = [c.name for c in action_components]
|
||||||
@@ -502,6 +504,10 @@ class PluginManager:
|
|||||||
if command_components:
|
if command_components:
|
||||||
command_names = [c.name for c in command_components]
|
command_names = [c.name for c in command_components]
|
||||||
logger.info(f" ⚡ Command组件: {', '.join(command_names)}")
|
logger.info(f" ⚡ Command组件: {', '.join(command_names)}")
|
||||||
|
|
||||||
|
if event_handler_components:
|
||||||
|
event_handler_names = [c.name for c in event_handler_components]
|
||||||
|
logger.info(f" 📢 EventHandler组件: {', '.join(event_handler_names)}")
|
||||||
|
|
||||||
# 依赖信息
|
# 依赖信息
|
||||||
if plugin_info.dependencies:
|
if plugin_info.dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user