From fe65ba6df61445a8795cc1ac97cbecff678043c9 Mon Sep 17 00:00:00 2001 From: minecraft1024a Date: Thu, 13 Nov 2025 16:01:40 +0800 Subject: [PATCH 1/2] =?UTF-8?q?refactor(mood=5Fapi):=20=E4=B8=BA=E6=83=85?= =?UTF-8?q?=E7=BB=AAAPI=E5=87=BD=E6=95=B0=E5=A2=9E=E5=8A=A0=E5=B8=83?= =?UTF-8?q?=E5=B0=94=E8=BF=94=E5=9B=9E=E5=80=BC=E5=92=8C=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 此重构修改了 `set_mood`, `lock_mood`, 和 `unlock_mood` 函数,使其返回布尔值以明确指示操作是否成功。 - 为 `set_mood` 和 `lock_mood` 添加了 `try...except` 块,以捕获异常并在失败时返回 `False`。 - `unlock_mood` 现在会在情绪本未锁定的情况下返回 `False`,提供了更清晰的状态反馈。 这些更改提高了API的健壮性,使插件等调用方能够更可靠地处理操作结果。 BREAKING CHANGE: `set_mood`, `lock_mood`, 和 `unlock_mood` 函数现在返回一个布尔值来表示操作是否成功,而不再是隐式地返回 `None`。 --- src/plugin_system/apis/mood_api.py | 58 +++++++++++++++++++----------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/src/plugin_system/apis/mood_api.py b/src/plugin_system/apis/mood_api.py index 612fb8b4e..d7afd3ed0 100644 --- a/src/plugin_system/apis/mood_api.py +++ b/src/plugin_system/apis/mood_api.py @@ -47,16 +47,23 @@ def get_mood(chat_id: str) -> str: return chat_mood.mood_state -def set_mood(chat_id: str, new_mood: str): +def set_mood(chat_id: str, new_mood: str) -> bool: """强制设定指定聊天的新情绪状态 Args: chat_id (str): 聊天ID new_mood (str): 新的情绪状态 + Returns: + bool: 操作是否成功 """ - chat_mood = mood_manager.get_mood_by_chat_id(chat_id) - chat_mood.mood_state = new_mood - logger.info(f"[{chat_id}] 情绪状态被强制设置为: {new_mood}") + try: + chat_mood = mood_manager.get_mood_by_chat_id(chat_id) + chat_mood.mood_state = new_mood + logger.info(f"[{chat_id}] 情绪状态被强制设置为: {new_mood}") + return True + except Exception as e: + logger.error(f"强制设定指定聊天的新情绪状态时发生错误:{e}") + return False async def lock_mood(chat_id: str, duration: float | None = None): @@ -66,30 +73,39 @@ async def lock_mood(chat_id: str, duration: float | None = None): Args: chat_id (str): 聊天ID duration (Optional[float]): 锁定时长(秒)。如果为 None,则永久锁定直到手动解锁。 + Returns: + bool: 操作是否成功 """ - if chat_id in _unlock_tasks: - _unlock_tasks[chat_id].cancel() - del _unlock_tasks[chat_id] + try: + if chat_id in _unlock_tasks: + _unlock_tasks[chat_id].cancel() + del _unlock_tasks[chat_id] - mood_manager.insomnia_chats.add(chat_id) - logger.info(f"[{chat_id}] 情绪已锁定。") + mood_manager.insomnia_chats.add(chat_id) + logger.info(f"[{chat_id}] 情绪已锁定。") - if duration: - logger.info(f"[{chat_id}] 情绪将于 {duration} 秒后自动解锁。") + if duration: + logger.info(f"[{chat_id}] 情绪将于 {duration} 秒后自动解锁。") - async def _unlock_after(): - await asyncio.sleep(duration) - if chat_id in mood_manager.insomnia_chats: - await unlock_mood(chat_id) - logger.info(f"[{chat_id}] 情绪已自动解锁。") - - task = asyncio.create_task(_unlock_after()) - _unlock_tasks[chat_id] = task + async def _unlock_after(): + await asyncio.sleep(duration) + if chat_id in mood_manager.insomnia_chats: + await unlock_mood(chat_id) + logger.info(f"[{chat_id}] 情绪已自动解锁。") + task = asyncio.create_task(_unlock_after()) + _unlock_tasks[chat_id] = task + return True + except Exception as e: + logger.error(f"锁定指定聊天的情绪时发生错误:{e}") + return False -async def unlock_mood(chat_id: str): +async def unlock_mood(chat_id: str) -> bool: """ 立即解除情绪锁定。 + + Returns: + bool: 如果成功解锁则返回 True,如果情绪未被锁定则返回 False。 """ if chat_id in _unlock_tasks: _unlock_tasks[chat_id].cancel() @@ -98,6 +114,8 @@ async def unlock_mood(chat_id: str): if chat_id in mood_manager.insomnia_chats: mood_manager.insomnia_chats.remove(chat_id) logger.info(f"[{chat_id}] 情绪已手动解锁。") + return True + return False def is_mood_locked(chat_id: str) -> bool: From 8e04bf36b4683b116c55a3c5362e6ee09f387044 Mon Sep 17 00:00:00 2001 From: Windpicker-owo <3431391539@qq.com> Date: Thu, 13 Nov 2025 16:22:28 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(config):=20=E6=B7=BB=E5=8A=A0=E8=A1=A8?= =?UTF-8?q?=E6=83=85=E5=8C=85=E5=9B=9E=E5=A4=8D=E9=85=8D=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E5=85=81=E8=AE=B8=E6=88=96=E7=A6=81=E6=AD=A2=E5=9B=9E=E5=A4=8D?= =?UTF-8?q?=E8=A1=A8=E6=83=85=E5=8C=85=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/chat/planner_actions/action_manager.py | 7 +++++++ src/config/official_configs.py | 2 ++ template/bot_config_template.toml | 4 +++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/chat/planner_actions/action_manager.py b/src/chat/planner_actions/action_manager.py index cb235c03e..0c83314c5 100644 --- a/src/chat/planner_actions/action_manager.py +++ b/src/chat/planner_actions/action_manager.py @@ -241,6 +241,13 @@ class ChatterActionManager: "command": command, } else: + # 检查目标消息是否为表情包消息以及配置是否允许回复表情包 + if target_message and getattr(target_message, 'is_emoji', False): + # 如果是表情包消息且配置不允许回复表情包,则跳过回复 + if not getattr(global_config.chat, 'allow_reply_to_emoji', True): + logger.info(f"{log_prefix} 目标消息为表情包且配置不允许回复表情包,跳过回复") + return {"action_type": action_name, "success": True, "reply_text": "", "skip_reason": "emoji_not_allowed"} + # 生成回复 (reply 或 respond) # reply: 针对单条消息的回复,使用 s4u 模板 # respond: 对未读消息的统一回应,使用 normal 模板 diff --git a/src/config/official_configs.py b/src/config/official_configs.py index 0f8d7da68..891ad1706 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -152,6 +152,8 @@ class ChatConfig(ValidatedConfigBase): multiple_replies_strategy: Literal["keep_first", "keep_best", "keep_last"] = Field( default="keep_first", description="多重回复处理策略:keep_first(保留第一个),keep_best(保留最佳),keep_last(保留最后一个)" ) + # 表情包回复配置 + allow_reply_to_emoji: bool = Field(default=True, description="是否允许回复表情包消息") class MessageReceiveConfig(ValidatedConfigBase): diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index f913ecdd6..4257e82e0 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -1,5 +1,5 @@ [inner] -version = "7.6.9" +version = "7.7.0" #----以下是给开发人员阅读的,如果你只是部署了MoFox-Bot,不需要阅读---- #如果你想要修改配置文件,请递增version的值 @@ -165,6 +165,8 @@ decision_history_length = 3 # 决策历史记录的长度,用于增强语言 enable_multiple_replies = false # 是否允许多重回复(True=允许多个回复动作,False=只保留一个回复动作) multiple_replies_strategy = "keep_first" # 多重回复处理策略:keep_first(保留第一个),keep_best(保留最佳),keep_last(保留最后一个) +# 表情包回复配置 +allow_reply_to_emoji = false # 是否允许回复表情包消息 [message_receive] # 以下是消息过滤,可以根据规则过滤特定消息,将不会读取这些消息