对"QQGame-大家来找茬"的辅助工具的改进
【前言】最近在博客园首页上看到有“大家来找茬”这个游戏(此游戏为找出两个相近图片的不同点)外挂的相关帖子,所以这里我也翻看了我之前(2009年5月)的写的一个简单的辅助程序(采用 VC6 开发的)。我在当时的写法是图快速和简单,代码效率上不是最高的,所以我现在使用更加合理的方法将其改进(采用 VC2005 开发)。因为发表时间临近春节,即将回籍贯老家,所以行文和排版等难免仓促,有待在将来继续改进。
之前我在 2009 年 5 月写的文章为:《快速“美女找茬”(辅助工具)》。
解决方案的主要步骤是相同的,找到游戏窗口,然后将游戏窗口的内容截图,然后把不同点用一个透明图层的方式,对齐覆盖到游戏窗口的相应位置。这里并没有继续去帮助用户做点击,因为这一步需要把图像上的差异点集合划分成五个区域,这需要进一步处理(留待将来考虑)。
相比之前的做法,本次改进内容包括:
(1)增加配置文件记录游戏窗口的布局信息(这些信息为截图后在 Photoshop 中测量得出),这样在游戏布局因为升级等原因发生改变时,程序不需要进行重新编译,普通用户只需要自行修改配置文件即可。
(2)检测差异像素点时,直接对图像像素数据进行分析,这样的效率会更高。(由于当前的 PC 已经普及多核 CPU,所以这一步也采用了多线程技术。)
(3)增加全局热键的配置,因为发出一个命令时,键盘操作的速度比鼠标这种定点设备操作 GUI 的速度更快。
在游戏时,效果如下图所示:
左侧是一个“鼠标穿透”的半透明图层窗口(称之为“提示窗口”),所以用户可以直接在左侧的红色方块内部点击即可。用户可以在程序位于通知栏的图标右键菜单中,选择设置,然后设置全局性热键,提示窗口的不透明度等信息。设置对话框如下图:
接下来主要分析以上改进(主要是 2 和 3 )的实现。
改进(1)比较容易,只需要增加一个配置文件即可,其主要内容如下:
; 连连看游戏窗口信息
[GameWnd]
Class=#32770
Text=大家来找茬 ;图片 1 的位置(客户区坐标)
[Image1]
Left=10
Top=186
Right=390
Bottom=471 ;图片 2 的位置(客户区坐标)
[Image2]
Left=403
Top=186
以上内容主要是用于存储游戏窗口的类名和标题,以及两幅图片在游戏窗口中的客户区坐标,比较直观。很显然,图片2的右下角坐标无需给出,因为两个图片很显然是相同大小的。
对于(2),我首先能想到的是,之前使用了 GetPixel / SetPixel 函数,尽管是对内存 DC 操作,但这样的效率可能仍然是不够高的。所以这一次我改为直接对像素数据块操作。同时,这一次我决定使用对两个图像的相同位置的像素数据直接用异或操作来处理,同时也把对应的指针和数据单位扩展为 4 个字节的 DWORD 类型(而不是单独操作每个像素的 R G B 通道),这样将会加快处理速度。这样做以后,如果我们直接把异或后的结果显示出来,效果如下图(提示窗口已经为完全不透明):
直接显示异或结果,很显然图像相同的部分会变为全黑色(因为相同的数据的异或结果为零),不同的位置会显示出一些比较鲜艳的色彩。这样的显示效果其实并不太好,不太容易辨别,所以我还是把结果变为红色。这里有两个问题,导致我得出最终的解决方案。
(2.1)为了让我对两个数据进行异或时,他们的地址能以 DWORD 对齐。所以我对游戏窗口抓图时,把两个图片分别复制到一个上下排列的内存位图(如下,其尺寸为单个图片宽度 * 二倍图片高度),然后对这个内存位图的像素数据进行异或。如果不这样截图,那么直接对游戏窗口原样图片进行操作,由于图片在游戏窗口中的位置对我们来说是“随机”的,那么就无法保证像素数据能正好对齐到 DWORD(这个问题在 24 bpp 位图时存在,但当采用 32 bpp 内存位图时,任何像素都一定会对齐到 DWORD,这个忧虑已经不存在了,但对于提高复制屏幕图像的效率而言,这样截图依然是应该的,因为在两幅图像以外的部分是我们不感兴趣的,也就没必要全部截取)。(注意这里有一个基本可以肯定的前提条件,系统在分配位图时,其像素数据的起始地址一定是对齐到 DWORD 的。)
图片 1 |
图片 2 |
(2.2)最开始我创建的内存位图为 24 BPP,这样一个像素占据 3 Bytes,而一个 DWORD 占据 4 Bytes,所以如果是 24 BPP,即使找到一个操作结果不为零,要定位到像素或者对此像素设置为特定颜色(例如红色)也会比较麻烦(需要做换算)。所以这里我创建内存位图时把 BPP 改为 32,这样每个 DWORD 就是一个像素,这样就能对图片上的差异像素很容易的设为特定颜色,例如红色就是 0x00FF0000 (这个数字书写出来的顺序是,0x-AA-RR-GG-BB,与 little - endian 的存储顺序相反)。使用 CreateDIBSection 创建一个内存位图,代码比较简单。
(2.3)执行异或时,采用多线程处理。如果是单个线程执行这个计算,那么对于图像数据的输入来说必然是串行的。为了发挥当前的多核 CPU 的优势,所以这里把此异或计算采用多线程执行,把图片从上到下切分为几个高度较小的横条(横条的宽度等于图片宽度,个数等于要创建的线程数),每个线程分配到图片的其中一个横条。由于几个横条部分的数据彼此独立,不会发生数据相关性,所以可以直接并行处理,只需要等所有线程任务完成后(WaitForMultipleObjects),再把内存位图刷新到窗口上即可。以下是线程过程代码(像素数据的起始地址在创建位图时已经被转换为 LPDWORD):
备注:这里的任务切分,为从上到下把图像进行细分,一是遍历像素的方便,二是同时 CPU 对“数据局部性”的偏好,这样可以保持比较理想的 cache 命中率。在这个问题中,还可以考虑能否利用上 Intel CPU 的 MMX 和 SSE2 特性,进一步提高处理的并行度,以提高处理效率。(2014年5月4日 补充 -- hoodlum1980)
DWORD WINAPI ThreadEntry(LPVOID lpParameter)
{
int count, i, lineSize;
LPTASK pTask = (LPTASK)lpParameter; //DWORD Per Line;
lineSize = g_AppData.nStrideLayer / sizeof(DWORD); //Total Count of DWORDS;
count = (pTask->nEnd - pTask->nStart) * lineSize; //[End, Start); p1 - Image1; p2 - Image2
LPDWORD p1 = g_AppData.lpBitsLayer
+ (g_Layout.nImageHeight * - - pTask->nEnd) * lineSize; LPDWORD p2 = g_AppData.lpBitsLayer
+ (g_Layout.nImageHeight - - pTask->nEnd) * lineSize; for(i = ; i < count; i++)
{
*p1 = *p1 ^ *p2; //0xAARRGGBB
if(*p1) *p1 = 0x00FF0000;
++p1;
++p2;
}
return ;
}
采用以上方法之后,执行速度有明显提高,在我的台式机,CPU 为 I7, 16GB 内存,操作系统为 WIN7,之前的程序检测一次的执行速度为 260 ms 左右,改进后的程序的执行速度为 15 ~ 16 ms(而且经常为 0 ms,让我觉得不可思议,这里我采用的只是 GetTickCount 相减得到的粗略估算,没有考虑 CPU 调度的影响,并且这个函数本身就对精确性的要求不是很高),速度上改进前大约为改进后的 16 倍。从用户体验角度看,改进前求解有少许延迟感,改进后速度太快感受不到延迟。由于速度太快,所以我放弃了原本想在检测过程中切换通知栏图标的想法。
最后是两个程序的可执行文件的下载链接(采用 VS2005 , C++ 开发):
http://files.cnblogs.com/hoodlum1980/FindItEx_Bin.zip
之后的工作则是模拟点击功能。根据判断结果把差异像素分解成 5 个集合,然后在这些集合所在位置单击一次。这将会进一步加快游戏完成速度。这一步属于相对简单的图像分析处理任务,留待将来考虑。
对"QQGame-大家来找茬"的辅助工具的改进的更多相关文章
- 2014中秋节,用java为QQ游戏美女找茬写辅助
引子 今年中秋闲在家,总要找点事做. 前几天开始学python,很早之前就有计划拿下这门语言了,可惜一直拖到现在……不可否认,我也是个拖沓症患者.在学习python的过程中 ...
- 用Python实现QQ找茬游戏外挂工具
源地址:http://cpiz.net/blog/2012/03/a_qq_zhaocha_assistant_by_python/ (原创作品,转载请注明出处)好久没写技术相关的博文,这次写篇有意思 ...
- C#外挂QQ找茬辅助源码,早期开发
这是一款几年前开发的工具,当年作为一民IT纯屌,为了当年自己心目中的一位女神熬夜开发完成.女神使用后找茬等级瞬间从眼明手快升级为三只眼...每次看到这个就会想起那段屌丝与女神的回忆.今天特地把代码更新 ...
- 【QT】找茬外挂制作
找茬外挂制作 找茬游戏大家肯定都很熟悉吧,两张类似的图片,找里面的不同.在下眼神不大好,经常瞪图片半天也找不到区别.于是乎决定做个辅助工具来解放一下自己的双眼. 一.使用工具 Qt:主要是用来做界面的 ...
- 项目实战:Qt+OpenCV大家来找茬(Qt抓图,穿透应用,识别左右图区别,框选区别,微调位置)
前言 本项目的出现理由只是笔者的一个念头,于是利用专业Qt和Opencv相关的知识开发一个辅助工具,本文章仅用于Qt和Opencv结合的学习. Demo演示效果 运行包下载地 ...
- 比较不错的一个ios找茬游戏源码
找茬游戏源码 ,这个是一款非常不错的ios找茬游戏源码,该游戏的兼容性非常好的,并且还可以支持ipad和iphone,UI界面设计得也很漂亮,游戏源码真的是一款非常完美,而且又很完整的一款休闲类的游戏 ...
- MFC版美女找茬
今天心情:捡了个闲暇. 前几天工作出了个漏洞,电话会议时候怎么都是忽大忽小的声音,实在没听清电话会议的内容,完了依据想象交了一个设计方案,之后便是赋闲. 进入正题,美女找茬实现不难,没有设计上的难度, ...
- C#编写QQ找茬外挂
QQ找茬外挂,用C#代码编写. 使用方法 这个工具的主要运行流程很简单:游戏截图->比较图片->标记图片不同点.实现代码 截图的处理类ScreenCapture: /// /// 提供全屏 ...
- 社交系统/社群系统“ThinkSNS+”H5及PC端终于来了!一起来“找茬”
[什么是TS+?] ThinkSNS(简称TS),一款全平台综合性社交系统,为国内外大中小企业和创业者提供社会化软件研发及技术解决方案,目前最新版本为ThinkSNS+,简称TS+. 还记得2017年 ...
随机推荐
- js跳转传递参数
额,利用j获取了GridView中选中行数据后,通过JavaScript做跳转,传递参数的时候发现,当参数有中文的时候就会乱码, 当然出现这种情况的时候就需要对跳转的url进行编码 var urlX ...
- 【 D3.js 入门系列 --- 6 】 如何让图表动起来
[5.1]节中制作了一个比较完善的图表,但它是静态的,想做出它的动态效果吗?在D3中只需要短短的几行代码即可. 这一节将涉及4个函数的使用. 1.transition() 启动转变效果只需要添加这个即 ...
- js 打印星星金字塔
/** * * 第一行: * * 第二行: *** * 第三行: ***** * 第四行: ******* * 第五行: ********* * */ document.write('<p al ...
- AndroidStudio 点9图片文件报错
如果项目中不仅9图报错,包含的资源还有一堆不合法PNG,那怎么办???这种情况下,正确的解决办法是找到build.gradle文件,在buildToolsVersion下面加入以下两句: aaptOp ...
- documentfragment
JS临时容器,父类是null,存储实际是把存储对象所有子类存储在里面,localStorage,浏览器支持情况下,保存本地变量
- 自动化测试工具QTP的使用实例 分类: 软件测试 2015-06-17 00:23 185人阅读 评论(0) 收藏
1. QTP简介 1.1QTP功能与特点 QTP是QuickTest Professional的简称,是一种自动化软件测试工具.在软件的测试过程中,QTP主要来用来通过已有的测试脚本执行重复的手动测试 ...
- 利用C语言获得网页编码
#include <stdio.h> #include <winsock.h> #include <string.h> #pragma comment(lib, & ...
- XML组成结构以及C#通过DTD验证规范性
XML 文档包含元素和属性等,它们提供一种灵活且功能强大的方法,为应用程序和组织之间交换数据.所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成: 1.元素 元素是XML的主要构建 ...
- 关于databinding的细节
原文在此:http://www.codeproject.com/Articles/24656/A-Detailed-Data-Binding-Tutorial 完整译文在此:http://www.cn ...
- 使用C#/.net语言进行ProE/Creo二次开发
随便哪个版本的Visual studio 设置系统环境变量 通常这个环境变量在安装ProE的时候如果选择安装VBAPI就会自动设置 注意32位和64位操作系统路径是不同的.我的是64位操作系统. 然后 ...