Big messy commit...

develop
Petr Mrázek 2011-04-20 01:28:47 +02:00
parent bc855b296f
commit 66bb9d448c
14 changed files with 117 additions and 70 deletions

@ -476,7 +476,7 @@ size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapa
return fit; return fit;
} }
void SHMProcess::writeSTLString(const uint32_t address, const std::string writeString) size_t SHMProcess::writeSTLString(const uint32_t address, const std::string writeString)
{ {
if(!d->locked) throw Error::MemoryAccessDenied(address); if(!d->locked) throw Error::MemoryAccessDenied(address);
@ -484,4 +484,5 @@ void SHMProcess::writeSTLString(const uint32_t address, const std::string writeS
strncpy(D_SHMDATA(char),writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator strncpy(D_SHMDATA(char),writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator
full_barrier full_barrier
d->SetAndWait(CORE_WRITE_STL_STRING); d->SetAndWait(CORE_WRITE_STL_STRING);
return writeString.length();
} }

@ -220,7 +220,7 @@ void LinuxProcessBase::writeByte (uint32_t offset, uint8_t data)
#endif #endif
} }
// blah. I hate the kernel devs for crippling /proc/PID/mem. THIS IS RIDICULOUS // blah. THIS IS RIDICULOUS
void LinuxProcessBase::write (uint32_t offset, uint32_t size, uint8_t *source) void LinuxProcessBase::write (uint32_t offset, uint32_t size, uint8_t *source)
{ {
uint32_t indexptr = 0; uint32_t indexptr = 0;

@ -71,7 +71,7 @@ namespace {
void readSTLVector(const uint32_t address, t_vecTriplet & triplet); void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
const std::string readSTLString (uint32_t offset); const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){}; size_t writeSTLString(const uint32_t address, const std::string writeString);
// get class name of an object with rtti/type info // get class name of an object with rtti/type info
std::string readClassName(uint32_t vptr); std::string readClassName(uint32_t vptr);
}; };
@ -157,6 +157,12 @@ size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcap
return stl.readSTLString(offset, buffer, bufcapacity); return stl.readSTLString(offset, buffer, bufcapacity);
} }
size_t WineProcess::writeSTLString(const uint32_t address, const std::string writeString)
{
return stl.writeSTLString(address,writeString);
}
const string WineProcess::readSTLString (uint32_t offset) const string WineProcess::readSTLString (uint32_t offset)
{ {
return stl.readSTLString(offset); return stl.readSTLString(offset);

@ -65,8 +65,8 @@ namespace {
void readSTLVector(const uint32_t address, t_vecTriplet & triplet); void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
const std::string readSTLString (uint32_t offset); const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){}; size_t writeSTLString(const uint32_t address, const std::string writeString);
void copySTLString(const uint32_t address, const uint32_t target); size_t copySTLString(const uint32_t address, const uint32_t target);
// get class name of an object with rtti/type info // get class name of an object with rtti/type info
std::string readClassName(uint32_t vptr); std::string readClassName(uint32_t vptr);
}; };
@ -126,9 +126,9 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * known_versions)
struct _Rep_base struct _Rep_base
{ {
uint32_t _M_length; uint32_t _M_length; // length of text stored, not including zero termination
uint32_t _M_capacity; uint32_t _M_capacity; // capacity, not including zero termination
uint32_t _M_refcount; uint32_t _M_refcount; // reference count (two STL strings can share a common buffer, copy on write rules apply)
}; };
size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
@ -141,6 +141,27 @@ size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufc
buffer[read_real] = 0; buffer[read_real] = 0;
return read_real; return read_real;
} }
//void LinuxProcessBase::write (uint32_t offset, uint32_t size, uint8_t *source)
size_t NormalProcess::writeSTLString(const uint32_t address, const std::string writeString)
{
_Rep_base header;
// get buffer location
uint32_t start = Process::readDWord(address);
// read the header
read(start - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header);
// the buffer has actual size = 1. no space for storing anything more than a zero byte
if(header._M_capacity == 0)
return 0;
// get writeable length (lesser of our string length and capacity of the target)
uint32_t lstr = writeString.length();
uint32_t allowed_copy = min(lstr, header._M_capacity);
// write string, add a zero terminator, return bytes written
write(start, allowed_copy, (uint8_t *) writeString.c_str());
writeByte(start + allowed_copy, 0);
return allowed_copy;
}
void NormalProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet) void NormalProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet)
{ {
@ -162,7 +183,7 @@ const string NormalProcess::readSTLString (uint32_t offset)
return ret; return ret;
} }
void NormalProcess::copySTLString (uint32_t offset, uint32_t target) size_t NormalProcess::copySTLString (uint32_t offset, uint32_t target)
{ {
_Rep_base header; _Rep_base header;
@ -170,7 +191,7 @@ void NormalProcess::copySTLString (uint32_t offset, uint32_t target)
uint32_t old_target = Process::readDWord(target); uint32_t old_target = Process::readDWord(target);
if (offset == old_target) if (offset == old_target)
return; return 0;
read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header);
@ -183,6 +204,7 @@ void NormalProcess::copySTLString (uint32_t offset, uint32_t target)
write(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); write(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header);
writeDWord(target, offset); writeDWord(target, offset);
return header._M_length;
} }
string NormalProcess::readClassName (uint32_t vptr) string NormalProcess::readClassName (uint32_t vptr)

@ -100,3 +100,8 @@ string MicrosoftSTL::readClassName (uint32_t vptr)
raw.resize(raw.length() - 2);// trim @@ from end raw.resize(raw.length() - 2);// trim @@ from end
return raw; return raw;
} }
size_t MicrosoftSTL::writeSTLString(const uint32_t address, const std::string writeString)
{
return 0;
}

@ -161,12 +161,20 @@ namespace DFHack
virtual const std::string readSTLString (uint32_t offset) = 0; virtual const std::string readSTLString (uint32_t offset) = 0;
/// read an STL string /// 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; * write an STL string
/// share the string at source with target; may leak target * @return length written
virtual void copySTLString(const uint32_t address, const uint32_t target) { */
writeSTLString(target, readSTLString(address)); virtual size_t writeSTLString(const uint32_t address, const std::string writeString) = 0;
/**
* attempt to copy a string from source address to target address. may truncate or leak, depending on platform
* @return length copied
*/
virtual size_t copySTLString(const uint32_t address, const uint32_t target)
{
return writeSTLString(target, readSTLString(address));
} }
/// read a STL vector /// read a STL vector
virtual void readSTLVector(const uint32_t address, t_vecTriplet & triplet) = 0; virtual void readSTLVector(const uint32_t address, t_vecTriplet & triplet) = 0;
/// get class name of an object with rtti/type info /// get class name of an object with rtti/type info

@ -39,7 +39,7 @@ namespace DFHack {
const std::string readSTLString (uint32_t offset); const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){}; size_t writeSTLString(const uint32_t address, const std::string writeString);
// get class name of an object with rtti/type info // get class name of an object with rtti/type info
std::string readClassName(uint32_t vptr); std::string readClassName(uint32_t vptr);
}; };

@ -70,7 +70,7 @@ namespace DFHack
const std::string readSTLString (uint32_t offset); const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString); size_t writeSTLString(const uint32_t address, const std::string writeString);
void readSTLVector(const uint32_t address, t_vecTriplet & triplet); void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
// get class name of an object with rtti/type info // get class name of an object with rtti/type info

@ -92,8 +92,6 @@ DFHACK_TOOL(dfcreature creature.cpp)
# Dig a specific pattern (in this case 3x3 bedrooms, modify as you like) # Dig a specific pattern (in this case 3x3 bedrooms, modify as you like)
DFHACK_TOOL(dfdigpattern digpattern.cpp) DFHACK_TOOL(dfdigpattern digpattern.cpp)
DFHACK_TOOL(dfcleanowned cleanowned.cpp)
DFHACK_TOOL(dffixbug-3708 fix-3708.cpp) DFHACK_TOOL(dffixbug-3708 fix-3708.cpp)
# this needs the C bindings # this needs the C bindings

@ -157,13 +157,13 @@ int main (int numargs, char ** args)
if (goblins.size() >= ghosts.size() && ghosts.size() > 0) if (goblins.size() >= ghosts.size() && ghosts.size() > 0)
{ {
DFHack::OffsetGroup *ogf = mem->getGroup("Legends")->getGroup("figures"); DFHack::OffsetGroup *grp_figures = mem->getGroup("Legends")->getGroup("figures");
uint32_t f_vector = p->readDWord(ogf->getAddress("vector")); uint32_t f_vector = p->readDWord(grp_figures->getAddress("vector"));
uint32_t f_id = ogf->getOffset("figure_id"); uint32_t f_id = grp_figures->getOffset("figure_id");
uint32_t f_unit = ogf->getOffset("unit_id"); uint32_t f_unit = grp_figures->getOffset("unit_id");
uint32_t f_name = ogf->getOffset("name"); uint32_t f_name = grp_figures->getOffset("name");
uint32_t f_race = ogf->getOffset("race"); uint32_t f_race = grp_figures->getOffset("race");
uint32_t f_profession = ogf->getOffset("profession"); uint32_t f_profession = grp_figures->getOffset("profession");
for (std::list<uint32_t>::iterator it = ghosts.begin(); it != ghosts.end(); ++it) for (std::list<uint32_t>::iterator it = ghosts.begin(); it != ghosts.end(); ++it)
{ {

@ -38,6 +38,9 @@ ENDIF()
# cleanmap - removes mud, snow, blood and similar stuff from a map. farmers beware # cleanmap - removes mud, snow, blood and similar stuff from a map. farmers beware
DFHACK_TOOL(dfcleanmap cleanmap.cpp) DFHACK_TOOL(dfcleanmap cleanmap.cpp)
# cleanowned - confiscate items owned by dwarves so they can be atomsmashed/reused/etc.
DFHACK_TOOL(dfcleanowned cleanowned.cpp)
# unstuck - make DF run if something goes wrong with the 'normal' memory access method # unstuck - make DF run if something goes wrong with the 'normal' memory access method
DFHACK_TOOL(dfunstuck unstuck.cpp) DFHACK_TOOL(dfunstuck unstuck.cpp)

@ -19,7 +19,7 @@ using namespace std;
#include <DFHack.h> #include <DFHack.h>
#include <dfhack/DFTileTypes.h> #include <dfhack/DFTileTypes.h>
template<template <typename> class P = std::less > template<template <typename> class P = std::greater >
struct compare_pair_first struct compare_pair_first
{ {
template<class T1, class T2> template<class T1, class T2>
@ -29,7 +29,7 @@ struct compare_pair_first
} }
}; };
template<template <typename> class P = std::less > template<template <typename> class P = std::greater >
struct compare_pair_second struct compare_pair_second
{ {
template<class T1, class T2> template<class T1, class T2>
@ -42,7 +42,6 @@ struct compare_pair_second
int main (int argc, const char* argv[]) int main (int argc, const char* argv[])
{ {
bool showhidden = false; bool showhidden = false;
bool showbaselayers = false;
for(int i = 1; i < argc; i++) for(int i = 1; i < argc; i++)
{ {
string test = argv[i]; string test = argv[i];
@ -50,20 +49,14 @@ int main (int argc, const char* argv[])
{ {
showhidden = true; showhidden = true;
} }
else if(test == "-b") else if(test == "--help")
{ {
showbaselayers = true; cout << "This is a prospector tool for the game Dwarf Fortress." << endl
} << "By default, only visible tiles are counted." << endl
else if(test == "-ab" || test == "-ba") << "Use the parameter '-a' to scan all tiles." << endl;
{ return 0;
showhidden = true;
showbaselayers = true;
} }
} }
// let's be more useful when double-clicked on windows
#ifndef LINUX_BUILD
showhidden = true;
#endif
uint32_t x_max,y_max,z_max; uint32_t x_max,y_max,z_max;
DFHack::mapblock40d Block; DFHack::mapblock40d Block;
@ -135,7 +128,7 @@ int main (int argc, const char* argv[])
} }
// get region geology // get region geology
if(showbaselayers && !Maps->ReadGeology( layerassign )) if(!Maps->ReadGeology( layerassign ))
{ {
cerr << "Can't get region geology." << endl; cerr << "Can't get region geology." << endl;
#ifndef LINUX_BUILD #ifndef LINUX_BUILD
@ -170,6 +163,8 @@ int main (int argc, const char* argv[])
DFHack::TileMaterial mat = DFHack::tileMaterial(tt[xx][yy]); DFHack::TileMaterial mat = DFHack::tileMaterial(tt[xx][yy]);
if(!DFHack::isWallTerrain(tt[xx][yy])) if(!DFHack::isWallTerrain(tt[xx][yy]))
continue; continue;
if(Block.designation[xx][yy].bits.hidden && !showhidden)
continue;
if(hardcoded_m.count(mat)) if(hardcoded_m.count(mat))
{ {
hardcoded_m[mat] += 1; hardcoded_m[mat] += 1;
@ -181,37 +176,35 @@ int main (int argc, const char* argv[])
} }
} }
// layer stone and soil // get the layer materials
if(showbaselayers) for(uint32_t xx = 0;xx<16;xx++)
{ {
// get the layer materials for (uint32_t yy = 0; yy< 16;yy++)
for(uint32_t xx = 0;xx<16;xx++)
{ {
for (uint32_t yy = 0; yy< 16;yy++) DFHack::TileMaterial mat = DFHack::tileMaterial(tt[xx][yy]);
DFHack::TileShape shape = DFHack::TileShape(tt[xx][yy]);
if(mat != DFHack::SOIL && mat != DFHack::STONE)
continue;
if(!DFHack::isWallTerrain(tt[xx][yy]))
continue;
if(Block.designation[xx][yy].bits.hidden && !showhidden)
continue;
uint8_t test = Block.designation[xx][yy].bits.biome;
if(test > maximum_regionoffset)
maximum_regionoffset = test;
if( test >= sizeof(Block.biome_indices))
{ {
DFHack::TileMaterial mat = DFHack::tileMaterial(tt[xx][yy]); num_overflows++;
DFHack::TileShape shape = DFHack::TileShape(tt[xx][yy]); continue;
if(mat != DFHack::SOIL && mat != DFHack::STONE) }
continue; uint16_t mat2 = layerassign [Block.biome_indices[test]] [Block.designation[xx][yy].bits.geolayer_index];
if(!DFHack::isWallTerrain(tt[xx][yy])) if(layer_m.count(mat2))
continue; {
uint8_t test = Block.designation[xx][yy].bits.biome; layer_m[mat2] += 1;
if(test > maximum_regionoffset) }
maximum_regionoffset = test; else
if( test >= sizeof(Block.biome_indices)) {
{ layer_m[mat2] = 1;
num_overflows++;
continue;
}
uint16_t mat2 = layerassign [Block.biome_indices[test]] [Block.designation[xx][yy].bits.geolayer_index];
if(layer_m.count(mat2))
{
layer_m[mat2] += 1;
}
else
{
layer_m[mat2] = 1;
}
} }
} }
} }
@ -223,6 +216,8 @@ int main (int argc, const char* argv[])
{ {
if(!DFHack::isWallTerrain(tt[xi][yi])) if(!DFHack::isWallTerrain(tt[xi][yi]))
continue; continue;
if(Block.designation[xi][yi].bits.hidden && !showhidden)
continue;
DFHack::TileMaterial mat = DFHack::tileMaterial(tt[xi][yi]); DFHack::TileMaterial mat = DFHack::tileMaterial(tt[xi][yi]);
if(Block.designation[xi][yi].bits.feature_global && mat == DFHack::FEATSTONE) if(Block.designation[xi][yi].bits.feature_global && mat == DFHack::FEATSTONE)
{ {
@ -355,6 +350,7 @@ int main (int argc, const char* argv[])
} }
// LAYERS // LAYERS
cout << endl << "Layer materials:" << endl; cout << endl << "Layer materials:" << endl;
uint32_t layers_total = 0;
for(p = layer_m.begin(); p != layer_m.end(); p++) for(p = layer_m.begin(); p != layer_m.end(); p++)
{ {
if(p->first == -1) if(p->first == -1)
@ -364,6 +360,7 @@ int main (int argc, const char* argv[])
else else
{ {
layers_sort.push_back( pair<int16_t,uint32_t>(p->first, p->second) ); layers_sort.push_back( pair<int16_t,uint32_t>(p->first, p->second) );
layers_total += p->second;
} }
} }
std::sort(layers_sort.begin(), layers_sort.end(), compare_pair_second<>()); std::sort(layers_sort.begin(), layers_sort.end(), compare_pair_second<>());
@ -376,7 +373,9 @@ int main (int argc, const char* argv[])
} }
cout << Mats->inorganic[layers_sort[i].first].id << " : " << layers_sort[i].second << endl; cout << Mats->inorganic[layers_sort[i].first].id << " : " << layers_sort[i].second << endl;
} }
cout << ">>> TOTAL = " << layers_total << endl;
// VEINS // VEINS
uint32_t veins_total = 0;
cout << endl << "Vein materials:" << endl; cout << endl << "Vein materials:" << endl;
for(p = vein_m.begin(); p != vein_m.end(); p++) for(p = vein_m.begin(); p != vein_m.end(); p++)
{ {
@ -387,6 +386,7 @@ int main (int argc, const char* argv[])
else else
{ {
veins_sort.push_back( pair<int16_t,uint32_t>(p->first, p->second) ); veins_sort.push_back( pair<int16_t,uint32_t>(p->first, p->second) );
veins_total += p->second;
} }
} }
std::sort(veins_sort.begin(), veins_sort.end(), compare_pair_second<>()); std::sort(veins_sort.begin(), veins_sort.end(), compare_pair_second<>());
@ -399,11 +399,14 @@ int main (int argc, const char* argv[])
} }
cout << Mats->inorganic[veins_sort[i].first].id << " : " << veins_sort[i].second << endl; cout << Mats->inorganic[veins_sort[i].first].id << " : " << veins_sort[i].second << endl;
} }
cout << ">>> TOTAL = " << veins_total << endl;
DF->Detach(); DF->Detach();
cout << endl << "Happy mining!";
#ifndef LINUX_BUILD #ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl; cout << " Press any key to finish.";
cin.ignore(); cin.ignore();
#endif #endif
cout << endl;
return 0; return 0;
} }