More work on dfusion. Embark anywhere script separated.
parent
da92fb9a1c
commit
86ec66c0fb
@ -1,108 +1,69 @@
|
|||||||
local dfu=require("dfusion")
|
local dfu=require("plugins.dfusion")
|
||||||
local ms=require("memscan")
|
local ms=require("memscan")
|
||||||
|
local MAX_RACES=100
|
||||||
CustomEmbark=defclass(CustomEmbark,dfu.BinaryPlugin)
|
CustomEmbark=defclass(CustomEmbark,dfu.BinaryPlugin)
|
||||||
CustomEmbark.ATTRS{filename="dfusion/embark/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL}
|
CustomEmbark.ATTRS{filename="dfusion/embark/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL}
|
||||||
function CustomEmbark:install()
|
function CustomEmbark:install()
|
||||||
local stoff=dfhack.internal.getAddress('start_dwarf_count')
|
local stoff=dfhack.internal.getAddress('start_dwarf_count')
|
||||||
|
if #self.race_caste_data<7 then
|
||||||
|
error("caste and race count must be bigger than 6")
|
||||||
|
end
|
||||||
|
if #self.race_caste_data>MAX_RACES then
|
||||||
|
error("caste and race count must be less then "..MAX_RACES)
|
||||||
|
end
|
||||||
if stoff==nil then
|
if stoff==nil then
|
||||||
error("address for start_dwarf_count not found!")
|
error("address for start_dwarf_count not found!")
|
||||||
end
|
end
|
||||||
local _,race_id_offset=df.sizeof(df.global.ui:_field("race_id"))
|
local _,race_id_offset=df.sizeof(df.global.ui:_field("race_id"))
|
||||||
local needle={0x0f,0xb7,0x0d} --movzx,...
|
print(string.format("start=%08x",stoff))
|
||||||
add_dword(needle,race_id_offset) -- ...word ptr[]
|
local needle={0x0f,0xb7,0x0d} --movzx eax,dword ptr [race_id]
|
||||||
|
local tmp_table=dfu.dwordToTable(race_id_offset)
|
||||||
|
for k,v in ipairs(tmp_table) do
|
||||||
|
table.insert(needle,v)
|
||||||
|
end
|
||||||
|
|
||||||
local mem=ms.get_code_segment()
|
local mem=ms.get_code_segment()
|
||||||
local trg_offset=mem.uint8_t.find(needle,stoff)--maybe endoff=stoff+bignumber
|
print(mem.uint8_t:addr2idx(stoff))
|
||||||
|
print(mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff)))
|
||||||
|
local _,trg_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff),nil)--maybe endoff=stoff+bignumber
|
||||||
if trg_offset==nil then
|
if trg_offset==nil then
|
||||||
error("address for race_load not found")
|
error("address for race_load not found")
|
||||||
end
|
end
|
||||||
|
local call_data={0x90,0x90}
|
||||||
|
local _,data_offset=df.sizeof(self.data)
|
||||||
|
dfu.concatTables(call_data,dfu.makeCall(trg_offset+2,data_offset))
|
||||||
|
self.call_patch=dfu.BinaryPatch{pre_data=needle,data=call_data,address=trg_offset,name="custom_embark_call_patch"}
|
||||||
needle={0x83,0xc8,0xff} -- or eax, 0xFF
|
needle={0x83,0xc8,0xff} -- or eax, 0xFF
|
||||||
local caste_offset=mem.uint8_t.find(needle,trg_offset)
|
local _,caste_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(trg_offset),nil)
|
||||||
if caste_offset==nil or caste_offset-stoff>1000 then
|
if caste_offset==nil or caste_offset-stoff>1000 then
|
||||||
error("Caste change code not found or found too far!")
|
error("Caste change code not found or found too far!")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.disable_castes=dfu.BinaryPatch{pre_data={0x83,0xc8,0xff},data={0x90,0x90,0x90},address=caste_offset,name="custom_embark_caste_disable"}
|
||||||
|
self.disable_castes:apply()
|
||||||
|
self.dwarfcount=dfu.BinaryPatch{pre_data=dfu.dwordToTable(7),data=dfu.dwordToTable(#self.race_caste_data),address=stoff,name="custom_embark_embarkcount"}
|
||||||
|
self.dwarfcount:apply()
|
||||||
|
local caste_array=self:allocate("caste_array","uint16_t",#self.race_caste_data)
|
||||||
|
local race_array=self:allocate("race_array","uint16_t",#self.race_caste_data)
|
||||||
|
for k,v in ipairs(self.race_caste_data) do
|
||||||
|
caste_array[k-1]=v[2]
|
||||||
|
race_array[k-1]=v[1]
|
||||||
end
|
end
|
||||||
function MakeTable(modpos,modsize,names)
|
local race_array_off,caste_array_off
|
||||||
count=0
|
local _
|
||||||
castes={}
|
_,race_array_off=df.sizeof(race_array)
|
||||||
--print("Making table")
|
_,caste_array_off=df.sizeof(caste_array)
|
||||||
for _,line in pairs(names) do
|
self:set_marker_dword("race",caste_array_off) --hehe... mixed them up i guess...
|
||||||
--print("Line:"..line)
|
self:set_marker_dword("caste",race_array_off)
|
||||||
tpos=string.find(line,":")
|
|
||||||
if tpos~=nil then
|
|
||||||
--print("Was line:"..line)
|
|
||||||
table.insert(castes,tonumber(string.sub(line,tpos+1)))
|
|
||||||
line=string.sub(line,1,tpos-1)
|
|
||||||
--print("IS line:"..line)
|
|
||||||
else
|
|
||||||
table.insert(castes,-1)
|
|
||||||
end
|
|
||||||
if RaceTable[line] == nil then
|
|
||||||
error("Failure, "..line.." not found!")
|
|
||||||
end
|
|
||||||
--print("adding:"..line.." id:"..RaceTable[line])
|
|
||||||
engine.pokew(modpos+modsize+count*2,RaceTable[line]) -- add race
|
|
||||||
count = count + 1
|
|
||||||
end
|
|
||||||
i=0
|
|
||||||
for _,caste in pairs(castes) do
|
|
||||||
|
|
||||||
engine.pokew(modpos+modsize+count*2+i*2,caste) -- add caste
|
|
||||||
i= i+1
|
|
||||||
end
|
|
||||||
|
|
||||||
engine.poked(stoff,count)
|
self:move_to_df()
|
||||||
return count
|
self.call_patch:apply()
|
||||||
|
self.installed=true
|
||||||
end
|
end
|
||||||
function embark(names)
|
function CustomEmbark:uninstall()
|
||||||
RaceTable=RaceTable or BuildNameTable()
|
if self.installed then
|
||||||
mypos=engine.getmod('Embark')
|
self.call_patch:remove()
|
||||||
stoff=VersionInfo.getAddress('start_dwarf_count')
|
self.disable_castes:remove()
|
||||||
if mypos then --if mod already loaded
|
self.dwarfcount:remove()
|
||||||
print("Mod already loaded @:"..mypos.." just updating")
|
|
||||||
modpos=mypos
|
|
||||||
_,modsize=engine.loadobj('dfusion/embark/embark.o')
|
|
||||||
|
|
||||||
count=MakeTable(modpos,modsize,names) --just remake tables
|
|
||||||
else
|
|
||||||
|
|
||||||
_,tofind=df.sizeof(df.global.ui:_field("race_id"))
|
|
||||||
|
|
||||||
loc=offsets.find(stoff,0x0f,0xb7,0x0d,DWORD_,tofind) --MOVZX ECX,WORD PTR[]
|
|
||||||
|
|
||||||
print(string.format("found:%x",loc))
|
|
||||||
if((loc~=0)and(loc-stoff<1000)) then
|
|
||||||
loc2=offsets.find(loc,0x83,0xc8,0xff) -- or eax, ffffff (for caste)
|
|
||||||
if loc2== 0 then
|
|
||||||
error ("Location for caste nulling not found!")
|
|
||||||
end
|
|
||||||
engine.pokeb(loc2,0x90)
|
|
||||||
engine.pokeb(loc2+1,0x90)
|
|
||||||
engine.pokeb(loc2+2,0x90)
|
|
||||||
ModData=engine.installMod("dfusion/embark/embark.o","Embark",256)
|
|
||||||
modpos=ModData.pos
|
|
||||||
modsize=ModData.size
|
|
||||||
local castepos=modpos+engine.FindMarker(ModData,"caste")
|
|
||||||
local racepos=modpos+engine.FindMarker(ModData,"race")
|
|
||||||
count=MakeTable(modpos,modsize,names)
|
|
||||||
engine.poked(castepos,modpos+modsize) --fix array start for race
|
|
||||||
engine.poked(racepos,modpos+modsize+count*2) --fix array start for caste
|
|
||||||
print("sucess loading mod @:"..modpos)
|
|
||||||
-- build race vector after module.
|
|
||||||
|
|
||||||
|
|
||||||
--finaly poke in the call!
|
|
||||||
engine.pokeb(loc,0x90)
|
|
||||||
engine.pokeb(loc+1,0x90)
|
|
||||||
engine.pokeb(loc+2,0xe8)
|
|
||||||
engine.poked(loc+3,modpos-loc-7)
|
|
||||||
--engine.pokeb(loc+5,0x90)
|
|
||||||
|
|
||||||
SetExecute(modpos)
|
|
||||||
else
|
|
||||||
error("did not find patch location, failing...")
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -0,0 +1,2 @@
|
|||||||
|
-- a binary hack/plugin collection for df
|
||||||
|
|
@ -0,0 +1,53 @@
|
|||||||
|
-- lets you embark anywhere.
|
||||||
|
helpstring=[[ embark [-t|-d|-e|-h]
|
||||||
|
-t test if the patch can be applied
|
||||||
|
-d disable the patch if enabled
|
||||||
|
-e enable the patch if disabled
|
||||||
|
-h shows help
|
||||||
|
]]
|
||||||
|
args={...}
|
||||||
|
if args[1]=="-h" then
|
||||||
|
print(helpstring)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local ms=require("memscan")
|
||||||
|
local dfu=require("plugins.dfusion")
|
||||||
|
local patch
|
||||||
|
function embark() --windows only?
|
||||||
|
local seg=ms.get_code_segment()
|
||||||
|
local idx,off
|
||||||
|
local patch=dfu.patches.embark_anywhere
|
||||||
|
if patch~=nil then
|
||||||
|
return patch
|
||||||
|
else
|
||||||
|
idx,off=seg.uint8_t:find_one{0x66, 0x83, 0x7F ,0x1A ,0xFF,0x74,0x04}
|
||||||
|
if idx then
|
||||||
|
patch=dfu.BinaryPatch{name="embark_anywhere",pre_data={0x74,0x04},data={0x90,0x90},address=off+5}
|
||||||
|
return patch
|
||||||
|
else
|
||||||
|
qerror("Offset for embark patch not found!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
patch=embark()
|
||||||
|
if args[1]=="-t" then
|
||||||
|
if patch:test() and not patch.is_applied then
|
||||||
|
print("all okay, patch can be applied")
|
||||||
|
elseif patch.is_applied then
|
||||||
|
print("patch is currently applied, can be removed")
|
||||||
|
else
|
||||||
|
qerror("patch can't be applied")
|
||||||
|
end
|
||||||
|
elseif args[1]=="-d" then
|
||||||
|
if patch.is_applied then
|
||||||
|
patch:remove()
|
||||||
|
print("patch removed")
|
||||||
|
end
|
||||||
|
elseif args[1]=="-e" then
|
||||||
|
if not patch.is_applied then
|
||||||
|
patch:apply()
|
||||||
|
print("patch applied")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print(helpstring)
|
||||||
|
end
|
Loading…
Reference in New Issue