develop
commit
a36d8b0619
@ -0,0 +1,13 @@
|
||||
#ifndef LUA_OFFSETS_H
|
||||
#define LUA_OFFSETS_H
|
||||
#include "luamain.h"
|
||||
|
||||
namespace lua
|
||||
{
|
||||
|
||||
void RegisterEngine(lua::state &st);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,13 @@
|
||||
#ifndef LUA_PROCESS_H
|
||||
#define LUA_PROCESS_H
|
||||
|
||||
#include <dfhack/Core.h>
|
||||
#include <dfhack/Process.h>
|
||||
|
||||
#include "luamain.h"
|
||||
|
||||
namespace lua
|
||||
{
|
||||
void RegisterProcess(lua::state &st,DFHack::Process *p);
|
||||
}
|
||||
#endif
|
@ -0,0 +1,61 @@
|
||||
offsets=offsets or {}
|
||||
offsets._toff={}
|
||||
offsets.get = function (name)
|
||||
return offsets._toff[name]
|
||||
end
|
||||
offsets.getEx = function (name)
|
||||
return offsets._toff[name]+Process.getBase()
|
||||
end
|
||||
offsets.load = function ()
|
||||
local f=io.open("dfusion/offsets.txt")
|
||||
local line=f:read()
|
||||
while line~=nil do
|
||||
--print(line)
|
||||
local sppliter=string.find(line,":")
|
||||
offsets._toff[string.sub(line,1,sppliter-2)]=tonumber(string.sub(line,sppliter+2))
|
||||
line=f:read()
|
||||
end
|
||||
end
|
||||
offsets.load()
|
||||
function unlockDF()
|
||||
local ranges=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 %d",k,v["start"],v["end"],v.name,num))
|
||||
local pos=string.find(v.name,".text")
|
||||
if pos~=nil then
|
||||
v["write"]=true
|
||||
Process.setPermisions(v,v)
|
||||
end
|
||||
end
|
||||
end
|
||||
function lockDF()
|
||||
local ranges=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 %d",k,v["start"],v["end"],v.name,num))
|
||||
local pos=string.find(v.name,".text")
|
||||
if pos~=nil then
|
||||
v["write"]=false
|
||||
Process.setPermisions(v,v)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- engine bindings
|
||||
engine=engine or {}
|
||||
engine.peekd=Process.readDWord
|
||||
engine.poked=Process.writeDWord
|
@ -0,0 +1,33 @@
|
||||
function err(msg) --make local maybe...
|
||||
print(msg)
|
||||
print(debug.traceback())
|
||||
end
|
||||
function dofile(filename) --safer dofile, with traceback (very usefull)
|
||||
f,perr=loadfile(filename)
|
||||
if f~=nil then
|
||||
return xpcall(f,err)
|
||||
else
|
||||
print(perr)
|
||||
end
|
||||
end
|
||||
dofile("dfusion/common.lua")
|
||||
|
||||
print("Unlocking Df .text section...")
|
||||
unlockDF()
|
||||
print("Done unlock")
|
||||
lockDF()
|
||||
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()
|
||||
Console.clear()
|
||||
Console.gotoxy(math.random(1,r),math.random(1,2))
|
||||
Console.color(math.random(0,15))
|
||||
Console.print("*")
|
||||
end
|
||||
OnTick=nil
|
@ -0,0 +1,15 @@
|
||||
AdvCreatureVec : 0x12c44ac
|
||||
CreatureGloss : 0x1308040
|
||||
CreaturePtr : 0xaf2430
|
||||
CreatureVec : 0x12c44ac
|
||||
CurrentRace : 0x10f0c28
|
||||
Items : 0x12c4550
|
||||
Legends : 0x12c451c
|
||||
Materials : 0x1307f50
|
||||
PlayerLegend : 0x145bfec
|
||||
SiteData : 0x1307778
|
||||
StartDwarfs : 0x518332
|
||||
WordVec : 0x1308254
|
||||
WorldData : 0x1306148
|
||||
Xpointer : 0x7347f0
|
||||
vtableLegends : 0x6e7594
|
@ -0,0 +1,15 @@
|
||||
function simple_embark(num)
|
||||
stoff=offsets.getEx('StartDwarfs')
|
||||
print("Starting dwarves found:"..engine.peekd(stoff))
|
||||
engine.poked(stoff,num)
|
||||
end
|
||||
if not(FILE) then
|
||||
print("Type in new ammount:")
|
||||
repeat
|
||||
ans=tonumber(io.read())
|
||||
if ans==nil or not(ans<=15000 and ans>0) then
|
||||
print("incorrect choice")
|
||||
end
|
||||
until ans~=nil and (ans<=15000 and ans>0)
|
||||
simple_embark(ans)
|
||||
end
|
@ -0,0 +1,19 @@
|
||||
Dfusion command runs file <df dir>\dfusion\init.lua
|
||||
Other than std lua commands supported:
|
||||
* Console.
|
||||
print(string)
|
||||
printerr(string)
|
||||
clear()
|
||||
gotoxy(x,y)
|
||||
color(int) //TODO add id's, use numbers upto 16 for now
|
||||
reset_color()
|
||||
cursor(true/false)
|
||||
msleep(int)
|
||||
get_columns()
|
||||
get_rows()
|
||||
lineedit(string) //text input through console
|
||||
history_add(string) // adds string to console history
|
||||
|
||||
Functions searched:
|
||||
OnTick()
|
||||
If defined is called each DFHack tick.
|
@ -0,0 +1,156 @@
|
||||
#include "lua_Offsets.h"
|
||||
//TODO make a seperate module with peeks/pokes and page permisions (linux/windows spec)
|
||||
unsigned char peekb(size_t offset)
|
||||
{
|
||||
return *((unsigned char*)(offset));
|
||||
}
|
||||
unsigned short peekw(size_t offset)
|
||||
{
|
||||
return *((unsigned short*)(offset));
|
||||
}
|
||||
unsigned peekd(size_t offset)
|
||||
{
|
||||
return *((unsigned*)(offset));
|
||||
}
|
||||
void peekarb(size_t offset, void *mem,size_t size)
|
||||
{
|
||||
memcpy(mem,(void*)offset,size);
|
||||
}
|
||||
void peekstr(size_t offset, char* buf, size_t maxsize)
|
||||
{
|
||||
strcpy_s(buf,maxsize,(char*)offset);
|
||||
}
|
||||
void pokeb(size_t offset,unsigned char val)
|
||||
{
|
||||
*((unsigned char*)(offset))=val;
|
||||
}
|
||||
void pokew(size_t offset,unsigned short val)
|
||||
{
|
||||
*((unsigned short*)(offset))=val;
|
||||
}
|
||||
void poked(size_t offset,unsigned val)
|
||||
{
|
||||
*((unsigned*)(offset))=val;
|
||||
}
|
||||
void pokearb(size_t offset, void *mem,size_t size)
|
||||
{
|
||||
memcpy((void*)offset,mem,size);
|
||||
}
|
||||
void pokestr(size_t offset, char* buf, size_t maxsize)
|
||||
{
|
||||
strcpy_s((char*)offset,maxsize,buf);
|
||||
}
|
||||
template <typename T>
|
||||
T peek(size_t offset) //prob lower performance
|
||||
{
|
||||
T tmp;
|
||||
peekarb(offset,&tmp,sizeof(T));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//// lua stuff here
|
||||
static int lua_peekb(lua_State *L)
|
||||
{
|
||||
lua::state st(L);
|
||||
st.push(peekb(st.as<size_t>(1)));
|
||||
return 1;
|
||||
}
|
||||
static int lua_peekd(lua_State *L)
|
||||
{
|
||||
lua::state st(L);
|
||||
st.push(peekd(st.as<size_t>(1)));
|
||||
return 1;
|
||||
}
|
||||
static int lua_peekw(lua_State *L)
|
||||
{
|
||||
lua::state st(L);
|
||||
st.push(peekw(st.as<size_t>(1)));
|
||||
return 1;
|
||||
}
|
||||
static int lua_peekarb(lua_State *L)
|
||||
{
|
||||
lua::state st(L);
|
||||
size_t size=st.as<size_t>(2);
|
||||
void *p=st.newuserdata(size);
|
||||
peekarb(st.as<size_t>(1),p,size);
|
||||
return 1;
|
||||
}
|
||||
static int lua_peekstr(lua_State *L)
|
||||
{
|
||||
lua::state st(L);
|
||||
char *buf;
|
||||
buf=new char[256];
|
||||
peekstr(st.as<size_t>(1),buf,256);
|
||||
std::string tstr(buf);
|
||||
st.push(tstr);
|
||||
delete [] buf;
|
||||
return 1;
|
||||
}
|
||||
/*static int lua_peekarb(lua_State *L)
|
||||
{
|
||||
lua::state st(L);
|
||||
st.push(peekarb(st.as<DWORD>(1)));
|
||||
return 1;
|
||||
}*/
|
||||
static int lua_pokeb(lua_State *L)
|
||||
{
|
||||
lua::state st(L);
|
||||
pokeb(st.as<size_t>(1),st.as<size_t>(2));
|
||||
return 0;
|
||||
}
|
||||
static int lua_poked(lua_State *L)
|
||||
{
|
||||
lua::state st(L);
|
||||
poked(st.as<size_t>(1),st.as<size_t>(2));
|
||||
return 0;
|
||||
}
|
||||
static int lua_pokew(lua_State *L)
|
||||
{
|
||||
lua::state st(L);
|
||||
pokew(st.as<size_t>(1),st.as<size_t>(2));
|
||||
return 0;
|
||||
}
|
||||
static int lua_pokearb(lua_State *L)
|
||||
{
|
||||
lua::state st(L);
|
||||
|
||||
|
||||
void *p=(void *)lua_touserdata(L, 2);//st.as<lua::userdata>(2);
|
||||
size_t size=st.as<size_t>(3);
|
||||
|
||||
pokearb(st.as<size_t>(1),p,size);
|
||||
return 0;
|
||||
}
|
||||
static int lua_pokestr(lua_State *L)
|
||||
{
|
||||
lua::state st(L);
|
||||
std::string trg=st.as<std::string>(2);
|
||||
pokestr(st.as<size_t>(1),(char*)trg.c_str(),trg.size());
|
||||
return 0;
|
||||
}
|
||||
const luaL_Reg lua_engine_func[]=
|
||||
{
|
||||
{"peekb",lua_peekb},
|
||||
{"peekw",lua_peekw},
|
||||
{"peekd",lua_peekd},
|
||||
{"peekarb",lua_peekarb},
|
||||
{"peekstr",lua_peekstr},
|
||||
{"pokeb",lua_pokeb},
|
||||
{"pokew",lua_pokew},
|
||||
{"poked",lua_poked},
|
||||
{"pokearb",lua_pokearb},
|
||||
{"pokestr",lua_pokestr},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
void lua::RegisterEngine(lua::state &st)
|
||||
{
|
||||
st.getglobal("engine");
|
||||
if(st.is<lua::nil>())
|
||||
{
|
||||
st.pop();
|
||||
st.newtable();
|
||||
}
|
||||
lua::RegFunctionsLocal(st,lua_engine_func);
|
||||
st.setglobal("engine");
|
||||
}
|
@ -0,0 +1,293 @@
|
||||
#include "lua_Process.h"
|
||||
|
||||
static DFHack::Process* GetProcessPtr(lua::state &st)
|
||||
{
|
||||
int t=st.gettop();
|
||||
st.getglobal("Process");
|
||||
st.getfield("__pointer");
|
||||
DFHack::Process* c=static_cast<DFHack::Process*>(lua_touserdata(st,-1));
|
||||
st.settop(t);
|
||||
return c;
|
||||
}
|
||||
|
||||
static int lua_Process_readDWord(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
uint32_t ret=c->readDWord(st.as<uint32_t>(1));
|
||||
st.push(ret);
|
||||
return 1;
|
||||
}
|
||||
static int lua_Process_writeDWord(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
c->writeDWord(st.as<uint32_t>(1),st.as<uint32_t>(2));
|
||||
return 0;
|
||||
}
|
||||
static int lua_Process_readFloat(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
float ret=c->readFloat(st.as<uint32_t>(1));
|
||||
st.push(ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lua_Process_readWord(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
uint16_t ret=c->readWord(st.as<uint32_t>(1));
|
||||
st.push(ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lua_Process_writeWord(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
c->writeWord(st.as<uint32_t>(1),st.as<uint16_t>(2));
|
||||
return 0;
|
||||
}
|
||||
static int lua_Process_readByte(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
uint8_t ret=c->readByte(st.as<uint32_t>(1));
|
||||
st.push(ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lua_Process_writeByte(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
c->writeByte(st.as<uint32_t>(1),st.as<uint8_t>(2));
|
||||
return 0;
|
||||
}
|
||||
static int lua_Process_read(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
size_t len=st.as<uint32_t>(2);
|
||||
uint8_t* buf;
|
||||
|
||||
if(!st.is<lua::nil>(3))
|
||||
buf=(uint8_t*)lua_touserdata(st,3);
|
||||
else
|
||||
buf=new uint8_t[len];
|
||||
c->read(st.as<uint32_t>(1),len,buf);
|
||||
st.pushlightuserdata(buf);
|
||||
return 1;
|
||||
}
|
||||
static int lua_Process_write(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
c-> write(st.as<uint32_t>(1),st.as<uint32_t>(2),static_cast<uint8_t*>(lua_touserdata(st,3)));
|
||||
return 0;
|
||||
}
|
||||
static int lua_Process_readSTLString (lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
std::string r=c->readSTLString(st.as<uint32_t>(1));
|
||||
st.push(r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lua_Process_writeSTLString(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
c->writeSTLString(st.as<uint32_t>(1),st.as<std::string>(2));
|
||||
return 0;
|
||||
}
|
||||
static int lua_Process_copySTLString(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
c->copySTLString(st.as<uint32_t>(1),st.as<uint32_t>(2));
|
||||
return 0;
|
||||
}
|
||||
static int lua_Process_doReadClassName(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
std::string r=c->doReadClassName((void*)st.as<size_t>(1));
|
||||
st.push(r);
|
||||
return 1;
|
||||
}
|
||||
static int lua_Process_readClassName(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
std::string r=c->readClassName((void*)st.as<size_t>(1));
|
||||
st.push(r);
|
||||
return 1;
|
||||
}
|
||||
static int lua_Process_readCString (lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
std::string r=c->readCString(st.as<uint32_t>(1));
|
||||
st.push(r);
|
||||
return 1;
|
||||
}
|
||||
static int lua_Process_isSuspended(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
st.push(c->isSuspended());
|
||||
return 1;
|
||||
}
|
||||
static int lua_Process_isIdentified(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
st.push(c->isIdentified());
|
||||
return 1;
|
||||
}
|
||||
static int lua_Process_getThreadIDs(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
std::vector<uint32_t> threads;
|
||||
c->getThreadIDs(threads);
|
||||
st.newtable();
|
||||
for(size_t i=0;i<threads.size();i++)
|
||||
{
|
||||
st.push(i);
|
||||
st.push(threads[i]);
|
||||
st.settable();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static int lua_Process_getMemRanges(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
std::vector<DFHack::t_memrange> ranges;
|
||||
c->getMemRanges(ranges);
|
||||
st.newtable();
|
||||
for(size_t i=0;i<ranges.size();i++)
|
||||
{
|
||||
st.push(i);
|
||||
st.newtable();
|
||||
st.push(ranges[i].start); // WARNING!! lua has only 32bit numbers, possible loss of data!!
|
||||
st.setfield("start");
|
||||
st.push(ranges[i].end);
|
||||
st.setfield("end");
|
||||
st.push(std::string(ranges[i].name));
|
||||
st.setfield("name");
|
||||
st.push(ranges[i].read);
|
||||
st.setfield("read");
|
||||
st.push(ranges[i].write);
|
||||
st.setfield("write");
|
||||
st.push(ranges[i].execute);
|
||||
st.setfield("execute");
|
||||
st.push(ranges[i].shared);
|
||||
st.setfield("shared");
|
||||
st.push(ranges[i].valid);
|
||||
st.setfield("valid");
|
||||
st.settable();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static int lua_Process_getBase(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
uint32_t base=c->getBase();
|
||||
st.push(base);
|
||||
return 1;
|
||||
}
|
||||
/*static int lua_Process_getPID(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
int ret=c->getPID();
|
||||
st.push(ret);
|
||||
return 1;
|
||||
}*/
|
||||
static int lua_Process_getPath(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
std::string ret=c->getPath();
|
||||
st.push(ret);
|
||||
return 1;
|
||||
}
|
||||
static int lua_Process_setPermisions(lua_State *S)
|
||||
{
|
||||
lua::state st(S);
|
||||
DFHack::Process* c=GetProcessPtr(st);
|
||||
DFHack::t_memrange range,trange;
|
||||
|
||||
st.getfield("start",1);
|
||||
range.start=st.as<uint64_t>();
|
||||
st.pop();
|
||||
st.getfield("end",1);
|
||||
range.end=st.as<uint64_t>();
|
||||
st.pop();
|
||||
|
||||
st.getfield("read",2);
|
||||
trange.read=st.as<bool>();
|
||||
st.pop();
|
||||
st.getfield("write",2);
|
||||
trange.write=st.as<bool>();
|
||||
st.pop();
|
||||
st.getfield("execute",2);
|
||||
trange.execute=st.as<bool>();
|
||||
st.pop();
|
||||
|
||||
c->setPermisions(range,trange);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#define PROC_FUNC(name) {#name,lua_Process_ ## name}
|
||||
const luaL_Reg lua_process_func[]=
|
||||
{
|
||||
PROC_FUNC(readDWord),
|
||||
PROC_FUNC(writeDWord),
|
||||
PROC_FUNC(readFloat),
|
||||
PROC_FUNC(readWord),
|
||||
PROC_FUNC(writeWord),
|
||||
PROC_FUNC(readByte),
|
||||
PROC_FUNC(writeByte),
|
||||
PROC_FUNC(read),
|
||||
PROC_FUNC(write),
|
||||
PROC_FUNC(readSTLString),
|
||||
PROC_FUNC(writeSTLString),
|
||||
PROC_FUNC(copySTLString),
|
||||
PROC_FUNC(doReadClassName),
|
||||
PROC_FUNC(readClassName),
|
||||
PROC_FUNC(readCString ),
|
||||
PROC_FUNC(isSuspended),
|
||||
PROC_FUNC(isIdentified),
|
||||
PROC_FUNC(getThreadIDs),
|
||||
PROC_FUNC(getMemRanges),
|
||||
PROC_FUNC(getBase),
|
||||
//PROC_FUNC(getPID), //not implemented
|
||||
PROC_FUNC(getPath),
|
||||
PROC_FUNC(setPermisions),
|
||||
{NULL,NULL}
|
||||
};
|
||||
#undef PROC_FUNC
|
||||
void lua::RegisterProcess(lua::state &st,DFHack::Process *p)
|
||||
{
|
||||
st.getglobal("Process");
|
||||
if(st.is<lua::nil>())
|
||||
{
|
||||
st.pop();
|
||||
st.newtable();
|
||||
}
|
||||
|
||||
st.pushlightuserdata(p);
|
||||
st.setfield("__pointer");
|
||||
|
||||
lua::RegFunctionsLocal(st, lua_process_func);
|
||||
|
||||
st.setglobal("Process");
|
||||
}
|
Loading…
Reference in New Issue