2009-09-13 18:02:46 -06:00
/*
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 .
*/
2009-11-10 20:37:28 -07:00
# include "DFCommonInternal.h"
2010-02-22 15:34:20 -07:00
/*
# if !defined(NDEBUG)
# define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
# define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
# endif
2010-02-23 11:26:15 -07:00
// really, we don't need it
# define BOOST_MULTI_INDEX_DISABLE_SERIALIZATION
2010-02-22 15:34:20 -07:00
# include <boost/multi_index_container.hpp>
# include <boost/multi_index/member.hpp>
# include <boost/multi_index/ordered_index.hpp>
# include <algorithm>
# include <iostream>
# include <iterator>
# include <string>
using boost : : multi_index_container ;
using namespace boost : : multi_index ;
*/
2009-11-13 20:46:56 -07:00
using namespace DFHack ;
2010-02-22 15:34:20 -07:00
/*
* Common data types
*/
struct t_class
{
string classname ;
uint32_t vtable ;
bool is_multiclass ;
uint32_t multi_index ;
uint32_t assign ; // index to typeclass array if multiclass. return value if not.
uint32_t type_offset ; // offset of type data for multiclass
} ;
struct t_type
{
string classname ;
uint32_t assign ;
uint32_t type ;
} ;
/*
* Private data
*/
class memory_info : : Private
{
public :
map < string , uint32_t > addresses ;
map < string , uint32_t > offsets ;
map < string , uint32_t > hexvals ;
map < string , string > strings ;
vector < string > professions ;
vector < string > jobs ;
vector < string > skills ;
vector < vector < string > > traits ;
map < uint32_t , string > labors ;
vector < t_class > classes ;
vector < vector < t_type > > classsubtypes ;
int32_t base ;
uint32_t classindex ;
string version ;
OSType OS ;
} ;
2009-09-13 18:02:46 -06:00
memory_info : : memory_info ( )
2010-02-22 15:34:20 -07:00
: d ( new Private )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
d - > base = 0 ;
d - > classindex = 0 ;
2009-09-13 18:02:46 -06:00
}
void memory_info : : setVersion ( const char * v )
{
2010-02-22 15:34:20 -07:00
d - > version = v ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setVersion ( const string & v )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
d - > version = v ;
2009-09-13 18:02:46 -06:00
}
string memory_info : : getVersion ( )
{
2010-02-22 15:34:20 -07:00
return d - > version ;
2009-09-13 18:02:46 -06:00
}
void memory_info : : setOS ( const char * os )
{
string oss = os ;
if ( oss = = " windows " )
2010-02-22 15:34:20 -07:00
d - > OS = OS_WINDOWS ;
2009-09-13 18:02:46 -06:00
else if ( oss = = " linux " )
2010-02-22 15:34:20 -07:00
d - > OS = OS_LINUX ;
2009-09-13 18:02:46 -06:00
else
2010-02-22 15:34:20 -07:00
d - > OS = OS_BAD ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setOS ( const string & os )
2009-09-13 18:02:46 -06:00
{
if ( os = = " windows " )
2010-02-22 15:34:20 -07:00
d - > OS = OS_WINDOWS ;
2009-09-13 18:02:46 -06:00
else if ( os = = " linux " )
2010-02-22 15:34:20 -07:00
d - > OS = OS_LINUX ;
2009-09-13 18:02:46 -06:00
else
2010-02-22 15:34:20 -07:00
d - > OS = OS_BAD ;
2009-09-13 18:02:46 -06:00
}
void memory_info : : setOS ( OSType os )
{
if ( os > = OS_WINDOWS & & os < OS_BAD )
{
2010-02-22 15:34:20 -07:00
d - > OS = os ;
2009-09-13 18:02:46 -06:00
return ;
}
2010-02-22 15:34:20 -07:00
d - > OS = OS_BAD ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
memory_info : : OSType memory_info : : getOS ( ) const
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
return d - > OS ;
2009-09-13 18:02:46 -06:00
}
// copy constructor
memory_info : : memory_info ( const memory_info & old )
2010-02-22 15:34:20 -07:00
: d ( new Private )
{
d - > version = old . d - > version ;
d - > OS = old . d - > OS ;
d - > addresses = old . d - > addresses ;
d - > offsets = old . d - > offsets ;
d - > hexvals = old . d - > hexvals ;
d - > strings = old . d - > strings ;
d - > base = old . d - > base ;
d - > classes = old . d - > classes ;
d - > classsubtypes = old . d - > classsubtypes ;
d - > classindex = old . d - > classindex ;
d - > professions = old . d - > professions ;
d - > jobs = old . d - > jobs ;
d - > skills = old . d - > skills ;
d - > traits = old . d - > traits ;
d - > labors = old . d - > labors ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
uint32_t memory_info : : getBase ( ) const
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
return d - > base ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setBase ( const string & s )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
d - > base = strtol ( s . c_str ( ) , NULL , 16 ) ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setBase ( const uint32_t b )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
d - > base = b ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setOffset ( const string & key , const string & value )
2009-09-13 18:02:46 -06:00
{
uint32_t offset = strtol ( value . c_str ( ) , NULL , 16 ) ;
2010-02-22 15:34:20 -07:00
d - > offsets [ key ] = offset ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setAddress ( const string & key , const string & value )
2009-09-13 18:02:46 -06:00
{
uint32_t address = strtol ( value . c_str ( ) , NULL , 16 ) ;
2010-02-22 15:34:20 -07:00
d - > addresses [ key ] = address ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setHexValue ( const string & key , const string & value )
2009-09-13 18:02:46 -06:00
{
uint32_t hexval = strtol ( value . c_str ( ) , NULL , 16 ) ;
2010-02-22 15:34:20 -07:00
d - > hexvals [ key ] = hexval ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setString ( const string & key , const string & value )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
d - > strings [ key ] = value ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setLabor ( const string & key , const string & value )
2009-11-09 16:18:20 -07:00
{
uint32_t keyInt = strtol ( key . c_str ( ) , NULL , 10 ) ;
2010-02-22 15:34:20 -07:00
d - > labors [ keyInt ] = value ;
2009-11-09 16:18:20 -07:00
}
2009-11-13 20:46:56 -07:00
2009-11-22 07:43:53 -07:00
void memory_info : : setProfession ( const string & key , const string & value )
2009-11-07 14:05:10 -07:00
{
2009-11-09 16:18:20 -07:00
uint32_t keyInt = strtol ( key . c_str ( ) , NULL , 10 ) ;
2010-02-22 15:34:20 -07:00
if ( d - > professions . size ( ) < = keyInt )
2009-11-13 20:46:56 -07:00
{
2010-02-22 15:34:20 -07:00
d - > professions . resize ( keyInt + 1 ) ;
2009-11-09 16:18:20 -07:00
}
2010-02-22 15:34:20 -07:00
d - > professions [ keyInt ] = value ;
2009-11-07 14:05:10 -07:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setJob ( const string & key , const string & value )
2009-11-07 14:05:10 -07:00
{
2009-11-09 16:18:20 -07:00
uint32_t keyInt = strtol ( key . c_str ( ) , NULL , 10 ) ;
2010-02-22 15:34:20 -07:00
if ( d - > jobs . size ( ) < = keyInt )
2009-11-13 20:46:56 -07:00
{
2010-02-22 15:34:20 -07:00
d - > jobs . resize ( keyInt + 1 ) ;
2009-11-09 16:18:20 -07:00
}
2010-02-22 15:34:20 -07:00
d - > jobs [ keyInt ] = value ;
2009-11-07 14:05:10 -07:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setSkill ( const string & key , const string & value )
2009-11-09 16:18:20 -07:00
{
uint32_t keyInt = strtol ( key . c_str ( ) , NULL , 10 ) ;
2010-02-22 15:34:20 -07:00
if ( d - > skills . size ( ) < = keyInt ) {
d - > skills . resize ( keyInt + 1 ) ;
2009-11-09 16:18:20 -07:00
}
2010-02-22 15:34:20 -07:00
d - > skills [ keyInt ] = value ;
2009-11-09 16:18:20 -07:00
}
2009-11-22 07:43:53 -07:00
void memory_info : : setTrait ( const string & key ,
const string & value ,
const string & zero ,
const string & one ,
const string & two ,
const string & three ,
const string & four ,
const string & five )
2009-11-09 16:18:20 -07:00
{
2009-11-13 20:46:56 -07:00
uint32_t keyInt = strtol ( key . c_str ( ) , NULL , 10 ) ;
2010-02-22 15:34:20 -07:00
if ( d - > traits . size ( ) < = keyInt )
2009-11-13 20:46:56 -07:00
{
2010-02-22 15:34:20 -07:00
d - > traits . resize ( keyInt + 1 ) ;
2009-11-13 20:46:56 -07:00
}
2010-02-22 15:34:20 -07:00
d - > traits [ keyInt ] . push_back ( zero ) ;
d - > traits [ keyInt ] . push_back ( one ) ;
d - > traits [ keyInt ] . push_back ( two ) ;
d - > traits [ keyInt ] . push_back ( three ) ;
d - > traits [ keyInt ] . push_back ( four ) ;
d - > traits [ keyInt ] . push_back ( five ) ;
d - > traits [ keyInt ] . push_back ( value ) ;
2009-11-09 16:18:20 -07:00
}
2009-09-13 18:02:46 -06:00
// FIXME: next three methods should use some kind of custom container so it doesn't have to search so much.
void memory_info : : setClass ( const char * name , const char * vtable )
{
2010-02-22 15:34:20 -07:00
for ( uint32_t i = 0 ; i < d - > classes . size ( ) ; i + + )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
if ( d - > classes [ i ] . classname = = name )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
d - > classes [ i ] . vtable = strtol ( vtable , NULL , 16 ) ;
2009-09-13 18:02:46 -06:00
return ;
}
}
t_class cls ;
2010-02-22 15:34:20 -07:00
cls . assign = d - > classindex ;
2009-09-13 18:02:46 -06:00
cls . classname = name ;
cls . is_multiclass = false ;
cls . type_offset = 0 ;
2010-02-22 15:34:20 -07:00
d - > classindex + + ;
2009-09-13 18:02:46 -06:00
cls . vtable = strtol ( vtable , NULL , 16 ) ;
2010-02-22 15:34:20 -07:00
d - > classes . push_back ( cls ) ;
2009-09-13 18:02:46 -06:00
//cout << "class " << name << ", assign " << cls.assign << ", vtable " << cls.vtable << endl;
}
// find old entry by name, rewrite, return its multi index. otherwise make a new one, append an empty vector of t_type to classtypes, return its index.
uint32_t memory_info : : setMultiClass ( const char * name , const char * vtable , const char * typeoffset )
{
2010-02-22 15:34:20 -07:00
for ( uint32_t i = 0 ; i < d - > classes . size ( ) ; i + + )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
if ( d - > classes [ i ] . classname = = name )
2009-09-13 18:02:46 -06:00
{
// vtable and typeoffset can be left out from the xml definition when there's already a named multiclass
if ( vtable ! = NULL )
2010-02-22 15:34:20 -07:00
d - > classes [ i ] . vtable = strtol ( vtable , NULL , 16 ) ;
2009-09-13 18:02:46 -06:00
if ( typeoffset ! = NULL )
2010-02-22 15:34:20 -07:00
d - > classes [ i ] . type_offset = strtol ( typeoffset , NULL , 16 ) ;
return d - > classes [ i ] . multi_index ;
2009-09-13 18:02:46 -06:00
}
}
//FIXME: add checking for vtable and typeoffset here. they HAVE to be valid. maybe change the return value into a bool and pass in multi index by reference?
t_class cls ;
2010-02-22 15:34:20 -07:00
cls . assign = d - > classindex ;
2009-09-13 18:02:46 -06:00
cls . classname = name ;
cls . is_multiclass = true ;
cls . type_offset = strtol ( typeoffset , NULL , 16 ) ;
cls . vtable = strtol ( vtable , NULL , 16 ) ;
2010-02-22 15:34:20 -07:00
cls . multi_index = d - > classsubtypes . size ( ) ;
d - > classes . push_back ( cls ) ;
d - > classindex + + ;
2009-09-13 18:02:46 -06:00
vector < t_type > thistypes ;
2010-02-22 15:34:20 -07:00
d - > classsubtypes . push_back ( thistypes ) ;
2009-09-13 18:02:46 -06:00
//cout << "multiclass " << name << ", assign " << cls.assign << ", vtable " << cls.vtable << endl;
2010-02-22 15:34:20 -07:00
return d - > classsubtypes . size ( ) - 1 ;
2009-09-13 18:02:46 -06:00
}
void memory_info : : setMultiClassChild ( uint32_t multi_index , const char * name , const char * type )
{
2010-02-22 15:34:20 -07:00
vector < t_type > & vec = d - > classsubtypes [ multi_index ] ;
2009-09-13 18:02:46 -06:00
for ( uint32_t i = 0 ; i < vec . size ( ) ; i + + )
{
if ( vec [ i ] . classname = = name )
{
vec [ i ] . type = strtol ( type , NULL , 16 ) ;
return ;
}
}
// new multiclass child
t_type mcc ;
2010-02-22 15:34:20 -07:00
mcc . assign = d - > classindex ;
2009-09-13 18:02:46 -06:00
mcc . classname = name ;
mcc . type = strtol ( type , NULL , 16 ) ;
vec . push_back ( mcc ) ;
2010-02-22 15:34:20 -07:00
d - > classindex + + ;
2009-09-13 18:02:46 -06:00
//cout << " classtype " << name << ", assign " << mcc.assign << ", vtable " << mcc.type << endl;
}
bool memory_info : : resolveClassId ( uint32_t address , int32_t & classid )
{
2009-12-22 14:19:39 -07:00
uint32_t vtable = g_pProcess - > readDWord ( address ) ;
2009-09-13 18:02:46 -06:00
// FIXME: stupid search. we need a better container
2010-02-22 15:34:20 -07:00
for ( uint32_t i = 0 ; i < d - > classes . size ( ) ; i + + )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
if ( d - > classes [ i ] . vtable = = vtable ) // got class
2009-09-13 18:02:46 -06:00
{
// if it is a multiclass, try resolving it
2010-02-22 15:34:20 -07:00
if ( d - > classes [ i ] . is_multiclass )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
vector < t_type > & vec = d - > classsubtypes [ d - > classes [ i ] . multi_index ] ;
uint32_t type = g_pProcess - > readWord ( address + d - > classes [ i ] . type_offset ) ;
2009-09-13 18:02:46 -06:00
//printf ("class %d:%s offset 0x%x\n", i , classes[i].classname.c_str(), classes[i].type_offset);
// return typed building if successful
for ( uint32_t k = 0 ; k < vec . size ( ) ; k + + )
{
if ( vec [ k ] . type = = type )
{
//cout << " multi " << address + classes[i].type_offset << " " << vec[k].classname << endl;
classid = vec [ k ] . assign ;
return true ;
}
}
}
// otherwise return the class we found
2010-02-22 15:34:20 -07:00
classid = d - > classes [ i ] . assign ;
2009-09-13 18:02:46 -06:00
return true ;
}
}
// we failed to find anything that would match
return false ;
}
2010-02-20 21:51:29 -07:00
//ALERT: doesn't care about multiclasses
uint32_t memory_info : : getClassVPtr ( string classname )
{
// FIXME: another stupid search.
2010-02-22 15:34:20 -07:00
for ( uint32_t i = 0 ; i < d - > classes . size ( ) ; i + + )
2010-02-20 21:51:29 -07:00
{
//if(classes[i].)
2010-02-22 15:34:20 -07:00
if ( d - > classes [ i ] . classname = = classname ) // got class
2010-02-20 21:51:29 -07:00
{
2010-02-22 15:34:20 -07:00
return d - > classes [ i ] . vtable ;
2010-02-20 21:51:29 -07:00
}
}
// we failed to find anything that would match
return 0 ;
}
2009-09-13 18:02:46 -06:00
// Flatten vtables into a index<->name mapping
2010-02-11 14:08:39 -07:00
void memory_info : : getClassIDMapping ( vector < string > & v_ClassID2ObjName )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
for ( uint32_t i = 0 ; i < d - > classes . size ( ) ; i + + )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
v_ClassID2ObjName . push_back ( d - > classes [ i ] . classname ) ;
if ( ! d - > classes [ i ] . is_multiclass )
2009-09-13 18:02:46 -06:00
{
continue ;
}
2010-02-22 15:34:20 -07:00
vector < t_type > & vec = d - > classsubtypes [ d - > classes [ i ] . multi_index ] ;
2009-09-13 18:02:46 -06:00
for ( uint32_t k = 0 ; k < vec . size ( ) ; k + + )
{
2010-02-11 14:08:39 -07:00
v_ClassID2ObjName . push_back ( vec [ k ] . classname ) ;
2009-09-13 18:02:46 -06:00
}
}
}
2009-11-14 21:25:00 -07:00
// change base of all addresses
2009-11-22 07:43:53 -07:00
void memory_info : : RebaseAddresses ( const int32_t new_base )
2009-09-13 18:02:46 -06:00
{
map < string , uint32_t > : : iterator iter ;
2010-02-22 15:34:20 -07:00
int32_t rebase = - ( int32_t ) d - > base + new_base ;
for ( iter = d - > addresses . begin ( ) ; iter ! = d - > addresses . end ( ) ; iter + + )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
d - > addresses [ iter - > first ] = iter - > second + rebase ;
2009-09-13 18:02:46 -06:00
}
}
2009-11-14 21:25:00 -07:00
// change base of all addresses *and* vtable entries
2009-09-13 18:02:46 -06:00
void memory_info : : RebaseAll ( int32_t new_base )
{
map < string , uint32_t > : : iterator iter ;
2010-02-22 15:34:20 -07:00
int32_t rebase = - ( int32_t ) d - > base + new_base ;
for ( iter = d - > addresses . begin ( ) ; iter ! = d - > addresses . end ( ) ; iter + + )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
d - > addresses [ iter - > first ] = iter - > second + rebase ;
2009-09-13 18:02:46 -06:00
}
RebaseVTable ( rebase ) ;
}
// change all vtable entries by offset
void memory_info : : RebaseVTable ( int32_t offset )
{
vector < t_class > : : iterator iter ;
2010-02-22 15:34:20 -07:00
for ( iter = d - > classes . begin ( ) ; iter ! = d - > classes . end ( ) ; iter + + )
2009-09-13 18:02:46 -06:00
{
iter - > vtable + = offset ;
}
}
// Get named address
2009-11-22 07:43:53 -07:00
uint32_t memory_info : : getAddress ( const char * key )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
map < string , uint32_t > : : iterator iter = d - > addresses . find ( key ) ;
2009-11-22 07:43:53 -07:00
2010-02-22 15:34:20 -07:00
if ( iter ! = d - > addresses . end ( ) )
2009-09-13 18:02:46 -06:00
{
2009-11-22 07:43:53 -07:00
return ( * iter ) . second ;
2009-09-13 18:02:46 -06:00
}
return 0 ;
}
// Get named offset
2009-11-22 07:43:53 -07:00
uint32_t memory_info : : getOffset ( const char * key )
{
2010-02-22 15:34:20 -07:00
map < string , uint32_t > : : iterator iter = d - > offsets . find ( key ) ;
if ( iter ! = d - > offsets . end ( ) )
2009-11-22 07:43:53 -07:00
{
return ( * iter ) . second ;
}
return 0 ;
}
// Get named numerical value
uint32_t memory_info : : getHexValue ( const char * key )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
map < string , uint32_t > : : iterator iter = d - > hexvals . find ( key ) ;
if ( iter ! = d - > hexvals . end ( ) )
2009-09-13 18:02:46 -06:00
{
2009-11-22 07:43:53 -07:00
return ( * iter ) . second ;
2009-09-13 18:02:46 -06:00
}
return 0 ;
}
2009-11-22 07:43:53 -07:00
// Get named address
uint32_t memory_info : : getAddress ( const string & key )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
map < string , uint32_t > : : iterator iter = d - > addresses . find ( key ) ;
2009-11-22 07:43:53 -07:00
2010-02-22 15:34:20 -07:00
if ( iter ! = d - > addresses . end ( ) )
2009-09-13 18:02:46 -06:00
{
2009-11-22 07:43:53 -07:00
return ( * iter ) . second ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
return 0 ;
2009-09-13 18:02:46 -06:00
}
2009-11-22 07:43:53 -07:00
// Get named offset
uint32_t memory_info : : getOffset ( const string & key )
{
2010-02-22 15:34:20 -07:00
map < string , uint32_t > : : iterator iter = d - > offsets . find ( key ) ;
if ( iter ! = d - > offsets . end ( ) )
2009-11-22 07:43:53 -07:00
{
return ( * iter ) . second ;
}
return 0 ;
}
2009-09-13 18:02:46 -06:00
// Get named numerical value
2009-11-22 07:43:53 -07:00
uint32_t memory_info : : getHexValue ( const string & key )
2009-09-13 18:02:46 -06:00
{
2010-02-22 15:34:20 -07:00
map < string , uint32_t > : : iterator iter = d - > hexvals . find ( key ) ;
if ( iter ! = d - > hexvals . end ( ) )
2009-09-13 18:02:46 -06:00
{
2009-11-22 07:43:53 -07:00
return ( * iter ) . second ;
2009-09-13 18:02:46 -06:00
}
return 0 ;
}
2009-11-22 07:43:53 -07:00
// Get named string
std : : string memory_info : : getString ( const string & key )
{
2010-02-22 15:34:20 -07:00
map < string , string > : : iterator iter = d - > strings . find ( key ) ;
if ( iter ! = d - > strings . end ( ) )
2009-11-22 07:43:53 -07:00
{
return ( * iter ) . second ;
}
return string ( " " ) ;
}
2009-11-07 14:05:10 -07:00
// Get Profession
2009-11-22 07:43:53 -07:00
string memory_info : : getProfession ( const uint32_t key ) const
2009-11-07 14:05:10 -07:00
{
2010-02-22 15:34:20 -07:00
if ( d - > professions . size ( ) > key )
2009-11-09 16:18:20 -07:00
{
2010-02-22 15:34:20 -07:00
return d - > professions [ key ] ;
2009-11-09 16:18:20 -07:00
}
2009-11-22 07:43:53 -07:00
else
{
2009-11-09 16:18:20 -07:00
return string ( " " ) ;
}
2009-11-07 14:05:10 -07:00
}
// Get Job
2009-11-22 07:43:53 -07:00
string memory_info : : getJob ( const uint32_t key ) const
2009-11-07 14:05:10 -07:00
{
2010-02-22 15:34:20 -07:00
if ( d - > jobs . size ( ) > key )
2009-11-22 07:43:53 -07:00
{
2010-02-22 15:34:20 -07:00
return d - > jobs [ key ] ;
2009-11-09 16:18:20 -07:00
}
return string ( " Job Does Not Exist " ) ;
}
2009-11-22 07:43:53 -07:00
string memory_info : : getSkill ( const uint32_t key ) const
2009-11-09 16:18:20 -07:00
{
2010-02-22 15:34:20 -07:00
if ( d - > skills . size ( ) > key )
2009-11-22 07:43:53 -07:00
{
2010-02-22 15:34:20 -07:00
return d - > skills [ key ] ;
2009-11-09 16:18:20 -07:00
}
return string ( " Skill is not Defined " ) ;
}
2009-11-13 06:35:44 -07:00
// FIXME: ugly hack that needs to die
int absolute ( int number )
{
if ( number < 0 )
return - number ;
return number ;
}
2009-11-22 07:43:53 -07:00
string memory_info : : getTrait ( const uint32_t traitIdx , const uint32_t traitValue ) const
2009-11-13 06:35:44 -07:00
{
2010-02-22 15:34:20 -07:00
if ( d - > traits . size ( ) > traitIdx )
2009-11-13 06:35:44 -07:00
{
int diff = absolute ( traitValue - 50 ) ;
if ( diff < 10 )
{
return string ( " " ) ;
}
if ( traitValue > = 91 )
2010-02-22 15:34:20 -07:00
return d - > traits [ traitIdx ] [ 5 ] ;
2009-11-13 06:35:44 -07:00
else if ( traitValue > = 76 )
2010-02-22 15:34:20 -07:00
return d - > traits [ traitIdx ] [ 4 ] ;
2009-11-13 06:35:44 -07:00
else if ( traitValue > = 61 )
2010-02-22 15:34:20 -07:00
return d - > traits [ traitIdx ] [ 3 ] ;
2009-11-13 06:35:44 -07:00
else if ( traitValue > = 25 )
2010-02-22 15:34:20 -07:00
return d - > traits [ traitIdx ] [ 2 ] ;
2009-11-13 06:35:44 -07:00
else if ( traitValue > = 10 )
2010-02-22 15:34:20 -07:00
return d - > traits [ traitIdx ] [ 1 ] ;
2009-11-13 06:35:44 -07:00
else
2010-02-22 15:34:20 -07:00
return d - > traits [ traitIdx ] [ 0 ] ;
2009-11-13 06:35:44 -07:00
}
return string ( " Trait is not Defined " ) ;
2009-11-09 16:18:20 -07:00
}
2009-11-22 07:43:53 -07:00
string memory_info : : getTraitName ( const uint32_t traitIdx ) const
2009-11-09 16:18:20 -07:00
{
2010-02-22 15:34:20 -07:00
if ( d - > traits . size ( ) > traitIdx )
2009-11-13 06:35:44 -07:00
{
2010-02-22 15:34:20 -07:00
return d - > traits [ traitIdx ] [ d - > traits [ traitIdx ] . size ( ) - 1 ] ;
2009-11-13 06:35:44 -07:00
}
return string ( " Trait is not Defined " ) ;
2009-11-07 14:05:10 -07:00
}
2009-11-22 07:43:53 -07:00
string memory_info : : getLabor ( const uint32_t laborIdx )
2009-11-09 16:18:20 -07:00
{
2010-02-22 15:34:20 -07:00
if ( d - > labors . count ( laborIdx ) )
2009-11-13 06:35:44 -07:00
{
2010-02-22 15:34:20 -07:00
return d - > labors [ laborIdx ] ;
2009-11-09 16:18:20 -07:00
}
return string ( " " ) ;
}
2009-09-13 18:02:46 -06:00
// Reset everything
void memory_info : : flush ( )
{
2010-02-22 15:34:20 -07:00
d - > base = 0 ;
d - > addresses . clear ( ) ;
d - > offsets . clear ( ) ;
d - > strings . clear ( ) ;
d - > hexvals . clear ( ) ;
d - > classes . clear ( ) ;
d - > classsubtypes . clear ( ) ;
d - > classindex = 0 ;
d - > version = " " ;
d - > OS = OS_BAD ;
2009-09-13 18:02:46 -06:00
}