async def handle_command(bot: NoneBot, event: CQEvent, manager: CommandManager) -> Optional[bool]: """ Handle a message as a command. This function is typically called by "handle_message". :param bot: NoneBot instance :param event: message event :param manager: command manager :return: the message is handled as a command """ cmd, current_arg = manager.parse_command(bot, str(event.message).lstrip()) is_privileged_cmd = cmd and cmd.privileged if is_privileged_cmd and cmd.only_to_me and not event['to_me']: is_privileged_cmd = False disable_interaction = bool(is_privileged_cmd) if is_privileged_cmd: logger.debug(f'Command {cmd.name} is a privileged command') ctx_id = context_id(event) if not is_privileged_cmd: # wait for 1.5 seconds (at most) if the current session is running retry = 5 while retry > 0 and \ _sessions.get(ctx_id) and _sessions[ctx_id].running: retry -= 1 await asyncio.sleep(0.3) check_perm = True session: Optional[CommandSession] = _sessions.get( ctx_id) if not is_privileged_cmd else None if session is not None: if session.running: logger.warning(f'There is a session of command ' f'{session.cmd.name} running, notify the user') asyncio.ensure_future( send(bot, event, render_expression(bot.config.SESSION_RUNNING_EXPRESSION))) # pretend we are successful, so that NLP won't handle it return True if session.is_valid: logger.debug(f'Session of command {session.cmd.name} exists') # since it's in a session, the user must be talking to me event['to_me'] = True session.refresh(event, current_arg=str(event['message'])) # there is no need to check permission for existing session check_perm = False else: # the session is expired, remove it logger.debug(f'Session of command {session.cmd.name} is expired') if ctx_id in _sessions: del _sessions[ctx_id] session = None if session is None: if not cmd: logger.debug('Not a known command, ignored') return False if cmd.only_to_me and not event['to_me']: logger.debug('Not to me, ignored') return False SessionImpl = cmd.session_impl or CommandSession session = SessionImpl(bot, event, cmd, current_arg=current_arg) logger.debug(f'New session of command {session.cmd.name} created') assert isinstance(session, CommandSession) return await _real_run_command(session, ctx_id, check_perm=check_perm, disable_interaction=disable_interaction)
async def handle_command(bot: NoneBot, event: CQEvent, manager: CommandManager) -> Optional[bool]: """ Handle a message as a command. This function is typically called by "handle_message". :param bot: NoneBot instance :param event: message event :param manager: command manager :return: the message is handled as a command """ # 尝试从字符中解析出对应的命令。 cmd, current_arg = manager.parse_command(bot, str(event.message).lstrip()) is_privileged_cmd = cmd and cmd.privileged if is_privileged_cmd and cmd.only_to_me and not event['to_me']: is_privileged_cmd = False disable_interaction = bool(is_privileged_cmd) if is_privileged_cmd: logger.debug(f'Command {cmd.name} is a privileged command') # Context 指的是(对话发起人,对话环境)形成的哈希索引。 ctx_id = context_id(event) # 这里防止命令还未执行完毕就开启新命令。 # 如果不是特殊命令,等待1.5秒。 if not is_privileged_cmd: # wait for 1.5 seconds (at most) if the current session is running retry = 5 while retry > 0 and \ _sessions.get(ctx_id) and _sessions[ctx_id].running: retry -= 1 await asyncio.sleep(0.3) check_perm = True session = _sessions.get(ctx_id) if not is_privileged_cmd else None if session: # 这里防止命令还未执行完毕就开启新命令。 if session.running: logger.warning(f'There is a session of command ' f'{session.cmd.name} running, notify the user') asyncio.ensure_future( send(bot, event, render_expression(bot.config.SESSION_RUNNING_EXPRESSION))) # pretend we are successful, so that NLP won't handle it return True # 不 running 的 Sessoion 是被挂起的。 # is_valid 检查会话时间是否超过 config.SESSION_EXPIRE_TIMEOUT # 如果 Session 还有效,即便是没找到 Command 也直接传入 if session.is_valid: logger.debug(f'Session of command {session.cmd.name} exists') # 因为 Session 还没过期,即使命令中没有AT我也是对我说的。 event['to_me'] = True session.refresh(event, current_arg=str(event['message'])) # there is no need to check permission for existing session check_perm = False # 超过时间就删掉这个 Session else: # the session is expired, remove it logger.debug(f'Session of command {session.cmd.name} is expired') if ctx_id in _sessions: del _sessions[ctx_id] session = None if not session: if not cmd: logger.debug('Not a known command, ignored') return False if cmd.only_to_me and not event['to_me']: logger.debug('Not to me, ignored') return False session = CommandSession(bot, event, cmd, current_arg=current_arg) logger.debug(f'New session of command {session.cmd.name} created') # 检查完 command 有效或者 Session 还在的情况,运行指令。 return await _real_run_command(session, ctx_id, check_perm=check_perm, disable_interaction=disable_interaction)