Originally Posted by
Edg
I want to read inventory. Im making helper application and I need reliable inventory reading. I could do that through website but it updates every couple of mins or so.
In HUD it also gets all info about item (name, level, stats, if its unindentified..)? I looked through code few times and its bit confusing
I'll explain it as best I can. Feel free to ask questions if I'm not clear at any point. I'll also assume you don't have a framework in place (and this is with vanilla, if you need offsets adjusted for Steam/Garena, let me know).
First, to read the player's inventory, you need the base pointer, which you can grab with this pattern:
Code:
0x50, 0x64, 0x89, 0x25, 0x00, 0x00, 0x00, 0x00,
0x81, 0xEC, 0xB0, 0x00, 0x00, 0x00, 0xA1, 0x00,
0x00, 0x00, 0x00, 0x85, 0xC0, 0x0F, 0x95, 0xC1,
0x84, 0xC9, 0x56, 0x0F, 0x94, 0xC1, 0x84, 0xC9
and this mask:
Code:
"xxxxxxxxxxxxxxx????xxxxxxxxxxxxx"
The base pointer is read at offset 0xF (the 4 ?s in the mask). (Also, there are other patterns/masks out there, you don't have to use the one I'm using.)
To get to the player's inventory from there (I'll put the HUD class names in parenthesis as I get to them):
Code:
Base->0x4->0xFC(TheGame)->0x11C(IngameState)->0x5E8(IngameUI)->0xA24(InventoryPanel)->0x9D0(InventoryZone)
Once you have the address for InventoryZone, there's a list of entity pointers that you can iterate through in InventoryZone. That list is pointed to at 0x788 and the end of the list is at 0x78C.
You'd do something like this to iterate through them, depending on your programming language:
Code:
List<Entity> InventoryList = new List<Entity>();
Start = readint(InventoryZone + 0x788);
End = readint(InventoryZone + 0x78C);
CurrPointer = Start;
While(CurrPointer < End)
{
InventoryList.Add(Entity(CurrPointer));
CurrPointer += 4;
}
And Entity would look something like:
Code:
class Entity(Address)
{
private int ComponentLookup => ReadInt(Address, 0x30, 0x18, 0);
private int ComponentList => ReadInt(Address + 4);
public string Path => ReadStringU(ReadInt(Address, 0x14));
public int Id => ReadInt(Address + 0x14);
public int InventoryId => ReadInt(Address + 0x18);
public long LongId => (long)Id << 32 ^ Path.GetHashCode();
public bool IsValid => ReadInt(Address, 0x14, 0) == 0x65004D; // Check for 'Me' at start of Path
public bool IsHostile => (ReadByte(Address + 0x19) & 1) == 0;
}
If you need help with iterating through components (where you're going to find mods, rarity, sockets, etc.), let me know.