所以,我一直在试图使用CGPostMouseEvent,并CGEventPostToPSN发送鼠标点击到Mac的游戏,可惜一直很成功.
我希望有人能够帮助我以不同的方式思考这个问题,或者意识到我所缺少的东西.谷歌没有太多帮助.
我的猜测是因为我试图将点击事件发送到游戏窗口(openGL),而不是普通窗口.
这是我要发送的另一个例子:CGEventRef CGEvent; NSEvent*customEvent; NSPoint位置; location.x = 746; location.y = 509;
customEvent = [NSEvent mouseEventWithType: NSLeftMouseDown location: location modifierFlags: NSLeftMouseDownMask timestamp: time(NULL) windowNumber: windowID context: NULL eventNumber: 0 clickCount: 1 pressure: 0]; CGEvent = [customEvent CGEvent]; CGEventPostToPSN(&psn, CGEvent);
有趣的是,我可以移动鼠标(CGDisplayMoveCursorToPoint(kCGDirectMainDisplay,clickPt);),我只是无法发送任何点击:/
任何帮助将不胜感激.
编辑:这是奇怪的,一旦我使用CGDisplayMoveCursorToPoint移动鼠标,我实际上必须在我甚至可以点击之前将我的鼠标向上或向下移动,这很奇怪.游戏不接受任何输入,除非我向上/向下移动(然后指针改变).
谢谢!
那么你试图构建的是"机器人"或"机器人",它基本上以有序的方式向游戏发送命令.基本上它会像你一样为你效力.这对于那些迫使你玩游戏以收获矿物,商品或任何能让你在游戏中前进的游戏非常有用.这真的很无聊.我已经成功地为一款热门游戏做了这个,虽然我不能提及游戏,因为它打破了所有这些类型的游戏对"机器人"的用户协议.所以要小心你在做什么,因为这可能会破坏你对许多MMPG的用户协议.但是我在这里成功发布了这个,因为Mac有更少的机器人可用,没有我能够研究,与我发现很多的PC相比.所以要平衡比赛场地......这里是代码.我建议将其编译为命令行,并在AppleScript中执行宏(逻辑将驻留在如何模仿游戏点击鼠标,移动和发送键,基本上是你的AI.
1.-首先,您需要运行能够获得所有游戏所具有的psn"进程序列号"的类.基本上它运行的是什么线程.您可以在Mac中的实用程序中找到名为"活动监视器"的进程名称.这也可以在AppleScript中轻松完成.一旦你有了这个名字,这个类就会找到并回馈它的psn.
#import#include #include @interface gamePSN : NSObject { ProcessSerialNumber gamePSN; ProcessInfoRec gameProcessInfo; pid_t gameUnixPID; } - (ProcessSerialNumber) gamePSN; - (ProcessInfoRec) gameProcessInfo; - (pid_t) gameUnixPID; - (void) getPSN; @end @implementation gameSN - (ProcessSerialNumber) gamePSN { return gamePSN; } - (ProcessInfoRec) gameProcessInfo { return gameProcessInfo; } - (pid_t) gameUnixPID; { return gameUnixPID; } - (void) getPSN { auto OSErr osErr = noErr; auto OSErr otherErr = noErr; auto ProcessSerialNumber process; auto ProcessInfoRec procInfo; auto Str255 procName; auto FSSpec appFSSpec; auto char cstrProcName[34]; auto char one ='G'; // FIRST CHARCTER OF GAME PROCESS NAME THESE NEED TO BE CHANGED AS I PUT IN FAKES auto char two ='A'; // SECOND CHARACTER OF GAME PROCESS NAME THESE NEED TO BE CHANGED AS I PUT IN FAKES auto char three = 'M'; // THIRD CHARACTER OF GAME PROCESS NAME THESE NEED TO BE CHANGED AS I PUT IN FAKES auto unsigned int size; process.highLongOfPSN = kNoProcess; process.lowLongOfPSN = kNoProcess; procInfo.processInfoLength = sizeof(ProcessInfoRec); procInfo.processName = procName; procInfo.processAppSpec = &appFSSpec; while (procNotFound != (osErr = GetNextProcess(&process))) { if (noErr == (osErr = GetProcessInformation(&process, &procInfo))) { size = (unsigned int) procName[0]; memcpy(cstrProcName, procName + 1, size); cstrProcName[size] = '\0'; // NEEDS TO MATCH THE SIGNATURE OF THE GAME..FIRST THREE LETTERS // IF YOU CANT FIND IT WITH THE ACTIVITY MONITOR UTILITY OF APPLE MAC OS // THEN RUN THIS SAME CLASS WITH AN NSLOG AND IT WILL LIST ALL YOUR RUNNING PROCESSES. if ( (((char *) &procInfo.processSignature)[0]==one) && (((char *) &procInfo.processSignature)[1]==two) && (((char *) &procInfo.processSignature)[2]==three) && (((char *) &procInfo.processSignature)[3]==two)) { gamePSN = process; otherErr = GetProcessInformation(&gamePSN, &gameProcessInfo); otherErr = GetProcessPID(&process, &gameUnixPID); } } } }
获得此进程编号后,可以轻松发送关键事件和鼠标事件.这是鼠标事件点击发送.
// mouseClicks.h // ClickDep // Created by AnonymousPlayer on 9/9/11. #import@interface mouseClicks : NSObject - (void) PostMouseEvent:(CGMouseButton) button eventType:(CGEventType) type fromPoint:(const CGPoint) point; - (void) LeftClick:(const CGPoint) point; - (void) RightClick:(const CGPoint) point; - (void) doubleLeftClick:(const CGPoint) point; - (void) doubleRightClick:(const CGPoint) point; @end / // mouseClicks.m // ClickDep // Created by AnonymousPlayer on 9/9/11.v #import "mouseClicks.h" @implementation mouseClicks - (id)init { self = [super init]; if (self) { // Initialization code here if you need any. } return self; } - (void) PostMouseEvent:(CGMouseButton) button eventType:(CGEventType) type fromPoint:(const CGPoint) point; { CGEventRef theEvent = CGEventCreateMouseEvent(NULL, type, point, button); CGEventSetType(theEvent, type); CGEventPost(kCGHIDEventTap, theEvent); CFRelease(theEvent); } - (void) LeftClick:(const CGPoint) point; { [self PostMouseEvent:kCGMouseButtonLeft eventType:kCGEventMouseMoved fromPoint:point]; NSLog(@"Click!"); [self PostMouseEvent:kCGMouseButtonLeft eventType:kCGEventLeftMouseDown fromPoint:point]; sleep(2); [self PostMouseEvent:kCGMouseButtonLeft eventType:kCGEventLeftMouseUp fromPoint:point]; } - (void) RightClick:(const CGPoint) point; { [self PostMouseEvent:kCGMouseButtonRight eventType:kCGEventMouseMoved fromPoint:point]; NSLog(@"Click Right"); [self PostMouseEvent:kCGMouseButtonRight eventType: kCGEventRightMouseDown fromPoint:point]; sleep(2); [self PostMouseEvent:kCGMouseButtonRight eventType: kCGEventRightMouseUp fromPoint:point]; } - (void) doubleLeftClick:(const CGPoint) point; { [self PostMouseEvent:kCGMouseButtonRight eventType:kCGEventMouseMoved fromPoint:point]; CGEventRef theEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, point, kCGMouseButtonLeft); CGEventPost(kCGHIDEventTap, theEvent); sleep(2); CGEventSetType(theEvent, kCGEventLeftMouseUp); CGEventPost(kCGHIDEventTap, theEvent); CGEventSetIntegerValueField(theEvent, kCGMouseEventClickState, 2); CGEventSetType(theEvent, kCGEventLeftMouseDown); CGEventPost(kCGHIDEventTap, theEvent); sleep(2); CGEventSetType(theEvent, kCGEventLeftMouseUp); CGEventPost(kCGHIDEventTap, theEvent); CFRelease(theEvent); } - (void) doubleRightClick:(const CGPoint) point; { [self PostMouseEvent:kCGMouseButtonRight eventType:kCGEventMouseMoved fromPoint:point]; CGEventRef theEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, point, kCGMouseButtonRight); CGEventPost(kCGHIDEventTap, theEvent); sleep(2); CGEventSetType(theEvent, kCGEventRightMouseUp); CGEventPost(kCGHIDEventTap, theEvent); CGEventSetIntegerValueField(theEvent, kCGMouseEventClickState, 2); CGEventSetType(theEvent, kCGEventRightMouseDown); CGEventPost(kCGHIDEventTap, theEvent); sleep(2); CGEventSetType(theEvent, kCGEventRightMouseUp); CGEventPost(kCGHIDEventTap, theEvent); CFRelease(theEvent); } @end
您可能需要使用睡眠,这是按下鼠标按钮并释放它之间的时间间隔.我发现使用1秒有时它不会这样做.放2秒使其始终有效.所以你的主要意见如下.
int main(int argc, char *argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSUserDefaults *args = [NSUserDefaults standardUserDefaults]; // Grabs command line arguments -x, -y, -clicks, -button // and 1 for the click count and interval, 0 for button ie left. int x = [args integerForKey:@"x"]; int y = [args integerForKey:@"y"]; int clicks = [args integerForKey:@"clicks"]; int button = [args integerForKey:@"button"]; //int interval= [args integerForKey:@"interval"]; int resultcode; // PUT DEFAULT VALUES HERE WHEN SENT WITH EMPTY VALUES /*if (x==0) { x= 1728+66; y= 89+80; clicks=2; button=0; } */ // The data structure CGPoint represents a point in a two-dimensional // coordinate system. Here, X and Y distance from upper left, in pixels. CGPoint pt; pt.x = x; pt.y = y; // Check CGEventPostToPSN Posts a Quartz event into the event stream for a specific application. // only added the front lines plus changed null in Create Events to kCGHIDEventTap gamePSN *gameData = [[gamePSN alloc] init]; [gameData getPSN]; ProcessSerialNumber psn = [gameData gamePSN]; resultcode = SetFrontProcess(&psn); mouseClicks *mouseEvent =[[mouseClicks alloc] init]; if (button == 0) { if (clicks==1) { [mouseEvent LeftClick:pt]; } else { [mouseEvent doubleLeftClick:pt]; } } if (button == 1) { if (clicks==1) { [mouseEvent RightClick:pt]; } else { [mouseEvent doubleRightClick:pt]; } } [gameData release]; [mouseEvent release]; [pool drain]; return 0; }
希望这有用....请记住,您可以通过发送以下命令在终端或AppleScript中执行此操作.
do shell script "/...Path to Compiled Program.../ClickDep" & " -x " & someX & " -y " & someY & " -clicks 1 -button 1"
快乐的游戏!!!!