The Battle for Wesnoth  1.15.5+dev
mp_game_utils.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 */
15 
16 #include "config.hpp"
17 #include "formula/string_utils.hpp"
18 #include "game_config_manager.hpp"
19 #include "gettext.hpp"
20 #include "log.hpp"
21 #include "saved_game.hpp"
22 #include "game_version.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_point()["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  multiplayer["mp_era"] = state.classification().era_id;
49  multiplayer["active_mods"] = utils::join(state.classification().active_mods, ",");
50 
51 }
52 
54 {
55  const mp_game_settings& params = state.mp_settings();
56  state.set_defaults();
57 
58  // Also impliers state.expand_scenario()
59  // We need to call this before expand_mp_events/options otherwise they might be overwritten.
60  state.expand_random_scenario();
61  state.expand_mp_events();
62  state.expand_mp_options();
63 
64  if(!state.valid()) {
65  throw config::error("Failed to load the scenario");
66  }
67 
68  config& scenario = state.get_starting_point();
69  if(state.mp_settings().saved_game == mp_game_settings::SAVED_GAME_MODE::NONE) {
70  state.set_random_seed();
71  }
72 
73  if(scenario["objectives"].empty()) {
74  // Generic victory objectives.
75  std::ostringstream ss;
76  ss << "<big>";
77  ss << t_string(N_("Victory:"), "wesnoth") << "</big>\n";
78  ss << "<span color='#00ff00'>" << font::unicode_bullet << " ";
79  ss << t_string(N_("Defeat enemy leader(s)"), "wesnoth") << "</span>";
80 
81  scenario["objectives"] = ss.str();
82  }
83 
84  config level = state.to_config();
85  add_multiplayer_classification(level.child_or_add("multiplayer"), state);
86 
87  // [multiplayer] mp_era= should be persistent over saves.
89 
90  /**
91  * [era] and [modification]s are toplevel tags here.
92  * They are not part of the saved_game and are only used during mp_staging/mp_join_game.
93  *
94  * @todo: see if all the comments ai algorithms are still up-to-date and relevant.
95  *
96  * -- vultraz, 2017-11-24
97  */
98 
100  const config& era_cfg = game_config.find_child("era", "id", era);
101 
102  if(!era_cfg) {
103  if(params.saved_game == mp_game_settings::SAVED_GAME_MODE::NONE) {
104  throw config::error(VGETTEXT("Cannot find era $era", {{"era", era}}));
105  }
106 
107  // FIXME: @todo We should tell user about missing era but still load game...
108  WRN_CF << "Missing era in MP load game " << era << std::endl;
109 
110  } else {
111  level.add_child("era", era_cfg);
112 
113  // Initialize the list of sides available for the current era.
114  // We also need this so not to get a segfault in mp_staging for ai configuration.
115  const config& custom_side = game_config.find_child("multiplayer_side", "id", "Custom");
116  level.child("era").add_child_at("multiplayer_side", custom_side, 0);
117  }
118 
119  // Add modifications, needed for ai algorithms which are applied in mp_staging.
120  const std::vector<std::string>& mods = state.classification().active_mods;
121 
122  for(unsigned i = 0; i < mods.size(); ++i) {
123  if(const config& mod_cfg = game_config.find_child("modification", "id", mods[i])) {
124  level.add_child("modification", mod_cfg);
125  }
126  }
127 
128  // This will force connecting clients to be using the same version number as us.
129  level["version"] = game_config::wesnoth_version.str();
130  return level;
131 }
132 
134 {
135  game_classification::CAMPAIGN_TYPE type = state.classification().campaign_type;
136  state = saved_game(level);
137  state.classification().campaign_type = type;
138 }
139 
140 void check_response(bool res, const config& data)
141 {
142  if(!res) {
143  throw wesnothd_error(_("Connection timed out"));
144  }
145 
146  if(const config& err = data.child("error")) {
147  throw wesnothd_error(err["message"]);
148  }
149 }
150 
151 } // end namespace mp
An error occurred 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:420
std::string era()
Definition: game.cpp:722
Interfaces for manipulating version numbers of engine, add-ons, etc.
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
static lg::log_domain log_config("config")
void set_defaults()
does some post loading stuff must be used before passing the data to connect_engine ...
Definition: saved_game.cpp:216
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:477
std::string campaign_name
The name of the campaign being played.
bool valid() const
Definition: saved_game.cpp:554
config & child_or_add(config_key_type key)
Definition: config.cpp:466
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:51
static game_config_manager * get()
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:100
void set_random_seed()
sets the random seed if that didn&#39;t already happen.
Definition: saved_game.cpp:167
std::vector< std::string > active_mods
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:411
config & add_child_at(config_key_type key, const config &val, unsigned index)
Definition: config.cpp:508
const game_config_view & game_config() const
config & get_starting_point()
Definition: saved_game.cpp:583
void check_response(bool res, const config &data)
std::string campaign
The id of the campaign being played.
std::size_t i
Definition: function.cpp:933
logger & err()
Definition: log.cpp:78
Default, unset return value.
Definition: retval.hpp:31
Game configuration data as global variables.
Definition: build_info.cpp:55
std::string get_scenario_id()
Definition: saved_game.cpp:649
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:370
#define N_(String)
Definition: gettext.hpp:108
const std::string unicode_bullet
Definition: constants.cpp:43
#define VGETTEXT(msgid,...)
Handy wrappers around interpolate_variables_into_string and gettext.
const version_info wesnoth_version(VERSION)
config & add_child(config_key_type key)
Definition: config.cpp:476
const config & find_child(config_key_type key, const std::string &name, const std::string &value) const
std::string difficulty
The difficulty level the game is being played on.
game_classification & classification()
Definition: saved_game.hpp:55
Standard logging facilities (interface).
std::string str() const
Serializes the version number into string form.
config to_config() const
Definition: saved_game.cpp:626
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
mp_game_settings & mp_settings()
Multiplayer parameters for this game.
Definition: saved_game.hpp:59
static lg::log_domain log_network("network")
static lg::log_domain log_engine("engine")
static void add_multiplayer_classification(config &multiplayer, saved_game &state)
auto * ss
Definition: result_set.cpp:281