The Battle for Wesnoth  1.15.12+dev
mp_game_settings.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2006 - 2018 by Joerg Hinrichs <joerg.hinrichs@alice-dsl.de>
3  wesnoth playlevel Copyright (C) 2003 by David White <dave@whitevine.net>
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 /**
17  * @file
18  * Container for multiplayer game-creation parameters.
19  */
20 
21 #include "log.hpp"
22 #include "mp_game_settings.hpp"
24 
25 static lg::log_domain log_engine("engine");
26 #define ERR_NG LOG_STREAM(err, log_engine)
27 #define WRN_NG LOG_STREAM(warn, log_engine)
28 #define LOG_NG LOG_STREAM(info, log_engine)
29 #define DBG_NG LOG_STREAM(debug, log_engine)
30 
32  name(),
33  password(),
34  hash(),
35  mp_era_name(),
36  mp_scenario(),
37  mp_scenario_name(),
38  mp_campaign(),
39  side_users(),
40  num_turns(0),
41  village_gold(0),
42  village_support(1),
43  xp_modifier(100),
44  mp_countdown_init_time(0),
45  mp_countdown_reservoir_time(0),
46  mp_countdown_turn_bonus(0),
47  mp_countdown_action_bonus(0),
48  mp_countdown(false),
49  use_map_settings(false),
50  random_start_time(false),
51  fog_game(false),
52  shroud_game(false),
53  allow_observers(true),
54  private_replay(false),
55  shuffle_sides(false),
56  saved_game(SAVED_GAME_MODE::NONE),
57  random_faction_mode(RANDOM_FACTION_MODE::DEFAULT),
58  options(),
59  addons()
60 {}
61 
63  : name(cfg["scenario"].str())
64  , password()
65  , hash(cfg["hash"].str())
66  , mp_era_name(cfg["mp_era_name"].str())
67  , mp_scenario(cfg["mp_scenario"].str())
68  , mp_scenario_name(cfg["mp_scenario_name"].str())
69  , mp_campaign(cfg["mp_campaign"].str())
70  , side_users(utils::map_split(cfg["side_users"]))
71  , num_turns(cfg["mp_num_turns"])
72  , village_gold(cfg["mp_village_gold"])
73  , village_support(cfg["mp_village_support"])
74  , xp_modifier(cfg["experience_modifier"].to_int(100))
75  , mp_countdown_init_time(cfg["mp_countdown_init_time"])
76  , mp_countdown_reservoir_time(cfg["mp_countdown_reservoir_time"])
77  , mp_countdown_turn_bonus(cfg["mp_countdown_turn_bonus"])
78  , mp_countdown_action_bonus(cfg["mp_countdown_action_bonus"])
79  , mp_countdown(cfg["mp_countdown"].to_bool())
80  , use_map_settings(cfg["mp_use_map_settings"].to_bool())
81  , random_start_time(cfg["mp_random_start_time"].to_bool())
82  , fog_game(cfg["mp_fog"].to_bool())
83  , shroud_game(cfg["mp_shroud"].to_bool())
84  , allow_observers(cfg["observer"].to_bool())
85  , private_replay(cfg["private_replay"].to_bool())
86  , shuffle_sides(cfg["shuffle_sides"].to_bool())
87  , saved_game(cfg["savegame"].to_enum<SAVED_GAME_MODE>(SAVED_GAME_MODE::NONE))
88  , random_faction_mode(cfg["random_faction_mode"].to_enum<RANDOM_FACTION_MODE>(RANDOM_FACTION_MODE::DEFAULT))
89  , options(cfg.child_or_empty("options"))
90  , addons()
91 {
92  for (const config & a : cfg.child_range("addon")) {
93  if (!a["id"].empty()) {
94  addons.emplace(a["id"].str(), addon_version_info(a));
95  }
96  }
97 }
98 
100 {
101  config cfg;
102 
103  cfg["scenario"] = name;
104  cfg["hash"] = hash;
105  cfg["mp_era_name"] = mp_era_name;
106  cfg["mp_scenario"] = mp_scenario;
107  cfg["mp_scenario_name"] = mp_scenario_name;
108  cfg["mp_campaign"] = mp_campaign;
109  cfg["side_users"] = utils::join_map(side_users);
110  cfg["experience_modifier"] = xp_modifier;
111  cfg["mp_countdown"] = mp_countdown;
112  cfg["mp_countdown_init_time"] = mp_countdown_init_time;
113  cfg["mp_countdown_turn_bonus"] = mp_countdown_turn_bonus;
114  cfg["mp_countdown_reservoir_time"] = mp_countdown_reservoir_time;
115  cfg["mp_countdown_action_bonus"] = mp_countdown_action_bonus;
116  cfg["mp_num_turns"] = num_turns;
117  cfg["mp_village_gold"] = village_gold;
118  cfg["mp_village_support"] = village_support;
119  cfg["mp_fog"] = fog_game;
120  cfg["mp_shroud"] = shroud_game;
121  cfg["mp_use_map_settings"] = use_map_settings;
122  cfg["mp_random_start_time"] = random_start_time;
123  cfg["observer"] = allow_observers;
124  cfg["private_replay"] = private_replay;
125  cfg["shuffle_sides"] = shuffle_sides;
126  cfg["random_faction_mode"] = random_faction_mode;
127  cfg["savegame"] = saved_game;
128  cfg.add_child("options", options);
129 
130  for(auto& p : addons) {
131  config & c = cfg.add_child("addon");
132  p.second.write(c);
133  c["id"] = p.first;
134  }
135 
136  return cfg;
137 }
138 
140  : version()
141  , min_version()
142  , name(cfg["name"])
143  , required(cfg["required"].to_bool(false))
144  , content()
145 {
146  if (!cfg["version"].empty()) {
147  version = cfg["version"].str();
148  }
149  if (!cfg["min_version"].empty()) {
150  min_version = cfg["min_version"].str();
151  }
152  for(const auto& child : cfg.child_range("content")) {
153  content.emplace_back(addon_content{ child["id"].str(), child["name"].str(), child["type"].str() });
154  }
155 }
156 
158  if (version) {
159  cfg["version"] = *version;
160  }
161  if (min_version) {
162  cfg["min_version"] = *min_version;
163  }
164 
165  cfg["name"] = name;
166  cfg["require"] = required;
167  for(const auto& item : content) {
168  config& c = cfg.add_child("content");
169  c["id"] = item.id;
170  c["name"] = item.name;
171  c["type"] = item.type;
172  }
173 }
174 
176  if (cfg["id"].empty()) {
177  WRN_NG << "Tried to add add-on metadata to a game, missing mandatory id field... skipping.\n" << cfg.debug() << "\n";
178  return;
179  }
180 
182 
184  // Check if this add-on already has an entry as a dependency for this scenario. If so, try to reconcile their version info,
185  // by taking the larger of the min versions. The version should be the same for all WML from the same add-on...
186  if (it != addons.end()) {
187  addon_version_info& addon = it->second;
188 
189  // an add-on can contain multiple types of content
190  // for example, an era and a scenario
191  for(const auto& item : new_data.content) {
192  addon.content.emplace_back(addon_content{ item.id, item.name, item.type });
193  }
194 
195  if(addon.version != new_data.version) {
196  ERR_NG << "Addon version data mismatch! Not all local WML has same version of the addon: '" << cfg["id"].str() << "'.\n";
197  }
198 
199  if(new_data.required) {
200  addon.required = true;
201 
202  if (new_data.min_version) {
203  if (!addon.min_version || (*new_data.min_version > *addon.min_version)) {
204  addon.min_version = *new_data.min_version;
205  }
206  }
207  }
208  } else {
209  // Didn't find this addon-id in the map, so make a new entry without setting the min_version.
210  if(!new_data.required) {
211  new_data.min_version.reset();
212  }
213  addons.emplace(cfg["id"].str(), new_data);
214  }
215 }
std::string mp_scenario
std::string join_map(const T &v, const std::string &major=",", const std::string &minor=":")
std::string random_faction_mode()
Definition: game.cpp:479
#define WRN_NG
int village_support
Definition: game_config.cpp:54
static lg::log_domain log_engine("engine")
int xp_modifier()
Definition: game.cpp:679
#define a
std::string mp_campaign
child_itors child_range(config_key_type key)
Definition: config.cpp:356
bool shuffle_sides()
Definition: game.cpp:469
std::string mp_era_name
std::map< std::string, std::string > map_split(const std::string &val, char major, char minor, int flags, const std::string &default_value)
Splits a string based on two separators into a map.
std::string mp_scenario_name
config to_config() const
const config & options()
Definition: game.cpp:563
void update_addon_requirements(const config &addon_cfg)
Takes a config with addon metadata (id, name, version, min_version) and adds it as a requirement for ...
std::vector< addon_content > content
int village_gold()
Definition: game.cpp:659
std::optional< version_info > version
Default, unset return value.
Definition: retval.hpp:31
mock_party p
std::map< std::string, addon_version_info > addons
the key is the addon_id
std::string password(const std::string &server, const std::string &login)
bool use_map_settings()
Definition: game.cpp:489
std::map< std::string, std::string > side_users
config & add_child(config_key_type key)
Definition: config.cpp:500
bool allow_observers()
Definition: game.cpp:459
Standard logging facilities (interface).
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:59
mock_char c
bool random_start_time()
Definition: game.cpp:523
#define ERR_NG
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
std::string debug() const
Definition: config.cpp:1322
std::optional< version_info > min_version
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:409