自动化测试实战项目(二)连连看外挂

news2024/11/15 6:52:38

自动化测试和做外挂的原理很相似,都是模拟用户的鼠标和键盘操作, 给自己的程序写自动化就是做测试,给别人的程序写自动化就是外挂了。

本文使用的技术也同样适用制作“对对碰”,"找茬" 之类游戏的外挂。

阅读目录

  1. QQ连连看外挂实现原理
  2. GUI自动化测试的原理
  3. 什么是句柄
  4. P/Invoke机制
  5. 获取游戏窗体的句柄
  6. 分析游戏窗口
  7. 对游戏窗口进行截图
  8. 根据游戏规则来写算法
  9. 模拟鼠标点击
  10. 源代码下载

QQ连连看外挂实现原理

1. 先调用Win32 API获取"连连看"游戏窗口的句柄,

2. 根据游戏窗口的句柄,然后获取游戏方块中的像素。

3. 用一个二维数组来保存每个方块的像素

4. 用算法判定两个一样的方块能否"消", 如果能"消"的话,就模拟鼠标去点击这两个方块。 继续"消" 下一组方块。

GUI自动化测试的原理

当你点击窗体中的一个button, button会响应然后执行一些操作。 这个过程的本质是: 你在屏幕上点击一个Button, Windows系统根据你点击的位置,知道你要点击哪个Button,然后给这个Button发送鼠标点击的消息。

自动化的原理是: 找到控件的句柄,通过句柄给这个控件发送消息,比如“键盘输入”消息或者“鼠标点击”消息。

什么是句柄

所有的Windows控件本质上都是一个窗体(Window). 每个控件/窗体都有一个与之关联的句柄(handle), 可以通过这个句柄来访问,操纵和检测这个控件/窗体

窗体句柄是由系统产生的一个值,你可以把它想象成与窗体关联的一个ID,通过这个ID可以访问相应的窗体。

在.NET中, 句柄的类型是System.IntPtr, 有点类似Int型。

P/Invoke机制

P/invoke机制叫做"平台调用"机制, 因为Win32API 函数是Windows操作系统的一部分,所以它是用传统的C++程序写的,而不是用C#托管代码写的。 所以我们需要一种机制,让C#中可以调用Win32 API函数.

具体的解决方案是: 先为想要使用的Win32函数创建一个C#外覆函数,或者叫别名函数, 然后调用这个别名函数

实例:

在Win32 API中获取窗体的句柄的函数是 FindWindow(), 它的函数签名用C++描述是这样的

HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName);

在C#中,给这个Win32 函数创建别名函数

需要先引用命名空间:  using System.Runtime.InteropServices;

[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

DllImport: 指定要使用的函数所在的DLL文件。

EntryPoint: Win32 API函数的名称.

CharSet.Auto: 让.NET框架来决定如何进行字符类型转换

当为一个Win32函数编写相应的C#方法别名的时候, 几乎总要使用static 和extern, 因为大多数Win32函数都是静态函数,而非实例函数。

注意:别名函数和Win32函数的名称并不要求一致。 但是名称一致可以保证代码的可读性.

获取游戏窗体的句柄

我们用Win32 API 函数来获取“连连看"游戏窗体的句柄

我们现在调用上节介绍的C#中的别名函数FindWindow(),就相当于调用了Win32 API 的FindWindow()函数

FindWindow函数接收2个参数,className 或者WindowName 然后返回句柄.

Spy++是.NET中自带工具,我们可以使用它来获取窗体的名字。

具体用法是,启动spy++, 点击"Findow Window"图标,弹出Findow Window 程序后, 用鼠标拖动“靶心”到你要测试的窗体上。

如下图。 可以得到游戏窗体的名字叫"QQ游戏 - 连连看角色版"

 

这样我们就能轻松获取 游戏窗体的句柄

IntPtr wndPane = Win32API.FindWindow(null, "QQ游戏 - 连连看角色版");

分析游戏窗口

通过屏幕标尺工具, 我们去测量游戏窗口。 (这个比较繁琐,需要你多次去测量,多次调整后才能得到准确的数据).

可以发现 "游戏区域" 距离游戏窗口 水平方向:15像素, 垂直方向:182像素

游戏中垂直方向有11个方块, 水平方向有19个方块

每个方块 长:31像素, 宽:35像素 如下图

 

对游戏窗口中的所有方块进行截图

一个方块有31*35=1085个像素, 事实上我们不需要获取方块中所有的像素点。 为了节省性能,我只需要获取一个方块中的几个像素就可以了。

我们需要用到2个函数来实现获取方块的像素。

[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hwnd);


[DllImport("Gdi32.dll")]
public static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);

GetDC函数的作用是指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄, 它的输入参数是窗口的句柄, (上节中我们介绍过可以使用FindWindow函数来获取窗口的句柄). 返回的是DC句柄。 (注意这两个句柄是不同的)

GetPixel根据GetDC获取的DC句柄和X坐标,Y坐标来获取像素点。

实例: 我们获取游戏中 "第三排第四列" 的方块的像素, 代码如下:

IntPtr wndPane = Win32API.FindWindow(null, "QQ游戏 - 连连看角色版");
IntPtr hdc = Win32API.GetDC(wndPane);
// X轴方向的像素要这么算15+31*3
// 因为游戏区域距离游戏窗口左边15像素,每个方块宽31像素,
// Y轴方向的像素要这么算 182+35*4
// 因为游戏区域距离游戏窗口上方182,每个方块高35像素
uint color = Win32API.GetPixel(hdc, 15+31*3 + offX, 182+35*4 + offY);

根据游戏规则来写算法

我们用一个二维数组来保存游戏中的所有方块

private Block[,] blocks = new Block[11, 19];

Block对象代表一个方块,如果方块为空,那么Block包含的是背景色。 如果有方块,那么Block对象中保存该方块的9个像素点。

详细请参考代码中的Block对象。

然后分析游戏规则来写算法来遍历二维数组。

垂直方向,如果两个一样的方块,处于同样的Y轴上,中间没有任何方块可以消, 如图

 

水平方向,如果两个一样的方块,处于同样的X轴上,中间没有任何方块, 可以消, 如图

 

拐1个弯, 如果两个一样的方块, 其中一个的X轴和另一个Y成90度,并且中间没有任何方块, 可以消, 如图

 

拐2个弯, 如图

 

 

根据上面这些游戏规则,来设计算法, 具体算法请参考源代码

模拟鼠标点击

模拟鼠标点击的的方法有很多,

其中的一个win32 API 方法为

        [DllImport("user32.dll")]
        public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
        const int MOUSEEVENTF_MOVE = 0x0001;        //移动鼠标
        public const int MOUSEEVENTF_LEFTDOWN = 0x0002;    //模拟鼠标左键按下
        public const int MOUSEEVENTF_LEFTUP = 0x0004;      //模拟鼠标左键抬起
        const int MOUSEEVENTF_RIGHTDOWN = 0x0008;   //模拟鼠标右键按下
        const int MOUSEEVENTF_RIGHTUP = 0x0010;     //模拟鼠标右键抬起
        const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;  //模拟鼠标中键按下
        const int MOUSEEVENTF_MIDDLEUP = 0x0040;    //模拟鼠标中键抬起
        const int MOUSEEVENTF_ABSOLUTE = 0x8000;    //标示是否采用绝对坐标 

源代码下载

留言昂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/594440.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《面试1v1》垃圾回收机制

我是 javapub,一名 Markdown 程序员从👨‍💻,八股文种子选手。 面试官: 小伙子,跟我聊聊垃圾回收机制吧。什么是垃圾?怎么回收? 候选人: 好的面试官,来吧!垃圾就是那些不再被程序使用的对象。Java 通过…

Spring Boot定时任务

目录 1.概述 2.Spring Boot定时任务 2.1.快速使用 2.2.cron表达式 3.业务示例 3.1.业务描述 3.2.业务实现 4.实现原理 5.自定义线程池 1.概述 在某些业务场景中,需要定时执行一些任务,有可能是定时统计然后生成报表,有可能是定时发…

Python自定义函数

目录 1. 语法 2. 常见用法 2.1. 函数的返回值 2.2. 函数互相调用 3. 实战练习 3.1. 定义执行Linux命令的函数 1. 语法 #定义函数 def 函数名(参数1, 参数2):函数体(代码块)......#调用函数(定义函数时使用了参数,调用也必须使用参数) 函数名(参数1, 参数2) 定…

React学习6 路由

SPA的理解 单页Web应用(single page web application,SPA)。整个应用只有一个完整的页面。点击页面中的链接不会刷新页面,只会做页面的局部更新。数据都需要通过ajax请求获取, 并在前端异步展现。 什么是路由? 一个路由就是一个…

网络连接管理除了TCP三次握手,还有TCP四次挥手

网络连接管理除了TCP三次握手,还有TCP四次挥手 TCP三次握手,TCP四次挥手 网络连接管理除了TCP三次握手,还有TCP四次挥手TCP三次握手TCP四次挥手总结 TCP三次握手 网络通信建立连接,TCP会进行三次握手,三次握手主要是两…

【叠高高】叠蛋糕游戏的微信小程序开发流程详解

记得小时候玩过的搭积木游戏吗,和叠高高游戏原理差不多的,与之类似的还有盖高楼游戏,就是看谁盖的(叠的)最高,这里讲一下比较基础的叠高高游戏小程序实现过程,对编程感兴趣的同学可以参考学习一…

Linux Shell 实现一键部署Rust1.69

rust 前言 一门赋予每个人,构建可靠且高效软件能力的语言。 全世界已有数百家公司在生产环境中使用 Rust,以达到快速、跨平台、低资源占用的目的。很多著名且受欢迎的软件,例如 Firefox、 Dropbox 和 Cloudflare 都在使用 Rust。从初创公司…

网络安全工程师的入门学习路径,年薪30W不是梦!

最近看到网上有很多人在问诸如:“怎样成为网络信息安全工程师”等相关问题,这可能与近几年网络安全事件频发,国家对于互联网信息安全和互联网舆情的重视程度不断提升有关,网络信息安全工程师随之成为炙手可热的职业。 首先&#…

Web的基本漏洞--文件包含漏洞

目录 一、文件包含漏洞的介绍 1.文件包含漏洞的原理 2.常见的文件包含函数 3.文件包含漏洞的分类 本地文件包含漏洞 远程文件包含漏洞 3.文件包含漏洞的危害 4.文件包含漏洞的防范措施 5.文件包含漏洞的绕过手法 空字符绕过 超长字符绕过 一、文件包含漏洞的介绍 1…

5年经验之谈:月薪3000到30000,测试工程师的变“行”记

自我介绍下,我是一名转IT测试人,我的专业是化学,去化工厂实习才发现这专业的坑人之处,化学试剂害人不浅,有毒,易燃易爆,实验室经常用丙酮,甲醇,四氯化碳,接触…

你需要知道的 Selenium4 新特性

前言 最近又用到了Selneium,发现已经来到了 4.9 版本了。本篇文章来介绍下它较比 Selenium3 的一些新特性。 记录下,当是做笔记了。 最令人惊喜的是,Selenium4 会自动回收浏览器资源。 本文所使用的 Selenium 版本为 4.9.9 知识点&#x1f4…

开发一个收废品小程序步骤

随着环保意识的提升和可持续发展的迫切需求,废品回收成为了一个重要的议题。预约上门回收小程序的开发为用户提供了方便、快捷的废品回收服务,促进了废品资源的再利用和环保行动的推进。本文将介绍开发预约上门回收小程序的流程,以帮助开发人…

java12--本章作业

1. 第1题 public class Hello{public static void main(String[] args){Person[] persons new Person[3];persons[0] new Person("zsq", 18, "学生");persons[1] new Person("zzq", 19, "大学生");persons[2] new Person("zq…

【leetcode】1130. 叶值的最小代价生成树

1130. 叶值的最小代价生成树 1、问题描述2、解决方案2.1、动态规划2.1.1、问题分析2.1.2、代码实现 2.2、单调栈 1、问题描述 1130. 叶值的最小代价生成树 给你一个正整数数组 arr,考虑所有满足以下条件的二叉树: 每个节点都有 0 个或是 2 个子节点。数…

一文3000字实现基于Selenium+Python的web自动化测试框架

一、什么是Selenium? Selenium是一个基于浏览器的自动化测试工具,它提供了一种跨平台、跨浏览器的端到端的web自动化解决方案。Selenium主要包括三部分:Selenium IDE、Selenium WebDriver 和Selenium Grid。 Selenium IDE:Firefo…

2.4 IDEA开发词频统计项目

一、词频统计准备工作 (一)启动集群的HDFS与Spark 启动HDFS服务 启动Spark集群 (二)在HDFS上准备单词文件 在master虚拟机上创建单词文件 - words.txt 将单词文件上传到HDFS指定目录/wordcount/input 二、本地模式运行Sp…

RCE漏洞演示,墨者靶场

#案列演示 打开墨者靶场,黑盒#命令注入执行分析 这个功能点有这么个功能,进行类似的像我们电脑上ping命令,这相当于就满足了命令,明显可能出现命令执行漏洞,可控变量和漏洞函数都存在。第一要去分析是什么操作系统&am…

批量 ping 网段的终极方法

我们分析和判定网络故障,如果有 10 设备,100 台设备,1000 台设备怎么办?一个个 ping 过去人都要疯掉了,这种情况在大型网络中我们有可能遇到,那怎么办呢?来听听海翎光电小编的一点看法吧&#x…

Spark写入Hive报错Mkdir failed on :com.alibaba.jfs.JindoRequestPath

1. 报错内容 23/05/31 14:32:13 INFO [Driver] FsStats: cmdmkdirs, srcoss://sync-to-bi.[马赛克].aliyuncs.com/tmp/hive, dstnull, size0, parameterFsPermission:rwx-wx-wx, time-in-ms32, version3.5.0 23/05/31 14:32:13 ERROR [Driver] ApplicationMaster: User class …

八大技术架构——升级之路

目录 一、单机架构 简介 工作原理 架构优缺点 相关软件 二、应用数据分离架构 简介 工作原理 架构优缺点 三、应用服务集群架构 简介 出现原因 工作原理 架构优缺点 相关软件 四、读写分离/主从分离架构 简介 工作原理 架构优缺点 相关软件 五、冷热分离架…