From da0602dbb1846cc9a9c887ff7098e5212d3ed4d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 12 Apr 2010 18:19:53 +0200 Subject: [PATCH 01/33] Dirty bit for creature equipment pickup on labor setting --- dfhack/modules/Creatures.cpp | 5 +++++ dfhack/shm/mod-creature2010.h | 1 + output/Memory.xml | 1 + 3 files changed, 7 insertions(+) diff --git a/dfhack/modules/Creatures.cpp b/dfhack/modules/Creatures.cpp index 0b756e81d..3ab33f27b 100644 --- a/dfhack/modules/Creatures.cpp +++ b/dfhack/modules/Creatures.cpp @@ -83,6 +83,7 @@ Creatures::Creatures(APIPrivate* _d) creatures.default_soul_offset = minfo->getOffset("creature_default_soul"); creatures.physical_offset = minfo->getOffset("creature_physical"); creatures.mood_offset = minfo->getOffset("creature_mood"); + creatures.pickup_equipment_bit = minfo->getOffset("creature_pickup_equipment_bit"); // soul offsets creatures.soul_skills_vector_offset = minfo->getOffset("soul_skills_vector"); creatures.soul_mental_offset = minfo->getOffset("soul_mental"); @@ -294,6 +295,10 @@ bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LA if(!d->Started) return false; uint32_t temp = * (uint32_t *) d->p_cre->at (index); g_pProcess->write(temp + d->creatures.labors_offset, NUM_CREATURE_LABORS, labors); + uint32_t pickup_equip; + g_pProcess->readDWord(temp + d->creatures.pickup_equipment_bit, pickup_equip); + pickup_equip |= 1u; + g_pProcess->writeDWord(temp + d->creatures.pickup_equipment_bit, pickup_equip); return true; } diff --git a/dfhack/shm/mod-creature2010.h b/dfhack/shm/mod-creature2010.h index ae8a2ec4d..c17da3d53 100644 --- a/dfhack/shm/mod-creature2010.h +++ b/dfhack/shm/mod-creature2010.h @@ -49,6 +49,7 @@ typedef struct uint32_t artifact_name_offset; uint32_t physical_offset; uint32_t mood_offset; + uint32_t pickup_equipment_bit; uint32_t soul_vector_offset; uint32_t default_soul_offset; // soul offsets diff --git a/output/Memory.xml b/output/Memory.xml index 116a87c5c..93aa8a3a9 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1132,6 +1132,7 @@ map_data_1b60_offset 0x1B9c 0x114 0X120 0X1F4 + 0X21C 0x238 0x464 From 549b845738c97e212cf60d6e47d2f6f9373e006b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 13 Apr 2010 00:03:29 +0200 Subject: [PATCH 02/33] Custom buildings (tested) --- dfhack/DFMemInfo.cpp | 16 ++++++++++++ dfhack/include/DFMemInfo.h | 5 +--- dfhack/include/modules/Buildings.h | 6 +++++ dfhack/modules/Buildings.cpp | 41 ++++++++++++++++++++++++++++-- examples/buildingsdump.cpp | 9 ++++++- output/Memory.xml | 5 ++++ 6 files changed, 75 insertions(+), 7 deletions(-) diff --git a/dfhack/DFMemInfo.cpp b/dfhack/DFMemInfo.cpp index af8aa875e..621ac56c2 100644 --- a/dfhack/DFMemInfo.cpp +++ b/dfhack/DFMemInfo.cpp @@ -393,6 +393,22 @@ bool memory_info::resolveClassnameToVPtr(const string classname, uint32_t & vptr return false; } +bool memory_info::resolveClassnameToClassID (const string classname, int32_t & classID) +{ + // FIXME: another stupid search. + classID = -1; + for(uint32_t i = 0;i< d->classnames.size();i++) + { + if(d->classnames[i] == classname) + { + classID = i; + return true; + } + } + // we failed to find anything that would match + return false; +} + bool memory_info::resolveClassIDToClassname (const int32_t classID, string & classname) { if (classID >=0 && (uint32_t)classID < d->classnames.size()) diff --git a/dfhack/include/DFMemInfo.h b/dfhack/include/DFMemInfo.h index 3712031d1..7b4be6cf8 100644 --- a/dfhack/include/DFMemInfo.h +++ b/dfhack/include/DFMemInfo.h @@ -160,18 +160,15 @@ namespace DFHack bool resolveObjectToClassID (const uint32_t address, int32_t & classID); /* - * Get a classID from an address. The address has to point to the start of a virtual object (one with a virtual base class) - * can fail if the class is not in the cache + * Get a ClassID when you know the classname. can fail if the class is not in the cache */ bool resolveClassnameToClassID (const string classname, int32_t & classID); - //bool resolveClassnameToClassID (const char * classname, int32_t & classID); /* * Get a vptr from a classname. Can fail if the type is not in the cache * limited to normal classes, variable-dependent types will resolve to the base class */ bool resolveClassnameToVPtr ( const string classname, uint32_t & vptr ); - //bool resolveClassnameToVPtr ( const char * classname, uint32_t & vptr ); /* * Get a classname from a previous classID. Can fail if the type is not in the cache (you use bogus classID) diff --git a/dfhack/include/modules/Buildings.h b/dfhack/include/modules/Buildings.h index fd3589bee..1d27a6f41 100644 --- a/dfhack/include/modules/Buildings.h +++ b/dfhack/include/modules/Buildings.h @@ -32,9 +32,15 @@ namespace DFHack Buildings(APIPrivate * d); ~Buildings(); bool Start(uint32_t & numBuildings); + // read one building at offset bool Read (const uint32_t index, t_building & building); bool Finish(); + // read a vector of names + bool ReadCustomWorkshopTypes(map & btypes); + // returns -1 on error, >= 0 for real value + int32_t GetCustomWorkshopType(t_building & building); + private: struct Private; Private *d; diff --git a/dfhack/modules/Buildings.cpp b/dfhack/modules/Buildings.cpp index 8e8c4de31..580ec5c5f 100644 --- a/dfhack/modules/Buildings.cpp +++ b/dfhack/modules/Buildings.cpp @@ -52,9 +52,12 @@ struct t_building_df40d struct Buildings::Private { uint32_t buildings_vector; - // translation + uint32_t custom_workshop_vector; + uint32_t building_custom_workshop_type; + uint32_t custom_workshop_type; + uint32_t custom_workshop_name; + int32_t custom_workshop_id; DfVector * p_bld; - APIPrivate *d; bool Inited; bool Started; @@ -66,7 +69,12 @@ Buildings::Buildings(APIPrivate * d_) d->d = d_; d->Inited = d->Started = false; memory_info * mem = d->d->offset_descriptor; + d->custom_workshop_vector = mem->getAddress("custom_workshop_vector"); + d->building_custom_workshop_type = mem->getOffset("building_custom_workshop_type"); + d->custom_workshop_type = mem->getOffset("custom_workshop_type"); + d->custom_workshop_name = mem->getOffset("custom_workshop_name"); d->buildings_vector = mem->getAddress ("buildings_vector"); + mem->resolveClassnameToClassID("building_custom_workshop", d->custom_workshop_id); d->Inited = true; } @@ -122,4 +130,33 @@ bool Buildings::Finish() } d->Started = false; return true; +} + +bool Buildings::ReadCustomWorkshopTypes(map & btypes) +{ + DfVector p_matgloss (g_pProcess, d->custom_workshop_vector, 4); + uint32_t size = p_matgloss.getSize(); + btypes.clear(); + for (uint32_t i = 0; i < size;i++) + { + string out = g_pProcess->readSTLString (*(uint32_t *) p_matgloss[i] + d->custom_workshop_name); + uint32_t type = g_pProcess->readDWord (*(uint32_t *) p_matgloss[i] + d->custom_workshop_type); + #ifdef DEBUG + cout << out << ": " << type << endl; + #endif + btypes[type] = out; + } + return true; +} + +int32_t Buildings::GetCustomWorkshopType(t_building & building) +{ + int32_t type = (int32_t)building.type; + int32_t ret = -1; + if(type != -1 && type == d->custom_workshop_id) + { + // read the custom workshop subtype + ret = (int32_t) g_pProcess->readDWord(building.origin + d->building_custom_workshop_type); + } + return ret; } \ No newline at end of file diff --git a/examples/buildingsdump.cpp b/examples/buildingsdump.cpp index ba6d77cc4..d4cccb440 100644 --- a/examples/buildingsdump.cpp +++ b/examples/buildingsdump.cpp @@ -44,7 +44,7 @@ int main (int argc,const char* argv[]) mode = 1; } - vector creaturestypes; + map custom_workshop_types; DFHack::API DF ("Memory.xml"); try @@ -59,6 +59,7 @@ int main (int argc,const char* argv[]) #endif return 1; } + DFHack::memory_info * mem = DF.getMemoryInfo(); DFHack::Buildings * Bld = DF.getBuildings(); DFHack::Position * Pos = DF.getPosition(); @@ -66,6 +67,7 @@ int main (int argc,const char* argv[]) uint32_t numBuildings; if(Bld->Start(numBuildings)) { + Bld->ReadCustomWorkshopTypes(custom_workshop_types); if(mode) { cout << numBuildings << endl; @@ -110,6 +112,11 @@ int main (int argc,const char* argv[]) mem->resolveClassIDToClassname(temp.type, typestr); printf("Address 0x%x, type %d (%s), %d/%d/%d\n",temp.origin, temp.type, typestr.c_str(), temp.x1,temp.y1,temp.z); printf("Material %d %d\n", temp.material.type, temp.material.index); + int32_t custom; + if((custom = Bld->GetCustomWorkshopType(temp)) != -1) + { + printf("Custom workshop type %s (%d)\n",custom_workshop_types[custom].c_str(),custom); + } hexdump(DF,temp.origin,120); } } diff --git a/output/Memory.xml b/output/Memory.xml index 93aa8a3a9..89aa73886 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -920,6 +920,7 @@ size=212 + @@ -1238,6 +1239,10 @@ map_data_1b60_offset 0x1B9c Buildings =========
0x0166f9a0
+ 0x164 +
0x016B8798
+ 0x4 + 0x20 Effects ======= From e85b4291271b63cf66605681ebaa74a76acc4fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 13 Apr 2010 03:11:26 +0200 Subject: [PATCH 03/33] Throw exceptions on memory read errors! Fix reading creatures that have no soul. --- dfhack/DFProcess-linux-SHM.cpp | 36 ++++++------- dfhack/DFProcess-linux-wine.cpp | 21 ++++---- dfhack/DFProcess-linux.cpp | 13 ++--- dfhack/DFProcess-windows-SHM.cpp | 36 ++++++------- dfhack/DFProcess-windows.cpp | 57 +++++++++++++-------- dfhack/include/DFError.h | 6 +-- dfhack/include/modules/Creatures.h | 2 +- dfhack/modules/Buildings.cpp | 4 ++ dfhack/modules/Creatures.cpp | 34 +++++++------ examples/creaturedump.cpp | 82 ++++++++++++++---------------- output/Memory.xml | 1 + 11 files changed, 155 insertions(+), 137 deletions(-) diff --git a/dfhack/DFProcess-linux-SHM.cpp b/dfhack/DFProcess-linux-SHM.cpp index bcc55fb08..8f7951d8d 100644 --- a/dfhack/DFProcess-linux-SHM.cpp +++ b/dfhack/DFProcess-linux-SHM.cpp @@ -608,7 +608,7 @@ bool SHMProcess::detach() void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); // normal read under 1MB if(size <= SHM_BODY) @@ -645,7 +645,7 @@ void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buff uint8_t SHMProcess::readByte (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -655,7 +655,7 @@ uint8_t SHMProcess::readByte (const uint32_t offset) void SHMProcess::readByte (const uint32_t offset, uint8_t &val ) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -665,7 +665,7 @@ void SHMProcess::readByte (const uint32_t offset, uint8_t &val ) uint16_t SHMProcess::readWord (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -675,7 +675,7 @@ uint16_t SHMProcess::readWord (const uint32_t offset) void SHMProcess::readWord (const uint32_t offset, uint16_t &val) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -685,7 +685,7 @@ void SHMProcess::readWord (const uint32_t offset, uint16_t &val) uint32_t SHMProcess::readDWord (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -694,7 +694,7 @@ uint32_t SHMProcess::readDWord (const uint32_t offset) } void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -708,7 +708,7 @@ void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) void SHMProcess::writeDWord (uint32_t offset, uint32_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -719,7 +719,7 @@ void SHMProcess::writeDWord (uint32_t offset, uint32_t data) // using these is expensive. void SHMProcess::writeWord (uint32_t offset, uint16_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -729,7 +729,7 @@ void SHMProcess::writeWord (uint32_t offset, uint16_t data) void SHMProcess::writeByte (uint32_t offset, uint8_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -739,7 +739,7 @@ void SHMProcess::writeByte (uint32_t offset, uint8_t data) void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); // normal write under 1MB if(size <= SHM_BODY) @@ -777,7 +777,7 @@ void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buf // FIXME: butt-fugly const std::string SHMProcess::readCString (uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); std::string temp; char temp_c[256]; @@ -796,7 +796,7 @@ const std::string SHMProcess::readCString (uint32_t offset) const std::string SHMProcess::readSTLString(uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -806,7 +806,7 @@ const std::string SHMProcess::readSTLString(uint32_t offset) size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -820,7 +820,7 @@ size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapa void SHMProcess::writeSTLString(const uint32_t address, const std::string writeString) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = address; strncpy(D_SHMDATA(char),writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator @@ -830,7 +830,7 @@ void SHMProcess::writeSTLString(const uint32_t address, const std::string writeS string SHMProcess::readClassName (uint32_t vptr) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); int typeinfo = readDWord(vptr - 0x4); int typestring = readDWord(typeinfo + 0x4); @@ -843,7 +843,7 @@ string SHMProcess::readClassName (uint32_t vptr) // get module index by name and version. bool 0 = error bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); modulelookup * payload = D_SHMDATA(modulelookup); payload->version = version; @@ -873,7 +873,7 @@ char * SHMProcess::getSHMStart (void) bool SHMProcess::Private::Aux_Core_Attach(bool & versionOK, pid_t & PID) { - if(!locked) throw Error::SHMAccessDenied(); + if(!locked) throw Error::MemoryAccessDenied(); SHMDATA(coreattach)->cl_affinity = OS_getAffinity(); if(!SetAndWait(CORE_ATTACH)) return false; diff --git a/dfhack/DFProcess-linux-wine.cpp b/dfhack/DFProcess-linux-wine.cpp index da4a11fb2..6177502d3 100644 --- a/dfhack/DFProcess-linux-wine.cpp +++ b/dfhack/DFProcess-linux-wine.cpp @@ -377,6 +377,7 @@ void WineProcess::read (const uint32_t offset, const uint32_t size, uint8_t *tar cerr << "pread failed: can't read " << size << " bytes at addres " << offset << endl; cerr << "errno: " << errno << endl; errno = 0; + throw Error::MemoryAccessDenied(); } else { @@ -516,20 +517,20 @@ size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcap Uint32 capacity */ uint32_t start_offset = offset + 4; - size_t length = g_pProcess->readDWord(offset + 20); + size_t length = readDWord(offset + 20); - size_t capacity = g_pProcess->readDWord(offset + 24); + size_t capacity = readDWord(offset + 24); size_t read_real = min(length, bufcapacity-1);// keep space for null termination // read data from inside the string structure if(capacity < 16) { - g_pProcess->read(start_offset, read_real , (uint8_t *)buffer); + read(start_offset, read_real , (uint8_t *)buffer); } else // read data from what the offset + 4 dword points to { - start_offset = g_pProcess->readDWord(start_offset);// dereference the start offset - g_pProcess->read(start_offset, read_real, (uint8_t *)buffer); + start_offset = readDWord(start_offset);// dereference the start offset + read(start_offset, read_real, (uint8_t *)buffer); } buffer[read_real] = 0; @@ -550,19 +551,19 @@ const string WineProcess::readSTLString (uint32_t offset) Uint32 capacity */ uint32_t start_offset = offset + 4; - uint32_t length = g_pProcess->readDWord(offset + 20); - uint32_t capacity = g_pProcess->readDWord(offset + 24); + uint32_t length = readDWord(offset + 20); + uint32_t capacity = readDWord(offset + 24); char * temp = new char[capacity+1]; // read data from inside the string structure if(capacity < 16) { - g_pProcess->read(start_offset, capacity, (uint8_t *)temp); + read(start_offset, capacity, (uint8_t *)temp); } else // read data from what the offset + 4 dword points to { - start_offset = g_pProcess->readDWord(start_offset);// dereference the start offset - g_pProcess->read(start_offset, capacity, (uint8_t *)temp); + start_offset = readDWord(start_offset);// dereference the start offset + read(start_offset, capacity, (uint8_t *)temp); } temp[length] = 0; diff --git a/dfhack/DFProcess-linux.cpp b/dfhack/DFProcess-linux.cpp index 71220a051..b92c5ca29 100644 --- a/dfhack/DFProcess-linux.cpp +++ b/dfhack/DFProcess-linux.cpp @@ -365,6 +365,7 @@ void NormalProcess::read (const uint32_t offset, const uint32_t size, uint8_t *t cerr << "pread failed: can't read " << size << " bytes at addres " << offset << endl; cerr << "errno: " << errno << endl; errno = 0; + throw Error::MemoryAccessDenied(); } else { @@ -500,10 +501,10 @@ struct _Rep_base size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) { _Rep_base header; - offset = g_pProcess->readDWord(offset); - g_pProcess->read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); + offset = readDWord(offset); + read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); size_t read_real = min((size_t)header._M_length, bufcapacity-1);// keep space for null termination - g_pProcess->read(offset,read_real,(uint8_t * )buffer); + read(offset,read_real,(uint8_t * )buffer); buffer[read_real] = 0; return read_real; } @@ -512,12 +513,12 @@ const string NormalProcess::readSTLString (uint32_t offset) { _Rep_base header; - offset = g_pProcess->readDWord(offset); - g_pProcess->read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); + offset = readDWord(offset); + read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); // FIXME: use char* everywhere, avoid string char * temp = new char[header._M_length+1]; - g_pProcess->read(offset,header._M_length+1,(uint8_t * )temp); + read(offset,header._M_length+1,(uint8_t * )temp); string ret(temp); delete temp; return ret; diff --git a/dfhack/DFProcess-windows-SHM.cpp b/dfhack/DFProcess-windows-SHM.cpp index 49ceabeac..5f776e93a 100644 --- a/dfhack/DFProcess-windows-SHM.cpp +++ b/dfhack/DFProcess-windows-SHM.cpp @@ -669,7 +669,7 @@ bool SHMProcess::detach() void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); // normal read under 1MB if(size <= SHM_BODY) @@ -706,7 +706,7 @@ void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buff uint8_t SHMProcess::readByte (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -716,7 +716,7 @@ uint8_t SHMProcess::readByte (const uint32_t offset) void SHMProcess::readByte (const uint32_t offset, uint8_t &val ) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -726,7 +726,7 @@ void SHMProcess::readByte (const uint32_t offset, uint8_t &val ) uint16_t SHMProcess::readWord (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -736,7 +736,7 @@ uint16_t SHMProcess::readWord (const uint32_t offset) void SHMProcess::readWord (const uint32_t offset, uint16_t &val) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -746,7 +746,7 @@ void SHMProcess::readWord (const uint32_t offset, uint16_t &val) uint32_t SHMProcess::readDWord (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -755,7 +755,7 @@ uint32_t SHMProcess::readDWord (const uint32_t offset) } void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -769,7 +769,7 @@ void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) void SHMProcess::writeDWord (uint32_t offset, uint32_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -780,7 +780,7 @@ void SHMProcess::writeDWord (uint32_t offset, uint32_t data) // using these is expensive. void SHMProcess::writeWord (uint32_t offset, uint16_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -790,7 +790,7 @@ void SHMProcess::writeWord (uint32_t offset, uint16_t data) void SHMProcess::writeByte (uint32_t offset, uint8_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -800,7 +800,7 @@ void SHMProcess::writeByte (uint32_t offset, uint8_t data) void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); // normal write under 1MB if(size <= SHM_BODY) @@ -838,7 +838,7 @@ void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buf // FIXME: butt-fugly const std::string SHMProcess::readCString (uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); std::string temp; char temp_c[256]; @@ -857,7 +857,7 @@ const std::string SHMProcess::readCString (uint32_t offset) const std::string SHMProcess::readSTLString(uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -867,7 +867,7 @@ const std::string SHMProcess::readSTLString(uint32_t offset) size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -881,7 +881,7 @@ size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapa void SHMProcess::writeSTLString(const uint32_t address, const std::string writeString) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = address; strncpy(D_SHMDATA(char),writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator @@ -901,7 +901,7 @@ string SHMProcess::readClassName (uint32_t vptr) // get module index by name and version. bool 0 = error bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); modulelookup * payload = D_SHMDATA(modulelookup); payload->version = version; @@ -924,13 +924,13 @@ bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint char * SHMProcess::getSHMStart (void) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); return /*d->shm_addr_with_cl_idx*/ d->shm_addr; } bool SHMProcess::Private::Aux_Core_Attach(bool & versionOK, uint32_t & PID) { - if(!locked) throw Error::SHMAccessDenied(); + if(!locked) throw Error::MemoryAccessDenied(); SHMDATA(coreattach)->cl_affinity = OS_getAffinity(); if(!SetAndWait(CORE_ATTACH)) return false; diff --git a/dfhack/DFProcess-windows.cpp b/dfhack/DFProcess-windows.cpp index b1dac9568..00a3b56d2 100644 --- a/dfhack/DFProcess-windows.cpp +++ b/dfhack/DFProcess-windows.cpp @@ -315,64 +315,75 @@ void NormalProcess::getMemRanges( vector & ranges ) uint8_t NormalProcess::readByte (const uint32_t offset) { uint8_t result; - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint8_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint8_t), NULL)) + throw Error::MemoryAccessDenied(); return result; } void NormalProcess::readByte (const uint32_t offset,uint8_t &result) { - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint8_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint8_t), NULL)) + throw Error::MemoryAccessDenied(); } uint16_t NormalProcess::readWord (const uint32_t offset) { uint16_t result; - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint16_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint16_t), NULL)) + throw Error::MemoryAccessDenied(); return result; } void NormalProcess::readWord (const uint32_t offset, uint16_t &result) { - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint16_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint16_t), NULL)) + throw Error::MemoryAccessDenied(); } uint32_t NormalProcess::readDWord (const uint32_t offset) { uint32_t result; - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint32_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint32_t), NULL)) + throw Error::MemoryAccessDenied(); return result; } void NormalProcess::readDWord (const uint32_t offset, uint32_t &result) { - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint32_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint32_t), NULL)) + throw Error::MemoryAccessDenied(); } void NormalProcess::read (const uint32_t offset, uint32_t size, uint8_t *target) { - ReadProcessMemory(d->my_handle, (int*) offset, target, size, NULL); + if(ReadProcessMemory(d->my_handle, (int*) offset, target, size, NULL)) + throw Error::MemoryAccessDenied(); } // WRITING void NormalProcess::writeDWord (const uint32_t offset, uint32_t data) { - WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint32_t), NULL); + if(!WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint32_t), NULL)) + throw Error::MemoryAccessDenied(); } // using these is expensive. void NormalProcess::writeWord (uint32_t offset, uint16_t data) { - WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint16_t), NULL); + if(!WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint16_t), NULL)) + throw Error::MemoryAccessDenied(); } void NormalProcess::writeByte (uint32_t offset, uint8_t data) { - WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint8_t), NULL); + if(!WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint8_t), NULL)) + throw Error::MemoryAccessDenied(); } void NormalProcess::write (uint32_t offset, uint32_t size, uint8_t *source) { - WriteProcessMemory(d->my_handle, (int*) offset, source, size, NULL); + if(!WriteProcessMemory(d->my_handle, (int*) offset, source, size, NULL)) + throw Error::MemoryAccessDenied(); } @@ -383,7 +394,9 @@ const string NormalProcess::readCString (const uint32_t offset) string temp; char temp_c[256]; DWORD read; - ReadProcessMemory(d->my_handle, (int *) offset, temp_c, 254, &read); // needs to be 254+1 byte for the null term + if(!ReadProcessMemory(d->my_handle, (int *) offset, temp_c, 254, &read)) + throw Error::MemoryAccessDenied(); + // needs to be 254+1 byte for the null term temp_c[read+1] = 0; temp.assign(temp_c); return temp; @@ -403,20 +416,20 @@ Uint32 length Uint32 capacity */ uint32_t start_offset = offset + 4; - size_t length = g_pProcess->readDWord(offset + 20); + size_t length = readDWord(offset + 20); - size_t capacity = g_pProcess->readDWord(offset + 24); + size_t capacity = readDWord(offset + 24); size_t read_real = min(length, bufcapacity-1);// keep space for null termination // read data from inside the string structure if(capacity < 16) { - g_pProcess->read(start_offset, read_real , (uint8_t *)buffer); + read(start_offset, read_real , (uint8_t *)buffer); } else // read data from what the offset + 4 dword points to { - start_offset = g_pProcess->readDWord(start_offset);// dereference the start offset - g_pProcess->read(start_offset, read_real, (uint8_t *)buffer); + start_offset = readDWord(start_offset);// dereference the start offset + read(start_offset, read_real, (uint8_t *)buffer); } buffer[read_real] = 0; @@ -437,19 +450,19 @@ const string NormalProcess::readSTLString (uint32_t offset) Uint32 capacity */ uint32_t start_offset = offset + 4; - uint32_t length = g_pProcess->readDWord(offset + 20); - uint32_t capacity = g_pProcess->readDWord(offset + 24); + uint32_t length = readDWord(offset + 20); + uint32_t capacity = readDWord(offset + 24); char * temp = new char[capacity+1]; // read data from inside the string structure if(capacity < 16) { - g_pProcess->read(start_offset, capacity, (uint8_t *)temp); + read(start_offset, capacity, (uint8_t *)temp); } else // read data from what the offset + 4 dword points to { - start_offset = g_pProcess->readDWord(start_offset);// dereference the start offset - g_pProcess->read(start_offset, capacity, (uint8_t *)temp); + start_offset = readDWord(start_offset);// dereference the start offset + read(start_offset, capacity, (uint8_t *)temp); } temp[length] = 0; diff --git a/dfhack/include/DFError.h b/dfhack/include/DFError.h index 375a5c581..15086b9bb 100644 --- a/dfhack/include/DFError.h +++ b/dfhack/include/DFError.h @@ -236,11 +236,11 @@ namespace DFHack return s.str().c_str(); } }; - class DFHACK_EXPORT SHMAccessDenied : public std::exception + class DFHACK_EXPORT MemoryAccessDenied : public std::exception { public: - SHMAccessDenied() {} - virtual ~SHMAccessDenied() throw(){}; + MemoryAccessDenied() {} + virtual ~MemoryAccessDenied() throw(){}; std::string type; diff --git a/dfhack/include/modules/Creatures.h b/dfhack/include/modules/Creatures.h index aa3627977..38ed7df56 100644 --- a/dfhack/include/modules/Creatures.h +++ b/dfhack/include/modules/Creatures.h @@ -346,7 +346,7 @@ namespace DFHack int32_t squad_leader_id; uint8_t sex; uint32_t pregnancy_timer; //Countdown timer to giving birth - + bool has_default_soul; t_soul defaultSoul; }; diff --git a/dfhack/modules/Buildings.cpp b/dfhack/modules/Buildings.cpp index 580ec5c5f..a3ccaa77c 100644 --- a/dfhack/modules/Buildings.cpp +++ b/dfhack/modules/Buildings.cpp @@ -134,6 +134,8 @@ bool Buildings::Finish() bool Buildings::ReadCustomWorkshopTypes(map & btypes) { + if(!d->Started) + return false; DfVector p_matgloss (g_pProcess, d->custom_workshop_vector, 4); uint32_t size = p_matgloss.getSize(); btypes.clear(); @@ -151,6 +153,8 @@ bool Buildings::ReadCustomWorkshopTypes(map & btypes) int32_t Buildings::GetCustomWorkshopType(t_building & building) { + if(!d->Inited) + return false; int32_t type = (int32_t)building.type; int32_t ret = -1; if(type != -1 && type == d->custom_workshop_id) diff --git a/dfhack/modules/Creatures.cpp b/dfhack/modules/Creatures.cpp index 3ab33f27b..2c29b9fc5 100644 --- a/dfhack/modules/Creatures.cpp +++ b/dfhack/modules/Creatures.cpp @@ -210,23 +210,27 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball) DfVector souls(g_pProcess,temp + offs.creature_soul_vector_offset,4); */ uint32_t soul = g_pProcess->readDWord(temp + offs.default_soul_offset); - // get first soul's skills - DfVector skills(g_pProcess, soul + offs.soul_skills_vector_offset, 4 ); - furball.defaultSoul.numSkills = skills.getSize(); - for (uint32_t i = 0; i < furball.defaultSoul.numSkills;i++) + furball.has_default_soul = false; + if(soul) { - uint32_t temp2 = * (uint32_t *) skills[i]; - // a byte: this gives us 256 skills maximum. - furball.defaultSoul.skills[i].id = g_pProcess->readByte (temp2); - furball.defaultSoul.skills[i].rating = g_pProcess->readByte (temp2 + 4); - furball.defaultSoul.skills[i].experience = g_pProcess->readWord (temp2 + 8); + furball.has_default_soul = true; + // get first soul's skills + DfVector skills(g_pProcess, soul + offs.soul_skills_vector_offset, 4 ); + furball.defaultSoul.numSkills = skills.getSize(); + for (uint32_t i = 0; i < furball.defaultSoul.numSkills;i++) + { + uint32_t temp2 = * (uint32_t *) skills[i]; + // a byte: this gives us 256 skills maximum. + furball.defaultSoul.skills[i].id = g_pProcess->readByte (temp2); + furball.defaultSoul.skills[i].rating = g_pProcess->readByte (temp2 + 4); + furball.defaultSoul.skills[i].experience = g_pProcess->readWord (temp2 + 8); + } + // mental attributes are part of the soul + g_pProcess->read(soul + offs.soul_mental_offset, sizeof(t_attrib) * 13, (uint8_t *)&furball.defaultSoul.analytical_ability); + + // traits as well + g_pProcess->read(soul + offs.soul_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS, (uint8_t *) &furball.defaultSoul.traits); } - // mental attributes are part of the soul - g_pProcess->read(soul + offs.soul_mental_offset, sizeof(t_attrib) * 13, (uint8_t *)&furball.defaultSoul.analytical_ability); - - // traits as well - g_pProcess->read(soul + offs.soul_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS, (uint8_t *) &furball.defaultSoul.traits); - //likes /* DfVector likes(d->p, temp + offs.creature_likes_offset, 4); diff --git a/examples/creaturedump.cpp b/examples/creaturedump.cpp index 5ef2d1a0c..3bd7ffea6 100644 --- a/examples/creaturedump.cpp +++ b/examples/creaturedump.cpp @@ -14,17 +14,8 @@ using namespace std; #include #include #include +#include "miscutils.h" -template -void print_bits ( T val, std::ostream& out ) -{ - T n_bits = sizeof ( val ) * CHAR_BIT; - - for ( unsigned i = 0; i < n_bits; ++i ) { - out<< !!( val & 1 ) << " "; - val >>= 1; - } -} struct matGlosses { vector plantMat; @@ -240,46 +231,46 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) */ cout << endl; - - //skills - cout << "Skills" << endl; - for(unsigned int i = 0; i < creature.defaultSoul.numSkills;i++) + if(creature.has_default_soul) { - if(i > 0) + //skills + cout << "Skills" << endl; + for(unsigned int i = 0; i < creature.defaultSoul.numSkills;i++) { - cout << ", "; + if(i > 0) + { + cout << ", "; + } + cout << mem->getSkill(creature.defaultSoul.skills[i].id) << ": " << creature.defaultSoul.skills[i].rating; } - cout << mem->getSkill(creature.defaultSoul.skills[i].id) << ": " << creature.defaultSoul.skills[i].rating; - } - cout << endl; - - // labors - cout << "Labors" << endl; - for(unsigned int i = 0; i < NUM_CREATURE_LABORS;i++) - { - if(!creature.labors[i]) - continue; - string laborname; - try + cout << endl; + cout << "Traits" << endl; + for(uint32_t i = 0; i < 30;i++) { - laborname = mem->getLabor(i); + string trait = mem->getTrait (i, creature.defaultSoul.traits[i]); + if(!trait.empty()) cout << trait << ", "; } - catch(exception &) + cout << endl; + + // labors + cout << "Labors" << endl; + for(unsigned int i = 0; i < NUM_CREATURE_LABORS;i++) { - break; + if(!creature.labors[i]) + continue; + string laborname; + try + { + laborname = mem->getLabor(i); + } + catch(exception &) + { + break; + } + cout << laborname << ", "; } - cout << laborname << ", "; - } - cout << endl; - - cout << "Traits" << endl; - for(uint32_t i = 0; i < 30;i++) - { - string trait = mem->getTrait (i, creature.defaultSoul.traits[i]); - if(!trait.empty()) - cout << trait << ", "; + cout << endl; } - cout << endl; /* * FLAGS 1 */ @@ -409,18 +400,21 @@ int main (void) cerr << "Can't get name tables" << endl; return 1; } - + vector addrs; //DF.InitViewAndCursor(); for(uint32_t i = 0; i < numCreatures; i++) { DFHack::t_creature temp; Creatures->ReadCreature(i,temp); - if(string(creaturestypes[temp.race].id) == "DWARF") + //if(string(creaturestypes[temp.race].id) == "DWARF") { cout << "index " << i << " "; + printCreature(DF,temp); + addrs.push_back(temp.origin); } } + interleave_hex(DF,addrs,200); /* uint32_t currentIdx; DFHack::t_creature currentCreature; diff --git a/output/Memory.xml b/output/Memory.xml index 89aa73886..ad1c7a066 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1135,6 +1135,7 @@ map_data_1b60_offset 0x1B9c 0X1F4 0X21C 0x238 + 0x23C 0x464 - - - - this is an array of 4B pointers to material templates and length 0x292 - base_type_array = WORLD + 0x5DF44 -
0x016b90cc
-
0x16afcec
- inorganics vector = WORLD + 0x54B7C = 0x16AFD04
0x16afd04
- 0x178
0x16afd1C
- + +
0x016AFE58
+ + + maybe maps beween organics_all and organics_plants
0x16afd4C
- + just wood
0x16afd64
- + maybe maps beween organics_all and organics_trees
0x16afd7C
- + body material stuff
0x16AFD94
0x16AFDAC
0x16AFDC4
0x16AFDDC
0x16AFDF4
- + *raw* creature types
0x16AFE0C
- -
0x016AFE58
- - + --> Constructions ============= + WORLD + 0x108
0x165b290
0x14 Translations ============ + WORLD + 0x54E50
0x016AFFD8
+ WORLD + 0x54E80
0x016B0008
0x4C Vegetation ========== + WORLD + 0x15184
0x0167030C
belal: 0x017f6d98 ... what? 0x6C Buildings ========= + WORLD + 0x14818
0x0166f9a0
0x164 + WORLD + 0x5D610
0x016B8798
0x4 0x20 @@ -1298,6 +1308,91 @@ map_data_1b60_offset 0x1B9c 23dfe141c7ea4e63ebb3c618a12b48ec 0x4BBDF378 + + + 94641d97a0ecff6f2194e3d0b310d946 + 0x4BC3C470 + + WORLD: 0x0165c1d0 ? + + Position + ======== +
0x17f6b00
Was 0x17f5ab8 + 0x17f6b00 + 0x17f6b08 + 0x17f6b10 + + Map + === +
0x016AE760
+ + * map size in blocks * +
0x016AE780
+
0x016AE784
+
0x016AE788
+ + * map size in tiles * +
0x016AE78C
+
0x016AE790
+
0x016AE794
+ + * Suspected region coords * +
0x016AE798
+
0x016AE79C
+
0x016AE7A0
+ + * World size * (WORDs) +
0x016AFE1C
+
0x016AFE1E
+ + * geology * +
0x16B0574
+
0x16B05BC
+ + Creatures + ========= +
0x166FD0C
+
0x01471fbc
+ + + Materials + ========= + + inorganics vector = WORLD + 0x54B7C = 0x16B0D4C +
0x16B0D4C
+ + +
0x16B0D64
inorg + 0x18 + + +
0x16B0EA0
inorg + 0x154 + + Constructions + ============= + WORLD + 0x108 +
0x165C2D8
+ + Translations + ============ + WORLD + 0x54E50 +
0x016AFFD8
+ WORLD + 0x54E80 +
0x16B1050
+ + Vegetation + ========== + WORLD + 0x15184 +
0x1671354
+ + Buildings + ========= + WORLD + 0x14818 +
0x16709E8
+ WORLD + 0x5D610 +
0x16B97E0
+ 0x4 + 0x20 +
.-"""-. ' \ From 81cf60c0e08189f3acdf1ceff2399aca06174048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 13 Apr 2010 07:36:16 +0200 Subject: [PATCH 05/33] Fixes to creature offsets. Needs more checking. --- examples/creaturedump.cpp | 6 +++--- output/Memory.xml | 32 +++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/examples/creaturedump.cpp b/examples/creaturedump.cpp index a4ddf9739..89016c45f 100644 --- a/examples/creaturedump.cpp +++ b/examples/creaturedump.cpp @@ -332,12 +332,12 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) cout << "from the underworld, "; } cout << endl; - /* + if(creature.flags1.bits.had_mood && (creature.mood == -1 || creature.mood == 8 ) ) { - string artifact_name = DF.TranslateName(creature.artifact_name,englishWords,foreignWords,false); + string artifact_name = Tran->TranslateName(creature.artifact_name,false); cout << "artifact: " << artifact_name << endl; - }*/ + } cout << endl; } diff --git a/output/Memory.xml b/output/Memory.xml index 3739e33b1..81a695cfc 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1135,7 +1135,7 @@ map_data_1b60_offset 0x1B9c 0X1F4 0X21C 0x238 - 0x23C + 0x464 + 0x0 + 0x6c + 0x88 + 0x8C + 0x90 + 0xF8 + 0xFC + 0x110 + 0x114 + 0X120 + 0X1F4 + 0X21C + 0x238 + + + 0x464 + + 0x390 + 0x6D4 + 0x774 + 0x0740 + 0x0758 + 0x834 Materials ========= From 4bcd653732c772bbed49d7828c19f328a6cd3a79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 13 Apr 2010 14:18:09 +0200 Subject: [PATCH 06/33] 0.3.1.2 tag, fixes for attach on Windows --- dfhack/DFProcess-windows.cpp | 20 +++++++++++++++----- examples/suspendtest.cpp | 1 - 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/dfhack/DFProcess-windows.cpp b/dfhack/DFProcess-windows.cpp index 00a3b56d2..7ac82aca9 100644 --- a/dfhack/DFProcess-windows.cpp +++ b/dfhack/DFProcess-windows.cpp @@ -82,11 +82,21 @@ NormalProcess::NormalProcess(uint32_t pid, vector & known_versio // temporarily assign this to allow some checks d->my_handle = hProcess; + d->my_main_thread = 0; // read from this process - uint32_t pe_offset = readDWord(base+0x3C); - read(base + pe_offset , sizeof(pe_header), (uint8_t *)&pe_header); - read(base + pe_offset+ sizeof(pe_header), sizeof(sections) , (uint8_t *)§ions ); - d->my_handle = 0; + try + { + uint32_t pe_offset = readDWord(base+0x3C); + read(base + pe_offset , sizeof(pe_header), (uint8_t *)&pe_header); + read(base + pe_offset+ sizeof(pe_header), sizeof(sections) , (uint8_t *)§ions ); + d->my_handle = 0; + } + catch (exception &) + { + CloseHandle(hProcess); + d->my_handle = 0; + return; + } // see if there's a version entry that matches this process vector::iterator it; @@ -356,7 +366,7 @@ void NormalProcess::readDWord (const uint32_t offset, uint32_t &result) void NormalProcess::read (const uint32_t offset, uint32_t size, uint8_t *target) { - if(ReadProcessMemory(d->my_handle, (int*) offset, target, size, NULL)) + if(!ReadProcessMemory(d->my_handle, (int*) offset, target, size, NULL)) throw Error::MemoryAccessDenied(); } diff --git a/examples/suspendtest.cpp b/examples/suspendtest.cpp index 9e89a2e93..70cbe1816 100644 --- a/examples/suspendtest.cpp +++ b/examples/suspendtest.cpp @@ -27,7 +27,6 @@ int main (void) #endif return 1; } - cout << "Attached, DF should be suspended now" << endl; getline(cin, blah); From 2594cd4eb3908250da0fc58738c030c0af4b2ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 13 Apr 2010 23:21:31 +0200 Subject: [PATCH 07/33] Fix language vector for 0.31.03 --- examples/creaturedump.cpp | 8 ++++++++ output/Memory.xml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/creaturedump.cpp b/examples/creaturedump.cpp index 89016c45f..5f216e92b 100644 --- a/examples/creaturedump.cpp +++ b/examples/creaturedump.cpp @@ -168,6 +168,14 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) cout << ", trans name: " << transName; addendl=true; } + + transName = Tran->TranslateName(creature.name,true); + if(!transName.empty()) + { + cout << ", last name: " << transName; + addendl=true; + } + /* cout << ", likes: "; diff --git a/output/Memory.xml b/output/Memory.xml index 81a695cfc..297c12dc7 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1405,7 +1405,7 @@ map_data_1b60_offset 0x1B9c Translations ============ WORLD + 0x54E50 -
0x016AFFD8
+
0x016B1020
WORLD + 0x54E80
0x16B1050
From e8a3106b1004c95010a7919f9e5da9dae8fc0ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 14 Apr 2010 12:16:56 +0200 Subject: [PATCH 08/33] Plant/Wood materials reading fixed. --- examples/materialtest.cpp | 14 +++++++++++++- output/Memory.xml | 40 ++++++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/examples/materialtest.cpp b/examples/materialtest.cpp index db7e5d2a8..9bc466c2b 100644 --- a/examples/materialtest.cpp +++ b/examples/materialtest.cpp @@ -56,12 +56,24 @@ int main (int numargs, const char ** args) { cout << i << ": " << matgloss[i].id << endl; } + cout << endl << "----==== Organic - trees ====----" << endl; + Materials->ReadWoodMaterials (matgloss); + for(uint32_t i = 0; i < matgloss.size();i++) + { + cout << i << ": " << matgloss[i].id << endl; + } + cout << endl << "----==== Organic - plants ====----" << endl; + Materials->ReadPlantMaterials (matgloss); + for(uint32_t i = 0; i < matgloss.size();i++) + { + cout << i << ": " << matgloss[i].id << endl; + } cout << endl << "----==== Creature types ====----" << endl; vector creature; Materials->ReadCreatureTypes (matgloss); for(uint32_t i = 0; i < matgloss.size();i++) { - cout << i << ": " << matgloss[i].id << endl; + cout << i << ": " << matgloss[i].id << endl ; } #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; diff --git a/output/Memory.xml b/output/Memory.xml index 297c12dc7..6189e55c6 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1178,16 +1178,23 @@ map_data_1b60_offset 0x1B9c Materials ========= - + soil, stone, metal inorganics vector = WORLD + 0x54B7C = 0x16AFD04
0x16afd04
- + wood and plant matter, WORLD + 0x54B94
0x16afd1C
- + plant matter, WORLD + 0x54BAC +
0x16afd34
+ + just wood, WORLD + 0x54BDC +
0x16afd64
+ + creature types actually used for creatures, WORLD + 0x54CD0
0x016AFE58
- + + 0x0 0x6c 0x88 @@ -1363,7 +1367,7 @@ map_data_1b60_offset 0x1B9c 0xFC 0x110 0x114 - 0X120 + 0X120 0X1F4 0X21C 0x238 @@ -1387,15 +1391,21 @@ map_data_1b60_offset 0x1B9c Materials ========= - + soil, stone, metal inorganics vector = WORLD + 0x54B7C = 0x16B0D4C
0x16B0D4C
- -
0x16B0D64
inorg + 0x18 + wood and plant matter, WORLD + 0x54B94 +
0x16B0D64
+ + plant matter, WORLD + 0x54BAC +
0x16B0D7C
+ + just wood, WORLD + 0x54BDC +
0x16B0DAC
- -
0x16B0EA0
inorg + 0x154 + creature types actually used for creatures, WORLD + 0x54CD0 +
0x16B0EA0
Constructions ============= From ab3a842fdb90f1840e6201127da0b6b6e6afe69b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 14 Apr 2010 22:12:02 +0200 Subject: [PATCH 09/33] Support for creature castes --- dfhack/include/modules/Materials.h | 15 +++++++++++++++ dfhack/modules/Materials.cpp | 31 ++++++++++++++++++++++++++++++ examples/creaturedump.cpp | 4 ++-- examples/materialtest.cpp | 19 ++++++++++++++---- output/Memory.xml | 10 ++++++---- 5 files changed, 69 insertions(+), 10 deletions(-) diff --git a/dfhack/include/modules/Materials.h b/dfhack/include/modules/Materials.h index 83a4f203b..0161d02a1 100644 --- a/dfhack/include/modules/Materials.h +++ b/dfhack/include/modules/Materials.h @@ -29,6 +29,20 @@ namespace DFHack char extract_name[128]; }; + struct t_creaturecaste + { + char rawname[128]; + char singular[128]; + char plural[128]; + char adjective[128]; + }; + + struct t_creaturetype + { + char rawname[128]; + vector castes; + }; + class DFHACK_EXPORT Materials { public: @@ -45,6 +59,7 @@ namespace DFHack // TODO: maybe move to creatures? bool ReadCreatureTypes (std::vector & output); + bool ReadCreatureTypesEx (vector & creatures); private: APIPrivate* d; }; diff --git a/dfhack/modules/Materials.cpp b/dfhack/modules/Materials.cpp index 265f5074c..4e2059705 100644 --- a/dfhack/modules/Materials.cpp +++ b/dfhack/modules/Materials.cpp @@ -212,3 +212,34 @@ bool Materials::ReadCreatureTypes (vector & creatures) return ReadNamesOnly(d->p, d->offset_descriptor->getAddress ("creature_type_vector"), creatures ); return true; } + +bool Materials::ReadCreatureTypesEx (vector & creatures) +{ + DfVector p_races (g_pProcess, d->offset_descriptor->getAddress ("creature_type_vector"), 4); + uint32_t castes_vector_offset = d->offset_descriptor->getOffset ("creature_type_caste_vector"); + uint32_t sizeof_string = d->offset_descriptor->getHexValue ("sizeof_string"); + uint32_t size = p_races.getSize(); + uint32_t sizecas = 0; + creatures.clear(); + creatures.reserve (size); + for (uint32_t i = 0; i < size;i++) + { + t_creaturetype mat; + g_pProcess->readSTLString (*(uint32_t *) p_races[i], mat.rawname, sizeof(mat.rawname)); + DfVector p_castes(g_pProcess,(*(uint32_t *) p_races[i]) + castes_vector_offset, 4); + sizecas = p_castes.getSize(); + for (uint32_t j = 0; j < sizecas;j++) + { + t_creaturecaste caste; + uint32_t caste_start = *(uint32_t *)p_castes[j]; + g_pProcess->readSTLString (caste_start, caste.rawname, sizeof(caste.rawname)); + g_pProcess->readSTLString (caste_start + sizeof_string, caste.singular, sizeof(caste.singular)); + g_pProcess->readSTLString (caste_start + 2 * sizeof_string, caste.plural, sizeof(caste.plural)); + g_pProcess->readSTLString (caste_start + 3 * sizeof_string, caste.adjective, sizeof(caste.adjective)); + mat.castes.push_back(caste); + } + creatures.push_back(mat); + } + return true; +} + diff --git a/examples/creaturedump.cpp b/examples/creaturedump.cpp index 5f216e92b..5bd8de0a8 100644 --- a/examples/creaturedump.cpp +++ b/examples/creaturedump.cpp @@ -407,7 +407,7 @@ int main (void) { DFHack::t_creature temp; Creatures->ReadCreature(i,temp); - if(string(creaturestypes[temp.race].id) == "DWARF") + if(string(creaturestypes[temp.race].id) == "HORSE") { cout << "index " << i << " "; @@ -415,7 +415,7 @@ int main (void) addrs.push_back(temp.origin); } } - //interleave_hex(DF,addrs,200); + interleave_hex(DF,addrs,200); /* uint32_t currentIdx; DFHack::t_creature currentCreature; diff --git a/examples/materialtest.cpp b/examples/materialtest.cpp index 9bc466c2b..1f397df41 100644 --- a/examples/materialtest.cpp +++ b/examples/materialtest.cpp @@ -69,11 +69,22 @@ int main (int numargs, const char ** args) cout << i << ": " << matgloss[i].id << endl; } cout << endl << "----==== Creature types ====----" << endl; - vector creature; - Materials->ReadCreatureTypes (matgloss); - for(uint32_t i = 0; i < matgloss.size();i++) + vector creature; + Materials->ReadCreatureTypesEx (creature); + for(uint32_t i = 0; i < creature.size();i++) { - cout << i << ": " << matgloss[i].id << endl ; + cout << i << ": " << creature[i].rawname << endl; + vector & castes = creature[i].castes; + for(uint32_t j = 0; j < castes.size();j++) + { + cout << " [" + << castes[j].rawname << ":" + << castes[j].singular << ":" + << castes[j].plural << ":" + << castes[j].adjective << "] "; + cout << endl; + } + cout << endl; } #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; diff --git a/output/Memory.xml b/output/Memory.xml index 6189e55c6..ed726a1d9 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1191,9 +1191,10 @@ map_data_1b60_offset 0x1B9c just wood, WORLD + 0x54BDC
0x16afd64
- creature types actually used for creatures, WORLD + 0x54CD0 + creature types actually used for creatures, + WORLD + 0x54CD0
0x016AFE58
- + 0x138 + + 0x28C + 0x290 0x464 + + 0x28C + 0x290 0x464 - 0x28C - 0x290 0x464 + 0X120 0X1F4 0X21C 0x238 @@ -1375,7 +1376,7 @@ map_data_1b60_offset 0x1B9c 0xFC 0x110 0x114 - 0X120 + 0X120 0X1F4 0X21C From ac57250f5ed75fea4aa39daca1ee52f2c88786cc Mon Sep 17 00:00:00 2001 From: "U-glouglou\\simon" Date: Mon, 19 Apr 2010 20:05:10 +0200 Subject: [PATCH 27/33] Forgot to remove this debugging help ... --- dfhack/modules/Creatures.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dfhack/modules/Creatures.cpp b/dfhack/modules/Creatures.cpp index ef50735e7..8c83e1ed9 100644 --- a/dfhack/modules/Creatures.cpp +++ b/dfhack/modules/Creatures.cpp @@ -331,7 +331,6 @@ int32_t Creatures::GetDwarfCivId() { if(!d->Inited) return -1; Process * p = d->owner; - printf("civid=%p\n", d->dwarf_civ_id_addr); return p->readDWord(d->dwarf_civ_id_addr); } /* From 8676ba5f071d82baea89e175dd84bd41a1003a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 20 Apr 2010 04:37:45 +0200 Subject: [PATCH 28/33] Extremely basic map feature reading, lives in vector check ... --- dfhack/include/DFTileTypes.h | 206 +++++++++++++++++----------------- dfhack/include/modules/Maps.h | 5 +- examples/veccheck.cpp | 189 +++++++++++++++++++++++++++---- output/Memory.xml | 24 +++- 4 files changed, 296 insertions(+), 128 deletions(-) diff --git a/dfhack/include/DFTileTypes.h b/dfhack/include/DFTileTypes.h index 8931a8422..dc6912be4 100644 --- a/dfhack/include/DFTileTypes.h +++ b/dfhack/include/DFTileTypes.h @@ -417,75 +417,75 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {"glowing floor" ,FLOOR, CYAN_GLOW, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall RD2",WALL,OBSIDIAN,VAR_1}, // 270 - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall R2D",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall R2U",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall RU2",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall L2U",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall LU2",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall L2D",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall LD2",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall LRUD",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall RUD",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall LRD",WALL,OBSIDIAN,VAR_1}, // 280 - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, + {"smooth obsidian wall LRU",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall LUD",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall RD",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall RU",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall LU",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall LD",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall UD",WALL,OBSIDIAN,VAR_1}, + {"smooth obsidian wall LR",WALL,OBSIDIAN,VAR_1}, + {"smooth featstone wall RD2",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall R2D",WALL,FEATSTONE,VAR_1}, // 290 - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall R2U",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall RU2",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall L2U",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall LU2",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall L2D",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall LD2",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall LRUD",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall RUD",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall LRD",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall LRU",WALL,FEATSTONE,VAR_1}, //300 - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth featstone? wall",WALL,FEATSTONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, + {"smooth featstone wall LUD",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall RD",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall RU",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall LU",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall LD",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall UD",WALL,FEATSTONE,VAR_1}, + {"smooth featstone wall LR",WALL,FEATSTONE,VAR_1}, + {"smooth stone wall RD2",WALL,STONE,VAR_1}, + {"smooth stone wall R2D",WALL,STONE,VAR_1}, + {"smooth stone wall R2U",WALL,STONE,VAR_1}, //310 - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, + {"smooth stone wall RU2",WALL,STONE,VAR_1}, + {"smooth stone wall L2U",WALL,STONE,VAR_1}, + {"smooth stone wall LU2",WALL,STONE,VAR_1}, + {"smooth stone wall L2D",WALL,STONE,VAR_1}, + {"smooth stone wall LD2",WALL,STONE,VAR_1}, + {"smooth stone wall LRUD",WALL,STONE,VAR_1}, + {"smooth stone wall RUD",WALL,STONE,VAR_1}, + {"smooth stone wall LRD",WALL,STONE,VAR_1}, + {"smooth stone wall LRU",WALL,STONE,VAR_1}, + {"smooth stone wall LUD",WALL,STONE,VAR_1}, //320 - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, - {"smooth stone wall",WALL,STONE,VAR_1}, + {"smooth stone wall RD",WALL,STONE,VAR_1}, + {"smooth stone wall RU",WALL,STONE,VAR_1}, + {"smooth stone wall LU",WALL,STONE,VAR_1}, + {"smooth stone wall LD",WALL,STONE,VAR_1}, + {"smooth stone wall UD",WALL,STONE,VAR_1}, + {"smooth stone wall LR",WALL,STONE,VAR_1}, {"obsidian fortification",FORTIFICATION,OBSIDIAN,VAR_1}, {"featstone? fortification",FORTIFICATION,FEATSTONE,VAR_1}, {"cracked obsidian wall",WALL,OBSIDIAN,VAR_1}, @@ -494,10 +494,14 @@ namespace DFHack // 330 {"worn obsidian wall",WALL,OBSIDIAN,VAR_1}, {"obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"cracked stone wall",WALL,STONE,VAR_1}, - {"damaged stone wall",WALL,STONE,VAR_1}, - {"worn stone wall",WALL,STONE,VAR_1}, - {"stone wall",WALL,STONE,VAR_1}, + /*MAPTILE_FEATSTONE_WALL_WORN1, + MAPTILE_FEATSTONE_WALL_WORN2, + MAPTILE_FEATSTONE_WALL_WORN3, + MAPTILE_FEATSTONE_WALL,*/ + {"cracked featstone wall",WALL,STONE,VAR_1}, + {"damaged featstone wall",WALL,STONE,VAR_1}, + {"worn featstone wall",WALL,STONE,VAR_1}, + {"featstone wall",WALL,STONE,VAR_1}, {"stone floor",FLOOR,STONE,VAR_1}, {"stone floor",FLOOR,STONE,VAR_2}, {"stone floor",FLOOR,STONE,VAR_3}, @@ -508,16 +512,16 @@ namespace DFHack {"obsidian floor",FLOOR,OBSIDIAN,VAR_2}, {"obsidian floor",FLOOR,OBSIDIAN,VAR_3}, {"obsidian floor",FLOOR,OBSIDIAN,VAR_4}, - {"featstone? floor",FLOOR,FEATSTONE,VAR_1}, - {"featstone? floor",FLOOR,FEATSTONE,VAR_2}, - {"featstone? floor",FLOOR,FEATSTONE,VAR_3}, - {"featstone? floor",FLOOR,FEATSTONE,VAR_4}, - {"grass",FLOOR,GRASS,VAR_1}, - {"grass",FLOOR,GRASS,VAR_2}, + {"featstone floor 1",FLOOR,FEATSTONE,VAR_1}, + {"featstone floor 2",FLOOR,FEATSTONE,VAR_2}, + {"featstone floor 3",FLOOR,FEATSTONE,VAR_3}, + {"featstone floor 4",FLOOR,FEATSTONE,VAR_4}, + {"grass 1",FLOOR,GRASS,VAR_1}, + {"grass 2",FLOOR,GRASS,VAR_2}, // 350 - {"grass",FLOOR,GRASS,VAR_3}, - {"grass",FLOOR,GRASS,VAR_4}, + {"grass 3",FLOOR,GRASS,VAR_3}, + {"grass 4",FLOOR,GRASS,VAR_4}, {"soil floor",FLOOR,SOIL,VAR_1}, {"soil floor",FLOOR,SOIL,VAR_2}, {"soil floor",FLOOR,SOIL,VAR_3}, @@ -533,58 +537,58 @@ namespace DFHack {"damaged ice wall",WALL,ICE,VAR_1}, {"worn ice wall",WALL,ICE,VAR_1}, {"ice wall",WALL,ICE,VAR_1}, - {"river",FLOOR,SOIL,VAR_1}, - {"river",FLOOR,SOIL,VAR_1}, - {"river",FLOOR,SOIL,VAR_1}, - {"river",FLOOR,SOIL,VAR_1}, - {"river",FLOOR,SOIL,VAR_1}, + {"river N",FLOOR,SOIL,VAR_1}, + {"river S",FLOOR,SOIL,VAR_1}, + {"river E",FLOOR,SOIL,VAR_1}, + {"river W",FLOOR,SOIL,VAR_1}, + {"river NW",FLOOR,SOIL,VAR_1}, //370 - {"river",FLOOR,SOIL,VAR_1}, - {"river",FLOOR,SOIL,VAR_1}, - {"river",FLOOR,SOIL,VAR_1}, - {"stream",FLOOR,SOIL,VAR_1}, - {"stream",FLOOR,SOIL,VAR_1}, - {"stream",FLOOR,SOIL,VAR_1}, - {"stream",FLOOR,SOIL,VAR_1}, - {"stream",FLOOR,SOIL,VAR_1}, - {"stream",FLOOR,SOIL,VAR_1}, - {"stream",FLOOR,SOIL,VAR_1}, + {"river NE",FLOOR,SOIL,VAR_1}, + {"river SW",FLOOR,SOIL,VAR_1}, + {"river SE",FLOOR,SOIL,VAR_1}, + {"stream bed N",FLOOR,SOIL,VAR_1}, + {"stream bed S",FLOOR,SOIL,VAR_1}, + {"stream bed E",FLOOR,SOIL,VAR_1}, + {"stream bed W",FLOOR,SOIL,VAR_1}, + {"stream bed NW",FLOOR,SOIL,VAR_1}, + {"stream bed NE",FLOOR,SOIL,VAR_1}, + {"stream bed SW",FLOOR,SOIL,VAR_1}, // 380 - {"stream",FLOOR,SOIL,VAR_1}, + {"stream bed SE",FLOOR,SOIL,VAR_1}, {"stream top",FLOOR,SOIL,VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - {"dry grass",FLOOR,GRASS_DRY,VAR_1}, - {"dry grass",FLOOR,GRASS_DRY,VAR_2}, - {"dry grass",FLOOR,GRASS_DRY,VAR_3}, + {"dry grass 1",FLOOR,GRASS_DRY,VAR_1}, + {"dry grass 2",FLOOR,GRASS_DRY,VAR_2}, + {"dry grass 3",FLOOR,GRASS_DRY,VAR_3}, // 390 - {"dry grass",FLOOR,GRASS_DRY,VAR_4}, + {"dry grass 4",FLOOR,GRASS_DRY,VAR_4}, {"dead tree",TREE_DEAD,SOIL,VAR_1}, {"dead sapling",SAPLING_DEAD,SOIL,VAR_1}, {"dead shrub",SHRUB_DEAD,SOIL,VAR_1}, - {"dead grass",FLOOR,GRASS_DEAD,VAR_1}, - {"dead grass",FLOOR,GRASS_DEAD,VAR_2}, - {"dead grass",FLOOR,GRASS_DEAD,VAR_3}, - {"dead grass",FLOOR,GRASS_DEAD,VAR_4}, - {"grass",FLOOR,GRASS2,VAR_1}, - {"grass",FLOOR,GRASS2,VAR_2}, + {"dead grass 1",FLOOR,GRASS_DEAD,VAR_1}, + {"dead grass 2",FLOOR,GRASS_DEAD,VAR_2}, + {"dead grass 3",FLOOR,GRASS_DEAD,VAR_3}, + {"dead grass 4",FLOOR,GRASS_DEAD,VAR_4}, + {"grass B1",FLOOR,GRASS2,VAR_1}, + {"grass B2",FLOOR,GRASS2,VAR_2}, // 400 - {"grass",FLOOR,GRASS2,VAR_3}, - {"grass",FLOOR,GRASS2,VAR_4}, + {"grass B3",FLOOR,GRASS2,VAR_3}, + {"grass B4",FLOOR,GRASS2,VAR_4}, {"boulder",BOULDER,STONE,VAR_1}, {"obsidian boulder",BOULDER,OBSIDIAN,VAR_1}, {"featstone? boulder",BOULDER,FEATSTONE,VAR_1}, - {"pebbles",PEBBLES,STONE,VAR_1}, - {"pebbles",PEBBLES,STONE,VAR_2}, - {"pebbles",PEBBLES,STONE,VAR_3}, - {"pebbles",PEBBLES,STONE,VAR_4}, + {"pebbles 1",PEBBLES,STONE,VAR_1}, + {"pebbles 2",PEBBLES,STONE,VAR_2}, + {"pebbles 3",PEBBLES,STONE,VAR_3}, + {"pebbles 4",PEBBLES,STONE,VAR_4}, {"obsidian shards",PEBBLES,OBSIDIAN,VAR_1}, // 410 diff --git a/dfhack/include/modules/Maps.h b/dfhack/include/modules/Maps.h index 721227362..2e03d54ce 100644 --- a/dfhack/include/modules/Maps.h +++ b/dfhack/include/modules/Maps.h @@ -114,9 +114,10 @@ namespace DFHack e_traffic traffic : 2; // needs enum unsigned int flow_forbid : 1; // what? unsigned int liquid_static : 1; - unsigned int moss : 1;// I LOVE MOSS - unsigned int feature_present : 1; // another wtf... is this required for magma pipes to work? + unsigned int feature_type_1 : 1; // this tile is a part of a feature + unsigned int feature_type_2 : 1; // this tile is a part of a feature unsigned int liquid_character : 2; // those ripples on streams? + }; union t_designation diff --git a/examples/veccheck.cpp b/examples/veccheck.cpp index adc318a5b..232021890 100644 --- a/examples/veccheck.cpp +++ b/examples/veccheck.cpp @@ -22,9 +22,76 @@ using namespace std; #include #include #include "miscutils.h" +#include using namespace DFHack; +/* +int __userpurge get_feature_at(__int16 tZ, __int16 tY, int world_base, signed __int16 tX) +{ + int block; // ebp@1 + signed __int16 __tX; // di@1 + signed int _tY; // esi@1 + int designation; // eax@2 + int _tX; // ecx@2 + signed int v9; // eax@4 + int v10; // edx@4 + __int64 region_x_local; // qax@4 + __int16 v12; // cx@4 + __int16 v13; // ax@5 + int v14; // esi@5 + int result; // eax@7 + unsigned int some_stuff; // ebp@10 + int v17; // edx@11 + int _designation; // [sp+10h] [bp+4h]@2 + __tX = tX; + LOWORD(_tY) = tY; + block = getBlock(world_base, tX, tY, tZ); + if ( !block ) + goto LABEL_17; + _tX = tX; + _tY = (signed __int16)_tY; + designation = *(_DWORD *)(block + 0x29C + 4 * ((signed __int16)_tY % 16 + 16 * tX % 16)); + _designation = designation; + if ( designation & 0x10000000 && *(_WORD *)(block + 0x2C) != -1 )// first feature_present bit - adamantine + { + region_x_local = __tX / 48 + *(_DWORD *)(world_base + 0x525C8);// tile_x / 48 + region_x + v12 = ((BYTE4(region_x_local) & 0xF) + (_DWORD)region_x_local) >> 4; + WORD2(region_x_local) = (_tY / 48 + *(_DWORD *)(world_base + 0x525CC)) / 16;// tile_y / 48 + region_y + v9 = v12; + _tX = SWORD2(region_x_local); + v10 = *(_DWORD *)(*(_DWORD *)(*(_DWORD *)(world_base + 0x54440) + 4 * (v9 >> 4)) + + 16 * (SWORD2(region_x_local) >> 4) + + 4); + if ( v10 ) + { + _tX %= 16; + v14 = v10 + 24 * ((signed __int16)_tX + 16 * v9 % 16); + v13 = *(_WORD *)(block + 0x2C); + if ( v13 >= 0 ) + { + _tX = (*(_DWORD *)(v14 + 16) - *(_DWORD *)(v14 + 12)) >> 2; + if ( v13 < (unsigned int)_tX ) + return *(_DWORD *)sub_519100(_tX, v10); + } + } + designation = _designation; + } + if ( designation & 0x20000000 && (some_stuff = *(_DWORD *)(block + 0x30), some_stuff != -1) )// second feature_present bit - slade and hell + { + v17 = (*(_DWORD *)(world_base + 0x54384) - *(_DWORD *)(world_base + 0x54380)) >> 2; + if ( some_stuff >= v17 ) + _invalid_parameter_noinfo(_tX, v17); + result = *(_DWORD *)(*(_DWORD *)(*(_DWORD *)(world_base + 0x54380) + 4 * some_stuff) + 0x100); + } + else + { +LABEL_17: + result = 0; + } + return result; +} +*/ int main (int numargs, const char ** args) { DFHack::API DF("Memory.xml"); @@ -40,10 +107,25 @@ int main (int numargs, const char ** args) #endif return 1; } - /* - DFHack::Position *Pos = DF.getPosition(); + DFHack::Position *Pos = DF.getPosition(); + DFHack::memory_info* mem = DF.getMemoryInfo(); DFHack::Maps *Maps = DF.getMaps(); + DFHack::Process * p = DF.getProcess(); + uint32_t designatus = mem->getOffset("map_data_designation"); + uint32_t block_feature1 = mem->getOffset("map_data_feature1"); + uint32_t block_feature2 = mem->getOffset("map_data_feature2"); + uint32_t region_x_offset = mem->getAddress("region_x"); + uint32_t region_y_offset = mem->getAddress("region_y"); + uint32_t region_z_offset = mem->getAddress("region_z"); + uint32_t feature1_start_ptr = mem->getAddress("feature1_start_ptr"); + uint32_t regionX, regionY, regionZ; + + // read position of the region inside DF world + p->readDWord (region_x_offset, regionX); + p->readDWord (region_y_offset, regionY); + p->readDWord (region_z_offset, regionZ); + Maps->Start(); int32_t cx, cy, cz; @@ -57,29 +139,92 @@ int main (int numargs, const char ** args) mapblock40d block; if(Maps->ReadBlock40d(bx,by,cz,&block)) { + printf("block addr: 0x%x\n", block.origin); int16_t tiletype = block.tiletypes[tx][ty]; - cout << tiletype << endl; - } - } - */ - vector classIdStrings; - DFHack::memory_info * minfo = DF.getMemoryInfo(); - if(!minfo) - { - cerr <<"FAIL!" << endl; - return 1; - } - for(int i = 0; ; i++) - { - string temp; - if(!minfo->resolveClassIDToClassname(i, temp)) - { - break; + naked_designation &des = block.designation[tx][ty].bits; + uint32_t &desw = block.designation[tx][ty].whole; + print_bits(block.designation[tx][ty].whole,cout); + cout << endl; + print_bits(block.occupancy[tx][ty].whole,cout); + cout << endl; + // tiletype + cout <<"tiletype: " << tiletype; + if(tileTypeTable[tiletype].name) + cout << " = " << tileTypeTable[tiletype].name; + cout << endl; + // feature present + if(des.feature_type_1) + { + cout << "feature type 1 present: " << p->readDWord(block.origin + block_feature1) << endl; + int32_t idx = p->readDWord(block.origin + block_feature1); + if(idx != -1) + { + uint64_t region_x_local = cx / 48 + regionX; + // blah, dumb disassembly. too tired to think + uint16_t v12 = ((uint8_t(region_x_local) & 0xF) + (uint32_t)region_x_local) >> 4; + region_x_local = (cy / 48 + regionY) / 16; + uint32_t base = p->readDWord(feature1_start_ptr); + uint32_t array_elem = p->readDWord(base + (v12 >> 4) * 4); + uint32_t wtf = p->readDWord(array_elem + 16 * (int16_t(region_x_local) >> 4) + 4) ; + if(wtf) + { + uint32_t feat_vector = wtf + 24 * (int16_t)tx + 16 * v12 % 16; + DfVector p_features(p, feat_vector); + string name = p->readClassName(p->readDWord( p_features[idx] )); + cout << name << endl; + } + } + } + if(des.feature_type_2) + { + int32_t idx = p->readDWord(block.origin + block_feature2); + cout << "feature type 2 present: " << idx << endl; + if(idx != -1) + { + DfVector p_features (p,mem->getAddress("feature2_vector")); + if(idx < p_features.size()) + { + uint32_t feat_ptr = p->readDWord(p_features[idx] + mem->getOffset("feature2_funcptr_")); + printf("feature descriptor?: 0x%x\n", feat_ptr); + string name = p->readClassName(p->readDWord( feat_ptr)); + cout << name << endl; + //string SHMProcess::readClassName (uint32_t vptr) + } + } + } + // biome, geolayer + cout << "biome: " << des.biome << endl; + cout << "geolayer: " << des.geolayer_index << endl; + // liquids + if(des.flow_size) + { + if(des.liquid_type == DFHack::liquid_magma) + cout <<"magma: "; + else cout <<"water: "; + cout << des.flow_size << endl; + } + if(des.flow_forbid) + cout << "flow forbid" << endl; + if(des.pile) + cout << "stockpile?" << endl; + if(des.rained) + cout << "rained?" << endl; + if(des.smooth) + cout << "smooth?" << endl; + uint32_t designato = block.origin + designatus + (tx * 16 + ty) * sizeof(t_designation); + printf("designation offset: 0x%x\n", designato); + /* + block.designation[tx][ty].bits.moss = 1; + block.designation[tx][ty].bits.geolayer_index = 15; + block.tiletypes[tx][ty] = 344; + + print_bits(block.designation[tx][ty].whole,cout); + Maps->WriteDesignations(bx,by,cz,&(block.designation)); + Maps->WriteTileTypes(bx,by,cz,&(block.tiletypes)); + */ + } - classIdStrings.push_back(temp); } - for (int i = 0; i < classIdStrings.size(); i++) - cout << i << ": " << classIdStrings[i] << endl; #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); diff --git a/output/Memory.xml b/output/Memory.xml index 647c0eb36..9924e696e 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1061,6 +1061,15 @@ size=212 0x179c 0x1D9C 0x0D9c + 0x2C adamantine? + 0x30 hell? + + WORLD + 0x54374 +
0x16AF4FC
+ 0x100 + WORLD + 0x54440 +
0x16AF5C8
+