From c9b3ab02f97e2d7a28dcc6a1688b6af000eabd01 Mon Sep 17 00:00:00 2001 From: Matthew Lam Date: Fri, 3 Jun 2022 07:32:49 -0400 Subject: [PATCH] Stream-based compression/decompression Add compression option to message creation functions. Based on #3870. --- network/Message.cpp | 1071 ++++++++++++++++++++++++++----------------- network/Message.h | 89 ++-- 2 files changed, 704 insertions(+), 456 deletions(-) diff --git a/network/Message.cpp b/network/Message.cpp index 6ec9daabc..796f699e5 100644 --- a/network/Message.cpp +++ b/network/Message.cpp @@ -4,6 +4,7 @@ #include "../Empire/EmpireManager.h" #include "../Empire/Supply.h" #include "../Empire/Diplomacy.h" +#include "../util/base64_filter.h" #include "../util/Logger.h" #include "../util/ModeratorAction.h" #include "../util/SaveGamePreviewUtils.h" @@ -17,6 +18,8 @@ #include "../util/Version.h" #include #include +#include +#include #include #include #include @@ -119,10 +122,19 @@ void HeaderToBuffer(const Message& message, Message::HeaderBuffer& buffer) { //////////////////////////////////////////////// // Message named ctors //////////////////////////////////////////////// -Message ErrorMessage(const std::string& problem, bool fatal, int player_id) { +Message ErrorMessage(const std::string& problem, bool fatal, int player_id, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(problem) << BOOST_SERIALIZATION_NVP(fatal) << BOOST_SERIALIZATION_NVP(player_id); @@ -130,23 +142,41 @@ Message ErrorMessage(const std::string& problem, bool fatal, int player_id) { return Message{Message::MessageType::ERROR_MSG, std::move(os).str()}; } -Message HostSPGameMessage(const SinglePlayerSetupData& setup_data) { +Message HostSPGameMessage(const SinglePlayerSetupData& setup_data, bool use_compression) { std::ostringstream os; { std::string client_version_string = FreeOrionVersionString(); - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(setup_data) << BOOST_SERIALIZATION_NVP(client_version_string); } return Message{Message::MessageType::HOST_SP_GAME, std::move(os).str()}; } -Message HostMPGameMessage(const std::string& host_player_name) +Message HostMPGameMessage(const std::string& host_player_name, bool use_compression) { std::ostringstream os; { std::string client_version_string = FreeOrionVersionString(); - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(host_player_name) << BOOST_SERIALIZATION_NVP(client_version_string); } @@ -156,10 +186,19 @@ Message HostMPGameMessage(const std::string& host_player_name) Message JoinGameMessage(const std::string& player_name, Networking::ClientType client_type, const std::map& dependencies, - boost::uuids::uuid cookie) { + boost::uuids::uuid cookie, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); std::string client_version_string = FreeOrionVersionString(); oa << BOOST_SERIALIZATION_NVP(player_name) << BOOST_SERIALIZATION_NVP(client_type) @@ -179,43 +218,35 @@ Message GameStartMessage(bool single_player_game, int empire_id, CombatLogManager& combat_logs, const SupplyManager& supply, const std::map& players, GalaxySetupData galaxy_setup_data, - bool use_binary_serialization) + bool use_binary_serialization, + bool use_compression) { std::ostringstream os; { - if (use_binary_serialization) { - freeorion_bin_oarchive oa(os); - oa << BOOST_SERIALIZATION_NVP(single_player_game) - << BOOST_SERIALIZATION_NVP(empire_id) - << BOOST_SERIALIZATION_NVP(current_turn); - GlobalSerializationEncodingForEmpire() = empire_id; - oa << BOOST_SERIALIZATION_NVP(empires) - << BOOST_SERIALIZATION_NVP(species); - SerializeIncompleteLogs(oa, combat_logs, 1); - oa << BOOST_SERIALIZATION_NVP(supply); - Serialize(oa, universe); - bool loaded_game_data = false; - oa << BOOST_SERIALIZATION_NVP(players) - << BOOST_SERIALIZATION_NVP(loaded_game_data); - galaxy_setup_data.encoding_empire = empire_id; - oa << BOOST_SERIALIZATION_NVP(galaxy_setup_data); - } else { - freeorion_xml_oarchive oa(os); - oa << BOOST_SERIALIZATION_NVP(single_player_game) - << BOOST_SERIALIZATION_NVP(empire_id) - << BOOST_SERIALIZATION_NVP(current_turn); - GlobalSerializationEncodingForEmpire() = empire_id; - oa << BOOST_SERIALIZATION_NVP(empires) - << BOOST_SERIALIZATION_NVP(species); - SerializeIncompleteLogs(oa, combat_logs, 1); - oa << BOOST_SERIALIZATION_NVP(supply); - Serialize(oa, universe); - bool loaded_game_data = false; - oa << BOOST_SERIALIZATION_NVP(players) - << BOOST_SERIALIZATION_NVP(loaded_game_data); - galaxy_setup_data.encoding_empire = empire_id; - oa << BOOST_SERIALIZATION_NVP(galaxy_setup_data); - } + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); + oa << BOOST_SERIALIZATION_NVP(single_player_game) + << BOOST_SERIALIZATION_NVP(empire_id) + << BOOST_SERIALIZATION_NVP(current_turn); + GlobalSerializationEncodingForEmpire() = empire_id; + oa << BOOST_SERIALIZATION_NVP(empires) + << BOOST_SERIALIZATION_NVP(species); + SerializeIncompleteLogs(oa, combat_logs, 1); + oa << BOOST_SERIALIZATION_NVP(supply); + Serialize(oa, universe); + bool loaded_game_data = false; + oa << BOOST_SERIALIZATION_NVP(players) + << BOOST_SERIALIZATION_NVP(loaded_game_data); + galaxy_setup_data.encoding_empire = empire_id; + oa << BOOST_SERIALIZATION_NVP(galaxy_setup_data); } return Message{Message::MessageType::GAME_START, std::move(os).str()}; } @@ -227,64 +258,49 @@ Message GameStartMessage(bool single_player_game, int empire_id, const std::map& players, const OrderSet& orders, const SaveGameUIData* ui_data, GalaxySetupData galaxy_setup_data, - bool use_binary_serialization) + bool use_binary_serialization, + bool use_compression) { std::ostringstream os; { - if (use_binary_serialization) { - freeorion_bin_oarchive oa(os); - oa << BOOST_SERIALIZATION_NVP(single_player_game) - << BOOST_SERIALIZATION_NVP(empire_id) - << BOOST_SERIALIZATION_NVP(current_turn); - GlobalSerializationEncodingForEmpire() = empire_id; - oa << BOOST_SERIALIZATION_NVP(empires) - << BOOST_SERIALIZATION_NVP(species); - SerializeIncompleteLogs(oa, combat_logs, 1); - oa << BOOST_SERIALIZATION_NVP(supply); - Serialize(oa, universe); - bool loaded_game_data = true; - oa << BOOST_SERIALIZATION_NVP(players) - << BOOST_SERIALIZATION_NVP(loaded_game_data); - Serialize(oa, orders); - bool ui_data_available = (ui_data != nullptr); - oa << BOOST_SERIALIZATION_NVP(ui_data_available); - if (ui_data_available) + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); + oa << BOOST_SERIALIZATION_NVP(single_player_game) + << BOOST_SERIALIZATION_NVP(empire_id) + << BOOST_SERIALIZATION_NVP(current_turn); + GlobalSerializationEncodingForEmpire() = empire_id; + oa << BOOST_SERIALIZATION_NVP(empires) + << BOOST_SERIALIZATION_NVP(species); + SerializeIncompleteLogs(oa, combat_logs, 1); + oa << BOOST_SERIALIZATION_NVP(supply); + Serialize(oa, universe); + bool loaded_game_data = true; + oa << BOOST_SERIALIZATION_NVP(players) + << BOOST_SERIALIZATION_NVP(loaded_game_data); + Serialize(oa, orders); + bool ui_data_available = (ui_data != nullptr); + oa << BOOST_SERIALIZATION_NVP(ui_data_available); + if (ui_data_available) { + if (ui_data) { oa << boost::serialization::make_nvp("ui_data", *ui_data); - bool save_state_string_available = false; - oa << BOOST_SERIALIZATION_NVP(save_state_string_available); - galaxy_setup_data.encoding_empire = empire_id; - oa << BOOST_SERIALIZATION_NVP(galaxy_setup_data); - } else { - freeorion_xml_oarchive oa(os); - oa << BOOST_SERIALIZATION_NVP(single_player_game) - << BOOST_SERIALIZATION_NVP(empire_id) - << BOOST_SERIALIZATION_NVP(current_turn); - GlobalSerializationEncodingForEmpire() = empire_id; - oa << BOOST_SERIALIZATION_NVP(empires) - << BOOST_SERIALIZATION_NVP(species); - SerializeIncompleteLogs(oa, combat_logs, 1); - oa << BOOST_SERIALIZATION_NVP(supply); - Serialize(oa, universe); - bool loaded_game_data = true; - oa << BOOST_SERIALIZATION_NVP(players) - << BOOST_SERIALIZATION_NVP(loaded_game_data); - Serialize(oa, orders); - bool ui_data_available = (ui_data != nullptr); - oa << BOOST_SERIALIZATION_NVP(ui_data_available); - if (ui_data_available) { - if (ui_data) { - oa << boost::serialization::make_nvp("ui_data", *ui_data); - } else { - ErrorLogger() << "GameStartMessage expected UI data but it was nullptr"; - SaveGameUIData temp_UI_data; - oa << boost::serialization::make_nvp("ui_data", temp_UI_data); - } + } else { + ErrorLogger() << "GameStartMessage expected UI data but it was nullptr"; + SaveGameUIData temp_UI_data; + oa << boost::serialization::make_nvp("ui_data", temp_UI_data); } - bool save_state_string_available = false; - oa << BOOST_SERIALIZATION_NVP(save_state_string_available); - galaxy_setup_data.encoding_empire = empire_id; - oa << BOOST_SERIALIZATION_NVP(galaxy_setup_data); } + bool save_state_string_available = false; + oa << BOOST_SERIALIZATION_NVP(save_state_string_available); + galaxy_setup_data.encoding_empire = empire_id; + oa << BOOST_SERIALIZATION_NVP(galaxy_setup_data); } return Message{Message::MessageType::GAME_START, std::move(os).str()}; } @@ -296,64 +312,49 @@ Message GameStartMessage(bool single_player_game, int empire_id, const std::map& players, const OrderSet& orders, const std::string* save_state_string, GalaxySetupData galaxy_setup_data, - bool use_binary_serialization) + bool use_binary_serialization, + bool use_compression) { std::ostringstream os; { - if (use_binary_serialization) { - freeorion_bin_oarchive oa(os); - oa << BOOST_SERIALIZATION_NVP(single_player_game) - << BOOST_SERIALIZATION_NVP(empire_id) - << BOOST_SERIALIZATION_NVP(current_turn); - GlobalSerializationEncodingForEmpire() = empire_id; - oa << BOOST_SERIALIZATION_NVP(empires) - << BOOST_SERIALIZATION_NVP(species); - SerializeIncompleteLogs(oa, combat_logs, 1); - oa << BOOST_SERIALIZATION_NVP(supply); - Serialize(oa, universe); - bool loaded_game_data = true; - oa << BOOST_SERIALIZATION_NVP(players) - << BOOST_SERIALIZATION_NVP(loaded_game_data); - Serialize(oa, orders); - bool ui_data_available = false; - oa << BOOST_SERIALIZATION_NVP(ui_data_available); - bool save_state_string_available = (save_state_string != nullptr); - oa << BOOST_SERIALIZATION_NVP(save_state_string_available); - if (save_state_string_available) + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); + oa << BOOST_SERIALIZATION_NVP(single_player_game) + << BOOST_SERIALIZATION_NVP(empire_id) + << BOOST_SERIALIZATION_NVP(current_turn); + GlobalSerializationEncodingForEmpire() = empire_id; + oa << BOOST_SERIALIZATION_NVP(empires) + << BOOST_SERIALIZATION_NVP(species); + SerializeIncompleteLogs(oa, combat_logs, 1); + oa << BOOST_SERIALIZATION_NVP(supply); + Serialize(oa, universe); + bool loaded_game_data = true; + oa << BOOST_SERIALIZATION_NVP(players) + << BOOST_SERIALIZATION_NVP(loaded_game_data); + Serialize(oa, orders); + bool ui_data_available = false; + oa << BOOST_SERIALIZATION_NVP(ui_data_available); + bool save_state_string_available = (save_state_string != nullptr); + oa << BOOST_SERIALIZATION_NVP(save_state_string_available); + if (save_state_string_available) { + if (save_state_string) { oa << boost::serialization::make_nvp("save_state_string", *save_state_string); - galaxy_setup_data.encoding_empire = empire_id; - oa << BOOST_SERIALIZATION_NVP(galaxy_setup_data); - } else { - freeorion_xml_oarchive oa(os); - oa << BOOST_SERIALIZATION_NVP(single_player_game) - << BOOST_SERIALIZATION_NVP(empire_id) - << BOOST_SERIALIZATION_NVP(current_turn); - GlobalSerializationEncodingForEmpire() = empire_id; - oa << BOOST_SERIALIZATION_NVP(empires) - << BOOST_SERIALIZATION_NVP(species); - SerializeIncompleteLogs(oa, combat_logs, 1); - oa << BOOST_SERIALIZATION_NVP(supply); - Serialize(oa, universe); - bool loaded_game_data = true; - oa << BOOST_SERIALIZATION_NVP(players) - << BOOST_SERIALIZATION_NVP(loaded_game_data); - Serialize(oa, orders); - bool ui_data_available = false; - oa << BOOST_SERIALIZATION_NVP(ui_data_available); - bool save_state_string_available = (save_state_string != nullptr); - oa << BOOST_SERIALIZATION_NVP(save_state_string_available); - if (save_state_string_available) { - if (save_state_string) { - oa << boost::serialization::make_nvp("save_state_string", *save_state_string); - } else { - ErrorLogger() << "GameStartMessage expectes save_state_string but it was nullptr"; - std::string temp_sss; - oa << boost::serialization::make_nvp("save_state_string", temp_sss); - } + } else { + ErrorLogger() << "GameStartMessage expectes save_state_string but it was nullptr"; + std::string temp_sss; + oa << boost::serialization::make_nvp("save_state_string", temp_sss); } - galaxy_setup_data.encoding_empire = empire_id; - oa << BOOST_SERIALIZATION_NVP(galaxy_setup_data); } + galaxy_setup_data.encoding_empire = empire_id; + oa << BOOST_SERIALIZATION_NVP(galaxy_setup_data); } return Message{Message::MessageType::GAME_START, std::move(os).str()}; } @@ -364,21 +365,39 @@ Message HostSPAckMessage(int player_id) Message HostMPAckMessage(int player_id) { return Message{Message::MessageType::HOST_MP_GAME, std::to_string(player_id)}; } -Message JoinAckMessage(int player_id, boost::uuids::uuid cookie) +Message JoinAckMessage(int player_id, boost::uuids::uuid cookie, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(player_id) << BOOST_SERIALIZATION_NVP(cookie); } return Message{Message::MessageType::JOIN_GAME, std::move(os).str()}; } -Message TurnOrdersMessage(const OrderSet& orders, const SaveGameUIData& ui_data) { +Message TurnOrdersMessage(const OrderSet& orders, const SaveGameUIData& ui_data, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); Serialize(oa, orders); bool ui_data_available = true; bool save_state_string_available = false; @@ -389,10 +408,19 @@ Message TurnOrdersMessage(const OrderSet& orders, const SaveGameUIData& ui_data) return Message{Message::MessageType::TURN_ORDERS, std::move(os).str()}; } -Message TurnOrdersMessage(const OrderSet& orders, const std::string& save_state_string) { +Message TurnOrdersMessage(const OrderSet& orders, const std::string& save_state_string, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); Serialize(oa, orders); bool ui_data_available = false; bool save_state_string_available = true; @@ -403,10 +431,19 @@ Message TurnOrdersMessage(const OrderSet& orders, const std::string& save_state_ return Message{Message::MessageType::TURN_ORDERS, std::move(os).str()}; } -Message TurnPartialOrdersMessage(const std::pair>& orders_updates) { +Message TurnPartialOrdersMessage(const std::pair>& orders_updates, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); Serialize(oa, orders_updates.first); oa << boost::serialization::make_nvp("deleted", orders_updates.second); } @@ -416,21 +453,40 @@ Message TurnPartialOrdersMessage(const std::pair>& order Message TurnTimeoutMessage(int timeout_remaining) { return Message{Message::MessageType::TURN_TIMEOUT, std::to_string(timeout_remaining)}; } -Message TurnProgressMessage(Message::TurnProgressPhase phase_id) { +Message TurnProgressMessage(Message::TurnProgressPhase phase_id, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(phase_id); } return Message{Message::MessageType::TURN_PROGRESS, std::move(os).str()}; } Message PlayerStatusMessage(Message::PlayerStatus player_status, - int about_empire_id) + int about_empire_id, + bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(player_status) << BOOST_SERIALIZATION_NVP(about_empire_id); } @@ -442,48 +498,49 @@ Message TurnUpdateMessage(int empire_id, int current_turn, const SpeciesManager& species, CombatLogManager& combat_logs, const SupplyManager& supply, const std::map& players, - bool use_binary_serialization) + bool use_binary_serialization, + bool use_compression) { std::ostringstream os; { - if (use_binary_serialization) { - freeorion_bin_oarchive oa(os); - GlobalSerializationEncodingForEmpire() = empire_id; - oa << BOOST_SERIALIZATION_NVP(current_turn); - oa << BOOST_SERIALIZATION_NVP(empires); - oa << BOOST_SERIALIZATION_NVP(species); - SerializeIncompleteLogs(oa, combat_logs, 1); - oa << BOOST_SERIALIZATION_NVP(supply); - Serialize(oa, universe); - oa << BOOST_SERIALIZATION_NVP(players); - } else { - freeorion_xml_oarchive oa(os); - GlobalSerializationEncodingForEmpire() = empire_id; - oa << BOOST_SERIALIZATION_NVP(current_turn) - << BOOST_SERIALIZATION_NVP(empires) - << BOOST_SERIALIZATION_NVP(species); - SerializeIncompleteLogs(oa, combat_logs, 1); - oa << BOOST_SERIALIZATION_NVP(supply); - Serialize(oa, universe); - oa << BOOST_SERIALIZATION_NVP(players); - } + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); + GlobalSerializationEncodingForEmpire() = empire_id; + oa << BOOST_SERIALIZATION_NVP(current_turn) + << BOOST_SERIALIZATION_NVP(empires) + << BOOST_SERIALIZATION_NVP(species); + SerializeIncompleteLogs(oa, combat_logs, 1); + oa << BOOST_SERIALIZATION_NVP(supply); + Serialize(oa, universe); + oa << BOOST_SERIALIZATION_NVP(players); } return Message{Message::MessageType::TURN_UPDATE, std::move(os).str()}; } Message TurnPartialUpdateMessage(int empire_id, const Universe& universe, - bool use_binary_serialization) { + bool use_binary_serialization, bool use_compression) { std::ostringstream os; { - if (use_binary_serialization) { - freeorion_bin_oarchive oa(os); - GlobalSerializationEncodingForEmpire() = empire_id; - Serialize(oa, universe); - } else { - freeorion_xml_oarchive oa(os); - GlobalSerializationEncodingForEmpire() = empire_id; - Serialize(oa, universe); - } + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); + GlobalSerializationEncodingForEmpire() = empire_id; + Serialize(oa, universe); } return Message{Message::MessageType::TURN_PARTIAL_UPDATE, std::move(os).str()}; } @@ -491,29 +548,57 @@ Message TurnPartialUpdateMessage(int empire_id, const Universe& universe, Message HostSaveGameInitiateMessage(std::string filename) { return Message{Message::MessageType::SAVE_GAME_INITIATE, std::move(filename)}; } -Message ServerSaveGameCompleteMessage(const std::string& save_filename, int bytes_written) { +Message ServerSaveGameCompleteMessage(const std::string& save_filename, int bytes_written, + bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(save_filename) << BOOST_SERIALIZATION_NVP(bytes_written); } return Message{Message::MessageType::SAVE_GAME_COMPLETE, std::move(os).str()}; } -Message DiplomacyMessage(const DiplomaticMessage& diplo_message) { +Message DiplomacyMessage(const DiplomaticMessage& diplo_message, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(diplo_message); } return Message{Message::MessageType::DIPLOMACY, std::move(os).str()}; } -Message DiplomaticStatusMessage(const DiplomaticStatusUpdateInfo& diplo_update) { +Message DiplomaticStatusMessage(const DiplomaticStatusUpdateInfo& diplo_update, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(diplo_update.empire1_id) << BOOST_SERIALIZATION_NVP(diplo_update.empire2_id) << BOOST_SERIALIZATION_NVP(diplo_update.diplo_status); @@ -522,11 +607,21 @@ Message DiplomaticStatusMessage(const DiplomaticStatusUpdateInfo& diplo_update) } Message EndGameMessage(Message::EndGameReason reason, - const std::string& reason_player_name) + const std::string& reason_player_name, + bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(reason) << BOOST_SERIALIZATION_NVP(reason_player_name); } @@ -536,11 +631,20 @@ Message EndGameMessage(Message::EndGameReason reason, Message AIEndGameAcknowledgeMessage() { return Message{Message::MessageType::AI_END_GAME_ACK, DUMMY_EMPTY_MESSAGE}; } -Message ModeratorActionMessage(const Moderator::ModeratorAction& action) { +Message ModeratorActionMessage(const Moderator::ModeratorAction& action, bool use_compression) { std::ostringstream os; { const Moderator::ModeratorAction* mod_action = &action; - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(mod_action); } return Message{Message::MessageType::MODERATOR_ACTION, std::move(os).str()}; @@ -554,37 +658,59 @@ Message RequestSavePreviewsMessage(std::string relative_directory) { return Message{Message::MessageType::REQUEST_SAVE_PREVIEWS, std::move(relative_directory)}; } /** returns the savegame previews to the client */ -Message DispatchSavePreviewsMessage(const PreviewInformation& previews) { +Message DispatchSavePreviewsMessage(const PreviewInformation& previews, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(previews); } return Message{Message::MessageType::DISPATCH_SAVE_PREVIEWS, std::move(os).str()}; } -Message RequestCombatLogsMessage(const std::vector& ids) { +Message RequestCombatLogsMessage(const std::vector& ids, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(ids); } return Message{Message::MessageType::REQUEST_COMBAT_LOGS, std::move(os).str()}; } Message DispatchCombatLogsMessage(const std::vector>& logs, - bool use_binary_serialization) + bool use_binary_serialization, bool use_compression) { std::ostringstream os; { + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + try { - if (use_binary_serialization) { - freeorion_bin_oarchive oa(os); - oa << BOOST_SERIALIZATION_NVP(logs); - } else { - freeorion_xml_oarchive oa(os); - oa << BOOST_SERIALIZATION_NVP(logs); - } + freeorion_xml_oarchive oa(zos); + oa << BOOST_SERIALIZATION_NVP(logs); } catch (const std::exception& e) { ErrorLogger() << "Caught exception serializing combat logs: " << e.what(); } @@ -593,10 +719,20 @@ Message DispatchCombatLogsMessage(const std::vector>& options) { +Message LoggerConfigMessage(int sender, const std::set>& options, + bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); std::size_t size = options.size(); oa << BOOST_SERIALIZATION_NVP(size); for (const auto& option_tuple : options) { @@ -612,28 +748,56 @@ Message LoggerConfigMessage(int sender, const std::set>& chat_history) { +Message ChatHistoryMessage(const std::vector>& chat_history, + bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); std::size_t size = chat_history.size(); oa << BOOST_SERIALIZATION_NVP(size); for (const auto& elem : chat_history) { @@ -643,10 +807,19 @@ Message ChatHistoryMessage(const std::vector recipients, bool pm) { +Message PlayerChatMessage(const std::string& data, std::set recipients, bool pm, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(recipients) << BOOST_SERIALIZATION_NVP(data) << BOOST_SERIALIZATION_NVP(pm); @@ -655,11 +828,20 @@ Message PlayerChatMessage(const std::string& data, std::set recipients, boo } Message ServerPlayerChatMessage(int sender, const boost::posix_time::ptime& timestamp, - const std::string& data, bool pm) + const std::string& data, bool pm, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(sender) << BOOST_SERIALIZATION_NVP(timestamp) << BOOST_SERIALIZATION_NVP(data) @@ -671,31 +853,58 @@ Message ServerPlayerChatMessage(int sender, const boost::posix_time::ptime& time Message StartMPGameMessage() { return Message{Message::MessageType::START_MP_GAME, DUMMY_EMPTY_MESSAGE}; } -Message ContentCheckSumMessage() { +Message ContentCheckSumMessage(bool use_compression) { auto checksums = CheckSumContent(); std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(checksums); } return Message{Message::MessageType::CHECKSUM, std::move(os).str()}; } -Message AuthRequestMessage(const std::string& player_name, const std::string& auth) { +Message AuthRequestMessage(const std::string& player_name, const std::string& auth, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(player_name) << BOOST_SERIALIZATION_NVP(auth); } return Message{Message::MessageType::AUTH_REQUEST, std::move(os).str()}; } -Message AuthResponseMessage(const std::string& player_name, const std::string& auth) { +Message AuthResponseMessage(const std::string& player_name, const std::string& auth, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(player_name) << BOOST_SERIALIZATION_NVP(auth); } @@ -711,10 +920,19 @@ Message EliminateSelfMessage() Message UnreadyMessage() { return Message{Message::MessageType::UNREADY, DUMMY_EMPTY_MESSAGE}; } -Message PlayerInfoMessage(const std::map& players) { +Message PlayerInfoMessage(const std::map& players, bool use_compression) { std::ostringstream os; { - freeorion_xml_oarchive oa(os); + boost::iostreams::zlib_params params; + params.level = boost::iostreams::zlib::no_compression; + if (use_compression) + params.level = boost::iostreams::zlib::default_compression; + + boost::iostreams::filtering_ostream zos; + zos.push(boost::iostreams::zlib_compressor(params)); + zos.push(os); + + freeorion_xml_oarchive oa(zos); oa << BOOST_SERIALIZATION_NVP(players); } return Message{Message::MessageType::PLAYER_INFO, std::move(os).str()}; @@ -730,7 +948,11 @@ Message AutoTurnMessage(int turns_count) { void ExtractErrorMessageData(const Message& msg, int& player_id, std::string& problem, bool& fatal) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(problem) >> BOOST_SERIALIZATION_NVP(fatal) >> BOOST_SERIALIZATION_NVP(player_id); @@ -746,7 +968,11 @@ void ExtractErrorMessageData(const Message& msg, int& player_id, std::string& pr void ExtractHostMPGameMessageData(const Message& msg, std::string& host_player_name, std::string& client_version_string) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(host_player_name) >> BOOST_SERIALIZATION_NVP(client_version_string); @@ -761,7 +987,11 @@ void ExtractHostMPGameMessageData(const Message& msg, std::string& host_player_n void ExtractLobbyUpdateMessageData(const Message& msg, MultiplayerLobbyData& lobby_data) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(lobby_data); } catch (const std::exception& err) { @@ -775,7 +1005,11 @@ void ExtractLobbyUpdateMessageData(const Message& msg, MultiplayerLobbyData& lob void ExtractChatHistoryMessage(const Message& msg, std::vector& chat_history) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); std::size_t size; ia >> BOOST_SERIALIZATION_NVP(size); chat_history.clear(); @@ -796,7 +1030,11 @@ void ExtractChatHistoryMessage(const Message& msg, std::vector& recipients, std::string& data, bool& pm) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(recipients) >> BOOST_SERIALIZATION_NVP(data) >> BOOST_SERIALIZATION_NVP(pm); @@ -815,7 +1053,11 @@ void ExtractServerPlayerChatMessageData(const Message& msg, { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(sender) >> BOOST_SERIALIZATION_NVP(timestamp) >> BOOST_SERIALIZATION_NVP(data) @@ -848,103 +1090,56 @@ void ExtractGameStartMessageData(std::string text, bool& single_player_game, int std::string& save_state_string, GalaxySetupData& galaxy_setup_data) { try { - bool try_xml = false; - if (strncmp(text.c_str(), "> BOOST_SERIALIZATION_NVP(single_player_game) - >> BOOST_SERIALIZATION_NVP(empire_id) - >> BOOST_SERIALIZATION_NVP(current_turn); - GlobalSerializationEncodingForEmpire() = empire_id; - - ScopedTimer deserialize_timer; - ia >> BOOST_SERIALIZATION_NVP(empires); - DebugLogger() << "ExtractGameStartMessage empire deserialization time " << deserialize_timer.DurationString(); - - ia >> BOOST_SERIALIZATION_NVP(species); - combat_logs.Clear(); // only needed when loading new game, not when incrementally serializing logs on turn update - SerializeIncompleteLogs(ia, combat_logs, 1); - ia >> BOOST_SERIALIZATION_NVP(supply); - - deserialize_timer.restart(); - Deserialize(ia, universe); - DebugLogger() << "ExtractGameStartMessage universe deserialization time " << deserialize_timer.DurationString(); - - - ia >> BOOST_SERIALIZATION_NVP(players) - >> BOOST_SERIALIZATION_NVP(loaded_game_data); - if (loaded_game_data) { - Deserialize(ia, orders); - ia >> BOOST_SERIALIZATION_NVP(ui_data_available); - if (ui_data_available) - ia >> BOOST_SERIALIZATION_NVP(ui_data); - ia >> BOOST_SERIALIZATION_NVP(save_state_string_available); - if (save_state_string_available) - ia >> BOOST_SERIALIZATION_NVP(save_state_string); - } else { - ui_data_available = false; - save_state_string_available = false; - } - ia >> BOOST_SERIALIZATION_NVP(galaxy_setup_data); - } catch (...) { - try_xml = true; - } + std::istringstream is(text); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); + ia >> BOOST_SERIALIZATION_NVP(single_player_game) + >> BOOST_SERIALIZATION_NVP(empire_id) + >> BOOST_SERIALIZATION_NVP(current_turn); + GlobalSerializationEncodingForEmpire() = empire_id; + + ScopedTimer deserialize_timer; + ia >> BOOST_SERIALIZATION_NVP(empires); + + DebugLogger() << "ExtractGameStartMessage empire deserialization time " << deserialize_timer.DurationString(); + + ia >> BOOST_SERIALIZATION_NVP(species); + combat_logs.Clear(); // only needed when loading new game, not when incrementally serializing logs on turn update + SerializeIncompleteLogs(ia, combat_logs, 1); + ia >> BOOST_SERIALIZATION_NVP(supply); + + deserialize_timer.restart(); + Deserialize(ia, universe); + DebugLogger() << "ExtractGameStartMessage universe deserialization time " << deserialize_timer.DurationString();; + + + ia >> BOOST_SERIALIZATION_NVP(players) + >> BOOST_SERIALIZATION_NVP(loaded_game_data); + TraceLogger() << "ExtractGameStartMessage players and loaded_game_data=" << loaded_game_data << " deserialization time " << deserialize_timer.DurationString(); + if (loaded_game_data) { + Deserialize(ia, orders); + TraceLogger() << "ExtractGameStartMessage orders deserialization time " << deserialize_timer.DurationString(); + ia >> BOOST_SERIALIZATION_NVP(ui_data_available); + if (ui_data_available) + ia >> BOOST_SERIALIZATION_NVP(ui_data); + TraceLogger() << "ExtractGameStartMessage UI data " << ui_data_available << " deserialization time " << deserialize_timer.DurationString(); + ia >> BOOST_SERIALIZATION_NVP(save_state_string_available); + if (save_state_string_available) + ia >> BOOST_SERIALIZATION_NVP(save_state_string); + TraceLogger() << "ExtractGameStartMessage save state " << save_state_string_available << " deserialization time " << deserialize_timer.DurationString(); } else { - try_xml = true; - } - if (try_xml) { - // if binary deserialization failed, try more-portable XML deserialization - std::istringstream is(text); - - freeorion_xml_iarchive ia(is); - ia >> BOOST_SERIALIZATION_NVP(single_player_game) - >> BOOST_SERIALIZATION_NVP(empire_id) - >> BOOST_SERIALIZATION_NVP(current_turn); - GlobalSerializationEncodingForEmpire() = empire_id; - - ScopedTimer deserialize_timer; - ia >> BOOST_SERIALIZATION_NVP(empires); - - DebugLogger() << "ExtractGameStartMessage empire deserialization time " << deserialize_timer.DurationString(); - - ia >> BOOST_SERIALIZATION_NVP(species); - combat_logs.Clear(); // only needed when loading new game, not when incrementally serializing logs on turn update - SerializeIncompleteLogs(ia, combat_logs, 1); - ia >> BOOST_SERIALIZATION_NVP(supply); - - deserialize_timer.restart(); - Deserialize(ia, universe); - DebugLogger() << "ExtractGameStartMessage universe deserialization time " << deserialize_timer.DurationString();; - - - ia >> BOOST_SERIALIZATION_NVP(players) - >> BOOST_SERIALIZATION_NVP(loaded_game_data); - TraceLogger() << "ExtractGameStartMessage players and loaded_game_data=" << loaded_game_data << " deserialization time " << deserialize_timer.DurationString(); - if (loaded_game_data) { - Deserialize(ia, orders); - TraceLogger() << "ExtractGameStartMessage orders deserialization time " << deserialize_timer.DurationString(); - ia >> BOOST_SERIALIZATION_NVP(ui_data_available); - if (ui_data_available) - ia >> BOOST_SERIALIZATION_NVP(ui_data); - TraceLogger() << "ExtractGameStartMessage UI data " << ui_data_available << " deserialization time " << deserialize_timer.DurationString(); - ia >> BOOST_SERIALIZATION_NVP(save_state_string_available); - if (save_state_string_available) - ia >> BOOST_SERIALIZATION_NVP(save_state_string); - TraceLogger() << "ExtractGameStartMessage save state " << save_state_string_available << " deserialization time " << deserialize_timer.DurationString(); - } else { - ui_data_available = false; - save_state_string_available = false; - } - ia >> BOOST_SERIALIZATION_NVP(galaxy_setup_data); - TraceLogger() << "ExtractGameStartMessage galaxy setup data deserialization time " << deserialize_timer.DurationString(); + ui_data_available = false; + save_state_string_available = false; } - + ia >> BOOST_SERIALIZATION_NVP(galaxy_setup_data); + TraceLogger() << "ExtractGameStartMessage galaxy setup data deserialization time " << deserialize_timer.DurationString(); } catch (const std::exception& err) { ErrorLogger() << "ExtractGameStartMessageData(...) failed! Message probably long, so not outputting to log.\n" << "Error: " << err.what(); + DebugLogger() << text; TraceLogger() << "Message: " << text; throw err; } @@ -960,7 +1155,11 @@ void ExtractJoinGameMessageData(const Message& msg, std::string& player_name, << " client type " << client_type; try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(player_name) >> BOOST_SERIALIZATION_NVP(client_type) >> BOOST_SERIALIZATION_NVP(version_string) @@ -987,7 +1186,11 @@ void ExtractJoinAckMessageData(const Message& msg, int& player_id, { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(player_id) >> BOOST_SERIALIZATION_NVP(cookie); @@ -1007,7 +1210,11 @@ void ExtractTurnOrdersMessageData(const Message& msg, OrderSet& orders, bool& ui { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); DebugLogger() << "deserializing orders"; Deserialize(ia, orders); DebugLogger() << "checking for ui data"; @@ -1025,6 +1232,7 @@ void ExtractTurnOrdersMessageData(const Message& msg, OrderSet& orders, bool& ui } catch (const std::exception& err) { ErrorLogger() << "ExtractTurnOrdersMessageData(const Message& msg, ...) failed! Message probably long, so not outputting to log.\n" + << msg.Text() << "\n" << "Error: " << err.what(); throw err; } @@ -1033,7 +1241,11 @@ void ExtractTurnOrdersMessageData(const Message& msg, OrderSet& orders, bool& ui void ExtractTurnPartialOrdersMessageData(const Message& msg, OrderSet& added, std::set& deleted) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); DebugLogger() << "deserializing partial orders"; Deserialize(ia, added); ia >> BOOST_SERIALIZATION_NVP(deleted); @@ -1059,40 +1271,20 @@ void ExtractTurnUpdateMessageData(std::string text, int empire_id, int& current_ try { ScopedTimer timer("Turn Update Unpacking"); - bool try_xml = false; - if (std::strncmp(text.c_str(), "> BOOST_SERIALIZATION_NVP(current_turn) - >> BOOST_SERIALIZATION_NVP(empires) - >> BOOST_SERIALIZATION_NVP(species); - SerializeIncompleteLogs(ia, combat_logs, 1); - ia >> BOOST_SERIALIZATION_NVP(supply); - Deserialize(ia, universe); - ia >> BOOST_SERIALIZATION_NVP(players); - } catch (...) { - try_xml = true; - } - } else { - try_xml = true; - } - if (try_xml) { - // try again with more-portable XML deserialization - std::istringstream is(text); - freeorion_xml_iarchive ia(is); - GlobalSerializationEncodingForEmpire() = empire_id; - ia >> BOOST_SERIALIZATION_NVP(current_turn) - >> BOOST_SERIALIZATION_NVP(empires) - >> BOOST_SERIALIZATION_NVP(species); - SerializeIncompleteLogs(ia, combat_logs, 1); - ia >> BOOST_SERIALIZATION_NVP(supply); - Deserialize(ia, universe); - ia >> BOOST_SERIALIZATION_NVP(players); - } - + std::istringstream is(text); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); + GlobalSerializationEncodingForEmpire() = empire_id; + ia >> BOOST_SERIALIZATION_NVP(current_turn) + >> BOOST_SERIALIZATION_NVP(empires) + >> BOOST_SERIALIZATION_NVP(species); + SerializeIncompleteLogs(ia, combat_logs, 1); + ia >> BOOST_SERIALIZATION_NVP(supply); + Deserialize(ia, universe); + ia >> BOOST_SERIALIZATION_NVP(players); } catch (const std::exception& err) { ErrorLogger() << "ExtractTurnUpdateMessageData(...) failed! Message probably long, so not outputting to log.\n" << "Error: " << err.what(); @@ -1104,28 +1296,14 @@ void ExtractTurnPartialUpdateMessageData(const Message& msg, int empire_id, Univ try { ScopedTimer timer("Mid Turn Update Unpacking"); - bool try_xml = false; - if (std::strncmp(msg.Data(), "> BOOST_SERIALIZATION_NVP(phase_id); } catch (const std::exception& err) { @@ -1150,7 +1332,11 @@ void ExtractTurnProgressMessageData(const Message& msg, Message::TurnProgressPha void ExtractPlayerStatusMessageData(const Message& msg, Message::PlayerStatus& status, int& about_empire_id) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(status) >> BOOST_SERIALIZATION_NVP(about_empire_id); @@ -1165,7 +1351,11 @@ void ExtractPlayerStatusMessageData(const Message& msg, Message::PlayerStatus& s void ExtractHostSPGameMessageData(const Message& msg, SinglePlayerSetupData& setup_data, std::string& client_version_string) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(setup_data) >> BOOST_SERIALIZATION_NVP(client_version_string); @@ -1180,7 +1370,11 @@ void ExtractHostSPGameMessageData(const Message& msg, SinglePlayerSetupData& set void ExtractEndGameMessageData(const Message& msg, Message::EndGameReason& reason, std::string& reason_player_name) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(reason) >> BOOST_SERIALIZATION_NVP(reason_player_name); @@ -1196,7 +1390,11 @@ void ExtractEndGameMessageData(const Message& msg, Message::EndGameReason& reaso void ExtractModeratorActionMessageData(const Message& msg, Moderator::ModeratorAction*& mod_action) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(mod_action); } catch (const std::exception& err) { @@ -1210,7 +1408,11 @@ void ExtractModeratorActionMessageData(const Message& msg, Moderator::ModeratorA void ExtractDiplomacyMessageData(const Message& msg, DiplomaticMessage& diplo_message) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(diplo_message); } catch (const std::exception& err) { @@ -1225,7 +1427,11 @@ void ExtractDiplomacyMessageData(const Message& msg, DiplomaticMessage& diplo_me void ExtractDiplomaticStatusMessageData(const Message& msg, DiplomaticStatusUpdateInfo& diplo_update) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(diplo_update.empire1_id) >> BOOST_SERIALIZATION_NVP(diplo_update.empire2_id) >> BOOST_SERIALIZATION_NVP(diplo_update.diplo_status); @@ -1244,7 +1450,11 @@ void ExtractRequestSavePreviewsMessageData(const Message& msg, std::string& dire void ExtractDispatchSavePreviewsMessageData(const Message& msg, PreviewInformation& previews) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(previews); } catch(const std::exception& err) { @@ -1258,7 +1468,11 @@ void ExtractDispatchSavePreviewsMessageData(const Message& msg, PreviewInformati FO_COMMON_API void ExtractServerSaveGameCompleteMessageData(const Message& msg, std::string& save_filename, int& bytes_written) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(save_filename) >> BOOST_SERIALIZATION_NVP(bytes_written); @@ -1273,7 +1487,11 @@ FO_COMMON_API void ExtractServerSaveGameCompleteMessageData(const Message& msg, FO_COMMON_API void ExtractRequestCombatLogsMessageData(const Message& msg, std::vector& ids) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(ids); } catch(const std::exception& err) { ErrorLogger() << "ExtractRequestCombatLogMessageData(const Message& msg, std::vector& ids) failed! Message:\n" @@ -1287,26 +1505,13 @@ FO_COMMON_API void ExtractDispatchCombatLogsMessageData( const Message& msg, std::vector>& logs) { try { - bool try_xml = false; - if (std::strncmp(msg.Data(), "> BOOST_SERIALIZATION_NVP(logs); - } catch (...) { - try_xml = true; - } - } else { - try_xml = true; - } - if (try_xml) { - // try again with more-portable XML deserialization - std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); - ia >> BOOST_SERIALIZATION_NVP(logs); - } + std::istringstream is(msg.Text()); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + freeorion_xml_iarchive ia(zis); + ia >> BOOST_SERIALIZATION_NVP(logs); } catch(const std::exception& err) { ErrorLogger() << "ExtractDispatchCombatLogMessageData(const Message& msg, std::vector>& logs) failed! Message:\n" << msg.Text() << "\n" @@ -1320,7 +1525,11 @@ FO_COMMON_API void ExtractLoggerConfigMessageData(const Message& msg, { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); std::size_t size; ia >> BOOST_SERIALIZATION_NVP(size); for (size_t ii = 0; ii < size; ++ii) { @@ -1345,7 +1554,11 @@ void ExtractContentCheckSumMessageData(const Message& msg, std::map> BOOST_SERIALIZATION_NVP(checksums); } catch(const std::exception& err) { @@ -1359,7 +1572,11 @@ void ExtractContentCheckSumMessageData(const Message& msg, std::map> BOOST_SERIALIZATION_NVP(player_name) >> BOOST_SERIALIZATION_NVP(auth); @@ -1374,7 +1591,11 @@ void ExtractAuthRequestMessageData(const Message& msg, std::string& player_name, void ExtractAuthResponseMessageData(const Message& msg, std::string& player_name, std::string& auth) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(player_name) >> BOOST_SERIALIZATION_NVP(auth); @@ -1392,7 +1613,11 @@ void ExtractSetAuthorizationRolesMessage(const Message &msg, Networking::AuthRol void ExtractPlayerInfoMessageData(const Message &msg, std::map& players) { try { std::istringstream is(msg.Text()); - freeorion_xml_iarchive ia(is); + boost::iostreams::filtering_istream zis; + zis.push(boost::iostreams::zlib_decompressor()); + zis.push(is); + + freeorion_xml_iarchive ia(zis); ia >> BOOST_SERIALIZATION_NVP(players); } catch(const std::exception& err) { ErrorLogger() << "ExtractPlayerInfo(const Message &msg, std::map& players) failed! Message:\n" diff --git a/network/Message.h b/network/Message.h index f7da32fa6..2fd59d3f3 100644 --- a/network/Message.h +++ b/network/Message.h @@ -183,20 +183,24 @@ FO_COMMON_API std::ostream& operator<<(std::ostream& os, const Message& msg); /** creates an ERROR_MSG message*/ FO_COMMON_API Message ErrorMessage(const std::string& problem, bool fatal = true, - int player_id = Networking::INVALID_PLAYER_ID); + int player_id = Networking::INVALID_PLAYER_ID, + bool use_compression = false); /** creates a HOST_SP_GAME message*/ -FO_COMMON_API Message HostSPGameMessage(const SinglePlayerSetupData& setup_data); +FO_COMMON_API Message HostSPGameMessage(const SinglePlayerSetupData& setup_data, + bool use_compression = false); /** creates a minimal HOST_MP_GAME message used to initiate multiplayer "lobby" setup*/ -FO_COMMON_API Message HostMPGameMessage(const std::string& host_player_name); +FO_COMMON_API Message HostMPGameMessage(const std::string& host_player_name, + bool use_compression = false); /** creates a JOIN_GAME message. The sender's player name, client type, and * cookie are sent in the message.*/ FO_COMMON_API Message JoinGameMessage(const std::string& player_name, Networking::ClientType client_type, const std::map& dependencies, - boost::uuids::uuid cookie); + boost::uuids::uuid cookie, + bool use_compression = false); /** creates a HOST_ID message. The player ID of the host is sent in the message. */ FO_COMMON_API Message HostIDMessage(int host_player_id); @@ -207,7 +211,8 @@ FO_COMMON_API Message GameStartMessage( const EmpireManager& empires, const Universe& universe, const SpeciesManager& species, CombatLogManager& combat_logs, const SupplyManager& supply, const std::map& players, - GalaxySetupData galaxy_setup_data, bool use_binary_serialization); + GalaxySetupData galaxy_setup_data, bool use_binary_serialization, + bool use_compression = false); /** creates a GAME_START message. Contains the initial game state visible to * the player. Also includes data loaded from a saved game. */ @@ -217,7 +222,8 @@ FO_COMMON_API Message GameStartMessage( const SpeciesManager& species, CombatLogManager& combat_logs, const SupplyManager& supply, const std::map& players, const OrderSet& orders, const SaveGameUIData* ui_data, - GalaxySetupData galaxy_setup_data, bool use_binary_serialization); + GalaxySetupData galaxy_setup_data, bool use_binary_serialization, + bool use_compression = false); /** creates a GAME_START message. Contains the initial game state visible to * the player. Also includes state string loaded from a saved game. */ @@ -227,7 +233,8 @@ FO_COMMON_API Message GameStartMessage( const SpeciesManager& species, CombatLogManager& combat_logs, const SupplyManager& supply, const std::map& players, const OrderSet& orders, const std::string* save_state_string, - GalaxySetupData galaxy_setup_data, bool use_binary_serialization); + GalaxySetupData galaxy_setup_data, bool use_binary_serialization, + bool use_compression = false); /** creates a HOST_SP_GAME acknowledgement message. The \a player_id is the ID * of the receiving player. This message should only be sent by the server.*/ @@ -240,37 +247,44 @@ FO_COMMON_API Message HostMPAckMessage(int player_id); /** creates a JOIN_GAME acknowledgement message. The \a player_id is the ID of * the receiving player and \a cookie is a token to quickly authenticate player. * This message should only be sent by the server.*/ -FO_COMMON_API Message JoinAckMessage(int player_id, boost::uuids::uuid cookie); +FO_COMMON_API Message JoinAckMessage(int player_id, boost::uuids::uuid cookie, + bool use_compression = false); /** creates a TURN_ORDERS message, including UI data but without a state string. */ -FO_COMMON_API Message TurnOrdersMessage(const OrderSet& orders, const SaveGameUIData& ui_data); +FO_COMMON_API Message TurnOrdersMessage(const OrderSet& orders, const SaveGameUIData& ui_data, + bool use_compression = false); /** creates a TURN_ORDERS message, without UI data but with a state string. */ -FO_COMMON_API Message TurnOrdersMessage(const OrderSet& orders, const std::string& save_state_string); +FO_COMMON_API Message TurnOrdersMessage(const OrderSet& orders, const std::string& save_state_string, + bool use_compression = false); /** creates a TURN_PARTIAL_ORDERS message with orders changes. */ -FO_COMMON_API Message TurnPartialOrdersMessage(const std::pair>& orders_updates); +FO_COMMON_API Message TurnPartialOrdersMessage(const std::pair>& orders_updates, + bool use_compression = false); /** creates a TURN_TIMEOUT message with remaining time \a timeout_. */ FO_COMMON_API Message TurnTimeoutMessage(int timeout_remainig); /** creates a TURN_PROGRESS message. */ -FO_COMMON_API Message TurnProgressMessage(Message::TurnProgressPhase phase_id); +FO_COMMON_API Message TurnProgressMessage(Message::TurnProgressPhase phase_id, bool use_compression = false); /** creates a PLAYER_STATUS message. */ FO_COMMON_API Message PlayerStatusMessage(Message::PlayerStatus player_status, - int about_empire_id); + int about_empire_id, + bool use_compression = false); /** creates a TURN_UPDATE message. */ FO_COMMON_API Message TurnUpdateMessage(int empire_id, int current_turn, const EmpireManager& empires, const Universe& universe, const SpeciesManager& species, CombatLogManager& combat_logs, const SupplyManager& supply, - const std::map& players, bool use_binary_serialization); + const std::map& players, bool use_binary_serialization, + bool use_compression = false); /** create a TURN_PARTIAL_UPDATE message. */ FO_COMMON_API Message TurnPartialUpdateMessage(int empire_id, const Universe& universe, - bool use_binary_serialization); + bool use_binary_serialization, + bool use_compression = false); /** creates a SAVE_GAME_INITIATE request message. This message should only be sent by * the host player.*/ @@ -279,24 +293,27 @@ FO_COMMON_API Message HostSaveGameInitiateMessage(std::string filename); /** creates a SAVE_GAME_COMPLETE complete message. This message should only be sent by the server to inform clients that the last initiated save has been completed successfully. */ -FO_COMMON_API Message ServerSaveGameCompleteMessage(const std::string& save_filename, int bytes_written); +FO_COMMON_API Message ServerSaveGameCompleteMessage(const std::string& save_filename, int bytes_written, + bool use_compression = false); /** creates a DIPLOMACY message, which is sent between players via the server to * declare, proposed, or accept / reject diplomatic arrangements or agreements. */ -FO_COMMON_API Message DiplomacyMessage(const DiplomaticMessage& diplo_message); +FO_COMMON_API Message DiplomacyMessage(const DiplomaticMessage& diplo_message, bool use_compression = false); /** creates a DIPLOMATIC_STATUS message, which is sent to players by the server to * update them on diplomatic status changes between players. */ -FO_COMMON_API Message DiplomaticStatusMessage(const DiplomaticStatusUpdateInfo& diplo_update); +FO_COMMON_API Message DiplomaticStatusMessage(const DiplomaticStatusUpdateInfo& diplo_update, + bool use_compression = false); /** creates an END_GAME message used to terminate an active game. */ -FO_COMMON_API Message EndGameMessage(Message::EndGameReason reason, const std::string& reason_player_name = ""); +FO_COMMON_API Message EndGameMessage(Message::EndGameReason reason, const std::string& reason_player_name = "", + bool use_compression = false); /** creates an AI_END_GAME_ACK message used to indicate that the AI has shutdown. */ FO_COMMON_API Message AIEndGameAcknowledgeMessage(); /** creates a MODERATOR_ACTION message used to implement moderator commands. */ -FO_COMMON_API Message ModeratorActionMessage(const Moderator::ModeratorAction& mod_action); +FO_COMMON_API Message ModeratorActionMessage(const Moderator::ModeratorAction& mod_action, bool use_compression = false); /** tells server to shut down. */ FO_COMMON_API Message ShutdownServerMessage(); @@ -305,17 +322,18 @@ FO_COMMON_API Message ShutdownServerMessage(); FO_COMMON_API Message RequestSavePreviewsMessage(std::string relative_directory); /** returns the savegame previews to the client */ -FO_COMMON_API Message DispatchSavePreviewsMessage(const PreviewInformation& preview); +FO_COMMON_API Message DispatchSavePreviewsMessage(const PreviewInformation& preview, bool use_compression = false); /** requests combat logs from server */ -FO_COMMON_API Message RequestCombatLogsMessage(const std::vector& ids); +FO_COMMON_API Message RequestCombatLogsMessage(const std::vector& ids, bool use_compression = false); /** returns combat logs to the client */ FO_COMMON_API Message DispatchCombatLogsMessage(const std::vector>& logs, - bool use_binary_serialization); + bool use_binary_serialization, bool use_compression = false); /** Sends logger configuration details to server or ai process. */ -FO_COMMON_API Message LoggerConfigMessage(int sender, const std::set>& options); +FO_COMMON_API Message LoggerConfigMessage(int sender, const std::set>& options, + bool use_compression = false); //////////////////////////////////////////////// // Multiplayer Lobby Message named ctors @@ -324,36 +342,41 @@ FO_COMMON_API Message LoggerConfigMessage(int sender, const std::set>& chat_history); +FO_COMMON_API Message ChatHistoryMessage(const std::vector>& chat_history, + bool use_compression = false); /** creates an PLAYER_CHAT message containing a chat string to be broadcast to player \a receiver, or all players if \a receiver is Networking::INVALID_PLAYER_ID. Note that the receiver of this message is always the server.*/ -FO_COMMON_API Message PlayerChatMessage(const std::string& text, std::set recipients, bool pm); +FO_COMMON_API Message PlayerChatMessage(const std::string& text, std::set recipients, bool pm, + bool use_compression = false); /** creates an PLAYER_CHAT message containing a chat string from \a sender at \a timestamp to be displayed in chat. This message should only be sent by the server.*/ FO_COMMON_API Message ServerPlayerChatMessage(int sender, const boost::posix_time::ptime& timestamp, - const std::string& text, bool pm = false); + const std::string& text, bool pm = false, + bool use_compression = false); /** creates a START_MP_GAME used to finalize the multiplayer lobby setup.*/ FO_COMMON_API Message StartMPGameMessage(); /** creates a CHECKSUM message containing checksums of parsed content. */ -FO_COMMON_API Message ContentCheckSumMessage(); +FO_COMMON_API Message ContentCheckSumMessage(bool use_compression = false); /** creates a AUTH_REQUEST message containing \a player_name to login and \a auth additional authentication data. */ -FO_COMMON_API Message AuthRequestMessage(const std::string& player_name, const std::string& auth); +FO_COMMON_API Message AuthRequestMessage(const std::string& player_name, const std::string& auth, + bool use_compression = false); /** creates a AUTH_RESPONSE message containing \a player_name to login and \a auth credentials. */ -FO_COMMON_API Message AuthResponseMessage(const std::string& player_name, const std::string& auth); +FO_COMMON_API Message AuthResponseMessage(const std::string& player_name, const std::string& auth, + bool use_compression = false); /** notifies client about changes in his authorization \a roles. */ FO_COMMON_API Message SetAuthorizationRolesMessage(const Networking::AuthRoles& roles); @@ -365,7 +388,7 @@ FO_COMMON_API Message EliminateSelfMessage(); FO_COMMON_API Message UnreadyMessage(); /** creates a PLAYER_INFO message to notify player about changes in the player list. */ -FO_COMMON_API Message PlayerInfoMessage(const std::map& players); +FO_COMMON_API Message PlayerInfoMessage(const std::map& players, bool use_compression = false); /** creates a AUTO_TURN message to set empire in auto-turn state for \a turns_count turns, * inifinity turns if -1 or set empire to playing state if 0. */ -- 2.36.1