From ab448d4109fcf2dfec41e6174f2ffd9a7a4e8cf7 Mon Sep 17 00:00:00 2001 From: Warmist Date: Sat, 17 Sep 2011 14:59:10 +0300 Subject: [PATCH] Small fixes + lua_bit lib (fixes flag manipulations) --- library/include/dfhack/VersionInfo.h | 2 +- plugins/Dfusion/dfusion.cpp | 5 +- plugins/Dfusion/include/bit.h | 17 ++ plugins/Dfusion/include/lua_Misc.h | 1 + plugins/Dfusion/luafiles/common.lua | 55 ++++-- plugins/Dfusion/luafiles/friendship/patch.lua | 2 + plugins/Dfusion/luafiles/init.lua | 2 +- plugins/Dfusion/luafiles/offsets_misc.lua | 10 +- .../Dfusion/luafiles/onfunction/locations.lua | 1 + plugins/Dfusion/src/bit.c | 181 ++++++++++++++++++ plugins/Dfusion/src/lua_Misc.cpp | 1 + 11 files changed, 251 insertions(+), 26 deletions(-) create mode 100644 plugins/Dfusion/include/bit.h create mode 100644 plugins/Dfusion/src/bit.c diff --git a/library/include/dfhack/VersionInfo.h b/library/include/dfhack/VersionInfo.h index f230f00b0..dc084eaae 100644 --- a/library/include/dfhack/VersionInfo.h +++ b/library/include/dfhack/VersionInfo.h @@ -31,7 +31,7 @@ distribution. #include "dfhack/Pragma.h" #include "dfhack/Export.h" #include "dfhack/Types.h" -#include +#include #include #include diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index 514a5509d..7aa4aba84 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -155,8 +155,11 @@ void RunDfusion(void *p) lua::state s=lua::glua::Get(); try{ + s.getglobal("err"); + int errpos=s.gettop(); s.loadfile("dfusion/init.lua"); //load script - s.pcall(0,0);// run it + + s.pcall(0,0,errpos);// run it } catch(lua::exception &e) { diff --git a/plugins/Dfusion/include/bit.h b/plugins/Dfusion/include/bit.h new file mode 100644 index 000000000..b75fdf05c --- /dev/null +++ b/plugins/Dfusion/include/bit.h @@ -0,0 +1,17 @@ +#ifndef BIT_H +#define BIT_H + +#define LUA_BITOP_VERSION "1.0.1" + +#define LUA_LIB +#include "lua.h" +#include "lauxlib.h" +#ifdef __cplusplus + extern "C" { +#endif +LUALIB_API int luaopen_bit(lua_State *L); +#ifdef __cplusplus + } +#endif +#endif // BIT_H + diff --git a/plugins/Dfusion/include/lua_Misc.h b/plugins/Dfusion/include/lua_Misc.h index 6f1416257..fa4dc404c 100644 --- a/plugins/Dfusion/include/lua_Misc.h +++ b/plugins/Dfusion/include/lua_Misc.h @@ -7,6 +7,7 @@ #include #include "luamain.h" #include "OutFile.h" +#include "bit.h" namespace lua { diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua index 55c3793f2..ce7eb1485 100644 --- a/plugins/Dfusion/luafiles/common.lua +++ b/plugins/Dfusion/luafiles/common.lua @@ -4,7 +4,11 @@ DWORD=1 WORD=2 BYTE=3 function GetTextRegion() - ranges__=ranges__ or Process.getMemRanges() + if __TEXT ~=nil then --Chache this, not going to change. + return __TEXT + end + + ranges__=Process.getMemRanges() --print("Ranges:"..#ranges__) for k,v in pairs(ranges__) do --for k2,v2 in pairs(v) do @@ -20,31 +24,27 @@ function GetTextRegion() --end local pos=string.find(v.name,".text") or string.find(v.name,"libs/Dwarf_Fortress") if(pos~=nil) and v["execute"] then + __TEXT=v; return v; end end - return nil + error(".Text region not found!") +end +function UpdateRanges() + ranges__=Process.getMemRanges() end function GetRegionIn(pos) - ranges__= Process.getMemRanges() + ranges__=ranges__ or 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 %x",k,v["start"],v["end"],v.name,pos)) - if pos>=v.start and pos<=v["end"] then + if pos>=v.start and pos%s",k,tostring(k2),tostring(v2))) @@ -54,12 +54,22 @@ function ValidOffset(pos) --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)) - if pos>=v.start and pos<=v["end"] then - return true + --print(string.format("%d %x->%x %s %x",k,v["start"],v["end"],v.name,pos)) + if pos>=v.start then --This is a hack to counter .text region suddenly shrinking. + if cr~=nil then + if v.start < cr.start then -- find region that start is closest + cr=v + end + else + cr=v + end end end - return false + return cr +end +function ValidOffset(pos) + ranges__=ranges__ or Process.getMemRanges() + return GetRegionIn(pos)~=nil end function unlockDF() local reg=GetTextRegion() @@ -72,6 +82,7 @@ function lockDF() Process.setPermisions(reg,reg) end function SetExecute(pos) + UpdateRanges() local reg=GetRegionIn(pos) reg.execute=true Process.setPermisions(reg,reg) -- TODO maybe make a page with only execute permisions or sth @@ -302,15 +313,18 @@ function ModPattern(itemoffset,pattern) end function findVectors() + if __VECTORS ~=nil then --chache + return __VECTORS + end local text=GetTextRegion() - local h=hexsearch(text.start,text["end"],0x8b,ANYBYTE,ANYDWORD,0x8b,ANYBYTE,ANYDWORD,0x2b,ANYBYTE) + local h=hexsearch(text.start,text["end"],0x8b,ANYBYTE,ANYDWORD,0x8b,ANYBYTE,ANYDWORD,0x2b) 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)) + print(string.format("%x - %x=%x",loc1,loc2,loc1-loc2)) if(loc1-loc2==4) then if T[loc1-4]~=nil then T[loc1-4]=T[loc1-4]+1 @@ -319,6 +333,7 @@ function findVectors() end end end + __VECTORS=T return T end diff --git a/plugins/Dfusion/luafiles/friendship/patch.lua b/plugins/Dfusion/luafiles/friendship/patch.lua index 0ae236dc5..3c4f3738a 100644 --- a/plugins/Dfusion/luafiles/friendship/patch.lua +++ b/plugins/Dfusion/luafiles/friendship/patch.lua @@ -1,4 +1,5 @@ function friendship_in.patch() + UpdateRanges() pos=GetTextRegion().start local crace=VersionInfo.getGroup("Creatures"):getAddress("current_race") hits={} @@ -24,6 +25,7 @@ function friendship_in.patch() repeat --print(string.format("Analyzing %x...",p)) + --TODO read offset from memory.xml pos1=offsets.find(myp,0x39,ANYBYTE,0x8c,00,00,00) -- compare [reg+08c] (creature race) with any reg pos2=offsets.find(myp,0x3b,ANYBYTE,0x8c,00,00,00) -- compare any reg with [reg+08c] (creature race) pos=minEx(pos1,pos2) diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index d5d067ea6..427682e45 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -25,7 +25,7 @@ function loadall(t1) --loads all non interactive plugin parts, so that later the end end function mainmenu(t1) - Console.clear() + --Console.clear() while true do print("No. Name Desc") for k,v in pairs(t1) do diff --git a/plugins/Dfusion/luafiles/offsets_misc.lua b/plugins/Dfusion/luafiles/offsets_misc.lua index 80f420baa..01460dc48 100644 --- a/plugins/Dfusion/luafiles/offsets_misc.lua +++ b/plugins/Dfusion/luafiles/offsets_misc.lua @@ -59,8 +59,8 @@ function offsets.searchoffsets(forcelazy) end end function offsets.find(startoffset,...) - local endadr; - if startoffset== 0 then + local endadr=GetTextRegion()["end"]; + --[=[if startoffset== 0 then local text=GetTextRegion() --print("searching in:"..text.name) startoffset=text.start @@ -68,8 +68,12 @@ function offsets.find(startoffset,...) else local reg=GetRegionIn(startoffset) --print("searching in:"..reg.name) + if reg==nil then + print(string.format("Warning: memory range for search @:%x not found!",startoffset)) + return 0 + end endadr=reg["end"] - end + end--]=] --print(string.format("Searching (%x->%x)",startoffset,endadr)) local h=hexsearch(startoffset,endadr,...) local pos=h:find() diff --git a/plugins/Dfusion/luafiles/onfunction/locations.lua b/plugins/Dfusion/luafiles/onfunction/locations.lua index 2f6e4d80c..4417990e2 100644 --- a/plugins/Dfusion/luafiles/onfunction/locations.lua +++ b/plugins/Dfusion/luafiles/onfunction/locations.lua @@ -1,6 +1,7 @@ if WINDOWS then --windows function defintions onfunction.AddFunction(0x55499D+offsets.base(),"Move") --on creature move found with "watch mem=xcoord" onfunction.AddFunction(0x275933+offsets.base(),"Die",{creature="edi"}) --on creature death? found by watching dead flag then stepping until new function + onfunction.AddFunction(0x2c1834+offsets.base(),"CreateCreature",{protocreature="eax"}) --arena else --linux onfunction.AddFunction(0x899befe+offsets.base(),"Move") -- found out by attaching watch... onfunction.AddFunction(0x850eecd+offsets.base(),"Die",{creature="ebx"}) -- same diff --git a/plugins/Dfusion/src/bit.c b/plugins/Dfusion/src/bit.c new file mode 100644 index 000000000..9f2d6f5a2 --- /dev/null +++ b/plugins/Dfusion/src/bit.c @@ -0,0 +1,181 @@ +/* +** Lua BitOp -- a bit operations library for Lua 5.1. +** http://bitop.luajit.org/ +** +** Copyright (C) 2008-2009 Mike Pall. All rights reserved. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +** [ MIT license: http://www.opensource.org/licenses/mit-license.php ] +*/ + +#include "bit.h" +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef _MSC_VER +/* MSVC is stuck in the last century and doesn't have C99's stdint.h. */ +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +#else +#include +#endif + +typedef int32_t SBits; +typedef uint32_t UBits; + +typedef union { + lua_Number n; +#ifdef LUA_NUMBER_DOUBLE + uint64_t b; +#else + UBits b; +#endif +} BitNum; + +/* Convert argument to bit type. */ +static UBits barg(lua_State *L, int idx) +{ + BitNum bn; + UBits b; + bn.n = lua_tonumber(L, idx); +#if defined(LUA_NUMBER_DOUBLE) + bn.n += 6755399441055744.0; /* 2^52+2^51 */ +#ifdef SWAPPED_DOUBLE + b = (UBits)(bn.b >> 32); +#else + b = (UBits)bn.b; +#endif +#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \ + defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \ + defined(LUA_NUMBER_LLONG) + if (sizeof(UBits) == sizeof(lua_Number)) + b = bn.b; + else + b = (UBits)(SBits)bn.n; +#elif defined(LUA_NUMBER_FLOAT) +#error "A 'float' lua_Number type is incompatible with this library" +#else +#error "Unknown number type, check LUA_NUMBER_* in luaconf.h" +#endif + if (b == 0 && !lua_isnumber(L, idx)) + luaL_typerror(L, idx, "number"); + return b; +} + +/* Return bit type. */ +#define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1; + +static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) } +static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) } + +#define BIT_OP(func, opr) \ + static int func(lua_State *L) { int i; UBits b = barg(L, 1); \ + for (i = lua_gettop(L); i > 1; i--) b opr barg(L, i); BRET(b) } +BIT_OP(bit_band, &=) +BIT_OP(bit_bor, |=) +BIT_OP(bit_bxor, ^=) + +#define bshl(b, n) (b << n) +#define bshr(b, n) (b >> n) +#define bsar(b, n) ((SBits)b >> n) +#define brol(b, n) ((b << n) | (b >> (32-n))) +#define bror(b, n) ((b << (32-n)) | (b >> n)) +#define BIT_SH(func, fn) \ + static int func(lua_State *L) { \ + UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) } +BIT_SH(bit_lshift, bshl) +BIT_SH(bit_rshift, bshr) +BIT_SH(bit_arshift, bsar) +BIT_SH(bit_rol, brol) +BIT_SH(bit_ror, bror) + +static int bit_bswap(lua_State *L) +{ + UBits b = barg(L, 1); + b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24); + BRET(b) +} + +static int bit_tohex(lua_State *L) +{ + UBits b = barg(L, 1); + SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2); + const char *hexdigits = "0123456789abcdef"; + char buf[8]; + int i; + if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } + if (n > 8) n = 8; + for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; } + lua_pushlstring(L, buf, (size_t)n); + return 1; +} + +static const struct luaL_Reg bit_funcs[] = { + { "tobit", bit_tobit }, + { "bnot", bit_bnot }, + { "band", bit_band }, + { "bor", bit_bor }, + { "bxor", bit_bxor }, + { "lshift", bit_lshift }, + { "rshift", bit_rshift }, + { "arshift", bit_arshift }, + { "rol", bit_rol }, + { "ror", bit_ror }, + { "bswap", bit_bswap }, + { "tohex", bit_tohex }, + { NULL, NULL } +}; + +/* Signed right-shifts are implementation-defined per C89/C99. +** But the de facto standard are arithmetic right-shifts on two's +** complement CPUs. This behaviour is required here, so test for it. +*/ +#define BAD_SAR (bsar(-8, 2) != (SBits)-2) + +LUALIB_API int luaopen_bit(lua_State *L) +{ + UBits b; + lua_pushnumber(L, (lua_Number)1437217655L); + b = barg(L, -1); + if (b != (UBits)1437217655L || BAD_SAR) { /* Perform a simple self-test. */ + const char *msg = "compiled with incompatible luaconf.h"; +#ifdef LUA_NUMBER_DOUBLE +#ifdef _WIN32 + if (b == (UBits)1610612736L) + msg = "use D3DCREATE_FPU_PRESERVE with DirectX"; +#endif + if (b == (UBits)1127743488L) + msg = "not compiled with SWAPPED_DOUBLE"; +#endif + if (BAD_SAR) + msg = "arithmetic right-shift broken"; + luaL_error(L, "bit library self-test failed (%s)", msg); + } + luaL_register(L, "bit", bit_funcs); + return 1; +} +#ifdef __cplusplus + } +#endif + + diff --git a/plugins/Dfusion/src/lua_Misc.cpp b/plugins/Dfusion/src/lua_Misc.cpp index 269f38ee9..c6d33dc3c 100644 --- a/plugins/Dfusion/src/lua_Misc.cpp +++ b/plugins/Dfusion/src/lua_Misc.cpp @@ -188,4 +188,5 @@ void lua::RegisterMisc(lua::state &st) } lua::RegFunctionsLocal(st, lua_misc_func); st.setglobal("engine"); + luaopen_bit(st); }