Beispiel #1
0
void read_addons_list(const config& cfg, addons_list& dest)
{
	dest.clear();

	unsigned order = 0;

	/** @todo FIXME: get rid of this legacy "campaign"/"campaigns" silliness
	 */
	const config::const_child_itors &addon_cfgs = cfg.child_range("campaign");
	for(const config& addon_cfg : addon_cfgs) {
		const std::string& id = addon_cfg["name"].str();
		if(dest.find(id) != dest.end()) {
			ERR_AC << "add-ons list has multiple entries for '" << id << "', not good; ignoring them" << std::endl;
			continue;
		}
		dest[id].read(addon_cfg);
		dest[id].order = order++;
	}
}
Beispiel #2
0
/** Warns the user about unresolved dependencies and installs them if they choose to do so. 
 * Returns: outcome: ABORT in case the user chose to abort because of an issue
 *                   SUCCESS otherwise
 *          wml_change: indicates if new wml content was installed
 */
addon_op_result do_resolve_addon_dependencies(display& disp, addons_client& client, const addons_list& addons, const addon_info& addon)
{
	addon_op_result result;
	result.outcome = SUCCESS;
	result.wml_changed = false;

	boost::scoped_ptr<cursor::setter> cursor_setter(new cursor::setter(cursor::WAIT));

	// TODO: We don't currently check for the need to upgrade. I'll probably
	// work on that when implementing dependency tiers later.

	const std::set<std::string>& deps = addon.resolve_dependencies(addons);

	std::vector<std::string> missing_deps;
	std::vector<std::string> broken_deps;

	BOOST_FOREACH(const std::string& dep, deps) {
		if(!is_addon_installed(dep)) {
			if(addons.find(dep) != addons.end()) {
				missing_deps.push_back(dep);
			} else {
				broken_deps.push_back(dep);
			}
		}
	}

	cursor_setter.reset();

	if(!broken_deps.empty()) {
		std::string broken_deps_report;

		broken_deps_report = _n(
			"The selected add-on has the following dependency, which is not currently installed or available from the server. Do you wish to continue?",
			"The selected add-on has the following dependencies, which are not currently installed or available from the server. Do you wish to continue?",
			broken_deps.size());
		broken_deps_report += "\n";

		BOOST_FOREACH(const std::string& broken_dep_id, broken_deps) {
			broken_deps_report += "\n    " + utils::unicode_bullet + " " + make_addon_title(broken_dep_id);
		}
Beispiel #3
0
	std::string make_display_dependencies(
		const std::string& addon_id,
		const addons_list& addons_list,
		const addons_tracking_list& addon_states)
	{
		const addon_info& addon = const_at(addon_id, addons_list);
		std::string str;

		const std::set<std::string>& deps = addon.resolve_dependencies(addons_list);

		for(const auto& dep_id : deps) {
			addon_info dep;
			addon_tracking_info depstate;

			addons_list::const_iterator ali = addons_list.find(dep_id);
			addons_tracking_list::const_iterator tli = addon_states.find(dep_id);

			if(ali == addons_list.end()) {
				dep.id = dep_id; // Build dummy addon_info.
			} else {
				dep = ali->second;
			}

			if(tli == addon_states.end()) {
				depstate = get_addon_tracking_info(dep);
			} else {
				depstate = tli->second;
			}

			if(!str.empty()) {
				str += ", ";
			}

			str += addon_list::colorize_addon_state_string(dep.display_title(), depstate.state);
		}

		return str;
	}
Beispiel #4
0
addons_client::install_result addons_client::do_resolve_addon_dependencies(const addons_list& addons, const addon_info& addon)
{
	install_result result;
	result.outcome = install_outcome::success;
	result.wml_changed = false;

	auto cursor_setter = std::make_unique<cursor::setter>(cursor::WAIT);

	// TODO: We don't currently check for the need to upgrade. I'll probably
	// work on that when implementing dependency tiers later.

	const std::set<std::string>& deps = addon.resolve_dependencies(addons);

	std::vector<std::string> missing_deps;
	std::vector<std::string> broken_deps;

	for(const std::string& dep : deps) {
		try {
			addon_tracking_info info = get_addon_tracking_info(addons.at(dep));

			// ADDON_NONE means not installed.
			if(info.state == ADDON_NONE) {
				missing_deps.push_back(dep);
			} else if(info.state == ADDON_INSTALLED_UPGRADABLE) {
				// Tight now, we don't need to distinguish the lists of missing
				// and outdated addons, so just add them to missing.
				missing_deps.push_back(dep);
			}
		} catch(const std::out_of_range&) {
			// Dependency wasn't found on server, check locally directly.
			if(!is_addon_installed(dep)) {
				broken_deps.push_back(dep);
			}
		}
	}

	cursor_setter.reset();

	if(!broken_deps.empty()) {
		std::string broken_deps_report;

		broken_deps_report = _n(
			"The selected add-on has the following dependency, which is not currently installed or available from the server. Do you wish to continue?",
			"The selected add-on has the following dependencies, which are not currently installed or available from the server. Do you wish to continue?",
			broken_deps.size());
		broken_deps_report += "\n";

		for(const std::string& broken_dep_id : broken_deps) {
			broken_deps_report += "\n    " + font::unicode_bullet + " " + make_addon_title(broken_dep_id);
		}

		if(gui2::show_message(_("Broken Dependencies"), broken_deps_report, gui2::dialogs::message::yes_no_buttons) != gui2::retval::OK) {
			result.outcome = install_outcome::abort;
			return result; // canceled by user
		}
	}

	if(missing_deps.empty()) {
		// No dependencies to install, carry on.
		return result;
	}

	{
		addons_list options;
		for(const std::string& dep : missing_deps) {
			options[dep] = addons.at(dep);
		}

		gui2::dialogs::install_dependencies dlg(options);
		bool cont = dlg.show();
		if(!cont) {
			return result; // the user has chosen to continue without installing anything.
		}
	}

	//
	// Install dependencies now.
	//

	std::vector<std::string> failed_titles;

	for(const std::string& dep : missing_deps) {
		const addon_info& missing_addon = addons.at(dep);

		if(!try_fetch_addon(missing_addon)) {
			failed_titles.push_back(missing_addon.title);
		} else {
			result.wml_changed = true;
		}
	}

	if(!failed_titles.empty()) {
		const std::string& failed_deps_report = _n(
			"The following dependency could not be installed. Do you still wish to continue?",
			"The following dependencies could not be installed. Do you still wish to continue?",
			failed_titles.size()) + std::string("\n\n") + utils::bullet_list(failed_titles);

		result.outcome = gui2::show_message(_("Dependencies Installation Failed"), failed_deps_report, gui2::dialogs::message::yes_no_buttons) == gui2::retval::OK ? install_outcome::success : install_outcome::abort; // If the user cancels, return abort. Otherwise, return success, since the user chose to ignore the failure.
		return result;
	}

	return result;
}