动态控制命令后续处理

This commit is contained in:
UnCLAS-Prommer
2025-07-25 11:01:14 +08:00
parent f6f441474c
commit bbb112d803
6 changed files with 27 additions and 35 deletions

View File

@@ -21,6 +21,8 @@
- `database_api.py`中的`db_query`方法调整了参数顺序以增强参数限制的同时保证了typing正确`db_get`方法增加了`single_result`参数,与`db_query`保持一致。
5. 增加了`logging_api`,可以用`get_logger`来获取日志记录器。
6. 增加了插件和组件管理的API。
7. `BaseCommand`的`execute`方法现在返回一个三元组,包含是否执行成功、可选的回复消息和是否拦截消息。
- 这意味着你终于可以动态控制是否继续后续消息的处理了。
# 插件系统修改
1. 现在所有的匹配模式不再是关键字了,而是枚举类。**(可能有遗漏)**

View File

@@ -77,9 +77,8 @@ class TimeCommand(BaseCommand):
command_pattern = r"^/time$" # 精确匹配 "/time" 命令
command_help = "查询当前时间"
command_examples = ["/time"]
intercept_message = True # 拦截消息,不让其他组件处理
async def execute(self) -> Tuple[bool, str]:
async def execute(self) -> Tuple[bool, str, bool]:
"""执行时间查询"""
import datetime
@@ -92,7 +91,7 @@ class TimeCommand(BaseCommand):
message = f"⏰ 当前时间:{time_str}"
await self.send_text(message)
return True, f"显示了当前时间: {time_str}"
return True, f"显示了当前时间: {time_str}", True
class PrintMessage(BaseEventHandler):

View File

@@ -92,7 +92,6 @@ class ChatBot:
command_result = component_registry.find_command_by_text(text)
if command_result:
command_class, matched_groups, command_info = command_result
intercept_message = command_info.intercept_message
plugin_name = command_info.plugin_name
command_name = command_info.name
if (
@@ -115,7 +114,7 @@ class ChatBot:
try:
# 执行命令
success, response = await command_instance.execute()
success, response, intercept_message = await command_instance.execute()
# 记录命令执行结果
if success:
@@ -128,8 +127,6 @@ class ChatBot:
except Exception as e:
logger.error(f"执行命令时出错: {command_class.__name__} - {e}")
import traceback
logger.error(traceback.format_exc())
try:
@@ -138,7 +135,7 @@ class ChatBot:
logger.error(f"发送错误消息失败: {send_error}")
# 命令出错时,根据命令的拦截设置决定是否继续处理消息
return True, str(e), not intercept_message
return True, str(e), False # 出错时继续处理消息
# 没有找到命令,继续处理消息
return False, None, True

View File

@@ -17,7 +17,6 @@ class BaseCommand(ABC):
- command_pattern: 命令匹配的正则表达式
- command_help: 命令帮助信息
- command_examples: 命令使用示例列表
- intercept_message: 是否拦截消息处理默认True拦截False继续传递
"""
command_name: str = ""
@@ -30,8 +29,6 @@ class BaseCommand(ABC):
command_help: str = ""
"""命令帮助信息"""
command_examples: List[str] = []
intercept_message: bool = True
"""是否拦截信息,默认拦截,不进行后续处理"""
def __init__(self, message: MessageRecv, plugin_config: Optional[dict] = None):
"""初始化Command组件
@@ -57,11 +54,11 @@ class BaseCommand(ABC):
self.matched_groups = groups
@abstractmethod
async def execute(self) -> Tuple[bool, Optional[str]]:
async def execute(self) -> Tuple[bool, Optional[str], bool]:
"""执行Command的抽象方法子类必须实现
Returns:
Tuple[bool, Optional[str]]: (是否执行成功, 可选的回复消息)
Tuple[bool, Optional[str], bool]: (是否执行成功, 可选的回复消息, 是否拦截消息 不进行 后续处理)
"""
pass
@@ -233,5 +230,4 @@ class BaseCommand(ABC):
command_pattern=cls.command_pattern,
command_help=cls.command_help,
command_examples=cls.command_examples.copy() if cls.command_examples else [],
intercept_message=cls.intercept_message,
)

View File

@@ -142,7 +142,6 @@ class CommandInfo(ComponentInfo):
command_pattern: str = "" # 命令匹配模式(正则表达式)
command_help: str = "" # 命令帮助信息
command_examples: List[str] = field(default_factory=list) # 命令使用示例
intercept_message: bool = True # 是否拦截消息处理(默认拦截)
def __post_init__(self):
super().__post_init__()

View File

@@ -18,9 +18,8 @@ class ManagementCommand(BaseCommand):
command_name: str = "management"
description: str = "管理命令"
command_pattern: str = r"(?P<manage_command>^/pm(\s[a-zA-Z0-9_]+)*\s*$)"
intercept_message: bool = True
async def execute(self) -> Tuple[bool, str]:
async def execute(self) -> Tuple[bool, str, bool]:
# sourcery skip: merge-duplicate-blocks
if (
not self.message
@@ -29,11 +28,11 @@ class ManagementCommand(BaseCommand):
or str(self.message.message_info.user_info.user_id) not in self.get_config("plugin.permission", []) # type: ignore
):
await self.send_text("你没有权限使用插件管理命令")
return False, "没有权限"
return False, "没有权限", True
command_list = self.matched_groups["manage_command"].strip().split(" ")
if len(command_list) == 1:
await self.show_help("all")
return True, "帮助已发送"
return True, "帮助已发送", True
if len(command_list) == 2:
match command_list[1]:
case "plugin":
@@ -44,7 +43,7 @@ class ManagementCommand(BaseCommand):
await self.show_help("all")
case _:
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
if len(command_list) == 3:
if command_list[1] == "plugin":
match command_list[2]:
@@ -58,7 +57,7 @@ class ManagementCommand(BaseCommand):
await self._rescan_plugin_dirs()
case _:
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
elif command_list[1] == "component":
if command_list[2] == "list":
await self._list_all_registered_components()
@@ -66,10 +65,10 @@ class ManagementCommand(BaseCommand):
await self.show_help("component")
else:
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
else:
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
if len(command_list) == 4:
if command_list[1] == "plugin":
match command_list[2]:
@@ -83,28 +82,28 @@ class ManagementCommand(BaseCommand):
await self._add_dir(command_list[3])
case _:
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
elif command_list[1] == "component":
if command_list[2] != "list":
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
if command_list[3] == "enabled":
await self._list_enabled_components()
elif command_list[3] == "disabled":
await self._list_disabled_components()
else:
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
else:
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
if len(command_list) == 5:
if command_list[1] != "component":
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
if command_list[2] != "list":
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
if command_list[3] == "enabled":
await self._list_enabled_components(target_type=command_list[4])
elif command_list[3] == "disabled":
@@ -113,11 +112,11 @@ class ManagementCommand(BaseCommand):
await self._list_registered_components_by_type(command_list[4])
else:
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
if len(command_list) == 6:
if command_list[1] != "component":
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
if command_list[2] == "enable":
if command_list[3] == "global":
await self._globally_enable_component(command_list[4], command_list[5])
@@ -125,7 +124,7 @@ class ManagementCommand(BaseCommand):
await self._locally_enable_component(command_list[4], command_list[5])
else:
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
elif command_list[2] == "disable":
if command_list[3] == "global":
await self._globally_disable_component(command_list[4], command_list[5])
@@ -133,12 +132,12 @@ class ManagementCommand(BaseCommand):
await self._locally_disable_component(command_list[4], command_list[5])
else:
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
else:
await self.send_text("插件管理命令不合法")
return False, "命令不合法"
return False, "命令不合法", True
return True, "命令执行完成"
return True, "命令执行完成", True
async def show_help(self, target: str):
help_msg = ""