zoukankan      html  css  js  c++  java
  • QQ机器人(转贴)

    这个元旦假期过的比较奇怪,为了向远方的GF表示忠诚。除了1号和同学吃了个大锅饭之外,尽量做到了大门不出二门不迈,躲在闺房守岁:)。
         在家闲着也不能干闲着,总得做点事情,想起前段时间一个师兄交代给我的任务:把若干个qq群串在一起。X国的政策一向比较Bt,你说开个群还要限制人数。H大在深圳有几千校友,一个群怎么可能放的下那么多人。好多在tx工作的师兄,明确告诉:我买通tx的人是不大可能了,搞一个传话筒才是解决之道。
           事情虽小,但也着实麻烦。你说要去分析QQ具体数据包,万一哪天tx一高兴把数据给改了,或者接口开放了,也够我郁闷一壶的了。那就找个最简单的办法吧,左一顿baidu,又一顿google. “QQ接口”搜出来的结果绝大多数是关于tx qq的http接口,既然大家那么推崇,那我就从Http接口下手,于是把我以前写的AJAX给拆了,在把所谓的qq接口研究成果给鼓捣在一起,然后去webqq(http://webqq.qq.com)上大抢一遍,那家伙,天昏地暗,相当的&(&(。
          代码我是用script写的:
    1//异步AJAX会话类
      2if(typeof(AjaxSession) == 'undefined')
      3var AjaxSession 
    = function(){
      
    4    
      
    5    //创建会话
      6    this.CreateSession = function()
      
    7    {
      
    8        if (window.ActiveXObject){  // IE
      9            try{    
     
    10                return new ActiveXObject('Microsoft.XMLHTTP');
     
    11            }
    catch(e){}
     
    12                
     
    13            try
     
    14                return new ActiveXObject('Msxml2.XMLHTTP');
     
    15            }
    catch(ee){}
     
    16        }
    else{                   //Mozilla, Safari
     17            var s = new XMLHttpRequest(); 
     
    18            if (s.readyState == null{
     
    19                s.readyState = 1;
     
    20                s.addEventListener("load", function () {
     
    21                    s.readyState = 4;
     
    22                    if (typeof(s.onreadystatechange) == "function")
     
    23                        s.onreadystatechange();
     
    24                }
    false);
     
    25            }

     
    26            
     
    27            return s;
     
    28        }

     
    29                    
     
    30        return null;
     
    31    }

     
    32    
     
    33    //进行请求
     34    this.Request = function(url, params, callback)
     
    35    {    
     
    36        
     
    37        var s = this.CreateSession();
     
    38        if(null == s)
     
    39            alert("对不起,您的浏览器不支持某些特性。");
     
    40        else
     
    41            s.abort();
     
    42        
     
    43        var isAsync =  typeof(callback) == 'function';
     
    44        var method = !params ? "GET" : "POST";
     
    45
     
    46        if(isAsync) s.onreadystatechange = function()
     
    47        {
     
    48            try{
     
    49                alert(s.status);
     
    50                if ((4 == s.readyState) && (200 == s.status || 304 == s.status))
     
    51                    callback(this.Response(s));
     
    52                else
     
    53                    alert("请求错误,错误原因:" + s.statusText);    
     
    54            }
    catch(e){}
     
    55        }

     
    56                
     
    57        s.open(method, url, isAsync);        
     
    58        s.setRequestHeader("Connection","Keep-Alive");        
     
    59        s.setRequestHeader("Content-Type","text/html; charset=gb2312");
     
    60        //s.setRequestHeader("Content-Type","text/plain; charset=UTF-8");
     61        
     
    62        if(method == "POST")
     
    63        {
     
    64            s.setRequestHeader("Content-Length",params.length)
     
    65            s.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
     
    66            
     
    67        }

     
    68
     
    69        alert(params);
     
    70        s.send(params);
     
    71        
     
    72            
     
    73        if(!isAsync)
     
    74            return  this.Response(s);
     
    75    }

     
    76    
     
    77    //返回应答信息
     78    this.Response = function(s)
     
    79    {
     
    80        if(s.status == 200  || 304 == s.status)
     
    81        {
     
    82            if(s.responseXML != null && s.responseXML.xml != null && s.responseXML.xml != '')
     
    83                return s.responseXML;
     
    84            else
     
    85                return s.responseText;
     
    86        }
        
     
    87    }

     
    88    
     
    89    //对字符串进行编码
     90    this.UncCoding = function(s) 
     
    91    {
     
    92        var output = '';
     
    93        for(var i = 0 ;i< s.length;i++){
     
    94            output = output + '%' + s.charCodeAt(i);
     
    95        }
            
     
    96
     
    97        return output; 
     
    98    }

     
    99
    100    //获取xml结构
    101    this.GetDom = function(s){
    102        var doc = new ActiveXObject('Microsoft.XMLDOM'); 
    103        doc.async = false;
    104        doc.loadXML(s) ;    
    105        return doc;
    106    }
     
    107    
    108    return this;
    109}


     1//会话类
     2if(typeof(QQSession) == 'undefined')
     3var QQSession 
    = function(){
     
    4    this.UIN = 0;
     
    5    this.Md5PasswordStr = "";
     
    6    this.WebQQUrl = "http://tqq.tencent.com:8000/";
     
    7    this.qs = null;    
     
    8    this.isLogin = false
     
    9    this.SeqIndex = null;
    10    
    11    //用户登陆
    12    this.Login = function(uin,passwd,vcode,qs){
    13        var m5 = new MD5();        
    14        this.UIN = uin;        
    15        this.Md5PasswordStr = m5.calcMD5(passwd);
    16        var CmdStr = "VER=1.0&CMD=1&SEQ=" + this.GetNewSEQ() + "&UIN=" + uin + "&PS=" + this.Md5PasswordStr + "&STATUS=10&VCODE=" + vcode + "&QQSESSION=" + qs ;    
    17        
    18        //if(!this.qs)
    19        //    this.qs = new AjaxSession();
    20        window.frames["proxy"].request(this.WebQQUrl,CmdStr);
    21        //this.qs.Request(this.WebQQUrl,CmdStr,this.ShowMsg);
    22        
    23        //document.getElementById("ssl_login").callback = this.ShowMsg;
    24        //document.getElementById("ssl_login").src = "https://webqq-proxy.qq.com/webqq/l?"+ CmdStr;
    25    }

    26    
    27    //用户信息
    28    this.GetInfo = function(){
    29        var CmdStr = "VER=1.0&CMD=10&SEQ=" + this.GetNewSEQ() + "&UIN=" + this.UIN + "&FUIN=" + this.UIN;
    30        this.qs.Request(this.WebQQUrl,CmdStr,this.ShowMsg);    
    31        //window.frames["proxy"].request(this.WebQQUrl,CmdStr);
    32    }

    33    
    34    //获取好友列表
    35    this.GetList = function(){
    36        var CmdStr = "VER=1.0&CMD=2&SEQ=" + this.GetNewSEQ() + "&UIN=" + this.UIN + "&NPOS=0";
    37        this.qs.Request(this.WebQQUrl,CmdStr,this.ShowMsg);    
    38    }

    39    
    40    //获得新的SEQ
    41    this.GetNewSEQ = function(){
    42        if(!this.SeqIndex){
    43            var d = new Date();
    44            this.SeqIndex = d.getTime()
    45        }

    46        
    47        this.SeqIndex ++;
    48        return this.SeqIndex;        
    49    }

    50    
    51    this.ShowMsg = function(s){
    52        alert(s);
    53    }

    54    
    55    return this;
    56}

        我在那用天真的眼神,盼望着能从这个地方掏出点东西来。可偏偏我这个比较倒霉的孩子,碰到了极其复杂的网络问题(家穷人丑,只好用手机上网,速度回到上世纪90年代),掏了半天啥也没弄到,返回的尽是12152错误。
         去翻MSDN时,遇到几个头疼的单词(鄙人英语着实差劲,单词量屈指可数),很习惯的就去开金山词霸。等等,金山词霸能把别的窗口的信息给拽出来,为什么我就不能。于是我就抛弃了前面的工作,从QQ对话窗口下手。nndx,偶就不信了,偶还灭不了你。
      说干就干,那就先勾吧,.net好象是干不了这事,但是winapi还是能干这活的。win32编程嘛,不就几个消息循环(—(—……*(—
      
      1using System;
      2
    using System.Drawing;
      3
    using System.Runtime.InteropServices;
      
    4
      5
    namespace TQQ
      
    6{
      
    7    /**//// <summary>
      8    /// WinApi调用
      9    /// </summary>
     10    public class WinApi
     
    11    {
     
    12        /**//// <summary>
     13        /// 根据鼠标位置获取窗体
     14        /// </summary>
     15        /// <param name="lpPoint"></param>
     16        /// <returns></returns>
     17        [DllImport("user32.dll")]
     
    18        public static extern IntPtr WindowFromPoint(Point lpPoint);
     
    19
     
    20        /**//// <summary>
     21        /// 获取鼠标位置
     22        /// </summary>
     23        /// <param name="lpPoint"></param>
     24        /// <returns></returns>
     25        [DllImport("user32.dll")]
     
    26        public static extern int GetCursorPos(out Point lpPoint);
     
    27
     
    28        /**//// <summary>
     29        /// 获取鼠标位置下的窗体
     30        /// </summary>
     31        /// <returns></returns>
     32        public static IntPtr GetLocalWindow()
     
    33        {
     
    34            Point point;
     
    35            GetCursorPos(out point);
     
    36            return WindowFromPoint(point);
     
    37        }

     
    38
     
    39        /**//// <summary>
     40        /// 申请内存空间
     41        /// </summary>
     42        /// <param name="hProcess"></param>
     43        /// <param name="lpAddress"></param>
     44        /// <param name="dwSize"></param>
     45        /// <param name="flAllocationType"></param>
     46        /// <param name="flProtect"></param>
     47        /// <returns></returns>
     48        [ DllImport( "Kernel32.dll" )]
     
    49        public static extern Int32 VirtualAllocEx(IntPtr hProcess,Int32 lpAddress,Int32 dwSize,Int16 flAllocationType,Int16 flProtect);
     
    50
     
    51        /**//// <summary>
     52        /// 读取内存空间
     53        /// </summary>
     54        /// <param name="hProcess"></param>
     55        /// <param name="lpBaseAddress"></param>
     56        /// <param name="lpBuffer"></param>
     57        /// <param name="nSize"></param>
     58        /// <param name="lpNumberOfBytesWritten"></param>
     59        /// <returns></returns>
     60        [ DllImport( "Kernel32.dll" )]
     
    61        public static extern int ReadProcessMemory(IntPtr hProcess, Int32 lpBaseAddress,byte[] lpBuffer,long nSize,long lpNumberOfBytesWritten);
     
    62
     
    63        /**//// <summary>
     64        /// 写内存空间
     65        /// </summary>
     66        /// <param name="hProcess"></param>
     67        /// <param name="lpBaseAddress"></param>
     68        /// <param name="lpBuffer"></param>
     69        /// <param name="nSize"></param>
     70        /// <param name="lpNumberOfBytesWritten"></param>
     71        /// <returns></returns>
     72        [ DllImport( "Kernel32.dll" )]
     
    73        public static extern int WriteProcessMemory(IntPtr hProcess, Int32 lpBaseAddress,byte[] lpBuffer,long nSize,long lpNumberOfBytesWritten);
     
    74
     
    75        /**//// <summary>
     76        /// 根据类/标题查找窗口
     77        /// </summary>
     78        /// <param name="lpClassName"></param>
     79        /// <param name="lpWindowName"></param>
     80        /// <returns></returns>
     81        [DllImport("User32.dll",EntryPoint="FindWindow")]
     
    82        public static extern IntPtr FindWindow(string lpClassName,string lpWindowName);
     
    83
     
    84        /**//// <summary>
     85        /// 获取窗口子对象
     86        /// </summary>
     87        /// <param name="hwndParent"></param>
     88        /// <param name="hwndChildAfter"></param>
     89        /// <param name="lpszClass"></param>
     90        /// <param name="lpszWindow"></param>
     91        /// <returns></returns>
     92        [DllImport("user32.dll",EntryPoint="FindWindowEx")]
     
    93        public static extern IntPtr FindWindowEx(IntPtr hwndParent,IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
     
    94
     
    95        /**//// <summary>
     96        /// 发送windows消息
     97        /// </summary>
     98        /// <param name="hWnd"></param>
     99        /// <param name="Msg"></param>
    100        /// <param name="wParam"></param>
    101        /// <param name="lParam"></param>
    102        /// <returns></returns>
    103        [DllImport("User32.dll")]
    104        public static extern IntPtr SendMessage(IntPtr hWnd,int Msg,IntPtr wParam,IntPtr lParam);
    105
    106        /**//// <summary>
    107        /// 发送windows消息
    108        /// </summary>
    109        /// <param name="hWnd"></param>
    110        /// <param name="Msg"></param>
    111        /// <param name="wParam"></param>
    112        /// <param name="lParam"></param>
    113        /// <returns></returns>
    114        [DllImport("User32.dll",EntryPoint="SendMessage")]
    115        public static extern int SendMessage(IntPtr hWnd,int Msg, IntPtr wParam, string lParam);
    116
    117        /**//// <summary>
    118        /// 发送windows消息
    119        /// </summary>
    120        /// <param name="hwnd"></param>
    121        /// <param name="wMsg"></param>
    122        /// <param name="wParam"></param>
    123        /// <param name="lParam"></param>
    124        /// <returns></returns>
    125        [DllImport("user32.dll", CharSet = CharSet.Auto)]
    126        public static extern int SendMessage( IntPtr hwnd, int wMsg, int wParam,string lParam);
    127
    128        /**//// <summary>
    129        /// 发送windows消息
    130        /// </summary>
    131        /// <param name="hwnd"></param>
    132        /// <param name="wMsg"></param>
    133        /// <param name="wParam"></param>
    134        /// <param name="lParam"></param>
    135        /// <returns></returns>
    136        [DllImport("user32.dll", CharSet = CharSet.Auto)]
    137        public static extern int SendMessage( IntPtr hwnd, int wMsg, int wParam,int lParam);
    138
    139        /**//// <summary>
    140        /// 发送windows消息
    141        /// </summary>
    142        /// <param name="hwnd"></param>
    143        /// <param name="wMsg"></param>
    144        /// <param name="wParam"></param>
    145        /// <param name="lParam"></param>
    146        /// <returns></returns>
    147        [DllImport("user32.dll", CharSet = CharSet.Auto)]
    148        public static extern int SendMessage( IntPtr hwnd, int wMsg, int wParam,System.Text.StringBuilder lParam);
    149
    150        public const int WM_GETTEXT = 0x000D;
    151        public const int WM_GETTEXTLENGTH = 0x000E;
    152        public const int WM_SETTEXT = 0x000C;
    153        public const int WM_CLICK = 0x00F5;
    154        public const int WM_CHAR = 0x0102;
    155        public const int EM_SETSEL = 0x00B1;
    156        public const int EM_REPLACESEL = 0x00C2;
    157
    158    }

    159}

    东西到手了,传话筒的工作基本上算是完成了,接下来就让它显示出来:

     1    /**//// <summary>
     2        /// 时钟事件
     3        /// </summary>
     4        /// <param name="sender"></param>
     5        /// <param name="e"></param>
     6        private void tmGetMsg_Tick(object sender, System.EventArgs e)
     
    7        {
     
    8            //群1里的消息
     9            string strMsg = QQHooks.GetMsg(txtGroupWinName1.Text);        
    10            string str = "";
    11            
    12            if(!string.Empty.Equals(strMsg))
    13            {
    14                ArrayList msgList = ParseMsg.Parse(strMsg);
    15
    16                foreach(QQMsg msg in msgList)
    17                {
    18                    if("253822559" == msg.Number.ToString())continue;
    19                    
    20                    if(string.Empty.Equals(msg.Msg.Trim()))
    21                        str =  string.Format("{0}在群1里做了个表情\r\n",msg.Name,msg.Msg);
    22                    else
    23                         str =  string.Format("{0}在群1里说:\r\n{1}\r\n",msg.Name,msg.Msg);
    24                    
    25                    lbGroupMsgList1.Items.Add(str);
    26                    //save msg 
    27                    
    28                    //发送消息
    29                    QQHooks.SendMsg(txtGroupWinName2.Text,str);
    30                    QQHooks.SendMsg(txtGroupWinName3.Text,str);
    31                    
    32                }
                    
    33            }

    34  }

    这里的txtGroupWinName1是让输入qq窗口标题。以前用asm32做程序的时候就觉的微软够BT的,要是每个窗口编译的时候就给限制个GUID多好—()—*)((—
    至此大功算是告成了,完美交差。拿着这东东,改天狠狠的宰我师兄几顿.

    (07-01-04)续:
    要的人太多了,我还是主动把东西传上来吧,要不然有骗 email地址之嫌
    源代码和相关资料下载:/Files/sukyboor/Q.rar

    附,说明:先介绍一下http方法:
     1,qq接口.txt
       是我在网络上找的一篇“C#编写QQ接口软件--QQ协议篇” 里面有QQhttp协议访问的详细的介绍,协议标准是v1.1。但是经过我是没调通,好象是http://tqq.tencent.com:8000被封了,你有没有好的运气我就不知道了。tx的webqq用的端口是http://webqq-proxy.qq.com:8080/这个就是慢点,用还是能用的。
     2,Maxthon_Appin 文件夹下面有2个文件QQTest.txt ,GetQQSession.txt。maxthon有个简易收集面板你可以动态的去调试脚本.用maxthon打开http://webqq.qq.com后装入qqtest.txt你会发现访问过程的一举一动都在你的监视之中。Log.txt就是这么来的。GetQQSession.txt操作同上,用于获取一个新的sessionid
     3,log.txt是监视http://webqq.qq.com的访问过程后得来的.你可以参考qq接口.txt看。不过tx的webqq用的是v1.0的接口,但大体上是相似的,相信聪明的你是可以看懂的。
      4,webqq文件夹下放着http://webqq.qq.com被我下到本地的页面。有兴趣的可以去看看里面的脚本,尤其是js\web_cmd.js虽然写的比我还烂,但还是值得一看。
     5,WQQ文件夹下放着我写的测试页面。不过我家的破电脑调不通。如果你运气好的话,在这个基础上继续干吧。不过别忘记了,到时候把做好的东西发给我一份(sukyboor·163.com)。
    好了,下面说说钩子方法
      项目在TQQ文件夹下面,注释写的挺详细的,自己看吧。
    就提醒4点,
     1 是app.config里面的qqnum一定要配置成你的qq号,否则你就等着别人骂你sx吧。
     2 主窗口上的几个输入框一定要配置成群聊窗口的标题,否则它啥也干不了
    3 别告诉我你还用qq2005
     4 消息被转发以后在窗口里是看不到的,得点聊天记录按纽以后才能看的见
     
    license.txt
      里面堆的是一堆套话,有空就瞅2眼.
  • 相关阅读:
    十道海量数据处理面试题与十个方法大总结[转]
    Velocity常用语法详解
    你选择哪一种方式创建线程?
    通俗易懂地讲解TCP建立连接的三次握手和释放连接的四次挥手
    由浅入深的理解网络编程【转】
    [转载]OSI七层模型详解
    简单谈谈数据库索引
    【HBase】 常用命令
    【HBase】知识小结+HMaster选举、故障恢复、读写流程
    【HBase】HBase架构中各种组件的作用
  • 原文地址:https://www.cnblogs.com/shf/p/806707.html
Copyright © 2011-2022 走看看