16 #define GETTEXT_DOMAIN "wesnoth-lib"
21 #include "addon/manager.hpp"
59 struct filter_transform
61 explicit filter_transform(
const std::vector<std::string>& filtertext) :
filtertext_(filtertext) {}
62 bool operator()(
const config& cfg)
const
69 std::string val = attribute.second.str();
70 if(std::search(val.begin(),
82 for(
const auto& attribute : child.attribute_range()) {
83 std::string val = attribute.second.str();
99 std::string make_display_dependencies(
100 const std::string& addon_id,
109 for(
const auto& dep_id : deps) {
113 addons_list::const_iterator ali =
addons_list.find(dep_id);
114 addons_tracking_list::const_iterator tli = addon_states.find(dep_id);
122 if(tli == addon_states.end()) {
125 depstate = tli->second;
138 std::string langcode_to_string(
const std::string& lcode)
142 if(ld.localename == lcode || ld.localename.substr(0, 2) == lcode) {
179 {
N_(
"addons_order^Name ($order)"),
"name", 0,
182 {
N_(
"addons_order^Author ($order)"),
"author", 1,
185 {
N_(
"addons_order^Size ($order)"),
"size", 2,
188 {
N_(
"addons_order^Downloads ($order)"),
"downloads", 3,
191 {
N_(
"addons_order^Type ($order)"),
"type", 4,
194 {
N_(
"addons_order^Last updated ($datelike_order)"),
"last_updated", -1,
197 {
N_(
"addons_order^First uploaded ($datelike_order)"),
"first_uploaded", -1,
214 const std::vector<addon_tag> tag_filter_types_{
215 {
"cooperative",
N_(
"addon_tag^Cooperative"),
217 N_(
"addon_tag^All human players are on the same team, versus the AI")},
218 {
"cosmetic",
N_(
"addon_tag^Cosmetic"),
220 N_(
"addon_tag^These make the game look different, without changing gameplay")},
221 {
"difficulty",
N_(
"addon_tag^Difficulty"),
223 N_(
"addon_tag^Can make campaigns easier or harder")},
224 {
"rng",
N_(
"addon_tag^RNG"),
226 N_(
"addon_tag^Modify the randomness in the combat mechanics, or remove it entirely")},
227 {
"survival",
N_(
"addon_tag^Survival"),
229 N_(
"addon_tag^Fight against waves of enemies")},
230 {
"terraforming",
N_(
"addon_tag^Terraforming"),
232 N_(
"addon_tag^Players can change the terrain")},
243 , need_wml_cache_refresh_(false)
253 switch(state.
state) {
256 ?
_(
"addon_state^Not installed")
257 :
_(
"addon_state^Published, not installed");
261 ?
_(
"addon_state^Installed")
262 :
_(
"addon_state^Published");
266 ?
_(
"addon_state^Installed, not tracking local version")
269 :
_(
"addon_state^Published, not tracking local version");
273 ?
_(
"addon_state^Installed ($local_version|), upgradable")
274 :
_(
"addon_state^Published ($local_version| installed), upgradable");
280 ?
_(
"addon_state^Installed ($local_version|), outdated on server")
281 :
_(
"addon_state^Published ($local_version| installed), outdated on server");
287 ?
_(
"addon_state^Installed, not ready to publish")
288 :
_(
"addon_state^Ready to publish");
292 ?
_(
"addon_state^Installed, broken")
293 :
_(
"addon_state^Published, broken");
296 s =
_(
"addon_state^Unknown");
318 auto addr_box =
dynamic_cast<styled_widget*
>(addr_visible->
find(
"server_addr",
false));
328 addr_box->set_label(full_id.str());
337 text_box& filter = find_widget<text_box>(&
window,
"filter",
false);
341 this, std::placeholders::_1));
343 this, std::placeholders::_1));
345 this, std::placeholders::_1));
348 this, std::placeholders::_1));
350 this, std::placeholders::_1));
357 menu_button& status_filter = find_widget<menu_button>(&
window,
"install_status_filter",
false);
359 std::vector<config> status_filter_entries;
364 status_filter.
set_values(status_filter_entries);
370 auto& tag_filter = find_widget<multimenu_button>(&
window,
"tag_filter",
false);
372 std::vector<config> tag_filter_entries;
373 for(
const auto&
f : tag_filter_types_) {
375 if(!
f.tooltip.empty()) {
380 tag_filter.set_values(tag_filter_entries);
387 std::vector<config> type_filter_entries;
399 std::set<std::string> languages_available;
401 for (
const auto&
b :
a.second.locales) {
402 languages_available.insert(
b);
405 std::set<std::string> language_strings_available;
406 for (
const auto&
i: languages_available) {
410 if (std::string lang_code_string = langcode_to_string(
i); !lang_code_string.empty()) {
411 language_strings_available.insert(lang_code_string);
414 for (
auto&
i: language_strings_available) {
419 std::vector<config> language_filter_entries;
421 language_filter_entries.emplace_back(
"label",
f.second,
"checkbox",
false);
424 language_filter.
set_values(language_filter_entries);
430 menu_button& order_dropdown = find_widget<menu_button>(&
window,
"order_dropdown",
false);
432 std::vector<config> order_dropdown_entries;
436 symbols[
"order"] =
_(
"ascending");
438 symbols[
"datelike_order"] =
_(
"oldest to newest");
440 order_dropdown_entries.push_back(entry);
441 symbols[
"order"] =
_(
"descending");
443 symbols[
"datelike_order"] =
_(
"newest to oldest");
444 entry[
"label"] =
VGETTEXT(
f.label.c_str(), symbols);
445 order_dropdown_entries.push_back(entry);
448 order_dropdown.
set_values(order_dropdown_entries);
453 if(!saved_order_name.empty()) {
455 [&saved_order_name](
const addon_order& order) {return order.as_preference == saved_order_name;});
459 if(saved_order_direction == sort_order::type::ascending) {
460 func = order_it->sort_func_asc;
462 func = order_it->sort_func_desc;
465 find_widget<menu_button>(&
window,
"order_dropdown",
false).set_value(
index,
false);
466 auto& addons = find_widget<addon_list>(&
window,
"addons",
false);
467 addons.set_addon_order(func);
468 addons.select_first_addon();
476 label& url_label = find_widget<label>(&
window,
"url",
false);
482 find_widget<button>(&
window,
"install",
false),
486 find_widget<button>(&
window,
"uninstall",
false),
490 find_widget<button>(&
window,
"update",
false),
494 find_widget<button>(&
window,
"publish",
false),
498 find_widget<button>(&
window,
"delete",
false),
502 find_widget<button>(&
window,
"update_all",
false),
506 find_widget<button>(&
window,
"show_help",
false),
510 button& btn = find_widget<button>(&
window,
"details_toggle",
false);
512 stk->select_layer(0);
517 version_filter_parent = stk->get_layer_grid(1);
520 menu_button& version_filter = find_widget<menu_button>(version_filter_parent,
"version_filter",
false);
567 for(std::string
id : publishable_addons) {
576 pbl_cfg[
"name"] =
id;
577 pbl_cfg[
"local_only"] =
true;
590 show_transient_message(
_(
"No Add-ons Available"),
_(
"There are no add-ons available for download from this server."));
596 bool has_upgradable_addons =
false;
601 has_upgradable_addons =
true;
605 find_widget<button>(
get_window(),
"update_all",
false).set_active(has_upgradable_addons);
615 find_widget<addon_list>(
get_window(),
"addons",
false).select_addon(
id);
621 const text_box& name_filter = find_widget<const text_box>(
get_window(),
"filter",
false);
622 const std::string& text = name_filter.
get_value();
625 boost::dynamic_bitset<> res;
631 const config& addon_cfg = *std::find_if(addon_cfgs.begin(), addon_cfgs.end(),
634 return cfg[
"name"] == a.first;
637 res.push_back(filter(addon_cfg));
645 const menu_button& status_filter = find_widget<const menu_button>(
get_window(),
"install_status_filter",
false);
648 boost::dynamic_bitset<> res;
666 const auto& tag_filter = find_widget<const multimenu_button>(
get_window(),
"tag_filter",
false);
667 const auto toggle_states = tag_filter.get_toggle_states();
668 if(toggle_states.none()) {
670 boost::dynamic_bitset<> res_flipped(
addons_.size());
674 std::vector<std::string> selected_tags;
675 for(std::size_t
i = 0;
i < tag_filter_types_.size(); ++
i) {
676 if(toggle_states[
i]) {
677 selected_tags.push_back(tag_filter_types_[
i].
id);
681 boost::dynamic_bitset<> res;
683 bool matched_tag =
false;
684 for(
const auto&
id : selected_tags) {
690 res.push_back(matched_tag);
701 if(toggle_states.none()) {
703 boost::dynamic_bitset<> res_flipped(
addons_.size());
706 boost::dynamic_bitset<> res;
711 [&
a](
const std::pair<ADDON_TYPE, std::string>& entry) {
712 return entry.first == a.second.type;
715 res.push_back(toggle_states[
index]);
727 if(toggle_states.none()) {
728 boost::dynamic_bitset<> res_flipped(
addons_.size());
731 boost::dynamic_bitset<> res;
736 std::vector<std::string> lang_string_vector;
737 for (
long unsigned int i = 0;
i <
a.second.locales.size();
i++) {
738 lang_string_vector.push_back(langcode_to_string(
a.second.locales[
i]));
741 for (
long unsigned int i = 0;
i < toggle_states.size();
i++) {
742 if (toggle_states[
i] ==
true) {
747 if ((contains_lang_code || contains_lang_string) ==
true)
766 auto list = find_widget<addon_list>(
get_window(),
"addons",
false,
false);
771 boost::dynamic_bitset<> res =
777 list->set_addon_shown(res);
782 const menu_button& order_menu = find_widget<const menu_button>(
get_window(),
"order_dropdown",
false);
786 if(order == sort_order::type::ascending) {
792 find_widget<addon_list>(
get_window(),
"addons",
false).set_addon_order(func);
801 [sort_column](
const addon_order& order) {return order.column_index == static_cast<int>(sort_column);});
803 if(order == sort_order::type::descending) {
811 template<
void(addon_manager::*fptr)(const addon_info& addon)>
816 stk->select_layer(0);
817 find_widget<button>(
get_window(),
"details_toggle",
false).set_label(
_(
"Add-on Details"));
823 if(addon ==
nullptr) {
828 (this->*fptr)(*addon);
839 parent = stk->get_layer_grid(1);
841 if(addon.
id == find_widget<addon_list>(
get_window(),
"addons",
false).get_selected_addon()->
id) {
842 versioned_addon.
current_version = find_widget<menu_button>(
parent,
"version_filter",
false).get_value_string();
859 _(
"The following add-on appears to have publishing or version control information stored locally, and will not be removed:") +
" " +
912 std::string server_msg;
914 const std::string addon_id = addon.
id;
918 const version_info& version_to_publish = cfg[
"version"].str();
920 if(version_to_publish <=
tracking_info_[addon_id].remote_version) {
922 _(
"The remote version of this add-on is greater or equal to the version being uploaded. Do you really wish to continue?"),
931 if(cfg[
"passphrase"].empty()) {
933 if(!gui2::dialogs::addon_auth::execute(cfg)) {
938 }
else if(cfg[
"forum_auth"].to_bool()) {
949 }
else if(gui2::dialogs::addon_license_prompt::execute(server_msg)) {
951 const std::string&
msg =
_(
"The add-on was rejected by the server:") +
954 if (!extra_data.empty()) {
976 const std::string addon_id = addon.
id;
978 "Deleting '$addon|' will permanently erase its download and upload counts on the add-ons server. Do you really wish to continue?",
988 std::string server_msg;
1010 VGETTEXT(
"Do you want to uninstall '$addon|'?", symbols),
1037 std::ostringstream ss;
1041 ?
_(
"%B %d %Y, %I:%M %p")
1043 :
_(
"%B %d %Y, %H:%M");
1058 parent = stk->get_layer_grid(1);
1059 parent_of_addons_list = stk->get_layer_grid(0);
1062 const addon_info*
info = find_widget<addon_list>(parent_of_addons_list,
"addons",
false).get_selected_addon();
1064 if(
info ==
nullptr) {
1068 find_widget<drawing>(
parent,
"image",
false).set_label(
info->display_icon());
1070 find_widget<styled_widget>(
parent,
"title",
false).set_label(
info->display_title_translated_or_original());
1071 find_widget<styled_widget>(
parent,
"description",
false).set_label(
info->description_translated());
1072 menu_button& version_filter = find_widget<menu_button>(
parent,
"version_filter",
false);
1073 find_widget<styled_widget>(
parent,
"author",
false).set_label(
info->author);
1074 find_widget<styled_widget>(
parent,
"type",
false).set_label(
info->display_type());
1078 status.set_use_markup(
true);
1081 find_widget<styled_widget>(
parent,
"downloads",
false).set_label(std::to_string(
info->downloads));
1085 find_widget<styled_widget>(
parent,
"dependencies",
false).set_label(!
info->depends.empty()
1087 :
_(
"addon_dependencies^None"));
1089 std::string languages;
1091 for(
const auto& lc :
info->locales) {
1092 const std::string& langlabel = langcode_to_string(lc);
1093 if(!langlabel.empty()) {
1094 if(!languages.empty()) {
1097 languages += langlabel;
1101 find_widget<styled_widget>(
parent,
"translations",
false).set_label(!languages.empty() ? languages :
_(
"translations^None"));
1103 const std::string& feedback_url =
info->feedback_url;
1104 find_widget<label>(
parent,
"url",
false).set_label(!feedback_url.empty() ? feedback_url :
_(
"url^None"));
1105 find_widget<label>(
parent,
"id",
false).set_label(
info->id);
1112 std::vector<config> version_filter_entries;
1117 stacked_widget& install_update_stack = find_widget<stacked_widget>(
parent,
"install_update_stack",
false);
1121 find_widget<button>(
parent,
"install",
false).set_active(!installed);
1123 find_widget<button>(
parent,
"update",
false).set_active(
true);
1126 find_widget<button>(
parent,
"uninstall",
false).set_active(installed);
1128 for(
const auto&
f :
info->versions) {
1129 version_filter_entries.emplace_back(
"label",
f.str());
1135 find_widget<button>(
parent,
"publish",
false).set_active(
true);
1136 find_widget<button>(
parent,
"delete",
false).set_active(!
info->local_only);
1139 version_filter_entries.emplace_back(
"label",
info->current_version.str());
1142 version_filter.
set_values(version_filter_entries);
1143 version_filter.
set_active(version_filter_entries.size() > 1);
1151 parent = stk->get_layer_grid(1);
1152 parent_of_addons_list = stk->get_layer_grid(0);
1155 const addon_info*
info = find_widget<addon_list>(parent_of_addons_list,
"addons",
false).get_selected_addon();
1157 if(
info ==
nullptr) {
1163 != find_widget<menu_button>(
parent,
"version_filter",
false).get_value_string();
1167 stacked_widget& install_update_stack = find_widget<stacked_widget>(
parent,
"install_update_stack",
false);
1169 find_widget<button>(
parent,
"update",
false).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.
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.
bool delete_remote_addon(const std::string &id, std::string &response_message)
Requests the specified add-on to be removed from the server.
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 request_addons_list(config &cfg)
Request the add-ons list 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.
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.
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_
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.
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 reload_list_and_reselect_item(const std::string id)
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()
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
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.
window * get_window()
Returns a pointer to the dialog's window.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
A label displays text that can be wrapped but no scrollbars are provided.
void set_link_aware(bool l)
std::string get_value() const
void set_text_changed_callback(std::function< void(text_box_base *textbox, const std::string text)> cb)
Set the text_changed callback.
Class for a single line text area.
base class of top level items, the only item which needs to store the final canvases to draw on.
void set_enter_disabled(const bool enter_disabled)
Disable the enter key.
void keyboard_capture(widget *widget)
void set_exit_hook(exit_hook mode, std::function< bool(window &)> func)
Sets the window's exit hook.
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.
Represents version numbers.
std::string str() const
Serializes the version number into string form.
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)
static std::string format_addon_time(std::time_t time)
REGISTER_DIALOG(tod_new_schedule)
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, int xloc, int yloc)
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.
void set_addon_manager_saved_order_direction(sort_order::type value)
std::string password(const std::string &server, const std::string &login)
sort_order::type addon_manager_saved_order_direction()
bool use_twelve_hour_clock_format()
void set_addon_manager_saved_order_name(const std::string &value)
std::string addon_manager_saved_order_name()
std::string campaign_server()
void set_password(const std::string &server, const std::string &login, const std::string &key)
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 index(const std::string &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.
bool chars_equal_insensitive(char a, char b)
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
version_info current_version
std::string display_title_translated_or_original() const
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.
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_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.