From ef4a45921457e3133d530f1438a7d26fc6144811 Mon Sep 17 00:00:00 2001 From: Warmist Date: Wed, 3 Aug 2011 17:59:06 +0300 Subject: [PATCH] Ported items plugin with more stuff --- plugins/Dfusion/include/hexsearch.h | 2 + plugins/Dfusion/luafiles/common.lua | 358 ++++++++++++++++++++++ plugins/Dfusion/luafiles/init.lua | 49 ++- plugins/Dfusion/luafiles/items/plugin.lua | 212 +++++++++++++ plugins/Dfusion/readme.txt | 23 +- plugins/Dfusion/src/hexsearch.cpp | 43 ++- plugins/Dfusion/src/lua_Hexsearch.cpp | 10 +- 7 files changed, 665 insertions(+), 32 deletions(-) create mode 100644 plugins/Dfusion/luafiles/items/plugin.lua diff --git a/plugins/Dfusion/include/hexsearch.h b/plugins/Dfusion/include/hexsearch.h index 335bfebde..b4ffb84d8 100644 --- a/plugins/Dfusion/include/hexsearch.h +++ b/plugins/Dfusion/include/hexsearch.h @@ -25,6 +25,8 @@ public: std::vector FindAll(); private: + bool Compare(int a,int b); + void ReparseArgs(); SearchArgType args_; uint64_t pos_,startpos_,endpos_; std::vector BadCharShifts,GoodSuffixShift; diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua index b80f70e3e..ca84b4f4f 100644 --- a/plugins/Dfusion/luafiles/common.lua +++ b/plugins/Dfusion/luafiles/common.lua @@ -17,6 +17,12 @@ offsets.load = function () end end offsets.load() + +STD_STRING=0 +DWORD=1 +WORD=2 +BYTE=3 + function GetTextRegion() local ranges=Process.getMemRanges() for k,v in pairs(ranges) do @@ -50,6 +56,358 @@ end engine=engine or {} engine.peekd=Process.readDWord engine.poked=Process.writeDWord +engine.peekb=Process.readByte +engine.pokeb=Process.writeByte +engine.peekw=Process.readWord +engine.pokew=Process.writeWord +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 + if rtype.off ==nil then + return engine.peekpattern(offset,rtype) + else + return engine.peek(rtype.off+offset,rtype.rtype) + end + end + if rtype==STD_STRING then + return engine.peekstr(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) + else + error("Invalid peek type") + return + end +end +function engine.poke(offset,rtype,val) + if type(rtype)=="table" then + if rtype.off ==nil then + return engine.pokepattern(offset,rtype,val) + else + return engine.poke(rtype.off+offset,rtype.rtype,val) + end + end + if rtype==STD_STRING then + return engine.pokestr(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) + else + error("Invalid poke type:"..tostring(rtype)) + return + end +end +function engine.sizeof(rtype) + if rtype==STD_STRING then + error("String has no constant size") + return + elseif rtype==DWORD then + return 4; + elseif rtype==WORD then + return 2; + elseif rtype==BYTE then + return 1; + else + error("Invalid sizeof type") + return + end +end +function engine.peekpattern(offset,pattern) + local ret={} + for k,v in pairs(pattern) do + --print("k:"..k.." v:"..type(v)) + if type(v)=="table" then + ret[k]=engine.peek(offset+v.off,v.rtype) + --print(k.." peeked:"..offset+v.off) + else + ret[k]=v + end + end + ret.__offset=offset + return ret +end +function engine.pokepattern(offset,pattern,val) + for k,v in pairs(pattern) do + --print("k:"..k.." v:"..type(v)) + if type(v)=="table" then + engine.poke(offset+v.off,v.rtype,val[k]) + end + end +end + + +it_menu={} +it_menu.__index=it_menu +function it_menu:add(name,func) + table.insert(self.items,{func,name}) +end +function it_menu:display() + print("Select choice (q exits):") + for p,c in pairs(self.items) do + print(p..")."..c[2]) + end + local ans + repeat + local r + r=io.stdin:read() + if r=='q' then return end + ans=tonumber(r) + + if ans==nil or not(ans<=table.maxn(self.items) and ans>0) then + print("incorrect choice") + end + + until ans~=nil and (ans<=table.maxn(self.items) and ans>0) + self.items[ans][1]() +end +function MakeMenu() + local ret={} + ret.items={} + setmetatable(ret,it_menu) + return ret +end + +function PrintPattern(loadedpattern) + for k,v in pairs(loadedpattern) do + if type(v)== "string" then + print(k.." "..v) + else + print(string.format("%s %d inhex:%x",k,v,v)) + end + end +end + +function printPattern(pattern) + local i=0; + local names={} + names[STD_STRING]="std_string (STD_STRING)" + names[DWORD]= "Double word (DWORD)" + names[WORD]= "Word (WORD)" + names[STD_STRING]="Byte (BYTE)" + ret={} + for k,v in pairs(pattern) do + if type(v)=="table" and v.off~=nil then + + if names[v.rtype]~=nil then + lname=names[v.rtype] + else + if type(v.rtype)=="table" then + lname="Table (prob subpattern)" + else + lname="Other" + end + end + print(string.format("%d. %s is %s with offset %x",i,k,lname,v.off)) + table.insert(ret,k) + else + print(string.format("%d. %s",i,k)) + end + i=i+1 + end + return ret; +end +function editPattern(offset,pattern,name) + if type(pattern[name].rtype)=="table" then + if pattern[name].rtype.setval~=nil then + print(string.format("%x",offset+pattern[name].off)) + local t=engine.peek(offset+pattern[name].off,pattern[name].rtype) + print("Value is now:"..t:getval()) + print("Enter new value:") + val=io.stdin:read() + t:setval(val) + else + ModPattern(offset+pattern[name].off,pattern[name].rtype) + end + return + end + val=engine.peek(offset,pattern[name]) + print("Value is now:"..val) + print("Enter new value:") + if pattern[name].rtype==STD_STRING then + val=io.stdin:read() + else + val=tonumber(io.stdin:read()) + end + engine.poke(offset,pattern[name],val) +end +function ModPattern(itemoffset,pattern) + print("Select what to edit:") + nm=printPattern(pattern) + q=tonumber(io.stdin:read()) + if q~=nil and q<#nm then + editPattern(itemoffset,pattern,nm[q+1]) + end +end + +function findVectors() + local text=GetTextRegion() + local h=hexsearch(text.start,text["end"],0x8b,ANYBYTE,ANYDWORD,0x8b,ANYBYTE,ANYDWORD,0x2b,ANYBYTE) + local pos=h:findall() + local T={} + for k,v in pairs(pos) do + local loc1,loc2 + loc1=engine.peekd(v+2) + loc2=engine.peekd(v+8) + --print(string.format("%x - %x=%x",loc1,loc2,loc1-loc2)) + if(math.abs(loc1-loc2)==4) then + if T[loc1-4]~=nil then + T[loc1-4]=T[loc1-4]+1 + else + T[loc1-4]=1 + end + end + end + return T +end + +function GetRaceToken(p) --actually gets token... + local vec=engine.peek(offsets.getEx('CreatureGloss'),ptr_vector) + local off=vec:getval(p) + local crgloss=engine.peek(off,ptr_CrGloss) + return crgloss.token:getval() +end +function BuildNameTable() + local rtbl={} + local vec=engine.peek(offsets.getEx('CreatureGloss'),ptr_vector) + --print(string.format("Vector start:%x",vec.st)) + --print(string.format("Vector end:%x",vec.en)) + --local i=0 + for p=0,vec:size()-1 do + local off=vec:getval(p) + --print("First member:"..off) + local name=engine.peek(off,ptt_dfstring) + --print("Loading:"..p.."="..name:getval()) + rtbl[name:getval()]=p + --i=i+1 + --if i>100 then + -- io.stdin:read() + -- i=0 + --end + end + return rtbl; +end +function BuildMaterialTable() + local rtbl={} + local vec=engine.peek(offsets.getEx('Materials'),ptr_vector) + --print(string.format("Vector start:%x",vec.st)) + --print(string.format("Vector end:%x",vec.en)) + --local i=0 + for p=0,vec:size()-1 do + local off=vec:getval(p) + --print("First member:"..off) + local name=engine.peek(off,ptt_dfstring) + --print("Loading:"..p.."="..name:getval()) + rtbl[name:getval()]=p + --i=i+1 + --if i>100 then + -- io.stdin:read() + -- i=0 + --end + end + return rtbl; +end +function BuildWordTables() + local names={} + local rnames={} + local vector=engine.peek(offsets.getEx('WordVec'),ptr_vector) +for i =0,vector:size()-1 do + local off=vector:getval(i) + local n=engine.peekstr(off) + names[i]=n + rnames[n]=i +end + return names,rnames +end +function ParseScript(file) + + io.input(file) + f="" + first=0 + nobraces=0 + function updFunction() + if f~="" then + first=0 + if nobraces==0 then + f=f.."}" + end + nobraces=0 + print("Doing:"..f) + assert(loadstring(f))() + + f="" + end + end + while true do + + local line = io.read("*line") + if line == nil then break end + if string.sub(line,1,2)==">>" then + updFunction() + if string.find(line,"%b()") then + f=string.sub(line,3) + nobraces=1 + else + f=string.sub(line,3).."{" + end + --print(string.sub(line,3)..) + else + if first~=0 then + f=f.."," + else + first=1 + end + f=f..string.format('%q',line) + + end + + end + updFunction() +end +function ParseNames(path) + local ret={} + local ff=io.open(path) + for n in ff:lines() do + table.insert(ret,n) + end + return ret +end + +function getxyz() -- this will return pointers x,y and z coordinates. + local off=offsets.getEx("Xpointer") -- lets find where in memory its being held + -- now lets read them (they are double words (or unsigned longs or 4 bits each) and go in sucesion + local x=engine.peekd(off) + local y=engine.peekd(off+4) --next is 4 from start + local z=engine.peekd(off+8) --next is 8 from start + --print("Pointer @:"..x..","..y..","..z) + return x,y,z -- return the coords +end +function GetCreatureAtPos(x,y,z) -- gets the creature index @ x,y,z coord + --local x,y,z=getxyz() --get 'X' coords + local vector=engine.peek(offsets.getEx("AdvCreatureVec"),ptr_vector) -- load all creatures + for i = 0, vector:size() do -- look into all creatures offsets + local curoff=vector:getval(i) -- get i-th creatures offset + local cx=engine.peek(curoff,ptr_Creature.x) --get its coordinates + local cy=engine.peek(curoff,ptr_Creature.y) + local cz=engine.peek(curoff,ptr_Creature.z) + if cx==x and cy==y and cz==z then --compare them + return i --return index + end + end + print("Creature not found!") + return -1 + +end dofile("dfusion/patterns.lua") dofile("dfusion/patterns2.lua") diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index fd345397c..ff088daa4 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -10,31 +10,30 @@ function dofile(filename) --safer dofile, with traceback (very usefull) print(perr) end end -dofile("dfusion/common.lua") - -print("Unlocking Df .text section...") ---unlockDF() -print("Done unlock") -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) -function OnTick() -- floods the console - r=Console.get_rows() - c=Console.get_columns() +function mainmenu(t1) Console.clear() - Console.gotoxy(math.random(1,r),math.random(1,2)) - Console.color(math.random(0,15)) - Console.print("*") + while true do + print("No. Name Desc") + for k,v in pairs(t1) do + print(string.format("%d %s %s",k,v[1],v[2])) + end + local q=Console.lineedit("Select plugin to run (q to quit):") + if q=='q' then return end + q=tonumber(q) + if q~=nil then + if q>=1 and q<=#t1 then + dofile("dfusion/"..t1[q][1].."/plugin.lua") + + end + end + end end -OnTick=nil \ No newline at end of file +dofile("dfusion/common.lua") +unlockDF() +plugins={} +table.insert(plugins,{"simple_embark","A simple embark dwarf count editor"}) +table.insert(plugins,{"items","A collection of item hacking tools"}) + +mainmenu(plugins) + diff --git a/plugins/Dfusion/luafiles/items/plugin.lua b/plugins/Dfusion/luafiles/items/plugin.lua new file mode 100644 index 000000000..8b92785bd --- /dev/null +++ b/plugins/Dfusion/luafiles/items/plugin.lua @@ -0,0 +1,212 @@ +items={} --> first lets make a menu table +items.menu=MakeMenu() + + +function items.dest() + myoff=offsets.getEx("Items") -- first find out where "item vector" is + vector=engine.peek(myoff,ptr_vector) -- get list of items + for i=0,vector:size()-1 do --look at each item + flg=engine.peek(vector:getval(i),ptr_item.flags) + flg:set(17,1) + engine.poke(vector:getval(i),ptr_item.flags,flg) + end +end +function items.eggs() + myoff=offsets.getEx("Items") -- first find out where "item vector" is + vector=engine.peek(myoff,ptr_vector) -- get list of items + for i=0,vector:size()-1 do --look at each item + rti=engine.peek(vector:getval(i),ptr_item.RTI) + if ptr_item.getname(nil,rti)=="item_eggst" then + egg=engine.peek(vector:getval(i),ptr_subitems["item_eggst"]) + egg.isfertile=1 + egg.hatchtime=0xffffff + --egg.race=123 -- change race for fun times + engine.poke(vector:getval(i),ptr_subitems["item_eggst"],egg) + end + end +end +function editFlags(offset) + while true do + flags=engine.peek(offset,ptr_item.flags) + for i=0,8*8-1 do + if flags:get(i) then + print(i.." is true") + else + print(i.." is false") + end + end + print(" enter number to switch flag or not a number to quit:") + q=tonumber(io.stdin:read()) + if q==nil then return end + flags:flip(q) + engine.poke(offset,ptr_item.flags,flags) + end +end +function editCovering(offset) + off=engine.peek(offset,ptr_item.ptr_covering) + if off == 0 then + print("No coverings found.") + end + vec=engine.peek(off,ptr_vector) + print("Covering list:") + for i=0,vec:size()-1 do + cov=engine.peek(vec:getval(i),ptr_cover) + print(string.format("%d. mat=%d submat=%d state=%d",i,cov.mat,cov.submat,cov.state)) + end + print("To edit type number:") + q=tonumber(io.stdin:read()) + if q==nil then return end + if q>=vec:size() or q<0 then return end + off=vec:getval(q) + cov=engine.peek(off,ptr_cover) + print("Enter mat:") + q=tonumber(io.stdin:read()) + if q==nil then q=0xffff end + print("Enter submat:") + v=tonumber(io.stdin:read()) + if v==nil then v=0xffff end + print("Enter state:") + y=tonumber(io.stdin:read()) + if y==nil then y=0 end + cov.mat=q + cov.submat=v + cov.state=y + engine.poke(off,ptr_cover,cov) +end +function editMaterial(offset) + print("Mat id 0 to 18 is in normal materials (inorganic, amber etc...) after that creature mat (with submat2 being race)") + print("from 219 with submat2=0xffffffff (type not a number) it reads legends id, from 419 submat2 means plant id") + print("Probably submat is not used :? ") + mat=engine.peek(offset,ptr_item.mat) + submat=engine.peek(offset,ptr_item.submat) + submat2=engine.peek(offset,ptr_item.submat2) + lid=engine.peek(offset,ptr_item.legendid) + print(string.format("Now is mat=%d, submat=%d submat2=%d legend id=%d",mat,submat,submat2,lid)) + print("Enter mat:") + q=tonumber(io.stdin:read()) + if q==nil then return end + print("Enter submat:") + v=tonumber(io.stdin:read()) + if v==nil then v=0xffff end + print("Enter submat2:") + z=tonumber(io.stdin:read()) + if z==nil then z=0xffffffff end + print("Enter legendid:") + y=tonumber(io.stdin:read()) + if y==nil then y=0xffffffff end + engine.poke(offset,ptr_item.mat,q) + engine.poke(offset,ptr_item.submat,v) + engine.poke(offset,ptr_item.legendid,y) + engine.poke(offset,ptr_item.submat2,z) + print("Done") +end +function items.select() + myoff=offsets.getEx("Items") + vector=engine.peek(myoff,ptr_vector) + tx,ty,tz=getxyz() + T={} + for i=0,vector:size()-1 do --this finds all item offsets that are on pointer + itoff=vector:getval(i) + x=engine.peek(itoff,ptr_item.x) + y=engine.peek(itoff,ptr_item.y) + z=engine.peek(itoff,ptr_item.z) + if x==tx and y==ty and z==tz then + table.insert(T,itoff) + end + end + print("Items under cursor:") + i=1 + for _,v in pairs(T) do + RTI=engine.peek(v,ptr_item.RTI) + print(i..". "..ptr_item.getname(nil,RTI)) + i=i+1 + end + print("Type number to edit or 'q' to exit") + while true do + q=io.stdin:read() + if q=='q' then return end + if tonumber(q) ~=nil and tonumber(q)readByte(pos_,buf[0]); - if(buf[0]==args_[0]) //TODO make a comparator + if(Compare(buf[0],args_[0])) { p->read(pos_,args_.size(),buf); for(size_t i=0;i pos=p->FindAll(); st.newtable(); - for(int i=0;i::Register(st); - -} \ No newline at end of file + __ADDCONST(ANYBYTE); + __ADDCONST(ANYDWORD); + __ADDCONST(DWORD_); +} +#undef __ADDCONST \ No newline at end of file