19 #include "addon/manager.hpp"
47 #define ERR_CONFIG LOG_STREAM(err, log_config)
48 #define WRN_CONFIG LOG_STREAM(warn, log_config)
49 #define LOG_CONFIG LOG_STREAM(info, log_config)
56 : cmdline_opts_(cmdline_opts)
80 if(
const std::string last_cleaned =
preferences::get(
"_last_cache_cleaned_ver"); !last_cleaned.empty()) {
144 return std::all_of(special.begin(), special.end(), [&
general](
const auto& pair) {
145 const auto it = general.find(pair.first);
146 return it != general.end() && it->second == pair.second;
156 out <<
"load_game_config: defines:";
159 out << pair.first <<
",";
169 bool reload_everything =
true;
174 reload_everything =
false;
178 reload_everything =
false;
182 LOG_CONFIG <<
"load_game_config reload everything: " << reload_everything;
205 if(reload_everything) {
219 std::vector<std::string> user_dirs;
222 std::vector<std::string> user_files;
227 for(
const std::string& umc : user_dirs) {
228 const std::string cores_file = umc +
"/cores.cfg";
238 bool current_core_valid =
false;
239 std::string wml_tree_root;
242 const std::string&
id = core[
"id"];
246 _(
"Error validating data core."),
247 _(
"Found a core without id attribute.")
248 +
'\n' +
_(
"Skipping the core."));
253 if(valid_cores.
find_child(
"core",
"id",
id)) {
256 _(
"Error validating data core."),
258 +
'\n' +
_(
"The ID is already in use.")
259 +
'\n' +
_(
"Skipping the core."));
264 const std::string&
path = core[
"path"];
268 _(
"Error validating data core."),
270 +
'\n' +
_(
"Core Path: ") +
path
271 +
'\n' +
_(
"File not found.")
272 +
'\n' +
_(
"Skipping the core."));
277 if(
id ==
"default" && !current_core_valid) {
278 wml_tree_root =
path;
281 current_core_valid =
true;
282 wml_tree_root =
path;
288 if(!current_core_valid) {
291 _(
"Error loading core data."),
293 +
'\n' +
_(
"Error loading the core with named id.")
294 +
'\n' +
_(
"Falling back to the default core."));
300 if(wml_tree_root.empty()) {
303 _(
"Error loading core data."),
304 _(
"Can't locate the default core.")
305 +
'\n' +
_(
"The game will now exit."));
311 std::unique_ptr<schema_validation::schema_validator> validator;
314 validator->set_create_exceptions(
false);
320 main_transaction.
lock();
334 LOG_CONFIG <<
"Configs not reloaded and active add-ons remain the same; returning early.";
359 ERR_CONFIG <<
"Error loading game configuration files\n" <<
e.message;
366 _(
"Error loading custom game configuration files. The game will try without loading add-ons."),
373 _(
"Error loading custom game configuration files. The game will fallback to the default core files."),
382 _(
"Error loading default core game configuration files. The game will now exit."),
397 for(
auto&
unit_type : units.child_range(
"unit_type")) {
398 for(
const auto& advancefrom :
unit_type.child_range(
"advancefrom")) {
400 {
"lower_level", advancefrom[
"unit"]},
407 "Error: [advancefrom] no longer works. ‘$lower_level’ units will not be able to advance to ‘$higher_level’; please ask the add-on author to use [modify_unit_type] instead.",
411 unit_type.remove_children(
"advancefrom", [](
const config&){
return true;});
417 static const std::set<std::string> deprecated_defines {
419 "DISABLE_GRAND_MARSHAL",
420 "ENABLE_ARMAGEDDON_DRAKE",
421 "ENABLE_DWARVISH_ARCANISTER",
422 "ENABLE_DWARVISH_RUNESMITH",
423 "ENABLE_WOLF_ADVANCEMENT",
425 "ENABLE_TROLL_SHAMAN",
426 "ENABLE_ANCIENT_LICH",
427 "ENABLE_DEATH_KNIGHT",
431 for(
auto& campaign : umc_cfg.
child_range(
"campaign")) {
432 for(
auto str :
utils::split(campaign[
"extra_defines"])) {
433 if(deprecated_defines.count(str) > 0) {
441 "campaign id='" + campaign[
"id"].str() +
"' has extra_defines=" + str,
444 _(
"instead, use the macro with the same name in the [campaign] tag")
455 std::vector<std::string> error_log;
456 std::vector<std::string> error_addons;
457 std::vector<std::string> user_dirs;
458 std::vector<std::string> user_files;
463 for(
const std::string& file : user_files) {
464 const int size_minus_extension = file.size() - 4;
466 if(file.substr(size_minus_extension, file.size()) ==
".cfg") {
467 ERR_CONFIG <<
"error reading usermade add-on '" << file <<
"'";
469 error_addons.push_back(file);
471 const int userdata_loc = file.find(
"data/add-ons") + 5;
474 << file.substr(userdata_loc)
475 <<
"' (for single-file add-ons) is not supported anymore, use '~"
476 << file.substr(userdata_loc, size_minus_extension - userdata_loc)
477 <<
"/_main.cfg' instead.";
479 error_log.push_back(log_msg);
483 loading_screen::spin();
492 loading_screen::spin();
495 for(
const std::string& addon_id : user_dirs) {
497 const std::string addon_dir = user_campaign_dir +
"/" + addon_id;
499 const std::string main_cfg = addon_dir +
"/_main.cfg";
500 const std::string info_cfg = addon_dir +
"/_info.cfg";
506 loading_screen::spin();
519 <<
"The provided addon has an invalid pbl file"
523 error_addons.push_back(
e.message);
524 error_log.push_back(log_msg);
534 std::string using_core = metadata[
"core"];
535 if(using_core.empty()) {
536 using_core =
"default";
545 std::string addon_title = metadata[
"title"].str();
546 if(addon_title.empty()) {
547 addon_title = addon_id;
553 std::unique_ptr<schema_validation::schema_validator> validator;
556 validator->set_create_exceptions(
false);
559 loading_screen::spin();
565 static const std::set<std::string> tags_with_addon_id {
577 if(tags_with_addon_id.count(child.key) > 0) {
578 auto& cfg = child.cfg;
579 cfg[
"addon_id"] = addon_id;
580 cfg[
"addon_title"] = addon_title;
582 cfg[
"addon_version"] = addon_version.
str();
586 loading_screen::spin();
590 loading_screen::spin();
592 static const std::set<std::string> entry_tags {
601 for(
const std::string& tagname : entry_tags) {
605 loading_screen::spin();
609 ERR_CONFIG <<
"config error reading usermade add-on '" << main_cfg <<
"'";
611 error_addons.push_back(main_cfg);
612 error_log.push_back(
err.message);
614 ERR_CONFIG <<
"preprocessor config error reading usermade add-on '" << main_cfg <<
"'";
616 error_addons.push_back(main_cfg);
617 error_log.push_back(
err.message);
619 ERR_CONFIG <<
"filesystem I/O error reading usermade add-on '" << main_cfg <<
"'";
620 error_addons.push_back(main_cfg);
626 ERR_CONFIG <<
"Didn’t find an add-on for --validate-addon - check whether the id has a typo";
628 <<
"Didn't find an add-on for --validate-addon - check whether the id has a typo";
629 error_log.push_back(log_msg);
630 throw game::error(
"Did not find an add-on for --validate-addon");
633 WRN_CONFIG <<
"Note: for --validate-addon to find errors, you have to play (in the GUI) a game that uses the add-on.";
636 if(!error_addons.empty()) {
637 const std::size_t
n = error_addons.size();
638 const std::string& msg1 =
639 _n(
"The following add-on had errors and could not be loaded:",
640 "The following add-ons had errors and could not be loaded:",
642 const std::string& msg2 =
643 _n(
"Please report this to the author or maintainer of this add-on.",
644 "Please report this to the respective authors or maintainers of these add-ons.",
647 const std::string& report =
utils::join(error_log,
"\n\n");
658 hashes[ch[
"id"].str()] = ch.
hash();
709 std::deque<game_config::scoped_preproc_define> extra_defines;
711 extra_defines.emplace_back(extra_define);
714 std::deque<game_config::scoped_preproc_define> modification_defines;
716 modification_defines.emplace_back(mod_define, !mod_define.empty());
724 std::deque<game_config::scoped_preproc_define> previous_defines;
726 previous_defines.emplace_back(preproc.first);
754 std::deque<game_config::scoped_preproc_define> previous_defines;
756 previous_defines.emplace_back(preproc.first);
770 for(
const std::string&
id : addon_ids) {
774 vec.push_back(it->second);
776 ERR_CONFIG <<
"Attempted to enable add-on '" <<
id <<
"' but its config could not be found";
789 LOG_CONFIG <<
"Enabling add-on " << pair.first;
790 vec.push_back(pair.second);
config get_addon_pbl_info(const std::string &addon_name, bool do_validate)
Gets the publish information 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.
void refresh_addon_version_info_cache()
Refreshes the per-session cache of add-on's version information structs.
Definitions for the terrain builder.
void reload()
Reads the mainline achievements.cfg and then all the achievements of each installed add-on.
static void init(const game_config_view &game_config)
Init the parameters of ai configuration parser.
std::optional< std::string > validate_addon
Non-empty if –validate-addon was given on the command line.
bool mptest
True if –mp-test was given on the command line.
bool multiplayer
True if –multiplayer was given on the command line.
bool validcache
True if –validcache was given on the command line.
bool noaddons
True if –noaddons was given on the command line.
std::optional< std::string > test
Non-empty if –test was given on the command line.
bool any_validation_option() const
True if the –validate or any of the –validate-* options are given.
bool validate_core
True if –validate-core was given on the command line.
bool nocache
True if –nocache was given on the command line.
std::optional< std::string > editor
Non-empty if –editor was given on the command line.
A config object defines a single node in a WML file, with access to child nodes.
void append(const config &cfg)
Append data from another config object to this one.
const config & child_or_empty(config_key_type key) const
Returns the first child with the given key, or an empty config if there is none.
void append_children_by_move(config &cfg, const std::string &key)
Moves children with the given name from the given config to this one.
optional_config_impl< config > find_child(config_key_type key, const std::string &name, const std::string &value)
Returns the first child of tag key with a name attribute containing value.
const_all_children_itors all_children_range() const
In-order iteration over all children.
child_itors child_range(config_key_type key)
const attribute_value * get(config_key_type key) const
Returns a pointer to the attribute with the given key or nullptr if it does not exist.
config & add_child(config_key_type key)
std::vector< std::string > campaign_xtra_defines
more customization of data
std::vector< std::string > mod_defines
If there are defines the modifications use to customize data.
std::set< std::string > active_addons(const std::string &scenario_id) const
std::string scenario_define
If there is a define the scenario uses to customize data.
std::string difficulty
The difficulty level the game is being played on.
std::string era_define
If there is a define the era uses to customize data.
std::string campaign_define
If there is a define the campaign uses to customize data.
bool is_multiplayer() const
Used to share macros between cache objects You have to create transaction object to load all macros t...
void lock()
Lock the transaction so no more macros are added.
void recheck_filetree_checksum()
Force cache checksum validation.
void set_use_cache(bool use)
Enable/disable caching.
const preproc_map & get_preproc_map() const
void clear_defines()
Clear stored defines map to default values.
bool clean_cache()
Deletes stale cache files not in use by the game.
void set_force_valid_cache(bool force)
Enable/disable cache validation.
void get_config(const std::string &path, config &cfg, abstract_validator *validator=nullptr)
Gets a config object from given path.
Used to set and unset scoped defines to preproc_map.
void load_game_config_with_loadscreen(FORCE_RELOAD_CONFIG force_reload, const game_classification *classification, const std::string &scenario_id)
@ FORCE_RELOAD
Always reload config.
@ NO_INCLUDE_RELOAD
Don't reload if the previous defines include the new defines.
@ NO_FORCE_RELOAD
Don't reload if the previous defines equal the new defines.
std::map< std::string, config > addon_cfgs_
bool init_game_config(FORCE_RELOAD_CONFIG force_reload)
achievements achievements_
static game_config_manager * get()
void load_game_config_for_game(const game_classification &classification, const std::string &scenario_id)
void load_game_config(bool reload_everything, const game_classification *classification, const std::string &scenario_id)
std::set< std::string > active_addons_
void load_game_config_for_create(bool is_mp, bool is_test=false)
filesystem::binary_paths_manager paths_manager_
void set_enabled_addon_all()
game_config_view game_config_view_
preproc_map old_defines_map_
game_config::config_cache & cache_
std::shared_ptr< terrain_type_data > tdata_
void set_multiplayer_hashes()
void reload_changed_game_config()
game_config_manager(const commandline_options &cmdline_opts)
void set_enabled_addon(std::set< std::string > addon_ids)
const game_config_view & game_config() const
const commandline_options & cmdline_opts_
void load_game_config_for_editor()
config_array_view & data()
static void extract_preload_scripts(const game_config_view &game_config)
static void progress(loading_stage stage=loading_stage::none)
Report what is being loaded to the loading screen.
static void display(std::function< void()> f)
static void display(const std::string &summary, const std::string &post_summary, const std::vector< std::string > &files, const std::string &details)
The display function; see modal_dialog for more information.
Realization of serialization/validator.hpp abstract validator.
static void set_terrain_rules_cfg(const game_config_view &cfg)
Set the config where we will parse the global terrain rules.
static void set_known_themes(const game_config_view *cfg)
Copies the theme configs from the main game config.
void set_config(const game_config_view &cfg)
Resets all data based on the provided config.
A single unit type that the player may recruit.
Represents version numbers.
std::string str() const
Serializes the version number into string form.
Managing the AIs configuration - headers.
std::string deprecated_message(const std::string &elem_name, DEP_LEVEL level, const version_info &version, const std::string &detail)
const std::string DEFAULT_DIFFICULTY
The default difficulty setting for campaigns.
static game_config_manager * singleton
static void show_deprecated_warnings(config &umc_cfg)
static lg::log_domain log_config("config")
Interfaces for manipulating version numbers of engine, add-ons, etc.
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()
void init_textdomains(const game_config_view &cfg)
Initializes the list of textdomains from a configuration object.
bool init_strings(const game_config_view &cfg)
Initializes certain English strings.
Standard logging facilities (interface).
#define log_scope2(domain, description)
#define FORCE_LOG_TO(logger, domain)
void set_about(const game_config_view &cfg)
Regenerates the credits data.
void call_in_main_thread(const std::function< void(void)> &f)
void get_files_in_dir(const std::string &dir, std::vector< std::string > *files, std::vector< std::string > *dirs, name_mode mode, filter_mode filter, reorder_mode reorder, file_tree_checksum *checksum)
Get a list of all files and/or directories in a given directory.
static bool file_exists(const bfs::path &fpath)
std::string get_wml_location(const std::string &filename, const std::string ¤t_dir)
Returns a complete path to the actual WML file or directory or an empty string if the file isn't pres...
const file_tree_checksum & data_tree_checksum(bool reset=false)
Get the time at which the data/ tree was last modified at.
void clear_binary_paths_cache()
std::string get_addons_dir()
Game configuration data as global variables.
const version_info wesnoth_version(VERSION)
static void add_color_info(const game_config_view &v, bool build_defaults)
void load_config(const config &v)
void load_default_hotkeys(const game_config_view &cfg)
Registers all hotkeys present in this config.
constexpr uint32_t scope_main
void flush_cache()
Purges all image caches.
void set_core_id(const std::string &core_id)
void set(const std::string &key, bool value)
void init_advanced_manager(const game_config_view &gc)
Initializes the manager singleton.
std::string get(const std::string &key)
game_classification * classification
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::map< std::string, t_string > string_map
std::vector< std::string > split(const config_attribute_value &val)
std::map< std::string, struct preproc_define > preproc_map
One of the realizations of serialization/validator.hpp abstract validator.
void set_paths(const game_config_view &cfg)
An exception object used when an IO error occurs.
Base class for all the errors encountered by the engine.
Exception thrown when the WML parser fails to read a .pbl file.
static map_location::DIRECTION n
Definitions related to theme-support.
unit_type_data unit_types