From 1d40168c81937afab611f84cd2496b982b5dd1e4 Mon Sep 17 00:00:00 2001 From: DrSmoothl <1787882683@qq.com> Date: Sat, 14 Mar 2026 00:44:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=91=BD=E4=BB=A4=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C=E6=96=B0=E5=A2=9E=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E6=B6=88=E6=81=AF=E6=A0=87=E8=AE=B0=E5=92=8C=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/chat/message_receive/bot.py | 153 +++++++++++++++++++------------- 1 file changed, 90 insertions(+), 63 deletions(-) diff --git a/src/chat/message_receive/bot.py b/src/chat/message_receive/bot.py index b02e037d..494bcc56 100644 --- a/src/chat/message_receive/bot.py +++ b/src/chat/message_receive/bot.py @@ -1,8 +1,9 @@ +from contextlib import suppress import traceback import os from maim_message import MessageBase -from typing import Dict, Any +from typing import Any, Dict, Optional from src.common.logger import get_logger @@ -89,7 +90,7 @@ class ChatBot: plugin_config=plugin_config, matched_groups=matched_groups, ) - message.intercept_message_level = intercept_message_level + self._mark_command_message(message, intercept_message_level) # 记录命令执行结果 if success: @@ -113,11 +114,7 @@ class ChatBot: # 没有找到旧系统命令,尝试新版本插件运行时 new_cmd_result = await self._process_new_runtime_command(message) - if new_cmd_result is not None: - return new_cmd_result - - # 新旧系统都没找到命令,继续处理消息 - return False, None, True + return new_cmd_result if new_cmd_result is not None else (False, None, True) except Exception as e: logger.error(f"处理命令时出错: {e}") @@ -140,6 +137,13 @@ class ChatBot: if matched is None: return None + command_name = matched["name"] + if message.session_id and command_name in global_announcement_manager.get_disabled_chat_commands( + message.session_id + ): + logger.info(f"[新运行时] 用户禁用的命令,跳过处理: {matched['full_name']}") + return False, None, True + message.is_command = True logger.info(f"[新运行时] 匹配命令: {matched['full_name']}") @@ -170,6 +174,8 @@ class ChatBot: response_text = cmd_result if cmd_result is not None else "" intercept = bool(matched["metadata"].get("intercept_message_level", 0)) + self._mark_command_message(message, int(intercept)) + if success: logger.info(f"[新运行时] 命令执行成功: {matched['full_name']}") else: @@ -181,62 +187,84 @@ class ChatBot: logger.error(f"[新运行时] 执行命令 {matched['full_name']} 异常: {e}", exc_info=True) return True, str(e), True + @staticmethod + def _mark_command_message(message: SessionMessage, intercept_message_level: int) -> None: + message.is_command = True + message.intercept_message_level = intercept_message_level + message.message_info.additional_config["intercept_message_level"] = intercept_message_level + + @staticmethod + def _store_intercepted_command_message(message: SessionMessage) -> None: + MessageUtils.store_message_to_db(message) + + async def _handle_command_processing_result( + self, + message: SessionMessage, + cmd_result: Optional[str], + continue_process: bool, + ) -> bool: + if continue_process: + return False + + self._store_intercepted_command_message(message) + logger.info(f"命令处理完成,跳过后续消息处理: {cmd_result}") + return True + async def handle_notice_message(self, message: SessionMessage): - if message.message_id == "notice": - message.is_notify = True - logger.debug("notice消息") - try: - seg = getattr(message, "message_segment", None) # SessionMessage 没有 message_segment - mi = message.message_info - sub_type = None - scene = None - msg_id = None - recalled_id = None + if message.message_id != "notice": + return - if getattr(seg, "type", None) == "notify" and isinstance(getattr(seg, "data", None), dict): - sub_type = seg.data.get("sub_type") - scene = seg.data.get("scene") - msg_id = seg.data.get("message_id") - recalled = seg.data.get("recalled_user_info") or {} + message.is_notify = True + logger.debug("notice消息") + try: + seg = getattr(message, "message_segment", None) # SessionMessage 没有 message_segment + mi = message.message_info + sub_type = None + scene = None + msg_id = None + recalled: Dict[str, Any] = {} + recalled_id = None + + if getattr(seg, "type", None) == "notify" and isinstance(getattr(seg, "data", None), dict): + sub_type = seg.data.get("sub_type") + scene = seg.data.get("scene") + msg_id = seg.data.get("message_id") + recalled = seg.data.get("recalled_user_info") or {} + if isinstance(recalled, dict): + recalled_id = recalled.get("user_id") + + op = mi.user_info + gid = mi.group_info.group_id if mi.group_info else None + + # 撤回事件打印;无法获取被撤回者则省略 + if sub_type == "recall": + op_name = ( + getattr(op, "user_cardname", None) + or getattr(op, "user_nickname", None) + or str(getattr(op, "user_id", None)) + ) + recalled_name = None + with suppress(Exception): if isinstance(recalled, dict): - recalled_id = recalled.get("user_id") + recalled_name = ( + recalled.get("user_cardname") + or recalled.get("user_nickname") + or str(recalled.get("user_id")) + ) - op = mi.user_info - gid = mi.group_info.group_id if mi.group_info else None - - # 撤回事件打印;无法获取被撤回者则省略 - if sub_type == "recall": - op_name = ( - getattr(op, "user_cardname", None) - or getattr(op, "user_nickname", None) - or str(getattr(op, "user_id", None)) - ) - recalled_name = None - try: - if isinstance(recalled, dict): - recalled_name = ( - recalled.get("user_cardname") - or recalled.get("user_nickname") - or str(recalled.get("user_id")) - ) - except Exception: - pass - - if recalled_name and str(recalled_id) != str(getattr(op, "user_id", None)): - logger.info(f"{op_name} 撤回了 {recalled_name} 的消息") - else: - logger.info(f"{op_name} 撤回了消息") + if recalled_name and str(recalled_id) != str(getattr(op, "user_id", None)): + logger.info(f"{op_name} 撤回了 {recalled_name} 的消息") else: - logger.debug( - f"[notice] sub_type={sub_type} scene={scene} op={getattr(op, 'user_nickname', None)}({getattr(op, 'user_id', None)}) " - f"gid={gid} msg_id={msg_id} recalled={recalled_id}" - ) - except Exception: - logger.info("[notice] (简略) 收到一条通知事件") + logger.info(f"{op_name} 撤回了消息") + else: + logger.debug( + f"[notice] sub_type={sub_type} scene={scene} op={getattr(op, 'user_nickname', None)}({getattr(op, 'user_id', None)}) " + f"gid={gid} msg_id={msg_id} recalled={recalled_id}" + ) + except Exception: + logger.info("[notice] (简略) 收到一条通知事件") - return True - - return + return True async def echo_message_process(self, raw_data: Dict[str, Any]) -> None: """ @@ -336,15 +364,14 @@ class ChatBot: # message.update_chat_stream(chat) - # TODO: 在新命令系统完成后恢复这里 # 命令处理 - 使用新插件系统检查并处理命令 - # is_command, cmd_result, continue_process = await self._process_commands(message) + # 注意:命令返回的 response 当前只用于日志记录和流程判断, + # 不会在这里自动作为回复消息发送回会话。 + is_command, cmd_result, continue_process = await self._process_commands(message) # 如果是命令且不需要继续处理,则直接返回 - # if is_command and not continue_process: - # await MessageStorage.store_message(message, chat) - # logger.info(f"命令处理完成,跳过后续消息处理: {cmd_result}") - # return + if is_command and await self._handle_command_processing_result(message, cmd_result, continue_process): + return # continue_flag, modified_message = await events_manager.handle_mai_events(EventType.ON_MESSAGE, message) # if not continue_flag: