Hello everyone !
As you should be aware by now as I keep repeating it, I'm a QA tester in a big video game company (editor).
For work, i'm actually trying to create a bot that'll run different tasks on games.
I started with autoit and i'm encountering an issue. i'm willing to change for autohotkey if needed (pretty much the same), but i'd like your opinion on the matter.
It might just be a perf issue that you can help with.
The problem is that the game is not always receiving the inputs i send, and i even send 20+ times the inputs.
It's appearing randomly, every two run is different. Keys that works might not work the next try with the same code.
So I did it in two parts :
- Writebot listen for UP/DOWN/LEFT/RIGHT/ENTER and writes them on a notepad with the timing.
Code:
#include <ButtonConstants.au3>#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include<misc.au3>
Run("notepad.exe")
; this will bring the notepad windows to the foreground and activates
Local $note = WinActivate("Sans titre - Bloc-notes") ; change to the proper name in your OS language
$dll = DllOpen("user32.dll")
While 1
; wait to start writing inputs until HOME is pressed
If _IsPressed("24", $dll) Then
Sleep ( 20 )
ExitLoop
EndIf
; starts waiting inputs
Local $t = TimerInit()
Local $time = @MIN *60000+ @SEC*1000 + @MSEC
While 1
Dim $cur_time = @MIN *60000+@SEC*1000+@MSEC;
; write on the notepad TIMER, new line, KEYCODE that was pressed, new line
If _IsPressed("25", $dll) Then
ControlSend("Sans titre - Bloc-notes", "", "[CLASS:Edit; INSTANCE:1]", $cur_time - $time & @CR & "25 " & @CR)
ElseIf _IsPressed("26", $dll) Then
ControlSend("Sans titre - Bloc-notes", "", "[CLASS:Edit; INSTANCE:1]",$cur_time-$time & @CR & "26 " & @CR)
ElseIf _IsPressed("27", $dll) Then
ControlSend("Sans titre - Bloc-notes", "", "[CLASS:Edit; INSTANCE:1]", $cur_time-$time & @CR & "27 " & @CR)
ElseIf _IsPressed("28", $dll) Then
ControlSend("Sans titre - Bloc-notes", "", "[CLASS:Edit; INSTANCE:1]", $cur_time - $time & @CR & "28 " & @CR)
ElseIf _IsPressed("0D", $dll) Then
ControlSend("Sans titre - Bloc-notes", "", "[CLASS:Edit; INSTANCE:1]", $cur_time-$time & @CR & "Enter" & @CR)
; "S" to stop writing and save the bot in "test1.txt"
ElseIf _IsPressed("53", $dll) Then
ControlSend("Sans titre - Bloc-notes", "", "[CLASS:Edit; INSTANCE:1]", "end")
$text = ControlGetText("Sans titre - Bloc-notes", "", "[CLASS:Edit; INSTANCE:1]") ; change to the proper name in your OS language
FileWrite("./test1.txt", $text) ; Write the text to file
WinKill("Sans titre - Bloc-notes") ; Close the window and ignore all dialog prompts
ExitLoop
ElseIf _IsPressed("23", $dll) Then
ExitLoop
EndIf
Sleep ( 10 )
WEnd
DllClose($dll)
- Readbot reads that file, and reproduces the inputs at the same timing.
Code:
#include <ButtonConstants.au3>#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Array.au3> ; Required for _ArrayDisplay.
#include<misc.au3>
#include <FileConstants.au3>
#include <MsgBoxConstants.au3>
WinActivate("Game name") ; write the name of the game/application
WinWaitActive("Game name"); write the name of the game/application
Opt("SendKeyDelay", 5)
Opt("SendKeyDownDelay", 7)
$dll = DllOpen("user32.dll")
Example()
Func Example()
; Create a constant variable in Local scope of the filepath that will be read/written to.
Local Const $sFilePath = "./test1.txt"
; Create a temporary file to read data from.
If Not FileCreate($sFilePath, "This is an example of using FileReadLine.") Then Return MsgBox($MB_SYSTEMMODAL, "", "An error occurred whilst writing the temporary file.")
; Open the file for reading and store the handle to a variable.
Local $hFileOpen = FileOpen($sFilePath, $FO_READ)
If $hFileOpen = -1 Then
MsgBox($MB_SYSTEMMODAL, "", "An error occurred when reading the file.")
Return False
EndIf
Local $arr[1][2]
; Read the fist line of the file using the handle returned by FileOpen.
Local $sFileRead = FileReadLine($hFileOpen, 1)
Local $i = 0
; fill the timing & inputs matrix
While $sFileRead <> "end"
$arr[$i][0] = $sFileRead
$sFileRead = FileReadLine($hFileOpen)
$arr[$i][1] = $sFileRead
$i = $i +1
$sFileRead = FileReadLine($hFileOpen)
if $sFileRead <> "end" then
ReDim $arr[UBound($arr,$UBOUND_ROWS) + 1][UBound($arr,$UBOUND_COLUMNS)]
EndIf
WEnd
FileClose($hFileOpen)
$hFileOpen = FileOpen($sFilePath, $FO_READ)
SendKeepActive("[CLASS:Window0]"); write the class of the game/application (see autoit windows info)
Local $t = TimerInit()
Local $c = 0;
Local $time = @MIN*60000 + @SEC*1000 + @MSEC
While $c + 1 <= UBound($arr,$UBOUND_ROWS)
; compary actual timing with the next command in line
if $arr[$c][0] <= @MIN*60000 + @SEC*1000 + @MSEC - $time Then
; switch between all the key codes to send the correct input
Switch $arr[$c][1]
Case 25
ControlSend(("Game name"), "", "[CLASS:Window0; INSTANCE:1]", "{LEFT 10}"); write the class of the game/application (see autoit windows info)
Send ("{LEFT 10}")
Case 26
ControlSend(("Game name), "", "[CLASS:Window0; INSTANCE:1]", "{UP 10}"); write the class of the game/application (see autoit windows info)
Send ("{UP 10}")
Case 27
ControlSend(("Game name"), "", "[CLASS:Window0; INSTANCE:1]", "{RIGHT 10}"); write the class of the game/application (see autoit windows info)
Send ("{RIGHT 10}")
Case 28
ControlSend(("Game name"), "", "[CLASS:Window0; INSTANCE:1]", "{DOWN 10}"); write the class of the game/application (see autoit windows info)
Send ("{DOWN 10}")
Case "Enter"
ControlSend(("Game name"), "", "[CLASS:Window0; INSTANCE:1]", "{ENTER 10}"); write the class of the game/application (see autoit windows info)
Send ("{ENTER 10}")
Case Else
; if the input isn't recognized, show a dialogbox
MsgBox(0,"_IsPressed", "End Key Pressed" & $sFileRead)
EndSwitch
$c = $c + 1
EndIf
; END to interrupt the loop
If _IsPressed("23", $dll) Then
MsgBox(0,"_IsPressed", "End Key Pressed")
ExitLoop
EndIf
WEnd
; close the reading
MsgBox(0,"finished", "finished" & TimerDiff($t))
; Close the handle returned by FileOpen.
FileClose($hFileOpen)
DllClose($dll)
EndFunc ;==>Example
; Create a file.
Func FileCreate($sFilePath, $sString)
Local $bReturn = True ; Create a variable to store a boolean value.
If FileExists($sFilePath) = 0 Then $bReturn = FileWrite($sFilePath, $sString) = 1 ; If FileWrite returned 1 this will be True otherwise False.
Return $bReturn ; Return the boolean value of either True of False, depending on the return value of FileWrite.
EndFunc ;==>FileCreate
Can you help me with ideas on how to improve my code ?
Do you need any help in the reading ?
Btw don't hesitate to use it, it's pretty efficient on tasks that do not require quick timings.
Thank you