diff --git a/library/include/dfhack/Virtual.h b/library/include/dfhack/Virtual.h index 11d8bc78d..fc6661f97 100644 --- a/library/include/dfhack/Virtual.h +++ b/library/include/dfhack/Virtual.h @@ -27,6 +27,7 @@ distribution. namespace DFHack { /// very generic representation of a virtual class... just the pointer to the vtable. + /// this is intended for instances where wrapping the classes properly hasn't been done yet. struct t_virtual { void * vptr; diff --git a/library/include/dfhack/modules/Items.h b/library/include/dfhack/modules/Items.h index 8fa7bac56..811783bef 100644 --- a/library/include/dfhack/modules/Items.h +++ b/library/include/dfhack/modules/Items.h @@ -32,7 +32,9 @@ distribution. #include "dfhack/Export.h" #include "dfhack/Module.h" #include "dfhack/Types.h" - +#include "dfhack/Virtual.h" +#include "dfhack/modules/Materials.h" +#include "dfhack/Process.h" /** * \defgroup grp_items Items module and its types * @ingroup grp_modules @@ -97,17 +99,31 @@ union t_itemflags }; }; +/** + * Describes relationship of an item with other objects + * \ingroup grp_items + */ +struct t_itemref : public t_virtual +{ + int32_t value; +}; + /** * Basic item data, read as a single chunk * \ingroup grp_items */ -struct t_item +struct t_item : public t_virtual { - uint32_t vtable; - int16_t x; - int16_t y; - int16_t z; - t_itemflags flags; + // vptr 0x0 + 4 + int16_t x; // 0x4 + 2 + int16_t y; // 0x6 + 2 + int16_t z; // 0x8 + 2 + // 2B padding 0xA + 2 + t_itemflags flags; // 0xC + 4 + uint32_t unk1; // 0x10 + 4 + uint32_t id; // 0x14 + 4 + std::vector unk2;// usage is pretty rare + std::vector itemrefs; }; /** @@ -116,13 +132,11 @@ struct t_item */ struct dfh_item { - int32_t id; - t_item base; + t_item * base; t_material matdesc; int32_t quantity; int32_t quality; int16_t wear_level; - uint32_t origin; }; /** @@ -148,8 +162,8 @@ public: bool Start(); bool Finish(); - bool readItemVector(std::vector &items); - uint32_t findItemByID(int32_t id); + bool readItemVector(std::vector &items); + t_item * findItemByID(int32_t id); /// get a string describing an item std::string getItemDescription(const dfh_item & item, Materials * Materials); @@ -157,7 +171,7 @@ public: std::string getItemClass(int32_t index); std::string getItemClass(const dfh_item & item); /// read an item, including the extra attributes - bool readItem(uint32_t itemptr, dfh_item & item); + bool readItem(t_item * itembase, dfh_item & item); /// write item base (position and flags only = t_item part of dfh_item) bool writeItem(const dfh_item & item); /// dump offsets used by accessors to a string diff --git a/library/include/dfhack/modules/Materials.h b/library/include/dfhack/modules/Materials.h index de14f5ef4..da44f025e 100644 --- a/library/include/dfhack/modules/Materials.h +++ b/library/include/dfhack/modules/Materials.h @@ -31,6 +31,7 @@ distribution. */ #include "dfhack/Export.h" #include "dfhack/Module.h" +#include "dfhack/Types.h" namespace DFHack { class DFContextShared; diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 3b2e553c8..21b1e9f92 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -72,7 +72,7 @@ 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); + int32_t getValue(t_item * objectPtr); bool isConstant(); }; class ItemImprovementDesc @@ -101,11 +101,11 @@ private: bool hasDecoration; int idFieldOffset; public: - ItemDesc(uint32_t VTable, Process * p); - bool readItem(uint32_t itemptr, dfh_item & item); + ItemDesc(void * VTable, Process * p); + bool readItem(t_item * itemptr, dfh_item & item); std::string dumpAccessors(); std::string className; - uint32_t vtable; + void * vtable; uint32_t mainType; std::vector improvement; }; @@ -306,7 +306,7 @@ string Accessor::dump() return sstr.str(); } -int32_t Accessor::getValue(uint32_t objectPtr) +int32_t Accessor::getValue(t_item * objectPtr) { int32_t offset = this->offset1; @@ -316,18 +316,18 @@ int32_t Accessor::getValue(uint32_t objectPtr) return this->constant; break; case ACCESSOR_DOUBLE_INDIRECT: - objectPtr = p->readDWord(objectPtr + this->offset1); + objectPtr = (t_item *) p->readDWord((uint32_t)objectPtr + this->offset1); offset = this->offset2; // fallthrough case ACCESSOR_INDIRECT: switch(this->dataWidth) { case Data32: - return p->readDWord(objectPtr + offset); + return p->readDWord((uint32_t)objectPtr + offset); case DataSigned16: - return (int16_t) p->readWord(objectPtr + offset); + return (int16_t) p->readWord((uint32_t)objectPtr + offset); case DataUnsigned16: - return (uint16_t) p->readWord(objectPtr + offset); + return (uint16_t) p->readWord((uint32_t)objectPtr + offset); default: return -1; } @@ -338,12 +338,12 @@ int32_t Accessor::getValue(uint32_t objectPtr) } // FIXME: turn into a proper factory with caching -Accessor * buildAccessor (OffsetGroup * I, Process * p, const char * name, uint32_t vtable) +Accessor * buildAccessor (OffsetGroup * I, Process * p, const char * name, void * vtable) { int32_t offset; if(I->getSafeOffset(name,offset)) { - return new Accessor( p->readDWord( vtable + offset ), p); + return new Accessor( p->readDWord( (uint32_t)vtable + offset ), p); } else { @@ -352,7 +352,7 @@ Accessor * buildAccessor (OffsetGroup * I, Process * p, const char * name, uint3 } } -ItemDesc::ItemDesc(uint32_t VTable, Process *p) +ItemDesc::ItemDesc(void * VTable, Process *p) { OffsetGroup * Items = p->getDescriptor()->getGroup("Items"); @@ -400,17 +400,15 @@ string ItemDesc::dumpAccessors() } -bool ItemDesc::readItem(uint32_t itemptr, DFHack::dfh_item &item) +bool ItemDesc::readItem(t_item * itemptr, DFHack::dfh_item &item) { - item.id = p->readDWord(itemptr+idFieldOffset); - p->read(itemptr, sizeof(t_item), (uint8_t*)&item.base); + item.base = itemptr; item.matdesc.itemType = AMainType->getValue(itemptr); item.matdesc.subType = ASubType->getValue(itemptr); item.matdesc.subIndex = ASubIndex->getValue(itemptr); item.matdesc.index = AIndex->getValue(itemptr); item.quality = AQuality->getValue(itemptr); item.quantity = AQuantity->getValue(itemptr); - item.origin = itemptr; // FIXME: use templates. seriously. // Note: this accessor returns a 32-bit value with the higher // half sometimes containing garbage, so the cast is essential: @@ -424,8 +422,8 @@ class Items::Private DFContextShared *d; Process * owner; std::map descType; - std::map descVTable; - std::map idLookupTable; + std::map descVTable; + std::map idLookupTable; uint32_t refVectorOffset; uint32_t idFieldOffset; uint32_t itemVectorAddress; @@ -461,29 +459,31 @@ bool Items::Finish() return true; } -bool Items::readItemVector(std::vector &items) +bool Items::readItemVector(std::vector &items) { - DFHack::DfVector p_items(d->itemVectorAddress); + std::vector *p_items = (std::vector *) d->itemVectorAddress; d->idLookupTable.clear(); - items.resize(p_items.size()); + items.resize(p_items->size()); - for (unsigned i = 0; i < p_items.size(); i++) { - uint32_t ptr = p_items[i]; + for (unsigned i = 0; i < p_items->size(); i++) + { + t_item * ptr = p_items->at(i); items[i] = ptr; - d->idLookupTable[d->owner->readDWord(ptr + d->idFieldOffset)] = ptr; + d->idLookupTable[ptr->id] = ptr; } return true; } -uint32_t Items::findItemByID(int32_t id) +t_item * Items::findItemByID(int32_t id) { if (id < 0) return 0; - if (d->idLookupTable.empty()) { - std::vector tmp; + if (d->idLookupTable.empty()) + { + std::vector tmp; readItemVector(tmp); } @@ -493,7 +493,7 @@ uint32_t Items::findItemByID(int32_t id) Items::~Items() { Finish(); - std::map::iterator it; + std::map::iterator it; it = d->descVTable.begin(); while (it != d->descVTable.end()) { @@ -505,13 +505,13 @@ Items::~Items() delete d; } -bool Items::readItem(uint32_t itemptr, DFHack::dfh_item &item) +bool Items::readItem(t_item * itembase, DFHack::dfh_item &item) { - std::map::iterator it; + std::map::iterator it; Process * p = d->owner; ItemDesc * desc; - uint32_t vtable = p->readDWord(itemptr); + void * vtable = itembase->vptr; it = d->descVTable.find(vtable); if(it == d->descVTable.end()) { @@ -522,25 +522,9 @@ bool Items::readItem(uint32_t itemptr, DFHack::dfh_item &item) else desc = it->second; - return desc->readItem(itemptr, item); -} - -bool Items::writeItem(const DFHack::dfh_item &item) -{ - if(item.origin) - { - d->owner->write(item.origin, sizeof(t_item),(uint8_t *)&(item.base)); - return true; - } - return false; + return desc->readItem(itembase, item); } -/* -void Items::setItemFlags(uint32_t itemptr, t_itemflags new_flags) -{ - d->owner->writeDWord(itemptr + 0x0C, new_flags.whole); -} -*/ int32_t Items::getItemOwnerID(const DFHack::dfh_item &item) { std::vector vals; @@ -566,15 +550,13 @@ bool Items::getContainedItems(const DFHack::dfh_item &item, std::vector bool Items::readItemRefs(const dfh_item &item, const ClassNameCheck &classname, std::vector &values) { - DFHack::DfVector p_refs(item.origin + d->refVectorOffset); - + std::vector &p_refs = item.base->itemrefs; values.clear(); for (uint32_t i=0; iowner->readDWord(p_refs[i]); - if (classname(d->owner, (void *) vtbl)) - values.push_back(int32_t(d->owner->readDWord(p_refs[i] + 4))); + if (classname(d->owner, p_refs[i]->vptr)) + values.push_back(int32_t(p_refs[i]->value)); } return !values.empty(); @@ -582,30 +564,24 @@ bool Items::readItemRefs(const dfh_item &item, const ClassNameCheck &classname, bool Items::removeItemOwner(dfh_item &item, Creatures *creatures) { - DFHack::DfVector p_refs(item.origin + d->refVectorOffset); - + std::vector &p_refs = item.base->itemrefs; for (uint32_t i=0; iowner->readDWord(p_refs[i]); - if (!d->isOwnerRefClass(d->owner, (void *) vtbl)) continue; + if (!d->isOwnerRefClass(d->owner, p_refs[i]->vptr)) + continue; - int32_t oid = d->owner->readDWord(p_refs[i]+4); + int32_t & oid = p_refs[i]->value; int32_t ix = creatures->FindIndexById(oid); - if (ix < 0 || !creatures->RemoveOwnedItemIdx(ix, item.id)) - { - cerr << "RemoveOwnedItemIdx: CREATURE " << ix << " ID " << item.id << " FAILED!" << endl; - return false; - } - - if (!p_refs.remove(i--)) + if (ix < 0 || !creatures->RemoveOwnedItemIdx(ix, item.base->id)) { - cerr << "p_refs.remove FAILED!" << endl; + cerr << "RemoveOwnedItemIdx: CREATURE " << ix << " ID " << item.base->id << " FAILED!" << endl; return false; } + p_refs.erase(p_refs.begin() + i--); } - item.base.flags.owned = 0; + item.base->flags.owned = 0; return true; } @@ -674,7 +650,7 @@ std::string Items::getItemDescription(const dfh_item & item, Materials * Materia /// dump offsets used by accessors of a valid item to a string std::string Items::dumpAccessors(const dfh_item & item) { - std::map< uint32_t, ItemDesc* >::const_iterator it = d->descVTable.find(item.base.vtable); + std::map< void *, ItemDesc* >::const_iterator it = d->descVTable.find(item.base->vptr); if(it != d->descVTable.end()) return it->second->dumpAccessors(); return "crud"; diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 995153120..55c5b35b8 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -831,29 +831,36 @@ bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z, vector else { string cname = p->readClassName(type); + //string cname = typeid(*(blockevent *)temp).name(); + //Core::getInstance().con.printerr("%s\n",cname.c_str()); if(!off.vein_ice_vptr && cname == "block_square_event_frozen_liquidst") { off.vein_ice_vptr = type; + Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type); goto retry; } else if(!off.vein_mineral_vptr &&cname == "block_square_event_mineralst") { off.vein_mineral_vptr = type; + Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type); goto retry; } else if(!off.vein_spatter_vptr && cname == "block_square_event_material_spatterst") { off.vein_spatter_vptr = type; + Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type); goto retry; } else if(!off.vein_grass_vptr && cname=="block_square_event_grassst") { off.vein_grass_vptr = type; + Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type); goto retry; } else if(!off.vein_worldconstruction_vptr && cname=="block_square_event_world_constructionst") { off.vein_worldconstruction_vptr = type; + Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type); goto retry; } #ifdef DEBUG diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 98c70950a..917ddcb9c 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -125,3 +125,4 @@ DFHACK_PLUGIN(cleanmap cleanmap.cpp) DFHACK_PLUGIN(weather weather.cpp) DFHACK_PLUGIN(vdig vdig.cpp) DFHACK_PLUGIN(colonies colonies.cpp) +DFHACK_PLUGIN(itemhacks itemhacks.cpp) \ No newline at end of file diff --git a/plugins/itemhacks.cpp b/plugins/itemhacks.cpp new file mode 100644 index 000000000..b518dc2d2 --- /dev/null +++ b/plugins/itemhacks.cpp @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::vector; +using std::string; +using namespace DFHack; + +DFhackCExport command_result df_dumpitems (Core * c, vector & parameters); +DFhackCExport command_result df_itscanvec1 (Core * c, vector & parameters); + +DFhackCExport const char * plugin_name ( void ) +{ + return "itemhacks"; +} + +DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) +{ + commands.clear(); + commands.push_back(PluginCommand("dumpitems", "Dump items...", df_dumpitems)); + commands.push_back(PluginCommand("itscanvec1", "Dump items that have the first vector valid.", df_itscanvec1)); + return CR_OK; +} + +DFhackCExport command_result plugin_shutdown ( Core * c ) +{ + return CR_OK; +} + +DFhackCExport command_result df_itscanvec1 (Core * c, vector & parameters) +{ + c->Suspend(); + DFHack::Items * Items = c->getItems(); + Items->Start(); + std::vector p_items; + Items->readItemVector(p_items); + for(int i = 0; i < p_items.size();i++) + { + t_item * itm = p_items[i]; + if(itm->unk2.size()) + { + c->con.print("Found %x, size %d\n",itm,itm->unk2.size()); + } + } + c->Resume(); + return CR_OK; +} + +DFhackCExport command_result df_dumpitems (Core * c, vector & parameters) +{ + c->Suspend(); + bool print_hex = false; + if(parameters.size() && parameters[0] == "hex") + print_hex = true; + DFHack::Materials * Materials = c->getMaterials(); + Materials->ReadAllMaterials(); + + DFHack::Gui * Gui = c->getGui(); + + DFHack::Items * Items = c->getItems(); + Items->Start(); + + int32_t x,y,z; + Gui->getCursorCoords(x,y,z); + + std::vector p_items; + Items->readItemVector(p_items); + uint32_t size = p_items.size(); + + for(size_t i = 0; i < size; i++) + { + DFHack::dfh_item itm; + memset(&itm, 0, sizeof(DFHack::dfh_item)); + Items->readItem(p_items[i],itm); + + if (x != -30000 + && !(itm.base->x == x && itm.base->y == y && itm.base->z == z + && itm.base->flags.on_ground + && !itm.base->flags.in_chest + && !itm.base->flags.in_inventory + && !itm.base->flags.in_building)) + continue; + + c->con.print( + "%5d: addr:0x%08x %6d %08x (%d,%d,%d) vptr:0x%08x [%d] *%d %s - %s\n", + i, itm.base, itm.base->id, itm.base->flags.whole, + itm.base->x, itm.base->y, itm.base->z, + itm.base->vptr, + itm.wear_level, + itm.quantity, + Items->getItemClass(itm.matdesc.itemType).c_str(), + Items->getItemDescription(itm, Materials).c_str() + ); + /* + if (print_hex) + hexdump(DF,p_items[i],0x300); +*/ + /* + if (print_acc) + c->con << Items->dumpAccessors(itm) << endl; + */ +/* + if (print_refs) { + DFHack::DfVector p_refs(p, itm.origin + ref_vector); + for (size_t j = 0; j < p_refs.size(); j++) { + uint32_t vptr = p->readDWord(p_refs[j]); + uint32_t val = p->readDWord(p_refs[j]+4); + c->con.print("\t-> %d \t%s\n", int(val), p->readClassName(vptr).c_str()); + } + } + */ + } + c->Resume(); + return CR_OK; +} diff --git a/tools/examples/dfitemdump.cpp b/tools/examples/dfitemdump.cpp index 0c8eceddc..ed7cfcf81 100644 --- a/tools/examples/dfitemdump.cpp +++ b/tools/examples/dfitemdump.cpp @@ -113,181 +113,6 @@ int main (int argc, char *argv[]) } } } -/* - printf("type\tvtable\tname\tquality\tdecorate\n"); - for (i=0;ireadDWord(p_items[i]); - uint32_t func0 = p->readDWord(vtable); - uint64_t funct0 = p->readQuad(func0); - uint32_t func1 = p->readDWord(vtable+0x238); - uint64_t funct1 = p->readQuad(func1); - uint32_t func2 = p->readDWord(vtable+0x288); - uint64_t funct2 = p->readQuad(func2); - uint32_t type = (funct0>>8)&0xffff; - - uint32_t funcB = p->readDWord(vtable + 4); - uint32_t funcC = p->readDWord(vtable + 8); - uint32_t funcD = p->readDWord(vtable + 12); - uint64_t funcBt = p->readQuad(funcB); - uint64_t funcCt = p->readQuad(funcC); - uint64_t funcDt = p->readQuad(funcD); - int16_t typeB = -1; - int16_t typeC = -1; - int32_t typeD = -1; - uint32_t quality = 0; - bool hasDecorations; - string desc = p->readClassName(vtable); - DFHack::dfh_item itm; - - Items->readItem(p_items[i], itm); - - if ( (funct0&0xFFFFFFFFFF000000LL) != 0xCCCCC30000000000LL ) - { - if (funct0 == 0xCCCCCCCCCCC3C033LL) - type = 0; - else - printf("bad type function address=%p", (void*)func0); - } - - if (funct1 == 0xC300000092818B66LL) - quality = p->readWord(p_items[i]+0x92); - if (funct1 == 0xC300000082818B66LL) - quality = p->readWord(p_items[i]+0x82); - else if (funct1 == 0xCCCCCCCCCCC3C033LL) - quality = 0; - else - printf("bad quality function address=%p\n", (void*) func1); - - if (funct2 == 0xCCCCCCCCCCC3C032LL) - hasDecorations = false; - else if (funct2 == 0xCCCCCCCCCCC301B0LL) - hasDecorations = true; - else - printf("bad decoration function address=%p\n", (void*) func2); - - if (funcBt == 0xCCCCCCCCC3FFC883LL) - typeB = -1; - else - { - uint64_t funcBtEnd = p->readQuad(funcB+8); - if ( - ((funcBt&0xFFFFFFFF0000FFFFLL) == 0x8B6600000000818BLL) && - ((funcBtEnd&0xFFFFFFFFFFFF00FFLL) == 0xCCCCCCCCCCC30040LL) ) - { - uint32_t off1 = (funcBt>>16) & 0xffff; - uint32_t off2 = (funcBtEnd>>8) & 0xff; - uint32_t pt1 = p->readDWord(p_items[i] + off1); - typeB = p->readWord(pt1 + off2); - } - else if ((funcBt&0xFFFFFF0000FFFFFFLL)==0xC300000000818B66LL) - { - uint32_t off1 = (funcBt>>24) & 0xffff; - typeB = p->readWord(p_items[i] + off1); - } - else if ( (funcBt&0x000000FF00FFFFFFLL) == 0x000000C300418B66LL ) - { - uint32_t off1 = (funcBt>>24) & 0xff; - typeB = p->readWord(p_items[i] + off1); - } - else - printf("bad typeB func @%p\n", (void*) funcB); - } - - if (funcCt == 0xCCCCCCCCC3FFC883LL) - typeC = -1; - else if ( (funcCt&0xFFFFFF0000FFFFFFLL) == 0xC300000000818B66LL ) - { - uint32_t off1 = (funcCt>>24)&0xffff; - typeC = p->readWord(p_items[i] + off1); - } - else if ( (funcCt&0x000000FF00FFFFFFLL) == 0x000000C300418B66LL ) - { - uint32_t off1 = (funcCt>>24) & 0xff; - typeC = p->readWord(p_items[i] + off1); - } - else if ( (funcCt&0x00000000FF00FFFFLL) == 0x00000000C300418BLL ) - { - uint32_t off1 = (funcCt>>16) & 0xff; - typeC = p->readWord(p_items[i] + off1); - } - else - printf("bad typeC func @%p\n", (void*) funcC); - - if (funcDt == 0xCCCCCCCCC3FFC883LL) - typeD = -1; - else if ( (funcDt&0xFFFFFFFF0000FFFFLL) == 0xCCC300000000818BLL ) - { - uint32_t off1 = (funcDt>>16) & 0xffff; - typeD = p->readWord(p_items[i] + off1); - } - else if ( (funcDt&0xFFFFFF0000FFFFFFLL) == 0xC30000000081BF0FLL ) - { - uint32_t off1 = (funcDt>>24) & 0xffff; - typeD = p->readWord(p_items[i] + off1); - } - else if ( (funcDt&0x000000FF00FFFFFFLL) == 0x000000C30041BF0FLL ) - { - uint32_t off1 = (funcDt>>24) & 0xff; - typeD = p->readWord(p_items[i] + off1); - } - else if ( (funcDt&0x000000FF00FFFFFFLL) == 0x000000C300418B66LL ) - { - uint32_t off1 = (funcDt>>24) & 0xff; - typeD = p->readWord(p_items[i] + off1); - } - else if ( (funcDt&0x00000000FF00FFFFLL) == 0x00000000C300418BLL ) - { - uint32_t off1 = (funcDt>>16) & 0xff; - typeD = p->readDWord(p_items[i] + off1); - } - else - printf("bad typeD func @%p\n", (void*) funcD); - -// printf("%p\t%.16LX\t", (void*) func2, funct2); - printf("%d\t%p\t%s\t%d\t[%d,%d,%d]", type, (void*)vtable, desc.c_str(), quality, - typeB, typeC, typeD); - printf("\t%s", Items->getItemDescription(p_items[i], Materials).c_str()); -// printf("\t%p\t%.16LX", (void *) funcD, funcDt); - if( (type!=itm.matdesc.itemType) || (typeB!=itm.matdesc.subType) || (typeC!=itm.matdesc.subIndex) || (typeD!=itm.matdesc.index) || (quality!=itm.quality) ) - printf("\tbad[%d,%d,%d,%d]", itm.matdesc.itemType, itm.matdesc.subType, itm.matdesc.subIndex, itm.matdesc.index); - if (hasDecorations) - { - bool sep = false; - printf("\tdeco=["); - uint32_t decStart = p->readDWord(p_items[i] + 0x90); // 0xAC pre .13 - uint32_t decEnd = p->readDWord(p_items[i] + 0x94); // 0xB0 pre .13 - if (decStart != decEnd) - { - for (j=decStart;jreadDWord(j); - uint32_t dvtable = p->readDWord(decoration); - string ddesc = p->readClassName(dvtable); - uint32_t dtypefunc = p->readDWord(dvtable + 20); - uint64_t dtypefunct = p->readQuad(dtypefunc); - uint32_t dtypeC = p->readWord(decoration + 0x4); - uint32_t dtypeD = p->readDWord(decoration + 0x8); - uint32_t dtype = 0; - uint32_t dqual = p->readWord(decoration + 20); - if ( (dtypefunct&0xFFFFFFFFFFFF00FFLL) == 0xCCCCC300000000B8LL) - dtype = (dtypefunct>>8)&0xfffffff; - else if ( dtypefunct == 0xCCCCCCCCCCC3C033LL) - dtype = 0; - else - printf("bad decoration type function, address=%p\n", (void*) dtypefunc); - if (sep) - printf(","); - //printf("%s[t=%d,q=%d,%s{%d,%d}]", ddesc.c_str(), dtype, dqual, getMatDesc(-1, dtypeC, dtypeD).c_str(), dtypeC, dtypeD); - sep = true; - } - } - printf("]"); - } - printf("\n"); - } -*/ #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore();