一個基於MFC的QQ機器人框架


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機器人了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM