2011-05-11 5 views
3

CGPostMouseEvent 및 CGEventPostToPSN을 사용하여 마우스 클릭을 Mac 게임에 보내려고했지만 불행히도 실패했습니다.마우스를 게임 창으로 보내려 고 시도했습니다.

나는 누군가가 나를 다르게 생각하거나 내가 누락 된 것을 깨닫도록 도울 수 있기를 바랬다. Google은 별 도움이되지 않았습니다.

제 생각에 일반 게임 대 게임 창 (openGL)에 클릭 이벤트를 보내려고하기 때문입니다.

다음은 내가 보내려고하는 또 다른 예입니다. CGEventRef CGEvent; NSEvent * customEvent; NSPoint 위치; location.x = 746; location.y = 509;/

어떤 도움을 크게 감상 할 수있다 : 난 그냥 어떤 클릭을 보낼 수 없습니다 (CGDisplayMoveCursorToPoint (kCGDirectMainDisplay, clickPt)) 흥미롭게도

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를 사용하여 마우스를 움직이면 사실 마우스를 움직이거나 움직일 때까지 실제로 마우스를 움직여야합니다. 게임은 위/아래로 움직이지 않으면 포인터가 바뀌지 만 입력을 받아들이지 않습니다.

감사합니다.

답변

5

글쎄, 기본적으로 명령을 게임에 보내주는 "봇"또는 "로봇"이 당신이 만들려고 노력하는 것입니다. 기본적으로 그것은 당신과 마찬가지로 당신을 위해 재생됩니다. 이것은 미네랄, 농산물 등을 수확하기 위해 게임을 강요하는 게임에 적합합니다. 정말 지루한 종류입니다. 나는 모든 종류의 게임이 "봇"에 대해 가지고있는 사용자 계약을 깰 때 게임을 언급 할 수는 없지만 대중적인 게임을 성공적으로 수행했습니다. 따라서 많은 MMPG에 대한 사용자 계약을 위반할 수 있으므로 현재 수행중인 작업에주의하십시오. 그러나 맥은 사용 가능한 보봇 (bot)이 적기 때문에 조사를 해본 적이 없다. 그래서 경기장을 평평하게하기 위해서 여기에 코드가 있습니다. 커맨드 라인으로 컴파일하고, AppleScript로 매크로를 실행하는 것이 좋습니다 (논리는 게임 마우스, 움직임을 모방하는 방법, 기본적으로 AI를 모방하는 방법이었습니다).

1. 먼저 모든 게임에 포함 된 psn "프로세스 일련 번호"를 얻을 수있는 클래스를 실행하십시오 기본적으로 어떤 스레드가 실행되고 있는지 Mac에서는 "Activity Monitor"라는 유틸리티에서 프로세스의 이름을 확인할 수 있습니다. 이 프로세스 번호가 있으면 AppleScript로 쉽게 수행. 당신이 이름을 갖게되면,이 클래스의 위치와 PSN 당신을 다시 줄 것이다.

#import <Cocoa/Cocoa.h> 
#include <Carbon/Carbon.h> 
#include <stdio.h> 

@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); 
     } 

     } 

    } 
} 

심지어 키 이벤트뿐만 아니라 마우스를 보낼 간단합니다 ts. 마우스 이벤트 클릭으로 보낼 수 있습니다.

// mouseClicks.h 
// ClickDep 
// Created by AnonymousPlayer on 9/9/11. 


#import <Foundation/Foundation.h> 

@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" 

해피 게이밍 !!!!

+0

참고로, SetFrontProcess는 이제 사용되지 않습니다. 이것은 흥미로운 대안이지만 : http://stackoverflow.com/a/2334362/880837 – Tiago

관련 문제