1 #ifndef _MultiplayerCommon_h_ 2 #define _MultiplayerCommon_h_ 3 4 #include "../universe/EnumsFwd.h" 5 #include "../network/Networking.h" 6 #include "Export.h" 7 #include "OptionsDB.h" 8 #include "Pending.h" 9 #include "Serialize.h" 10 11 #include <GG/Clr.h> 12 13 #include <list> 14 #include <set> 15 #include <vector> 16 #include <map> 17 #include <boost/serialization/access.hpp> 18 #include <boost/date_time/posix_time/posix_time_types.hpp> 19 20 21 FO_COMMON_API extern const std::string MP_SAVE_FILE_EXTENSION; 22 FO_COMMON_API extern const std::string SP_SAVE_FILE_EXTENSION; 23 FO_COMMON_API extern const int ALL_EMPIRES; 24 FO_COMMON_API extern const int INVALID_GAME_TURN; 25 26 27 /** The data that represent the galaxy setup for a new game. */ 28 struct FO_COMMON_API GalaxySetupData { 29 /** \name Structors */ //@{ 30 GalaxySetupData(); 31 GalaxySetupData(const GalaxySetupData&) = default; 32 GalaxySetupData(GalaxySetupData&& base); 33 //@} 34 35 /** \name Accessors */ //@{ 36 const std::string& GetSeed() const; 37 int GetSize() const; 38 Shape GetShape() const; 39 GalaxySetupOption GetAge() const; 40 GalaxySetupOption GetStarlaneFreq() const; 41 GalaxySetupOption GetPlanetDensity() const; 42 GalaxySetupOption GetSpecialsFreq() const; 43 GalaxySetupOption GetMonsterFreq() const; 44 GalaxySetupOption GetNativeFreq() const; 45 Aggression GetAggression() const; 46 const std::map<std::string, std::string>& 47 GetGameRules() const; 48 const std::string& GetGameUID() const; 49 //@} 50 51 /** \name Mutators */ //@{ 52 void SetSeed(const std::string& seed); 53 void SetGameUID(const std::string& game_uid); 54 //@} 55 56 GalaxySetupData& operator=(const GalaxySetupData&) = default; 57 58 std::string m_seed; 59 int m_size; 60 Shape m_shape; 61 GalaxySetupOption m_age; 62 GalaxySetupOption m_starlane_freq; 63 GalaxySetupOption m_planet_density; 64 GalaxySetupOption m_specials_freq; 65 GalaxySetupOption m_monster_freq; 66 GalaxySetupOption m_native_freq; 67 Aggression m_ai_aggr; 68 std::map<std::string, std::string> 69 m_game_rules; 70 std::string m_game_uid; 71 72 /** HACK! This must be set to the encoding empire's id when serializing a 73 * GalaxySetupData, so that only the relevant parts of the galaxy data are 74 * serialized. The use of this local field is done just so I don't 75 * have to rewrite any custom boost::serialization classes that implement 76 * empire-dependent visibility. */ 77 int m_encoding_empire; ///< used during serialization to globally set what empire knowledge to use 78 79 private: 80 friend class boost::serialization::access; 81 template <typename Archive> 82 void serialize(Archive& ar, const unsigned int version); 83 }; 84 85 BOOST_CLASS_VERSION(GalaxySetupData, 3); 86 87 88 /** Contains the UI data that must be saved in save game files in order to 89 * restore games to the users' last views. */ 90 struct FO_COMMON_API SaveGameUIData { 91 int map_top = 0; 92 int map_left = 0; 93 double map_zoom_steps_in = 0.0; 94 std::set<int> fleets_exploring; 95 96 // See DesignWnd.cpp for the usage of the following variables. 97 int obsolete_ui_event_count = 0; 98 std::vector<std::pair<int, boost::optional<std::pair<bool, int>>>> ordered_ship_design_ids_and_obsolete; 99 std::vector<std::pair<std::string, std::pair<bool, int>>> ordered_ship_hull_and_obsolete; 100 std::unordered_map<std::string, int> obsolete_ship_parts; 101 102 private: 103 friend class boost::serialization::access; 104 template <typename Archive> 105 void serialize(Archive& ar, const unsigned int version); 106 }; 107 108 BOOST_CLASS_VERSION(SaveGameUIData, 4); 109 110 111 /** The data for one empire necessary for game-setup during multiplayer loading. */ 112 struct FO_COMMON_API SaveGameEmpireData { 113 /** \name Structors */ //@{ SaveGameEmpireDataSaveGameEmpireData114 SaveGameEmpireData() : 115 m_empire_id(ALL_EMPIRES), 116 m_empire_name(), 117 m_player_name(), 118 m_color(), 119 m_authenticated(false), 120 m_eliminated(false), 121 m_won(false) 122 {} SaveGameEmpireDataSaveGameEmpireData123 SaveGameEmpireData(int empire_id, const std::string& empire_name, 124 const std::string& player_name, const GG::Clr& colour, 125 bool authenticated, bool eliminated, bool won) : 126 m_empire_id(empire_id), 127 m_empire_name(empire_name), 128 m_player_name(player_name), 129 m_color(colour), 130 m_authenticated(authenticated), 131 m_eliminated(eliminated), 132 m_won(won) 133 {} 134 //@} 135 136 int m_empire_id; 137 std::string m_empire_name; 138 std::string m_player_name; 139 GG::Clr m_color; 140 bool m_authenticated; 141 bool m_eliminated; 142 bool m_won; 143 144 private: 145 friend class boost::serialization::access; 146 template <typename Archive> 147 void serialize(Archive& ar, const unsigned int version); 148 }; 149 150 BOOST_CLASS_VERSION(SaveGameEmpireData, 2); 151 152 /** Contains basic data about a player in a game. */ 153 struct FO_COMMON_API PlayerSaveHeaderData { PlayerSaveHeaderDataPlayerSaveHeaderData154 PlayerSaveHeaderData() : 155 m_name(), 156 m_empire_id(ALL_EMPIRES), 157 m_client_type(Networking::INVALID_CLIENT_TYPE) 158 {} 159 PlayerSaveHeaderDataPlayerSaveHeaderData160 PlayerSaveHeaderData(const std::string& name, int empire_id, 161 Networking::ClientType client_type) : 162 m_name(name), 163 m_empire_id(empire_id), 164 m_client_type(client_type) 165 {} 166 167 std::string m_name; 168 int m_empire_id; 169 Networking::ClientType m_client_type; 170 171 private: 172 friend class boost::serialization::access; 173 template <typename Archive> 174 void serialize(Archive& ar, const unsigned int version); 175 }; 176 177 /** Contains data that must be saved for a single player. */ 178 struct FO_COMMON_API PlayerSaveGameData : public PlayerSaveHeaderData { PlayerSaveGameDataPlayerSaveGameData179 PlayerSaveGameData() : 180 PlayerSaveHeaderData(), 181 m_orders(), 182 m_ui_data(), 183 m_save_state_string() 184 {} 185 PlayerSaveGameDataPlayerSaveGameData186 PlayerSaveGameData(const std::string& name, int empire_id, 187 const std::shared_ptr<OrderSet>& orders, 188 const std::shared_ptr<SaveGameUIData>& ui_data, 189 const std::string& save_state_string, 190 Networking::ClientType client_type) : 191 PlayerSaveHeaderData(name, empire_id, client_type), 192 m_orders(orders), 193 m_ui_data(ui_data), 194 m_save_state_string(save_state_string) 195 {} 196 197 std::shared_ptr<OrderSet> m_orders; 198 std::shared_ptr<SaveGameUIData> m_ui_data; 199 std::string m_save_state_string; 200 201 private: 202 friend class boost::serialization::access; 203 template <typename Archive> 204 void serialize(Archive& ar, const unsigned int version); 205 }; 206 207 BOOST_CLASS_VERSION(PlayerSaveGameData, 2); 208 209 /** Data that must be retained by the server when saving and loading a 210 * game that isn't player data or the universe */ 211 struct FO_COMMON_API ServerSaveGameData { ServerSaveGameDataServerSaveGameData212 ServerSaveGameData() : 213 m_current_turn(INVALID_GAME_TURN) 214 {} 215 ServerSaveGameDataServerSaveGameData216 ServerSaveGameData(int current_turn) : 217 m_current_turn(current_turn) 218 {} 219 220 int m_current_turn; 221 222 private: 223 friend class boost::serialization::access; 224 template <typename Archive> 225 void serialize(Archive& ar, const unsigned int version); 226 }; 227 228 /** The data structure used to represent a single player's setup options for a 229 * multiplayer game (in the multiplayer lobby screen). */ 230 struct PlayerSetupData { 231 /** \name Structors */ //@{ PlayerSetupDataPlayerSetupData232 PlayerSetupData() : 233 m_player_name(), 234 m_player_id(Networking::INVALID_PLAYER_ID), 235 m_empire_name(), 236 m_empire_color(GG::Clr(0, 0, 0, 0)), 237 m_starting_species_name(), 238 m_save_game_empire_id(ALL_EMPIRES), 239 m_client_type(Networking::INVALID_CLIENT_TYPE), 240 m_player_ready(false), 241 m_authenticated(false), 242 m_starting_team(Networking::NO_TEAM_ID) 243 {} 244 //@} 245 246 std::string m_player_name; ///< the player's name 247 int m_player_id; ///< player id 248 std::string m_empire_name; ///< the name of the player's empire when starting a new game 249 GG::Clr m_empire_color; ///< the color used to represent this player's empire when starting a new game 250 std::string m_starting_species_name;///< name of the species with which the player starts when starting a new game 251 int m_save_game_empire_id; ///< when loading a game, the ID of the empire that this player will control 252 Networking::ClientType m_client_type; ///< is this player an AI, human player or...? 253 bool m_player_ready; ///< if player ready to play. 254 bool m_authenticated; ///< if player was authenticated 255 int m_starting_team; ///< team id or -1 if no team. 256 257 private: 258 friend class boost::serialization::access; 259 template <typename Archive> 260 void serialize(Archive& ar, const unsigned int version); 261 }; 262 bool FO_COMMON_API operator==(const PlayerSetupData& lhs, const PlayerSetupData& rhs); 263 bool operator!=(const PlayerSetupData& lhs, const PlayerSetupData& rhs); 264 265 BOOST_CLASS_VERSION(PlayerSetupData, 2); 266 267 /** The data needed to establish a new single player game. If \a m_new_game 268 * is true, a new game is to be started, using the remaining members besides 269 * \a m_filename. Otherwise, the saved game \a m_filename will be loaded 270 * instead. */ 271 struct SinglePlayerSetupData : public GalaxySetupData { 272 /** \name Structors */ //@{ SinglePlayerSetupDataSinglePlayerSetupData273 SinglePlayerSetupData(): 274 m_new_game(true), 275 m_filename(), 276 m_players() 277 {} 278 //@} 279 280 bool m_new_game; 281 std::string m_filename; 282 std::vector<PlayerSetupData> m_players; 283 284 private: 285 friend class boost::serialization::access; 286 template <typename Archive> 287 void serialize(Archive& ar, const unsigned int version); 288 }; 289 290 /** The data structure that represents the state of the multiplayer lobby. */ 291 struct FO_COMMON_API MultiplayerLobbyData : public GalaxySetupData { 292 /** \name Structors */ //@{ MultiplayerLobbyDataMultiplayerLobbyData293 MultiplayerLobbyData() : 294 m_any_can_edit(false), 295 m_new_game(true), 296 m_start_locked(false), 297 m_players(), 298 m_save_game(), 299 m_save_game_empire_data(), 300 m_save_game_current_turn(0), 301 m_in_game(false) 302 {} 303 MultiplayerLobbyDataMultiplayerLobbyData304 MultiplayerLobbyData(const GalaxySetupData& base) : 305 GalaxySetupData(base), 306 m_any_can_edit(false), 307 m_new_game(true), 308 m_start_locked(false), 309 m_players(), 310 m_save_game(), 311 m_save_game_empire_data(), 312 m_save_game_current_turn(0), 313 m_in_game(false) 314 {} 315 MultiplayerLobbyDataMultiplayerLobbyData316 MultiplayerLobbyData(GalaxySetupData&& base) : 317 GalaxySetupData(std::move(base)), 318 m_any_can_edit(false), 319 m_new_game(true), 320 m_start_locked(false), 321 m_players(), 322 m_save_game(), 323 m_save_game_empire_data(), 324 m_save_game_current_turn(0), 325 m_in_game(false) 326 {} 327 //@} 328 329 std::string Dump() const; 330 331 bool m_any_can_edit; 332 bool m_new_game; 333 bool m_start_locked; 334 // TODO: Change from a list<(player_id, PlayerSetupData)> where 335 // PlayerSetupData contain player_id to a vector of PlayerSetupData 336 std::list<std::pair<int, PlayerSetupData>> m_players; // <player_id, PlayerSetupData> 337 338 std::string m_save_game; //< File name of a save file 339 std::map<int, SaveGameEmpireData> m_save_game_empire_data;// indexed by empire_id 340 int m_save_game_current_turn; 341 342 std::string m_start_lock_cause; 343 bool m_in_game; ///< In-game lobby 344 345 private: 346 friend class boost::serialization::access; 347 template <typename Archive> 348 void serialize(Archive& ar, const unsigned int version); 349 }; 350 351 BOOST_CLASS_VERSION(MultiplayerLobbyData, 2); 352 353 /** The data structure stores information about latest chat massages. */ 354 struct FO_COMMON_API ChatHistoryEntity { 355 /** \name Structors */ //@{ ChatHistoryEntityChatHistoryEntity356 ChatHistoryEntity() 357 {} 358 //@} 359 360 boost::posix_time::ptime m_timestamp; 361 std::string m_player_name; 362 std::string m_text; 363 GG::Clr m_text_color; 364 365 private: 366 friend class boost::serialization::access; 367 template <typename Archive> 368 void serialize(Archive& ar, const unsigned int version); 369 }; 370 371 BOOST_CLASS_VERSION(ChatHistoryEntity, 1); 372 373 /** Information about one player that other players are informed of. Assembled by server and sent to players. */ 374 struct PlayerInfo { PlayerInfoPlayerInfo375 PlayerInfo() : 376 name(""), 377 empire_id(ALL_EMPIRES), 378 client_type(Networking::INVALID_CLIENT_TYPE), 379 host(false) 380 {} PlayerInfoPlayerInfo381 PlayerInfo(const std::string& player_name_, int empire_id_, 382 Networking::ClientType client_type_, bool host_) : 383 name(player_name_), 384 empire_id(empire_id_), 385 client_type(client_type_), 386 host(host_) 387 {} 388 389 std::string name; ///< name of this player (not the same as the empire name) 390 int empire_id; ///< id of the player's empire 391 Networking::ClientType client_type; ///< is this a human player, AI player, or observer? 392 bool host; ///< true iff this is the host player 393 394 friend class boost::serialization::access; 395 template <typename Archive> 396 void serialize(Archive& ar, const unsigned int version); 397 }; 398 399 // Note: *::serialize() implemented in SerializeMultiplayerCommon.cpp. 400 401 #endif // _MultiplayerCommon_h_ 402