⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skyblue_llk_cheatdlg.cpp

📁 使用C++配合MFC 编写的连连看的源代码和外挂的源代码.
💻 CPP
字号:
//
/*++

Copyright (c) AFE(Active-Free-Elegance)

Module Name:

    skyblue_LLK_CheatDlg.cpp

Abstract:

	the game's cheating-kernal-solving Dialog class

Author:

    Weijian Luo (Arthur Luo)   15-Jun-2005

	E-mail: skybluehacker@yahoo.com.cn

Revision History:      1.0

--*/
#include "stdafx.h"
#include "skyblue_LLK_Cheat.h"
#include "skyblue_LLK_CheatDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif





#define BKCOLOR         RGB(128,128,128)	//背景颜色
#define FRONTWIDTH	    (39+2)			    //前面方块的宽度
#define FRONTHEIGHT	    (39+12)			    //前面方块的高度
#define BKWIDTH	        46					//背景方块的宽度
#define BKHEIGHT        56					//背景方块的高度
#define ROWCOUNT        7					//行数
#define COLCOUNT        12					//列数

#define BLANK_STATE     -1                  //空方块(没有任何动物)
#define INVALID_POS     -1                  //无效坐标位置

#define BLOCK_WIDTH_SIZE	        (39+2)					//背景方块的宽度
#define BLOCK_HEIGHT_SIZE        (39+12)					//背景方块的高度

/////////////////////////////////////////////////////////////////////////////
// CSkyblue_LLK_CheatDlg dialog

CSkyblue_LLK_CheatDlg::CSkyblue_LLK_CheatDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSkyblue_LLK_CheatDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSkyblue_LLK_CheatDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	//记录方块置为无效状态
	m_nY1= INVALID_POS;
	m_nX1= INVALID_POS;

	//初始化行列数
	m_nRow=ROWCOUNT;
	m_nCol=COLCOUNT;

	m_hHackDC = NULL; 
	m_hwndHack = NULL;

	//不是自动作弊(控制目标程序销方块
	m_bAutoKick = FALSE;

	//根据行列数动态分配内核数据数组空间
	m_map=new int[m_nRow*m_nCol];

}

void CSkyblue_LLK_CheatDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSkyblue_LLK_CheatDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSkyblue_LLK_CheatDlg, CDialog)
	//{{AFX_MSG_MAP(CSkyblue_LLK_CheatDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BT_HACK, OnButtonHack)
	ON_BN_CLICKED(IDC_BT_AUTO_KICK, OnButtonAutoKick)

	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSkyblue_LLK_CheatDlg message handlers

BOOL CSkyblue_LLK_CheatDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	//获取程序框架的设备环境
	CDC *pWinDC = GetDC();		
	//整个游戏区域内存位图	
	m_MemDC.CreateCompatibleDC(pWinDC);
	m_memBitmap.CreateCompatibleBitmap(pWinDC,m_nCol*FRONTWIDTH+5,m_nRow*FRONTHEIGHT+5);
	m_MemDC.SelectObject(&m_memBitmap);
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CSkyblue_LLK_CheatDlg::OnPaint() 
{
		CPaintDC dc(this); 

		dc.BitBlt(30,70,               //在对话框的偏移位置
			m_DestClientRect.Width(),  //图像宽度
			m_DestClientRect.Height(), //图像高度
			&m_MemDC                   //来源于与内存设备环境关联的内存位图
			,0,0,SRCCOPY               //0偏移拷贝
			);
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CSkyblue_LLK_CheatDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}


//
//X直接连通
//
BOOL CSkyblue_LLK_CheatDlg::X1_Link_X2(int x, int y1,int y2)
{
	//保证y1的值小于y2
	if(y1>y2)
	{
		//数据交换
		int n=y1;
		y1=y2;
		y2=n;
	}

	//直通 	
	for(int i=y1+1;i<=y2;i++)
	{
		if(i==y2)
			return TRUE;
		if(m_map[i*m_nCol+x]!=BLANK_STATE)
			break;
	}
	//左通
	if(XThrough(x-1,y1,FALSE)&&XThrough(x-1,y2,FALSE))
		return TRUE;
	//右通
	if(XThrough(x+1,y1,TRUE)&&XThrough(x+1,y2,TRUE))
		return TRUE;
	return FALSE;
}

//
//Y直接连通
//
BOOL CSkyblue_LLK_CheatDlg::Y1_Link_Y2(int x1,int x2,int y)
{
	if(x1>x2)
	{
		int x=x1;
		x1=x2;
		x2=x;
	}
	//直通
	for(int i=x1+1;i<=x2;i++)
	{
		if(i==x2)
			return TRUE;
		if(m_map[y*m_nCol+i]!=BLANK_STATE)
			break;
	}
	//上通
	if(YThrough(x1,y-1,FALSE)&&YThrough(x2,y-1,FALSE))
		return TRUE;
	//下通
	if(YThrough(x1,y+1,TRUE)&&YThrough(x2,y+1,TRUE))
		return TRUE;
	return FALSE;
}

//
// 是否同一直线通
//
BOOL CSkyblue_LLK_CheatDlg::LineX(int x,int y1,int y2)
{
	if(y1>y2)
	{
		int y=y1;
		y1=y2;
		y2=y;
	}
	for(int y=y1;y<=y2;y++)
	{
		if(m_map[y*m_nCol+x]!=BLANK_STATE)
			return FALSE;
		if(y==y2)
			return TRUE;
	}
	return FALSE;
}

//
// 是否同一直线通
//
BOOL CSkyblue_LLK_CheatDlg::LineY(int x1,int x2,int y)
{
	if(x1>x2)
	{
		int x=x1;
		x1=x2;
		x2=x;
	}
	for(int x=x1;x<=x2;x++)
	{
		if(m_map[y*m_nCol+x]!=BLANK_STATE)
			return FALSE;
		if(x==x2)
			return TRUE;
	}
	return FALSE;
}

//
//  1直角接口连通
//
BOOL CSkyblue_LLK_CheatDlg::OneCornerLink(int x1, int y1,int x2, int y2)
{
	if(x1>x2)
	{
		int n=x1;
		x1=x2;
		x2=n;
		n=y1;
		y1=y2;
		y2=n;
	}
	if(y2<y1)
	{
		if(LineY(x1+1,x2,y1)&&LineX(x2,y1,y2+1))
			return TRUE;
		if(LineY(x2-1,x1,y2)&&LineX(x1,y2,y1-1))
			return TRUE;
		return FALSE;
	}	
	else
	{
		if(LineY(x1+1,x2,y1)&&LineX(x2,y1,y2-1))
			return TRUE;
		if(LineY(x2-1,x1,y2)&&LineX(x1,y2,y1+1))
			return TRUE;		
		return FALSE;
	}
	return FALSE;
}

//
//  2直角接口连通
//
BOOL CSkyblue_LLK_CheatDlg::TwoCornerLink(int x1, int y1, int x2, int y2)
{
	if(x1>x2)
	{
		int n=x1;
		x1=x2;
		x2=n;
		n=y1;
		y1=y2;
		y2=n;
	}
	//右通
	if(XThrough(x1+1,y1,TRUE)&&XThrough(x2+1,y2,TRUE))
		return TRUE;
	//左通
	if(XThrough(x1-1,y1,FALSE)&&XThrough(x2-1,y2,FALSE))
		return TRUE;
	//上通
	if(YThrough(x1,y1-1,FALSE)&&YThrough(x2,y2-1,FALSE))
		return TRUE;
	//下通
	if(YThrough(x1,y1+1,TRUE)&&YThrough(x2,y2+1,TRUE))
		return TRUE;
	//右
	for(int x=x1+1;x<m_nCol;x++)
	{
		if(m_map[y1*m_nCol+x]!=BLANK_STATE)
			break;
		if(OneCornerLink(x,y1,x2,y2))
			return TRUE;
	}
	//左
	for(x=x1-1;x>-1;x--)
	{
		if(m_map[y1*m_nCol+x]!=BLANK_STATE)
			break;
		if(OneCornerLink(x,y1,x2,y2))
			return TRUE;
	}
	//上
	for(int y=y1-1;y>-1;y--)
	{
		if(m_map[y*m_nCol+x1]!=BLANK_STATE)
			break;
		if(OneCornerLink(x1,y,x2,y2))
			return TRUE;
	}
	//下
	for(y=y1+1;y<m_nRow;y++)
	{
		if(m_map[y*m_nCol+x1]!=BLANK_STATE)
			break;
		if(OneCornerLink(x1,y,x2,y2))
			return TRUE;
	}
	
	return FALSE;
}

BOOL CSkyblue_LLK_CheatDlg::XThrough(int x, int y, BOOL bAdd)
{
	if(bAdd)
	{
		for(int i=x;i<m_nCol;i++)
			if(m_map[y*m_nCol+i]!=BLANK_STATE)
				return FALSE;
	}
	else
	{
		for(int i=0;i<=x;i++)
			if(m_map[y*m_nCol+i]!=BLANK_STATE)
				return FALSE;
	}
	return TRUE;
}

BOOL CSkyblue_LLK_CheatDlg::YThrough(int x, int y,BOOL bAdd)
{
	if(bAdd)
	{
		for(int i=y;i<m_nRow;i++)
			if(m_map[i*m_nCol+x]!=BLANK_STATE)
				return FALSE;
	}
	else
	{
		for(int i=0;i<=y;i++)
			if(m_map[i*m_nCol+x]!=BLANK_STATE)
				return FALSE;
	}
	return TRUE;
}

//
//  判断选中的两个方块是否可以消除
//
BOOL CSkyblue_LLK_CheatDlg::IsLink(int x1, int y1, int x2, int y2)
{
	//X直连方式
	if(x1==x2)
	{
		if(X1_Link_X2(x1,y1,y2))
			return TRUE;
	}
	//Y直连方式
	else if(y1==y2)
	{
		if(Y1_Link_Y2(x1,x2,y1))
			return TRUE;
	}

	//一个转弯直角的联通方式
	if(OneCornerLink(x1,y1,x2,y2))
	{
		return TRUE;
	}
	//两个转弯直角的联通方式
	else if(TwoCornerLink(x1,y1,x2,y2))
	{
		return TRUE;
	}
	return FALSE;
}



//
// 自动找出两个可以连通的方块
//
BOOL CSkyblue_LLK_CheatDlg::Find2Rect(int &x1,int &y1, int &x2, int &y2)
{
	BOOL bFound=FALSE;
	int* pMap=m_map;
	
	//第一个方块从地图的0位置开始
	for(int i=0;i<m_nRow*m_nCol;i++)
	{
		//找到则跳出循环
		if(bFound)
			break;
		//无动物的空格跳过
		if(pMap[i]==BLANK_STATE)
			continue;
		
		//第二个方块从前一个方块的后面开始
		for(int j=i+1;j<m_nRow*m_nCol;j++)
		{
			
			//第二个方块不为空 且与第一个方块的动物相同
			if(pMap[j]!=BLANK_STATE&&pMap[i]==pMap[j])
			{
				//算出对应的虚拟行列位置
				x1=i%m_nCol;
				y1=i/m_nCol;/*+(x1?1:0)*/
				x2=j%m_nCol;
				y2=j/m_nCol;/*+(x2?1:0)*/
				
				//判断是否可以连通
				if(IsLink(x1,y1,x2,y2))
				{
					bFound=TRUE;
					break;
				}
			}
		}			
	}
	
	return bFound;
}

//
//  尝试侵入目标程序
//
BOOL CSkyblue_LLK_CheatDlg::HackIn(CString strWinName)
{
	//进入目标窗口,获取其控制权
	CWnd * m_pWndHack = FindWindow(NULL,strWinName);
	m_hwndHack = m_pWndHack->GetSafeHwnd();
	
	if(m_hwndHack != NULL)
	{
		m_hHackDC = ::GetDC(m_hwndHack);
		
		::GetClientRect(m_hwndHack,&m_DestClientRect);
		//	TextOut(m_hHackDC,100,100,"hi, my name is 007, you have been hacke!!",20);
		
		//拷贝目标程序的画面到本端内存位图
		::BitBlt(m_MemDC,0,0,
			m_DestClientRect.Width(),
			m_DestClientRect.Height(),
			m_hHackDC,0,0,SRCCOPY);
		
		//分析图像并生成本端地图数据
		GenMap();
		
		::ReleaseDC(m_hwndHack, m_hHackDC);

		return TRUE;
	}
	else
	{
		return FALSE;	
	}
	
}



//
// 根据图像分析生成游戏地图
//
void CSkyblue_LLK_CheatDlg::GenMap()
{
	int colorDate;
	int i = 0;

	for(i=0;i<m_nRow*m_nCol;i++)
	{
		//算出对应的虚拟行列位置
		int x=i%m_nCol;
		int y=i/m_nCol;

		colorDate = GetRectData(x,y);
		m_map[i] = colorDate;
	}
}

//
// 分析出位置(x,y)方块的图像类别
//
int CSkyblue_LLK_CheatDlg::GetRectData( int x, int y)
{
	COLORREF colorArray[5];
	int colorDate;


	int basicX,basicY; //该方块的左上角基本位置;
	basicX = x * BLOCK_WIDTH_SIZE;
	basicY =  y* BLOCK_HEIGHT_SIZE;	
	
	//取该方块的5个点判断
/*
	   *
	 * * * 
	   *
*/
	CPoint aPos[5];
	
	aPos[0].x = basicX+BLOCK_WIDTH_SIZE/2;
	aPos[0].y = basicY+BLOCK_HEIGHT_SIZE/2+3;
	aPos[1].x = basicX+BLOCK_WIDTH_SIZE/2;
	aPos[1].y = basicY+BLOCK_HEIGHT_SIZE/2-3;
	
	aPos[2].x = basicX+BLOCK_WIDTH_SIZE/2;
	aPos[2].y = basicY+BLOCK_HEIGHT_SIZE/2;
	
	aPos[3].x = basicX+BLOCK_WIDTH_SIZE/2+3;
	aPos[3].y = basicY+BLOCK_HEIGHT_SIZE/2;
	aPos[4].x = basicX+BLOCK_WIDTH_SIZE/2-3;
	aPos[4].y = basicY+BLOCK_HEIGHT_SIZE/2;
	
	
	int xPos, yPos;//坐标位置	
	for( int i=0; i< 5; i++)
	{
		xPos = aPos[i].x;
		yPos= aPos[i].y;
		//记录5个象素值
		colorArray[i]= GetPixel(m_MemDC,xPos,yPos);
	}
	

	int nSameCount = 0;
	for(i=0; i<4; i++)
	{	
		//将方块中采样的5个点的象素值累加
		colorDate += colorArray[i];	

		if(colorArray[i] == colorArray[i+1] &&
			colorArray[i] == RGB(128,128,128))
		{
			nSameCount++;
		}	
	}

	//判断是不是空白方块	
	//如果超过3点相同,则是背景
	if(nSameCount>=3)
	{
		return BLANK_STATE;
	}	
	
	return colorDate;
}


//
//  作弊按钮消息处理
//
void CSkyblue_LLK_CheatDlg::OnButtonHack() 
{
	Hack();	
}

//
//  一次完整的入侵攻击操作
//
void CSkyblue_LLK_CheatDlg::Hack(void)
{
	//操作成功判断记录值
	BOOL bOk; 

	//入侵获取目标程序控制权
	//目标程序名称
	CString strWinName = "skyblue 连连看";
	bOk = HackIn(strWinName);	
	if(!bOk)
	{
		MessageBox("获取失败,目标游戏可能没有运行");
		return;
	}
	
	//分析寻找一组可销的方块
	int x1,y1,x2,y2;
	bOk = Find2Rect(x1, y1, x2, y2);	
	if(!bOk)
	{
		MessageBox("找不到一组可销方块,可能游戏已经胜利");	
		return;
	}

	//根据标记选择作弊的功能	
	if(m_bAutoKick)
	{
		//远端销除找到的两个可连通方块			
		RemoteButtonKick(x1,y1,x2,y2);
	}
	else
	{
		//在本端以及目标程序端绘制提示图像		
		Local_RemoteHintDraw(x1,y1,x2,y2);
	}
}

//
// 在本端以及目标程序端绘制提示图像
//
void CSkyblue_LLK_CheatDlg::Local_RemoteHintDraw( int x1, int y1, int x2, int y2)
{
		//本端显示找到的两个可连通方块		
		CBrush brush(RGB(255,0,0));
		m_MemDC.SelectObject(&brush);
		//标记方块1
		m_MemDC.Ellipse(x1*FRONTWIDTH,y1*FRONTHEIGHT,
			x1*FRONTWIDTH+20,y1*FRONTHEIGHT+20);
		//标记方块2			
		m_MemDC.Ellipse(x2*FRONTWIDTH,y2*FRONTHEIGHT,
			x2*FRONTWIDTH+20,y2*FRONTHEIGHT+20);	
		Invalidate(FALSE);

		//目标程序的绘图实现
		m_hHackDC = ::GetDC(m_hwndHack);
		SelectObject(m_hHackDC,brush.m_hObject);
		Ellipse(m_hHackDC,x1*FRONTWIDTH,y1*FRONTHEIGHT,
			x1*FRONTWIDTH+20,y1*FRONTHEIGHT+20);
		Ellipse(m_hHackDC,x2*FRONTWIDTH,y2*FRONTHEIGHT,
			x2*FRONTWIDTH+20,y2*FRONTHEIGHT+20);
}

//
//  模拟远端程序的鼠标点击
//
void CSkyblue_LLK_CheatDlg::RemoteButtonKick( int x1, int y1, int x2, int y2)
{
		int DestX,DestY;				
		//发送鼠标DOWN的消息
		DestX =  x1*FRONTWIDTH +FRONTWIDTH/2;
		DestY = y1*FRONTHEIGHT + FRONTHEIGHT/2;
		//鼠标点击的坐标
		LPARAM lParam = MAKELPARAM(DestX,DestY);
		::SendMessage(m_hwndHack,WM_LBUTTONDOWN,MK_LBUTTON,lParam);
		::SendMessage(m_hwndHack,WM_LBUTTONUP,MK_LBUTTON,lParam);
		
		DestX =  x2*FRONTWIDTH +FRONTWIDTH/2;
		DestY = y2*FRONTHEIGHT + FRONTHEIGHT/2;
		//鼠标点击的坐标
		lParam = MAKELPARAM(DestX,DestY);
		::SendMessage(m_hwndHack,WM_LBUTTONDOWN,MK_LBUTTON,lParam);
		::SendMessage(m_hwndHack,WM_LBUTTONUP,MK_LBUTTON,lParam);
		
		Invalidate(FALSE);
}

//
//  配置修改按钮 "远端自动销行"or"本端显示"
//
void CSkyblue_LLK_CheatDlg::OnButtonAutoKick() 
{
	//取反,修改原来配置
	m_bAutoKick = !m_bAutoKick;	

	CString btHackSelectInfo;
	CString btHackInfo;
	if(m_bAutoKick)
	{
		btHackSelectInfo = "(&S)屏蔽自动销块功能";
		btHackInfo = "(&H)销除一组可销方块";
	}
	else
	{
		btHackSelectInfo = "(&S)启动自动销块功能";
		btHackInfo = "(&H)获取一组可销方块";
	}

	//根据修改后的值设置按钮的提示
	SetDlgItemText(IDC_BT_AUTO_KICK,btHackSelectInfo);
	SetDlgItemText(IDC_BT_HACK,btHackInfo);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -