Have mainline content send [multiplayer][addon] info as well.

This commit:
* sends the era and scenario as part of a [multiplayer][addon] in order to make it consistent with how add-ons' information is sent to wesnothd. this means all of the game's content information is now available in the [multiplayer][addon] data.
* correctly covers the case of there potentially being modifications added to mainline at some point. the current code looks at the [multiplayer]mp_scenario= and [multiplayer]mp_era attributes to cover the case of a mainline era/scenario being used, but looks for modifications only in the [multiplayer][addon] data, which wouldn't have any entry for a mainline modification right now if one were added.
This commit is contained in:
Pentarctagon 2020-08-09 12:52:07 -05:00 committed by Pentarctagon
parent 4a640274c5
commit 5a77a86330
3 changed files with 34 additions and 34 deletions

View file

@ -296,47 +296,43 @@ void saved_game::expand_scenario()
void saved_game::check_require_scenario()
{
if(starting_point_["addon_id"].empty()) {
return;
}
config required_scenario;
required_scenario["id"] = starting_point_["addon_id"];
required_scenario["name"] = starting_point_["addon_title"];
required_scenario["version"] = starting_point_["addon_version"];
required_scenario["min_version"] = starting_point_["addon_min_version"];
required_scenario["required"] = starting_point_["require_scenario"].to_bool(false);
config& content = required_scenario.add_child("content");
const std::string version_default = starting_point_["addon_id"].empty() ? game_config::wesnoth_version.str() : "";
config scenario;
scenario["id"] = starting_point_["addon_id"].str("mainline");
scenario["name"] = starting_point_["addon_title"].str("mainline");
scenario["version"] = starting_point_["addon_version"].str(version_default);
scenario["min_version"] = starting_point_["addon_min_version"];
scenario["required"] = starting_point_["require_scenario"].to_bool(false);
config& content = scenario.add_child("content");
content["id"] = starting_point_["id"];
content["type"] = "scenario";
mp_settings_.update_addon_requirements(required_scenario);
mp_settings_.update_addon_requirements(scenario);
}
void saved_game::load_mod(const std::string& type, const std::string& id, size_t pos)
// "non scenario" at the time of writing this meaning any era, campaign, mods, or resources (see expand_mp_events() below).
void saved_game::load_non_scenario(const std::string& type, const std::string& id, size_t pos)
{
if(const config& cfg = game_config_manager::get()->game_config().find_child(type, "id", id)) {
// Note the addon_id if this mod is required to play the game in mp.
std::string require_attr = "require_" + type;
// By default, eras have "require_era = true", and mods have "require_modification = false".
bool require_default = (type == "era");
// anything with no addon_id is from mainline, and therefore isn't required in the sense that all players already have it
const bool require_default = cfg["addon_id"].empty() ? false : type == "era";
const std::string version_default = cfg["addon_id"].empty() ? game_config::wesnoth_version.str() : "";
config non_scenario;
// if there's no addon_id, then this isn't an add-on
non_scenario["id"] = cfg["addon_id"].str("mainline");
non_scenario["name"] = cfg["addon_title"].str("mainline");
non_scenario["version"] = cfg["addon_version"].str(version_default);
non_scenario["min_version"] = cfg["addon_min_version"];
non_scenario["required"] = cfg[require_attr].to_bool(require_default);
config& content = non_scenario.add_child("content");
content["id"] = id;
content["type"] = type;
if(!cfg["addon_id"].empty()) {
config required_mod;
required_mod["id"] = cfg["addon_id"];
required_mod["name"] = cfg["addon_title"];
required_mod["version"] = cfg["addon_version"];
required_mod["min_version"] = cfg["addon_min_version"];
required_mod["required"] = cfg[require_attr].to_bool(require_default);
config& content = required_mod.add_child("content");
content["id"] = id;
content["type"] = type;
mp_settings_.update_addon_requirements(required_mod);
}
mp_settings_.update_addon_requirements(non_scenario);
// Copy events
for(const config& modevent : cfg.child_range("event")) {
@ -393,7 +389,7 @@ void saved_game::expand_mp_events()
}
for(modevents_entry& mod : mods) {
load_mod(mod.type, mod.id, starting_point_.all_children_count());
load_non_scenario(mod.type, mod.id, starting_point_.all_children_count());
}
mods.clear();
@ -404,7 +400,7 @@ void saved_game::expand_mp_events()
starting_point_.remove_child("load_resource", 0);
if(loaded_resources.find(id) == loaded_resources.end()) {
loaded_resources.insert(id);
load_mod("resource", id, pos);
load_non_scenario("resource", id, pos);
}
}
this->starting_point_["has_mod_events"] = true;

View file

@ -72,7 +72,7 @@ public:
/// should be called after expand_scenario() but before expand_carryover()
void expand_mp_events();
/// helper for expand_mp_events();
void load_mod(const std::string& type, const std::string& id, size_t pos);
void load_non_scenario(const std::string& type, const std::string& id, size_t pos);
/// adds values of [option]s into [carryover_sides_start][variables] so that they are applied in the next level.
/// Note that since [variabels] are persistent we only use this once at the beginning
/// of a campaign but calling it multiple times is no harm eigher

View file

@ -1632,21 +1632,25 @@ void server::handle_player_in_game(socket_ptr socket, std::shared_ptr<simple_wml
if(user_handler_) {
const simple_wml::node& m = *g.level().root().child("multiplayer");
DBG_SERVER << simple_wml::node_to_string(m) << '\n';
// [addon] info handling
std::string scenario_addon_id = "";
std::string scenario_addon_version = "";
std::string scenario_id = "";
std::string era_addon_id = "";
std::string era_addon_version = "";
std::string era_id = "";
for(const auto& addon : m.children("addon")) {
for(const auto& content : addon->children("content")) {
const simple_wml::string_span& type = content->attr("type");
if(type == "scenario") {
scenario_addon_id = addon->attr("id").to_string();
scenario_addon_version = addon->attr("version").to_string();
scenario_id = content->attr("id").to_string();
} else if(type == "era") {
era_addon_id = addon->attr("id").to_string();
era_addon_version = addon->attr("version").to_string();
era_id = content->attr("id").to_string();
} else if(type == "modification") {
user_handler_->db_insert_modification_info(uuid_, g.db_id(), content->attr("id").to_string(), addon->attr("id").to_string(), addon->attr("version").to_string());
} else {
@ -1655,7 +1659,7 @@ void server::handle_player_in_game(socket_ptr socket, std::shared_ptr<simple_wml
}
}
user_handler_->db_insert_game_info(uuid_, g.db_id(), game_config::wesnoth_version.str(), g.name(), m["mp_scenario"].to_string(), m["mp_era"].to_string(), g.is_reload(), m["observer"].to_bool(), !m["private_replay"].to_bool(), g.has_password(), scenario_addon_id, scenario_addon_version, era_addon_id, era_addon_version);
user_handler_->db_insert_game_info(uuid_, g.db_id(), game_config::wesnoth_version.str(), g.name(), scenario_id, era_id, g.is_reload(), m["observer"].to_bool(), !m["private_replay"].to_bool(), g.has_password(), scenario_addon_id, scenario_addon_version, era_addon_id, era_addon_version);
const simple_wml::node::child_list& sides = g.get_sides_list();
for(unsigned side_index = 0; side_index < sides.size(); ++side_index) {