skyblue_LLK_CheatDlg.cpp
上传用户:hbrsgg1
上传日期:2014-05-08
资源大小:2826k
文件大小:14k
源码类别:

其他智力游戏

开发平台:

C/C++

  1. //
  2. /*++
  3. Copyright (c) AFE(Active-Free-Elegance)
  4. Module Name:
  5.     skyblue_LLK_CheatDlg.cpp
  6. Abstract:
  7. the game's cheating-kernal-solving Dialog class
  8. Author:
  9.     Weijian Luo (Arthur Luo)   15-Jun-2005
  10. E-mail: skybluehacker@yahoo.com.cn
  11. Revision History:      1.0
  12. --*/
  13. #include "stdafx.h"
  14. #include "skyblue_LLK_Cheat.h"
  15. #include "skyblue_LLK_CheatDlg.h"
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. #define BKCOLOR         RGB(128,128,128) //背景颜色
  22. #define FRONTWIDTH     (39+2)     //前面方块的宽度
  23. #define FRONTHEIGHT     (39+12)     //前面方块的高度
  24. #define BKWIDTH         46 //背景方块的宽度
  25. #define BKHEIGHT        56 //背景方块的高度
  26. #define ROWCOUNT        7 //行数
  27. #define COLCOUNT        12 //列数
  28. #define BLANK_STATE     -1                  //空方块(没有任何动物)
  29. #define INVALID_POS     -1                  //无效坐标位置
  30. #define BLOCK_WIDTH_SIZE         (39+2) //背景方块的宽度
  31. #define BLOCK_HEIGHT_SIZE        (39+12) //背景方块的高度
  32. /////////////////////////////////////////////////////////////////////////////
  33. // CSkyblue_LLK_CheatDlg dialog
  34. CSkyblue_LLK_CheatDlg::CSkyblue_LLK_CheatDlg(CWnd* pParent /*=NULL*/)
  35. : CDialog(CSkyblue_LLK_CheatDlg::IDD, pParent)
  36. {
  37. //{{AFX_DATA_INIT(CSkyblue_LLK_CheatDlg)
  38. // NOTE: the ClassWizard will add member initialization here
  39. //}}AFX_DATA_INIT
  40. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  41. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  42. //记录方块置为无效状态
  43. m_nY1= INVALID_POS;
  44. m_nX1= INVALID_POS;
  45. //初始化行列数
  46. m_nRow=ROWCOUNT;
  47. m_nCol=COLCOUNT;
  48. m_hHackDC = NULL; 
  49. m_hwndHack = NULL;
  50. //不是自动作弊(控制目标程序销方块
  51. m_bAutoKick = FALSE;
  52. //根据行列数动态分配内核数据数组空间
  53. m_map=new int[m_nRow*m_nCol];
  54. }
  55. void CSkyblue_LLK_CheatDlg::DoDataExchange(CDataExchange* pDX)
  56. {
  57. CDialog::DoDataExchange(pDX);
  58. //{{AFX_DATA_MAP(CSkyblue_LLK_CheatDlg)
  59. // NOTE: the ClassWizard will add DDX and DDV calls here
  60. //}}AFX_DATA_MAP
  61. }
  62. BEGIN_MESSAGE_MAP(CSkyblue_LLK_CheatDlg, CDialog)
  63. //{{AFX_MSG_MAP(CSkyblue_LLK_CheatDlg)
  64. ON_WM_PAINT()
  65. ON_WM_QUERYDRAGICON()
  66. ON_BN_CLICKED(IDC_BT_HACK, OnButtonHack)
  67. ON_BN_CLICKED(IDC_BT_AUTO_KICK, OnButtonAutoKick)
  68. //}}AFX_MSG_MAP
  69. END_MESSAGE_MAP()
  70. /////////////////////////////////////////////////////////////////////////////
  71. // CSkyblue_LLK_CheatDlg message handlers
  72. BOOL CSkyblue_LLK_CheatDlg::OnInitDialog()
  73. {
  74. CDialog::OnInitDialog();
  75. // Set the icon for this dialog.  The framework does this automatically
  76. //  when the application's main window is not a dialog
  77. SetIcon(m_hIcon, TRUE); // Set big icon
  78. SetIcon(m_hIcon, FALSE); // Set small icon
  79. //获取程序框架的设备环境
  80. CDC *pWinDC = GetDC();
  81. //整个游戏区域内存位图
  82. m_MemDC.CreateCompatibleDC(pWinDC);
  83. m_memBitmap.CreateCompatibleBitmap(pWinDC,m_nCol*FRONTWIDTH+5,m_nRow*FRONTHEIGHT+5);
  84. m_MemDC.SelectObject(&m_memBitmap);
  85. return TRUE;  // return TRUE  unless you set the focus to a control
  86. }
  87. // If you add a minimize button to your dialog, you will need the code below
  88. //  to draw the icon.  For MFC applications using the document/view model,
  89. //  this is automatically done for you by the framework.
  90. void CSkyblue_LLK_CheatDlg::OnPaint() 
  91. {
  92. CPaintDC dc(this); 
  93. dc.BitBlt(30,70,               //在对话框的偏移位置
  94. m_DestClientRect.Width(),  //图像宽度
  95. m_DestClientRect.Height(), //图像高度
  96. &m_MemDC                   //来源于与内存设备环境关联的内存位图
  97. ,0,0,SRCCOPY               //0偏移拷贝
  98. );
  99. }
  100. // The system calls this to obtain the cursor to display while the user drags
  101. //  the minimized window.
  102. HCURSOR CSkyblue_LLK_CheatDlg::OnQueryDragIcon()
  103. {
  104. return (HCURSOR) m_hIcon;
  105. }
  106. //
  107. //X直接连通
  108. //
  109. BOOL CSkyblue_LLK_CheatDlg::X1_Link_X2(int x, int y1,int y2)
  110. {
  111. //保证y1的值小于y2
  112. if(y1>y2)
  113. {
  114. //数据交换
  115. int n=y1;
  116. y1=y2;
  117. y2=n;
  118. }
  119. //直通 
  120. for(int i=y1+1;i<=y2;i++)
  121. {
  122. if(i==y2)
  123. return TRUE;
  124. if(m_map[i*m_nCol+x]!=BLANK_STATE)
  125. break;
  126. }
  127. //左通
  128. if(XThrough(x-1,y1,FALSE)&&XThrough(x-1,y2,FALSE))
  129. return TRUE;
  130. //右通
  131. if(XThrough(x+1,y1,TRUE)&&XThrough(x+1,y2,TRUE))
  132. return TRUE;
  133. return FALSE;
  134. }
  135. //
  136. //Y直接连通
  137. //
  138. BOOL CSkyblue_LLK_CheatDlg::Y1_Link_Y2(int x1,int x2,int y)
  139. {
  140. if(x1>x2)
  141. {
  142. int x=x1;
  143. x1=x2;
  144. x2=x;
  145. }
  146. //直通
  147. for(int i=x1+1;i<=x2;i++)
  148. {
  149. if(i==x2)
  150. return TRUE;
  151. if(m_map[y*m_nCol+i]!=BLANK_STATE)
  152. break;
  153. }
  154. //上通
  155. if(YThrough(x1,y-1,FALSE)&&YThrough(x2,y-1,FALSE))
  156. return TRUE;
  157. //下通
  158. if(YThrough(x1,y+1,TRUE)&&YThrough(x2,y+1,TRUE))
  159. return TRUE;
  160. return FALSE;
  161. }
  162. //
  163. // 是否同一直线通
  164. //
  165. BOOL CSkyblue_LLK_CheatDlg::LineX(int x,int y1,int y2)
  166. {
  167. if(y1>y2)
  168. {
  169. int y=y1;
  170. y1=y2;
  171. y2=y;
  172. }
  173. for(int y=y1;y<=y2;y++)
  174. {
  175. if(m_map[y*m_nCol+x]!=BLANK_STATE)
  176. return FALSE;
  177. if(y==y2)
  178. return TRUE;
  179. }
  180. return FALSE;
  181. }
  182. //
  183. // 是否同一直线通
  184. //
  185. BOOL CSkyblue_LLK_CheatDlg::LineY(int x1,int x2,int y)
  186. {
  187. if(x1>x2)
  188. {
  189. int x=x1;
  190. x1=x2;
  191. x2=x;
  192. }
  193. for(int x=x1;x<=x2;x++)
  194. {
  195. if(m_map[y*m_nCol+x]!=BLANK_STATE)
  196. return FALSE;
  197. if(x==x2)
  198. return TRUE;
  199. }
  200. return FALSE;
  201. }
  202. //
  203. //  1直角接口连通
  204. //
  205. BOOL CSkyblue_LLK_CheatDlg::OneCornerLink(int x1, int y1,int x2, int y2)
  206. {
  207. if(x1>x2)
  208. {
  209. int n=x1;
  210. x1=x2;
  211. x2=n;
  212. n=y1;
  213. y1=y2;
  214. y2=n;
  215. }
  216. if(y2<y1)
  217. {
  218. if(LineY(x1+1,x2,y1)&&LineX(x2,y1,y2+1))
  219. return TRUE;
  220. if(LineY(x2-1,x1,y2)&&LineX(x1,y2,y1-1))
  221. return TRUE;
  222. return FALSE;
  223. }
  224. else
  225. {
  226. if(LineY(x1+1,x2,y1)&&LineX(x2,y1,y2-1))
  227. return TRUE;
  228. if(LineY(x2-1,x1,y2)&&LineX(x1,y2,y1+1))
  229. return TRUE;
  230. return FALSE;
  231. }
  232. return FALSE;
  233. }
  234. //
  235. //  2直角接口连通
  236. //
  237. BOOL CSkyblue_LLK_CheatDlg::TwoCornerLink(int x1, int y1, int x2, int y2)
  238. {
  239. if(x1>x2)
  240. {
  241. int n=x1;
  242. x1=x2;
  243. x2=n;
  244. n=y1;
  245. y1=y2;
  246. y2=n;
  247. }
  248. //右通
  249. if(XThrough(x1+1,y1,TRUE)&&XThrough(x2+1,y2,TRUE))
  250. return TRUE;
  251. //左通
  252. if(XThrough(x1-1,y1,FALSE)&&XThrough(x2-1,y2,FALSE))
  253. return TRUE;
  254. //上通
  255. if(YThrough(x1,y1-1,FALSE)&&YThrough(x2,y2-1,FALSE))
  256. return TRUE;
  257. //下通
  258. if(YThrough(x1,y1+1,TRUE)&&YThrough(x2,y2+1,TRUE))
  259. return TRUE;
  260. //右
  261. for(int x=x1+1;x<m_nCol;x++)
  262. {
  263. if(m_map[y1*m_nCol+x]!=BLANK_STATE)
  264. break;
  265. if(OneCornerLink(x,y1,x2,y2))
  266. return TRUE;
  267. }
  268. //左
  269. for(x=x1-1;x>-1;x--)
  270. {
  271. if(m_map[y1*m_nCol+x]!=BLANK_STATE)
  272. break;
  273. if(OneCornerLink(x,y1,x2,y2))
  274. return TRUE;
  275. }
  276. //上
  277. for(int y=y1-1;y>-1;y--)
  278. {
  279. if(m_map[y*m_nCol+x1]!=BLANK_STATE)
  280. break;
  281. if(OneCornerLink(x1,y,x2,y2))
  282. return TRUE;
  283. }
  284. //下
  285. for(y=y1+1;y<m_nRow;y++)
  286. {
  287. if(m_map[y*m_nCol+x1]!=BLANK_STATE)
  288. break;
  289. if(OneCornerLink(x1,y,x2,y2))
  290. return TRUE;
  291. }
  292. return FALSE;
  293. }
  294. BOOL CSkyblue_LLK_CheatDlg::XThrough(int x, int y, BOOL bAdd)
  295. {
  296. if(bAdd)
  297. {
  298. for(int i=x;i<m_nCol;i++)
  299. if(m_map[y*m_nCol+i]!=BLANK_STATE)
  300. return FALSE;
  301. }
  302. else
  303. {
  304. for(int i=0;i<=x;i++)
  305. if(m_map[y*m_nCol+i]!=BLANK_STATE)
  306. return FALSE;
  307. }
  308. return TRUE;
  309. }
  310. BOOL CSkyblue_LLK_CheatDlg::YThrough(int x, int y,BOOL bAdd)
  311. {
  312. if(bAdd)
  313. {
  314. for(int i=y;i<m_nRow;i++)
  315. if(m_map[i*m_nCol+x]!=BLANK_STATE)
  316. return FALSE;
  317. }
  318. else
  319. {
  320. for(int i=0;i<=y;i++)
  321. if(m_map[i*m_nCol+x]!=BLANK_STATE)
  322. return FALSE;
  323. }
  324. return TRUE;
  325. }
  326. //
  327. //  判断选中的两个方块是否可以消除
  328. //
  329. BOOL CSkyblue_LLK_CheatDlg::IsLink(int x1, int y1, int x2, int y2)
  330. {
  331. //X直连方式
  332. if(x1==x2)
  333. {
  334. if(X1_Link_X2(x1,y1,y2))
  335. return TRUE;
  336. }
  337. //Y直连方式
  338. else if(y1==y2)
  339. {
  340. if(Y1_Link_Y2(x1,x2,y1))
  341. return TRUE;
  342. }
  343. //一个转弯直角的联通方式
  344. if(OneCornerLink(x1,y1,x2,y2))
  345. {
  346. return TRUE;
  347. }
  348. //两个转弯直角的联通方式
  349. else if(TwoCornerLink(x1,y1,x2,y2))
  350. {
  351. return TRUE;
  352. }
  353. return FALSE;
  354. }
  355. //
  356. // 自动找出两个可以连通的方块
  357. //
  358. BOOL CSkyblue_LLK_CheatDlg::Find2Rect(int &x1,int &y1, int &x2, int &y2)
  359. {
  360. BOOL bFound=FALSE;
  361. int* pMap=m_map;
  362. //第一个方块从地图的0位置开始
  363. for(int i=0;i<m_nRow*m_nCol;i++)
  364. {
  365. //找到则跳出循环
  366. if(bFound)
  367. break;
  368. //无动物的空格跳过
  369. if(pMap[i]==BLANK_STATE)
  370. continue;
  371. //第二个方块从前一个方块的后面开始
  372. for(int j=i+1;j<m_nRow*m_nCol;j++)
  373. {
  374. //第二个方块不为空 且与第一个方块的动物相同
  375. if(pMap[j]!=BLANK_STATE&&pMap[i]==pMap[j])
  376. {
  377. //算出对应的虚拟行列位置
  378. x1=i%m_nCol;
  379. y1=i/m_nCol;/*+(x1?1:0)*/
  380. x2=j%m_nCol;
  381. y2=j/m_nCol;/*+(x2?1:0)*/
  382. //判断是否可以连通
  383. if(IsLink(x1,y1,x2,y2))
  384. {
  385. bFound=TRUE;
  386. break;
  387. }
  388. }
  389. }
  390. }
  391. return bFound;
  392. }
  393. //
  394. //  尝试侵入目标程序
  395. //
  396. BOOL CSkyblue_LLK_CheatDlg::HackIn(CString strWinName)
  397. {
  398. //进入目标窗口,获取其控制权
  399. CWnd * m_pWndHack = FindWindow(NULL,strWinName);
  400. m_hwndHack = m_pWndHack->GetSafeHwnd();
  401. if(m_hwndHack != NULL)
  402. {
  403. m_hHackDC = ::GetDC(m_hwndHack);
  404. ::GetClientRect(m_hwndHack,&m_DestClientRect);
  405. // TextOut(m_hHackDC,100,100,"hi, my name is 007, you have been hacke!!",20);
  406. //拷贝目标程序的画面到本端内存位图
  407. ::BitBlt(m_MemDC,0,0,
  408. m_DestClientRect.Width(),
  409. m_DestClientRect.Height(),
  410. m_hHackDC,0,0,SRCCOPY);
  411. //分析图像并生成本端地图数据
  412. GenMap();
  413. ::ReleaseDC(m_hwndHack, m_hHackDC);
  414. return TRUE;
  415. }
  416. else
  417. {
  418. return FALSE;
  419. }
  420. }
  421. //
  422. // 根据图像分析生成游戏地图
  423. //
  424. void CSkyblue_LLK_CheatDlg::GenMap()
  425. {
  426. int colorDate;
  427. int i = 0;
  428. for(i=0;i<m_nRow*m_nCol;i++)
  429. {
  430. //算出对应的虚拟行列位置
  431. int x=i%m_nCol;
  432. int y=i/m_nCol;
  433. colorDate = GetRectData(x,y);
  434. m_map[i] = colorDate;
  435. }
  436. }
  437. //
  438. // 分析出位置(x,y)方块的图像类别
  439. //
  440. int CSkyblue_LLK_CheatDlg::GetRectData( int x, int y)
  441. {
  442. COLORREF colorArray[5];
  443. int colorDate;
  444. int basicX,basicY; //该方块的左上角基本位置;
  445. basicX = x * BLOCK_WIDTH_SIZE;
  446. basicY =  y* BLOCK_HEIGHT_SIZE;
  447. //取该方块的5个点判断
  448. /*
  449.    *
  450.  * * * 
  451.    *
  452. */
  453. CPoint aPos[5];
  454. aPos[0].x = basicX+BLOCK_WIDTH_SIZE/2;
  455. aPos[0].y = basicY+BLOCK_HEIGHT_SIZE/2+3;
  456. aPos[1].x = basicX+BLOCK_WIDTH_SIZE/2;
  457. aPos[1].y = basicY+BLOCK_HEIGHT_SIZE/2-3;
  458. aPos[2].x = basicX+BLOCK_WIDTH_SIZE/2;
  459. aPos[2].y = basicY+BLOCK_HEIGHT_SIZE/2;
  460. aPos[3].x = basicX+BLOCK_WIDTH_SIZE/2+3;
  461. aPos[3].y = basicY+BLOCK_HEIGHT_SIZE/2;
  462. aPos[4].x = basicX+BLOCK_WIDTH_SIZE/2-3;
  463. aPos[4].y = basicY+BLOCK_HEIGHT_SIZE/2;
  464. int xPos, yPos;//坐标位置
  465. for( int i=0; i< 5; i++)
  466. {
  467. xPos = aPos[i].x;
  468. yPos= aPos[i].y;
  469. //记录5个象素值
  470. colorArray[i]= GetPixel(m_MemDC,xPos,yPos);
  471. }
  472. int nSameCount = 0;
  473. for(i=0; i<4; i++)
  474. {
  475. //将方块中采样的5个点的象素值累加
  476. colorDate += colorArray[i];
  477. if(colorArray[i] == colorArray[i+1] &&
  478. colorArray[i] == RGB(128,128,128))
  479. {
  480. nSameCount++;
  481. }
  482. }
  483. //判断是不是空白方块
  484. //如果超过3点相同,则是背景
  485. if(nSameCount>=3)
  486. {
  487. return BLANK_STATE;
  488. }
  489. return colorDate;
  490. }
  491. //
  492. //  作弊按钮消息处理
  493. //
  494. void CSkyblue_LLK_CheatDlg::OnButtonHack() 
  495. {
  496. Hack();
  497. }
  498. //
  499. //  一次完整的入侵攻击操作
  500. //
  501. void CSkyblue_LLK_CheatDlg::Hack(void)
  502. {
  503. //操作成功判断记录值
  504. BOOL bOk; 
  505. //入侵获取目标程序控制权
  506. //目标程序名称
  507. CString strWinName = "skyblue 连连看";
  508. bOk = HackIn(strWinName);
  509. if(!bOk)
  510. {
  511. MessageBox("获取失败,目标游戏可能没有运行");
  512. return;
  513. }
  514. //分析寻找一组可销的方块
  515. int x1,y1,x2,y2;
  516. bOk = Find2Rect(x1, y1, x2, y2);
  517. if(!bOk)
  518. {
  519. MessageBox("找不到一组可销方块,可能游戏已经胜利");
  520. return;
  521. }
  522. //根据标记选择作弊的功能
  523. if(m_bAutoKick)
  524. {
  525. //远端销除找到的两个可连通方块
  526. RemoteButtonKick(x1,y1,x2,y2);
  527. }
  528. else
  529. {
  530. //在本端以及目标程序端绘制提示图像
  531. Local_RemoteHintDraw(x1,y1,x2,y2);
  532. }
  533. }
  534. //
  535. // 在本端以及目标程序端绘制提示图像
  536. //
  537. void CSkyblue_LLK_CheatDlg::Local_RemoteHintDraw( int x1, int y1, int x2, int y2)
  538. {
  539. //本端显示找到的两个可连通方块
  540. CBrush brush(RGB(255,0,0));
  541. m_MemDC.SelectObject(&brush);
  542. //标记方块1
  543. m_MemDC.Ellipse(x1*FRONTWIDTH,y1*FRONTHEIGHT,
  544. x1*FRONTWIDTH+20,y1*FRONTHEIGHT+20);
  545. //标记方块2
  546. m_MemDC.Ellipse(x2*FRONTWIDTH,y2*FRONTHEIGHT,
  547. x2*FRONTWIDTH+20,y2*FRONTHEIGHT+20);
  548. Invalidate(FALSE);
  549. //目标程序的绘图实现
  550. m_hHackDC = ::GetDC(m_hwndHack);
  551. SelectObject(m_hHackDC,brush.m_hObject);
  552. Ellipse(m_hHackDC,x1*FRONTWIDTH,y1*FRONTHEIGHT,
  553. x1*FRONTWIDTH+20,y1*FRONTHEIGHT+20);
  554. Ellipse(m_hHackDC,x2*FRONTWIDTH,y2*FRONTHEIGHT,
  555. x2*FRONTWIDTH+20,y2*FRONTHEIGHT+20);
  556. }
  557. //
  558. //  模拟远端程序的鼠标点击
  559. //
  560. void CSkyblue_LLK_CheatDlg::RemoteButtonKick( int x1, int y1, int x2, int y2)
  561. {
  562. int DestX,DestY;
  563. //发送鼠标DOWN的消息
  564. DestX =  x1*FRONTWIDTH +FRONTWIDTH/2;
  565. DestY = y1*FRONTHEIGHT + FRONTHEIGHT/2;
  566. //鼠标点击的坐标
  567. LPARAM lParam = MAKELPARAM(DestX,DestY);
  568. ::SendMessage(m_hwndHack,WM_LBUTTONDOWN,MK_LBUTTON,lParam);
  569. ::SendMessage(m_hwndHack,WM_LBUTTONUP,MK_LBUTTON,lParam);
  570. DestX =  x2*FRONTWIDTH +FRONTWIDTH/2;
  571. DestY = y2*FRONTHEIGHT + FRONTHEIGHT/2;
  572. //鼠标点击的坐标
  573. lParam = MAKELPARAM(DestX,DestY);
  574. ::SendMessage(m_hwndHack,WM_LBUTTONDOWN,MK_LBUTTON,lParam);
  575. ::SendMessage(m_hwndHack,WM_LBUTTONUP,MK_LBUTTON,lParam);
  576. Invalidate(FALSE);
  577. }
  578. //
  579. //  配置修改按钮 "远端自动销行"or"本端显示"
  580. //
  581. void CSkyblue_LLK_CheatDlg::OnButtonAutoKick() 
  582. {
  583. //取反,修改原来配置
  584. m_bAutoKick = !m_bAutoKick;
  585. CString btHackSelectInfo;
  586. CString btHackInfo;
  587. if(m_bAutoKick)
  588. {
  589. btHackSelectInfo = "(&S)屏蔽自动销块功能";
  590. btHackInfo = "(&H)销除一组可销方块";
  591. }
  592. else
  593. {
  594. btHackSelectInfo = "(&S)启动自动销块功能";
  595. btHackInfo = "(&H)获取一组可销方块";
  596. }
  597. //根据修改后的值设置按钮的提示
  598. SetDlgItemText(IDC_BT_AUTO_KICK,btHackSelectInfo);
  599. SetDlgItemText(IDC_BT_HACK,btHackInfo);
  600. }