feat(bot): 实现 BotManager 并完善机器人注销逻辑

添加全局 BotManager 单例用于统一管理所有 Bot 实例
在 WS 关闭和 ReverseWSManager 清理时调用注销逻辑
修改广播插件使用 BotManager 获取所有活跃 Bot 实例
移除 echo 插件的权限限制并更新文档配置
This commit is contained in:
2026-03-08 12:25:13 +08:00
parent 789d4e8ac7
commit dec1a43f28
8 changed files with 120 additions and 33 deletions

View File

@@ -114,10 +114,21 @@ async def broadcast_subscription_loop():
logger.info(f"[Broadcast] 收到跨机器人广播消息: 来源 {robot_id}")
# 获取当前机器人的实例
from core.ws import WS
if WS.instance:
await broadcast_message_to_groups(WS.instance, message_data, robot_id)
# 获取所有活跃的 Bot 实例
from core.managers.bot_manager import bot_manager
all_bots = bot_manager.get_all_bots()
if not all_bots:
logger.warning("[Broadcast] 没有活跃的 Bot 实例,无法转发广播消息")
continue
# 遍历所有 Bot 进行广播
for bot in all_bots:
# 避免重复广播:如果消息来源就是当前 Bot则跳过
if str(bot.self_id) == str(robot_id):
continue
await broadcast_message_to_groups(bot, message_data, robot_id)
except json.JSONDecodeError as e:
logger.error(f"[Broadcast] 解析广播消息失败: {e}")
@@ -178,16 +189,26 @@ async def handle_broadcast_content(event: MessageEvent):
await event.reply("捕获到的消息为空,已取消广播。")
return True
# 获取当前机器人ID使用反向WS的机器人ID
from core.ws import WS
# 获取当前机器人ID
robot_id = "unknown"
if WS.instance and hasattr(WS.instance, 'self_id'):
robot_id = str(WS.instance.self_id)
if event.bot and hasattr(event.bot, 'self_id'):
robot_id = str(event.bot.self_id)
# --- 执行本地广播 ---
# 1. 先让接收到指令的这个 Bot 进行广播
await broadcast_message_to_groups(event.bot, message_to_broadcast, robot_id)
# --- 通过 Redis 发布消息给其他机器人 ---
# 2. 获取其他所有 Bot 并进行广播(针对同一进程内的其他 Bot
from core.managers.bot_manager import bot_manager
all_bots = bot_manager.get_all_bots()
for bot in all_bots:
# 跳过已经广播过的 Bot (即当前接收指令的 Bot)
if str(bot.self_id) == robot_id:
continue
await broadcast_message_to_groups(bot, message_to_broadcast, robot_id)
# --- 通过 Redis 发布消息给其他进程的机器人 ---
try:
if redis_manager.redis:
broadcast_data = {

View File

@@ -6,7 +6,6 @@ Echo 与交互插件
from core.managers.command_manager import matcher
from core.bot import Bot
from models.events.message import MessageEvent
from core.permission import Permission
__plugin_meta__ = {
"name": "echo",
@@ -14,7 +13,7 @@ __plugin_meta__ = {
"usage": "/echo [内容] - 复读内容\n/赞我 - 让机器人给你点赞",
}
@matcher.command("echo", permission=Permission.ADMIN)
@matcher.command("echo")
async def handle_echo(bot: Bot, event: MessageEvent, args: list[str]):
"""
处理 echo 指令,原样回复用户输入的内容