小艾的幸福生活

我们都在自己的路上追逐梦想......

[ZT]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;
  2using System.Drawing;
  3using System.Runtime.InteropServices;
  4
  5namespace 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