local LoadAllIDs = false local function GetIdAddressLine(id) local idOffset = 0xC local lineSize = 0x20 local tablePointer = memoryReadIntPtr( getProc(), addresses.tablesBase, addresses.tablesBaseOffset ) local startAddressOffsets = {0,addresses.tableStartPtrOffset, addresses.tableDataStartPtrOffset} local dataPointer = memoryReadIntPtr( getProc(), tablePointer , startAddressOffsets ) - lineSize local IdTableHeader for i=0,10 do local offset0 = memoryReadInt( getProc(), dataPointer - lineSize * i ) local offset8 = memoryReadInt( getProc(), (dataPointer - lineSize * i ) + 0x8) if offset0 == offset8 then IdTableHeader = offset0 break end end local smallestIdAddress = memoryReadInt( getProc(), IdTableHeader ) local middleIdAddress = memoryReadInt( getProc(), IdTableHeader + 0x4 ) local largestIdAdress = memoryReadInt( getProc(), IdTableHeader + 0x8 ) local smallestId = memoryReadInt( getProc(), smallestIdAddress + idOffset ) local middleId = memoryReadInt( getProc(), middleIdAddress + idOffset ) local largestId = memoryReadInt( getProc(), largestIdAdress + idOffset ) local function ReadBlockConnections() local memBlocks = {} BlockConnectionList = {} for i= 0x100000,0x1FFF0000,0x10000 do local offset18 = memoryReadInt( getProc(), i + 0x18 ) local offset1C = memoryReadInt( getProc(), i + 0x1C ) local temp1 = true local temp2 = true if offset18 == 0x0 and offset1C == 0x0 then for a=1,10 do local offset0 = memoryReadInt( getProc(), i + lineSize * (a - 1) ) local offset8 = memoryReadInt( getProc(), i + lineSize * (a - 1) + 0x8 ) if temp1 and offset0 == offset8 and offset0 == IdTableHeader then local IDonTop = memoryReadInt( getProc(), i + lineSize * (a - 1) + idOffset ) memBlocks[i] = IDonTop temp1 = false end local offset0 = memoryReadInt( getProc(), i + 0x10000 - lineSize * a ) local offset8 = memoryReadInt( getProc(), i + 0x10000 - lineSize * a + 0x8 ) if temp2 and offset0 == offset8 and offset0 == IdTableHeader then local IDonEnd = memoryReadInt( getProc(), i + 0x10000 - lineSize * a + idOffset ) memBlocks[i + 0xFFE0] = IDonEnd temp2 = false end end end end for i,v in pairs(memBlocks) do if i % 0x10000 == 0 then local closestId = nil local closestBlock = nil for a,b in pairs(memBlocks) do if (a + lineSize) % 0x10000 == 0 then if closestId == nil or math.abs(v - b) < math.abs(v - closestId) then closestId = b closestBlock = a end end end BlockConnectionList[i] = closestBlock end end end local function HandleBlockConnections(_IdAddressLine, direction) if direction == "up" then if _IdAddressLine % 0x10000 == 0 then if not BlockConnectionList then ReadBlockConnections() end for i,v in pairs(BlockConnectionList) do if i == _IdAddressLine then printf("%X -> %X\n",_IdAddressLine,v) return v end end else return _IdAddressLine - lineSize end elseif direction == "down" then if (_IdAddressLine + lineSize) % 0x10000 == 0 then if not BlockConnectionList then ReadBlockConnections() end for i,v in pairs(BlockConnectionList) do if v == _IdAddressLine then printf("%X <- %X\n",i,_IdAddressLine) return i end end else return _IdAddressLine + lineSize end end end -- Finds the nearest address in 'IdAddressTables' with the closest id to '_id' local function FindNearestIdAddress(_id) local closestId for i,v in pairs(IdAddressTables) do if closestId == nil or math.abs(_id - i) < math.abs(_id - closestId) then closestId = i end end return IdAddressTables[closestId] end -- Searches for the address in memory for the id 'IdToFind' local function FindIdAddress(IdToFind) -- Get closest existing address from IdAddressTables to start search if IdToFind > largestId or IdToFind < smallestId or LoadAllIDs == true then return end local dataPointer = FindNearestIdAddress(IdToFind) 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 = memoryReadInt( getProc(), 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 = memoryReadInt( getProc(), dataPointer ) -- Get the id local currentId = memoryReadInt( getProc(), dataPointer + addresses.idOffset ); --printf("currentAddress %X , current ID %X:%d IdToFind %X:%d\n",dataPointer,currentId,currentId,IdToFind,IdToFind) -- 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 = HandleBlockConnections( dataPointer , "down" ) else dataPointer = offset0 end elseif currentId < IdToFind then if offset0 == offset8 or offset8 == IdTableHeader then dataPointer = HandleBlockConnections( dataPointer , "up" ) else dataPointer = offset8 end end until currentId == IdToFind or loopTest > 200 return dataPointer end --first initialization if IdAddressTables == nil and LoadAllIDs == true then IdAddressTables = {} ReadBlockConnections() local dataPointer = IdTableHeader - lineSize * 3 local counter = 0 repeat local currentId = memoryReadInt( getProc(), dataPointer + addresses.idOffset ) if currentId ~= nil and currentId > smallestId and currentId < largestId then IdAddressTables[currentId] = dataPointer end dataPointer = HandleBlockConnections( dataPointer , "up" ) counter = counter + 1 until dataPointer == nil BlockConnectionList = nil cprintf(cli.red, "%d Object-IDs transfered\n", counter) end if IdAddressTables == nil then IdAddressTables = {} IdAddressTables[smallestId] = smallestIdAddress IdAddressTables[middleId] = middleIdAddress IdAddressTables[largestId] = largestIdAdress 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) if id then local addressline = GetIdAddressLine(id) if addressline then local address = memoryReadIntPtr( getProc(), addressline + 0x10, 0x8) if address == 0 then -- Item data not substanciated yet. Do "GetCraftRequestItem", then the address will exist. RoMScript("GetCraftRequestItem("..id..", -1)") address = memoryReadIntPtr( getProc(), addressline + 0x10, 0x8) end return address else printf("Id %d not found\n", id) end else printf("Id is nil\n") end end -- Returns the name for a given id function GetIdName(itemId) if itemId ~= nil and itemId > 0 then local itemAddress = GetItemAddress(itemId) if itemAddress ~= nil and itemAddress > 0 then name = memoryReadStringPtr(getProc(), itemAddress + addresses.nameOffset, 0) if name == nil then -- Item data not totally substanciated yet. Do "GetCraftRequestItem", then the address will exist. RoMScript("GetCraftRequestItem("..itemId..", -1)") name = memoryReadStringPtr(getProc(), itemAddress + addresses.nameOffset, 0) end return name end end end