From e8788d88722f1b42e2141bfae2abbf62c91c2ab9 Mon Sep 17 00:00:00 2001 From: Warmist Date: Sun, 4 Mar 2012 14:45:15 +0200 Subject: [PATCH] Lots of work done with xml parsing. --- plugins/Dfusion/dfusion.cpp | 2 + plugins/Dfusion/luafiles/common.lua | 22 ++++- plugins/Dfusion/luafiles/init.lua | 4 +- plugins/Dfusion/luafiles/patterns.lua | 4 +- plugins/Dfusion/luafiles/xml_struct.lua | 83 +++++++++++++---- plugins/Dfusion/luafiles/xml_types.lua | 117 +++++++++++++++++++++--- plugins/Dfusion/src/lua_Offsets.cpp | 114 ++++++++++++++--------- 7 files changed, 269 insertions(+), 77 deletions(-) diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index 29492d801..b06a7d278 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -19,6 +19,7 @@ #include "lua_VersionInfo.h" #include "functioncall.h" #include "lua_FunctionCall.h" +#include "lua_Offsets.h" using std::vector; using std::string; @@ -48,6 +49,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector lua::RegisterMisc(st); lua::RegisterVersionInfo(st); lua::RegisterFunctionCall(st); + lua::RegisterEngine(st); #ifdef LINUX_BUILD st.push(1); diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua index 98043f463..4548acecf 100644 --- a/plugins/Dfusion/luafiles/common.lua +++ b/plugins/Dfusion/luafiles/common.lua @@ -3,6 +3,9 @@ STD_STRING=0 DWORD=1 WORD=2 BYTE=3 +QWORD=4 +DOUBLE=5 +FLOAT=6 function printd(...) if DEBUG then print(...) @@ -94,6 +97,7 @@ function SetExecute(pos) end -- engine bindings engine=engine or {} +--[=[ use default peek/pokes for now engine.peekd=Process.readDWord engine.poked=Process.writeDWord engine.peekb=Process.readByte @@ -106,7 +110,7 @@ engine.peekstr=Process.readCString --engine.pokestr=Process.readCString engine.peekarb=Process.read engine.pokearb=Process.write - +--]=] function engine.peek(offset,rtype) if type(rtype)=="table" then @@ -117,13 +121,19 @@ function engine.peek(offset,rtype) end end if rtype==STD_STRING then - return engine.peekstr(offset) + return engine.peekstr2(offset) elseif rtype==DWORD then return engine.peekd(offset) elseif rtype==WORD then return engine.peekw(offset) elseif rtype==BYTE then return engine.peekb(offset) + elseif rtype==QWORD then + return engine.peekq(offset) + elseif rtype==FLOAT then + return engine.peekfloat(offset) + elseif rtype==DOUBLE then + return engine.peekdouble(offset) else error("Invalid peek type") return @@ -138,13 +148,19 @@ function engine.poke(offset,rtype,val) end end if rtype==STD_STRING then - return engine.pokestr(offset,val) + return engine.pokestr2(offset,val) elseif rtype==DWORD then return engine.poked(offset,val) elseif rtype==WORD then return engine.pokew(offset,val) elseif rtype==BYTE then return engine.pokeb(offset,val) + elseif rtype==QWORD then + return engine.pokeq(offset,val) + elseif rtype==FLOAT then + return engine.pokefloat(offset,val) + elseif rtype==DOUBLE then + return engine.pokedouble(offset,val) else error("Invalid poke type:"..tostring(rtype)) return diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index 5adb9abe3..4e6ebc6cb 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -60,12 +60,12 @@ table.insert(plugins,{"onfunction","run lua on some df function"}) loadall(plugins) dofile_silent("dfusion/initcustom.lua") -print("Locating saves...") +--[=[print("Locating saves...") local str=engine.peekstr(0x1447A40+offsets.base()) print("Current region:"..str) str="data/save/"..str.."/dfusion/init.lua" dofile_silent(str) - +--]=] if not INIT then mainmenu(plugins) end diff --git a/plugins/Dfusion/luafiles/patterns.lua b/plugins/Dfusion/luafiles/patterns.lua index c9f0e8c37..34aa0c274 100644 --- a/plugins/Dfusion/luafiles/patterns.lua +++ b/plugins/Dfusion/luafiles/patterns.lua @@ -170,11 +170,11 @@ end ]]-- ptr_Creature={} -local posoff=VersionInfo.getGroup("Creatures"):getGroup("creature"):getOffset("position") +local posoff=0 --VersionInfo.getGroup("Creatures"):getGroup("creature"):getOffset("position") ptr_Creature.x={off=posoff,rtype=WORD} --ok ptr_Creature.y={off=posoff+2,rtype=WORD} --ok ptr_Creature.z={off=posoff+4,rtype=WORD} --ok -ptr_Creature.flags={off=VersionInfo.getGroup("Creatures"):getGroup("creature"):getOffset("flags1"),rtype=ptt_dfflag.new(10)} +ptr_Creature.flags={off=0,rtype=ptt_dfflag.new(10)} ptr_Creature.name={off=0,rtype=ptt_dfstring} ptr_Creature.ID={off=252,rtype=DWORD} --ok i guess ptr_Creature.followID={off=592,rtype=DWORD} --ok diff --git a/plugins/Dfusion/luafiles/xml_struct.lua b/plugins/Dfusion/luafiles/xml_struct.lua index e0f519b50..0a6b54138 100644 --- a/plugins/Dfusion/luafiles/xml_struct.lua +++ b/plugins/Dfusion/luafiles/xml_struct.lua @@ -24,47 +24,96 @@ types.building=sometype ]=] function parseTree(t) - - for k,v in ipairs(t) do if v.xarg~=nil and v.xarg["type-name"]~=nil and v.label=="ld:global-type" then local name=v.xarg["type-name"]; - print("Parsing:"..name) - for kk,vv in pairs(v.xarg) do - print("\t"..kk.." "..tostring(vv)) + if(types[name]==nil) then + --print("Parsing:"..name) + --for kk,vv in pairs(v.xarg) do + -- print("\t"..kk.." "..tostring(vv)) + --end + types[name]=makeType(v) + --print("found "..name.." or type:"..v.xarg.meta or v.xarg.base) end - types[name]=makeType(v) - - - print("found "..name.." or type:"..v.xarg.meta or v.xarg.base) end end end +function parseTreeGlobals(t) + local glob={} + print("Parsing global-objects") + for k,v in ipairs(t) do + if v.xarg~=nil and v.label=="ld:global-object" then + local name=v.xarg["name"]; + --print("Parsing:"..name) + local subitem=v[1] + if subitem==nil then + error("Global-object subitem is nil:"..name) + end + local ret=makeType(subitem) + if ret==nil then + error("Make global returned nil!") + end + glob[name]=ret + end + end + --print("Printing globals:") + --for k,v in pairs(glob) do + -- print(k) + --end + return glob +end function findAndParse(tname) for k,v in ipairs(main_tree) do - local name=v.xarg["type-name"]; + local name=v.xarg["type-name"]; if v.xarg~=nil and v.xarg["type-name"]~=nil and v.label=="ld:global-type" then + if(name ==tname) then - print("Parsing:"..name) - for kk,vv in pairs(v.xarg) do - print("\t"..kk.." "..tostring(vv)) - end + --print("Parsing:"..name) + --for kk,vv in pairs(v.xarg) do + -- print("\t"..kk.." "..tostring(vv)) + --end types[name]=makeType(v) 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 +local df_meta={} +function df_meta:__index(key) + local addr=VersionInfo.getAddress(key) + local vartype=rawget(df,"types")[key]; + if addr==nil then + error("No such global address exist") + elseif vartype==nil then + error("No such global type exist") + else + return type_read(vartype,addr) + end +end +function df_meta:__newindex(key,val) + local addr=VersionInfo.getAddress(key) + local vartype=rawget(df,"types")[key]; + if addr==nil then + error("No such global address exist") + elseif vartype==nil then + error("No such global type exist") + else + return type_write(vartype,addr,val) + end +end +setmetatable(df,df_meta) -------------------------------- types=types or {} dofile("dfusion/patterns/xml_angavrilov.lua") +-- [=[ main_tree=parseXmlFile("dfusion/patterns/supplementary.xml")[1] parseTree(main_tree) main_tree=parseXmlFile("dfusion/patterns/codegen.out.xml")[1] parseTree(main_tree) +rawset(df,"types",parseTreeGlobals(main_tree)) +--]=] --[=[labels={} for k,v in ipairs(t) do labels[v.label]=labels[v.label] or {meta={}} diff --git a/plugins/Dfusion/luafiles/xml_types.lua b/plugins/Dfusion/luafiles/xml_types.lua index 02e49fe9e..b96e77b47 100644 --- a/plugins/Dfusion/luafiles/xml_types.lua +++ b/plugins/Dfusion/luafiles/xml_types.lua @@ -1,15 +1,16 @@ function type_read(valtype,address) - if type(valtype)~= "table" then - return engine.peek(valtype,address) + if valtype.issimple then + print("Simple read:"..tostring(valtype.ctype)) + return engine.peek(address,valtype.ctype) else return valtype:makewrap(address) end end function type_write(valtype,address,val) - if type(valtype)~= "table" then - engine.poke(valtype,address,val) + if altype.issimple then + engine.poke(address,valtype.ctype,val) else - engine.poke(DWORD,address,rawget(val,"ptr")) + engine.poke(address,DWORD,rawget(val,"ptr")) end end function first_of_type(node,labelname) @@ -65,6 +66,9 @@ xtypes["static-array"]=sarr simpletypes={} + +simpletypes["s-float"]={FLOAT,4} +simpletypes.int64_t={QWORD,8} simpletypes.uint32_t={DWORD,4} simpletypes.uint16_t={WORD,2} simpletypes.uint8_t={BYTE,1} @@ -78,6 +82,7 @@ function getSimpleType(typename) local o={} o.ctype=simpletypes[typename][1] o.size=simpletypes[typename][2] + o.issimple=true return o end local type_enum={} @@ -130,7 +135,7 @@ function type_class.new(node) local t_name="" local name=v.xarg.name or v.xarg["anon-name"] or ("unk_"..k) - print("\t"..k.." "..name.."->"..v.xarg.meta.." ttype:"..v.label) + --print("\t"..k.." "..name.."->"..v.xarg.meta.." ttype:"..v.label) local ttype=makeType(v) --for k,v in pairs(ttype) do @@ -206,11 +211,49 @@ xtypes["pointer"]=type_class --stl-vector (beginptr,endptr,allocptr) --df-flagarray (ptr,size) xtypes.containers={} +local dfarr={} +dfarr.__index=dfarr +function dfarr.new(node) + local o={} + setmetatable(o,dfarr) + o.size=8 + return o +end +function dfarr:makewrap(address) + local o={} + o.mtype=self + o.ptr=address + setmetatable(o,self.wrap) + return o +end +dfarr.wrap={} +function dfarr.wrap:__index(key) + local num=tonumber(key) + local mtype=rawget(self,"mtype") + local size=type_read(rawget(self,"ptr")+4,DWORD) + error("TODO make __index for dfarray") + if num~=nil and num +#include //TODO make a seperate module with peeks/pokes and page permisions (linux/windows spec) //TODO maybe remove alltogether- use DFHack::Process instead? -unsigned char peekb(size_t offset) -{ - return *((unsigned char*)(offset)); -} -unsigned short peekw(size_t offset) +template +T engine_peek(size_t offset) { - return *((unsigned short*)(offset)); + return *(reinterpret_cast(offset)); } -unsigned peekd(size_t offset) +template +void engine_poke(size_t offset,T val) { - return *((unsigned*)(offset)); + *(reinterpret_cast(offset))=val; } + void peekarb(size_t offset, void *mem,size_t size) { memcpy(mem,(void*)offset,size); @@ -22,18 +22,6 @@ void peekstr(size_t offset, char* buf, size_t maxsize) { strncpy(buf,(char*)offset,maxsize); } -void pokeb(size_t offset,unsigned char val) -{ - *((unsigned char*)(offset))=val; -} -void pokew(size_t offset,unsigned short val) -{ - *((unsigned short*)(offset))=val; -} -void poked(size_t offset,unsigned val) -{ - *((unsigned*)(offset))=val; -} void pokearb(size_t offset, void *mem,size_t size) { memcpy((void*)offset,mem,size); @@ -42,31 +30,42 @@ void pokestr(size_t offset, char* buf, size_t maxsize) { strncpy((char*)offset,buf,maxsize); } -template -T peek(size_t offset) //prob lower performance -{ - T tmp; - peekarb(offset,&tmp,sizeof(T)); - return tmp; -} //// lua stuff here static int lua_peekb(lua_State *L) { lua::state st(L); - st.push(peekb(st.as(1))); + st.push(engine_peek(st.as(1))); + return 1; +} +static int lua_peekw(lua_State *L) +{ + lua::state st(L); + st.push(engine_peek(st.as(1))); return 1; } static int lua_peekd(lua_State *L) { lua::state st(L); - st.push(peekd(st.as(1))); + st.push(engine_peek(st.as(1))); return 1; } -static int lua_peekw(lua_State *L) +static int lua_peekq(lua_State *L) +{ + lua::state st(L); + st.push(engine_peek(st.as(1))); + return 1; +} +static int lua_peekfloat(lua_State *L) +{ + lua::state st(L); + st.push(engine_peek(st.as(1))); + return 1; +} +static int lua_peekdouble(lua_State *L) { lua::state st(L); - st.push(peekw(st.as(1))); + st.push(engine_peek(st.as(1))); return 1; } static int lua_peekarb(lua_State *L) @@ -88,38 +87,53 @@ static int lua_peekstr(lua_State *L) delete [] buf; return 1; } -/*static int lua_peekarb(lua_State *L) +static int lua_peekstr2(lua_State *L) { lua::state st(L); - st.push(peekarb(st.as(1))); + st.push(engine_peek(st.as(1))); return 1; -}*/ +} static int lua_pokeb(lua_State *L) { lua::state st(L); - pokeb(st.as(1),st.as(2)); + engine_poke(st.as(1),st.as(2)); + return 0; +} +static int lua_pokew(lua_State *L) +{ + lua::state st(L); + engine_poke(st.as(1),st.as(2)); return 0; } static int lua_poked(lua_State *L) { lua::state st(L); - poked(st.as(1),st.as(2)); + engine_poke(st.as(1),st.as(2)); return 0; } -static int lua_pokew(lua_State *L) +static int lua_pokeq(lua_State *L) { lua::state st(L); - pokew(st.as(1),st.as(2)); + engine_poke(st.as(1),st.as(2)); + return 0; +} +static int lua_pokefloat(lua_State *L) +{ + lua::state st(L); + engine_poke(st.as(1),st.as(2)); + return 0; +} +static int lua_pokedouble(lua_State *L) +{ + lua::state st(L); + engine_poke(st.as(1),st.as(2)); return 0; } static int lua_pokearb(lua_State *L) { lua::state st(L); - - void *p=(void *)lua_touserdata(L, 2);//st.as(2); size_t size=st.as(3); - pokearb(st.as(1),p,size); return 0; } @@ -130,18 +144,36 @@ static int lua_pokestr(lua_State *L) pokestr(st.as(1),(char*)trg.c_str(),trg.size()); return 0; } +static int lua_pokestr2(lua_State *L) +{ + lua::state st(L); + std::string trg=st.as(2); + engine_poke(st.as(1),trg); + return 0; +} const luaL_Reg lua_engine_func[]= { {"peekb",lua_peekb}, {"peekw",lua_peekw}, {"peekd",lua_peekd}, + {"peekq",lua_peekq}, + {"peekfloat",lua_peekfloat}, + {"peekdouble",lua_peekdouble}, + {"peekarb",lua_peekarb}, {"peekstr",lua_peekstr}, + {"peekstr2",lua_peekstr2}, + {"pokeb",lua_pokeb}, {"pokew",lua_pokew}, {"poked",lua_poked}, + {"pokeq",lua_pokeq}, + {"pokefloat",lua_pokefloat}, + {"pokedouble",lua_pokedouble}, + {"pokearb",lua_pokearb}, {"pokestr",lua_pokestr}, + {"pokestr2",lua_pokestr2}, {NULL,NULL} };