相信经常上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); }
关闭弹出来的人满对话框,有三种方法:
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); } }

附件中有整个工程以及编译好的可执行文件
本程序使用Dev-C++开发