使用第三方接口,可以很轻松的实现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 };

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);

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 }

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();