arkane Posted January 3, 2010 Share Posted January 3, 2010 (edited) 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 : expandcollapse popup#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 January 3, 2010 by arkane Link to comment Share on other sites More sharing options...
Info Posted January 3, 2010 Share Posted January 3, 2010 (edited) 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 January 3, 2010 by Info Link to comment Share on other sites More sharing options...
arkane Posted January 3, 2010 Author Share Posted January 3, 2010 (edited) 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 January 3, 2010 by arkane Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 3, 2010 Moderators Share Posted January 3, 2010 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: expandcollapse popup#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 EndFuncM23  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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
arkane Posted January 3, 2010 Author Share Posted January 3, 2010 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 More sharing options...
Info Posted January 3, 2010 Share Posted January 3, 2010 It works for me... Link to comment Share on other sites More sharing options...
arkane Posted January 3, 2010 Author Share Posted January 3, 2010 (edited) 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 January 3, 2010 by arkane Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 3, 2010 Moderators Share Posted January 3, 2010 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 ;==>testAs 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  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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
arkane Posted January 3, 2010 Author Share Posted January 3, 2010 (edited) 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 . 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 . expandcollapse popup#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 January 4, 2010 by arkane Link to comment Share on other sites More sharing options...
arkane Posted January 4, 2010 Author Share Posted January 4, 2010 (edited) 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 : expandcollapse popup#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 January 4, 2010 by arkane Link to comment Share on other sites More sharing options...
arkane Posted January 6, 2010 Author Share Posted January 6, 2010 Please, if you think this thread hasn't its place here, just put it in an another section . Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now