出处:http://www.cnblogs.com/hjf1223/archive/2008/01/22/LumaQQ_Robot.html
自从博客园闪存发布了QQ机器人以后,闪存数量一下子就上升了很多。很多人也一直都在询问QQ机器人是如何开发的,这足以说明QQ在中国不仅仅是普通人使用的IM工具,在程序员圈子里也相当有人缘的,其老大地位不容怀疑啊。我这篇也算是给解答一些朋友的疑惑吧。
所谓的IM机器人(QQ,MSN),其实就是一个简化版的IM客户端(QQ,MSN)。利用这个简单的客户端连接到IM服务器,接收和发送消息来达到自动回复的目的。可惜,.NET中并没有开源的QQ机器人的开发包(MSN,有DotMSN,详见《使用DotMSN 2.0开发MSN机器人》)。博客园使用的是商业组件,而对大部分人来说更希望是免费的。.NET中没有开源开发包,但是JAVA中却有。在Liunx等其它非Windows平台下,会有很多的开源QQ,其中的LumaQQ也算是比较有名的开源QQ了,你可以从它的官方主页上了解更多的信息。在网络上也已经有人根据LumaQQ的协议,使用C#来开发机器人了。遗憾的是,没有一个是开源的。没有也罢,那我们就直接使用JAVA版本来的LumaQQ来开发自己的机器人吧。
其实使用JAVA语法,对于我们来说并不是一件难事。我想大家主要的麻烦就在于如何去使用JAVA的开发工具,引用LumaQQ的包,以及编译,调试,打包和部署。但这些在这里都不是难事,我会提供引用好了点整个的Eclipse解决方案(工作空间)。你下载了,直接在这个空间下开发编辑源代码即可。下面先来说说简单的原理。
原理部分
这个机器人,我们直接开发一个一直运行的机器人即可。如果你对JAVA本身并不是很了解的话,那么我建议QQ机器人本身只提供一个QQ客户端收发信息的作用,并不将机器人逻辑写在这个机器人客户端里面,把机器人逻辑写到一个WebService中。一方面你可以用你最擅长的语言来开发WebService;一方面,如果你需要多种平台的机器人(MSN机器人等)这部分的逻辑是可以公用的,而不需再次去开发测试这部分。
代码部分
关于LumaQQ接口开发机器人,网上已经有很多的代码了,我也是从网上直接拷贝的代码下来的。最关键的代码有以下两部分:
CODE 1:设置参数,登录代码
1: private void connect()
2: {
3: try
4: {
5: client = new QQClient();
6: client.addQQListener(this);
7: client.setConnectionPoolFactory(new PortGateFactory());
8: user = new QQUser(739330764, "qqrobot");
9: user.setStatus(QQ.QQ_LOGIN_MODE_NORMAL);
10:
11: client.setUser(user);
12: //TCP登录
13: user.setUdp(false);
14: client.setTcpLoginPort(8000);
15: client.setLoginServer("219.133.48.103");
16: //UDP登录
17: //user.setUdp(true);
18: //clent.setLoginServer("sz.tencent.com");
19:
20: //client.setProxyType("Socks5");
21: // client.setProxy(new InetSocketAddress("AF25",1080));
22:
23: client.login();
24: }
25: catch (Exception ex)
26: {
27: ex.printStackTrace();
28: //client.release();
29: }
30: }
这部分代码里面提供了两种方式:TCP和UDP来登录到服务器。大家都知道QQ直接这两种方式的登录,但是需要使用不同的服务器地址。
CDOE 2:事件处理代码
1: public void qqEvent(QQEvent e)
2: {
3: switch (e.type)
4: {
5: case QQEvent.QQ_LOGIN_SUCCESS:
6: msg("QQ_LOGIN_SUCCESS");
7: break;
8: case QQEvent.QQ_LOGIN_FAIL:
9: msg("QQ_LOGIN_FAIL");
10: msg("reconnect");
11: connect();
12: // client.release();
13: //System.exit(0);
14: break;
15: case QQEvent.QQ_LOGIN_UNKNOWN_ERROR:
16: msg("QQ_LOGIN_UNKNOWN_ERROR");
17: msg("reconnect");
18: connect();
19: // client.release();
20: //System.exit(0);
21: break;
22: case QQEvent.QQ_LOGIN_REDIRECT_NULL:
23: msg("QQ_LOGIN_REDIRECT_NULL");
24: msg("reconnect");
25: connect();
26: // client.release();
27: //System.exit(0);
28: break;
29: case QQEvent.QQ_CONNECTION_LOST:
30: msg("QQ_CONNECTION_LOST");
31: msg("reconnect");
32: connect();
33: // client.release();
34: //System.exit(0);
35: break;
36: case QQEvent.QQ_NETWORK_ERROR:
37: msg("QQ_NETWORK_ERROR");
38: msg("reconnect");
39: connect();
40: // client.release();
41: //System.exit(0);
42: break;
43: case QQEvent.QQ_CONNECTION_BROKEN:
44: msg("QQ_CONNECTION_BROKEN");
45: msg("reconnect");
46: connect();
47: // client.release();
48: //System.exit(0);
49: break;
50: case QQEvent.QQ_RECEIVE_TEMP_SESSION_IM:
51: SimpleDateFormat tempDate = new SimpleDateFormat("MM-dd HH:mm");
52: impacket = (ReceiveIMPacket) e.getSource();
53: qqnum = impacket.tempSessionIM.sender;
54: immsg = new String(impacket.tempSessionIM.message);
55: msg("["
56: + tempDate.format(new Date(impacket.tempSessionIM.time))
57: + "] " + qqnum + ":" + immsg);
58: addFriend(qqnum);
59: msg("临时回复");
60: client.sendIM(qqnum, Util.getBytes("对不起:" + impacket.tempSessionIM.nick + ",GK助手暂时还不支持临时会话,请先将我加为好友,然后在正常聊天窗体与我聊天,这样我才能帮助你。:)"));
61: break;
62: case QQEvent.QQ_RECEIVE_NORMAL_IM:// 收到正常消息�?
63: SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm");
64: impacket = (ReceiveIMPacket) e.getSource();
65: qqnum = impacket.normalHeader.sender;
66: immsg = new String(impacket.normalIM.messageBytes);
67: msg("["
68: + sdf.format(new Date(impacket.normalHeader.sendTime))
69: + "] " + qqnum + ":" + immsg);
70: if (impacket.normalIM.replyType != QQ.QQ_IM_AUTO_REPLY)
71: {
72: msg("好友:" + qqnum +"请求信息:" + immsg );
73: client.sendIM(qqnum, Util.getBytes(immsg));
74: }
75: //if (immsg.trim().equalsIgnoreCase("exit"))
76: // {
77: // System.out.println(qqnum + "命令你�退出");
78: // client.logout();
79: // client.release();
80: // System.exit(0);
81: // }
82: break;
83: case QQEvent.QQ_ADDED_BY_OTHERS:// 事件发生在有人将我加为好友时
84: case QQEvent.QQ_ADDED_BY_OTHERS_EX:// 事件发生在有人将我加为好友时
85: msg("QQ_ADDED_BY_OTHERS_EX");
86: snpacket = (SystemNotificationPacket) e.getSource();
87: qqnum = snpacket.from;
88: msg(qqnum + "把我加为了好友�?");
89: client.sendIM(qqnum, Util.getBytes("hello."));
90: break;
91: case QQEvent.QQ_REQUEST_ADD_ME:// 事件发生在有人请求加我为好友�?
92: case QQEvent.QQ_REQUEST_ADD_ME_EX:// 事件发生在有人请求加我为好友�?
93: msg("QQ_REQUEST_ADD_ME_EX");
94: snpacket = (SystemNotificationPacket) e.ge