`

QQ连连看外挂制作

    博客分类:
  • vc
阅读更多

这几天做了个外挂,主要是想学习下相关技术,

参考的是郁金香老师的视频

核心算法是我自己实现的

 

我在判断3条线路连通性时,用了4个辅助点,纵向pa和pb,横向pc和pd

让其中2个点与我们棋盘上的棋子形成一个矩形,

然后遍历它们组成这个矩形的所有行和所有列
把所有的情况都考虑成3条路径,因为它们都在一个矩形上
其中有的点重合的话那就是2条或1条路径
只要保证2个参考点p1和p2不重叠就行了
纵向时的pa与pb 可以和参考点p1或p2重叠 
横向时的pc与pd 可以和参考点p1或p2重叠




 


 

 

xp_sp2

vc6的MFC程序

在框架代码中调用下面的方法就可以了

 

//llk_wg.h
const PCHAR gameCaption="QQ游戏 - 连连看角色版"; //程序窗口标题
const LPARAM lpStartMenu= (568<<16)+655;	//开始按钮坐标
HWND hGame=::FindWindow(NULL,gameCaption);	//获取游戏窗口句柄
DWORD dwProcessId;							//进程的pid
HANDLE hProcess;							//进程句柄
LPCVOID lpBaseAddress;						//基地址
byte arrChessData[11][19];					//棋盘数据存放
DWORD rDwLen;								//实际读取的字节数
LPDWORD lpNumberOfBytesRead=&rDwLen;		//实际读取的字节数指针
BOOL readFlag=false;						//读取数据标志失败

BOOL ReadData(LPCVOID lpBaseAddress,LPVOID lpRead,DWORD nsize);//读数据
void LeftClick(POINT pp);					//模拟鼠标单击
BOOL ReadChessData();						//读棋盘数组数据
BOOL CheckChess(POINT p1,POINT p2);			//检测棋子是否可清除
BOOL CheckLine2p(POINT pi,POINT pj)	;		//检测2点是否直通(无障碍)
BOOL Click2p(POINT p1,POINT p2);			//模拟点击消息
void ClearPairOfChess(BOOL b)	;			//消除棋子主过程
void KillAll();								//秒杀
void AutoStart();							//自动开局

BOOL CheckLine2p(POINT pi,POINT pj)//检测同行或同列的2点是否连通(无障碍)
{	//关键算法之一
	POINT pUp;
	POINT pDown;
	POINT pLeft;
	POINT pRight;
	if ((pi.x==pj.x)&&(pi.y==pj.y))  //棋子重叠可连通
	{
		return true;
	}

	if (pi.x==pj.x)					//同列时(x相等,y不等)
	{
		if (pi.y<pj.y)
		{
			pUp=pi;
			pDown=pj;
		}
		else
		{
			pUp=pj;
			pDown=pi;
		}

		if ( 1==(pDown.y-pUp.y) )	//相邻棋子可连通
		{
			return true;
		}
		else						//不相邻时
		{
			for (int lineNum=pUp.y+1; lineNum<pDown.y; lineNum++) 
			{
				if (arrChessData[lineNum][pUp.x]!=0)
				{
					return false;	//有障碍
				}
			}
		}
	}//

	if (pi.y==pj.y)					//同行时(x不等,y相等)
	{
		if (pi.x<pj.x)
		{
			pLeft=pi;
			pRight=pj;
		}
		else
		{
			pLeft=pj;
			pRight=pi;
		}

		if ( 1==(pRight.x-pLeft.x) )	//相邻棋子可连通
		{
			return true;				
		}
		else
		{
			for (int columnNum=pLeft.x+1; columnNum<pRight.x; columnNum++)
			{
				if (arrChessData[pLeft.y][columnNum]!=0)
				{
					return false;		//有障碍
				}
			}
		}
	}//
	return true;	
}

BOOL CheckChess(POINT p1,POINT p2)  //检测棋子可否消除
{	//关键算法之一
	bool checkFlag=false;
	POINT pa,pb;//pa的x坐标与p1相等,pb的x坐标与p2相等
	pa.x=p1.x;
	pb.x=p2.x;

	POINT pc,pd;//pc的y坐标与p1相等,pd的y坐标与p2相等
	pc.y=p1.y;
	pd.y=p2.y;

	for (int lineNum=0;lineNum<11;lineNum++)
	{
		pa.y=lineNum;
		pb.y=lineNum;
		if( CheckLine2p(p1,pa)&&CheckLine2p(pa,pb)&&CheckLine2p(pb,p2) )
		{
			//Click2p(p1,p2);  //执行消除
			checkFlag=true;
		}
	}

	for (int columnNum=0;columnNum<19;columnNum++)
	{
		pc.x=columnNum;
		pd.x=columnNum;
		if ( CheckLine2p(p1,pc)&&CheckLine2p(pc,pd)&&CheckLine2p(pd,p2) )
		{
			//Click2p(p1,p2);  //执行消除
			checkFlag=true;
		}
	}
	return checkFlag;
}

BOOL Click2p(POINT p1,POINT p2) //模拟单击事件
{	//棋子宽度31,高度35  
	//int x=25,y=195;			//第一个棋子坐标
	LeftClick(p1);
	LeftClick(p2);
	ReadChessData();
	if (arrChessData[p1.y][p1.x]==0)
	{
		return true;		//成功消除一对棋子
	}
	return false;
}

void KillAll()				//秒杀
{
	for (int a=0;a<10;a++)
	{
		ClearPairOfChess(true); //一般5次循环内就完成秒杀
	}
}

void ClearPairOfChess(BOOL b)	//清除一对棋子的主过程
{	
	ReadChessData();			//更新一下棋盘数据
	
	//遍历棋盘,找出成对的棋子
	POINT p1,p2;
	int x1,y1;
	int x2,y2;
	for (y1=0;y1<11;y1++)		//遍历行数y
	{
		for (x1=0;x1<19;x1++)   //遍历列数x
		{
			if (arrChessData[y1][x1]!=0) //不为空子时,此子设为p1
			{
				for (y2=y1;y2<11;y2++)
				{			
					for (x2=0;x2<19;x2++)
					{
						if ((arrChessData[y1][x1]==arrChessData[y2][x2])&&
							(!((x1==x2)&&(y1==y2)))
						   )
						{   //存在p2时
							p1.x=x1;
							p1.y=y1;
							p2.x=x2;
							p2.y=y2;
							if (CheckChess(p1,p2)) //检测是否可清除
							{
								if (Click2p(p1,p2))//消除
								{	
									if (!b)  //不秒杀
									{
										return;
									}
								}
							}	
						}
					}
				}
			}
		}
	}	
}

void LeftClick(POINT pp)						//模拟鼠标单击
{
	if (hGame)
	{
		LPARAM lParam = ((195+pp.y*35)<<16)+(25+pp.x*31);
		SendMessage(hGame,WM_LBUTTONDOWN,0,lParam);
		SendMessage(hGame,WM_LBUTTONUP,0,lParam);
	}
}

void AutoStart()  //自动开始按钮
{	
	hGame=::FindWindow(NULL,gameCaption);		//获取游戏窗口句柄	
	if (hGame)
	{	
		LPARAM lParam = lpStartMenu;			//(568<<16)+655
		PostMessage(hGame,WM_LBUTTONDOWN,MK_LBUTTON,lParam);
		PostMessage(hGame,WM_LBUTTONUP,0,lParam);	
	}
}




BOOL ReadData(LPCVOID lpBaseAddress,LPVOID lpRead,DWORD nsize) //读数据
{	//3个参数分别是,基址,读取数据存放的缓冲区指针,要读取的数据大小
	hGame=::FindWindow(NULL,gameCaption);//获取游戏窗口句柄
	if (hGame==NULL)
	{	
		//AfxMessageBox(gameErr); 
		return readFlag;		
	}
	
	::GetWindowThreadProcessId(hGame,&dwProcessId);	//获取进程id
	hProcess=::OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessId); //打开
	readFlag=::ReadProcessMemory(hProcess,lpBaseAddress,
						lpRead,nsize,lpNumberOfBytesRead);	//读一个字节
	return readFlag;
}


BOOL ReadChessData()							//读棋盘数组数据
{
	lpBaseAddress= (LPCVOID)0x0012A480;			//棋盘数组基址
	ReadData(lpBaseAddress,arrChessData,sizeof(byte)*11*19);
	return readFlag;
}

 

  • 大小: 28.5 KB
  • 大小: 36 KB
分享到:
评论
5 楼 xouou_53320 2012-05-02  
//支持xp和win7
void CheckOsVersion()
{
OSVERSIONINFO ovi;
ovi.dwOSVersionInfoSize=sizeof(ovi);
GetVersionEx(&ovi);
if (ovi.dwMajorVersion == 5 && ovi.dwMinorVersion == 1) //WinXP
{
//MessageBox(NULL,"xp系统","提示",MB_OK);
lpBaseAddress = (LPCVOID)0x0012A480; //基址

}
else if (ovi.dwMajorVersion == 6 && ovi.dwMinorVersion == 1) //Win7
{
lpBaseAddress = (LPCVOID)0x0012A444;
}else
{
MessageBox(NULL,"版本不支持!","提示",MB_OK);
ExitProcess(0);
}
}
4 楼 xouou_53320 2012-04-08  
genime 写道
已经搞定了- -

3 楼 genime 2012-04-07  
已经搞定了- -
2 楼 genime 2012-04-07  
请教一下,为什么我查找的基址是一样的,读出来的都是00 呢? 座位号读的倒是对的
1 楼 genime 2012-04-07  
请教一下,为什么我读的棋盘数据都是00呢

相关推荐

    易语言qq连连看辅助程序源码

    【标题】易语言qq连连看辅助程序源码 在编程领域,辅助程序通常是用来增强或自动化某一特定软件功能的工具,而"易语言"是一种基于汉语词汇的编程语言,旨在降低编程的难度,让更多人能够参与到编程活动中。本资源...

    QQ连连看辅助工具源码

    这个代码只目前适合平面连连看游戏,可以用鼠标点击,也可以自己修改...本代码在第一高手的代码基础上修改而成,主要修改QQ游戏背景添加后原工具不能正常工作的bug。以每个图标的左上角标志性白点为识别点进行定位查找。

    易语言QQ连连看辅助源码

    易语言QQ连连看辅助源码! 原创 要的速度了

    QQ连连看辅助工具java源码

    qq连连看辅助工具java源码,Idea项目

    QQ连连看按键精灵代码_QQ_连连看_Vbscript_按键精灵_

    QQ连连看是一款深受玩家喜爱的经典休闲游戏,而“按键精灵”是一种自动化工具,它能够模拟用户的键盘和鼠标操作,极大地提升了工作效率或者游戏体验。在这个场景中,我们将关注的重点放在使用Vbscript(Visual Basic...

    QQ游戏连连看源码

    QQ游戏连连看源码,直接就可以编译,秒杀一切QQ游戏连连看

    QQ连连看辅助易语言源码

    易语言源码,仅供大家学习编程做参考,只做参考价值,有兴趣学习易语言的

    qq连连看秒杀源码

    QQ连连看秒杀源码是一种基于经典游戏QQ连连看的作弊工具,主要目的是帮助玩家在游戏中快速消除匹配项,实现秒杀效果。这类源码通常由编程爱好者或黑客编写,利用了游戏的某些漏洞或者机制来达到秒杀的目的。在本案例...

    qq连连看辅助工具python版源代码

    自学python时, 拿来练手的小代码, 基于python3.4, PyQt, Pywin32, 并提供了py2exe的setup.py及相关dll, ... 功能上实现了QQ连连看手动消除, 自动定时消除, 功能. 核心算法是基于递归调用的一个连连看相关模块的查找.

    QQ连连看秒杀源码 - 易语言

    QQ连连看秒杀源码 - 易语言

    QQ连连看 VC++源代码

    QQ连连看是一款经典的休闲益智游戏,其VC++源代码的提供对于学习和研究游戏开发,尤其是C++编程和Windows GUI编程的开发者来说是宝贵的资源。这个源代码包含的功能有自动消除、秒杀以及单个消除,这展示了游戏逻辑和...

    仿QQ连连看单机版

    QQ连连看是一款深受玩家喜爱的经典休闲游戏,其2D版本更是简单易上手,适合各年龄段的用户。本文将深入探讨“仿QQ连连看单机版”这一项目,旨在解析其核心技术和实现方法,帮助开发者们更好地理解和创建类似的游戏。...

    Java仿QQ连连看

    【Java仿QQ连连看】项目是一个使用Java Swing库构建的桌面游戏,旨在模仿经典游戏QQ连连看的玩法和界面。Swing是Java提供的一种用于构建图形用户界面(GUI)的工具包,它允许开发者创建丰富的交互式应用。下面将详细...

    QQ连连看辅助源码

    QQ连连看辅助源码,一次消去一对方格或一键秒杀

    JS连连看游戏,QQ连连看

    【JS连连看游戏,QQ连连看】是一款基于JavaScript、HTML和CSS开发的在线游戏,它模仿了QQ游戏中心的经典连连看玩法。这款游戏的核心是利用JavaScript的事件处理、DOM操作以及数组算法来实现游戏逻辑,而HTML则构建了...

    QQ连连看辅助工具java实现

    QQ连连看是一款深受玩家喜爱的经典休闲游戏,而“QQ连连看辅助工具java实现”则是一个专为此游戏设计的辅助程序,由Java编程语言编写,并利用JNI(Java Native Interface)技术来实现。本文将深入探讨这个工具的核心...

    连连看 [FLEX版本]

    连连看是一款广受欢迎的休闲益智游戏,其FLEX版本是使用Adobe的Flex技术进行开发的。Flex是一种基于...通过深入理解这些技术,开发者不仅可以制作连连看游戏,还可以进一步开发其他类型的富互联网应用程序。

    单机版QQ连连看源码

    QQ连连看是一款经典的休闲益智游戏,其源码对于初学者和游戏开发者而言,是一个非常有价值的参考资料。通过学习和分析单机版QQ连连看的源码,我们可以深入了解游戏开发的基本流程,以及涉及到的关键技术。 首先,...

Global site tag (gtag.js) - Google Analytics