Fix accessor mess I made. Added Accessor description dump to the dfitemdump tool and Items module.

develop
Petr Mrázek 2011-04-14 01:42:03 +02:00
parent 2aad508d2b
commit 1a8c27ce01
5 changed files with 164 additions and 42 deletions

@ -1769,6 +1769,7 @@
<Group name="job"> <Group name="job">
<Offset name="id" value="0x08" /> <Offset name="id" value="0x08" />
<Offset name="type" value="0x40" />
</Group> </Group>
</Group> </Group>
<Group name="Vegetation"> <Group name="Vegetation">
@ -1961,6 +1962,7 @@
</Group> </Group>
<Group name="job" valid="false"> <Group name="job" valid="false">
<Offset name="id" valid="true" /> <Offset name="id" valid="true" />
<Offset name="type" valid="true" />
</Group> </Group>
</Group> </Group>
<Group name="Maps" valid="true"> <Group name="Maps" valid="true">

@ -125,6 +125,8 @@ public:
bool writeItem(const dfh_item & item); bool writeItem(const dfh_item & item);
/// who owns this item we already read? /// who owns this item we already read?
int32_t getItemOwnerID(const dfh_item & item); int32_t getItemOwnerID(const dfh_item & item);
/// dump offsets used by accessors to a string
std::string dumpAccessors(const dfh_item & item);
private: private:
class Private; class Private;
Private* d; Private* d;

@ -25,6 +25,7 @@ distribution.
#include "Internal.h" #include "Internal.h"
#include <string> #include <string>
#include <sstream>
#include <vector> #include <vector>
#include <cstdio> #include <cstdio>
#include <map> #include <map>
@ -64,9 +65,11 @@ private:
int32_t offset2; int32_t offset2;
Process * p; Process * p;
DataWidth dataWidth; DataWidth dataWidth;
uint32_t method;
public: public:
Accessor(uint32_t function, Process * p); Accessor(uint32_t function, Process * p);
Accessor(accessor_type type, int32_t constant, uint32_t offset1, uint32_t offset2, uint32_t dataWidth, Process * p); Accessor(accessor_type type, int32_t constant, uint32_t offset1, uint32_t offset2, uint32_t dataWidth, Process * p);
std::string dump();
int32_t getValue(uint32_t objectPtr); int32_t getValue(uint32_t objectPtr);
bool isConstant(); bool isConstant();
}; };
@ -96,6 +99,7 @@ private:
public: public:
ItemDesc(uint32_t VTable, Process * p); ItemDesc(uint32_t VTable, Process * p);
bool readItem(uint32_t itemptr, dfh_item & item); bool readItem(uint32_t itemptr, dfh_item & item);
std::string dumpAccessors();
std::string className; std::string className;
uint32_t vtable; uint32_t vtable;
uint32_t mainType; uint32_t mainType;
@ -178,22 +182,22 @@ Accessor::Accessor(uint32_t function, Process *p)
this->constant = 0; this->constant = 0;
return; return;
} }
uint32_t ptr = function; method = function;
int data_reg = -1; int data_reg = -1;
uint64_t v = p->readQuad(ptr); uint64_t v = p->readQuad(method);
if (do_match(ptr, v, 2, 0xFFFF, 0xC033) || if (do_match(method, v, 2, 0xFFFF, 0xC033) ||
do_match(ptr, v, 2, 0xFFFF, 0xC031)) // XOR EAX, EAX do_match(method, v, 2, 0xFFFF, 0xC031)) // XOR EAX, EAX
{ {
data_reg = 0; data_reg = 0;
this->constant = 0; this->constant = 0;
} }
else if (do_match(ptr, v, 3, 0xFFFFFF, 0xFFC883)) // OR EAX, -1 else if (do_match(method, v, 3, 0xFFFFFF, 0xFFC883)) // OR EAX, -1
{ {
data_reg = 0; data_reg = 0;
this->constant = -1; this->constant = -1;
} }
else if (do_match(ptr, v, 5, 0xFF, 0xB8)) // MOV EAX,imm else if (do_match(method, v, 5, 0xFF, 0xB8)) // MOV EAX,imm
{ {
data_reg = 0; data_reg = 0;
this->constant = (v>>8) & 0xFFFFFFFF; this->constant = (v>>8) & 0xFFFFFFFF;
@ -204,22 +208,22 @@ Accessor::Accessor(uint32_t function, Process *p)
int ptr_reg = 1, tmp; // ECX int ptr_reg = 1, tmp; // ECX
// MOV REG,[ESP+4] // MOV REG,[ESP+4]
if (do_match(ptr, v, 4, 0xFFFFC7FFU, 0x0424448B)) if (do_match(method, v, 4, 0xFFFFC7FFU, 0x0424448B))
{ {
ptr_reg = (v>>11)&7; ptr_reg = (v>>11)&7;
v = p->readQuad(ptr); v = p->readQuad(method);
} }
if (match_MOV_MEM(ptr, v, ptr_reg, tmp, this->offset1, xsize)) { if (match_MOV_MEM(method, v, ptr_reg, tmp, this->offset1, xsize)) {
data_reg = tmp; data_reg = tmp;
this->type = ACCESSOR_INDIRECT; this->type = ACCESSOR_INDIRECT;
this->dataWidth = xsize; this->dataWidth = xsize;
if (xsize == Data32) if (xsize == Data32)
{ {
v = p->readQuad(ptr); v = p->readQuad(method);
if (match_MOV_MEM(ptr, v, data_reg, tmp, this->offset2, xsize)) { if (match_MOV_MEM(method, v, data_reg, tmp, this->offset2, xsize)) {
data_reg = tmp; data_reg = tmp;
this->type = ACCESSOR_DOUBLE_INDIRECT; this->type = ACCESSOR_DOUBLE_INDIRECT;
this->dataWidth = xsize; this->dataWidth = xsize;
@ -228,9 +232,9 @@ Accessor::Accessor(uint32_t function, Process *p)
} }
} }
v = p->readQuad(ptr); v = p->readQuad(method);
if (data_reg == 0 && do_match(ptr, v, 1, 0xFF, 0xC3)) // RET if (data_reg == 0 && do_match(method, v, 1, 0xFF, 0xC3)) // RET
return; return;
else else
{ {
@ -248,6 +252,55 @@ bool Accessor::isConstant()
return false; return false;
} }
string Accessor::dump()
{
stringstream sstr;
sstr << hex << "method @0x" << method << dec << " ";
switch(type)
{
case ACCESSOR_CONSTANT:
sstr << "Constant: " << dec << constant;
break;
case ACCESSOR_INDIRECT:
switch(dataWidth)
{
case Data32:
sstr << "int32_t ";
break;
case DataSigned16:
sstr << "int16_t ";
break;
case DataUnsigned16:
sstr << "uint16_t ";
break;
default:
sstr << "unknown ";
break;
}
sstr << hex << "[obj + 0x" << offset1 << " ]";
break;
case ACCESSOR_DOUBLE_INDIRECT:
switch(dataWidth)
{
case Data32:
sstr << "int32_t ";
break;
case DataSigned16:
sstr << "int16_t ";
break;
case DataUnsigned16:
sstr << "uint16_t ";
break;
default:
sstr << "unknown ";
break;
}
sstr << hex << "[ [obj + 0x" << offset1 << " ] + 0x" << offset2 << " ]";
break;
}
return sstr.str();
}
int32_t Accessor::getValue(uint32_t objectPtr) int32_t Accessor::getValue(uint32_t objectPtr)
{ {
int32_t offset = this->offset1; int32_t offset = this->offset1;
@ -283,8 +336,10 @@ int32_t Accessor::getValue(uint32_t objectPtr)
Accessor * buildAccessor (OffsetGroup * I, Process * p, const char * name, uint32_t vtable) Accessor * buildAccessor (OffsetGroup * I, Process * p, const char * name, uint32_t vtable)
{ {
int32_t offset; int32_t offset;
if(I->getSafeOffset("item_type_accessor",offset)) if(I->getSafeOffset(name,offset))
{
return new Accessor( p->readDWord( vtable + offset ), p); return new Accessor( p->readDWord( vtable + offset ), p);
}
else else
{ {
fprintf(stderr,"Missing offset for item accessor \"%s\"\n", name); fprintf(stderr,"Missing offset for item accessor \"%s\"\n", name);
@ -324,6 +379,19 @@ ItemDesc::ItemDesc(uint32_t VTable, Process *p)
} }
} }
string ItemDesc::dumpAccessors()
{
std::stringstream outss;
outss << "MainType :" << AMainType->dump() << endl;
outss << "ASubType :" << ASubType->dump() << endl;
outss << "ASubIndex :" << ASubIndex->dump() << endl;
outss << "AIndex :" << AIndex->dump() << endl;
outss << "AQuality :" << AQuality->dump() << endl;
outss << "AWear :" << AWear->dump() << endl;
return outss.str();
}
bool ItemDesc::readItem(uint32_t itemptr, DFHack::dfh_item &item) bool ItemDesc::readItem(uint32_t itemptr, DFHack::dfh_item &item)
{ {
p->read(itemptr, sizeof(t_item), (uint8_t*)&item.base); p->read(itemptr, sizeof(t_item), (uint8_t*)&item.base);
@ -485,19 +553,38 @@ std::string Items::getItemClass(int32_t index)
std::string Items::getItemDescription(const dfh_item & item, Materials * Materials) std::string Items::getItemDescription(const dfh_item & item, Materials * Materials)
{ {
std::string out; std::stringstream outss;
switch(item.quality) switch(item.quality)
{ {
case 0: break; case 0:
case 1: out.append("Well crafted "); break; outss << "Ordinary ";
case 2: out.append("Finely crafted "); break; break;
case 3: out.append("Superior quality "); break; case 1:
case 4: out.append("Exceptionnal "); break; outss << "Well crafted ";
case 5: out.append("Masterful "); break; break;
default: out.append("Crazy quality "); break; case 2:
outss << "Finely crafted ";
break;
case 3:
outss << "Superior quality ";
break;
case 4:
outss << "Exceptionnal ";
break;
case 5:
outss << "Masterful ";
break;
default: outss << "Crazy quality " << item.quality << " "; break;
} }
out.append(Materials->getDescription(item.matdesc)); outss << Materials->getDescription(item.matdesc) << " " << getItemClass(item.matdesc.itemType);
out.append(" "); return outss.str();
out.append(this->getItemClass(item.matdesc.itemType));
return out;
} }
/// dump offsets used by accessors of a valid item to a string
std::string Items::dumpAccessors(const dfh_item & item)
{
uint32_t vtable = item.base.vtable;
std::map< uint32_t, ItemDesc* >::const_iterator it = d->descVTable.find(vtable);
ItemDesc * desc = it->second;
return desc->dumpAccessors();
}

@ -212,12 +212,20 @@ void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature)
cout << Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].part << " "; cout << Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].part << " ";
uint32_t color = Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].colorlist[creature.color[i]]; uint32_t color = Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].colorlist[creature.color[i]];
if(color<Materials->color.size()) if(color<Materials->color.size())
{
cout << Materials->color[color].name << "[" cout << Materials->color[color].name << "["
<< (unsigned int) (Materials->color[color].r*255) << ":" << (unsigned int) (Materials->color[color].r*255) << ":"
<< (unsigned int) (Materials->color[color].v*255) << ":" << (unsigned int) (Materials->color[color].v*255) << ":"
<< (unsigned int) (Materials->color[color].b*255) << "]"; << (unsigned int) (Materials->color[color].b*255) << "]";
else }
else if (color < Materials->alldesc.size())
{
cout << Materials->alldesc[color].id; cout << Materials->alldesc[color].id;
}
else
{
cout << "Unknown color " << color << endl;
}
if( Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate > 0 ) if( Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate > 0 )
{ {
if( (Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate <= dayoflife) && if( (Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate <= dayoflife) &&
@ -467,7 +475,7 @@ int main (int numargs, char ** args)
Materials->ReadPlantMaterials(); Materials->ReadPlantMaterials();
Materials->ReadCreatureTypes(); Materials->ReadCreatureTypes();
Materials->ReadCreatureTypesEx(); Materials->ReadCreatureTypesEx();
Materials->ReadDescriptorColors(); //Materials->ReadDescriptorColors();
if(!Tran->Start()) if(!Tran->Start())
{ {

@ -10,7 +10,7 @@
#include <vector> #include <vector>
#include <cstring> #include <cstring>
using namespace std; using namespace std;
#define DFHACK_WANT_MISCUTILS
#include <DFHack.h> #include <DFHack.h>
#include <dfhack/DFVector.h> #include <dfhack/DFVector.h>
@ -35,13 +35,16 @@ int main ()
} }
DFHack::Materials * Materials = DF->getMaterials(); DFHack::Materials * Materials = DF->getMaterials();
Materials->ReadAllMaterials(); Materials->ReadAllMaterials();
DFHack::Gui * Gui = DF->getGui();
DFHack::Items * Items = DF->getItems(); DFHack::Items * Items = DF->getItems();
Items->Start(); Items->Start();
DFHack::VersionInfo * mem = DF->getMemoryInfo(); DFHack::VersionInfo * mem = DF->getMemoryInfo();
p = DF->getProcess(); p = DF->getProcess();
int32_t x,y,z;
Gui->getCursorCoords(x,y,z);
// FIXME: tools should never be exposed to DFHack internals! // FIXME: tools should never be exposed to DFHack internals!
DFHack::OffsetGroup* itemGroup = mem->getGroup("Items"); DFHack::OffsetGroup* itemGroup = mem->getGroup("Items");
DFHack::DfVector <uint32_t> p_items (p, itemGroup->getAddress("items_vector")); DFHack::DfVector <uint32_t> p_items (p, itemGroup->getAddress("items_vector"));
@ -52,15 +55,35 @@ int main ()
DFHack::dfh_item itm; DFHack::dfh_item itm;
memset(&itm, 0, sizeof(DFHack::dfh_item)); memset(&itm, 0, sizeof(DFHack::dfh_item));
Items->readItem(p_items[i],itm); Items->readItem(p_items[i],itm);
printf( if(x != -30000)
"%5d: %08x %08x (%d,%d,%d) #%08x [%d] %s - %s\n", {
i, itm.origin, itm.base.flags.whole, if(itm.base.x == x && itm.base.y == y && itm.base.z == z)
itm.base.x, itm.base.y, itm.base.z, {
itm.base.vtable, printf(
itm.wear_level, "%5d: %08x %08x (%d,%d,%d) #%08x [%d] %s - %s\n",
Items->getItemClass(itm.matdesc.itemType).c_str(), i, itm.origin, itm.base.flags.whole,
Items->getItemDescription(itm, Materials).c_str() itm.base.x, itm.base.y, itm.base.z,
); itm.base.vtable,
itm.wear_level,
Items->getItemClass(itm.matdesc.itemType).c_str(),
Items->getItemDescription(itm, Materials).c_str()
);
hexdump(DF,p_items[i],0x100);
cout << Items->dumpAccessors(itm) << endl;
}
}
else
{
printf(
"%5d: %08x %08x (%d,%d,%d) #%08x [%d] %s - %s\n",
i, itm.origin, itm.base.flags.whole,
itm.base.x, itm.base.y, itm.base.z,
itm.base.vtable,
itm.wear_level,
Items->getItemClass(itm.matdesc.itemType).c_str(),
Items->getItemDescription(itm, Materials).c_str()
);
}
} }
/* /*
printf("type\tvtable\tname\tquality\tdecorate\n"); printf("type\tvtable\tname\tquality\tdecorate\n");