cyanray / mirai-cpp

本项目为 mirai-api-http 的 C++ 封装,方便使用 C++ 开发基于 mirai-api-http 插件。
GNU Affero General Public License v3.0
148 stars 38 forks source link

拆分含有 Operator 且 Operator 可能为 Bot 的事件 #34

Closed cyanray closed 3 years ago

cyanray commented 3 years ago

背景

一些事件中,如群成员消息撤回事件(GroupRecallEvent),Operator 被定义为 GroupMember_t 类型的属性,表示引起该事件的操作者。 mirai-http 返回的这个事件的json,这个 Operator 可能为 null,表示 Operator 为 bot 自己。 然而,mirai-cpp最初为了简洁的设计,所有的事件类都没有用 getter/setter 编程样式,采用了直接暴露类成员的方式。(当事人表示非常后悔) 所以,现在的 mirai-cpp 无法处理 Operator 为 null 时的情况。

临时的解决方案

对于所有含有 Operator 且 Operator 可能为null的事件,都提供了一个 OperatorIsBot 的函数。读取 Operator 前,应该调用该函数,做一次判断,如果该函数返回 true,则不应该读取该事件的 Operator 成员。

临时解决方案存在的问题

如果忘了做判断,当 Operator 为null时直接读取 Operator,是不会有任何异常、报错出现的。(读取到的值都是没有意义的值)

其他的解决方案

  1. mirai-http 的 Operator 为 null 时,将 Operator 设置为 bot 的信息。(无法实现,当前无法根据 QQ_t 获取 GroupMember_t)
  2. 将编程样式改为 getter/setter 的编程样式(需要修改的地方太多了,影响太大)
  3. 将事件一分为二,如 GroupRecallEvent 可以拆分为 GroupRecallEvent 和 BotGroupRecallEvent 两个事件。而BotGroupRecallEvent 中不包含 Operator 属性。(需要修改事件系统)

未来的计划

暂时按照第三个解决方案进行,临时解决方案将废弃。

cyanray commented 3 years ago

计划在mirai-cpp 2.0时提升最低c++标准为c++17,使用 std::optional 来实现可空(std::nullopt)成员。