creatures almost done

develop
Petr Mrázek 2009-11-14 03:46:56 +00:00
parent e88e9b2951
commit 37d08a05ca
17 changed files with 518 additions and 435 deletions

@ -23,7 +23,7 @@ distribution.
*/
#include "DFCommonInternal.h"
using namespace DFHack;
DfVector DMWindows40d::readVector (uint32_t offset, uint32_t item_size)
{

@ -25,30 +25,32 @@ distribution.
#ifndef DATAMODEL_H_INCLUDED
#define DATAMODEL_H_INCLUDED
class DfVector;
// let's go pure virtual.
class DataModel
{
public:
// read a string
virtual const string readSTLString (uint32_t offset) = 0;
// read a vector from memory
virtual DfVector readVector (uint32_t offset, uint32_t item_size) = 0;
};
class DMWindows40d : public DataModel
namespace DFHack
{
virtual const string readSTLString (uint32_t offset);
// read a vector from memory
virtual DfVector readVector (uint32_t offset, uint32_t item_size);
};
class DMLinux40d : public DataModel
{
virtual const string readSTLString (uint32_t offset);
// read a vector from memory
virtual DfVector readVector (uint32_t offset, uint32_t item_size);
};
class DfVector;
// let's go pure virtual.
class DataModel
{
public:
// read a string
virtual const string readSTLString (uint32_t offset) = 0;
// read a vector from memory
virtual DfVector readVector (uint32_t offset, uint32_t item_size) = 0;
};
class DMWindows40d : public DataModel
{
virtual const string readSTLString (uint32_t offset);
// read a vector from memory
virtual DfVector readVector (uint32_t offset, uint32_t item_size);
};
class DMLinux40d : public DataModel
{
virtual const string readSTLString (uint32_t offset);
// read a vector from memory
virtual DfVector readVector (uint32_t offset, uint32_t item_size);
};
}
#endif // DATAMODEL_H_INCLUDED

@ -953,7 +953,7 @@ void API::Private::getLaborsByAddress(const uint32_t &address, vector<t_labor> &
tempLabor.name = offset_descriptor->getLabor(i);
tempLabor.value = laborArray[i];
labors.push_back(tempLabor);
}
}
}*/
bool API::ReadCreature(const uint32_t &index, t_creature & furball)
{
@ -973,18 +973,33 @@ bool API::ReadCreature(const uint32_t &index, t_creature & furball)
Mread(temp + d->creature_last_name_offset,sizeof(t_lastname), (uint8_t *) &furball.last_name );
Mread(temp + d->creature_squad_name_offset,sizeof(t_squadname), (uint8_t *) &furball.squad_name );
// custom profession
fill_char_buf(furball.custom_profession, d->dm->readSTLString(temp+d->creature_first_name_offset));
/*
furball.profession = d->getProfessionByAddress(temp+d->creature_profession_offset);
furball.current_job = d->getCurrentJobByAddress(temp+d->creature_current_job_offset);
d->getSkillsByAddress(temp+d->creature_skills_offset,furball.skills);
d->getTraitsByAddress(temp+d->creature_traits_offset,furball.traits);
d->getLaborsByAddress(temp+d->creature_labors_offset,furball.labors);
*/
fill_char_buf(furball.custom_profession, d->dm->readSTLString(temp+d->creature_custom_profession_offset));
// labors
Mread(temp+d->creature_labors_offset, NUM_CREATURE_LABORS, furball.labors);
// traits
Mread(temp+d->creature_traits_offset, sizeof(uint16_t) * NUM_CREATURE_TRAITS, (uint8_t *) &furball.traits);
// learned skills
DfVector skills(d->dm->readVector(temp+d->creature_skills_offset,4));
furball.numSkills = skills.getSize();
for(uint32_t i = 0; i<furball.numSkills;i++)
{
uint32_t temp2;
skills.read(i, (uint8_t *) &temp2);
// a byte: this gives us 256 skills maximum.
furball.skills[i].id= MreadByte(temp2);
furball.skills[i].rating = MreadByte(temp2+4);
furball.skills[i].experience = MreadWord(temp2+8);
}
// profession
furball.profession = MreadByte(temp+d->creature_profession_offset);
// current job HACK: the job object isn't cleanly represented here
uint32_t jobIdAddr = MreadDWord(temp+d->creature_current_job_offset);
if(furball.current_job.active = jobIdAddr != 0)
{
furball.current_job.jobId = MreadByte(jobIdAddr+d->creature_current_job_id_offset);
}
MreadDWord(temp + d->creature_happiness_offset, furball.happiness);
MreadDWord(temp + d->creature_id_offset, furball.id);
MreadDWord(temp + d->creature_agility_offset, furball.agility);
@ -1150,4 +1165,9 @@ bool API::setCursorCoords (const int32_t &x, const int32_t &y, const int32_t &z)
int32_t coords[3] = {x,y,z};
Mwrite(d->cursor_xyz_offset,3*sizeof(int32_t),(uint8_t *)coords);
return true;
}
memory_info API::getMemoryInfo()
{
return *d->offset_descriptor;
}

@ -25,174 +25,159 @@ distribution.
#ifndef SIMPLEAPI_H_INCLUDED
#define SIMPLEAPI_H_INCLUDED
/// TODO: add visibility for GCC?
#ifdef LINUX_BUILD
# ifndef DFHACK_EXPORT
# define DFHACK_EXPORT
# endif
#else
# ifdef BUILD_DFHACK_LIB
# ifndef DFHACK_EXPORT
# define DFHACK_EXPORT __declspec(dllexport)
# endif
# else
# ifndef DFHACK_EXPORT
# define DFHACK_EXPORT __declspec(dllimport)
# endif
# endif
#endif
#include "Export.h"
#include <string>
#include <vector>
#include "integers.h"
namespace DFHack
{
enum VegetationType
{
TREE_DEAD,
TREE_OK,
SAPLING_DEAD,
SAPLING_OK,
SHRUB_DEAD,
SHRUB_OK
};
DFHACK_EXPORT bool isWallTerrain(int in);
DFHACK_EXPORT bool isFloorTerrain(int in);
DFHACK_EXPORT bool isRampTerrain(int in);
DFHACK_EXPORT bool isStairTerrain(int in);
DFHACK_EXPORT bool isOpenTerrain(int in);
DFHACK_EXPORT int getVegetationType(int in);
class DFHACK_EXPORT API
{
class Private;
Private * const d;
public:
API(const string path_to_xml);
~API();
bool Attach();
bool Detach();
bool isAttached();
/**
* Matgloss. next four methods look very similar. I could use two and move the processing one level up...
* I'll keep it like this, even with the code duplication as it will hopefully get more features and separate data types later.
* Yay for nebulous plans for a rock survey tool that tracks how much of which metal could be smelted from available resorces
*/
bool ReadStoneMatgloss(vector<t_matgloss> & output);
bool ReadWoodMatgloss (vector<t_matgloss> & output);
bool ReadMetalMatgloss(vector<t_matgloss> & output);
bool ReadPlantMatgloss(vector<t_matgloss> & output);
bool ReadCreatureMatgloss(vector<t_matgloss> & output);
// read region surroundings, get their vectors of geolayers so we can do translation (or just hand the translation table to the client)
// returns an array of 9 vectors of indices into stone matgloss
/**
Method for reading the geological surrounding of the currently loaded region.
assign is a reference to an array of nine vectors of unsigned words that are to be filled with the data
array is indexed by the BiomeOffset enum
I omitted resolving the layer matgloss in this API, because it would
introduce overhead by calling some method for each tile. You have to do it
yourself. First get the stuff from ReadGeology and then for each block get
the RegionOffsets. For each tile get the real region from RegionOffsets and
cross-reference it with the geology stuff (region -- array of vectors, depth --
vector). I'm thinking about turning that Geology stuff into a
two-dimensional array with static size.
this is the algorithm for applying matgloss:
void DfMap::applyGeoMatgloss(Block * b)
{
// load layer matgloss
for(int x_b = 0; x_b < BLOCK_SIZE; x_b++)
class memory_info;
enum VegetationType
{
TREE_DEAD,
TREE_OK,
SAPLING_DEAD,
SAPLING_OK,
SHRUB_DEAD,
SHRUB_OK
};
DFHACK_EXPORT bool isWallTerrain(int in);
DFHACK_EXPORT bool isFloorTerrain(int in);
DFHACK_EXPORT bool isRampTerrain(int in);
DFHACK_EXPORT bool isStairTerrain(int in);
DFHACK_EXPORT bool isOpenTerrain(int in);
DFHACK_EXPORT int getVegetationType(int in);
class DFHACK_EXPORT API
{
class Private;
Private * const d;
public:
API(const string path_to_xml);
~API();
bool Attach();
bool Detach();
bool isAttached();
/**
* Matgloss. next four methods look very similar. I could use two and move the processing one level up...
* I'll keep it like this, even with the code duplication as it will hopefully get more features and separate data types later.
* Yay for nebulous plans for a rock survey tool that tracks how much of which metal could be smelted from available resorces
*/
bool ReadStoneMatgloss(vector<t_matgloss> & output);
bool ReadWoodMatgloss (vector<t_matgloss> & output);
bool ReadMetalMatgloss(vector<t_matgloss> & output);
bool ReadPlantMatgloss(vector<t_matgloss> & output);
bool ReadCreatureMatgloss(vector<t_matgloss> & output);
// read region surroundings, get their vectors of geolayers so we can do translation (or just hand the translation table to the client)
// returns an array of 9 vectors of indices into stone matgloss
/**
Method for reading the geological surrounding of the currently loaded region.
assign is a reference to an array of nine vectors of unsigned words that are to be filled with the data
array is indexed by the BiomeOffset enum
I omitted resolving the layer matgloss in this API, because it would
introduce overhead by calling some method for each tile. You have to do it
yourself. First get the stuff from ReadGeology and then for each block get
the RegionOffsets. For each tile get the real region from RegionOffsets and
cross-reference it with the geology stuff (region -- array of vectors, depth --
vector). I'm thinking about turning that Geology stuff into a
two-dimensional array with static size.
this is the algorithm for applying matgloss:
void DfMap::applyGeoMatgloss(Block * b)
{
for(int y_b = 0; y_b < BLOCK_SIZE; y_b++)
// load layer matgloss
for(int x_b = 0; x_b < BLOCK_SIZE; x_b++)
{
int geolayer = b->designation[x_b][y_b].bits.geolayer_index;
int biome = b->designation[x_b][y_b].bits.biome;
b->material[x_b][y_b].type = Mat_Stone;
b->material[x_b][y_b].index = v_geology[b->RegionOffsets[biome]][geolayer];
for(int y_b = 0; y_b < BLOCK_SIZE; y_b++)
{
int geolayer = b->designation[x_b][y_b].bits.geolayer_index;
int biome = b->designation[x_b][y_b].bits.biome;
b->material[x_b][y_b].type = Mat_Stone;
b->material[x_b][y_b].index = v_geology[b->RegionOffsets[biome]][geolayer];
}
}
}
}
*/
bool ReadGeology( vector < vector <uint16_t> >& assign );
/*
* BLOCK DATA
*/
/// allocate and read pointers to map blocks
bool InitMap();
/// destroy the mapblock cache
bool DestroyMap();
/// get size of the map in tiles
void getSize(uint32_t& x, uint32_t& y, uint32_t& z);
/**
* Return false/0 on failure, buffer allocated by client app, 256 items long
*/
bool isValidBlock(uint32_t blockx, uint32_t blocky, uint32_t blockz);
bool ReadTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint16_t *buffer); // 256 * sizeof(uint16_t)
bool WriteTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint16_t *buffer); // 256 * sizeof(uint16_t)
bool ReadDesignations(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint32_t *buffer); // 256 * sizeof(uint32_t)
bool WriteDesignations (uint32_t blockx, uint32_t blocky, uint32_t blockz, uint32_t *buffer);
bool ReadOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint32_t *buffer); // 256 * sizeof(uint32_t)
bool WriteOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint32_t *buffer); // 256 * sizeof(uint32_t)
/// read region offsets of a block
bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint8_t *buffer); // 16 * sizeof(uint8_t)
/// read aggregated veins of a block
bool ReadVeins(uint32_t blockx, uint32_t blocky, uint32_t blockz, vector <t_vein> & veins);
/**
* Buildings, constructions, plants, all pretty straighforward. InitReadBuildings returns all the building types as a mapping between a numeric values and strings
*/
uint32_t InitReadConstructions();
bool ReadConstruction(const uint32_t &index, t_construction & construction);
void FinishReadConstructions();
uint32_t InitReadBuildings(vector <string> &v_buildingtypes);
bool ReadBuilding(const uint32_t &index, t_building & building);
void FinishReadBuildings();
uint32_t InitReadVegetation();
bool ReadVegetation(const uint32_t &index, t_tree_desc & shrubbery);
void FinishReadVegetation();
uint32_t InitReadCreatures();
bool ReadCreature(const uint32_t &index, t_creature & furball);
void FinishReadCreatures();
void ReadRaw (const uint32_t &offset, const uint32_t &size, uint8_t *target);
void WriteRaw (const uint32_t &offset, const uint32_t &size, uint8_t *source);
bool InitViewAndCursor();
bool getViewCoords (int32_t &x, int32_t &y, int32_t &z);
bool setViewCoords (const int32_t &x, const int32_t &y, const int32_t &z);
bool getCursorCoords (int32_t &x, int32_t &y, int32_t &z);
bool setCursorCoords (const int32_t &x, const int32_t &y, const int32_t &z);
/*
// FIXME: add a real creature class, move these
string getLastName(const uint32_t &index, bool);
string getSquadName(const uint32_t &index, bool);
string getProfession(const uint32_t &index);
string getCurrentJob(const uint32_t &index);
vector<t_skill> getSkills(const uint32_t &index);
vector<t_trait> getTraits(const uint32_t &index);
vector<t_labor> getLabors(const uint32_t &index);
*/
void InitReadNameTables();
void FinishReadNameTables();
};
*/
bool ReadGeology( vector < vector <uint16_t> >& assign );
/*
* BLOCK DATA
*/
/// allocate and read pointers to map blocks
bool InitMap();
/// destroy the mapblock cache
bool DestroyMap();
/// get size of the map in tiles
void getSize(uint32_t& x, uint32_t& y, uint32_t& z);
/**
* Return false/0 on failure, buffer allocated by client app, 256 items long
*/
bool isValidBlock(uint32_t blockx, uint32_t blocky, uint32_t blockz);
bool ReadTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint16_t *buffer); // 256 * sizeof(uint16_t)
bool WriteTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint16_t *buffer); // 256 * sizeof(uint16_t)
bool ReadDesignations(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint32_t *buffer); // 256 * sizeof(uint32_t)
bool WriteDesignations (uint32_t blockx, uint32_t blocky, uint32_t blockz, uint32_t *buffer);
bool ReadOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint32_t *buffer); // 256 * sizeof(uint32_t)
bool WriteOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint32_t *buffer); // 256 * sizeof(uint32_t)
/// read region offsets of a block
bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz, uint8_t *buffer); // 16 * sizeof(uint8_t)
/// read aggregated veins of a block
bool ReadVeins(uint32_t blockx, uint32_t blocky, uint32_t blockz, vector <t_vein> & veins);
/**
* Buildings, constructions, plants, all pretty straighforward. InitReadBuildings returns all the building types as a mapping between a numeric values and strings
*/
uint32_t InitReadConstructions();
bool ReadConstruction(const uint32_t &index, t_construction & construction);
void FinishReadConstructions();
uint32_t InitReadBuildings(vector <string> &v_buildingtypes);
bool ReadBuilding(const uint32_t &index, t_building & building);
void FinishReadBuildings();
uint32_t InitReadVegetation();
bool ReadVegetation(const uint32_t &index, t_tree_desc & shrubbery);
void FinishReadVegetation();
uint32_t InitReadCreatures();
bool ReadCreature(const uint32_t &index, t_creature & furball);
void FinishReadCreatures();
void ReadRaw (const uint32_t &offset, const uint32_t &size, uint8_t *target);
void WriteRaw (const uint32_t &offset, const uint32_t &size, uint8_t *source);
bool InitViewAndCursor();
bool getViewCoords (int32_t &x, int32_t &y, int32_t &z);
bool setViewCoords (const int32_t &x, const int32_t &y, const int32_t &z);
bool getCursorCoords (int32_t &x, int32_t &y, int32_t &z);
bool setCursorCoords (const int32_t &x, const int32_t &y, const int32_t &z);
/*
// FIXME: add a real creature class, move these
string getLastName(const uint32_t &index, bool);
string getSquadName(const uint32_t &index, bool);
string getProfession(const uint32_t &index);
string getCurrentJob(const uint32_t &index);
vector<t_skill> getSkills(const uint32_t &index);
vector<t_trait> getTraits(const uint32_t &index);
vector<t_labor> getLabors(const uint32_t &index);
*/
void InitReadNameTables();
void FinishReadNameTables();
memory_info getMemoryInfo();
};
} // namespace DFHack
#endif // SIMPLEAPI_H_INCLUDED

@ -25,9 +25,6 @@ distribution.
#ifndef PROCESSUTIL_H_INCLUDED
#define PROCESSUTIL_H_INCLUDED
// SLOW!
// #include "LinuxMemAccess-ptrace.h"
#ifdef LINUX_BUILD
#include "LinuxMemAccess-memfiles.h"
#else

@ -24,6 +24,8 @@ distribution.
#include "DFCommonInternal.h"
using namespace DFHack;
memory_info::memory_info()
{
base = 0;
@ -105,7 +107,7 @@ memory_info::memory_info(const memory_info &old)
professions = old.professions;
jobs = old.jobs;
skills = old.skills;
traits = old.traits;
traits = old.traits;
labors = old.labors;
}
@ -159,10 +161,12 @@ void memory_info::setLabor(string key, string value)
uint32_t keyInt = strtol(key.c_str(), NULL, 10);
labors[keyInt] = value;
}
void memory_info::setProfession (string key, string value)
{
uint32_t keyInt = strtol(key.c_str(), NULL, 10);
if(professions.size() <= keyInt){
if(professions.size() <= keyInt)
{
professions.resize(keyInt+1);
}
professions[keyInt] = value;
@ -171,7 +175,8 @@ void memory_info::setProfession (string key, string value)
void memory_info::setJob (string key, string value)
{
uint32_t keyInt = strtol(key.c_str(), NULL, 10);
if(jobs.size() <= keyInt){
if(jobs.size() <= keyInt)
{
jobs.resize(keyInt+1);
}
jobs[keyInt] = value;
@ -188,17 +193,18 @@ void memory_info::setSkill (string key, string value)
void memory_info::setTrait(string key,string value,string zero,string one,string two,string three,string four,string five)
{
uint32_t keyInt = strtol(key.c_str(), NULL, 10);
if(traits.size() <= keyInt){
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);
uint32_t keyInt = strtol(key.c_str(), NULL, 10);
if(traits.size() <= keyInt)
{
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);
}
// FIXME: next three methods should use some kind of custom container so it doesn't have to search so much.
@ -475,20 +481,20 @@ string memory_info::getTrait (uint32_t traitIdx, uint32_t traitValue)
return string("Trait is not Defined");
}
string memory_info::getTraitName(uint32_t key)
string memory_info::getTraitName(uint32_t traitIdx)
{
if(traits.size() > key)
if(traits.size() > traitIdx)
{
return traits[key][traits[key].size()-1];
return traits[traitIdx][traits[traitIdx].size()-1];
}
return string("Trait is not Defined");
}
string memory_info::getLabor (uint32_t key)
string memory_info::getLabor (uint32_t laborIdx)
{
if(labors.count(key))
if(labors.count(laborIdx))
{
return labors[key];
return labors[laborIdx];
}
return string("");
}

@ -25,108 +25,116 @@ distribution.
#ifndef MEMINFO_H_INCLUDED
#define MEMINFO_H_INCLUDED
class memory_info
#include "Export.h"
#include <map>
#include <vector>
#include <string>
namespace DFHack
{
public:
enum OSType
{
OS_WINDOWS,
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
class DFHACK_EXPORT memory_info
{
string classname;
uint32_t assign;
uint32_t type;
public:
enum OSType
{
OS_WINDOWS,
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&);
void RebaseAddresses(int32_t new_base);
void RebaseAll(int32_t new_base);
uint32_t getBase ();
void setBase (string);
void setBase (uint32_t);
uint32_t getOffset (string);
uint32_t getAddress (string);
uint32_t getHexValue (string);
string getString (string);
string getProfession(uint32_t);
string getJob(uint32_t);
string getSkill (uint32_t);
string getTrait (uint32_t, uint32_t);
string getTraitName(uint32_t);
string getLabor (uint32_t);
void setVersion(const char *);
void setVersion(string);
string getVersion();
void setOS(const char *);
void setOS(string);
void setOS(OSType);
OSType getOS();
void setOffset (string, int32_t);
void setAddress (string, uint32_t);
void setHexValue (string, uint32_t);
void setOffset (string, const char *);
void setAddress (string, const char *);
void setHexValue (string, const char *);
void setString (string, const char *);
void setOffset (string, string);
void setAddress (string, string);
void setHexValue (string, string);
void setString (string, string);
void setProfession(string, string);
void setJob(string, string);
void setSkill(string, string);
void setTrait(string,string,string,string,string,string,string,string);
void setLabor(string, string);
void RebaseVTable(int32_t offset);
void setClass (const char * name, const char * vtable);
uint32_t setMultiClass (const char * name, const char * vtable, const char * typeoffset);
void setMultiClassChild (uint32_t multi_index, const char * name, const char * type);
// ALERT: uses memory reading directly
bool resolveClassId(uint32_t address, int32_t & classid);
void copyBuildings(vector<string> & v_buildingtypes);
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;
};
memory_info();
memory_info(const memory_info&);
void RebaseAddresses(int32_t new_base);
void RebaseAll(int32_t new_base);
uint32_t getBase ();
void setBase (string);
void setBase (uint32_t);
uint32_t getOffset (string);
uint32_t getAddress (string);
uint32_t getHexValue (string);
string getString (string);
string getProfession(uint32_t);
string getJob(uint32_t);
string getSkill (uint32_t);
string getTrait (uint32_t, uint32_t);
string getTraitName(uint32_t);
string getLabor (uint32_t);
void setVersion(const char *);
void setVersion(string);
string getVersion();
void setOS(const char *);
void setOS(string);
void setOS(OSType);
OSType getOS();
void setOffset (string, int32_t);
void setAddress (string, uint32_t);
void setHexValue (string, uint32_t);
void setOffset (string, const char *);
void setAddress (string, const char *);
void setHexValue (string, const char *);
void setString (string, const char *);
void setOffset (string, string);
void setAddress (string, string);
void setHexValue (string, string);
void setString (string, string);
void setProfession(string, string);
void setJob(string, string);
void setSkill(string, string);
void setTrait(string,string,string,string,string,string,string,string);
void setLabor(string, string);
void RebaseVTable(int32_t offset);
void setClass (const char * name, const char * vtable);
uint32_t setMultiClass (const char * name, const char * vtable, const char * typeoffset);
void setMultiClassChild (uint32_t multi_index, const char * name, const char * type);
// ALERT: uses memory reading directly
bool resolveClassId(uint32_t address, int32_t & classid);
void copyBuildings(vector<string> & v_buildingtypes);
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

@ -23,7 +23,7 @@ distribution.
*/
#include "DFCommonInternal.h"
using namespace DFHack;
Process::Process(DataModel * dm, memory_info* mi, ProcessHandle ph, uint32_t pid)
{

@ -23,11 +23,12 @@ distribution.
*/
#include "DFCommonInternal.h"
using namespace DFHack;
/// HACK: global variables (only one process can be attached at the same time.)
Process * g_pProcess; ///< current process. non-NULL when picked
ProcessHandle g_ProcessHandle; ///< cache of handle to current process. used for speed reasons
int g_ProcessMemFile; ///< opened /proc/PID/mem, valid when attached
Process * DFHack::g_pProcess; ///< current process. non-NULL when picked
ProcessHandle DFHack::g_ProcessHandle; ///< cache of handle to current process. used for speed reasons
int DFHack::g_ProcessMemFile; ///< opened /proc/PID/mem, valid when attached
#ifdef LINUX_BUILD

@ -25,73 +25,77 @@ distribution.
#ifndef PROCESSMANAGER_H_INCLUDED
#define PROCESSMANAGER_H_INCLUDED
#ifdef LINUX_BUILD
typedef pid_t ProcessHandle;
#else
typedef HANDLE ProcessHandle;
#endif
class memory_info;
class DataModel;
class TiXmlElement;
class Process;
/*
* Currently attached process and its handle
*/
extern Process * g_pProcess; ///< current process. non-NULL when picked
extern ProcessHandle g_ProcessHandle; ///< cache of handle to current process. used for speed reasons
extern int g_ProcessMemFile; ///< opened /proc/PID/mem, valid when attached
class Process
namespace DFHack
{
friend class ProcessManager;
protected:
Process(DataModel * dm, memory_info* mi, ProcessHandle ph, uint32_t pid);
~Process();
DataModel* my_datamodel;
memory_info * my_descriptor;
ProcessHandle my_handle;
uint32_t my_pid;
string memFile;
bool attached;
void freeResources();
void setMemFile(const string & memf);
public:
// Set up stuff so we can read memory
bool attach();
bool detach();
// is the process still there?
memory_info *getDescriptor();
DataModel *getDataModel();
};
/*
* Process manager
*/
class ProcessManager
{
public:
ProcessManager( string path_to_xml);
~ProcessManager();
bool findProcessess();
uint32_t size();
Process * operator[](uint32_t index);
class memory_info;
class DataModel;
class Process;
#ifdef LINUX_BUILD
typedef pid_t ProcessHandle;
#else
typedef HANDLE ProcessHandle;
#endif
/*
* Currently attached process and its handle
*/
extern Process * g_pProcess; ///< current process. non-NULL when picked
extern ProcessHandle g_ProcessHandle; ///< cache of handle to current process. used for speed reasons
extern int g_ProcessMemFile; ///< opened /proc/PID/mem, valid when attached
private:
// memory info entries loaded from a file
std::vector<memory_info> meminfo;
// vector to keep track of dynamically created memory_info entries
std::vector<memory_info *> destroy_meminfo;
Process * currentProcess;
ProcessHandle currentProcessHandle;
std::vector<Process *> processes;
bool loadDescriptors( string path_to_xml);
void ParseVTable(TiXmlElement* vtable, memory_info& mem);
void ParseEntry (TiXmlElement* entry, memory_info& mem, map <string ,TiXmlElement *>& knownEntries);
#ifdef LINUX_BUILD
Process* addProcess(const string & exe,ProcessHandle PH,const string & memFile);
#endif
};
class Process
{
friend class ProcessManager;
protected:
Process(DataModel * dm, memory_info* mi, ProcessHandle ph, uint32_t pid);
~Process();
DataModel* my_datamodel;
memory_info * my_descriptor;
ProcessHandle my_handle;
uint32_t my_pid;
string memFile;
bool attached;
void freeResources();
void setMemFile(const string & memf);
public:
// Set up stuff so we can read memory
bool attach();
bool detach();
// is the process still there?
memory_info *getDescriptor();
DataModel *getDataModel();
};
/*
* Process manager
*/
class ProcessManager
{
public:
ProcessManager( string path_to_xml);
~ProcessManager();
bool findProcessess();
uint32_t size();
Process * operator[](uint32_t index);
private:
// memory info entries loaded from a file
std::vector<memory_info> meminfo;
// vector to keep track of dynamically created memory_info entries
std::vector<memory_info *> destroy_meminfo;
Process * currentProcess;
ProcessHandle currentProcessHandle;
std::vector<Process *> processes;
bool loadDescriptors( string path_to_xml);
void ParseVTable(TiXmlElement* vtable, memory_info& mem);
void ParseEntry (TiXmlElement* entry, memory_info& mem, map <string ,TiXmlElement *>& knownEntries);
#ifdef LINUX_BUILD
Process* addProcess(const string & exe,ProcessHandle PH,const string & memFile);
#endif
};
}
#endif // PROCESSMANAGER_H_INCLUDED

@ -25,6 +25,8 @@ distribution.
#ifndef TYPES_H_INCLUDED
#define TYPES_H_INCLUDED
#include "Export.h"
struct t_matgloss
{
char id[128];
@ -447,16 +449,33 @@ struct t_trait
}
};
*/
/*
CREATURE
*/
struct t_lastname
{
int names[7];
};
struct t_squadname
{
int names[6];
};
struct t_skill
{
uint16_t id;
uint32_t experience;
uint16_t rating;
};
struct t_job
{
bool active;
uint8_t jobId;
};
#define NUM_CREATURE_TRAITS 30
#define NUM_CREATURE_LABORS 102
struct t_creature
{
uint16_t x;
@ -469,11 +488,19 @@ struct t_creature
char nick_name [128];
t_lastname last_name;
t_squadname squad_name;
uint8_t profession;
char custom_profession[128];
// enabled labors
uint8_t labors[NUM_CREATURE_LABORS];
// personality traits
uint16_t traits[NUM_CREATURE_TRAITS];
uint8_t numSkills;
t_skill skills[256];
/*
//string last_name;
string current_job;
*/
t_job current_job;
uint32_t happiness;
uint32_t id;
uint32_t agility;
@ -482,7 +509,6 @@ struct t_creature
uint32_t money;
int32_t squad_leader_id;
uint8_t sex;
uint8_t profession;
/*
vector <t_skill> skills;
vector <t_trait> traits;

@ -24,7 +24,8 @@ distribution.
#ifndef DFVECTOR_H_INCLUDED
#define DFVECTOR_H_INCLUDED
namespace DFHack
{
class DfVector
{
private:
@ -64,4 +65,5 @@ public:
};
};
}
#endif // DFVECTOR_H_INCLUDED

@ -0,0 +1,40 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
/// TODO: add visibility for GCC?
#ifdef LINUX_BUILD
# ifndef DFHACK_EXPORT
# define DFHACK_EXPORT
# endif
#else
# ifdef BUILD_DFHACK_LIB
# ifndef DFHACK_EXPORT
# define DFHACK_EXPORT __declspec(dllexport)
# endif
# else
# ifndef DFHACK_EXPORT
# define DFHACK_EXPORT __declspec(dllimport)
# endif
# endif
#endif

@ -38,7 +38,7 @@ void Mread (const uint32_t &offset, const uint32_t &size, uint8_t *target)
if(size == 0) return;
int result;
result = pread(g_ProcessMemFile, target,size,offset);
result = pread(DFHack::g_ProcessMemFile, target,size,offset);
if(result != size)
{
if(result == -1)
@ -102,7 +102,7 @@ void MreadDWord (const uint32_t &offset, uint32_t &val)
inline
void MwriteDWord (uint32_t offset, uint32_t data)
{
ptrace(PTRACE_POKEDATA,g_ProcessHandle, offset, data);
ptrace(PTRACE_POKEDATA,DFHack::g_ProcessHandle, offset, data);
}
// using these is expensive.
@ -116,7 +116,7 @@ void MwriteWord (uint32_t offset, uint16_t data)
orig |= 0x0000FFFF;
orig &= data;
*/
ptrace(PTRACE_POKEDATA,g_ProcessHandle, offset, orig);
ptrace(PTRACE_POKEDATA,DFHack::g_ProcessHandle, offset, orig);
}
inline
@ -129,7 +129,7 @@ void MwriteByte (uint32_t offset, uint8_t data)
orig |= 0x000000FF;
orig &= data;
*/
ptrace(PTRACE_POKEDATA,g_ProcessHandle, offset, orig);
ptrace(PTRACE_POKEDATA,DFHack::g_ProcessHandle, offset, orig);
}
// blah. I hate the kernel devs for crippling /proc/PID/mem. THIS IS RIDICULOUS

@ -42,7 +42,7 @@ inline
uint8_t MreadByte (const uint32_t &offset)
{
uint8_t result;
ReadProcessMemory(g_ProcessHandle, (int*) offset, &result, sizeof(uint8_t), NULL);
ReadProcessMemory(DFHack::g_ProcessHandle, (int*) offset, &result, sizeof(uint8_t), NULL);
return result;
}
@ -50,7 +50,7 @@ uint8_t MreadByte (const uint32_t &offset)
inline
void MreadByte (const uint32_t &offset,uint8_t &result)
{
ReadProcessMemory(g_ProcessHandle, (int*) offset, &result, sizeof(uint8_t), NULL);
ReadProcessMemory(DFHack::g_ProcessHandle, (int*) offset, &result, sizeof(uint8_t), NULL);
}
@ -58,7 +58,7 @@ inline
uint16_t MreadWord (const uint32_t &offset)
{
uint16_t result;
ReadProcessMemory(g_ProcessHandle, (int*) offset, &result, sizeof(uint16_t), NULL);
ReadProcessMemory(DFHack::g_ProcessHandle, (int*) offset, &result, sizeof(uint16_t), NULL);
return result;
}
@ -66,7 +66,7 @@ uint16_t MreadWord (const uint32_t &offset)
inline
void MreadWord (const uint32_t &offset, uint16_t &result)
{
ReadProcessMemory(g_ProcessHandle, (int*) offset, &result, sizeof(uint16_t), NULL);
ReadProcessMemory(DFHack::g_ProcessHandle, (int*) offset, &result, sizeof(uint16_t), NULL);
}
@ -74,7 +74,7 @@ inline
uint32_t MreadDWord (const uint32_t &offset)
{
uint32_t result;
ReadProcessMemory(g_ProcessHandle, (int*) offset, &result, sizeof(uint32_t), NULL);
ReadProcessMemory(DFHack::g_ProcessHandle, (int*) offset, &result, sizeof(uint32_t), NULL);
return result;
}
@ -82,7 +82,7 @@ uint32_t MreadDWord (const uint32_t &offset)
inline
void MreadDWord (const uint32_t &offset, uint32_t &result)
{
ReadProcessMemory(g_ProcessHandle, (int*) offset, &result, sizeof(uint32_t), NULL);
ReadProcessMemory(DFHack::g_ProcessHandle, (int*) offset, &result, sizeof(uint32_t), NULL);
}
@ -90,7 +90,7 @@ inline
uint64_t MreadQuad (const uint32_t &offset)
{
uint64_t result;
ReadProcessMemory(g_ProcessHandle, (int*) offset, &result, sizeof(uint64_t), NULL);
ReadProcessMemory(DFHack::g_ProcessHandle, (int*) offset, &result, sizeof(uint64_t), NULL);
return result;
}
@ -98,40 +98,40 @@ uint64_t MreadQuad (const uint32_t &offset)
inline
void MreadQuad (const uint32_t &offset, uint64_t &result)
{
ReadProcessMemory(g_ProcessHandle, (int*) offset, &result, sizeof(uint64_t), NULL);
ReadProcessMemory(DFHack::g_ProcessHandle, (int*) offset, &result, sizeof(uint64_t), NULL);
}
inline
void Mread (const uint32_t &offset, uint32_t size, uint8_t *target)
{
ReadProcessMemory(g_ProcessHandle, (int*) offset, target, size, NULL);
ReadProcessMemory(DFHack::g_ProcessHandle, (int*) offset, target, size, NULL);
}
// WRITING
inline
void MwriteDWord (const uint32_t offset, uint32_t data)
{
WriteProcessMemory(g_ProcessHandle, (int*) offset, &data, sizeof(uint32_t), NULL);
WriteProcessMemory(DFHack::g_ProcessHandle, (int*) offset, &data, sizeof(uint32_t), NULL);
}
// using these is expensive.
inline
void MwriteWord (uint32_t offset, uint16_t data)
{
WriteProcessMemory(g_ProcessHandle, (int*) offset, &data, sizeof(uint16_t), NULL);
WriteProcessMemory(DFHack::g_ProcessHandle, (int*) offset, &data, sizeof(uint16_t), NULL);
}
inline
void MwriteByte (uint32_t offset, uint8_t data)
{
WriteProcessMemory(g_ProcessHandle, (int*) offset, &data, sizeof(uint8_t), NULL);
WriteProcessMemory(DFHack::g_ProcessHandle, (int*) offset, &data, sizeof(uint8_t), NULL);
}
inline
void Mwrite (uint32_t offset, uint32_t size, uint8_t *source)
{
WriteProcessMemory(g_ProcessHandle, (int*) offset, source, size, NULL);
WriteProcessMemory(DFHack::g_ProcessHandle, (int*) offset, source, size, NULL);
}
@ -143,7 +143,7 @@ const string MreadCString (const uint32_t &offset)
string temp;
char temp_c[256];
DWORD read;
ReadProcessMemory(g_ProcessHandle, (int *) offset, temp_c, 255, &read);
ReadProcessMemory(DFHack::g_ProcessHandle, (int *) offset, temp_c, 255, &read);
temp_c[read+1] = 0;
temp = temp_c;
return temp;

@ -7,7 +7,6 @@
#include <vector>
#include <ctime>
using namespace std;
#include <DFTypes.h>
#include <DFHackAPI.h>

@ -8,6 +8,7 @@ using namespace std;
#include <DFTypes.h>
#include <DFHackAPI.h>
#include <DFMemInfo.h>
template <typename T>
void print_bits ( T val, std::ostream& out )
@ -31,7 +32,8 @@ int main (void)
cerr << "DF not found" << endl;
return 1;
}
DFHack::memory_info mem = DF.getMemoryInfo();
// get stone matgloss mapping
if(!DF.ReadCreatureMatgloss(creaturestypes))
{
@ -44,7 +46,7 @@ int main (void)
{
t_creature temp;
DF.ReadCreature(i, temp);
cout << "creature type " << creaturestypes[temp.type].id << ", position:" << temp.x << " " << temp.y << " "<< temp.z << endl;
cout << "creature type: " << creaturestypes[temp.type].id << ", position: " << temp.x << "x " << temp.y << "y "<< temp.z << "z" << endl;
bool addendl = false;
if(temp.first_name[0])
{
@ -71,36 +73,27 @@ int main (void)
cout << endl;
addendl = false;
}
/*
if(!temp.profession.empty()){
cout << ", profession: " << temp.profession;
addendl = false;
}
if(!temp.custom_profession.empty()){
cout << "profession: " << mem.getProfession(temp.profession) << "(" << (int) temp.profession << ")";
if(temp.custom_profession[0])
{
cout << ", custom profession: " << temp.custom_profession;
addendl = false;
}
if(!temp.current_job.empty()){
cout << ", current job: " << temp.current_job;
addendl = false;
}
*/
if(addendl)
if(temp.current_job.active)
{
cout << endl;
addendl = false;
cout << ", current job: " << mem.getJob(temp.current_job.jobId);
}
cout << ", happiness: " << temp.happiness << ", strength: " << temp.strength << ", agility: "
cout << endl;
cout << "happiness: " << temp.happiness << ", strength: " << temp.strength << ", agility: "
<< temp.agility << ", toughness: " << temp.toughness << ", money: " << temp.money << ", id: " << temp.id;
if(temp.squad_leader_id != -1){
cout << ", squad_leader_id: " << temp.squad_leader_id;
}
cout << ", sex";
cout << ", sex: ";
if(temp.sex == 0){
cout << ", Female";
cout << "Female";
}
else{
cout <<", Male";
cout <<"Male";
}
cout << endl;
/*
@ -158,19 +151,19 @@ int main (void)
}
if(temp.flags2.bits.resident)
{
cout << "resident ";
cout << "resident, ";
}
if(temp.flags2.bits.gutted)
{
cout << "gutted ";
cout << "gutted, ";
}
if(temp.flags2.bits.slaughter)
{
cout << "slaughter ";
cout << "marked for slaughter, ";
}
if(temp.flags2.bits.underworld)
{
cout << "from the underworld ";
cout << "from the underworld, ";
}
cout << endl << endl;
}