【前言】最近在博客园首页上看到有“大家来找茬”这个游戏(此游戏为找出两个相近图片的不同点)外挂的相关帖子,所以这里我也翻看了我之前(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 - Image2LPDWORD p1 = g_AppData.lpBitsLayer+ (g_Layout.nImageHeight * 2 - 1 - pTask->nEnd) * lineSize;LPDWORD p2 = g_AppData.lpBitsLayer+ (g_Layout.nImageHeight - 1 - pTask->nEnd) * lineSize;for(i = 0; i < count; i++){*p1 = *p1 ^ *p2;//0xAARRGGBBif(*p1) *p1 = 0x00FF0000;++p1;++p2;}return 0;
}

  采用以上方法之后,执行速度有明显提高,在我的台式机,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 个集合,然后在这些集合所在位置单击一次。这将会进一步加快游戏完成速度。这一步属于相对简单的图像分析处理任务,留待将来考虑。

转载于:https://www.cnblogs.com/hoodlum1980/p/3536444.html

对QQGame-大家来找茬的辅助工具的改进相关推荐

  1. 找茬类辅助工具的编写

    主要有两个方面:屏幕抓图与贴图和像素比较与重设 若使用GDI,建议使用CImage类,比较方便. 原理很简单:将两幅图抓取下来,按像素比较,相同的设一种色,不同的设另一种色,然后形成新的图,再将此图贴 ...

  2. 跟我学 编写QQ找茬辅助1 -原创文章

    今天把完美日志更新一下打算早点睡觉的.        被朋友拉着玩了一下QQ找茬..高手大有人在啊..很是悲惨..           朋友痛恨的说.不行,要找外挂玩玩..百度一下,也还有不少..对于 ...

  3. QQ找茬辅助工具的制作

    QQ找茬辅助工具的制作 转载请注明出处:http://www.cppblog.com/greatws/archive/2009/05/05/81996.html 这段时间GF一直在玩QQ找茬,看了一下 ...

  4. QQ找茬辅助工具 C#

    昨天晚上用C#做了一个QQ游戏"找茬"辅助工具.这个不能算是一个外挂工具,因为不涉及到服务器和客户端的问题,只涉及到图像处理的知识.目前只是实现了基本的功能,但是已经够用了,玩了几 ...

  5. 大家来找茬辅助工具实现

    昨天看到同学在玩大家来找茬,一时兴起,打算自己写个辅助工具.其实游戏很简单,就是找出两幅图片中的不同之处.游戏规则了解了,那外挂的思路也就很明朗了只要对比两幅图片的像素,有不相同就存储进数组就可以了. ...

  6. “图片差异检查”辅助工具(即“大家来找茬”辅助工具)源码分享

    忽然心血来潮,想写一个辅助工具,让朋友们在"大家来找茬"之类的游戏中可以少费一些眼睛. 在Java方面我是新手,在折腾了一段时间后,终于还是写出了一个基本可用的测试版程序.详细的使 ...

  7. QQ找茬辅助工具的制作[转]

    出处:http://www.cppblog.com/greatws/archive/2009/05/05/81996.html 这段时间GF一直在玩QQ找茬,看了一下,原理很简单,就是找到2附图片的不 ...

  8. 封校大学生在宿舍无聊玩起图像大找茬——一个关于游戏的练手小项目(一起领略Python脚本的风采吧)

    ???一个帅气的boy,你可以叫我 ?? 个人主页:的个人主页 ???如果对你有帮助的话希望三连???支持一下博主 图像大找茬 前言 基础知识 图片找茬 抓取句柄图片 GUI界面搭建 前言 在一个月黑 ...

  9. 大家来找茬:谁降低了游戏研发的品质

    ----为游戏研发品质找茬! 试着勇敢一点 我越来越觉得勇敢是非常优秀也是必备的品质,每个人迟早要学会勇敢面对一切,越早学会失去得越少.面对那些使游戏研发品质降低的错误,我们要勇敢.积极地处理. 一. ...

  10. AI一眼识别这是什么鸟 “我们来找茬”十级选手诞生

    话说,你能看出这三只鹦鹉有什么不一样吗?脸盲如我,要使出玩"我们来找茬"的十级能力. AWSL,鹦鹉鹦鹉,傻傻分不清楚. 结果,AI一顿操作猛如虎,进行了判断:左边的是桃面牡丹鹦鹉 ...

最新文章

  1. java awt table_java.awt.image 类 LookupTable - Java 中文参考手册
  2. 在centos8 stream启用 Extra Packages
  3. Spring Bean名称
  4. 疫情与资本寒冬双重危机下,智领云为何能拿到数千万融资?
  5. *和**在Python中意味着什么?它与指针和地址有关吗?
  6. bean json转kotlin_Android--------kotlin插件神器Json直接生成javaBean
  7. PyTorch 1.0 中文文档:torch.utils.dlpack
  8. .net MVC Model
  9. 设计灵感|信息图表海报竟然能设计的这么有趣!
  10. Maven下 SpringMvn+thymeleaf 搭建
  11. 国内服务器带宽价格是多少?国内服务器带宽为什么贵?
  12. matlab一维数组操作,Matlab创建一维数组的具体操作方法
  13. 批处理版音视频播放器(甲兵时代原创批处理)(上)
  14. 针对VMware安装Win10需要安装.NET Framework 3.5常见的0x800F0906、0x800F081F错误解决办法
  15. 服务器win10系统开机慢,Win10系统更新后开机变得很慢的解决方法
  16. 01.使用.svg格式图片生成app图标详细步骤和注意事项
  17. SQuirreL SQL Client (小松鼠) 数据库连接工具
  18. 强化学习精要-第二部分-蒙特卡罗、TD、DQN
  19. 【教程】记录:python基础爬虫代码(下载妹子福利图片)
  20. 解决手机连上笔记本wifi几分钟后就上不了网

热门文章

  1. 【好题分享】适合c++初学者(从易到难)
  2. DIY回音壁多媒体音箱
  3. 创新移动互联,阿凡题学习神器引领搜索新体验
  4. 【python】计算圆周率到任意位支持任意位(速度快)
  5. linux学习笔记(十二)
  6. 法国三家银行加入R3 Corda区块链贷款平台
  7. python辛普森积分_辛普森在Python中的规则
  8. 学计算机选择师范类好吗,师范教育类专业和计算机类专业,两者相比,哪个更适合自考生报读...
  9. [975]python requests实现HTTPS客户端的证书导入
  10. 这下爽了,居然有人通过这个把Linux的命令提示符给整明白了