local itemtable = {} local function GetIdAddressLine(id) if itemtable[id] then return itemtable[id] end local proc = getProc() local lineSize = 0x20; local tablePointer = memoryReadUIntPtr( proc, addresses.tablesBase, addresses.tablesBaseOffset ) local startAddressOffsets = {0,addresses.tableStartPtrOffset, addresses.tableDataStartPtrOffset} local dataPointer = memoryReadUIntPtr( proc, tablePointer , startAddressOffsets ) - lineSize local IdTableHeader --Reads into the table to get a 'IdTableHeader' address for i=0,10 do local offset0 = memoryReadUInt( proc, dataPointer - lineSize * i ) local offset8 = memoryReadUInt( proc, (dataPointer - lineSize * i ) + 0x8) if offset0 == offset8 then IdTableHeader = offset0 break end end if IdTableHeader == nil then error("Unable to find a valid IdTableAddress") end --Get informations from the 'IdTableHeader' local smallestIdAddress = memoryReadUInt( proc, IdTableHeader ) local middleIdAddress = memoryReadUInt( proc, IdTableHeader + 0x4 ) local largestIdAdress = memoryReadUInt( proc, IdTableHeader + 0x8 ) local smallestId = memoryReadInt( proc, smallestIdAddress + addresses.idOffset ) local largestId = memoryReadInt( proc, largestIdAdress + addresses.idOffset ) -- up to here is simply to know that Id start at 1000 and ends at 850682 (13/4/13) -- Searches for the address in memory for the id 'IdToFind' local function FindIdAddress(IdToFind) -- Check the 'IdToFind'. if IdToFind == nil or IdToFind < smallestId or IdToFind > largestId then return end -- Use the middleIdAddress from IdAddressTables to start search -- should be able to improve this. local dataPointer = middleIdAddress local loopTest = 0 -- Used to make sure it doesn't get stuck in a loop if bad id repeat loopTest = loopTest + 1 -- Get 0 and 8 offsets local offset8 = memoryReadUInt( proc, dataPointer + 8) -- Read a valid value? Has it reached the end of the table? if offset8 == nil or offset8 < 0x100000 then return end local offset0 = memoryReadUInt( proc, dataPointer ) -- Get the id local currentId = memoryReadInt( proc, dataPointer + addresses.idOffset ) --printf("currentAddress %X , current ID %X:%d IdToFind %X:%d\n",dataPointer,currentId,currentId,IdToFind,IdToFind) itemtable[currentId] = dataPointer -- Check the id. if currentId == nil or currentId < smallestId or currentId > largestId then return end -- Add to table to speed future searches if not IdAddressTables[currentId] then IdAddressTables[currentId] = dataPointer end -- Id not found. Get next dataPointer. if currentId > IdToFind then if offset0 == offset8 or offset0 == IdTableHeader then dataPointer = dataPointer + lineSize else dataPointer = offset0 end elseif currentId < IdToFind then if offset0 == offset8 or offset8 == IdTableHeader then dataPointer = dataPointer - lineSize else dataPointer = offset8 end end until currentId == IdToFind or loopTest > 500 return dataPointer end if IdAddressTables == nil then IdAddressTables = {} end -- Is it already in the table if IdAddressTables[id] then return IdAddressTables[id] end -- Else find it in memory return FindIdAddress(id) end function GetItemAddress(id) local proc = getProc() if id then local addressline = GetIdAddressLine(id) if addressline then local address = memoryReadUIntPtr( proc, addressline + 0x10, 0x8) if address == 0 then print("Address not gotten from memory but used a RoMScript: "..id) -- Item data not substanciated yet. Do "GetCraftRequestItem", then the address will exist. if RoMScript then RoMScript("GetCraftRequestItem("..id..", -1)") end address = memoryReadUIntPtr( proc, addressline + 0x10, 0x8); end return address else if settings.options.DEBUGGING == true then printf("Id %d not found\n", id) end end else if settings.options.DEBUGGING == true then printf("Id is nil\n") end end end -- Returns the name for a given id function GetIdName(itemId) local proc = getProc() if itemId ~= nil and itemId > 0 then local itemAddress = GetItemAddress(itemId) if itemAddress ~= nil and itemAddress > 0 then local name = memoryReadStringPtr(proc, itemAddress + addresses.nameOffset, 0) if name == nil then print("Id not gotten from memory but used a RoMScript: "..itemId) -- Item data not totally substanciated yet. Do "GetCraftRequestItem", then the address will exist. if RoMScript then RoMScript("GetCraftRequestItem("..itemId..", -1)") end name = memoryReadStringPtr(proc, itemAddress + addresses.nameOffset, 0) end return name end end end