Jump to content

Start / Stop button, and a loop


arkane
 Share

Recommended Posts

Hi everybody.

I'm making a bot for a game. Everything seems to be working fine.

But I've a small issue :

I've made a minimalist script to show you what I'm talking about :

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("WinTitleMatchMode", 2)

$Win = GUICreate(".: Test :.", 300, 125, 0, 0, -1, $WS_EX_TOPMOST)
$Start = GUICtrlCreateButton("Start", 80, 80, 50, 20)
$Stop = GUICtrlCreateButton("Stop", 160, 80, 50, 20)    
GUISetState(@SW_SHOW)
    
While 1
    $msg = GUIGetMsg()
    
    Select          
        Case $msg = $GUI_EVENT_CLOSE
            GUISwitch($Win)
            GUIDelete()
            Exit
        Case $msg = $start
            test()
            
        Case $msg = $stop
            ExitLoop
    EndSelect
WEnd

Func test()
    $num = 0
    while 1

        If WinActive("[CLASS:Notepad]") Then ;~ step1
            Send($num) ;~ step2
            sleep(1000)  ;~ step3
        else  ;~ step4
            WinActivate("[CLASS:Notepad]")  ;~ step5
        EndIf ;~ step6
        $num = $num+1 &@CRLF  ;~ step7
    wend
EndFunc

When I start the macro, even if I click Stop, it doesn't want to exit the loop.

How can I do to make the stop button works, at any time and any step in the loop ?

I mean, if my function sends click and key presses and last at least 10minutes, I don't want to have to wait that the loop is ended before I can stop.

Any idea ?

Thanks in advance, and sorry for my english.

Edited by arkane
Link to comment
Share on other sites

Func test()
    $num = 0
    while 1
        If GUIGetMsg() = $stop Then ExitLoop ;<----
        If WinActive("[CLASS:Notepad]") Then ;~ step1
            Send($num) ;~ step2
            sleep(1000)  ;~ step3
        else  ;~ step4
            WinActivate("[CLASS:Notepad]")  ;~ step5
        EndIf ;~ step6
        $num = $num+1 &@CRLF  ;~ step7
    wend
EndFunc

Edited by Info
Link to comment
Share on other sites

It doesn't really work. For exemple if I do :

Func test()
    $num = 0
    while 1
        If GUIGetMsg() = $stop Then ExitLoop
        If WinActive("[CLASS:Notepad]") Then
            Send($num)
            sleep(10000)
        else 
            WinActivate("[CLASS:Notepad]")
        EndIf
        $num = $num+1 &@CRLF
    wend

It won't cancel the loop.

I guess that what I need is "If GUIGetMsg() = $stop Then ExitLoop" between each line. But I don't think it's a good solution.

Plus, it won't cancel sleep().

Edited by arkane
Link to comment
Share on other sites

  • Moderators

arkane,

If you want to stop the function while it is running, you need to check if the Stop button is pressed within the function: ;)

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("WinTitleMatchMode", 2)

$Win = GUICreate(".: Test :.", 300, 125, 0, 0, -1, $WS_EX_TOPMOST)
$Start = GUICtrlCreateButton("Start", 80, 80, 50, 20)
$Stop = GUICtrlCreateButton("Stop", 160, 80, 50, 20)
GUISetState(@SW_SHOW)

While 1
    $msg = GUIGetMsg()

    Select
        Case $msg = $GUI_EVENT_CLOSE
            GUISwitch($Win)
            GUIDelete()
            Exit
        Case $msg = $start
            test()
        Case $msg = $stop
            ExitLoop
    EndSelect
WEnd

Func test()
    $num = 0
    while 1
        $msg = GUIGetMsg()
        Select
            Case $msg = $stop
                ExitLoop
        EndSelect

        If WinActive("[CLASS:Notepad]") Then ;~ step1
            Send($num) ;~ step2
            sleep(1000)  ;~ step3
        else  ;~ step4
            WinActivate("[CLASS:Notepad]")  ;~ step5
        EndIf ;~ step6
        $num = $num+1 &@CRLF  ;~ step7
    wend
EndFunc

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thank you for your answer, but there is the same issue than before :

Func test()
    $num = 0
    while 1
        $msg = GUIGetMsg()
        Select
            Case $msg = $stop
                ExitLoop
        EndSelect

        If WinActive("[CLASS:Notepad]") Then ;~ step1
            Send($num) ;~ step2
            sleep(40000)  ;~ step3
        else  ;~ step4
            WinActivate("[CLASS:Notepad]")  ;~ step5
        EndIf ;~ step6
        $num = $num+1 &@CRLF  ;~ step7
    wend
EndFunc

If I've for example a sleep of 40 seconds, it won't cancel until 40sec have past.

Link to comment
Share on other sites

Well, it works if notepad isn't opened. Otherwise, it doesn't.

Quick other question.

For my bot, I've loops in loops. For example, a do-until, in a while(1). As I need to wait (do-until) before I go further.

Will this method work also in this internal loop ? Or do I need to set

$msg = GUIGetMsg()
        Select
            Case $msg = $stop
                ExitLoop
        EndSelect

At the beginning of all my loops ?

Edited by arkane
Link to comment
Share on other sites

  • Moderators

arkane,

If you want to have long delays, you need to use timers and not Sleep. That way the script stays active and you can check for the Stop button:

Func test()
    $num = 0
    While 1
        If WinActive("[CLASS:Notepad]") Then ;~ step1
            Send($num) ;~ step2
            ; Get time stamp
            $ibegin = TimerInit()
            ; Until 40000 ms from time stamp
            While TimerDiff) $ibegin) < 40000 ; ~ step3
                $msg = GUIGetMsg()
                Select
                    Case $msg = $Stop
                        ExitLoop ; Leave this inner loop and restart the outer loop
                EndSelect
            WEnd
        Else ;~ step4
            WinActivate("[CLASS:Notepad]") ;~ step5
        EndIf ;~ step6
        $num = $num + 1 & @CRLF ;~ step7
    WEnd
EndFunc   ;==>test

As to the other question, you need to check GUIGetMsg any time you are in a loop and want to see if a control has been actioned. Or you might like to look at OnEvent mode.... ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks, I'll take a look at that and keep you aware ;).

Quick question : Do you know why "sleep()" doesn't exactly works the same for everyone ?

For exemple, if I program something like this (assuming Z is a key which make a character in a game walk forward) :

z up

sleep 3000

z down

For some people, it will not stop to the same place (0 to 10 for normal people, 0 to 12 for others)

the older the computer is, the worse the timing seems to be. Do you have any idea why ? May timers make the thing works better ?

Edit : Your function works great. I had to change the level to ExitLoop(2) but it works nicely :evil:. Thanks

Edit 2 : I've absolutely no idea about how to adapt this to my code. I make a minimal code so you might help me :evil:.

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("SendKeyDownDelay", 25)
Opt("MouseClickDownDelay", 50)

$BotFenetre = GUICreate(".: Test 2 :.", 300, 325, 0, 0, -1, $WS_EX_TOPMOST)
$Start = GUICtrlCreateButton("Start", 80, 280, 50, 20)
$Stop = GUICtrlCreateButton("Stop", 160, 280, 50, 20)
GUISetState(@SW_SHOW)
    
While 1
    $msg = GUIGetMsg(1)
    Select
        Case $msg[0] = $GUI_EVENT_CLOSE
                If $msg[1] = $BotFenetre Then
                    GUISwitch($BotFenetre)
                    GUIDelete()
                    Exit
                EndIf
                    
        Case $msg[0] = $GUI_EVENT_CLOSE         
            If $msg[1] = $BotFenetre Then
                GUISwitch($BotFenetre)
                GUIDelete()
                Exit
            EndIf

        Case $msg[0] = $Start
            TailleS4()
            ActiverJoueur()
    EndSelect
WEnd

Func TailleS4()
    global $RatioX, $RatioY, $size
    If ProcessExists("S4Client.exe") Then
        $Size = WinGetClientSize("S4 Client")
        $RatioX = $size[0]/1280
        $RatioY = $size[1]/1024
        Return $RatioX & $RatioY
    Else
        MsgBox(262144, "Boulet mon ami, mon ami boulet !", "Veuillez lancer S4 league avant de lancer ce bot.")
        GUIDelete()
        Exit
    EndIf 
Endfunc


Func TuerPorteur()
    ;~  On sprint
    Send("{z down}")
    sleep(30)
    Send("{z up}")
    sleep(30)
    Send("{z down}")
    sleep(7400)
    Send("{z up}")

    ;~  On tue
    Send("{q down}")
    sleep(150)
    Send("{q up}")
    MouseDown("left")
    sleep(4000)
    MouseUp("left")
EndFunc

Func ActiverJoueur()
    While 1
        ;~  On se met pret
        MouseClick("left", 636*$RatioX, 896*$RatioY, 1, 0)
        sleep(2500) 
        
        ;~  On va tuer le porteur
        TuerPorteur()
        
        ;~  On attends : Partie finie > Lobby > Master.....
        do
            sleep(25)
            Send("{CTRLDOWN}")
            sleep(500)
            Send("{CTRLUP}")
            sleep(500)
            PixelSearch( 200*$RatioX, 713*$RatioY, 259*$RatioX,736*$RatioY, 0xFF1ABD,15)            
        Until @error = 0
;~ 
    WEnd
EndFunc

Oh and yes, "$msg = GUIGetMsg(1)". I use multiples windows (just an option windows).

Edited by arkane
Link to comment
Share on other sites

Arf, it seems no one knows ? ;)

I also tried the onevent mode, it doesn't work better. It doesn't want to cancel loop, as it's written in the help :

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1) 
Opt("SendKeyDownDelay", 25)
Opt("MouseClickDownDelay", 50)

$BotFenetre = GUICreate(".: Test 2 :.", 300, 325, 0, 0, -1, $WS_EX_TOPMOST)
$Start = GUICtrlCreateButton("Start", 80, 280, 50, 20)
GUICtrlSetOnEvent($Start, "ActiverJoueur")
$Stop = GUICtrlCreateButton("Stop", 160, 280, 50, 20)
GUICtrlSetOnEvent($Stop, "Quitter")
GUISetOnEvent($GUI_EVENT_CLOSE, "Quitter")
GUISetState(@SW_SHOW)
    
While 1
    $msg = GUIGetMsg(1)
    Select
        Case $msg[0] = $GUI_EVENT_CLOSE
                If $msg[1] = $BotFenetre Then
                    GUISwitch($BotFenetre)
                    GUIDelete()
                    Exit
                EndIf
                    
        Case $msg[0] = $GUI_EVENT_CLOSE         
            If $msg[1] = $BotFenetre Then
                GUISwitch($BotFenetre)
                GUIDelete()
                Exit
            EndIf

        Case $msg[0] = $Start
            TailleS4()
            ActiverJoueur()
    EndSelect
WEnd

Func TailleS4()
    global $RatioX, $RatioY, $size
    If ProcessExists("S4Client.exe") Then
        $Size = WinGetClientSize("S4 Client")
        $RatioX = $size[0]/1280
        $RatioY = $size[1]/1024
        Return $RatioX & $RatioY
    Else
        MsgBox(262144, "Boulet mon ami, mon ami boulet !", "Veuillez lancer S4 league avant de lancer ce bot.")
        GUIDelete()
        Exit
    EndIf 
Endfunc

Func Quitter()
    GUIDelete()
    Exit
EndFunc
    
Func TuerPorteur()
    ;~  On sprint
    Send("{z down}")
    sleep(30)
    Send("{z up}")
    sleep(30)
    Send("{z down}")
    sleep(7400)
    Send("{z up}")

    ;~  On tue
    Send("{q down}")
    sleep(150)
    Send("{q up}")
    MouseDown("left")
    sleep(4000)
    MouseUp("left")
EndFunc

Func ActiverJoueur()
    TailleS4()
    While 1
        ;~  On se met pret
        MouseClick("left", 636*$RatioX, 896*$RatioY, 1, 0)
        sleep(2500) 
        
        ;~  On va tuer le porteur
        TuerPorteur()
        
        ;~  On attends : Partie finie > Lobby > Master.....
;~         do
;~             sleep(25)
;~             Send("{CTRLDOWN}")
;~             sleep(500)
;~             Send("{CTRLUP}")
;~             sleep(500)
;~             PixelSearch( 200*$RatioX, 713*$RatioY, 259*$RatioX,736*$RatioY, 0xFF1ABD,15)            
;~         Until @error = 0
;~ 
    WEnd
EndFunc
Edited by arkane
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...