WARNING: This is NOT actually 100% reliable in identify boots x__x, this is used to tell whether a confirmation message will appear if you drop the item.
(Confirmation messages ('safe trade can be performed in trading post' never appear for dropping boots though)
(Small amount of ores could be false positives)
As far as I know most public bots seem to use image compare instead of reading memory for dropping boots...
This is my original research, if you use this in your bot please give credits :)
Base: trove.exe+0x0088F584
Pointers: 0x17c, 0x78, i*4, 0x40, 0x88, 0
where i is the inventory slot index
Data: (the complicated part, please see C++ implementation below)
First you have to xor the data with 0x88940CB6
Then you add 0x190 to get your address...
Outcome:
0 if a warning is not given when the item is dropped, 1 if a warning is given when the item is dropped
NOTE: As of inventory slot upgrade update, inventory slot beyond 45 has not been tested. :o
Inventory has to be kept open for the pointers to work.
Code:
#define INVENTORY_ADDR 0x0088F584
#define MAGIC_CONV 0x88940CB6
#define INVENTORY_SLOT_COUNT 45
//Get base address
DWORD gameBase = x::GetModuleBase(pid,_T("trove.exe"));
//Get inventory base address
DWORD invCBase = gameBase+INVENTORY_ADDR;
long invIds[INVENTORY_SLOT_COUNT]; //allocate array for storing results
if ( x::RPM<DWORD>(pid,invCBase) ) //if inventory is open
{
for (size_t i = 0; i < INVENTORY_SLOT_COUNT; i++)
{
DWORD invObjOff[] = {0x17c, 0x78, i*4, 0x40};
DWORD invObjAddr = x::RPMPtr(pid,invCBase,invObjOff,sizeof(invObjOff)/sizeof(DWORD)); //get pointer address
DWORD invObj = x::RPM<DWORD>(pid,invObjAddr); //read process memory
if (invObj) //the slot is filled with an item
{
DWORD invIdOff[] = {0x17c, 0x78, i*4, 0x40, 0x88, 0};
DWORD invIdAddr = x::RPMPtr(pid,invCBase,invIdOff,sizeof(invIdOff)/sizeof(DWORD)); //get pointed address
invIdAddr = ((x::RPM<DWORD>(pid,invIdAddr)) ^ MAGIC_CONV) + 0x190; //some weird xor (game protection?)
invIds[i] = x::RPM<BYTE>(pid, invIdAddr); //0 = no warning, 1 = give warning
}
else
invIds[i] = 0xFFFFFFFF; //slot is empty
}
}
invIds[i] will be either -1 (empty), 0 (no drop warning) or 1 (give drop warning)
Before you C+P the code above, I would remind you to replace the following:
Code:
DWORD x::GetModuleBase(DWORD pid, TCHAR *szModuleName)
with your own implementation of - Get remote module address (at which the module is loaded)
Code:
DWORD x::RPMPtr (DWORD pid, DWORD baseAddress, DWORD *offsets, size_t offsets_size)
Get pointed address (not data!) from offsets
Code:
template <typename T> T x::RPM(pid, DWORD dwAddress)
- Read process memory at dwAddress
Please be easy on my 1st post.