The Battle for Wesnoth  1.15.11+dev
game_config_manager.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2018 by Andrius Silinskas <silinskas.andrius@gmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "game_config_manager.hpp"
16 
17 #include "about.hpp"
18 #include "addon/manager.hpp"
19 #include "ai/configuration.hpp"
20 #include "cursor.hpp"
21 #include "events.hpp"
22 #include "formatter.hpp"
23 #include "game_classification.hpp"
24 #include "game_config.hpp"
25 #include "game_version.hpp"
26 #include "gettext.hpp"
30 #include "hotkey/hotkey_item.hpp"
31 #include "language.hpp"
32 #include "log.hpp"
33 #include "picture.hpp"
34 #include "preferences/advanced.hpp"
35 #include "preferences/general.hpp"
38 #include "sound.hpp"
39 #include "terrain/builder.hpp"
40 #include "terrain/type_data.hpp"
41 #include "theme.hpp"
42 #include "units/types.hpp"
43 
44 static lg::log_domain log_config("config");
45 #define ERR_CONFIG LOG_STREAM(err, log_config)
46 #define WRN_CONFIG LOG_STREAM(warn, log_config)
47 #define LOG_CONFIG LOG_STREAM(info, log_config)
48 
50 
52  : cmdline_opts_(cmdline_opts)
53  , game_config_()
54  , game_config_view_()
55  , addon_cfgs_()
56  , active_addons_()
57  , old_defines_map_()
58  , paths_manager_()
59  , cache_(game_config::config_cache::instance())
60 {
61  assert(!singleton);
62  singleton = this;
63 
64  // All of the validation options imply --nocache, as the validation happens during cache
65  // rebuilding. If the cache isn't rebuilt, validation is silently skipped.
67  cache_.set_use_cache(false);
68  }
69 
72  }
73 
74  // Clean the cache of any old Wesnoth version's cache data
75  if(const std::string last_cleaned = preferences::get("_last_cache_cleaned_ver"); !last_cleaned.empty()) {
76  if(version_info{last_cleaned} < game_config::wesnoth_version) {
77  if(cache_.clean_cache()) {
78  preferences::set("_last_cache_cleaned_ver", game_config::wesnoth_version.str());
79  }
80  }
81  } else {
82  // If the preference wasn't set, set it, else the cleaning will never happen :P
83  preferences::set("_last_cache_cleaned_ver", game_config::wesnoth_version.str());
84  }
85 }
86 
88 {
89  assert(singleton);
90  singleton = nullptr;
91 }
92 
94 {
95  return singleton;
96 }
97 
99 {
100  // Add preproc defines according to the command line arguments.
102  game_config::scoped_preproc_define test("TEST", cmdline_opts_.test.has_value());
105  game_config::scoped_preproc_define title_screen("TITLE_SCREEN",
107 
109 
110  load_game_config_with_loadscreen(force_reload);
111 
112  game_config::load_config(game_config().child("game_config"));
113 
116 
117  // Load the standard hotkeys, then apply any player customizations.
120 
121  // TODO: consider making this part of preferences::manager in some fashion
123 
127 
128  return true;
129 }
130 
131 namespace
132 {
133 /** returns true if every define in special is also defined in general */
134 bool map_includes(const preproc_map& general, const preproc_map& special)
135 {
136  return std::all_of(special.begin(), special.end(), [&general](const auto& pair) {
137  const auto it = general.find(pair.first);
138  return it != general.end() && it->second == pair.second;
139  });
140 }
141 } // end anonymous namespace
142 
144  FORCE_RELOAD_CONFIG force_reload, game_classification const*, std::optional<std::set<std::string>> active_addons)
145 {
146  if(!lg::info().dont_log(log_config)) {
147  auto out = formatter();
148  out << "load_game_config: defines:";
149 
150  for(const auto& pair : cache_.get_preproc_map()) {
151  out << pair.first << ",";
152  }
153 
154  out << "\n add_ons:";
155  if(active_addons) {
156  for(const auto& str : *active_addons) {
157  out << str << ",";
158  }
159  } else {
160  out << "\n Everything:";
161  }
162 
163  out << "\n";
164  FORCE_LOG_TO(lg::info(), log_config) << out.str();
165  }
166 
167  game_config::scoped_preproc_define debug_mode("DEBUG_MODE",
169 
170  bool reload_everything = true;
171 
172  // Game_config already holds requested config in memory.
173  if(!game_config_.empty()) {
174  if((force_reload == NO_FORCE_RELOAD) && old_defines_map_ == cache_.get_preproc_map()) {
175  reload_everything = false;
176  }
177 
178  if((force_reload == NO_INCLUDE_RELOAD) && map_includes(old_defines_map_, cache_.get_preproc_map())) {
179  reload_everything = false;
180  }
181 
182  if(!reload_everything && active_addons == active_addons_) {
183  LOG_CONFIG << "load_game_config aborting\n";
184  return;
185  }
186  }
187 
188  active_addons_ = active_addons;
189 
190  LOG_CONFIG << "load_game_config: everything:" << reload_everything << "\n";
191 
192  gui2::dialogs::loading_screen::display([this, reload_everything]() {
193  load_game_config(reload_everything);
194  });
195 }
196 
197 void game_config_manager::load_game_config(bool reload_everything)
198 {
199  // Make sure that 'debug mode' symbol is set
200  // if command line parameter is selected
201  // also if we're in multiplayer and actual debug mode is disabled.
202 
203  // The loadscreen will erase the titlescreen.
204  // NOTE: even without loadscreen, needed after MP lobby.
205  try {
206  // Read all game configs.
207  // First we load all core configs, the mainline one and the ones from the addons.
208  // Validate the cores and discard the invalid.
209  // Then find the path to the selected core.
210  // Load the selected core.
211  // Handle terrains so that they are last loaded from the core.
212  // Load every compatible addon.
213  if(reload_everything) {
217 
218  // Start transaction so macros are shared.
219  game_config::config_cache_transaction main_transaction;
220 
221  // Load mainline cores definition file.
222  config cores_cfg;
223  cache_.get_config(game_config::path + "/data/cores.cfg", cores_cfg);
224 
225  // Append the $user_campaign_dir/*/cores.cfg files to the cores.
226  std::vector<std::string> user_dirs;
227  {
228  const std::string user_campaign_dir = filesystem::get_addons_dir();
229  std::vector<std::string> user_files;
231  user_campaign_dir, &user_files, &user_dirs, filesystem::name_mode::ENTIRE_FILE_PATH);
232  }
233 
234  for(const std::string& umc : user_dirs) {
235  const std::string cores_file = umc + "/cores.cfg";
236  if(filesystem::file_exists(cores_file)) {
237  config cores;
238  cache_.get_config(cores_file, cores);
239  cores_cfg.append(cores);
240  }
241  }
242 
243  // Validate every core
244  config valid_cores;
245  bool current_core_valid = false;
246  std::string wml_tree_root;
247 
248  for(const config& core : cores_cfg.child_range("core")) {
249  const std::string& id = core["id"];
250  if(id.empty()) {
253  _("Error validating data core."),
254  _("Found a core without id attribute.")
255  + '\n' + _("Skipping the core."));
256  });
257  continue;
258  }
259 
260  if(*&valid_cores.find_child("core", "id", id)) {
263  _("Error validating data core."),
264  _("Core ID: ") + id
265  + '\n' + _("The ID is already in use.")
266  + '\n' + _("Skipping the core."));
267  });
268  continue;
269  }
270 
271  const std::string& path = core["path"];
275  _("Error validating data core."),
276  _("Core ID: ") + id
277  + '\n' + _("Core Path: ") + path
278  + '\n' + _("File not found.")
279  + '\n' + _("Skipping the core."));
280  });
281  continue;
282  }
283 
284  if(id == "default" && !current_core_valid) {
285  wml_tree_root = path;
286  }
287  if(id == preferences::core_id()) {
288  current_core_valid = true;
289  wml_tree_root = path;
290  }
291 
292  valid_cores.add_child("core", core); // append(core);
293  }
294 
295  if(!current_core_valid) {
298  _("Error loading core data."),
299  _("Core ID: ") + preferences::core_id()
300  + '\n' + _("Error loading the core with named id.")
301  + '\n' + _("Falling back to the default core."));
302  });
303  preferences::set_core_id("default");
304  }
305 
306  // check if we have a valid default core which should always be the case.
307  if(wml_tree_root.empty()) {
310  _("Error loading core data."),
311  _("Can't locate the default core.")
312  + '\n' + _("The game will now exit."));
313  });
314  throw;
315  }
316 
317  // Load the selected core
318  std::unique_ptr<schema_validation::schema_validator> validator;
320  validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/game_config.cfg")));
321  validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
322  }
323 
324  cache_.get_config(filesystem::get_wml_location(wml_tree_root), game_config_, validator.get());
325  game_config_.append(valid_cores);
326 
327  main_transaction.lock();
328 
330  load_addons_cfg();
331  }
332  }
333 
334  if(active_addons_) {
336  } else {
338  }
339 
340  // Extract the Lua scripts at toplevel.
342 
343  set_unit_data();
345  tdata_ = std::make_shared<terrain_type_data>(game_config());
348 
350 
352 
353  } catch(const game::error& e) {
354  ERR_CONFIG << "Error loading game configuration files\n" << e.message << '\n';
355 
356  // Try reloading without add-ons
358  game_config::no_addons = true;
361  _("Error loading custom game configuration files. The game will try without loading add-ons."),
362  e.message);
363  });
364  load_game_config(reload_everything);
365  } else if(preferences::core_id() != "default") {
368  _("Error loading custom game configuration files. The game will fallback to the default core files."),
369  e.message);
370  });
371  preferences::set_core_id("default");
372  game_config::no_addons = false;
373  load_game_config(reload_everything);
374  } else {
377  _("Error loading default core game configuration files. The game will now exit."),
378  e.message);
379  });
380  throw;
381  }
382  }
383 
385 
386  // Set new binary paths.
388 }
389 
391 {
392  const std::string user_campaign_dir = filesystem::get_addons_dir();
393 
394  std::vector<std::string> error_log;
395  std::vector<std::string> error_addons;
396  std::vector<std::string> user_dirs;
397  std::vector<std::string> user_files;
398 
399  filesystem::get_files_in_dir(user_campaign_dir, &user_files, &user_dirs, filesystem::name_mode::ENTIRE_FILE_PATH);
400 
401  // Warn player about addons using the no-longer-supported single-file format.
402  for(const std::string& file : user_files) {
403  const int size_minus_extension = file.size() - 4;
404 
405  if(file.substr(size_minus_extension, file.size()) == ".cfg") {
406  ERR_CONFIG << "error reading usermade add-on '" << file << "'\n";
407 
408  error_addons.push_back(file);
409 
410  const int userdata_loc = file.find("data/add-ons") + 5;
411  const std::string log_msg = formatter()
412  << "The format '~"
413  << file.substr(userdata_loc)
414  << "' (for single-file add-ons) is not supported anymore, use '~"
415  << file.substr(userdata_loc, size_minus_extension - userdata_loc)
416  << "/_main.cfg' instead.";
417 
418  error_log.push_back(log_msg);
419  }
420  }
421 
422  // Rerun the directory scan using filename only, to get the addon_ids more easily.
423  user_files.clear();
424  user_dirs.clear();
425 
426  filesystem::get_files_in_dir(user_campaign_dir, nullptr, &user_dirs,
428 
429  // Load the addons.
430  for(const std::string& addon_id : user_dirs) {
431  log_scope2(log_config, "Loading add-on '" + addon_id + "'");
432  const std::string addon_dir = user_campaign_dir + "/" + addon_id;
433 
434  const std::string main_cfg = addon_dir + "/_main.cfg";
435  const std::string info_cfg = addon_dir + "/_info.cfg";
436 
437  if(!filesystem::file_exists(main_cfg)) {
438  continue;
439  }
440 
441  // Try to find this addon's metadata. Author publishing info (_server.pbl) is given
442  // precedence over addon sever-generated info (_info.cfg). If neither are found, it
443  // probably means the addon was installed manually and certain defaults will be used.
444  config metadata;
445 
446  if(have_addon_pbl_info(addon_id)) {
447  // Publishing info needs to be read from disk.
448  try {
449  metadata = get_addon_pbl_info(addon_id);
450  } catch(const invalid_pbl_exception& e) {
451  const std::string log_msg = formatter()
452  << "The provided addon has an invalid pbl file"
453  << " for addon "
454  << addon_id;
455 
456  error_addons.push_back(e.message);
457  error_log.push_back(log_msg);
458  }
459  } else if(filesystem::file_exists(info_cfg)) {
460  // Addon server-generated info can be fetched from cache.
461  config temp;
462  cache_.get_config(info_cfg, temp);
463 
464  metadata = temp.child_or_empty("info");
465  }
466 
467  std::string using_core = metadata["core"];
468  if(using_core.empty()) {
469  using_core = "default";
470  }
471 
472  // Skip add-ons not matching our current core. Cores themselves should be selectable
473  // at all times, so they aren't considered here.
474  if(!metadata.empty() && metadata["type"] != "core" && using_core != preferences::core_id()) {
475  continue;
476  }
477 
478  std::string addon_title = metadata["title"].str();
479  if(addon_title.empty()) {
480  addon_title = addon_id;
481  }
482 
483  version_info addon_version(metadata["version"]);
484 
485  try {
486  std::unique_ptr<schema_validation::schema_validator> validator;
488  validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/game_config.cfg")));
489  validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
490  }
491 
492  // Load this addon from the cache to a config.
493  config umc_cfg;
494  cache_.get_config(main_cfg, umc_cfg, validator.get());
495 
496  static const std::set<std::string> tags_with_addon_id {
497  "era",
498  "modification",
499  "resource",
500  "multiplayer",
501  "scenario",
502  "campaign",
503  "test"
504  };
505 
506  // Annotate appropriate addon types with addon_id info.
507  for(auto child : umc_cfg.all_children_range()) {
508  if(tags_with_addon_id.count(child.key) > 0) {
509  auto& cfg = child.cfg;
510  cfg["addon_id"] = addon_id;
511  cfg["addon_title"] = addon_title;
512  // Note that this may reformat the string in a canonical form.
513  cfg["addon_version"] = addon_version.str();
514  }
515  }
516 
517  config advancefroms;
518  for(auto& units : umc_cfg.child_range("units")) {
519  for(auto& unit_type : units.child_range("unit_type")) {
520  for(const auto& advancefrom : units.child_range("advancefrom")) {
521  config modify_unit_type {
522  "type", unit_type["id"],
523  "add_advancement", advancefrom["unit"],
524  "set_experience", advancefrom["experience"]
525  };
527  "[advancefrom]",
529  {1, 17, 0},
530  _("Use [modify_unit_type]\n") + modify_unit_type.debug() + "\n [/modify_unit_type] instead in [campaign]"
531  );
532 
533  advancefroms.add_child("modify_unit_type", modify_unit_type);
534  }
535  unit_type.remove_children("advancefrom", [](const config&){return true;});
536  }
537  }
538 
539  // hardcoded list of 1.14 advancement macros, just used for the error mesage below.
540  static const std::set<std::string> deprecated_defines {
541  "ENABLE_PARAGON",
542  "DISABLE_GRAND_MARSHAL",
543  "ENABLE_ARMAGEDDON_DRAKE",
544  "ENABLE_DWARVISH_ARCANISTER",
545  "ENABLE_DWARVISH_RUNESMITH",
546  "ENABLE_WOLF_ADVANCEMENT",
547  "ENABLE_NIGHTBLADE",
548  "ENABLE_TROLL_SHAMAN",
549  "ENABLE_ANCIENT_LICH",
550  "ENABLE_DEATH_KNIGHT",
551  "ENABLE_WOSE_SHAMAN"
552  };
553 
554  for(auto& campaign : umc_cfg.child_range("campaign")) {
555  campaign.append_children(std::move(advancefroms));
556 
557  for(auto str : utils::split(campaign["extra_defines"])) {
558  if(deprecated_defines.count(str) > 0) {
559  //TODO: we could try to implement a compatibility path by
560  // somehow getting the content of that macro from the
561  // cache_ object, but considering that 1) the breakage
562  // isn't that bad (just one disabled unit) and 2)
563  // it before also didn't work in all cases (see #4402)
564  // i don't think it is worth it.
566  "extra_defines=" + str,
568  {1, 15, 4},
569  _("instead, use the macro with the same name in the [campaign] tag")
570  );
571  }
572  }
573  }
574 
575  static const std::set<std::string> entry_tags {
576  "era",
577  "modification",
578  "resource",
579  "multiplayer",
580  "scenario",
581  "campaign"
582  };
583 
584  for(const std::string& tagname : entry_tags) {
585  game_config_.append_children_by_move(umc_cfg, tagname);
586  }
587 
588  addon_cfgs_[addon_id] = std::move(umc_cfg);
589  } catch(const config::error& err) {
590  ERR_CONFIG << "error reading usermade add-on '" << main_cfg << "'" << std::endl;
591  ERR_CONFIG << err.message << '\n';
592  error_addons.push_back(main_cfg);
593  error_log.push_back(err.message);
594  } catch(const preproc_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 filesystem::io_exception&) {
600  ERR_CONFIG << "error reading usermade add-on '" << main_cfg << "'" << std::endl;
601  error_addons.push_back(main_cfg);
602  }
603  }
604 
607  ERR_CONFIG << "Didn’t find an add-on for --validate-addon - check whether the id has a typo" << std::endl;
608  const std::string log_msg = formatter()
609  << "Didn't find an add-on for --validate-addon - check whether the id has a typo";
610  error_log.push_back(log_msg);
611  throw game::error("Did not find an add-on for --validate-addon");
612  }
613 
614  WRN_CONFIG << "Note: for --validate-addon to find errors, you have to play (in the GUI) a game that uses the add-on.";
615  }
616 
617  if(!error_addons.empty()) {
618  const std::size_t n = error_addons.size();
619  const std::string& msg1 =
620  _n("The following add-on had errors and could not be loaded:",
621  "The following add-ons had errors and could not be loaded:",
622  n);
623  const std::string& msg2 =
624  _n("Please report this to the author or maintainer of this add-on.",
625  "Please report this to the respective authors or maintainers of these add-ons.",
626  n);
627 
628  const std::string& report = utils::join(error_log, "\n\n");
630  gui2::dialogs::wml_error::display(msg1, msg2, error_addons, report);
631  });
632  }
633 }
634 
636 {
637  config& hashes = game_config_.add_child("multiplayer_hashes");
638  for(const config& ch : game_config().child_range("multiplayer")) {
639  hashes[ch["id"].str()] = ch.hash();
640  }
641 }
642 
644 {
646  unit_types.set_config(game_config().merged_children_view("units"));
647 }
648 
650 {
651  // Rebuild addon version info cache.
653 
654  // Force a reload of configuration information.
656  old_defines_map_.clear();
659 
662 }
663 
665 {
668 }
669 
671  const game_classification& classification, const std::string& scenario_id)
672 {
673  game_config::scoped_preproc_define difficulty(classification.difficulty,
674  !classification.difficulty.empty());
675  game_config::scoped_preproc_define campaign(classification.campaign_define,
676  !classification.campaign_define.empty());
677  game_config::scoped_preproc_define scenario(classification.scenario_define,
678  !classification.scenario_define.empty());
680  !classification.era_define.empty());
681  game_config::scoped_preproc_define multiplayer("MULTIPLAYER",
682  classification.is_multiplayer());
684  classification.is_multiplayer());
685 
686  //
687  // NOTE: these deques aren't used here, but the objects within are utilized as RAII helpers.
688  //
689 
690  std::deque<game_config::scoped_preproc_define> extra_defines;
691  for(const std::string& extra_define : classification.campaign_xtra_defines) {
692  extra_defines.emplace_back(extra_define);
693  }
694 
695  std::deque<game_config::scoped_preproc_define> modification_defines;
696  for(const std::string& mod_define : classification.mod_defines) {
697  modification_defines.emplace_back(mod_define, !mod_define.empty());
698  }
699 
700  try {
701  load_game_config_with_loadscreen(NO_FORCE_RELOAD, &classification, classification.active_addons(scenario_id));
702  } catch(const game::error&) {
704 
705  std::deque<game_config::scoped_preproc_define> previous_defines;
706  for(const preproc_map::value_type& preproc : old_defines_map_) {
707  previous_defines.emplace_back(preproc.first);
708  }
709 
711  throw;
712  }
713 
714  // This needs to be done in the main thread since this function (load_game_config_for_game)
715  // might be called from a loading screen worker thread (and currently is, in fact). If the
716  // image cache is purged from the worker thread, there's a possibility for a data race where
717  // the main thread accesses the image cache and the worker thread simultaneously clears it.
719 }
720 
722 {
723  game_config::scoped_preproc_define multiplayer("MULTIPLAYER", is_mp);
724  game_config::scoped_preproc_define test("TEST", is_test);
725  game_config::scoped_preproc_define mptest("MP_TEST", cmdline_opts_.mptest && is_mp);
726  /** During an mp game the default difficulty define is also defined so better already load it now if we already must reload config cache. */
729 
730  try {
732  } catch(const game::error&) {
734 
735  std::deque<game_config::scoped_preproc_define> previous_defines;
736  for (const preproc_map::value_type& preproc : old_defines_map_) {
737  previous_defines.emplace_back(preproc.first);
738  }
739 
741  throw;
742  }
743 }
744 
745 void game_config_manager::set_enabled_addon(std::set<std::string> addon_ids)
746 {
747  auto& vec = game_config_view_.data();
748  vec.clear();
749  vec.push_back(game_config_);
750 
751  for(const std::string& id : addon_ids) {
752  auto it = addon_cfgs_.find(id);
753  if(it != addon_cfgs_.end()) {
754  vec.push_back(it->second);
755  }
756  }
757 }
758 
760 {
761  auto& vec = game_config_view_.data();
762  vec.clear();
763  vec.push_back(game_config_);
764 
765  for(const auto& pair : addon_cfgs_) {
766  vec.push_back(pair.second);
767  }
768 }
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:96
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:953
std::string era()
Definition: game.cpp:689
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:34
void append(const config &cfg)
Append data from another config object to this one.
Definition: config.cpp:281
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:306
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:860
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:88
Exception thrown when the WML parser fails to read a .pbl file.
Definition: manager.hpp:43
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:356
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:919
unit_type_data unit_types
Definition: types.cpp:1447
void set(const std::string &key, bool value)
Definition: general.cpp:178
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:356
static std::string _(const char *str)
Definition: gettext.hpp:92
void load_config(const config &v)
A single unit type that the player may recruit.
Definition: types.hpp:44
Used to set and unset scoped defines to preproc_map.
void call_in_main_thread(const std::function< void(void)> &f)
Definition: events.cpp:866
void flush_cache()
Purges all image caches.
Definition: picture.cpp:221
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:114
std::string get(const std::string &key)
Definition: general.cpp:226
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:29
void load_hotkeys()
Definition: general.cpp:879
std::optional< std::set< std::string > > active_addons_
std::ostringstream wrapper.
Definition: formatter.hpp:38
bool clean_cache()
Deletes stale cache files not in use by the game.
const std::string message
Error message to display.
Definition: manager.hpp:59
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)
Populates &#39;files&#39; with all the files and &#39;dirs&#39; with all the directories in dir.
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:323
static game_config_manager * singleton
std::string path
Definition: game_config.cpp:38
#define log_scope2(domain, description)
Definition: log.hpp:207
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:355
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:379
log_domain & general()
Definition: log.cpp:102
config get_addon_pbl_info(const std::string &addon_name)
Gets the publish information for an add-on.
Definition: manager.cpp:67
std::string era_define
If there is a define the era uses to customize data.
void flush_cache()
Definition: sound.cpp:194
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:219
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:76
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:62
void load_game_config_for_create(bool is_mp, bool is_test=false)
Game configuration data as global variables.
Definition: build_info.cpp:58
const preproc_map & get_preproc_map() const
An exception object used when an IO error occurs.
Definition: filesystem.hpp:45
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:52
Represents version numbers.
config & add_child(config_key_type key)
Definition: config.cpp:500
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:317
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:1062
std::vector< std::string > split(const config_attribute_value &val)
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:27
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:29
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:477
#define WRN_CONFIG
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:59
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:291
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:1367
config_array_view & data()
void init_advanced_manager(const game_config_view &gc)
Initializes the manager singleton.
Definition: advanced.cpp:71
bool empty() const
Definition: config.cpp:916
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.