#SingleInstance force ; #NoTrayIcon #InstallMouseHook #InstallKeybdHook #Persistent settimer, idleCheck, 5000 ; check for idle every 5 seconds sessionLocked = 0 checkSession("sessionMsgHandler") ;call back for when the Windows session changes CoordMode, Mouse, Screen circleScale := 30 ; in pixels speed := 1 ; pixels per step(?) msIdle := 60000 ; 60 seconds - time after considered idle msIdleMax := 300000 ; 5 minutes - time after anti-afk should stop return ; Call back for when the windows session changes sessionMsgHandler(status, ID, Msg, hwnd){ global sessionLocked if (status=0x7) { sessionLocked = 1 } else if (status=0x8) { sessionLocked = 0 } return } idleCheck: global sessionLocked if ((sessionLocked = 0) and (A_TimeIdlePhysical >= msIdle) and (A_TimeIdlePhysical < msIdleMax)) { centreX := A_ScreenWidth/2 centreY := A_ScreenHeight/2 yCoords := [] xCoords := [] degToRad := 3.14159265358979323846/180 loop, 4 { xCoords.Push(Round(centreX + Sin((A_Index-1)*90*degToRad) * circleScale)) yCoords.Push(Round(centreY + Cos((A_Index+1)*90*degToRad) * circleScale)) } Loop { if (A_TimeIdlePhysical < msIdle or (sessionLocked = 1)) { return } xFrom := xCoords[Mod(A_Index-1, 4)+1] xTo := xCoords[Mod(A_Index , 4)+1] yFrom := yCoords[Mod(A_Index-1, 4)+1] yTo := yCoords[Mod(A_Index , 4)+1] MouseMove_Ellipse(xTo, yTo, "B S" speed " i0 OX" xFrom " OY" yFrom) if (A_TimeIdlePhysical > msIdleMax) { return } } } return rand(l, h) { random, r, l, h return r } MouseMove_Ellipse(pos_X1, pos_Y1, param_Options="") { StringUpper, param_Options, param_Options MouseGetPos, loc_MouseX, loc_MouseY ; Use mouse coordinates if origin is omitted pos_X0 := !RegExMatch(param_Options,"i)OX\d+",loc_Match) ? loc_MouseX : SubStr(loc_Match,3) pos_Y0 := !RegExMatch(param_Options,"i)OY\d+",loc_Match) ? loc_MouseY : SubStr(loc_Match,3) ; set speed (default is 1) loc_Speed := !RegExMatch(param_Options,"i)S\d+\.?\d*",loc_Match) ? 1 : SubStr(loc_Match,2) If !RegExMatch(param_Options,"i)I[01]",loc_Match) Random, loc_Inv, 0, 1 ; randomly invert by default Else loc_Inv := SubStr(loc_Match,2) If InStr(param_Options,"R") ; support relative movements pos_X1 += pos_X0 , pos_Y1 += pos_Y0 If ( loc_Block := InStr(param_Options,"B") ) ; Block any mouse input BlockInput, Mouse loc_B := Abs(pos_X0-pos_X1) , loc_A := Abs(pos_Y0-pos_Y1) ; B: Width , A: Height loc_Temp := loc_Inv ^ (pos_X0 loc_A ) { ; If distance from pos_X0 to pos_X1 is greater then pos_Y0 to pos_Y1 loc_MultX := ( pos_X0 < pos_X1 ) ? 1 : (-1) loc_MultY := loc_MultX * ( loc_Inv ? 1 : (-1) ) Loop, % ( loc_B / loc_Speed ) { loc_X := pos_X0 + ( A_Index * loc_Speed * loc_MultX ) ; Add or subtract loc_Speed from X loc_Y := ( loc_MultY * Sqrt(loc_A**2*((loc_X-loc_H)**2/loc_B**2-1)*-1) ) + loc_K ; Formula for Y with a given X MouseMove, %loc_X%, %loc_Y%, 0 } } Else { ; If distance from pos_Y0 to pos_Y1 is greater then pos_X0 to pos_X1 loc_MultY := ( pos_Y0 < pos_Y1 ) ? 1 : (-1) loc_MultX := loc_MultY * ( loc_Inv ? (-1) : 1 ) Loop, % ( loc_A / loc_Speed ) { loc_Y := pos_Y0 + ( A_Index * loc_Speed * loc_MultY ) ; Add or subtract loc_Speed from Y loc_X := ( loc_MultX * Sqrt(loc_B**2*(1-(loc_Y-loc_K)**2/loc_A**2)) ) + loc_H ; Formula for X with a given Y MouseMove, %loc_X%, %loc_Y%, 0 ; Move mouse to new position } } ; Sometimes loop would end with mouse more than "loc_Speed" pixels away from pos_X1,pos_Y1 MouseMove, %pos_X1%, %pos_Y1%, 0 If ( loc_Block ) BlockInput, Off SetMouseDelay, %loc_MDelay% ; Restore previous mouse delay } /* Creates a session message routine targeted at the given function. Format will be changed to hex for the duration of the function call. NOTE: globals must be used Parameters: --------------- - Parameters (explicit call) param1:str - function called upon recieving message param2:bool - return only the wParam, or session status - Parameters (message call) param1:int - wParam: session status param2:int - lParam: session ID param3:int - Msg: message ID (always 0x02B1 or 689) param4:int - hWnd: hwnd of script - Status ID's WTS_CONSOLE_CONNECT (0x1) WTS_CONSOLE_DISCONNECT (0x2) WTS_REMOTE_CONNECT (0x3) WTS_REMOTE_DISCONNECT (0x4) WTS_SESSION_LOGON (0x5) WTS_SESSION_LOGOFF (0x6) WTS_SESSION_LOCK (0x7) WTS_SESSION_UNLOCK (0x8) WTS_SESSION_REMOTE_CONTROL (0x9) WTS_SESSION_CREATE (0xA) (not implemented as of Windows 8.1) WTS_SESSION_TERMINATE (0xB) (not implemented as of Windows 8.1) More info: https://msdn.microsoft.com/en-us/library/aa383828%28v=vs.85%29.aspx --------------- Example: ------------ ; keep a log when a computer becomes locked or unlocked checkSession("sessionMsgHandler") sessionMsgHandler(status,ID,Msg,hwnd){ if (status=0x7) fileAppend,Session Locked`n,%a_desktop%\log.txt else if (status=0x8) fileAppend,Session Unlocked`n,%a_desktop%\log.txt fileAppend,% " " format("{:#x}",status) " " format("{:#x}",ID) " " format("{:#x}",Msg) " " format("{:#x}",hwnd) "`n",%a_desktop%\log.txt return } ----------- */ checkSession(callback){ onMessage(0x02B1,callback) ;WM_WTSSESSION_CHANGE dllCall("Wtsapi32.dll\WTSRegisterSessionNotification","uint",a_scriptHwnd,"uint",NOTIFY_FOR_ALL_SESSIONS) }