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