一些前置方法
Matcher的其它方法
Matcher.get_receive
class Matcher(metaclass=MatcherMeta): @overload def get_receive(self, id: str) -> Union[Event, None]: ... @overload def get_receive(self, id: str, default: T) -> Union[Event, T]: ... def get_receive( self, id: str, default: Optional[T] = None ) -> Optional[Union[Event, T]]: return self.state.get(RECEIVE_KEY.format(id=id), default) # 根据id从state中获取之前放入的Event,如果没有则返回default
Matcher.set_receive
class Matcher(metaclass=MatcherMeta): def set_receive(self, id: str, event: Event) -> None: self.state[RECEIVE_KEY.format(id=id)] = event self.state[LAST_RECEIVE_KEY] = event # 将Event放入state中,同时将last event设为这个event
Matcher.get_last_receive
class Matcher(metaclass=MatcherMeta): @overload def get_last_receive(self) -> Union[Event, None]: ... @overload def get_last_receive(self, default: T) -> Union[Event, T]: ... def get_last_receive( self, default: Optional[T] = None ) -> Optional[Union[Event, T]]: return self.state.get(LAST_RECEIVE_KEY, default) # 取出last event,也就是最后一次set_receive放入的Event
Matcher.get_arg
class Matcher(metaclass=MatcherMeta): @overload def get_arg(self, key: str) -> Union[Message, None]: ... @overload def get_arg(self, key: str, default: T) -> Union[Message, T]: ... def get_arg( self, key: str, default: Optional[T] = None ) -> Optional[Union[Message, T]]: return self.state.get(ARG_KEY.format(key=key), default) # 根据key从state中获取之前放入的Message,如果没有则返回default
Matcher.set_arg
class Matcher(metaclass=MatcherMeta): def set_arg(self, key: str, message: Message) -> None: self.state[ARG_KEY.format(key=key)] = message # 将Message放入state中
Matcher.set_target
class Matcher(metaclass=MatcherMeta): def set_target(self, target: str, cache: bool = True) -> None: if cache: self.state[REJECT_CACHE_TARGET] = target else: self.state[REJECT_TARGET] = target # 将target放入state中
Matcher.get_target
class Matcher(metaclass=MatcherMeta): @overload def get_target(self) -> Union[str, None]: ... @overload def get_target(self, default: T) -> Union[str, T]: ... def get_target(self, default: Optional[T] = None) -> Optional[Union[str, T]]: return self.state.get(REJECT_TARGET, default) # 从state中取出放入的target,若没有则返回default
Matcher.stop_propagation
class Matcher(metaclass=MatcherMeta): def stop_propagation(self): self.block = True # 将Matcher的block设为true
Matcher.resolve_reject
class Matcher(metaclass=MatcherMeta): async def resolve_reject(self): handler = current_handler.get() # 获取当前current_handler,是抛出RejectedException的handler self.handlers.insert(0, handler) # 将抛出RejectedException的handler放到handlers第一位 if REJECT_CACHE_TARGET in self.state: ``` 如果state中有REJECT_CACHE_TARGET,将其作为reject的target(见Matcher.set_target) ``` self.state[REJECT_TARGET] = self.state[REJECT_CACHE_TARGET]
补充Matcher.receive与Matcher.got
之前介绍Matcher.receive与Matcher.got是说它们的特点是parameterless第一位是Depends,那时候我们还不知道parameterless的用法,所以没深入介绍,现在介绍他们的作用
根据前面的内容,我们知道parameterless的元素会被转换为Param子类,然后调用Param._solve,_solve的返回值会被忽略。由于只有DependParam可以通过自定义函数进行一些操作,所以一般来说parameterless的元素只能是Depends,例如receive和got
这样来看,parameterless更像是hook,可以在运行handler之前执行一些操作
Matcher.receive
class Matcher(metaclass=MatcherMeta): @classmethod def receive( cls, id: str = "", parameterless: Optional[Iterable[Any]] = None ) -> Callable[[T_Handler], T_Handler]: async def _receive(event: Event, matcher: "Matcher") -> Union[None, NoReturn]: matcher.set_target(RECEIVE_KEY.format(id=id)) ``` 将传入的id设为receive target 由于set_target的cache未传,默认值为True,因此REJECT_CACHE_TARGET为传入的id ``` if matcher.get_target() == RECEIVE_KEY.format(id=id): ``` 如果有REJECT_TARGET,将RECEIVE_KEY和LAST_RECEIVE_KEY设为当前event并返回 ``` matcher.set_receive(id, event) return if matcher.get_receive(id, ...) is not ...: ``` get_receive默认值为...,返回值不是...,说明RECEIVE_KEY存在 即不存在REJECT_TARGET,存在RECEIVE_KEY存在则直接返回 ``` return await matcher.reject() # 抛出RejectedException _parameterless = (Depends(_receive), *(parameterless or tuple())) ``` parameterless会在handler之前触发,运行_receive函数 ``` ...
这样来看,parameterless更像是hook,可以在运行handler之前执行一些操作
Matcher.got
class Matcher(metaclass=MatcherMeta): @classmethod def got( cls, key: str, prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None, parameterless: Optional[Iterable[Any]] = None, ) -> Callable[[T_Handler], T_Handler]: async def _key_getter(event: Event, matcher: "Matcher"): matcher.set_target(ARG_KEY.format(key=key)) ``` 将传入的id设为arg target 由于set_target的cache未传,默认值为True,因此REJECT_CACHE_TARGET为传入的id ``` if matcher.get_target() == ARG_KEY.format(key=key): ``` 如果有arg target是REJECT_TARGET,将设为当前message并返回 ``` matcher.set_arg(key, event.get_message()) return if matcher.get_arg(key, ...) is not ...: return await matcher.reject(prompt) _parameterless = (Depends(_key_getter), *(parameterless or tuple())) ...
send相关方法
Matcher.send
class Matcher(metaclass=MatcherMeta): @classmethod async def send( cls, message: Union[str, Message, MessageSegment, MessageTemplate], **kwargs: Any, ) -> Any: bot = current_bot.get() # 获取当前bot event = current_event.get() # 获取当前event state = current_matcher.get().state # 获取当前state,是Matcher的state,当然包含全局state if isinstance(message, MessageTemplate): # 如果是MessageTemplate类型,要先构造成message _message = message.format(**state) else: _message = message return await bot.send(event=event, message=_message, **kwargs) # 发送
Matcher.finish
class Matcher(metaclass=MatcherMeta): async def finish( cls, message: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None, **kwargs, ) -> NoReturn: if message is not None: # 发消息 await cls.send(message, **kwargs) raise FinishedException ``` 抛出FinishedException,结束之后的handler和Matcher,直接开始运行event_postprocessor ```
Matcher.pause
class Matcher(metaclass=MatcherMeta): async def pause( cls, prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None, **kwargs, ) -> NoReturn: if prompt is not None: # 发消息 await cls.send(prompt, **kwargs) raise PausedException ``` 抛出PausedException,结束之后的handler和Matcher,直接开始运行event_postprocessor 生成一个更新了的temp Matcher,由下一条消息触发 ```
Matcher.reject
class Matcher(metaclass=MatcherMeta): @classmethod async def reject( cls, prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None, **kwargs, ) -> NoReturn: if prompt is not None: # 发消息 await cls.send(prompt, **kwargs) raise RejectedException ``` RejectedException将在后文统一分析 ```