16 #define GETTEXT_DOMAIN "wesnoth-lib"
21 #include "addon/manager.hpp"
57 struct filter_transform
59 explicit filter_transform(
const std::vector<std::string>& filtertext) :
filtertext_(filtertext) {}
60 bool operator()(
const config& cfg)
const
74 for(
const auto& [
_, value] : child.attribute_range()) {
90 std::string make_display_dependencies(
91 const std::string& addon_id,
100 for(
const auto& dep_id : deps) {
104 addons_list::const_iterator ali =
addons_list.find(dep_id);
105 addons_tracking_list::const_iterator tli = addon_states.find(dep_id);
113 if(tli == addon_states.end()) {
116 depstate = tli->second;
129 std::string langcode_to_string(
const std::string& lcode)
133 if(ld.localename == lcode || ld.localename.substr(0, 2) == lcode) {
171 {
N_(
"addons_order^Name ($order)"),
"name", 0,
174 {
N_(
"addons_order^Author ($order)"),
"author", 1,
177 {
N_(
"addons_order^Size ($order)"),
"size", 2,
180 {
N_(
"addons_order^Downloads ($order)"),
"downloads", 3,
183 {
N_(
"addons_order^Type ($order)"),
"type", 4,
186 {
N_(
"addons_order^Last updated ($datelike_order)"),
"last_updated", -1,
189 {
N_(
"addons_order^First uploaded ($datelike_order)"),
"first_uploaded", -1,
206 const std::vector<addon_tag> tag_filter_types_{
207 {
"cooperative",
N_(
"addon_tag^Cooperative"),
209 N_(
"addon_tag^All human players are on the same team, versus the AI")},
210 {
"cosmetic",
N_(
"addon_tag^Cosmetic"),
212 N_(
"addon_tag^These make the game look different, without changing gameplay")},
213 {
"difficulty",
N_(
"addon_tag^Difficulty"),
215 N_(
"addon_tag^Can make campaigns easier or harder")},
216 {
"rng",
N_(
"addon_tag^RNG"),
218 N_(
"addon_tag^Modify the randomness in the combat mechanics, or remove it entirely")},
219 {
"survival",
N_(
"addon_tag^Survival"),
221 N_(
"addon_tag^Fight against waves of enemies")},
222 {
"terraforming",
N_(
"addon_tag^Terraforming"),
224 N_(
"addon_tag^Players can change the terrain")},
235 , need_wml_cache_refresh_(false)
245 switch(state.
state) {
248 ?
_(
"addon_state^Not installed")
249 :
_(
"addon_state^Published, not installed");
253 ?
_(
"addon_state^Installed")
254 :
_(
"addon_state^Published");
258 ?
_(
"addon_state^Installed, not tracking local version")
261 :
_(
"addon_state^Published, not tracking local version");
265 ?
_(
"addon_state^Installed ($local_version|), upgradable")
266 :
_(
"addon_state^Published ($local_version| installed), upgradable");
272 ?
_(
"addon_state^Installed ($local_version|), outdated on server")
273 :
_(
"addon_state^Published ($local_version| installed), outdated on server");
279 ?
_(
"addon_state^Installed, not ready to publish")
280 :
_(
"addon_state^Ready to publish");
284 ?
_(
"addon_state^Installed, broken")
285 :
_(
"addon_state^Published, broken");
288 s =
_(
"addon_state^Unknown");
298 stacked_widget& addr_info = find_widget<stacked_widget>(
"server_conn_info");
310 auto addr_box =
dynamic_cast<styled_widget*
>(addr_visible->
find(
"server_addr",
false));
320 addr_box->set_label(full_id.str());
327 addon_list& list = find_widget<addon_list>(
"addons");
333 this, std::placeholders::_1));
335 this, std::placeholders::_1));
337 this, std::placeholders::_1));
340 this, std::placeholders::_1));
342 this, std::placeholders::_1));
349 menu_button& status_filter = find_widget<menu_button>(
"install_status_filter");
351 std::vector<config> status_filter_entries;
362 status_filter.
set_values(status_filter_entries);
368 auto& tag_filter = find_widget<multimenu_button>(
"tag_filter");
370 std::vector<config> tag_filter_entries;
371 for(
const auto&
f : tag_filter_types_) {
373 if(!
f.tooltip.empty()) {
378 tag_filter.set_values(tag_filter_entries);
383 multimenu_button& type_filter = find_widget<multimenu_button>(
"type_filter");
385 std::map<ADDON_TYPE, int> type_counts = {
401 for(
const auto& addon :
addons_) {
402 type_counts[addon.second.type]++;
405 std::vector<config> type_filter_entries;
407 type_filter_entries.emplace_back(
"label",
t_string(
f.second,
GETTEXT_DOMAIN)+
" ("+std::to_string(type_counts[
f.first])+
")",
"checkbox",
false);
417 std::set<std::string> languages_available;
419 for (
const auto&
b : a.second.
locales) {
420 languages_available.insert(
b);
423 std::set<std::string> language_strings_available;
424 for (
const auto&
i: languages_available) {
428 if (std::string lang_code_string = langcode_to_string(
i); !lang_code_string.empty()) {
429 language_strings_available.insert(lang_code_string);
432 for (
auto&
i: language_strings_available) {
436 multimenu_button& language_filter = find_widget<multimenu_button>(
"language_filter");
437 std::vector<config> language_filter_entries;
439 language_filter_entries.emplace_back(
"label",
f.second,
"checkbox",
false);
442 language_filter.
set_values(language_filter_entries);
448 menu_button& order_dropdown = find_widget<menu_button>(
"order_dropdown");
450 std::vector<config> order_dropdown_entries;
454 symbols[
"order"] =
_(
"ascending");
456 symbols[
"datelike_order"] =
_(
"oldest to newest");
458 order_dropdown_entries.push_back(entry);
459 symbols[
"order"] =
_(
"descending");
461 symbols[
"datelike_order"] =
_(
"newest to oldest");
462 entry[
"label"] =
VGETTEXT(
f.label.c_str(), symbols);
463 order_dropdown_entries.push_back(entry);
466 order_dropdown.
set_values(order_dropdown_entries);
468 const std::string saved_order_name =
prefs::get().addon_manager_saved_order_name();
471 if(!saved_order_name.empty()) {
473 [&saved_order_name](
const addon_order& order) {return order.as_preference == saved_order_name;});
477 if(saved_order_direction == sort_order::type::ascending) {
478 func = order_it->sort_func_asc;
480 func = order_it->sort_func_desc;
483 find_widget<menu_button>(
"order_dropdown").set_value(
index);
484 auto& addons = find_widget<addon_list>(
"addons");
485 addons.set_addon_order(func);
486 addons.select_first_addon();
494 label& url_label = find_widget<label>(
"url");
500 find_widget<button>(
"install"),
504 find_widget<button>(
"uninstall"),
508 find_widget<button>(
"update"),
512 find_widget<button>(
"publish"),
516 find_widget<button>(
"delete"),
521 find_widget<button>(
"info"),
524 find_widget<button>(
"info").set_visible(
false);
528 find_widget<button>(
"update_all"),
532 find_widget<button>(
"show_help"),
535 if(
stacked_widget* stk = find_widget<stacked_widget>(
"main_stack",
false,
false)) {
536 button& btn = find_widget<button>(
"details_toggle");
540 stk->select_layer(0);
543 stk->get_layer_grid(1)->find_widget<
menu_button>(
"version_filter"),
547 find_widget<menu_button>(
"version_filter"),
594 for(std::string
id : publishable_addons) {
603 pbl_cfg[
"name"] =
id;
604 pbl_cfg[
"local_only"] =
true;
617 show_transient_message(
_(
"No Add-ons Available"),
_(
"There are no add-ons available for download from this server."));
620 addon_list& list = find_widget<addon_list>(
"addons");
623 bool has_upgradable_addons =
false;
628 has_upgradable_addons =
true;
632 find_widget<button>(
"update_all").set_active(has_upgradable_addons);
642 find_widget<addon_list>(
"addons").select_addon(
id);
648 const text_box& name_filter = find_widget<const text_box>(
"filter");
649 const std::string& text = name_filter.
get_value();
652 boost::dynamic_bitset<> res;
658 const config& addon_cfg = *std::find_if(addon_cfgs.begin(), addon_cfgs.end(),
661 return cfg[
"name"] == a.first;
664 res.push_back(
filter(addon_cfg));
672 const menu_button& status_filter = find_widget<const menu_button>(
"install_status_filter");
675 boost::dynamic_bitset<> res;
693 const auto& tag_filter = find_widget<const multimenu_button>(
"tag_filter");
694 const auto toggle_states = tag_filter.get_toggle_states();
695 if(toggle_states.none()) {
697 boost::dynamic_bitset<> res_flipped(
addons_.size());
701 std::vector<std::string> selected_tags;
702 for(std::size_t
i = 0;
i < tag_filter_types_.size(); ++
i) {
703 if(toggle_states[
i]) {
704 selected_tags.push_back(tag_filter_types_[
i].
id);
708 boost::dynamic_bitset<> res;
710 bool matched_tag =
false;
711 for(
const auto&
id : selected_tags) {
717 res.push_back(matched_tag);
725 const multimenu_button& type_filter = find_widget<const multimenu_button>(
"type_filter");
728 if(toggle_states.none()) {
730 boost::dynamic_bitset<> res_flipped(
addons_.size());
733 boost::dynamic_bitset<> res;
738 [&a](
const std::pair<ADDON_TYPE, std::string>& entry) {
739 return entry.first == a.second.type;
742 res.push_back(toggle_states[
index]);
750 const multimenu_button& lang_filter = find_widget<const multimenu_button>(
"language_filter");
754 if(toggle_states.none()) {
755 boost::dynamic_bitset<> res_flipped(
addons_.size());
758 boost::dynamic_bitset<> res;
763 std::vector<std::string> lang_string_vector;
764 for (
long unsigned int i = 0;
i < a.second.
locales.size();
i++) {
765 lang_string_vector.push_back(langcode_to_string(a.second.
locales[
i]));
768 for (
long unsigned int i = 0;
i < toggle_states.size();
i++) {
769 if (toggle_states[
i] ==
true) {
774 if ((contains_lang_code || contains_lang_string) ==
true)
793 auto list = find_widget<addon_list>(
"addons",
false,
false);
798 boost::dynamic_bitset<> res =
804 list->set_addon_shown(res);
809 const menu_button& order_menu = find_widget<const menu_button>(
"order_dropdown");
813 if(order == sort_order::type::ascending) {
819 find_widget<addon_list>(
"addons").set_addon_order(func);
826 menu_button& order_menu = find_widget<menu_button>(
"order_dropdown");
828 [sort_column](
const addon_order& order) {return order.column_index == static_cast<int>(sort_column);});
830 if(order == sort_order::type::descending) {
834 prefs::get().set_addon_manager_saved_order_name(order_it->as_preference);
838 template<
void(addon_manager::*fptr)(const addon_info& addon)>
842 if(
stacked_widget* stk = find_widget<stacked_widget>(
"main_stack",
false,
false)) {
843 stk->select_layer(0);
844 find_widget<button>(
"details_toggle").set_label(
_(
"Add-on Details"));
847 addon_list& addons = find_widget<addon_list>(
"addons");
850 if(addon ==
nullptr) {
855 (this->*fptr)(*addon);
864 if(
stacked_widget* stk = find_widget<stacked_widget>(
"main_stack",
false,
false)) {
867 if(addon.
id == find_widget<addon_list>(
"addons").get_selected_addon()->id) {
868 versioned_addon.
current_version = find_widget<menu_button>(
"version_filter").get_value_string();
885 _(
"The following add-on appears to have publishing or version control information stored locally, and will not be removed:")
940 if(
stacked_widget* stk = find_widget<stacked_widget>(
"main_stack",
false,
false)) {
941 stk->select_layer(0);
942 find_widget<button>(
"details_toggle").set_label(
_(
"Add-on Details"));
945 addon_list& addons = find_widget<addon_list>(
"addons");
948 bool needs_refresh =
false;
949 if(addon ==
nullptr) {
950 gui2::dialogs::addon_server_info::execute(
client_,
"", needs_refresh);
952 gui2::dialogs::addon_server_info::execute(
client_, addon->
id, needs_refresh);
964 std::string server_msg;
966 const std::string addon_id = addon.
id;
970 const version_info& version_to_publish = cfg[
"version"].str();
972 if(version_to_publish <=
tracking_info_[addon_id].remote_version) {
974 _(
"The remote version of this add-on is greater or equal to the version being uploaded. Do you really wish to continue?"),
983 if(cfg[
"passphrase"].empty()) {
985 if(!gui2::dialogs::addon_auth::execute(cfg)) {
990 }
else if(cfg[
"forum_auth"].to_bool()) {
1001 }
else if(gui2::dialogs::addon_license_prompt::execute(server_msg)) {
1003 const std::string&
msg =
_(
"The add-on was rejected by the server:") +
1006 if (!extra_data.empty()) {
1028 const std::string addon_id = addon.
id;
1029 const std::string& text =
VGETTEXT(
1030 "Deleting '$addon|' will permanently erase its download and upload counts on the add-ons server. Do you really wish to continue?",
1040 std::string server_msg;
1062 VGETTEXT(
"Do you want to uninstall '$addon|'?", symbols),
1088 if(time == std::chrono::system_clock::time_point{}) {
1095 ?
_(
"%B %d %Y, %I:%M %p")
1098 :
_(
"%B %d %Y, %H:%M");
1100 auto as_time_t = std::chrono::system_clock::to_time_t(time);
1108 if(
stacked_widget* stk = find_widget<stacked_widget>(
"main_stack",
false,
false)) {
1109 parent = stk->get_layer_grid(1);
1110 info = stk->get_layer_grid(0)->find_widget<
addon_list>(
"addons").get_selected_addon();
1112 info = find_widget<addon_list>(
"addons").get_selected_addon();
1115 if(
info ==
nullptr) {
1128 status.set_use_markup(
true);
1137 :
_(
"addon_dependencies^None"));
1139 std::string languages;
1141 for(
const auto& lc :
info->locales) {
1142 const std::string& langlabel = langcode_to_string(lc);
1143 if(!langlabel.empty()) {
1144 if(!languages.empty()) {
1147 languages += langlabel;
1153 const std::string& feedback_url =
info->feedback_url;
1162 std::vector<config> version_filter_entries;
1178 for(
const auto&
f :
info->versions) {
1179 version_filter_entries.emplace_back(
"label",
f.str());
1189 version_filter_entries.emplace_back(
"label",
info->current_version.str());
1192 version_filter.set_values(version_filter_entries);
1193 version_filter.set_active(version_filter_entries.size() > 1);
1199 if(
stacked_widget* stk = find_widget<stacked_widget>(
"main_stack",
false,
false)) {
1201 parent_of_addons_list = stk->get_layer_grid(0);
1206 if(
info ==
nullptr) {
1212 != find_widget<menu_button>(
"version_filter").get_value_string();
1216 stacked_widget& install_update_stack = find_widget<stacked_widget>(
"install_update_stack");
1218 find_widget<button>(
"update").set_active(updatable);
bool remove_local_addon(const std::string &addon)
Removes the specified add-on, deleting its full directory structure.
config get_addon_pbl_info(const std::string &addon_name, bool do_validate)
Gets the publish information for an add-on.
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.
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 > available_addons()
Returns a list of local add-ons that can be published.
std::vector< std::string > installed_addons()
Retrieves the names of all installed add-ons.
void refresh_addon_version_info_cache()
Refreshes the per-session cache of add-on's version information structs.
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.
const std::string & get_last_server_error_data() const
Returns the last error message extra data sent by the server, or an empty string.
@ abort
User aborted the operation because of an issue with dependencies or chose not to overwrite the add-on...
const std::string & server_id() const
bool delete_remote_addon(const std::string &id, std::string &response_message, const std::set< std::string > &admin_set={})
Requests the specified add-on to be removed from the server.
bool using_tls() const
Returns whether the current connection uses TLS.
bool request_distribution_terms(std::string &terms)
Request the add-ons server distribution terms message.
const std::string & get_last_server_error() const
Returns the last error message sent by the server, or an empty string.
const std::string & addr() const
Returns the current hostname:port used for this connection.
bool request_addons_list(config &cfg, bool icons)
Request the add-ons list from the server.
const std::string & server_version() const
bool upload_addon(const std::string &id, std::string &response_message, config &cfg, bool local_only)
Uploads an add-on to the server.
A config object defines a single node in a WML file, with access to child nodes.
const_attr_itors attribute_range() const
child_itors child_range(config_key_type key)
boost::iterator_range< const_child_iterator > const_child_itors
config & add_child(config_key_type key)
void set_uninstall_function(addon_op_func_t function)
Sets the function to call when the player clicks the uninstall button.
std::function< bool(const addon_info &, const addon_info &)> addon_sort_func
void set_publish_function(addon_op_func_t function)
Sets the function to upload an addon to the addons server.
void add_list_to_keyboard_chain()
Adds the internal listbox to the keyboard event chain.
void set_install_function(addon_op_func_t function)
Sets the function to call when the player clicks the install button.
void set_delete_function(addon_op_func_t function)
Sets the function to install an addon from the addons server.
const addon_info * get_selected_addon() const
Returns the selected add-on.
void set_update_function(addon_op_func_t function)
Sets the function to call when the player clicks the update button.
void set_modified_signal_handler(const std::function< void()> &callback)
Sets up a callback that will be called when the player selects an add-on.
void set_callback_order_change(std::function< void(unsigned, sort_order::type)> callback)
Sets up a callback that will be called when the player changes the sorting order.
static const int DEFAULT_ACTION_RETVAL
Special retval for the toggle panels in the addons list.
static std::string colorize_addon_state_string(const std::string &str, ADDON_STATUS state, bool verbose=false)
Changes the color of an add-on state string (installed, outdated, etc.) according to the state itself...
void set_addons(const addons_list &addons)
Sets the add-ons to show.
virtual void set_active(const bool active) override
See styled_widget::set_active.
void uninstall_addon(const addon_info &addon)
void on_order_changed(unsigned int sort_column, sort_order::type order)
static const std::vector< std::pair< ADDON_STATUS_FILTER, std::string > > status_filter_types_
virtual void pre_show() override
Actions to be taken before showing the window.
boost::dynamic_bitset get_lang_filter_visibility() const
boost::dynamic_bitset get_status_filter_visibility() const
void update_selected_addon()
void execute_default_action(const addon_info &addon)
Called when the player double-clicks an add-on.
void reload_list_and_reselect_item(const std::string &id)
std::vector< std::pair< int, std::string > > language_filter_types_
void execute_default_action_on_selected_addon()
boost::dynamic_bitset get_name_filter_visibility() const
void toggle_details(button &btn, stacked_widget &stk)
void delete_addon(const addon_info &addon)
Performs all backend and UI actions for taking down the specified add-on.
addon_manager(addons_client &client)
config cfg_
Config which contains the list with the campaigns.
boost::dynamic_bitset get_type_filter_visibility() const
void install_selected_addon()
void delete_selected_addon()
void execute_action_on_selected_addon()
addons_tracking_list tracking_info_
static const std::vector< addon_order > all_orders_
void uninstall_selected_addon()
boost::dynamic_bitset get_tag_filter_visibility() const
void publish_selected_addon()
static const std::vector< std::pair< ADDON_TYPE, std::string > > type_filter_types_
void install_addon(const addon_info &addon)
void update_addon(const addon_info &addon)
bool need_wml_cache_refresh_
void publish_addon(const addon_info &addon)
Performs all backend and UI actions for publishing the specified add-on.
void on_selected_version_change()
@ yes_no_buttons
Shows a yes and no button.
@ ok_cancel_buttons
Shows an ok and cancel button.
Abstract base class for all modal dialogs.
widget * find(const std::string_view id, const bool must_be_active) override
See widget::find.
void set_link_aware(bool l)
std::string get_value() const
A widget that allows the user to input text in single line.
void set_enter_disabled(const bool enter_disabled)
Disable the enter key.
void keyboard_capture(widget *widget)
void close()
Requests to close the window.
status
The status of the window.
void set_escape_disabled(const bool escape_disabled)
Disable the escape key.
void set_exit_hook(exit_hook mode, const Func &hook)
Sets the window's exit hook.
void set_addon_manager_saved_order_direction(sort_order::type value)
void set_password(const std::string &server, const std::string &login, const std::string &key)
sort_order::type addon_manager_saved_order_direction()
bool use_twelve_hour_clock_format()
std::string password(const std::string &server, const std::string &login)
Represents version numbers.
std::string str() const
Serializes the version number into string form.
Definitions for the interface to Wesnoth Markup Language (WML).
static std::string _(const char *str)
std::string label
What to show in the filter's drop-down list.
const std::vector< std::string > filtertext_
std::string tooltip
Shown when hovering over an entry in the filter's drop-down list.
std::string id
Text to match against addon_info.tags()
std::string size_display_string(double size)
Get a human-readable representation of the specified byte count.
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
language_list get_languages(bool all)
Return a list of available translations.
std::deque< std::unique_ptr< editor_action > > action_stack
Action stack typedef.
const std::string unicode_em_dash
static std::string describe_status_verbose(const addon_tracking_info &state)
REGISTER_DIALOG(editor_edit_unit)
static std::string format_addon_time(const std::chrono::system_clock::time_point &time)
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
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.
retval
Default window/dialog return values.
@ OK
Dialog was closed with the OK button.
void show_help(const std::string &show_topic)
Open the help browser, show topic with id show_topic.
bool exists(const image::locator &i_locator)
Returns true if the given image actually exists, without loading it.
std::string strftime(const std::string &format, const std::tm *time)
bool ci_search(const std::string &s1, const std::string &s2)
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
std::string interpolate_variables_into_string(const std::string &str, const string_map *const symbols)
Function which will interpolate variables, starting with '$' in the string 'str' with the equivalent ...
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
std::map< std::string, t_string > string_map
std::vector< std::string > split(const config_attribute_value &val)
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
addon_tracking_info get_addon_tracking_info(const addon_info &addon)
Get information about an add-on comparing its local state with the add-ons server entry.
bool is_installed_addon_status(ADDON_STATUS s)
@ ADDON_NOT_TRACKED
No tracking information available.
@ ADDON_INSTALLED_OUTDATED
Version in the server is older than local installation.
@ ADDON_NONE
Add-on is not installed.
@ ADDON_INSTALLED_UPGRADABLE
Version in the server is newer than local installation.
@ ADDON_INSTALLED
Version in the server matches local installation.
@ ADDON_INSTALLED_LOCAL_ONLY
No version in the server.
@ ADDON_INSTALLED_BROKEN
Dependencies not satisfied.
ADDON_STATUS_FILTER
Add-on installation status filters for the user interface.
std::map< std::string, addon_tracking_info > addons_tracking_list
std::vector< std::string > tags
version_info current_version
std::string display_type() const
Get an add-on type identifier for display in the user's language.
std::chrono::system_clock::time_point updated
std::string display_title_translated_or_original() const
std::chrono::system_clock::time_point created
std::string display_title_full() const
std::set< std::string > resolve_dependencies(const addons_list &addons) const
Resolve an add-on's dependency tree in a recursive fashion.
std::vector< std::string > locales
Stores additional status information about add-ons.
version_info installed_version
Contains the outcome of an add-on install operation.
install_outcome outcome
Overall outcome of the operation.
bool wml_changed
Specifies if WML on disk was altered and needs to be reloaded.
addon_list::addon_sort_func sort_func_desc
addon_list::addon_sort_func sort_func_asc
std::string as_preference
The value used in the preferences file.
Exception thrown when the WML parser fails to read a .pbl file.
static map_location::direction s
@ ADDON_THEME
GUI2 Themes.
@ ADDON_SP_SCENARIO
Single-player scenario.
@ ADDON_MP_SCENARIO
Multiplayer scenario.
@ ADDON_MP_CAMPAIGN
Multiplayer campaign.
@ ADDON_MP_FACTION
Multiplayer faction.
@ ADDON_MEDIA
Miscellaneous content/media (unit packs, terrain packs, music packs, etc.).
@ ADDON_MP_ERA
Multiplayer era.
@ ADDON_CORE
Total Conversion Core.
@ ADDON_SP_CAMPAIGN
Single-player campaign.
@ ADDON_OTHER
an add-on that fits in no other category
@ ADDON_SP_MP_CAMPAIGN
Hybrid campaign.
@ ADDON_MP_MAPS
Multiplayer plain (no WML) map pack.
@ ADDON_MOD
Modification of the game.