std::map<std::string, WORLDPTR> worldfactory::get_all_worlds() { std::map<std::string, WORLDPTR> retworlds; std::vector<std::string> qualifiers; qualifiers.push_back(WORLD_OPTION_FILE); qualifiers.push_back(SAVE_MASTER); if (!all_worlds.empty()) { for( auto &elem : all_worlds ) { delete elem.second; } all_worlds.clear(); all_worldnames.clear(); } // get the master files. These determine the validity of a world // worlds exist by having an option file // create worlds for( const auto &world_dir : get_directories_with(qualifiers, FILENAMES["savedir"], true) ) { // get the option file again // we can assume that there is only one master.gsav, so just collect the first path bool no_options = true; auto const detected_world_op = get_files_from_path( WORLD_OPTION_FILE, world_dir, false ); if ( ! detected_world_op.empty() ) { no_options = false; } // get the save files auto world_sav_files = get_files_from_path( SAVE_EXTENSION, world_dir, false ); // split the save file names between the directory and the extension for( auto &world_sav_file : world_sav_files ) { size_t save_index = world_sav_file.find( SAVE_EXTENSION ); world_sav_file = world_sav_file.substr( world_dir.size() + 1, save_index - ( world_dir.size() + 1 ) ); } // the directory name is the name of the world std::string worldname; unsigned name_index = world_dir.find_last_of( "/\\" ); worldname = world_dir.substr( name_index + 1 ); // create and store the world retworlds[worldname] = new WORLD(); // give the world a name retworlds[worldname]->world_name = worldname; all_worldnames.push_back(worldname); // add sav files for( auto &world_sav_file : world_sav_files ) { retworlds[worldname]->world_saves.push_back( world_sav_file ); } // set world path retworlds[worldname]->world_path = world_dir; mman->load_mods_list(retworlds[worldname]); // load options into the world if ( no_options ) { for( auto &elem : OPTIONS ) { if( elem.second.getPage() == "world_default" ) { retworlds[worldname]->world_options[elem.first] = elem.second; } } retworlds[worldname]->world_options["DELETE_WORLD"].setValue("yes"); save_world(retworlds[worldname]); } else { retworlds[worldname]->world_options = get_world_options(detected_world_op[0]); } } // check to see if there exists a worldname "save" which denotes that a world exists in the save // directory and not in a sub-world directory if (retworlds.find("save") != retworlds.end()) { WORLDPTR converted_world = convert_to_world(retworlds["save"]->world_path); if (converted_world) { converted_world->world_saves = retworlds["save"]->world_saves; converted_world->world_options = retworlds["save"]->world_options; std::vector<std::string>::iterator oldindex = std::find(all_worldnames.begin(), all_worldnames.end(), "save"); delete retworlds["save"]; retworlds.erase("save"); all_worldnames.erase(oldindex); retworlds[converted_world->world_name] = converted_world; all_worldnames.push_back(converted_world->world_name); } } all_worlds = retworlds; return retworlds; }
bool mod_manager::copy_mod_contents(const t_mod_list &mods_to_copy, const std::string &output_base_path) { if (mods_to_copy.empty()) { // nothing to copy, so technically we succeeded already! return true; } std::vector<std::string> search_extensions; search_extensions.push_back(".json"); DebugLog( D_INFO, DC_ALL ) << "Copying mod contents into directory: " << output_base_path; if (!assure_dir_exist(output_base_path)) { DebugLog( D_ERROR, DC_ALL ) << "Unable to create or open mod directory at [" << output_base_path << "] for saving"; return false; } std::ostringstream number_stream; for (size_t i = 0; i < mods_to_copy.size(); ++i) { number_stream.str(std::string()); number_stream.width(5); number_stream.fill('0'); number_stream << (i + 1); MOD_INFORMATION &mod = *mod_map[mods_to_copy[i]]; size_t start_index = mod.path.size(); // now to get all of the json files inside of the mod and get them ready to copy auto input_files = get_files_from_path(".json", mod.path, true, true); auto input_dirs = get_directories_with(search_extensions, mod.path, true); if (input_files.empty() && mod.path.find(MOD_SEARCH_FILE) != std::string::npos) { // Self contained mod, all data is inside the modinfo.json file input_files.push_back(mod.path); start_index = mod.path.find_last_of("/\\"); if (start_index == std::string::npos) { start_index = 0; } } if (input_files.empty()) { continue; } // create needed directories std::ostringstream cur_mod_dir; cur_mod_dir << output_base_path << "/mod_" << number_stream.str(); std::queue<std::string> dir_to_make; dir_to_make.push(cur_mod_dir.str()); for( auto &input_dir : input_dirs ) { dir_to_make.push( cur_mod_dir.str() + "/" + input_dir.substr( start_index ) ); } while (!dir_to_make.empty()) { if (!assure_dir_exist(dir_to_make.front())) { DebugLog( D_ERROR, DC_ALL ) << "Unable to create or open mod directory at [" << dir_to_make.front() << "] for saving"; } dir_to_make.pop(); } std::ofstream fout; // trim file paths from full length down to just /data forward for( auto &input_file : input_files ) { std::string output_path = input_file; output_path = cur_mod_dir.str() + output_path.substr(start_index); std::ifstream infile( input_file.c_str(), std::ifstream::in | std::ifstream::binary ); // and stuff it into ram std::istringstream iss( std::string( (std::istreambuf_iterator<char>(infile)), std::istreambuf_iterator<char>() ) ); infile.close(); fout.open(output_path.c_str()); fout << iss.str(); fout.close(); } } return true; }