The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
mp_game_utils.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2017 by Andrius Silinskas <silinskas.andrius@gmail.com>
3  Part of the Battle for Wesnoth Project http://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 */
15 
16 #include "config.hpp"
17 #include "formula/string_utils.hpp"
18 #include "game_config.hpp"
19 #include "game_config_manager.hpp"
20 #include "gettext.hpp"
21 #include "log.hpp"
22 #include "saved_game.hpp"
24 
25 static lg::log_domain log_engine("engine");
26 #define LOG_NG LOG_STREAM(info, log_engine)
27 #define ERR_NG LOG_STREAM(err, log_engine)
28 
29 static lg::log_domain log_config("config");
30 #define LOG_CF LOG_STREAM(info, log_config)
31 #define WRN_CF LOG_STREAM(warn, log_config)
32 #define ERR_CF LOG_STREAM(err, log_config)
33 
34 static lg::log_domain log_network("network");
35 #define LOG_NW LOG_STREAM(info, log_network)
36 #define ERR_NW LOG_STREAM(err, log_network)
37 
38 namespace mp
39 {
40 // This is for the wesnothd server, it expects a more detailed summary in [multiplayer]
41 static void add_multiplayer_classification(config& multiplayer, saved_game& state)
42 {
43  multiplayer["mp_scenario"] = state.get_scenario_id();
44  multiplayer["mp_scenario_name"] = state.get_starting_pos()["name"];
45  multiplayer["difficulty_define"] = state.classification().difficulty;
46  multiplayer["mp_campaign"] = state.classification().campaign;
47  multiplayer["mp_campaign_name"] = state.classification().campaign_name;
48 }
49 
51 {
52  const mp_game_settings& params = state.mp_settings();
53  state.set_defaults();
54 
55  // Also impliers state.expand_scenario()
56  // We need to call this before expand_mp_events/options otherwise they might be overwritten.
57  state.expand_random_scenario();
58  state.expand_mp_events();
59  state.expand_mp_options();
60 
61  if(!state.valid()) {
62  throw config::error("Failed to load the scenario");
63  }
64 
65  config& scenario = state.get_starting_pos();
66  if(!state.mp_settings().saved_game) {
67  state.set_random_seed();
68  }
69 
70  if(scenario["objectives"].empty()) {
71  // Generic victory objectives.
72  std::ostringstream ss;
73  ss << "<big>";
74  ss << t_string(N_("Victory:"), "wesnoth") << "</big>\n";
75  ss << "<span color='#00ff00'>" << font::unicode_bullet << " ";
76  ss << t_string(N_("Defeat enemy leader(s)"), "wesnoth") << "</span>";
77 
78  scenario["objectives"] = ss.str();
79  }
80 
81  config level = state.to_config();
82  add_multiplayer_classification(level.child_or_add("multiplayer"), state);
83 
84  // [multiplayer] mp_era= should be persistent over saves.
85  std::string era = params.mp_era;
86 
87  /**
88  * [era] and [modification]s are toplevel tags here.
89  * They are not part of the saved_game and are only used during mp_staging/mp_join_game.
90  *
91  * @todo: see if all the comments ai algorithms are still up-to-date and relevant.
92  *
93  * -- vultraz, 2017-11-24
94  */
95 
97  const config& era_cfg = game_config.find_child("era", "id", era);
98 
99  if(!era_cfg) {
100  if(!params.saved_game) {
101  throw config::error(vgettext("Cannot find era $era", {{"era", era}}));
102  }
103 
104  // FIXME: @todo We should tell user about missing era but still load game...
105  WRN_CF << "Missing era in MP load game " << era << std::endl;
106 
107  // Otherwise we get an error when when we try to add ai algorithms in mp_staging.
108  level.add_child("era");
109  } else {
110  level.add_child("era", era_cfg);
111 
112  // Initialize the list of sides available for the current era.
113  // We also need this so not to get a segfault in mp_staging for ai configuration.
114  const config& custom_side = game_config.find_child("multiplayer_side", "id", "Custom");
115  level.child("era").add_child_at("multiplayer_side", custom_side, 0);
116  }
117 
118  // Add modifications, needed for ai algorithms which are applied in mp_staging.
119  const std::vector<std::string>& mods = params.active_mods;
120 
121  for(unsigned i = 0; i < mods.size(); ++i) {
122  level.add_child("modification", game_config.find_child("modification", "id", mods[i]));
123  }
124 
125  // This will force connecting clients to be using the same version number as us.
126  level["version"] = game_config::version;
127  return level;
128 }
129 
131 {
132  game_classification::CAMPAIGN_TYPE type = state.classification().campaign_type;
133  state = saved_game(level);
134  state.classification().campaign_type = type;
135 }
136 
137 void check_response(bool res, const config& data)
138 {
139  if(!res) {
140  throw wesnothd_error(_("Connection timed out"));
141  }
142 
143  if(const config& err = data.child("error")) {
144  throw wesnothd_error(err["message"]);
145  }
146 }
147 
148 } // end namespace mp
An error occured during when trying to coommunicate with the wesnothd server.
config & child(config_key_type key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:400
std::vector< char_t > string
std::string era()
Definition: game.cpp:700
config to_config() const
Definition: saved_game.cpp:532
static lg::log_domain log_config("config")
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:763
void set_defaults()
does some post loading stuff must be used before passing the data to connect_engine ...
Definition: saved_game.cpp:178
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:39
config initial_level_config(saved_game &state)
void expand_random_scenario()
takes care of generate_map=, generate_scenario=, map= attributes This should be called before expandi...
Definition: saved_game.cpp:402
std::string campaign_name
The name of the campaign being played.
config & child_or_add(config_key_type key)
Definition: config.cpp:446
void level_to_gamestate(const config &level, saved_game &state)
Definitions for the interface to Wesnoth Markup Language (WML).
#define WRN_CF
Pubic entry points for the MP workflow.
Definition: lobby_data.cpp:48
std::vector< std::string > active_mods
static game_config_manager * get()
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:89
void set_random_seed()
sets the random seed if that didn't already happen.
Definition: saved_game.cpp:131
void expand_mp_options()
adds values of [option]s into [carryover_sides_start][variables] so that they are applied in the next...
Definition: saved_game.cpp:361
config & add_child_at(config_key_type key, const config &val, unsigned index)
Definition: config.cpp:488
void check_response(bool res, const config &data)
std::string campaign
The id of the campaign being played.
config & get_starting_pos()
Definition: saved_game.cpp:489
logger & err()
Definition: log.cpp:79
Game configuration data as global variables.
Definition: build_info.cpp:53
const config & game_config() const
std::string get_scenario_id()
Definition: saved_game.cpp:555
size_t i
Definition: function.cpp:933
void expand_mp_events()
adds [event]s from [era] and [modification] into this scenario does NOT expand [option]s because vari...
Definition: saved_game.cpp:317
#define N_(String)
Definition: gettext.hpp:97
const std::string unicode_bullet
Definition: constants.cpp:42
bool valid() const
Definition: saved_game.cpp:460
config & add_child(config_key_type key)
Definition: config.cpp:456
std::string difficulty
The difficulty level the game is being played on.
std::string vgettext(const char *msgid, const utils::string_map &symbols)
game_classification & classification()
Definition: saved_game.hpp:55
Standard logging facilities (interface).
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:93
mp_game_settings & mp_settings()
Multiplayer parameters for this game.
Definition: saved_game.hpp:59
static lg::log_domain log_network("network")
const std::string version
Definition: game_config.cpp:39
static lg::log_domain log_engine("engine")
static void add_multiplayer_classification(config &multiplayer, saved_game &state)