鼠标模拟扫雷方块快速胜利
程序是Windows控制台应用程序
进去SaoLei.cpp里面的代码书写主要分下面六部分
#include "stdafx.h"
#include <Windows.h>//必备
#include <iostream>//要用到c++的输出,测试用
#include <string> //cout输出字符串string 必备
using namespace std;
{
//1.获得窗口句柄 获得游戏进程
//2.根据进程id打开进程
//3.取进程内存数据
//4.读取棋盘数据,遍历
//5.分析炸弹和方块
//6.鼠标模拟点击方块
return 0;
}
接下来书写代码,首先获得扫雷游戏的窗口句柄,我们可以利用vs2017工具的Spy++查找工具查看扫雷的窗口名
FindWindow 通过创建窗口的类名和窗口名查找窗口,并返回窗口的句柄
//1.获得窗口句柄 获得游戏进程
HWND d_Gameh = ::FindWindow(NULL, "扫雷");//句柄
DWORD ProcessId;//要打开窗口的进程标识符
::GetWindowThreadProcessId(d_Gameh, &ProcessId);
GetWindowThreadProcessId 返回创建指定窗口线程的标识和创建窗口的进程标识符
//2.根据进程id打开进程
HANDLE processH;
processH = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
OpenProcess 函数调用成功将返回进程句柄,否则返回NULL,使用后一定要调用CloseHandle()关闭打开的
PROCESS_ALL_ACCESS 所能偶能获得的权限
FALSE 是否可以被继承
ProcessId 需要打开的进程标识符
//3.取进程内存数据
接下来就是读进程里面我们需要的数据
BYTE SaoLeidata[35][16] = { 0 };//数据
DWORD Readbyte;
LPCVOID pBase = (LPCVOID)0x1005361;//这是保存棋盘数据的基地址这个后面我会再说
//读进程句柄 processH 地址为pBase的数据到SaoLeidata字节数组,大小为16*32,Readbyte返回标志
::ReadProcessMemory(processH, pBase, &SaoLeidata, 16 * 32, &Readbyte);
//4.读取棋盘数据,遍历
string str = "";//保存字串
char bufTmp[9] = " ";//临时字符串
BYTE Data[16][16] = {0};//干净的数组
int xx = -1;
for (int i = 0; i <=32; i =i+2)
{
xx++;
int yy = -1;//逻辑错误
for (int j = 0; j < 16; j++)
{
_itoa_s(SaoLeidata[i][j], bufTmp, 16); //总算读出来了
//sprintf_s(bufTmp,"%X", SaoLeidata[j]);
str += bufTmp;
str += " ";
yy++;
if (strcmp(bufTmp, "8f") == 0)
{
Data[xx][yy] = '0';
}
if (strcmp(bufTmp, "8f") != 0)
{
//cout << "i:" << i << "y:" << j << "--num:" << num;
Data[xx][yy] = '1';
}
}
cout << endl;
//c++ 输出字符串需要包含 string 头文件
str += "\n"; //读取成功 16*16的格子
}
cout << str << endl;//输出查看数据的正确性
//5.分析炸弹和方块
对数据的分析可以知道,并且8f为炸弹是不能点击的其他的都是可以点击的我们就把不等于‘8f’的位置Data[xx][yy]为1。
/*$ ==> >10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
$+10 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
(1005361的数据)$+20 >0F 8A 0F 0F 0F 0F 0F 0F 0F 0F 8A 0F 0F 8A 0F 0F ???
$+30 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+40 >0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 8A 0F 0F 0F ?
$+50 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+60 >0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 8A 8A 妸
$+70 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+80 >0F 0F 0F 0F 0F 0F 8A 0F 0F 0F 0F 0F 8A 0F 0F 0F ??
$+90 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+A0 >0F 0F 0F 8A 0F 0F 0F 0F 0F 8A 0F 8A 0F 0F 0F 0F ???
$+B0 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+C0 >0F 8A 8A 0F 0F 0F 0F 0F 0F 0F 0F 8A 0F 0F 8A 0F 妸??
$+D0 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+E0 >8A 8A 0F 0F 0F 0F 0F 0F 0F 8A 0F 0F 0F 0F 0F 8A 妸??
$+F0 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+100 >0F 0F 0F 0F 8A 8A 0F 0F 8A 0F 8A 0F 8A 0F 0F 0F 妸???
$+110 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+120 >8A 0F 0F 0F 8A 0F 0F 0F 0F 0F 0F 0F 8A 0F 0F 8A ????
$+130 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+140 >0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 42 41 41 BAA
$+150 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+160 >8A 0F 0F 0F 0F 8A 0F 0F 0F 0F 0F 0F 8A 41 40 40 ??夾@@
$+170 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+180 >0F 0F 0F 0F 0F 8A 0F 8A 0F 0F 8A 42 41 41 40 40 ??夿AA@@
$+190 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+1A0 >0F 8A 0F 0F 8A 42 42 41 42 8A 42 41 40 40 41 41 ?夿BAB夿A@@AA
$+1B0 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+1C0 >8A 42 41 41 41 41 40 40 41 41 41 40 40 40 42 8A 夿AAAA@@AAA@@@B?
$+1D0 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+1E0 >41 41 40 40 40 40 40 40 40 40 40 40 40 40 42 CC AA@@@@@@@@@@@@B?
$+1F0 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+200 >40 40 40 40 40 40 40 40 40 40 40 40 40 40 41 41 @@@@@@@@@@@@@@AA
$+210 >10 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 10
$+220 >10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
*/
我们写一个函数对窗口发送鼠标点击的消息
void SendMouseL(int x,int y) {
HWND d_Gameh = ::FindWindow(NULL, "扫雷");//窗口句柄
//19,63 是第一个方块的中心坐标 spy++
//16 16 是方块的宽和高
::SendMessage(d_Gameh, WM_LBUTTONDOWN, 0, ((63 + y * 16) << 16) + 19 + x * 16);
: :SendMessage(d_Gameh, WM_LBUTTONUP, 0, ((63 + y * 16) << 16) + 19 + x * 16);
int n = 30;
while (n>0)
{
n--;
}
}
鼠标点击的坐标看图个人理解
窗口坐标和数组的位置有变化,还是看图吧,x,y坐标是反的 坐标轴上的 (1,0)是数组的(0,1).
图有点灵魂,如果不是很懂,留言我再用文字解释一下
模块都写好了 最后写一个遍历数组模拟点击,程序目前只支持初级和中级
void Client() {
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
if (Data[i][j]=='1')
{
SendMouseL(j, i);//注意 i,j 是反过来的
}
}
}
}
大功告成。嘻嘻!!
扫雷游戏下载:点击下载