Lots of comments. Using templates in the search tool.

develop
Petr Mrázek 2010-05-30 05:13:59 +02:00
parent 5ee4acfd2e
commit 123fb5a9d0
11 changed files with 446 additions and 202 deletions

@ -23,10 +23,10 @@ distribution.
*/ */
#include "Internal.h" #include "Internal.h"
#include "DFMemInfoManager.h"
#include "dfhack/DFProcess.h" #include "dfhack/DFProcess.h"
#include "dfhack/DFProcessEnumerator.h" #include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFMemInfoManager.h"
#include "dfhack/DFError.h" #include "dfhack/DFError.h"
#include "dfhack/DFContext.h" #include "dfhack/DFContext.h"

@ -23,8 +23,9 @@ distribution.
*/ */
#include "Internal.h" #include "Internal.h"
#include "DFMemInfoManager.h"
#include "dfhack/DFMemInfo.h" #include "dfhack/DFMemInfo.h"
#include "dfhack/DFMemInfoManager.h"
#include "dfhack/DFError.h" #include "dfhack/DFError.h"
using namespace DFHack; using namespace DFHack;

@ -23,10 +23,12 @@ distribution.
*/ */
#include "Internal.h" #include "Internal.h"
#include "DFMemInfoManager.h"
#include "dfhack/DFProcessEnumerator.h" #include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFProcess.h" #include "dfhack/DFProcess.h"
#include "dfhack/DFMemInfo.h" #include "dfhack/DFMemInfo.h"
#include "dfhack/DFMemInfoManager.h"
using namespace DFHack; using namespace DFHack;
@ -254,7 +256,7 @@ void ProcessEnumerator::Private::EnumPIDs (vector <ProcessID> &PIDs)
} }
#endif #endif
bool ProcessEnumerator::Refresh( BadProcesses* invalidated_processes) bool ProcessEnumerator::Refresh( BadProcesses* invalidated_processes )
{ {
// PIDs to process // PIDs to process
vector <ProcessID> PIDs; vector <ProcessID> PIDs;
@ -330,11 +332,6 @@ bool ProcessEnumerator::Refresh( BadProcesses* invalidated_processes)
return false; return false;
} }
bool ProcessEnumerator::findProcessess()
{
return Refresh();
}
uint32_t ProcessEnumerator::size() uint32_t ProcessEnumerator::size()
{ {
return d->Processes.size(); return d->Processes.size();

@ -59,6 +59,7 @@ namespace DFHack
/// stop the tracked process /// stop the tracked process
bool Suspend(); bool Suspend();
/// @return true if the process is stopped
bool isSuspended(); bool isSuspended();
/// stop the tracked process, asynchronous /// stop the tracked process, asynchronous
@ -77,41 +78,44 @@ namespace DFHack
void WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source); void WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source);
// FIXME: this is crap. // FIXME: this is crap.
// get the creatures module
/// get the creatures module
Creatures * getCreatures(); Creatures * getCreatures();
// get the maps module /// get the maps module
Maps * getMaps(); Maps * getMaps();
// get the gui module /// get the gui module
Gui * getGui(); Gui * getGui();
// get the world module /// get the world module
World * getWorld(); World * getWorld();
// get the position module /// get the position module
Position * getPosition(); Position * getPosition();
// get the materials module /// get the materials module
Materials * getMaterials(); Materials * getMaterials();
// get the items module /// get the items module
Items * getItems(); Items * getItems();
// get the translation module /// get the translation module
Translation * getTranslation(); Translation * getTranslation();
// get the vegetation module /// get the vegetation module
Vegetation * getVegetation(); Vegetation * getVegetation();
// get the buildings module /// get the buildings module
Buildings * getBuildings(); Buildings * getBuildings();
// get the constructions module /// get the constructions module
Constructions * getConstructions(); Constructions * getConstructions();
// get the Window management and I/O module /// get the Window management and I/O module
WindowIO * getWindow(); WindowIO * getWindow();
// DEAD CODE, WAITING TO BE UPDATED TO DF2010
/* /*
* Effects like mist, dragonfire or dust * Effects like mist, dragonfire or dust
*/ */

@ -74,7 +74,7 @@ namespace DFHack
/** /**
* Get a context by index * Get a context by index
* @param index index of the context to be returned * @param index index of the context to be returned
* @return pointer to a Context * @return pointer to a Context. 0 if the index is out of range.
*/ */
Context * operator[](uint32_t index); Context * operator[](uint32_t index);

@ -158,30 +158,30 @@ namespace DFHack
t_class * setClass (const char * classname, uint32_t vptr = 0, uint32_t typeoffset = 0); t_class * setClass (const char * classname, uint32_t vptr = 0, uint32_t typeoffset = 0);
void setClassChild (t_class * parent, const char * classname, const char * type); void setClassChild (t_class * parent, const char * classname, const char * type);
/* /**
* Get a classID from an address. The address has to point to the start of a virtual object (one with a virtual base class) * Get a classID from an address. The address has to point to the start of a virtual object (one with a virtual base class)
* uses memory reading directly, needs suspend. input = address of the object * uses memory reading directly, needs suspend. input = address of the object
* fails if it's unable to read from memory * fails if it's unable to read from memory
*/ */
bool resolveObjectToClassID (const uint32_t address, int32_t & classID); bool resolveObjectToClassID (const uint32_t address, int32_t & classID);
/* /**
* Get a ClassID when you know the classname. can fail if the class is not in the cache * Get a ClassID when you know the classname. can fail if the class is not in the cache
*/ */
bool resolveClassnameToClassID (const std::string classname, int32_t & classID); bool resolveClassnameToClassID (const std::string classname, int32_t & classID);
/* /**
* Get a vptr from a classname. Can fail if the type is not in the cache * Get a vptr from a classname. Can fail if the type is not in the cache
* limited to normal classes, variable-dependent types will resolve to the base class * limited to normal classes, variable-dependent types will resolve to the base class
*/ */
bool resolveClassnameToVPtr ( const std::string classname, uint32_t & vptr ); bool resolveClassnameToVPtr ( const std::string classname, uint32_t & vptr );
/* /**
* Get a classname from a previous classID. Can fail if the type is not in the cache (you use bogus classID) * Get a classname from a previous classID. Can fail if the type is not in the cache (you use bogus classID)
*/ */
bool resolveClassIDToClassname (const int32_t classID, std::string & classname); bool resolveClassIDToClassname (const int32_t classID, std::string & classname);
/* /**
* Get the internal classID->classname mapping (for speed). DO NOT MANIPULATE THE VECTOR! * Get the internal classID->classname mapping (for speed). DO NOT MANIPULATE THE VECTOR!
*/ */
const vector<std::string> * getClassIDMapping(); const vector<std::string> * getClassIDMapping();

@ -72,92 +72,115 @@ namespace DFHack
if (address >= start && address <= end) return true; if (address >= start && address <= end) return true;
return false; return false;
} }
inline void print() uint8_t * buffer;
{
std::cout << std::hex << start << " - " << end << "|" << (read ? "r" : "-") << (write ? "w" : "-") << (execute ? "x" : "-") << "|" << name << std::endl;
}
}; };
class DFHACK_EXPORT Process class DFHACK_EXPORT Process
{ {
public: public:
// this is the single most important destructor ever. ~px /// this is the single most important destructor ever. ~px
virtual ~Process(){}; virtual ~Process(){};
// Set up stuff so we can read memory, suspends synchronously /// Set up stuff so we can read memory, suspends synchronously
virtual bool attach() = 0; virtual bool attach() = 0;
// detach from DF, resume its execution if it's suspended /// detach from DF, resume its execution if it's suspended
virtual bool detach() = 0; virtual bool detach() = 0;
/**
// synchronous suspend * synchronous suspend
// waits for DF to be actually suspended, * waits for DF to be actually suspended,
// this might take a while depending on implementation * this might take a while depending on implementation
*/
virtual bool suspend() = 0; virtual bool suspend() = 0;
// asynchronous suspend to use together with polling and timers /// asynchronous suspend to use together with polling and timers
virtual bool asyncSuspend() = 0; virtual bool asyncSuspend() = 0;
// resume DF execution /// resume DF execution
virtual bool resume() = 0; virtual bool resume() = 0;
// force-resume DF execution /// force-resume DF execution
virtual bool forceresume() = 0; virtual bool forceresume() = 0;
/// read a 8-byte integer
virtual uint64_t readQuad(const uint32_t address) = 0; virtual uint64_t readQuad(const uint32_t address) = 0;
/// read a 8-byte integer
virtual void readQuad(const uint32_t address, uint64_t & value) = 0; virtual void readQuad(const uint32_t address, uint64_t & value) = 0;
/// write a 8-byte integer
virtual void writeQuad(const uint32_t address, const uint64_t value) = 0; virtual void writeQuad(const uint32_t address, const uint64_t value) = 0;
/// read a 4-byte integer
virtual uint32_t readDWord(const uint32_t address) = 0; virtual uint32_t readDWord(const uint32_t address) = 0;
/// read a 4-byte integer
virtual void readDWord(const uint32_t address, uint32_t & value) = 0; virtual void readDWord(const uint32_t address, uint32_t & value) = 0;
/// write a 4-byte integer
virtual void writeDWord(const uint32_t address, const uint32_t value) = 0; virtual void writeDWord(const uint32_t address, const uint32_t value) = 0;
/// read a float
virtual float readFloat(const uint32_t address) = 0; virtual float readFloat(const uint32_t address) = 0;
/// write a float
virtual void readFloat(const uint32_t address, float & value) = 0; virtual void readFloat(const uint32_t address, float & value) = 0;
/// read a 2-byte integer
virtual uint16_t readWord(const uint32_t address) = 0; virtual uint16_t readWord(const uint32_t address) = 0;
/// read a 2-byte integer
virtual void readWord(const uint32_t address, uint16_t & value) = 0; virtual void readWord(const uint32_t address, uint16_t & value) = 0;
/// write a 2-byte integer
virtual void writeWord(const uint32_t address, const uint16_t value) = 0; virtual void writeWord(const uint32_t address, const uint16_t value) = 0;
/// read a byte
virtual uint8_t readByte(const uint32_t address) = 0; virtual uint8_t readByte(const uint32_t address) = 0;
/// read a byte
virtual void readByte(const uint32_t address, uint8_t & value) = 0; virtual void readByte(const uint32_t address, uint8_t & value) = 0;
/// write a byte
virtual void writeByte(const uint32_t address, const uint8_t value) = 0; virtual void writeByte(const uint32_t address, const uint8_t value) = 0;
/// read an arbitrary amount of bytes
virtual void read( uint32_t address, uint32_t length, uint8_t* buffer) = 0; virtual void read( uint32_t address, uint32_t length, uint8_t* buffer) = 0;
/// write an arbitrary amount of bytes
virtual void write(uint32_t address, uint32_t length, uint8_t* buffer) = 0; virtual void write(uint32_t address, uint32_t length, uint8_t* buffer) = 0;
// read a string /// read an STL string
virtual const string readSTLString (uint32_t offset) = 0; virtual const string readSTLString (uint32_t offset) = 0;
/// read an STL string
virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) = 0; virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) = 0;
/// write an STL string
virtual void writeSTLString(const uint32_t address, const std::string writeString) = 0; virtual void writeSTLString(const uint32_t address, const std::string writeString) = 0;
// get class name of an object with rtti/type info /// get class name of an object with rtti/type info
virtual string readClassName(uint32_t vptr) = 0; virtual string readClassName(uint32_t vptr) = 0;
/// read a null-terminated C string
virtual const std::string readCString (uint32_t offset) = 0; virtual const std::string readCString (uint32_t offset) = 0;
/// @return true if the process is suspended
virtual bool isSuspended() = 0; virtual bool isSuspended() = 0;
/// @return true if the process is attached
virtual bool isAttached() = 0; virtual bool isAttached() = 0;
/// @return true if the process is identified -- has a Memory.xml entry
virtual bool isIdentified() = 0; virtual bool isIdentified() = 0;
// find the thread IDs of the process /// find the thread IDs of the process
virtual bool getThreadIDs(vector<uint32_t> & threads ) = 0; virtual bool getThreadIDs(vector<uint32_t> & threads ) = 0;
// get virtual memory ranges of the process (what is mapped where) /// get virtual memory ranges of the process (what is mapped where)
virtual void getMemRanges( vector<t_memrange> & ranges ) = 0; virtual void getMemRanges( vector<t_memrange> & ranges ) = 0;
// get the flattened Memory.xml entry of this process /// get the flattened Memory.xml entry of this process
virtual memory_info *getDescriptor() = 0; virtual memory_info *getDescriptor() = 0;
// get the DF Process ID /// get the DF Process ID
virtual int getPID() = 0; virtual int getPID() = 0;
// get module index by name and version. bool 1 = error /// get module index by name and version. bool 1 = error
virtual bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) = 0; virtual bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) = 0;
// get the SHM start if available /// get the SHM start if available
virtual char * getSHMStart (void) = 0; virtual char * getSHMStart (void) = 0;
// set a SHM command and wait for a response, return 0 on error or throw exception /// set a SHM command and wait for a response, return 0 on error or throw exception
virtual bool SetAndWait (uint32_t state) = 0; virtual bool SetAndWait (uint32_t state) = 0;
}; };
////////////////////////////////////////////////////////////////////////////
// Compiler appeasement area. Not worth a look really... //
////////////////////////////////////////////////////////////////////////////
class DFHACK_EXPORT NormalProcess : virtual public Process class DFHACK_EXPORT NormalProcess : virtual public Process
{ {
friend class ProcessEnumerator; friend class ProcessEnumerator;
class Private; class Private;
private: private:
Private * const d; Private * const d;
public: public:
NormalProcess(uint32_t pid, vector <memory_info *> & known_versions); NormalProcess(uint32_t pid, vector <memory_info *> & known_versions);
~NormalProcess(); ~NormalProcess();

@ -33,35 +33,99 @@ namespace DFHack
class memory_info; class memory_info;
class Process; class Process;
class BadProcesses; class BadProcesses;
/* /**
* Process manager * Process enumerator
* Used to enumerate, create and destroy Processes.
* @see DFHack::Process
*/ */
class DFHACK_EXPORT ProcessEnumerator class DFHACK_EXPORT ProcessEnumerator
{ {
class Private; class Private;
Private * const d; Private * const d;
public: public:
/**
* Constructs the ProcessEnumerator.
* @param path_to_xml the path to the file that defines memory offsets. (Memory.xml)
*/
ProcessEnumerator( string path_to_xml ); ProcessEnumerator( string path_to_xml );
/**
* Destroys the ProcessEnumerator.
*/
~ProcessEnumerator(); ~ProcessEnumerator();
/**
* Refresh the internal list of valid Process objects.
* @param invalidated_processes pointer to a BadProcesses object. Not required. All processes are automatically destroyed if the object is not provided.
* @see DFHack::BadProcesses
* @return true if there's at least one valit Process
*/
bool Refresh(BadProcesses * invalidated_processes = 0); bool Refresh(BadProcesses * invalidated_processes = 0);
bool findProcessess();
/**
* @return Number of tracked processes
*/
uint32_t size(); uint32_t size();
/**
* Get a Process by index
* @param index index of the Process to be returned
* @return pointer to a Process. 0 if the index is out of range.
*/
Process * operator[](uint32_t index); Process * operator[](uint32_t index);
/**
* Destroy all tracked Process objects
* Normally called during object destruction. Calling this from outside ProcessManager is nasty.
*/
void purge(void); void purge(void);
}; };
/**
* Class used for holding a set of invalidated Process objects temporarily and destroy them safely.
* @see DFHack::Process
*/
class DFHACK_EXPORT BadProcesses class DFHACK_EXPORT BadProcesses
{ {
class Private; class Private;
Private * const d; Private * const d;
void push_back(Process * p); void push_back(Process * p);
friend class ProcessEnumerator; friend class ProcessEnumerator;
void clear();
public: public:
BadProcesses(); BadProcesses();
/**
* Destructor.
* All Processes tracked by the BadProcesses object will be destroyed also.
*/
~BadProcesses(); ~BadProcesses();
/**
* Test if a Process is among the invalidated Processes
* @param p pointer to a Process to be checked
* @return true if the Process is among the invalidated. false otherwise.
*/
bool Contains(Process* p); bool Contains(Process* p);
/**
* Remove a Process from the tracked invalidated Processes. Used by BadContexts.
* @param p pointer to a Process to be excised
* @see DFHack::BadContexts
* @return true if the Process was among the invalidated. false otherwise.
*/
bool excise (Process* p); bool excise (Process* p);
/**
* Get the number of tracked invalid contexts.
* @return Number of tracked invalid contexts
*/
uint32_t size(); uint32_t size();
void clear();
/**
* Get an invalid Process by index
* @param index index of the invalid Process to be returned
* @return pointer to an invalid Process
*/
Process * operator[](uint32_t index); Process * operator[](uint32_t index);
}; };
} }

@ -19,6 +19,7 @@ namespace DFHack
feature_Underworld, feature_Underworld,
feature_Hell_Temple feature_Hell_Temple
}; };
static const char * sa_feature[]= static const char * sa_feature[]=
{ {
(char*)"Other", (char*)"Other",
@ -26,6 +27,8 @@ namespace DFHack
(char*)"Underworld", (char*)"Underworld",
(char*)"Hell Temple" (char*)"Hell Temple"
}; };
/// used as a key for the local feature map. combines X an Y coords.
union planecoord union planecoord
{ {
uint32_t xy; uint32_t xy;
@ -40,40 +43,60 @@ namespace DFHack
return false; return false;
} }
}; };
struct t_feature struct t_feature
{ {
e_feature type; e_feature type;
/// main material type - decides between stuff like bodily fluids, inorganics, vomit, amber, etc.
int16_t main_material; int16_t main_material;
/// generally some index to a vector of material types.
int32_t sub_material; int32_t sub_material;
bool discovered; // placeholder. /// placeholder
bool discovered;
/// this is NOT part of the DF feature, but an address of the feature as seen by DFhack.
uint32_t origin; uint32_t origin;
}; };
/// mineral vein object
struct t_vein struct t_vein
{ {
uint32_t vtable; uint32_t vtable;
/// index into the inorganic material vector
int32_t type; int32_t type;
/// bit mask describing how the vein maps to the map block
/// assignment[y] & (1 << x) describes the tile (x, y) of the block
int16_t assignment[16]; int16_t assignment[16];
uint32_t flags; uint32_t flags;
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack. /// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
}; };
// stores what tiles should appear when the ice melts
/// stores what tiles should appear when the ice melts
struct t_frozenliquidvein struct t_frozenliquidvein
{ {
uint32_t vtable; uint32_t vtable;
/// a 16x16 array of the original tile types
int16_t tiles[16][16]; int16_t tiles[16][16];
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack. /// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
}; };
/// a 'spattervein' defines what coverings the individual map tiles have (snow, blood, etc)
/// @see PrintSplatterType in DFMiscUtils.h -- incomplete, but illustrative
struct t_spattervein struct t_spattervein
{ {
uint32_t vtable; uint32_t vtable;
/// generic material.
uint16_t mat1; uint16_t mat1;
uint16_t unk1; uint16_t unk1;
/// material vector index
uint32_t mat2; uint32_t mat2;
/// something even more specific?
uint16_t mat3; uint16_t mat3;
/// 16x16 array of covering 'intensity'
uint8_t intensity[16][16]; uint8_t intensity[16][16];
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack. /// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
}; };
enum BiomeOffset enum BiomeOffset
@ -98,16 +121,25 @@ namespace DFHack
traffic_restricted traffic_restricted
}; };
/// type of a designation for a tile
enum e_designation enum e_designation
{ {
/// no designation
designation_no, designation_no,
designation_default, // dig walls, remove stairs and ramps, gather plants, fell trees /// dig walls, remove stairs and ramps, gather plants, fell trees. depends on tile type
designation_ud_stair, // dig up/down stairs designation_default,
designation_channel, // dig a channel /// dig up/down stairs
designation_ramp, // dig ramp out of a wall designation_ud_stair,
designation_d_stair, // dig a stair down /// dig a channel
designation_u_stair, // dig a stair up designation_channel,
designation_7 // whatever /// dig ramp out of a wall
designation_ramp,
/// dig a stair down
designation_d_stair,
/// dig a stair up
designation_u_stair,
/// whatever. for completenes I guess
designation_7
}; };
enum e_liquidtype enum e_liquidtype
@ -120,41 +152,43 @@ namespace DFHack
{ {
unsigned int flow_size : 3; // how much liquid is here? unsigned int flow_size : 3; // how much liquid is here?
unsigned int pile : 1; // stockpile? unsigned int pile : 1; // stockpile?
/* /// All the different dig designations
* All the different dig designations... needs more info, probably an enum
*/
e_designation dig : 3; e_designation dig : 3;
unsigned int smooth : 2; unsigned int smooth : 2;
unsigned int hidden : 1; unsigned int hidden : 1;
/* /**
* This one is rather involved, but necessary to retrieve the base layer matgloss index * This one is rather involved, but necessary to retrieve the base layer matgloss index
* see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284 for details * @see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284
*/ */
unsigned int geolayer_index :4; unsigned int geolayer_index :4;
unsigned int light : 1; unsigned int light : 1;
unsigned int subterranean : 1; // never seen the light of day? unsigned int subterranean : 1; // never seen the light of day?
unsigned int skyview : 1; // sky is visible now, it rains in here when it rains unsigned int skyview : 1; // sky is visible now, it rains in here when it rains
/* /**
* Probably similar to the geolayer_index. Only with a different set of offsets and different data. * Probably similar to the geolayer_index. Only with a different set of offsets and different data.
* we don't use this yet * we don't use this yet
*/ */
unsigned int biome : 4; unsigned int biome : 4;
/* /**
* 0 = water * 0 = water
* 1 = magma * 1 = magma
*/ */
e_liquidtype liquid_type : 1; e_liquidtype liquid_type : 1;
unsigned int water_table : 1; // srsly. wtf? unsigned int water_table : 1; // srsly. wtf?
unsigned int rained : 1; // does this mean actual rain (as in the blue blocks) or a wet tile? unsigned int rained : 1; // does this mean actual rain (as in the blue blocks) or a wet tile?
e_traffic traffic : 2; // needs enum e_traffic traffic : 2;
unsigned int flow_forbid : 1; // what? /// the tile is not evaluated when calculating flows?
unsigned int flow_forbid : 1;
/// no liquid spreading
unsigned int liquid_static : 1; unsigned int liquid_static : 1;
unsigned int feature_local : 1; // this tile is a part of a feature /// this tile is a part of a local feature. can be combined with 'featstone' tiles
unsigned int feature_global : 1; // this tile is a part of a feature unsigned int feature_local : 1;
unsigned int liquid_character : 2; // those ripples on streams? /// this tile is a part of a global feature. can be combined with 'featstone' tiles
unsigned int feature_global : 1;
/// those ripples on streams?
unsigned int liquid_character : 2;
}; };
union t_designation union t_designation
@ -166,12 +200,16 @@ namespace DFHack
// occupancy flags (rat,dwarf,horse,built wall,not build wall,etc) // occupancy flags (rat,dwarf,horse,built wall,not build wall,etc)
struct naked_occupancy struct naked_occupancy
{ {
unsigned int building : 3;// building type... should be an enum? // building type... should be an enum?
// 7 = door // 7 = door
unsigned int building : 3;
/// the tile contains a standing? creature
unsigned int unit : 1; unsigned int unit : 1;
/// the tile contains a prone creature
unsigned int unit_grounded : 1; unsigned int unit_grounded : 1;
/// the tile contains an item
unsigned int item : 1; unsigned int item : 1;
// splatter. everyone loves splatter. /// splatter. everyone loves splatter. this doesn't seem to be used anymore
unsigned int mud : 1; unsigned int mud : 1;
unsigned int vomit :1; unsigned int vomit :1;
unsigned int broken_arrows_color :4; unsigned int broken_arrows_color :4;
@ -199,12 +237,14 @@ namespace DFHack
struct naked_occupancy_grouped struct naked_occupancy_grouped
{ {
unsigned int building : 3;// building type... should be an enum? unsigned int building : 3;
// 7 = door /// the tile contains a standing? creature
unsigned int unit : 1; unsigned int unit : 1;
/// the tile contains a prone creature
unsigned int unit_grounded : 1; unsigned int unit_grounded : 1;
/// the tile contains an item
unsigned int item : 1; unsigned int item : 1;
// splatter. everyone loves splatter. /// splatter. everyone loves splatter. this doesn't seem to be used anymore
unsigned int splatter : 26; unsigned int splatter : 26;
}; };
@ -218,12 +258,15 @@ namespace DFHack
// map block flags // map block flags
struct naked_blockflags struct naked_blockflags
{ {
unsigned int designated : 1;// designated for jobs (digging and stuff like that) /// designated for jobs (digging and stuff like that)
unsigned int unk_1 : 1; // possibly related to the designated flag unsigned int designated : 1;
// two flags required for liquid flow. no idea why /// possibly related to the designated flag
unsigned int unk_1 : 1;
/// two flags required for liquid flow.
unsigned int liquid_1 : 1; unsigned int liquid_1 : 1;
unsigned int liquid_2 : 1; unsigned int liquid_2 : 1;
unsigned int unk_2: 28; // rest of the flags is completely unknown /// rest of the flags is completely unknown
unsigned int unk_2: 28;
// there's a possibility that this flags field is shorter than 32 bits // there's a possibility that this flags field is shorter than 32 bits
}; };
@ -241,13 +284,20 @@ namespace DFHack
typedef struct typedef struct
{ {
/// type of the tiles
tiletypes40d tiletypes; tiletypes40d tiletypes;
/// flags determining the state of the tiles
designations40d designation; designations40d designation;
/// flags determining what's on the tiles
occupancies40d occupancy; occupancies40d occupancy;
/// values used for geology/biome assignment
biome_indices40d biome_indices; biome_indices40d biome_indices;
uint32_t origin; // the address where it came from /// the address where the block came from
uint32_t origin;
t_blockflags blockflags; t_blockflags blockflags;
/// index into the global feature vector
int16_t global_feature; int16_t global_feature;
/// index into the local feature vector... complicated
int16_t local_feature; int16_t local_feature;
} mapblock40d; } mapblock40d;
@ -321,6 +371,7 @@ namespace DFHack
* Return false/0 on failure, buffer allocated by client app, 256 items long * 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 isValidBlock(uint32_t blockx, uint32_t blocky, uint32_t blockz);
/** /**
* Get the address of a block or 0 if block is not valid * Get the address of a block or 0 if block is not valid
*/ */
@ -350,10 +401,8 @@ namespace DFHack
bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit); bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit);
/// read/write the block flags /// read/write the block flags
bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags &blockflags);
t_blockflags &blockflags); bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags blockflags);
bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz,
t_blockflags blockflags);
/// read/write features /// read/write features
bool ReadFeatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t & local, int16_t & global); bool ReadFeatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t & local, int16_t & global);
bool WriteLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1); bool WriteLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1);

@ -25,10 +25,12 @@ distribution.
#ifndef MEMINFO_MANAGER_H_INCLUDED #ifndef MEMINFO_MANAGER_H_INCLUDED
#define MEMINFO_MANAGER_H_INCLUDED #define MEMINFO_MANAGER_H_INCLUDED
#include "DFPragma.h" #include "dfhack/DFPragma.h"
class TiXmlElement;
namespace DFHack namespace DFHack
{ {
class memory_info;
class MemInfoManager class MemInfoManager
{ {
friend class ProcessEnumerator; friend class ProcessEnumerator;

@ -19,16 +19,125 @@ using namespace std;
#endif #endif
#include <DFHack.h> #include <DFHack.h>
class SegmentedFinder;
class SegmentFinder
{
public:
SegmentFinder(DFHack::t_memrange & mr, DFHack::Context * DF)
{
_DF = DF;
mr_ = mr;
mr_.buffer = (uint8_t *)malloc (mr_.end - mr_.start);
DF->ReadRaw(mr_.start,(mr_.end - mr_.start),mr_.buffer);
}
~SegmentFinder()
{
delete mr_.buffer;
}
template <class T, typename P >
bool Find (T needle, const uint8_t increment ,vector <uint64_t> &found, vector <uint64_t> &newfound, P oper)
{
if(found.empty())
{
//loop
for(uint64_t offset = 0; offset < (mr_.end - mr_.start) - sizeof(T); offset += increment)
{
if( (*(T *)(mr_.buffer + offset)) == needle)
newfound.push_back(mr_.start + offset);
}
}
else
{
for( uint64_t i = 0; i < found.size(); i++)
{
if(mr_.isInRange(found[i]))
{
uint64_t corrected = found[i] - mr_.start;
if( oper((T *)(mr_.buffer + corrected), needle) )
newfound.push_back(found[i]);
}
}
}
return true;
}
private:
friend class SegmentedFinder;
DFHack::Context * _DF;
DFHack::t_memrange mr_;
};
class SegmentedFinder
{
public:
SegmentedFinder(vector <DFHack::t_memrange>& ranges, DFHack::Context * DF)
{
_DF = DF;
for(int i = 0; i < ranges.size(); i++)
{
segments.push_back(new SegmentFinder(ranges[i], DF));
}
}
~SegmentedFinder()
{
for(int i = 0; i < segments.size(); i++)
{
delete segments[i];
}
}
SegmentFinder * getSegmentForAddress (uint64_t addr)
{
for(int i = 0; i < segments.size(); i++)
{
if(segments[i]->mr_.isInRange(addr))
{
return segments[i];
}
}
}
template<class T, typename P>
bool Find (const T dword, const uint8_t increment, vector <uint64_t> &found, vector <uint64_t> &newfound, P oper)
{
newfound.clear();
for(int i = 0; i < segments.size(); i++)
{
segments[i]->Find<T,P>(dword, increment, found, newfound, oper);
}
found.clear();
found = newfound;
return !(found.empty());
}
private:
DFHack::Context * _DF;
vector <SegmentFinder *> segments;
};
template <typename T>
bool equalityP (T *x, T y)
{
return (*x) == y;
}
typedef struct
{
uint32_t start;
uint32_t finish;
uint32_t alloc_finish;
} vecTriplet;
template <typename T>
bool vectorLength (T *x, T y)
{
return (*x) == y;
}
//TODO: lots of optimization //TODO: lots of optimization
void searchLoop(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges, int size, int alignment) void searchLoop(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges, int size, int alignment)
{ {
int32_t test1; uint32_t test1;
int32_t test2; vector <uint64_t> found;
vector <int64_t> found; vector <uint64_t> newfound;
vector <int64_t> newfound; found.reserve(100);
found.reserve(100000); newfound.reserve(100);
newfound.reserve(100000);
//bool initial = 1; //bool initial = 1;
cout << "search ready - insert integers, 'p' for results" << endl; cout << "search ready - insert integers, 'p' for results" << endl;
string select; string select;
@ -50,53 +159,45 @@ void searchLoop(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ran
DFMgr.Refresh(); DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext(); DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach(); DF->Attach();
SegmentedFinder sf(ranges,DF);
newfound.clear(); switch(size)
bool initial = found.empty();
if(initial)
{
// for each range
for (int i = 0; i < ranges.size();i++)
{
// can't read? range is invalid to us
if(!ranges[i].read)
continue;
//loop
for(uint64_t offset = ranges[i].start;offset <= ranges[i].end - size; offset+=alignment)
{ {
DF->ReadRaw(offset, size, (uint8_t *) &test2); case 1:
if(test1 == test2 ) sf.Find<uint8_t>(test1,alignment,found,newfound, equalityP<uint8_t>);
found.push_back(offset); break;
} case 2:
} sf.Find<uint16_t>(test1,alignment,found,newfound, equalityP<uint16_t>);
cout << "found " << found.size() << " addresses" << endl; break;
case 4:
sf.Find<uint32_t>(test1,alignment,found,newfound, equalityP<uint32_t>);
break;
} }
else if( found.size() == 1)
{ {
for(int j = 0; j < found.size();j++) cout << "Found an address!" << endl;
{ cout << hex << "0x" << found[0] << endl;
DF->ReadRaw(found[j], size, (uint8_t *) &test2);
if(test1 == test2)
{
newfound.push_back(found[j]);
}
}
cout << "matched " << newfound.size() << " addresses out of " << found.size() << endl;
found = newfound;
} }
else
cout << "Found " << dec << found.size() << " addresses." << endl;
DF->Detach(); DF->Detach();
} }
else break; else break;
} }
} }
typedef struct /*
class VecVerifyPredicate
{ {
uint32_t start; public:
uint32_t finish; VecVerifyPredicate(){}
uint32_t alloc_finish; bool operator()(vecTriplet * vt, uint64_t length)
} vecTriplet; {
if(vt.start <= vt.finish && vt.finish <= vt.alloc_finish)
return true;
return false;
}
};
*/
void searchLoopVector(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges, uint32_t element_size) void searchLoopVector(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges, uint32_t element_size)
{ {
vecTriplet load; vecTriplet load;
@ -190,7 +291,10 @@ void mkcopy(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges,
DF->Detach(); DF->Detach();
DFMgr.purge(); DFMgr.purge();
} }
inline void printRange(DFHack::t_memrange * tpr)
{
std::cout << std::hex << tpr->start << " - " << tpr->end << "|" << (tpr->read ? "r" : "-") << (tpr->write ? "w" : "-") << (tpr->execute ? "x" : "-") << "|" << tpr->name << std::endl;
}
int main (void) int main (void)
{ {
string select; string select;
@ -216,7 +320,7 @@ int main (void)
for(int i = 0; i< ranges.size();i++) for(int i = 0; i< ranges.size();i++)
{ {
cout << dec << "(" << i << ") "; cout << dec << "(" << i << ") ";
ranges[i].print(); printRange(&(ranges[i]));
} }
try_again_ranges: try_again_ranges:
@ -258,7 +362,7 @@ int main (void)
selected_ranges.insert(selected_ranges.begin(),ranges.begin() + start, ranges.begin() + end); selected_ranges.insert(selected_ranges.begin(),ranges.begin() + start, ranges.begin() + end);
for(int i = 0; i< selected_ranges.size();i++) for(int i = 0; i< selected_ranges.size();i++)
{ {
selected_ranges[i].print(); printRange(&(selected_ranges[i]));
} }
try_again_type: try_again_type:
cout << "Select search type: 1=number(default), 2=vector, 3=string" << endl; cout << "Select search type: 1=number(default), 2=vector, 3=string" << endl;