"""指令解析器""" import re import logging from typing import Optional, Tuple logger = logging.getLogger(__name__) class CommandParser: """指令解析器""" # 指令映射表 COMMAND_MAP = { # 用户注册系统(必须在骰娘之前) '.register': 'register', '.注册': 'register', # 骰娘 '.r': 'dice', '.roll': 'dice', # 石头剪刀布 '.rps': 'rps', # 运势占卜 '.fortune': 'fortune', '.运势': 'fortune', # 猜数字 '.guess': 'guess', '.猜数字': 'guess', # 问答 '.quiz': 'quiz', '.问答': 'quiz', # 成语接龙 '.idiom': 'idiom', '.成语接龙': 'idiom', '.成语': 'idiom', # 五子棋 '.gomoku': 'gomoku', '.五子棋': 'gomoku', '.gobang': 'gomoku', # 积分系统 '.points': 'points', '.积分': 'points', '.checkin': 'points', '.签到': 'points', '.打卡': 'points', # 炼金系统 '.alchemy': 'alchemy', '.炼金': 'alchemy', # 冒险系统 '.adventure': 'adventure', '.冒险': 'adventure', # 积分赠送系统 '.gift': 'gift', '.赠送': 'gift', '.送': 'gift', # AI对话系统 '.ai': 'ai_chat', '.aiconfig': 'ai_chat', # 帮助 '.help': 'help', '.帮助': 'help', # 统计 '.stats': 'stats', '.统计': 'stats', } # 机器人名称模式(用于从@消息中提取) AT_PATTERN = re.compile(r'@[^\s]+\s+(.+)', re.DOTALL) @classmethod def parse(cls, content: str) -> Optional[Tuple[str, str]]: """解析消息内容,提取游戏类型和指令 Args: content: 消息内容 Returns: (游戏类型, 完整指令) 或 None """ # 去除首尾空格 content = content.strip() # 尝试提取@后的内容 at_match = cls.AT_PATTERN.search(content) if at_match: content = at_match.group(1).strip() # 检查是否以指令开头 for cmd_prefix, game_type in cls.COMMAND_MAP.items(): if content == cmd_prefix: # 返回游戏类型和完整指令 return game_type, content # 特殊处理:.ai 和 .aiconfig 指令支持参数 if content.startswith('.ai '): return 'ai_chat', content if content.startswith('.aiconfig '): return 'ai_chat', content # 没有匹配的指令 logger.debug(f"未识别的指令: {content}") return None @classmethod def extract_command_args(cls, command: str) -> Tuple[str, str]: """提取指令和参数 Args: command: 完整指令,如 ".r 1d20" 或 ".guess 50" Returns: (指令前缀, 参数部分) """ parts = command.split(maxsplit=1) cmd = parts[0] if parts else "" args = parts[1] if len(parts) > 1 else "" return cmd, args @classmethod def is_help_command(cls, command: str) -> bool: """判断是否为帮助指令""" return command.strip() in ['.help', '.帮助', 'help', '帮助']