diff --git a/library/lua/memscan.lua b/library/lua/memscan.lua index ba3efd708..6796b3563 100644 --- a/library/lua/memscan.lua +++ b/library/lua/memscan.lua @@ -24,7 +24,7 @@ function CheckedArray:__len() return self.count end function CheckedArray:__index(idx) - if type(idx) == number then + if type(idx) == "number" then if idx >= self.count then error('Index out of bounds: '..tostring(idx)) end diff --git a/plugins/Dfusion/luafiles/embark/init.lua b/plugins/Dfusion/luafiles/embark/init.lua index 529c2d1e5..aa8f2822d 100644 --- a/plugins/Dfusion/luafiles/embark/init.lua +++ b/plugins/Dfusion/luafiles/embark/init.lua @@ -1,3 +1,28 @@ +local dfu=require("dfusion") +local ms=require("memscan") + +CustomEmbark=defclass(CustomEmbark,dfu.BinaryPlugin) +CustomEmbark.ATTRS{filename="dfusion/embark/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL} +function CustomEmbark:install() + local stoff=dfhack.internal.getAddress('start_dwarf_count') + if stoff==nil then + error("address for start_dwarf_count not found!") + end + local _,race_id_offset=df.sizeof(df.global.ui:_field("race_id")) + local needle={0x0f,0xb7,0x0d} --movzx,... + add_dword(needle,race_id_offset) -- ...word ptr[] + local mem=ms.get_code_segment() + local trg_offset=mem.uint8_t.find(needle,stoff)--maybe endoff=stoff+bignumber + if trg_offset==nil then + error("address for race_load not found") + end + needle={0x83,0xc8,0xff} -- or eax, 0xFF + local caste_offset=mem.uint8_t.find(needle,trg_offset) + if caste_offset==nil or caste_offset-stoff>1000 then + error("Caste change code not found or found too far!") + end + +end function MakeTable(modpos,modsize,names) count=0 castes={} diff --git a/plugins/lua/dfusion.lua b/plugins/lua/dfusion.lua new file mode 100644 index 000000000..06128d29b --- /dev/null +++ b/plugins/lua/dfusion.lua @@ -0,0 +1,163 @@ +-- Stuff used by dfusion +local _ENV = mkmodule('plugins.dfusion') + +local ms=require("memscan") + +local marker={0xDE,0xAD,0xBE,0xEF} +patches={} +-- A reversable binary patch +BinaryPatch=defclass(BinaryPatch) +BinaryPatch.ATTRS {pre_data=DEFAULT_NIL,data=DEFAULT_NIL,address=DEFAULT_NIL,name=DEFAULT_NIL} +function BinaryPatch:init(args) + self.is_applied=false + if args.pre_data==nil or args.data==nil or args.address==nil or args.name==nil then + error("Invalid parameters to binary patch") + end + if patches[self.name]~=nil then + error("Patch already exist") + end + self.max_val=0 + for k,v in pairs(args.pre_data) do + if type(k)~="number" then + error("non number key in pre_data") + end + if self.max_val