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;
}
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);
@ -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
full_barrier
d->SetAndWait(CORE_WRITE_STL_STRING);
return writeString.length();
}

@ -220,7 +220,7 @@ void LinuxProcessBase::writeByte (uint32_t offset, uint8_t data)
#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)
{
uint32_t indexptr = 0;

@ -71,7 +71,7 @@ namespace {
void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
const std::string readSTLString (uint32_t offset);
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
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);
}
size_t WineProcess::writeSTLString(const uint32_t address, const std::string writeString)
{
return stl.writeSTLString(address,writeString);
}
const string WineProcess::readSTLString (uint32_t offset)
{
return stl.readSTLString(offset);

@ -65,8 +65,8 @@ namespace {
void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){};
void copySTLString(const uint32_t address, const uint32_t target);
size_t writeSTLString(const uint32_t address, const std::string writeString);
size_t copySTLString(const uint32_t address, const uint32_t target);
// get class name of an object with rtti/type info
std::string readClassName(uint32_t vptr);
};
@ -126,9 +126,9 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * known_versions)
struct _Rep_base
{
uint32_t _M_length;
uint32_t _M_capacity;
uint32_t _M_refcount;
uint32_t _M_length; // length of text stored, not including zero termination
uint32_t _M_capacity; // capacity, not including zero termination
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)
@ -141,6 +141,27 @@ size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufc
buffer[read_real] = 0;
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)
{
@ -162,7 +183,7 @@ const string NormalProcess::readSTLString (uint32_t offset)
return ret;
}
void NormalProcess::copySTLString (uint32_t offset, uint32_t target)
size_t NormalProcess::copySTLString (uint32_t offset, uint32_t target)
{
_Rep_base header;
@ -170,7 +191,7 @@ void NormalProcess::copySTLString (uint32_t offset, uint32_t target)
uint32_t old_target = Process::readDWord(target);
if (offset == old_target)
return;
return 0;
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);
writeDWord(target, offset);
return header._M_length;
}
string NormalProcess::readClassName (uint32_t vptr)

@ -100,3 +100,8 @@ string MicrosoftSTL::readClassName (uint32_t vptr)
raw.resize(raw.length() - 2);// trim @@ from end
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;
/// read an STL string
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;
/// share the string at source with target; may leak target
virtual void copySTLString(const uint32_t address, const uint32_t target) {
writeSTLString(target, readSTLString(address));
/**
* write an STL string
* @return length written
*/
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
virtual void readSTLVector(const uint32_t address, t_vecTriplet & triplet) = 0;
/// get class name of an object with rtti/type info

@ -39,7 +39,7 @@ namespace DFHack {
const std::string readSTLString (uint32_t offset);
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
std::string readClassName(uint32_t vptr);
};

@ -70,7 +70,7 @@ namespace DFHack
const std::string readSTLString (uint32_t offset);
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);
// 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)
DFHACK_TOOL(dfdigpattern digpattern.cpp)
DFHACK_TOOL(dfcleanowned cleanowned.cpp)
DFHACK_TOOL(dffixbug-3708 fix-3708.cpp)
# this needs the C bindings

@ -157,13 +157,13 @@ int main (int numargs, char ** args)
if (goblins.size() >= ghosts.size() && ghosts.size() > 0)
{
DFHack::OffsetGroup *ogf = mem->getGroup("Legends")->getGroup("figures");
uint32_t f_vector = p->readDWord(ogf->getAddress("vector"));
uint32_t f_id = ogf->getOffset("figure_id");
uint32_t f_unit = ogf->getOffset("unit_id");
uint32_t f_name = ogf->getOffset("name");
uint32_t f_race = ogf->getOffset("race");
uint32_t f_profession = ogf->getOffset("profession");
DFHack::OffsetGroup *grp_figures = mem->getGroup("Legends")->getGroup("figures");
uint32_t f_vector = p->readDWord(grp_figures->getAddress("vector"));
uint32_t f_id = grp_figures->getOffset("figure_id");
uint32_t f_unit = grp_figures->getOffset("unit_id");
uint32_t f_name = grp_figures->getOffset("name");
uint32_t f_race = grp_figures->getOffset("race");
uint32_t f_profession = grp_figures->getOffset("profession");
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
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
DFHACK_TOOL(dfunstuck unstuck.cpp)

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