From 1f2782d5b86ee62d821ec0c7e33833048fc06b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 29 Feb 2012 23:58:52 +0100 Subject: [PATCH] Get rid of pointless old code --- tools/examples/CMakeLists.txt | 43 - tools/examples/buildingsdump.cpp | 179 ---- tools/examples/construction_dump.cpp | 95 -- tools/examples/creaturedump.cpp | 528 ---------- tools/examples/dfitemdump.cpp | 121 --- tools/examples/engravingdump.cpp | 105 -- tools/examples/hotkeynotedump.cpp | 66 -- tools/examples/materialtest.cpp | 149 --- tools/examples/processenum.cpp | 146 --- tools/examples/settlementdump.cpp | 85 -- tools/examples/spatterdump.cpp | 197 ---- tools/examples/treedump.cpp | 146 --- tools/playground/blockflags.cpp | 66 -- tools/playground/dftry.cpp | 133 --- tools/playground/findnameindexes.cpp | 111 --- tools/playground/hexsearch2.c | 1355 -------------------------- tools/playground/hexsearch2.h | 219 ----- tools/playground/lumberjack.cpp | 5 - tools/playground/moodump.cpp | 119 --- tools/playground/paths.cpp | 31 - tools/playground/primitives.cpp | 27 - tools/playground/printtiletypes.cpp | 100 -- tools/playground/renamer.cpp | 470 --------- tools/playground/test.c | 58 -- tools/playground/typeblocks.cpp | 43 - 25 files changed, 4597 deletions(-) delete mode 100644 tools/examples/CMakeLists.txt delete mode 100644 tools/examples/buildingsdump.cpp delete mode 100644 tools/examples/construction_dump.cpp delete mode 100644 tools/examples/creaturedump.cpp delete mode 100644 tools/examples/dfitemdump.cpp delete mode 100644 tools/examples/engravingdump.cpp delete mode 100644 tools/examples/hotkeynotedump.cpp delete mode 100644 tools/examples/materialtest.cpp delete mode 100644 tools/examples/processenum.cpp delete mode 100644 tools/examples/settlementdump.cpp delete mode 100644 tools/examples/spatterdump.cpp delete mode 100644 tools/examples/treedump.cpp delete mode 100644 tools/playground/blockflags.cpp delete mode 100644 tools/playground/dftry.cpp delete mode 100644 tools/playground/findnameindexes.cpp delete mode 100644 tools/playground/hexsearch2.c delete mode 100644 tools/playground/hexsearch2.h delete mode 100644 tools/playground/lumberjack.cpp delete mode 100644 tools/playground/moodump.cpp delete mode 100644 tools/playground/paths.cpp delete mode 100644 tools/playground/primitives.cpp delete mode 100644 tools/playground/printtiletypes.cpp delete mode 100644 tools/playground/renamer.cpp delete mode 100644 tools/playground/test.c delete mode 100644 tools/playground/typeblocks.cpp diff --git a/tools/examples/CMakeLists.txt b/tools/examples/CMakeLists.txt deleted file mode 100644 index 43979af44..000000000 --- a/tools/examples/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -if(NOT DEFINED DFHACK_CONSISTENCY) - MESSAGE(FATAL_ERROR "Please build the whole thing, not parts. You can turn parts on/off using options.") -ENDIF() - -# this is required to ensure we use the right configuration for the system. -IF(UNIX) - add_definitions(-DLINUX_BUILD) -ENDIF(UNIX) - -# buildingsdump - dump buildings and their raw data filtered by type -DFHACK_TOOL(dfbuildingsdump buildingsdump.cpp) - -# constructiondump - dump engravings! -DFHACK_TOOL(dfengravingdump engravingdump.cpp) - -# constructiondump - dump constructions! -DFHACK_TOOL(dfconstructiondump construction_dump.cpp) - -# creaturedump - basic creature dump - a test of the creature related exports -DFHACK_TOOL(dfcreaturedump creaturedump.cpp) - -# materialtest - just list the first material of each type -DFHACK_TOOL(dfmaterialtest materialtest.cpp) - -# itemdump - dump the item under the cursor -DFHACK_TOOL(dfitemdump dfitemdump.cpp) - -# hotkeynotedump - dumps the hotkeys and notes for the loaded map -# Author: belal -DFHACK_TOOL(dfhotkeynotedump hotkeynotedump.cpp) - -# settlementdump - dumps the settlements on the loaded map -# Author: belal -# DFHACK_TOOL(dfsettlementdump settlementdump.cpp) - -# treedump - dump them trees! -DFHACK_TOOL(dftreedump treedump.cpp) - -# spatterdump - dump spatter 'veins' -DFHACK_TOOL(dfspatterdump spatterdump.cpp) - -# processenum - demonstrates the use of ProcessEnumerator -DFHACK_TOOL(dfprocessenum processenum.cpp) diff --git a/tools/examples/buildingsdump.cpp b/tools/examples/buildingsdump.cpp deleted file mode 100644 index 9dd5fb13e..000000000 --- a/tools/examples/buildingsdump.cpp +++ /dev/null @@ -1,179 +0,0 @@ -// Building dump - -#include -#include -#include -#include -#include -#include -//using namespace std; - -#define DFHACK_WANT_MISCUTILS -#include - -void doWordPerLine(DFHack::Context *DF, DFHack::VersionInfo * mem, - DFHack::Buildings * Bld, uint32_t numBuildings, - const char* type, int lines) -{ - std::cout << numBuildings << std::endl; - std::vector < uint32_t > addresses; - for(uint32_t i = 0; i < numBuildings; i++) - { - DFHack::t_building temp; - Bld->Read(i, temp); - if(temp.type != 0xFFFFFFFF) // check if type isn't invalid - { - std::string typestr; - mem->resolveClassIDToClassname(temp.type, typestr); - std::cout << typestr << std::endl; - if(typestr == type) - addresses.push_back(temp.origin); - } - else - { - // couldn't translate type, print out the vtable - std::cout << "unknown vtable: " << temp.vtable << std::endl; - } - } - - if (addresses.empty()) - { - std::cout << "No buildings matching '" << type << "'" << endl; - return; - } - - interleave_hex(DF,addresses,lines / 4); -} - -void doUnderCursor(DFHack::Context *DF, DFHack::VersionInfo * mem, - DFHack::Buildings * Bld, uint32_t numBuildings, - int32_t x, int32_t y, int32_t z) -{ - std::map custom_workshop_types; - Bld->ReadCustomWorkshopTypes(custom_workshop_types); - - uint32_t num_under_cursor = 0; - - for(uint32_t i = 0; i < numBuildings; i++) - { - DFHack::t_building temp; - Bld->Read(i, temp); - if( (uint32_t)x >= temp.x1 - && (uint32_t)x <= temp.x2 - && (uint32_t)y >= temp.y1 - && (uint32_t)y <= temp.y2 - && (uint32_t)z == temp.z - ) - { - num_under_cursor++; - std::string typestr; - 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, 34*16); - } - } - - if (num_under_cursor == 0) - std::cout << "No buildings present under cursor." << endl; -} - -void doListAll(DFHack::VersionInfo * mem, DFHack::Buildings * Bld, - uint32_t numBuildings) -{ - std::cout << "Num buildings present: " << numBuildings << std::endl; - for(uint32_t i = 0; i < numBuildings; i++) - { - DFHack::t_building temp; - Bld->Read(i, temp); - std::string typestr; - mem->resolveClassIDToClassname(temp.type, typestr); - printf("Address 0x%x, type %d (%s), Coord %d/%d/%d\n", temp.origin, - temp.type, typestr.c_str(), temp.x1,temp.y1,temp.z); - } -} - -void doFinish(DFHack::Context *DF) -{ - DF->Detach(); - #ifndef LINUX_BUILD - std::cout << "Done. Press any key to continue" << std::endl; - cin.ignore(); - #endif -} - -int main (int argc,const char* argv[]) -{ - int lines = 16; - bool word_per_line = false; - if (argc == 3) - { - std::string num = argv[2]; //blah. I don't care - std::istringstream ins; // Declare an input string stream. - ins.str(num); // Specify string to read. - ins >> lines; // Reads the integers from the string. - word_per_line = true; - } - - DFHack::ContextManager DFMgr ("Memory.xml"); - DFHack::Context *DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (std::exception& e) - { - std::cerr << e.what() << std::endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - DFHack::VersionInfo * mem = DF->getMemoryInfo(); - DFHack::Buildings * Bld = DF->getBuildings(); - DFHack::Gui * Gui = DF->getGui(); - - uint32_t numBuildings; - if(!Bld->Start(numBuildings)) - { - std::cerr << "buildings not supported for this DF version" << std::endl; - doFinish(DF); - return 1; - } - - if (numBuildings == 0) - { - cout << "No buildings on site." << endl; - doFinish(DF); - return 0; - } - - if (word_per_line) - doWordPerLine(DF, mem, Bld, numBuildings, argv[1], lines); - else - { - int32_t x,y,z; - Gui->getCursorCoords(x,y,z); - - if(x != -30000) - doUnderCursor(DF, mem, Bld, numBuildings, x, y, z); - else - doListAll(mem, Bld, numBuildings); - } - - Bld->Finish(); - - doFinish(DF); - - return 0; -} diff --git a/tools/examples/construction_dump.cpp b/tools/examples/construction_dump.cpp deleted file mode 100644 index a1d8c12ae..000000000 --- a/tools/examples/construction_dump.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Just show some position data - -#include -#include -#include -#include -#include -#include -#include -#include - -#define DFHACK_WANT_MISCUTILS -#include -using namespace DFHack; - -int main (int numargs, const char ** args) -{ - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context* DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (std::exception& e) - { - std::cerr << e.what() << std::endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - DFHack::Gui *Gui = DF->getGui(); - - DFHack::Constructions *Cons = DF->getConstructions(); - DFHack::Materials *Mats = DF->getMaterials(); - Mats->ReadInorganicMaterials(); - Mats->ReadOrganicMaterials(); - uint32_t numConstr; - Cons->Start(numConstr); - - int32_t cx, cy, cz; - Gui->getCursorCoords(cx,cy,cz); - if(cx != -30000) - { - t_construction con; - for(uint32_t i = 0; i < numConstr; i++) - { - Cons->Read(i,con); - if(cx == con.x && cy == con.y && cz == con.z) - { - printf("Construction %d/%d/%d @ 0x%x\n", con.x, con.y, con.z,con.origin); - // inorganic stuff - we can recognize that - printf("Material: form %d, type %d, index %d\n",con.form, con.mat_type, con.mat_idx); - std::string matstr = "unknown"; - if(con.mat_type == 0) - { - if(con.mat_idx != 0xffffffff) - matstr = Mats->inorganic[con.mat_idx].id; - else matstr = "inorganic"; - } - if(con.mat_type == 420) - { - if(con.mat_idx != 0xffffffff) - matstr = Mats->organic[con.mat_idx].id; - else matstr = "organic"; - } - switch(con.form) - { - case constr_bar: - printf("It is made of %s bars!\n",matstr.c_str()); - break; - case constr_block: - printf("It is made of %s blocks!\n",matstr.c_str()); - break; - case constr_boulder: - printf("It is made of %s stones!\n",matstr.c_str()); - break; - case constr_logs: - printf("It is made of %s logs!\n",matstr.c_str()); - break; - default: - printf("It is made of something we don't know yet! The material is %s.\n",matstr.c_str()); - } - hexdump(DF,con.origin,32); - } - } - } - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -} diff --git a/tools/examples/creaturedump.cpp b/tools/examples/creaturedump.cpp deleted file mode 100644 index 32beae150..000000000 --- a/tools/examples/creaturedump.cpp +++ /dev/null @@ -1,528 +0,0 @@ -// Creature dump - -#include -#include -#include -#include -#include -using namespace std; - -#define DFHACK_WANT_MISCUTILS -#include - -enum likeType -{ - FAIL = 0, - MATERIAL = 1, - ITEM = 2, - FOOD = 3 -}; - -DFHack::Materials * Materials; -DFHack::VersionInfo *mem; -vector< vector > englishWords; -vector< vector > foreignWords; -DFHack::Creatures * Creatures = NULL; -uint32_t current_year; -uint32_t current_tick; -/* -likeType printLike40d(DFHack::t_like like, const matGlosses & mat,const vector< vector > & itemTypes) -{ // The function in DF which prints out the likes is a monster, it is a huge switch statement with tons of options and calls a ton of other functions as well, - //so I am not going to try and put all the possibilites here, only the low hanging fruit, with stones and metals, as well as items, - //you can easily find good canidates for military duty for instance - //The ideal thing to do would be to call the df function directly with the desired likes, the df function modifies a string, so it should be possible to do... - if(like.active){ - if(like.type ==0){ - switch (like.material.type) - { - case 0: - cout << mat.woodMat[like.material.index].name; - return(MATERIAL); - case 1: - cout << mat.stoneMat[like.material.index].name; - return(MATERIAL); - case 2: - cout << mat.metalMat[like.material.index].name; - return(MATERIAL); - case 12: // don't ask me why this has such a large jump, maybe this is not actually the matType for plants, but they all have this set to 12 - cout << mat.plantMat[like.material.index].name; - return(MATERIAL); - case 32: - cout << mat.plantMat[like.material.index].name; - return(MATERIAL); - case 121: - cout << mat.creatureMat[like.material.index].name; - return(MATERIAL); - default: - return(FAIL); - } - } - else if(like.type == 4 && like.itemIndex != -1){ - switch(like.itemClass) - { - case 24: - cout << itemTypes[0][like.itemIndex].name; - return(ITEM); - case 25: - cout << itemTypes[4][like.itemIndex].name; - return(ITEM); - case 26: - cout << itemTypes[8][like.itemIndex].name; - return(ITEM); - case 27: - cout << itemTypes[9][like.itemIndex].name; - return(ITEM); - case 28: - cout << itemTypes[10][like.itemIndex].name; - return(ITEM); - case 29: - cout << itemTypes[7][like.itemIndex].name; - return(ITEM); - case 38: - cout << itemTypes[5][like.itemIndex].name; - return(ITEM); - case 63: - cout << itemTypes[11][like.itemIndex].name; - return(ITEM); - case 68: - case 69: - cout << itemTypes[6][like.itemIndex].name; - return(ITEM); - case 70: - cout << itemTypes[1][like.itemIndex].name; - return(ITEM); - default: - // cout << like.itemClass << ":" << like.itemIndex; - return(FAIL); - } - } - else if(like.material.type != -1){// && like.material.index == -1){ - if(like.type == 2){ - switch(like.itemClass) - { - case 52: - case 53: - case 58: - cout << mat.plantMat[like.material.type].name; - return(FOOD); - case 72: - if(like.material.type =! 10){ // 10 is for milk stuff, which I don't know how to do - cout << mat.plantMat[like.material.index].extract_name; - return(FOOD); - } - return(FAIL); - case 74: - cout << mat.plantMat[like.material.index].drink_name; - return(FOOD); - case 75: - cout << mat.plantMat[like.material.index].food_name; - return(FOOD); - case 47: - case 48: - cout << mat.creatureMat[like.material.type].name; - return(FOOD); - default: - return(FAIL); - } - } - } - } - return(FAIL); -} -*/ - -void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature) -{ - uint32_t dayoflife; - cout << "address: " << hex << creature.origin << dec << ", creature race: " << creature.race << "/" << Materials->raceEx[creature.race].rawname - << "[" << Materials->raceEx[creature.race].tile_character - << "," << Materials->raceEx[creature.race].tilecolor.fore - << "," << Materials->raceEx[creature.race].tilecolor.back - << "," << Materials->raceEx[creature.race].tilecolor.bright - << "]" - << ", position: " << creature.x << "x " << creature.y << "y "<< creature.z << "z" << endl; - bool addendl = false; - if(creature.name.first_name[0]) - { - cout << "first name: " << creature.name.first_name; - addendl = true; - } - if(creature.name.nickname[0]) - { - cout << ", nick name: " << creature.name.nickname; - addendl = true; - } - - DFHack::Translation *Tran = DF->getTranslation(); - DFHack::VersionInfo *mem = DF->getMemoryInfo(); - - string transName = Tran->TranslateName(creature.name,false); - if(!transName.empty()) - { - cout << ", trans name: " << transName; - addendl=true; - } - - transName = Tran->TranslateName(creature.name,true); - if(!transName.empty()) - { - cout << ", last name: " << transName; - addendl=true; - } - - if(creature.civ) - { - cout << ", civilization: " << creature.civ; - addendl = true; - } - - /* - cout << ", likes: "; - for(uint32_t i = 0;igetProfession(creature.profession) << "(" << (int) creature.profession << ")"; - - if(creature.custom_profession[0]) - { - cout << ", custom profession: " << creature.custom_profession; - } - - if(creature.current_job.active) - { - try{ - cout << ", current job: " << mem->getJob(creature.current_job.jobId); - } - catch(exception & e) - { - cout << e.what() << endl; - } - } - - cout << endl; - dayoflife = creature.birth_year*12*28 + creature.birth_time/1200; - cout << "Born on the year " << creature.birth_year << ", month " << (creature.birth_time/1200/28) << ", day " << ((creature.birth_time/1200) % 28 + 1) << ", " << dayoflife << " days lived." << endl; - cout << "Appearance : "; - for(unsigned int i = 0; iraceEx[creature.race].castes[creature.caste].ColorModifier[i].part << " "; - uint32_t color = Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].colorlist[creature.color[i]]; - if(colorcolor.size()) - { - cout << Materials->color[color].name << "[" - << (unsigned int) (Materials->color[color].red*255) << ":" - << (unsigned int) (Materials->color[color].green*255) << ":" - << (unsigned int) (Materials->color[color].blue*255) << "]"; - } - else if (color < Materials->alldesc.size()) - { - cout << Materials->alldesc[color].id; - } - else - { - cout << "Unknown color " << color << endl; - } - if( Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate > 0 ) - { - if( (Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate <= dayoflife) && - (Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].enddate > dayoflife) ) - cout << "[active]"; - else - cout << "[inactive]"; - } - cout << " - "; - - } - cout << endl; - cout << "happiness: " << creature.happiness - << ", strength: " << creature.strength.level - << ", agility: " << creature.agility.level - << ", toughness: " << creature.toughness.level - << ", endurance: " << creature.endurance.level - << ", recuperation: " << creature.recuperation.level - << ", disease resistance: " << creature.disease_resistance.level - //<< ", money: " << creature.money - << ", id: " << creature.id; - /* - if(creature.squad_leader_id != -1) - { - cout << ", squad_leader_id: " << creature.squad_leader_id; - } - if(creature.mood != -1){ - cout << ", mood: " << creature.mood << " "; - }*/ - cout << ", sex: "; - if(creature.sex == 0) - { - cout << "Female"; - } - else - { - cout <<"Male"; - } - cout << endl; - - if((creature.mood != -1) && (creature.mood<5)) - { - cout << "mood: " << creature.mood << ", skill: " << mem->getSkill(creature.mood_skill) << endl; - vector mymat; - if(Creatures->ReadJob(&creature, mymat)) - { - 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].subType, mymat[i].subIndex, mymat[i].index, mymat[i].flags); - } - } - } - - // FIXME: TOO BAD... - std::vector inventory; - if( Creatures->ReadInventoryPtr(creature.origin, inventory)) - { - DFHack::Items * Items = DF->getItems(); - printf("\tInventory:\n"); - for(unsigned int i = 0; i < inventory.size(); i++) - { - DFHack::dfh_item item; - if (Items->readItem(inventory[i], item)) - printf("\t\t%d: %s\n", item.id, Items->getItemDescription(item, Materials).c_str()); - } - } - - std::vector owned; - if( Creatures->ReadOwnedItemsPtr(creature.origin, owned)) - { - DFHack::Items * Items = DF->getItems(); - printf("\tOwns:\n"); - for (int i = 0; i < owned.size(); i++) { - uint32_t pitem = Items->findItemByID(owned[i]); - DFHack::dfh_item item; - if (!pitem || !Items->readItem(pitem,item)) - pitem = 0; - printf("\t\t%d: %s\n", owned[i], - pitem ? Items->getItemDescription(item, Materials).c_str() : "?"); - } - } - - /* - if(creature.pregnancy_timer > 0) - cout << "gives birth in " << creature.pregnancy_timer/1200 << " days. "; - cout << "Blood: " << creature.blood_current << "/" << creature.blood_max << " bleeding: " << creature.bleed_rate; - */ - cout << endl; - - if(creature.has_default_soul) - { - //skills - cout << "Skills" << endl; - for(unsigned int i = 0; i < creature.defaultSoul.numSkills;i++) - { - if(i > 0) - { - cout << ", "; - } - try - { - cout << mem->getSkill(creature.defaultSoul.skills[i].id) << ": " << creature.defaultSoul.skills[i].rating; - } - catch(DFHack::Error::AllMemdef &e) - { - cout << "Unknown skill! : " << creature.defaultSoul.skills[i].id <<", rating: " << creature.defaultSoul.skills[i].rating << endl; - cout << e.what() << endl; - } - } - 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; - - // labors - cout << "Labors" << endl; - for(unsigned int i = 0; i < NUM_CREATURE_LABORS;i++) - { - if(!creature.labors[i]) - continue; - string laborname; - try - { - laborname = mem->getLabor(i); - } - catch(exception &) - { - break; - } - cout << laborname << ", "; - } - cout << endl; - } - /* - * FLAGS 1 - */ - cout << "flags1: "; - print_bits(creature.flags1.whole, cout); - cout << endl; - if(creature.flags1.bits.dead) - { - cout << "dead "; - } - if(creature.flags1.bits.on_ground) - { - cout << "on the ground, "; - } - if(creature.flags1.bits.skeleton) - { - cout << "skeletal "; - } - if(creature.flags1.bits.zombie) - { - cout << "zombie "; - } - if(creature.flags1.bits.tame) - { - cout << "tame "; - } - if(creature.flags1.bits.royal_guard) - { - cout << "royal_guard "; - } - if(creature.flags1.bits.fortress_guard) - { - cout << "fortress_guard "; - } - /* - * FLAGS 2 - */ - cout << endl << "flags2: "; - print_bits(creature.flags2.whole, cout); - cout << endl; - if(creature.flags2.bits.killed) - { - cout << "killed by kill function, "; - } - if(creature.flags2.bits.resident) - { - cout << "resident, "; - } - if(creature.flags2.bits.gutted) - { - cout << "gutted, "; - } - if(creature.flags2.bits.slaughter) - { - cout << "marked for slaughter, "; - } - if(creature.flags2.bits.underworld) - { - cout << "from the underworld, "; - } - cout << endl; - - if(creature.flags1.bits.had_mood && (creature.mood == -1 || creature.mood == 8 ) ) - { - string artifact_name = Tran->TranslateName(creature.artifact_name,false); - cout << "artifact: " << artifact_name << endl; - } - - - cout << endl; -} - - -int main (int numargs, char ** args) -{ - DFHack::World * World; - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context* DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - string check = ""; - if(numargs == 2) - check = args[1]; - - Creatures = DF->getCreatures(); - Materials = DF->getMaterials(); - World = DF->getWorld(); - current_year = World->ReadCurrentYear(); - current_tick = World->ReadCurrentTick(); - DFHack::Translation * Tran = DF->getTranslation(); - - uint32_t numCreatures; - if(!Creatures->Start(numCreatures)) - { - cerr << "Can't get creatures" << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - if(!numCreatures) - { - cerr << "No creatures to print" << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - mem = DF->getMemoryInfo(); - Materials->ReadInorganicMaterials(); - Materials->ReadOrganicMaterials(); - Materials->ReadWoodMaterials(); - Materials->ReadPlantMaterials(); - Materials->ReadCreatureTypes(); - Materials->ReadCreatureTypesEx(); - //Materials->ReadDescriptorColors(); - - if(!Tran->Start()) - { - cerr << "Can't get name tables" << endl; - return 1; - } - vector addrs; - for(uint32_t i = 0; i < numCreatures; i++) - { - DFHack::t_creature temp; - Creatures->ReadCreature(i,temp); - if(check.empty() || string(Materials->raceEx[temp.race].rawname) == check) - { - printCreature(DF,temp); - addrs.push_back(temp.origin); - } - } - if(addrs.size() <= 10) - { - interleave_hex(DF,addrs,200); - } - Creatures->Finish(); - DF->Detach(); - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -} diff --git a/tools/examples/dfitemdump.cpp b/tools/examples/dfitemdump.cpp deleted file mode 100644 index 655caf409..000000000 --- a/tools/examples/dfitemdump.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Simple, pretty item dump example. - */ - -#include -#include -#include -#include -#include -#include -#include -using namespace std; -#define DFHACK_WANT_MISCUTILS -#include -#include - -int main (int argc, char *argv[]) -{ - bool print_refs = false; - bool print_hex = false; - bool print_acc = false; - - for(int i = 1; i < argc; i++) - { - char *arg = argv[i]; - if (arg[0] != '-') - continue; - - for (; *arg; arg++) { - switch (arg[0]) { - case 'r': print_refs = true; break; - case 'x': print_hex = true; break; - case 'a': print_acc = true; break; - } - } - } - - - DFHack::Process * p; - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context * DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; -#ifndef LINUX_BUILD - cin.ignore(); -#endif - return 1; - } - DFHack::Materials * Materials = DF->getMaterials(); - Materials->ReadAllMaterials(); - - DFHack::Gui * Gui = DF->getGui(); - - DFHack::Items * Items = DF->getItems(); - Items->Start(); - - DFHack::VersionInfo * mem = DF->getMemoryInfo(); - p = DF->getProcess(); - int32_t x,y,z; - Gui->getCursorCoords(x,y,z); - - std::vector p_items; - Items->readItemVector(p_items); - uint32_t size = p_items.size(); - - // FIXME: tools should never be exposed to DFHack internals! - DFHack::OffsetGroup* itemGroup = mem->getGroup("Items"); - uint32_t ref_vector = itemGroup->getOffset("item_ref_vector"); - - 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; - - printf( - "%5d: %08x %6d %08x (%d,%d,%d) #%08x [%d] *%d %s - %s\n", - i, itm.origin, itm.id, itm.base.flags.whole, - itm.base.x, itm.base.y, itm.base.z, - itm.base.vtable, - itm.wear_level, - itm.quantity, - Items->getItemClass(itm).c_str(), - Items->getItemDescription(itm, Materials).c_str() - ); - - if (print_hex) - hexdump(DF,p_items[i],0x300); - - if (print_acc) - cout << 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); - printf("\t-> %d \t%s\n", int(val), p->readClassName(vptr).c_str()); - } - } - } -#ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); -#endif - return 0; -} diff --git a/tools/examples/engravingdump.cpp b/tools/examples/engravingdump.cpp deleted file mode 100644 index a50250c79..000000000 --- a/tools/examples/engravingdump.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// Just show some position data - -#include -#include -#include -#include -#include -#include -#include -#include - -#define DFHACK_WANT_MISCUTILS -#include -using namespace DFHack; - -void describe (dfh_engraving &engraving) -{ - t_engraving &data = engraving.s; - printf("Engraving %d/%d/%d @ 0x%x\n", data.x, data.y, data.z, engraving.origin); - // inorganic stuff - we can recognize that - printf("type %d, index %d, character %c\n",data.type, data.subtype_idx, data.display_character); - printf("quality %d\n",data.quality); - printf("engraved: "); - if(data.flags.floor) - printf("On the floor."); - if(data.flags.north) - printf("From north."); - if(data.flags.south) - printf("From south."); - if(data.flags.east) - printf("From east."); - if(data.flags.west) - printf("From west."); - if(data.flags.northeast) - printf("From north-east."); - if(data.flags.northwest) - printf("From north-west."); - if(data.flags.southeast) - printf("From south-east."); - if(data.flags.southwest) - printf("From south-west."); - printf("\n"); - if(data.flags.hidden) - printf("The symbol is hidden.\n"); -}; - -int main (int numargs, const char ** args) -{ - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context* DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (std::exception& e) - { - std::cerr << e.what() << std::endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - DFHack::Gui *Gui = DF->getGui(); - - DFHack::Engravings *Cons = DF->getEngravings(); - uint32_t numEngr; - Cons->Start(numEngr); - - int32_t cx, cy, cz; - Gui->getCursorCoords(cx,cy,cz); - if(cx != -30000) - { - dfh_engraving engraved; - t_engraving &data = engraved.s; - for(uint32_t i = 0; i < numEngr; i++) - { - Cons->Read(i,engraved); - if(cx == data.x && cy == data.y && cz == data.z) - { - describe(engraved); - hexdump(DF,engraved.origin,0x28); - } - } - } - else - { - dfh_engraving engraved; - t_engraving &data = engraved.s; - for(uint32_t i = 0; i < numEngr; i++) - { - Cons->Read(i,engraved); - { - describe(engraved); - hexdump(DF,engraved.origin,0x28); - } - } - } - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -} diff --git a/tools/examples/hotkeynotedump.cpp b/tools/examples/hotkeynotedump.cpp deleted file mode 100644 index 4d0b73812..000000000 --- a/tools/examples/hotkeynotedump.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Hotkey and Note Dump -// Or Hot Keynote Dump? :P -#include -#include -#include -using namespace std; -#include - - -int main (void) -{ - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context * DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - DFHack::VersionInfo * mem = DF->getMemoryInfo(); - DFHack::Gui * Gui = DF->getGui(); - // get stone matgloss mapping - /* - uint32_t numNotes; - if(!DF.InitReadNotes(numNotes)) - { - cerr << "Can't get notes" << endl; - return 1; - } - */ - /* - cout << "Notes" << endl; - for(uint32_t i = 0; i < numNotes; i++) - { - DFHack::t_note temp; - DF.ReadNote(i,temp); - cout << "x: " << temp.x << "\ty: " << temp.y << "\tz: " << temp.z << - "\tsymbol: " << temp.symbol << "\tfg: " << temp.foreground << "\tbg: " << temp.background << - "\ttext: " << temp.name << endl; - } - */ - cout << "Hotkeys" << endl; - DFHack::t_hotkey hotkeys[NUM_HOTKEYS]; - Gui->ReadHotkeys(hotkeys); - for(uint32_t i =0;i< NUM_HOTKEYS;i++) - { - cout << "x: " << hotkeys[i].x << "\ty: " << hotkeys[i].y << "\tz: " << hotkeys[i].z << - "\ttext: " << hotkeys[i].name << endl; - } - //DF.FinishReadNotes(); - DF->Detach(); - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -} - diff --git a/tools/examples/materialtest.cpp b/tools/examples/materialtest.cpp deleted file mode 100644 index dafc4c245..000000000 --- a/tools/examples/materialtest.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// Just show some position data - -#include -#include -#include -#include -#include -using namespace std; - -#include - -int main (int numargs, const char ** args) -{ - uint32_t addr; - if (numargs == 2) - { - istringstream input (args[1],istringstream::in); - input >> std::hex >> addr; - } - - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context * DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - DFHack::Process* p = DF->getProcess(); - DFHack::VersionInfo* mem = DF->getMemoryInfo(); - DFHack::Materials *Materials = DF->getMaterials(); - - cout << "----==== Inorganic ====----" << endl; - Materials->ReadInorganicMaterials (); - for(uint32_t i = 0; i < Materials->inorganic.size();i++) - { - cout << i << ": " << Materials->inorganic[i].id << endl; - } - - cout << endl << "----==== Organic ====----" << endl; - Materials->ReadOrganicMaterials (); - for(uint32_t i = 0; i < Materials->organic.size();i++) - { - cout << i << ": " << Materials->organic[i].id << endl; - } - cout << endl << "----==== Organic - trees ====----" << endl; - Materials->ReadWoodMaterials (); - for(uint32_t i = 0; i < Materials->tree.size();i++) - { - cout << i << ": " << Materials->tree[i].id << endl; - } - cout << endl << "----==== Organic - plants ====----" << endl; - Materials->ReadPlantMaterials (); - for(uint32_t i = 0; i < Materials->plant.size();i++) - { - cout << i << ": " << Materials->plant[i].id << endl; - } - cout << endl << "----==== Color descriptors ====----" << endl; - Materials->ReadDescriptorColors(); - for(uint32_t i = 0; i < Materials->color.size();i++) - { - cout << i << ": " << Materials->color[i].id << " - " << Materials->color[i].name << "[" - << (unsigned int) (Materials->color[i].red*255) << ":" - << (unsigned int) (Materials->color[i].green*255) << ":" - << (unsigned int) (Materials->color[i].blue*255) - << "]" << endl; - } - cout << endl << "----==== All descriptors ====----" << endl; - Materials->ReadDescriptorColors(); - for(uint32_t i = 0; i < Materials->alldesc.size();i++) - { - cout << i << ": " << Materials->alldesc[i].id << endl; - } - - cout << endl << "----==== Creature types ====----" << endl; - Materials->ReadCreatureTypesEx (); - for(uint32_t i = 0; i < Materials->raceEx.size();i++) - { - cout << i << ": " << Materials->raceEx[i].rawname << endl; - vector & castes = Materials->raceEx[i].castes; - for(uint32_t j = 0; j < castes.size();j++) - { - cout << " [" - << castes[j].rawname << ":" - << castes[j].singular << ":" - << castes[j].plural << ":" - << castes[j].adjective << "] [" - << "st:" << castes[j].strength.level << "/" - << "ag:" << castes[j].agility.level << "/" - << "to:" << castes[j].toughness.level << "/" - << "en:" << castes[j].endurance.level << "/" - << "re:" << castes[j].recuperation.level << "/" - << "di:" << castes[j].disease_resistance.level << "/" - << "an:" << castes[j].analytical_ability.level << "/" - << "fo:" << castes[j].focus.level << "/" - << "wi:" << castes[j].willpower.level << "/" - << "cr:" << castes[j].creativity.level << "/" - << "in:" << castes[j].intuition.level << "/" - << "pa:" << castes[j].patience.level << "/" - << "me:" << castes[j].memory.level << "/" - << "li:" << castes[j].linguistic_ability.level << "/" - << "sp:" << castes[j].spatial_sense.level << "/" - << "mu:" << castes[j].musicality.level << "/" - << "ki:" << castes[j].kinesthetic_sense.level << "]"; - cout << endl; - for(uint32_t k = 0; k < castes[j].ColorModifier.size(); k++) - { - cout << " colormod[" << castes[j].ColorModifier[k].part; - if(castes[j].ColorModifier[k].startdate>0) - cout << " start:" << castes[j].ColorModifier[k].startdate << " days, end:" << castes[j].ColorModifier[k].enddate << " days"; - cout << "] "; - for(uint32_t l = 0; l < castes[j].ColorModifier[k].colorlist.size(); l++) - { - if( castes[j].ColorModifier[k].colorlist[l] < Materials->color.size() ) - cout << Materials->color[castes[j].ColorModifier[k].colorlist[l]].name << " "; - else - cout << Materials->alldesc[castes[j].ColorModifier[k].colorlist[l]].id << " "; - } - cout << endl; - } - cout << " body: "; - for(uint32_t k = 0; k < castes[j].bodypart.size(); k++) - { - cout << castes[j].bodypart[k].category << " "; - } - cout << endl; - } - cout << endl; - } - cout << endl << "----==== Other ====----" << endl; - Materials->ReadOthers (); - for(uint32_t i = 0; i < Materials->other.size();i++) - { - cout << i << ": " << Materials->other[i].rawname << endl; - } - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -} diff --git a/tools/examples/processenum.cpp b/tools/examples/processenum.cpp deleted file mode 100644 index ff15c8645..000000000 --- a/tools/examples/processenum.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// Demonstrates the use of ProcessEnumerator -// queries the Enumerator for all DF Processes on user input. Prints them to the terminal. -// also tracks processes that were invalidated - -#include -#include -#include -#include -using namespace std; - -#include -#include -using namespace DFHack; -#ifndef LINUX_BUILD -#endif - -void printhelp () -{ - cout << "enter empty line for next try." << endl; - cout << "enter 'next' or 'n' for next test." << endl; - cout << "enter 'help' to show this text again." << endl; -} - -int inputwait (const char * prompt) -{ -inputwait_reset: - string command = ""; - cout <<"[" << prompt << "]# "; - getline(cin, command); - if(command == "help") - { - printhelp(); - goto inputwait_reset; - } - else if(command == "") - { - return 1; - } - else if(command == "next") - { - return 0; - } - else - { - cout << "Command not recognized. Try 'help' for a list of valid commands." << endl; - goto inputwait_reset; - } - return 0; -} - -int main (void) -{ - printhelp(); - cout << endl; - // first test ProcessEnumerator and BadProcesses - { - cout << "Testing ProcessEnumerator" << endl; - ProcessEnumerator Penum("Memory.xml"); - VersionInfo * mem; - do - { - // make the ProcessEnumerator update its list of Processes - // by passing the pointer to 'inval', we make it export expired - // processes instead of destroying them outright - // (processes expire when the OS kills them for whatever reason) - BadProcesses inval; - Penum.Refresh(&inval); - int nProc = Penum.size(); - int nInval = inval.size(); - - cout << "Processes:" << endl; - for(int i = 0; i < nProc; i++) - { - mem = Penum[i]->getDescriptor(); - cout << "DF instance: " << Penum[i]->getPID() - << ", " << mem->getVersion() << endl; - } - - cout << "Invalidated:" << endl; - for(int i = 0; i < nInval; i++) - { - mem = inval[i]->getDescriptor(); - cout << "DF instance: " << inval[i]->getPID() - << ", " << mem->getVersion() << endl; - } - } - while(inputwait("ProcessEnumerator")); - } - // next test ContextManager and BadContexts - { - cout << "Testing ContextManager" << endl; - ContextManager Cman("Memory.xml"); - VersionInfo * mem; - do - { - // make the ContextManager update its list of Contexts - // by passing the pointer to 'inval', we make it export expired - // contexts instead of destroying them outright - // (contexts expire when the OS kills their process for whatever - // reason) - BadContexts inval; - Cman.Refresh(&inval); - int nCont = Cman.size(); - int nInval = inval.size(); - DFHack::Context * cont = Cman.getSingleContext(); - if(cont) - { - if(cont->Attach()) - { - DFHack::Maps * mapz = cont->getMaps(); - cont->Suspend(); - mapz->Start(); - cont->Resume(); - } - - bool result = cont->Detach(); - if(!result) - { - cerr << "Something went horribly wrong during detach" << endl; - } - } - - cout << "Contexts:" << endl; - for(int i = 0; i < nCont; i++) - { - mem = Cman[i]->getMemoryInfo(); - cout << "DF instance: " << Cman[i]->getProcess()->getPID() - << ", " << mem->getVersion() << endl; - } - - cout << "Invalidated:" << endl; - for(int i = 0; i < nInval; i++) - { - mem = inval[i]->getMemoryInfo(); - cout << "DF instance: " << inval[i]->getProcess()->getPID() - << ", " << mem->getVersion() << endl; - } - } - while(inputwait("ContextManager")); - } - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -} diff --git a/tools/examples/settlementdump.cpp b/tools/examples/settlementdump.cpp deleted file mode 100644 index 5424d423c..000000000 --- a/tools/examples/settlementdump.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include -#include -#include -#include -#include -using namespace std; - -#include -#include -#include - - -void printSettlement(DFHack::ContextManager & DF, const DFHack::t_settlement & settlement, const vector< vector > &englishWords, const vector< vector > &foreignWords) -{ - cout << "First name: " << settlement.name.first_name << endl << "Nickname: " << settlement.name.nickname << endl; - cout << settlement.name.words[0] << " " << settlement.name.words[1] << " " << settlement.name.words[2] << " " - << settlement.name.words[3] << " " << settlement.name.words[4] << " " << settlement.name.words[5] << " " - << settlement.name.words[6] << " " << settlement.name.words[7] << endl; - cout << settlement.name.parts_of_speech[0] << " " << settlement.name.parts_of_speech[1] << " " << settlement.name.parts_of_speech[2] << " " - << settlement.name.parts_of_speech[3] << " " << settlement.name.parts_of_speech[4] << " " << settlement.name.parts_of_speech[5] << " " - << settlement.name.parts_of_speech[6] << " " << settlement.name.parts_of_speech[7] << endl; - - printf("Origin: 0x%x\n",settlement.origin); - - string genericName = DF.TranslateName(settlement.name,englishWords,foreignWords,true); - string dwarfName = DF.TranslateName(settlement.name,englishWords,foreignWords,false); - cout << dwarfName << " " << genericName << " " << "world x: " << settlement.world_x << " world y: " << settlement.world_y - << " local_x: " << settlement.local_x1 << " local_y: " << settlement.local_y1 << " size: " << settlement.local_x2 - settlement.local_x1 << " by " << settlement.local_y2 - settlement.local_y1 << "\n"; -} - -int main (int argc,const char* argv[]) -{ - DFHack::ContextManager DF("Memory.xml"); - try - { - DF.Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - DFHack::t_settlement current; - uint32_t numSettlements; - if(!DF.InitReadSettlements(numSettlements)) - { - cerr << "Could not read Settlements" << endl; - return 1; - } - - vector< vector > englishWords; - vector< vector > foreignWords; - if(!DF.InitReadNameTables(englishWords,foreignWords)) - { - cerr << "Can't get name tables" << endl; - return 1; - } - - cout << "Settlements\n"; - /*for(uint32_t i =0;i -#include -#include -#include -#include -#include -#include -using namespace std; -#define DFHACK_WANT_MISCUTILS -#include - -using namespace DFHack; - -//FIXME: A pile of magic numbers. looks like decompiled number -typedef uint32_t _DWORD; -int get_material_vector(uint32_t vein_8, uint16_t vein_4, int WORLD_) -{ - int result; // eax@2 - int v4; // ecx@11 - int v5; // eax@12 - - if ( (uint16_t)(vein_4 - 0x1A3) > 0xC7u ) - { - if ( ((int16_t)vein_4 < 19 || (int16_t)vein_4 > 0xDAu) - && (uint16_t)(vein_4 - 219) > 0xC7u ) - { - if ( vein_4 ) - { - if ( vein_4 > 0x292u ) - result = 0; - else - result = *(_DWORD *)(WORLD_ + 4 * (int16_t)vein_4 + 0x5DF44); - } - else - { - if ( (signed int)vein_8 >= 0 - && (v4 = *(_DWORD *)(WORLD_ + 0x54B88), vein_8 < (*(_DWORD *)(WORLD_ + 0x54B8C) - v4) >> 2) - && (v5 = *(_DWORD *)(v4 + 4 * vein_8)) != 0 ) - result = v5 + 0x178; - else - result = *(_DWORD *)(WORLD_ + 0x5DF44); - } - } - else - { - /* - result = sub_4D47A0(vein_8, vein_4, WORLD_ + 0x54C84); - if ( !result ) - result = *(_DWORD *)(WORLD_ + 0x5DF90); - */ - } - } - else - { - /* - result = sub_41F430(WORLD_ + 0x54B94, vein_4); - if ( !result ) - result = *(_DWORD *)(WORLD_ + 0x5E5D0); - */ - } - return result; -} -char shades[10] = {'#','$','O','=','+','|','-','^','.',' '}; - -void printSpatter(DFHack::Context * DF, t_spattervein & spatter) -{ - DFHack::Materials *Mats = DF->getMaterials(); - printf("Splatter\nmat1: %d\nunknown: %d\nmat2: %d\n",spatter.mat1,spatter.unk1,spatter.mat2); - printf ("Material : %d - ", spatter.matter_state); - // FIXME: stupid - switch(spatter.matter_state) - { - case state_gas: - printf("Gas "); - break; - case state_solid: - printf("Solid "); - break; - case state_liquid: - printf("Liquid "); - break; - case state_paste: - printf("Paste "); - break; - case state_powder: - printf("Powder "); - break; - case state_pressed: - printf("Pressed "); - break; - default: - printf("Unknown state "); - } - cout << PrintSplatterType(spatter.mat1,spatter.mat2,Mats->race) << endl; - printf("Address 0x%08x\n",spatter.address_of); - for(uint32_t yyy = 0; yyy < 16; yyy++) - { - cout << "|"; - for(uint32_t xxx = 0; xxx < 16; xxx++) - { - uint8_t intensity = spatter.intensity[xxx][yyy]; - cout << shades[9 - (intensity / 28)]; - } - cout << "|" << endl; - } - hexdump(DF, spatter.address_of,20*16); -} - -int main (int numargs, const char ** args) -{ - uint32_t x_max,y_max,z_max; - vector veinVector; - vector IceVeinVector; - vector splatter; - - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context * DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - DFHack::Maps *Maps =DF->getMaps(); - DFHack::Gui *Gui =DF->getGui(); - DFHack::Materials *Mats =DF->getMaterials(); - - Mats->ReadCreatureTypes(); - - // init the map - if(!Maps->Start()) - { - cerr << "Can't init map." << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - int32_t cx, cy, cz; - Maps->getSize(x_max,y_max,z_max); - Gui->getCursorCoords(cx,cy,cz); - if(cx == -30000) - { - // walk the map - for(uint32_t x = 0; x< x_max;x++) for(uint32_t y = 0; y< y_max;y++) for(uint32_t z = 0; z< z_max;z++) - { - if(Maps->isValidBlock(x,y,z)) - { - // look for splater veins - Maps->ReadVeins(x,y,z,0,0,&splatter); - if(splatter.size()) - { - printf("Block %d/%d/%d\n",x,y,z); - for(uint32_t i = 0; i < splatter.size(); i++) - { - cout << i << ":" << endl; - printSpatter(DF,splatter[i]); - } - } - } - } - } - else - { - uint32_t bx,by,bz; - bx = cx / 16; - by = cy / 16; - bz = cz; - // look for splater veins - Maps->ReadVeins(bx,by,bz,0,0,&splatter); - if(splatter.size()) - { - printf("Block %d/%d/%d\n",bx,by,bz); - for(uint32_t i = 0; i < splatter.size(); i++) - { - printSpatter(DF,splatter[i]); - cout << endl; - } - } - } - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -} diff --git a/tools/examples/treedump.cpp b/tools/examples/treedump.cpp deleted file mode 100644 index b599b6656..000000000 --- a/tools/examples/treedump.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// Just show some position data - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -#define DFHACK_WANT_MISCUTILS -#include -/* - uint16_t material; // +0x3E - uint16_t x; // +0x40 - uint16_t y; // +0x42 - uint16_t z; // +0x44 - uint16_t padding; // +0x46 - uint32_t unknown_1; // +0x48 - uint16_t temperature_1; // +0x4C - uint16_t temperature_2; // +0x4E - maybe fraction? - uint32_t mystery_flag; // 0x50: yes, just one - uint32_t unknown_2; // 0x54 - uint32_t unknown_3; // 0x58 - // a vector is here - uint32_t address; - */ -void print_tree( DFHack::Context * DF , DFHack::dfh_plant & tree) -{ - DFHack::Materials * mat = DF->getMaterials(); - DFHack::t_plant & tdata = tree.sdata; - printf("%d:%d = ",tdata.type,tdata.material); - if(tdata.watery) - { - cout << "near-water "; - } - cout << mat->organic[tdata.material].id << " "; - if(!tdata.is_shrub) - { - cout << "tree"; - } - else - { - cout << "shrub"; - } - cout << endl; - printf("Grow counter: 0x%08x\n", tdata.grow_counter); - printf("temperature 1: %d\n", tdata.temperature_1); - printf("temperature 2: %d\n", tdata.temperature_2); - printf("On fire: %d\n", tdata.is_burning); - printf("hitpoints: 0x%08x\n", tdata.hitpoints); - printf("update order: %d\n", tdata.update_order); - printf("Address: 0x%x\n", tree.address); - hexdump(DF,tree.address,13*16); -} - -int main (int numargs, const char ** args) -{ - uint32_t addr; - if (numargs == 2) - { - istringstream input (args[1],istringstream::in); - input >> std::hex >> addr; - } - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context * DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - DFHack::Process* p = DF->getProcess(); - DFHack::VersionInfo* mem = DF->getMemoryInfo(); - DFHack::Gui * Gui = DF->getGui(); - DFHack::Vegetation * v = DF->getVegetation(); - DFHack::Maps * mps = DF->getMaps(); - DFHack::Materials * mat = DF->getMaterials(); - mat->ReadOrganicMaterials(); - - int32_t x,y,z; - Gui->getCursorCoords(x,y,z); - - uint32_t numVegs = 0; - v->Start(numVegs); - if(x == -30000) - { - cout << "----==== Trees ====----" << endl; - for(uint32_t i =0; i < numVegs; i++) - { - DFHack::dfh_plant tree; - v->Read(i,tree); - printf("%d/%d/%d, %d:%d\n",tree.sdata.x,tree.sdata.y,tree.sdata.z,tree.sdata.type,tree.sdata.material); - } - } - else - { - // new method, gets the vector of trees in a block. can show farm plants - if(mps->Start()) - { - vector alltrees; - if(mps->ReadVegetation(x/16,y/16,z,&alltrees)) - { - for(int i = 0 ; i < alltrees.size(); i++) - { - DFHack::dfh_plant & tree = alltrees[i]; - // you could take the tree coords from the struct and % them with 16 for use in loops over the whole block - if(tree.sdata.x == x && tree.sdata.y == y && tree.sdata.z == z) - { - cout << "----==== Tree at "<< x << "/" << y << "/" << z << " ====----" << endl; - print_tree(DF, tree); - break; - } - } - } - } - // old method, gets the tree from the global vegetation vector. can't show farm plants - for(uint32_t i =0; i < numVegs; i++) - { - DFHack::dfh_plant tree; - v->Read(i,tree); - if(tree.sdata.x == x && tree.sdata.y == y && tree.sdata.z == z) - { - cout << "----==== Tree at "<< dec << x << "/" << y << "/" << z << " ====----" << endl; - print_tree(DF, tree); - break; - } - } - } - v->Finish(); - - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -} diff --git a/tools/playground/blockflags.cpp b/tools/playground/blockflags.cpp deleted file mode 100644 index f78a8894e..000000000 --- a/tools/playground/blockflags.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Invert/toggle all block flags, to see what they do. -// Seems like they don't do anything... - -#include -#include - -using namespace std; -#include -#include -#include - - -int main(int argc, char *argv[]) -{ - bool temporary_terminal = TemporaryTerminal(); - - uint32_t x_max = 0, y_max = 0, z_max = 0; - DFHack::ContextManager manager("Memory.xml"); - - DFHack::Context *context = manager.getSingleContext(); - if (!context->Attach()) - { - std::cerr << "Unable to attach to DF!" << std::endl; - if(temporary_terminal) - std::cin.ignore(); - return 1; - } - - DFHack::Maps *maps = context->getMaps(); - if (!maps->Start()) - { - std::cerr << "Cannot get map info!" << std::endl; - context->Detach(); - if(temporary_terminal) - std::cin.ignore(); - return 1; - } - maps->getSize(x_max, y_max, z_max); - MapExtras::MapCache map(maps); - - for(uint32_t z = 0; z < z_max; z++) - { - for(uint32_t b_y = 0; b_y < y_max; b_y++) - { - for(uint32_t b_x = 0; b_x < x_max; b_x++) - { - // Get the map block - DFHack::DFCoord blockCoord(b_x, b_y); - MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z)); - if (!b || !b->valid) - { - continue; - } - - DFHack::t_blockflags flags = b->BlockFlags(); - flags.whole = flags.whole ^ 0xFFFFFFFF; - b->setBlockFlags(flags); - b->Write(); - } // block x - } // block y - } // z - - maps->Finish(); - context->Detach(); - return 0; -} diff --git a/tools/playground/dftry.cpp b/tools/playground/dftry.cpp deleted file mode 100644 index d7693ae8b..000000000 --- a/tools/playground/dftry.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include -#include -#include - -using namespace std; - -bool getNumber (string prompt, int & output, int def, bool pdef = true) -{ - cout << prompt; - if(pdef) - cout << ", default=" << def << endl; - while (1) - { - string select; - cout << ">>"; - std::getline(cin, select); - if(select.empty()) - { - output = def; - break; - } - else if( sscanf(select.c_str(), "%d", &output) == 1 ) - { - break; - } - else - { - continue; - } - } - return true; -} - -bool splitvector(const vector & in, vector & out1, vector & out2) -{ - size_t length = in.size(); - if(length > 1) - { - size_t split = length / 2; - out1.clear(); - out2.clear(); - out1.insert(out1.begin(),in.begin(),in.begin() + split); - out2.insert(out2.begin(),in.begin() + split,in.end()); - return true; - } - return false; -} -void printvector (const vector &in) -{ - cout << "[" << endl; - for(size_t i = 0; i < in.size(); i++) - { - cout << hex << in[i] << endl; - } - cout << "]" << endl; -} - -bool tryvals (DFHack::Context * DF, const vector &in, uint8_t current, uint8_t testing) -{ - DF->Suspend(); - DFHack::Process * p = DF->getProcess(); - for(size_t i = 0; i < in.size(); i++) - { - p->writeByte(in[i],testing); - } - DF->Resume(); - int result; - while (!getNumber("Is the change good? 0 for no, positive for yes.",result,0)); - DF->Suspend(); - for(size_t i = 0; i < in.size(); i++) - { - p->writeByte(in[i],current); - } - DF->Resume(); - if(result) - return true; - return false; -} - -bool dotry (DFHack::Context * DF, const vector &in, uint8_t current, uint8_t testing) -{ - vector a, b; - bool found = false; - if(!tryvals(DF,in,current,testing)) - return false; - if(splitvector(in, a,b)) - { - if(dotry(DF, a, current, testing)) - return true; - if(dotry(DF, b, current, testing)) - return true; - return false; - } - return false; -} - -int main() -{ - vector addresses; - vector a1; - vector a2; - vector values; - string line; - - DFHack::ContextManager CM("Memory.xml"); - DFHack::Context * DF = CM.getSingleContext(); - if(!DF) - return 1; - DF->Resume(); - - ifstream fin("siege.txt"); - if(!fin.is_open()) - return 1; - do - { - getline(fin,line); - stringstream input (line); - input << hex; - uint64_t value; - input >> value; - if(value) - { - cout << hex << value << endl; - addresses.push_back(value); - } - } while (!fin.eof()); - int val_current,val_testing; - while (!getNumber("Insert current value",val_current,1)); - while (!getNumber("Insert testing value",val_testing,0)); - dotry(DF, addresses,val_current,val_testing); - return 0; -} \ No newline at end of file diff --git a/tools/playground/findnameindexes.cpp b/tools/playground/findnameindexes.cpp deleted file mode 100644 index 0a9f48c66..000000000 --- a/tools/playground/findnameindexes.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Dwarf fortress names are a complicated beast, in objects they are displayed -// as indexes into the language vectors -// -// use this tool if you are trying to find what the indexes are for a displayed -// name, so you can then search for it in your object - -#include -#include -#include -#include -#include -using namespace std; - -#include - -// returns a lower case version of the string -string tolower (const string & s) -{ - string d (s); - - transform (d.begin (), d.end (), d.begin (), (int(*)(int)) tolower); - return d; -} -string groupBy2(const string & s) -{ - string d; - for(int i =2;i>24) | - ((x<<8) & 0x00FF0000) | - ((x>>8) & 0x0000FF00) | - (x<<24); - return x; -} - - -int main (void) -{ - DFHack::ContextManager DF("Memory.xml"); - DFHack::Context * C; - DFHack::Translation * Tran; - try - { - C = DF.getSingleContext(); - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - Tran = C->getTranslation(); - - if(!Tran->Start()) - { - cerr << "Could not get Names" << endl; - return 1; - } - DFHack::Dicts dicts = *(Tran->getDicts()); - DFHack::DFDict & englishWords = dicts.translations; - DFHack::DFDict & foreignWords = dicts.foreign_languages; - - C->Detach(); - string input; - - cout << "\nSelect Name to search or q to Quit" << endl; - getline (cin, input); - while(input != "q"){ - for( uint32_t i = 0; i < englishWords.size();i++){ - for( uint32_t j = 0;j < englishWords[i].size();j++){ - if(englishWords[i][j] != ""){ - uint32_t found = tolower(input).find(tolower(englishWords[i][j])); - if(found != string::npos){ - stringstream value; - value << setfill('0') << setw(8) << hex << endian_swap(j); - cout << englishWords[i][j] << " " << groupBy2(value.str()) << endl; - } - } - } - } - for( uint32_t i = 0; i < foreignWords.size();i++){ - for( uint32_t j = 0;j < foreignWords[i].size();j++){ - uint32_t found = tolower(input).find(tolower(foreignWords[i][j])); - if(found != string::npos){ - stringstream value; - value << setfill('0') << setw(8) << hex << endian_swap(j); - cout << foreignWords[i][j] << " " << groupBy2(value.str()) << endl; - } - } - } - getline(cin,input); - } - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -} diff --git a/tools/playground/hexsearch2.c b/tools/playground/hexsearch2.c deleted file mode 100644 index 44872e2d1..000000000 --- a/tools/playground/hexsearch2.c +++ /dev/null @@ -1,1355 +0,0 @@ -/* - * Author: Silas Dunsmore aka 0x517A5D vim:ts=4:sw=4 - * - * Released under the MIT X11 license; feel free to use some or all of this - * code, as long as you include the copyright and license statement (below) - * in all copies of the source code. In fact, I truly encourage reuse. - * - * If you do use large portions of this code, I suggest but do not require - * that you keep this code in a seperate file (such as this hexsearch.c file) - * so that it is clear that the terms of the license do not also apply to - * your code. - * - * Should you make fundamental changes, or bugfixes, to this code, I would - * appreciate it if you would give me a copy of your changes. - * - * - * Be advised that I use several advanced idioms of the C language: - * macro expansion, stringification, and variable argument functions. - * You do not need to understand them. Usage should be obvious. - * - * - * Lots of logging output is sent to OutputDebugString(). - * The Sysinternals' DebugView program is very useful in monitering this. - * - * - * Copyright (C) 2007-2008 Silas Dunsmore - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * See also: http://www.opensource.org/licenses/mit-license.php - * and http://en.wikipedia.org/wiki/MIT_License - */ - -#include // va_list and friends -#include // vsnprintf() -#include // atexit() -#include -#define WINVER 0x0500 // OpenThread() -#define WIN32_LEAN_AND_MEAN -#include -#include -#include "hexsearch2.h" - - -#define SKIPME 0xFEDCBA98 // token for internal use only. - - -// exported globals -HANDLE df_h_process, df_h_thread; -DWORD df_pid, df_main_win_tid; -DWORD here[16]; -DWORD target[16]; -char *errormessage; -DWORD df_memory_base, df_memory_start, df_memory_end; - - -// local globals -static BOOL change_page_permissions; -static BOOL suspended; -static BYTE *copy_of_df_memory; -static int nexthere; -static int nexttarget; -static DWORD searchmemstart, searchmemend; - - -#define dump(x) d_printf("%-32s == %08X\n", #x, (x)); -#define dumps(x) d_printf("%-32s == '%s'\n", #x, (x)); - - -// ============================================================================ -// send info to KERNEL32:OutputDebugString(), useful for non-console programs. -// you can watch this with SysInternals' DebugView. -// http://www.microsoft.com/technet/sysinternals/Miscellaneous/DebugView.mspx -// -void d_printf(const char *format, ...) -{ - va_list va; - char debugstring[4096]; // debug strings can be up to 4K. - - va_start(va, format); - _vsnprintf(debugstring, sizeof(debugstring) - 2, format, va); - va_end(va); - - OutputDebugString(debugstring); -} - - -// ============================================================================ -BOOL isvalidaddress(DWORD address) -{ - MEMORY_BASIC_INFORMATION mbi; - return (VirtualQueryEx(df_h_process, (void *)address, &mbi, sizeof(mbi)) - == sizeof(mbi) && mbi.State == MEM_COMMIT); -} - - -// ---------------------------------------------------------------------------- -BOOL peekarb(DWORD address, OUT void *data, DWORD len) -{ - BOOL ok = FALSE; - DWORD succ = 0; - DWORD OldProtect; - MEMORY_BASIC_INFORMATION mbi = {0, 0, 0, 0, 0, 0, 0}; - - errormessage = ""; - - // do {} while(0) is a construct that lets you abort a piece of code - // in the middle without using gotos. - - do - { - - if ((succ = VirtualQueryEx(df_h_process, (BYTE *)address + len - 1, - &mbi, sizeof(mbi))) != sizeof(mbi)) - { - dump(address + len - 1); - dump(succ); - errormessage = "peekarb(): VirtualQueryEx() on end address failed"; - break; - } - if (mbi.State != MEM_COMMIT) - { - dump(mbi.State); - errormessage = "peekarb(): VirtualQueryEx() says end address " - "is not MEM_COMMIT"; - break; - } - - if ((succ = VirtualQueryEx(df_h_process, (void *)address, &mbi, - sizeof(mbi))) != sizeof(mbi)) - { - dump(address); - dump(succ); - errormessage ="peekarb(): VirtualQueryEx() on start address failed"; - break; - } - if (mbi.State != MEM_COMMIT) - { - dump(mbi.State); - errormessage = "peekarb(): VirtualQueryEx() says start address is " - "not MEM_COMMIT"; - break; - } - - if (change_page_permissions) - { - if (!VirtualProtectEx(df_h_process, mbi.AllocationBase, - mbi.RegionSize, PAGE_READWRITE, &OldProtect)) - { - errormessage = "peekarb(): VirtualProtectEx() failed"; - break; - } - } - - if (!ReadProcessMemory(df_h_process, (void *)address, data, len, &succ)) - { - errormessage = "peekarb(): ReadProcessMemory() failed"; - - // note that we do NOT break here, as we want to restore the - // page protection. - } - else if (len != succ) - { - errormessage = "peekarb(): ReadProcessMemory() returned " - "partial read"; - } - else ok = TRUE; - - if (change_page_permissions) - { - if (!VirtualProtectEx(df_h_process, mbi.AllocationBase, - mbi.RegionSize, OldProtect, &OldProtect)) - { - errormessage = "peekarb(): undo VirtualProtectEx() failed"; - break; - } - } - } while (0); - - if (errormessage != NULL && strlen(errormessage) != 0) - { - d_printf("%s\n", errormessage); - dump(address); - //dump(len); - //dump(succ); - //dump(mbi.AllocationBase); - } - - return(ok); -} - - -// ---------------------------------------------------------------------------- -BYTE peekb(DWORD address) -{ - BYTE data; - return(peekarb(address, &data, sizeof(data)) ? data : 0); - // pop quiz: why don't we set errormessage? -} - - -// ---------------------------------------------------------------------------- -WORD peekw(DWORD address) -{ - WORD data; - return(peekarb(address, &data, sizeof(data)) ? data : 0); -} - - -// ---------------------------------------------------------------------------- -DWORD peekd(DWORD address) -{ - DWORD data; - return(peekarb(address, &data, sizeof(data)) ? data : 0); -} - - -// ---------------------------------------------------------------------------- -char *peekstr(DWORD address, OUT char *data, DWORD maxlen) -{ - BYTE c; - int i = 0; - - data[0] = '\0'; - if (!isvalidaddress(address)) return(data); - - while (--maxlen && (c = peekb(address++)) >= ' ' && c <= '~') - { - if (!isvalidaddress(address)) return(data); - data[i++] = c; - data[i] = '\0'; - } - // for convenience - return(data); -} - - -// ---------------------------------------------------------------------------- -char *peekwstr(DWORD address, OUT char *data, DWORD maxlen) -{ - BYTE c; - int i = 0; - - data[0] = '\0'; - if (!isvalidaddress(address)) return(data); - - while (--maxlen && (c = peekb(address++)) >= ' ' && c <= '~' && peekb(address++) == 0) - { - if (!isvalidaddress(address)) - { - return(data); - } - data[i++] = c; - data[i] = '\0'; - } - // for convenience - return(data); -} - - -// ---------------------------------------------------------------------------- -BOOL pokearb(DWORD address, const void *data, DWORD len) -{ - BOOL ok = FALSE; - DWORD succ = 0; - DWORD OldProtect; - MEMORY_BASIC_INFORMATION mbi; - - errormessage = ""; - - do - { - if (!isvalidaddress(address)) - { - errormessage = "pokearb() failed: invalid address"; - break; - } - - if (!isvalidaddress(address + len - 1)) - { - errormessage = "pokearb() failed: invalid end address"; - break; - } - - if (change_page_permissions) - { - if (VirtualQueryEx(df_h_process, (void *)address, &mbi, sizeof(mbi)) != sizeof(mbi)) - { - errormessage = "pokearb(): VirtualQueryEx() failed"; - break; - } - - if (!VirtualProtectEx(df_h_process, mbi.AllocationBase, mbi.RegionSize, PAGE_READWRITE, &OldProtect)) - { - errormessage = "pokearb(): VirtualProtectEx() failed"; - break; - } - } - - if (!WriteProcessMemory(df_h_process, (void *)address, data, len, &succ)) - { - errormessage = "pokearb(): WriteProcessMemory() failed"; - // note that we do NOT break here, as we want to restore the - // page protection. - } - else if (len != succ) - { - errormessage = "pokearb(): WriteProcessMemory() did partial write"; - } - else - { - ok = TRUE; - } - - if (change_page_permissions) - { - if (!VirtualProtectEx(df_h_process, mbi.AllocationBase, mbi.RegionSize, OldProtect, &OldProtect)) - { - errormessage = "pokearb(): undo VirtualProtectEx() failed"; - break; - } - } - } while (0); - - if (errormessage != NULL && strlen(errormessage) != 0) - { - d_printf("%s\n", errormessage); - dump(address); - //dump(len); - //dump(succ); - //dump(mbi.AllocationBase); - } - - return(ok); -} - - -// ---------------------------------------------------------------------------- -BOOL pokeb(DWORD address, BYTE data) -{ - return(pokearb(address, &data, sizeof(data))); -} - - -// ---------------------------------------------------------------------------- -BOOL pokew(DWORD address, WORD data) -{ - return(pokearb(address, &data, sizeof(data))); -} - - -// ---------------------------------------------------------------------------- -BOOL poked(DWORD address, DWORD data) -{ - return(pokearb(address, &data, sizeof(data))); -} - - -// ---------------------------------------------------------------------------- -BOOL pokestr(DWORD address, const BYTE *data) -{ -// can't include a "\x00" in the string, obviously. - return(pokearb(address, data, strlen((const char *)data))); -} - - -// ---------------------------------------------------------------------------- -// helper function for hexsearch. recursive, with backtracking. -// this checks if a particular memory offset matches the given pattern. -// returns location of start of match (in the cached copy of DF memory). -// returns NULL on mismatch. -// -// TODO: there is a harmless bug in the recursion related to the very first -// recursive call, probably on each level of recursion. -static BYTE *hexsearch_match2(BYTE *p, DWORD token1, va_list va) -{ - static DWORD recursion_level = 0; - DWORD tokensprocessed = 0; - DWORD token = 0x4DECADE5, b1, b2, lo, hi; - BYTE *retval = p; - BOOL ok = FALSE, lookedahead; - int savenexthere = nexthere; - int savenexttarget = nexttarget; - - // TODO token is being used without being inited on recursion. - - //if (recursion_level) dump(recursion_level); - //if (recursion_level) dump(p); - //if (recursion_level) dump(tokensprocessed); - - if (token1 != SKIPME) - { - lookedahead = TRUE; - token = token1; - tokensprocessed = 1; - } - - while (1) - { - // if the previous argument looked ahead, token is already set. - // peekahead is currently unused. - if (!lookedahead) - { - token = va_arg(va, unsigned int); - tokensprocessed++; - } - lookedahead = FALSE; - - // exact-match a byte, advance. - if (token <= 0xFF) - { - if (token != *p++) break; - } - - // the remaining tokens (the metas) ought to be a switch. - // but that would make it hard to break out of the while(1). - - // if we hit an EOL, the match succeeded. - else if (token == EOL) - { - ok = TRUE; - break; - } - - // match any byte, advance. - else if (token == ANYBYTE) - { - p++; - } - - // return the address of the next matching byte instead of the - // address of the start of the pattern. don't advance. - else if (token == HERE) - { - retval = p; - here[nexthere++] = (DWORD)p; // needs postprocessing. - } - - // accept either of the next two parameters as a match. advance. - // note that this does not count as peeking. - else if (token == EITHER) - { - if ((b1 = va_arg(va, unsigned int)) > 0xFF) - { - d_printf("EITHER: not followed by a legal token (byte1): %08X\n", b1); - break; - } - tokensprocessed++; - if ((b2 = va_arg(va, unsigned int)) > 0xFF) - { - d_printf("EITHER: not followed by a legal token (byte2): %08X\n", b2); - break; - } - tokensprocessed++; - if (!(*p == b1 || *p == b2)) break; - p++; - } - - #ifdef FF_OR_00 //DEPRECATED - // accept either 0x00 or 0xFF. advance. - else if (token == FF_OR_00) - { - if (!(*p == 0x00 || *p == 0xFF)) - { - break; - } - p++; - } - #endif - - // set low value for range comparison. don't advance. DEPRECATED. - else if (token == RANGE_LO) - { - if ((lo = va_arg(va, unsigned int)) > 0xFF) - { - d_printf("RANGE_LO: not followed by a legal token: %08X\n", lo); - break; - } - tokensprocessed++; - // Q: peek here to ensure next token is RANGE_HI ? - } - - // set high value for range comparison, and do comparison. advance. - // DEPRECATED. - else if (token == RANGE_HI) - { - if ((hi = va_arg(va, unsigned int)) > 0xFF) { - d_printf("RANGE_HI: not followed by a legal token: %08X\n", hi); - break; - } - if (*p < lo || *p > hi) - { - break; - } - p++; - tokensprocessed++; - } - - // do a byte-size range comparison - else if (token == BYTERANGE) - { - if ((lo = va_arg(va, unsigned int)) > 0xFF) - { - d_printf("BYTERANGE: not followed by a legal token: %08X\n", lo); - break; - } - tokensprocessed++; - - if ((hi = va_arg(va, unsigned int)) > 0xFF) - { - d_printf("BYTERANGE: not followed by a legal token: %08X\n", hi); - break; - } - if (*p < lo || *p > hi) - { - break; - } - p++; - tokensprocessed++; - } - - // do a dword-size range comparison - else if (token == DWORDRANGE) - { - lo = va_arg(va, unsigned int); - tokensprocessed++; - - hi = va_arg(va, unsigned int); - if (*(DWORD *)p < lo || *(DWORD *)p > hi) - { - break; - } - p++; - tokensprocessed++; - } - - // this is the fun one. this is where we recurse. - else if (token == SKIP_UP_TO) - { - DWORD len; - BYTE * subretval; - - len = va_arg(va, unsigned int) + 1; - tokensprocessed++; - - while (len) - { - // um. This is a kludge. It ought to work to not set any - // heres or targets if we're in a recursion. (not tested) - int savenexthere; - int savenexttarget; - - // I think it's not technically legal to copy va_lists; - // but it should work on any stack-based machine, which is - // everything except old Crays and weird dataflow processors. - - savenexthere = nexthere; - savenexttarget = nexttarget; - //dump(tokensprocessed); - //dump(recursion_level); - //dumps("-->"); - recursion_level++; - subretval = hexsearch_match2(p, SKIPME, va); - recursion_level--; - //dumps("<--"); - //dump(recursion_level); - //dump(tokensprocessed); - nexthere = savenexthere; - nexttarget = savenexttarget; - if (subretval != NULL) { - // okay, we now know that the bytes starting at p - // match the remainder of the pattern. - // Nonetheless, for ease of programming, we will - // go through the motions instead of trying to - // early-out. (Basically done for HERE tokens.) - break; - } - - p++; - len--; - } - if (subretval != NULL) - { - continue; - } - // no match within nn bytes, abort. - break; - } - - // exact-match a dword. advance 4. - else if (token == DWORD_) - { - DWORD d = va_arg(va, unsigned int); - if (*(DWORD *)p != d) break; - p += 4; - tokensprocessed++; - } - - // match any dword. advance 4. - else if (token == ANYDWORD) - { - p += 4; - } - - // match any legal address in - else if (token == ADDRESS) - { - // program text. advance 4. - if (*(DWORD *)p < df_memory_start) - { - break; - } - if (*(DWORD *)p > df_memory_end) - { - break; - } - p += 4; - } - - // match any call. advance 5. - else if (token == CALL) - { - if (*p++ != 0xE8) - { - break; - } - target[nexttarget++] = *(DWORD *)p + (DWORD)p + 4; -#if 0 - if (*(DWORD *)p > DF_CODE_SIZE - && *(DWORD *)p < (DWORD)-DF_CODE_SIZE) - break; -#endif - p += 4; - } - - // match any short or near jump. - else if (token == JUMP) - { - // advance 2 or 5 respectively. - if (*p == 0xEB) - { - target[nexttarget++] = *(signed char *)(p+1) + (DWORD)p + 1; - p += 2; - continue; - } - - if (*p++ != 0xE9) - { - break; - } - - target[nexttarget++] = *(DWORD *)p + (DWORD)p + 4; -#if 0 - if (*(DWORD *)p > DF_CODE_SIZE - && *(DWORD *)p < (DWORD)-DF_CODE_SIZE) - break; -#endif - p += 4; - } - - // match a JZ instruction - else if (token == JZ) - { - if (*p == 0x74) - { - target[nexttarget++] = *(signed char *)(p+1) + (DWORD)p + 2; - p += 2; - continue; - } - else if (*p == 0x0F && *(p+1) == 0x84 - && (*(p+4) == 0x00 || *(p+4) == 0xFF) // assume dist < 64k - && (*(p+5) == 0x00 || *(p+5) == 0xFF)) - { - target[nexttarget++] = *(DWORD *)(p+2) + (DWORD)p + 6; - p += 6; - continue; - } - else break; - } - - // match a JNZ instruction - else if (token == JNZ) - { - if (*p == 0x75) { - target[nexttarget++] = *(signed char *)(p+1) + (DWORD)p + 2; - p += 2; - continue; - } - else if (*p == 0x0F && *(p+1) == 0x85 - && (*(p+4) == 0x00 || *(p+4) == 0xFF) // assume dist < 64k - && (*(p+5) == 0x00 || *(p+5) == 0xFF) - ) { - target[nexttarget++] = *(DWORD *)(p+2) + (DWORD)p + 6; - p += 6; - continue; - } - else break; - } - - // match any conditional jump - else if (token == JCC) - { - if (*p >= 0x70 && *p <= 0x7F) - { - target[nexttarget++] = *(signed char *)(p+1) + (DWORD)p + 2; - p += 2; - continue; - } - else if (*p == 0x0F && *(p+1) >= 0x80 && *(p+1) <= 0x8F - && (*(p+4) == 0x00 || *(p+4) == 0xFF) // assume dist < 64k - && (*(p+5) == 0x00 || *(p+5) == 0xFF)) - { - target[nexttarget++] = *(DWORD *)(p+2) + (DWORD)p + 6; - p += 6; - continue; - } - else break; - } - - // unknown token, abort - else - { - d_printf("unknown token: %08X\n", token); - dump(p); - dump(recursion_level); - break; - } // end of huge if-else - - } // end of while(1) - - if (!ok) - { - retval = NULL; - nexthere = savenexthere; - nexttarget = savenexttarget; - } - return (retval); -} - - -// ============================================================================ -// The name has changed because the API HAS CHANGED! -// -// Now instead of returning HERE, it always returns the start of the match. -// -// However, there is an array, here[], that is filled with the locations of -// the HERE tokens. -// (Starting at 1. here[0] is a copy of the start of the match.) -// -// The here[] array, starting at 1, is filled with the locations of the -// HERE token. -// here[0] is a copy of the start of the match. -// -// Also, the target[] array, starting at 1, is filled with the target -// addresses of all CALL, JMP, JZ, JNZ, and JCC tokens. -// -// Finally, you no longer pass it a search length. Instead, each set of -// search terms must end with an EOL. -// -// -// -// Okay, I admit this one is complicated. Treat it as a black box. -// -// Search Dwarf Fortress's code and initialized data segments for a pattern. -// (Does not search stack, heap, or thread-local memory.) -// -// Parameters: any number of search tokens, all unsigned ints. -// The last token must be EOL. -// -// 0x00 - 0xFF: Match this byte. -// EOL: End-of-list. The match succeeds when this token is reached. -// ANYBYTE: Match any byte. -// DWORD_: Followed by a dword. Exact-match the dword. -// Equivalent to 4 match-this-byte tokens. -// ANYDWORD: Match any dword. Equivalant to 4 ANYBYTEs. -// HERE: Put the current address into the here[] array. -// SKIP_UP_TO, nn: Allow up to nn bytes between the previous match -// and the next match. The next token must be a match-this-byte -// token. There is sweet, sweet backtracking. -// EITHER: Accept either of the next two tokens as a match. -// Both must be match-this-byte tokens. -// RANGE_LO, nn: Set low byte for a range comparison. DEPRECATED. -// RANGE_HI, nn: Set high byte for a range comparison, and do the -// comparison. Should immediately follow a RANGE_LO. DEPRECATED. -// BYTERANGE, nn, mm: followed by two bytes, the low and high limits -// of the range. This is the new way to do ranges. -// DWORDRANGE, nnnnnnnn, mmmmmmmm: works like BYTERANGE. -// ADDRESS: Accept any legal address in the program's text. -// DOES NOT accept pointers into heap space and such. -// CALL: Match a near call instruction to a reasonable address. -// JUMP: Match a short or near unconditional jump to a reasonable -// address. -// JZ: Match a short or long jz (jump if zero) instruction. -// JNZ: Match a short or long jnz (jump if not zero) instruction. -// JCC: Match any short or long conditional jump instruction. -// More tokens can easily be added. -// -// Returns the offset in Dwarf Fortress of the first match of the pattern. -// Also sets global variables here[] and target[]. -// -// Note: starting a pattern with ANYBYTE, ANYDWORD, SKIP_UP_TO, or EOL -// is explicitly illegal. -// -// -// implementation detail: search() uses a cached copy of the memory, so -// poke()s and patch()s will not be reflected in the searches. -// -// implementation detail: Q: why don't we discard count and always use EOL? -// A: because we need a fixed parameter to start the va_list. -// (Hmm, could we grab address of a local variable, walk the stack -// until we see &hexsearch, and use that address to init va_list?) -// (No, dummy, because &hexsearch is not on the stack. The stack -// holds the return address.) -// (Could we grab the EBP register and treat it as a stack frame?) -// (Maybe, but the compiler decides if EBP really is a stack frame, -// so that would be an implementation dependency. Don't do it.) -// -// TODO: should be a way to repeat a search in case we want the second or -// eleventh occurance. -// -// TODO: allow EITHER to accept arbitrary (sets of) tokens. -// (How would that work? Have two sub-patterns, each terminating -// with EOL?) -// -DWORD hexsearch2(DWORD token1, ...) -{ - DWORD size; - BYTE *nextoffset, *foundit; - DWORD token; - int i; - va_list va; - - for (i = 0; i < 16; i++) here[i] = 0; - for (i = 0; i < 16; i++) target[i] = 0; - - nexthere = 1; - nexttarget = 1; - - if ( token1 == ANYBYTE - || token1 == ANYDWORD - || token1 == SKIP_UP_TO - || token1 == HERE - || token1 == EOL ) - { - return 0; - } - - dump(searchmemstart); - dump(searchmemend); - dump(df_memory_start); - dump(copy_of_df_memory); - nextoffset = copy_of_df_memory; - nextoffset += (searchmemstart - df_memory_start); - dump(nextoffset); - size = searchmemend - searchmemstart; - dump(size); - - while (1) - { - // for speed, if we start with a raw byte, use a builtin function - // to skip ahead to the next actual occurance. - if (token1 <= 0xFF) - { - nextoffset = (BYTE *)memchr(nextoffset, token1, - size - (nextoffset - copy_of_df_memory)); - if (nextoffset == NULL) break; - } - - va_start(va, token1); - foundit = hexsearch_match2(nextoffset, token1, va); - va_end(va); - - if (foundit) - { - break; - } - - if ((DWORD)(++nextoffset - copy_of_df_memory - (searchmemstart - df_memory_start)) >= size) - { - break; - } - - } - - if (!foundit) - { - d_printf("hexsearch2(%X", token1); - i = 0; - va_start(va, token1); - do - { - d_printf(",%X", token = va_arg(va, DWORD)); - } while (EOL != token && i++ < 64); - va_end(va); - if (i >= 64) d_printf("..."); - d_printf(")\n"); - d_printf("search failed!\n"); - for (i = 0; i < 16; i++) - { - here[i] = 0; - target[i] = 0; - } - return 0; - } - - here[0] = (DWORD)foundit; - for (i = 0; i < 16; i++) - { - if (i < nexthere && here[i] != 0) - { - here[i] += df_memory_start - (DWORD)copy_of_df_memory; - } - else here[i] = 0; - } - for (i = 0; i < 16; i++) - { - if (i < nexttarget && target[i] != 0) - { - target[i] += df_memory_start - (DWORD)copy_of_df_memory; - } - else target[i] = 0; - } - - return df_memory_start + (foundit - copy_of_df_memory); -} - - -// ---------------------------------------------------------------------------- -void set_hexsearch2_limits(DWORD start, DWORD end) -{ - if (end < start) end = start; - - searchmemstart = start >= df_memory_start ? start : df_memory_start; - searchmemend = end >= df_memory_start && end <= df_memory_end ? - end : df_memory_end; -} - - -// ============================================================================ -// helper function for patch and verify. does the actual work. -static BOOL vpatchengine(BOOL mode, DWORD address, va_list va) -{ - // mode: TRUE == patch, FALSE == verify - DWORD next = address, a, c; - // a is token, c is helper value, b is asm instruction byte to use. - BYTE b; - BOOL ok = FALSE; - - while (1) - { - //if (length == 0) { ok = TRUE; break; } - //length--; - a = va_arg(va, unsigned int); - - if (a == EOL) - { - ok = TRUE; - break; - } - - if (a == DWORD_) - { - //if (length-- == 0) break; - c = va_arg(va, unsigned int); - if (mode ? !poked(next, c) : c != peekd(next)) break; - next += 4; - continue; - } - - if (a == CALL || a == JUMP) - { - b = (a == CALL ? 0xE8 : 0xE9); - //if (length-- == 0) break; - c = va_arg(va, unsigned int) - (next + 5); - if (mode ? !pokeb(next, b) : b != peekb(next)) break; - // do NOT merge the next++ into the previous if statement. - next++; - if (mode ? !poked(next, c) : c != peekd(next)) break; - next += 4; - continue; - } - - if (a == JZ || a == JNZ) - { - b = (a == JZ ? 0x84 : 0x85); - //if (length-- == 0) break; - c = va_arg(va, unsigned int) - (next + 6); - if (mode ? !pokeb(next, 0x0F) : 0x0F != peekb(next)) break; - next++; - if (mode ? !pokeb(next, b) : b != peekb(next)) break; - next++; - if (mode ? !poked(next, c) : c != peekd(next)) break; - next += 4; - continue; - } - - if (a <= 0xFF) - { - if (mode ? !pokeb(next, a) : a != peekb(next)) break; - next++; - continue; - } - - d_printf("vpatchengine: unsupported token: %08X\n", a); - break; // unsupported token - } - -// d_printf("vpatchengine returning %d, length is %d, next is %08X\n", -// ok, length, next); - return(ok); -} - - -// ---------------------------------------------------------------------------- -// patch() and verify() support a modified subset of hex_search() tokens: -// -// 0x00 - 0xFF: poke the byte. -// EOL: end-of-list. terminate when this token is reached. -// DWORD_: Followed by a DWORD, not a byte. Poke the DWORD. -// CALL: given an _address_; pokes near call with the proper _delta_. -// JUMP: given an _address_; pokes near jump with the proper _delta_. -// JZ: given an _address_; assembles a near (not short) jz & delta. -// JNZ: given an _address_; assembles a near jnz & delta. -// -// Particularly note that, unlike hex_search(), CALL, JUMP, JZ, and JNZ -// are followed by a dword-sized target address. -// -// Note that patch() does its own verify(), so you don't have to. -// -// TODO: doing so many individual pokes and peeks is slow. Consider -// building a copy, then doing a pokearb/peekarb. - -// Make an offset in Dwarf Fortress have certain bytes. -BOOL patch2(DWORD address, ...) -{ - va_list va; - BOOL ok; - - va_start(va, address); - ok = vpatchengine(TRUE, address, va); - va_end(va); - - va_start(va, address); - if (ok) ok = vpatchengine(FALSE, address, va); - va_end(va); - return(ok); -} - - -// ---------------------------------------------------------------------------- -// Check that an offset in Dwarf Fortress has certain bytes. -// -// See patch() documentation. -BOOL verify2(DWORD address, ...) -{ - BOOL ok; - va_list va; - va_start(va, address); - ok = vpatchengine(FALSE, address, va); - va_end(va); - return(ok); -} - -// ---------------------------------------------------------------------------- -// Get the exe name of the DF executable -static DWORD get_exe_base(DWORD pid) -{ - HANDLE snap = INVALID_HANDLE_VALUE; - PROCESSENTRY32 process = {0}; - MODULEENTRY32 module = {0}; - - do - { - snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (snap == INVALID_HANDLE_VALUE) - { - errormessage = "CreateToolhelp32Snapshot(Process) failed."; - break; - } - - // Get the process exe name - process.dwSize = sizeof(PROCESSENTRY32); - if (!Process32First(snap, &process)) - { - errormessage = "Process32First(snapshot) failed."; - break; - } - do - { - if (process.th32ProcessID == pid) - { - break; - } - else - { - //d_printf("Process: %d \"%.*s\"", process.th32ProcessID, MAX_PATH, process.szExeFile); - } - } while (Process32Next(snap, &process)); - if (process.th32ProcessID != pid) - { - errormessage = "Process32List(snapshot) Couldn't find the target process in the snapshot?"; - break; - } - - d_printf("Target Process: %d \"%.*s\"", process.th32ProcessID, MAX_PATH, process.szExeFile); - CloseHandle(snap); - - snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); - if (snap == INVALID_HANDLE_VALUE) - { - errormessage = "CreateToolhelp32Snapshot(Modules) failed."; - break; - } - - // Now find the module - module.dwSize = sizeof(MODULEENTRY32); - if (!Module32First(snap, &module)) - { - errormessage = "Module32First(snapshot) failed."; - break; - } - do - { - if (!stricmp(module.szModule, process.szExeFile)) - { - break; - } - else - { - //d_printf("Module: %08X \"%.*s\" \"%.*s\"", (DWORD)(SIZE_T)module.modBaseAddr, MAX_MODULE_NAME32 + 1, module.szModule, MAX_PATH, module.szExePath); - } - } while (Module32Next(snap, &module)); - if (stricmp(module.szModule, process.szExeFile)) - { - errormessage = "Module32List(snapshot) Couldn't find the target module in the snapshot?"; - break; - } - d_printf("Target Module: %08X \"%.*s\" \"%.*s\"", (DWORD)(SIZE_T)module.modBaseAddr, MAX_MODULE_NAME32 + 1, module.szModule, MAX_PATH, module.szExePath); - } while (0); - - if (snap != INVALID_HANDLE_VALUE) - { - CloseHandle(snap); - } - - if (errormessage != NULL && strlen(errormessage) != 0) - { - d_printf("%s\n", errormessage); - return 0; - } - - return (DWORD)(SIZE_T)module.modBaseAddr; -} - -// ============================================================================ -void cleanup(void) -{ - - if (copy_of_df_memory != NULL) - { - GlobalFree(copy_of_df_memory); - copy_of_df_memory = NULL; - } - - if (suspended) - { - if ((DWORD)-1 == ResumeThread(df_h_thread)) - { - // do what? apologise? - } - else suspended = FALSE; - } -#if 0 - // do this incase earlier runs crashed without executing the atexit handler. - // TODO: trap exceptions? - ResumeThread(df_h_thread); - ResumeThread(df_h_thread); - ResumeThread(df_h_thread); - ResumeThread(df_h_thread); - ResumeThread(df_h_thread); - ResumeThread(df_h_thread); - ResumeThread(df_h_thread); - ResumeThread(df_h_thread); - ResumeThread(df_h_thread); - ResumeThread(df_h_thread); - ResumeThread(df_h_thread); - ResumeThread(df_h_thread); -#endif - - if (df_h_thread != NULL) - { - CloseHandle(df_h_thread); - df_h_thread = NULL; - } - if (df_h_process != NULL) - { - CloseHandle(df_h_process); - df_h_process = NULL; - } -} - - -// ---------------------------------------------------------------------------- -BOOL open_dwarf_fortress(void) -{ - HANDLE df_main_wh; - char *state; - - change_page_permissions = FALSE; - - atexit(cleanup); - - df_memory_base = 0x400000; // executables start here unless - // explicitly relocated. - errormessage = ""; - - - // trigger a GPF - //*(char *)(0) = '!'; - - // trigger an invalid instruction (or DEP on newer processors). - // 0F 0B is the UD1 pseudo-instruction, explicitly reserved as an invalid - // instruction to trigger faults. - //asm(".fill 1, 1, 0x0F; .fill 1, 1, 0x0B"); - - state = "calling FindWindow()... "; - d_printf(state); - df_main_wh = FindWindow("OpenGL","Dwarf Fortress"); - d_printf("done\n"); - dump(df_main_wh); - if (df_main_wh == 0) - { - df_main_wh = FindWindow("SDL_app","Dwarf Fortress"); - if (df_main_wh == 0) - { - errormessage = "FindWindow(Dwarf Fortress) failed.\nIs the game running?"; - return FALSE; - } - } - - state = "calling GetWindowThreadProcessId()... "; - d_printf(state); - df_main_win_tid = GetWindowThreadProcessId(df_main_wh, &df_pid); - d_printf("done\n"); - dump(df_pid); - dump(df_main_win_tid); - - if (df_main_win_tid == 0) { - errormessage = - "GetWindowThreadProcessId(Dwarf Fortress) failed.\n" - "That should not have happened!"; - return FALSE; - } - - state = "calling OpenProcess()... "; - d_printf(state); - df_h_process = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_VM_OPERATION | PROCESS_SUSPEND_RESUME | PROCESS_QUERY_INFORMATION, FALSE, df_pid); - d_printf("done\n"); - dump(df_h_process); - if (df_h_process == NULL) - { - errormessage = "OpenProcess(Dwarf Fortress) failed.\n" - "Are you the same user that started the game?"; - return(FALSE); - } - - state = "calling OpenThread()... "; - d_printf(state); - df_h_thread = OpenThread(THREAD_ALL_ACCESS, FALSE, df_main_win_tid); - d_printf("done\n"); - dump(df_h_thread); - if (df_h_thread == NULL) - { - errormessage = "OpenThread(Dwarf Fortress) failed."; - return(FALSE); - } - - // TODO enum and suspend all threads? - state = "calling SuspendThread()... "; - d_printf(state); - if ((DWORD)-1 == SuspendThread(df_h_thread)) - { - errormessage = "SuspendThread(Dwarf Fortress) failed."; - return(FALSE); - } - d_printf("done\n"); - suspended = TRUE; - - // get the base of the df executable - df_memory_base = get_exe_base(df_pid); - if (!df_memory_base) - { - errormessage = "GetModuleBase(Dwarf Fortress) failed."; - return(FALSE); - } - dump(df_memory_base); - - // we could get this from the PE header, but why bother? - df_memory_start = df_memory_base + 0x1000; - dump(df_memory_start); - - // df_memory_end is based on the SizeOfImage field from the in-memory - // copy of the PE header. - df_memory_end = df_memory_base + peekd(df_memory_base+peekd(df_memory_base+0x3C)+0x50)-1; - dump(df_memory_end); - - state = "calling GlobalAlloc(huge)... "; - d_printf(state); - dump(df_memory_end - df_memory_start + 0x100); - if (NULL == (copy_of_df_memory = (BYTE *)GlobalAlloc(GPTR, df_memory_end - df_memory_start + 0x100))) - { - errormessage = "GlobalAlloc() of copy_of_df_memory failed"; - return FALSE; - } - d_printf("done\n"); - - state = "copying memory... "; - if (!peekarb(df_memory_start, copy_of_df_memory, df_memory_end-df_memory_start)) - { - d_printf("peekarb(entire program) for search()'s use failed\n"); - return FALSE; - } - - set_hexsearch2_limits(0, 0); - - return(TRUE); -} - - -// not (normally) necessary because it is done at exit time by atexit(). -// however you can call this to resume DF before putting up a dialog box. -void close_dwarf_fortress(void) -{ - cleanup(); -} - diff --git a/tools/playground/hexsearch2.h b/tools/playground/hexsearch2.h deleted file mode 100644 index 8cff56b90..000000000 --- a/tools/playground/hexsearch2.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Author: Silas Dunsmore aka 0x517A5D vim:ts=4:sw=4 - * - * Released under the MIT X11 license; feel free to use some or all of this - * code, as long as you include the copyright and license statement (below) - * in all copies of the source code. In fact, I truly encourage reuse. - * - * If you do use large portions of this code, I suggest but do not require - * that you keep this code in a seperate file (such as this hexsearch.h file) - * so that it is clear that the terms of the license do not also apply to - * your code. - * - * Should you make fundamental changes, or bugfixes, to this code, I would - * appreciate it if you would give me a copy of your changes. - * - * - * Copyright (C) 2007-2008 Silas Dunsmore - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * See also: http://www.opensource.org/licenses/mit-license.php - * and http://en.wikipedia.org/wiki/MIT_License - */ - - -#ifndef HEXSEARCH_H -#define HEXSEARCH_H -#ifdef __cplusplus -extern "C" -{ -#endif - - -extern DWORD df_memory_base, df_memory_start, df_memory_end; -extern HANDLE df_h_process, df_h_thread; -extern DWORD df_pid, df_main_win_tid; - -extern DWORD here[16]; -extern DWORD target[16]; - -// ============================================================================ -// export these in case you need to work with them directly. -//extern HANDLE df_h_process, df_h_thread; -//extern DWORD df_pid, df_main_win_tid; -extern char *errormessage; - - -// ============================================================================ -// send info to KERNEL32:OutputDebugString(), useful for non-console programs. -// (you can watch this with SysInternals' DebugView.) -// http://www.microsoft.com/technet/sysinternals/Miscellaneous/DebugView.mspx -void d_printf(const char *format, ...); -// it turned out that dprintf() is semi-standard to printf to a file descriptor. - - -// ============================================================================ -// encapsulate the housekeeping. -BOOL open_dwarf_fortress(void); -void close_dwarf_fortress(void); // is not (normally) necessary because - // it is done at exit time. - - -// ============================================================================ -// memory reads and writes (peeks and pokes, in old BASIC terminology) -BOOL isvalidaddress(DWORD ea); -BOOL peekarb(DWORD ea, OUT void *data, DWORD len); -BYTE peekb(DWORD ea); -WORD peekw(DWORD ea); -DWORD peekd(DWORD ea); -char *peekstr(DWORD ea, OUT char *data, DWORD maxlen); -char *peekustr(DWORD ea, OUT char *data, DWORD maxlen); -BOOL pokearb(DWORD ea, const void *data, DWORD len); -BOOL pokeb(DWORD ea, BYTE data); -BOOL pokew(DWORD ea, WORD data); -BOOL poked(DWORD ea, DWORD data); -BOOL pokestr(DWORD ea, const BYTE *data); - - -// ============================================================================ -// The name has changed because the API HAS CHANGED! -// -// Now instead of returning HERE, it always returns the start of the match. -// -// However, there is an array, here[], that is filled with the locations of -// the HERE tokens. -// (Starting at 1. here[0] is a copy of the start of the match.) -// -// The here[] array, starting at 1, is filled with the locations of the -// HERE token. -// here[0] is a copy of the start of the match. -// -// Also, the target[] array, starting at 1, is filled with the target -// addresses of all CALL, JMP, JZ, JNZ, and JCC tokens. -// -// Finally, you no longer pass it a search length. Instead, each set of -// search terms must end with an EOL. -// -// -// -// Okay, I admit this one is complicated. Treat it as a black box. -// -// Search Dwarf Fortress's code and initialized data segments for a pattern. -// (Does not search stack, heap, or thread-local memory.) -// -// Parameters: any number of search tokens, all unsigned ints. -// The last token must be EOL. -// -// 0x00 - 0xFF: Match this byte. -// EOL: End-of-list. The match succeeds when this token is reached. -// ANYBYTE: Match any byte. -// DWORD_: Followed by a dword. Exact-match the dword. -// Equivalent to 4 match-this-byte tokens. -// ANYDWORD: Match any dword. Equivalant to 4 ANYBYTEs. -// HERE: Put the current address into the here[] array. -// SKIP_UP_TO, nn: Allow up to nn bytes between the previous match -// and the next match. The next token must be a match-this-byte -// token. There is sweet, sweet backtracking. -// EITHER: Accept either of the next two tokens as a match. -// Both must be match-this-byte tokens. -// RANGE_LO, nn: Set low byte for a range comparison. DEPRECATED. -// RANGE_HI, nn: Set high byte for a range comparison, and do the -// comparison. Should immediately follow a RANGE_LO. DEPRECATED. -// BYTERANGE, nn, mm: followed by two bytes, the low and high limits -// of the range. This is the new way to do ranges. -// DWORDRANGE, nnnnnnnn, mmmmmmmm: works like BYTERANGE. -// ADDRESS: Accept any legal address in the program's text. -// DOES NOT accept pointers into heap space and such. -// CALL: Match a near call instruction to a reasonable address. -// JUMP: Match a short or near unconditional jump to a reasonable -// address. -// JZ: Match a short or long jz (jump if zero) instruction. -// JNZ: Match a short or long jnz (jump if not zero) instruction. -// JCC: Match any short or long conditional jump instruction. -// More tokens can easily be added. -// -// Returns the offset in Dwarf Fortress of the first match of the pattern. -// Also sets global variables here[] and target[]. -// -// Note: starting a pattern with ANYBYTE, ANYDWORD, SKIP_UP_TO, or EOL -// is explicitly illegal. -// -#define EOL 0x100 -#define ANYBYTE 0x101 -//#define FF_OR_00 0x102 // deprecated -#define HERE 0x103 -#define EITHER 0x104 -#define SKIP_UP_TO 0x105 -#define RANGE_LO 0x106 // deprecated -#define RANGE_HI 0x107 // deprecated -#define DWORD_ 0x108 -#define ANYDWORD 0x109 -#define ADDRESS 0x10A -#define BYTERANGE 0x10B -#define DWORDRANGE 0x10C -#define JZ 0x174 -#define JNZ 0x175 -#define JCC 0x170 -#define CALL 0x1E8 -#define JUMP 0x1E9 - - -DWORD hexsearch2(DWORD token1, ...); - -// You can use this to limit the search to a particular part of memory. -// Use 0 for start to search from the very start of Dwarf Fortress. -// Use 0 for end to stop searching at the very end of Dwarf Fortress. -void set_hexsearch2_limits(DWORD start, DWORD end); - - -// ============================================================================ -// patch2() and verify2() support a modified subset of hex_search2() tokens: -// The names changed because the API HAS CHANGED! -// -// 0x00 - 0xFF: pokes the byte. -// EOL: End-of-list. Allows you to specify count as 10000 or so -// and terminate (with success) when this token is reached. -// DWORD_: Followed by a DWORD. Pokes the DWORD. -// CALL: given an _address_; pokes near call with the proper _delta_. -// JUMP: given an _address_; pokes near jump with the proper _delta_. -// JZ: given an _address_; assembles a near (not short) jz & delta. -// JNZ: given an _address_; assembles a near jnz & delta. -// -// Particularly note that, unlike hex_search(), CALL, JUMP, JZ, and JNZ -// are followed by a dword-sized target address. -// -// Note that patch2() does its own verify(), so you don't have to. - -// TODO: is verify() useful enough to maintain? - -// Make an offset in Dwarf Fortress have certain bytes. -BOOL patch2(DWORD offset, ...); -// Check that an offset in Dwarf Fortress has certain bytes. -BOOL verify2(DWORD offset, ...); - - - -#ifdef __cplusplus -} -#endif -#endif // HEXSEARCH_H \ No newline at end of file diff --git a/tools/playground/lumberjack.cpp b/tools/playground/lumberjack.cpp deleted file mode 100644 index 85cd34d07..000000000 --- a/tools/playground/lumberjack.cpp +++ /dev/null @@ -1,5 +0,0 @@ - -int main (int numargs, const char ** args) -{ - return 0; -} diff --git a/tools/playground/moodump.cpp b/tools/playground/moodump.cpp deleted file mode 100644 index 37c52a3d9..000000000 --- a/tools/playground/moodump.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include -#include -using namespace std; -#include - -DFHack::Materials * Materials; -DFHack::VersionInfo *mem; -vector< vector > englishWords; -vector< vector > foreignWords; - -int main (int numargs, char ** args) -{ - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context *DF = DFMgr.getSingleContext(); - DFHack::Process * p; - try - { - DF->Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - p = DF->getProcess(); - string check = ""; - if(numargs == 2) - check = args[1]; - - DFHack::Creatures * Creatures = DF->getCreatures(); - Materials = DF->getMaterials(); - DFHack::Translation * Tran = DF->getTranslation(); - - uint32_t numCreatures; - if(!Creatures->Start(numCreatures)) - { - cerr << "Can't get creatures" << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - if(!numCreatures) - { - cerr << "No creatures to print" << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - mem = DF->getMemoryInfo(); - - if(!Materials->ReadInorganicMaterials()) - { - cerr << "Can't get the inorganics types." << endl; - return 1; - } - if(!Materials->ReadCreatureTypesEx()) - { - cerr << "Can't get the creature types." << endl; - return 1; - } - if(!Tran->Start()) - { - 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; - unsigned int current_job; - unsigned int mat_start; - unsigned int mat_end; - unsigned int j,k; - unsigned int matptr; - - Creatures->ReadCreature(i,temp); - if(temp.mood>=0) - { - current_job = p->readDWord(temp.origin + 0x390); - if(current_job == 0) - continue; - mat_start = p->readDWord(current_job + 0xa4 + 4*3); - mat_end = p->readDWord(current_job + 0xa4 + 4*4); - for(j=mat_start;jreadDWord(j); - for(k=0;k<4;k++) - printf("%.4X ", p->readWord(matptr + k*2)); - for(k=0;k<3;k++) - printf("%.8X ", p->readDWord(matptr + k*4 + 0x8)); - for(k=0;k<2;k++) - printf("%.4X ", p->readWord(matptr + k*2 + 0x14)); - for(k=0;k<3;k++) - printf("%.8X ", p->readDWord(matptr + k*4 + 0x18)); - for(k=0;k<4;k++) - printf("%.2X ", p->readByte(matptr + k + 0x24)); - for(k=0;k<6;k++) - printf("%.8X ", p->readDWord(matptr + k*4 + 0x28)); - for(k=0;k<4;k++) - printf("%.2X ", p->readByte(matptr + k + 0x40)); - for(k=0;k<9;k++) - printf("%.8X ", p->readDWord(matptr + k*4 + 0x44)); - printf(" [%p]\n", matptr); - } - } - } - Creatures->Finish(); - DF->Detach(); - return 0; -} - diff --git a/tools/playground/paths.cpp b/tools/playground/paths.cpp deleted file mode 100644 index cc00f79a3..000000000 --- a/tools/playground/paths.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include -using namespace std; - -#include -using namespace DFHack; - -int main () -{ - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context *DF = DFMgr.getSingleContext(); - try - { - DF->Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - DFHack::Process * Process = DF->getProcess(); - DFHack::Gui * gui = DF->getGui(); - cout << Process->getPath() << endl; - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -} \ No newline at end of file diff --git a/tools/playground/primitives.cpp b/tools/playground/primitives.cpp deleted file mode 100644 index bdf837d62..000000000 --- a/tools/playground/primitives.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -using namespace std; -std::string teststr1; - std::string * teststr2; - std::string teststr3("test"); -int main (int numargs, const char ** args) -{ - printf("std::string E : 0x%x\n", &teststr1); - teststr1 = "This is a fairly long string, much longer than the one made by default constructor."; - cin.ignore(); - printf("std::string L : 0x%x\n", &teststr1); - teststr1 = "This one is shorter"; - cin.ignore(); - printf("std::string S : 0x%x\n", &teststr1); - cin.ignore(); - teststr2 = new string(); - printf("std::string * : 0x%x\n", &teststr2); - printf("std::string(\"test\") : 0x%x\n", &teststr3); - cin.ignore(); - return 0; -} diff --git a/tools/playground/printtiletypes.cpp b/tools/playground/printtiletypes.cpp deleted file mode 100644 index 6d37e0a1b..000000000 --- a/tools/playground/printtiletypes.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Prints all the Tile Types known by DFHack. -// File is both fixed-field and CSV parsable. - -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -#include -#include - -using namespace DFHack; - -int main (int argc, char **argv) -{ - FILE *f=stdout; - const int Columns = 7; - const char * Headings[Columns] = {"TileTypeID","Class","Material","V","Special","Direction","Description"}; - size_t Size[ Columns ] = {}; - int i; - - //First, figure out column widths. - for(i=0;i(Size[1],strlen(TileShapeString[i])); - fprintf(f,"%4i ; %s\n", i, TileShapeString[i] ,0 ); - } - - //Materials - fprintf(f,"\nTile Type Materials:\n"); - for(i=0;i(Size[2],strlen(TileMaterialString[i])); - fprintf(f,"%4i ; %s\n", i, TileMaterialString[i] ,0 ); - } - - //Specials - fprintf(f,"\nTile Type Specials:\n"); - for(i=0;i(Size[4],strlen(TileSpecialString[i])); - fprintf(f,"%4i ; %s\n", i, TileSpecialString[i] ,0 ); - } - - /* - Not needed for now - - //Direction is tricky - for(i=0;i -#include -#include -#include -using namespace std; - -#define DFHACK_WANT_MISCUTILS -#include -#include -#include -#include - -vector< vector > englishWords; -vector< vector > foreignWords; -uint32_t numCreatures; -vector creaturestypes; - -void printDwarves(DFHack::ContextManager & DF) -{ - int dwarfCounter = 0; - DFHack::Creatures * c = DF.getCreatures(); - for (uint32_t i = 0; i < numCreatures; i++) - { - DFHack::t_creature temp; - c->ReadCreature(i, temp); - string type = creaturestypes[temp.type].id; - if (type == "DWARF" && !temp.flags1.bits.dead && !temp.flags2.bits.killed) - { - cout << i << ":"; - if (temp.name.nickname[0]) - { - cout << temp.name.nickname; - } - else - { - cout << temp.name.first_name; - } - string transName = DF.TranslateName(temp.name,englishWords,foreignWords, false); - cout << " " << temp.custom_profession; //transName; - if (dwarfCounter%3 != 2) - { - cout << '\t'; - } - else - { - cout << endl; - } - dwarfCounter++; - } - } -} - -bool getDwarfSelection(DFHack::ContextManager & DF, DFHack::t_creature & toChange,string & changeString, string & commandString,int & eraseAmount,int &dwarfNum,bool &isName) -{ - static string lastText; - bool dwarfSuccess = false; - - while (!dwarfSuccess) - { - string input; - cout << "\nSelect Dwarf to Change or q to Quit" << endl; - DF.Resume(); - getline (cin, input); - DF.Suspend(); - if (input == "q") - { - return false; - } - else if (input == "r") - { - printDwarves(DF); - } - else if (!input.empty()) - { - int num; - stringstream(input) >> num;//= atol(input.c_str()); - dwarfSuccess = DF.ReadCreature(num,toChange); - string type = creaturestypes[toChange.type].id; - if (type != "DWARF") - { - dwarfSuccess = false; - } - else - { - dwarfNum = num; - } - } - } - bool changeType = false; - while (!changeType) - { - string input; - cout << "\n(n)ickname or (p)rofession?" << endl; - getline(cin, input); - if (input == "q") - { - return false; - } - if (input == "n") - { - commandString = "pzyn"; - eraseAmount = string(toChange.name.nickname).length(); - changeType = true; - isName = true; - } - else if (input == "p") - { - commandString = "pzyp"; - eraseAmount = string(toChange.custom_profession).length(); - changeType = true; - isName = false; - } - } - bool changeValue = false; - while (!changeValue) - { - string input; - cout << "value to change to?" << endl; - getline(cin, input); - if (input == "q") - { - return false; - } - if (!lastText.empty() && input.empty()) - { - changeValue = true; - } - else if ( !input.empty()) - { - lastText = input; - changeValue = true; - } - } - changeString = lastText; - return true; -} - -bool waitTillChanged(DFHack::ContextManager &DF, int creatureToCheck, string changeValue, bool isName) -{ - DFHack::DFWindow * w = DF.getWindow(); - DF.Suspend(); - DFHack::t_creature testCre; - DF.ReadCreature(creatureToCheck,testCre); - int tryCount = 0; - if (isName) - { - while (testCre.name.nickname != changeValue && tryCount <50) - { - DF.Resume(); - w->TypeSpecial(DFHack::WAIT,1,100); - DF.Suspend(); - DF.ReadCreature(creatureToCheck,testCre); - tryCount++; - } - } - else - { - while (testCre.custom_profession != changeValue && tryCount < 50) - { - DF.Resume(); - w->TypeSpecial(DFHack::WAIT,1,100); - DF.Suspend(); - DF.ReadCreature(creatureToCheck,testCre); - tryCount++; - } - } - if (tryCount >= 50) - { - cerr << "Something went wrong, make sure that DF is at the correct screen"; - return false; - } - DF.Resume(); - return true; -} - - -bool waitTillScreenState(DFHack::ContextManager &DF, string screenState,bool EqualTo=true) -{ - DFHack::DFWindow * w = DF.getWindow(); - DFHack::t_viewscreen current; - DF.Suspend(); - DF.ReadViewScreen(current); - string nowScreenState; - DF.getMemoryInfo()->resolveClassIDToClassname(current.type,nowScreenState); - int tryCount = 0; - while (((EqualTo && nowScreenState != screenState) || (!EqualTo && nowScreenState == screenState)) && tryCount < 50) - { - DF.Resume(); - w->TypeSpecial(DFHack::WAIT,1,100); - DF.Suspend(); - DF.ReadViewScreen(current); - tryCount++; - } - if (tryCount >= 50) { - cerr << "Something went wrong, DF at " << nowScreenState << endl; - return false; - } - DF.Resume(); - return true; -} - - -bool waitTillCursorState(DFHack::ContextManager &DF, bool On) -{ - DFHack::DFWindow * w = DF.getWindow(); - int32_t x,y,z; - int tryCount = 0; - DF.Suspend(); - bool cursorResult = DF.getCursorCoords(x,y,z); - while (tryCount < 50 && On && !cursorResult || !On && cursorResult) - { - DF.Resume(); - w->TypeSpecial(DFHack::WAIT,1,100); - tryCount++; - DF.Suspend(); - cursorResult = DF.getCursorCoords(x,y,z); - } - if (tryCount >= 50) - { - cerr << "Something went wrong, cursor at x: " << x << " y: " << y << " z: " << z << endl; - return false; - } - DF.Resume(); - return true; -} - - -bool waitTillMenuState(DFHack::ContextManager &DF, uint32_t menuState,bool EqualTo=true) -{ - int tryCount = 0; - DFHack::DFWindow * w = DF.getWindow(); - DF.Suspend(); - uint32_t testState = DF.ReadMenuState(); - while (tryCount < 50 && ((EqualTo && menuState != testState) || (!EqualTo && menuState == testState))) - { - DF.Resume(); - w->TypeSpecial(DFHack::WAIT,1,100); - tryCount++; - DF.Suspend(); - testState = DF.ReadMenuState(); - } - if (tryCount >= 50) - { - cerr << "Something went wrong, menuState: "<resolveClassIDToClassname(current.type,classname); - while (classname != "viewscreen_dwarfmode") - { - w->TypeSpecial(DFHack::F9); // cancel out of text input in names -// DF.TypeSpecial(DFHack::ENTER); // cancel out of text input in hotkeys - w->TypeSpecial(DFHack::SPACE); // should move up a level - if (!waitTillScreenState(DF,classname,false)) return false; // wait until screen changes from current - DF.ReadViewScreen(current); - DF.getMemoryInfo()->resolveClassIDToClassname(current.type,classname); - } - if (DF.ReadMenuState() != 0) {// if menu state != 0 then there is a menu, so escape it - w->TypeSpecial(DFHack::F9); - w->TypeSpecial(DFHack::ENTER); // exit out of any text prompts - w->TypeSpecial(DFHack::SPACE); // go back to base state - if (!waitTillMenuState(DF,0))return false; - } - DF.Resume(); - return true; -} - - -bool setCursorToCreature(DFHack::ContextManager &DF) -{ - DFHack::DFWindow * w = DF.getWindow(); - int32_t x,y,z; - DF.Suspend(); - DF.getCursorCoords(x,y,z); - DF.Resume(); - if (x == -30000) { - w->TypeStr("v"); - if (!waitTillCursorState(DF,true)) return false; - } - else { // reset the cursor to be the creature cursor - w->TypeSpecial(DFHack::SPACE); - if (!waitTillCursorState(DF,false)) return false; - w->TypeStr("v"); - if (!waitTillCursorState(DF,true)) return false; - } - return true; -} - - -int main (void) -{ - DFHack::ContextManager DF("Memory.xml"); - DFHack::Creatures *c; - DFHack::Materials *m; - try - { - DF.Attach(); - c = DF.getCreatures(); - - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - DFHack::memory_info * mem = DF.getMemoryInfo(); - - - if (!m->ReadCreatureTypes(creaturestypes)) - { - cerr << "Can't get the creature types." << endl; - return 1; - } - - DF.InitReadNameTables(englishWords,foreignWords); - c->Start(numCreatures); - // DF.InitViewAndCursor(); - DFHack::Process * p = DF.getProcess(); - DFHack::DFWindow * w = DF.getWindow(); - - DFHack::t_creature toChange; - string changeString,commandString; - int eraseAmount; - int toChangeNum; - bool isName; - bool useKeys = true; - string input2; - - // use key event emulation or direct writing? - cout << "\nUse \n1:Key simulation\n2:Direct Writing" << endl; - getline(cin,input2); - if (input2 == "1") - { - useKeys = true; - } - else { - useKeys = false; - } - printDwarves(DF); - - while (getDwarfSelection(DF,toChange,changeString,commandString,eraseAmount,toChangeNum,isName)) - { - // limit length, DF doesn't accept input after this point - if (changeString.size() > 39) - { - changeString.resize(39); - } -start: - bool completed = false; - if (useKeys) { - if (moveToBaseWindow(DF) && setCursorToCreature(DF)) - { - DF.Suspend(); - DF.setCursorCoords(toChange.x, toChange.y,toChange.z); - uint32_t underCursor; - DF.getCurrentCursorCreature(underCursor); - while (underCursor != toChangeNum) - { - DF.Resume(); - w->TypeStr("v",100); - DF.Suspend(); - DF.setCursorCoords(toChange.x, toChange.y,toChange.z); - DF.ReadCreature(toChangeNum,toChange); - DF.getCurrentCursorCreature(underCursor); - } - /*//CurrentCursorCreatures gives the creatures in the order that you see them with the 'k' cursor. - //The 'v' cursor displays them in the order of last, then first,second,third and so on - //Pretty weird, but it works - //The only place that seems to display which creature is currently selected is on the stack, whose location is likely not static, so not usable - if (underCursor[underCursor.size()-1] != toChange.origin) - { - for (int i = 0;iTypeStr("v",100); - if (underCursor[i] == toChange.origin) - { - break; - } - } - }*/ - DF.Resume(); - w->TypeStr(commandString.c_str()); - if (waitTillScreenState(DF,"viewscreen_customize_unit")) - { - DF.Resume(); - w->TypeSpecial(DFHack::BACK_SPACE,eraseAmount); - if (waitTillChanged(DF,toChangeNum,"",isName)) - { - DF.Resume(); - w->TypeStr(changeString.c_str()); - if (waitTillChanged(DF,toChangeNum,changeString,isName)) - { - DF.Resume(); - w->TypeSpecial(DFHack::ENTER); - w->TypeSpecial(DFHack::SPACE); // should take you to unit screen if everything worked - if (waitTillScreenState(DF,"viewscreen_unit")) - { - DF.Resume(); - w->TypeSpecial(DFHack::SPACE); - if (waitTillScreenState(DF,"viewscreen_dwarfmode")) - { - DF.Resume(); - w->TypeSpecial(DFHack::SPACE); - if (waitTillCursorState(DF,false)) - { - completed = true; - } - } - } - } - } - } - } - if (!completed) { - cerr << "Something went wrong, please reset DF to its original state, then press any key to continue" << endl; - goto start; - } - } - else - { - // will only work with the shm probably should check for it, but I don't know how, - // I have the writeString function do nothing for normal mode - if (commandString == "pzyn") // change nickname - { - try - { - uint32_t nickname = mem->getOffset("creature_name") + mem->getOffset("name_nickname"); - p->writeSTLString(toChange.origin+nickname,changeString); - } - catch (DFHack::Error::AllMemdef&) - { - cerr << "Writing creature nicknames unsupported in this version!" << endl; - } - } - else - { - try - { - uint32_t custom_prof = mem->getOffset("creature_custom_profession"); - p->writeSTLString(toChange.origin+custom_prof,changeString); - } - catch (DFHack::Error::AllMemdef&) - { - cerr << "Writing creature custom profession unsupported in this version!" << endl; - } - - } - } - DF.Suspend(); - printDwarves(DF); - } - return 0; -} diff --git a/tools/playground/test.c b/tools/playground/test.c deleted file mode 100644 index 0266e8f25..000000000 --- a/tools/playground/test.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include - -int main (int numargs, const char ** args) -{ - printf("From C: "); - DFHackObject* cman = ContextManager_Alloc("Memory.xml"); - DFHackObject* context = ContextManager_getSingleContext(cman); - if(context) - { - Context_Attach(context); - DFHackObject * maps = Context_getMaps(context); - if(maps) - { - Maps_Start(maps); - uint32_t x,y,z; - Maps_getSize(maps, &x, &y, &z); - printf("Map size: %d, %d, %d\n", x,y,z); - } - } - ContextManager_Free(cman); - - cout << "From C++:"; - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context * DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - // DO STUFF HERE - Maps * m = DF->getMaps(); - m->Start(); - uint32_t x,y,z; - m->getSize(x,y,z); - cout << "Map size " << x << ", "<< y << ", " << z << endl; - - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -} diff --git a/tools/playground/typeblocks.cpp b/tools/playground/typeblocks.cpp deleted file mode 100644 index 3a0b88f31..000000000 --- a/tools/playground/typeblocks.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -#include -using namespace DFHack; - -namespace TBlocks -{ - -} - -int main (int numargs, const char ** args) -{ - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context * DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - // DO STUFF HERE - - #ifndef LINUX_BUILD - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - #endif - return 0; -}