自从博客园闪存发布了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 :          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:事件处理代码

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>  28:             break;<br>  29:         case QQEvent.QQ_CONNECTION_LOST:<br>  30:             msg("QQ_CONNECTION_LOST");<br>  31:             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的了解也不够多。下面再来介绍一下Eclipse的打包吧,这也是一个比较麻烦的地方,没有同事的帮忙我也是一时半会 儿也搞不定。 

编译,打包部分

  同事给我的是装有ObjectWeb Lomboz插件的eclipse,我还必须要说明一下,我的eclipse目录是在:D:\Program Files\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工程文件

图六:引用的第三方包

图七:编译中

  经过这一系列的步骤后,你所得到的exe文件,就是一个可用的控制台程序了。这时候除了JRE外,不需要其它的插件的支持了。

写在最后

  做为一个.NET平台的开发人员,以上的步骤对我们来说确实是太过于烦杂了。在寒冬季节我写这样的一篇文章都快要满头大汗了,我相信各位看官如 果能坚持看到这里那么你一定是非常有耐力了。但是没有办法,我们需要忍受。如果有时间,有精力,我还是很愿意以LumaQQ为样本,开发一个开源的QQ开 发包,这样大家就不用再这么麻烦了。

分代码里面提供了两种方式:TCP和UDP来登录到服务器 。大家都知道QQ直接这两种方式的登录,但是需要使用不同的服务器地址。

CDOE 2:事件处理代码

大家看到了LumaQQ里面的事件处理看起来似乎比较原始了一点。但是没关系,它是确实可用的。LumaQQ里面支持的QQ事件协议 都 在QQEvent中已经有定义了,同时不同的事件,它的事件参数e.getSource()都是不同类型的对象。比如接收到正常消息,它的事件枚举是 QQEvent.QQ_RECEIVE_NORMAL_IM,e.getSource()的类型是ReceiveIMPacket.你把这个对象转换成 ReceiveIMPacket类型后,就可以得知是谁发送的什么样的消息了。这时候你就可以调用client.sendIM方法来回复消息了。至于回复 什么,就是你的机器人要做的事件了,它里可以调用WebService,也可以把业务逻辑直接写在这边。

  还有就是断点重连,LumaQQ已经可以保证长时间在线了。但是我们也要有断线重连的功能,这个在例子中也已经有了。还有其它的事件和接口我就 不详细介绍了,因为我个人对JAVA的了解也不够多。下面再来介绍一下Eclipse的打包吧,这也是一个比较麻烦的地方,没有同事的帮忙我也是一时半会 儿也搞不定。 

编译,打包部分

  同事给我的是装有ObjectWeb Lomboz插件的eclipse,我还必须要说明一下,我的eclipse目录是在:D:\Program Files\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工程文件

图六:引用的第三方包

图七:编译中

  经过这一系列的步骤后,你所得到的exe文件,就是一个可用的控制台程序了。这时候除了JRE外,不需要其它的插件的支持了。

写在最后

  做为一个.NET平台的开发人员,以上的步骤对我们来说确实是太过于烦杂了。在寒冬季节我写这样的一篇文章都快要满头大汗了,我相信各位看官如 果能坚持看到这里那么你一定是非常有耐力了。但是没有办法,我们需要忍受。如果有时间,有精力,我还是很愿意以LumaQQ为样本,开发一个开源的QQ开 发包,这样大家就不用再这么麻烦了。

转自:http://blog.csdn.net/lynnlin1122/archive/2008/06/02/2504504.aspx

使用LumaQQ来开发QQ机器人相关推荐

  1. 酷q插件开发Java_如何使用Java开发QQ机器人 方法一

    使用Java开发QQ机器人- CQ & HTTP API 使用库Q平台下的CQ HTTP API插件以及simple-robot核心标准库作为依赖. 此插件与框架的 简陋 简单介绍:文档处简介 ...

  2. 使用酷Q SDK开发QQ机器人

    酷Q SDK下载地址:https://github.com/CoolQ/cqsdk-vc 打开工程,编辑appmain.cpp 将"私聊消息"处的代码 更改为 CQEVENT(in ...

  3. 基于Go-cqhttp和python开发QQ机器人

    第一步,下载go-cqhttp 网址:https://github.com/Mrs4s/go-cqhttp/releases 根据自己电脑的配置下载相应的压缩包(因为压缩包下载快一些),我下载的是wi ...

  4. 基于chatgpt开发QQ机器人

    格言:自立才能自主,靠人更须靠己.有志之人立长志,无志之人常立志.千里之行,始于足下:艰难困苦,玉汝于成.少壮不努力,老大徒伤悲.✊✊✊

  5. 开发 mirai QQ机器人起步教程

    前言 虽然该文最终是达到以python开发mirai机器人的目的,但起步教程,尤其是环境配置上仍然有大量的相同操作,对其他编程语言仍有借鉴之处 假设你已经安装好了 Java.Python等运行必须的环 ...

  6. PHP开发基于Mirai的QQ机器人

    博客和更新地址:PHP开发基于Mirai的QQ机器人 前言 在完成配置开源安卓QQ协议库Mirai后,便可使用已有开源项目来部署自己的QQ机器人,但自行开发显然更符合需求.借助mirai-api-ht ...

  7. 记一次python,QQ机器人开发(入门)

    由于网页版qq已经没了,所以开发网页版qq机器人不可能了 但这样丝毫不影响我们开发QQ机器人 可以用酷q来进行开发 酷q现在不能下载了,大家自行百度,不提供链接 这里用的模块是 nonebot 具体安 ...

  8. 基于SpringBoot实现QQ机器人

    本QQ机器人实现的功能 1.输入关机,进入30秒倒计时关机 2.输入锁屏,电脑自动进行锁屏操作 3.输入取消关机,即可取消关机指令 4.调用青云客的API进行自动聊天 5.输入关键词自动添加为好友 技 ...

  9. 腾讯严打第三方QQ机器人:多家QQ机器人暂停服务

    近日,腾讯突然跟第三方QQ机器人干上了,其中晨风机器人作者被起诉并且跨省传唤,一时间,圈内十几家QQ机器人全部宣布暂停服务! 了解到,QQ机器人其实就是围绕QQ开发的一些插件,可以提供 自动回复,群管 ...

最新文章

  1. 《机器学习Python实践》——数据导入(CSV)
  2. 官方解读,谷歌“T5”模型,如何突破迁移学习局限,实现多基准测试SOTA
  3. JavaScript中匿名函数的作用和用法
  4. MySql项目中使用的小窍门
  5. SAP Spartacus pop over 元素的单元测试
  6. javafx 自定义控件_JavaFX自定义控件– Nest Thermostat第2部分
  7. 数据结构之栈的应用:树的层次遍历、图的广度优先遍历、OS的FCFS策略
  8. CenOS下安装Eclipse并配置PyDev
  9. Android 系统(247)---Android Go项目, Launcher no Notification Dots
  10. Android 蓝牙技术 实现终端间数据传输
  11. php 辅助函数,辅助函数 - Laravel 5.8 中文文档手册 - php中文网手册
  12. MSYS2 的安装与使用
  13. 人人商城源码怎么安装MySQL_人人商城12个常见错误解决方案
  14. android配置网络权限管理,Android 网络权限配置
  15. 程序员记录之人性弱点
  16. 如何解决 zsh: event not found: e]st1问题
  17. 压缩包修改所属目录Linux,LINUX 压缩、解压、打包文件 修改文件所属组
  18. 【软件下载】Excel下载 word下载 官方 官网下载 原始镜像 开发工具 开发软件下载
  19. 设计模式----创建型设计模式(单例模式、工厂方法模式、构建者模式)
  20. 妙用Java 8中的 Function接口 消灭if...else...

热门文章

  1. 苹果太狠了:升级iOS 8小心变砖
  2. Linux中ssh登录跳过RSA key fingerprint输入yes/no
  3. ProgressBar.js – 漂亮的响应式 SVG 进度条
  4. 10个顶尖响应式HTML5网页
  5. 蓝桥杯python组——猜生日
  6. Memcached快递上手之C#
  7. dwz导出excel java_dwz怎么导出excel
  8. 2016年最新高效的60个网络推广方法汇总
  9. IDEA默认JDK版本号变成11了
  10. Android常用技巧总结