int main (void) { string select; 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 * p = DF->getProcess(); vector <DFHack::t_memrange> selected_ranges; getRanges(p,selected_ranges); DFHack::memory_info *minfo = DF->getMemoryInfo(); DFHack::memory_info::OSType os = minfo->getOS(); string prompt = "Select search type: 1=number(default), 2=vector by length, 3=vector>object>string,\n" " 4=string, 5=automated offset search, 6=vector by address in its array,\n" " 7=pointer vector by address of an object, 8=vector>first object>string\n"; int mode; do { getNumber(prompt,mode, 1, false); } while (mode < 1 || mode > 8 ); switch (mode) { case 1: DF->Detach(); FindIntegers(DFMgr, selected_ranges); break; case 2: DF->Detach(); FindVectorByLength(DFMgr, selected_ranges); break; case 3: DF->Detach(); FindVectorByObjectRawname(DFMgr, selected_ranges); break; case 4: DF->Detach(); FindStrings(DFMgr, selected_ranges); break; case 5: automatedLangtables(DF,selected_ranges); break; case 6: DF->Detach(); FindVectorByBounds(DFMgr,selected_ranges); break; case 7: DF->Detach(); FindPtrVectorsByObjectAddress(DFMgr,selected_ranges); break; case 8: DF->Detach(); FindVectorByFirstObjectRawname(DFMgr, selected_ranges); break; default: cout << "not implemented :(" << endl; } #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); #endif return 0; }
int main () { DFHack::ContextManager DF ("Memory.xml"); cout << "This utility lets you mass-designate items by type and material." << endl << "Like set on fire all MICROCLINE item_stone..." << endl << "Some unusual combinations might be untested and cause the program to crash..."<< endl << "so, watch your step and backup your fort" << endl; try { DF.Attach(); } catch (exception& e) { cerr << e.what() << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } DFHack::memory_info *mem = DF.getMemoryInfo(); DF.Suspend(); DF.InitViewAndCursor(); matGlosses mat; DF.ReadPlantMatgloss(mat.plantMat); DF.ReadWoodMatgloss(mat.woodMat); DF.ReadStoneMatgloss(mat.stoneMat); DF.ReadMetalMatgloss(mat.metalMat); DF.ReadCreatureMatgloss(mat.creatureMat); // vector <string> objecttypes; // DF.getClassIDMapping(objecttypes); uint32_t numItems; DF.InitReadItems(numItems); map< string, map<string,vector<uint32_t> > > count; int failedItems = 0; map <string, int > bad_mat_items; for(uint32_t i=0; i< numItems; i++) { DFHack::t_item temp; DF.ReadItem(i,temp); if(temp.type != -1) // this should be the case pretty much always { string typestr; mem->resolveClassIDToClassname(temp.type,typestr); string material = getMaterialType(temp,typestr,mat); if (material != "Invalid") { count[typestr][material].push_back(i); } else { if(bad_mat_items.count(typestr)) { int tmp = bad_mat_items[typestr]; tmp ++; bad_mat_items[typestr] = tmp; } else { bad_mat_items[typestr] = 1; } } } } map< string, int >::iterator it_bad; if(! bad_mat_items.empty()) { cout << "Items with badly assigned materials:" << endl; for(it_bad = bad_mat_items.begin(); it_bad!=bad_mat_items.end();it_bad++) { cout << it_bad->first << " : " << it_bad->second << endl; } } map< string, map<string,vector<uint32_t> > >::iterator it1; int i =0; for(it1 = count.begin(); it1!=count.end();it1++) { cout << i << ": " << it1->first << "\n"; i++; } if(i == 0) { cout << "No items found" << endl; DF.FinishReadBuildings(); DF.Detach(); return 0; } cout << endl << "Select an item type from the list:"; int number; string in; stringstream ss; getline(cin, in); ss.str(in); ss >> number; int j = 0; it1 = count.begin(); while(j < number && it1!=count.end()) { it1++; j++; } cout << it1->first << "\n"; map<string,vector<uint32_t> >::iterator it2; i=0; for(it2 = it1->second.begin();it2!=it1->second.end();it2++){ cout << i << ":\t" << it2->first << " [" << it2->second.size() << "]" << endl; i++; } cout << endl << "Select a material type: "; int number2; ss.clear(); getline(cin, in); ss.str(in); ss >> number2; decideAgain: cout << "Select a designation - (d)ump, (f)orbid, (m)melt, set on fi(r)e :" << flush; string designationType; getline(cin,designationType); DFHack::t_itemflags changeFlag = {0}; if(designationType == "d" || designationType == "dump") { changeFlag.bits.dump = 1; } else if(designationType == "f" || designationType == "forbid") { changeFlag.bits.forbid = 1; } else if(designationType == "m" || designationType == "melt") { changeFlag.bits.melt = 1; } else if(designationType == "r" || designationType == "fire") { changeFlag.bits.on_fire = 1; } else { goto decideAgain; } j=0; it2= it1->second.begin(); while(j < number2 && it2!=it1->second.end()) { it2++; j++; } for(uint32_t k = 0;k< it2->second.size();k++) { DFHack::t_item temp; DF.ReadItem(it2->second[k],temp); temp.flags.whole |= changeFlag.whole; DF.WriteRaw(temp.origin+12,sizeof(uint32_t),(uint8_t *)&temp.flags.whole); } DF.FinishReadItems(); DF.Detach(); #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); #endif return 0; }
int main ( int argc, char** argv ) { DFHack::memory_info *mem; DFHack::Process *proc; uint32_t creature_pregnancy_offset; //bool femaleonly = 0; bool showcreatures = 0; int maxpreg = 1000; // random start value, since its not required and im not sure how to set it to infinity list<string> s_creatures; // parse input, handle this nice and neat before we get to the connecting argstream as(argc,argv); as // >>option('f',"female",femaleonly,"Impregnate females only") >>option('s',"show",showcreatures,"Show creature list (read only)") >>parameter('m',"max",maxpreg,"The maximum limit of pregnancies ", false) >>values<string>(back_inserter(s_creatures), "any number of creatures") >>help(); // make the creature list unique s_creatures.unique(); if (!as.isOk()) { cout << as.errorLog(); return(0); } else if (as.helpRequested()) { cout<<as.usage()<<endl; return(1); } else if(showcreatures==1) { } else if (s_creatures.size() == 0 && showcreatures != 1) { cout << as.usage() << endl << "---------------------------------------" << endl; cout << "Creature list empty, assuming CATs" << endl; s_creatures.push_back("CAT"); } 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; } proc = DF->getProcess(); mem = DF->getMemoryInfo(); DFHack::Materials *Mats = DF->getMaterials(); DFHack::Creatures *Cre = DF->getCreatures(); creature_pregnancy_offset = mem->getOffset("creature_pregnancy"); if(!Mats->ReadCreatureTypesEx()) { cerr << "Can't get the creature types." << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } uint32_t numCreatures; if(!Cre->Start(numCreatures)) { cerr << "Can't get creatures" << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } int totalcount=0; int totalchanged=0; string sextype; // shows all the creatures and returns. int maxlength = 0; map<string, vector <t_creature> > male_counts; map<string, vector <t_creature> > female_counts; // classify for(uint32_t i =0;i < numCreatures;i++) { DFHack::t_creature creature; Cre->ReadCreature(i,creature); DFHack::t_creaturetype & crt = Mats->raceEx[creature.race]; string castename = crt.castes[creature.sex].rawname; if(castename == "FEMALE") { female_counts[Mats->raceEx[creature.race].rawname].push_back(creature); male_counts[Mats->raceEx[creature.race].rawname].size(); } else // male, other, etc. { male_counts[Mats->raceEx[creature.race].rawname].push_back(creature); female_counts[Mats->raceEx[creature.race].rawname].size(); //auto initialize the females as well } } // print (optional) if (showcreatures == 1) { cout << "Type\t\tMale #\tFemale #" << endl; for(map<string, vector <t_creature> >::iterator it1 = male_counts.begin();it1!=male_counts.end();it1++) { cout << it1->first << "\t\t" << it1->second.size() << "\t" << female_counts[it1->first].size() << endl; } } // process for (list<string>::iterator it = s_creatures.begin(); it != s_creatures.end(); ++it) { std::string clinput = *it; std::transform(clinput.begin(), clinput.end(), clinput.begin(), ::toupper); vector <t_creature> &females = female_counts[clinput]; uint32_t sz_fem = females.size(); totalcount += sz_fem; for(uint32_t i = 0; i < sz_fem && totalchanged != maxpreg; i++) { t_creature & female = females[i]; uint32_t preg_timer = proc->readDWord(female.origin + creature_pregnancy_offset); if(preg_timer != 0) { proc->writeDWord(female.origin + creature_pregnancy_offset, rand() % 100 + 1); totalchanged++; } } } cout << totalchanged << " pregnancies accelerated. Total creatures checked: " << totalcount << "." << endl; Cre->Finish(); DF->Detach(); #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); #endif return 0; }
Maps::Maps(DFContextShared* _d) { d = new Private; d->d = _d; Process *p = d->owner = _d->p; d->Inited = d->Started = false; DFHack::memory_info * mem = p->getDescriptor(); Server::Maps::maps_offsets &off = d->offsets; // get the offsets once here off.map_offset = mem->getAddress ("map_data"); off.x_count_offset = mem->getAddress ("x_count_block"); off.y_count_offset = mem->getAddress ("y_count_block"); off.z_count_offset = mem->getAddress ("z_count_block"); off.tile_type_offset = mem->getOffset ("map_data_type"); off.designation_offset = mem->getOffset ("map_data_designation"); off.occupancy_offset = mem->getOffset("map_data_occupancy"); off.biome_stuffs = mem->getOffset ("map_data_biome_stuffs"); off.veinvector = mem->getOffset ("map_data_vein_vector"); off.local_feature_offset = mem->getOffset ("map_data_feature_local"); off.global_feature_offset = mem->getOffset ("map_data_feature_global"); off.temperature1_offset = mem->getOffset ("map_data_temperature1_offset"); off.temperature2_offset = mem->getOffset ("map_data_temperature2_offset"); off.region_x_offset = mem->getAddress ("region_x"); off.region_y_offset = mem->getAddress ("region_y"); off.region_z_offset = mem->getAddress ("region_z"); off.world_regions = mem->getAddress ("ptr2_region_array"); off.region_size = mem->getHexValue ("region_size"); off.region_geo_index_offset = mem->getOffset ("region_geo_index_off"); off.geolayer_geoblock_offset = mem->getOffset ("geolayer_geoblock_offset"); off.world_geoblocks_vector = mem->getAddress ("geoblock_vector"); off.type_inside_geolayer = mem->getOffset ("type_inside_geolayer"); off.world_size_x = mem->getAddress ("world_size_x"); off.world_size_y = mem->getAddress ("world_size_y"); // these can fail and will be found when looking at the actual veins later // basically a cache off.vein_ice_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_frozen_liquid", off.vein_ice_vptr); off.vein_mineral_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_mineral",off.vein_mineral_vptr); // upload offsets to SHM server if possible d->maps_module = 0; if(p->getModuleIndex("Maps2010",1,d->maps_module)) { // supply the module with offsets so it can work with them Server::Maps::maps_offsets *off2 = SHMDATA(Server::Maps::maps_offsets); memcpy(off2, &(d->offsets), sizeof(Server::Maps::maps_offsets)); full_barrier const uint32_t cmd = Server::Maps::MAP_INIT + (d->maps_module << 16); p->SetAndWait(cmd); } d->Inited = true; }
int main () { DFHack::Process *proc; DFHack::memory_info *meminfo; DFHack::DfVector *items_vector; DFHack::t_item_df40d item_40d; DFHack::t_matglossPair item_40d_material; vector<DFHack::t_matgloss> stoneMat; uint32_t item_material_offset; uint32_t temp; int32_t type; int items; int found = 0, converted = 0; DFHack::API DF("Memory.xml"); try { DF.Attach(); } catch (exception& e) { cerr << e.what() << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } // Find out which material is bauxite if(!DF.ReadStoneMatgloss(stoneMat)) { cout << "Materials not supported for this version of DF, exiting." << endl; #ifndef LINUX_BUILD cin.ignore(); #endif DF.Detach(); return EXIT_FAILURE; } int bauxiteIndex = -1; for (int i = 0; i < stoneMat.size();i++) { if(strcmp(stoneMat[i].id, "BAUXITE") == 0) { bauxiteIndex = i; break; } } if(bauxiteIndex == -1) { cout << "Cannot locate bauxite in the DF raws, exiting" << endl; #ifndef LINUX_BUILD cin.ignore(); #endif DF.Detach(); return EXIT_FAILURE; } // Get some basics needed for full access proc = DF.getProcess(); meminfo = proc->getDescriptor(); // Get the object name/ID mapping //FIXME: work on the 'supported features' system required // Check availability of required addresses and offsets (doing custom stuff here) items = meminfo->getAddress("items"); item_material_offset = meminfo->getOffset("item_materials"); if( !items || ! item_material_offset) { cout << "Items not supported for this DF version, exiting" << endl; #ifndef LINUX_BUILD cin.ignore(); #endif DF.Detach(); return EXIT_FAILURE; } items_vector = new DFHack::DfVector (proc->readVector (items, 4)); for(uint32_t i = 0; i < items_vector->getSize(); i++) { // get pointer to object temp = * (uint32_t *) items_vector->at (i); // read object proc->read (temp, sizeof (DFHack::t_item_df40d), (uint8_t *) &item_40d); // resolve object type type = -1; // skip things we can't identify if(!meminfo->resolveObjectToClassID (temp, type)) continue; string classname; if(!meminfo->resolveClassIDToClassname (type, classname)) continue; if(classname == "item_trapparts") { proc->read (temp + item_material_offset, sizeof (DFHack::t_matglossPair), (uint8_t *) &item_40d_material); cout << dec << "Mechanism at x:" << item_40d.x << " y:" << item_40d.y << " z:" << item_40d.z << " ID:" << item_40d.ID << endl; if (item_40d_material.index != bauxiteIndex) { item_40d_material.index = bauxiteIndex; proc->write (temp + item_material_offset, sizeof (DFHack::t_matglossPair), (uint8_t *) &item_40d_material); converted++; } found++; } } if (found == 0) { cout << "No mechanisms to convert" << endl; } else { cout << found << " mechanisms found" << endl; cout << converted << " mechanisms converted" << endl; } DF.Resume(); DF.Detach(); delete items_vector; #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); #endif return 0; }
void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature) { uint32_t dayoflife; cout << "address: " << hex << creature.origin << dec << " creature type: " << 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::memory_info *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; } /* cout << ", likes: "; for(uint32_t i = 0;i<creature.numLikes; i++) { if(printLike(creature.likes[i],mat,itemTypes)) { cout << ", "; } } */ if(addendl) { cout << endl; addendl = false; } cout << "profession: " << mem->getProfession(creature.profession) << "(" << (int) creature.profession << ")"; if(creature.custom_profession[0]) { cout << ", custom profession: " << creature.custom_profession; } /* if(creature.current_job.active) { cout << ", current job: " << mem->getJob(creature.current_job.jobId); } */ 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; i<creature.nbcolors ; i++) { cout << Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].part << " "; uint32_t color = Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].colorlist[creature.color[i]]; if(color<Materials->color.size()) cout << Materials->color[color].name << "[" << (unsigned int) (Materials->color[color].r*255) << ":" << (unsigned int) (Materials->color[color].v*255) << ":" << (unsigned int) (Materials->color[color].b*255) << "]"; else cout << Materials->alldesc[color].id; 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<DFHack::t_material> 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); } } } /* 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 << ", "; } cout << mem->getSkill(creature.defaultSoul.skills[i].id) << ": " << creature.defaultSoul.skills[i].rating; } 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; }