一个基于MFC的QQ机器人框架_weixin_30556161的博客-程序员宅基地

0x00 这是什么?

欢迎使用本QQ机器人开发框架(如果有人会用的话)。本框架是主要使用MFC中的Windows API制作而成、利用Windows的消息机制以及一些系统级底层架构实现利用TIM客户端自动收发QQ消息的QQ机器人框架,用其制作的QQ机器人程序已在VS2017下编译通过(仅支持ANSI字符集)并可正常运行。

在框架开发时主要考虑了其拓展性,通过拓展该框架,可以实现包括自动回复、定时推送、发送图片、调用其他进程并进行通信甚至连接MySQL的功能,您不仅可以用本框架制作常规的群聊机器人,还可以让QQ机器人成为你访问各种程序的接口,这也是本QQ机器人框架开发的初衷。

本QQ机器人框架由HarmoniaLeo完全独立开发,部分代码参考CSDN论坛和各种博客,在此向所有为本框架诞生提供帮助的前辈们表达真诚的谢意。

0x01 我能做出什么样的QQ机器人?

1.自动回复

自动回复的本质是通过接收消息记录中特定模式的消息调用对应的CString类函数,特定模式的消息指形如“口令 参数1 参数2……”的消息。调用函数后返回的CString result将会以**@发送消息的用户名 result** 的形式被机器人发送到对应的会话窗口。参数个数需要与函数配置时申请的参数个数一致,若过少则不会回复,若过多则最后一个参数将是带 空 格的字符串(函数的配置会在0x03中介绍)。

在这里插入图片描述

2.订阅与定时推送

functions.cpp中预置有函数CString subscribe(CString* valuelist,HWND hwnd,CString caller),对应口令为“订阅”,当会话中出现形如订阅 口令名[(参数1,参数2……)] YYYY:MM:DD:HH:MM:SS [Nd][Nh][Nm][Ns]([]内的内容可以省略)的消息时,机器人会自动记录该订阅,回复“@用户名 订阅成功:口令名”,并根据YYYY:MM:DD:HH:MM:SS和[Nd][Nh][Nm][Ns]这两个参数来定时调用口令名对应的函数,并回复消息。假如这个口令名没有对应函数,则机器人会回复该口令原本的内容。

在这里插入图片描述

举个例子:我想要订阅口令名为“复读”的函数,想要从1919年11月4日5点14分开始每隔8小时1秒调用一次,我可以在会话中回复“订阅 复读 1919:11:4:5:14:0 8h1s”,如果我想从现在开始调用函数,则YYYY:MM:DD:HH:MM:SS参数可以被替换为-1,如果我只想让它推送一次该函数,之后就将这个订阅删除,我可以把[Nd][Nh][Nm][Ns]参数替换为-1。如果“复读”没有对应函数,那么它就会从1919年11月4日5点14分开始每隔8小时1秒回复一次“复读”。

此外,functions.cpp中预置有函数CString checkscribe(CString* valuelist,HWND hwnd,CString caller)和CString unscribe(CString* valuelist,HWND hwnd,CString caller),对应的消息分别为“查询订阅”和“取消订阅 口令名”。试试看吧!

和订阅功能有关的外部储存文件会被储存在和.exe文件相同目录下的“订阅”文件夹下,其储存采用.txt方式。

由于该框架的高度可拓展性,您甚至可以制作出终端类的QQ机器人,这可以通过本框架提供的API实现。

在这里插入图片描述

0x02 听起来不错,那么我怎么开始呢?

首先您需要的是本项目文件夹中的所有文件,还需要一台装有Windows系统的服务器,以及一个TIM客户端。

我们接下来以阿里云的Windows Server 2012 R2为例进行介绍。

Step1:打开TIM客户端,登录机器人账号,将需要回复的会话窗口拖出嵌入式的对话框,并将其全屏(注意不要最小化)。

在这里插入图片描述

Step2:测出会话窗口聊天区中4个安全点的x、y坐标(就是点击后只是把焦点设置在消息列表,而不会执行其他操作)(可以使用 https://github.com/HarmoniaLeo/Windows-Screen-Ruler 提供的工具测量),这个坐标主要受windows服务器内部设置的屏幕分辨率影响。将其填入functions.cpp中的extern const int position[8][2] 数组的初始化值中。如果您使用的是阿里云的Windows Server 2012 R2,则使用默认值即可。

在这里插入图片描述

const int position[8][2] = { {
                43,121},{
                      970,121},{
                            43,344},{
                                  970,344} };//更改四个定位点的坐标 

Step3:在functions.cpp中的extern const CString windowList[windowNum] 的初始化值中填入所有要回复的会话窗口的标题,并将QQbot3.h中的宏windowNum改为会话窗口的总数目。

const CString windowList[windowNum] = { /*以"会话名1","会话名2"……的方式添加会话名*/}; #define windowNum 2//更改窗口数目 

0x03 如何为QQ机器人配置函数呢?

Step1:在functions.cpp中的指定位置,以CString 函数名(CString* valuelist,HWND hwnd,CString caller) 为函数头添加函数。

函数的参数介绍:

CString* valuelist:参数列表,全部使用MFC内建的CString类来传入参数,用户通过回复“口令 参数1 参数2……”这样的消息将参数传入函数,您可以在函数中对这些参数进行处理并返回不同的结果。

HWND hwnd:窗口句柄,Windows API中的概念,根据QQ机器人响应的会话窗口不同而有所不同,通过这个参数可以用来调用本框架提供的各种API。

CString caller:调用该函数的用户名。

函数的返回值:

若函数返回了一个CString类字符串,那么调用函数后返回的CString result将会以**@发送消息的用户名 result** 的形式被机器人发送到对应的会话窗口。若返回了空串,则机器人不会执行任何动作,可以用来拒绝参数格式不正确的输入。

Step2:在functions.cpp中的**void funcInit()**函数中加入语句:funclist[函数编号(从4开始(0-3为预留))]=&函数名;

void funcInit()
{ funclist[0] = &listCommands; funclist[1] = &subscribe; funclist[2] = &unscribe; funclist[3] = &checkscribe; //初始化自定义函数 } 

Step3:在functions.cpp中的extern const CString functions[fnum] 的初始化值中函数编号对应的位置填入需要响应的口令名(也就是用户用来调用该函数的口令)

const CString functions[fnum] = { "查询命令","订阅","取消订阅","查询订阅"/*以"口令名1","口令名2"……的方式添加口令名*/ }; 

Step4:在functions.cpp中的extern const int values[fnum] 的初始化值中函数编号对应的位置填入申请的参数个数

const int values[fnum] = { 0,3,1,0/*以"参数数目1","参数数目2"……的方式添加参数数目*/ }; 

Step5:将QQbot3.h中的宏fnum改为函数的总数目。

#define fnum 19//更改函数数目

0x04 框架为我提供了哪些API呢?

1.针对一些对于MFC并不是特别熟悉的用户,也为了开发方便起见,以下列出该框架提供的基础API列表:

CString getTimeStamp()//获取当前时间用Y/M/D H:M:S表示的时间戳(TIM消息记录中时间戳的格式 同时也是本框架在通过文件保存时间戳时的标准形式)

void timeATOI(int* time,CString TMP)//将用Y/M/D H:M:S表示的时间戳TMP转换为一个长度至少为6的int型数组anwser void periodTOI(CString period,int* anwser)//将用NyNmNdNhNmNs(N表示对应数字)表示的时间戳period转换为一个长度至少为6的int型数组anwser(为用户提供更方便的时间输入方式) CString turnTimeToAddForm(CString target)//将用Y:M:D:H:M:S表示的时间戳target转换为用Y/M/D H:M:S表示的时间戳(为用户提供更方便的时间输入方式) CString timeAdd(CString TMP,CString period)//将用Y/M/D H:M:S表示的时间戳TMP和用NyNmNdNhNmNs(N表示对应数字)表示的时间戳period相加并输出新的用Y:M:D H:M:S表示的时间戳 CString cutLeft(CString source,CString obj)//获取source字符串第一个obj字符串以前(不包括obj)的字符串 CString cutRightBI(CString source,int index)//获取source字符串index以后(不包括index)的字符串 CString cutRight(CString source,char obj)//获取source字符串最后一个obj字符以后(不包括obj)的字符串 CString getTitle(HWND hwnd)//获取窗口标题 void exec(CString route);//启动外部程序(route为该程序路径以及该程序的命令行参数,用空格分隔)(可以用来执行python脚本等) int openFile(CString dir,vector<CString>* list)//打开或创建dir所表示的文件,并分行读入所有内容到一个CString类的vector里,返回读入的行数 void writeFile(CString dir,vector<CString> list,int count)//将一个CString类的vector里的前count行内容分行写入dir所示的文件中 

2.针对一些想要丰富消息发送方式的用户,用户可以在配置函数时随时使用以下API:

CString get(HWND hwnd)//获取会话窗口的消息记录

void pasteMessage(CString source,HWND hwnd)//将source中的消息填入消息发送栏 void toClipboard(CString source,HWND hwnd)//发送source中的消息 void pasteIMG(CString path,HWND hwnd)//将文件路径path所指向的bmp图片复制到消息发送栏 void send(HWND hwnd)//发送消息发送栏里面填入的消息 

3.针对想要开发终端交互式QQ机器人程序的用户,本框架提供以下API:

aTime getATime()//获取当前时间,需要在终端交互函数的开始初始化时间,用aTime类保存,并在之后将aTime类对象的指针传入lastSpeak以响应特定用户最后发送的消息

CString lastSpeak(CString source,CString caller,aTime* last,HWND hwnd)//获取消息记录source中昵称为caller的用户最后发送的消息,获取失败则返回空串,last是一个指向aTime的指针。可以通过一个while循环,判断返回值是否为空,来等待特定用户的输入 

实际上终端交互式QQ机器人程序就是让机器人响应一个长周期的函数,利用lastSpeak不断接收特定用户的消息,再利用2中所示的函数即时地发送消息罢了。

0x05 上面这些我都做完了,还需要做什么呢?

做完了以上这些,在MFC框架支持下建立控制台程序,编译项目,将生成的.exe文件和(如果使用了MySQL API的话)上传至服务器。运行之后就完成属于你的QQ机器人了!

转载于:https://www.cnblogs.com/HarmoniaLeo/p/10568861.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30556161/article/details/95114037

智能推荐

Hive SQL练习之影评案例_软件手的博客-程序员宅基地

找的练习hive,内容非原创链接 https://www.cnblogs.com/frankdeng/p/9309668.html一、建表,导入数据1、建表[[email protected] hadoop]# hiveLogging initialized using configuration in jar:file:/usr/local/src/apache-hive-1.2.2-bin/lib/hive-common-1.2.2.jar!/hive-log4j.propertieshive&gt.

QMovie与内存泄露_enjoyfate的博客-程序员宅基地

http://blog.sina.com.cn/s/blog_d0d644520102vjnb.html内存泄露:简单地说就是申请了一块内存空间,使用完毕后没有释放掉。它的一般表现方式是程序运行时间越长,占用内存越多,最终用尽全部内存,整个系统崩溃。由程序申请的一块内存,且没有任何一个指针指向它,那么这块内存就泄露了。周期性调用!!需要生成很多QMovie实例。时间久了当然句柄数不够。...

spring boot 结合netty搭建服务端实现自定义协议全过程_qq_33071429的博客-程序员宅基地

前言 公司准备做一个关于物联网的试点项目,其中硬件部门需要与我们软件部进行数据对接,将设备获取的数据传给我们软件部门处理。于是安排我来负责与硬件部门数据的对接,搭建netty服务器数据平台.(我们公司是一个小公司,人员有限!!!) 于是现学netty服务端,现在框架也搭得差不多,把整个过程分享出来,希望能帮助到大家,有不足之处请指导。1.协议的制定 数据头: 两个字节,固定值 设备id号:代表每个通讯的设备MAC地址;SN号对...

填空题实现_码农老郭的博客-程序员宅基地

&amp;lt;div style='margin:3% 8% 1%'&amp;gt; &amp;lt;label [ngStyle]=&quot;tip&quot;&amp;gt;题干 &amp;lt;/label&amp;gt; &amp;lt;label style=&quot; color:#A9B3BF&quot;&amp;gt;这里填写题目描述&amp;lt;/label&amp;gt; &amp;lt;input #Judge

nGrinder中快速编写groovy脚本03-在GET请求中发送参数_媛测的博客-程序员宅基地

一、通过UI界面添加通过 UI 设置:脚本 -&amp;amp;amp;amp;amp;gt; 新建脚本 -&amp;amp;amp;amp;amp;gt; 显示高级配置生成代码如下:@RunWith(GrinderRunner)@FixMethodOrder(MethodSorters.NAME_ASCENDING)class TestRunner { public static GTest test public static HTTPRequest r...

随便推点

关系型数据库MySQL之触发器和表数据操作_JiekeXu的博客-程序员宅基地

一、触发器(TRIGGER)触发器是MySQL的数据库对象之一,该对象与编程语言中的函数非常类似,都需要申明、执行等。1.1、 创建触发器1&amp;gt; 创建有一条执行语句的触发器创建触发器通过SQL语句CREATE TRIGGER 来实现,其语法形式如下:Create trigger trigger_name BEFORE|AFTTER trig...

python elementtree属性_python通过ElementTree操作XML获取结点读取属性美化XML_方大凯的博客-程序员宅基地

1.引入库需要用到3个类,ElementTree,Element以及建立子类的包装类SubElementfrom xml.etree.ElementTree import ElementTreefrom xml.etree.ElementTree import Elementfrom xml.etree.ElementTree import SubElement as SE2.读入并解析tree ...

道歉,让教育发光_ctfr3038的博客-程序员宅基地

【案例】一天早上,我正在办公室里埋头批改日记。翻开一本精美的日记本,就看到了那娟秀的、熟悉的字迹,我一下子就认出这是她写的日记。我细细读着。她在日记的开头部分用欢快的笔触记录了“六一”快...

Logistic回归和Softmax回归 对比_人鱼线的博客-程序员宅基地

Logistic回归和Softmax回归 都是基于sigmoid函数:Logistic回归主要应用于二分类问题,回归问题的表达式: , 将得到的y值经过sigmoid函数转化为二分类问题.表示y=1的概率,其中单个样本的概率分布:m个样本的概率分布 --&gt; 似然函数:对数似然函数:损失函数:Softm...

测试岗工作记录_青枣早的博客-程序员宅基地

证券金融行业更多的技术集中的业务方面,经验的积累体现在业务积累上体验。引用一段百度问答中的回答:“集中交易是正式的称呼,柜台系统是以前的称呼。以前的交易系统,以营业部作为单位,在营业部柜台安装的系统叫柜台系统,用于柜员向客户提供开户、资金转账、查询、销户等服务。与之相对应的系统是周边系统,比如热自助系统、电话委托系统、刷卡委托系统等等。这些周边系统是指客户(投资者)可以通过以上手段下单、查询。后来,一个营业部一套系统的弊端逐渐显露出来,证券公司总部便采取了集中交易系统的模式,也就是说将数据全部集中存放到

solr初次使用_ae8390的博客-程序员宅基地

什么是solr?Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。solr整合Tomcat步骤第一步:安装tomcat。D:\temp\apache-tomcat-7.0.53第二步:把solr的war包复制到to...

推荐文章

热门文章

相关标签