I tried to make something on my own but I couldn't get these two offsets to work how should i use these offsets?
Code:
import pymem
import pymem.process
import pymem.ptypes
import time
import traceback
# Constants
TROVE_EXE = "Trove.exe"
ENTITY_LIST = 0x11FBBD0
LOCAL_PLAYER = 0x11F9424
POSITION_OFFSETS = [0x8, 0x28, 0xC4, 0x4, 0x80]
# Scale offsets
ENTITY_OBJECT_SCALE_OFFSETS = [0x74]
ENTITY_OBJECT_SIZE_OFFSETS = [0x8]
# Names to exclude
EXCLUDED_NAMES = [
"pet", "portal", "abilities", "placeable", "cornerstone",
"services", "client", "karma", "mana", "outpost"
]
class Vec3:
def __init__(self, x=0.0, y=0.0, z=0.0):
self.x = float(x)
self.y = float(y)
self.z = float(z)
def __sub__(self, other):
return Vec3(self.x - other.x, self.y - other.y, self.z - other.z)
def length(self):
return (self.x**2 + self.y**2 + self.z**2)**0.5
def read_pointer_chain(pm, base, offsets):
"""Read memory through a chain of pointers"""
try:
ptr = pymem.ptypes.RemotePointer(pm.process_handle, base)
for offset in offsets[:-1]:
ptr = pymem.ptypes.RemotePointer(pm.process_handle, ptr.value + offset)
return ptr.value + offsets[-1]
except Exception as e:
print(f"Pointer chain failed: {e}")
return None
def get_address(pm, base, offsets):
"""Get final address from offset chain"""
try:
addr = base
for offset in offsets[:-1]:
addr = pm.read_uint(addr + offset)
if addr == 0:
return 0
return addr + offsets[-1]
except Exception as e:
print(f"Address calculation failed: {e}")
return 0
def read_string(pm, address, max_len=96):
"""Read string from memory address"""
try:
raw = pm.read_bytes(address, max_len)
return raw.split(b'\0', 1)[0].decode('latin-1', errors='replace')
except Exception as e:
print(f"String read failed: {e}")
return ""
def get_local_position(pm, base):
"""Get player's current position"""
try:
addr = read_pointer_chain(pm, base + LOCAL_PLAYER, POSITION_OFFSETS)
if addr:
x = pm.read_float(addr)
y = pm.read_float(addr + 0x4)
z = pm.read_float(addr + 0x8)
return Vec3(x, y, z)
except Exception as e:
print(f"Position read failed: {e}")
return Vec3()
def read_entity_scale(pm, entity_addr):
"""Read entity scale using the provided offsets"""
try:
scale_addr = get_address(pm, entity_addr, ENTITY_OBJECT_SCALE_OFFSETS)
if scale_addr:
return pm.read_float(scale_addr)
except Exception as e:
print(f"Scale read failed: {e}")
return 0.0
def read_entity_size(pm, entity_addr):
"""Read entity size using the provided offsets"""
try:
size_addr = get_address(pm, entity_addr, ENTITY_OBJECT_SIZE_OFFSETS)
if size_addr:
return pm.read_float(size_addr)
except Exception as e:
print(f"Size read failed: {e}")
return 0.0
def get_monsters_with_scales(pm, world_addr, our_pos, max_range=50.0):
"""Get all monsters within range and their scale values"""
monsters = []
nodes = []
try:
if world_addr == 0:
return monsters
# Get entity list structure
node_info = get_address(pm, world_addr, [0x7C])
base_addr = pm.read_uint(node_info)
size_addr = get_address(pm, node_info, [0x8])
size = pm.read_uint(size_addr)
step = pm.read_uint(get_address(pm, node_info, [0x4]))
# Traverse entity nodes
if size == 0:
address = base_addr
for _ in range(100):
next_addr = pm.read_uint(address) & 0xFFFFFFFE
if next_addr == 0:
break
nodes.append(address)
address = next_addr
else:
for i in range(size):
address = base_addr + i * step
while True:
next_addr = pm.read_uint(address)
if next_addr == 1:
break
nodes.append(address)
address = next_addr & 0xFFFFFFFE
if address == 0:
break
# Process each entity node
for node in nodes:
try:
entity = get_address(pm, node, [0x10, 0xC4, 0x4, 0x0])
if not entity:
continue
# Get entity name
name_addr = get_address(pm, entity, [0x58, 0x64, 0x0])
if not name_addr:
continue
name = read_string(pm, name_addr)
if not name:
continue
name_lower = name.lower()
# Skip excluded entities
if any(ex in name_lower for ex in EXCLUDED_NAMES):
continue
# Get entity position
pos_addr = get_address(pm, entity, [0x58, 0xC4, 0x4, 0x80])
if not pos_addr:
continue
position = Vec3(
pm.read_float(pos_addr),
pm.read_float(pos_addr + 0x4),
pm.read_float(pos_addr + 0x8)
)
# Check if within range
distance = (position - our_pos).length()
if distance > max_range:
continue
# Read scale and size
scale = read_entity_scale(pm, entity)
size = read_entity_size(pm, entity)
monsters.append({
'name': name,
'distance': distance,
'scale': scale,
'size': size,
'position': position
})
except Exception as e:
print(f"Entity processing error: {e}")
continue
except Exception as e:
print(f"get_monsters_with_scales error: {e}")
traceback.print_exc()
return monsters
def main():
print("Bot ")
print("find monsters and print their scale values.")
print("Press Ctrl+C to stop.\n")
try:
# Connect to Trove process
pm = pymem.Pymem(TROVE_EXE)
base = pymem.process.module_from_name(pm.process_handle, TROVE_EXE).lpBaseOfDll
print("[+] Connected to Trove.exe")
print("[+] Base address:", hex(base))
print("-" * 50)
last_scan_time = 0
scan_interval = 2.0 # Scan every 2 seconds
while True:
try:
current_time = time.time()
# Only scan every few seconds to avoid spam
if current_time - last_scan_time < scan_interval:
time.sleep(0.1)
continue
last_scan_time = current_time
# Get player position
local_pos = get_local_position(pm, base)
if local_pos.x == 0 and local_pos.y == 0 and local_pos.z == 0:
print("[!] Could not read player position, retrying...")
time.sleep(1)
continue
# Get world entity list
world_addr = pm.read_uint(base + ENTITY_LIST)
if world_addr == 0:
print("[!] Could not read world address, retrying...")
time.sleep(1)
continue
# Find monsters and their scales
monsters = get_monsters_with_scales(pm, world_addr, local_pos, 50.0)
if monsters:
print(f"\n[SCAN] Found {len(monsters)} monster(s):")
print("-" * 70)
for monster in sorted(monsters, key=lambda x: x['distance']):
print(f"Name: {monster['name']:<25} | "
f"Scale: {monster['scale']:<8.3f} | "
f"Size: {monster['size']:<8.3f} | "
f"Distance: {monster['distance']:.1f}")
print("-" * 70)
else:
print("[SCAN] No monsters found nearby.")
except KeyboardInterrupt:
print("\n[!] Bot stopped by user.")
break
except Exception as e:
print(f"[!] Scan error: {e}")
time.sleep(1)
continue
except pymem.exception.ProcessNotFound:
print("[!] Trove.exe not found! Make sure the game is running.")
except pymem.exception.CouldNotOpenProcess:
print("[!] Could not open Trove process. Run as administrator.")
except Exception as e:
print(f"[!] Initialization error: {e}")
traceback.print_exc()
input("\nPress ENTER to exit...")
if __name__ == "__main__":
main()