The library is compilable under Linux with GCC and under Windows with
MinGW32 and MSVC compilers. It is using the cmake build system. See
COMPILE for details.
@@ -490,17 +502,17 @@ the dfhack repository is welcome and the right thing to do :)
code does have a lot of comments though (and getting better all the
time).
-
+
Several things should be kept in mind when contributing to DFHack.
-
+
DFhack uses ANSI formatting and four spaces as indentation. Line
endings are UNIX. The files use UTF-8 encoding. Code not following this
won't make me happy, because I'll have to fix it. There's a good chance
I'll make you fix it ;)
-
+
You can send patches or make a clone of the github repo and ask me on
the IRC channel to pull your code in. I'll review it and see if there
are any problems. I'll fix them if they are minor.
@@ -510,7 +522,7 @@ this is also a good place to dump new ideas and/or bugs that need
fixing.
-
+
DFHack uses modules to partition sets of features into manageable
chunks. A module can have both client and server side.
Client side is the part that goes into the main library and is
@@ -548,7 +560,7 @@ server, it allows accelerating the reading of map blocks.
pretty fast, but needs quite a bit of care to not break.
-
+
- Internal
- either part of the codebase or statically linked.
@@ -560,7 +572,7 @@ dependencies for core dfhack should be either public domain or require
attribution at most. External dependencies for tools can be either
that, or any Free Software licenses.
-
+
- tinyxml
- used by core dfhack to read offset definitions from Memory.xml
@@ -572,7 +584,7 @@ DF binaries on Linux.
-
+
- wide-character ncurses
- used for the veinlook tool on Linux.
@@ -581,7 +593,7 @@ DF binaries on Linux.
-
+
- cmake
- you need cmake to generate the build system and some configuration
@@ -592,7 +604,7 @@ headers
-
+
The files with memory offset definitions used by dfhack can be found in the
data folder.
diff --git a/data/Memory-ng.xml b/data/Memory-ng.xml
index f331c10d2..96ef2f53f 100644
--- a/data/Memory-ng.xml
+++ b/data/Memory-ng.xml
@@ -674,6 +674,22 @@
+
+
+
+
+
+
@@ -885,7 +901,7 @@
-
+
@@ -938,6 +954,11 @@
+
+
+
+
+
@@ -1217,7 +1238,6 @@
-
@@ -1454,7 +1474,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0x01482874 - current race
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ vector
+ vector
+
+
+ YES
+
+
+
+
+
+ NO!
+
+ YES
+ YES
+ YES
+ YES
+
+ YES
+ MAYBE
+ YES
+
+ YES
+
+
+
+
+ YES
+
+
+
+
+
+
+
+
+ this is crap it seems
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 31.13 WEATHER_START 0147E94E
.-"""-.
' \
|,. ,-. | _________________________
@@ -1693,6 +1870,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CHMOD
+
+
+
+
@@ -1731,6 +1926,9 @@
+
+
+
@@ -1747,6 +1945,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/DFProcess-linux-wine.cpp b/library/DFProcess-linux-wine.cpp
index 489118d5b..f92d4b5cd 100644
--- a/library/DFProcess-linux-wine.cpp
+++ b/library/DFProcess-linux-wine.cpp
@@ -53,6 +53,9 @@ class WineProcess::Private
bool attached;
bool suspended;
bool identified;
+ uint32_t STLSTR_buf_off;
+ uint32_t STLSTR_size_off;
+ uint32_t STLSTR_cap_off;
bool validate(char * exe_file, uint32_t pid, char * mem_file, vector
& known_versions);
};
@@ -155,6 +158,10 @@ bool WineProcess::Private::validate(char* exe_file, uint32_t pid, char* mem_file
// tell WineProcess about the /proc/PID/mem file
memFile = mem_file;
identified = true;
+ OffsetGroup * strGrp = m->getGroup("string")->getGroup("MSVC");
+ STLSTR_buf_off = strGrp->getOffset("buffer");
+ STLSTR_size_off = strGrp->getOffset("size");
+ STLSTR_cap_off = strGrp->getOffset("capacity");
return true;
}
}
@@ -563,21 +570,10 @@ const std::string WineProcess::readCString (uint32_t offset)
size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
{
- /*
- MSVC++ string
- ptr allocator
- union
- {
- char[16] start;
- char * start_ptr
- }
- Uint32 length
- Uint32 capacity
- */
- uint32_t start_offset = offset + 4;
- size_t length = readDWord(offset + 20);
+ uint32_t start_offset = offset + d->STLSTR_buf_off;
+ size_t length = readDWord(offset + d->STLSTR_size_off);
+ size_t capacity = readDWord(offset + d->STLSTR_cap_off);
- size_t capacity = readDWord(offset + 24);
size_t read_real = min(length, bufcapacity-1);// keep space for null termination
// read data from inside the string structure
@@ -597,20 +593,10 @@ size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcap
const string WineProcess::readSTLString (uint32_t offset)
{
- /*
- MSVC++ string
- ptr allocator
- union
- {
- char[16] start;
- char * start_ptr
- }
- Uint32 length
- Uint32 capacity
- */
- uint32_t start_offset = offset + 4;
- uint32_t length = readDWord(offset + 20);
- uint32_t capacity = readDWord(offset + 24);
+ uint32_t start_offset = offset + d->STLSTR_buf_off;
+ size_t length = readDWord(offset + d->STLSTR_size_off);
+ size_t capacity = readDWord(offset + d->STLSTR_cap_off);
+
char * temp = new char[capacity+1];
// read data from inside the string structure
diff --git a/library/DFProcess-windows.cpp b/library/DFProcess-windows.cpp
index 9471116aa..5bc7bbe23 100644
--- a/library/DFProcess-windows.cpp
+++ b/library/DFProcess-windows.cpp
@@ -48,6 +48,9 @@ class NormalProcess::Private
bool attached;
bool suspended;
bool identified;
+ uint32_t STLSTR_buf_off;
+ uint32_t STLSTR_size_off;
+ uint32_t STLSTR_cap_off;
};
NormalProcess::NormalProcess(uint32_t pid, vector & known_versions)
@@ -134,7 +137,10 @@ NormalProcess::NormalProcess(uint32_t pid, vector & known_versio
vector threads;
getThreadIDs( threads );
d->my_main_thread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads[0]);
-
+ OffsetGroup * strGrp = m->getGroup("string")->getGroup("MSVC");
+ d->STLSTR_buf_off = strGrp->getOffset("buffer");
+ d->STLSTR_size_off = strGrp->getOffset("size");
+ d->STLSTR_cap_off = strGrp->getOffset("capacity");
found = true;
break; // break the iterator loop
}
@@ -430,21 +436,9 @@ const string NormalProcess::readCString (const uint32_t offset)
size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
{
- /*
- MSVC++ string
- ptr allocator
- union
- {
- char[16] start;
- char * start_ptr
-}
-Uint32 length
-Uint32 capacity
-*/
- uint32_t start_offset = offset + 4;
- size_t length = readDWord(offset + 20);
-
- size_t capacity = readDWord(offset + 24);
+ uint32_t start_offset = offset + d->STLSTR_buf_off;
+ size_t length = readDWord(offset + d->STLSTR_size_off);
+ size_t capacity = readDWord(offset + d->STLSTR_cap_off);
size_t read_real = min(length, bufcapacity-1);// keep space for null termination
// read data from inside the string structure
@@ -464,20 +458,9 @@ Uint32 capacity
const string NormalProcess::readSTLString (uint32_t offset)
{
- /*
- MSVC++ string
- ptr allocator
- union
- {
- char[16] start;
- char * start_ptr
- }
- Uint32 length
- Uint32 capacity
- */
- uint32_t start_offset = offset + 4;
- uint32_t length = readDWord(offset + 20);
- uint32_t capacity = readDWord(offset + 24);
+ uint32_t start_offset = offset + d->STLSTR_buf_off;
+ size_t length = readDWord(offset + d->STLSTR_size_off);
+ size_t capacity = readDWord(offset + d->STLSTR_cap_off);
char * temp = new char[capacity+1];
// read data from inside the string structure
diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp
index 83102648e..b9a640663 100644
--- a/library/VersionInfoFactory.cpp
+++ b/library/VersionInfoFactory.cpp
@@ -605,7 +605,7 @@ bool VersionInfoFactory::loadFile(string path_to_xml)
if(name)
{
string str_name = name;
- knownVersions[str_name] = v_descr (pMemInfo, NULL);
+ knownVersions[str_name] = v_descr (pMemInfo, (VersionInfo *) NULL);
v_sEntries.push_back(str_name);
}
}
diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp
index 2ad78361e..608e7b663 100644
--- a/library/modules/Materials.cpp
+++ b/library/modules/Materials.cpp
@@ -402,19 +402,23 @@ bool Materials::ReadCreatureTypesEx (void)
p->readSTLString (caste_start + sizeof_string, caste.singular, sizeof(caste.singular));
p->readSTLString (caste_start + 2 * sizeof_string, caste.plural, sizeof(caste.plural));
p->readSTLString (caste_start + 3 * sizeof_string, caste.adjective, sizeof(caste.adjective));
+ cout << "Caste " << caste.rawname << " " << caste.singular << ": 0x" << hex << caste_start << endl;
if(have_advanced)
{
/* color mod reading */
+ // Caste + offset > color mod vector
DfVector p_colormod(p, caste_start + caste_colormod_offset);
sizecolormod = p_colormod.size();
caste.ColorModifier.resize(sizecolormod);
for(uint32_t k = 0; k < sizecolormod;k++)
{
+ // color mod [0] -> color list
DfVector p_colorlist(p, p_colormod[k]);
sizecolorlist = p_colorlist.size();
caste.ColorModifier[k].colorlist.resize(sizecolorlist);
for(uint32_t l = 0; l < sizecolorlist; l++)
caste.ColorModifier[k].colorlist[l] = p_colorlist[l];
+ // color mod [color_modifier_part_offset] = string part
p->readSTLString( p_colormod[k] + color_modifier_part_offset, caste.ColorModifier[k].part, sizeof(caste.ColorModifier[k].part));
caste.ColorModifier[k].startdate = p->readDWord( p_colormod[k] + color_modifier_startdate_offset );
caste.ColorModifier[k].enddate = p->readDWord( p_colormod[k] + color_modifier_enddate_offset );
diff --git a/library/modules/World.cpp b/library/modules/World.cpp
index 009b696ac..3e1a670de 100644
--- a/library/modules/World.cpp
+++ b/library/modules/World.cpp
@@ -133,12 +133,22 @@ uint32_t World::ReadCurrentDay()
uint8_t World::ReadCurrentWeather()
{
if (d->Inited && d->StartedWeather)
- return(d->owner->readByte(d->weather_offset));
+ return(d->owner->readByte(d->weather_offset + 12));
return 0;
}
-
+/*
void World::SetCurrentWeather(uint8_t weather)
{
if (d->Inited && d->StartedWeather)
d->owner->writeByte(d->weather_offset,weather);
}
+*/
+void World::SetCurrentWeather(uint8_t weather)
+{
+ if (d->Inited && d->StartedWeather)
+ {
+ uint8_t buf[25];
+ memset(&buf,weather, sizeof(buf));
+ d->owner->write(d->weather_offset,sizeof(buf),buf);
+ }
+}
diff --git a/tools/examples/creaturedump.cpp b/tools/examples/creaturedump.cpp
index eb611eefe..dddd6e018 100644
--- a/tools/examples/creaturedump.cpp
+++ b/tools/examples/creaturedump.cpp
@@ -134,7 +134,7 @@ likeType printLike40d(DFHack::t_like like, const matGlosses & mat,const vector<
void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature)
{
uint32_t dayoflife;
- cout << "address: " << hex << creature.origin << dec << " creature type: " << Materials->raceEx[creature.race].rawname
+ cout << "address: " << hex << creature.origin << dec << ", creature race: " << creature.race << "/" << Materials->raceEx[creature.race].rawname
<< "[" << Materials->raceEx[creature.race].tile_character
<< "," << Materials->raceEx[creature.race].tilecolor.fore
<< "," << Materials->raceEx[creature.race].tilecolor.back
@@ -172,7 +172,7 @@ void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature)
if(creature.civ)
{
- cout << "civilization: " << creature.civ;
+ cout << ", civilization: " << creature.civ;
addendl = true;
}
@@ -191,7 +191,7 @@ void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature)
cout << endl;
addendl = false;
}
- cout << "profession: " << mem->getProfession(creature.profession) << "(" << (int) creature.profession << ")";
+ cout << ", profession: " << mem->getProfession(creature.profession) << "(" << (int) creature.profession << ")";
if(creature.custom_profession[0])
{
diff --git a/tools/playground/SegmentedFinder.h b/tools/playground/SegmentedFinder.h
index c50cc4c6f..98de87711 100644
--- a/tools/playground/SegmentedFinder.h
+++ b/tools/playground/SegmentedFinder.h
@@ -311,4 +311,11 @@ bool findString (SegmentedFinder* s, uint32_t *addr, const char * compare )
return false;
}
+bool findStrBuffer (SegmentedFinder* s, uint32_t *addr, const char * compare )
+{
+ if(strcmp((const char *)addr, compare) == 0)
+ return true;
+ return false;
+}
+
#endif // SEGMENTED_FINDER_H
\ No newline at end of file
diff --git a/tools/playground/incrementalsearch.cpp b/tools/playground/incrementalsearch.cpp
index 68ce20014..918577944 100644
--- a/tools/playground/incrementalsearch.cpp
+++ b/tools/playground/incrementalsearch.cpp
@@ -482,6 +482,22 @@ void FindPtrVectorsByObjectAddress(DFHack::ContextManager & DFMgr, vector & ranges)
+{
+ vector found;
+ string select;
+ while (Incremental(found,"buffer",select,"buffer","buffers"))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ SegmentedFinder sf(ranges,DF);
+ sf.Find< const char * ,uint32_t>(select.c_str(),1,found, findStrBuffer);
+ DF->Detach();
+ }
+}
+
+
void FindStrings(DFHack::ContextManager & DFMgr, vector & ranges)
{
@@ -799,12 +815,13 @@ int main (void)
string prompt =
"Select search type: 1=number(default), 2=vector by length, 3=vector>object>string,\n"
" 4=string, 5=automated offset search, 6=vector by address in its array,\n"
- " 7=pointer vector by address of an object, 8=vector>first object>string\n";
+ " 7=pointer vector by address of an object, 8=vector>first object>string\n"
+ " 9=string buffers\n";
int mode;
do
{
getNumber(prompt,mode, 1, false);
- } while (mode < 1 || mode > 8 );
+ } while (mode < 1 || mode > 9 );
switch (mode)
{
case 1:
@@ -838,6 +855,10 @@ int main (void)
DF->Detach();
FindVectorByFirstObjectRawname(DFMgr, selected_ranges);
break;
+ case 9:
+ DF->Detach();
+ FindStrBufs(DFMgr, selected_ranges);
+ break;
default:
cout << "not implemented :(" << endl;
}
diff --git a/tools/supported/reveal.cpp b/tools/supported/reveal.cpp
index 2c82075f7..e2a1579b2 100644
--- a/tools/supported/reveal.cpp
+++ b/tools/supported/reveal.cpp
@@ -8,6 +8,20 @@ using namespace std;
#include
#include
+#ifdef LINUX_BUILD
+#include
+void waitmsec (int delay)
+{
+ usleep(delay);
+}
+#else
+#include
+void waitmsec (int delay)
+{
+ Sleep(delay);
+}
+#endif
+
struct hideblock
{
uint32_t x;
@@ -48,7 +62,7 @@ int main (void)
// this here hack sets the pause state, resumes DF, waits a second for it to enter the pause (I know, BS value.) and suspends.
Gui->SetPauseState(true);
DF->Resume();
- sleep(1);
+ waitmsec(1000);
DF->Suspend();
// init the map