AutoQuit and Potions menu

Shout-Out

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 15 of 18
  1. #1
    rxemi115566's Avatar Member
    Reputation
    9
    Join Date
    Oct 2017
    Posts
    15
    Thanks G/R
    0/8
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    AutoQuit and Potions

    This been my first attempt to look for the offsets and pointers, just needed something to autoquit and use potions. Below is python script to launch it - Anyone knowledgable, am I on right path ?


    24/04/2025 update - 1.2.1.1

    Code:
    import sys
    import time
    import ctypes
    import keyboard
    import pymem
    import pymem.process
    import pymem.exception
    
    class LastEpochMonitor:
        def __init__(self, exe="Last Epoch.exe", mod="GameAssembly.dll",
                     key_delay=1.0, low_hp_pct=60, potion_pct=90, busy_val=500,
                     auto_quit=False):
            self.exe = exe
            self.mod = mod
            self.key_delay = key_delay
            self.low_hp_pct = low_hp_pct
            self.potion_pct = potion_pct
            self.busy_val = busy_val
            self.auto_quit = auto_quit
            self.ptr_defs = {
                "cur_hp": {"static": 0x4040968, "chain": (0x88, 0x128, 0x90, 0x80, 0xB8, 0x10, 0xB0), "type": "float"},
                "es":     {"static": 0x4105E38, "chain": (0xB8, 0x0, 0x18, 0x2D4), "type": "float"},
                "max_hp": {"static": 0x40F7038, "chain": (0xB8, 0x0, 0xE0, 0x68), "type": "int"}
            }
            self.pm = None
            self.base = None
            self.attach_process()
    
        def attach_process(self):
            try:
                self.pm = pymem.Pymem(self.exe)
                print(f"Successfully attached to process: {self.exe}")
            except pymem.exception.ProcessNotFound:
                print(f"Error: Process '{self.exe}' not running. Please start the game.")
                sys.exit(1)
            except Exception as e:
                print(f"An unexpected error occurred while attaching to process: {e}")
                sys.exit(1)
    
            try:
                self.base = pymem.process.module_from_name(self.pm.process_handle, self.mod).lpBaseOfDll
                if not self.base:
                     raise pymem.exception.ProcessError(f"Got null base address for module {self.mod}")
                print(f"Found module '{self.mod}' at base address: {hex(self.base)}")
            except (AttributeError, pymem.exception.ProcessError):
                print(f"Error: Module '{self.mod}' not found in '{self.exe}'.")
                print("Ensure the game is fully loaded (e.g., at the character selection screen or in-game).")
                self.pm.close_process()
                sys.exit(1)
            except Exception as e:
                print(f"An unexpected error occurred while finding module: {e}")
                if self.pm:
                    self.pm.close_process()
                sys.exit(1)
    
        def _resolve_ptr(self, base_addr, chain):
            try:
                addr = self.pm.read_longlong(base_addr)
                if not addr:
                    raise pymem.exception.MemoryReadError(f"Base address read returned null at {hex(base_addr)}")
            except pymem.exception.MemoryReadError as e:
                raise pymem.exception.MemoryReadError(f"Failed initial read at {hex(base_addr)}: {e}")
    
            for i, off in enumerate(chain[:-1]):
                try:
                    next_addr = self.pm.read_longlong(addr + off)
                    if not next_addr:
                        raise pymem.exception.MemoryReadError(f"Pointer became null at chain index {i}, offset {hex(off)} (current address: {hex(addr)})")
                    addr = next_addr
                except pymem.exception.MemoryReadError as e:
                    raise pymem.exception.MemoryReadError(f"Failed reading offset {hex(off)} at chain index {i} (current address: {hex(addr)}): {e}")
    
            final_address = addr + chain[-1]
            return final_address
    
        def read_value(self, key):
            p = self.ptr_defs[key]
            try:
                address = self._resolve_ptr(self.base + p["static"], p["chain"])
                if p["type"] == "float":
                    value = self.pm.read_float(address)
                elif p["type"] == "int":
                    value = self.pm.read_int(address)
                else:
                     raise ValueError(f"Unknown data type '{p['type']}' for key '{key}'")
                return value
            except pymem.exception.MemoryReadError as e:
                raise pymem.exception.MemoryReadError(f"Failed to read value for '{key}': {e}")
            except ValueError as e:
                raise ValueError(e)
    
    
        def safe_read(self, key):
            try:
                return self.read_value(key)
            except (pymem.exception.MemoryReadError, pymem.exception.WinAPIError, TypeError, ValueError) as e:
                print(f"Read error for '{key}': {e}. Attempting to re-attach...")
                self.attach_process()
                time.sleep(1.5)
                try:
                     return self.read_value(key)
                except (pymem.exception.MemoryReadError, pymem.exception.WinAPIError, TypeError, ValueError) as e2:
                     print(f"Read error persisted for '{key}' after re-attach: {e2}")
                     return None
                except Exception as e_fatal:
                     print(f"Unexpected critical error reading '{key}' after re-attach: {e_fatal}")
                     self.quit_game(f"Fatal read error: {e_fatal}")
                     return None
            except Exception as e_fatal:
                 print(f"Unexpected critical error reading '{key}': {e_fatal}")
                 self.quit_game(f"Fatal read error: {e_fatal}")
                 return None
    
    
        def quit_game(self, reason):
            print(f"Quit triggered: {reason}")
            try:
                print("Attempting Alt+F4...")
                keyboard.press_and_release('alt+f4')
                time.sleep(0.3)
            except Exception as e:
                print(f"Warning: Failed to send Alt+F4 ({e}). Proceeding with termination.")
    
            try:
                if self.pm and self.pm.process_handle:
                    print(f"Terminating process ID: {self.pm.process_id}")
                    handle = int(self.pm.process_handle)
                    if handle:
                         success = ctypes.windll.kernel32.TerminateProcess(handle, 0)
                         if success:
                             print("Process terminated successfully.")
                         else:
                             error_code = ctypes.windll.kernel32.GetLastError()
                             print(f"Failed to terminate process. Error code: {error_code}")
                    else:
                         print("Process handle is invalid, cannot terminate.")
                    self.pm.close_process()
                else:
                    print("No valid process handle to terminate.")
            except Exception as e:
                print(f"Error during process termination: {e}")
    
            print("Exiting script.")
            sys.exit(0)
    
        def main(self):
            last_pot_time = 0.0
            error_count = 0
            max_errors = 15
    
            print("Starting health monitor loop...")
            while True:
                try:
                    hp = self.safe_read("cur_hp")
                    es = self.safe_read("es")
                    max_hp = self.safe_read("max_hp")
    
                    loading_state = False
                    loading_reason = ""
    
                    if hp is None or es is None or max_hp is None:
                        print("Failed to read one or more values after retry.")
                        error_count += 1
                        loading_state = True
                        loading_reason = "Read Error"
                    elif hp <= 0:
                        loading_state = True
                        loading_reason = f"HP <= 0 ({hp})"
                    elif hp == self.busy_val:
                        loading_state = True
                        loading_reason = f"HP == busy_val ({hp})"
                    elif max_hp <= 0:
                         loading_state = True
                         loading_reason = f"Max HP <= 0 ({max_hp})"
                    elif max_hp == self.busy_val:
                         loading_state = True
                         loading_reason = f"Max HP == busy_val ({max_hp})"
    
                    if loading_state:
                        if loading_reason != "Read Error":
                             print(f"Loading state detected ({loading_reason}). Waiting...")
                        error_count = 0
                        time.sleep(0.5)
                        continue
                    else:
                        error_count = 0
                        current_effective_hp = hp + es
                        pct = (current_effective_hp / max_hp) * 100
    
                        print(f"HP: {hp:.1f} ES: {es:.1f} | Total: {current_effective_hp:.1f}/{max_hp} ({pct:.0f}%)")
    
                        if pct < self.low_hp_pct:
                            if self.auto_quit:
                                self.quit_game(f"Health low: {pct:.0f}% < {self.low_hp_pct}%")
                            else:
                                print(f"LOW HEALTH WARNING: {pct:.0f}% < {self.low_hp_pct}% (Auto-quit disabled)")
    
                        current_time = time.time()
                        if pct < self.potion_pct and (current_time - last_pot_time) >= self.key_delay:
                            print(f"Using potion at {pct:.0f}% health.")
                            try:
                                keyboard.press_and_release('1')
                                last_pot_time = current_time
                            except Exception as key_error:
                                 print(f"Warning: Failed to press potion key '1': {key_error}")
    
                    if error_count > max_errors:
                        print(f"Exceeded maximum consecutive read errors ({max_errors}). Exiting.")
                        self.quit_game("Too many read errors")
    
                    time.sleep(0.05 if error_count == 0 and not loading_state else 0.5)
    
                except KeyboardInterrupt:
                    print("\nKeyboard interrupt received. Exiting.")
                    if self.pm:
                        self.pm.close_process()
                    sys.exit(0)
                except Exception as loop_error:
                     print(f"Unexpected error in main loop: {loop_error}")
                     error_count +=1
                     if error_count > max_errors:
                          self.quit_game(f"Fatal loop error: {loop_error}")
                     time.sleep(1)
    
    
    if __name__ == "__main__":
        monitor = LastEpochMonitor(auto_quit=True)
        monitor.main()
    KEY_DELAY - Delay on pressing speed (key 1)
    LOW_HP_PCT - When to ALT+F4 (in our example: 60%)
    POTION_PCT - When to use potion (in our example: 90%)
    BUSY_VAL - is just for loading screens to recheck, i noticed that when user is changing location or logging in, HP value goes to 500, so we ignore it.


    Pointers:
    cur_hp - Current Health
    es - Energy Shield
    max_hp - Max Health


    simple2.png

    Current_Hp Eventually becomes (Cur_hp + es) - i did this because healing potion can be used to heal energy shield - I play this game first time and was baffled about it.
    Attached Thumbnails Attached Thumbnails AutoQuit and Potions-simple-png  
    Last edited by rxemi115566; 04-24-2025 at 03:01 PM. Reason: unstable ES pointer

    AutoQuit and Potions
  2. Thanks hackerlol, SquareCubiC (2 members gave Thanks to rxemi115566 for this useful post)
  3. #2
    rxemi115566's Avatar Member
    Reputation
    9
    Join Date
    Oct 2017
    Posts
    15
    Thanks G/R
    0/8
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    23/04/2025 update - 1.2.0.4

  4. #3
    MetkataTipcheto's Avatar Member
    Reputation
    6
    Join Date
    Sep 2014
    Posts
    59
    Thanks G/R
    0/5
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey bro I am getting error after the last update:
    Read error persisted for 'cur_hp' after re-attach: MemoryReadError.__init__() missing 1 required positional argument: 'length'
    Read error for 'es': MemoryReadError.__init__() missing 1 required positional argument: 'length'. Attempting to re-attach...
    Successfully attached to process: Last Epoch.exe
    Found module 'GameAssembly.dll' at base address: 0x7ffe35e90000
    Read error persisted for 'es' after re-attach: MemoryReadError.__init__() missing 1 required positional argument: 'length'
    Read error for 'max_hp': MemoryReadError.__init__() missing 1 required positional argument: 'length'. Attempting to re-attach...
    Successfully attached to process: Last Epoch.exe
    Found module 'GameAssembly.dll' at base address: 0x7ffe35e90000
    Read error persisted for 'max_hp' after re-attach: MemoryReadError.__init__() missing 1 required positional argument: 'length'
    Failed to read one or more values after retry.
    Read error for 'cur_hp': MemoryReadError.__init__() missing 1 required positional argument: 'length'. Attempting to re-attach...
    Successfully attached to process: Last Epoch.exe
    Found module 'GameAssembly.dll' at base address: 0x7ffe35e90000
    Read error persisted for 'cur_hp' after re-attach: MemoryReadError.__init__() missing 1 required positional argument: 'length'
    Read error for 'es': MemoryReadError.__init__() missing 1 required positional argument: 'length'. Attempting to re-attach...
    Successfully attached to process: Last Epoch.exe
    Found module 'GameAssembly.dll' at base address: 0x7ffe35e90000
    Read error persisted for 'es' after re-attach: MemoryReadError.__init__() missing 1 required positional argument: 'length'
    Read error for 'max_hp': MemoryReadError.__init__() missing 1 required positional argument: 'length'. Attempting to re-attach...
    Successfully attached to process: Last Epoch.exe
    Found module 'GameAssembly.dll' at base address: 0x7ffe35e90000
    Last version was working just fine. Am I doing something wrong?

  5. #4
    rxemi115566's Avatar Member
    Reputation
    9
    Join Date
    Oct 2017
    Posts
    15
    Thanks G/R
    0/8
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    They pushed another update, let me check - 10 min i should be able to find
    Last edited by rxemi115566; 04-23-2025 at 07:46 PM. Reason: Update

  6. Thanks SquareCubiC (1 members gave Thanks to rxemi115566 for this useful post)
  7. #5
    rxemi115566's Avatar Member
    Reputation
    9
    Join Date
    Oct 2017
    Posts
    15
    Thanks G/R
    0/8
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    23/04/2025 update - 1.2.1

  8. Thanks SquareCubiC (1 members gave Thanks to rxemi115566 for this useful post)
  9. #6
    MetkataTipcheto's Avatar Member
    Reputation
    6
    Join Date
    Sep 2014
    Posts
    59
    Thanks G/R
    0/5
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the quick update bro!

  10. #7
    rxemi115566's Avatar Member
    Reputation
    9
    Join Date
    Oct 2017
    Posts
    15
    Thanks G/R
    0/8
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Check Code again, had ES wrong, i gonna go sleep.



    Code:
    self.ptr_defs = {
                "cur_hp": {"static": 0x4111D68, "chain": (0xB8, 0x0, 0xB0), "type": "float"},
                "es":     {"static": 0x40C8120, "chain": (0xD0, 0xB8, 0x0, 0x70, 0x2D4), "type": "float"},
                "max_hp": {"static": 0x4093F00, "chain": (0xB8, 0x10, 0xE0, 0x68), "type": "int"}
            }
    These look to be stable
    Last edited by rxemi115566; 04-23-2025 at 08:54 PM.

  11. Thanks SquareCubiC (1 members gave Thanks to rxemi115566 for this useful post)
  12. #8
    MetkataTipcheto's Avatar Member
    Reputation
    6
    Join Date
    Sep 2014
    Posts
    59
    Thanks G/R
    0/5
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Successfully attached to process: Last Epoch.exe
    Found module 'GameAssembly.dll' at base address: 0x7ffe35e90000
    Starting health monitor loop...
    Read error for 'cur_hp': MemoryReadError.__init__() missing 1 required positional argument: 'length'. Attempting to re-attach...
    Successfully attached to process: Last Epoch.exe
    Found module 'GameAssembly.dll' at base address: 0x7ffe35e90000
    Read error persisted for 'cur_hp' after re-attach: MemoryReadError.__init__() missing 1 required positional argument: 'length'
    Read error for 'es': MemoryReadError.__init__() missing 1 required positional argument: 'length'. Attempting to re-attach...
    Successfully attached to process: Last Epoch.exe
    Found module 'GameAssembly.dll' at base address: 0x7ffe35e90000
    Read error persisted for 'es' after re-attach: MemoryReadError.__init__() missing 1 required positional argument: 'length'
    Read error for 'max_hp': MemoryReadError.__init__() missing 1 required positional argument: 'length'. Attempting to re-attach...
    Successfully attached to process: Last Epoch.exe
    Found module 'GameAssembly.dll' at base address: 0x7ffe35e90000
    Sadly still doesn't seem to work. Anyway whenever you have time buddy

  13. #9
    miracle1's Avatar Active Member
    Reputation
    37
    Join Date
    Jun 2014
    Posts
    269
    Thanks G/R
    114/30
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi, thanks for the script. Took me some time to fix the script but it works, however i can't make pointers work, static adresses works without any problem.

    Here is edited code for static addresses, without auto quit and with hp threshold

    Code:
    import sys
    import time
    import ctypes
    import keyboard
    import pymem
    import pymem.process
    import pymem.exception
    
    class LastEpochMonitor:
        def __init__(self, exe="Last Epoch.exe", mod="GameAssembly.dll",
                     key_delay=2, low_hp_threshold=1800, potion_key='1'):
            self.exe = exe
            self.mod = mod
            self.key_delay = key_delay
            self.low_hp_threshold = low_hp_threshold  
            self.potion_key = potion_key 
            self.ptr_defs = {
                "cur_hp": {"static": 0x2348414A724, "type": "float"},
                "max_hp": {"static": 0x235408C9368, "type": "int"}
            }
            self.pm = None
            self.base = None
            self.attach_process()
    
        def attach_process(self):
            try:
                self.pm = pymem.Pymem(self.exe)
                print(f"Successfully attached to process: {self.exe}")
            except pymem.exception.ProcessNotFound:
                print(f"Error: Process '{self.exe}' not running. Please start the game.")
                sys.exit(1)
            except Exception as e:
                print(f"An unexpected error occurred while attaching to process: {e}")
                sys.exit(1)
    
            try:
                self.base = pymem.process.module_from_name(self.pm.process_handle, self.mod).lpBaseOfDll
                if not self.base:
                     raise pymem.exception.ProcessError(f"Got null base address for module {self.mod}")
                print(f"Found module '{self.mod}' at base address: {hex(self.base)}")
            except (AttributeError, pymem.exception.ProcessError):
                print(f"Error: Module '{self.mod}' not found in '{self.exe}'.")
                print("Ensure the game is fully loaded (e.g., at the character selection screen or in-game).")
                self.pm.close_process()
                sys.exit(1)
            except Exception as e:
                print(f"An unexpected error occurred while finding module: {e}")
                if self.pm:
                    self.pm.close_process()
                sys.exit(1)
    
        def read_value(self, key):
            p = self.ptr_defs[key]
            try:
                address = p["static"] 
                if p["type"] == "float":
                    value = self.pm.read_float(address)
                elif p["type"] == "int":
                    value = self.pm.read_int(address)
                else:
                     raise ValueError(f"Unknown data type '{p['type']}' for key '{key}'")
                return value
            except pymem.exception.MemoryReadError as e:
                raise pymem.exception.MemoryReadError(f"Failed to read value for '{key}': {e}")
            except ValueError as e:
                raise ValueError(e)
    
        def safe_read(self, key):
            try:
                return self.read_value(key)
            except (pymem.exception.MemoryReadError, pymem.exception.WinAPIError, TypeError, ValueError) as e:
                print(f"Read error for '{key}': {e}. Attempting to re-attach...")
                self.attach_process()
                time.sleep(1.5)
                try:
                     return self.read_value(key)
                except (pymem.exception.MemoryReadError, pymem.exception.WinAPIError, TypeError, ValueError) as e2:
                     print(f"Read error persisted for '{key}' after re-attach: {e2}")
                     return None
                except Exception as e_fatal:
                     print(f"Unexpected critical error reading '{key}' after re-attach: {e_fatal}")
                     self.quit_game(f"Fatal read error: {e_fatal}")
                     return None
            except Exception as e_fatal:
                 print(f"Unexpected critical error reading '{key}': {e_fatal}")
                 self.quit_game(f"Fatal read error: {e_fatal}")
                 return None
    
        def main(self):
            last_pot_time = 0.0
            error_count = 0
            max_errors = 15
    
            print("Starting health monitor loop...")
            while True:
                try:
                    hp = self.safe_read("cur_hp")
                    max_hp = self.safe_read("max_hp")
    
                    loading_state = False
                    loading_reason = ""
    
                    if hp is None or max_hp is None:
                        print("Failed to read one or more values after retry.")
                        error_count += 1
                        loading_state = True
                        loading_reason = "Read Error"
                    elif hp <= 0:
                        loading_state = True
                        loading_reason = f"HP <= 0 ({hp})"
                    elif max_hp <= 0:
                         loading_state = True
                         loading_reason = f"Max HP <= 0 ({max_hp})"
    
                    if loading_state:
                        if loading_reason != "Read Error":
                             print(f"Loading state detected ({loading_reason}). Waiting...")
                        error_count = 0
                        time.sleep(0.5)
                        continue
                    else:
                        error_count = 0
                        pct = (hp / max_hp) * 100
    
                        print(f"HP: {hp:.1f} | Max HP: {max_hp} | ({pct:.0f}%)")
    
                        current_time = time.time()
                        if hp < self.low_hp_threshold and (current_time - last_pot_time) >= self.key_delay:
                            print(f"Using potion at {hp:.0f} HP.")
                            try:
                                keyboard.press_and_release('1')
                                last_pot_time = current_time
                            except Exception as key_error:
                                 print(f"Warning: Failed to press potion key '1': {key_error}")
    
                    if error_count > max_errors:
                        print(f"Exceeded maximum consecutive read errors ({max_errors}). Exiting.")
                        self.quit_game("Too many read errors")
    
                    time.sleep(0.05 if error_count == 0 and not loading_state else 0.5)
    
                except KeyboardInterrupt:
                    print("\nKeyboard interrupt received. Exiting.")
                    if self.pm:
                        self.pm.close_process()
                    sys.exit(0)
                except Exception as loop_error:
                     print(f"Unexpected error in main loop: {loop_error}")
                     error_count +=1
                     if error_count > max_errors:
                          self.quit_game(f"Fatal loop error: {loop_error}")
                     time.sleep(1)
    
    
    if __name__ == "__main__":
        monitor = LastEpochMonitor()
        monitor.main()
    Last edited by miracle1; 04-24-2025 at 03:50 AM.

  14. #10
    rxemi115566's Avatar Member
    Reputation
    9
    Join Date
    Oct 2017
    Posts
    15
    Thanks G/R
    0/8
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'll have another look, they have pushed another update, its 1.2.1.1 now - something came up 2-3 hours.
    Last edited by rxemi115566; 04-24-2025 at 05:07 AM.

  15. Thanks SquareCubiC (1 members gave Thanks to rxemi115566 for this useful post)
  16. #11
    MetkataTipcheto's Avatar Member
    Reputation
    6
    Join Date
    Sep 2014
    Posts
    59
    Thanks G/R
    0/5
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for you contribution to this script, it's very useful.

  17. #12
    rxemi115566's Avatar Member
    Reputation
    9
    Join Date
    Oct 2017
    Posts
    15
    Thanks G/R
    0/8
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    24/04/2025 update - 1.2.1.1

    Code:
                "cur_hp": {"static": 0x4040968, "chain": (0x88, 0x128, 0x90, 0x80, 0xB8, 0x10, 0xB0), "type": "float"},
                "es":     {"static": 0x4105E38, "chain": (0xB8, 0x0, 0x18, 0x2D4), "type": "float"},
                "max_hp": {"static": 0x40F7038, "chain": (0xB8, 0x0, 0xE0, 0x68), "type": "int"}
    Last edited by rxemi115566; 04-24-2025 at 03:02 PM.

  18. Thanks SquareCubiC (1 members gave Thanks to rxemi115566 for this useful post)
  19. #13
    MetkataTipcheto's Avatar Member
    Reputation
    6
    Join Date
    Sep 2014
    Posts
    59
    Thanks G/R
    0/5
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Successfully attached to process: Last Epoch.exe
    Found module 'GameAssembly.dll' at base address: 0x7ffe35e90000
    Starting health monitor loop...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    Loading state detected (HP <= 0 (0.0)). Waiting...
    I just always says that and doesn't work

  20. #14
    rxemi115566's Avatar Member
    Reputation
    9
    Join Date
    Oct 2017
    Posts
    15
    Thanks G/R
    0/8
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    self.ptr_defs = {
                "cur_hp": {"static": 0x4040968, "chain": (0x88, 0x128, 0x90, 0x80, 0xB8, 0x10, 0xB0), "type": "float"},
                "es":     {"static": 0x4105E38, "chain": (0xB8, 0x0, 0x18, 0x2D4), "type": "float"},
                "max_hp": {"static": 0x40F7038, "chain": (0xB8, 0x0, 0xE0, 0x68), "type": "int"}
            }
    Double check that you're using above pointers, works for me.

  21. Thanks SquareCubiC (1 members gave Thanks to rxemi115566 for this useful post)
  22. #15
    MetkataTipcheto's Avatar Member
    Reputation
    6
    Join Date
    Sep 2014
    Posts
    59
    Thanks G/R
    0/5
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I am using them, here is my full script:
    import sys
    import time
    import ctypes
    import keyboard
    import pymem
    import pymem.process
    import pymem.exception

    class LastEpochMonitor:
    def __init__(self, exe="Last Epoch.exe", mod="GameAssembly.dll",
    key_delay=1.0, low_hp_pct=0, potion_pct=50, busy_val=500,
    auto_quit=False):
    self.exe = exe
    self.mod = mod
    self.key_delay = key_delay
    self.low_hp_pct = low_hp_pct
    self.potion_pct = potion_pct
    self.busy_val = busy_val
    self.auto_quit = auto_quit
    self.ptr_defs = {
    "cur_hp": {"static": 0x4040968, "chain": (0x88, 0x128, 0x90, 0x80, 0xB8, 0x10, 0xB0), "type": "float"},
    "es": {"static": 0x4105E38, "chain": (0xB8, 0x0, 0x18, 0x2D4), "type": "float"},
    "max_hp": {"static": 0x40F7038, "chain": (0xB8, 0x0, 0xE0, 0x6, "type": "int"}
    }
    self.pm = None
    self.base = None
    self.attach_process()

    def attach_process(self):
    try:
    self.pm = pymem.Pymem(self.exe)
    print(f"Successfully attached to process: {self.exe}")
    except pymem.exception.ProcessNotFound:
    print(f"Error: Process '{self.exe}' not running. Please start the game.")
    sys.exit(1)
    except Exception as e:
    print(f"An unexpected error occurred while attaching to process: {e}")
    sys.exit(1)

    try:
    self.base = pymem.process.module_from_name(self.pm.process_handle, self.mod).lpBaseOfDll
    if not self.base:
    raise pymem.exception.ProcessError(f"Got null base address for module {self.mod}")
    print(f"Found module '{self.mod}' at base address: {hex(self.base)}")
    except (AttributeError, pymem.exception.ProcessError):
    print(f"Error: Module '{self.mod}' not found in '{self.exe}'.")
    print("Ensure the game is fully loaded (e.g., at the character selection screen or in-game).")
    self.pm.close_process()
    sys.exit(1)
    except Exception as e:
    print(f"An unexpected error occurred while finding module: {e}")
    if self.pm:
    self.pm.close_process()
    sys.exit(1)

    def _resolve_ptr(self, base_addr, chain):
    try:
    addr = self.pm.read_longlong(base_addr)
    if not addr:
    raise pymem.exception.MemoryReadError(f"Base address read returned null at {hex(base_addr)}")
    except pymem.exception.MemoryReadError as e:
    raise pymem.exception.MemoryReadError(f"Failed initial read at {hex(base_addr)}: {e}")

    for i, off in enumerate(chain[:-1]):
    try:
    next_addr = self.pm.read_longlong(addr + off)
    if not next_addr:
    raise pymem.exception.MemoryReadError(f"Pointer became null at chain index {i}, offset {hex(off)} (current address: {hex(addr)})")
    addr = next_addr
    except pymem.exception.MemoryReadError as e:
    raise pymem.exception.MemoryReadError(f"Failed reading offset {hex(off)} at chain index {i} (current address: {hex(addr)}): {e}")

    final_address = addr + chain[-1]
    return final_address

    def read_value(self, key):
    p = self.ptr_defs[key]
    try:
    address = self._resolve_ptr(self.base + p["static"], p["chain"])
    if p["type"] == "float":
    value = self.pm.read_float(address)
    elif p["type"] == "int":
    value = self.pm.read_int(address)
    else:
    raise ValueError(f"Unknown data type '{p['type']}' for key '{key}'")
    return value
    except pymem.exception.MemoryReadError as e:
    raise pymem.exception.MemoryReadError(f"Failed to read value for '{key}': {e}")
    except ValueError as e:
    raise ValueError(e)


    def safe_read(self, key):
    try:
    return self.read_value(key)
    except (pymem.exception.MemoryReadError, pymem.exception.WinAPIError, TypeError, ValueError) as e:
    print(f"Read error for '{key}': {e}. Attempting to re-attach...")
    self.attach_process()
    time.sleep(1.5)
    try:
    return self.read_value(key)
    except (pymem.exception.MemoryReadError, pymem.exception.WinAPIError, TypeError, ValueError) as e2:
    print(f"Read error persisted for '{key}' after re-attach: {e2}")
    return None
    except Exception as e_fatal:
    print(f"Unexpected critical error reading '{key}' after re-attach: {e_fatal}")
    self.quit_game(f"Fatal read error: {e_fatal}")
    return None
    except Exception as e_fatal:
    print(f"Unexpected critical error reading '{key}': {e_fatal}")
    self.quit_game(f"Fatal read error: {e_fatal}")
    return None


    def quit_game(self, reason):
    print(f"Quit triggered: {reason}")
    try:
    print("Attempting Alt+F4...")
    keyboard.press_and_release('alt+f4')
    time.sleep(0.3)
    except Exception as e:
    print(f"Warning: Failed to send Alt+F4 ({e}). Proceeding with termination.")

    try:
    if self.pm and self.pm.process_handle:
    print(f"Terminating process ID: {self.pm.process_id}")
    handle = int(self.pm.process_handle)
    if handle:
    success = ctypes.windll.kernel32.TerminateProcess(handle, 0)
    if success:
    print("Process terminated successfully.")
    else:
    error_code = ctypes.windll.kernel32.GetLastError()
    print(f"Failed to terminate process. Error code: {error_code}")
    else:
    print("Process handle is invalid, cannot terminate.")
    self.pm.close_process()
    else:
    print("No valid process handle to terminate.")
    except Exception as e:
    print(f"Error during process termination: {e}")

    print("Exiting script.")
    sys.exit(0)

    def main(self):
    last_pot_time = 0.0
    error_count = 0
    max_errors = 15

    print("Starting health monitor loop...")
    while True:
    try:
    hp = self.safe_read("cur_hp")
    es = self.safe_read("es")
    max_hp = self.safe_read("max_hp")

    loading_state = False
    loading_reason = ""

    if hp is None or es is None or max_hp is None:
    print("Failed to read one or more values after retry.")
    error_count += 1
    loading_state = True
    loading_reason = "Read Error"
    elif hp <= 0:
    loading_state = True
    loading_reason = f"HP <= 0 ({hp})"
    elif hp == self.busy_val:
    loading_state = True
    loading_reason = f"HP == busy_val ({hp})"
    elif max_hp <= 0:
    loading_state = True
    loading_reason = f"Max HP <= 0 ({max_hp})"
    elif max_hp == self.busy_val:
    loading_state = True
    loading_reason = f"Max HP == busy_val ({max_hp})"

    if loading_state:
    if loading_reason != "Read Error":
    print(f"Loading state detected ({loading_reason}). Waiting...")
    error_count = 0
    time.sleep(0.5)
    continue
    else:
    error_count = 0
    current_effective_hp = hp + es
    pct = (current_effective_hp / max_hp) * 100

    print(f"HP: {hp:.1f} ES: {es:.1f} | Total: {current_effective_hp:.1f}/{max_hp} ({pct:.0f}%)")

    if pct < self.low_hp_pct:
    if self.auto_quit:
    self.quit_game(f"Health low: {pct:.0f}% < {self.low_hp_pct}%")
    else:
    print(f"LOW HEALTH WARNING: {pct:.0f}% < {self.low_hp_pct}% (Auto-quit disabled)")

    current_time = time.time()
    if pct < self.potion_pct and (current_time - last_pot_time) >= self.key_delay:
    print(f"Using potion at {pct:.0f}% health.")
    try:
    keyboard.press_and_release('1')
    last_pot_time = current_time
    except Exception as key_error:
    print(f"Warning: Failed to press potion key '1': {key_error}")

    if error_count > max_errors:
    print(f"Exceeded maximum consecutive read errors ({max_errors}). Exiting.")
    self.quit_game("Too many read errors")

    time.sleep(0.05 if error_count == 0 and not loading_state else 0.5)

    except KeyboardInterrupt:
    print("\nKeyboard interrupt received. Exiting.")
    if self.pm:
    self.pm.close_process()
    sys.exit(0)
    except Exception as loop_error:
    print(f"Unexpected error in main loop: {loop_error}")
    error_count +=1
    if error_count > max_errors:
    self.quit_game(f"Fatal loop error: {loop_error}")
    time.sleep(1)


    if __name__ == "__main__":
    monitor = LastEpochMonitor(auto_quit=True)
    monitor.main()

Page 1 of 2 12 LastLast

Similar Threads

  1. on use trinkets and potions
    By lg40 in forum PE Support forum
    Replies: 7
    Last Post: 12-26-2014, 04:58 AM
  2. [Selling] Crafting Materials, Gems and Potions
    By NonMinorMiner in forum Diablo 3 Buy Sell Trade
    Replies: 0
    Last Post: 03-25-2014, 10:13 AM
  3. 50% off dyes and potions
    By Cirvantes1 in forum Diablo 3 Exploits
    Replies: 4
    Last Post: 05-28-2012, 08:59 PM
  4. Infinate chests and potions exploit
    By Veareas in forum Diablo 3 Exploits
    Replies: 8
    Last Post: 05-26-2012, 10:32 PM
  5. [Trick] Get free gold and potions with "Create a free level 50"
    By Tehdew in forum Age of Conan Exploits|Hacks
    Replies: 8
    Last Post: 07-15-2009, 10:35 AM
All times are GMT -5. The time now is 02:51 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search