Sign in to follow this  
Followers 0
Drefsab

Is this even possable?

3 posts in this topic

Hi guys, I've been having a play with autoit and so far I really like it. How ever this is one thing I want to do with it but cant seam to get worked out. Basically its a game bot but a very simple one. All it would do is hold down one f key and left click on a specific area of the game window. Now this bit I have been able to get working ok.

But im wanting to have 2 copys of the game running at one time on the same computer and I only want the macro to work on one of the windows (both have the same title etc so I was thinking I would need to send the macro at a particular process id but I dont know where to begin with that).

Last of all I came accross the mouse click plus UDF but this doesnt seam to work at all, sure I can see it moving its pointer (well I can see something that moves in the game window depending on where you move your pointer change) but I can not get it to click at all. Is there any way at all that I could get the above macro to work when the window is not in focus? (ie so the macro runs on one copy of the game while you use another).

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Hi guys, I've been having a play with autoit and so far I really like it. How ever this is one thing I want to do with it but cant seam to get worked out. Basically its a game bot but a very simple one. All it would do is hold down one f key and left click on a specific area of the game window. Now this bit I have been able to get working ok.

But im wanting to have 2 copys of the game running at one time on the same computer and I only want the macro to work on one of the windows (both have the same title etc so I was thinking I would need to send the macro at a particular process id but I dont know where to begin with that).

Last of all I came accross the mouse click plus UDF but this doesnt seam to work at all, sure I can see it moving its pointer (well I can see something that moves in the game window depending on where you move your pointer change) but I can not get it to click at all. Is there any way at all that I could get the above macro to work when the window is not in focus? (ie so the macro runs on one copy of the game while you use another).

I'm not as fluent in the scripting language as some of the people here, but I will try to point you in the right direction.

This can get you the internal handle of a window which you can use so that if the title is the same as another window, your script will know which window you mean:

$WinHandle = WinGetHandle ("title")

Edit: I think if you do this is gets the active window handle, but i could be wrong:

$WinHandle = WinGetHandle ("")

This is done easier if you establish the internal handle of each window as you open it. It will require some more scripting to get the handle of each window if there are more than one open at the time you do this.

You can then send your mouse clicks to the correct window using the internal handle, like this:

WinActivate ( $WinHandle)

MouseClick ( "button" , x, y, clicks , speed)

I do not know of a way to do mouse movements/clicks in a window that is not in focus. I don't think you can.

I hope this helps,

Nomad

Edited by Nomad

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Depending on how the program/game interprets Windows messages, it's definitely possible using PostMessage API and AutoIt's (Beta) DllCall. I wrote this UDF for another game so it could receive mouse-clicks and button presses while minimized; there's no guarantee that it'll work for your game, but it's something to start with.

#include-once

Func _MakeLong($LoWord, $HiWord)
  Return BitOR($HiWord * 0x10000, BitAND($LoWord, 0xFFFF))
EndFunc

Func _MouseClick($hWnd, $button, $x, $y, $times=1, $delay=250)
    If $hWnd = 0 Then
        SetError(-1)
        Return
    EndIf
    
    Local $ix
    Local $lParam = _MakeLong($x, $y)
    
    $button = StringLower($button)
    
    If $button = "left" Then
        For $ix = 1 To $times
            DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x200, "int", 0, "long", $lParam)
            DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x201, "int", 1, "long", $lParam)
            DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x202, "int", 0, "long", $lParam)
            
            If $ix < $times Then Sleep($delay)
        Next
    ElseIf $button = "right" Then
        For $ix = 1 To $times
            DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x200, "int", 0, "long", $lParam)
            DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x204, "int", 2, "long", $lParam)
            DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x205, "int", 0, "long", $lParam)
            
            If $ix < $times Then Sleep($delay)
        Next
    Else
        SetError(-2)
        Return
    EndIf
EndFunc

Func _SendKeys($hWnd, $keys)
    If $hWnd <= 0 Or StringLen($keys) = 0 Then
        SetError(-1)
        Return False
    EndIf
    
    $keys = StringUpper($keys)
    
    $keys = StringReplace($keys, "`", Chr(0xC0))
    $keys = StringReplace($keys, "~", Chr(0xC0))
    $keys = StringReplace($keys, "-", Chr(0xBD))
    $keys = StringReplace($keys, "=", Chr(0xBB))
    $keys = StringReplace($keys, "{ENTER}", Chr(0xD))
    $keys = StringReplace($keys, "{TAB}", Chr(0x9))
    $keys = StringReplace($keys, "{ESC}", Chr(0x1B))
    $keys = StringReplace($keys, "{F5}", Chr(0x74))
    $keys = StringReplace($keys, "{F12}", Chr(0x7B))
    $keys = StringReplace($keys, "{SHIFT}", "+")
    
    Local $i, $ret
    Local $shiftdown = False
    
    For $i = 1 To StringLen($keys)
        If StringMid($keys, $i, 1) = "+" Then
            DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x100, "int", 0x10, "long", 0x002A0001)
            DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x100, "int", 0x10, "long", 0x402A0001)
            $shiftdown = True
            Sleep(1)
            ContinueLoop
        Else
            $ret = DllCall("user32.dll", "int", "MapVirtualKey", "int", Asc(StringMid($keys, $i, 1)), "int", 0)
            If IsArray($ret) Then
                DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x100, "int", Asc(StringMid($keys, $i, 1)), "long", _MakeLong(1, $ret[0]))
                Sleep(1)
                DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x101, "int", Asc(StringMid($keys, $i, 1)), "long", _MakeLong(1, $ret[0]) + 0xC0000000)
                Sleep(1)
            EndIf
        EndIf
        If $shiftdown Then
            DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x101, "int", 0x10, "long", 0xC02A0001)
            Sleep(1)
            $shiftdown = False
        EndIf
    Next
    
    Return True
EndFunc

Func _SendText($hWnd, $str)
    If $hWnd = 0 Or StringLen($str) = 0 Then
        SetError(-1)
        Return
    EndIf
    
    For $i = 1 To StringLen($str)
        DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWnd, "int", 0x102, "int", Asc(StringMid($str, $i, 1)), "long", 0)
        Sleep(1)
    Next
EndFunc

First try _SendKeys, then, if that doesn't work, try _SendText. _SendText will most likely NOT work, but it's worth a shot (it usually only works when a text box is open for direct-input games).

Now, your second problem. There's a few ways you can go about it. WinGetHandle will always return a handle to the top-most window that matches the title passed to it; that said, the simplest way would be to always have the game to which you want input to be sent on top of the other game when you run the script (click it in the taskbar, alt-tab to your script, run it, have it activate the window so you make sure you're running the right one).

The other way to go about it would to have your script loop through all instances of the game and re-title them in an ascending fashion ("Game" and "Game" become "Game1" and "Game2"), then pop up a message box asking you which game you'd like to get the handle to. You input 1 or 2, it looks for "Game" & $inputboxreturn or something. Here's a sample:

AutoItSetOption("WinTitleMatchMode", 3);make sure we only match EXACT titles
Dim $hWnd
Dim $numGames = 0

While 1
    $hWnd = WinGetHandle("Game")
    If @error Then
        ExitLoop
    Else
        $numGames = $numGames + 1
    EndIf

    WinSetTitle($hWnd, "", "Game" & $numGames)
WEnd

$inputboxreturn = InputBox("Which Window?", "Please enter the number of the game to which you want input sent.", "1")
If $inputboxreturn = 0 Or $inputboxreturn > $numGames Then
    MsgBox(16, "ERROR!", "Invalid window specified.")
    Exit
EndIf

$hWNd = WinGetHandle("Game" & $inputboxreturn)
If @error Then
    MsgBox(16, "Window Not Found", "Game" & $inputboxreturn & " could not be found.")
    Exit
EndIf

;...rest of your script goes here

Hope it helps.

-Shynd

Edited by Outshynd

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0