~QQ新版对对碰游戏外挂的制作方法~

来源:互联网 发布:matlab约束粒子群算法 编辑:程序博客网 时间:2024/04/30 15:18

  这段时间休假在家,无聊的时候玩了会qq的对对碰游戏,以前用过网友阿东的qq对对碰外挂,但是阿东的外挂在对对碰游戏改版后好像不好使了,正好自己也想重新写一个,于是开始动手。
.思路
1.
获取游戏窗体句柄。
  
这个很简单,FindWindow()即可

2.获得游戏的每一个动物单元的信息,说白了就是获取游戏窗口的颜色值。
  
这个稍微麻烦点,获得游戏区域的起始点坐标(第一个动物单元的左上角),我在window自带的画图里可以得到是(269, 95)qq游戏作者这次耍了个花招,最外层的动物单元的宽高比原来要少一个像素,所以有些外挂获取颜色时会导致出现偏差所以失效,就是因为这个才导致一些旧的外挂不能正常运行。具体的每个单元像素值见下图。
    
第一行,最后一行的高要少一个像素
    
第一列,最后一列的宽要少一个像素
有了游戏区域的起始坐标,根据每个单元的高宽可以获取每个动物单元的起始坐标,就开始取每个单元的是什么动物了,我取相对于每个动物单元的左上角的偏移(x12y24)点处的颜色,这个是个体力活,有耐心就行,在画图程序中把图片放大了后,找到不同的七个动物计算每个动物单元取颜色的像素点然后用取颜色工具取其颜色值,但是注意,最外一层的偏移要根据所处位置宽或高相对要少一个像素,程序中取颜色时的偏移也要减去一个像素,得到不同动物的颜色值后就可以开始写程序了。
   (ps:
关于截图:可以用Alt + 截屏键来截取当前窗口,不会把整个屏幕都截下来)

3.遍历每一个动物单元计算能够进行消除的动物单元。
定义一个(8*8)的二维数组,存放每个动物单元的动物属性
enum ANIMALCELL{AC_NONE, AC_CATTLE, AC_MonKEY, AC_CHICK, AC_DOG, AC_FROG, AC_CAT, AC_PANDA};
ANIMALCELL m_arrCells[8][8]; //!< 
动物单元数组

//! 获取指定坐标点的动物信息
/*!
/param[in] pt
坐标点
/return
动物信息
*/
ANIMALCELL CDDBLayout::GetAnimal(CPoint pt)
{
ANIMALCELL ac = AC_NONE;
switch ( ::GetPixel(m_hdc, pt.x, pt.y) )
{
case RGB(248, 244, 240): // 

ac = AC_CATTLE;
break;

case RGB(128, 76, 24): // 猴子
ac = AC_MonKEY;
break;

case RGB(248, 248, 232): // 

ac = AC_CHICK;
break;

case RGB(104, 108, 104): // 

ac = AC_DOG;
break;

case RGB(56, 248, 56): // 
青蛙
ac = AC_FROG;
break;

case RGB(0, 0, 0): // 
熊猫
ac = AC_PANDA;
break;

case RGB(144, 144, 144): // 

ac = AC_CAT;
break;
default:
break;
}

return ac;
}
重点就在上面的参数CPoint pt,由于最外层的动物单元宽或高少一个像素,所以根据行、列情况取颜色时的偏移量X或偏移量Y也要根据情况减少一个像素。

4.根据步骤三得到的动物单元,模拟鼠标操作。
  
得到每一个动物单元的动物并填充完m_arrCells[8][8]里的每个单元后,就可以对m_arrCells[8][8]进行遍历,找到能消除的动物单元就行了。
  
算法部分太长了,就不贴出来了,基本和阿东的类似,是一种比较笨的方法,简单说一下,下面列举了横向的几种(纵向的也类似)能进行消除的情况,相邻的A B 就是可以进行消除的单元。
A A BA 

A B AA

   A
A B A

A B A
  A

    A
A A B

A A B
    A

A
B A A

B A A
A

只要对数组进行遍历,满足上面的情况就表示找到能消除的两个单元。换算成坐标执行ClearUp就行了。
执行消除操作如下,即向游戏窗口发送鼠标消息,此处是直接拿的阿东的代码,注意此处采用的模拟鼠标拖拽的消息,要比直接向两个位置发送单击的消息要好,大家可以想想为什么?
void CDDBUtilEx::ClearUp(CPoint pt1, CPoint pt2)
{
// 
模拟鼠标操作
::PostMessage(m_hTarget, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(pt1.x, pt1.y));
::PostMessage(m_hTarget, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(pt2.x, pt2.y));
Sleep(100);
::PostMessage(m_hTarget, WM_LBUTTONUP, 0, MAKELPARAM(pt2.x, pt2.y));
}

关键的地方就这么多了,程序虽小,我在程序中仍用了两个类,
分别是CDDBUtilEx CDDBLayout
CDDBLayout
负责取颜色、坐标换算、算法相关部分的核心工作
CDDBUtilEx
只是使用CDDBLayout类进行工作,并向外界(对话框)提供外挂功能,CDDBLayout对于外界是透明的,,这样下次如果对对碰游戏再做什么改动的话,只需要修改CDDBLayout内的相关功能,和界面部分不用做任何改动。

附:原来阿东的程序中hook了游戏的sleep()函数,能够提高游戏速度,但是在新的对对碰游戏中我试了hookSleep()函数,却不能提高游戏速度,这一点游戏可能也做了修改。另外,以前的对对碰游戏会判断鼠标消息是来自鼠标硬件还是模拟的鼠标消息来识别玩家是否采用外挂,新版的对对碰游戏却取消了此判断,不知道为了啥?