自定義QQ機器人,實現關鍵字回復


使用第三方接口,可以很輕松的實現QQ機器人的自定義:打開源代碼->找到相應接口(私聊或群聊或其他)->自定義自己的內容->編譯生成*.dll動態庫->放入下載好的酷Q相應文件夾->登陸酷Q(最好用小號)。

這里主要強調有兩個方面:

1、如何實現自定義的對人友好化:即不需要編程知識也可以自定義實現。可以把關鍵字、回復內容放入一個配置文檔內,這樣只需修該配置文檔即可。我使用的是xml。在源代碼添加一個xmlLoader類即可解決問題

2、如何提高機器人處理消息的性能:給程序添加一個專門處理消息的線程。其中自己在使用互斥鎖時不夠熟練,應記得及時解鎖,否則會出現函數堵塞。

具體代碼如下:

 1 #pragma once
 2 #include "qqSupport.h"
 3 #include <list>
 4 #include "tinyxml/tinyxml.h"
 5 
 6 using namespace std;
 7 
 8 class xmlLoader
 9 {
10 public:
11     string getXmlPath()
12     {
13         string xP = getPath();
14         string xmlPath = xP + "config.xml";
15 
16         return xmlPath;
17     }
18 
19 
20     int loadXml(string xmlPath)
21     {
22         //加載xml文件
23         TiXmlDocument* doc = new TiXmlDocument();
24         if (doc == NULL)
25         {
26             return -1;
27         }
28         doc->LoadFile(xmlPath);
29 
30         TiXmlElement* xmlRoot = doc->RootElement();
31         TiXmlElement* xmlChildDef = xmlRoot->FirstChildElement("default");
32         defaultAnswer = xmlChildDef->GetText();
33 
34 
35         TiXmlElement* xmlChild = xmlRoot->FirstChildElement("match");
36         while (xmlChild)
37         {
38             TiXmlElement* xmlKW = xmlChild->FirstChildElement("keyword");
39             TiXmlElement* xmlAS = xmlChild->FirstChildElement("answer");
40             msgContent mC;
41             mC.keyword = xmlKW->GetText();
42             mC.answer = xmlAS->GetText();
43 
44             m_msgContentList.push_back(mC);
45             //addLog(mC.keyword.c_str());
46             //addLog(mC.anwser.c_str());
47 
48             xmlChild = xmlChild->NextSiblingElement("match");
49         }
50 
51         return 0;
52     }
53 
54     string findAnswer(int type,string msg)
55     {
56         //根據關鍵字找答案
57         for (list<msgContent>::iterator iter = m_msgContentList.begin();
58             iter != m_msgContentList.end(); iter++)
59         {
60             
61             msgContent& mC = *iter;
62             addLog(mC.keyword.c_str());
63             addLog(msg.c_str());
64             addLog(mC.answer.c_str());
65             if ((int)msg.find(mC.keyword)>0)
66             {
67                 //addLog("有答案");
68                 return mC.answer;
69             }
70         }
71 
72         return defaultAnswer;
73     }
74 
75 private:
76     struct msgContent //xml內容
77     {
78         string keyword;
79         string answer;
80     };
81     list<msgContent> m_msgContentList; //保存到列表
82     string defaultAnswer;
83 };
xmlLoader.h
 1 #pragma once
 2 #include "afos/AfMutex.h"
 3 #include "afos/AfThread.h"
 4 #include "xmlLoader.h"
 5 #include <list>
 6 
 7 using namespace std;
 8 
 9 class syncTask:public AfThread
10 {
11 public:
12     int startService();
13     void stopService();
14     int addMsg(int type, int64_t from, const char *msg);
15 private:
16     int ThreadMain();
17 private:
18     struct recvMsg   //收到的信息
19     {
20         int type;
21         int64_t from;
22         string msg;
23     };
24 
25 private:
26 
27     list<recvMsg> m_recvMsgList;   //保存信息到列表
28     AfMutex m_mutex;  //互斥鎖
29     bool m_quitFlag;
30     xmlLoader m_loader;  //加載xml類
31 };
32 
33 
34 void myIniti();
35 
36 void myEexit();
37 
38 void msgToThread(int type,int64_t from,const char *msg);
myplugin.h
 1 #include "myplugin.h"
 2 #include "xmlLoader.h"
 3 #include "qqSupport.h"
 4 
 5 
 6 syncTask m_serviceTask;
 7 
 8 int syncTask::startService()
 9 {
10     std::string xp = m_loader.getXmlPath();
11     if (m_loader.loadXml(xp)<0)
12     {
13         return -1;
14         //addLog("不能加載xml");
15     }
16     m_quitFlag = false;
17 
18     //進入線程
19     this->Run();
20 
21     return 0;
22 }
23 
24 
25 void syncTask::stopService()
26 {
27     m_quitFlag = true;
28     Join(this);
29 }
30 
31 
32 int syncTask::ThreadMain()
33 {
34     //addLog("進入線程");
35     while (!m_quitFlag)
36     {
37         AfThread::Msleep(50);
38 
39         bool flag=false;
40         recvMsg rM;
41         m_mutex.Lock();//加鎖
42         if (m_recvMsgList.size()>0)
43         {
44             flag = true;
45             rM = m_recvMsgList.front();
46             addLog(rM.msg.c_str());
47             m_recvMsgList.pop_front();
48             //addLog("有消息進入");
49         }
50         m_mutex.Unlock();
51         if (!flag)
52         {
53             continue;
54         }
55         std::string answer = m_loader.findAnswer(rM.type, rM.msg);
56         sendMsg(rM.type, rM.from, answer.c_str());
57     }
58     return 0;
59 }
60 
61 
62 int syncTask::addMsg(int type, int64_t from, const char * msg)
63 {
64     recvMsg rM;
65     rM.type = type;
66     rM.from = from;
67     rM.msg = msg;
68 
69     m_mutex.Lock();//加鎖
70     if (m_recvMsgList.size()<100)
71     {
72         m_recvMsgList.push_back(rM);
73     }
74     m_mutex.Unlock();
75     
76     return 0;
77 }
78 
79 
80 
81 void myIniti()
82 {
83     m_serviceTask.startService();
84 }
85 
86 void myEexit()
87 {
88     m_serviceTask.stopService();
89 }
90 
91 void msgToThread(int type, int64_t from, const char *msg)
92 {
93     m_serviceTask.addMsg(type, from, msg);
94 }
myplugin.cpp
1 #pragma once
2 #include "stdafx.h"
3 #include <string>
4 #include "cqp.h"
5 #include "appmain.h"
6 
7 void sendMsg(int type, int64_t from, std::string msg);
8 void addLog(const char* msg);
9 std::string getPath();
qqSupport.h

 


免責聲明!

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



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