Sign in to follow this  
Followers 0
brandonb

Help with simple (4) Key Logger / Timer

16 posts in this topic

#1 ·  Posted (edited)

I hope you don't think this is about a keylogger... but in a way it is.

My goal of this small application is to log whenever the up, down, left, and right arrows are pressed.

The harder trick is that I want the timing for each as well, so it can replicate everything in sync (timing).

What I have right now will run and record, but it gives an incorrect playback. What's wrong? (I took out a lot of sleep(55)'s I originally had put in because of the timers)

For the latest code, please go to the bottom of the page POST # 15.

For the latest code, please go to the bottom of the page Post #15

Edited by brandonb

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

At a quick loop your problem is that you are waiting for a time determinded by TimerDiff after you press a key, but that is incorrect because the previous key might have been pressed after the timierinit finction was called which you used for a different key.

(I expect that sounds a much like nonsense to you as it does to me when I read it back.)

take this bit

$timerT = TimerInit()
  
            Do
                    If _IsPressed($keyU) Then
                        FileWrite($file,  "Sleep(" & TimerDiff($timerT) & ")"  &  @CRLF &  "Send('{UP down}')" & @CRLF)
                        KeyU()
                        Do
                        Until NOT _IsPressed($
                        FileWrite($file,  "Sleep(" & TimerDiff($timerU) & ")"  &  @CRLF &  "Send('{UP up}')" & @CRLF)
                    EndIf
                    If _IsPressed($keyR) Then
                        FileWrite($file,  "Sleep(" & TimerDiff($timerT) & ")"  &  @CRLF &  "Send('{RIGHT down}')" & @CRLF)
                        KeyR()
                        Do
                        Until NOT _IsPressed($keyR)
                        FileWrite($file,  "Sleep(" & TimerDiff($timerR) & ")"  &  @CRLF &  "Send('{RIGHT up}')" & @CRLF)
                    EndIf
                    If _IsPressed($keyD) Then
                        FileWrite($file,  "Sleep(" & TimerDiff($timerT) & ")"  &  @CRLF &  "Send('{DOWN down}')" & @CRLF)
                        KeyD()
                        Do
                        Until NOT _IsPressed($keyD)
                        FileWrite($file,  "Sleep(" & TimerDiff($timerD) & ")"  &  @CRLF &  "Send('{DOWN up}')" & @CRLF)
                    EndIf
            Until NOT _IsPressed($keyL)

Say we start at time = 0

Suppose keyU is pressed after 1 second, held down for 1 sec and released. Now we are at 2 seconds

So you write

wait 1s, press keyU wait 1s, release keyU

Then keyR is pressed 1 second later so the time is at 3s, and th ekey is held down for 1s again

You write

wait 3s, press keyR, wait 1s, release keyR

That is where it goes wrong because you shouldn't wait 3s but only 1 s.

The solution might be that every time you detect a key down and record the wait delay, you reset the TimerT with TimerInit when that key is released. Like this, but I haven't tested either this or what you posted.

$timerT = TimerInit()
           Do
                    If _IsPressed($keyU) Then
                        FileWrite($file,  "Sleep(" & TimerDiff($timerT) & ")"  &  @CRLF &  "Send('{UP down}')" & @CRLF)
                        KeyU()
                        Do
                        sleep(20)
                        Until NOT _IsPressed($keyU)
                        $timerT = TimerInit()
                        FileWrite($file,  "Sleep(" & TimerDiff($timerU) & ")"  &  @CRLF &  "Send('{UP up}')" & @CRLF)</span>
                    EndIf
                    If _IsPressed($keyR) Then
                        FileWrite($file,  "Sleep(" & TimerDiff($timerT) & ")"  &  @CRLF &  "Send('{RIGHT down}')" & @CRLF)
                        KeyR()
                        Do
                        sleep(20)
                        Until NOT _IsPressed($keyR)
                        $timerT = TimerInit()
                        FileWrite($file,  "Sleep(" & TimerDiff($timerR) & ")"  &  @CRLF &  "Send('{RIGHT up}')" & @CRLF)
                    EndIf
                    If _IsPressed($keyD) Then
                        FileWrite($file,  "Sleep(" & TimerDiff($timerT) & ")"  &  @CRLF &  "Send('{DOWN down}')" & @CRLF)
                        KeyD()
                        Do
                       sleep(20)
                       Until NOT _IsPressed($keyD)
                        $timerT = TimerInit()
                        FileWrite($file,  "Sleep(" & TimerDiff($timerD) & ")"  &  @CRLF &  "Send('{DOWN up}')" & @CRLF)  
                    EndIf
            Until NOT _IsPressed($keyL)

I added a 'sleep' inside the do loops to reduce processor loading.

EDIT

BTW, welcome to the forums :P

It's not recommended that you even mention the dreaded K word especially in you first post, but I don't think there is any problem with your post at all.

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

At a quick loop your problem is that you are waiting for a time determinded by TimerDiff after you press a key, but that is incorrect because the previous key might have been pressed after the timierinit finction was called which you used for a different key.

(I expect that sounds a much like nonsense to you as it does to me when I read it back.)

Perfect, You're making complete sense.. I figured this was part of what was happening.

I'll go ahead and apply your code asap to see how it works.

Thanks for the warm welcome!

Share this post


Link to post
Share on other sites

Tried, but I couldn't get it to work.

I also found a logical problem.

Situation: You press Left down, and then while holding that you press Up down.

Problem: If you release Left before you release Up, it will not release until after Up key is released.

Looks like I've got a couple of kinks to work out.

As always, any help is appreciated.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Tried, but I couldn't get it to work.

I also found a logical problem.

Situation: You press Left down, and then while holding that you press Up down.

Problem: If you release Left before you release Up, it will not release until after Up key is released.

Looks like I've got a couple of kinks to work out.

As always, any help is appreciated.

In that case I would suggest a different approach.There are 4 keys you are intersted in. HAve a loop which notes the state of each key and if it has changed then log it with a sleep which is worked out from the time for the change less the last record made.

This is the basic idea (made up as I write it)

Global $aKeys[4][3] = [["25", "Left", 2],["26", "Up", 2],["27", "Right", 2],["28", "Down", 2]]
 $t0 = TimerInit()
 $lastevent = 0
 While $something
     For $n = 0 To 3;for each key
         If $aKeys[$n][2] <> _IsPressed($aKey[$n][0]) Then
             $aKeys[$n][2] = _IsPressed($aKey[$n][0])
             FileWriteLine($file, "Sleep(" & TimerDiff($t0) - $lastevent & ")")
             $lastevent = TimerDiff($t0)
             If $aKeys[$n][2] = 1 Then
                 FileWriteLine($file, 'Send("{' & $aKeys[$n][0] & ' down}")'
             Else
                 FileWriteLine($file, 'Send("{' & $aKeys[$n][0] & ' up}")'
             EndIf
             
         EndIf
 
     Next
     
 WEnd
Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Martin, Thanks for the suggestion. I also think that would work great, but I wasn't able to implement it properly (I kept getting errors)....

In the meantime I decided to go from the classic 'If' statements to a Select... (seems more practical)

This is everything. If someone could please help make it work... I know a problem lies in the part where I write to file or how I do it: "Sleep(" & TimerDiff($timerS) & ")"

Well.. I'll keep trying to implement martins code for the time being....

$Title = InputBox("Title?","Give a title.","","",230,130)
If @Error <> 0 Or $Title == '' Then
    Exit
EndIf
$DesktopDir = @DesktopDir
$file = FileOpen($DesktopDir & "\" & $Title & ".au3", 2)
If $file = -1 Then
    MsgBox(0, "Error", "Unable to create or open the file.")
    Exit
EndIf
FileWrite($file, ";---" & $Title & @CRLF)
FileWrite($file, ";---Start---" & @CRLF & @CRLF)
FileWrite($file, 'HotKeySet("{ESC}", "Terminate")' & @CRLF & 'Func Terminate()' & @CRLF & 'Exit 0' & @CRLF & 'EndFunc' & @CRLF)
FileWrite($file, 'ToolTip("Running - ' & $Title & '", 0, 0, "", "", 4)' & @CRLF & @CRLF)
$timerL = 0
$timerU = 0
$timerR = 0
$timerD = 0
$keyL = "25"; Left
$keyU = "26"; Up
$keyR = "27"; Right
$keyD = "28"; Down 
$keyLpressed = 0
$keyUpressed = 0
$keyRpressed = 0
$keyDpressed = 0 
$timerAll = TimerInit()
$timerS = TimerInit()
While 1
    Select
    ;;LEFT
        Case _IsPressed($keyL) And $keyLpressed == 0
            FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{LEFT down}')" & @CRLF) 
            $keyLpressed = 1
            $timerS = TimerInit()
            $timerL = TimerInit()
        Case Not _IsPressed($keyL) And $keyLpressed == 1
            FileWrite($file, "Sleep(" & TimerDiff($timerL) & ")" & @CRLF & "Send('{LEFT up}')" & @CRLF)
            $keyLpressed = 0
            $timerL = 0
    ;;UP
        Case _IsPressed($keyU) And $keyUpressed == 0
            FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{UP down}')" & @CRLF)
            $keyUpressed = 1
            $timerS = TimerInit()
            $timerU = TimerInit()
        Case Not _IsPressed($keyU) And $keyUpressed == 1
            FileWrite($file, "Sleep(" & TimerDiff($timerU) & ")" & @CRLF & "Send('{UP up}')" & @CRLF)
            $keyUpressed = 0
            $timerU = 0
    ;;RIGHT
        Case _IsPressed($keyR) And $keyRpressed == 0
            FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{RIGHT down}')" & @CRLF)
            $keyRpressed = 1
            $timerS = TimerInit()
            $timerR = TimerInit()
        Case Not _IsPressed($keyR) And $keyRpressed == 1
            FileWrite($file, "Sleep(" & TimerDiff($timerR) & ")" & @CRLF & "Send('{RIGHT up}')" & @CRLF)
            $keyRpressed = 0
            $timerR = 0
    ;;DOWN
        Case _IsPressed($keyD) And $keyDpressed == 0
            FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{DOWN down}')" & @CRLF)
            $keyDpressed = 1
            $timerS = TimerInit()
            $timerD = TimerInit()
        Case Not _IsPressed($keyD) And $keyDpressed == 1
            FileWrite($file, "Sleep(" & TimerDiff($timerD) & ")" & @CRLF & "Send('{DOWN up}')" & @CRLF)
            $keyDpressed = 0
            $timerD = 0
    ;;ESCAPE
        Case _IsPressed("1B")
            FileWrite($file, ";---End---")
            FileClose($file)
            Exit 0
    EndSelect
;;ToolTip
    If $keyLpressed == 1 Then
        $keyLtool = "Left - " & Round(TimerDiff($timerL), -1) & @CRLF
    Else
        $keyLtool = "Left - 0" & @CRLF
    EndIf
    If $keyUpressed == 1 Then
        $keyUtool = "Up - " & Round(TimerDiff($timerU), -1) & @CRLF
    Else
        $keyUtool = "Up - 0" & @CRLF
    EndIf
    If $keyRpressed == 1 Then
        $keyRtool = "Right - 0" & Round(TimerDiff($timerR), -1) & @CRLF
    Else
        $keyRtool = "Right - 0" & @CRLF
    EndIf
    If $keyDpressed == 1 Then
        $keyDtool = "Down - " & Round(TimerDiff($timerD), -1) & @CRLF
    Else
        $keyDtool = "Down - 0" & @CRLF
    EndIf
    ToolTip("Running..." & @CRLF & "Total Time: " & Round(TimerDiff($timerAll), -1) & @CRLF & Round(TimerDiff($timerS), -1) & @CRLF & $keyLtool & $keyUtool & $keyRtool & $keyDtool, 0, 0, "", "", 4)
WEnd

Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
; $hexKey must be the value of one of the keys.
; _Is_Key_Pressed will return 0 if the key is not pressed, 1 if it is.
    Local $a_R = DllCall($vDLL, "int", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If Not @error And BitAND($a_R[0], 0x8000) = 0x8000 Then Return 1
    Return 0
EndFunc  ;==>_IsPressed

Share this post


Link to post
Share on other sites

@brandonb,

I haven't looked at you code in the previous post but here is a working example of what I was suggesting. As I said, I just wrote it out before to give the idea but I'm afraid there were some errors.

This one has been tested :P

#include <misc.au3>
Global $aKeys[4][3] = [["25", "Left", 2],["26", "Up", 2],["27", "Right", 2],["28", "Down", 2]]
$t0 = TimerInit(); our 'clock' which starts at 0
$lastevent = 0; the last time that a key changed
$file = fileopen("testpress.au3",2)
While timerdiff($t0) < 30000;in this example we'll just record for 30 seconds
     For $n = 0 To 3;for each key
         If $aKeys[$n][2] <> _IsPressed($aKeys[$n][0]) Then
             $aKeys[$n][2] = _IsPressed($aKeys[$n][0])
             FileWriteLine($file, "Sleep(" & Int(TimerDiff($t0) - $lastevent) & ")")
             $lastevent = TimerDiff($t0)
             If $aKeys[$n][2] = 1 Then
                 FileWriteLine($file, 'Send("{' & $aKeys[$n][1] & ' down}")')
             Else
                 FileWriteLine($file, 'Send("{' & $aKeys[$n][1] & ' up}")')
             EndIf
            
         EndIf

     Next
    
WEnd

fileclose($file)

It seems to work ok when only one key at a time is pressed down but otherwise I'm not sure. It looks as though a key held down doesn't auto repeat. If that's true then you need to search for a ready-made solution or invent some way of making the effect.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

martin, Thank you so much for posting this working code.

I've been thinking a lot lately and realized that having multiple keys pressed at the same time poses a (complex timing) problem.

I'll keep it on the back burner and hopefully invent a way to do it (I'll be sure to share as always).

Thanks again for the great help.

Share this post


Link to post
Share on other sites

martin, Thank you so much for posting this working code.

I've been thinking a lot lately and realized that having multiple keys pressed at the same time poses a (complex timing) problem.

I'll keep it on the back burner and hopefully invent a way to do it (I'll be sure to share as always).

Thanks again for the great help.

This is a quick idea which would deal with sending repeated keys press while a key is held down. It's not an exact solution as you will find.

You need to set $option to 0 or 1 to suit the behaviour you want.

#include <misc.au3>
Global $repeatperiod = 50;ms
;key code, key name, state, repeat req
Global $aKeys[4][4] = [["25", "Left", 2,0],["26", "Up", 2,0],["27", "Right", 2,0],["28", "Down", 2,0]]
$t0 = TimerInit(); our 'clock' which starts at 0
$lastevent = 0; the last time that a key changed
$file = FileOpen("testpress.au3", 2)
AdlibEnable("repeatkeys", $repeatperiod)
$option = 1;if a keyX is pressed down and then another key is pressed then keyX will stop operating
;option 1 is how my keyboard behaves but it might not be correct for a game.
;option = 0 means that when a key is down it will always repeat every $repeat period.(roughly)
While TimerDiff($t0) < 10000;in this example we'll just record for 10 seconds
    For $n = 0 To 3;for each key
        If $aKeys[$n][2] <> _IsPressed($aKeys[$n][0]) Then
            $aKeys[$n][2] = _IsPressed($aKeys[$n][0])
            FileWriteLine($file, "Sleep(" & Int(TimerDiff($t0) - $lastevent) & ")")
            $lastevent = TimerDiff($t0)
            If $aKeys[$n][2] = 1 Then
                FileWriteLine($file, 'Send("{' & $aKeys[$n][1] & ' down}")')
                If $option = 1 Then;don't repeat a key held down if another key pressed
                    For $p = 0 To 3
                        $aKeys[$p][3] = 0;stop repeating other keys
                    Next
                EndIf

                $aKeys[$n][2] = 1
                $aKeys[$n][3] = 1;we want to reat it untill it is up
            Else
                FileWriteLine($file, 'Send("{' & $aKeys[$n][1] & ' up}")')
                $aKeys[$n][2] = 0
                $aKeys[$n][3] = 0
            EndIf
                          


        EndIf

    Next

WEnd

FileClose($file)

Func repeatkeys();a bit approximate
    Local $donesleep = False
    For $k = 0 To 3
        If $aKeys[$k][3] = 1 Then
            If Not $donesleep Then
                FileWriteLine($file, "Sleep(" & Int(TimerDiff($t0) - $lastevent) & ")")
                $donesleep = True
                $lastevent = TimerDiff($t0)
            EndIf
            
            FileWriteLine($file, 'Send("{' & $aKeys[$k][1] & '}")')
        EndIf


    Next

EndFunc  ;==>repeatkeys

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Great Code, I really Like the Idea... I used it a bit, but it's still slightly off like mine...

I am rather curious at this point as to why my code right here won't work properly.. It seems it's grabbing the code, but something is wrong....

Select
        Case _IsPressed($keyL) And $keyLpressed == 0
            $keyLpressed = 1
            FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{LEFT down}')" & @CRLF)
            $timerS = TimerInit()
        Case Not _IsPressed($keyL) And $keyLpressed == 1
            $keyLpressed = 0
            FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{LEFT up}')" & @CRLF)
            $timerS = TimerInit()
        .... Same for other 3 keys....
    EndSelect

Since I restart the timer every time regardless and switch the keyLpressed on and off, it should (imho) work perfectly...

It does, just not when I press two keys simultaneously...

I guess I should work on a solution which watches for both pressed? (I thought there was no true simultaneous action though)

I'm just a bit confused... maybe it's taking a couple of processes extra to calculate some things causing it to be off???

Sorry to drag this on, but I'm really determined to get it working... I may need to use a different language but I really love AutoIt.

Share this post


Link to post
Share on other sites

Great Code, I really Like the Idea... I used it a bit, but it's still slightly off like mine...

I am rather curious at this point as to why my code right here won't work properly.. It seems it's grabbing the code, but something is wrong....

Select
         Case _IsPressed($keyL) And $keyLpressed == 0
             $keyLpressed = 1
             FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{LEFT down}')" & @CRLF)
             $timerS = TimerInit()
         Case Not _IsPressed($keyL) And $keyLpressed == 1
             $keyLpressed = 0
             FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{LEFT up}')" & @CRLF)
             $timerS = TimerInit()
         .... Same for other 3 keys....
     EndSelect

Since I restart the timer every time regardless and switch the keyLpressed on and off, it should (imho) work perfectly...

It does, just not when I press two keys simultaneously...

I guess I should work on a solution which watches for both pressed? (I thought there was no true simultaneous action though)

I'm just a bit confused... maybe it's taking a couple of processes extra to calculate some things causing it to be off???

Sorry to drag this on, but I'm really determined to get it working... I may need to use a different language but I really love AutoIt.

If the other 3 keys are in the same select statement then it the problem might be because as soon as one select condition is found that it true the others are ignored.

You need to do it with If/Else for each key instead.

If _IsPressed($keyL) And $keyLpressed == 0 then
             $keyLpressed = 1
             FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{LEFT down}')" & @CRLF)
             $timerS = TimerInit()
   ElseIf Not _IsPressed($keyL) And $keyLpressed == 1 then
             $keyLpressed = 0
             FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{LEFT up}')" & @CRLF)
             $timerS = TimerInit()
  Endif
 
 If _IsPressed
         .... Same for other 3 keys....

I would encourage you to use arrays. Then if you have to change a condition you only have to change one line not N lines for N keys. And if you needed to change it to use 20 keys then you would only have to change the upper limit of the for /next loop and add the key names and not make the script 5 times as long. So your 4 if statements would reduce to something like this.

Dim $key[4]=["26","27","28","29"]
Dim $keyname[4] = ["Up","Left","Down","Right"]
Dim $keypressed[4]

 For $n = 0 To 3
    If _IsPressed($key[$n]) And $keypressed[$n] == 0 Then
        $keypressed[$n] = 1
        FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{' & $keyname[$n] & ' down}')" & @CRLF)
        $timerS = TimerInit()
    ElseIf Not _IsPressed($key[$n]) And $keypressed[$n] == 1 Then
        $keypressed[$n] = 0
        FileWrite($file, "Sleep(" & TimerDiff($timerS) & ")" & @CRLF & "Send('{' & $keyname[$n] & 'up}')" & @CRLF)
        $timerS = TimerInit()
    EndIf;
Next

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

I would encourage you to use arrays. Then if you have to change a condition you only have to change one line not N lines for N keys. And if you needed to change it to use 20 keys then you would only have to change the upper limit of the for /next loop and add the key names and not make the script 5 times as long. So your 4 if statements would reduce to something like this.

You're right, it's better using the For loop with arrays.

Perfect. I'm using the code you recommend. I'll post an update if I get anywhere...

If anyone else has interest... It'd be great to see what someone else can also do.

Share this post


Link to post
Share on other sites

Interesting. Would this be for Trackmania by any chance?

I've thought about trying to write something like this to record my races in practice mode so I could play it back in official mode. Nothing more frustrating to have a practice run thats perfect and an official run that is a couple hundreds of second slower and no matter how much I redo it I cant get that one perfect run in.

I haven't looked at your code in detail yet. But you might want to avoid the file writes in the middle of your recording session. I'm pretty sure this will slow stuff down and throw off your time calculations. Store it all in an array and write it to a file after you have stopped recording.

doing any code of course takes time but I would think an external IO operation would be much slower then changing an array in memory.

Share this post


Link to post
Share on other sites

Thanks Cal, I was wondering whether it was my file writes that could be throwing me off (since it was perfectly accurate sometimes and off other times)...

I'm actually building it for Trials 2: Second Edition...

Just so i can get a perfect run w/out spending 5 hours on a map.... so I get to a check point, record it, and play it back (heh, i did it before... i'll just have it mimic my past actions :P

Cheating or not? Idk, it's completely objectionable.

It's not worth an argument, just worth the ability to get code to record keystrokes completely accurate.

I'll post what I have working in a couple of hours (after I implement what cal just suggested), so anyone can take off from there...

Share this post


Link to post
Share on other sites

Here's what I got... Seems dead now... It'd be great if someone could figure out how to make it work...

I believe the problem is when you press two keys (even almost) simultaneously.. also i feel there is still something buggy with the timer.

;---------------;
;   3-03-2009  ;
;   4 Key Log  ;
;   Brandon B  ;
;---------------;

#include <Array.au3>
#include <misc.au3>

;File Creation
$RunName = InputBox("Run Name?","Give this Run a name.","","",230,130)
If @Error <> 0 Or $RunName == '' Then
    Exit
EndIf
;Writes the file you put in $RunName Input box to the desktop as an .au3 file so you can compile it and use it also.
$DesktopDir = @DesktopDir
$file = FileOpen($DesktopDir & "\" & $RunName & ".au3", 2)
If $file = -1 Then
    MsgBox(0, "Error", "Unable to create or replace the file on your desktop. Exiting Now.")
    Exit
EndIf

Local $Recording[10] = [';Starting Track: ' & $RunName,';---Start---','HotKeySet("{ESC}", "TerminateProg")','Func TerminateProg()',@TAB & 'Send("{LEFT up}")',@TAB & 'Send("{UP up}")',@TAB & 'Send("{RIGHT up}")',@TAB & 'Send("{DOWN up}")',@TAB & 'Exit 0','EndFunc' & @CRLF]
_ArrayAdd($Recording, 'ToolTip("Activate Window",0,0,"","",4)')
_ArrayAdd($Recording, 'WinWaitActive("Trials 2 - Second Edition")')
_ArrayAdd($Recording, 'ToolTip("Running ' & $RunName & '",0,0,"","",4)' & @CRLF)

;Set a HotKey, so when you Press ESC the recording will exit.
HotKeySet("{ESC}", "TerminateProg")
Func TerminateProg()
    _ArrayAdd($Recording, ';---End---')
;Write the array to File.
    For $r = 0 to UBound($Recording,1) - 1
        FileWrite($file, $Recording[$r] & @CRLF)
    Next
    FileClose($file)
    Exit 0
EndFunc

ToolTip("Activate Window",0,0,"","",4)
WinWaitActive('Trials 2 - Second Edition')
ToolTip("Running " & $RunName,0,0,"","",4)

;Declare our stuff
Dim $key[4]=["25","26","27","28"]
Dim $keyname[4] = ["LEFT","UP","RIGHT","DOWN"]
Dim $keypressed[4] = ["0","0","0","0"]
$timer = TimerInit()

;Begin working
While 1;Script continues until ESC is pressed.
    For $n = 0 To 3
        If _IsPressed($key[$n]) And $keypressed[$n] == 0 Then
            _ArrayAdd($Recording, "Sleep(" & TimerDiff($timer) & ")" & @CRLF & "Send('{" & $keyname[$n] & " down}')")
            $timer = TimerInit()
            $keypressed[$n] = 1
        ElseIf Not _IsPressed($key[$n]) And $keypressed[$n] == 1 Then
            _ArrayAdd($Recording, "Sleep(" & TimerDiff($timer) & ")" & @CRLF & "Send('{" & $keyname[$n] & " up}')")
            $timer = TimerInit()
            $keypressed[$n] = 0
        EndIf
    Next
WEnd

Share this post


Link to post
Share on other sites

Here's what I got... Seems dead now... It'd be great if someone could figure out how to make it work...

I believe the problem is when you press two keys (even almost) simultaneously.. also i feel there is still something buggy with the timer.

;---------------;
;   3-03-2009 ;
;   4 Key Log ;
;   Brandon B ;
;---------------;
 
 #include <Array.au3>
 #include <misc.au3>
 
;File Creation
 $RunName = InputBox("Run Name?","Give this Run a name.","","",230,130)
 If @Error <> 0 Or $RunName == '' Then
     Exit
 EndIf
;Writes the file you put in $RunName Input box to the desktop as an .au3 file so you can compile it and use it also.
 $DesktopDir = @DesktopDir
 $file = FileOpen($DesktopDir & "\" & $RunName & ".au3", 2)
 If $file = -1 Then
     MsgBox(0, "Error", "Unable to create or replace the file on your desktop. Exiting Now.")
     Exit
 EndIf
 
 Local $Recording[10] = [';Starting Track: ' & $RunName,';---Start---','HotKeySet("{ESC}", "TerminateProg")','Func TerminateProg()',@TAB & 'Send("{LEFT up}")',@TAB & 'Send("{UP up}")',@TAB & 'Send("{RIGHT up}")',@TAB & 'Send("{DOWN up}")',@TAB & 'Exit 0','EndFunc' & @CRLF]
 _ArrayAdd($Recording, 'ToolTip("Activate Window",0,0,"","",4)')
 _ArrayAdd($Recording, 'WinWaitActive("Trials 2 - Second Edition")')
 _ArrayAdd($Recording, 'ToolTip("Running ' & $RunName & '",0,0,"","",4)' & @CRLF)
 
;Set a HotKey, so when you Press ESC the recording will exit.
 HotKeySet("{ESC}", "TerminateProg")
 Func TerminateProg()
     _ArrayAdd($Recording, ';---End---')
;Write the array to File.
     For $r = 0 to UBound($Recording,1) - 1
         FileWrite($file, $Recording[$r] & @CRLF)
     Next
     FileClose($file)
     Exit 0
 EndFunc
 
 ToolTip("Activate Window",0,0,"","",4)
 WinWaitActive('Trials 2 - Second Edition')
 ToolTip("Running " & $RunName,0,0,"","",4)
 
;Declare our stuff
 Dim $key[4]=["25","26","27","28"]
 Dim $keyname[4] = ["LEFT","UP","RIGHT","DOWN"]
 Dim $keypressed[4] = ["0","0","0","0"]
 $timer = TimerInit()
 
;Begin working
 While 1;Script continues until ESC is pressed.
     For $n = 0 To 3
         If _IsPressed($key[$n]) And $keypressed[$n] == 0 Then
             _ArrayAdd($Recording, "Sleep(" & TimerDiff($timer) & ")" & @CRLF & "Send('{" & $keyname[$n] & " down}')")
             $timer = TimerInit()
             $keypressed[$n] = 1
         ElseIf Not _IsPressed($key[$n]) And $keypressed[$n] == 1 Then
             _ArrayAdd($Recording, "Sleep(" & TimerDiff($timer) & ")" & @CRLF & "Send('{" & $keyname[$n] & " up}')")
             $timer = TimerInit()
             $keypressed[$n] = 0
         EndIf
     Next
 WEnd
The Sleep function takes an integer so you need

Int(TimerDiff($timer))

If you're going to be fussy then I suppose you could say you should initialize the $keypressed array to zeros not strings since you are comparing with integers.

I had to comment out the lines with WinWaitACtive because there will be no such window on my PC so if the script seems to be dead then add a line after WInWaitACtive to write something to the console output so you know the script has got passed that line.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

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