From 1a8c27ce0101d32fdb61066ac579de364637975b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 14 Apr 2011 01:42:03 +0200 Subject: [PATCH] Fix accessor mess I made. Added Accessor description dump to the dfitemdump tool and Items module. --- Memory.xml | 2 + library/include/dfhack/modules/Items.h | 2 + library/modules/Items.cpp | 139 ++++++++++++++++++++----- tools/examples/creaturedump.cpp | 18 +++- tools/examples/dfitemdump.cpp | 45 ++++++-- 5 files changed, 164 insertions(+), 42 deletions(-) diff --git a/Memory.xml b/Memory.xml index bb0c78fdd..339cabcf0 100644 --- a/Memory.xml +++ b/Memory.xml @@ -1769,6 +1769,7 @@ + @@ -1961,6 +1962,7 @@ + diff --git a/library/include/dfhack/modules/Items.h b/library/include/dfhack/modules/Items.h index d0f1c3e79..a69f657e1 100644 --- a/library/include/dfhack/modules/Items.h +++ b/library/include/dfhack/modules/Items.h @@ -125,6 +125,8 @@ public: bool writeItem(const dfh_item & item); /// who owns this item we already read? int32_t getItemOwnerID(const dfh_item & item); + /// dump offsets used by accessors to a string + std::string dumpAccessors(const dfh_item & item); private: class Private; Private* d; diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 817a87a01..40d7f66b8 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -25,6 +25,7 @@ distribution. #include "Internal.h" #include +#include #include #include #include @@ -64,9 +65,11 @@ private: int32_t offset2; Process * p; DataWidth dataWidth; + uint32_t method; public: Accessor(uint32_t function, 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); bool isConstant(); }; @@ -96,6 +99,7 @@ private: public: ItemDesc(uint32_t VTable, Process * p); bool readItem(uint32_t itemptr, dfh_item & item); + std::string dumpAccessors(); std::string className; uint32_t vtable; uint32_t mainType; @@ -178,22 +182,22 @@ Accessor::Accessor(uint32_t function, Process *p) this->constant = 0; return; } - uint32_t ptr = function; + method = function; int data_reg = -1; - uint64_t v = p->readQuad(ptr); + uint64_t v = p->readQuad(method); - if (do_match(ptr, v, 2, 0xFFFF, 0xC033) || - do_match(ptr, v, 2, 0xFFFF, 0xC031)) // XOR EAX, EAX + if (do_match(method, v, 2, 0xFFFF, 0xC033) || + do_match(method, v, 2, 0xFFFF, 0xC031)) // XOR EAX, EAX { data_reg = 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; 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; this->constant = (v>>8) & 0xFFFFFFFF; @@ -204,22 +208,22 @@ Accessor::Accessor(uint32_t function, Process *p) int ptr_reg = 1, tmp; // ECX // 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; - 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; this->type = ACCESSOR_INDIRECT; this->dataWidth = xsize; 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; this->type = ACCESSOR_DOUBLE_INDIRECT; 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; else { @@ -248,6 +252,55 @@ bool Accessor::isConstant() 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 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) { int32_t offset; - if(I->getSafeOffset("item_type_accessor",offset)) + if(I->getSafeOffset(name,offset)) + { return new Accessor( p->readDWord( vtable + offset ), p); + } else { 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) { 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 out; + std::stringstream outss; switch(item.quality) { - case 0: break; - case 1: out.append("Well crafted "); break; - case 2: out.append("Finely crafted "); break; - case 3: out.append("Superior quality "); break; - case 4: out.append("Exceptionnal "); break; - case 5: out.append("Masterful "); break; - default: out.append("Crazy quality "); break; + case 0: + outss << "Ordinary "; + break; + case 1: + outss << "Well crafted "; + 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)); - out.append(" "); - out.append(this->getItemClass(item.matdesc.itemType)); - return out; + outss << Materials->getDescription(item.matdesc) << " " << getItemClass(item.matdesc.itemType); + return outss.str(); } + +/// 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(); +} \ No newline at end of file diff --git a/tools/examples/creaturedump.cpp b/tools/examples/creaturedump.cpp index e22760388..55505b152 100644 --- a/tools/examples/creaturedump.cpp +++ b/tools/examples/creaturedump.cpp @@ -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 << " "; uint32_t color = Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].colorlist[creature.color[i]]; if(colorcolor.size()) + { cout << Materials->color[color].name << "[" - << (unsigned int) (Materials->color[color].r*255) << ":" - << (unsigned int) (Materials->color[color].v*255) << ":" - << (unsigned int) (Materials->color[color].b*255) << "]"; - else + << (unsigned int) (Materials->color[color].r*255) << ":" + << (unsigned int) (Materials->color[color].v*255) << ":" + << (unsigned int) (Materials->color[color].b*255) << "]"; + } + else if (color < Materials->alldesc.size()) + { 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 <= dayoflife) && @@ -467,7 +475,7 @@ int main (int numargs, char ** args) Materials->ReadPlantMaterials(); Materials->ReadCreatureTypes(); Materials->ReadCreatureTypesEx(); - Materials->ReadDescriptorColors(); + //Materials->ReadDescriptorColors(); if(!Tran->Start()) { diff --git a/tools/examples/dfitemdump.cpp b/tools/examples/dfitemdump.cpp index 875f38b76..bbae94883 100644 --- a/tools/examples/dfitemdump.cpp +++ b/tools/examples/dfitemdump.cpp @@ -10,7 +10,7 @@ #include #include using namespace std; - +#define DFHACK_WANT_MISCUTILS #include #include @@ -35,13 +35,16 @@ int main () } DFHack::Materials * Materials = DF->getMaterials(); Materials->ReadAllMaterials(); + + DFHack::Gui * Gui = DF->getGui(); DFHack::Items * Items = DF->getItems(); Items->Start(); DFHack::VersionInfo * mem = DF->getMemoryInfo(); p = DF->getProcess(); - + int32_t x,y,z; + Gui->getCursorCoords(x,y,z); // FIXME: tools should never be exposed to DFHack internals! DFHack::OffsetGroup* itemGroup = mem->getGroup("Items"); DFHack::DfVector p_items (p, itemGroup->getAddress("items_vector")); @@ -52,15 +55,35 @@ int main () DFHack::dfh_item itm; memset(&itm, 0, sizeof(DFHack::dfh_item)); Items->readItem(p_items[i],itm); - 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() - ); + if(x != -30000) + { + if(itm.base.x == x && itm.base.y == y && itm.base.z == z) + { + 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() + ); + 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");