From f46a7f1213fb878d999c7c0b4f9b39c2dd22f9ab Mon Sep 17 00:00:00 2001 From: "U-glouglou\\simon" Date: Sun, 2 May 2010 10:35:23 +0200 Subject: [PATCH] Basic code for item handling, now it should be tested :) --- dfhack/CMakeLists.txt | 3 +- dfhack/include/modules/Items.h | 66 ++++++++++ dfhack/include/modules/Materials.h | 2 +- dfhack/modules/Creatures.cpp | 4 +- dfhack/modules/Items.cpp | 202 +++++++++++++++++++++++++++++ examples/creaturedump.cpp | 2 +- output/Memory.xml | 6 + 7 files changed, 280 insertions(+), 5 deletions(-) create mode 100755 dfhack/include/modules/Items.h create mode 100755 dfhack/modules/Items.cpp diff --git a/dfhack/CMakeLists.txt b/dfhack/CMakeLists.txt index c00d3218e..f3b49b315 100644 --- a/dfhack/CMakeLists.txt +++ b/dfhack/CMakeLists.txt @@ -36,6 +36,7 @@ depends/tinyxml/tinyxmlparser.cpp modules/Creatures.cpp modules/Gui.cpp +modules/Items.cpp modules/Maps.cpp modules/Materials.cpp modules/Position.cpp @@ -135,4 +136,4 @@ ENDIF(UNIX) # SWIG_ADD_MODULE(pydfhack python pydfhack.i) # SWIG_LINK_LIBRARIES(pydfhack ${PYTHON_LIBRARIES} dfhack) # ENDIF(PYTHONLIBS_FOUND) -#ENDIF(SWIG_FOUND) \ No newline at end of file +#ENDIF(SWIG_FOUND) diff --git a/dfhack/include/modules/Items.h b/dfhack/include/modules/Items.h new file mode 100755 index 000000000..30f4bd8d8 --- /dev/null +++ b/dfhack/include/modules/Items.h @@ -0,0 +1,66 @@ +#ifndef CL_MOD_ITEMS +#define CL_MOD_ITEMS +/* +* Creatures +*/ +#include "Export.h" +namespace DFHack +{ + +enum accessor_type {ACCESSOR_CONSTANT, ACCESSOR_INDIRECT, ACCESSOR_DOUBLE_INDIRECT}; + +/* this is used to store data about the way accessors work */ +class DFHACK_EXPORT Accessor +{ +private: + accessor_type type; + int32_t constant; + uint32_t offset1; + uint32_t offset2; + Process * p; + uint32_t dataWidth; +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); + int32_t getValue(uint32_t objectPtr); +}; + +struct t_item +{ + t_material matdesc; + int32_t quantity; + int32_t quality; +}; + +class DFHACK_EXPORT ItemDesc +{ +private: + Accessor * AMainType; + Accessor * ASubType; + Accessor * ASubIndex; + Accessor * AIndex; + Accessor * AQuality; + Process * p; + bool hasDecoration; +public: + ItemDesc(uint32_t VTable, Process * p); + bool getItem(uint32_t itemptr, t_item & item); + std::string className; + uint32_t vtable; +}; + +class DFHACK_EXPORT Items +{ +public: + Items(DFHack::APIPrivate * _d); + ~Items(); + std::string getItemDescription(uint32_t itemptr); + bool getItemData(uint32_t itemptr, t_item & item); +private: + class Private; + Private* d; + /*std::map descType; might be useful later */ + std::map descVTable; +}; +} +#endif diff --git a/dfhack/include/modules/Materials.h b/dfhack/include/modules/Materials.h index 8198b2991..1fd4d66fe 100644 --- a/dfhack/include/modules/Materials.h +++ b/dfhack/include/modules/Materials.h @@ -74,8 +74,8 @@ namespace DFHack struct t_material { int16_t itemType; - int16_t typeB; int16_t subType; + int16_t subIndex; int32_t index; uint32_t flags; }; diff --git a/dfhack/modules/Creatures.cpp b/dfhack/modules/Creatures.cpp index 9b22d2ad8..55e86f18b 100644 --- a/dfhack/modules/Creatures.cpp +++ b/dfhack/modules/Creatures.cpp @@ -375,8 +375,8 @@ bool Creatures::ReadJob(const t_creature * furball, vector & mat) for(i=0;ireadWord(cmats[i] + minfo->getOffset("job_material_maintype")); - mat[i].typeB = p->readWord(cmats[i] + minfo->getOffset("job_material_sectype1")); - mat[i].subType = p->readWord(cmats[i] + minfo->getOffset("job_material_sectype2")); + mat[i].subType = p->readWord(cmats[i] + minfo->getOffset("job_material_sectype1")); + mat[i].subIndex = p->readWord(cmats[i] + minfo->getOffset("job_material_sectype2")); mat[i].index = p->readDWord(cmats[i] + minfo->getOffset("job_material_sectype3")); mat[i].flags = p->readDWord(cmats[i] + minfo->getOffset("job_material_flags")); } diff --git a/dfhack/modules/Items.cpp b/dfhack/modules/Items.cpp new file mode 100755 index 000000000..093236d97 --- /dev/null +++ b/dfhack/modules/Items.cpp @@ -0,0 +1,202 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "DFCommonInternal.h" +#include "../private/APIPrivate.h" +#include "modules/Materials.h" +#include "modules/Items.h" +#include "DFMemInfo.h" +#include "DFProcess.h" +#include "DFVector.h" + +using namespace DFHack; + +class Items::Private +{ + public: + APIPrivate *d; + Process * owner; + /* + bool Inited; + bool Started; + */ +}; + +Items::Items(APIPrivate * d_) +{ + d = new Private; + d->d = d_; + d->owner = d_->p; +} +Items::~Items() +{ + delete d; + /* TODO : delete all item descs */ +} + +Accessor::Accessor(uint32_t function, Process *p) +{ + this->p = p; + this->constant = 0; + this->offset1 = 0; + this->offset2 = 0; + this->type = ACCESSOR_CONSTANT; + this->dataWidth = 2; + uint64_t funcText = p->readQuad(function); + if( funcText == 0xCCCCCCCCCCC3C033LL ) + { + return; + } + if( funcText == 0xCCCCCCCCC3FFC883LL ) + { + /* or eax,-1; ret; */ + this->constant = -1; + return; + } + if( (funcText&0xFFFFFFFFFF0000FFLL) == 0xCCCCC300000000B8LL ) + { + /* mov eax, xx; ret; */ + this->constant = (funcText>>8) & 0xffff; + return; + } + if( (funcText&0xFFFFFF0000FFFFFFLL) == 0xC300000000818B66LL ) + { + /* mov ax, [ecx+xx]; ret; */ + this->type = ACCESSOR_INDIRECT; + this->offset1 = (funcText>>24) & 0xffff; + return; + } + if( (funcText&0xFFFFFFFF0000FFFFLL) == 0x8B6600000000818BLL ) + { + uint64_t funcText2 = p->readQuad(function+8); + if( (funcText2&0xFFFFFFFFFFFF00FFLL) == 0xCCCCCCCCCCC30040LL ) + { + this->type = ACCESSOR_DOUBLE_INDIRECT; + this->offset1 = (funcText>>16) & 0xffff; + this->offset2 = (funcText2>>8) & 0xff; + return; + } + } + if( (funcText&0xFFFFFFFF0000FFFFLL) == 0xCCC300000000818BLL ) + { + /* mov eax, [ecx+xx]; ret; */ + this->type = ACCESSOR_INDIRECT; + this->offset1 = (funcText>>16) & 0xffff; + this->dataWidth = 4; + return; + } + printf("bad accessor @0x%x\n", function); +} + +int32_t Accessor::getValue(uint32_t objectPtr) +{ + switch(this->type) + { + case ACCESSOR_CONSTANT: + return this->constant; + break; + case ACCESSOR_INDIRECT: + switch(this->dataWidth) + { + case 2: + return p->readWord(objectPtr + this->offset1); + case 4: + return p->readDWord(objectPtr + this->offset1); + default: + return -1; + } + break; + case ACCESSOR_DOUBLE_INDIRECT: + switch(this->dataWidth) + { + case 2: + return p->readWord(p->readDWord(objectPtr + this->offset1) + this->offset2); + case 4: + return p->readDWord(p->readDWord(objectPtr + this->offset1) + this->offset2); + default: + return -1; + } + break; + default: + return -1; + } +} + +ItemDesc::ItemDesc(uint32_t VTable, Process *p) +{ + uint32_t funcOffsetA = p->getDescriptor()->getOffset("item_type_accessor"); + uint32_t funcOffsetB = p->getDescriptor()->getOffset("item_subtype_accessor"); + uint32_t funcOffsetC = p->getDescriptor()->getOffset("item_subindex_accessor"); + uint32_t funcOffsetD = p->getDescriptor()->getOffset("item_index_accessor"); + uint32_t funcOffsetQuality = p->getDescriptor()->getOffset("item_quality_accessor"); + this->vtable = VTable; + this->p = p; + this->className = p->readClassName(VTable); + this->AMainType = new Accessor( p->readDWord( VTable + funcOffsetA ), p); + this->ASubType = new Accessor( p->readDWord( VTable + funcOffsetB ), p); + this->ASubIndex = new Accessor( p->readDWord( VTable + funcOffsetC ), p); + this->AIndex = new Accessor( p->readDWord( VTable + funcOffsetD ), p); + this->AQuality = new Accessor( p->readDWord( VTable + funcOffsetQuality ), p); + this->hasDecoration = false; +} + +bool ItemDesc::getItem(uint32_t itemptr, DFHack::t_item &item) +{ + item.matdesc.itemType = this->AMainType->getValue(itemptr); + item.matdesc.subType = this->ASubType->getValue(itemptr); + item.matdesc.subIndex = this->ASubIndex->getValue(itemptr); + item.matdesc.index = this->AIndex->getValue(itemptr); + item.quality = this->AQuality->getValue(itemptr); + item.quantity = 1; /* TODO */ + return true; +} + +bool Items::getItemData(uint32_t itemptr, DFHack::t_item &item) +{ + std::map::iterator it; + Process * p = d->owner; + ItemDesc * desc; + + it = this->descVTable.find(itemptr); + if(it==descVTable.end()) + { + uint32_t vtable = p->readDWord(itemptr); + desc = new ItemDesc(vtable, p); + this->descVTable[vtable] = desc; + } + else + desc = it->second; + + return desc->getItem(itemptr, item); +} + +std::string Items::getItemDescription(uint32_t itemptr) +{ + DFHack::t_item item; + std::string out; + + if(!this->getItemData(itemptr, item)) + return "??"; + return "!!"; +} \ No newline at end of file diff --git a/examples/creaturedump.cpp b/examples/creaturedump.cpp index 2c08f7532..02378a3b5 100644 --- a/examples/creaturedump.cpp +++ b/examples/creaturedump.cpp @@ -241,7 +241,7 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) { for(unsigned int i = 0; i < mymat.size(); i++) { - printf("\t%s(%d)\t%d %d %d - %.8x\n", Materials->getDescription(mymat[i]).c_str(), mymat[i].itemType, mymat[i].typeB, mymat[i].subType, mymat[i].index, mymat[i].flags); + printf("\t%s(%d)\t%d %d %d - %.8x\n", Materials->getDescription(mymat[i]).c_str(), mymat[i].itemType, mymat[i].subType, mymat[i].subIndex, mymat[i].index, mymat[i].flags); } } } diff --git a/output/Memory.xml b/output/Memory.xml index a54ef24b5..b9dced466 100755 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1502,6 +1502,12 @@ map_data_1b60_offset 0x1B9c Items =====
0x166FE00
+ List of offsets in the VTable : + 0x0 + 0x4 + 0x8 + 0xC + 0x238 0xA0 0x14