使用LumaQQ来开发QQ机器人
文章分类:Java编程
自从博客园闪存发布了QQ机器人以后 闪存数量一下子就上升了很多。很多人也一直都在询问QQ机器人是如何开发的这足以说明QQ在中国不仅仅是普通人使用的IM工具在程序员圈子里也相当有人缘的其老大地位不容怀疑啊。我这篇也算是给解答一些朋友的疑惑吧。
所谓的IM机器人QQMSN 其实就是一个简化版的IM客户端QQMSN 。利用这个简单的客户端连接到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接口开发机器人 网上已经有很多的代码了我也是从网上直接拷贝的代码下来的。最关键的代码有以下两部分
C ODE 1设置参数登录代码
自从博客园闪存发布了QQ机器人以后 闪存数量一下子就上升了很多。很多人也一直都在询问QQ机器人是如何开发的这足以说明QQ在中国不仅仅是普通人使用的IM工具在程序员圈子里也相当有人缘的其老大地位不容怀疑啊。我这篇也算是给解答一些朋友的疑惑吧。
所谓的IM机器人QQMSN 其实就是一个简化版的IM客户端QQMSN 。利用这个简单的客户端连接到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接口开发机器人 网上已经有很多的代码了我也是从网上直接拷贝的代码下来的。最关键的代码有以下两部分
C ODE 1设置参数登录代码view plain copy to clipboard print ?
1. 1 : private void connect() 2 : { 3 : try
4 : { 5 : client = new QQClient() ; 6
: client.addQQListener( this ) ; 7 : clien
t. 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. 1
33.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事件处理代码view plain copy to clipboard print ?
1. 1 : public void qqEvent(QQEvent e)<br> 2 : {<br> 3 :switch (e. type)<br> 4 : {<br> 5 : case
QQEvent.QQ_LOGIN_SUCCESS:<br> 6 : msg( "QQ_LOGIN_SUCCESS" ) ;<br> 7 : break ;<br> 8 :case QQEvent.QQ_LOGIN_FAIL:<br> 9 : msg( "QQ_LOGIN_FAIL" ) ;<br> 10 : msg( "reconnect" ) ;<br>
11 : connect() ;<br> 12 : // client.release() ;<br> 13: //System. exit(0) ;<br> 14:break;<br> 15: case QQEvent.QQ_LOGIN_UNKNOWN_ERROR:<br> 16: msg("QQ_LOGIN_UNKNOWN_ERROR") ;<br>
17: msg("reconnect") ;<br> 18: connect() ;<br> 19: // client.release() ;<br> 20:
//System.exit(0) ;<br> 21 : break;<br> 22:case QQEvent.QQ_LOGIN_REDIRECT_NULL:<br> 23:msg("QQ_LOGIN_REDIRECT_NULL") ;<br> 24: msg("reconnect") ;<br> 25: connect() ;<br> 26: //client.release() ;<br> 27: //System. exit(0) ;<br> 2
8: break;<br> 29: case QQEvent.QQ_CONNECTION_LOST:<br> 30: msg("QQ_CONNECTION_LOST") ;<br> 3
1: msg("reconnect") ;<br> 32: connect();<br> 33: // client.release() ;<br> 34:
//System.exit(0) ;<br> 35: break;<br> 36:
case QQEvent.QQ_NETWORK_ERROR:<br> 37: msg("QQ_NETWORK_ERROR") ;<br> 38: msg("reconnect") ;<br> 39:connect() ;<br> 40: // client.release() ;<br> 41: //System. exit(0) ;<br> 42:break;<br> 43: case QQEvent.QQ_CONNECTION_BROKEN:<br>
44: msg("QQ_CONNECTION_BROKEN") ;<br> 45:msg("reconnect") ;<br> 46: connect() ;<br> 47:
// client.release() ;<br> 48: //System.exit(0) ;<br> 49: break;<br> 50: case QQEvent.QQ_RECEIVE_TEMP_SESSION_IM:<br> 51 : SimpleDateFormat tempDate = new SimpleDateFormat("MM-dd HH:mm") ;<br> 52: impacket = (ReceiveIMPacket) e.getSource() ;<br> 53: qqnum = impacket. tempSessionIM. sender;<br> 54: immsg = new String(impacket. tempSessionIM.message) ;& lt;br> 55: msg("
["<br> 56: + tempDate.format(new Date(impacket. tempSessionIM. time) )<br> 57: + "] " +qqnum + ":" + immsg) ;<br> 58: addFriend(qqnum) ;<br> 59: msg("临时回复
") ;<br> 60: client. sendIM(qqnum, Util.getBytes("对不起:" + impacket. tempSessionIM.nick + " GK助手暂时还不支持临时会话请先将我加为好友然后在正常聊天窗体与我聊天,这样我才能帮助
你。 : )") ) ;<br> 61 : break;<br> 62: case QQEvent.QQ_RECEIVE_NORMAL_IM://收到正常消息
?<br> 63: SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm") ;<br> 64: impacket = (ReceiveIMPacket) e.getSource() ;<br> 65: qqnum = impacket.normalHeader. sender;<br> 66: immsg = new String(impacket.normalIM.messageBytes) ;& lt;br> 67: msg("
["<br> 68: + sdf.format(new Date(impacket.normalHeader. sendTime) )<br> 69: + "] " + qqnum + ":" + immsg) ;<br> 70: if (impacket.normalIM.replyType != QQ.QQ_IM_AUTO_REPLY)<br> 71: {<br> 72: msg("好友:" + qqnum +"请求信
息:" + immsg ) ;<br> 73: client. sendIM(qqnum, Util.getBytes(immsg) ) ;<br> 74: }<br> 75:
//if (immsg. trim() .equalsIgnoreCase("exit") )<br> 76:
// {<br> 77: // System.out.println(qqnum +
"命令你退出
") ;<br> 78: // client. logout() ;<br> 79:
// client.release() ;<br> 80: // System.exit(0) ;<br> 81: // }<br> 82: break;<br> 83: case QQEvent.QQ_ADDED_BY_OTHERS: //事件发生在有人将我加为好友时
<br> 84: case QQEvent.QQ_ADDED_BY_OTHERS_EX://事件发生在有人将我加为好友时
<br> 85: msg("QQ_ADDED_BY_OTHERS_EX") ;<br> 86:snpacket = (SystemNotificationPacket) e.getSource() ;<br> 87: qqnum = snpacket.from;<br> 88: msg(qqnum + "把我加为了好友
?") ;<br> 89: client. sendIM(qqnum, Util.getBytes("hello. ") ) ;<br> 90: break;<br> 91 : case QQEvent.QQ_REQUEST_ADD_ME://事件发生在有人请求加我为好友?<br> 92: case QQEvent.QQ_REQUEST_ADD_ME_EX://事件发生在有人请求加我为好友
?<br> 93: msg("QQ_REQUEST_ADD_ME_EX") ;<br> 94:snpacket = (SystemNotificationPacket) e.getSource();& lt;br> 95: qqnum = snpacket.from;<br> 96: msg(qqnum + "想加我为好友
") ;// 1675103<br> 97: client.approveAddMe(qqnum);<br> 98: addFriend(qqnum) ;<br> 99: break;<br> 100: case QQEvent.QQ_ADD_FRIEND_NEED_AUTH:<br> 101: AddFriendExReplyPacket packet = (AddFriendExReplyPacket)e.getSource() ;<br> 102: qqnum = packet.friendQQ;<br> 103: sendAddFriendAuth(qqnum) ;<br> 104:break;<br> 105: case QQEvent.QQ_REQUEST_ADD_OTHER_APPROVED://事件发生在有人请求加我为好友时我同意并且加他为好友<br> 106: msg("QQ_REQUEST_ADD_OTHER_APPROVED") ;<br>
107: break;<br> 108: case QQEvent.QQ_REQUEST_ADD_OTHER_APPROVED_AND_ADD://事件发生在有人请求加我为好友时我同意并且加他为好友
<br> 109: msg("QQ_REQUEST_ADD_OTHER_APPROVED_AND_ADD") ;<br> 110: break;<br> 111 : case QQEvent.QQ_REQUEST_ADD_OTHER_REJECTED://事件发生在我请求加一个人那个人拒绝
?<br> 112: snpacket = (SystemNotificationPacket)e.getSource() ;<br> 113: msg(snpacket.from<br> 114:
+ "拒绝加我为好友?理由为
"<br> 115: + ( (snpacket.message == null | |
snpacket.message<br> 116: . equals("") ) ? "?" :snpacket.message) ) ;<br> 117: break;<br> 118:case QQEvent.QQ_KICKED_OUT_BY_SYSTEM:<br> 119: msg("QQ在别处登录了,重新登
录. ") ;<br> 120: connect() ;<br> 121 : break;<br> 122: default :<br> 123: msg(e. type) ;<br> 124: break;<br> 125: }<br> 126: }大家看到了LumaQQ里面的事件处理看起来似乎比较原始了一点。但是没关系它是确实可用的。 LumaQQ里面支持的QQ事件协议都在QQEvent中已经有定义了 同时不同的事件它的事件参数e.getSource 都是不同类型的对象。比如接收到正常消息它的事件枚举是QQEvent.QQ_RECEIVE_NORMAL_IMe.getSource 的类型是ReceiveIMPacket.你把这个对象转换成
ReceiveIMPacket类型后就可以得知是谁发送的什么样的消息了。这时候你就可以调用client. sendIM方法来回复消息了。至于回复什么就是你的机器人要做的事件了它里可以调用WebService也可以把业务逻辑直接写在这边。
还有就是断点重连 LumaQQ已经可以保证长时间在线了。但是我们也要有断线重连的功能这个在例子中也已经有了。还有其它的事件和接口我就不详细介绍了 因为我个人对JAVA的了解也不够多。下面再来介绍一下Ecl ipse的打包吧这也是一个比较麻烦的地方没有同事的帮忙我也是一时半会儿也搞不定。
编译打包部分
同事给我的是装有ObjectWeb Lomboz插件的eclipse我还必须要说明一下我的eclipse目录是在 D \ProgramFiles\ecplise 因为它有可能影响到一些包的引用和编译。它的启动界面是这样的
图一
大家下载完附件的示例代码后在文件菜单下点击"Switch Workspace"选择解压后的目录。就可以打开解决方案了工作空间里面会有三个工程LumaQQ是QQ协议工程 LumaQQ.net是LumaQQ负责网络连接部分的工程代码 robot是QQ机器人工程。如果你要在eclipse里面运行或调试机器人 点击QQRobot. java右键在菜单中选择RunAs或DebugAs Java Applcation就可以运行或调试了
图二
更多的调试技巧我就不多介绍了。下面来介绍打包吧。 eclipse要打包成控制台程序那也不是一件容易的事情。要先将这个解决方案导出成jar包 File--- Export选择Java 目录下的JAR File
图三
把三个工程都选择起来选择包存放的路径和包的文件名图四
一路Next或者直接Finish可能是弹出警告提示看不懂也不用管它。转到你刚才包的保存路径正常情况下你可以看到你刚才保存的文件名. jar这么一个文件。接下来的工作就是把这个jar打包成exe控制台程序了。这还得借助于另一个工具的帮忙我使用的是exe4j你从网络上去下载就可以了。不过它是共享软件非注册版本打包的exe在运行前会弹出一个提示告诉你是这个exe是用什么打包的。宣传一下有点讨厌。
打包exe需要创建exe4j的工程文件。还有一个麻烦的就是要指定它所引用的所有第三方包的路径而且设置输出路径版本运行环境等等这么信息。为了方便起见我也把这个文件放在附件的示例中了。安装了exe4j后就可以打开这个文件了打开了点击Finish就在编译了。
图五 exe4j工程文件
图六 引用的第三方包
提速啦的来历提速啦是 网站 本着“良心 便宜 稳定”的初衷 为小白用户避免被坑 由赣州王成璟网络科技有限公司旗下赣州提速啦网络科技有限公司运营 投资1000万人民币 在美国Cera 香港CTG 香港Cera 国内 杭州 宿迁 浙江 赣州 南昌 大连 辽宁 扬州 等地区建立数据中心 正规持有IDC ISP CDN 云牌照 公司。公司购买产品支持3天内退款 超过3天步退款政策。提速啦的市场定位提速啦主...
触碰云怎么样?触碰云是一家成立于2019年的商家。触碰云主营香港/美国 VPS服务器、独立服务器以及免备案CDN。采用的是kvm虚拟构架,硬盘Raid10,Cn2线路,去程电信CN2、移动联通直连,回程三网CN2。最低1核1G带宽1M仅20.8元/月,不过这里推荐香港4核4G15M,香港cn2 gia线路云服务器,仅115.2元/月起,性价比还是不错的。点击进入:触碰云官方网站地址触碰云优惠码:优...
Megalayer 商家我们还算是比较熟悉的,商家主要业务方向是CN2优化带宽、国际BGP和全向带宽的独立服务器和站群服务器,且后来也有增加云服务器(VPS主机)业务。这次中秋节促销活动期间,有发布促销活动,这次活动力度认为还是比较大的,有提供香港、美国、菲律宾的年付VPS主机,CN2优化方案线路的低至年付159元。这次活动截止到10月30日,如果我们有需要的话可以选择。第一、特价限量年付VPS主...