Fixed loops in linked lists, split xml_types into windows (and in the future linux) versions. Works, but not tested. Also updated offset for migrants.

develop
Warmist 2012-03-13 21:40:25 +02:00
parent 081aee1363
commit 04a43501ac
6 changed files with 243 additions and 156 deletions

@ -49,11 +49,11 @@ dofile("dfusion/xml_struct.lua")
unlockDF()
plugins={}
table.insert(plugins,{"simple_embark","A simple embark dwarf count editor"})
table.insert(plugins,{"embark","Multi race embark"})
table.insert(plugins,{"items","A collection of item hacking tools"})
table.insert(plugins,{"offsets","Find all offsets"})
table.insert(plugins,{"friendship","Multi race fort enabler"})
table.insert(plugins,{"friendship_civ","Multi civ fort enabler"})
table.insert(plugins,{"embark","Multi race embark"})
table.insert(plugins,{"adv_tools","some tools for (mainly) advneturer hacking"})
table.insert(plugins,{"tools","some misc tools"})
table.insert(plugins,{"triggers","a function calling plug (discontinued...)"})

@ -8,9 +8,9 @@ Legends : 0x12c451c
Materials : 0x1307f50
PlayerLegend : 0x145bfec
SiteData : 0x1307778
StartDwarfs : 0x518332
WordVec : 0x1308254
WorldData : 0x1306148
Xpointer : 0x7347f0
vtableLegends : 0x6e7594
Buildings : 0x12C4DA8
Buildings : 0x12C4DA8
StartDwarfs : 0x5A5170

@ -1 +1 @@
function findVectorsSized(size) local ret={} local text=GetTextRegion() for k,v in pairs(offsets.getvectors()) do if GetRegionIn2(k)~=nil then --if v>4 then local tv=engine.peek(k,ptr_vector) if tv:size() == size then print(string.format("%x is size %d",k,size)) table.insert(ret,k) end end end return ret end function findMaterial(mattype,matname) --currently only stones local tbl=BuildMaterialTable() return tbl[matname] end
function findVectorsSized(size) local ret={} local text=GetTextRegion() for k,v in pairs(offsets.getvectors()) do if GetRegionIn2(k)~=nil then --if v>4 then local tv=engine.peek(k,ptr_vector) if tv:size() == size then print(string.format("%x is size %d",k,size)) table.insert(ret,k) end end end return ret end function findMaterial(mattype,matname) --currently only stones local tbl=BuildMaterialTable() return tbl[matname] end function iter(tbl) if getmetatable(tbl) ~=nil then if getmetatable(tbl).__next~= nil then return getmetatable(tbl).__next,tbl else return getmetatable(tbl).__pairs(tbl) or pairs(tbl) end else return pairs(tbl) end end

@ -34,6 +34,9 @@ function parseTree(t)
--end
types[name]=makeType(v)
--print("found "..name.." or type:"..v.xarg.meta or v.xarg.base)
else
types[name]=makeType(v,types[name])
end
end
end
@ -63,6 +66,8 @@ function parseTreeGlobals(t)
return glob
end
function findAndParse(tname)
--if types[tname]==nil then types[tname]={} end
-- [=[
for k,v in ipairs(main_tree) do
local name=v.xarg["type-name"];
if v.xarg~=nil and v.xarg["type-name"]~=nil and v.label=="ld:global-type" then
@ -72,11 +77,12 @@ function findAndParse(tname)
--for kk,vv in pairs(v.xarg) do
-- print("\t"..kk.." "..tostring(vv))
--end
types[name]=makeType(v)
types[name]=makeType(v,types[name])
end
--print("found "..name.." or type:"..v.xarg.meta or v.xarg.base)
end
end
--]=]
end
df={}
df.types=rawget(df,"types") or {} --temporary measure for debug
@ -149,6 +155,6 @@ function printFields(object)
error("Not an class_type or a class_object")
end
for k,v in pairs(tbl.types) do
print(k)
print(string.format("%s %x",k,v[2]))
end
end

@ -20,21 +20,33 @@ function first_of_type(node,labelname)
end
end
end
function padAddress(curoff,sizetoadd) --return new offset to place things
xtypes={} -- list of all types prototypes (e.g. enum-type -> announcement_type)
-- type must have size, new and makewrap (that makes a wrapper around ptr)
if WINDOWS then
dofile("dfusion/xml_types_windows.lua")
elseif LINUX then
dofile("dfusion/xml_types_linux.lua")
end
function padAddress(curoff,sizetoadd) --return new offset to place things... Maybe linux is different?
--windows -> sizeof(x)==alignof(x)
--[=[
if sizetoadd>8 then sizetoadd=8 end
if(math.mod(curoff,sizetoadd)==0) then
return curoff
else
return curoff+(sizetoadd-math.mod(curoff,sizetoadd))
end
--]=]
return curoff
end
xtypes={} -- list of all types prototypes (e.g. enum-type -> announcement_type)
-- type must have new and makewrap (that makes a wrapper around ptr)
local sarr={}
sarr.__index=sarr
function sarr.new(node)
local o={}
function sarr.new(node,obj)
local o=obj or {}
setmetatable(o,sarr)
--print("Making array.")
o.count=tonumber(node.xarg.count)
@ -89,9 +101,9 @@ simpletypes.int16_t={WORD,2}
simpletypes.int8_t={BYTE,1}
simpletypes.bool={BYTE,1}
simpletypes["stl-string"]={STD_STRING,24}
function getSimpleType(typename)
function getSimpleType(typename,obj)
if simpletypes[typename] == nil then return end
local o={}
local o=obj or {}
o.ctype=simpletypes[typename][1]
o.size=simpletypes[typename][2]
o.issimple=true
@ -99,8 +111,8 @@ function getSimpleType(typename)
end
local type_enum={}
type_enum.__index=type_enum
function type_enum.new(node)
local o={}
function type_enum.new(node,obj)
local o=obj or {}
setmetatable(o,type_enum)
for k,v in pairs(node) do
if type(v)=="table" and v.xarg~=nil then
@ -118,11 +130,12 @@ xtypes["enum-type"]=type_enum
local type_bitfield={} --bitfield can be accessed by number (bf[1]=true) or by name bf.DO_MEGA=true
type_bitfield.__index=type_bitfield
function type_bitfield.new(node)
local o={}
function type_bitfield.new(node,obj)
local o=obj or {}
setmetatable(o,type_bitfield)
o.size=0
o.fields={}
o.fields_named={}
o.fields_numed={}
for k,v in pairs(node) do
if type(v)=="table" and v.xarg~=nil then
@ -131,8 +144,8 @@ function type_bitfield.new(node)
name="anon_"..tostring(k)
end
--print("\t"..k.." "..name)
o.fields[k]=name
o.fields[name]=k
o.fields_numed[k]=name
o.fields_named[name]=k
o.size=o.size+1
end
end
@ -163,18 +176,27 @@ function type_bitfield:makewrap(address)
setmetatable(o,self.wrap)
return o
end
function type_bitfield.wrap.__next(tbl,key)
local kk,vv=next(rawget(tbl,"mtype").fields_named,key)
if kk ~= nil then
return kk,tbl[kk]
else
return nil
end
end
function type_bitfield.wrap:__index(key)
local myptr=rawget(self,"ptr")
local mytype=rawget(self,"mtype")
local num=tonumber(key)
if num~=nil then
if mytype.fields[num]~=nil then
if mytype.fields_numed[num]~=nil then
return mytype:bitread(myptr,num-1)
else
error("No bit with index:"..tostring(num))
end
elseif mytype.fields[key]~= nil then
return mytype:bitread(myptr,mytype.fields[key]-1)
elseif mytype.fields_named[key]~= nil then
return mytype:bitread(myptr,mytype.fields_named[key]-1)
else
error("No such field exists")
end
@ -184,13 +206,13 @@ function type_bitfield.wrap:__newindex(key,value)
local mytype=rawget(self,"mtype")
local num=tonumber(key)
if num~=nil then
if mytype.fields[num]~=nil then
if mytype.fields_numed[num]~=nil then
return mytype:bitwrite(myptr,num-1,value)
else
error("No bit with index:"..tostring(num))
end
elseif mytype.fields[key]~= nil then
return mytype:bitwrite(myptr,mytype.fields[key]-1,value)
elseif mytype.fields_named[key]~= nil then
return mytype:bitwrite(myptr,mytype.fields_named[key]-1,value)
else
error("No such field exists")
end
@ -200,8 +222,8 @@ xtypes["bitfield-type"]=type_bitfield
local type_class={}
type_class.__index=type_class
function type_class.new(node)
local o={}
function type_class.new(node,obj)
local o=obj or {}
setmetatable(o,type_class)
o.types={}
o.base={}
@ -224,11 +246,12 @@ function type_class.new(node)
--print("\t"..k.." "..name.."->"..v.xarg.meta.." ttype:"..v.label)
local ttype=makeType(v)
if ttype.size==0 then error("Field with 0 size! type="..node.xarg["type-name"].."."..name) end
--for k,v in pairs(ttype) do
-- print(k..tostring(v))
--end
local off=padAddress(o.size,ttype.size)
--print("var:"..name.." ->"..tostring(off).. " :"..ttype.size)
o.size=off
o.types[name]={ttype,o.size}
o.size=o.size+ttype.size
@ -267,26 +290,31 @@ xtypes["struct-type"]=type_class
xtypes["class-type"]=type_class
local type_pointer={}
type_pointer.__index=type_pointer
function type_pointer.new(node)
local o={}
function type_pointer.new(node,obj)
local o=obj or {}
setmetatable(o,type_pointer)
o.ptype=makeType(first_of_type(node,"ld:item"))
local subnode=first_of_type(node,"ld:item")
if subnode~=nil then
o.ptype=makeType(subnode,nil,true)
end
o.size=4
return o
end
type_pointer.wrap={}
type_pointer.wrap.__index=type_pointer.wrap
function type_pointer.wrap:tonumber()
local myptr=rawget(self,"ptr")
return type_read(myptr,DWORD)
return engine.peekd(myptr)--type_read(DWORD,myptr)
end
function type_pointer.wrap:fromnumber(num)
local myptr=rawget(self,"ptr")
return type_write(myptr,DWORD,num)
return engine.poked(myptr,num)--type_write(DWORD,myptr,num)
end
function type_pointer.wrap:deref()
local myptr=rawget(self,"ptr")
local mytype=rawget(self,"ptype")
return type_read(myptr,mytype)
local mytype=rawget(self,"mtype")
return type_read(mytype.ptype,engine.peekd(myptr))
end
function type_pointer:makewrap(ptr)
local o={}
@ -295,15 +323,15 @@ function type_pointer:makewrap(ptr)
setmetatable(o,self.wrap)
return o
end
xtypes["pointer"]=type_class
xtypes["pointer"]=type_pointer
--------------------------------------------
--stl-vector (beginptr,endptr,allocptr)
--df-flagarray (ptr,size)
xtypes.containers={}
xtypes.containers=xtypes.containers or {}
local dfarr={}
dfarr.__index=dfarr
function dfarr.new(node)
local o={}
function dfarr.new(node,obj)
local o=obj or {}
setmetatable(o,dfarr)
o.size=8
return o
@ -340,8 +368,8 @@ end
xtypes.containers["df-array"]=dfarr
local farr={}
farr.__index=farr
function farr.new(node)
local o={}
function farr.new(node,obj)
local o=obj or {}
setmetatable(o,farr)
o.size=8
return o
@ -381,139 +409,60 @@ end
xtypes.containers["df-flagarray"]=farr
local stl_vec={}
stl_vec.__index=stl_vec
function stl_vec.new(node)
local o={}
o.size=16
local titem=first_of_type(node,"ld:item")
if titem~=nil then
o.item_type=makeType(titem)
else
o.item_type=getSimpleType("uint32_t")
end
setmetatable(o,stl_vec)
return o
end
function stl_vec:makewrap(address)
local o={}
o.mtype=self
o.ptr=address
setmetatable(o,self.wrap)
return o
end
stl_vec.wrap={}
function stl_vec.wrap:__index(key)
local num=tonumber(key)
local mtype=rawget(self,"mtype")
local ptr=rawget(self,"ptr")
local p_begin=engine.peek(ptr,DWORD)
local p_end=engine.peek(ptr+4,DWORD)
if key=="size" then
return (p_end-p_begin)/mtype.item_type.size;
end
--allocend=type_read(ptr+8,DWORD)
error("TODO make __index for stl_vec")
if num~=nil and num<sizethen then
return type_read(mtype.ctype,num*mtype.ctype.size+rawget(self,"ptr"))
else
error("invalid key to df-flagarray")
end
end
function stl_vec.wrap:__newindex(key,val)
local num=tonumber(key)
error("TODO make __index for stl_vec")
if num~=nil and num<rawget(self,"mtype").count then
return type_write(mtype.ctype,num*mtype.ctype.size+rawget(self,"ptr"),val)
else
error("invalid key to static-array")
end
end
xtypes.containers["stl-vector"]=stl_vec
local stl_vec_bit={}
stl_vec_bit.__index=stl_vec_bit
function stl_vec_bit.new(node)
local o={}
setmetatable(o,stl_vec_bit)
o.size=20
return o
end
function stl_vec_bit:makewrap(address)
local o={}
o.mtype=self
o.ptr=address
setmetatable(o,self.wrap)
return o
end
stl_vec_bit.wrap={}
function stl_vec_bit.wrap:__index(key)
local num=tonumber(key)
local mtype=rawget(self,"item_type")
local ptr=rawget(self,"ptr")
local p_begin=type_read(ptr,DWORD)
local p_end=type_read(ptr+4,DWORD)
--allocend=type_read(ptr+8,DWORD)
error("TODO make __index for stl_vec_bit")
if num~=nil and num<sizethen then
return type_read(mtype.ctype,num*mtype.ctype.size+rawget(self,"ptr"))
else
error("invalid key to df-flagarray")
end
end
function stl_vec_bit.wrap:__newindex(key,val)
local num=tonumber(key)
error("TODO make __index for stl_vec_bit")
if num~=nil and num<rawget(self,"mtype").count then
return type_write(mtype.ctype,num*mtype.ctype.size+rawget(self,"ptr"),val)
else
error("invalid key to static-array")
end
end
xtypes.containers["stl-bit-vector"]=stl_vec_bit
--------------------------------------------
local bytes_pad={}
bytes_pad.__index=bytes_pad
function bytes_pad.new(node)
local o={}
function bytes_pad.new(node,obj)
local o=obj or {}
setmetatable(o,bytes_pad)
o.size=tonumber(node.xarg.size)
return o
end
xtypes["bytes"]=bytes_pad
--------------------------------------------
function getGlobal(name)
function getGlobal(name,canDelay)
if types[name]== nil then
findAndParse(name)
if types[name]== nil then
error("type:"..name.." failed find-and-parse")
end
--error("type:"..node.xarg["type-name"].." should already be ready")
if canDelay then
types[name]={}
return types[name]
end
findAndParse(name)
if types[name]== nil then
error("type:"..name.." failed find-and-parse")
end
return types[name]
--error("type:"..node.xarg["type-name"].." should already be ready")
end
if types[name].size==nil and canDelay==nil then --was delayed, now need real type
findAndParse(name)
if types[name]== nil then
error("type:"..name.." failed find-and-parse")
end
end
return types[name]
end
parser={}
parser["ld:global-type"]=function (node)
return xtypes[node.xarg.meta].new(node)
parser["ld:global-type"]=function (node,obj)
return xtypes[node.xarg.meta].new(node,obj)
end
parser["ld:global-object"]=function (node)
end
parser["ld:field"]=function (node)
parser["ld:field"]=function (node,obj,canDelay)
local meta=node.xarg.meta
if meta=="number" or (meta=="primitive" and node.xarg.subtype=="stl-string") then
return getSimpleType(node.xarg.subtype)
return getSimpleType(node.xarg.subtype,obj)
elseif meta=="static-array" then
return xtypes["static-array"].new(node)
return xtypes["static-array"].new(node,obj)
elseif meta=="global" then
return getGlobal(node.xarg["type-name"])
return getGlobal(node.xarg["type-name"],canDelay)
elseif meta=="compound" then
if node.xarg.subtype==nil then
return xtypes["struct-type"].new(node)
return xtypes["struct-type"].new(node,obj)
else
return xtypes[node.xarg.subtype.."-type"].new(node)
return xtypes[node.xarg.subtype.."-type"].new(node,obj)
end
elseif meta=="container" then
local subtype=node.xarg.subtype
@ -521,22 +470,22 @@ parser["ld:field"]=function (node)
if xtypes.containers[subtype]==nil then
error(subtype.." not implemented... (container)")
else
return xtypes.containers[subtype].new(node)
return xtypes.containers[subtype].new(node,obj)
end
elseif meta=="pointer" then
return xtypes["pointer"].new(node)
return xtypes["pointer"].new(node,obj)
elseif meta=="bytes" then
return xtypes["bytes"].new(node)
return xtypes["bytes"].new(node,obj)
else
error("Unknown meta:"..meta)
end
end
parser["ld:item"]=parser["ld:field"]
function makeType(node,overwrite)
local label=overwrite or node.label
function makeType(node,obj,canDelay)
local label=node.label
if parser[label] ~=nil then
--print("Make Type with:"..label)
local ret=parser[label](node)
local ret=parser[label](node,obj,canDelay)
if ret==nil then
error("Error parsing:"..label.." nil returned!")
else
@ -554,7 +503,7 @@ function makeType(node,overwrite)
end
print("Trying to make:"..node.xarg.meta)
if xtypes[node.xarg.meta]~=nil then
return xtypes[node.xarg.meta].new(node)
return xtypes[node.xarg.meta].new(node,obj)
end
if node.xarg.meta=="global" then

@ -0,0 +1,132 @@
xtypes.containers=xtypes.containers or {}
local stl_vec={}
--[=[
(make-instance 'pointer :name $start)
(make-instance 'pointer :name $end)
(make-instance 'pointer :name $block-end)
(make-instance 'padding :name $pad :size 4 :alignment 4)
--]=]
stl_vec.__index=stl_vec
function stl_vec.new(node,obj)
local o=obj or {}
o.size=16
local titem=first_of_type(node,"ld:item")
if titem~=nil then
o.item_type=makeType(titem)
else
o.item_type=getSimpleType("uint32_t")
end
setmetatable(o,stl_vec)
return o
end
function stl_vec:makewrap(address)
local o=obj or {}
o.mtype=self
o.ptr=address
setmetatable(o,self.wrap)
return o
end
stl_vec.wrap={}
function stl_vec.wrap:__index(key)
local num=tonumber(key)
local mtype=rawget(self,"mtype")
local ptr=rawget(self,"ptr")
local p_begin=engine.peek(ptr,DWORD)
local p_end=engine.peek(ptr+4,DWORD)
local size=(p_end-p_begin)/mtype.item_type.size
if key=="size" then
return size
end
--allocend=type_read(ptr+8,DWORD)
if num~=nil and num<size then
return type_read(mtype.item_type,num*mtype.item_type.size+p_begin)
else
error("invalid key to df-flagarray")
end
end
function stl_vec.wrap:__newindex(key,val)
local num=tonumber(key)
error("TODO make __index for stl_vec")
if num~=nil and num<rawget(self,"mtype").count then
return type_write(mtype.item_type,num*mtype.item_type.size+rawget(self,"ptr"),val)
else
error("invalid key to static-array")
end
end
xtypes.containers["stl-vector"]=stl_vec
local stl_vec_bit={}
--[=[
(make-instance 'pointer :name $start)
(make-instance 'pointer :name $end)
(make-instance 'pointer :name $block-end)
(make-instance 'padding :name $pad :size 4)
(make-instance 'int32_t :name $size)
--]=]
stl_vec_bit.__index=stl_vec_bit
function stl_vec_bit.new(node,obj)
local o=obj or {}
setmetatable(o,stl_vec_bit)
o.size=20
return o
end
function stl_vec_bit:makewrap(address)
local o=obj or {}
o.mtype=self
o.ptr=address
setmetatable(o,self.wrap)
return o
end
stl_vec_bit.wrap={}
function stl_vec_bit.wrap:__index(key)
local num=tonumber(key)
local mtype=rawget(self,"item_type")
local ptr=rawget(self,"ptr")
local p_begin=type_read(ptr,DWORD)
local p_end=type_read(ptr+4,DWORD)
--allocend=type_read(ptr+8,DWORD)
error("TODO make __index for stl_vec_bit")
if num~=nil and num<sizethen then
return type_read(mtype.ctype,num*mtype.ctype.size+rawget(self,"ptr"))
else
error("invalid key to df-flagarray")
end
end
function stl_vec_bit.wrap:__newindex(key,val)
local num=tonumber(key)
error("TODO make __index for stl_vec_bit")
if num~=nil and num<rawget(self,"mtype").count then
return type_write(mtype.ctype,num*mtype.ctype.size+rawget(self,"ptr"),val)
else
error("invalid key to static-array")
end
end
xtypes.containers["stl-bit-vector"]=stl_vec_bit
local stl_deque={}
--[=[
(make-instance 'pointer :name $proxy)
(make-instance 'pointer :name $map)
(make-instance 'int32_t :name $map-size)
(make-instance 'int32_t :name $off)
(make-instance 'int32_t :name $size)
(make-instance 'padding :size 4 :alignment 4)
--]=]
stl_deque.__index=stl_deque
function stl_deque.new(node,obj)
local o=obj or {}
setmetatable(o,stl_deque)
o.size=24
return o
end
xtypes.containers["stl-deque"]=stl_deque
local dfllist={}
function dfllist.new(node,obj)
local realtype=makeType(first_of_type(node,"ld:item"))
return realtype --.new(node,obj)
end
xtypes.containers["df-linked-list"]=dfllist