The Battle for Wesnoth  1.15.5+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  registered_users_only(false),
55  private_replay(false),
56  shuffle_sides(false),
57  saved_game(SAVED_GAME_MODE::NONE),
58  random_faction_mode(RANDOM_FACTION_MODE::DEFAULT),
59  options(),
60  addons()
61 {}
62 
64  : name(cfg["scenario"].str())
65  , password()
66  , hash(cfg["hash"].str())
67  , mp_era_name(cfg["mp_era_name"].str())
68  , mp_scenario(cfg["mp_scenario"].str())
69  , mp_scenario_name(cfg["mp_scenario_name"].str())
70  , mp_campaign(cfg["mp_campaign"].str())
71  , side_users(utils::map_split(cfg["side_users"]))
72  , num_turns(cfg["mp_num_turns"])
73  , village_gold(cfg["mp_village_gold"])
74  , village_support(cfg["mp_village_support"])
75  , xp_modifier(cfg["experience_modifier"].to_int(100))
76  , mp_countdown_init_time(cfg["mp_countdown_init_time"])
77  , mp_countdown_reservoir_time(cfg["mp_countdown_reservoir_time"])
78  , mp_countdown_turn_bonus(cfg["mp_countdown_turn_bonus"])
79  , mp_countdown_action_bonus(cfg["mp_countdown_action_bonus"])
80  , mp_countdown(cfg["mp_countdown"].to_bool())
81  , use_map_settings(cfg["mp_use_map_settings"].to_bool())
82  , random_start_time(cfg["mp_random_start_time"].to_bool())
83  , fog_game(cfg["mp_fog"].to_bool())
84  , shroud_game(cfg["mp_shroud"].to_bool())
85  , allow_observers(cfg["observer"].to_bool())
86  , registered_users_only(cfg["registered_users_only"].to_bool())
87  , private_replay(cfg["private_replay"].to_bool())
88  , shuffle_sides(cfg["shuffle_sides"].to_bool())
89  , saved_game(cfg["savegame"].to_enum<SAVED_GAME_MODE>(SAVED_GAME_MODE::NONE))
90  , random_faction_mode(cfg["random_faction_mode"].to_enum<RANDOM_FACTION_MODE>(RANDOM_FACTION_MODE::DEFAULT))
91  , options(cfg.child_or_empty("options"))
92  , addons()
93 {
94  for (const config & a : cfg.child_range("addon")) {
95  if (!a["id"].empty()) {
96  addons.emplace(a["id"].str(), addon_version_info(a));
97  }
98  }
99 }
100 
102 {
103  config cfg;
104 
105  cfg["scenario"] = name;
106  cfg["hash"] = hash;
107  cfg["mp_era_name"] = mp_era_name;
108  cfg["mp_scenario"] = mp_scenario;
109  cfg["mp_scenario_name"] = mp_scenario_name;
110  cfg["mp_campaign"] = mp_campaign;
111  cfg["side_users"] = utils::join_map(side_users);
112  cfg["experience_modifier"] = xp_modifier;
113  cfg["mp_countdown"] = mp_countdown;
114  cfg["mp_countdown_init_time"] = mp_countdown_init_time;
115  cfg["mp_countdown_turn_bonus"] = mp_countdown_turn_bonus;
116  cfg["mp_countdown_reservoir_time"] = mp_countdown_reservoir_time;
117  cfg["mp_countdown_action_bonus"] = mp_countdown_action_bonus;
118  cfg["mp_num_turns"] = num_turns;
119  cfg["mp_village_gold"] = village_gold;
120  cfg["mp_village_support"] = village_support;
121  cfg["mp_fog"] = fog_game;
122  cfg["mp_shroud"] = shroud_game;
123  cfg["mp_use_map_settings"] = use_map_settings;
124  cfg["mp_random_start_time"] = random_start_time;
125  cfg["observer"] = allow_observers;
126  cfg["registered_users_only"] = registered_users_only;
127  cfg["private_replay"] = private_replay;
128  cfg["shuffle_sides"] = shuffle_sides;
129  cfg["random_faction_mode"] = random_faction_mode;
130  cfg["savegame"] = saved_game;
131  cfg.add_child("options", options);
132 
133  for(auto& p : addons) {
134  config & c = cfg.add_child("addon");
135  p.second.write(c);
136  c["id"] = p.first;
137  }
138 
139  return cfg;
140 }
141 
143  : version()
144  , min_version()
145  , name(cfg["name"])
146  , required(cfg["required"].to_bool(false))
147  , content()
148 {
149  if (!cfg["version"].empty()) {
150  version = cfg["version"].str();
151  }
152  if (!cfg["min_version"].empty()) {
153  min_version = cfg["min_version"].str();
154  }
155  for(const auto& child : cfg.child_range("content")) {
156  content.emplace_back(addon_content{ child["id"].str(), child["type"].str() });
157  }
158 }
159 
161  if (version) {
162  cfg["version"] = *version;
163  }
164  if (min_version) {
165  cfg["min_version"] = *min_version;
166  }
167 
168  cfg["name"] = name;
169  cfg["require"] = required;
170  for(const auto& item : content) {
171  config& c = cfg.add_child("content");
172  c["id"] = item.id;
173  c["type"] = item.type;
174  }
175 }
176 
178  if (cfg["id"].empty()) {
179  WRN_NG << "Tried to add add-on metadata to a game, missing mandatory id field... skipping.\n" << cfg.debug() << "\n";
180  return;
181  }
182 
184 
186  // Check if this add-on already has an entry as a dependency for this scenario. If so, try to reconcile their version info,
187  // by taking the larger of the min versions. The version should be the same for all WML from the same add-on...
188  if (it != addons.end()) {
189  addon_version_info& addon = it->second;
190 
191  // an add-on can contain multiple types of content
192  // for example, an era and a scenario
193  for(const auto& item : new_data.content) {
194  addon.content.emplace_back(addon_content{ item.id, item.type });
195  }
196 
197  if(addon.version != new_data.version) {
198  ERR_NG << "Addon version data mismatch! Not all local WML has same version of the addon: '" << cfg["id"].str() << "'.\n";
199  }
200 
201  if(new_data.required) {
202  addon.required = true;
203 
204  if (new_data.min_version) {
205  if (!addon.min_version || (*new_data.min_version > *addon.min_version)) {
206  addon.min_version = *new_data.min_version;
207  }
208  }
209  }
210  } else {
211  // Didn't find this addon-id in the map, so make a new entry without setting the min_version.
212  if(!new_data.required) {
213  new_data.min_version = boost::none;
214  }
215  addons.emplace(cfg["id"].str(), new_data);
216  }
217 }
boost::optional< version_info > version
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:507
#define WRN_NG
int village_support
Definition: game_config.cpp:55
static lg::log_domain log_engine("engine")
int xp_modifier()
Definition: game.cpp:712
#define a
std::string mp_campaign
child_itors child_range(config_key_type key)
Definition: config.cpp:362
bool shuffle_sides()
Definition: game.cpp:497
boost::optional< version_info > min_version
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 str
Definition: statement.cpp:110
std::string mp_scenario_name
config to_config() const
const config & options()
Definition: game.cpp:592
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
bool registered_users_only()
Definition: game.cpp:487
int village_gold()
Definition: game.cpp:692
Default, unset return value.
Definition: retval.hpp:31
mock_party p
std::map< std::string, addon_version_info > addons
std::string password(const std::string &server, const std::string &login)
bool use_map_settings()
Definition: game.cpp:515
std::map< std::string, std::string > side_users
config & add_child(config_key_type key)
Definition: config.cpp:476
bool allow_observers()
Definition: game.cpp:477
Standard logging facilities (interface).
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
mock_char c
bool random_start_time()
Definition: game.cpp:552
#define ERR_NG
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
std::string debug() const
Definition: config.cpp:1290
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:384