Mouse Repeater

An effective mouse macro recorder – AutoHotKey

My foray into the versatile AutoHotKey. I’ve made a super simple program that allows the user to record and then play a sequence of mouse moments/actions. It can iterate any number of times and will be useful in removing the needless grind that plagues many games.
Full script below (Creative Commons 4.0).

Usage

The application is simple and easy to use. Simply download below and you’re ready to go! You may have to install AutoHotKey but I’m not sure that it’s necessary.
The Mouse Repeat app is the one showcased in the video that records all mouse movements, the Mouse Click Repeat only mimics clicks.

Press Ctrl-R to prepare for recording. The sequence will begin when you first click you mouse. When done recording, press Esc.
Press Ctrl-E to execute the sequence you just recorded. You’ll get a prompt for the amount of times you want it to repeat (leave it blank for infinite).
That’s it. Press Esc to cancel any active operation and then once more to exit the app. Enjoy!

I originally make this in the effort to disenchant a plethora of champion shards in League of Legends but it’s use is limitless. You could even expand it to pick up on other recordings.
I’m aware plenty of apps like already this exist but this is quite lightweight and it was a super fun project.

Downloads

Unzip and run the application (the .exe file), then follow the instructions above. Or, compile the code yourself, it’s all included in the zip.

Mouse Repeat
Dropbox

Code

As follows is the main script, see the tutorial above for the in-depth overview of its functionality.

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

;ArmanDoesStuff 2020
;records mouse moves/clicks and repeats them a desired amount of times
;ctrl+r to record, ctrl+e to execute, esc to stop recording/playing or exit application

;Sequence vars - A sequence is made up of multiple 10 milisecond intervals (denoted by i) and checks mouse position (x & y)
;and whether or not the mouse is pressed (so far only 0 or 1 for mouseVals, but could expand with other buttons)
posX := []
posY := []
mouseVals := []
i := 0

;Timer that cuts off the begginging of the recording
startTimerRunning := true
timer := 0

recording := false
playing := false

;Auto execute/Start/Main
;Set cord mode here otherwise user must keep window selected
CoordMode, Mouse , Screen
MsgBox, 0, Mouse Repeat, Press ctrl-r to record and ctrl-e to execute`nEsc will stop record/play or close the app if no operation is active
Return

^r::            
    MsgBox, 0, Recording, Click to start recording - Esc to stop, 1
    playing := false
    
    ;reset vars
    i := 0
    timer := 0
    startTimerRunning := true
                
    recording := true
    while(recording = true)
    {
        MouseGetPos, x, y
        posX[i] := x
        posY[i] := y
        mouseVals[i] := 0
        sleep 40
        i++
        if(startTimerRunning = true)
        {
        timer++
        }
    }
            
    if(startTimerRunning = true)
    {
        i := 0
        MsgBox, 0, Recording, Recording failed - you must click to start, 2 
    }
    else
    {
        MsgBox, 0, Recording, Recording completed, 2
    }
    recording := false
return
    
LButton::
    Send {LButton down}
    
    if(recording = true)
    {
        startTimerRunning = false;
        mouseVals[i] := 1
    }
return

LButton up::Send {LButton Up}

^e::
    if(recording = true)
    {
        MsgBox, 0, Still recording, Press esc to finish current recording, 1
    }
    else if(i = 0)
    {
        MsgBox, 0, No recording, Please use ctrl+r to record mouse sequence, 2
    }
    else
    {
        iterations := 0
        InputBox, iterations, Set Iterations, Leave blank for infinity
        
        if(iterations <= 0)
        {
            iterations := -1
            MsgBox, 0, Playing, Playing sequence infinitely - esc to stop, 1
        }
        else
        {
            MsgBox, 0, Playing, Playing sequence %iterations% times - esc to stop, 1
        }
        
        playing := true

        l := i
        while(iterations != 0 && playing = true)
        {
            j := timer
            while(j <= l && playing = true)
            {
                x := posX[j]
                y := posY[j]
                MouseMove, %x%, %y%
                if(mouseVals[j] = 1)
                {
                    Click
                }                   
                sleep 40
                j++             
            }
            iterations--
        }
        MsgBox, 0, Playing, Sequence has ended, 1
        playing := false
    }   
return

Escape::    
    if(recording = true)
    {
        recording := false
        return
    }
    if(playing = true)
    {
        playing := false
        return
    }   
    MsgBox, 0, App Closed, Exiting Application, 1
    ExitApp
return

Below is a more compact/more efficient code that doesn’t track mouse movement and handles the clicks using a timer instead of frame by frame

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

;ArmanDoesStuff 2020
;records mouse clicks and repeats them a desired amount of times
;ctrl+r to record, ctrl+e to execute, esc to stop recording/playing or exit application

posX := []
posY := []
timer := []
i := 0
t := 0

recording := false
playing := false

;Auto execute/Start function
;Set cord mode here otherwise user must keep window selected
CoordMode, Mouse , Screen
MsgBox, 0, Mouse Click Repeat, Press ctrl-r to record and ctrl-e to execute - Esc will stop record/play or close the app if nothing is no operation is active
Return

^r::            
    MsgBox, 0, Recording, Recording Starting, 1 
    playing := false        
    recording := true
    iterations := 0 
    i := 0
    t := 0
    while(recording = true)
    {
        t++
        sleep 10
    }
    MsgBox, 0, Recording, Recording completed, 2    
Return

LButton::
    Send {LButton down}
    if(recording)
    {
        MouseGetPos, x, y
        posX[i] := x
        posY[i] := y
        timer[i] := t * 10
        t = 0
        i++
    }
Return

LButton up::Send {LButton Up}

^e::
    if(recording = true)
    {
        MsgBox, 0, Still recording, Press esc to finish current recording, 1
    }
    else if(i = 0)
    {
        MsgBox, 0, No recording, Please use ctrl+r to record mouse sequence, 2
    }
    else
    {   
    iterations := 0
        InputBox, iterations, Set Iterations, Leave blank for infinity
        
        if(iterations <= 0)
        {
            iterations := -1
            MsgBox, 0, Playing, Playing sequence infinitely - esc to stop, 1
        }
        else
        {
            MsgBox, 0, Playing, Playing sequence %iterations% times - esc to stop, 1
        }
        
        playing := true
        l := i
        ;also have to check "playing" here otherwise infinite loops never break
        while(iterations != 0 && playing = true)
        {
            j := 0
            while(j <= l && playing = true)
            {           
                sleep timer[j]
                x := posX[j]
                y := posY[j]
                Click, %x%, %y%
                j++
            }
            iterations--
        }
        MsgBox, 0, Playing, Sequence has ended, 1
    }
Return

Escape::    
    if(recording = true)
    {
        recording := false
        Return
    }
    if(playing = true)
    {
        playing := false
        Return
    }   
    MsgBox, 0, App Closed, Exiting Application, 1
    ExitApp
Return
Creative Commons License

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.