1 #include "Serialize.h"
2 
3 #include "MultiplayerCommon.h"
4 #include "OptionsDB.h"
5 #include "OrderSet.h"
6 #include "Order.h"
7 #include "../universe/System.h"
8 
9 #include "Serialize.ipp"
10 
11 #include <boost/date_time/posix_time/time_serialize.hpp>
12 #include <boost/uuid/random_generator.hpp>
13 #include <boost/uuid/uuid_io.hpp>
14 
15 
16 template <typename Archive>
serialize(Archive & ar,const unsigned int version)17 void GalaxySetupData::serialize(Archive& ar, const unsigned int version)
18 {
19     if (Archive::is_saving::value && m_encoding_empire != ALL_EMPIRES && (!GetOptionsDB().Get<bool>("network.server.publish-seed"))) {
20         std::string dummy = "";
21         ar  & boost::serialization::make_nvp("m_seed", dummy);
22     } else {
23         ar  & BOOST_SERIALIZATION_NVP(m_seed);
24     }
25 
26     ar  & BOOST_SERIALIZATION_NVP(m_size)
27         & BOOST_SERIALIZATION_NVP(m_shape)
28         & BOOST_SERIALIZATION_NVP(m_age)
29         & BOOST_SERIALIZATION_NVP(m_starlane_freq)
30         & BOOST_SERIALIZATION_NVP(m_planet_density)
31         & BOOST_SERIALIZATION_NVP(m_specials_freq)
32         & BOOST_SERIALIZATION_NVP(m_monster_freq)
33         & BOOST_SERIALIZATION_NVP(m_native_freq)
34         & BOOST_SERIALIZATION_NVP(m_ai_aggr);
35 
36     if (version >= 1) {
37         ar & BOOST_SERIALIZATION_NVP(m_game_rules);
38     }
39 
40     if (version >= 2) {
41         ar & BOOST_SERIALIZATION_NVP(m_game_uid);
42     } else {
43         if (Archive::is_loading::value) {
44             m_game_uid = boost::uuids::to_string(boost::uuids::random_generator()());
45         }
46     }
47 }
48 
49 template void GalaxySetupData::serialize<freeorion_bin_oarchive>(freeorion_bin_oarchive&, const unsigned int);
50 template void GalaxySetupData::serialize<freeorion_bin_iarchive>(freeorion_bin_iarchive&, const unsigned int);
51 template void GalaxySetupData::serialize<freeorion_xml_oarchive>(freeorion_xml_oarchive&, const unsigned int);
52 template void GalaxySetupData::serialize<freeorion_xml_iarchive>(freeorion_xml_iarchive&, const unsigned int);
53 
54 
55 template <typename Archive>
serialize(Archive & ar,const unsigned int version)56 void SinglePlayerSetupData::serialize(Archive& ar, const unsigned int version)
57 {
58     ar  & BOOST_SERIALIZATION_BASE_OBJECT_NVP(GalaxySetupData)
59         & BOOST_SERIALIZATION_NVP(m_new_game)
60         & BOOST_SERIALIZATION_NVP(m_filename)
61         & BOOST_SERIALIZATION_NVP(m_players);
62 }
63 
64 template void SinglePlayerSetupData::serialize<freeorion_bin_oarchive>(freeorion_bin_oarchive&, const unsigned int);
65 template void SinglePlayerSetupData::serialize<freeorion_bin_iarchive>(freeorion_bin_iarchive&, const unsigned int);
66 template void SinglePlayerSetupData::serialize<freeorion_xml_oarchive>(freeorion_xml_oarchive&, const unsigned int);
67 template void SinglePlayerSetupData::serialize<freeorion_xml_iarchive>(freeorion_xml_iarchive&, const unsigned int);
68 
69 
70 template <typename Archive>
serialize(Archive & ar,const unsigned int version)71 void SaveGameUIData::serialize(Archive& ar, const unsigned int version)
72 {
73     TraceLogger() << "SaveGameUIData::serialize " << (Archive::is_saving::value ? "saving" : "loading")
74                   << " version " << version;
75     ar  & BOOST_SERIALIZATION_NVP(map_top)
76         & BOOST_SERIALIZATION_NVP(map_left)
77         & BOOST_SERIALIZATION_NVP(map_zoom_steps_in)
78         & BOOST_SERIALIZATION_NVP(fleets_exploring)
79         & BOOST_SERIALIZATION_NVP(obsolete_ui_event_count);
80     TraceLogger() << "SaveGameUIData::serialize processed obsolete UI event count";
81     if (Archive::is_saving::value || version >= 3) {
82         // serializing / deserializing boost::optional can cause problem, so
83         // store instead in separate containers
84 
85         // std::vector<std::pair<int, boost::optional<std::pair<bool, int>>>> ordered_ship_design_ids_and_obsolete;
86         std::vector<int> ordered_ship_design_ids;
87         std::map<int, std::pair<bool, int>> ids_obsolete;
88 
89         if (Archive::is_saving::value) {
90             // populate temp containers
91             for (auto id_pair_pair : ordered_ship_design_ids_and_obsolete) {
92                 ordered_ship_design_ids.push_back(id_pair_pair.first);
93                 if (id_pair_pair.second)
94                     ids_obsolete[id_pair_pair.first] = id_pair_pair.second.get();
95             }
96             // serialize into archive
97             TraceLogger() << "SaveGameUIData::serialize design data into archive";
98             ar  & BOOST_SERIALIZATION_NVP(ordered_ship_design_ids)
99                 & BOOST_SERIALIZATION_NVP(ids_obsolete);
100             TraceLogger() << "SaveGameUIData::serialize design data into archive completed";
101         } else {    // is_loading with version >= 3
102             // deserialize into temp containers
103             TraceLogger() << "SaveGameUIData::serialize design data from archive";
104             ar  & BOOST_SERIALIZATION_NVP(ordered_ship_design_ids)
105                 & BOOST_SERIALIZATION_NVP(ids_obsolete);
106             TraceLogger() << "SaveGameUIData::serialize design data from archive completed";
107 
108             // extract from temp containers into member storage with boost::optional
109             ordered_ship_design_ids_and_obsolete.clear();
110             for (int id : ordered_ship_design_ids) {
111                 auto it = ids_obsolete.find(id);
112                 auto opt_p_i = it == ids_obsolete.end() ?
113                     boost::optional<std::pair<bool, int>>() :
114                     boost::optional<std::pair<bool, int>>(it->second);
115                 ordered_ship_design_ids_and_obsolete.push_back(std::make_pair(id, opt_p_i));
116             }
117             TraceLogger() << "SaveGameUIData::serialize design data extracted";
118         }
119     } else {    // is_loading with version < 3
120         // (attempt to) directly deserialize / load design ordering and obsolescence
121         try {
122             ar  & BOOST_SERIALIZATION_NVP(ordered_ship_design_ids_and_obsolete);
123         } catch (...) {
124             ErrorLogger() << "Deserializing ship design ids and obsoletes failed. Skipping hull order and obsoletion, and obsolete ship parts.";
125             return;
126         }
127     }
128     ar  & BOOST_SERIALIZATION_NVP(ordered_ship_hull_and_obsolete);
129     TraceLogger() << "SaveGameUIData::serialize ship hull processed";
130     if (Archive::is_saving::value || version >= 4) {
131         std::map<std::string, int> ordered_obsolete_ship_parts;
132 
133         if (Archive::is_saving::value) {
134             // populate temp container
135             ordered_obsolete_ship_parts = std::map<std::string, int>(obsolete_ship_parts.begin(), obsolete_ship_parts.end());
136             // serialize into archive
137             ar & BOOST_SERIALIZATION_NVP(ordered_obsolete_ship_parts);
138         } else {
139             // deserialize into temp container
140             ar & BOOST_SERIALIZATION_NVP(ordered_obsolete_ship_parts);
141 
142             // extract from temp container
143             obsolete_ship_parts = std::unordered_map<std::string, int>(ordered_obsolete_ship_parts.begin(), ordered_obsolete_ship_parts.end());
144         }
145     } else {    // is_loading with version < 4
146         try {
147             ar  & BOOST_SERIALIZATION_NVP(obsolete_ship_parts);
148         } catch (...) {
149             ErrorLogger() << "Deserializing obsolete ship parts failed.";
150         }
151     }
152     TraceLogger() << "SaveGameUIData::serialize obsoleted ship parts processed " << obsolete_ship_parts.size()
153                   << " items. Bucket count " << obsolete_ship_parts.bucket_count();
154 }
155 
156 template void SaveGameUIData::serialize<freeorion_bin_oarchive>(freeorion_bin_oarchive&, const unsigned int);
157 template void SaveGameUIData::serialize<freeorion_bin_iarchive>(freeorion_bin_iarchive&, const unsigned int);
158 template void SaveGameUIData::serialize<freeorion_xml_oarchive>(freeorion_xml_oarchive&, const unsigned int);
159 template void SaveGameUIData::serialize<freeorion_xml_iarchive>(freeorion_xml_iarchive&, const unsigned int);
160 
161 
162 template <typename Archive>
serialize(Archive & ar,const unsigned int version)163 void SaveGameEmpireData::serialize(Archive& ar, const unsigned int version)
164 {
165     ar  & BOOST_SERIALIZATION_NVP(m_empire_id)
166         & BOOST_SERIALIZATION_NVP(m_empire_name)
167         & BOOST_SERIALIZATION_NVP(m_player_name)
168         & BOOST_SERIALIZATION_NVP(m_color);
169     if (version >= 1) {
170         ar & BOOST_SERIALIZATION_NVP(m_authenticated);
171     }
172     if (version >= 2) {
173         ar & BOOST_SERIALIZATION_NVP(m_eliminated);
174         ar & BOOST_SERIALIZATION_NVP(m_won);
175     }
176 }
177 
178 template void SaveGameEmpireData::serialize<freeorion_bin_oarchive>(freeorion_bin_oarchive&, const unsigned int);
179 template void SaveGameEmpireData::serialize<freeorion_bin_iarchive>(freeorion_bin_iarchive&, const unsigned int);
180 template void SaveGameEmpireData::serialize<freeorion_xml_oarchive>(freeorion_xml_oarchive&, const unsigned int);
181 template void SaveGameEmpireData::serialize<freeorion_xml_iarchive>(freeorion_xml_iarchive&, const unsigned int);
182 
183 
184 template <typename Archive>
serialize(Archive & ar,const unsigned int version)185 void PlayerSaveHeaderData::serialize(Archive& ar, const unsigned int version)
186 {
187     ar  & BOOST_SERIALIZATION_NVP(m_name)
188         & BOOST_SERIALIZATION_NVP(m_empire_id)
189         & BOOST_SERIALIZATION_NVP(m_client_type);
190 }
191 
192 template void PlayerSaveHeaderData::serialize<freeorion_bin_oarchive>(freeorion_bin_oarchive&, const unsigned int);
193 template void PlayerSaveHeaderData::serialize<freeorion_bin_iarchive>(freeorion_bin_iarchive&, const unsigned int);
194 template void PlayerSaveHeaderData::serialize<freeorion_xml_oarchive>(freeorion_xml_oarchive&, const unsigned int);
195 template void PlayerSaveHeaderData::serialize<freeorion_xml_iarchive>(freeorion_xml_iarchive&, const unsigned int);
196 
197 
198 template <typename Archive>
serialize(Archive & ar,const unsigned int version)199 void PlayerSaveGameData::serialize(Archive& ar, const unsigned int version)
200 {
201     ar  & BOOST_SERIALIZATION_NVP(m_name)
202         & BOOST_SERIALIZATION_NVP(m_empire_id)
203         & BOOST_SERIALIZATION_NVP(m_orders)
204         & BOOST_SERIALIZATION_NVP(m_ui_data)
205         & BOOST_SERIALIZATION_NVP(m_save_state_string)
206         & BOOST_SERIALIZATION_NVP(m_client_type);
207     if (version == 1) {
208         bool ready{false};
209         ar & boost::serialization::make_nvp("m_ready", ready);
210     }
211 }
212 
213 template void PlayerSaveGameData::serialize<freeorion_bin_oarchive>(freeorion_bin_oarchive&, const unsigned int);
214 template void PlayerSaveGameData::serialize<freeorion_bin_iarchive>(freeorion_bin_iarchive&, const unsigned int);
215 template void PlayerSaveGameData::serialize<freeorion_xml_oarchive>(freeorion_xml_oarchive&, const unsigned int);
216 template void PlayerSaveGameData::serialize<freeorion_xml_iarchive>(freeorion_xml_iarchive&, const unsigned int);
217 
218 
219 template <typename Archive>
serialize(Archive & ar,const unsigned int version)220 void ServerSaveGameData::serialize(Archive& ar, const unsigned int version)
221 {
222     ar  & BOOST_SERIALIZATION_NVP(m_current_turn);
223 }
224 
225 template void ServerSaveGameData::serialize<freeorion_bin_oarchive>(freeorion_bin_oarchive&, const unsigned int);
226 template void ServerSaveGameData::serialize<freeorion_bin_iarchive>(freeorion_bin_iarchive&, const unsigned int);
227 template void ServerSaveGameData::serialize<freeorion_xml_oarchive>(freeorion_xml_oarchive&, const unsigned int);
228 template void ServerSaveGameData::serialize<freeorion_xml_iarchive>(freeorion_xml_iarchive&, const unsigned int);
229 
230 
231 template <typename Archive>
serialize(Archive & ar,const unsigned int version)232 void PlayerSetupData::serialize(Archive& ar, const unsigned int version)
233 {
234     ar  & BOOST_SERIALIZATION_NVP(m_player_name)
235         & BOOST_SERIALIZATION_NVP(m_player_id)
236         & BOOST_SERIALIZATION_NVP(m_empire_name)
237         & BOOST_SERIALIZATION_NVP(m_empire_color)
238         & BOOST_SERIALIZATION_NVP(m_starting_species_name)
239         & BOOST_SERIALIZATION_NVP(m_save_game_empire_id)
240         & BOOST_SERIALIZATION_NVP(m_client_type)
241         & BOOST_SERIALIZATION_NVP(m_player_ready);
242     if (version >= 1) {
243         ar & BOOST_SERIALIZATION_NVP(m_authenticated);
244     }
245     if (version >= 2) {
246         ar & BOOST_SERIALIZATION_NVP(m_starting_team);
247     }
248 }
249 
250 template void PlayerSetupData::serialize<freeorion_bin_oarchive>(freeorion_bin_oarchive&, const unsigned int);
251 template void PlayerSetupData::serialize<freeorion_bin_iarchive>(freeorion_bin_iarchive&, const unsigned int);
252 template void PlayerSetupData::serialize<freeorion_xml_oarchive>(freeorion_xml_oarchive&, const unsigned int);
253 template void PlayerSetupData::serialize<freeorion_xml_iarchive>(freeorion_xml_iarchive&, const unsigned int);
254 
255 
256 template <typename Archive>
serialize(Archive & ar,const unsigned int version)257 void MultiplayerLobbyData::serialize(Archive& ar, const unsigned int version)
258 {
259     ar  & BOOST_SERIALIZATION_BASE_OBJECT_NVP(GalaxySetupData)
260         & BOOST_SERIALIZATION_NVP(m_new_game)
261         & BOOST_SERIALIZATION_NVP(m_players)
262         & BOOST_SERIALIZATION_NVP(m_save_game)
263         & BOOST_SERIALIZATION_NVP(m_save_game_empire_data)
264         & BOOST_SERIALIZATION_NVP(m_any_can_edit)
265         & BOOST_SERIALIZATION_NVP(m_start_locked)
266         & BOOST_SERIALIZATION_NVP(m_start_lock_cause);
267     if (version >= 1) {
268         ar & BOOST_SERIALIZATION_NVP(m_save_game_current_turn);
269     }
270     if (version >= 2) {
271         ar & BOOST_SERIALIZATION_NVP(m_in_game);
272     }
273 }
274 
275 template void MultiplayerLobbyData::serialize<freeorion_bin_oarchive>(freeorion_bin_oarchive&, const unsigned int);
276 template void MultiplayerLobbyData::serialize<freeorion_bin_iarchive>(freeorion_bin_iarchive&, const unsigned int);
277 template void MultiplayerLobbyData::serialize<freeorion_xml_oarchive>(freeorion_xml_oarchive&, const unsigned int);
278 template void MultiplayerLobbyData::serialize<freeorion_xml_iarchive>(freeorion_xml_iarchive&, const unsigned int);
279 
280 
281 template <typename Archive>
serialize(Archive & ar,const unsigned int version)282 void ChatHistoryEntity::serialize(Archive& ar, const unsigned int version)
283 {
284     if (version < 1) {
285         ar  & BOOST_SERIALIZATION_NVP(m_timestamp)
286             & BOOST_SERIALIZATION_NVP(m_player_name)
287             & BOOST_SERIALIZATION_NVP(m_text);
288     } else {
289         ar  & BOOST_SERIALIZATION_NVP(m_text)
290             & BOOST_SERIALIZATION_NVP(m_player_name)
291             & BOOST_SERIALIZATION_NVP(m_text_color)
292             & BOOST_SERIALIZATION_NVP(m_timestamp);
293     }
294 }
295 
296 template void ChatHistoryEntity::serialize<freeorion_bin_oarchive>(freeorion_bin_oarchive&, const unsigned int);
297 template void ChatHistoryEntity::serialize<freeorion_bin_iarchive>(freeorion_bin_iarchive&, const unsigned int);
298 template void ChatHistoryEntity::serialize<freeorion_xml_oarchive>(freeorion_xml_oarchive&, const unsigned int);
299 template void ChatHistoryEntity::serialize<freeorion_xml_iarchive>(freeorion_xml_iarchive&, const unsigned int);
300 
301 
302 template <typename Archive>
serialize(Archive & ar,const unsigned int version)303 void PlayerInfo::serialize(Archive& ar, const unsigned int version)
304 {
305     ar  & BOOST_SERIALIZATION_NVP(name)
306         & BOOST_SERIALIZATION_NVP(empire_id)
307         & BOOST_SERIALIZATION_NVP(client_type)
308         & BOOST_SERIALIZATION_NVP(host);
309 }
310 
311 template void PlayerInfo::serialize<freeorion_bin_oarchive>(freeorion_bin_oarchive&, const unsigned int);
312 template void PlayerInfo::serialize<freeorion_bin_iarchive>(freeorion_bin_iarchive&, const unsigned int);
313 template void PlayerInfo::serialize<freeorion_xml_oarchive>(freeorion_xml_oarchive&, const unsigned int);
314 template void PlayerInfo::serialize<freeorion_xml_iarchive>(freeorion_xml_iarchive&, const unsigned int);
315