The Battle for Wesnoth  1.17.0-dev
game_config_manager.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2021
3  by Andrius Silinskas <silinskas.andrius@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #include "game_config_manager.hpp"
17 
18 #include "about.hpp"
19 #include "addon/manager.hpp"
20 #include "ai/configuration.hpp"
21 #include "cursor.hpp"
22 #include "events.hpp"
23 #include "formatter.hpp"
24 #include "game_classification.hpp"
25 #include "game_config.hpp"
26 #include "game_version.hpp"
27 #include "gettext.hpp"
31 #include "hotkey/hotkey_item.hpp"
32 #include "language.hpp"
33 #include "log.hpp"
34 #include "picture.hpp"
35 #include "preferences/advanced.hpp"
36 #include "preferences/general.hpp"
39 #include "sound.hpp"
40 #include "terrain/builder.hpp"
41 #include "terrain/type_data.hpp"
42 #include "theme.hpp"
43 #include "units/types.hpp"
44 
45 static lg::log_domain log_config("config");
46 #define ERR_CONFIG LOG_STREAM(err, log_config)
47 #define WRN_CONFIG LOG_STREAM(warn, log_config)
48 #define LOG_CONFIG LOG_STREAM(info, log_config)
49 
51 
53  : cmdline_opts_(cmdline_opts)
54  , game_config_()
55  , game_config_view_()
56  , addon_cfgs_()
57  , active_addons_()
58  , old_defines_map_()
59  , paths_manager_()
60  , cache_(game_config::config_cache::instance())
61 {
62  assert(!singleton);
63  singleton = this;
64 
65  // All of the validation options imply --nocache, as the validation happens during cache
66  // rebuilding. If the cache isn't rebuilt, validation is silently skipped.
68  cache_.set_use_cache(false);
69  }
70 
73  }
74 
75  // Clean the cache of any old Wesnoth version's cache data
76  if(const std::string last_cleaned = preferences::get("_last_cache_cleaned_ver"); !last_cleaned.empty()) {
77  if(version_info{last_cleaned} < game_config::wesnoth_version) {
78  if(cache_.clean_cache()) {
79  preferences::set("_last_cache_cleaned_ver", game_config::wesnoth_version.str());
80  }
81  }
82  } else {
83  // If the preference wasn't set, set it, else the cleaning will never happen :P
84  preferences::set("_last_cache_cleaned_ver", game_config::wesnoth_version.str());
85  }
86 }
87 
89 {
90  assert(singleton);
91  singleton = nullptr;
92 }
93 
95 {
96  return singleton;
97 }
98 
100 {
101  // Add preproc defines according to the command line arguments.
103  game_config::scoped_preproc_define test("TEST", cmdline_opts_.test.has_value());
106  game_config::scoped_preproc_define title_screen("TITLE_SCREEN",
108 
110 
111  load_game_config_with_loadscreen(force_reload);
112 
113  game_config::load_config(game_config().child("game_config"));
114 
115  // It's necessary to block the event thread while load_hotkeys() runs, otherwise keyboard input
116  // can cause a crash by accessing the list of hotkeys while it's being modified.
117  events::call_in_main_thread([this]() {
120 
121  // Load the standard hotkeys, then apply any player customizations.
124  });
125 
126  // TODO: consider making this part of preferences::manager in some fashion
128 
132 
133  return true;
134 }
135 
136 namespace
137 {
138 /** returns true if every define in special is also defined in general */
139 bool map_includes(const preproc_map& general, const preproc_map& special)
140 {
141  return std::all_of(special.begin(), special.end(), [&general](const auto& pair) {
142  const auto it = general.find(pair.first);
143  return it != general.end() && it->second == pair.second;
144  });
145 }
146 } // end anonymous namespace
147 
149  FORCE_RELOAD_CONFIG force_reload, game_classification const*, std::optional<std::set<std::string>> active_addons)
150 {
151  if(!lg::info().dont_log(log_config)) {
152  auto out = formatter();
153  out << "load_game_config: defines:";
154 
155  for(const auto& pair : cache_.get_preproc_map()) {
156  out << pair.first << ",";
157  }
158 
159  out << "\n add_ons:";
160  if(active_addons) {
161  for(const auto& str : *active_addons) {
162  out << str << ",";
163  }
164  } else {
165  out << "\n Everything:";
166  }
167 
168  out << "\n";
169  FORCE_LOG_TO(lg::info(), log_config) << out.str();
170  }
171 
172  game_config::scoped_preproc_define debug_mode("DEBUG_MODE",
174 
175  bool reload_everything = true;
176 
177  // Game_config already holds requested config in memory.
178  if(!game_config_.empty()) {
179  if((force_reload == NO_FORCE_RELOAD) && old_defines_map_ == cache_.get_preproc_map()) {
180  reload_everything = false;
181  }
182 
183  if((force_reload == NO_INCLUDE_RELOAD) && map_includes(old_defines_map_, cache_.get_preproc_map())) {
184  reload_everything = false;
185  }
186 
187  if(!reload_everything && active_addons == active_addons_) {
188  LOG_CONFIG << "load_game_config aborting\n";
189  return;
190  }
191  }
192 
193  active_addons_ = active_addons;
194 
195  LOG_CONFIG << "load_game_config: everything:" << reload_everything << "\n";
196 
197  gui2::dialogs::loading_screen::display([this, reload_everything]() {
198  load_game_config(reload_everything);
199  });
200 }
201 
202 void game_config_manager::load_game_config(bool reload_everything)
203 {
204  // Make sure that 'debug mode' symbol is set
205  // if command line parameter is selected
206  // also if we're in multiplayer and actual debug mode is disabled.
207 
208  // The loadscreen will erase the titlescreen.
209  // NOTE: even without loadscreen, needed after MP lobby.
210  try {
211  // Read all game configs.
212  // First we load all core configs, the mainline one and the ones from the addons.
213  // Validate the cores and discard the invalid.
214  // Then find the path to the selected core.
215  // Load the selected core.
216  // Handle terrains so that they are last loaded from the core.
217  // Load every compatible addon.
218  if(reload_everything) {
222 
223  // Start transaction so macros are shared.
224  game_config::config_cache_transaction main_transaction;
225 
226  // Load mainline cores definition file.
227  config cores_cfg;
228  cache_.get_config(game_config::path + "/data/cores.cfg", cores_cfg);
229 
230  // Append the $user_campaign_dir/*/cores.cfg files to the cores.
231  std::vector<std::string> user_dirs;
232  {
233  const std::string user_campaign_dir = filesystem::get_addons_dir();
234  std::vector<std::string> user_files;
236  user_campaign_dir, &user_files, &user_dirs, filesystem::name_mode::ENTIRE_FILE_PATH);
237  }
238 
239  for(const std::string& umc : user_dirs) {
240  const std::string cores_file = umc + "/cores.cfg";
241  if(filesystem::file_exists(cores_file)) {
242  config cores;
243  cache_.get_config(cores_file, cores);
244  cores_cfg.append(cores);
245  }
246  }
247 
248  // Validate every core
249  config valid_cores;
250  bool current_core_valid = false;
251  std::string wml_tree_root;
252 
253  for(const config& core : cores_cfg.child_range("core")) {
254  const std::string& id = core["id"];
255  if(id.empty()) {
258  _("Error validating data core."),
259  _("Found a core without id attribute.")
260  + '\n' + _("Skipping the core."));
261  });
262  continue;
263  }
264 
265  if(*&valid_cores.find_child("core", "id", id)) {
268  _("Error validating data core."),
269  _("Core ID: ") + id
270  + '\n' + _("The ID is already in use.")
271  + '\n' + _("Skipping the core."));
272  });
273  continue;
274  }
275 
276  const std::string& path = core["path"];
280  _("Error validating data core."),
281  _("Core ID: ") + id
282  + '\n' + _("Core Path: ") + path
283  + '\n' + _("File not found.")
284  + '\n' + _("Skipping the core."));
285  });
286  continue;
287  }
288 
289  if(id == "default" && !current_core_valid) {
290  wml_tree_root = path;
291  }
292  if(id == preferences::core_id()) {
293  current_core_valid = true;
294  wml_tree_root = path;
295  }
296 
297  valid_cores.add_child("core", core); // append(core);
298  }
299 
300  if(!current_core_valid) {
303  _("Error loading core data."),
304  _("Core ID: ") + preferences::core_id()
305  + '\n' + _("Error loading the core with named id.")
306  + '\n' + _("Falling back to the default core."));
307  });
308  preferences::set_core_id("default");
309  }
310 
311  // check if we have a valid default core which should always be the case.
312  if(wml_tree_root.empty()) {
315  _("Error loading core data."),
316  _("Can't locate the default core.")
317  + '\n' + _("The game will now exit."));
318  });
319  throw;
320  }
321 
322  // Load the selected core
323  std::unique_ptr<schema_validation::schema_validator> validator;
325  validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/game_config.cfg")));
326  validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
327  }
328 
329  cache_.get_config(filesystem::get_wml_location(wml_tree_root), game_config_, validator.get());
330  game_config_.append(valid_cores);
331 
332  main_transaction.lock();
333 
335  load_addons_cfg();
336  }
337  }
338 
339  if(active_addons_) {
341  } else {
343  }
344 
345  // Extract the Lua scripts at toplevel.
347 
348  set_unit_data();
350  tdata_ = std::make_shared<terrain_type_data>(game_config());
353 
355 
357 
358  } catch(const game::error& e) {
359  ERR_CONFIG << "Error loading game configuration files\n" << e.message << '\n';
360 
361  // Try reloading without add-ons
363  game_config::no_addons = true;
366  _("Error loading custom game configuration files. The game will try without loading add-ons."),
367  e.message);
368  });
369  load_game_config(reload_everything);
370  } else if(preferences::core_id() != "default") {
373  _("Error loading custom game configuration files. The game will fallback to the default core files."),
374  e.message);
375  });
376  preferences::set_core_id("default");
377  game_config::no_addons = false;
378  load_game_config(reload_everything);
379  } else {
382  _("Error loading default core game configuration files. The game will now exit."),
383  e.message);
384  });
385  throw;
386  }
387  }
388 
390 
391  // Set new binary paths.
393 }
394 
396 {
397  const std::string user_campaign_dir = filesystem::get_addons_dir();
398 
399  std::vector<std::string> error_log;
400  std::vector<std::string> error_addons;
401  std::vector<std::string> user_dirs;
402  std::vector<std::string> user_files;
403 
404  filesystem::get_files_in_dir(user_campaign_dir, &user_files, &user_dirs, filesystem::name_mode::ENTIRE_FILE_PATH);
405 
406  // Warn player about addons using the no-longer-supported single-file format.
407  for(const std::string& file : user_files) {
408  const int size_minus_extension = file.size() - 4;
409 
410  if(file.substr(size_minus_extension, file.size()) == ".cfg") {
411  ERR_CONFIG << "error reading usermade add-on '" << file << "'\n";
412 
413  error_addons.push_back(file);
414 
415  const int userdata_loc = file.find("data/add-ons") + 5;
416  const std::string log_msg = formatter()
417  << "The format '~"
418  << file.substr(userdata_loc)
419  << "' (for single-file add-ons) is not supported anymore, use '~"
420  << file.substr(userdata_loc, size_minus_extension - userdata_loc)
421  << "/_main.cfg' instead.";
422 
423  error_log.push_back(log_msg);
424  }
425  }
426 
427  // Rerun the directory scan using filename only, to get the addon_ids more easily.
428  user_files.clear();
429  user_dirs.clear();
430 
431  filesystem::get_files_in_dir(user_campaign_dir, nullptr, &user_dirs,
433 
434  // Load the addons.
435  for(const std::string& addon_id : user_dirs) {
436  log_scope2(log_config, "Loading add-on '" + addon_id + "'");
437  const std::string addon_dir = user_campaign_dir + "/" + addon_id;
438 
439  const std::string main_cfg = addon_dir + "/_main.cfg";
440  const std::string info_cfg = addon_dir + "/_info.cfg";
441 
442  if(!filesystem::file_exists(main_cfg)) {
443  continue;
444  }
445 
446  // Try to find this addon's metadata. Author publishing info (_server.pbl) is given
447  // precedence over addon sever-generated info (_info.cfg). If neither are found, it
448  // probably means the addon was installed manually and certain defaults will be used.
449  config metadata;
450 
451  if(have_addon_pbl_info(addon_id)) {
452  // Publishing info needs to be read from disk.
453  try {
454  metadata = get_addon_pbl_info(addon_id);
455  } catch(const invalid_pbl_exception& e) {
456  const std::string log_msg = formatter()
457  << "The provided addon has an invalid pbl file"
458  << " for addon "
459  << addon_id;
460 
461  error_addons.push_back(e.message);
462  error_log.push_back(log_msg);
463  }
464  } else if(filesystem::file_exists(info_cfg)) {
465  // Addon server-generated info can be fetched from cache.
466  config temp;
467  cache_.get_config(info_cfg, temp);
468 
469  metadata = temp.child_or_empty("info");
470  }
471 
472  std::string using_core = metadata["core"];
473  if(using_core.empty()) {
474  using_core = "default";
475  }
476 
477  // Skip add-ons not matching our current core. Cores themselves should be selectable
478  // at all times, so they aren't considered here.
479  if(!metadata.empty() && metadata["type"] != "core" && using_core != preferences::core_id()) {
480  continue;
481  }
482 
483  std::string addon_title = metadata["title"].str();
484  if(addon_title.empty()) {
485  addon_title = addon_id;
486  }
487 
488  version_info addon_version(metadata["version"]);
489 
490  try {
491  std::unique_ptr<schema_validation::schema_validator> validator;
493  validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/game_config.cfg")));
494  validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
495  }
496 
497  // Load this addon from the cache to a config.
498  config umc_cfg;
499  cache_.get_config(main_cfg, umc_cfg, validator.get());
500 
501  static const std::set<std::string> tags_with_addon_id {
502  "era",
503  "modification",
504  "resource",
505  "multiplayer",
506  "scenario",
507  "campaign",
508  "test"
509  };
510 
511  // Annotate appropriate addon types with addon_id info.
512  for(auto child : umc_cfg.all_children_range()) {
513  if(tags_with_addon_id.count(child.key) > 0) {
514  auto& cfg = child.cfg;
515  cfg["addon_id"] = addon_id;
516  cfg["addon_title"] = addon_title;
517  // Note that this may reformat the string in a canonical form.
518  cfg["addon_version"] = addon_version.str();
519  }
520  }
521 
522  config advancefroms;
523  for(auto& units : umc_cfg.child_range("units")) {
524  for(auto& unit_type : units.child_range("unit_type")) {
525  for(const auto& advancefrom : units.child_range("advancefrom")) {
526  config modify_unit_type {
527  "type", unit_type["id"],
528  "add_advancement", advancefrom["unit"],
529  "set_experience", advancefrom["experience"]
530  };
532  "[advancefrom]",
534  {1, 17, 0},
535  _("Use [modify_unit_type]\n") + modify_unit_type.debug() + "\n [/modify_unit_type] instead in [campaign]"
536  );
537 
538  advancefroms.add_child("modify_unit_type", modify_unit_type);
539  }
540  unit_type.remove_children("advancefrom", [](const config&){return true;});
541  }
542  }
543 
544  // hardcoded list of 1.14 advancement macros, just used for the error mesage below.
545  static const std::set<std::string> deprecated_defines {
546  "ENABLE_PARAGON",
547  "DISABLE_GRAND_MARSHAL",
548  "ENABLE_ARMAGEDDON_DRAKE",
549  "ENABLE_DWARVISH_ARCANISTER",
550  "ENABLE_DWARVISH_RUNESMITH",
551  "ENABLE_WOLF_ADVANCEMENT",
552  "ENABLE_NIGHTBLADE",
553  "ENABLE_TROLL_SHAMAN",
554  "ENABLE_ANCIENT_LICH",
555  "ENABLE_DEATH_KNIGHT",
556  "ENABLE_WOSE_SHAMAN"
557  };
558 
559  for(auto& campaign : umc_cfg.child_range("campaign")) {
560  campaign.append_children(std::move(advancefroms));
561 
562  for(auto str : utils::split(campaign["extra_defines"])) {
563  if(deprecated_defines.count(str) > 0) {
564  //TODO: we could try to implement a compatibility path by
565  // somehow getting the content of that macro from the
566  // cache_ object, but considering that 1) the breakage
567  // isn't that bad (just one disabled unit) and 2)
568  // it before also didn't work in all cases (see #4402)
569  // i don't think it is worth it.
571  "extra_defines=" + str,
573  {1, 15, 4},
574  _("instead, use the macro with the same name in the [campaign] tag")
575  );
576  }
577  }
578  }
579 
580  static const std::set<std::string> entry_tags {
581  "era",
582  "modification",
583  "resource",
584  "multiplayer",
585  "scenario",
586  "campaign"
587  };
588 
589  for(const std::string& tagname : entry_tags) {
590  game_config_.append_children_by_move(umc_cfg, tagname);
591  }
592 
593  addon_cfgs_[addon_id] = std::move(umc_cfg);
594  } catch(const config::error& err) {
595  ERR_CONFIG << "error reading usermade add-on '" << main_cfg << "'" << std::endl;
596  ERR_CONFIG << err.message << '\n';
597  error_addons.push_back(main_cfg);
598  error_log.push_back(err.message);
599  } catch(const preproc_config::error& err) {
600  ERR_CONFIG << "error reading usermade add-on '" << main_cfg << "'" << std::endl;
601  ERR_CONFIG << err.message << '\n';
602  error_addons.push_back(main_cfg);
603  error_log.push_back(err.message);
604  } catch(const filesystem::io_exception&) {
605  ERR_CONFIG << "error reading usermade add-on '" << main_cfg << "'" << std::endl;
606  error_addons.push_back(main_cfg);
607  }
608  }
609 
612  ERR_CONFIG << "Didn’t find an add-on for --validate-addon - check whether the id has a typo" << std::endl;
613  const std::string log_msg = formatter()
614  << "Didn't find an add-on for --validate-addon - check whether the id has a typo";
615  error_log.push_back(log_msg);
616  throw game::error("Did not find an add-on for --validate-addon");
617  }
618 
619  WRN_CONFIG << "Note: for --validate-addon to find errors, you have to play (in the GUI) a game that uses the add-on.";
620  }
621 
622  if(!error_addons.empty()) {
623  const std::size_t n = error_addons.size();
624  const std::string& msg1 =
625  _n("The following add-on had errors and could not be loaded:",
626  "The following add-ons had errors and could not be loaded:",
627  n);
628  const std::string& msg2 =
629  _n("Please report this to the author or maintainer of this add-on.",
630  "Please report this to the respective authors or maintainers of these add-ons.",
631  n);
632 
633  const std::string& report = utils::join(error_log, "\n\n");
635  gui2::dialogs::wml_error::display(msg1, msg2, error_addons, report);
636  });
637  }
638 }
639 
641 {
642  config& hashes = game_config_.add_child("multiplayer_hashes");
643  for(const config& ch : game_config().child_range("multiplayer")) {
644  hashes[ch["id"].str()] = ch.hash();
645  }
646 }
647 
649 {
651  unit_types.set_config(game_config().merged_children_view("units"));
652 }
653 
655 {
656  // Rebuild addon version info cache.
658 
659  // Force a reload of configuration information.
661  old_defines_map_.clear();
664 
667 }
668 
670 {
673 }
674 
676  const game_classification& classification, const std::string& scenario_id)
677 {
678  game_config::scoped_preproc_define difficulty(classification.difficulty,
679  !classification.difficulty.empty());
680  game_config::scoped_preproc_define campaign(classification.campaign_define,
681  !classification.campaign_define.empty());
682  game_config::scoped_preproc_define scenario(classification.scenario_define,
683  !classification.scenario_define.empty());
685  !classification.era_define.empty());
686  game_config::scoped_preproc_define multiplayer("MULTIPLAYER",
687  classification.is_multiplayer());
689  classification.is_multiplayer());
690 
691  //
692  // NOTE: these deques aren't used here, but the objects within are utilized as RAII helpers.
693  //
694 
695  std::deque<game_config::scoped_preproc_define> extra_defines;
696  for(const std::string& extra_define : classification.campaign_xtra_defines) {
697  extra_defines.emplace_back(extra_define);
698  }
699 
700  std::deque<game_config::scoped_preproc_define> modification_defines;
701  for(const std::string& mod_define : classification.mod_defines) {
702  modification_defines.emplace_back(mod_define, !mod_define.empty());
703  }
704 
705  try {
706  load_game_config_with_loadscreen(NO_FORCE_RELOAD, &classification, classification.active_addons(scenario_id));
707  } catch(const game::error&) {
709 
710  std::deque<game_config::scoped_preproc_define> previous_defines;
711  for(const preproc_map::value_type& preproc : old_defines_map_) {
712  previous_defines.emplace_back(preproc.first);
713  }
714 
716  throw;
717  }
718 
719  // This needs to be done in the main thread since this function (load_game_config_for_game)
720  // might be called from a loading screen worker thread (and currently is, in fact). If the
721  // image cache is purged from the worker thread, there's a possibility for a data race where
722  // the main thread accesses the image cache and the worker thread simultaneously clears it.
724 }
725 
727 {
728  game_config::scoped_preproc_define multiplayer("MULTIPLAYER", is_mp);
729  game_config::scoped_preproc_define test("TEST", is_test);
730  game_config::scoped_preproc_define mptest("MP_TEST", cmdline_opts_.mptest && is_mp);
731  /** During an mp game the default difficulty define is also defined so better already load it now if we already must reload config cache. */
734 
735  try {
737  } catch(const game::error&) {
739 
740  std::deque<game_config::scoped_preproc_define> previous_defines;
741  for (const preproc_map::value_type& preproc : old_defines_map_) {
742  previous_defines.emplace_back(preproc.first);
743  }
744 
746  throw;
747  }
748 }
749 
750 void game_config_manager::set_enabled_addon(std::set<std::string> addon_ids)
751 {
752  auto& vec = game_config_view_.data();
753  vec.clear();
754  vec.push_back(game_config_);
755 
756  for(const std::string& id : addon_ids) {
757  auto it = addon_cfgs_.find(id);
758  if(it != addon_cfgs_.end()) {
759  vec.push_back(it->second);
760  }
761  }
762 }
763 
765 {
766  auto& vec = game_config_view_.data();
767  vec.clear();
768  vec.push_back(game_config_);
769 
770  for(const auto& pair : addon_cfgs_) {
771  vec.push_back(pair.second);
772  }
773 }
Don&#39;t reload if the previous defines include the new defines.
static std::string _n(const char *str1, const char *str2, int n)
Definition: gettext.hpp:97
bool any_validation_option() const
True if the –validate or any of the –validate-* options are given.
bool mptest
True if –mp-test was given on the command line.
const_all_children_itors all_children_range() const
In-order iteration over all children.
Definition: config.cpp:959
std::string era()
Definition: game.cpp:695
Interfaces for manipulating version numbers of engine, add-ons, etc.
std::optional< std::string > test
Non-empty if –test was given on the command line.
game_classification * classification
Definition: resources.cpp:35
void append(const config &cfg)
Append data from another config object to this one.
Definition: config.cpp:286
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
void append_children_by_move(config &cfg, const std::string &key)
Moves children with the given name from the given config to this one.
Definition: config.cpp:311
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.
Definition: config.cpp:866
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:40
bool noaddons
True if –noaddons was given on the command line.
logger & info()
Definition: log.cpp:89
Exception thrown when the WML parser fails to read a .pbl file.
Definition: manager.hpp:44
void lock()
Lock the transaction so no more macros are added.
void set_scope_active(scope s, bool set)
static bool file_exists(const bfs::path &fpath)
Definition: filesystem.cpp:263
static void init(const game_config_view &game_config)
Init the parameters of ai configuration parser.
child_itors child_range(config_key_type key)
Definition: config.cpp:361
filesystem::binary_paths_manager paths_manager_
static void progress(loading_stage stage=loading_stage::none)
void load_game_config_for_game(const game_classification &classification, const std::string &scenario_id)
const std::string DEFAULT_DIFFICULTY
The default difficulty setting for campaigns.
#define ERR_CONFIG
static void set_known_themes(const game_config_view *cfg)
Definition: theme.cpp:920
unit_type_data unit_types
Definition: types.cpp:1481
void set(const std::string &key, bool value)
Definition: general.cpp:161
Don&#39;t reload if the previous defines equal the new defines.
static lg::log_domain log_config("config")
void init_textdomains(const game_config_view &cfg)
Initializes the list of textdomains from a configuration object.
Definition: language.cpp:367
static std::string _(const char *str)
Definition: gettext.hpp:93
void load_config(const config &v)
A single unit type that the player may recruit.
Definition: types.hpp:45
Used to set and unset scoped defines to preproc_map.
void call_in_main_thread(const std::function< void(void)> &f)
Definition: events.cpp:867
void flush_cache()
Purges all image caches.
Definition: picture.cpp:222
void clear_binary_paths_cache()
One of the realizations of serialization/validator.hpp abstract validator.
#define LOG_CONFIG
static game_config_manager * get()
void set_about(const game_config_view &cfg)
Regenerates the credits data.
Definition: about.cpp:116
std::string get(const std::string &key)
Definition: general.cpp:209
std::set< std::string > active_addons(const std::string &scenario_id) const
std::string deprecated_message(const std::string &elem_name, DEP_LEVEL level, const version_info &version, const std::string &detail)
Definition: deprecation.cpp:30
void load_hotkeys()
Definition: general.cpp:885
std::optional< std::set< std::string > > active_addons_
std::ostringstream wrapper.
Definition: formatter.hpp:39
bool clean_cache()
Deletes stale cache files not in use by the game.
const std::string message
Error message to display.
Definition: manager.hpp:60
std::optional< std::string > validate_addon
Non-empty if –validate-addon was given on the command line.
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.
Definition: filesystem.cpp:349
std::string campaign_define
If there is a define the campaign uses to customize data.
const game_config_view & game_config() const
game_config_view game_config_view_
void set_force_valid_cache(bool force)
Enable/disable cache validation.
void set_core_id(const std::string &core_id)
Definition: general.cpp:329
static game_config_manager * singleton
std::string path
Definition: game_config.cpp:39
#define log_scope2(domain, description)
Definition: log.hpp:219
bool multiplayer
True if –multiplayer was given on the command line.
void refresh_addon_version_info_cache()
Refreshes the per-session cache of add-on&#39;s version information structs.
Definition: manager.cpp:356
static void add_color_info(const game_config_view &v, bool build_defaults)
void deactivate_all_scopes()
bool init_strings(const game_config_view &cfg)
Initializes certain English strings.
Definition: language.cpp:390
log_domain & general()
Definition: log.cpp:103
config get_addon_pbl_info(const std::string &addon_name)
Gets the publish information for an add-on.
Definition: manager.cpp:68
std::string era_define
If there is a define the era uses to customize data.
void flush_cache()
Definition: sound.cpp:195
void get_config(const std::string &path, config &cfg, abstract_validator *validator=nullptr)
Gets a config object from given path.
void set_use_cache(bool use)
Enable/disable caching.
#define FORCE_LOG_TO(logger, domain)
Definition: log.hpp:231
void clear_defines()
Clear stored defines map to default values.
bool nocache
True if –nocache was given on the command line.
logger & err()
Definition: log.cpp:77
void set_enabled_addon(std::set< std::string > addon_ids)
std::vector< std::string > campaign_xtra_defines
more customization of data
std::string get_wml_location(const std::string &filename, const std::string &current_dir)
Returns a complete path to the actual WML file or directory or an empty string if the file isn&#39;t pres...
bool have_addon_pbl_info(const std::string &addon_name)
Returns whether a .pbl file is present for the specified add-on or not.
Definition: manager.cpp:63
void load_game_config_for_create(bool is_mp, bool is_test=false)
Game configuration data as global variables.
Definition: build_info.cpp:59
const preproc_map & get_preproc_map() const
An exception object used when an IO error occurs.
Definition: filesystem.hpp:48
void reset_color_info()
std::string scenario_define
If there is a define the scenario uses to customize data.
std::vector< std::string > mod_defines
If there are defines the modifications use to customize data.
Definitions related to theme-support.
const bool & debug
Definitions for the terrain builder.
const version_info wesnoth_version(VERSION)
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.
Definition: wml_error.hpp:53
Represents version numbers.
config & add_child(config_key_type key)
Definition: config.cpp:505
const file_tree_checksum & data_tree_checksum(bool reset=false)
Get the time at which the data/ tree was last modified at.
std::string difficulty
The difficulty level the game is being played on.
std::string core_id()
Definition: general.cpp:323
Used to share macros between cache objects You have to create transaction object to load all macros t...
void set_paths(const game_config_view &cfg)
static void display(std::function< void()> f)
game_config_manager(const commandline_options &cmdline_opts)
void set_config(const game_config_view &cfg)
Resets all data based on the provided config.
Definition: types.cpp:1096
std::vector< std::string > split(const config_attribute_value &val)
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:28
std::string get_addons_dir()
Managing the AIs configuration - headers.
bool validate_core
True if –validate-core was given on the command line.
void load_game_config(bool reload_everything)
Standard logging facilities (interface).
std::string str() const
Serializes the version number into string form.
std::string message
Definition: exceptions.hpp:30
const commandline_options & cmdline_opts_
bool validcache
True if –validcache was given on the command line.
std::optional< std::string > editor
Non-empty if –editor was given on the command line.
game_config::config_cache & cache_
std::map< std::string, struct preproc_define > preproc_map
#define e
Realization of serialization/validator.hpp abstract validator.
void load_hotkeys(const game_config_view &cfg, bool set_as_default)
Iterates through all hotkeys present in the config struct and creates and adds them to the hotkey lis...
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.
Definition: config.cpp:482
#define WRN_CONFIG
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:60
static void set_terrain_rules_cfg(const game_config_view &cfg)
Set the config where we will parse the global terrain rules.
Definition: builder.cpp:292
static map_location::DIRECTION n
void load_game_config_with_loadscreen(FORCE_RELOAD_CONFIG force_reload, game_classification const *classification=nullptr, std::optional< std::set< std::string >> active_addons={})
bool init_game_config(FORCE_RELOAD_CONFIG force_reload)
std::map< std::string, config > addon_cfgs_
std::string hash() const
Definition: config.cpp:1373
config_array_view & data()
void init_advanced_manager(const game_config_view &gc)
Initializes the manager singleton.
Definition: advanced.cpp:72
bool empty() const
Definition: config.cpp:922
static void extract_preload_scripts(const game_config_view &game_config)
std::shared_ptr< terrain_type_data > tdata_
void recheck_filetree_checksum()
Force cache checksum validation.