From f4179652fa97cde183872aeb1ac26ffbb65a699d Mon Sep 17 00:00:00 2001 From: Warmist Date: Wed, 3 Aug 2011 16:07:57 +0300 Subject: [PATCH] Lots of changes, including hexsearch and wrapper for lua, also LUNE - an object oriented lua wrapper --- plugins/Dfusion/dfusion.cpp | 2 + plugins/Dfusion/include/hexsearch.h | 35 +++ plugins/Dfusion/include/lua_Hexsearch.h | 33 ++ plugins/Dfusion/include/luamain.h | 2 +- plugins/Dfusion/include/lune.h | 361 ++++++++++++++++++++++ plugins/Dfusion/luafiles/common.lua | 39 +-- plugins/Dfusion/luafiles/init.lua | 15 +- plugins/Dfusion/luafiles/itempatterns.lua | 62 ++++ plugins/Dfusion/luafiles/patterns.lua | 243 +++++++++++++++ plugins/Dfusion/luafiles/patterns2.lua | 29 ++ plugins/Dfusion/src/hexsearch.cpp | 74 +++++ plugins/Dfusion/src/lua_Hexsearch.cpp | 57 ++++ plugins/Dfusion/src/lune.cpp | 2 + 13 files changed, 927 insertions(+), 27 deletions(-) create mode 100644 plugins/Dfusion/include/hexsearch.h create mode 100644 plugins/Dfusion/include/lua_Hexsearch.h create mode 100644 plugins/Dfusion/include/lune.h create mode 100644 plugins/Dfusion/luafiles/itempatterns.lua create mode 100644 plugins/Dfusion/luafiles/patterns.lua create mode 100644 plugins/Dfusion/luafiles/patterns2.lua create mode 100644 plugins/Dfusion/src/hexsearch.cpp create mode 100644 plugins/Dfusion/src/lua_Hexsearch.cpp create mode 100644 plugins/Dfusion/src/lune.cpp diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index 4b6a33710..45aa3c687 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -14,6 +14,7 @@ #include "luamain.h" #include "lua_Console.h" #include "lua_Process.h" +#include "lua_Hexsearch.h" #include "functioncall.h" using std::vector; @@ -37,6 +38,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector //maybe remake it to run automaticaly lua::RegisterConsole(lua::glua::Get(),&c->con); lua::RegisterProcess(lua::glua::Get(),c->p); + lua::RegisterHexsearch(lua::glua::Get()); commands.push_back(PluginCommand("dfusion","Init dfusion system.",dfusion)); commands.push_back(PluginCommand("lua", "Run interactive interpreter.\ \n Options: = run instead",lua_run)); diff --git a/plugins/Dfusion/include/hexsearch.h b/plugins/Dfusion/include/hexsearch.h new file mode 100644 index 000000000..335bfebde --- /dev/null +++ b/plugins/Dfusion/include/hexsearch.h @@ -0,0 +1,35 @@ +#ifndef HEXSEARCH_H +#define HEXSEARCH_H +#include +#include "dfhack/Core.h" //for some reason process.h needs core +#include "dfhack/Process.h" + +//(not yet)implemented using Boyer-Moore algorithm + +class Hexsearch +{ +public: + typedef std::vector SearchArgType; + enum SearchConst //TODO add more + { + ANYBYTE=0x101,DWORD_,ANYDWORD,ADDRESS + }; + + Hexsearch(const SearchArgType &args,uint64_t startpos,uint64_t endpos); + ~Hexsearch(); + + void Reset(){pos_=startpos_;}; + void SetStart(uint64_t pos){pos_=pos;}; + + uint64_t FindNext(); + std::vector FindAll(); + +private: + SearchArgType args_; + uint64_t pos_,startpos_,endpos_; + std::vector BadCharShifts,GoodSuffixShift; + void PrepareGoodSuffixTable(); + void PrepareBadCharShift(); +}; + +#endif \ No newline at end of file diff --git a/plugins/Dfusion/include/lua_Hexsearch.h b/plugins/Dfusion/include/lua_Hexsearch.h new file mode 100644 index 000000000..030db079e --- /dev/null +++ b/plugins/Dfusion/include/lua_Hexsearch.h @@ -0,0 +1,33 @@ +#ifndef LUA_HEXSEARCH_H +#define LUA_HEXSEARCH_H +#include "hexsearch.h" + +#include "luamain.h" + + + +namespace lua +{ + +class Hexsearch +{ + int tblid; + ::Hexsearch *p; +public: + Hexsearch(lua_State *L,int id); + ~Hexsearch(); + + int GetTableId(){return tblid;}; + + int find(lua_State *L); + int findall(lua_State *L); + int reset(lua_State *L); + + DEF_LUNE(Hexsearch); +}; +void RegisterHexsearch(lua::state &st);//TODO remake into OO oriented thing + +} + + +#endif \ No newline at end of file diff --git a/plugins/Dfusion/include/luamain.h b/plugins/Dfusion/include/luamain.h index aee073729..89524a52d 100644 --- a/plugins/Dfusion/include/luamain.h +++ b/plugins/Dfusion/include/luamain.h @@ -11,7 +11,7 @@ extern "C" { #include "lualib.h" } -//#include "lune.h" +#include "lune.h" #include "luaxx.hpp" namespace lua diff --git a/plugins/Dfusion/include/lune.h b/plugins/Dfusion/include/lune.h new file mode 100644 index 000000000..9acd80cc2 --- /dev/null +++ b/plugins/Dfusion/include/lune.h @@ -0,0 +1,361 @@ +#ifndef LUNE_H +#define LUNE_H + +extern "C" { +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +} + +#include "luaxx.hpp" +#include + +namespace lua +{ + class object + { + state &myst; + int myref; + public: + object(state &myst):myst(myst) + { + myref=luaL_ref(myst,LUA_REGISTRYINDEX); + } + ~object() + { + luaL_unref(myst,LUA_REGISTRYINDEX,myref); + } + void Get() + { + lua_rawgeti(myst,LUA_REGISTRYINDEX,myref); + } + state &GetState(){return myst;}; + }; + + class local_object + { + state myst; + int myref; + static object *mytbl; + public: + local_object(lua_State *L) + { + + myst=state(L); + //LOG<<"Creating local object...\n"; + //StackDump(L); + if(!mytbl) + { + //LOG<<" Metable...\n"; + myst.newtable(); //2 + if(myst.newmetatable("WEAKTABLE"))//3 + { + //StackDump(L); + myst.push("kv"); //4 + myst.setfield("__mode");//3 + //LOG<<" Setting Metable...\n"; + //StackDump(L); + } + //LOG<<" Attaching to holder...\n"; + + //myst.setfield("__metatable");//2 + lua_setmetatable(myst,-1); + mytbl=new object(myst); + //StackDump(L); + //LOG<<" Done Metatable...\n"; + } + //StackDump(L); + mytbl->Get(); + //LOG<<" Got my table...\n"; + //StackDump(L); + myst.insert(-2); + myref=luaL_ref(myst,-2); + //LOG<<"Before pop:"; + //StackDump(L); + myst.pop(1); + GetTable(); + //LOG<<"========Done...\n"<<"Ref="<Get(); + //StackDump(L); + //LOG<<"===========================\n"; + } + ~local_object() + { + //LOG<<"Deleting local object...\n"; + ReleaseTable(); + } + void ReleaseTable() + { + mytbl->Get(); + int pos=myst.gettop(); + luaL_unref(myst,pos,myref); + myst.remove(pos); + } + state GetState(){return myst;} + void GetTable() + { + //LOG<<"Getting ref="<Get(); + int pos=myst.gettop(); + //StackDump(myst); + //LOG<<"Tbl get\n"; + //int pos=myst.gettop(); + lua_rawgeti(myst,pos,myref); + //StackDump(myst); + //LOG<<"Done\n"; + myst.remove(pos); + } + protected: + + }; +}; + +template +class Lune +{ +public: + typedef struct + { + T *pT; + int tableref; + } userdataType; + + typedef int (T::*mfp)(lua_State *L); + typedef struct + { + const char *name; + mfp mfunc; + } RegType; + + static void Register(lua_State *L) + { + lua_newtable(L); + int methods = lua_gettop(L); + + luaL_newmetatable(L, T::className); + int metatable = lua_gettop(L); + + // store method table in globals so that + // scripts can add functions written in Lua. + lua_pushstring(L, T::className); + lua_pushvalue(L, methods); + lua_settable(L, LUA_GLOBALSINDEX); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methods); + lua_settable(L, metatable); // hide metatable from Lua getmetatable() + + lua_pushliteral(L, "__index"); + lua_pushcfunction(L, index_T); + lua_settable(L, metatable); + + //lua_pushliteral(L, "__name"); + //lua_pushstring(L, T::className); + //lua_settable(L, metatable); + + lua_pushliteral(L, "__newindex"); + lua_pushcfunction(L, newindex_T); + lua_settable(L, metatable); + + lua_pushliteral(L, "__instances"); + lua_newtable(L); + lua_settable(L, metatable); + if(GC) + { + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_T); + lua_settable(L, metatable); + } + + + lua_newtable(L); // metatable for method table + int mt = lua_gettop(L); + lua_pushliteral(L, "__call"); + lua_pushcfunction(L, new_T); + lua_pushliteral(L, "new"); + lua_pushvalue(L, -2); // dup new_T function + lua_settable(L, methods); // add new_T to method table + lua_settable(L, mt); // mt.__call = new_T + lua_setmetatable(L, methods); + //LOG<<"lune: registered class \""<name; l++) + { + /* edited by Snaily: shouldn't it be const RegType *l ... ? */ + lua_pushstring(L, l->name); + lua_pushlightuserdata(L, (void*)l); + lua_pushcclosure(L, thunk, 1); + lua_settable(L, methods); + //LOG<<"lune: method \""<name<<"\"\n"; + } + + lua_pop(L, 2); // drop metatable and method table + }; + static void GetTable(lua_State *L,T *p) + { + GetTableEx(L,p->GetTableId()); + } + static void GetTableEx(lua_State *L,int id) + { + lua::state s(L); + s.getmetatable(T::className); + s.getfield("__instances"); + int ins=s.gettop(); + lua_rawgeti(L, ins, id); + s.insert(-3); + s.pop(2); + } + static T *check(lua_State *L, int narg) + { + userdataType *ud = + static_cast(luaL_checkudata(L, narg, T::className)); //TODO FIX THIs.. + //(lua_touserdata(L, narg));// + if(!ud) luaL_typerror(L, narg, T::className); + return ud->pT; // pointer to T object + } +protected: +private: + + static int RegTable(lua_State *L) + { + // LOG<<"Regging....\n"; + //lua::StackDump(L); + + lua::state s(L); + int ssize=s.gettop(); + //s.getglobal(T::className); + s.getmetatable(T::className); + s.getfield("__instances"); + int ins=s.gettop(); + s.newtable(); + int id=luaL_ref(L,ins); + //LOG<<"After reg:\n"; + //lua::StackDump(L); + s.settop(ssize); + return id; + } + static void UnregTable(lua_State *L,int id) + { + lua::state s(L); + s.getmetatable(T::className); + s.getfield("__instances"); + int ins=s.gettop(); + //LOG<<"Unreg table id:"<(-1); + T *p=check(L,1); + GetTable(L,p); + st.insert(-2); + //LOG<<"Index:\n"; + //lua::StackDump(L); + lua_rawget(L,-2); //try getting from normal table + if(st.is()) //failed + { + st.pop(2); + st.getglobal(T::className); //try class tables then + st.push(key); + st.gettable(); + } + return 1; + } + static int newindex_T(lua_State *L) + { + //LOG<<"New index....\n"; + //lua::StackDump(L); + + lua::state st(L); + T *p=check(L,1); + GetTable(L,p); + //st.insert(-3); + //LOG<<"Before set:\n"; + st.insert(-3); + //lua::StackDump(L); + lua_rawset(L,-3); + return 0; + } + static int thunk(lua_State *L) + { + //LOG<<"Size of stack:"<(lua_touserdata(L,1))->pT; + lua_remove(L, 1); // remove self so member function args start at index 1 + // get member function from upvalue + RegType *l = static_cast(lua_touserdata(L, lua_upvalueindex(1))); + return (obj->*(l->mfunc))(L); // call member function + } + static int gc_T(lua_State *L) + { + //lua_getfield(L,,"__ud"); + //LOG<<"Garbage collecting.\n"; + //lua::StackDump(L); + userdataType *ud = static_cast(lua_touserdata(L, 1)); + T *obj = ud->pT; + + delete obj; // call destructor for T objects + UnregTable(L,ud->tableref); + return 0; + } + static int new_T(lua_State *L) + { + //LOG<<"Pre build:"<(lua_newuserdata(L, sizeof(userdataType))); + //lua::StackDump(L); + luaL_getmetatable(L, T::className); // lookup metatable in Lua registry + lua_setmetatable(L,-2); + //LOG<<"metatable set\n"; + + //lua::StackDump(L); + GetTable(L,obj); + lua_pushliteral(L,"__obj"); + lua_pushvalue(L,-3); + lua_settable(L,-3); + lua_pop(L,1); + //LOG<<"Object referenced\n"; + //lua::StackDump(L); + //T *p = new(ud) T(L); // call constructor for T objects + //lua::StackDump(L); + ud->pT = obj; // store pointer to object in userdata + ud->tableref=id; + //luaL_getmetatable(L, T::className); // lookup metatable in Lua registry + //lua_setmetatable(L, tableindex); + //lua::StackDump(L); + //LOG<<"Push done\n"; + return 1; // userdata containing pointer to T object + } + Lune() {}; //non constructable... +}; +#define method(class, name) {#name, &class::name} +#define DEF_LUNE(class) static const char className[];\ + static Lune::RegType methods[]; +#define DEF_LUNE_NOGC(class) static const char className[];\ + static Lune::RegType methods[]; +#define IMP_LUNE(class,lua_name) const char class::className[]=#lua_name; +#define LUNE_METHODS_START(class) Lune::RegType class::methods[] = { +#define LUNE_METHODS_START_NOGC(class) Lune::RegType class::methods[] = { +#define LUNE_METHODS_END() {0,0}} +#endif // LUNE_H diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua index aeca0a820..b80f70e3e 100644 --- a/plugins/Dfusion/luafiles/common.lua +++ b/plugins/Dfusion/luafiles/common.lua @@ -17,7 +17,7 @@ offsets.load = function () end end offsets.load() -function unlockDF() +function GetTextRegion() local ranges=Process.getMemRanges() for k,v in pairs(ranges) do --for k2,v2 in pairs(v) do @@ -30,32 +30,27 @@ function unlockDF() --if(v["execute"]) then num=num+100 end --print(string.format("%d %x->%x %s %d",k,v["start"],v["end"],v.name,num)) local pos=string.find(v.name,".text") - if pos~=nil then - v["write"]=true - Process.setPermisions(v,v) + if(pos~=nil) then + return v; end end + return nil +end +function unlockDF() + local reg=GetTextRegion() + reg["write"]=true + Process.setPermisions(reg,reg) end function lockDF() - local ranges=Process.getMemRanges() - for k,v in pairs(ranges) do - --for k2,v2 in pairs(v) do - -- print(string.format("%d %s->%s",k,tostring(k2),tostring(v2))) - --end - --local num - --num=0 - --if(v["read"])then num=num+1 end - --if(v["write"])then num=num+10 end - --if(v["execute"]) then num=num+100 end - --print(string.format("%d %x->%x %s %d",k,v["start"],v["end"],v.name,num)) - local pos=string.find(v.name,".text") - if pos~=nil then - v["write"]=false - Process.setPermisions(v,v) - end - end + local reg=GetTextRegion() + reg["write"]=false + Process.setPermisions(reg,reg) end -- engine bindings engine=engine or {} engine.peekd=Process.readDWord -engine.poked=Process.writeDWord \ No newline at end of file +engine.poked=Process.writeDWord + +dofile("dfusion/patterns.lua") +dofile("dfusion/patterns2.lua") +dofile("dfusion/itempatterns.lua") \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index 4056da046..0cd34cc5c 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -15,10 +15,17 @@ dofile("dfusion/common.lua") print("Unlocking Df .text section...") unlockDF() print("Done unlock") -lockDF() -dofile("dfusion/simple_embark/plugin.lua") -print("hello world") -Console.print("Hello world in console!\n") +text=GetTextRegion() +h=hexsearch(text.start,text["end"],0x73,0x02,0x8b,0xce,0x53,0x6a,0x01,0x6a,0x06) +pos=h:findall() +for k,v in pairs(pos) do + print(k..v) +end +--hexsearch.delete(h) +lockDF() --DOES NOT WORK?! +--dofile("dfusion/simple_embark/plugin.lua") +--print("hello world") +--Console.print("Hello world in console!\n") --name=Console.lineedit("Enter name:") --Console.print("Your name is:"..name) diff --git a/plugins/Dfusion/luafiles/itempatterns.lua b/plugins/Dfusion/luafiles/itempatterns.lua new file mode 100644 index 000000000..da62c26d2 --- /dev/null +++ b/plugins/Dfusion/luafiles/itempatterns.lua @@ -0,0 +1,62 @@ +--dofile("patterns2.lua") moved to common.lua +ptr_item={} +ptr_item.RTI={off=0,rtype=DWORD} +ptr_item.x={off=4,rtype=WORD} +ptr_item.y={off=6,rtype=WORD} +ptr_item.z={off=8,rtype=WORD} +ptr_item.ref={off=0x28,rtype=ptr_vector} + +ptr_item.mat={off=0x78,rtype=WORD} +ptr_item.submat={off=0x7A,rtype=WORD} +ptr_item.submat2={off=0x7C,rtype=DWORD} +ptr_item.legendid={off=0x80,rtype=DWORD} -- i don't remember writing this... +ptr_item.decorations={off=0x90,rtype=ptr_vector} +ptr_item.flags={off=0xC,rtype=ptt_dfflag.new(8)} +ptr_item.ptr_covering={off=0x64,rtype=DWORD} +ptr_item.stack={off=0x58,rtype=WORD} +function ptr_item.getname(self,RTI) + if RTI == nil then + return string.sub(RTTI_GetName(self.RTI),5,-3) + else + return string.sub(RTTI_GetName(RTI),5,-3) + end +end +ptr_subitems={} +ptr_subitems["item_slabst"]={} +ptr_subitems["item_slabst"].msgptr={off=0xA0,rtype=ptt_dfstring} +ptr_subitems["item_slabst"].signtype={off=0xC0,rtype=DWORD} + +ptr_subitems["item_fisthst"]={} +ptr_subitems["item_fisthst"].fisthtype={off=0x78,rtype=WORD} + +ptr_subitems["item_eggst"]={} +ptr_subitems["item_eggst"].race={off=0x78,rtype=DWORD} +ptr_subitems["item_eggst"].isfertile={off=0xa0,rtype=DWORD} --0 or 1 +ptr_subitems["item_eggst"].hatchtime={off=0xa4,rtype=DWORD} + +ptr_decoration_gen={} +ptr_decoration_gen.RTI={off=0,rtype=DWORD} +ptr_decoration_gen.material={off=0x04,rtype=WORD} -- same for all? +ptr_decoration_gen.submat={off=0x08,rtype=DWORD} +function ptr_decoration_gen.getname(self,RTI) + if RTI == nil then + return string.sub(RTTI_GetName(self.RTI),21,-5) + else + return string.sub(RTTI_GetName(RTI),21,-5) + end +end +ptr_decoration={} +ptr_decoration["covered"]={} +ptr_decoration["covered"].material={off=0x04,rtype=WORD} +ptr_decoration["covered"].submat={off=0x08,rtype=DWORD} +ptr_decoration["art_image"]={} +ptr_decoration["art_image"].material={off=0x04,rtype=WORD} +ptr_decoration["art_image"].submat={off=0x08,rtype=DWORD} +ptr_decoration["art_image"].image={off=0x24,rtype=DWORD} +ptr_decoration["bands"]={} +ptr_decoration["bands"].material={off=0x04,rtype=WORD} +ptr_decoration["bands"].submat={off=0x08,rtype=DWORD} +ptr_cover={} --covering of various types (blood, water, etc) +ptr_cover.mat={off=0,rtype=WORD} +ptr_cover.submat={off=4,rtype=DWORD} +ptr_cover.state={off=8,rtype=WORD} \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/patterns.lua b/plugins/Dfusion/luafiles/patterns.lua new file mode 100644 index 000000000..f7c37da0d --- /dev/null +++ b/plugins/Dfusion/luafiles/patterns.lua @@ -0,0 +1,243 @@ +ptt_dfstring={} +if(COMPATMODE) then +ptt_dfstring.ptr={off=4,rtype=DWORD} +ptt_dfstring.size={off=20,rtype=DWORD} + +else +ptt_dfstring.ptr={off=0,rtype=DWORD} +ptt_dfstring.size={off=16,rtype=DWORD} +ptt_dfstring.alloc={off=20,rtype=DWORD} +end +function ptt_dfstring:getval() + --print(string.format("GETTING FROM:%x",self.__offset)) + if self.size<16 then + --print(string.format("GETTING FROM:%x",self.__offset)) + return string.sub(engine.peekstr(self.__offset),1,self.size) + else + --print(string.format("GETTING FROM:%x",self.ptr)) + return string.sub(engine.peekstr(self.ptr),1,self.size) + end +end +function ptt_dfstring:setval(newstring) + local offset=self.__offset + local strl=string.len(newstring) + if strl<16 then + --print(string.format("GETTING FROM:%x",self.__offset)) + + engine.poked(offset+ptt_dfstring.size.off,strl) + engine.poked(offset+ptt_dfstring.alloc.off,15) + engine.pokestr(offset,newstring) + + else + local loc + if engine.peekd(offset+ptt_dfstring.alloc.off) > strl then + loc=engine.peekd(offset) + print("Will fit:"..loc.." len:"..strl) + else + loc=Allocate(strl+1) + engine.poked(offset+ptt_dfstring.alloc.off,strl) + print("Will not fit:"..loc.." len:"..strl) + end + --print(string.format("GETTING FROM:%x",self.ptr)) + engine.poked(self.__offset+ptt_dfstring.size.off,strl) + engine.pokestr(loc,newstring) + engine.poked(self.__offset,loc) + end +end + +--if(COMPATMODE) then +--ptr_vector={} +--ptr_vector.st={off=4,rtype=DWORD} +--ptr_vector.en={off=8,rtype=DWORD} +--else +ptr_vector={} +ptr_vector.st={off=0,rtype=DWORD} +ptr_vector.en={off=4,rtype=DWORD} +ptr_vector.alloc={off=8,rtype=DWORD} +--end +function ptr_vector:clone(settype) + local ret={} + for k,v in pairs(self) do + ret[k]=v + end + ret.type=settype + return ret +end +function ptr_vector:size() + return (self.en-self.st)/engine.sizeof(self.type) +end +ptr_vector.type=DWORD +function ptr_vector:getval(num) + return engine.peek(self.st+engine.sizeof(self.type)*num,self.type) +end +function ptr_vector:setval(num,val) + return engine.poke(self.st+engine.sizeof(self.type)*num,self.type,val) +end +function ptr_vector:append(val) + if self.alloc - self.en > 0 then + local num=self:size() + self.en=self.en+engine.sizeof(self.type) + self:setval(val,num) + else + error("larger than allocated arrays not implemented yet") + local num=self:size() + local ptr=Allocate(num*2) + + end +end +ptt_dfflag={} +function ptt_dfflag.flip(self,num) --flip one bit in flags + local of=math.floor (num/8); + + self[of]=bit.bxor(self[of],bit.lshift(1,num%8)) +end + +function ptt_dfflag.get(self,num) -- get one bit in flags + local of=math.floor (num/8); + + if bit.band(self[of],bit.lshift(1,num%8))~=0 then + return true + else + return false + end +end +function ptt_dfflag.set(self,num,val) --set to on or off one bit in flags + if (self:get(num)~=val) then + self:flip(num) + end +end +function ptt_dfflag.new(size) -- create new flag pattern of size(in bytes) + local ret={} + for i=0,size-1 do + ret[i]={off=i,rtype=BYTE}; + end + ret.flip=ptt_dfflag.flip --change to metatable stuff... + ret.get=ptt_dfflag.get + ret.set=ptt_dfflag.set + return ret; +end +--[[ + Creature: + 0 name (df_string) 28 + 28 nick (df_string) 56 + 56 surname- namearray(7*dword(4)) 84 ... + 140 race (dword) 144 + 224 flags + 264 civ (dword) + 252 ID + 592 following ID + 904 bleed vector? hurt vector or sth... + 0x790 legends id? + 2128 known names? or knowledge? + flags: + 0 Can the dwarf move or are they waiting for their movement timer + 1 Dead (might also be set for incoming/leaving critters that are alive) + 2 Currently in mood + 3 Had a mood + 4 "marauder" -- wide class of invader/inside creature attackers + 5 Drowning + 6 Active merchant + 7 "forest" (used for units no longer linked to merchant/diplomacy, they just try to leave mostly) + 8 Left (left the map) + 9 Rider + 10 Incoming + 11 Diplomat + 12 Zombie + 13 Skeleton + 14 Can swap tiles during movement (prevents multiple swaps) + 15 On the ground (can be conscious) + 16 Projectile + 17 Active invader (for organized ones) + 18 Hidden in ambush + 19 Invader origin (could be inactive and fleeing) + 20 Will flee if invasion turns around + 21 Active marauder/invader moving inward + 22 Marauder resident/invader moving in all the way + 23 Check against flows next time you get a chance + 24 Ridden + 25 Caged + 26 Tame + 27 Chained + 28 Royal guard + 29 Fortress guard + 30 Suppress wield for beatings/etc + 31 Is an important historical figure + 32 swiming + +]]-- +ptr_Creature={} +ptr_Creature.x={off=144,rtype=WORD} --ok +ptr_Creature.y={off=146,rtype=WORD} --ok +ptr_Creature.z={off=148,rtype=WORD} --ok +ptr_Creature.flags={off=224,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 +ptr_Creature.race={off=140,rtype=DWORD} --ok +ptr_Creature.civ={off=264,rtype=DWORD} +ptr_Creature.legends={off=344,rtype=ptr_vector} --ok +ptr_Creature.hurt1={off=0x308,rtype=ptr_vector:clone(BYTE)} --byte vector... +ptr_Creature.hurt2={off=0x338,rtype=ptr_vector} +ptr_Creature.wounds={off=0x388,rtype=ptr_vector} +ptr_Creature.itemlist1={off=0x1D0,rtype=ptr_vector} +ptr_Creature.itemlist2={off=0x288,rtype=ptr_vector} +ptr_Creature.bloodlvl={off=0x490,rtype=DWORD} +ptr_Creature.bleedlvl={off=0x494,rtype=DWORD} + +ptr_CrGloss={} +ptr_CrGloss.token={off=0,rtype=ptt_dfstring} +ptr_CrGloss.castes={off=296,rtype=ptr_vector} + +ptr_CrCaste={} +ptr_CrCaste.name={off=0,rtype=ptt_dfstring} +ptr_CrCaste.flags_ptr={off=0x524,rtype=DWORD} --size 17? +--[=[ + Flags: + 57 - is sentient (allows setting labours) +--]=] +ptr_LEntry={} -- all size 256 +ptr_LEntry.name={off=36,rtype=ptt_dfstring} +ptr_LEntry.id1={off=160,rtype=DWORD} +ptr_LEntry.id2={off=164,rtype=DWORD} +ptr_LEntry.somlist={off=220,rtype=DWORD} + +ptr_dfname={} +for i=0,6 do +ptr_dfname[i]={off=i*4,rtype=DWORD} +end +--[[ + Site docs: + 0x38 name struct todo... + 0x78 type: + 0 - mountain halls (yours) + 1 - dark fort + 2 - cave + 3 - mountain hall (other) + 4 - forest + 5 - hamlet + 6 - imp location + 7 - lair + 8 - fort + 9 - camp + 0x7a some sort of id? + 0x84 some vec (ids) + 0x94 some other vec (ids) + 0xa4 some vec (prts) + 0x118 ptr to sth + + 0x14c ptr to mapdata +]]-- + + +ptr_site={} +ptr_site.type={off=0x78,rtype=WORD} +ptr_site.id={off=0x7a,rtype=DWORD} +ptr_site.name={off=0x38,rtype=ptr_dfname} +ptr_site.flagptr={off=0x118,rtype=DWORD} + +ptr_legends2={} +ptr_legends2.id={off=0,rtype=DWORD} +ptr_legends2.follow={off=0x18,rtype=DWORD} + +ptr_material={} +ptr_material.token={off=0,rtype=ptt_dfstring} diff --git a/plugins/Dfusion/luafiles/patterns2.lua b/plugins/Dfusion/luafiles/patterns2.lua new file mode 100644 index 000000000..09a3b0db8 --- /dev/null +++ b/plugins/Dfusion/luafiles/patterns2.lua @@ -0,0 +1,29 @@ +ptr_COL={} -- complete object locator... +ptr_COL.sig={off=0,rtype=DWORD} +ptr_COL.offset={off=4,rtype=DWORD} --offset of this vtable in the complete class +ptr_COL.cdoffset={off=8,rtype=DWORD} -- constructor displacement +ptr_COL.typePointer={off=12,rtype=DWORD} +ptr_COL.hierarchyPointer={off=16,rtype=DWORD} + +ptr_RTTI_Type={} +ptr_RTTI_Type.vftPointer={off=0,rtype=DWORD} +ptr_RTTI_Type.name={off=8,rtype=STD_STRING} + +function RTTI_GetName(vtable) + local COLoff=engine.peek(vtable-4,DWORD) + --print(string.format("Look:%x vtable:%x",vtable,engine.peek(vtable-4,DWORD))) + COL=engine.peek(COLoff,ptr_COL) + --print(string.format("COL:%x Typeptr:%x Type:%s",COLoff,COL.typePointer,engine.peek(COL.typePointer,ptr_RTTI_Type.name))) + return engine.peek(COL.typePointer,ptr_RTTI_Type.name) +end +ptr_RTTI_Hierarchy={} +ptr_RTTI_Hierarchy.sig={off=0,rtype=DWORD} +ptr_RTTI_Hierarchy.attributes={off=4,rtype=DWORD} +ptr_RTTI_Hierarchy.numBaseClasses={off=8,rtype=DWORD} +ptr_RTTI_Hierarchy.ptrBases={off=12,rtype=DWORD} + +ptr_RTTI_BaseClass={} +ptr_RTTI_BaseClass.typePointer={off=0,rtype=DWORD} +ptr_RTTI_BaseClass.numContained={off=4,rtype=DWORD} +--todo PMD +--todo flags \ No newline at end of file diff --git a/plugins/Dfusion/src/hexsearch.cpp b/plugins/Dfusion/src/hexsearch.cpp new file mode 100644 index 000000000..dda04c9ab --- /dev/null +++ b/plugins/Dfusion/src/hexsearch.cpp @@ -0,0 +1,74 @@ +#include "hexsearch.h" + + +Hexsearch::Hexsearch(const SearchArgType &args,uint64_t startpos,uint64_t endpos):args_(args),pos_(startpos_),startpos_(startpos),endpos_(endpos) +{ + +} +Hexsearch::~Hexsearch() +{ + +} + +uint64_t Hexsearch::FindNext() //TODO rewrite using Boyer-Moore algorithm +{ + DFHack::Core &inst=DFHack::Core::getInstance(); + DFHack::Process *p=inst.p; + uint8_t *buf; + buf=new uint8_t[args_.size()]; + while(pos_readByte(pos_,buf[0]); + if(buf[0]==args_[0]) //TODO make a comparator + { + p->read(pos_,args_.size(),buf); + for(size_t i=0;i Hexsearch::FindAll() +{ + std::vector ret; + uint64_t cpos=pos_; + while(cpos!=0) + { + cpos=FindNext(); + if(cpos!=0) + ret.push_back(cpos); + } + return ret; +} +void Hexsearch::PrepareBadCharShift() +{ + BadCharShifts.resize(256,-1); + int i=0; + for(SearchArgType::reverse_iterator it=args_.rbegin();it!=args_.rend();it++) + { + BadCharShifts[*it]=i; + i++; + } +} +void Hexsearch::PrepareGoodSuffixTable() +{ + GoodSuffixShift.resize(args_.size()+1,0); + +} \ No newline at end of file diff --git a/plugins/Dfusion/src/lua_Hexsearch.cpp b/plugins/Dfusion/src/lua_Hexsearch.cpp new file mode 100644 index 000000000..a4e5e9ea5 --- /dev/null +++ b/plugins/Dfusion/src/lua_Hexsearch.cpp @@ -0,0 +1,57 @@ +#include "lua_Hexsearch.h" +int lua::Hexsearch::find(lua_State *L) +{ + lua::state st(L); + uint64_t pos=p->FindNext(); + st.push(pos); + return 1; +} +int lua::Hexsearch::findall(lua_State *L) +{ + lua::state st(L); + std::vector pos=p->FindAll(); + st.newtable(); + for(int i=0;i(2); + end=st.as(3); + for(int i=4;i(i)); + } + p=new ::Hexsearch(args,start,end); +} +lua::Hexsearch::~Hexsearch() +{ + delete p; +} +int lua::Hexsearch::reset(lua_State *L) +{ + lua::state st(L); + p->Reset(); + return 0; +} + +IMP_LUNE(lua::Hexsearch,hexsearch); +LUNE_METHODS_START(lua::Hexsearch) + method(lua::Hexsearch,find), + method(lua::Hexsearch,findall), + method(lua::Hexsearch,reset), +LUNE_METHODS_END(); +void lua::RegisterHexsearch(lua::state &st) +{ + + Lune::Register(st); + +} \ No newline at end of file diff --git a/plugins/Dfusion/src/lune.cpp b/plugins/Dfusion/src/lune.cpp new file mode 100644 index 000000000..186f56fb5 --- /dev/null +++ b/plugins/Dfusion/src/lune.cpp @@ -0,0 +1,2 @@ +#include "lune.h" +lua::object *lua::local_object::mytbl=0;