Refactor of memory_info class, now with more d-pointer

develop
Petr Mrázek 2010-02-22 23:34:20 +01:00
parent 9aeee1b48e
commit 1e04722a63
17 changed files with 295 additions and 244 deletions

@ -161,7 +161,7 @@ int main (void)
DF.ReadMetalMatgloss(mat.metalMat);
DF.ReadCreatureMatgloss(mat.creatureMat);
DFHack::memory_info mem = DF.getMemoryInfo();
DFHack::memory_info *mem = DF.getMemoryInfo();
// get stone matgloss mapping
if(!DF.ReadCreatureMatgloss(creaturestypes))
{
@ -229,14 +229,14 @@ int main (void)
cout << endl;
addendl = false;
}
cout << "profession: " << mem.getProfession(temp.profession) << "(" << (int) temp.profession << ")";
cout << "profession: " << mem->getProfession(temp.profession) << "(" << (int) temp.profession << ")";
if(temp.custom_profession[0])
{
cout << ", custom profession: " << temp.custom_profession;
}
if(temp.current_job.active)
{
cout << ", current job: " << mem.getJob(temp.current_job.jobId);
cout << ", current job: " << mem->getJob(temp.current_job.jobId);
}
cout << endl;
cout << "happiness: " << temp.happiness << ", strength: " << temp.strength << ", agility: "

@ -21,7 +21,7 @@ int main (void)
return 1;
}
DFHack::memory_info mem = DF.getMemoryInfo();
DFHack::memory_info * mem = DF.getMemoryInfo();
// get stone matgloss mapping
uint32_t numNotes;
if(!DF.InitReadNotes(numNotes))

@ -20,7 +20,7 @@ int main (void)
return 1;
}
vector <DFHack::t_matgloss> Woods;
DF.ReadPlantMatgloss(Woods);
DF.ReadWoodMatgloss(Woods);
vector <DFHack::t_matgloss> Plants;
DF.ReadPlantMatgloss(Plants);

@ -317,7 +317,7 @@ int main (void)
return 1;
}
DFHack::memory_info mem = DF.getMemoryInfo();
DFHack::memory_info * mem = DF.getMemoryInfo();
if (!DF.ReadCreatureMatgloss(creaturestypes))
{
@ -434,11 +434,11 @@ start:
// I have the writeString function do nothing for normal mode
if (commandString == "pzyn") // change nickname
{
p->writeSTLString(toChange.origin+mem.getOffset("creature_nick_name"),changeString);
p->writeSTLString(toChange.origin+mem->getOffset("creature_nick_name"),changeString);
}
else
{
p->writeSTLString(toChange.origin+mem.getOffset("creature_custom_profession"),changeString);
p->writeSTLString(toChange.origin+mem->getOffset("creature_custom_profession"),changeString);
}
}
DF.Suspend();

@ -395,6 +395,7 @@ bool API::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein> & veins,
// read the vein pointer from the vector
uint32_t temp = * (uint32_t *) p_veins[i];
uint32_t type = g_pProcess->readDWord(temp);
try_again:
if(type == d->vein_mineral_vptr)
{
// read the vein data (dereference pointer)
@ -410,6 +411,21 @@ bool API::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein> & veins,
// store it in the vector
ices.push_back (fv);
}
//#define ___FIND_
#ifdef ___FIND_THEM
else if(g_pProcess->readClassName(type) == "block_square_event_frozen_liquid")
{
d->vein_ice_vptr = type;
cout << "block_square_event_frozen_liquid : 0x" << hex << type << endl;
goto try_again;
}
else if(g_pProcess->readClassName(type) == "block_square_event_mineral")
{
d->vein_mineral_vptr = type;
cout << "block_square_event_mineral : 0x" << hex << type << endl;
goto try_again;
}
#endif
}
return true;
}
@ -1420,9 +1436,9 @@ bool API::getClassIDMapping (vector <string>& objecttypes)
return false;
}
memory_info API::getMemoryInfo()
memory_info *API::getMemoryInfo()
{
return *d->offset_descriptor;
return d->offset_descriptor;
}
Process * API::getProcess()
{

@ -229,7 +229,7 @@ namespace DFHack
// wrapper for meminfo method of the same name
bool getClassIDMapping (vector <string>& objecttypes);
memory_info getMemoryInfo();
memory_info *getMemoryInfo();
Process * getProcess();
DFWindow * getWindow();
/*

@ -23,31 +23,95 @@ distribution.
*/
#include "DFCommonInternal.h"
/*
#if !defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#endif
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
using boost::multi_index_container;
using namespace boost::multi_index;
*/
using namespace DFHack;
/*
* Common data types
*/
struct t_class
{
string classname;
uint32_t vtable;
bool is_multiclass;
uint32_t multi_index;
uint32_t assign;// index to typeclass array if multiclass. return value if not.
uint32_t type_offset; // offset of type data for multiclass
};
struct t_type
{
string classname;
uint32_t assign;
uint32_t type;
};
/*
* Private data
*/
class memory_info::Private
{
public:
map <string, uint32_t> addresses;
map <string, uint32_t> offsets;
map <string, uint32_t> hexvals;
map <string, string> strings;
vector<string> professions;
vector<string> jobs;
vector<string> skills;
vector< vector<string> > traits;
map <uint32_t, string> labors;
vector<t_class> classes;
vector<vector<t_type> > classsubtypes;
int32_t base;
uint32_t classindex;
string version;
OSType OS;
};
memory_info::memory_info()
:d(new Private)
{
base = 0;
classindex = 0;
d->base = 0;
d->classindex = 0;
}
void memory_info::setVersion(const char * v)
{
version = v;
d->version = v;
}
void memory_info::setVersion(const string &v)
{
version = v;
d->version = v;
}
string memory_info::getVersion()
{
return version;
return d->version;
}
@ -55,22 +119,22 @@ void memory_info::setOS(const char *os)
{
string oss = os;
if(oss == "windows")
OS = OS_WINDOWS;
d->OS = OS_WINDOWS;
else if(oss == "linux")
OS = OS_LINUX;
d->OS = OS_LINUX;
else
OS = OS_BAD;
d->OS = OS_BAD;
}
void memory_info::setOS(const string &os)
{
if(os == "windows")
OS = OS_WINDOWS;
d->OS = OS_WINDOWS;
else if(os == "linux")
OS = OS_LINUX;
d->OS = OS_LINUX;
else
OS = OS_BAD;
d->OS = OS_BAD;
}
@ -78,117 +142,118 @@ void memory_info::setOS(OSType os)
{
if(os >= OS_WINDOWS && os < OS_BAD)
{
OS = os;
d->OS = os;
return;
}
OS = OS_BAD;
d->OS = OS_BAD;
}
memory_info::OSType memory_info::getOS() const
{
return OS;
return d->OS;
}
// copy constructor
memory_info::memory_info(const memory_info &old)
{
version = old.version;
OS = old.OS;
addresses = old.addresses;
offsets = old.offsets;
hexvals = old.hexvals;
strings = old.strings;
base = old.base;
classes = old.classes;
classsubtypes = old.classsubtypes;
classindex = old.classindex;
professions = old.professions;
jobs = old.jobs;
skills = old.skills;
traits = old.traits;
labors = old.labors;
:d(new Private)
{
d->version = old.d->version;
d->OS = old.d->OS;
d->addresses = old.d->addresses;
d->offsets = old.d->offsets;
d->hexvals = old.d->hexvals;
d->strings = old.d->strings;
d->base = old.d->base;
d->classes = old.d->classes;
d->classsubtypes = old.d->classsubtypes;
d->classindex = old.d->classindex;
d->professions = old.d->professions;
d->jobs = old.d->jobs;
d->skills = old.d->skills;
d->traits = old.d->traits;
d->labors = old.d->labors;
}
uint32_t memory_info::getBase () const
{
return base;
return d->base;
}
void memory_info::setBase (const string &s)
{
base = strtol(s.c_str(), NULL, 16);
d->base = strtol(s.c_str(), NULL, 16);
}
void memory_info::setBase (const uint32_t b)
{
base = b;
d->base = b;
}
void memory_info::setOffset (const string & key, const string & value)
{
uint32_t offset = strtol(value.c_str(), NULL, 16);
offsets[key] = offset;
d->offsets[key] = offset;
}
void memory_info::setAddress (const string & key, const string & value)
{
uint32_t address = strtol(value.c_str(), NULL, 16);
addresses[key] = address;
d->addresses[key] = address;
}
void memory_info::setHexValue (const string & key, const string & value)
{
uint32_t hexval = strtol(value.c_str(), NULL, 16);
hexvals[key] = hexval;
d->hexvals[key] = hexval;
}
void memory_info::setString (const string & key, const string & value)
{
strings[key] = value;
d->strings[key] = value;
}
void memory_info::setLabor(const string & key, const string & value)
{
uint32_t keyInt = strtol(key.c_str(), NULL, 10);
labors[keyInt] = value;
d->labors[keyInt] = value;
}
void memory_info::setProfession (const string & key, const string & value)
{
uint32_t keyInt = strtol(key.c_str(), NULL, 10);
if(professions.size() <= keyInt)
if(d->professions.size() <= keyInt)
{
professions.resize(keyInt+1);
d->professions.resize(keyInt+1);
}
professions[keyInt] = value;
d->professions[keyInt] = value;
}
void memory_info::setJob (const string & key, const string & value)
{
uint32_t keyInt = strtol(key.c_str(), NULL, 10);
if(jobs.size() <= keyInt)
if(d->jobs.size() <= keyInt)
{
jobs.resize(keyInt+1);
d->jobs.resize(keyInt+1);
}
jobs[keyInt] = value;
d->jobs[keyInt] = value;
}
void memory_info::setSkill (const string & key, const string & value)
{
uint32_t keyInt = strtol(key.c_str(), NULL, 10);
if(skills.size() <= keyInt){
skills.resize(keyInt+1);
if(d->skills.size() <= keyInt){
d->skills.resize(keyInt+1);
}
skills[keyInt] = value;
d->skills[keyInt] = value;
}
void memory_info::setTrait(const string & key,
@ -201,39 +266,39 @@ void memory_info::setTrait(const string & key,
const string & five)
{
uint32_t keyInt = strtol(key.c_str(), NULL, 10);
if(traits.size() <= keyInt)
if(d->traits.size() <= keyInt)
{
traits.resize(keyInt+1);
d->traits.resize(keyInt+1);
}
traits[keyInt].push_back(zero);
traits[keyInt].push_back(one);
traits[keyInt].push_back(two);
traits[keyInt].push_back(three);
traits[keyInt].push_back(four);
traits[keyInt].push_back(five);
traits[keyInt].push_back(value);
d->traits[keyInt].push_back(zero);
d->traits[keyInt].push_back(one);
d->traits[keyInt].push_back(two);
d->traits[keyInt].push_back(three);
d->traits[keyInt].push_back(four);
d->traits[keyInt].push_back(five);
d->traits[keyInt].push_back(value);
}
// FIXME: next three methods should use some kind of custom container so it doesn't have to search so much.
void memory_info::setClass (const char * name, const char * vtable)
{
for (uint32_t i=0; i<classes.size(); i++)
for (uint32_t i=0; i<d->classes.size(); i++)
{
if(classes[i].classname == name)
if(d->classes[i].classname == name)
{
classes[i].vtable = strtol(vtable, NULL, 16);
d->classes[i].vtable = strtol(vtable, NULL, 16);
return;
}
}
t_class cls;
cls.assign = classindex;
cls.assign = d->classindex;
cls.classname = name;
cls.is_multiclass = false;
cls.type_offset = 0;
classindex++;
d->classindex++;
cls.vtable = strtol(vtable, NULL, 16);
classes.push_back(cls);
d->classes.push_back(cls);
//cout << "class " << name << ", assign " << cls.assign << ", vtable " << cls.vtable << endl;
}
@ -241,40 +306,40 @@ void memory_info::setClass (const char * name, const char * vtable)
// find old entry by name, rewrite, return its multi index. otherwise make a new one, append an empty vector of t_type to classtypes, return its index.
uint32_t memory_info::setMultiClass (const char * name, const char * vtable, const char * typeoffset)
{
for (uint32_t i=0; i<classes.size(); i++)
for (uint32_t i=0; i<d->classes.size(); i++)
{
if(classes[i].classname == name)
if(d->classes[i].classname == name)
{
// vtable and typeoffset can be left out from the xml definition when there's already a named multiclass
if(vtable != NULL)
classes[i].vtable = strtol(vtable, NULL, 16);
d->classes[i].vtable = strtol(vtable, NULL, 16);
if(typeoffset != NULL)
classes[i].type_offset = strtol(typeoffset, NULL, 16);
return classes[i].multi_index;
d->classes[i].type_offset = strtol(typeoffset, NULL, 16);
return d->classes[i].multi_index;
}
}
//FIXME: add checking for vtable and typeoffset here. they HAVE to be valid. maybe change the return value into a bool and pass in multi index by reference?
t_class cls;
cls.assign = classindex;
cls.assign = d->classindex;
cls.classname = name;
cls.is_multiclass = true;
cls.type_offset = strtol(typeoffset, NULL, 16);
cls.vtable = strtol(vtable, NULL, 16);
cls.multi_index = classsubtypes.size();
classes.push_back(cls);
classindex++;
cls.multi_index = d->classsubtypes.size();
d->classes.push_back(cls);
d->classindex++;
vector<t_type> thistypes;
classsubtypes.push_back(thistypes);
d->classsubtypes.push_back(thistypes);
//cout << "multiclass " << name << ", assign " << cls.assign << ", vtable " << cls.vtable << endl;
return classsubtypes.size() - 1;
return d->classsubtypes.size() - 1;
}
void memory_info::setMultiClassChild (uint32_t multi_index, const char * name, const char * type)
{
vector <t_type>& vec = classsubtypes[multi_index];
vector <t_type>& vec = d->classsubtypes[multi_index];
for (uint32_t i=0; i<vec.size(); i++)
{
if(vec[i].classname == name)
@ -285,11 +350,11 @@ void memory_info::setMultiClassChild (uint32_t multi_index, const char * name, c
}
// new multiclass child
t_type mcc;
mcc.assign = classindex;
mcc.assign = d->classindex;
mcc.classname = name;
mcc.type = strtol(type, NULL, 16);
vec.push_back(mcc);
classindex++;
d->classindex++;
//cout << " classtype " << name << ", assign " << mcc.assign << ", vtable " << mcc.type << endl;
}
@ -298,15 +363,15 @@ bool memory_info::resolveClassId(uint32_t address, int32_t & classid)
{
uint32_t vtable = g_pProcess->readDWord(address);
// FIXME: stupid search. we need a better container
for(uint32_t i = 0;i< classes.size();i++)
for(uint32_t i = 0;i< d->classes.size();i++)
{
if(classes[i].vtable == vtable) // got class
if(d->classes[i].vtable == vtable) // got class
{
// if it is a multiclass, try resolving it
if(classes[i].is_multiclass)
if(d->classes[i].is_multiclass)
{
vector <t_type>& vec = classsubtypes[classes[i].multi_index];
uint32_t type = g_pProcess->readWord(address + classes[i].type_offset);
vector <t_type>& vec = d->classsubtypes[d->classes[i].multi_index];
uint32_t type = g_pProcess->readWord(address + d->classes[i].type_offset);
//printf ("class %d:%s offset 0x%x\n", i , classes[i].classname.c_str(), classes[i].type_offset);
// return typed building if successful
for (uint32_t k = 0; k < vec.size();k++)
@ -320,7 +385,7 @@ bool memory_info::resolveClassId(uint32_t address, int32_t & classid)
}
}
// otherwise return the class we found
classid = classes[i].assign;
classid = d->classes[i].assign;
return true;
}
}
@ -332,12 +397,12 @@ bool memory_info::resolveClassId(uint32_t address, int32_t & classid)
uint32_t memory_info::getClassVPtr(string classname)
{
// FIXME: another stupid search.
for(uint32_t i = 0;i< classes.size();i++)
for(uint32_t i = 0;i< d->classes.size();i++)
{
//if(classes[i].)
if(classes[i].classname == classname) // got class
if(d->classes[i].classname == classname) // got class
{
return classes[i].vtable;
return d->classes[i].vtable;
}
}
// we failed to find anything that would match
@ -347,14 +412,14 @@ uint32_t memory_info::getClassVPtr(string classname)
// Flatten vtables into a index<->name mapping
void memory_info::getClassIDMapping(vector<string> & v_ClassID2ObjName)
{
for(uint32_t i = 0;i< classes.size();i++)
for(uint32_t i = 0;i< d->classes.size();i++)
{
v_ClassID2ObjName.push_back(classes[i].classname);
if(!classes[i].is_multiclass)
v_ClassID2ObjName.push_back(d->classes[i].classname);
if(!d->classes[i].is_multiclass)
{
continue;
}
vector <t_type>& vec = classsubtypes[classes[i].multi_index];
vector <t_type>& vec = d->classsubtypes[d->classes[i].multi_index];
for (uint32_t k = 0; k < vec.size();k++)
{
v_ClassID2ObjName.push_back(vec[k].classname);
@ -367,10 +432,10 @@ void memory_info::getClassIDMapping(vector<string> & v_ClassID2ObjName)
void memory_info::RebaseAddresses(const int32_t new_base)
{
map<string, uint32_t>::iterator iter;
int32_t rebase = - (int32_t)base + new_base;
for(iter = addresses.begin(); iter != addresses.end(); iter++)
int32_t rebase = - (int32_t)d->base + new_base;
for(iter = d->addresses.begin(); iter != d->addresses.end(); iter++)
{
addresses[iter->first] = iter->second + rebase;
d->addresses[iter->first] = iter->second + rebase;
}
}
@ -379,10 +444,10 @@ void memory_info::RebaseAddresses(const int32_t new_base)
void memory_info::RebaseAll(int32_t new_base)
{
map<string, uint32_t>::iterator iter;
int32_t rebase = - (int32_t)base + new_base;
for(iter = addresses.begin(); iter != addresses.end(); iter++)
int32_t rebase = - (int32_t)d->base + new_base;
for(iter = d->addresses.begin(); iter != d->addresses.end(); iter++)
{
addresses[iter->first] = iter->second + rebase;
d->addresses[iter->first] = iter->second + rebase;
}
RebaseVTable(rebase);
}
@ -392,7 +457,7 @@ void memory_info::RebaseAll(int32_t new_base)
void memory_info::RebaseVTable(int32_t offset)
{
vector<t_class>::iterator iter;
for(iter = classes.begin(); iter != classes.end(); iter++)
for(iter = d->classes.begin(); iter != d->classes.end(); iter++)
{
iter->vtable += offset;
}
@ -401,9 +466,9 @@ void memory_info::RebaseVTable(int32_t offset)
// Get named address
uint32_t memory_info::getAddress (const char *key)
{
map <string, uint32_t>::iterator iter = addresses.find(key);
map <string, uint32_t>::iterator iter = d->addresses.find(key);
if(iter != addresses.end())
if(iter != d->addresses.end())
{
return (*iter).second;
}
@ -414,8 +479,8 @@ uint32_t memory_info::getAddress (const char *key)
// Get named offset
uint32_t memory_info::getOffset (const char *key)
{
map <string, uint32_t>::iterator iter = offsets.find(key);
if(iter != offsets.end())
map <string, uint32_t>::iterator iter = d->offsets.find(key);
if(iter != d->offsets.end())
{
return (*iter).second;
}
@ -425,8 +490,8 @@ uint32_t memory_info::getOffset (const char *key)
// Get named numerical value
uint32_t memory_info::getHexValue (const char *key)
{
map <string, uint32_t>::iterator iter = hexvals.find(key);
if(iter != hexvals.end())
map <string, uint32_t>::iterator iter = d->hexvals.find(key);
if(iter != d->hexvals.end())
{
return (*iter).second;
}
@ -437,9 +502,9 @@ uint32_t memory_info::getHexValue (const char *key)
// Get named address
uint32_t memory_info::getAddress (const string &key)
{
map <string, uint32_t>::iterator iter = addresses.find(key);
map <string, uint32_t>::iterator iter = d->addresses.find(key);
if(iter != addresses.end())
if(iter != d->addresses.end())
{
return (*iter).second;
}
@ -450,8 +515,8 @@ uint32_t memory_info::getAddress (const string &key)
// Get named offset
uint32_t memory_info::getOffset (const string &key)
{
map <string, uint32_t>::iterator iter = offsets.find(key);
if(iter != offsets.end())
map <string, uint32_t>::iterator iter = d->offsets.find(key);
if(iter != d->offsets.end())
{
return (*iter).second;
}
@ -461,8 +526,8 @@ uint32_t memory_info::getOffset (const string &key)
// Get named numerical value
uint32_t memory_info::getHexValue (const string &key)
{
map <string, uint32_t>::iterator iter = hexvals.find(key);
if(iter != hexvals.end())
map <string, uint32_t>::iterator iter = d->hexvals.find(key);
if(iter != d->hexvals.end())
{
return (*iter).second;
}
@ -472,8 +537,8 @@ uint32_t memory_info::getHexValue (const string &key)
// Get named string
std::string memory_info::getString (const string &key)
{
map <string, string>::iterator iter = strings.find(key);
if(iter != strings.end())
map <string, string>::iterator iter = d->strings.find(key);
if(iter != d->strings.end())
{
return (*iter).second;
}
@ -483,9 +548,9 @@ std::string memory_info::getString (const string &key)
// Get Profession
string memory_info::getProfession (const uint32_t key) const
{
if(professions.size() > key)
if(d->professions.size() > key)
{
return professions[key];
return d->professions[key];
}
else
{
@ -496,18 +561,18 @@ string memory_info::getProfession (const uint32_t key) const
// Get Job
string memory_info::getJob (const uint32_t key) const
{
if(jobs.size() > key)
if(d->jobs.size() > key)
{
return jobs[key];
return d->jobs[key];
}
return string("Job Does Not Exist");
}
string memory_info::getSkill (const uint32_t key) const
{
if(skills.size() > key)
if(d->skills.size() > key)
{
return skills[key];
return d->skills[key];
}
return string("Skill is not Defined");
}
@ -522,7 +587,7 @@ int absolute (int number)
string memory_info::getTrait (const uint32_t traitIdx, const uint32_t traitValue) const
{
if(traits.size() > traitIdx)
if(d->traits.size() > traitIdx)
{
int diff = absolute(traitValue-50);
if(diff < 10)
@ -530,35 +595,35 @@ string memory_info::getTrait (const uint32_t traitIdx, const uint32_t traitValue
return string("");
}
if (traitValue >= 91)
return traits[traitIdx][5];
return d->traits[traitIdx][5];
else if (traitValue >= 76)
return traits[traitIdx][4];
return d->traits[traitIdx][4];
else if (traitValue >= 61)
return traits[traitIdx][3];
return d->traits[traitIdx][3];
else if (traitValue >= 25)
return traits[traitIdx][2];
return d->traits[traitIdx][2];
else if (traitValue >= 10)
return traits[traitIdx][1];
return d->traits[traitIdx][1];
else
return traits[traitIdx][0];
return d->traits[traitIdx][0];
}
return string("Trait is not Defined");
}
string memory_info::getTraitName(const uint32_t traitIdx) const
{
if(traits.size() > traitIdx)
if(d->traits.size() > traitIdx)
{
return traits[traitIdx][traits[traitIdx].size()-1];
return d->traits[traitIdx][d->traits[traitIdx].size()-1];
}
return string("Trait is not Defined");
}
string memory_info::getLabor (const uint32_t laborIdx)
{
if(labors.count(laborIdx))
if(d->labors.count(laborIdx))
{
return labors[laborIdx];
return d->labors[laborIdx];
}
return string("");
}
@ -566,14 +631,14 @@ string memory_info::getLabor (const uint32_t laborIdx)
// Reset everything
void memory_info::flush()
{
base = 0;
addresses.clear();
offsets.clear();
strings.clear();
hexvals.clear();
classes.clear();
classsubtypes.clear();
classindex = 0;
version = "";
OS = OS_BAD;
d->base = 0;
d->addresses.clear();
d->offsets.clear();
d->strings.clear();
d->hexvals.clear();
d->classes.clear();
d->classsubtypes.clear();
d->classindex = 0;
d->version = "";
d->OS = OS_BAD;
}

@ -34,8 +34,12 @@ distribution.
namespace DFHack
{
class DFHACK_EXPORT memory_info
{
private:
class Private;
Private * d;
public:
enum OSType
{
@ -43,21 +47,6 @@ namespace DFHack
OS_LINUX,
OS_BAD
};
struct t_class
{
string classname;
uint32_t vtable;
bool is_multiclass;
uint32_t multi_index;
uint32_t assign;// index to typeclass array if multiclass. return value if not.
uint32_t type_offset; // offset of type data for multiclass
};
struct t_type
{
string classname;
uint32_t assign;
uint32_t type;
};
memory_info();
memory_info(const memory_info&);
@ -123,25 +112,6 @@ namespace DFHack
uint32_t getClassVPtr(string classname);
void flush();
private:
map <string, uint32_t> addresses;
map <string, uint32_t> offsets;
map <string, uint32_t> hexvals;
map <string, string> strings;
vector<string> professions;
vector<string> jobs;
vector<string> skills;
vector< vector<string> > traits;
map <uint32_t, string> labors;
vector<t_class> classes;
vector<vector<t_type> > classsubtypes;
int32_t base;
uint32_t classindex;
string version;
OSType OS;
};
}
#endif // MEMINFO_H_INCLUDED

@ -25,7 +25,7 @@ distribution.
#include "DFCommonInternal.h"
using namespace DFHack;
void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info& mem)
void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info* mem)
{
TiXmlElement* pClassEntry;
TiXmlElement* pClassSubEntry;
@ -34,7 +34,7 @@ void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info& mem)
if(rebase)
{
int32_t rebase_offset = strtol(rebase, NULL, 16);
mem.RebaseVTable(rebase_offset);
mem->RebaseVTable(rebase_offset);
}
// parse vtable entries
pClassEntry = vtable->FirstChildElement();
@ -46,14 +46,14 @@ void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info& mem)
// it's a simple class
if(type== "class")
{
mem.setClass(cstr_name, cstr_vtable);
mem->setClass(cstr_name, cstr_vtable);
}
// it's a multi-type class
else if (type == "multiclass")
{
// get offset of the type variable
const char *cstr_typeoffset = pClassEntry->Attribute("typeoffset");
int mclass = mem.setMultiClass(cstr_name, cstr_vtable, cstr_typeoffset);
int mclass = mem->setMultiClass(cstr_name, cstr_vtable, cstr_typeoffset);
// parse class sub-entries
pClassSubEntry = pClassEntry->FirstChildElement();
for(;pClassSubEntry;pClassSubEntry=pClassSubEntry->NextSiblingElement())
@ -64,7 +64,7 @@ void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info& mem)
// type is a value loaded from type offset
cstr_name = pClassSubEntry->Attribute("name");
const char *cstr_value = pClassSubEntry->Attribute("type");
mem.setMultiClassChild(mclass,cstr_name,cstr_value);
mem->setMultiClassChild(mclass,cstr_name,cstr_value);
}
}
}
@ -73,14 +73,13 @@ void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info& mem)
void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info& mem, map <string ,TiXmlElement *>& knownEntries)
void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info* mem, map <string ,TiXmlElement *>& knownEntries)
{
TiXmlElement* pMemEntry;
const char *cstr_version = entry->Attribute("version");
const char *cstr_os = entry->Attribute("os");
const char *cstr_base = entry->Attribute("base");
const char *cstr_rebase = entry->Attribute("rebase");
// printf("%s : %s\n",cstr_version, cstr_os);
if(cstr_base)
{
string base = cstr_base;
@ -95,28 +94,28 @@ void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info& mem, map <str
return;
}
string os = cstr_os;
mem.setVersion(cstr_version);
mem.setOS(cstr_os);
mem->setVersion(cstr_version);
mem->setOS(cstr_os);
// offset inherited addresses by 'rebase'.
int32_t rebase = 0;
if(cstr_rebase)
{
rebase = mem.getBase() + strtol(cstr_rebase, NULL, 16);
mem.RebaseAddresses(rebase);
rebase = mem->getBase() + strtol(cstr_rebase, NULL, 16);
mem->RebaseAddresses(rebase);
}
//set base to default, we're overwriting this because the previous rebase could cause havoc on Vista/7
if(os == "windows")
{
// set default image base. this is fixed for base relocation later
mem.setBase(0x400000);
mem->setBase(0x400000);
}
else if(os == "linux")
{
// this is wrong... I'm not going to do base image relocation on linux though.
// users are free to use a sane kernel that doesn't do this kind of **** by default
mem.setBase(0x0);
mem->setBase(0x0);
}
else if ( os == "all")
{
@ -154,39 +153,39 @@ void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info& mem, map <str
value = cstr_value;
if (type == "HexValue")
{
mem.setHexValue(name, value);
mem->setHexValue(name, value);
}
else if (type == "Address")
{
mem.setAddress(name, value);
mem->setAddress(name, value);
}
else if (type == "Offset")
{
mem.setOffset(name, value);
mem->setOffset(name, value);
}
else if (type == "String")
{
mem.setString(name, value);
mem->setString(name, value);
}
else if (type == "Profession")
{
mem.setProfession(value,name);
mem->setProfession(value,name);
}
else if (type == "Job")
{
mem.setJob(value,name);
mem->setJob(value,name);
}
else if (type == "Skill")
{
mem.setSkill(value,name);
mem->setSkill(value,name);
}
else if (type == "Trait")
{
mem.setTrait(value, name,pMemEntry->Attribute("level_0"),pMemEntry->Attribute("level_1"),pMemEntry->Attribute("level_2"),pMemEntry->Attribute("level_3"),pMemEntry->Attribute("level_4"),pMemEntry->Attribute("level_5"));
mem->setTrait(value, name,pMemEntry->Attribute("level_0"),pMemEntry->Attribute("level_1"),pMemEntry->Attribute("level_2"),pMemEntry->Attribute("level_3"),pMemEntry->Attribute("level_4"),pMemEntry->Attribute("level_5"));
}
else if (type == "Labor")
{
mem.setLabor(value,name);
mem->setLabor(value,name);
}
else
{
@ -235,6 +234,10 @@ bool MemInfoManager::loadFile(string path_to_xml)
// transform elements
{
// trash existing list
for(int i = 0; i < meminfo.size(); i++)
{
delete meminfo[i];
}
meminfo.clear();
TiXmlElement* pMemInfo=hRoot.FirstChild( "MemoryDescriptors" ).FirstChild( "Entry" ).Element();
map <string ,TiXmlElement *> map_pNamedEntries;
@ -251,7 +254,7 @@ bool MemInfoManager::loadFile(string path_to_xml)
}
for(uint32_t i = 0; i< v_pEntries.size();i++)
{
memory_info mem;
memory_info *mem = new memory_info();
//FIXME: add a set of entries processed in a step of this cycle, use it to check for infinite loops
/* recursive */ParseEntry( v_pEntries[i] , mem , map_pNamedEntries);
meminfo.push_back(mem);

@ -38,9 +38,9 @@ namespace DFHack
bool loadFile( string path_to_xml);
bool isInErrorState() const {return error;};
private:
std::vector<memory_info> meminfo;
void ParseVTable(TiXmlElement* vtable, memory_info& mem);
void ParseEntry (TiXmlElement* entry, memory_info& mem, map <string ,TiXmlElement *>& knownEntries);
std::vector<memory_info*> meminfo;
void ParseVTable(TiXmlElement* vtable, memory_info* mem);
void ParseEntry (TiXmlElement* entry, memory_info* mem, map <string ,TiXmlElement *>& knownEntries);
bool error;
};
}

@ -60,7 +60,7 @@ class SHMProcess::Private
bool suspended;
bool identified;
bool validate(char * exe_file, uint32_t pid, vector <memory_info> & known_versions);
bool validate(char* exe_file, uint32_t pid, std::vector< memory_info* >& known_versions);
bool waitWhile (DF_PINGPONG state);
bool DF_TestBridgeVersion(bool & ret);
bool DF_GetPID(pid_t & ret);
@ -124,7 +124,7 @@ bool SHMProcess::Private::DF_GetPID(pid_t & ret)
return true;
}
SHMProcess::SHMProcess(vector <memory_info> & known_versions)
SHMProcess::SHMProcess(vector <memory_info *> & known_versions)
: d(new Private())
{
char exe_link_name [256];
@ -214,19 +214,19 @@ bool SHMProcess::isIdentified()
return d->identified;
}
bool SHMProcess::Private::validate(char * exe_file, uint32_t pid, vector <memory_info> & known_versions)
bool SHMProcess::Private::validate(char * exe_file, uint32_t pid, vector <memory_info *> & known_versions)
{
md5wrapper md5;
// get hash of the running DF process
string hash = md5.getHashFromFile(exe_file);
vector<memory_info>::iterator it;
vector<memory_info *>::iterator it;
cerr << exe_file << " " << hash << endl;
// iterate over the list of memory locations
for ( it=known_versions.begin() ; it < known_versions.end(); it++ )
{
if(hash == (*it).getString("md5")) // are the md5 hashes the same?
if(hash == (*it)->getString("md5")) // are the md5 hashes the same?
{
memory_info * m = &*it;
memory_info * m = *it;
my_descriptor = m;
my_pid = pid;
identified = true;

@ -49,10 +49,10 @@ class WineProcess::Private
bool attached;
bool suspended;
bool identified;
bool validate(char * exe_file, uint32_t pid, char * mem_file, vector <memory_info> & known_versions);
bool validate(char * exe_file, uint32_t pid, char * mem_file, vector <memory_info *> & known_versions);
};
WineProcess::WineProcess(uint32_t pid, vector <memory_info> & known_versions)
WineProcess::WineProcess(uint32_t pid, vector <memory_info *> & known_versions)
: d(new Private())
{
char dir_name [256];
@ -129,20 +129,20 @@ bool WineProcess::isIdentified()
return d->identified;
}
bool WineProcess::Private::validate(char * exe_file,uint32_t pid, char * memFile, vector <memory_info> & known_versions)
bool WineProcess::Private::validate(char* exe_file, uint32_t pid, char* mem_file, std::vector< memory_info* >& known_versions)
{
md5wrapper md5;
// get hash of the running DF process
string hash = md5.getHashFromFile(exe_file);
vector<memory_info>::iterator it;
vector<memory_info *>::iterator it;
// iterate over the list of memory locations
for ( it=known_versions.begin() ; it < known_versions.end(); it++ )
{
// are the md5 hashes the same?
if(memory_info::OS_WINDOWS == (*it).getOS() && hash == (*it).getString("md5"))
if(memory_info::OS_WINDOWS == (*it)->getOS() && hash == (*it)->getString("md5"))
{
memory_info * m = &*it;
memory_info * m = *it;
my_descriptor = m;
my_handle = my_pid = pid;
// tell WineProcess about the /proc/PID/mem file

@ -49,10 +49,10 @@ class NormalProcess::Private
bool attached;
bool suspended;
bool identified;
bool validate(char * exe_file, uint32_t pid, char * mem_file, vector <memory_info> & known_versions);
bool validate(char * exe_file, uint32_t pid, char * mem_file, vector <memory_info *> & known_versions);
};
NormalProcess::NormalProcess(uint32_t pid, vector <memory_info> & known_versions)
NormalProcess::NormalProcess(uint32_t pid, vector< memory_info* >& known_versions)
: d(new Private())
{
char dir_name [256];
@ -104,20 +104,20 @@ bool NormalProcess::isIdentified()
return d->identified;
}
bool NormalProcess::Private::validate(char * exe_file,uint32_t pid, char * memFile, vector <memory_info> & known_versions)
bool NormalProcess::Private::validate(char * exe_file,uint32_t pid, char * memFile, vector <memory_info *> & known_versions)
{
md5wrapper md5;
// get hash of the running DF process
string hash = md5.getHashFromFile(exe_file);
vector<memory_info>::iterator it;
vector<memory_info *>::iterator it;
// iterate over the list of memory locations
for ( it=known_versions.begin() ; it < known_versions.end(); it++ )
{
if(hash == (*it).getString("md5")) // are the md5 hashes the same?
if(hash == (*it)->getString("md5")) // are the md5 hashes the same?
{
memory_info * m = &*it;
if (memory_info::OS_LINUX == (*it).getOS())
memory_info * m = *it;
if (memory_info::OS_LINUX == m->getOS())
{
my_descriptor = m;
my_handle = my_pid = pid;

@ -145,7 +145,7 @@ bool SHMProcess::Private::DF_GetPID(uint32_t & ret)
return true;
}
SHMProcess::SHMProcess(vector <memory_info> & known_versions)
SHMProcess::SHMProcess(vector <memory_info *> & known_versions)
: d(new Private())
{
// get server and client mutex
@ -227,13 +227,13 @@ SHMProcess::SHMProcess(vector <memory_info> & known_versions)
read(base + pe_offset+ sizeof(pe_header), sizeof(sections) , (uint8_t *)&sections );
// iterate over the list of memory locations
vector<memory_info>::iterator it;
vector<memory_info *>::iterator it;
for ( it=known_versions.begin() ; it < known_versions.end(); it++ )
{
uint32_t pe_timestamp = (*it).getHexValue("pe_timestamp");
uint32_t pe_timestamp = (*it)->getHexValue("pe_timestamp");
if (pe_timestamp == pe_header.FileHeader.TimeDateStamp)
{
memory_info *m = new memory_info(*it);
memory_info *m = new memory_info(**it);
m->RebaseAll(base);
d->my_descriptor = m;
d->identified = true;

@ -49,7 +49,7 @@ class NormalProcess::Private
bool identified;
};
NormalProcess::NormalProcess(uint32_t pid, vector <memory_info> & known_versions)
NormalProcess::NormalProcess(uint32_t pid, vector <memory_info *> & known_versions)
: d(new Private())
{
HMODULE hmod = NULL;
@ -85,24 +85,24 @@ NormalProcess::NormalProcess(uint32_t pid, vector <memory_info> & known_versions
d->my_handle = 0;
// see if there's a version entry that matches this process
vector<memory_info>::iterator it;
vector<memory_info*>::iterator it;
for ( it=known_versions.begin() ; it < known_versions.end(); it++ )
{
// filter by OS
if(memory_info::OS_WINDOWS != (*it).getOS())
if(memory_info::OS_WINDOWS != (*it)->getOS())
continue;
// filter by timestamp
uint32_t pe_timestamp = (*it).getHexValue("pe_timestamp");
uint32_t pe_timestamp = (*it)->getHexValue("pe_timestamp");
if (pe_timestamp != pe_header.FileHeader.TimeDateStamp)
continue;
// all went well
{
printf("Match found! Using version %s.\n", (*it).getVersion().c_str());
printf("Match found! Using version %s.\n", (*it)->getVersion().c_str());
d->identified = true;
// give the process a data model and memory layout fixed for the base of first module
memory_info *m = new memory_info(*it);
memory_info *m = new memory_info(**it);
m->RebaseAll(base);
// keep track of created memory_info object so we can destroy it later
d->my_descriptor = m;

@ -129,7 +129,7 @@ namespace DFHack
Private * const d;
public:
NormalProcess(uint32_t pid, vector <memory_info> & known_versions);
NormalProcess(uint32_t pid, vector <memory_info *> & known_versions);
~NormalProcess();
bool attach();
bool detach();
@ -181,7 +181,7 @@ namespace DFHack
Private * const d;
public:
SHMProcess(vector <memory_info> & known_versions);
SHMProcess(vector <memory_info *> & known_versions);
~SHMProcess();
// Set up stuff so we can read memory
bool attach();
@ -235,7 +235,7 @@ namespace DFHack
Private * const d;
public:
WineProcess(uint32_t pid, vector <memory_info> & known_versions);
WineProcess(uint32_t pid, vector <memory_info *> & known_versions);
~WineProcess();
bool attach();
bool detach();

@ -47,9 +47,6 @@ bool ProcessEnumerator::findProcessess()
DIR *dir_p;
struct dirent *dir_entry_p;
int errorcount;
int result;
Process *p = 0;
p = new SHMProcess(d->meminfo->meminfo);
if(p->isIdentified())