Posted on 2007-01-03 11:24
笨小苏 阅读(12559)
评论(67) 编辑 收藏 网摘
这个元旦假期过的比较奇怪,为了向远方的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写的:

异步AJAX会话类
1
//异步AJAX会话类
2
if(typeof(AjaxSession) == 'undefined')
3
var 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
}

//QQ会话类
1
//会话类
2
if(typeof(QQSession) == 'undefined')
3
var 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编程嘛,不就几个消息循环(—(—……*(—

WinApi调用
1
using 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