21 #include "addon/manager.hpp"
41 #define ERR_CFG LOG_STREAM(err, log_config)
42 #define INFO_CFG LOG_STREAM(info, log_config)
44 #define ERR_NET LOG_STREAM(err, log_network)
46 #define ERR_FS LOG_STREAM(err, log_filesystem)
48 #define LOG_AC LOG_STREAM(info, log_addons_client)
65 bool addons_manager_ui(
const std::string& remote_address)
67 bool need_wml_cache_refresh =
false;
80 ERR_CFG <<
"config::error thrown during transaction with add-on server; \""<<
e.message <<
"\"";
83 ERR_NET <<
"network_asio::error thrown during transaction with add-on server; \""<<
e.what() <<
"\"";
86 ERR_FS <<
"filesystem::io_exception thrown while installing an addon; \"" <<
e.what() <<
"\"";
89 ERR_CFG <<
"could not read .pbl file " <<
e.path <<
": " <<
e.message;
92 symbols[
"path"] =
e.path;
93 symbols[
"msg"] =
e.message;
96 VGETTEXT(
"A local file with add-on publishing information could not be read.\n\nFile: $path\nError message: $msg", symbols));
100 LOG_AC <<
"initial connection canceled by user";
102 LOG_AC <<
"attempt to reconnect canceled by user";
107 return need_wml_cache_refresh;
110 bool uninstall_local_addons()
112 const std::string list_lead =
"\n\n";
121 std::map<std::string, std::string> addon_titles_map;
123 for(
const std::string&
id : addons) {
132 if(!info_cfg.
empty()) {
133 title = info_cfg[
"title"].str();
142 addon_titles_map[
id] = title;
147 std::vector<std::string> remove_ids;
148 std::set<std::string> remove_names;
155 if(remove_ids.empty()) {
159 remove_names.clear();
161 for(
const std::string&
id : remove_ids) {
162 remove_names.insert(addon_titles_map[
id]);
165 const std::string confirm_message =
_n(
166 "Are you sure you want to remove the following installed add-on?",
167 "Are you sure you want to remove the following installed add-ons?",
176 std::set<std::string> failed_names, skipped_names, succeeded_names;
178 for(
const std::string&
id : remove_ids) {
179 const std::string& name = addon_titles_map[
id];
182 skipped_names.insert(name);
184 succeeded_names.insert(name);
186 failed_names.insert(name);
190 if(!skipped_names.empty()) {
191 const std::string dlg_msg =
_n(
192 "The following add-on appears to have publishing or version control information stored locally, and will not be removed:",
193 "The following add-ons appear to have publishing or version control information stored locally, and will not be removed:",
194 skipped_names.size());
200 if(!failed_names.empty()) {
202 "The following add-on could not be deleted properly:",
203 "The following add-ons could not be deleted properly:",
207 if(!succeeded_names.empty()) {
208 const std::string dlg_title =
209 _n(
"Add-on Deleted",
"Add-ons Deleted", succeeded_names.size());
210 const std::string dlg_msg =
_n(
211 "The following add-on was successfully deleted:",
212 "The following add-ons were successfully deleted:",
213 succeeded_names.size());
230 static const int addon_download = 0;
232 static const int addon_uninstall = 2;
242 res = addon_download;
247 return addons_manager_ui(host_name);
248 case addon_uninstall:
249 return uninstall_local_addons();
267 if(!get_addons_list(client, addons)) {
272 bool return_value =
true;
273 std::ostringstream os;
274 for(
const std::string& addon_id : addon_ids) {
275 addons_list::const_iterator it = addons.find(addon_id);
276 if(it != addons.end()) {
279 const std::string info_cfg = addon_dir+
"/_info.cfg";
283 INFO_CFG <<
"No _info.cfg exists for '" << addon_id <<
"', skipping update.\n";
292 version_info installed_addon_version(
info.child_or_empty(
"info")[
"version"]);
308 return_value =
false;
314 symbols[
"addon_ids"] = os.str();
321 ERR_CFG <<
"config::error thrown during transaction with add-on server; \""<<
e.message <<
"\"";
324 ERR_NET <<
"network_asio::error thrown during transaction with add-on server; \""<<
e.what() <<
"\"";
327 ERR_FS <<
"io_exception thrown while installing an addon; \"" <<
e.what() <<
"\"";
330 ERR_CFG <<
"could not read .pbl file " <<
e.path <<
": " <<
e.message;
333 symbols[
"path"] =
e.path;
334 symbols[
"msg"] =
e.message;
337 VGETTEXT(
"A local file with add-on publishing information could not be read.\n\nFile: $path\nError message: $msg", symbols));
341 LOG_AC <<
"initial connection canceled by user";
bool remove_local_addon(const std::string &addon)
Removes the specified add-on, deleting its full directory structure.
bool have_addon_in_vcs_tree(const std::string &addon_name)
Returns whether the specified add-on appears to be managed by a VCS or not.
void get_addon_install_info(const std::string &addon_name, config &cfg)
Gets the installation info (_info.cfg) for an add-on.
bool have_addon_pbl_info(const std::string &addon_name)
Returns whether a .pbl file is present for the specified add-on or not.
std::vector< std::string > installed_addons()
Retrieves the names of all installed add-ons.
bool have_addon_install_info(const std::string &addon_name)
Returns true if there is a local installation info (_info.cfg) file for the add-on.
Add-ons (campaignd) client class.
install_result install_addon_with_checks(const addons_list &addons, const addon_info &addon)
Performs an add-on download and install cycle.
@ success
The add-on was correctly installed.
void connect()
Tries to establish a connection to the add-ons server.
bool request_addons_list(config &cfg, bool icons)
Request the add-ons list from the server.
A config object defines a single node in a WML file, with access to child nodes.
Singleton class to manage game config file caching.
static config_cache & instance()
Get reference to the singleton object.
void get_config(const std::string &path, config &cfg, abstract_validator *validator=nullptr)
Gets a config object from given path.
bool get_need_wml_cache_refresh() const
std::vector< std::string > selected_addons() const
@ yes_no_buttons
Shows a yes and no button.
bool show(const unsigned auto_close_time=0)
Shows the window.
int get_retval() const
Returns the cached window exit code.
void set_campaign_server(const std::string &host)
std::string campaign_server()
Represents version numbers.
Networked add-ons (campaignd) client interface.
Declarations for File-IO.
static std::string _n(const char *str1, const char *str2, int n)
static std::string _(const char *str)
std::string id
Text to match against addon_info.tags()
std::string make_addon_title(const std::string &id)
Replaces underscores to dress up file or dirnames as add-on titles.
void read_addons_list(const config &cfg, addons_list &dest)
Parse the specified add-ons list WML into an actual addons_list object.
std::map< std::string, addon_info > addons_list
Standard logging facilities (interface).
static lg::log_domain log_filesystem("filesystem")
bool ad_hoc_addon_fetch_session(const std::vector< std::string > &addon_ids)
Conducts an ad-hoc add-ons server connection to download an add-on with a particular id and all it's ...
static lg::log_domain log_addons_client("addons-client")
static lg::log_domain log_network("network")
bool manage_addons()
Shows the add-ons server connection dialog, for access to the various management front-ends.
static lg::log_domain log_config("config")
static bool file_exists(const bfs::path &fpath)
std::string get_addons_dir()
void show_transient_message(const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup)
Shows a transient message to the user.
void show_error_message(const std::string &msg, bool message_use_markup)
Shows an error message to the user.
void show_message(const std::string &title, const std::string &msg, const std::string &button_caption, const bool auto_close, const bool message_use_markup, const bool title_use_markup)
Shows a message to the user.
@ OK
Dialog was closed with the OK button.
std::string bullet_list(const T &v, std::size_t indent=4, const std::string &bullet=font::unicode_bullet)
Generates a new string containing a bullet list.
std::map< std::string, t_string > string_map
version_info current_version
Contains the outcome of an add-on install operation.
install_outcome outcome
Overall outcome of the operation.
An exception object used when an IO error occurs.
Exception thrown when the WML parser fails to read a .pbl file.
Helper class, don't construct this directly.
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...