铃心自定义——理论上的巅峰

经过一段时间的思考后,我决定采用一种非常规的方式来突破铃心最后的限制,截止到现在,测试机情况表现良好,理论上可以大规模投入使用。

编辑于2021.3.6,转载请注明原作者

何为“理论上的巅峰”?

任何东西都有其最终意义,或者说有其理论意义。

在开始介绍我们现在实现了什么之前,为了防止一些“云玩家”迷惑,我先解释一下QQ机器人的基本结构。

在这个粗略的接收流程中,我们用户扮演了信息的源。通过类似于xq或者mirai这类的bot框架转接/预处理消息,再拉起后端的应用去进一步的处理。

铃心自定义也不例外,其分类就是分类在“直接调度dll”的那部分。
铃心的唯一特点就是能够将用户编写好的脚本语言转换成可以在内存中直接进行调用的程序——仅此而已。

那么按照这个理论来说,任何先驱框架接收到的消息,铃心都可以进行接收并且加以处理。但是实际情况是——由于一些原因,铃心并没有更新这些功能,而基于他人的源码进行直接的更新又过于复杂,因此截止到目前,有些消息就无法被铃心接收处理(如同意群申请)。

那么如何让铃心发挥框架的全部能力?在之前我们就有提到过一种通过直接dll调用xqapi.dll的方法,可以让铃心使用几乎全部的xq api,那么顺着这个思路来,是不是可以让铃心完全发挥自己的力量呢?

曾经的尝试

通过轮询来伪获取事件

XQ除了API之外,还有一系列特殊的事件铃心没法进行直接的处理。但是在正常的开发流程中,是可以对于这些特殊的消息类型进行处理的,因此一个合理的方式就是通过自己撰写的插件,接收到这些消息,然后拉起铃心,让铃心也接收到这些消息并且加以处理和反馈。

在一开始,我个人尝试的方法是“利用监控事件轮询一个文本”。

以群邀请事件为例,通过查看先驱SDK里面的HandleGroupEvent,我们可以发现,其需要一个特殊的seq才能完成置群请求的操作,而这个seq的参数是来源于XQ接收到群邀请事件之后得到的原始消息。

因此一个极其合理的想法是,让这个插件在接收到事件之后,把接收到的内容按照一个格式写出到一个公共的文本中,然后再用铃心通过监控事件的轮询进行处理。

在一开始采用的这个方法还算是比较可行的,但是其有着几个显而易见的缺点:

  • 没法即时处理消息,存在一个轮询的时间差
  • 如果遇到多个相同事件发生,处理起来会涉及到一些有趣的逻辑问题
  • 文本传输数据存在一些未知的爆炸可能
  • 暴露在外的“轮询缓存区”非常的危险

虽然曾经还采用数据库的方式处理数据,但都不是非常的优雅,并且任何方式下都会存在着这个“延时”的问题。
因此我的目光很快就转到了另一个地方——铃心的web服务器。

开启web服务——拉起铃心的方法

综合上文来看,我们的问题就变成了“如何有效的通过其他插件拉起铃心自定义”。这个问题一开始本来还是有些扑朔迷离的,但是直到我回忆起一个东西的时候,事情就变得简单了起来。

什么叫做web服务?顾名思义,就是铃心通过监听一个服务器端口,通过那个端口的访问情况,经过后端处理,然后返回数据到对应的端口上。

这意味着,插件可以通过把事件上报到铃心所监听的端口的方式,即时的拉起铃心,让铃心迅速的处理消息。

在通过这样简单的代码编写之后,通过开启铃心自定义的web服务,就可以让铃心接收/处理这些事件了。
经过铃心处理之后,铃心可以通过dll调用xqapi中的api,完成群申请同意之类的api操作。

进一步的尝试

那么,有没有办法让铃心处理多种框架的消息呢,要知道,先驱是PC协议,对于一些安卓、平板乃至手表端独占的一些api和事件,先驱是没有办法获得的。

首先我们要明确一点,就是在框架不同的情况下,是可以同时登录多个不同框架,并且通过几个不同的后端体系进行回复的。

那既然我们已经确定了我们的主要技术是通过铃心的web服务器拉起铃心自定义进行消息处理,因此我们只需要让一个“东西”把消息从一个框架转发到这个窗口就可以了。

我的目光停留在了 GO-CQHTTP 这个项目上。

GO-CQHTTP

GO-CQHTTP 是使用 mirai (opens new window)以及 MiraiGo (opens new window)开发的 cqhttp golang 原生实现, 并在 cqhttp 原版 (opens new window)的基础上做了部分修改和拓展。

好吧,我们只需要知道,这是一个可以通过以下四个接口进行消息交互的系统:

  • HTTP API
  • 反向HTTP POST
  • 正向Websocket
  • 反向Websocket

在一开始,我考虑的是通过反向HTTP POST 让铃心的web服务器直接接收到GO-CQHTTP所获取的消息,但是我浏览了一番之后发现其传递消息的方式和铃心并不相同,因此接下来的方案就变成了两个:

  1. 通过修改代码,自行编译一个适合铃心的 GO- CQHTTP
  2. 通过一个外挂的程序,建立与GO-CQHTTP的正向ws,将接收到的事件转发到铃心监听的端口。

作为一个怂包+废物,我选择了第二种方案。

基于nodejs,转发事件至某端口

其实这个过程很简单,很容易就可以完成这样的一个程序。

这里是以“戳一戳”消息的接收作为例子的,然后通过它也得到了我预期的效果。
除此之外,铃心也可以通过超级访问GO-CQHTTP 的 HTTP 接口的方式,直接的调用某些接口,完成手机上才能完成的操作,在此我就不加以额外的赘述。

大功告成,到达了期盼许久的巅峰

至此,我们已经可以让铃心以曾经想都未想过的方式肆意的接收和调用所有框架的所有事件和接口了,可喜可贺可喜可贺。
本篇中虽然没有叙述什么实际上的代码之类的,但我认为其意义重大,从CQ消失以来的半年多,本以为没落的世界却因为各种各样的东西再次繁荣起来。

就这样吧,还有事情要做呢。

Yorunina

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>

相关推荐