消息类
消息创建
自动格式化
- 初始化时进行消息的自动格式化
- 将字符串的消息内容转换为消息段格式,消息段格式的不进行转换
- 将字母+数字或者是纯数字的其他属性统一转换为字符串
- 生成唯一编号
- 由秒级时间戳+计数器生成,上限 1 秒内 1k 条消息
- 当两条消息在同一秒内创建时,计数器自增,确保 num 唯一
- 不直接使用
time.time_ns()的原因:- 在高并发下,多条消息可能在同一事件循环周期内被批量处理,即使网络层到达时间不同,也可能被记录为同一毫秒
自动处理
- 消息创建后,在 init 函数中自动加入消息池
- 只需要调用
Msg(xx)就可以创建消息后自动处理
打印
- 重写
__repr__方法- 打印时仅显示非空字段
- 输出为一个去掉了括号的属性字典字符串,便于调试和日志记录
消息字段解析
- 字符串-消息段的双向转换
字符串格式
- 只存在于日志打印的消息内容,以及指令匹配的匹配文本(在匹配时自动转换为消息段)、发送消息的发送文本(在消息初始化时自动转换为消息段)中
- 即字符串->消息段的转换内容完全由程序员控制,
若转换失败也是程序员的问题
消息段格式
- 所有接收的消息、发送的消息均为消息段格式
- 所有比较均为消息段格式
消息段转字符串
- content_join
- handlers 里面列出了 type 对应的处理函数 lambda
- 处理时,对于消息内容中的每个消息段,根据 type 属性调用对应的处理函数(默认为
lambda _: f"[未知类型:{seg['type']}]),随后用处理函数处理 data 属性 - 处理函数会获取 data 中的关键字段(消息字段中的加粗字段)
- 其中表情解析可以解析不存在于 emoji.yaml 但存在 face_text 的表情自动加入 emoji.yaml
字符串转消息段
- content_disjoin
- _content_token_match 里可以解析 [prefix:value] 的消息段
- 解析规则
- value 中包含 [] 可以正常解析(通过 depth)
- [] 之间、之前、之后的文本可以正常解析
- 若存在未闭合的 [ ],会匹配失败到最后,整段保留为文本
- 最后合并相邻的文本防止发送/匹配逻辑出错
- _face_disjoin 针对含 | 的动画表情,自动把名称转换成对应的几个字段后发送,可以发送商城表情;若名称不在商城表情列表里,则为从文件发送表情
- 先使用 _content_token_match 返回 prefix,value,查找 handles 中 prefix 对应的函数(默认为
lambda _: {"type": "text", "data": {"text": f"{p}:{v}"}}),然后用函数处理(func(v))
v in "123456" 不能代替 v in ["1","2","3","4","5","6"],因为有 12 (
消息字段比较
- 消息字段比较分为全等和包含两种
- 二者均分段进行比较
- 全等时,消息段中所有段与匹配段中所有段比较
- 若长度不相等直接跳过
- 包含时,消息段中设置动态区间与匹配段中所有段比较
- 全等时,消息段中所有段与匹配段中所有段比较
- 比较时,每一项使用 _seg_match 比较
- 种类不同直接跳过
- 不支持节点、转发的比较(收发转发不同,节点、表情只能发送)
- 戳戳类型全部相同(只能收到一种戳戳)
- 比较字段
- 图片类型,若均存在 summary 使用 summary 比较,否则使用 file 比较
- 其他均用消息字段中的加粗字段进行比较
- 比较内容
- 若种类为文本
- 相等:两个字段必须相等
- 包含:匹配字段" "空格则均可以匹配,否则需要消息字段包含匹配字段
- 若种类为其他
- 相等/包含:若匹配字段为"any"则均可以匹配,否则必须相等
- 若种类为文本