相信经常上VS对战平台玩游戏的朋友都曾有过下面这样的经历

过程非常痛苦!!!怎么办?难道花钱充VIP?做个RMB玩家固然感觉非常好,但stalker还是个学生,没有收入,把父母的血汗钱花到游戏上,实在不忍心。
于是想到用按键精灵写一个脚本,虽然能代替手工操作,但生成小精灵广告频弹,非常不爽。stalker一直很讨厌广告,并不是因为广告烦人,而是因为自己没有钱购买广告中的商品
恰好最近正在学习C++程序设计,于是打算自己动手开发一个程序,取代那令人纠结的小精灵。
首先我设计了一个类,如下

代码:
//SimulatingActions.h

class SimulatingActions

{

      public:

             void MouseDown(bool bLeftRight);

             void MouseUp(bool bLeftRight);

             void MouseClick(bool bLeftRight);

             void MouseDbClick(bool bLeftRight);

             void KeyDown(char vKey);

             void KeyUp(char vKey);

             void KeyHit(char vKey);

             

};

从类的成员函数名称,很容易看出它们的作用
前四个成员函数,分别模拟鼠标按键的按下,弹起,单击和双击动作,参数bLeftRight用于指示模拟左键还是右键动作(设计时没有考虑滚轮^_^)。
后三个成员函数,分别模拟键盘键的按下,弹起和击键动作(stalker对击键动作的定义是:键被按下并弹起),参数vKey用于指定具体的键。

设计完成之后,就剩下具体的实现,众所周知,模拟鼠标和键盘动作可以用Windows API mouse_event,keybd_event和SendInput。由于前面两个函数比较古老,stalker选择了二者功能兼备的SendInput。
具体代码如下,由于本人初学C++,编码可能有很多不好的地方,还希望大家能多指教!
代码:
//SimulatingActions.cpp

#define _WIN32_WINNT 0x0500

#include<windows.h>

#include"SimulatingActions.h"



void SimulatingActions::MouseDown(bool bLeftRight)

{

     INPUT myinput;

     MOUSEINPUT mymi;

     POINT mypoint;

     GetCursorPos(&mypoint);

     mymi.dx = mypoint.x;

     mymi.dy = mypoint.y;

     mymi.mouseData = 0;

     mymi.dwFlags = MOUSEEVENTF_LEFTDOWN;

     mymi.time = 0;

     mymi.dwExtraInfo = GetMessageExtraInfo();

     if(bLeftRight)

         mymi.dwFlags = MOUSEEVENTF_RIGHTDOWN;

     myinput.type = INPUT_MOUSE;

     myinput.mi = mymi;

     SendInput(1,&myinput,sizeof(INPUT));

     

}



void SimulatingActions::MouseUp(bool bLeftRight)

{

     INPUT myinput;

     MOUSEINPUT mymi;

     POINT mypoint;

     GetCursorPos(&mypoint);

     mymi.dx = mypoint.x;

     mymi.dy = mypoint.y;

     mymi.mouseData = 0;

     mymi.dwFlags = MOUSEEVENTF_LEFTUP;

     mymi.time = 0;

     mymi.dwExtraInfo = GetMessageExtraInfo();

     if(bLeftRight)

         mymi.dwFlags = MOUSEEVENTF_RIGHTUP;

     myinput.type = INPUT_MOUSE;

     myinput.mi = mymi;

     SendInput(1,&myinput,sizeof(INPUT));

     

}



void SimulatingActions::MouseClick(bool bLeftRight)

{

     MouseDown(bLeftRight);

     MouseUp(bLeftRight);

}



void SimulatingActions::MouseDbClick(bool bLeftRight)

{

     MouseClick(bLeftRight);

     MouseClick(bLeftRight);

}



void SimulatingActions::KeyDown(char vKey)

{

     INPUT myinput;

     KEYBDINPUT myki;

     myki.wVk = vKey;

     myki.wScan = MapVirtualKey(vKey,0);

     myki.dwFlags = KEYEVENTF_EXTENDEDKEY;

     myki.time = 0;

     myki.dwExtraInfo = GetMessageExtraInfo();

     myinput.type = INPUT_KEYBOARD;

     myinput.ki = myki;

     SendInput(1,&myinput,sizeof(INPUT));

     

}



void SimulatingActions::KeyUp(char vKey)

{

     INPUT myinput;

     KEYBDINPUT myki;

     myki.wVk = vKey;

     myki.wScan = MapVirtualKey(vKey,0);

     myki.dwFlags = KEYEVENTF_KEYUP;

     myki.time = 0;

     myki.dwExtraInfo = GetMessageExtraInfo();

     myinput.type = INPUT_KEYBOARD;

     myinput.ki = myki;

     SendInput(1,&myinput,sizeof(INPUT));

     

}



void SimulatingActions::KeyHit(char vKey)

{

     KeyDown(vKey);

     KeyUp(vKey);

}

在VS对战平台中,进入一个房间的操作非常简单,就是双击想要进入的房间,而挤房的操作就是不停的双击,如果弹出人满对话框,关闭之,继续双击,如此循环反复,直到进入该房间为止。
关闭弹出来的人满对话框,有三种方法:
1.按ESC键
2.按ALT+F4组合键
3.移动鼠标点对话框右上角的X
其中方法3最难,我选择了最简单的方法1

最后的主程序如下
代码:
#include<windows.h>

#include"SimulatingActions.h"

DWORD WINAPI ThreadProc(LPVOID lpParameter);



int WINAPI WinMain(HINSTANCE a,HINSTANCE b,LPSTR c,int d)

{

        bool bSwitch = true;

        SHORT s1,s2,s3;

        HANDLE hThread,hMutex; 

        //判断程序是否已经运行,如果已经运行则退出 

        CreateMutex(NULL,false,"specialmutexofstalker");

        if(ERROR_ALREADY_EXISTS == GetLastError())

        {

            MessageBox(NULL,"Program already run!","Information",MB_ICONERROR);

            ExitProcess(0);

        } 

        while(true)

        {

             s1 = GetKeyState(VK_CONTROL);

             s1 >>= (sizeof(SHORT)*8 - 1);

             s2 = GetKeyState(VK_SHIFT);

             s2 >>= (sizeof(SHORT)*8 - 1);

             s3 = GetKeyState('Q');

             s3 >>= (sizeof(SHORT)*8 - 1);

             //Ctrl+Shift+Q被按下,则退出程序 

             if(s1&&s2&&s3)

                 ExitProcess(0);

             s1 = GetKeyState(VK_CONTROL);

             s2 = GetKeyState('P');

             s1 >>= (sizeof(SHORT)*8 - 1);

             s2 >>= (sizeof(SHORT)*8 - 1);

             //Ctrl+P被按下,停止动作 ,并设置bSwitch为true,

             //否则程序将不能再创建模拟动作线程 

             if(s1&&s2&&(!bSwitch))

             {

                 TerminateThread(hThread,0);

                 bSwitch = true;

             }

             s1 = GetKeyState(VK_CONTROL);

             s2 = GetKeyState('S');

             s1 >>= (sizeof(SHORT)*8 - 1);

             s2 >>= (sizeof(SHORT)*8 - 1);

             //Ctrl+S被按下,开始动作,并设置bSwitch为false,

             //防止程序创建多个线程             

             if(s1&&s2&&bSwitch)

             {

                 hThread = CreateThread(NULL,0,&ThreadProc,NULL,0,NULL);

                 if(NULL != hThread)

                     bSwitch = false;

             }

             Sleep(100);

        }

        return 0;

}



DWORD WINAPI ThreadProc(LPVOID lpParameter)

{

      SimulatingActions mySA;

      while(true)

      {

          mySA.MouseDbClick(0);

          Sleep(500);

          mySA.KeyHit(VK_ESCAPE);

      }

}

在程序中我没有使用热键,而是使用GetKeyState函数判断键的状态来控制程序的行为,这样做有一个缺点,就是不太灵敏,但也有优点,就是不用担心热键已经被其他程序注册
附件中有整个工程以及编译好的可执行文件
本程序使用Dev-C++开发
上传的附件 source.rar

  • 标 题:VS竞技游戏平台后台挤房的实现
  • 作 者:stalker
  • 时 间:2010-01-30 00:00:18

想要实现后台挤房,就不能再用SendInput来模拟鼠标动作。我们运行VS竞技游戏平台,spy lite表窗口的信息,如下图所示

是一个ListView窗口,直接对该窗口发送WM_LBUTTONDBLCLK消息即可取代以前的
方法实现后台挤房,大概过程如下

使用Spy Lite和MS的Spy++可以得到如下的窗口层次结构:
VS竞技游戏平台主窗口-->窗口1(CtlID0x49A)-->窗口2(CtlID0x483)-->窗口3(CtlID0x47B)-->目标窗口(CtlID0x1F6)

VS主窗体句柄可以通过枚举窗体并判断标题是否包含"VS竞技游戏平台"字符串获得
如何判断已经成功进入房间这个问题比较棘手,我们首先来对比一下进入房
间前后vs界面上的差别
进入之前

进入之后

在上图红色圈住的地方有很多window,开始我想可以通过判断其中某个window的Text是否变化来确定是否成功进入房间,结果用spylite一看,那些window的Text无论进入前后都是空串""
最后发现通过判断聊天窗口(同样使用前面提到的工具来获得它与vs主窗体的关系)的text是否为空可以判断是否已经成功进入房间

发一张程序截图


成品
letmeinexe.rar
工程
LetMeIn.rar
stalker的blog:
http://hi.baidu.com/89419883
希望能够认识更多的朋友