机器人使用LumaQQ来开发QQ机器人

lumaqq  时间:2021-02-14  阅读:()

使用LumaQQ来开发QQ机器人

文章分类:Java编程

自从博客园闪存发布了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接口开发机器人 网上已经有很多的代码了我也是从网上直接拷贝的代码下来的。最关键的代码有以下两部分

C ODE 1设置参数登录代码

自从博客园闪存发布了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接口开发机器人 网上已经有很多的代码了我也是从网上直接拷贝的代码下来的。最关键的代码有以下两部分

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() ;&lt;br> 53: qqnum = impacket. tempSessionIM. sender;<br&gt; 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() ;&lt;br> 65: qqnum = impacket.normalHeader. sender;<br&gt; 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)&lt;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() ;&lt;br> 87: qqnum = snpacket.from;<br&gt; 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&gt; 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() ;&lt;br> 102: qqnum = packet.friendQQ;<br&gt; 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() ;&lt;br> 113: msg(snpacket.from<br> 114:

+ "拒绝加我为好友?理由为

"<br> 115: + ( (snpacket.message == null | |

snpacket.message&lt;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_IMe.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工程文件

图六 引用的第三方包

HostWebis:美国/法国便宜服务器,100Mbps不限流量,高配置大硬盘,$44/月起

hostwebis怎么样?hostwebis昨天在webhosting发布了几款美国高配置大硬盘机器,但报价需要联系客服。看了下该商家的其它产品,发现几款美国服务器、法国服务器还比较实惠,100Mbps不限流量,高配置大硬盘,$44/月起,有兴趣的可以关注一下。HostWebis是一家国外主机品牌,官网宣称1998年就成立了,根据目标市场的不同,以不同品牌名称提供网络托管服务。2003年,通过与W...

ZJI(月付450元),香港华为云线路服务器、E3服务器起

ZJI发布了9月份促销信息,针对香港华为云线路物理服务器华为一型提供立减300元优惠码,优惠后香港华为一型月付仅450元起。ZJI是原来Wordpress圈知名主机商家:维翔主机,成立于2011年,2018年9月更名为ZJI,提供中国香港、台湾、日本、美国独立服务器(自营/数据中心直营)租用及VDS、虚拟主机空间、域名注册等业务,商家所选数据中心均为国内访问质量高的机房和线路,比如香港阿里云、华为...

vpsdime:VPS内存/2核/VPS,4G内存/2核/50gSSD/2T流量/达拉斯机房达拉斯机房,新产品系列-Windows VPS

vpsdime上了新产品系列-Windows VPS,配置依旧很高但是价格依旧是走低端线路。或许vpsdime的母公司Nodisto IT想把核心产品集中到vpsdime上吧,当然这只是站长个人的猜测,毕竟winity.io也是专业卖Windows vps的,而且也是他们自己的品牌。vpsdime是一家新上来不久的奇葩VPS提供商,实际是和backupspy以及crowncloud等都是同一家公司...

lumaqq为你推荐
解压程序什么解压软件最好,速度最快最稳定云播怎么看片手机云播怎么用?eset最新用户名密码求ESET Smart Security最新用户名和密码公章制作如何用photoshop制作公章数码资源网哪个网站可以直接在线做照片?功能要齐全的`ejb开发什么是EJB?它是干什么的?和JAVA,JSP有关系吗?他们各有什么特点和用途?mate8价格现在买华为mate8高配划算吗srv记录如何验证是否为域控制器创建了 SRV DNS 记录虚拟机软件下载谁有好用的虚拟机软件?网站优化方案网站建设及优化的方案
虚拟主机提供商 哈尔滨服务器租用 万网域名空间 域名服务器的作用 rackspace 外国域名 线路工具 dropbox网盘 合肥鹏博士 三拼域名 e蜗牛 网站卫士 isp服务商 万网空间管理 西安服务器托管 贵阳电信 云服务是什么意思 阿里云邮箱个人版 server2008 西部主机 更多