酷Q插件开发之中级篇
前言
相信大家读过基础篇后对酷Q的使用和开发流程有了一个整体的认识,这里讲述一下插件的具体开发流程和相关函数的说明,以及注意事项等
架构
我们先简单了解一下酷Q的插件调用顺序和流程,如图1所示,我们发现存在所谓的优先级,有20000,30000和40000之分,数字越小,证明越先接收到消息,享有优先处理权。第二张图显示了酷Q消息的大概处理流程,是一条路走下去的,也就是说在写插件的时候,如果你其中一个插件迟迟不予以返回,或者处理时间过长就会导致酷Q消息处理卡死,无法正常工作。
10000 最高 – 监控类应用,无法用于拦截消息。(如:消息数目统计等)
20000 高 – 消息控制类应用,可用于拦截消息。(如:机器人开关等)
30000 一般 – 普通功能类应用。(如:天气查询、游戏类等)
40000 低 – 聊天对话类应用。(如:词库、云词库)
这个优先级是在json文件中设置的,具体参考官方文档中事件信息分类
SDK
接着我们来熟悉一下SDK的结构,酷Q有很多语言的SDK,但是所有的SDK都是由回调函数,功能性API加json配置文件组成,回调函数负责接收QQ的各类消息,比如聊天消息,加群消息等。 而功能性API则是用来提供给我们来进行回复消息,获取群列表,踢人等等操作。另外还有一个json文件,这个文件是用来设置插件需要接受的消息类型,事件优先级,插件名等,可以看实例json文件获取更多信息。在阅读下面内容的时候,请顺带参考基础篇里面讲到的酷Q开发相关文档和sdk示例代码注释来理解。
举个例子,以c++ sdk为例,c++ sdk的功能性API接口是在cqp.h头文件里面,我们需要实现的和QQ交互的功能都需要通过这些API来实现:
/*
部分API如下,想要了解这些API的作用可以通过两个方面考虑,1. 英文翻译 2. 操作流程。我们需要知道函数名和参数名英文的大概意思,
这样我们就知道函数是做什么用的,然后我们需要对qq操作的基本流程和要素有所理解。 比如【CQ_sendPrivateMsg】这个函数,翻译过
来就是发送私有消息,那么很容易联想到是私聊,接着我们考虑qq发送私聊消息的要素和流程,就是获取对方的qq号发送消息即可,然后
加上QQID和msg的意思,我们就知道这两个参数是qq号和消息了,至于AuthCode,翻译过来是认证码,那么应该是属于qq登陆后保存的
一个认证信息,所有函数都有这个参数,这个参数由回调函数提供
*/
CQAPI(int32_t) CQ_sendPrivateMsg(int32_t AuthCode, int64_t QQID, const char *msg);
CQAPI(int32_t) CQ_sendGroupMsg(int32_t AuthCode, int64_t groupid, const char *msg);
CQAPI(int32_t) CQ_sendDiscussMsg(int32_t AuthCode, int64_t discussid, const char *msg);
...... \\下面还有其他API
接下来是c++ sdk的回调部分,也是插件的主体组成,代码位于appmain.cpp里面, 我们写代码也是在这个位置,这里也节选部分说明。在我们编写插件的时候,我们只需要对自己感兴趣的消息回调进行处理即可
/*
* 接收应用AuthCode,酷Q读取应用信息后,如果接受该应用,将会调用这个函数并传递AuthCode。
* 不要在本函数处理其他任何代码,以免发生异常情况。如需执行初始化代码请在Startup事件中执行(Type=1001)。
*/
CQEVENT(int32_t, Initialize, 4)(int32_t AuthCode) {
ac = AuthCode;
return 0;
}
/*
* Type=1001 酷Q启动
* 无论本应用是否被启用,本函数都会在酷Q启动后执行一次,请在这里执行应用初始化代码。
* 如非必要,不建议在这里加载窗口。(可以添加菜单,让用户手动打开窗口)
*/
CQEVENT(int32_t, __eventStartup, 0)() {
return 0;
}
/*
* Type=1002 酷Q退出
* 无论本应用是否被启用,本函数都会在酷Q退出前执行一次,请在这里执行插件关闭代码。
* 本函数调用完毕后,酷Q将很快关闭,请不要再通过线程等方式执行其他代码。
*/
CQEVENT(int32_t, __eventExit, 0)() {
return 0;
}
/*
* Type=1003 应用已被启用
* 当应用被启用后,将收到此事件。
* 如果酷Q载入时应用已被启用,则在_eventStartup(Type=1001,酷Q启动)被调用后,本函数也将被调用一次。
* 如非必要,不建议在这里加载窗口。(可以添加菜单,让用户手动打开窗口)
*/
CQEVENT(int32_t, __eventEnable, 0)() {
enabled = true;
return 0;
}
/*
* Type=1004 应用将被停用
* 当应用被停用前,将收到此事件。
* 如果酷Q载入时应用已被停用,则本函数*不会*被调用。
* 无论本应用是否被启用,酷Q关闭前本函数都*不会*被调用。
*/
CQEVENT(int32_t, __eventDisable, 0)() {
enabled = false;
return 0;
}
/*
* 这个地方就是处理私聊消息的地方,如果你要处理私聊消息就在这里写代码
* Type=21 私聊消息
* subType 子类型,11/来自好友 1/来自在线状态 2/来自群 3/来自讨论组
*/
CQEVENT(int32_t, __eventPrivateMsg, 24)(int32_t subType, int32_t sendTime, int64_t fromQQ, const char *msg, int32_t font) {
//如果要回复消息,请调用酷Q方法发送,并且这里 return EVENT_BLOCK - 截断本条消息,不再继续处理 注意:应用优先级设置为"最高"(10000)时,不得使用本返回值
//如果不回复消息,交由之后的应用/过滤器处理,这里 return EVENT_IGNORE - 忽略本条消息
return EVENT_IGNORE;
}
/*
* 这个地方就是处理群消息的地方,如果你要处理群聊消息就在这里写代码
* Type=2 群消息
*/
CQEVENT(int32_t, __eventGroupMsg, 36)(int32_t subType, int32_t sendTime, int64_t fromGroup, int64_t fromQQ, const char *fromAnonymous, const char *msg, int32_t font) {
return EVENT_IGNORE; //关于返回值说明, 见“_eventPrivateMsg”函数
}
/*
* 这个地方就是处理讨论组消息的地方,如果你要处理讨论组消息就在这里写代码
* Type=4 讨论组消息
*/
CQEVENT(int32_t, __eventDiscussMsg, 32)(int32_t subType, int32_t sendTime, int64_t fromDiscuss, int64_t fromQQ, const char *msg, int32_t font) {
return EVENT_IGNORE; //关于返回值说明, 见“_eventPrivateMsg”函数
}
......\\下面还有好友请求回调,入群消息回调等,可自己查看相关函数和注释
最后我们要注意的是json文件,json文件可以让酷Q知道:
- 我们想要处理哪些回调,我们通过注册自己感兴趣的回调来避免其他回调代码的处理和干扰。
- 插件的优先级信息,这决定我们插件处理消息的先后循序
- 部分功能性API接口调用需要插件具备特定权限,我们也需要在json文件中予以声明。
- 我们插件需要几个菜单,就可以在json注册几个,然后在回调代码文件加入相关代码
- 程序版本信息,描述等,最终和我们插件dll打包成cpk文件发布
CQ码
在基础篇中我们提到过CQ码,有了一个简单的认识,这里讲述一下CQ码的使用方法和注意事项
比如我们需要发送一张图片,那么查询CQ码手册(基础篇)可以看到这段说明
那么我们就应该这样操作:CQ_sendPrivateMsg(ac, 8888888, "测试[CQ:image,file=myimg\1.jpg]");
这段代码效果就是向8888888发送了一段信息,信息是 “ 测试+图片1.jpg“,这里可以看出CQ码是直接放到消息里面即可,可以和其他消息随意组合。这里比文档多了一个myimg,那么我们这个1.jpg的路径就是data\image\myimg\1.jpg,建议写插件的时候创建一个自己的图片文件夹。其他的CQ码使用方法类似。
在发送图片和声音的时候,需要注意,酷Q的CQ码是没法指定图片或者音频的完整路径的,必须放在酷Q程序下的特定目录(E:\酷Q Air\data),然后使用相对路径。 data目录下有image和record两个文件夹,分别代表图片和声音,建议在这两个文件夹的下面再创建一个你自己的文件夹,比如创建一个test,那么最终你程序下载和使用的图片路径为 E:\酷Q Air\data\image\test这种,在发送的时候使用的路径就是test\1.jpg这种相对路径
注意事项
- QQ消息的默认编码是GBK,c++默认编码也是GBK,所以不需要进行附带处理,但是如果你是python sdk或者其他类似sdk,那么就需要进行编码处理
- 千万不要在回调中处理阻塞性的事物,这样会导致酷Q整个卡顿,可以试着开线程或者定时器
- json和dll的文件名要保持一致
微信赞赏
支付宝赞赏