[Release][Autohotkey script] PoE Autoflasks & autoquit. menu

User Tag List

Page 1 of 32 12345 ... LastLast
Results 1 to 15 of 473
  1. #1
    Wrongusername's Avatar Sergeant
    Reputation
    100
    Join Date
    Feb 2011
    Posts
    65
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Release][Autohotkey script] PoE Autoflasks & autoquit.

    0.11.5 update
    gameState 0x1d78->0x1ff8
    Updated for 0.11.3b
    gamestate 0x1bf8->01d78
    Updated for 0.11.2b
    framebase pointerpath 0x84->0x94
    Updated for 0.11.1c
    Updated for 0.11c
    Updated for 0.10.8, player stats multiptr changed 0x51C -> 0x59C
    Changed autoquit method again to memory-writing 1 UInt instead of those unreliable clicks... For those updating from older version you also need to update autohotkeymemorylib.ahk since it requests process handle with VM_READ|VM_WRITE|VM_OPERATION access for new autoquit type now.

    Requires Autohotkey_L to run
    http://l.autohotkey.net/AutoHotkey_L_Install.exe

    Autohotkey_L installed should be exactly Unicode x32 version(you get to choose and on Win x64 it defaults to x64 version, i think that may mean calling 64-bit dllcalls which would screw this script up).

    Uses passive memory reading & keypress sending.

    It reads basic flasks properties like flask type/current charges/charges per use/recovery duration to try and optimally use your Mana/Health/Hybrid flasks

    It does not read out prefixes/suffixes(it actually really only cares for ones that affect recovery speed) but allows you to easily specify such differences in by-character-name Flaskconfig.

    Also allows you to specify min life/nshield % to auto-quit on hardcore.

    Currently most use from this can be gained if used for multiboxing, it'll manage all your open PoE windows.

    Default toggle hotkey - F1


    In case of a new client update you can try commenting out this line to let it try to find new offset
    baseMgrPtr:=
    comment it out like this
    ; baseMgrPtr:=

    To use script with ISBoxer change line
    cliname=Path of Exile
    to
    cliname=is
    and run script as administrator
    Also probably need to turn off repeating for 1-5 if it's on.

    Update:
    Fixed multiple drinking/spamming potions.
    Default requested process rights changed to VM_READ only since it's been reported to fix script not working for some.
    Default autoQuit method changed to quit to main menu, resolution independent, should succeed in case of lags too.
    Some additional checks and fixes to make sure it doesn't auto-quit forever if auto-quit is enabled.
    Hybrid flasks now considered for both regen queues regardless of which resource type(hp/mana) they're initially used for
    Fixed bug with not reading energy shield.
    0.10.1f bptr updated, built-in AoB successfully scans for it too but wouldn't use it right away unless you followed it's advice and saved it to script.
    Fixed incorrect reading of reserved mana amount(read reserved hp instead)
    Further fixes to reservation cases : turns out flat value auras and % reserved are stored separately

    Multiple fixes and additions:
    BasePointer scan immediate use of found value was still bugged.

    In multiboxing environment 1 dead/non-ingame toon could prevent script from checking out other windows since it used break on client windows iteration loop instead of continue.

    Further attempt at fixing excessive quitting(closing game window when already at login menu/trying to log back in).
    Quit mechanism reworked to also send "Space" - close all panels key, will get you out in case for example some mob sneaks up on you while you're looking at passive skilltree or whatever

    Added tolerance time for soft-quit to mainmenu method "autoQuitSoftToleranceBeforeKill", in case it doesn't get out to mainmenu within tolerance time for whatever reason it'll resort to ending process.

    Basic granite flask support added with configurable life/nshield tresholds. Since NShield regen kicks in after quite a while it's likely to waste some charges on all granite CI toons by drinking some of that flasks even after mobs are dead, but it should work well on otherwise hp-flask using toons(either for hp regen or nshield regen through zealot's oath).

    Some vars/arrays renamed to better reflect their purpose, a bit of streamlining/cleanup done.

    Since it seems to be easy enough on resources for this to decrease performance in any noticeable way and this greatly increases chances of you getting saved from death, reduced default watchdog period to 100 ms from 1000ms.
    Now defaults to "On" state when run since it seems to adequately handle distinguishing between menu/ingame states & alive/dead toons at this point.

    Some basic error messages for critical error cases instead of silent failures, will also auto-quit script in that cases:
    Running script on AutoHotkey 64-bit
    Failure to obtain moduleBase, moduleSize
    Failure to obtain valid process handle for client
    (AoBScan failure produced notification, will auto-quit now in addition to make it clear script can't work in that case)

    Fixed a bug that would lead to script cpu-hogging while in mainmenu(which in turn exposed whole design flaw with sleeping between drinking potions related to multiboxing, since that "sleep" accidentally wound up in main loop that basically meant sequential only & not parallel drinking of potions...)

    Flask timers are now reset in case you get to 100% of respective resource.

    Updated to 0.10.2, besides basepointer changing, flasks pointerpath changed a bit
    Updated for 0.10.3, just a basepointer change, fixed yet another minor bug with using scanned bptr right away.
    Updated to 0.10.4, bptr change, player entity ptr change 0x49C > 0x51C. Fixed quit to loginscreen > client resolution ptrs shifted by +8.
    Flask load-balancing implemented, to maximize charges intake from killing monsters it now doesn't try to drain flasks sequentially but takes sips from flaks of same type in turns.
    Playername length limit raised from 15 to 50 characters

    As usual test autoquit to menu by pressing F4

    PoE_AutoFlasks.ahk
    Code:
    SetBatchLines, -1
    DetectHiddenWindows, On
    
    cliname=Path of Exile
    cliexe=Client.exe
    trayNotifications:=true ;display tray notifications about script actions : drinking potions, autoquitting
    autoPotionsWatchdogPeriod:=100 ;milliseconds, decrease this value to have script recheck life/mana/flasks availability more often/increase chances of getting saved from death in time
    lagCompensation:=50
    
    autoQuitMode:=1 ; default autoQuit method : 0 =winKill, 1 = exit to login screen
    autoQuitPauseBeforeClick:=100
    autoQuitSoftToleranceBeforeKill:=2000 ; try to quit to loginscreen at most milliseconds before killing game window(in case we can't quit by clicking menu option for some reason)
    
    PlayerConfig:={}
    PlayerConfig["Default"]:={minLifeRatioToDrink: 0.45, minManaRatioToDrink: 0.55, minManaToDrink: 40, minLifeRatioToPopGranite: 0.65, minLifeRatioToQuit: 0.35} ;  disableAutoPotions:true, minLifeRatioToQuit:, minNShieldRatioToQuit: , HasZealotsOath: false, }
    
    PlayerConfig["Default"].FlaskConfig:=[]
    
    PlayerConfig["Default"].FlaskConfig[1]:={Hotkey:"{1 Down 1 UP}"} ; ,OverrideFlaskDuration:70, instantRecoveryOnLowLife:true, } ;specify override recovery time in deciseconds, e.g. 7 seconds = 70
    PlayerConfig["Default"].FlaskConfig[2]:={Hotkey:"{2 Down 2 UP}"}
    PlayerConfig["Default"].FlaskConfig[3]:={Hotkey:"{3 Down 3 UP}"}
    PlayerConfig["Default"].FlaskConfig[4]:={Hotkey:"{4 Down 4 UP}"}
    PlayerConfig["Default"].FlaskConfig[5]:={Hotkey:"{5 Down 5 UP}"}
    
    PlayerConfig["YourHardcorePlayerName"]:={minLifeRatioToDrink: 0.7, minManaRatioToDrink: 0.35, minManaToDrink: 70, minLifeRatioToQuit: 0.4}
    PlayerConfig["YourHardcorePlayerName"].FlaskConfig:=[]
    PlayerConfig["YourHardcorePlayerName"].FlaskConfig[1]:={Hotkey:"{1 Down 1 UP}"}
    PlayerConfig["YourHardcorePlayerName"].FlaskConfig[2]:={Hotkey:"{2 Down 2 UP}"}
    PlayerConfig["YourHardcorePlayerName"].FlaskConfig[3]:={Hotkey:"{3 Down 3 UP}"}
    PlayerConfig["YourHardcorePlayerName"].FlaskConfig[4]:={Hotkey:"{4 Down 4 UP}"}
    PlayerConfig["YourHardcorePlayerName"].FlaskConfig[5]:={Hotkey:"{5 Down 5 UP}"}
    
    autoPotionsState:=true
    
    WindowQueuedFlaskEffects:=[] ;keyed by "%hwnd%%CurrPid%", hpQueueEndtime, manaQueueEndtime
    
    baseMgrPtr:=0x71E008 ; 0.11.3b delete for script to try to auto-scan for it in newer versions, scan takes 4-5 seconds
    
    basePtrAoBArray:=[0x6A,0xFF,0x68,"?","?","?","?",0x50,0x64,"?","?","?","?","?","?",0xA1,"?","?","?","?",0x81,0xEC,"?","?","?","?",0x53,0x55,0x56,0x57,0x33,0xFF,0x3B,0xC7]
    basePtrAobOffset:=0x10
    
    WindowBasicsCache:=[] ; keyed by "%hwnd%%CurrPid%", entries are objects with properties processHandle, moduleBase, moduleSize, baseFramePtr
    
    #Include AutoHotkeyMemoryLib.ahk
    
    Loop
    {
       AutoPotions()
    }
    
    GetWindowBasics(hwnd, byref mB="", byref pH="", byref mS="")
    {
       
       global WindowBasicsCache
       global cliexe
       
       WinGet, CurrPid, PID, ahk_id %hwnd%
       
       k="%hwnd%%CurrPid%"
       
       mB:=WindowBasicsCache[k].mBase
       mS:=WindowBasicsCache[k].mSize
       
       if mB=
       {
          WindowBasicsCache[k]:=Object()
          GetModuleInfo(cliexe, CurrPid, mB, mS)
          if (mB="" || mS="")
          {
             MsgBox, Failed to obtain moduleBase or moduleSize for PID %CurrPid%, script will now terminate
             ExitApp
          }      
          WindowBasicsCache[k].mBase:=mB
          WindowBasicsCache[k].mSize:=mS
       }
    
       pH:=WindowBasicsCache[k].ProcessHandle
       if pH=
       {
          pH:=GetProcessHandle(CurrPid)
          if (pH="" || pH=-1)
          {
             MsgBox, Invalid process handle obtained for PID %CurrPid%, script will now terminate
             ExitApp
          }      
          WindowBasicsCache[k].ProcessHandle:=pH
       }
    }
    
    ScanBaseMgrPtr(mBase,pH,moduleSize)
    {
       global basePtrAoBArray
       global basePtrAobOffset
       global baseMgrPtr
       aobResult:=AobScan(pH,mBase,moduleSize,basePtrAoBArray)
    
       if aobResult
       {
          SetFormat, IntegerFast, hex
          baseMgrPtr:=ReadMemUInt(pH,mBase+aobResult+basePtrAobOffset)-mBase
          MsgBox, PoE Base ptr found with AoB Scan baseMgrPtr = %baseMgrPtr%, save this value to script for quick startup
          SetFormat, IntegerFast, dec
       }
       else
       {
          MsgBox, baseMgrPtr not found with AoBScan, script will now terminate
          ExitApp
       }   
    }
    
    GetFrameBase(hwnd)
    {
       global baseMgrPtr
       global WindowBasicsCache
    
       WinGet, CurrPid, PID, ahk_id %hwnd%
       k="%hwnd%%CurrPid%"
    
       fB:=WindowBasicsCache[k].fBase
    
       if fB=
       {
          GetWindowBasics(hwnd, mBase, pH, mSize)
    
          if baseMgrPtr=
          {
             ScanBaseMgrPtr(mBase, pH, mSize)
          }
    
          fB:=GetMultilevelPointer(pH,[mBase+baseMgrPtr,4,0x7C,0x94])
          WindowBasicsCache[k].fBase:=fB
       }
       return fB
    }
    
    GetUiBase(hwnd)
    {
       global baseMgrPtr
    
          GetWindowBasics(hwnd, mBase, pH, mSize)
          
          if baseMgrPtr=
          {
             ScanBaseMgrPtr(mBase, pH, mSize)
          }
          
    	FrameBase:=GetFrameBase(hwnd)
    	if (FrameBase="" || FrameBase=0)
    		return
    	uiBase:=GetMultilevelPointer(pH,[FrameBase+0x38,0x78,0xA4,0x50])
    	return uiBase
    }
    
    ReadClientResolution(hwnd, ByRef w, ByRef h)
    {
       GetWindowBasics(hwnd,mBase,pH)
       if (mBase!=0 && pH && pH!=-1)
       {
          FrameBase:=GetFrameBase(hwnd)
          w:=ReadMemUInt(pH,FrameBase+0x1340)
          h:=ReadMemUInt(pH,FrameBase+0x1344)
          return true
       }   
    }
    
    ReadPlayerStats(hwnd, byRef PlayerStats)
    {
       GetWindowBasics(hwnd, mBase, pH)
       fBase:=GetFrameBase(hwnd)
       PlayerBase:=GetMultilevelPointer(pH,[fBase+0xb4,0x59C])
       PlayerMain:=ReadMemUInt(pH,PlayerBase+4)
       PlayerStatsOffset:=ReadMemUInt(pH,PlayerMain+0xC)
    	PlayerStats.MaxHP:=ReadMemUInt(pH,PlayerStatsOffset+0x50)
    	PlayerStats.CurrHP:=ReadMemUInt(pH,PlayerStatsOffset+0x54)	
    	PlayerStats.ReservedHPFlat:=ReadMemUInt(pH,PlayerStatsOffset+0x5C)
    	PlayerStats.ReservedHPPercent:=ReadMemUInt(pH,PlayerStatsOffset+0x60)
    	PlayerStats.MaxMana:=ReadMemUInt(pH,PlayerStatsOffset+0x74)
    	PlayerStats.ReservedManaFlat:=ReadMemUInt(pH,PlayerStatsOffset+0x80)
    	PlayerStats.ReservedManaPercent:=ReadMemUInt(pH,PlayerStatsOffset+0x84)
    	PlayerStats.CurrMana:=ReadMemUInt(pH,PlayerStatsOffset+0x78)
    	PlayerStats.MaxNShield:=ReadMemUInt(pH,PlayerStatsOffset+0x98)
    	PlayerStats.CurrNShield:=ReadMemUInt(pH,PlayerStatsOffset+0x9C)
       
       if (ReadMemUInt(pH, ReadMemUInt(pH,PlayerMain+0x14)+0x24)<8) ;names shorter than 7 chars are stored immediately in component
          PlayerStats.Name:=ReadMemStr(pH, ReadMemUint(pH,PlayerMain+0x14)+0x10,100,"UTF-16") ;immediate name in component
       else
          PlayerStats.Name:=ReadMemStr(pH, GetMultilevelPointer(pH,[PlayerMain+0x14,0x10]),100,"UTF-16") ; otherwise pointer to name is stored
    }
    
    ReadFlasksData(hwnd, byRef FlasksData)
    {
       GetWindowBasics(hwnd, mBase, pH)
       
       UiBase:=GetUiBase(hwnd)
       
       if (!UiBase) ;not InGame
          return
       
       FlaskInvBase:=GetMultilevelPointer(pH,[UiBase+0x8d0,0x8e8,0x28])
    
       Loop, 5
       {
          currFlaskPtr:=ReadMemUInt(pH,FlaskInvBase+(A_Index-1)*4)
          if (currFlaskPtr!=0) ; there's a flask in said slot
          {
             FlasksData[A_Index]:={}
    
             FlaskChargesPtr:=GetMultilevelPointer(ph,[currFlaskPtr,4,0x1C,4,4,0xC])
             FlasksData[A_Index].ChargesCurrent:=ReadMemUInt(pH,FlaskChargesPtr+0xC)
             FlasksData[A_Index].ChargesPerUse:=ReadMemUInt(pH,ReadMemUInt(pH,FlaskChargesPtr+8)+0xC)
             
             if (FlasksData[A_Index].ChargesCurrent < FlasksData[A_Index].ChargesPerUse) ; not enough charges in this flask to use it, don't bother
                continue
    
             FlaskMetadataPtr:=GetMultilevelPointer(ph,[currFlaskPtr,0,8])
             FlaskMetadataStr:=ReadMemStr(ph,FlaskMetadataPtr,70,"UTF-16")
             FlaskTypeStr:=SubStr(FlaskMetadataStr,23)
             FlasksData[A_Index].type:=FlaskTypeStr
             
             FlaskLocalstatsPtr:=GetMultilevelPointer(ph,[currFlaskPtr,4,0x18,0x20,0xC])
             
             if InStr(FlaskTypeStr, "Life")
             {
                FlasksData[A_Index].HPRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+4)
                FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0xC)
             }
    
             if InStr(FlaskTypeStr, "Mana")
             {
                FlasksData[A_Index].ManaRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+4)
                FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0xC)
             }
             
             if InStr(FlaskTypeStr, "Hybrid")
             {
                FlasksData[A_Index].HPRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+4)
                FlasksData[A_Index].ManaRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+0xC)
                FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0x14)
             }
    
             if InStr(FlaskTypeStr, "FlaskUtility")
             {
                FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0x4)
             }
          }
       }
    }
    
    IsInGame(hwnd)
    {
    	if (hwnd=0 || hwnd="")
    		return false
    	GetWindowBasics(hwnd,mBase,pH)
    	if (mBase="" || mBase=0 || pH="" || pH=-1)
    		return false
    	fBase:=GetFrameBase(hwnd)
    	if (fBase="" || fBase=0)
    		return false
    	localConnection:=ReadMemUInt(pH,fBase+0xb8)
    	if (localConnection=0 || localConnection="")
    		return false
    	else
    		return true
    }
    
    SetGameStateMenu(hwnd)
    {
    	if (hwnd=0 || hwnd="")
    		return false
    	GetWindowBasics(hwnd,mBase,pH)
    	if (mBase="" || mBase=0 || pH="" || pH=-1)
    		return false
    	fBase:=GetFrameBase(hwnd)
    	if (fBase="" || fBase=0)
    		return false
    	localConnection:=ReadMemUInt(pH,fBase+0xb8)
    	if (localConnection!="" && localConnection!=0)
    	{
    		WriteMemUInt(pH,localConnection+0x1ff8,1)
    	}
    }
    
    ReadCursorScreenPosition(hwnd,ByRef cX, ByRef cY)
    {
       GetWindowBasics(hwnd,mBase,pH)
       if (mBase!=0 && pH && pH!=-1)
       {
          FrameBase:=GetFrameBase(hwnd)
          cX:=ReadMemSInt(pH,FrameBase+0x155c)
          cY:=ReadMemSInt(pH,FrameBase+0x1560)
          return true
       }   
    }
    
    ScreenToClient(hwnd, ByRef x, ByRef y)
    {
        VarSetCapacity(pt, 8)
        NumPut(x, pt, 0)
        NumPut(y, pt, 4)
        DllCall("ScreenToClient", "uint", hwnd, "uint", &pt)
        x := NumGet(pt, 0, "int")
        y := NumGet(pt, 4, "int")
       VarSetCapacity(pt, 0)
    }
    
    GetClientCoords(byRef mx, byRef my)
    {
       hwnd:=WinActive("A")   
       CoordMode, Mouse, Screen
       MouseGetPos, mx, my
       ScreenToClient(hwnd,mx,my) ;get mouse pos relative to window client rect
    }
    
    GetFractionalCoords(ByRef fX, ByRef fY)
    {
       hwnd:=WinActive("A")
       
       if (!IsInGame(hwnd))
          GetClientCoords(mx,my)
       else
          ReadCursorScreenPosition(hwnd,mx,my)
       
       ReadClientResolution(hwnd,w,h)
       
       fX:=mx/w
       fY:=my/h
    }
    
    GetClientCoordsFromFractional(hwnd, fX,fY, ByRef cX, ByRef cY)
    {
       ReadClientResolution(hwnd,w,h)
       cX:=fX*w
       cY:=fY*h      
    }
    
    QuitToLoginScreen(hwnd)
    {	
    	if (!IsInGame(hwnd))
    	{
    		return
    	}
    	SetGameStateMenu(hwnd)
    }
    
    GetMaxChargesFlaskOfType(ByRef FlasksData,TypeStr)
    {
       currMaxCharges:=0
       Loop, 5
          if (InStr(FlasksData[A_Index].type,TypeStr))
          {
             if FlasksData[A_Index].ChargesCurrent>currMaxCharges
             {
                currMaxI:=A_Index
                currMaxCharges:=FlasksData[A_Index].ChargesCurrent
             }
          }
       return currMaxI
    }
    
    AutoPotions()
    {
       global autoPotionsWatchdogPeriod
       global lagCompensation
       global PlayerConfig
       global WindowQueuedFlaskEffects
       global cliname
       global cliexe
       global trayNotifications
       global autoQuitMode
       
       if (autoPotionsState!=true)
          return
    
       WinGet, WinID, List, %cliname%
       
       Loop, %WinID%
       {
          
          WinGet, ProcModuleName, ProcessName,  % "ahk_id" WinID%A_Index%
          
          If(ProcModuleName!=cliexe) ; got a window with title "Path of Exile" but exe is not Client.exe, perhaps we have browser window open with PoE site, ignore it
             continue
          
          if (!IsInGame(WinID%A_Index%)) ;not ingame
             continue
    		 
    	if (WinID%A_Index%=WinActive("A"))
    	   ThisID:=WinActive("A")
          
          PlayerStats:={}
          ReadPlayerStats(WinID%A_Index%, PlayerStats)
          
          if (PlayerStats.MaxHP<1 || PlayerStats.CurrHP=0) ;dead, don't bother
             continue
    
          if (PlayerConfig.HasKey(PlayerStats.Name))
             CurrentConfig:=PlayerConfig[PlayerStats.Name]
          else
             CurrentConfig:=PlayerConfig["Default"]
             
          
          if PlayerStats.MaxNShield>0
          {
             currNShieldRatio:=PlayerStats.CurrNShield/PlayerStats.MaxNShield
          }
          
          if (PlayerStats.MaxHP>1)
          {
             currLifeRatio:=PlayerStats.CurrHP/(PlayerStats.MaxHP-PlayerStats.ReservedHPFlat-PlayerStats.MaxHP*PlayerStats.ReservedHPPercent/100)
          }
          
          if CurrentConfig.HasZealotsOath
          {
             currLifeRatio:=currNShieldRatio
          }
             
          if (PlayerStats.MaxMana>0)
          {
             currManaRatio:=PlayerStats.CurrMana/(PlayerStats.MaxMana-PlayerStats.ReservedManaFlat-PlayerStats.MaxMana*PlayerStats.ReservedManaPercent/100)
          }
          
          if (currLifeRatio<CurrentConfig.minLifeRatioToQuit || currNShieldRatio<CurrentConfig.minNShieldRatioToQuit)
          {
             if (autoQuitMode=0)
             {
                TrayTip, PoE autoPotions AutoQuit by closing window, specified min life reached, %A_Space% , 2
                WinKill, % "ahk_id" WinID%A_Index%
             }
             else if (autoQuitMode=1)
             {
                QuitToLoginScreen(WinID%A_Index%)
             }
    		 autoQuit:=1
             continue
          }
          
          if (CurrentConfig.disableAutoPotions)
             continue
          
          FlasksData:=[]
          ReadFlasksData(WinID%A_Index%,FlasksData)
          
          WinGet, CurrPID, PID,  % "ahk_id" WinID%A_Index%
          hwnd:=WinID%A_Index%
          k="%hwnd%%CurrPid%"
          if (!WindowQueuedFlaskEffects.HasKey(k))
          {
             WindowQueuedFlaskEffects[k]:={}
          }
          
          if (currLifeRatio<CurrentConfig.minLifeRatioToPopGranite || currNShieldRatio<CurrentConfig.minNShieldRatioToPopGranite)
             if ((!WindowQueuedFlaskEffects[k].HasKey("graniteQueueEndtime")) || (A_TickCount>=(WindowQueuedFlaskEffects[k].graniteQueueEndtime-lagCompensation)))
                {
                   flaskNum:=GetMaxChargesFlaskOfType(FlasksData,"FlaskUtility5") ; granite flask
                   if (flaskNum!="")
                   {
                      if CurrentConfig.FlaskConfig[flaskNum].HasKey("OverrideFlaskDuration")
                         EffectDuration:=CurrentConfig.FlaskConfig[flaskNum].OverrideFlaskDuration
                      else
                         EffectDuration:=FlasksData[flaskNum].EffectDuration
                         
                      WindowQueuedFlaskEffects[k].graniteQueueEndtime:=A_TickCount+EffectDuration*100
    
                      if (trayNotifications)
                      {
                         pname:=PlayerStats.Name
                         TrayTip, PoE autoPotions popping Granite flask %flaskNum% on %pname%, %A_Space% , 2
                      }
                      hKey:=CurrentConfig.FlaskConfig[flaskNum].Hotkey
                      ControlSend,,%hkey%, % "ahk_id" hwnd
                      break
                   }
                }
                   
          if (currLifeRatio=1)
             WindowQueuedFlaskEffects[k].hpQueueEndtime:=A_TickCount
          
          if (currManaRatio=1)
             WindowQueuedFlaskEffects[k].ManaQueueEndtime:=A_TickCount
          
          if (currLifeRatio<CurrentConfig.minLifeRatioToDrink || (PlayerStats.CurrHP<CurrentConfig.minLifeToDrink))
             if ((!WindowQueuedFlaskEffects[k].HasKey("hpQueueEndtime")) || (A_TickCount>=(WindowQueuedFlaskEffects[k].hpQueueEndtime-lagCompensation)))
             {
                      tflaskNum1:=GetMaxChargesFlaskOfType(FlasksData,"FlaskLife")
                      tflaskNum2:=GetMaxChargesFlaskOfType(FlasksData,"FlaskHybrid")
                      if ((tflaskNum1!=) && (tflaskNum2!=))
                         flaskNum:=(FlasksData[tflaskNum1].ChargesCurrent>FlasksData[tflaskNum2].ChargesCurrent) ? tflaskNum1 : tflaskNum2
                      else
                      {
                         if (tflaskNum1!="")
                            flaskNum:=tflaskNum1
                         if (tflaskNum2!="")
                            flaskNum:=tflaskNum2
                      }
                      if (flaskNum!="")
                      {
                         if CurrentConfig.FlaskConfig[flaskNum].HasKey("OverrideFlaskDuration")
                            EffectDuration:=CurrentConfig.FlaskConfig[flaskNum].OverrideFlaskDuration
                         else
                            EffectDuration:=FlasksData[flaskNum].EffectDuration
                         
                         if ((CurrentConfig.FlaskConfig[flaskNum].instantRecoveryOnLowLife) && ((PlayerStats.CurrHP/PlayerStats.MaxHP)<=0.35)) ; "Low life" can be caused by auras hp reservation from blood magic
                            EffectDuration:=lagCompensation
                            
                         WindowQueuedFlaskEffects[k].hpQueueEndtime:=A_TickCount+EffectDuration*100
                         if (FlasksData[flaskNum].HasKey("ManaRegAmount")) ; hybrid flask
                            WindowQueuedFlaskEffects[k].ManaQueueEndtime:=A_TickCount+EffectDuration*100
    
                         if (trayNotifications)
                         {
                            pname:=PlayerStats.Name
                            TrayTip, PoE autoPotions sipping HP flask %flaskNum% on %pname%, %A_Space% , 2
                         }
                         hKey:=CurrentConfig.FlaskConfig[flaskNum].Hotkey
                         ControlSend,,%hkey%, % "ahk_id" hwnd
                         break
                      }
                }
    
          if (PlayerStats.MaxMana>0 && (currManaRatio<CurrentConfig.minManaRatioToDrink || PlayerStats.CurrMana<CurrentConfig.minManaToDrink))      
             if ((!WindowQueuedFlaskEffects[k].HasKey("ManaQueueEndtime")) || (A_TickCount>=(WindowQueuedFlaskEffects[k].ManaQueueEndtime-lagCompensation)))
             {
                   tflaskNum1:=GetMaxChargesFlaskOfType(FlasksData,"FlaskMana")
                   tflaskNum2:=GetMaxChargesFlaskOfType(FlasksData,"FlaskHybrid")
                   
                   if ((tflaskNum1!=) && (tflaskNum2!=))
                      flaskNum:=(FlasksData[tflaskNum1].ChargesCurrent>FlasksData[tflaskNum2].ChargesCurrent) ? tflaskNum1 : tflaskNum2
                   else
                   {
                      if (tflaskNum1!="")
                         flaskNum:=tflaskNum1
                      if (tflaskNum2!="")
                         flaskNum:=tflaskNum2
                   }
    
                   if (flaskNum!="")
                   {
                      if CurrentConfig.FlaskConfig[flaskNum].HasKey("OverrideFlaskDuration")
                         {
                            EffectDuration:=CurrentConfig.FlaskConfig[flaskNum].OverrideFlaskDuration
                         }
                      else
                         EffectDuration:=FlasksData[flaskNum].EffectDuration
    
                      if ((CurrentConfig.FlaskConfig[flaskNum].instantRecoveryOnLowLife) && ((PlayerStats.CurrHP/PlayerStats.MaxHP)<=0.35))
                         EffectDuration:=lagCompensation
                      
                      WindowQueuedFlaskEffects[k].ManaQueueEndtime:=A_TickCount+EffectDuration*100
                      if (FlasksData[flaskNum].HasKey("HPRegAmount")) ; hybrid flask
                         WindowQueuedFlaskEffects[k].hpQueueEndtime:=A_TickCount+EffectDuration*100
                      
                      hKey:=CurrentConfig.FlaskConfig[flaskNum].Hotkey
                      if (trayNotifications)
                      {
                         pname:=PlayerStats.Name
                         TrayTip, PoE autoPotions sipping mana flask %flaskNum% on %pname%, %A_Space% , 2
                      }
                      ControlSend,,%hkey%, % "ahk_id" hwnd
                      break
                   }
             }               
       }
       
        if ((autoQuit=1) && (ThisID!="") && (ThisID!=WinActive("A")))
          WinActivate, % "ahk_id" ThisID
    
       Sleep, %autoPotionsWatchdogPeriod%   
    }
    
    F1::
       global autoPotionsState
       global trayNotifications
       autoPotionsState:=not autoPotionsState
       if (trayNotifications)
       {
          if (autoPotionsState=true)
             TrayTip, PoE autoPotions is on, %A_Space% , 2
          else
             TrayTip, PoE autoPotions is off, %A_Space%  , 2
       }
    return
    
    F2::
       GetClientCoords(mx,my)
       GetFractionalCoords(fx,fy)
       msgbox, mx=%mx% my=%my% fx=%fx% fy=%fy%
    return
    
    F4::
       QuitToLoginScreen(WinActive("A"))
    return
    AutoHotkeyMemoryLib.ahk
    Code:
    if (A_PtrSize != 4)
    {
    	MsgBox, You are not running 32-bit version of Autohotkey L, reinstall correct version. Script will now terminate.
    	ExitApp	
    }
    GetModuleInfo(ModuleName, PID, byRef mBase="", byRef mSize="")
    {
        TH32CS_SNAPMODULE := 0x00000008
        INVALID_HANDLE_VALUE = -1
        VarSetCapacity(me32, 548, 0)
        NumPut(548, me32)
    	
        snapMod := DllCall("CreateToolhelp32Snapshot", "Uint", TH32CS_SNAPMODULE, "Uint", PID)
    	
        If (snapMod = INVALID_HANDLE_VALUE) {
            Return 0
        }
    	
        If (DllCall("Module32First", "Uint", snapMod, "Uint", &me32)){
    		
    		If StrGet(&me32 + 32, "cp0")=ModuleName
    		{
                    mBase:=NumGet(&me32 + 20)
    				mSize:=NumGet(&me32 + 24)
                    DllCall("CloseHandle", "UInt", snapMod)
    				Return
    
    		}
    				
            while(DllCall("Module32Next", "Uint", snapMod, "UInt", &me32)) 
    		{
                If StrGet(&me32 + 32, "cp0")=ModuleName
    			{
                    mBase:=NumGet(&me32 + 20)
    				mSize:=NumGet(&me32 + 24)
                    DllCall("CloseHandle", "UInt", snapMod)
                    Return
                }
            }
        }
    	
        DllCall("CloseHandle", "Uint", snapMod)
    }
    
    GetProcessHandle(pid)
    {
    	return DllCall("OpenProcess", "UInt", 0x8|0x10|0x20, "UInt", 0, "UInt", pid, "UInt")
    }
    
    ReadMemFloat(ProcessHandle, MADDRESS) 
    {
    	if DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Float*",MVALUE,"UInt",4,"UInt*",0)!=0
    	{
    		return MVALUE
    	}	
    }
    
    ReadMemUInt(ProcessHandle, MADDRESS) 
    { 
    	if DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"UInt*",MVALUE,"UInt",4,"UInt*",0)!=0
    	{
    		return MVALUE
    	}	
    }
    
    ReadMemSInt(ProcessHandle, MADDRESS) 
    { 
    	if DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Int*",MVALUE,"UInt",4,"UInt*",0)!=0
    	{
    		return MVALUE
    	}	
    }
    
    WriteMemUInt(ProcessHandle, MADDRESS, val) 
    { 
    	DllCall("WriteProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"UInt*",val,"UInt",4,"UInt*",0)!=0
    }
    
    WriteMemSInt(ProcessHandle, MADDRESS, val) 
    { 
    	DllCall("WriteProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Int*",val,"UInt",4,"UInt*",0)!=0
    }
    
    WriteMemFloat(ProcessHandle, MADDRESS, val) 
    { 
    	DllCall("WriteProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Float*",val,"UInt",4,"UInt*",0)!=0
    }
    
    ReadMemStr(ProcessHandle, MADDRESS, maxlen=255, cp="cp0") 
    { 
    	
    	VarSetCapacity(MVALUE,maxlen)
    	
    	if DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"PTR",&MVALUE,"UInt",maxlen,"UInt*",bytesread)!=0
    	{
    		Str:=StrGet(&MVALUE,cp)
    		VarSetCapacity(MVALUE,0)
    		return Str
    	}
    	
    	VarSetCapacity(MVALUE,0)	
    }
    
    GetMultilevelPointer(ProcessHandle, PARRAY)
    {		
    	if PARRAY._MaxIndex()<2
    		return
    	
    	if (DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",PARRAY[1],"UInt*",currOffset,"UInt",4,"UInt*",0)!=0)	
    	{
    
    		i:=2
    		while (i<=PARRAY._MaxIndex() && DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",currOffset+PARRAY[i],"UInt*",currOffset,"UInt",4,"UInt*",0)!=0)
    		{
    			i:=i+1
    		}
    		
    		if (i>PARRAY._MaxIndex())
    		{
    			return currOffset
    		}
    	}
    }
    
    AobScan(ProcessHandle,mBase,mSize, ByRef patternArray)
    {
    	if (patternArray._MaxIndex()>mSize)
    	{
    		MsgBox, aobscan fail : pattern array is larger than module size
    		return
    	}
    
    	VarSetCapacity(ClientCodeSegment,mSize)
    	
    	if (DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",mBase,"PTR",&ClientCodeSegment,"UInt",mSize,"UInt*",bytesread)!=0)
    	{
    		
    		pLen:=patternArray._MaxIndex()		
    		if (bytesread<>mSize)
    		{
    			VarSetCapacity(ClientCodeSegment,0)
    			MsgBox, aobscan fail : mSize=%mSize%  bytesread=%bytesread%
    			return
    		}		
    		i:=0
    		
    		while (i<=mSize-pLen-1)
    		{
    			j:=1
    			while (j<=pLen)
    			{
    				if (patternArray[j]="?" || NumGet(ClientCodeSegment, i+j-1, "UChar")=patternArray[j])
    				{
    					j:=j+1
    				}
    				else
    				{
    					break
    				}
    			}
    			
    			if (j>pLen)
    			{
    				VarSetCapacity(ClientCodeSegment,0)
    				return i
    			}
    			i:=i+1			
    		}	
    	}
    	MsgBox, aobscan fail : pattern not found
    	VarSetCapacity(ClientCodeSegment,0)
    }
    Last edited by Wrongusername; 09-10-2013 at 05:18 PM.

    [Release][Autohotkey script] PoE Autoflasks &amp; autoquit.
  2. #2
    AK2337's Avatar Member
    Reputation
    8
    Join Date
    Feb 2013
    Posts
    72
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Looks promising. Will try this out after current race ends.

  3. #3
    histachii's Avatar Member
    Reputation
    2
    Join Date
    Mar 2012
    Posts
    146
    Thanks G/R
    7/0
    Trade Feedback
    7 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cant wait to try this

  4. #4
    Manciuszz's Avatar Private
    Reputation
    1
    Join Date
    Feb 2013
    Posts
    4
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Haha.. dat private message... Thanks! Very nice, far more better than expected!
    Last edited by Manciuszz; 02-23-2013 at 06:52 PM.

  5. #5
    mrmordy's Avatar Member
    Reputation
    1
    Join Date
    Apr 2011
    Posts
    8
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Trying it in softcore, can't get it to work. Which fields do I have to fill?
    Last edited by mrmordy; 02-23-2013 at 09:09 PM.

  6. #6
    OHNaGe's Avatar Member
    Reputation
    13
    Join Date
    Jun 2012
    Posts
    34
    Thanks G/R
    2/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I cant get this to run to save my life either. Im running in windowed mode but dont think that should matter, most people Multi-Boxing will be doing the same thing. Cant get it to auto use Life or Mana and cant get the chicken feature to work. Maybe a quickie step by step setup?

  7. #7
    OHNaGe's Avatar Member
    Reputation
    13
    Join Date
    Jun 2012
    Posts
    34
    Thanks G/R
    2/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So I have been messing around with the script and I am going to assume the issue has something to do with colors dealing with line 31 "baseMgrPtr". The note says ";0.10.1e, delete for script to try to auto-scan for it in newer versions, scan takes 4-5 seconds" so I delete this value, or the entire line, tried many ways, and I get the "MsgBox, aobscan fail : pattern array is larger than module size" from the AutoHotkeyMemoryLib.ahk so I am not sure whats going on. If I knew what that Hex color was supposed to be I could just screen shot PoE and eye-drop it in Photoshop to find the value but right now its some grayish blue. Lol. Im lost. Any help or direction on how to get this script running smoothly would be very helpful. When I start it with its defaults it simply sits there and does nothing. So some sort of config needs to be done on my part and ive been messing with it and cant figure out what. Lol

  8. #8
    Wrongusername's Avatar Sergeant
    Reputation
    100
    Join Date
    Feb 2011
    Posts
    65
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If I comment out the baseptr to let it scan itself, it gives the error "aobscan fail : pattern array is larger than module size".
    It's likely unable to read memory at all in that case. At least on Win7 x64 it doesn't require admin rights to run/do it things, but you may try to change memlib function to this

    GetProcessHandle(pid)
    {
    return DllCall("OpenProcess", "UInt", 0x10, "UInt", 0, "UInt", pid, "UInt")
    }

    for it to request less(but sufficient for this script_ process access rights or try running it as admin.

    For those for whom it doesn't work, Autohotkey_L installed should be exactly Unicode x32 version(you get to choose and on Win x64 it defaults to x64 version, i think that may mean calling 64-bit dllcalls which would screw this script up), make sure _both_ PoE_AutoFlasks.ahk and AutoHotkeyMemoryLib.ahk are in same folder


    Also an error crawled in there during simplifying script which cause it to spam potions, fixed.

  9. #9
    Manciuszz's Avatar Private
    Reputation
    1
    Join Date
    Feb 2013
    Posts
    4
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by OHNaGe View Post
    So I have been messing around with the script and I am going to assume the issue has something to do with colors dealing with line 31 "baseMgrPtr". The note says ";0.10.1e, delete for script to try to auto-scan for it in newer versions, scan takes 4-5 seconds" so I delete this value, or the entire line, tried many ways, and I get the "MsgBox, aobscan fail : pattern array is larger than module size" from the AutoHotkeyMemoryLib.ahk so I am not sure whats going on. If I knew what that Hex color was supposed to be I could just screen shot PoE and eye-drop it in Photoshop to find the value but right now its some grayish blue. Lol. Im lost. Any help or direction on how to get this script running smoothly would be very helpful. When I start it with its defaults it simply sits there and does nothing. So some sort of config needs to be done on my part and ive been messing with it and cant figure out what. Lol
    Works fine. You have to install Autohotkey unicode x32 version, may not work for x64 ( This is how I made it to work for me )
    Last edited by Manciuszz; 02-24-2013 at 04:34 AM.

  10. #10
    OHNaGe's Avatar Member
    Reputation
    13
    Join Date
    Jun 2012
    Posts
    34
    Thanks G/R
    2/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry if this is dumb, but what exactly am I replacing with that? The baseptr thats giving the problems? or something in the MemoryLib file?

  11. #11
    OHNaGe's Avatar Member
    Reputation
    13
    Join Date
    Jun 2012
    Posts
    34
    Thanks G/R
    2/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Manciuszz View Post
    Works fine. You have to install Autohotkey unicode x32 version, may not work for x64.
    The link at the beginning of this forum post gives a direct download and I installed the x32. So no, for me, and a lot of other people posting here and on blizz hackers, its doesn't "work fine". Lol. Just trying to figure everything out.

  12. #12
    OHNaGe's Avatar Member
    Reputation
    13
    Join Date
    Jun 2012
    Posts
    34
    Thanks G/R
    2/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I figured out the where to make that chance, and it seems to have worked. Does the chicken method pretty much alt+f4? or does it actually hit esc+exit path of exile?

  13. #13
    Manciuszz's Avatar Private
    Reputation
    1
    Join Date
    Feb 2013
    Posts
    4
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by OHNaGe View Post
    I figured out the where to make that chance, and it seems to have worked. Does the chicken method pretty much alt+f4? or does it actually hit esc+exit path of exile?
    It kills the process.

    if (currLifeRatio<CurrentConfig.minLifeRatioToQuit || currNShieldRatio<CurrentConfig.minNShieldRatioToQuit)
    {
    blankstr:=" "
    TrayTip, PoE autoPotions AutoQuit, specified min life reached, %blankstr% , 2
    WinKill, % "ahk_id" WinID%A_Index% ««« «««
    }
    Last edited by Manciuszz; 02-24-2013 at 04:38 AM.

  14. #14
    OHNaGe's Avatar Member
    Reputation
    13
    Join Date
    Jun 2012
    Posts
    34
    Thanks G/R
    2/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok. I noticed you used the "Kill Window" which simulates a disconnect, so it does leave you in game for a couple seconds afterwords and I lost me level 2 HC chr I was testing the script out with because I was in a big pack. Lol. So, I swapped

    WinKill, % "ahk_id" WinID%A_Index%
    With

    SendInput, {Esc}
    MouseClick, Left, 521, 339,,Fast
    This works with my windowed mode to simply throw your chr into the login screen and is an immediate disconnect. Using the window spy anyone can change the x,y to whatever they have there stuff set to. Just thought I would share.

    Thanks for the amazing script though, good work, and thanks for the help.

    EDIT: Im sure there is a "Hover/Hit This Button" that could be done for peoples "Exit To Login Screen" I am just not as fluent in AutoHotKey and some and do not know exactly how to do it to make it more of an "Out of box" solution for everyone without having to go threw and use the window spy for the x,y or I would have to help out. Sry.
    Last edited by OHNaGe; 02-24-2013 at 04:43 AM.

  15. #15
    romantic179's Avatar Member
    Reputation
    1
    Join Date
    Feb 2013
    Posts
    2
    Thanks G/R
    1/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok, i get the flask thing work for me without any problems. But for what is this thing "AutoHotkeyMemoryLib.ahk" ?

Page 1 of 32 12345 ... LastLast

Similar Threads

  1. [Release] Custom scripts
    By ion564 in forum World of Warcraft Emulator Servers
    Replies: 20
    Last Post: 05-12-2008, 07:02 PM
  2. [Release] WarsongGulch Script
    By Pragma in forum World of Warcraft Emulator Servers
    Replies: 33
    Last Post: 03-23-2008, 08:07 PM
  3. [Release] |Custom Scripted Instance| Shadow Lair
    By wurstbr0t in forum World of Warcraft Emulator Servers
    Replies: 18
    Last Post: 03-05-2008, 12:03 PM
  4. [RELEASE]Ascent/script compiles 3710 (latest 2/6/08)
    By vivec45 in forum WoW EMU Guides & Tutorials
    Replies: 0
    Last Post: 02-06-2008, 07:04 AM
  5. [RELEASE] FunServer Script's ( + Level Cap 80-255 )
    By ~SaiLyn~ in forum World of Warcraft Emulator Servers
    Replies: 36
    Last Post: 01-10-2008, 02:44 PM
All times are GMT -5. The time now is 09:19 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search