Seemingly working VersionInfo loading parts. The offset names are now all wrong in the modules. DO NOT USE

develop
Petr Mrázek 2010-08-28 03:57:56 +02:00
parent b33d56354f
commit f2dea86819
11 changed files with 412 additions and 182 deletions

@ -813,6 +813,9 @@
<class name="buildingst"/>
</VTable>
<Offsets>
<Address name="WORLD" description="A huge object that many things in DF are part of. Contains the whole game and can be used as a base
for many of the addresses." />
<HexValue name="sdasdasdizeof" description="The total size in bytes." />
<Group name="vector" description="An STL vector.">
<HexValue name="sizeof" description="The total size in bytes." />
<Offset name="start" description="The offset where the actual start/end/alloc_end triplet is." />
@ -1407,7 +1410,7 @@
<!-- Windows logo by Microsoft -->
<!-- Tux logo by the Linux guys :) -->
<Version version="v0.31.05 linux" os="linux" base="DF2010">
<Version name="v0.31.05 linux" os="linux" base="DF2010">
<MD5 value="fea3801a26538b1741f3cc9294139fca" />
<Offsets>
<Address name="WORLD" value="0x92C60E0" valid="false" />
@ -1603,7 +1606,7 @@
</Group>
</Offsets>
</Version>
<Version version="v0.31.06 linux" os="linux" base="v0.31.05 linux" rebase="-0x20E0">
<Version name="v0.31.06 linux" os="linux" base="v0.31.05 linux" rebase="-0x20E0">
<MD5 value="13a1c19e8f59b74e307e094e2a0f28c3" />
<Offsets>
<Address name="WORLD" value="0x92C4000" />
@ -1618,18 +1621,18 @@
0x92d7a10
</Offsets>
</Version>
<Version version="v0.31.07 linux" os="linux" base="v0.31.06 linux" rebase="0x2000">
<Version name="v0.31.07 linux" os="linux" base="v0.31.06 linux" rebase="0x2000">
<MD5 value="b31979551782e89c049b11db8d2d86d7" />
</Version>
<Version version="v0.31.08 linux" os="linux" base="v0.31.07 linux">
<Version name="v0.31.08 linux" os="linux" base="v0.31.07 linux">
<MD5 value="e37750890350d7b9d8203879aff8fa5c" />
</Version>
<Version version="v0.31.09 linux" os="linux" base="v0.31.08 linux" rebase="0x11000">
<Version name="v0.31.09 linux" os="linux" base="v0.31.08 linux" rebase="0x11000">
<!-- TODO: fix creature offsets -->
<!-- TODO: small offsets added all over the place, investigate -->
<MD5 value="4f1f988bc1b425d4193d3d8b7b0579a5" />
</Version>
<Version version="v0.31.10 linux" os="linux" base="v0.31.09 linux">
<Version name="v0.31.10 linux" os="linux" base="v0.31.09 linux">
<MD5 value="3e7bea269018a6fb88ef53715685aa64" />
<Offsets>
<Group name="Buildings">
@ -1647,17 +1650,19 @@
<multiclass name="building_siegeenginest" typeoffset="0xC0" />
</VTable>
</Version>
<Version version="v0.31.11 linux" os="linux" base="v0.31.10 linux" rebase="0x1D020">
<Version name="v0.31.11 linux" os="linux" base="v0.31.10 linux" rebase="0x1D020">
<!-- BIG rebase, possible broken stuff -->
<MD5 value="7b04ad536b8b657588ac209a7f95e1d1" />
<Offsets>
<Address name="window_x" value="0x8cf7a58" /> VERIFIED
<Address name="window_y" value="0x8cf7a5C" /> VERIFIED
<Address name="window_z" value="0x8cf7a60" /> VERIFIED
<Address name="cursor_xyz" value="0x8b3b328" /> VERIFIED
<Group name="Position">
<Address name="window_x" value="0x8cf7a58" /> VERIFIED
<Address name="window_y" value="0x8cf7a5C" /> VERIFIED
<Address name="window_z" value="0x8cf7a60" /> VERIFIED
<Address name="cursor_xyz" value="0x8b3b328" /> VERIFIED
</Group>
</Offsets>
</Version>
<Version version="v0.31.12 linux" os="linux" base="v0.31.11 linux" rebase="-0x1000">
<Version name="v0.31.12 linux" os="linux" base="v0.31.11 linux" rebase="-0x1000">
<MD5 value="e79cead03187ecb692961b316b7cdcd4" />
</Version>
</DFHack>

@ -27,10 +27,10 @@ include_directories (${CMAKE_SOURCE_DIR}/library/depends/argstream/)
include_directories (${CMAKE_SOURCE_DIR}/library/private/)
SET(PROJECT_HDRS
private/VersionInfoFactory.h
private/ContextShared.h
private/Internal.h
include/dfhack/DFError.h
include/dfhack/VersionInfoFactory.h
include/dfhack/VersionInfo.h
include/dfhack/DFProcessEnumerator.h
include/dfhack/DFProcess.h

@ -23,8 +23,8 @@ distribution.
*/
#include "Internal.h"
#include "VersionInfoFactory.h"
#include "dfhack/VersionInfoFactory.h"
#include "dfhack/DFProcess.h"
#include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFError.h"

@ -120,6 +120,7 @@ bool NormalProcess::Private::validate(char * exe_file,uint32_t pid, char * memFi
{
try
{
//cout << hash << " ?= " << (*it)->getMD5() << endl;
if(hash == (*it)->getMD5()) // are the md5 hashes the same?
{
VersionInfo * m = *it;

@ -23,8 +23,8 @@ distribution.
*/
#include "Internal.h"
#include "VersionInfoFactory.h"
#include "dfhack/VersionInfoFactory.h"
#include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFProcess.h"
#include "dfhack/VersionInfo.h"

@ -87,132 +87,195 @@ namespace DFHack
*/
namespace DFHack
{
typedef pair <bool, uint32_t> nullableUint32;
typedef map <string, nullableUint32 >::iterator uint32_Iter;
typedef pair <bool, int32_t> nullableInt32;
typedef map <string, nullableInt32 >::iterator int32_Iter;
typedef pair <bool, string> nullableString;
typedef map <string, nullableString >::iterator strings_Iter;
typedef map <string, OffsetGroup *>::iterator groups_Iter;
class OffsetGroupPrivate
{
public:
map <string, uint32_t> addresses;
map <string, int32_t> offsets;
map <string, uint32_t> hexvals;
map <string, string> strings;
map <string, OffsetGroup> groups;
map <string, nullableUint32 > addresses;
map <string, nullableUint32 > hexvals;
map <string, nullableInt32 > offsets;
map <string, nullableString > strings;
map <string, OffsetGroup *> groups;
};
}
void OffsetGroup::createOffset(const string & key)
{
OGd->offsets[key] = nullableInt32(false, 0);
}
void OffsetGroup::createAddress(const string & key)
{
OGd->addresses[key] = nullableUint32(false, 0);
}
void OffsetGroup::createHexValue(const string & key)
{
OGd->hexvals[key] = nullableUint32(false, 0);
}
void OffsetGroup::createString(const string & key)
{
OGd->strings[key] = nullableString(false, std::string());
}
void OffsetGroup::setOffset (const string & key, const string & value)
{
int32_t offset = strtol(value.c_str(), NULL, 16);
d->offsets[key] = offset;
int32_Iter it;
if((it = OGd->offsets.find(key)) != OGd->offsets.end())
{
int32_t offset = strtol(value.c_str(), NULL, 16);
(*it).second.second = offset;
(*it).second.first = true;
}
else throw Error::MissingMemoryDefinition("offset", key);
}
void OffsetGroup::setAddress (const string & key, const string & value)
{
uint32_t address = strtol(value.c_str(), NULL, 16);
d->addresses[key] = address;
uint32_Iter it;
if((it = OGd->addresses.find(key)) != OGd->addresses.end())
{
int32_t address = strtol(value.c_str(), NULL, 16);
(*it).second.second = address;
(*it).second.first = true;
}
else throw Error::MissingMemoryDefinition("address", key);
}
void OffsetGroup::setHexValue (const string & key, const string & value)
{
uint32_t hexval = strtol(value.c_str(), NULL, 16);
d->hexvals[key] = hexval;
uint32_Iter it;
if((it = OGd->hexvals.find(key)) != OGd->hexvals.end())
{
(*it).second.second = strtol(value.c_str(), NULL, 16);
(*it).second.first = true;
}
else throw Error::MissingMemoryDefinition("hexvalue", key);
}
void OffsetGroup::setString (const string & key, const string & value)
{
d->strings[key] = value;
strings_Iter it;
if((it = OGd->strings.find(key)) != OGd->strings.end())
{
(*it).second.second = value;
(*it).second.first = true;
}
else throw Error::MissingMemoryDefinition("string", key);
}
// Get named address
uint32_t OffsetGroup::getAddress (const char *key)
uint32_t OffsetGroup::getAddress (const string & key)
{
map <string, uint32_t>::iterator iter = d->addresses.find(key);
uint32_Iter iter = OGd->addresses.find(key);
if(iter != d->addresses.end())
if(iter != OGd->addresses.end())
{
return (*iter).second;
if((*iter).second.first)
return (*iter).second.second;
throw Error::UnsetMemoryDefinition("address", key);
}
throw Error::MissingMemoryDefinition("address", key);
}
// Get named offset
int32_t OffsetGroup::getOffset (const char *key)
int32_t OffsetGroup::getOffset (const string & key)
{
map <string, int32_t>::iterator iter = d->offsets.find(key);
if(iter != d->offsets.end())
int32_Iter iter = OGd->offsets.find(key);
if(iter != OGd->offsets.end())
{
return (*iter).second;
if((*iter).second.first)
return (*iter).second.second;
throw Error::UnsetMemoryDefinition("offset", key);
}
throw Error::MissingMemoryDefinition("offset", key);
}
// Get named numerical value
uint32_t OffsetGroup::getHexValue (const char *key)
uint32_t OffsetGroup::getHexValue (const string & key)
{
map <string, uint32_t>::iterator iter = d->hexvals.find(key);
if(iter != d->hexvals.end())
uint32_Iter iter = OGd->hexvals.find(key);
if(iter != OGd->hexvals.end())
{
return (*iter).second;
if((*iter).second.first)
return (*iter).second.second;
throw Error::UnsetMemoryDefinition("hexvalue", key);
}
throw Error::MissingMemoryDefinition("hexvalue", key);
}
// Get named address
uint32_t OffsetGroup::getAddress (const string &key)
// Get named string
std::string OffsetGroup::getString (const string &key)
{
map <string, uint32_t>::iterator iter = d->addresses.find(key);
if(iter != d->addresses.end())
strings_Iter iter = OGd->strings.find(key);
if(iter != OGd->strings.end())
{
return (*iter).second;
if((*iter).second.first)
return (*iter).second.second;
throw Error::UnsetMemoryDefinition("string", key);
}
throw Error::MissingMemoryDefinition("address", key.c_str());
throw Error::MissingMemoryDefinition("string", key);
}
// Get named offset
int32_t OffsetGroup::getOffset (const string &key)
OffsetGroup * OffsetGroup::getGroup(const std::string &name)
{
map <string, int32_t>::iterator iter = d->offsets.find(key);
if(iter != d->offsets.end())
{
return (*iter).second;
}
throw Error::MissingMemoryDefinition("offset", key.c_str());
groups_Iter iter = OGd->groups.find(name);
if(iter != OGd->groups.end())
return ((*iter).second);
return 0;
}
OffsetGroup * OffsetGroup::createGroup(const std::string &name)
{
OffsetGroup * ret = getGroup(name);
if(ret)
return ret;
ret = new OffsetGroup();
OGd->groups[name] = ret;
return ret;
}
// Get named numerical value
uint32_t OffsetGroup::getHexValue (const string &key)
void OffsetGroup::RebaseAddresses(int32_t offset)
{
map <string, uint32_t>::iterator iter = d->hexvals.find(key);
if(iter != d->hexvals.end())
for(uint32_Iter iter = OGd->addresses.begin(); iter != OGd->addresses.end(); iter++)
{
if(iter->second.first)
OGd->addresses[iter->first].second = iter->second.second + offset;
}
for(groups_Iter iter = OGd->groups.begin(); iter != OGd->groups.end(); iter++)
{
return (*iter).second;
(*iter).second->RebaseAddresses(offset);
}
throw Error::MissingMemoryDefinition("hexvalue", key.c_str());
}
OffsetGroup::OffsetGroup()
{
OGd = new OffsetGroupPrivate();
}
// Get named string
std::string OffsetGroup::getString (const string &key)
OffsetGroup::~OffsetGroup()
{
map <string, string>::iterator iter = d->strings.find(key);
if(iter != d->strings.end())
for(groups_Iter it = OGd->groups.begin();it != OGd->groups.end();it++)
{
return (*iter).second;
delete (*it).second;
}
throw Error::MissingMemoryDefinition("string", key.c_str());
OGd->groups.clear();
delete OGd;
}
/*
* Private data
*/
@ -221,11 +284,6 @@ namespace DFHack
class VersionInfoPrivate
{
public:
map <string, uint32_t> addresses;
map <string, int32_t> offsets;
map <string, uint32_t> hexvals;
map <string, string> strings;
vector<string> professions;
vector<string> jobs;
vector<string> skills;
@ -277,16 +335,26 @@ VersionInfo::VersionInfo(const VersionInfo &old)
copy(&old);
}
void OffsetGroup::copy(const OffsetGroup * old)
{
OGd->addresses = old->OGd->addresses;
OGd->offsets = old->OGd->offsets;
OGd->hexvals = old->OGd->hexvals;
OGd->strings = old->OGd->strings;
for(groups_Iter it = old->OGd->groups.begin(); it != old->OGd->groups.end(); it++)
{
OffsetGroup * ogn = new OffsetGroup();
ogn->copy((*it).second);
OGd->groups[(*it).first] = ogn;
}
}
void VersionInfo::copy(const VersionInfo * old)
{
d->version = old->d->version;
d->OS = old->d->OS;
d->md5 = old->d->md5;
d->PE_timestamp = old->d->PE_timestamp;
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;
for(uint32_t i = 0; i < old->d->classes.size(); i++)
@ -303,6 +371,7 @@ void VersionInfo::copy(const VersionInfo * old)
d->labors = old->d->labors;
d->levels = old->d->levels;
d->moods = old->d->moods;
OffsetGroup::copy(reinterpret_cast<const OffsetGroup *>(old));
}
void VersionInfo::setParentProcess(Process * _p)
@ -677,12 +746,7 @@ const vector<string> * VersionInfo::getClassIDMapping()
// change base of all addresses
void VersionInfo::RebaseAddresses(const int32_t new_base)
{
map<string, uint32_t>::iterator iter;
int32_t rebase = - (int32_t)d->base + new_base;
for(iter = d->addresses.begin(); iter != d->addresses.end(); iter++)
{
d->addresses[iter->first] = iter->second + rebase;
}
OffsetGroup::RebaseAddresses(- (int32_t)d->base + new_base);
}
@ -841,25 +905,27 @@ std::string VersionInfo::PrintOffsets()
ss << " UNKNOWN" << endl;
}
ss << "<Offsets>" << endl;
/*
map<string,uint32_t>::const_iterator iter;
for(iter = d->addresses.begin(); iter != d->addresses.end(); iter++)
for(iter = OGd->addresses.begin(); iter != OGd->addresses.end(); iter++)
{
ss << " <Address name=\"" << (*iter).first << "\" value=\"" << hex << "0x" << (*iter).second << "\" />" << endl;
}
map<string,int32_t>::const_iterator iter2;
for(iter2 = d->offsets.begin(); iter2 != d->offsets.end(); iter2++)
for(iter2 = OGd->offsets.begin(); iter2 != OGd->offsets.end(); iter2++)
{
ss << " <Offset name=\"" << (*iter2).first << "\" value=\"" << hex << "0x" << (*iter2).second <<"\" />" << endl;
}
for(iter = d->hexvals.begin(); iter != d->hexvals.end(); iter++)
for(iter = OGd->hexvals.begin(); iter != OGd->hexvals.end(); iter++)
{
ss << " <HexValue name=\"" << (*iter).first << "\" value=\"" << hex << "0x" << (*iter).second <<"\" />" << endl;
}
map<string,string>::const_iterator iter3;
for(iter3 = d->strings.begin(); iter3 != d->strings.end(); iter3++)
for(iter3 = OGd->strings.begin(); iter3 != OGd->strings.end(); iter3++)
{
ss << " <String name=\"" << (*iter3).first << "\" value=\"" << (*iter3).second <<"\" />" << endl;
}
*/
ss << "</Offsets>" << endl;
ss << "</Version>" << endl;
return ss.str();

@ -23,10 +23,11 @@ distribution.
*/
#include "Internal.h"
#include "VersionInfoFactory.h"
#include "dfhack/VersionInfoFactory.h"
#include "dfhack/VersionInfo.h"
#include "dfhack/DFError.h"
#include <algorithm>
using namespace DFHack;
@ -94,6 +95,167 @@ void VersionInfoFactory::ParseVTable(TiXmlElement* vtable, VersionInfo* mem)
}
}
// FIXME: this is ripe for replacement with a more generic approach
void VersionInfoFactory::ParseOffsets(TiXmlElement * parent, VersionInfo* target, bool initial)
{
// we parse the groups iteratively instead of recursively
// breadcrubs acts like a makeshift stack
// first pair entry stores the current element of that level
// second pair entry the group object from OffsetGroup
typedef pair < TiXmlElement *, OffsetGroup * > groupPair;
vector< groupPair > breadcrumbs;
{
TiXmlElement* pEntry;
// we get the <Offsets>, look at the children
pEntry = parent->FirstChildElement();
if(!pEntry)
return;
OffsetGroup * currentGroup = reinterpret_cast<OffsetGroup *> (target);
breadcrumbs.push_back(groupPair(pEntry,currentGroup));
}
// work variables
OffsetGroup * currentGroup = 0;
TiXmlElement * currentElem = 0;
cerr << "<Offsets>"<< endl;
while(1)
{
// get current work variables
currentElem = breadcrumbs.back().first;
currentGroup = breadcrumbs.back().second;
// we reached the end of the current group?
if(!currentElem)
{
// go one level up
breadcrumbs.pop_back();
// exit if no more work
if(breadcrumbs.empty())
{
break;
}
else
{
cerr << "</group>" << endl;
continue;
}
}
if(!currentGroup)
{
groupPair & gp = breadcrumbs.back();
gp.first = gp.first->NextSiblingElement();
continue;
}
// skip non-elements
if (currentElem->Type() != TiXmlNode::ELEMENT)
{
groupPair & gp = breadcrumbs.back();
gp.first = gp.first->NextSiblingElement();
continue;
}
// we have a valid current element and current group
// get properties
string type = currentElem->Value();
std::transform(type.begin(), type.end(), type.begin(), ::tolower);
const char *cstr_name = currentElem->Attribute("name");
if(!cstr_name)
{
// ERROR, missing attribute
}
// evaluate elements
const char *cstr_value = currentElem->Attribute("value");
if(type == "group")
{
// FIXME: possibly use setGroup always, with the initial flag as parameter?
// create or get group
OffsetGroup * og;
if(initial)
og = currentGroup->createGroup(cstr_name);
else
og = currentGroup->getGroup(cstr_name);
cerr << "<group name=\"" << cstr_name << "\">" << endl;
// advance this level to the next element
groupPair & gp = breadcrumbs.back();
gp.first = gp.first->NextSiblingElement();
// add a new level that will be processed next
breadcrumbs.push_back(groupPair(currentElem->FirstChildElement(), og));
continue;
}
else if(type == "address")
{
if(initial)
{
currentGroup->createAddress(cstr_name);
}
else if(cstr_value)
{
currentGroup->setAddress(cstr_name, cstr_value);
}
else
{
// ERROR, missing attribute
}
}
else if(type == "offset")
{
if(initial)
{
currentGroup->createOffset(cstr_name);
}
else if(cstr_value)
{
currentGroup->setOffset(cstr_name, cstr_value);
}
else
{
// ERROR, missing attribute
}
}
else if(type == "string")
{
if(initial)
{
currentGroup->createString(cstr_name);
}
else if(cstr_value)
{
currentGroup->setString(cstr_name, cstr_value);
}
else
{
// ERROR, missing attribute
}
}
else if(type == "hexvalue")
{
if(initial)
{
currentGroup->createHexValue(cstr_name);
}
else if(cstr_value)
{
currentGroup->setHexValue(cstr_name, cstr_value);
}
else
{
// ERROR, missing attribute
}
}
// advance to next element
groupPair & gp = breadcrumbs.back();
gp.first = gp.first->NextSiblingElement();
continue;
}
cerr << "</Offsets>"<< endl;
}
void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem)
{
TiXmlElement* pElement;
@ -121,12 +283,12 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem)
else if(type == "Offsets")
{
// we don't care about the descriptions here, do nothing
//ParseBaseOffsets(pMemEntry, mem);
ParseOffsets(pElement, mem, true);
continue;
}
else if (type == "Professions")
{
pElement2nd = entry->FirstChildElement("Profession")->ToElement();
pElement2nd = entry->FirstChildElement("Profession");
for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Profession"))
{
const char * id = pElement2nd->Attribute("id");
@ -145,7 +307,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem)
}
else if (type == "Jobs")
{
pElement2nd = entry->FirstChildElement("Job")->ToElement();
pElement2nd = entry->FirstChildElement("Job");
for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Job"))
{
const char * id = pElement2nd->Attribute("id");
@ -163,7 +325,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem)
}
else if (type == "Skills")
{
pElement2nd = entry->FirstChildElement("Skill")->ToElement();
pElement2nd = entry->FirstChildElement("Skill");
for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Skill"))
{
const char * id = pElement2nd->Attribute("id");
@ -181,7 +343,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem)
}
else if (type == "Traits")
{
pElement2nd = entry->FirstChildElement("Trait")->ToElement();
pElement2nd = entry->FirstChildElement("Trait");
for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Trait"))
{
const char * id = pElement2nd->Attribute("id");
@ -205,7 +367,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem)
}
else if (type == "Labors")
{
pElement2nd = entry->FirstChildElement("Labor")->ToElement();
pElement2nd = entry->FirstChildElement("Labor");
for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Labor"))
{
const char * id = pElement2nd->Attribute("id");
@ -223,7 +385,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem)
}
else if (type == "Levels")
{
pElement2nd = entry->FirstChildElement("Level")->ToElement();
pElement2nd = entry->FirstChildElement("Level");
for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Level"))
{
const char * id = pElement2nd->Attribute("id");
@ -242,7 +404,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem)
}
else if (type == "Moods")
{
pElement2nd = entry->FirstChildElement("Mood")->ToElement();
pElement2nd = entry->FirstChildElement("Mood");
for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Mood"))
{
const char * id = pElement2nd->Attribute("id");
@ -276,7 +438,6 @@ void VersionInfoFactory::EvalVersion(string base, VersionInfo * mem)
VersionInfo * newmem = new VersionInfo();
ParseVersion(desc.first, newmem);
desc.second = newmem;
versions.push_back(newmem);
}
mem->copy(desc.second);
}
@ -345,29 +506,7 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem)
}
else if(type == "Offsets")
{
/*
if (type == "HexValue")
{
mem->setHexValue(name, value);
}
else if (type == "Address")
{
mem->setAddress(name, value);
}
else if (type == "Offset")
{
mem->setOffset(name, value);
}
else if (type == "String")
{
mem->setString(name, value);
}
else
{
throw Error::MemoryXmlUnknownType(type.c_str());
}
*/
//ParseOffsets(pMemEntry, mem);
ParseOffsets(pMemEntry, mem);
continue;
}
else if (type == "MD5")
@ -382,7 +521,7 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem)
const char *cstr_value = pMemEntry->Attribute("value");
if(!cstr_value)
throw Error::MemoryXmlUnderspecifiedEntry(cstr_name);
mem->setPE(atol(cstr_value));
mem->setPE(strtol(cstr_value, 0, 16));
}
} // for
} // method
@ -446,6 +585,7 @@ bool VersionInfoFactory::loadFile(string path_to_xml)
{
string str_name = name;
VersionInfo *base = new VersionInfo();
mem = new VersionInfo();
ParseBase( pMemInfo , mem );
knownVersions[str_name] = v_descr (pMemInfo, mem);
}

@ -78,10 +78,10 @@ namespace DFHack
class DFHACK_EXPORT MissingMemoryDefinition : public std::exception
{
public:
MissingMemoryDefinition(const char* _type, const char* _key) : type(_type), key(_key)
MissingMemoryDefinition(const char* _type, const std::string _key) : type(_type), key(_key)
{
std::stringstream s;
s << "memory definition missing: type " << type << " key " << key;
s << "memory object not declared: type " << type << " key " << key;
full = s.str();
}
// Used by functios using integer keys, such as getTrait
@ -92,24 +92,44 @@ namespace DFHack
key = s1.str();
std::stringstream s;
s << "memory definition missing: type " << type << " key " << key;
s << "memory object not declared: type " << type << " key " << key;
full = s.str();
}
virtual ~MissingMemoryDefinition() throw(){};
// (perhaps it should be an enum, but this is intended for easy printing/logging)
// type can be any of the following:
//
// address
// offset
// hexvalue
// string
// profession
// job
// skill
// trait
// traitname
// labor
std::string full;
const std::string type;
std::string key;
virtual const char* what() const throw()
{
return full.c_str();
}
};
// a call to DFHack::mem_info::get* failed
class DFHACK_EXPORT UnsetMemoryDefinition : public std::exception
{
public:
UnsetMemoryDefinition(const char* _type, const std::string _key) : type(_type), key(_key)
{
std::stringstream s;
s << "memory object not set: type " << type << " key " << key;
full = s.str();
}
// Used by functios using integer keys, such as getTrait
UnsetMemoryDefinition(const char* _type, uint32_t _key) : type(_type)
{
std::stringstream s1;
s1 << _key;
key = s1.str();
std::stringstream s;
s << "memory object not set: type " << type << " key " << key;
full = s.str();
}
virtual ~UnsetMemoryDefinition() throw(){};
std::string full;
const std::string type;
std::string key;

@ -39,38 +39,42 @@ namespace DFHack
struct t_class;
class VersionInfoPrivate;
class OffsetGroupPrivate;
/*
* Offset Group
*/
class DFHACK_EXPORT OffsetGroup
{
protected:
OffsetGroupPrivate * d;
OffsetGroupPrivate * OGd;
public:
int32_t getOffset (const std::string&);
uint32_t getAddress (const std::string&);
uint32_t getHexValue (const std::string&);
std::string getString (const std::string&);
int32_t getOffset (const char *);
uint32_t getAddress (const char *);
uint32_t getHexValue (const char *);
std::string getString (const char *);
void setOffset (const std::string &, const int32_t);
void setAddress (const std::string &, const uint32_t);
void setHexValue (const std::string &, const uint32_t);
void setOffset (const std::string &, const char *);
void setAddress (const std::string &, const char *);
void setHexValue (const std::string &, const char *);
void setString (const std::string &, const char *);
void setOffset (const std::string &, const std::string &);
void setAddress (const std::string &, const std::string &);
void setHexValue (const std::string &, const std::string &);
void setString (const std::string &, const std::string &);
OffsetGroup & getGroup (const std::string name);
OffsetGroup();
~OffsetGroup();
void copy(const OffsetGroup * old); // recursive
void RebaseAddresses( int32_t offset ); // recursive
void createOffset (const std::string & key);
void createAddress (const std::string & key);
void createHexValue (const std::string & key);
void createString (const std::string & key);
OffsetGroup * createGroup ( const std::string & name );
int32_t getOffset (const std::string & key);
uint32_t getAddress (const std::string & key);
uint32_t getHexValue (const std::string & key);
std::string getString (const std::string & key);
OffsetGroup * getGroup ( const std::string & name );
void setOffset (const std::string & key, const std::string & value);
void setAddress (const std::string & key, const std::string & value);
void setHexValue (const std::string & key, const std::string & value);
void setString (const std::string & key, const std::string & value);
};
/*
* Version Info
*/
class DFHACK_EXPORT VersionInfo : public OffsetGroup
{
private:

@ -26,12 +26,13 @@ distribution.
#define MEMINFO_MANAGER_H_INCLUDED
#include "dfhack/DFPragma.h"
#include "dfhack/DFExport.h"
class TiXmlElement;
namespace DFHack
{
class VersionInfo;
class VersionInfoFactory
class DFHACK_EXPORT VersionInfoFactory
{
friend class ProcessEnumerator;
public:
@ -47,6 +48,8 @@ namespace DFHack
void ParseVersion (TiXmlElement* version, VersionInfo* mem);
// copy version 'base' to 'target' or throw
void EvalVersion(std::string base, VersionInfo* target);
void ParseOffsets(TiXmlElement* elem, VersionInfo* target, bool initial = false);
bool error;
typedef std::pair < TiXmlElement *, VersionInfo *> v_descr;
std::map <std::string , v_descr > knownVersions;

@ -8,31 +8,22 @@
using namespace std;
#include <DFHack.h>
#include <dfhack/VersionInfoFactory.h>
using namespace DFHack;
int main (int numargs, const char ** args)
{
DFHack::ContextManager DFMgr("Memory.xml");
DFHack::Context * DF;
try
{
DF = DFMgr.getSingleContext();
DF->Attach();
}
catch (exception& e)
DFHack::VersionInfoFactory * VIF = new DFHack::VersionInfoFactory("Memory.xml");
for(int i = 0; i < VIF->versions.size(); i++)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
cout << VIF->versions[i]->PrintOffsets();
}
VersionInfo * minfo = DF->getMemoryInfo();
if(minfo)
cout << minfo->PrintOffsets();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
delete VIF;
return 0;
}