当前位置:编程学习 > C#/ASP.NET >>

用C#打造"QQ对战平台挤房器"

一、什么是“QQ对战平台挤房器”?

喜欢在“QQ对战平台”或“浩方对战平台”玩游戏的人都知道。平常平台上的房间基本很多都是人满的,如果想找个房间,那可是要费好长的时间来“挤”才能进去,如果是节假日或晚上,那更要花费更多的时间在“挤”房上了,如下图:

qq-fr-tr-1

而对于“QQ对战平台”,如果房间已满挤不进去,却变态的还会弹出两次提示!平时,就只有拼命的按“回车键”或“空格键”关闭这两个讨厌的弹出窗口,然后再用鼠标点房间,如果房间还是进不去,就只能再按上面来一次循环……一次、两次不是问题;五次、十次也许还不是问题;但如果十几次或上百次还是挤不进去,还手按那就有问题了!当然,如果你喜欢手虐那就另外说了-_-#

我不喜欢手虐,所以当有次碰到N次还是挤不进去时,我就在想,为什么不写个工具来代替我的手,用工具自动去帮我“挤”房间,帮我点那两个讨厌的提示窗口呢?于是这篇文章中的“QQ对战平台挤房器”就这样诞生了(这可解放多少人的双手啊,大家鼓掌……)

二、“挤房”要怎样“挤”?

上面说了,“挤房器”就是帮我们自动“挤”房,但是它要怎么帮我们“挤”呢?它毕竟是机器,而不是人,它不会自动一看到房间就帮我们“挤”,除非我们给它定制了一套规则(也可以叫命令)。机器就是机器,有规则它才会去做事,如果没规则也会做事,那它就是“人”(智能机器人?)了。

这规则要怎样定制?让我们先来看看我们平时进入房间的流程,如下图:

qq-fr-tr-2

好了,根据上面的流程,我们要给“挤房器”定制的规则就是分别以下几条:

1)、点击房间。

2)、判断是否已进入房间,如果没有进入房间,则负责将显示房间满的两个讨厌的提示窗口关闭掉,并重新回到第1步。

3)、已进入房间,则停止“挤”房动作。

三、自动“挤房”的实现。

这里的实现,就是用代码去实现上面定制的三个规则。

1、点击房间:

在这里我们简单点,只是模拟鼠标去点击鼠标当前所在的房间。说到这里,也许做过WINDOWS应用程序开发的朋友已想到了用哪几个API函数去模拟,对!就是以下几个API的结合一起使用,就能实现鼠标的模拟点击了。

1)、GetCursorPos : 获取鼠标的当前所在位置。

定义原型如下:

[DllImport("user32.dll")]
internal static extern bool GetCursorPos(out Point lpPoint);

此函数返回当前鼠标所在的坐标位置。

2)、mouse_event : 鼠标事件的模拟

定义原型如下:

[DllImport("user32.dll", EntryPoint = "mouse_event")]
public static extern void mouse_event(
    int dwFlags,
    int dx,
    int dy,
    int dwData,
    int dwExtraInfo
);

此函数通过不同的dwFlags参数定义,可以模拟不同的鼠标事件,如鼠标左键的按下、弹起事件等。

结合以上两个API函数,我们就能实现自动点击鼠标所在的房间"的效果了,类似如下代码:

Point point;

if(Win32API.GetCursorPos(out point)){

     //MouseAPI是对mouse_event API函数的一个简单封装。

     MouseAPI.SendMouseEvent(MouseAPI.MouseEvents.LeftButtonDown | MouseAPI.MouseEvents.LeftButtonUp, point, true);

}

但是上面的代码是非常“机械”的,也即是不管当前鼠标所在的窗口是不是在房间上,它都会自动“点击”一次!这样可不人性化,所以我们再改进一下,点击时先判断当前鼠标停留的是不是在对战平台的房间上,但可惜的QQ对战平台的房间不是标准WINDOWS控件,所以无法获取到房间的数据,最后只好简单点判断鼠标停留的窗口是不是QQ对战平台的大厅,因为大厅是可获取到的WINDOWS窗口控件,如下图是用Spy++获取到的大厅数据:

qq-fr-tr-3

也就是我们判断鼠标停留的窗口的类型是不是属于“Afx:400000:3”即可,如果是则表明鼠标是停留在QQ对战平台的游戏大厅中的,就可以点击房间了(注意:这里停留的位置不一定是房间上,但这不影响使用,所以我就没加以处理了)

这里需要使用的API有:

3)、WindowFromPoint : 获取某个坐标位置所在的窗口

定义原型如下:

[DllImport("user32.dll")]
internal static extern IntPtr WindowFromPoint(Point Point);

4)、GetClassName : 获取某个窗口的类型名称

定义原形如下:

[DllImport("user32.dll",  CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int GetClassName(IntPtr hWnd, StringBuilder buf, int nMaxCount);

加入上面的条件判断,上面的代码改进后如下:

if (Win32API.GetCursorPos(out point))
{
    hwnd = Win32API.WindowFromPoint(point);
    if (hwnd != IntPtr.Zero)
    {
        string className = Win32API.GetWindowClassName(hwnd);
        if (className.Equals("Afx:400000:3"))
        {
            MouseAPI.SendMouseEvent(MouseAPI.MouseEvents.LeftButtonDown | MouseAPI.MouseEvents.LeftButtonUp, point, true);
        }
    }
}
这样“点击房间”这步就可以算完美了,当鼠标不在房间(正确的说不在游戏大厅)上停留时,鼠标也不会乱点,这就方便在“挤房间”时随时可以切换窗口了。

2、判断是否已进入房间,如果没有进入房间,则负责将显示房间满的两个讨厌的提示窗口关闭掉。

 1)判断是否已进入房间: 和上面那步判断鼠标是否停

补充:软件开发 , C# ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,