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