Code:
AntiAFK_Code(Index, Key, ByRef RunningVar, ByRef StopVar)
{
;- Check if the HotKey is already running.
if RunningVar
{
; Let's signal the running thread it to stop.
StopVar := true
return
}
;- Make sure that we actually have a Trove window targeted.
if not WinActive("Trove")
return
;- Signal that we have officially been able to start.
RunningVar := true
;- If it's not running, we'll start by grabbing information about the games window.
WinGet, PID, PID, A
WinGet, HWND, ID, A
; Show a tooltip at the windows position.
CoordMode, ToolTip, Screen
WinGetPos, winX, winY, winW, winH, ahk_pid %PID%
;- The actual loop that does our work.
Timer := 0
Time_Start := A_TickCount
Loop
{
; Avoiding AFK is as simple as opening up the Character menu.
ControlSend, , {c down}, ahk_pid %PID%
Sleep, 86
ControlSend, , {c up}, ahk_pid %PID%
; Sleep in order to not look like a spammer.
Random, SleepTime, 5, 50
Loop %SleepTime%
{
; Check if we should stop.
if StopVar
break 2
; Display AFK time.
CoordMode, ToolTip, Screen
WinGetPos, winX, winY, winW, winH, ahk_pid %PID%
Time := A_TickCount - Time_Start
ToolTipText =
(
Anti-AFK Bot %Index% is running, press %Key% to stop it.
Total Time: %Time% ms.
)
ToolTip, %ToolTipText%, %winX%, %winY%
Random, SleepTime, 86, 111
Sleep, %SleepTime%
Timer := Timer + 1
}
}
; Reset state for re-use.
RunningVar := false
StopVar := false
ToolTip, , , , 1
}
AutoFishing_Code(Index, Key, ByRef RunningVar, ByRef StopVar)
{
;- Check if the HotKey is already running.
if RunningVar
{
; Let's signal the running thread it to stop.
StopVar := true
return
}
;- Make sure that we actually have a Trove window targeted.
if not WinActive("Trove")
return
;- Signal that we're running now.
RunningVar := true
;- If it's not running, we'll start by grabbing information about the games window.
WinGet, PID, PID, A
WinGet, HWND, ID, A
;- Pointers
Base := getProcessBaseAddress(HWND)
WaterAddress := GetAddressWater(PID, Base, 0x009570DC)
LavaAddress := GetAddressLava(PID, Base, 0x009570DC)
ChocoAddress := GetAddressChoco(PID, Base, 0x009570DC)
;- Statistics
Time_Start := A_TickCount
Time := 0
Fishing_Start := A_TickCount
Fishing := 0
Fish := 0
HumanPressButton(b, ahk_pid %PID%)
; The main loop based on a State-Machine.
State=0
Loop
{
; Show a tooltip at the windows position.
CoordMode, ToolTip, Screen
WinGetPos, winX, winY, winW, winH, ahk_pid %PID%
Time := A_TickCount - Time_Start
ToolTipText=
(
Auto-Fishing Bot %Index% is running, press %Key% to stop it.
Total Time: %Time% ms
Total Fish Caught: %Fish%
Fishing Time: %Fishing% ms
State: %State%/%StateNext%
)
ToolTip, %ToolTipText%, %winX%, %winY%, 1s
;- State-Machine
If IsLabel("AutoFishing-" . State)
{
Loop 1 {
Goto AutoFishing-%State%
; State: Anti-AFK
AutoFishing-0:
AutoFishing-AntiAFK-Init:
ControlSend, , {c down}, ahk_pid %PID%
; Advance
State=AntiAFK
StateTimer=0
Break
AutoFishing-AntiAFK:
ControlSend, , {c up}, ahk_pid %PID%
; Advance
State=AntiDetection-Init
StateNext=ThrowHook-Init
StateTimer=0
Break
; State: Throw Hook
AutoFishing-2:
AutoFishing-ThrowHook-Init:
ControlSend, , {f down}, ahk_pid %PID%
; Advance
State=ThrowHook
StateTimer=0
Random, StateMaxTimer, 2, 15
Break
AutoFishing-ThrowHook:
ControlSend, , {f up}, ahk_pid %PID%
; Time Display
Fishing_Start := A_TickCount
; Advance
State=AntiDetection-Init
StateNext=Prepare
Break
; State: Prepare for Check
AutoFishing-Prepare:
; Update Statistics
Fishing := A_TickCount - Fishing_Start
; Read memory to determine if we're in the pool of things (it's 1 until it hits the surface).
CaughtWater := ReadMemory(PID, WaterAddress)
CaughtLava := ReadMemory(PID, LavaAddress)
CaughtChoco := ReadMemory(PID, ChocoAddress)
if !(CaughtWater || CaughtLava || CaughtChoco)
{
State=Check
}
else {
; If 5 seconds have passed, assume we hit the ground and reset.
If (Fishing > 5000)
State=0
}
Break
; State: Check for Fish
AutoFishing-Check:
; Update Statistics
Fishing := A_TickCount - Fishing_Start
; Read memory to determine if we have something hooked or not.
; (Can we do this without reading memory? This is easily detectable, we'd have to mask it like a virus scanner.)
CaughtWater := ReadMemory(PID, WaterAddress)
CaughtLava := ReadMemory(PID, LavaAddress)
CaughtChoco := ReadMemory(PID, ChocoAddress)
if (CaughtWater || CaughtLava || CaughtChoco)
{
Fish := Fish + 1
State=AntiDetection-Init
StateNext=ReelIn-Init
}
else
{
; If 45 seconds have passed, we're bugged so reset.
if (Fishing > 45000)
{
State=AntiDetection-Init
StateNext=ReelIn-Init
}
}
Break
; State: Reel In Hook
AutoFishing-ReelIn-Init:
ControlSend, , {f down}, ahk_pid %PID%
State=ReelIn
Break
AutoFishing-ReelIn:
ControlSend, , {f up}, ahk_pid %PID%
State=CompleteCycle
StateNext=Reset
Break
; State: Complete Cycle
AutoFishing-CompleteCycle-Init:
Random, StateMaxTimer, 8, 16
State=CompleteCycle
StateTimer=0
Break
AutoFishing-CompleteCycle:
StateTimer := StateTimer + 1
if (StateTimer > StateMaxTimer)
{
State=AntiDetection-Init
StateNext=Reset
}
Break
; Reset State
AutoFishing-Reset:
State=0
StateNext=
StateTimer=0
StateMaxTimer=0
Break
; Utility State: Anti-Detection (wait humane amount of time)
AutoFishing-AntiDetection-Init:
Random, StateMaxTimer, 8, 16
State=AntiDetection
StateTimer=0
Break
AutoFishing-AntiDetection:
StateTimer := StateTimer + 1
if (StateTimer > StateMaxTimer)
{
State=%StateNext%
StateNext=
StateTimer=0
}
Break
}
}
; Check if we should stop.
if StopVar
break
HumanLikeSleep()
}
HumanPressButton(b, ahk_pid %PID%)
; Reset state for re-use.
RunningVar := false
StopVar := false
ToolTip, , , , 1
}
HumanPressButton(Button, To)
{
ControlSend, , {%Button% down}, %To%
HumanLikeSleep()
ControlSend, , {%Button% up}, %To%
}
HumanLikeSleep()
{
Random, SleepTime, 66, 122
Sleep, %SleepTime%
}
;- Helpers & Utility
GetAddressWater(PID, Base, Address)
{
pointerBase := base + Address
y1 := ReadMemory(PID, pointerBase)
y2 := ReadMemory(PID, y1 + 0x144)
y3 := ReadMemory(PID, y2 + 0xe4)
Return WaterAddress := (y3 + 0x70)
}
GetAddressLava(PID, Base, Address)
{
pointerBase := base + Address
y1 := ReadMemory(PID, pointerBase)
y2 := ReadMemory(PID, y1 + 0x144)
y3 := ReadMemory(PID, y2 + 0xe4)
Return LavaAddress := (y3 + 0x514)
}
GetAddressChoco(PID, Base, Address)
{
pointerBase := base + Address
y1 := ReadMemory(PID, pointerBase)
y2 := ReadMemory(PID, y1 + 0x144)
y3 := ReadMemory(PID, y2 + 0xe4)
Return ChocoAddress := (y3 + 0x2c0)
}
getProcessBaseAddress(HWND)
{
return DllCall( A_PtrSize = 4
? "GetWindowLong"
: "GetWindowLongPtr"
, "Ptr", HWND
, "Int", -6
, "Int64") ; Use Int64 to prevent negative overflow when AHK is 32 bit and target process is 64bit
; If DLL call fails, returned value will = 0
}
ReadMemory(PID, MADDRESS)
{
VarSetCapacity(MVALUE,4,0)
ProcessHandle := DllCall("OpenProcess", "Int", 24, "Char", 0, "UInt", PID, "UInt")
;DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",4,"UInt *",0)
DllCall("ReadProcessMemory", "UInt", ProcessHandle, "Ptr", MADDRESS, "Ptr", &MVALUE, "Uint",4)
Loop 4
result += *(&MVALUE + A_Index-1) << 8*(A_Index-1)
return, result
}