/* { vector <uint64_t> found; Bytestream select; while (Incremental(found,"byte stream",select,"byte stream","byte streams")) { DFMgr.Refresh(); DFHack::Context * DF = DFMgr.getSingleContext(); DF->Attach(); SegmentedFinder sf(ranges,DF); sf.Incremental< Bytestream ,uint32_t>(select,1,found, findBytestream); DF->Detach(); } } */ void DataPtrTrace(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges) { int element_size; do { getNumber("Set search granularity",element_size, 4); } while (element_size < 1); vector <uint64_t> found; set <uint64_t> check; // to detect circles uint32_t select; Bytestream bs_select; DFHack::Context * DF = DFMgr.getSingleContext(); DF->Attach(); DFMgr.Refresh(); found.clear(); SegmentedFinder sf(ranges,DF); while(found.empty()) { Incremental(found,"byte stream",bs_select,"byte stream","byte streams"); sf.Incremental< Bytestream ,uint32_t>(bs_select,1,found, findBytestream); } select = found[0]; cout <<"Starting: 0x" << hex << select << endl; while(sf.getSegmentForAddress(select)) { sf.Incremental<uint32_t,uint32_t>(select,element_size,found, equalityP<uint32_t>); if(found.empty()) { cout << "."; cout.flush(); select -=element_size; continue; } cout << endl; cout <<"Object start: 0x" << hex << select << endl; cout <<"Pointer: 0x" << hex << found[0] << endl; // make sure we don't go in circles' if(check.count(select)) { break; } check.insert(select); // ascend select = found[0]; found.clear(); } DF->Detach(); }
void FindStrings(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges) { vector <uint64_t> found; string select; while (Incremental(found,"string",select,"string","strings")) { DFMgr.Refresh(); DFHack::Context * DF = DFMgr.getSingleContext(); DF->Attach(); SegmentedFinder sf(ranges,DF); sf.Incremental< const char * ,uint32_t>(select.c_str(),1,found, findString); DF->Detach(); } }
void FindData(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges) { vector <uint64_t> found; Bytestream select; while (Incremental(found,"byte stream",select,"byte stream","byte streams")) { DFMgr.Refresh(); DFHack::Context * DF = DFMgr.getSingleContext(); DF->Attach(); SegmentedFinder sf(ranges,DF); sf.Incremental< Bytestream ,uint32_t>(select,1,found, findBytestream); DF->Detach(); } }
void FindPtrVectorsByObjectAddress(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges) { vector <uint64_t> found; uint32_t select; while (Incremental(found, "object address",select,"vector","vectors")) { DFMgr.Refresh(); DFHack::Context * DF = DFMgr.getSingleContext(); DF->Attach(); SegmentedFinder sf(ranges,DF); sf.Find<int ,vecTriplet>(0,4,found, vectorAll); sf.Filter<uint32_t ,vecTriplet>(select,found, vectorOfPtrWithin); DF->Detach(); } }
void FindVectorByFirstObjectRawname(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges) { vector <uint64_t> found; string select; while (Incremental(found, "raw name",select,"vector","vectors")) { DFMgr.Refresh(); DFHack::Context * DF = DFMgr.getSingleContext(); DF->Attach(); SegmentedFinder sf(ranges,DF); sf.Find<int ,vecTriplet>(0,4,found, vectorAll); sf.Filter<const char * ,vecTriplet>(select.c_str(),found, vectorStringFirst); DF->Detach(); } }
void FindVectorByBounds(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges) { vector <uint64_t> found; uint32_t select; while (Incremental(found, "address between vector.start and vector.end",select,"vector","vectors")) { DFMgr.Refresh(); DFHack::Context * DF = DFMgr.getSingleContext(); DF->Attach(); SegmentedFinder sf(ranges,DF); sf.Find<int ,vecTriplet>(0,4,found, vectorAll); sf.Filter<uint32_t ,vecTriplet>(select,found, vectorAddrWithin); // sort by size of vector std::sort(found.begin(), found.end(), VectorSizeFunctor(sf)); DF->Detach(); } }
void FindVectorByLength(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges ) { int element_size; do { getNumber("Select searched vector item size in bytes",element_size, 4); } while (element_size < 1); uint32_t length; vector <uint64_t> found; found.reserve(100); while (Incremental(found, "vector length",length,"vector","vectors")) { DFMgr.Refresh(); DFHack::Context * DF = DFMgr.getSingleContext(); DF->Attach(); SegmentedFinder sf(ranges,DF); sf.Incremental<int ,vecTriplet>(0,4,found,vectorAll); sf.Filter<uint32_t,vecTriplet>(length * element_size,found,vectorLength<uint32_t>); DF->Detach(); } }
void FindIntegers(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges) { // input / validation of variable size int size; do { getNumber("Select variable size (1,2,4 bytes)",size, 4); } while (size != 1 && size != 2 && size != 4); // input / validation of variable alignment (default is to use the same alignment as size) int alignment; do { getNumber("Select variable alignment (1,2,4 bytes)",alignment, size); } while (alignment != 1 && alignment != 2 && alignment != 4); uint32_t test1; vector <uint64_t> found; found.reserve(100); while(Incremental(found, "integer",test1)) { DFMgr.Refresh(); DFHack::Context * DF = DFMgr.getSingleContext(); DF->Attach(); SegmentedFinder sf(ranges,DF); switch(size) { case 1: sf.Incremental<uint8_t,uint8_t>(test1,alignment,found, equalityP<uint8_t>); break; case 2: sf.Incremental<uint16_t,uint16_t>(test1,alignment,found, equalityP<uint16_t>); break; case 4: sf.Incremental<uint32_t,uint32_t>(test1,alignment,found, equalityP<uint32_t>); break; } DF->Detach(); } }
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; }