diff --git a/library/DFDataModel.cpp b/library/DFDataModel.cpp index 7e24c7951..9e684315e 100644 --- a/library/DFDataModel.cpp +++ b/library/DFDataModel.cpp @@ -23,7 +23,7 @@ distribution. */ #include "DFCommonInternal.h" - +using namespace DFHack; DfVector DMWindows40d::readVector (uint32_t offset, uint32_t item_size) { diff --git a/library/DFDataModel.h b/library/DFDataModel.h index 519cb98e2..c6b9e6a85 100644 --- a/library/DFDataModel.h +++ b/library/DFDataModel.h @@ -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 diff --git a/library/DFHackAPI.cpp b/library/DFHackAPI.cpp index 73a4bb201..155f35801 100644 --- a/library/DFHackAPI.cpp +++ b/library/DFHackAPI.cpp @@ -953,7 +953,7 @@ void API::Private::getLaborsByAddress(const uint32_t &address, vector & 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; icreature_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; } \ No newline at end of file diff --git a/library/DFHackAPI.h b/library/DFHackAPI.h index 59afc4344..e0b964b4a 100644 --- a/library/DFHackAPI.h +++ b/library/DFHackAPI.h @@ -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 #include #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 & output); - bool ReadWoodMatgloss (vector & output); - bool ReadMetalMatgloss(vector & output); - bool ReadPlantMatgloss(vector & output); - bool ReadCreatureMatgloss(vector & 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 & output); + bool ReadWoodMatgloss (vector & output); + bool ReadMetalMatgloss(vector & output); + bool ReadPlantMatgloss(vector & output); + bool ReadCreatureMatgloss(vector & 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 >& 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 & 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 &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 getSkills(const uint32_t &index); - vector getTraits(const uint32_t &index); - vector getLabors(const uint32_t &index); - */ - void InitReadNameTables(); - void FinishReadNameTables(); -}; - + */ + bool ReadGeology( vector < vector >& 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 & 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 &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 getSkills(const uint32_t &index); + vector getTraits(const uint32_t &index); + vector getLabors(const uint32_t &index); + */ + void InitReadNameTables(); + void FinishReadNameTables(); + + memory_info getMemoryInfo(); + }; } // namespace DFHack #endif // SIMPLEAPI_H_INCLUDED diff --git a/library/DFMemAccess.h b/library/DFMemAccess.h index f9c210454..1d98c8f80 100644 --- a/library/DFMemAccess.h +++ b/library/DFMemAccess.h @@ -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 diff --git a/library/DFMemInfo.cpp b/library/DFMemInfo.cpp index 4b63c4c48..74d75baed 100644 --- a/library/DFMemInfo.cpp +++ b/library/DFMemInfo.cpp @@ -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(""); } diff --git a/library/DFMemInfo.h b/library/DFMemInfo.h index 853be5a7f..b9fb4a4c4 100644 --- a/library/DFMemInfo.h +++ b/library/DFMemInfo.h @@ -25,108 +25,116 @@ distribution. #ifndef MEMINFO_H_INCLUDED #define MEMINFO_H_INCLUDED -class memory_info +#include "Export.h" +#include +#include +#include + +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 & v_buildingtypes); + + void flush(); + + private: + map addresses; + map offsets; + map hexvals; + map strings; + + vector professions; + vector jobs; + vector skills; + vector< vector > traits; + map labors; + + vector classes; + vector > 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 & v_buildingtypes); - - void flush(); - -private: - map addresses; - map offsets; - map hexvals; - map strings; - - vector professions; - vector jobs; - vector skills; - vector< vector > traits; - map labors; - - vector classes; - vector > classsubtypes; - int32_t base; - uint32_t classindex; - string version; - OSType OS; -}; +} #endif // MEMINFO_H_INCLUDED diff --git a/library/DFProcess.cpp b/library/DFProcess.cpp index 82ac00365..1c9e66106 100644 --- a/library/DFProcess.cpp +++ b/library/DFProcess.cpp @@ -23,7 +23,7 @@ distribution. */ #include "DFCommonInternal.h" - +using namespace DFHack; Process::Process(DataModel * dm, memory_info* mi, ProcessHandle ph, uint32_t pid) { diff --git a/library/DFProcessManager.cpp b/library/DFProcessManager.cpp index 1a459c4bb..d4a4c9155 100644 --- a/library/DFProcessManager.cpp +++ b/library/DFProcessManager.cpp @@ -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 diff --git a/library/DFProcessManager.h b/library/DFProcessManager.h index d82d5c044..d5ef36326 100644 --- a/library/DFProcessManager.h +++ b/library/DFProcessManager.h @@ -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 meminfo; - // vector to keep track of dynamically created memory_info entries - std::vector destroy_meminfo; - Process * currentProcess; - ProcessHandle currentProcessHandle; - std::vector processes; - bool loadDescriptors( string path_to_xml); - void ParseVTable(TiXmlElement* vtable, memory_info& mem); - void ParseEntry (TiXmlElement* entry, memory_info& mem, map & 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 meminfo; + // vector to keep track of dynamically created memory_info entries + std::vector destroy_meminfo; + Process * currentProcess; + ProcessHandle currentProcessHandle; + std::vector processes; + bool loadDescriptors( string path_to_xml); + void ParseVTable(TiXmlElement* vtable, memory_info& mem); + void ParseEntry (TiXmlElement* entry, memory_info& mem, map & knownEntries); + #ifdef LINUX_BUILD + Process* addProcess(const string & exe,ProcessHandle PH,const string & memFile); + #endif + }; +} #endif // PROCESSMANAGER_H_INCLUDED diff --git a/library/DFTypes.h b/library/DFTypes.h index 92c8ae89a..b11024a85 100644 --- a/library/DFTypes.h +++ b/library/DFTypes.h @@ -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 skills; vector traits; diff --git a/library/DFVector.h b/library/DFVector.h index 6d2d4628c..a30b7fb68 100644 --- a/library/DFVector.h +++ b/library/DFVector.h @@ -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 diff --git a/library/Export.h b/library/Export.h new file mode 100644 index 000000000..98cac2e66 --- /dev/null +++ b/library/Export.h @@ -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 diff --git a/library/LinuxMemAccess-memfiles.h b/library/LinuxMemAccess-memfiles.h index 99ee2cf06..b520c0ba4 100644 --- a/library/LinuxMemAccess-memfiles.h +++ b/library/LinuxMemAccess-memfiles.h @@ -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 diff --git a/library/WindowsMemAccess.h b/library/WindowsMemAccess.h index eb702fa19..77b01d28b 100644 --- a/library/WindowsMemAccess.h +++ b/library/WindowsMemAccess.h @@ -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; diff --git a/tools/attachtest.cpp b/tools/attachtest.cpp index 81fc42086..2797c28e2 100644 --- a/tools/attachtest.cpp +++ b/tools/attachtest.cpp @@ -7,7 +7,6 @@ #include #include using namespace std; - #include #include diff --git a/tools/creaturedump.cpp b/tools/creaturedump.cpp index 515fd9ea9..50cd24ee8 100644 --- a/tools/creaturedump.cpp +++ b/tools/creaturedump.cpp @@ -8,6 +8,7 @@ using namespace std; #include #include +#include template 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; }