Files
NeoBot/core/command_manager.py

169 lines
4.7 KiB
Python

"""
命令管理器模块
提供装饰器用于注册消息指令、通知处理器和请求处理器,并负责事件的分发。
"""
import inspect
from typing import Any, Callable, Dict, List, Tuple
from .config_loader import global_config
# 从配置中获取命令前缀
comm_prefixes = global_config.bot.get("command", ("/",))
class CommandManager:
"""
命令管理器,负责注册和分发指令、通知和请求事件
"""
def __init__(self, prefixes: Tuple[str, ...] = ("/",)):
"""
初始化命令管理器
:param prefixes: 命令前缀元组
"""
self.prefixes = prefixes
self.commands: Dict[str, Callable] = {} # 存储消息指令
self.notice_handlers: List[Dict] = [] # 存储通知处理器
self.request_handlers: List[Dict] = [] # 存储请求处理器
# --- 1. 消息指令装饰器 ---
def command(self, name: str):
"""
装饰器:注册消息指令
:param name: 指令名称(不含前缀)
:return: 装饰器函数
"""
def decorator(func):
self.commands[name] = func
return func
return decorator
# --- 2. 通知事件装饰器 ---
def on_notice(self, notice_type: str = None):
"""
装饰器:注册通知处理器
:param notice_type: 通知类型,如果为 None 则处理所有通知
:return: 装饰器函数
"""
def decorator(func):
self.notice_handlers.append({"type": notice_type, "func": func})
return func
return decorator
# --- 3. 请求事件装饰器 ---
def on_request(self, request_type: str = None):
"""
装饰器:注册请求处理器
:param request_type: 请求类型,如果为 None 则处理所有请求
:return: 装饰器函数
"""
def decorator(func):
self.request_handlers.append({"type": request_type, "func": func})
return func
return decorator
# --- 消息分发逻辑 ---
async def handle_message(self, bot, event):
"""
解析并分发消息指令
:param bot: Bot 实例
:param event: 消息事件对象
"""
if not event.raw_message:
return
raw_text = event.raw_message.strip()
# 1. 检查前缀
prefix_found = None
for p in self.prefixes:
if raw_text.startswith(p):
prefix_found = p
break
if not prefix_found:
return
# 2. 拆分指令和参数
full_cmd = raw_text[len(prefix_found) :].split()
if not full_cmd:
return
cmd_name = full_cmd[0]
args = full_cmd[1:]
# 3. 查找并执行
if cmd_name in self.commands:
func = self.commands[cmd_name]
await self._run_handler(func, bot, event, args)
# --- 通知分发逻辑 ---
async def handle_notice(self, bot, event):
"""
分发通知事件
:param bot: Bot 实例
:param event: 通知事件对象
"""
for handler in self.notice_handlers:
if handler["type"] is None or handler["type"] == event.notice_type:
await self._run_handler(handler["func"], bot, event)
# --- 请求分发逻辑 ---
async def handle_request(self, bot, event):
"""
分发请求事件
:param bot: Bot 实例
:param event: 请求事件对象
"""
for handler in self.request_handlers:
if handler["type"] is None or handler["type"] == event.request_type:
await self._run_handler(handler["func"], bot, event)
# --- 通用执行器:自动注入参数 ---
async def _run_handler(self, func, bot, event, args=None):
"""
根据函数签名自动注入 bot, event 或 args
:param func: 目标处理函数
:param bot: Bot 实例
:param event: 事件对象
:param args: 指令参数(仅消息指令有效)
"""
sig = inspect.signature(func)
params = sig.parameters
kwargs = {}
if "bot" in params:
kwargs["bot"] = bot
if "event" in params:
kwargs["event"] = event
if "args" in params and args is not None:
kwargs["args"] = args
# 执行函数
await func(**kwargs)
# 确保前缀是元组格式
if isinstance(comm_prefixes, list):
comm_prefixes = tuple[Any, ...](comm_prefixes)
elif isinstance(comm_prefixes, str):
comm_prefixes = (comm_prefixes,)
# 实例化全局管理器
matcher = CommandManager(prefixes=comm_prefixes)