I edited the script from dl748 and added Skill Exp and Skill Level for each character.
Code: Select all
{$lua}
local function hex(a, c)
if a == nil then
return "(nil)"
end
local fmt = "%X"
if type(c) == "number" then
fmt = "%0"..c.."X"
end
return string.format(fmt, a)
end
local function pointerSize()
if targetIs64Bit() then
return 8
end
return 4
end
local function readSignedInteger(a)
local v = readInteger(a)
if v ~= nil then
if v > 0x7FFFFFFF then
v = -(0x100000000 - v)
end
end
return v
end
local function findRecord(parent, desc)
if parent == nil and memrec ~= nil then
parent = memrec
end
local found
if parent ~= nil and parent.Count > 0 then
local i
for i = 0, parent.Count-1 do
if parent.Child[i].Description == desc then
found = parent.Child[i]
end
end
end
return found
end
local function updateRecord(parent, desc, type, addr, offsets)
if parent == nil and memrec ~= nil then
parent = memrec
end
local rec = findRecord(parent,desc)
if rec == nil then
rec = getAddressList().createMemoryRecord()
rec.Description = desc
rec.VarType = type
if addr ~= nil then
rec.setAddress(addr, offsets)
end
if parent ~= nil then
rec.appendToEntry(parent)
end
else
local a = rec.Address
if addr ~= a then
rec.setAddress(addr, offsets)
end
end
return rec
end
local cached = {}
local function updatePath(path, desc, vartype, addr, offsets, opts)
if memrec == nil then
return nil
end
if type(opts) ~= "table" then
opts = {}
end
if type(opts["noupdate"]) ~= "boolean" then
opts["noupdate"] = false
end
if type(opts["onCreate"]) ~= "function" then
opts["onCreate"] = nil
end
if type(opts["onUpdate"]) ~= "function" then
opts["onUpdate"] = nil
end
local fullpath = ""
if path ~= nil and path ~= "" then
fullpath = path.."\\"..desc
else
fullpath = desc
end
local rec
if cached[fullpath] == nil or cached[fullpath].Parent == nil then
local i
local arr = {}
local parent
for i in string.gmatch(path, "[^\\]+") do
table.insert(arr, i)
end
if #arr > 0 then
local item = table.remove(arr)
parent = updatePath(table.concat(arr, '\\'), item, "vtCustom", 0, {}, { noupdate = true })
else
parent = memrec
end
rec = getAddressList().createMemoryRecord()
rec.Description = desc
rec.VarType = vartype
rec.setAddress(addr, offsets)
rec.appendToEntry(parent)
if vartype == "vtCustom" then
rec.IsGroupHeader = true
end
cached[fullpath] = rec
if opts["onCreate"] then
opts["onCreate"](rec)
end
else
rec = cached[fullpath]
if opts["noupdate"] == false then
local a = rec.Address
if addr ~= a then
rec.setAddress(addr, offsets)
end
if opts["onUpdate"] then
opts["onUpdate"](rec)
end
end
end
return cached[fullpath]
end
local function removePath(path)
if cached[path] ~= nil then
local spath = path.."\\"
local k,v
for k,v in pairs(cached) do
if k:sub(1,spath:len()) == spath then
cached[k] = nil
end
end
if cached[path].getAddress() ~= "" then
cached[path]:Delete()
end
cached[path] = nil
end
end
local function cleanupPath(path, list)
local pathlist = {}
local i,v
for i,v in pairs(list) do
table.insert(pathlist, path.."\\"..i)
end
for i,v in pairs(cached) do
if string.sub(i,1,string.len(path)+1) == path.."\\" then
local r,z
local found = false
for r,z in ipairs(pathlist) do
if i == z or string.sub(i,1,string.len(z)+1) == z.."\\" then
found = true
break
end
end
if not found then
removePath(i)
end
end
end
end
local function getHeader(parent, desc)
if parent == nil and memrec ~= nil then
parent = memrec
end
local rec = findRecord(parent,desc)
if rec == nil then
rec = getAddressList().createMemoryRecord()
rec.Description = desc
rec.IsGroupHeader = true
if parent ~= nil then
rec.appendToEntry(parent)
end
end
return rec
end
local function getFlag(desc)
local result = false
if memrec ~= nil then
local rec = findRecord(memrec, desc)
if rec == nil then
rec = getAddressList().createMemoryRecord()
rec.Description = desc
rec.IsGroupHeader = true
rec.appendToEntry(memrec)
end
result = rec.Active
end
return result
end
local function getCodeOffset(addr, off)
if addr == nil or addr == 0 then
return nil
end
local o = readSignedInteger(addr + off)
if o ~= nil then
return addr + o + off + 4
end
return nil
end
local function followAddress(addr, offs, opts)
if type(opts) ~= "table" then
opts = {}
end
if type(opts["debug"]) ~= "boolean" then
opts["debug"] = false
end
local i
for i = 1,#offs do
if addr ~= nil then
local ot = type(offs[i])
if ot == "table" then
if type(offs[i]["offset"]) ~= "number" then
return nil
end
if offs[i]["rc"] == true then
addr = getCodeOffset(addr, offs[i]["offset"])
elseif offs[i]["r32"] == true then
addr = readInteger(addr + offs[i]["offset"])
else
addr = readPointer(addr + offs[i]["offset"])
end
elseif ot == "number" then
addr = readPointer(addr + offs[i])
else
return nil
end
if opts["debug"] then
print(" "..hex(addr))
end
end
end
if type(opts["endingoffset"]) == "number" then
addr = addr + opts["endingoffset"]
end
return addr
end
if timers == nil then
timers = {}
end
if aobscans == nil then
aobscans = {}
end
local function getTimer()
if memrec ~= nil then
local id = memrec.id
if timers[id] == nil then
timers[id] = createTimer()
timers[id].Enabled = false
timers[id].Interval = getFreezeTimer().Interval
end
return timers[id]
end
return nil
end
local function killTimer()
if memrec ~= nil then
local id = memrec.id
if timers[id] ~= nil then
timers[id]:Destroy()
timers[id] = nil
end
end
end
local function setScan(name, opts)
if memrec == nil then
return false
end
if aobscans[memrec.id] ~= nil then
aobscans[memrec.id][name] = nil
end
if opts["bytes"] == nil then
return false
end
local perm = opts["perm"]
if perm == nil then
perm = "-C-W+X" -- Not CopyOnWrite, Not Writable, but executable by default
end
local startaddress = 0
local endaddress = 0x7FFFFFFFFFFFFFFF
if opts["module"] ~= nil then
startaddress = getAddress(opts["module"])
endaddress = startaddress + getModuleSize(opts["module"])
end
local bytes = opts["bytes"]
local ms = createMemScan()
local success = false
if aobscans[memrec.id] == nil then
aobscans[memrec.id] = {}
end
if ms ~= nil then
ms.firstScan(soExactValue, vtByteArray, 0, bytes, "", startaddress, endaddress, perm, fsmNotAligned, "1", true, false, false, false)
ms.waitTillDone()
local fl = createFoundList(ms)
if fl ~= nil then
fl.initialize()
if fl.Count > 0 then
aobscans[memrec.id][name] = {}
local i
for i=0,fl.Count-1 do
table.insert(aobscans[memrec.id][name], tonumber("0x"..fl.Address[i]))
end
end
fl:Destroy()
end
ms:Destroy()
if success then
return true
end
end
return false
end
local function setScans(list, perm)
local k,v
for k,v in pairs(list) do
setScan(k, v, perm)
end
end
local function getScan(name)
if memrec ~= nil then
local id = memrec.id
if aobscans[id] ~= nil then
if aobscans[id][name] ~= nil then
return aobscans[id][name]
end
end
end
return nil
end
local function forEach(startaddress, toaddress, itemsize, func)
if startaddress < toaddress then
local addr = startaddress
while addr < toaddress do
local r = func(addr)
if r == false then
break
end
addr = addr + itemsize
end
end
end
if syntaxcheck then
return
end
[ENABLE]
-- For Debugging
--local le = getLuaEngine()
--le.mOutput.Lines:Clear()
--le.cbShowOnPrint.Checked = True
--le:Show()
-- AOBScans here
local exename = "ffxv_s.exe"
local ov = errorOnLookupFailure(false)
local id = getAddress("ffxv_u.exe")
if id ~= nil and id ~= 0 then
exename = "ffxv_u.exe"
end
errorOnLookupFailure(ov)
setScans({
main = {
bytes = "48 8B 0D ?? ?? ?? ?? 48 8B 49 10 48 81 C1 10 07 20 00 BA",
modules = exename
},
player = {
bytes = "48 8B 1D ?? ?? ?? ?? BA 33 02 00 00",
modules = exename
},
time = {
bytes = "48 8B 0D ?? ?? ?? ?? BA 38 00 00 00 E8 ?? ?? ?? ?? 48 C7",
perm = "+X+W+C",
modules = exename
},
regalia = {
bytes = "48 8B 1D ?? ?? ?? ?? BA 33 02 00 00",
modules = exename
},
hunt = {
bytes = "48 8B 35 ?? ?? ?? ?? 48 85 F6 0F 85 ?? ?? ?? ?? BA 83",
modules = exename
}
})
local function searchFor(addr, key)
local result = nil
while addr ~= nil do
local id = readInteger(addr + 0x20)
local i = readBytes(addr + 0x19, 1)
if i ~= 0 then
break
end
if id == key then
result = followAddress(addr, { 0x28 })
break
elseif id > key then
addr = followAddress(addr, { 0x0 })
else
addr = followAddress(addr, { 0x10 })
end
end
return result
end
local function Run()
local mainscan = getScan("main")
if mainscan ~= nil then
local mainaddr = followAddress(mainscan[1], { { offset=0x3, rc=true }, 0x0, 0x10 })
if mainaddr ~= nil then
updatePath("", "Gil", "vtDword", hex(mainaddr + 0x00200710 + 0x5650), {})
updatePath("", "AP", "vtDword", hex(mainaddr + 0x00200710 + 0x565C), {})
updatePath("", "Armiger", "vtSingle", hex(mainaddr + 0x00200710 + 0x57B4), {})
updatePath("", "Max Armiger", "vtSingle", hex(mainaddr + 0x00200710 + 0x57B8), {})
updatePath("Elemancy", "Fire", "vtSingle", hex(mainaddr + 0x00200710 + 9*4 + 0x5770), {})
updatePath("Elemancy", "Ice", "vtSingle", hex(mainaddr + 0x00200710 + 10*4 + 0x5770), {})
updatePath("Elemancy", "Lightning", "vtSingle", hex(mainaddr + 0x00200710 + 11*4 + 0x5770), {})
if freezeel then
writeFloat(mainaddr + 0x00200710 + 9*4 + 0x5770, 98.0)
writeFloat(mainaddr + 0x00200710 + 10*4 + 0x5770, 98.0)
writeFloat(mainaddr + 0x00200710 + 11*4 + 0x5770, 98.0)
end
if freezear then
local max = readInteger(mainaddr + 0x00200710 + 0x57B8)
if max ~= nil and max>0 then
writeInteger(mainaddr + 0x00200710 + 0x57B4, max)
end
end
local i
for i=0,11 do
local addr = mainaddr + 0x30 + 0xD7C0*i
local name = readString(addr + 0x10, 0x20)
if name ~= nil and name ~= "" then
updatePath(name, "Level", "vtDword", hex(addr + 0x12C), {})
updatePath(name, "EXP To Add", "vtDword", hex(addr + 0x698), {})
updatePath(name, "EXP", "vtDword", hex(addr + 0x69C), {})
if i <= 3 then
updatePath(name, "Skill EXP", "vtDword", hex(addr + 0xD7C0 - 0x50), {})
updatePath(name, "Skill Level", "vtDword", hex(addr + 0xD7C0 - 0x4C), {})
end
end
end
end
end
local huntscan = getScan("hunt")
if huntscan ~= nil then
local huntaddr = followAddress(huntscan[1], { { offset=0x3, rc=true}, 0x0, 0x400 })
if huntaddr ~= nil then
updatePath("Hunt", "Level", "vtDword", hex(huntaddr + 0x11C), {})
updatePath("Hunt", "Stars", "vtDword", hex(huntaddr + 0x124), {})
end
end
collectgarbage()
collectgarbage()
end
if memrec ~= nil then
local t = getTimer()
t.OnTimer = Run
Run()
t.Enabled = true -- Enable timer ONLY after first run in case of error
end
[DISABLE]
if memrec ~= nil then
killTimer()
while memrec.Count > 0 do
memrec.Child[0]:Delete()
end
end
cached = {}
collectgarbage()
collectgarbage()
You can find it in "Character Editor/Read Characters Stats" in the new table (it's hard to find names for stuff as im not english
I also added the inventory reader in "Item Editor", the Stance thing in Combat, and other stuff i don't remember.
Edit : I don't have enough time to do all the stuff i want to do/add in the table, life suxx
Edit 2 : Crap, i forgot to add the "model switcher" from the other topic (which allow to change the face of characters and such)
Edit 3 : V6 contains the "model swapper" from OleMagne (use "old noctis" face instead of young and stuff like that) in "Others/Change character models" Read this post to know how it works