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

摘要:
一、什么是“QQ对战平台挤房器”?喜欢在“QQ对战平台”或“浩方对战平台”玩游戏的人都知道。平常平台上的房间基本很多都是人满的,如果想找个房间,那可是要费好长的时间来“挤”才能进去,如果是节假日或晚上,那更要花费更多的时间在“挤”房上了,如下图:而对于“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)判断是否已进入房间: 和上面那步判断鼠标是否停留在游戏大厅一样,也是判断鼠标是否停留在聊天室中,如果是那么就表示已挤进去了。用Spy++获取到聊天室的窗口类型分别是“RichEdit20A”和“Afx:44a0000:0” ,所以判断代码如下:

//判断鼠标是否停留在聊天窗口上if (Win32API.GetCursorPos(out point))
{
    hwnd = Win32API.WindowFromPoint(point);    if (hwnd != IntPtr.Zero)
    {        string className = Win32API.GetWindowClassName(hwnd);        if (className.Equals("RichEdit20A")
            || className.Equals("Afx:44a0000:0"))
        {
            isOk = true;
        }
    }
}

如果isOk=true则表示已挤进房间。则就可以停止“挤房”,否则就要处理那两个讨厌的提示窗口了。

2)关闭提示窗口

先需要判断是否有这两个提示窗口出现,因为在挤房过程中,QQ对战平台会优先显示一个进度条(窗口)。我们为了简单点处理,只是判断当前活动窗口是否是“提示窗口”即可,也即是简单的判断当前活动窗口中是否包含那个“确定”按钮,如果存在,那么就简单的认为这窗口是那提示窗口,关闭它即可。需要用到的API函数有以下几个:

A、GetForegroundWindow : 获取当前活动窗口

它的定义原形:

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 
public static extern IntPtr GetForegroundWindow();

B、FindWindowEx : 查找某个窗口

它的定义原型:

[DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true, CharSet = CharSet.Unicode)] 
internal static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

关闭提示窗口,则只使用简单的方法,也即是发送“回车键”即可,因为我们获取到的窗口是当前活动窗口,并且又是模式窗口,所以它能接受键盘消息。关于键盘的模拟,请参考我的这篇文章《C#对游戏手柄的编程开发-API篇(3)》。

最后代码如下:

if (!isOk)
{    //没有挤进去,则判断是否有提示窗口弹出,有的话关闭掉它    hwnd = Win32API.GetForegroundWindow();    if (hwnd != IntPtr.Zero)
    {        //查找活动窗口是否包含有"确定"按钮        IntPtr buttonHwnd = Win32API.FindWindowEx(hwnd, IntPtr.Zero, "Button", null);        if (buttonHwnd != IntPtr.Zero)
        {            KeyboardAPI.SendKeyEvent(Keys.Enter, KeyboardAPI.KeyboardEvents.KeyDown | KeyboardAPI.KeyboardEvents.KeyUp);
        }
    }
}

isOk是上面判断有没有“挤”进去的值,如果没有“挤”进去就进行上面的“关闭提示窗口”的操作,如果已“挤进去”则停止即可。

到此,将上面的所有代码整合到一起,并加入到Timer的定时执行中,我们的“QQ对战平台挤房器”就实现了。

 

以下提供程序下载(不提供源码,但你可以对其反编译查看):

/Files/kingthy/QQBattleThruster.rar

免责声明:文章转载自《用C#打造"QQ对战平台挤房器"》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇psp影音播放器的需求分析一个简短的yahoo YUI介绍下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

基于Qt5 跨平台应用开发

1.Qt简介 2.Qt 编程关键技术 2.1 信号与槽 2.2 Qt事件处理 3.Qt开发与实例分析 3.1 开发环境 3.2 系统实现基本框架 3.3 数据库管理 3.5 对Excel进行操作 4.系统的打包和测试 4.1 Mac系统上打包Qt 4.2 Windows系统上打包Qt。 4.3 发布软件测试 5.Qt开发常见问题 5...

腾讯云 远程通过端口3306访问MYSQL数据库

背景 网上自己找了一圈,要么就是资料太老,要么就是太简单,比较零散。 强行提笔,总结一下,关于腾讯云 mysql8.0 开启3306端口,用远程非本地访问数据库。 安装 Mysql8 可以执行下面的命令就可以安装了,并设置为开机自启动。 wget -i -c https://repo.mysql.com//mysql80-community-release...

UOS安装zerotier-one

一、在线安装方式 下载安装 curl -s https://install.zerotier.com/ | sudo bash 添加开机自启 sudo systemctl enable zerotier-one.service 启动zerotier-one.service sudo systemctl start zerotier-one.servic...

python+opencv中最近出现的一些变化( OpenCV 官方的 Python tutorial目前好像还没有改过来?) 记一次全景图像的拼接

最近在学习过程中发现opencv有了很多变动, OpenCV 官方的 Python tutorial目前好像还没有改过来,导致大家在学习上面都出现了一些问题,现在做一个小小的罗列,希望对大家有用 做的是关于全景图像的拼接,关于sift和surf的语法之后有需要会另开文章具体阐述,此篇主要是解决大家困惑许久的问题。 笔者python3.x 首先是安装上,必须...

编程语言 IDE 对比

IDE是集成开发环境的英文缩写,所谓集成开发环境,就是将你在开发过程中所需要的工具或功能集成到了一起,比如代码编写、分析、编译、调试等功能,从而最大化地提高开发者的工作效率。 每种编程语言都有一些特定的IDE,本文将简单为你介绍这些IDE之间的区别,希望能够为你选择IDE时提供一些帮助。  目 录 [ - ] Java C/C++ C#...

ARM 汇编的mov操作立即数的疑问

1. 因为对arm汇编有些指令还不能理解,特别是一些相似功能指令间的区别。偶然在网上搜到“faq ARM assembly”,其中描述的几个问题还是值得好好研究一下。 2. 慢慢的发现自己也不再害怕英文的文档了,耐心看至少也能懂个大概。大批经典的文章和书籍都是en文的,所以经常看英文文档是一个非常好的习惯。看看GNU的一些reference manual,...