[Path of Exile] Auto Potion

Ask gaming related questions (AHK v1.1 and older)
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

[Path of Exile] Auto Potion

23 Feb 2017, 22:18

Hi I'm new here. I'm not completely new to coding but have limited experience with it. I coded this auto potion myself. It is crude but has worked but it doesn't work always and I'm trying to understand why. If anyone can help with this I would appreciate it. There are other improvements that I want to make as well but these are secondary goals.

I get the address values for current hp (chp) and maximum hp (mhp) using Cheat Engine (CE) once at the start of each session. (i would really like an auto updating solution to this perhaps even without using CE if anyone has tips)

Buttons 1,2,3 are hp potions while 4,5,e are other helpful potions and e is a helpful skill. What I'm doing is cycling which potion gets used. So instead of completely depleting potion 1 and then going to potion 2 etc I'm using 1 charge of each potion. This is more efficient if you know the game the potions recharge after monsters are killed so it is smarter to use one of each that way when you kill monsters you gain more charges back then the aforementioned usage scenario.

Here is the actual auto potion:

Code: Select all

#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.

^!p::Pause

SendMode Play
SetKeyDelay, 150, 150, Play
counter:=0
pot:=0

^j::
	loop
	{
		chp:=ReadMemory(0x82B352A0)
		mhp:=ReadMemory(0x82B352A4)
		if (mhp-chp>1200)
		{
			if (Mod(counter, 3)=0)
			{
			Send, {1 1}
			Send, {4 1}
			Send, {5 1}
			Send, {e 1}
			Sleep, 200
			}
			if (Mod(counter, 3)=1)
			{
			Send, {2 1}
			Send, {4 1}
			Send, {5 1}
			Send, {e 1}
			Sleep, 200
			}
			if (Mod(counter, 3)=2)
			{
			Send, {3 1}
			Send, {4 1}
			Send, {5 1}
			Send, {e 1}
			Sleep, 200
			}
		}
		counter+=1
	}
Return
I use this ReadMemory function made by another AHK user placed in the lib folder (C:\Program Files\AutoHotkey\lib):

Code: Select all

#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.

ReadMemory(MADDRESS)
{
winget, pid, PID, Path of Exile

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)

Loop 4
result += *(&MVALUE + A_Index-1) << 8*(A_Index-1)

return, result  
}
Much Love,

Lemon
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

Re: [Path of Exile] Auto Potion

24 Feb 2017, 20:15

I mean the script works it just stops working if i alt+tab for long and i think if i afk for long. That's what i don't understand.
User avatar
Spawnova
Posts: 557
Joined: 08 Jul 2015, 00:12
Contact:

Re: [Path of Exile] Auto Potion

24 Feb 2017, 21:52

I assume those addresses are not static, so it's possible that your player memory address changes after some time, if you haven't already re check your addresses when it stops working to see if they've moved.

Also, If you know how to find pointers in cheat engine you can utilize this in ahk so you do not need to keep re-finding addresses, if you search the forums you can find many examples of reading values from memory pointers.
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

Re: [Path of Exile] Auto Potion

24 Feb 2017, 22:14

I don't think addresses change. The current hp and max hp values remain the same for as long as the game client is open. They change when a new instance of the game client is launched.

Do you have an example to point me to regarding finding addresses in ahk? If i have something similar to look at I'm pretty good at deducing and figuring it out on my own.

My usage and understanding of CE is basic. I know how to search for values and I copy the current and max hp address I've found into the code above. I'm learning about pointers right now. There is a nice guide on CE forums.
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

Re: [Path of Exile] Auto Potion

25 Feb 2017, 00:47

Ok so I figured out how to find static pointers + offsets that yield the max hp and current hp values permanently using CE with this guide and part 2 of the same guide since there were multiple pointers before I got the static.

For Path of Exile:
mhp = 01A110BC + 8E8 + 8C4 + 8E4
chp = 01A110BC + 8E8 + 8C4 + 8E0

So if I understand what you are saying I can now use this in my code as opposed to the nonstatic addresses I had before? Do I just replace the addresses from before with these ones? Is there a particular syntax for address + offset?
Or did you mean I can find these static address + offset values using ahk only (without CE)?

I'll continue experimenting maybe I can answer some of my own questions. In the meantime I appreciate any help.
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

Re: [Path of Exile] Auto Potion

25 Feb 2017, 01:39

Ok I figured it out. Here is my updated code (see below particularly right after loop start). Now I'm just curious is there a way to find the static address + offsets using ahk only? So i never have to go hunting in CE anymore. So will the static address ever change? I mean like what if the game gets patched or updated?

I can now actually begin improving the potion usage logic. It is satisfactory atm but it could be made a lot more intelligently.

Thank you for pointing me in the right direction. I love figuring things out.

http://imgur.com/a/y2CGD

Code: Select all

#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.

^!p::Pause

SendMode Play
SetKeyDelay, 150, 150, Play
counter:=0

^j::
	loop
	{
		pointer1:=ReadMemory(0x01A110BC)
		pointer2:=pointer1+0x8E8
		pointer3:=ReadMemory(pointer2)
		pointer4:=pointer3+0x8C4
		pointer5:=ReadMemory(pointer4)
		pointer6:=pointer5+0x8E0
		chp:=ReadMemory(pointer6)

		pointer7:=pointer5+0x8E4
		mhp:=ReadMemory(pointer7)

		if (mhp-chp>1200)
		{
			if (Mod(counter, 3)=0)
			{
			Send, {1 1}
			Send, {4 1}
			Send, {5 1}
			Send, {e 1}
			Sleep, 200
			}
			if (Mod(counter, 3)=1)
			{
			Send, {2 1}
			Send, {4 1}
			Send, {5 1}
			Send, {e 1}
			Sleep, 200
			}
			if (Mod(counter, 3)=2)
			{
			Send, {3 1}
			Send, {4 1}
			Send, {5 1}
			Send, {e 1}
			Sleep, 200
			}
		}
		counter+=1
	}
Return
RHCP
Posts: 202
Joined: 30 Sep 2013, 10:59

Re: [Path of Exile] Auto Potion

25 Feb 2017, 02:10

A few things come to mind:

Code: Select all

SendMode Play
SetKeyDelay, 150, 150, Play
counter:=0
pot:=0
This code will never be executed, even if you press ^!p. As a result you are using sendmode Input without a keyboard hook installed, this can lead to keys (particularly modifiers) becoming logically stuck down, especially when the send command is invoked while the user is pressing a modifier key. Try installing the keyboard hook (#InstallKeybdHook). This could explain why it stops working after you alt+tab - often manually pressing the modifier keys can logically release the key.


Your readMemory function doesn't close the opened process handle, and since it is being called so frequently it will leak millions of handles. You should call closeHandle after performing the RPM, e.g.

Code: Select all

ReadMemory(address)
{
    ; It would be safer to use a more exact title for winget e.g.
    ; winget, pid, PID, ahk_exe PathOfExile.exe ; or what ever the exe is called
    ; otherwise you risk reading from another process when PoE isn't the active window.
    winget, pid, PID, Path of Exile
    if !pid 
        return 
    if !hProcess := DllCall("OpenProcess", "UInt", 24, "Int", False, "UInt", pid, "Ptr") 
        return 
    success := DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", address, "UInt*", result, "Ptr", 4, "Ptr",0)
    DllCall("CloseHandle", "Ptr", hProcess)
    return success ? result : ""
}

Code: Select all

counter+=1
That line of code may be in the wrong spot - atm the code is randomly choosing one of the three potions, rather than cycling between them in an ordered manner.

This thread may also be of interest to you - it has an AHK example: http://www.ownedcore.com/forums/mmo/pat ... ost3679476
Pointers can change after a patch, but sometimes they dont. The script at ownedCore uses array of byte scanning which is more resilient to patches.

https://autohotkey.com/boards/viewtopic ... 85#p126100
This post shows a single line method to reading a pointer.

Cheers.
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

Re: [Path of Exile] Auto Potion

25 Feb 2017, 03:10

So yea even after I update my code with static address + offsets the code stops running randomly and it does seem to do with alt+tab because while I am in game it consistently works.

I don't understand why this will never be executed. The intent wasn't for it to be run after pressing ^!p but rather I was trying to set the SendMode and some variables globally. Do I have to put this code after a hotkey trigger like after ^j::? Will code not run unless it is preceded by a hotkey trigger? I'm trying it now after ^j:: to see if anything is different.

Code: Select all

SendMode Play
SetKeyDelay, 150, 150, Play
counter:=0
pot:=0
I just copied the ReadMemory function from another user I found through a simple google search. In the comments other users mentioned the same flaw you mentioned about closing the handles. But since I think this stuff is a little above my head I just used the code exactly as I found it. It seemed to be working but I am now updating with your version. I think I will also update with a more precise winget statement as you suggest but I have to experiment since I'm not sure I'll get it right on first try. One change at a time so I can isolate problematic steps. I think this may be the thing that solves why the code stops working after alt+tab for prolonged periods.

I think the counter+=1 is in the right spot. I was going for this algorithm:

counter = 0

if damage > 1200
use pot 1 because Mod(counter, 3)=0 that is 0 mod 3 = 0
counter = counter + 1
next time
if damage > 1200
use pot 2 because Mod(counter, 3)=1 that is 1 mod 3 = 1
counter = counter + 1
next time
if damage > 1200
use pot 3 because Mod(counter, 3)=2 that is 2 mod 3 = 2
counter = counter + 1
... it begins to repeat now pot 1 2 3 1 2 3 1 2 3

I think it is correct no?

I will report back some results later.
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

Re: [Path of Exile] Auto Potion

25 Feb 2017, 05:23

Oh you were right. counter+=1 should be 1 level up. There are some really good relevant links you gave but I fear it is a bit over my head. I am so close to having my own solution I'd rather just iron the kinks out of my code. Plus there is a sense of pride involved.

You were also right about the SendMode Play and SetKeyDelay commands not being executed. When I moved them to the appropriate spot they caused my program to not work so I got rid of them completely.

I changed MemoryRead winget function into this as suggested I'm hoping this will solve the alt+tab problem:

Code: Select all

WinGet, pid, PID, ahk_exe PathofExileSteam.exe
I tried simplifying the address calculations into 1 line each but that caused my code to stop working entirely so I reverted back to this it works no need to mess with it:

Code: Select all

pointer1:=ReadMemory(0x01A110BC)
pointer2:=pointer1+0x8E8
pointer3:=ReadMemory(pointer2)
pointer4:=pointer3+0x8C4
pointer5:=ReadMemory(pointer4)
pointer6:=pointer5+0x8E0
chp:=ReadMemory(pointer6)

pointer7:=pointer5+0x8E4
mhp:=ReadMemory(pointer7)
RHCP
Posts: 202
Joined: 30 Sep 2013, 10:59

Re: [Path of Exile] Auto Potion

25 Feb 2017, 05:44

I don't understand why this will never be executed.
After the script has been loaded, it begins executing at the top line, continuing until a Return, Exit, hotkey/hotstring label, or the physical end of the script is encountered (whichever comes first). This top portion of the script is referred to as the auto-execute section.
if a hotkey needs to execute only a single line, that line can be listed to the right of the double-colon. In other words, the return is implicit:
#n::Run Notepad
Note, anything listed under that hotkey will not be executed as a result of pressing #n.

I have zero experience with sendPlay (it always gave my win7 PCs instant BSODS), but it may help. Alternatively, using the keyboard hook and sendInput should prevent sticky modifiers, however sendInput sends keys instantly (without delays) which may not work for some games. Controlsend is also worth a shot.

In AHK it's generally better to use timers rather than a never ending loop. It doesn't matter in this case, but when a script has other hotkeys, features, timers, etc it can cause issues.

I doubt winget was causing any issues when PoE was the active window (even if you alt tabbed out and back in). When using the non-specific window title and PoE is NOT the active window it's possible for winget to retrieve the PID of another process which has a window title beginning with 'Path of Exile' (such as a web page or open folder directory). However, once you alt+tab back into a game winget will prioritise the active window and the RPM will work fine.

Cheers.
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

Re: [Path of Exile] Auto Potion

25 Feb 2017, 08:08

Well i don't know after changing winget parameters everything works so well now. I alt tab all the time and afk and it has not yet broken my script. So I think that was it. Thanks for all the help. Everything works really well now. Maybe I'll play around with directives like #IfWinActive and the keyboard hook you mentioned. Here are my final scripts:

Auto Potion:

Code: Select all

#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.

^!p::Pause

^j::

	;SendMode Play
	;SetKeyDelay, 150, 150, Play
	counter:=0

	loop
	{
		pointer1:=ReadMemory(0x01A110BC)
		pointer2:=pointer1+0x8E8
		pointer3:=ReadMemory(pointer2)
		pointer4:=pointer3+0x8C4
		pointer5:=ReadMemory(pointer4)
		pointer6:=pointer5+0x8E0
		chp:=ReadMemory(pointer6)

		pointer7:=pointer5+0x8E4
		mhp:=ReadMemory(pointer7)

		if (mhp-chp>1200)
		{
			if (Mod(counter, 3)=0)
			{
			Send, {1 1}
			Send, {4 1}
			Send, {5 1}
			Send, {e 1}
			Sleep, 200
			}
			if (Mod(counter, 3)=1)
			{
			Send, {2 1}
			Send, {4 1}
			Send, {5 1}
			Send, {e 1}
			Sleep, 200
			}
			if (Mod(counter, 3)=2)
			{
			Send, {3 1}
			Send, {4 1}
			Send, {5 1}
			Send, {e 1}
			Sleep, 200
			}
			counter+=1
		}
	}
Return
ReadMemory

Code: Select all

#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.

ReadMemory(address)
{
    ; It would be safer to use a more exact title for winget e.g.
    ; winget, pid, PID, ahk_exe PathOfExile.exe ; or what ever the exe is called
    ; otherwise you risk reading from another process when PoE isn't the active window.
    WinGet, pid, PID, ahk_exe PathofExileSteam.exe
    if !pid 
        return 
    if !hProcess := DllCall("OpenProcess", "UInt", 24, "Int", False, "UInt", pid, "Ptr") 
        return 
    success := DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", address, "UInt*", result, "Ptr", 4, "Ptr",0)
    DllCall("CloseHandle", "Ptr", hProcess)
    return success ? result : ""
}
0sync0
Posts: 46
Joined: 05 Aug 2016, 13:57

Re: [Path of Exile] Auto Potion

25 Feb 2017, 13:42

What needs to be modified in the ReadMemory function to make it work with float values?
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

Re: [Path of Exile] Auto Potion

25 Feb 2017, 15:34

uhh i don't know man i'm new to this... but it works for me! :)
RHCP
Posts: 202
Joined: 30 Sep 2013, 10:59

Re: [Path of Exile] Auto Potion

25 Feb 2017, 20:04

0sync0 wrote:What needs to be modified in the ReadMemory function to make it work with float values?
Change

Code: Select all

success := DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", address, "UInt*", result, "Ptr", 4, "Ptr",0)
to

Code: Select all

success := DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", address, "Float*", result, "Ptr", 4, "Ptr",0)
Guest

Re: [Path of Exile] Auto Potion

26 Feb 2017, 20:11

RHCP wrote:
0sync0 wrote:What needs to be modified in the ReadMemory function to make it work with float values?
Change

Code: Select all

success := DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", address, "UInt*", result, "Ptr", 4, "Ptr",0)
to

Code: Select all

success := DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", address, "Float*", result, "Ptr", 4, "Ptr",0)
Thanks.

Code: Select all

SetFormat, Integer, hex
pointer1:=ReadMemory(0x019D45B0)
pointer2:=ReadMemory(pointer1+0x2C)
pointer3:=ReadMemory(pointer2+0xF4)
pointer4:=ReadMemory(pointer3+0x74)
pointer5:=ReadMemory(pointer4+0x79C)
pointer6:=ReadMemory(pointer5+0xA4)
This code uses values from this Cheat Engine pointer scan.
http://imgur.com/a/zdiJZ

The first pointer for the base address doesn't match the value that CE shows.
0sync0
Posts: 46
Joined: 05 Aug 2016, 13:57

Re: [Path of Exile] Auto Potion

27 Feb 2017, 16:59

@LemonHaze Is the code you posted the full version? When I read the base address of my first pointer I don't get the expected value. I think it might be because there is no code for getting the base address of the game.
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

Re: [Path of Exile] Auto Potion

28 Feb 2017, 21:20

The code has been posted in full and is working without problems (use the code in my last post). All issues I had with it have now been resolved thanks to RHCP's help.

The ReadMemory function needs to be in this location C:\Program Files\AutoHotkey\lib

welp... nvm it was working but since the Breach league merger with Standard league the pointers have changed. I have to find the new pointer and offsets now.
RHCP
Posts: 202
Joined: 30 Sep 2013, 10:59

Re: [Path of Exile] Auto Potion

28 Feb 2017, 22:45

Guest wrote:
RHCP wrote:
0sync0 wrote:What needs to be modified in the ReadMemory function to make it work with float values?
Change

Code: Select all

success := DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", address, "UInt*", result, "Ptr", 4, "Ptr",0)
to

Code: Select all

success := DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", address, "Float*", result, "Ptr", 4, "Ptr",0)
Thanks.

Code: Select all

SetFormat, Integer, hex
pointer1:=ReadMemory(0x019D45B0)
pointer2:=ReadMemory(pointer1+0x2C)
pointer3:=ReadMemory(pointer2+0xF4)
pointer4:=ReadMemory(pointer3+0x74)
pointer5:=ReadMemory(pointer4+0x79C)
pointer6:=ReadMemory(pointer5+0xA4)
This code uses values from this Cheat Engine pointer scan.
http://imgur.com/a/zdiJZ

The first pointer for the base address doesn't match the value that CE shows.
Just so everyone's on the same page, that pointer is for Elder Scrolls. You need to find the base address of the process, i.e. the memory address that eso.exe resolves to in CE.
Here are two methods to get the base address of the program.

If the first method doesn't work, try the second.

Code: Select all

; The base address for some programs is dynamic. This can retrieve the current base address of the main module (e.g. Calc.exe), 
; which can then be added to your various offsets.	
; This function will return the correct address regardless of the 
; bitness (32 or 64 bit) of both the AHK exe and the target process.
; That is they can both be 32 bit or 64 bit, or the target process
; can be 32 bit while ahk is 64bit

; Return values:
;   Null        The process's window couldn't be found.
;   0           The GetWindowLong or GetWindowLongPtr call failed.
;   Non-Zero    The base address of the process (success).

getProcessBaseAddress(WindowTitle, windowMatchMode := "3")    ;WindowTitle can be anything ahk_exe ahk_class etc
{
    if (windowMatchMode && A_TitleMatchMode != windowMatchMode)
    {
        mode := A_TitleMatchMode ; This is a string and will not contain the 0x prefix
        StringReplace, windowMatchMode, windowMatchMode, 0x ; remove hex prefix as SetTitleMatchMode will throw a run time error. This will occur if integer mode is set to hex and matchmode param is passed as an number not a string.
        SetTitleMatchMode, %windowMatchMode%    ;mode 3 is an exact match
    }
    WinGet, hWnd, ID, %WindowTitle%
    if mode
        SetTitleMatchMode, %mode%    ; In case executed in autoexec
    if !hWnd
        return ; return blank failed to find window
    return DllCall(A_PtrSize = 4     ; If DLL call fails, returned value will = 0
        ? "GetWindowLong"
        : "GetWindowLongPtr"
        , "Ptr", hWnd, "Int", -6, A_Is64bitOS ? "Int64" : "UInt")  
        ; For the returned value when the OS is 64 bit use Int64 to prevent negative overflow when AHK is 32 bit and target process is 64bit 
        ; however if the OS is 32 bit, must use UInt, otherwise the number will be huge (however it will still work as the lower 4 bytes are correct)      
        ; Note - it's the OS bitness which matters here, not the scripts/AHKs
} 

Code: Select all

; Parameters:
;   Program - Can be any window title/class e.g "AHK_EXE calc.exe"
;   Module - The file name of the module/dll to find e.g. "GDI32.dll", "Battle.net.dll" etc
;            If no module is specified, the address of the base module - main() (program) will be returned e.g. C:\Program Files (x86)\Skype\Phone\Skype.exe

; Return Values: 
;   Positive integer - Module base address
;   -1 - Module not found
;   -2 - Couldn't find the process. The program isn't running or you passed an incorrect program identifier parameter
;   -3 - Couldn't open the process. If the target process is running with admin rights, then the script will also need to be ran as admin. 
;   -4 - Problem with EnumProcessModules. This shouldn't happen.
;   -5 - The AHK script is 32 bit and you are trying to access the modules of a 64 bit target process.

; Note: A 64 bit AHK can enumerate the modules of a target 64 or 32 bit process.
;       A 32 bit AHK (any process actually) can only enumerate the modules of another 32 bit process

getModuleBaseAddress(program, module := "")
{
    WinGet, pid, pid, %program%
    if pid                              ; PROCESS_QUERY_INFORMATION + PROCESS_VM_READ 
        hProc := DllCall("OpenProcess", "UInt", 0x0400 | 0x0010 , "Int", 0, "UInt", pid)
    else return -2
    if !hProc
        return -3
    if (A_PtrSize = 4) ; AHK 32bit
    {
        DllCall("IsWow64Process", "Ptr", hProc, "Int*", result)
        if !result 
            return -5, DllCall("CloseHandle","Ptr",hProc)  ; AHK is 32bit and target process is 64 bit, this function wont work 
    }
    if (module = "")
    {        
        VarSetCapacity(mainExeNameBuffer, 2048 * (A_IsUnicode ? 2 : 1))
        DllCall("psapi\GetModuleFileNameEx", "Ptr", hProc, "UInt", 0
                    , "Ptr", &mainExeNameBuffer, "UInt", 2048 / (A_IsUnicode ? 2 : 1))
        mainExeFullPath := StrGet(&mainExeNameBuffer)
        ; mainExeName = main executable module of the process (will include full directory path)
    }
    size := VarSetCapacity(lphModule, 4)
    loop 
    {
        DllCall("psapi\EnumProcessModules", "Ptr", hProc, "Ptr", &lphModule
                , "UInt", size, "UInt*", reqSize)
        if ErrorLevel
            return -4, DllCall("CloseHandle","Ptr",hProc) 
        else if (size >= reqSize)
            break
        else 
            size := VarSetCapacity(lphModule, reqSize)    
    }
    VarSetCapacity(lpFilename, 2048 * (A_IsUnicode ? 2 : 1))
    loop % reqSize / A_PtrSize ; sizeof(HMODULE) - enumerate the array of HMODULEs
    {
        DllCall("psapi\GetModuleFileNameEx", "Ptr", hProc, "Ptr", numget(lphModule, (A_index - 1) * A_PtrSize)
                , "Ptr", &lpFilename, "UInt", 2048 / (A_IsUnicode ? 2 : 1))
        ; module will contain directory path as well e.g C:\Windows\syswow65\GDI32.dll
        moduleFullPath := StrGet(&lpFilename) 
        SplitPath, moduleFullPath, fileName ; strips the path so = GDI32.dll
        if (module = "" && mainExeFullPath = moduleFullPath) || (module != "" && module = filename)
        {
            VarSetCapacity(MODULEINFO, A_PtrSize = 4 ? 12 : 24)
            DllCall("psapi\GetModuleInformation", "Ptr", hProc, "Ptr", numget(lphModule, (A_index - 1) * A_PtrSize)
                , "Ptr", &MODULEINFO, "UInt", A_PtrSize = 4 ? 12 : 24)
            return numget(MODULEINFO, 0, "Ptr"), DllCall("CloseHandle","Ptr",hProc)
        }
    }
    return -1, DllCall("CloseHandle","Ptr",hProc) ; not found
}

Example:

Code: Select all

base := getProcessBaseAddress("ahk_exe eso.exe")
; Or 
; base := getModuleBaseAddress("ahk_exe eso.exe")

pointer1:=ReadMemory(base + 0x019D45B0)
pointer2:=ReadMemory(pointer1+0x2C)
pointer3:=ReadMemory(pointer2+0xF4)
pointer4:=ReadMemory(pointer3+0x74)
pointer5:=ReadMemory(pointer4+0x79C)
value:=ReadMemory(pointer5+0xA4)
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

Re: [Path of Exile] Auto Potion

28 Feb 2017, 23:06

I figured out a new working set of static address and offsets (well only the static address changed the offsets are still the same). My program works fine with the new values. But now how do I use this getProcessBaseAddress functions you posted for the sake of learning?

I use it to get a base address value. Now assuming this is a static address how do i find the offsets from this base that lead to current hp and max hp? And so if the function always finds the base address and if the offsets from that base address to my desired variable never change then this is a more update/patch proof solution is that right?
LemonHaze_
Posts: 21
Joined: 23 Feb 2017, 22:02

Re: [Path of Exile] Auto Potion

28 Feb 2017, 23:25

For Path of Exile new static address is: 0165 10BC
The offsets remain the same.
For chp: + 8e8 + 8c4 + 8e0
For chp: + 8e8 + 8c4 + 8e4

I changed the healing logic of my code to suit the Berserker class with 25% warcry healing on the e key.

I will likely have to update the static address yet again on Friday when the new league is released.

Code: Select all

#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.

^!p::Pause

^j::

	counter:=0

	loop
	{
		p1:=ReadMemory(0x016510bc)
		p2:=ReadMemory(p1+0x8E8)
		p3:=ReadMemory(p2+0x8C4)
		chp:=ReadMemory(p3+0x8E0)

		mhp:=ReadMemory(p3+0x8E4)

		if (chp/mhp<=0.60)
		{
			if (Mod(counter, 2)=0)
			{
				Send, {1 1}
				Send, {4 1}
				Send, {5 1}
				Send, {e 1}
				Sleep, 200
			}
			if (Mod(counter, 2)=1)
			{
				Send, {2 1}
				Send, {4 1}
				Send, {5 1}
				Send, {e 1}
				Sleep, 200
			}
			counter+=1
		}

		if (chp/mhp<=0.75)
		{
			Send, {e 1}
			Sleep, 200
		}
	}
Return

Return to “Gaming Help (v1)”

Who is online

Users browsing this forum: DaveyW and 36 guests