Lots of changes, including hexsearch and wrapper for lua, also LUNE - an object oriented lua wrapper
parent
ff4d545ae7
commit
f4179652fa
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef HEXSEARCH_H
|
||||||
|
#define HEXSEARCH_H
|
||||||
|
#include <vector>
|
||||||
|
#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<int> 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<uint64_t> FindAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SearchArgType args_;
|
||||||
|
uint64_t pos_,startpos_,endpos_;
|
||||||
|
std::vector<int> BadCharShifts,GoodSuffixShift;
|
||||||
|
void PrepareGoodSuffixTable();
|
||||||
|
void PrepareBadCharShift();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -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
|
@ -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 <string>
|
||||||
|
|
||||||
|
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="<<myref<<"\n";
|
||||||
|
//mytbl->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="<<myref<<"\n";
|
||||||
|
//StackDump(myst);
|
||||||
|
//LOG<<"Tbl preget\n";
|
||||||
|
mytbl->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 <typename T,bool GC=true>
|
||||||
|
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 \""<<T::className<<"\"\n";
|
||||||
|
// fill method table with methods from class T
|
||||||
|
for (RegType *l = T::methods; l->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 \""<<l->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<userdataType*>(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:"<<id<<"stack dump:\n";
|
||||||
|
//lua::StackDump(L);
|
||||||
|
luaL_unref(L,ins,id);
|
||||||
|
}
|
||||||
|
static int index_T(lua_State *L) // calls with (table, key), return value
|
||||||
|
{
|
||||||
|
lua::state st(L);
|
||||||
|
string key=st.as<string>(-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<lua::nil>()) //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_gettop(L)<<"\n";
|
||||||
|
//lua::StackDump(L);
|
||||||
|
if(lua_gettop(L)<1)
|
||||||
|
luaL_error(L,"Member function called without 'self'");
|
||||||
|
//LOG<<"Size of stack after:"<<lua_gettop(L)<<"\n";
|
||||||
|
// stack has userdata, followed by method args
|
||||||
|
T *obj = check(L, 1); // get 'self', or if you prefer, 'this'
|
||||||
|
//T *obj=static_cast<userdataType*>(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<RegType*>(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<userdataType*>(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_gettop(L)<<"\n";
|
||||||
|
//lua::StackDump(L);
|
||||||
|
lua_remove(L, 1); // use classname:new(), instead of classname.new()
|
||||||
|
//lua_newtable(L);
|
||||||
|
int id=RegTable(L);
|
||||||
|
//LOG<<"Registred as:"<<id<<"\n";
|
||||||
|
//int ssize=lua_gettop(L);
|
||||||
|
T *obj = new T(L,id); // call constructor for T objects
|
||||||
|
lua_settop(L,0); //no need for parameters later.
|
||||||
|
//LOG<<"Post build:"<<lua_gettop(L)<<"\t";
|
||||||
|
//lua::StackDump(L);
|
||||||
|
//LOG<<"TSOP\n";
|
||||||
|
|
||||||
|
userdataType *ud =
|
||||||
|
static_cast<userdataType*>(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<class>::RegType methods[];
|
||||||
|
#define DEF_LUNE_NOGC(class) static const char className[];\
|
||||||
|
static Lune<class,false>::RegType methods[];
|
||||||
|
#define IMP_LUNE(class,lua_name) const char class::className[]=#lua_name;
|
||||||
|
#define LUNE_METHODS_START(class) Lune<class>::RegType class::methods[] = {
|
||||||
|
#define LUNE_METHODS_START_NOGC(class) Lune<class,false>::RegType class::methods[] = {
|
||||||
|
#define LUNE_METHODS_END() {0,0}}
|
||||||
|
#endif // LUNE_H
|
@ -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}
|
@ -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}
|
@ -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
|
@ -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_<endpos_)
|
||||||
|
{
|
||||||
|
bool found=true;
|
||||||
|
p->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<args_.size();i++)
|
||||||
|
{
|
||||||
|
if(buf[i]!=args_[i])
|
||||||
|
{
|
||||||
|
pos_+=i;
|
||||||
|
found=false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(found)
|
||||||
|
{
|
||||||
|
pos_+=args_.size();
|
||||||
|
delete [] buf;
|
||||||
|
return pos_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos_++;
|
||||||
|
}
|
||||||
|
delete [] buf;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint64_t> Hexsearch::FindAll()
|
||||||
|
{
|
||||||
|
std::vector<uint64_t> 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);
|
||||||
|
|
||||||
|
}
|
@ -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<uint64_t> pos=p->FindAll();
|
||||||
|
st.newtable();
|
||||||
|
for(int i=0;i<pos.size();i++)
|
||||||
|
{
|
||||||
|
st.push(i+1);
|
||||||
|
st.push(pos[i]);
|
||||||
|
st.settable();
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
lua::Hexsearch::Hexsearch(lua_State *L,int id):tblid(id)
|
||||||
|
{
|
||||||
|
lua::state st(L);
|
||||||
|
uint64_t start,end;
|
||||||
|
::Hexsearch::SearchArgType args;
|
||||||
|
start=st.as<uint32_t>(2);
|
||||||
|
end=st.as<uint32_t>(3);
|
||||||
|
for(int i=4;i<st.gettop();i++)
|
||||||
|
{
|
||||||
|
args.push_back(st.as<int>(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<lua::Hexsearch>::Register(st);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
#include "lune.h"
|
||||||
|
lua::object *lua::local_object::mytbl=0;
|
Loading…
Reference in New Issue