include("addresses.lua"); include("functions.lua"); -- Note: We get 'char' and 'macro' data from functions.lua -- because it is used in other scripts. --[[ Required: pattern The pattern, obviously. mask ...The mask? offset Offset from the start of the pattern that the requested data exists. startloc Where to start the search, in bytes Optional: searchlen The length, in bytes, to continue searching (default: 0xA0000) adjustment How many bytes to adjust the returned value forward or backward (default: 0) size The length, in bytes, of the data (default: 4) comment A string of text that will be appended in the output ]] local updatePatterns = { swimAddress = { pattern = string.char( 0x89, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x4B, 0x8B, 0x7B, 0xFF, 0x83, 0xBF), mask = "xx????xxxx?XX", offset = 0, startloc = 0x440000, }, } -- This function will attempt to automatically find the true addresses -- from RoM, even if they have moved. -- Only works on MicroMacro v1.0 or newer. function findOffsets() for name,values in pairs(updatePatterns) do local found = 0; local readFunc = nil; local pattern = values["pattern"]; local mask = values["mask"]; local offset = values["offset"]; local startloc = values["startloc"]; local searchlen = values["searchlen"] or 0xA0000; local adjustment = values["adjustment"] or 0; local size = values["size"] or 4; local comment = values["comment"] or ""; found = findPatternInProcess(getProc(), pattern, mask, startloc, searchlen); if( found == 0 ) then error("Unable to find \'" .. name .. "\' in module.", 0); end if( size == 1 ) then readFunc = memoryReadUByte; elseif( size == 2 ) then readFunc = memoryReadUShort; elseif( size == 4 ) then readFunc = memoryReadUInt else -- default, assume 4 bytes readFunc = memoryReadUInt; end addresses[name] = readFunc(getProc(), found + offset) + adjustment; local msg = sprintf("Patched addresses.%s\t (value: 0x%X, at: 0x%X)", name, addresses[name], found + offset); printf(msg .. "\n"); logMessage(msg); -- Special cases; record found locations if( name == "staticbase_char" ) then addresses.staticpattern_char = found; elseif( name == "staticbase_macro" ) then addresses.staticpattern_macro = found; elseif( name == "functionTargetPatchAddr" ) then addresses.functionTargetPatchAddr = found; elseif( name == "functionMousePatchAddr" ) then addresses.functionMousePatchAddr = found; elseif( name == "swimAddress" ) then addresses.swimAddress = found; elseif( name == "charClassInfoBase" ) then addresses.charClassInfoBase = memoryReadUInt(getProc(),addresses.charClassInfoBase) end end -- Assumption-based updating. -- Not very accurate, but is quick-and-easy for those -- hard to track values. printf("\n\n"); local function assumptionUpdate(name, newValue) local assumptionUpdateMsg = "Assuming information for \'addresses.%s\'; now 0x%X, was 0x%X\n"; printf(assumptionUpdateMsg, name, newValue, (addresses[name] or 0)); addresses[name] = newValue; end printf("\n"); local function readBytesUpdate(name, address, number) local readBytesUpdateMsg = "Read bytes for %s at: 0x%X Bytes:%s\n" local bytesString = "" local tmp = {} for i = 0, number-1 do local tmpbyte = memoryReadUByte(getProc(),address + i) table.insert(tmp, tmpbyte) bytesString = bytesString ..string.format(" %02X", tmpbyte) end if tmp[1] == 0x90 then error("Patch bytes = 0x90. Please restart the game before trying to run \"rom\update\" again.") end printf(readBytesUpdateMsg, name, address, bytesString) addresses[name] = tmp end readBytesUpdate("swimAddressBytes", addresses.swimAddress, 6) end function rewriteAddresses() local filename = getExecutionPath() .. "/addresses.lua"; getProc(); -- Just to make sure we open the process first printf("Scanning for updated addresses...\n"); findOffsets(); printf("Finished.\n"); local addresses_new = {}; for i,v in pairs(addresses) do table.insert(addresses_new, {index = i, value = v}); end -- Sort alphabetically by index local function addressSort(tab1, tab2) if( tab1.index < tab2.index ) then return true; end return false; end table.sort(addresses_new, addressSort); local file = io.open(filename, "w"); file:write( sprintf("-- Auto-generated by update.lua\n") .. "addresses = {\n" ); for i,v in pairs(addresses_new) do local comment = ""; if( updatePatterns[v.index] ) then local tmp = updatePatterns[v.index].comment; if( tmp ) then comment = "\t--[[ " .. tmp .. " ]]"; end end -- Index part file:write( sprintf("\t%s = ", v.index)) -- Value part if type(v.value) == "table" then -- if it's a table of bytes file:write( sprintf("{")) for i = 1, #v.value do if i ~= 1 then file:write( sprintf(", ")) end file:write( sprintf("0x%02X", v.value[i])) end file:write( sprintf("},")) else -- if it's an address or offset file:write( sprintf("0x%X,", v.value)) end -- Comment part file:write( sprintf("%s\n", comment) ); end file:write("}\n"); file:close(); end rewriteAddresses();