1 /***********************************************************************
2  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2, or (at your option)
6    any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 ***********************************************************************/
13 
14 /*
15   This file includes the definition of a new savegame format introduced with
16   2.3.0. It is defined by the mandatory option '+version2'. The main load
17   function checks if this option is present. If not, the old (pre-2.3.0)
18   loading routines are used.
19   The format version is also saved in the settings section of the savefile, as an
20   integer (savefile.version). The integer is used to determine the version
21   of the savefile.
22 
23   Structure of this file:
24 
25   - The main functions are savegame2_load() and savegame2_save(). Within
26     former function the savegame version is tested and the requested savegame version is
27     loaded.
28 
29   - The real work is done by savegame2_load_real() and savegame2_save_real().
30     This function call all submodules (settings, players, etc.)
31 
32   - The remaining part of this file is split into several sections:
33      * helper functions
34      * save / load functions for all submodules (and their subsubmodules)
35 
36   - If possible, all functions for load / save submodules should exit in
37     pairs named sg_load_<submodule> and sg_save_<submodule>. If one is not
38     needed please add a comment why.
39 
40   - The submodules can be further divided as:
41     sg_load_<submodule>_<subsubmodule>
42 
43   - If needed (due to static variables in the *.c files) these functions
44     can be located in the corresponding source files (as done for the settings
45     and the event_cache).
46 
47   Creating a savegame:
48 
49   (nothing at the moment)
50 
51   Loading a savegame:
52 
53   - The status of the process is saved within the static variable
54     'sg_success'. This variable is set to TRUE within savegame2_load_real().
55     If you encounter an error use sg_failure_*() to set it to FALSE and
56     return an error message. Furthermore, sg_check_* should be used at the
57     start of each (submodule) function to return if previous functions failed.
58 
59   - While the loading process dependencies between different modules exits.
60     They can be handled within the struct loaddata *loading which is used as
61     first argument for all sg_load_*() function. Please indicate the
62     dependencies within the definition of this struct.
63 
64 */
65 
66 #ifdef HAVE_CONFIG_H
67 #include <fc_config.h>
68 #endif
69 
70 #include <ctype.h>
71 #include <stdarg.h>
72 #include <stdio.h>
73 #include <stdlib.h>
74 #include <string.h>
75 
76 /* utility */
77 #include "bitvector.h"
78 #include "fcintl.h"
79 #include "idex.h"
80 #include "log.h"
81 #include "mem.h"
82 #include "rand.h"
83 #include "registry.h"
84 #include "shared.h"
85 #include "support.h"            /* bool type */
86 #include "timing.h"
87 
88 /* common */
89 #include "achievements.h"
90 #include "ai.h"
91 #include "bitvector.h"
92 #include "capability.h"
93 #include "citizens.h"
94 #include "city.h"
95 #include "game.h"
96 #include "government.h"
97 #include "map.h"
98 #include "mapimg.h"
99 #include "movement.h"
100 #include "multipliers.h"
101 #include "packets.h"
102 #include "research.h"
103 #include "rgbcolor.h"
104 #include "specialist.h"
105 #include "unit.h"
106 #include "unitlist.h"
107 #include "version.h"
108 
109 /* server */
110 #include "barbarian.h"
111 #include "citizenshand.h"
112 #include "citytools.h"
113 #include "cityturn.h"
114 #include "diplhand.h"
115 #include "maphand.h"
116 #include "meta.h"
117 #include "notify.h"
118 #include "plrhand.h"
119 #include "report.h"
120 #include "ruleset.h"
121 #include "sanitycheck.h"
122 #include "savecompat.h"
123 #include "savegame.h"
124 #include "score.h"
125 #include "settings.h"
126 #include "spacerace.h"
127 #include "srv_main.h"
128 #include "stdinhand.h"
129 #include "techtools.h"
130 #include "unittools.h"
131 
132 /* server/advisors */
133 #include "advdata.h"
134 #include "advbuilding.h"
135 #include "infracache.h"
136 
137 /* server/generator */
138 #include "mapgen.h"
139 #include "utilities.h"
140 
141 /* server/scripting */
142 #include "script_server.h"
143 
144 /* ai */
145 #include "aitraits.h"
146 #include "difficulty.h"
147 
148 #include "savegame2.h"
149 
150 extern bool sg_success;
151 
152 #ifdef FREECIV_TESTMATIC
153 #define SAVE_DUMMY_TURN_CHANGE_TIME 1
154 #endif
155 
156 /*
157  * This loops over the entire map to save data. It collects all the data of
158  * a line using GET_XY_CHAR and then executes the macro SECFILE_INSERT_LINE.
159  *
160  * Parameters:
161  *   ptile:         current tile within the line (used by GET_XY_CHAR)
162  *   GET_XY_CHAR:   macro returning the map character for each position
163  *   secfile:       a secfile struct
164  *   secpath, ...:  path as used for sprintf() with arguments; the last item
165  *                  will be the the y coordinate
166  * Example:
167  *   SAVE_MAP_CHAR(ptile, terrain2char(ptile->terrain), file, "map.t%04d");
168  */
169 #define SAVE_MAP_CHAR(ptile, GET_XY_CHAR, secfile, secpath, ...)            \
170 {                                                                           \
171   char _line[game.map.xsize + 1];                                           \
172   int _nat_x, _nat_y;                                                       \
173                                                                             \
174   for (_nat_y = 0; _nat_y < game.map.ysize; _nat_y++) {                     \
175     for (_nat_x = 0; _nat_x < game.map.xsize; _nat_x++) {                   \
176       struct tile *ptile = native_pos_to_tile(_nat_x, _nat_y);              \
177       fc_assert_action(ptile != NULL, continue);                            \
178       _line[_nat_x] = (GET_XY_CHAR);                                        \
179       sg_failure_ret(fc_isprint(_line[_nat_x] & 0x7f),                      \
180                      "Trying to write invalid map data at position "        \
181                      "(%d, %d) for path %s: '%c' (%d)", _nat_x, _nat_y,     \
182                      secpath, _line[_nat_x], _line[_nat_x]);                \
183     }                                                                       \
184     _line[game.map.xsize] = '\0';                                           \
185     secfile_insert_str(secfile, _line, secpath, ## __VA_ARGS__, _nat_y);    \
186   }                                                                         \
187 }
188 
189 /*
190  * This loops over the entire map to load data. It inputs a line of data
191  * using the macro SECFILE_LOOKUP_LINE and then loops using the macro
192  * SET_XY_CHAR to load each char into the map at (map_x, map_y). Internal
193  * variables ch, map_x, map_y, nat_x, and nat_y are allocated within the
194  * macro but definable by the caller.
195  *
196  * Parameters:
197  *   ch:            a variable to hold a char (data for a single position,
198  *                  used by SET_XY_CHAR)
199  *   ptile:         current tile within the line (used by SET_XY_CHAR)
200  *   SET_XY_CHAR:   macro to load the map character at each (map_x, map_y)
201  *   secfile:       a secfile struct
202  *   secpath, ...:  path as used for sprintf() with arguments; the last item
203  *                  will be the the y coordinate
204  * Example:
205  *   LOAD_MAP_CHAR(ch, ptile,
206  *                 map_get_player_tile(ptile, plr)->terrain
207  *                   = char2terrain(ch), file, "player%d.map_t%04d", plrno);
208  *
209  * Note: some (but not all) of the code this is replacing used to skip over
210  *       lines that did not exist. This allowed for backward-compatibility.
211  *       We could add another parameter that specified whether it was OK to
212  *       skip the data, but there's not really much advantage to exiting
213  *       early in this case. Instead, we let any map data type to be empty,
214  *       and just print an informative warning message about it.
215  */
216 #define LOAD_MAP_CHAR(ch, ptile, SET_XY_CHAR, secfile, secpath, ...)        \
217 {                                                                           \
218   int _nat_x, _nat_y;                                                       \
219   bool _printed_warning = FALSE;                                            \
220   for (_nat_y = 0; _nat_y < game.map.ysize; _nat_y++) {                     \
221     const char *_line = secfile_lookup_str(secfile, secpath,                \
222                                            ## __VA_ARGS__, _nat_y);         \
223     if (NULL == _line) {                                                    \
224       char buf[64];                                                         \
225       fc_snprintf(buf, sizeof(buf), secpath, ## __VA_ARGS__, _nat_y);       \
226       log_verbose("Line not found='%s'", buf);                              \
227       _printed_warning = TRUE;                                              \
228       continue;                                                             \
229     } else if (strlen(_line) != game.map.xsize) {                           \
230       char buf[64];                                                         \
231       fc_snprintf(buf, sizeof(buf), secpath, ## __VA_ARGS__, _nat_y);       \
232       log_verbose("Line too short (expected %d got %lu)='%s'",              \
233                   game.map.xsize, (unsigned long) strlen(_line), buf);      \
234       _printed_warning = TRUE;                                              \
235       continue;                                                             \
236     }                                                                       \
237     for (_nat_x = 0; _nat_x < game.map.xsize; _nat_x++) {                   \
238       const char ch = _line[_nat_x];                                        \
239       struct tile *ptile = native_pos_to_tile(_nat_x, _nat_y);              \
240       (SET_XY_CHAR);                                                        \
241     }                                                                       \
242   }                                                                         \
243   if (_printed_warning) {                                                   \
244     /* TRANS: Minor error message. */                                       \
245     log_sg(_("Saved game contains incomplete map data. This can"            \
246              " happen with old saved games, or it may indicate an"          \
247              " invalid saved game file. Proceed at your own risk."));       \
248   }                                                                         \
249 }
250 
251 /* Iterate on the extras half-bytes */
252 #define halfbyte_iterate_extras(e, num_extras_types)                        \
253 {                                                                           \
254   int e;                                                                    \
255   for(e = 0; 4 * e < (num_extras_types); e++) {
256 
257 #define halfbyte_iterate_extras_end                                         \
258   }                                                                         \
259 }
260 
261 /* Iterate on the specials half-bytes */
262 #define halfbyte_iterate_special(s, num_specials_types)                     \
263 {                                                                           \
264   enum tile_special_type s;                                                 \
265   for(s = 0; 4 * s < (num_specials_types); s++) {
266 
267 #define halfbyte_iterate_special_end                                        \
268   }                                                                         \
269 }
270 
271 /* Iterate on the bases half-bytes */
272 #define halfbyte_iterate_bases(b, num_bases_types)                          \
273 {                                                                           \
274   int b;                                                                    \
275   for(b = 0; 4 * b < (num_bases_types); b++) {
276 
277 #define halfbyte_iterate_bases_end                                          \
278   }                                                                         \
279 }
280 
281 /* Iterate on the roads half-bytes */
282 #define halfbyte_iterate_roads(r, num_roads_types)                          \
283 {                                                                           \
284   int r;                                                                    \
285   for(r = 0; 4 * r < (num_roads_types); r++) {
286 
287 #define halfbyte_iterate_roads_end                                          \
288   }                                                                         \
289 }
290 
291 struct savedata {
292   struct section_file *file;
293   char secfile_options[512];
294 
295   /* set by the caller */
296   const char *save_reason;
297   bool scenario;
298 
299   /* Set in sg_save_game(); needed in sg_save_map_*(); ... */
300   bool save_players;
301 };
302 
303 #define TOKEN_SIZE 10
304 
305 #define log_worker      log_verbose
306 
307 static const char savefile_options_default[] =
308   " +version2";
309 /* The following savefile option are added if needed:
310  *  - specials
311  *  - riversoverlay
312  * See also calls to sg_save_savefile_options(). */
313 
314 static const char num_chars[] =
315   "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+";
316 
317 static void savegame2_load_real(struct section_file *file);
318 static void savegame2_save_real(struct section_file *file,
319                                 const char *save_reason,
320                                 bool scenario);
321 static struct loaddata *loaddata_new(struct section_file *file);
322 static void loaddata_destroy(struct loaddata *loading);
323 
324 static struct savedata *savedata_new(struct section_file *file,
325                                      const char *save_reason,
326                                      bool scenario);
327 static void savedata_destroy(struct savedata *saving);
328 
329 static enum unit_orders char2order(char order);
330 static char order2char(enum unit_orders order);
331 static enum direction8 char2dir(char dir);
332 static char dir2char(enum direction8 dir);
333 static char activity2char(enum unit_activity activity);
334 static enum unit_activity char2activity(char activity);
335 static char *quote_block(const void *const data, int length);
336 static int unquote_block(const char *const quoted_, void *dest,
337                          int dest_length);
338 static void worklist_load(struct section_file *file, struct worklist *pwl,
339                           const char *path, ...);
340 static void worklist_save(struct section_file *file,
341                           const struct worklist *pwl,
342                           int max_length, const char *path, ...);
343 static void unit_ordering_calc(void);
344 static void unit_ordering_apply(void);
345 static void sg_extras_set(bv_extras *extras, char ch, struct extra_type **idx);
346 static char sg_extras_get(bv_extras extras, const int *idx);
347 static void sg_special_set(struct tile *ptile, bv_extras *extras, char ch,
348                            const enum tile_special_type *idx,
349                            bool rivers_overlay);
350 static void sg_bases_set(bv_extras *extras, char ch, struct base_type **idx);
351 static void sg_roads_set(bv_extras *extras, char ch, struct road_type **idx);
352 static struct resource *char2resource(char c);
353 static char resource2char(const struct resource *presource);
354 static char num2char(unsigned int num);
355 static int char2num(char ch);
356 static struct terrain *char2terrain(char ch);
357 static char terrain2char(const struct terrain *pterrain);
358 static Tech_type_id technology_load(struct section_file *file,
359                                     const char* path, int plrno);
360 static void technology_save(struct section_file *file,
361                             const char* path, int plrno, Tech_type_id tech);
362 
363 static void sg_load_ruleset(struct loaddata *loading);
364 static void sg_load_savefile(struct loaddata *loading);
365 static void sg_save_savefile(struct savedata *saving);
366 static void sg_save_savefile_options(struct savedata *saving,
367                                      const char *option);
368 
369 static void sg_load_game(struct loaddata *loading);
370 static void sg_save_game(struct savedata *saving);
371 
372 static void sg_load_ruledata(struct loaddata *loading);
373 static void sg_save_ruledata(struct savedata *saving);
374 
375 static void sg_load_random(struct loaddata *loading);
376 static void sg_save_random(struct savedata *saving);
377 
378 static void sg_load_script(struct loaddata *loading);
379 static void sg_save_script(struct savedata *saving);
380 
381 static void sg_load_scenario(struct loaddata *loading);
382 static void sg_save_scenario(struct savedata *saving);
383 
384 static void sg_load_settings(struct loaddata *loading);
385 static void sg_save_settings(struct savedata *saving);
386 
387 static void sg_load_map(struct loaddata *loading);
388 static void sg_save_map(struct savedata *saving);
389 static void sg_load_map_tiles(struct loaddata *loading);
390 static void sg_save_map_tiles(struct savedata *saving);
391 static void sg_load_map_tiles_extras(struct loaddata *loading);
392 static void sg_save_map_tiles_extras(struct savedata *saving);
393 static void sg_load_map_tiles_bases(struct loaddata *loading);
394 static void sg_load_map_tiles_roads(struct loaddata *loading);
395 static void sg_load_map_tiles_specials(struct loaddata *loading,
396                                        bool rivers_overlay);
397 static void sg_load_map_tiles_resources(struct loaddata *loading);
398 static void sg_save_map_tiles_resources(struct savedata *saving);
399 
400 static void sg_load_map_startpos(struct loaddata *loading);
401 static void sg_save_map_startpos(struct savedata *saving);
402 static void sg_load_map_owner(struct loaddata *loading);
403 static void sg_save_map_owner(struct savedata *saving);
404 static void sg_load_map_worked(struct loaddata *loading);
405 static void sg_save_map_worked(struct savedata *saving);
406 static void sg_load_map_known(struct loaddata *loading);
407 static void sg_save_map_known(struct savedata *saving);
408 
409 static void sg_load_players_basic(struct loaddata *loading);
410 static void sg_load_players(struct loaddata *loading);
411 static void sg_load_player_main(struct loaddata *loading,
412                                 struct player *plr);
413 static void sg_load_player_cities(struct loaddata *loading,
414                                   struct player *plr);
415 static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
416                                 struct city *pcity, const char *citystr);
417 static void sg_load_player_city_citizens(struct loaddata *loading,
418                                          struct player *plr,
419                                          struct city *pcity,
420                                          const char *citystr);
421 static void sg_load_player_units(struct loaddata *loading,
422                                  struct player *plr);
423 static bool sg_load_player_unit(struct loaddata *loading,
424                                 struct player *plr, struct unit *punit,
425                                 const char *unitstr);
426 static void sg_load_player_units_transport(struct loaddata *loading,
427                                            struct player *plr);
428 static void sg_load_player_attributes(struct loaddata *loading,
429                                       struct player *plr);
430 static void sg_load_player_vision(struct loaddata *loading,
431                                   struct player *plr);
432 static bool sg_load_player_vision_city(struct loaddata *loading,
433                                        struct player *plr,
434                                        struct vision_site *pdcity,
435                                        const char *citystr);
436 static void sg_save_players(struct savedata *saving);
437 static void sg_save_player_main(struct savedata *saving,
438                                 struct player *plr);
439 static void sg_save_player_cities(struct savedata *saving,
440                                   struct player *plr);
441 static void sg_save_player_units(struct savedata *saving,
442                                  struct player *plr);
443 static void sg_save_player_attributes(struct savedata *saving,
444                                       struct player *plr);
445 static void sg_save_player_vision(struct savedata *saving,
446                                   struct player *plr);
447 
448 static void sg_load_researches(struct loaddata *loading);
449 static void sg_save_researches(struct savedata *saving);
450 
451 static void sg_load_event_cache(struct loaddata *loading);
452 static void sg_save_event_cache(struct savedata *saving);
453 
454 static void sg_save_treaties(struct savedata *saving);
455 
456 static void sg_load_treaties(struct loaddata *loading);
457 
458 static void sg_load_history(struct loaddata *loading);
459 static void sg_save_history(struct savedata *saving);
460 
461 static void sg_load_mapimg(struct loaddata *loading);
462 static void sg_save_mapimg(struct savedata *saving);
463 
464 static void sg_load_sanitycheck(struct loaddata *loading);
465 static void sg_save_sanitycheck(struct savedata *saving);
466 
467 
468 /****************************************************************************
469   Main entry point for loading a game.
470   Called only in ./server/stdinhand.c:load_command().
471   The entire ruleset is always sent afterwards->
472 ****************************************************************************/
savegame2_load(struct section_file * file)473 void savegame2_load(struct section_file *file)
474 {
475   const char *savefile_options;
476 
477   fc_assert_ret(file != NULL);
478 
479 #ifdef DEBUG_TIMERS
480   struct timer *loadtimer = timer_new(TIMER_CPU, TIMER_DEBUG);
481   timer_start(loadtimer);
482 #endif
483 
484   savefile_options = secfile_lookup_str(file, "savefile.options");
485 
486   if (!savefile_options) {
487     log_error("Missing savefile options. Can not load the savegame.");
488     return;
489   }
490 
491   if (!has_capabilities("+version2", savefile_options)) {
492     /* load old format (freeciv 2.2.x) */
493     log_verbose("loading savefile in old format ...");
494     secfile_allow_digital_boolean(file, TRUE);
495     legacy_game_load(file);
496   } else {
497     /* load new format (freeciv 2.2.99 and newer) */
498     log_verbose("loading savefile in new format ...");
499     savegame2_load_real(file);
500   }
501 
502   players_iterate(pplayer) {
503     unit_list_iterate(pplayer->units, punit) {
504       CALL_PLR_AI_FUNC(unit_got, pplayer, punit);
505     } unit_list_iterate_end;
506 
507     city_list_iterate(pplayer->cities, pcity) {
508       CALL_PLR_AI_FUNC(city_got, pplayer, pplayer, pcity);
509     } city_list_iterate_end;
510   } players_iterate_end;
511 
512 #ifdef DEBUG_TIMERS
513   timer_stop(loadtimer);
514   log_debug("Loading secfile in %.3f seconds.", timer_read_seconds(loadtimer));
515   timer_destroy(loadtimer);
516 #endif /* DEBUG_TIMERS */
517 }
518 
519 /****************************************************************************
520   Main entry point for saving a game.
521   Called only in ./server/srv_main.c:save_game().
522 ****************************************************************************/
savegame2_save(struct section_file * file,const char * save_reason,bool scenario)523 void savegame2_save(struct section_file *file, const char *save_reason,
524                     bool scenario)
525 {
526   fc_assert_ret(file != NULL);
527 
528 #ifdef DEBUG_TIMERS
529   struct timer *savetimer = timer_new(TIMER_CPU, TIMER_DEBUG);
530   timer_start(savetimer);
531 #endif
532 
533   log_verbose("saving game in new format ...");
534   savegame2_save_real(file, save_reason, scenario);
535 
536 #ifdef DEBUG_TIMERS
537   timer_stop(savetimer);
538   log_debug("Creating secfile in %.3f seconds.", timer_read_seconds(savetimer));
539   timer_destroy(savetimer);
540 #endif /* DEBUG_TIMERS */
541 }
542 
543 /* =======================================================================
544  * Basic load / save functions.
545  * ======================================================================= */
546 
547 /****************************************************************************
548   Really loading the savegame.
549 ****************************************************************************/
savegame2_load_real(struct section_file * file)550 static void savegame2_load_real(struct section_file *file)
551 {
552   struct loaddata *loading;
553   bool was_send_city_suppressed, was_send_tile_suppressed;
554 
555   /* initialise loading */
556   was_send_city_suppressed = send_city_suppression(TRUE);
557   was_send_tile_suppressed = send_tile_suppression(TRUE);
558   loading = loaddata_new(file);
559   sg_success = TRUE;
560 
561   /* Load the savegame data. */
562   /* Set up correct ruleset */
563   sg_load_ruleset(loading);
564   /* [compat] */
565   sg_load_compat(loading);
566   /* [savefile] */
567   sg_load_savefile(loading);
568   /* [game] */
569   sg_load_game(loading);
570   /* [scenario] */
571   sg_load_scenario(loading);
572   /* [random] */
573   sg_load_random(loading);
574   /* [settings] */
575   sg_load_settings(loading);
576   /* [ruledata] */
577   sg_load_ruledata(loading);
578   /* [players] (basic data) */
579   sg_load_players_basic(loading);
580   /* [map]; needs width and height loaded by [settings]  */
581   sg_load_map(loading);
582   /* [research] */
583   sg_load_researches(loading);
584   /* [player<i>] */
585   sg_load_players(loading);
586   /* [event_cache] */
587   sg_load_event_cache(loading);
588   /* [treaties] */
589   sg_load_treaties(loading);
590   /* [history] */
591   sg_load_history(loading);
592   /* [mapimg] */
593   sg_load_mapimg(loading);
594   /* [script] -- must come last as may reference game objects */
595   sg_load_script(loading);
596 
597   /* Sanity checks for the loaded game. */
598   sg_load_sanitycheck(loading);
599 
600   /* deinitialise loading */
601   loaddata_destroy(loading);
602   send_tile_suppression(was_send_tile_suppressed);
603   send_city_suppression(was_send_city_suppressed);
604 
605   if (!sg_success) {
606     log_error("Failure loading savegame!");
607     /* Try to get the server back to a vaguely sane state */
608     server_game_free();
609     server_game_init();
610     load_rulesets(NULL, TRUE, FALSE);
611   }
612 }
613 
614 /****************************************************************************
615   Really save the game to a file.
616 ****************************************************************************/
savegame2_save_real(struct section_file * file,const char * save_reason,bool scenario)617 static void savegame2_save_real(struct section_file *file,
618                                 const char *save_reason,
619                                 bool scenario)
620 {
621   struct savedata *saving;
622 
623   /* initialise loading */
624   saving = savedata_new(file, save_reason, scenario);
625   sg_success = TRUE;
626 
627   /* [scenario] */
628   /* This should be first section so scanning through all scenarios just for
629    * names and descriptions would go faster. */
630   sg_save_scenario(saving);
631   /* [savefile] */
632   sg_save_savefile(saving);
633   /* [game] */
634   sg_save_game(saving);
635   /* [random] */
636   sg_save_random(saving);
637   /* [script] */
638   sg_save_script(saving);
639   /* [settings] */
640   sg_save_settings(saving);
641   /* [ruledata] */
642   sg_save_ruledata(saving);
643   /* [map] */
644   sg_save_map(saving);
645   /* [player<i>] */
646   sg_save_players(saving);
647   /* [research] */
648   sg_save_researches(saving);
649   /* [event_cache] */
650   sg_save_event_cache(saving);
651   /* [treaty<i>] */
652   sg_save_treaties(saving);
653   /* [history] */
654   sg_save_history(saving);
655   /* [mapimg] */
656   sg_save_mapimg(saving);
657 
658   /* Sanity checks for the saved game. */
659   sg_save_sanitycheck(saving);
660 
661   /* deinitialise saving */
662   savedata_destroy(saving);
663 
664   if (!sg_success) {
665     log_error("Failure saving savegame!");
666   }
667 }
668 
669 /****************************************************************************
670   Create new loaddata item for given section file.
671 ****************************************************************************/
loaddata_new(struct section_file * file)672 static struct loaddata *loaddata_new(struct section_file *file)
673 {
674   struct loaddata *loading = calloc(1, sizeof(*loading));
675   loading->file = file;
676   loading->secfile_options = NULL;
677 
678   loading->improvement.order = NULL;
679   loading->improvement.size = -1;
680   loading->technology.order = NULL;
681   loading->technology.size = -1;
682   loading->trait.order = NULL;
683   loading->trait.size = -1;
684   loading->extra.order = NULL;
685   loading->extra.size = -1;
686   loading->multiplier.order = NULL;
687   loading->multiplier.size = -1;
688   loading->special.order = NULL;
689   loading->special.size = -1;
690   loading->base.order = NULL;
691   loading->base.size = -1;
692   loading->road.order = NULL;
693   loading->road.size = -1;
694   loading->specialist.order = NULL;
695   loading->specialist.size = -1;
696   loading->ds_t.order = NULL;
697   loading->ds_t.size = -1;
698 
699   loading->server_state = S_S_INITIAL;
700   loading->rstate = fc_rand_state();
701   loading->worked_tiles = NULL;
702 
703   return loading;
704 }
705 
706 /****************************************************************************
707   Free resources allocated for loaddata item.
708 ****************************************************************************/
loaddata_destroy(struct loaddata * loading)709 static void loaddata_destroy(struct loaddata *loading)
710 {
711   if (loading->improvement.order != NULL) {
712     free(loading->improvement.order);
713   }
714 
715   if (loading->technology.order != NULL) {
716     free(loading->technology.order);
717   }
718 
719   if (loading->trait.order != NULL) {
720     free(loading->trait.order);
721   }
722 
723   if (loading->extra.order != NULL) {
724     free(loading->extra.order);
725   }
726 
727   if (loading->multiplier.order != NULL) {
728     free(loading->multiplier.order);
729   }
730 
731   if (loading->special.order != NULL) {
732     free(loading->special.order);
733   }
734 
735   if (loading->base.order != NULL) {
736     free(loading->base.order);
737   }
738 
739   if (loading->road.order != NULL) {
740     free(loading->road.order);
741   }
742 
743   if (loading->specialist.order != NULL) {
744     free(loading->specialist.order);
745   }
746 
747   if (loading->ds_t.order != NULL) {
748     free(loading->ds_t.order);
749   }
750 
751   if (loading->worked_tiles != NULL) {
752     free(loading->worked_tiles);
753   }
754 
755   free(loading);
756 }
757 
758 /****************************************************************************
759   Create new savedata item for given file.
760 ****************************************************************************/
savedata_new(struct section_file * file,const char * save_reason,bool scenario)761 static struct savedata *savedata_new(struct section_file *file,
762                                      const char *save_reason,
763                                      bool scenario)
764 {
765   struct savedata *saving = calloc(1, sizeof(*saving));
766   saving->file = file;
767   saving->secfile_options[0] = '\0';
768 
769   saving->save_reason = save_reason;
770   saving->scenario = scenario;
771 
772   saving->save_players = FALSE;
773 
774   return saving;
775 }
776 
777 /****************************************************************************
778   Free resources allocated for savedata item
779 ****************************************************************************/
savedata_destroy(struct savedata * saving)780 static void savedata_destroy(struct savedata *saving)
781 {
782   free(saving);
783 }
784 
785 /* =======================================================================
786  * Helper functions.
787  * ======================================================================= */
788 
789 /****************************************************************************
790   Returns an order for a character identifier.  See also order2char.
791 ****************************************************************************/
char2order(char order)792 static enum unit_orders char2order(char order)
793 {
794   switch (order) {
795   case 'm':
796   case 'M':
797     return ORDER_MOVE;
798   case 'w':
799   case 'W':
800     return ORDER_FULL_MP;
801   case 'b':
802   case 'B':
803     return ORDER_BUILD_CITY;
804   case 'a':
805   case 'A':
806     return ORDER_ACTIVITY;
807   case 'd':
808   case 'D':
809     return ORDER_DISBAND;
810   case 'u':
811   case 'U':
812     return ORDER_BUILD_WONDER;
813   case 't':
814   case 'T':
815     return ORDER_TRADE_ROUTE;
816   case 'h':
817   case 'H':
818     return ORDER_HOMECITY;
819   case 'x':
820   case 'X':
821     return ORDER_ACTION_MOVE;
822   }
823 
824   /* This can happen if the savegame is invalid. */
825   return ORDER_LAST;
826 }
827 
828 /****************************************************************************
829   Returns a character identifier for an order.  See also char2order.
830 ****************************************************************************/
order2char(enum unit_orders order)831 static char order2char(enum unit_orders order)
832 {
833   switch (order) {
834   case ORDER_MOVE:
835     return 'm';
836   case ORDER_FULL_MP:
837     return 'w';
838   case ORDER_ACTIVITY:
839     return 'a';
840   case ORDER_BUILD_CITY:
841     return 'b';
842   case ORDER_DISBAND:
843     return 'd';
844   case ORDER_BUILD_WONDER:
845     return 'u';
846   case ORDER_TRADE_ROUTE:
847     return 't';
848   case ORDER_HOMECITY:
849     return 'h';
850   case ORDER_ACTION_MOVE:
851     return 'x';
852   case ORDER_LAST:
853     break;
854   }
855 
856   fc_assert(FALSE);
857   return '?';
858 }
859 
860 /****************************************************************************
861   Returns a direction for a character identifier.  See also dir2char.
862 ****************************************************************************/
char2dir(char dir)863 static enum direction8 char2dir(char dir)
864 {
865   /* Numberpad values for the directions. */
866   switch (dir) {
867   case '1':
868     return DIR8_SOUTHWEST;
869   case '2':
870     return DIR8_SOUTH;
871   case '3':
872     return DIR8_SOUTHEAST;
873   case '4':
874     return DIR8_WEST;
875   case '6':
876     return DIR8_EAST;
877   case '7':
878     return DIR8_NORTHWEST;
879   case '8':
880     return DIR8_NORTH;
881   case '9':
882     return DIR8_NORTHEAST;
883   }
884 
885   /* This can happen if the savegame is invalid. */
886   return direction8_invalid();
887 }
888 
889 /****************************************************************************
890   Returns a character identifier for a direction.  See also char2dir.
891 ****************************************************************************/
dir2char(enum direction8 dir)892 static char dir2char(enum direction8 dir)
893 {
894   /* Numberpad values for the directions. */
895   switch (dir) {
896   case DIR8_NORTH:
897     return '8';
898   case DIR8_SOUTH:
899     return '2';
900   case DIR8_EAST:
901     return '6';
902   case DIR8_WEST:
903     return '4';
904   case DIR8_NORTHEAST:
905     return '9';
906   case DIR8_NORTHWEST:
907     return '7';
908   case DIR8_SOUTHEAST:
909     return '3';
910   case DIR8_SOUTHWEST:
911     return '1';
912   }
913 
914   fc_assert(FALSE);
915   return '?';
916 }
917 
918 /****************************************************************************
919   Returns a character identifier for an activity.  See also char2activity.
920 ****************************************************************************/
activity2char(enum unit_activity activity)921 static char activity2char(enum unit_activity activity)
922 {
923   switch (activity) {
924   case ACTIVITY_IDLE:
925     return 'w';
926   case ACTIVITY_POLLUTION:
927     return 'p';
928   case ACTIVITY_OLD_ROAD:
929     return 'r';
930   case ACTIVITY_MINE:
931     return 'm';
932   case ACTIVITY_IRRIGATE:
933     return 'i';
934   case ACTIVITY_FORTIFIED:
935     return 'f';
936   case ACTIVITY_FORTRESS:
937     return 't';
938   case ACTIVITY_SENTRY:
939     return 's';
940   case ACTIVITY_OLD_RAILROAD:
941     return 'l';
942   case ACTIVITY_PILLAGE:
943     return 'e';
944   case ACTIVITY_GOTO:
945     return 'g';
946   case ACTIVITY_EXPLORE:
947     return 'x';
948   case ACTIVITY_TRANSFORM:
949     return 'o';
950   case ACTIVITY_AIRBASE:
951     return 'a';
952   case ACTIVITY_FORTIFYING:
953     return 'y';
954   case ACTIVITY_FALLOUT:
955     return 'u';
956   case ACTIVITY_BASE:
957     return 'b';
958   case ACTIVITY_GEN_ROAD:
959     return 'R';
960   case ACTIVITY_CONVERT:
961     return 'c';
962   case ACTIVITY_UNKNOWN:
963   case ACTIVITY_PATROL_UNUSED:
964     return '?';
965   case ACTIVITY_LAST:
966     break;
967   }
968 
969   fc_assert(FALSE);
970   return '?';
971 }
972 
973 /****************************************************************************
974   Returns an activity for a character identifier.  See also activity2char.
975 ****************************************************************************/
char2activity(char activity)976 static enum unit_activity char2activity(char activity)
977 {
978   enum unit_activity a;
979 
980   for (a = 0; a < ACTIVITY_LAST; a++) {
981     char achar = activity2char(a);
982 
983     if (activity == achar) {
984       return a;
985     }
986   }
987 
988   /* This can happen if the savegame is invalid. */
989   return ACTIVITY_LAST;
990 }
991 
992 /****************************************************************************
993   Quote the memory block denoted by data and length so it consists only of
994   " a-f0-9:". The returned string has to be freed by the caller using free().
995 ****************************************************************************/
quote_block(const void * const data,int length)996 static char *quote_block(const void *const data, int length)
997 {
998   char *buffer = fc_malloc(length * 3 + 10);
999   size_t offset;
1000   int i;
1001 
1002   sprintf(buffer, "%d:", length);
1003   offset = strlen(buffer);
1004 
1005   for (i = 0; i < length; i++) {
1006     sprintf(buffer + offset, "%02x ", ((unsigned char *) data)[i]);
1007     offset += 3;
1008   }
1009   return buffer;
1010 }
1011 
1012 /****************************************************************************
1013   Unquote a string. The unquoted data is written into dest. If the unquoted
1014   data will be larger than dest_length the function aborts. It returns the
1015   actual length of the unquoted block.
1016 ****************************************************************************/
unquote_block(const char * const quoted_,void * dest,int dest_length)1017 static int unquote_block(const char *const quoted_, void *dest,
1018                          int dest_length)
1019 {
1020   int i, length, parsed, tmp;
1021   char *endptr;
1022   const char *quoted = quoted_;
1023 
1024   parsed = sscanf(quoted, "%d", &length);
1025   fc_assert_ret_val(1 == parsed, 0);
1026 
1027   if (length > dest_length) {
1028     return 0;
1029   }
1030   quoted = strchr(quoted, ':');
1031   fc_assert_ret_val(quoted != NULL, 0);
1032   quoted++;
1033 
1034   for (i = 0; i < length; i++) {
1035     tmp = strtol(quoted, &endptr, 16);
1036     fc_assert_ret_val((endptr - quoted) == 2, 0);
1037     fc_assert_ret_val(*endptr == ' ', 0);
1038     fc_assert_ret_val((tmp & 0xff) == tmp, 0);
1039     ((unsigned char *) dest)[i] = tmp;
1040     quoted += 3;
1041   }
1042   return length;
1043 }
1044 
1045 /****************************************************************************
1046   Load the worklist elements specified by path to the worklist pointed to
1047   by 'pwl'. 'pwl' should be a pointer to an existing worklist.
1048 ****************************************************************************/
worklist_load(struct section_file * file,struct worklist * pwl,const char * path,...)1049 static void worklist_load(struct section_file *file, struct worklist *pwl,
1050                           const char *path, ...)
1051 {
1052   int i;
1053   const char *kind;
1054   const char *name;
1055   char path_str[1024];
1056   va_list ap;
1057 
1058   /* The first part of the registry path is taken from the varargs to the
1059    * function. */
1060   va_start(ap, path);
1061   fc_vsnprintf(path_str, sizeof(path_str), path, ap);
1062   va_end(ap);
1063 
1064   worklist_init(pwl);
1065   pwl->length = secfile_lookup_int_default(file, 0,
1066                                            "%s.wl_length", path_str);
1067 
1068   for (i = 0; i < pwl->length; i++) {
1069     kind = secfile_lookup_str(file, "%s.wl_kind%d", path_str, i);
1070 
1071     /* We lookup the production value by name. An invalid entry isn't a
1072      * fatal error; we just truncate the worklist. */
1073     name = secfile_lookup_str_default(file, "-", "%s.wl_value%d",
1074                                       path_str, i);
1075     pwl->entries[i] = universal_by_rule_name(kind, name);
1076     if (pwl->entries[i].kind == universals_n_invalid()) {
1077       log_sg("%s.wl_value%d: unknown \"%s\" \"%s\".", path_str, i, kind,
1078              name);
1079       pwl->length = i;
1080       break;
1081     }
1082   }
1083 }
1084 
1085 /****************************************************************************
1086   Save the worklist elements specified by path from the worklist pointed to
1087   by 'pwl'. 'pwl' should be a pointer to an existing worklist.
1088 ****************************************************************************/
worklist_save(struct section_file * file,const struct worklist * pwl,int max_length,const char * path,...)1089 static void worklist_save(struct section_file *file,
1090                           const struct worklist *pwl,
1091                           int max_length, const char *path, ...)
1092 {
1093   char path_str[1024];
1094   int i;
1095   va_list ap;
1096 
1097   /* The first part of the registry path is taken from the varargs to the
1098    * function. */
1099   va_start(ap, path);
1100   fc_vsnprintf(path_str, sizeof(path_str), path, ap);
1101   va_end(ap);
1102 
1103   secfile_insert_int(file, pwl->length, "%s.wl_length", path_str);
1104 
1105   for (i = 0; i < pwl->length; i++) {
1106     const struct universal *entry = pwl->entries + i;
1107     secfile_insert_str(file, universal_type_rule_name(entry),
1108                        "%s.wl_kind%d", path_str, i);
1109     secfile_insert_str(file, universal_rule_name(entry),
1110                        "%s.wl_value%d", path_str, i);
1111   }
1112 
1113   fc_assert_ret(max_length <= MAX_LEN_WORKLIST);
1114 
1115   /* We want to keep savegame in tabular format, so each line has to be
1116    * of equal length. Fill table up to maximum worklist size. */
1117   for (i = pwl->length ; i < max_length; i++) {
1118     secfile_insert_str(file, "", "%s.wl_kind%d", path_str, i);
1119     secfile_insert_str(file, "", "%s.wl_value%d", path_str, i);
1120   }
1121 }
1122 
1123 /****************************************************************************
1124   Assign values to ord_city and ord_map for each unit, so the values can be
1125   saved.
1126 ****************************************************************************/
unit_ordering_calc(void)1127 static void unit_ordering_calc(void)
1128 {
1129   int j;
1130 
1131   players_iterate(pplayer) {
1132     /* to avoid junk values for unsupported units: */
1133     unit_list_iterate(pplayer->units, punit) {
1134       punit->server.ord_city = 0;
1135     } unit_list_iterate_end;
1136     city_list_iterate(pplayer->cities, pcity) {
1137       j = 0;
1138       unit_list_iterate(pcity->units_supported, punit) {
1139         punit->server.ord_city = j++;
1140       } unit_list_iterate_end;
1141     } city_list_iterate_end;
1142   } players_iterate_end;
1143 
1144   whole_map_iterate(ptile) {
1145     j = 0;
1146     unit_list_iterate(ptile->units, punit) {
1147       punit->server.ord_map = j++;
1148     } unit_list_iterate_end;
1149   } whole_map_iterate_end;
1150 }
1151 
1152 /****************************************************************************
1153   For each city and tile, sort unit lists according to ord_city and ord_map
1154   values.
1155 ****************************************************************************/
unit_ordering_apply(void)1156 static void unit_ordering_apply(void)
1157 {
1158   players_iterate(pplayer) {
1159     city_list_iterate(pplayer->cities, pcity) {
1160       unit_list_sort_ord_city(pcity->units_supported);
1161     }
1162     city_list_iterate_end;
1163   } players_iterate_end;
1164 
1165   whole_map_iterate(ptile) {
1166     unit_list_sort_ord_map(ptile->units);
1167   } whole_map_iterate_end;
1168 }
1169 
1170 /****************************************************************************
1171   Helper function for loading extras from a savegame.
1172 
1173   'ch' gives the character loaded from the savegame. Extras are packed
1174   in four to a character in hex notation. 'index' is a mapping of
1175   savegame bit -> base bit.
1176 ****************************************************************************/
sg_extras_set(bv_extras * extras,char ch,struct extra_type ** idx)1177 static void sg_extras_set(bv_extras *extras, char ch, struct extra_type **idx)
1178 {
1179   int i, bin;
1180   const char *pch = strchr(hex_chars, ch);
1181 
1182   if (!pch || ch == '\0') {
1183     log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1184     bin = 0;
1185   } else {
1186     bin = pch - hex_chars;
1187   }
1188 
1189   for (i = 0; i < 4; i++) {
1190     struct extra_type *pextra = idx[i];
1191 
1192     if (pextra == NULL) {
1193       continue;
1194     }
1195     if ((bin & (1 << i))
1196         && (game.map.server.have_huts || !is_extra_caused_by(pextra, EC_HUT))) {
1197       BV_SET(*extras, extra_index(pextra));
1198     }
1199   }
1200 }
1201 
1202 /****************************************************************************
1203   Helper function for saving extras into a savegame.
1204 
1205   Extras are packed in four to a character in hex notation. 'index'
1206   specifies which set of extras are included in this character.
1207 ****************************************************************************/
sg_extras_get(bv_extras extras,const int * idx)1208 static char sg_extras_get(bv_extras extras, const int *idx)
1209 {
1210   int i, bin = 0;
1211 
1212   for (i = 0; i < 4; i++) {
1213     int extra = idx[i];
1214 
1215     if (extra < 0) {
1216       break;
1217     }
1218 
1219     if (BV_ISSET(extras, extra)) {
1220       bin |= (1 << i);
1221     }
1222   }
1223 
1224   return hex_chars[bin];
1225 }
1226 
1227 /****************************************************************************
1228   Complicated helper function for loading specials from a savegame.
1229 
1230   'ch' gives the character loaded from the savegame. Specials are packed
1231   in four to a character in hex notation. 'index' is a mapping of
1232   savegame bit -> special bit. S_LAST is used to mark unused savegame bits.
1233 ****************************************************************************/
sg_special_set(struct tile * ptile,bv_extras * extras,char ch,const enum tile_special_type * idx,bool rivers_overlay)1234 static void sg_special_set(struct tile *ptile, bv_extras *extras, char ch,
1235                            const enum tile_special_type *idx,
1236                            bool rivers_overlay)
1237 {
1238   int i, bin;
1239   const char *pch = strchr(hex_chars, ch);
1240 
1241   if (!pch || ch == '\0') {
1242     log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1243     bin = 0;
1244   } else {
1245     bin = pch - hex_chars;
1246   }
1247 
1248   for (i = 0; i < 4; i++) {
1249     enum tile_special_type sp = idx[i];
1250 
1251     if (sp == S_LAST) {
1252       continue;
1253     }
1254     if (rivers_overlay && sp != S_OLD_RIVER) {
1255       continue;
1256     }
1257 
1258     if (sp == S_HUT && !game.map.server.have_huts) {
1259       /* It would be logical to have this in the saving side -
1260        * really not saving the huts in the first place, BUT
1261        * 1) They have been saved by older versions, so we
1262        *    have to deal with such savegames.
1263        * 2) This makes scenario author less likely to lose
1264        *    one's work completely after carefully placing huts
1265        *    and then saving with 'have_huts' disabled. */
1266       continue;
1267     }
1268 
1269     if (bin & (1 << i)) {
1270       if (sp == S_OLD_ROAD) {
1271         struct road_type *proad;
1272 
1273         proad = road_by_compat_special(ROCO_ROAD);
1274         if (proad) {
1275           BV_SET(*extras, extra_index(road_extra_get(proad)));
1276         }
1277       } else if (sp == S_OLD_RAILROAD) {
1278         struct road_type *proad;
1279 
1280         proad = road_by_compat_special(ROCO_RAILROAD);
1281         if (proad) {
1282           BV_SET(*extras, extra_index(road_extra_get(proad)));
1283         }
1284       } else if (sp == S_OLD_RIVER) {
1285         struct road_type *proad;
1286 
1287         proad = road_by_compat_special(ROCO_RIVER);
1288         if (proad) {
1289           BV_SET(*extras, extra_index(road_extra_get(proad)));
1290         }
1291       } else {
1292         struct extra_type *pextra = NULL;
1293         enum extra_cause cause = EC_COUNT;
1294 
1295         /* Converting from old hardcoded specials to as sensible extra as we can */
1296         switch (sp) {
1297         case S_IRRIGATION:
1298         case S_FARMLAND:
1299           /* If old savegame has both irrigation and farmland, EC_IRRIGATION
1300            * gets applied twice, which hopefully has the correct result. */
1301           cause = EC_IRRIGATION;
1302           break;
1303         case S_MINE:
1304           cause = EC_MINE;
1305           break;
1306         case S_POLLUTION:
1307           cause = EC_POLLUTION;
1308           break;
1309         case S_HUT:
1310           cause = EC_HUT;
1311           break;
1312         case S_FALLOUT:
1313           cause = EC_FALLOUT;
1314           break;
1315         default:
1316           pextra = extra_type_by_rule_name(special_rule_name(sp));
1317           break;
1318         }
1319 
1320         if (cause != EC_COUNT) {
1321           struct tile *vtile = tile_virtual_new(ptile);
1322 
1323           /* Do not let the extras already set to the real tile mess with setup
1324            * of the player tiles if that's what we're doing. */
1325           vtile->extras = *extras;
1326 
1327           /* It's ok not to know which player or which unit originally built the extra -
1328            * in the rules used when specials were saved these could not have made any
1329            * difference. */
1330           pextra = next_extra_for_tile(vtile, cause, NULL, NULL);
1331 
1332           tile_virtual_destroy(vtile);
1333         }
1334 
1335         if (pextra) {
1336           BV_SET(*extras, extra_index(pextra));
1337         }
1338       }
1339     }
1340   }
1341 }
1342 
1343 /****************************************************************************
1344   Helper function for loading bases from a savegame.
1345 
1346   'ch' gives the character loaded from the savegame. Bases are packed
1347   in four to a character in hex notation. 'index' is a mapping of
1348   savegame bit -> base bit.
1349 ****************************************************************************/
sg_bases_set(bv_extras * extras,char ch,struct base_type ** idx)1350 static void sg_bases_set(bv_extras *extras, char ch, struct base_type **idx)
1351 {
1352   int i, bin;
1353   const char *pch = strchr(hex_chars, ch);
1354 
1355   if (!pch || ch == '\0') {
1356     log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1357     bin = 0;
1358   } else {
1359     bin = pch - hex_chars;
1360   }
1361 
1362   for (i = 0; i < 4; i++) {
1363     struct base_type *pbase = idx[i];
1364 
1365     if (pbase == NULL) {
1366       continue;
1367     }
1368     if (bin & (1 << i)) {
1369       BV_SET(*extras, extra_index(base_extra_get(pbase)));
1370     }
1371   }
1372 }
1373 
1374 /****************************************************************************
1375   Helper function for loading roads from a savegame.
1376 
1377   'ch' gives the character loaded from the savegame. Roads are packed
1378   in four to a character in hex notation. 'index' is a mapping of
1379   savegame bit -> road bit.
1380 ****************************************************************************/
sg_roads_set(bv_extras * extras,char ch,struct road_type ** idx)1381 static void sg_roads_set(bv_extras *extras, char ch, struct road_type **idx)
1382 {
1383   int i, bin;
1384   const char *pch = strchr(hex_chars, ch);
1385 
1386   if (!pch || ch == '\0') {
1387     log_sg("Unknown hex value: '%c' (%d)", ch, ch);
1388     bin = 0;
1389   } else {
1390     bin = pch - hex_chars;
1391   }
1392 
1393   for (i = 0; i < 4; i++) {
1394     struct road_type *proad = idx[i];
1395 
1396     if (proad == NULL) {
1397       continue;
1398     }
1399     if (bin & (1 << i)) {
1400       BV_SET(*extras, extra_index(road_extra_get(proad)));
1401     }
1402   }
1403 }
1404 
1405 /****************************************************************************
1406   Return the resource for the given identifier.
1407 ****************************************************************************/
char2resource(char c)1408 static struct resource *char2resource(char c)
1409 {
1410   /* speed common values */
1411   if (c == RESOURCE_NULL_IDENTIFIER
1412    || c == RESOURCE_NONE_IDENTIFIER) {
1413     return NULL;
1414   }
1415   return resource_by_identifier(c);
1416 }
1417 
1418 /****************************************************************************
1419   Return the identifier for the given resource.
1420 ****************************************************************************/
resource2char(const struct resource * presource)1421 static char resource2char(const struct resource *presource)
1422 {
1423   return presource ? presource->identifier : RESOURCE_NONE_IDENTIFIER;
1424 }
1425 
1426 /****************************************************************************
1427   Converts number in to single character. This works to values up to ~70.
1428 ****************************************************************************/
num2char(unsigned int num)1429 static char num2char(unsigned int num)
1430 {
1431   if (num >= strlen(num_chars)) {
1432     return '?';
1433   }
1434 
1435   return num_chars[num];
1436 }
1437 
1438 /****************************************************************************
1439   Converts single character into numerical value. This is not hex conversion.
1440 ****************************************************************************/
char2num(char ch)1441 static int char2num(char ch)
1442 {
1443   const char *pch;
1444 
1445   pch = strchr(num_chars, ch);
1446 
1447   sg_failure_ret_val(NULL != pch, 0,
1448                      "Unknown ascii value for num: '%c' %d", ch, ch);
1449 
1450   return pch - num_chars;
1451 }
1452 
1453 /****************************************************************************
1454   Dereferences the terrain character.  See terrains[].identifier
1455     example: char2terrain('a') => T_ARCTIC
1456 ****************************************************************************/
char2terrain(char ch)1457 static struct terrain *char2terrain(char ch)
1458 {
1459   /* terrain_by_identifier plus fatal error */
1460   if (ch == TERRAIN_UNKNOWN_IDENTIFIER) {
1461     return T_UNKNOWN;
1462   }
1463   terrain_type_iterate(pterrain) {
1464     if (pterrain->identifier_load == ch) {
1465       return pterrain;
1466     }
1467   } terrain_type_iterate_end;
1468 
1469   log_fatal("Unknown terrain identifier '%c' in savegame.", ch);
1470 
1471   exit(EXIT_FAILURE);
1472 
1473   RETURN_VALUE_AFTER_EXIT(NULL);
1474 }
1475 
1476 /****************************************************************************
1477   References the terrain character.  See terrains[].identifier
1478     example: terrain2char(T_ARCTIC) => 'a'
1479 ****************************************************************************/
terrain2char(const struct terrain * pterrain)1480 static char terrain2char(const struct terrain *pterrain)
1481 {
1482   if (pterrain == T_UNKNOWN) {
1483     return TERRAIN_UNKNOWN_IDENTIFIER;
1484   } else {
1485     return pterrain->identifier;
1486   }
1487 }
1488 
1489 /*****************************************************************************
1490   Load technology from path_name and if doesn't exist (because savegame
1491   is too old) load from path.
1492 *****************************************************************************/
technology_load(struct section_file * file,const char * path,int plrno)1493 static Tech_type_id technology_load(struct section_file *file,
1494                                     const char* path, int plrno)
1495 {
1496   char path_with_name[128];
1497   const char* name;
1498   struct advance *padvance;
1499 
1500   fc_snprintf(path_with_name, sizeof(path_with_name),
1501               "%s_name", path);
1502 
1503   name = secfile_lookup_str(file, path_with_name, plrno);
1504 
1505   if (!name || name[0] == '\0') {
1506     /* used by researching_saved */
1507     return A_UNKNOWN;
1508   }
1509   if (fc_strcasecmp(name, "A_FUTURE") == 0) {
1510     return A_FUTURE;
1511   }
1512   if (fc_strcasecmp(name, "A_NONE") == 0) {
1513     return A_NONE;
1514   }
1515   if (fc_strcasecmp(name, "A_UNSET") == 0) {
1516     return A_UNSET;
1517   }
1518 
1519   padvance = advance_by_rule_name(name);
1520   sg_failure_ret_val(NULL != padvance, A_NONE,
1521                      "%s: unknown technology \"%s\".", path_with_name, name);
1522 
1523   return advance_number(padvance);
1524 }
1525 
1526 /*****************************************************************************
1527   Save technology in secfile entry called path_name.
1528 *****************************************************************************/
technology_save(struct section_file * file,const char * path,int plrno,Tech_type_id tech)1529 static void technology_save(struct section_file *file,
1530                             const char* path, int plrno, Tech_type_id tech)
1531 {
1532   char path_with_name[128];
1533   const char* name;
1534 
1535   fc_snprintf(path_with_name, sizeof(path_with_name),
1536               "%s_name", path);
1537 
1538   switch (tech) {
1539     case A_UNKNOWN: /* used by researching_saved */
1540        name = "";
1541        break;
1542     case A_NONE:
1543       name = "A_NONE";
1544       break;
1545     case A_UNSET:
1546       name = "A_UNSET";
1547       break;
1548     case A_FUTURE:
1549       name = "A_FUTURE";
1550       break;
1551     default:
1552       name = advance_rule_name(advance_by_number(tech));
1553       break;
1554   }
1555 
1556   secfile_insert_str(file, name, path_with_name, plrno);
1557 }
1558 
1559 /* =======================================================================
1560  * Load / save savefile data.
1561  * ======================================================================= */
1562 
1563 /****************************************************************************
1564   Set up correct ruleset for the savegame
1565 ****************************************************************************/
sg_load_ruleset(struct loaddata * loading)1566 static void sg_load_ruleset(struct loaddata *loading)
1567 {
1568   const char *ruleset = secfile_lookup_str_default(loading->file,
1569                                                    GAME_DEFAULT_RULESETDIR,
1570                                                    "savefile.rulesetdir");
1571 
1572   /* Load ruleset. */
1573   sz_strlcpy(game.server.rulesetdir, ruleset);
1574   if (!strcmp("default", game.server.rulesetdir)) {
1575     int version;
1576 
1577     version = secfile_lookup_int_default(loading->file, -1, "savefile.version");
1578     if (version >= 30) {
1579       /* Here 'default' really means current default.
1580        * Saving happens with real ruleset name, so savegames containing this
1581        * are special scenarios. */
1582       sz_strlcpy(game.server.rulesetdir, GAME_DEFAULT_RULESETDIR);
1583     } else {
1584       /* 'default' is the old name of the classic ruleset */
1585       sz_strlcpy(game.server.rulesetdir, "classic");
1586     }
1587     log_verbose("Savegame specified ruleset '%s'. Really loading '%s'.",
1588                 ruleset, game.server.rulesetdir);
1589   }
1590   if (!load_rulesets(NULL, TRUE, FALSE)) {
1591     /* Failed to load correct ruleset */
1592     sg_failure_ret(FALSE, _("Failed to load ruleset '%s' needed for savegame."),
1593                    ruleset);
1594   }
1595 }
1596 
1597 /****************************************************************************
1598   Load '[savefile]'.
1599 ****************************************************************************/
sg_load_savefile(struct loaddata * loading)1600 static void sg_load_savefile(struct loaddata *loading)
1601 {
1602   int i;
1603   const char *terr_name;
1604 
1605   /* Check status and return if not OK (sg_success != TRUE). */
1606   sg_check_ret();
1607 
1608   /* Load savefile options. */
1609   loading->secfile_options
1610     = secfile_lookup_str(loading->file, "savefile.options");
1611 
1612   /* We don't need these entries, but read them anyway to avoid
1613    * warnings about unread secfile entries. */
1614   (void) secfile_entry_by_path(loading->file, "savefile.reason");
1615   (void) secfile_entry_by_path(loading->file, "savefile.revision");
1616 
1617   /* In case of savegame2.c saves, missing entry means savegame older than support
1618    * for saving last_updated by turn. So this must default to TRUE. */
1619   game.server.last_updated_year = secfile_lookup_bool_default(loading->file, TRUE,
1620                                                               "savefile.last_updated_as_year");
1621 
1622   /* Load improvements. */
1623   loading->improvement.size
1624     = secfile_lookup_int_default(loading->file, 0,
1625                                  "savefile.improvement_size");
1626   if (loading->improvement.size) {
1627     loading->improvement.order
1628       = secfile_lookup_str_vec(loading->file, &loading->improvement.size,
1629                                "savefile.improvement_vector");
1630     sg_failure_ret(loading->improvement.size != 0,
1631                    "Failed to load improvement order: %s",
1632                    secfile_error());
1633   }
1634 
1635   /* Load technologies. */
1636   loading->technology.size
1637     = secfile_lookup_int_default(loading->file, 0,
1638                                  "savefile.technology_size");
1639   if (loading->technology.size) {
1640     loading->technology.order
1641       = secfile_lookup_str_vec(loading->file, &loading->technology.size,
1642                                "savefile.technology_vector");
1643     sg_failure_ret(loading->technology.size != 0,
1644                    "Failed to load technology order: %s",
1645                    secfile_error());
1646   }
1647 
1648   /* Load traits. */
1649   loading->trait.size
1650     = secfile_lookup_int_default(loading->file, 0,
1651                                  "savefile.trait_size");
1652   if (loading->trait.size) {
1653     loading->trait.order
1654       = secfile_lookup_str_vec(loading->file, &loading->trait.size,
1655                                "savefile.trait_vector");
1656     sg_failure_ret(loading->trait.size != 0,
1657                    "Failed to load trait order: %s",
1658                    secfile_error());
1659   }
1660 
1661   /* Load extras. */
1662   loading->extra.size
1663     = secfile_lookup_int_default(loading->file, 0,
1664                                  "savefile.extras_size");
1665   if (loading->extra.size) {
1666     const char **modname;
1667     size_t nmod;
1668     int j;
1669 
1670     modname = secfile_lookup_str_vec(loading->file, &loading->extra.size,
1671                                      "savefile.extras_vector");
1672     sg_failure_ret(loading->extra.size != 0,
1673                    "Failed to load extras order: %s",
1674                    secfile_error());
1675     sg_failure_ret(!(game.control.num_extra_types < loading->extra.size),
1676                    "Number of extras defined by the ruleset (= %d) are "
1677                    "lower than the number in the savefile (= %d).",
1678                    game.control.num_extra_types, (int)loading->extra.size);
1679     /* make sure that the size of the array is divisible by 4 */
1680     nmod = 4 * ((loading->extra.size + 3) / 4);
1681     loading->extra.order = fc_calloc(nmod, sizeof(*loading->extra.order));
1682     for (j = 0; j < loading->extra.size; j++) {
1683       loading->extra.order[j] = extra_type_by_rule_name(modname[j]);
1684     }
1685     free(modname);
1686     for (; j < nmod; j++) {
1687       loading->extra.order[j] = NULL;
1688     }
1689   }
1690 
1691   /* Load multipliers. */
1692   loading->multiplier.size
1693     = secfile_lookup_int_default(loading->file, 0,
1694                                  "savefile.multipliers_size");
1695   if (loading->multiplier.size) {
1696     const char **modname;
1697     int j;
1698 
1699     modname = secfile_lookup_str_vec(loading->file, &loading->multiplier.size,
1700                                      "savefile.multipliers_vector");
1701     sg_failure_ret(loading->multiplier.size != 0,
1702                    "Failed to load multipliers order: %s",
1703                    secfile_error());
1704     /* It's OK for the set of multipliers in the savefile to differ
1705      * from those in the ruleset. */
1706     loading->multiplier.order = fc_calloc(loading->multiplier.size,
1707                                           sizeof(*loading->multiplier.order));
1708     for (j = 0; j < loading->multiplier.size; j++) {
1709       loading->multiplier.order[j] = multiplier_by_rule_name(modname[j]);
1710       if (!loading->multiplier.order[j]) {
1711         log_verbose("Multiplier \"%s\" in savegame but not in ruleset, "
1712                     "discarding", modname[j]);
1713       }
1714     }
1715     free(modname);
1716   }
1717 
1718   /* Load specials. */
1719   loading->special.size
1720     = secfile_lookup_int_default(loading->file, 0,
1721                                  "savefile.specials_size");
1722   if (loading->special.size) {
1723     const char **modname;
1724     size_t nmod;
1725     enum tile_special_type j;
1726 
1727     modname = secfile_lookup_str_vec(loading->file, &loading->special.size,
1728                                      "savefile.specials_vector");
1729     sg_failure_ret(loading->special.size != 0,
1730                    "Failed to load specials order: %s",
1731                    secfile_error());
1732     /* make sure that the size of the array is divisible by 4 */
1733     /* Allocating extra 4 slots, just a couple of bytes,
1734      * in case of special.size being divisible by 4 already is intentional.
1735      * Added complexity would cost those couple of bytes in code size alone,
1736      * and we actually need at least one slot immediately after last valid
1737      * one. That's where S_LAST is (or was in version that saved the game)
1738      * and in some cases S_LAST gets written to savegame, at least as
1739      * activity target special when activity targets some base or road
1740      * instead. By having current S_LAST in that index allows us to map
1741      * that old S_LAST to current S_LAST, just like any real special within
1742      * special.size gets mapped. */
1743     nmod = loading->special.size + (4 - (loading->special.size % 4));
1744     loading->special.order = fc_calloc(nmod,
1745                                        sizeof(*loading->special.order));
1746     for (j = 0; j < loading->special.size; j++) {
1747       if (!strcasecmp("Road", modname[j])) {
1748         loading->special.order[j] = S_OLD_ROAD;
1749       } else if (!strcasecmp("Railroad", modname[j])) {
1750         loading->special.order[j] = S_OLD_RAILROAD;
1751       } else if (!strcasecmp("River", modname[j])) {
1752         loading->special.order[j] = S_OLD_RIVER;
1753       } else {
1754         loading->special.order[j] = special_by_rule_name(modname[j]);
1755       }
1756     }
1757     free(modname);
1758     for (; j < nmod; j++) {
1759       loading->special.order[j] = S_LAST;
1760     }
1761   }
1762 
1763   /* Load bases. */
1764   loading->base.size
1765     = secfile_lookup_int_default(loading->file, 0,
1766                                  "savefile.bases_size");
1767   if (loading->base.size) {
1768     const char **modname;
1769     size_t nmod;
1770     int j;
1771 
1772     modname = secfile_lookup_str_vec(loading->file, &loading->base.size,
1773                                      "savefile.bases_vector");
1774     sg_failure_ret(loading->base.size != 0,
1775                    "Failed to load bases order: %s",
1776                    secfile_error());
1777     /* make sure that the size of the array is divisible by 4 */
1778     nmod = 4 * ((loading->base.size + 3) / 4);
1779     loading->base.order = fc_calloc(nmod, sizeof(*loading->base.order));
1780     for (j = 0; j < loading->base.size; j++) {
1781       struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1782 
1783       sg_failure_ret(pextra != NULL
1784                      || game.control.num_base_types >= loading->base.size,
1785                      "Unknown base type %s in savefile.",
1786                      modname[j]);
1787 
1788       if (pextra != NULL) {
1789         loading->base.order[j] = extra_base_get(pextra);
1790       } else {
1791         loading->base.order[j] = NULL;
1792       }
1793     }
1794     free(modname);
1795     for (; j < nmod; j++) {
1796       loading->base.order[j] = NULL;
1797     }
1798   }
1799 
1800   /* Load roads. */
1801   loading->road.size
1802     = secfile_lookup_int_default(loading->file, 0,
1803                                  "savefile.roads_size");
1804   if (loading->road.size) {
1805     const char **modname;
1806     size_t nmod;
1807     int j;
1808 
1809     modname = secfile_lookup_str_vec(loading->file, &loading->road.size,
1810                                      "savefile.roads_vector");
1811     sg_failure_ret(loading->road.size != 0,
1812                    "Failed to load roads order: %s",
1813                    secfile_error());
1814     sg_failure_ret(!(game.control.num_road_types < loading->road.size),
1815                    "Number of roads defined by the ruleset (= %d) are "
1816                    "lower than the number in the savefile (= %d).",
1817                    game.control.num_road_types, (int)loading->road.size);
1818     /* make sure that the size of the array is divisible by 4 */
1819     nmod = 4 * ((loading->road.size + 3) / 4);
1820     loading->road.order = fc_calloc(nmod, sizeof(*loading->road.order));
1821     for (j = 0; j < loading->road.size; j++) {
1822       struct extra_type *pextra = extra_type_by_rule_name(modname[j]);
1823 
1824       if (pextra != NULL) {
1825         loading->road.order[j] = extra_road_get(pextra);
1826       } else {
1827         loading->road.order[j] = NULL;
1828       }
1829     }
1830     free(modname);
1831     for (; j < nmod; j++) {
1832       loading->road.order[j] = NULL;
1833     }
1834   }
1835 
1836   /* Load specialists. */
1837   loading->specialist.size
1838     = secfile_lookup_int_default(loading->file, 0,
1839                                  "savefile.specialists_size");
1840   if (loading->specialist.size) {
1841     const char **modname;
1842     size_t nmod;
1843     int j;
1844 
1845     modname = secfile_lookup_str_vec(loading->file, &loading->specialist.size,
1846                                      "savefile.specialists_vector");
1847     sg_failure_ret(loading->specialist.size != 0,
1848                    "Failed to load specialists order: %s",
1849                    secfile_error());
1850     sg_failure_ret(!(game.control.num_specialist_types < loading->specialist.size),
1851                    "Number of specialists defined by the ruleset (= %d) are "
1852                    "lower than the number in the savefile (= %d).",
1853                    game.control.num_specialist_types, (int)loading->specialist.size);
1854     /* make sure that the size of the array is divisible by 4 */
1855     /* That's not really needed with specialists at the moment, but done this way
1856      * for consistency with other types, and to be prepared for the time it needs
1857      * to be this way. */
1858     nmod = 4 * ((loading->specialist.size + 3) / 4);
1859     loading->specialist.order = fc_calloc(nmod, sizeof(*loading->specialist.order));
1860     for (j = 0; j < loading->specialist.size; j++) {
1861       loading->specialist.order[j] = specialist_by_rule_name(modname[j]);
1862     }
1863     free(modname);
1864     for (; j < nmod; j++) {
1865       loading->specialist.order[j] = NULL;
1866     }
1867   }
1868 
1869   /* Load diplomatic state type order. */
1870   loading->ds_t.size
1871     = secfile_lookup_int_default(loading->file, 0,
1872                                  "savefile.diplstate_type_size");
1873 
1874   sg_failure_ret(loading->ds_t.size > 0,
1875                  "Failed to load diplomatic state type order: %s",
1876                  secfile_error());
1877 
1878   if (loading->ds_t.size) {
1879     const char **modname;
1880     int j;
1881 
1882     modname = secfile_lookup_str_vec(loading->file, &loading->ds_t.size,
1883                                      "savefile.diplstate_type_vector");
1884 
1885     loading->ds_t.order = fc_calloc(loading->ds_t.size,
1886                                   sizeof(*loading->ds_t.order));
1887 
1888     for (j = 0; j < loading->ds_t.size; j++) {
1889       loading->ds_t.order[j] = diplstate_type_by_name(modname[j],
1890                                                     fc_strcasecmp);
1891     }
1892 
1893     free(modname);
1894   }
1895 
1896     terrain_type_iterate(pterr) {
1897     pterr->identifier_load = '\0';
1898   } terrain_type_iterate_end;
1899 
1900   i = 0;
1901   while ((terr_name = secfile_lookup_str_default(loading->file, NULL,
1902                                                  "savefile.terrident%d.name", i)) != NULL) {
1903     struct terrain *pterr = terrain_by_rule_name(terr_name);
1904 
1905     if (pterr != NULL) {
1906       const char *iptr =  secfile_lookup_str_default(loading->file, NULL,
1907                                                      "savefile.terrident%d.identifier", i);
1908 
1909       pterr->identifier_load = *iptr;
1910     } else {
1911       log_error("Identifier for unknown terrain type %s.", terr_name);
1912     }
1913     i++;
1914   }
1915 
1916   terrain_type_iterate(pterr) {
1917     terrain_type_iterate(pterr2) {
1918       if (pterr != pterr2  && pterr->identifier_load != '\0') {
1919         sg_failure_ret((pterr->identifier_load != pterr2->identifier_load),
1920                        "%s and %s share a saved identifier",
1921                        terrain_rule_name(pterr), terrain_rule_name(pterr2));
1922       }
1923     } terrain_type_iterate_end;
1924   } terrain_type_iterate_end;
1925 }
1926 
1927 /****************************************************************************
1928   Save '[savefile]'.
1929 ****************************************************************************/
sg_save_savefile(struct savedata * saving)1930 static void sg_save_savefile(struct savedata *saving)
1931 {
1932   int i;
1933 
1934   /* Check status and return if not OK (sg_success != TRUE). */
1935   sg_check_ret();
1936 
1937   /* Save savefile options. */
1938   sg_save_savefile_options(saving, savefile_options_default);
1939 
1940   secfile_insert_int(saving->file, current_compat_ver(), "savefile.version");
1941 
1942   /* Save reason of the savefile generation. */
1943   secfile_insert_str(saving->file, saving->save_reason, "savefile.reason");
1944 
1945   /* Save as accurate freeciv revision information as possible */
1946   secfile_insert_str(saving->file, freeciv_datafile_version(), "savefile.revision");
1947 
1948   /* Save rulesetdir at this point as this ruleset is required by this
1949    * savefile. */
1950   secfile_insert_str(saving->file, game.server.rulesetdir, "savefile.rulesetdir");
1951 
1952   if (game.control.version[0] != '\0') {
1953     /* Current ruleset has version information, save it.
1954      * This is never loaded, but exist in savegame file only for debugging purposes. */
1955     secfile_insert_str(saving->file, game.control.version, "savefile.rulesetversion");
1956   }
1957 
1958   secfile_insert_bool(saving->file, game.server.last_updated_year,
1959                       "savefile.last_updated_as_year");
1960 
1961   /* Save improvement order in savegame, so we are not dependent on ruleset
1962    * order. If the game isn't started improvements aren't loaded so we can
1963    * not save the order. */
1964   secfile_insert_int(saving->file, improvement_count(),
1965                      "savefile.improvement_size");
1966   if (improvement_count() > 0) {
1967     const char* buf[improvement_count()];
1968 
1969     improvement_iterate(pimprove) {
1970       buf[improvement_index(pimprove)] = improvement_rule_name(pimprove);
1971     } improvement_iterate_end;
1972 
1973     secfile_insert_str_vec(saving->file, buf, improvement_count(),
1974                            "savefile.improvement_vector");
1975   }
1976 
1977   /* Save technology order in savegame, so we are not dependent on ruleset
1978    * order. If the game isn't started advances aren't loaded so we can not
1979    * save the order. */
1980   secfile_insert_int(saving->file, game.control.num_tech_types,
1981                      "savefile.technology_size");
1982   if (game.control.num_tech_types > 0) {
1983     const char* buf[game.control.num_tech_types];
1984 
1985     buf[A_NONE] = "A_NONE";
1986     advance_iterate(A_FIRST, a) {
1987       buf[advance_index(a)] = advance_rule_name(a);
1988     } advance_iterate_end;
1989     secfile_insert_str_vec(saving->file, buf, game.control.num_tech_types,
1990                            "savefile.technology_vector");
1991   }
1992 
1993   /* Save activities order in the savegame. */
1994   secfile_insert_int(saving->file, ACTIVITY_LAST,
1995                      "savefile.activities_size");
1996   if (ACTIVITY_LAST > 0) {
1997     const char **modname;
1998     int j;
1999 
2000     i = 0;
2001 
2002     modname = fc_calloc(ACTIVITY_LAST, sizeof(*modname));
2003 
2004     for (j = 0; j < ACTIVITY_LAST; j++) {
2005       modname[i++] = unit_activity_name(j);
2006     }
2007 
2008     secfile_insert_str_vec(saving->file, modname,
2009                            ACTIVITY_LAST,
2010                            "savefile.activities_vector");
2011     free(modname);
2012   }
2013 
2014   /* Save specialists order in the savegame. */
2015   secfile_insert_int(saving->file, specialist_count(),
2016                      "savefile.specialists_size");
2017   {
2018     const char **modname;
2019 
2020     i = 0;
2021     modname = fc_calloc(specialist_count(), sizeof(*modname));
2022 
2023     specialist_type_iterate(sp) {
2024       modname[i++] = specialist_rule_name(specialist_by_number(sp));
2025     } specialist_type_iterate_end;
2026 
2027     secfile_insert_str_vec(saving->file, modname, specialist_count(),
2028                            "savefile.specialists_vector");
2029 
2030     free(modname);
2031   }
2032 
2033   /* Save trait order in savegame. */
2034   secfile_insert_int(saving->file, TRAIT_COUNT,
2035                      "savefile.trait_size");
2036   {
2037     const char **modname;
2038     enum trait tr;
2039     int j;
2040 
2041     modname = fc_calloc(TRAIT_COUNT, sizeof(*modname));
2042 
2043     for (tr = trait_begin(), j = 0; tr != trait_end(); tr = trait_next(tr), j++) {
2044       modname[j] = trait_name(tr);
2045     }
2046 
2047     secfile_insert_str_vec(saving->file, modname, TRAIT_COUNT,
2048                            "savefile.trait_vector");
2049     free(modname);
2050   }
2051 
2052   /* Save extras order in the savegame. */
2053   secfile_insert_int(saving->file, game.control.num_extra_types,
2054                      "savefile.extras_size");
2055   if (game.control.num_extra_types > 0) {
2056     const char **modname;
2057 
2058     i = 0;
2059     modname = fc_calloc(game.control.num_extra_types, sizeof(*modname));
2060 
2061     extra_type_iterate(pextra) {
2062       modname[i++] = extra_rule_name(pextra);
2063     } extra_type_iterate_end;
2064 
2065     secfile_insert_str_vec(saving->file, modname,
2066                            game.control.num_extra_types,
2067                            "savefile.extras_vector");
2068     free(modname);
2069   }
2070 
2071   /* Save multipliers order in the savegame. */
2072   secfile_insert_int(saving->file, multiplier_count(),
2073                      "savefile.multipliers_size");
2074   if (multiplier_count() > 0) {
2075     const char **modname;
2076 
2077     i = 0;
2078     modname = fc_calloc(multiplier_count(), sizeof(*modname));
2079 
2080     multipliers_iterate(pmul) {
2081       modname[multiplier_index(pmul)] = multiplier_rule_name(pmul);
2082     } multipliers_iterate_end;
2083 
2084     secfile_insert_str_vec(saving->file, modname,
2085                            multiplier_count(),
2086                            "savefile.multipliers_vector");
2087     free(modname);
2088   }
2089 
2090   /* Save diplstate type order in the savegame. */
2091   secfile_insert_int(saving->file, DS_LAST,
2092                      "savefile.diplstate_type_size");
2093   if (DS_LAST > 0) {
2094     const char **modname;
2095     int j;
2096 
2097     i = 0;
2098     modname = fc_calloc(DS_LAST, sizeof(*modname));
2099 
2100     for (j = 0; j < DS_LAST; j++) {
2101       modname[i++] = diplstate_type_name(j);
2102     }
2103 
2104     secfile_insert_str_vec(saving->file, modname,
2105                            DS_LAST,
2106                            "savefile.diplstate_type_vector");
2107     free(modname);
2108   }
2109 
2110   /* Save city_option order in the savegame. */
2111   secfile_insert_int(saving->file, CITYO_LAST,
2112                      "savefile.city_options_size");
2113   if (CITYO_LAST > 0) {
2114     const char **modname;
2115     int j;
2116 
2117     i = 0;
2118     modname = fc_calloc(CITYO_LAST, sizeof(*modname));
2119 
2120     for (j = 0; j < CITYO_LAST; j++) {
2121       modname[i++] = city_options_name(j);
2122     }
2123 
2124     secfile_insert_str_vec(saving->file, modname,
2125                            CITYO_LAST,
2126                            "savefile.city_options_vector");
2127     free(modname);
2128   }
2129 
2130   /* Save terrain character mapping in the savegame. */
2131   i = 0;
2132   terrain_type_iterate(pterr) {
2133     char buf[2];
2134 
2135     secfile_insert_str(saving->file, terrain_rule_name(pterr), "savefile.terrident%d.name", i);
2136     buf[0] = terrain_identifier(pterr);
2137     buf[1] = '\0';
2138     secfile_insert_str(saving->file, buf, "savefile.terrident%d.identifier", i++);
2139   } terrain_type_iterate_end;
2140 }
2141 
2142 /****************************************************************************
2143   Save options for this savegame. sg_load_savefile_options() is not defined.
2144 ****************************************************************************/
sg_save_savefile_options(struct savedata * saving,const char * option)2145 static void sg_save_savefile_options(struct savedata *saving,
2146                                      const char *option)
2147 {
2148   /* Check status and return if not OK (sg_success != TRUE). */
2149   sg_check_ret();
2150 
2151   if (option == NULL) {
2152     /* no additional option */
2153     return;
2154   }
2155 
2156   sz_strlcat(saving->secfile_options, option);
2157   secfile_replace_str(saving->file, saving->secfile_options,
2158                       "savefile.options");
2159 }
2160 
2161 /* =======================================================================
2162  * Load / save game status.
2163  * ======================================================================= */
2164 
2165 /****************************************************************************
2166   Load '[ruledata]'.
2167 ****************************************************************************/
sg_load_ruledata(struct loaddata * loading)2168 static void sg_load_ruledata(struct loaddata *loading)
2169 {
2170   int i;
2171   const char *name;
2172 
2173   /* Check status and return if not OK (sg_success != TRUE). */
2174   sg_check_ret();
2175 
2176   for (i = 0;
2177        (name = secfile_lookup_str_default(loading->file, NULL,
2178                                           "ruledata.government%d.name", i));
2179        i++) {
2180     struct government *gov = government_by_rule_name(name);
2181 
2182     if (gov != NULL) {
2183       gov->changed_to_times = secfile_lookup_int_default(loading->file, 0,
2184                                                          "ruledata.government%d.changes", i);
2185     }
2186   }
2187 }
2188 
2189 /****************************************************************************
2190   Load '[game]'.
2191 ****************************************************************************/
sg_load_game(struct loaddata * loading)2192 static void sg_load_game(struct loaddata *loading)
2193 {
2194   int game_version;
2195   const char *string;
2196   const char *level;
2197   int i;
2198 
2199   /* Check status and return if not OK (sg_success != TRUE). */
2200   sg_check_ret();
2201 
2202   /* Load version. */
2203   game_version
2204     = secfile_lookup_int_default(loading->file, 0, "game.version");
2205   /* We require at least version 2.2.99 */
2206   sg_failure_ret(20299 <= game_version, "Saved game is too old, at least "
2207                                         "version 2.2.99 required.");
2208 
2209   /* Load server state. */
2210   string = secfile_lookup_str_default(loading->file, "S_S_INITIAL",
2211                                       "game.server_state");
2212   loading->server_state = server_states_by_name(string, strcmp);
2213   if (!server_states_is_valid(loading->server_state)) {
2214     /* Don't take any risk! */
2215     loading->server_state = S_S_INITIAL;
2216   }
2217 
2218   string = secfile_lookup_str_default(loading->file,
2219                                       default_meta_patches_string(),
2220                                       "game.meta_patches");
2221   set_meta_patches_string(string);
2222   game.server.meta_info.user_message_set
2223     = secfile_lookup_bool_default(loading->file, FALSE,
2224                                   "game.meta_usermessage");
2225   if (game.server.meta_info.user_message_set) {
2226     string = secfile_lookup_str_default(loading->file,
2227                                         default_meta_message_string(),
2228                                         "game.meta_message");
2229     set_user_meta_message_string(string);
2230   }
2231 
2232   if (0 == strcmp(DEFAULT_META_SERVER_ADDR, srvarg.metaserver_addr)) {
2233     /* Do not overwrite this if the user requested a specific metaserver
2234      * from the command line (option --Metaserver). */
2235     sz_strlcpy(srvarg.metaserver_addr,
2236                secfile_lookup_str_default(loading->file,
2237                                           DEFAULT_META_SERVER_ADDR,
2238                                           "game.meta_server"));
2239   }
2240 
2241   if ('\0' == srvarg.serverid[0]) {
2242     /* Do not overwrite this if the user requested a specific metaserver
2243      * from the command line (option --serverid). */
2244     sz_strlcpy(srvarg.serverid,
2245                secfile_lookup_str_default(loading->file, "",
2246                                           "game.serverid"));
2247   }
2248   sz_strlcpy(server.game_identifier,
2249              secfile_lookup_str_default(loading->file, "", "game.id"));
2250   /* We are not checking game_identifier legality just yet.
2251    * That's done when we are sure that rand seed has been initialized,
2252    * so that we can generate new game_identifier, if needed.
2253    * See sq_load_sanitycheck(). */
2254 
2255   level = secfile_lookup_str_default(loading->file, NULL,
2256                                      "game.level");
2257   if (level != NULL) {
2258     game.info.skill_level = ai_level_by_name(level, fc_strcasecmp);
2259   } else {
2260     game.info.skill_level = ai_level_invalid();
2261   }
2262 
2263   if (!ai_level_is_valid(game.info.skill_level)) {
2264     game.info.skill_level
2265       = ai_level_convert(secfile_lookup_int_default(loading->file,
2266                                                     GAME_HARDCODED_DEFAULT_SKILL_LEVEL,
2267                                                     "game.skill_level"));
2268   }
2269   game.info.phase_mode
2270     = secfile_lookup_int_default(loading->file, GAME_DEFAULT_PHASE_MODE,
2271                                  "game.phase_mode");
2272   game.server.phase_mode_stored
2273     = secfile_lookup_int_default(loading->file, GAME_DEFAULT_PHASE_MODE,
2274                                  "game.phase_mode_stored");
2275   game.info.phase
2276     = secfile_lookup_int_default(loading->file, 0,
2277                                  "game.phase");
2278   game.server.scoreturn
2279     = secfile_lookup_int_default(loading->file,
2280                                  game.info.turn + GAME_DEFAULT_SCORETURN,
2281                                  "game.scoreturn");
2282 
2283   game.server.timeoutint
2284     = secfile_lookup_int_default(loading->file, GAME_DEFAULT_TIMEOUTINT,
2285                                  "game.timeoutint");
2286   game.server.timeoutintinc
2287     = secfile_lookup_int_default(loading->file, GAME_DEFAULT_TIMEOUTINTINC,
2288                                  "game.timeoutintinc");
2289   game.server.timeoutinc
2290     = secfile_lookup_int_default(loading->file, GAME_DEFAULT_TIMEOUTINC,
2291                                  "game.timeoutinc");
2292   game.server.timeoutincmult
2293     = secfile_lookup_int_default(loading->file, GAME_DEFAULT_TIMEOUTINCMULT,
2294                                  "game.timeoutincmult");
2295   game.server.timeoutcounter
2296     = secfile_lookup_int_default(loading->file, GAME_DEFAULT_TIMEOUTCOUNTER,
2297                                  "game.timeoutcounter");
2298 
2299   game.info.turn
2300     = secfile_lookup_int_default(loading->file, 0, "game.turn");
2301   sg_failure_ret(secfile_lookup_int(loading->file, &game.info.year32,
2302                                     "game.year"), "%s", secfile_error());
2303   game.info.year16 = game.info.year32;
2304   game.info.year_0_hack
2305     = secfile_lookup_bool_default(loading->file, FALSE, "game.year_0_hack");
2306 
2307   game.info.globalwarming
2308     = secfile_lookup_int_default(loading->file, 0, "game.globalwarming");
2309   game.info.heating
2310     = secfile_lookup_int_default(loading->file, 0, "game.heating");
2311   game.info.warminglevel
2312     = secfile_lookup_int_default(loading->file, 0, "game.warminglevel");
2313 
2314   game.info.nuclearwinter
2315     = secfile_lookup_int_default(loading->file, 0, "game.nuclearwinter");
2316   game.info.cooling
2317     = secfile_lookup_int_default(loading->file, 0, "game.cooling");
2318   game.info.coolinglevel
2319     = secfile_lookup_int_default(loading->file, 0, "game.coolinglevel");
2320 
2321   /* Global advances. */
2322   string = secfile_lookup_str_default(loading->file, NULL,
2323                                       "game.global_advances");
2324   if (string != NULL) {
2325     sg_failure_ret(strlen(string) == loading->technology.size,
2326                    "Invalid length of 'game.global_advances' (%lu ~= %lu).",
2327                    (unsigned long) strlen(string),
2328                    (unsigned long) loading->technology.size);
2329     for (i = 0; i < loading->technology.size; i++) {
2330       sg_failure_ret(string[i] == '1' || string[i] == '0',
2331                      "Undefined value '%c' within 'game.global_advances'.",
2332                      string[i]);
2333       if (string[i] == '1') {
2334         struct advance *padvance =
2335             advance_by_rule_name(loading->technology.order[i]);
2336 
2337         if (padvance != NULL) {
2338           game.info.global_advances[advance_number(padvance)] = TRUE;
2339         }
2340       }
2341     }
2342   }
2343 
2344   game.info.is_new_game
2345     = !secfile_lookup_bool_default(loading->file, TRUE, "game.save_players");
2346 
2347   game.server.turn_change_time
2348     = secfile_lookup_int_default(loading->file, 0, "game.last_turn_change_time") / 100;
2349 }
2350 
2351 /****************************************************************************
2352   Save '[ruledata]'.
2353 ****************************************************************************/
sg_save_ruledata(struct savedata * saving)2354 static void sg_save_ruledata(struct savedata *saving)
2355 {
2356   int set_count = 0;
2357 
2358   governments_iterate(pgov) {
2359      char path[256];
2360 
2361      fc_snprintf(path, sizeof(path),
2362                  "ruledata.government%d", set_count++);
2363 
2364      secfile_insert_str(saving->file, government_rule_name(pgov),
2365                         "%s.name", path);
2366      secfile_insert_int(saving->file, pgov->changed_to_times,
2367                         "%s.changes", path);
2368   } governments_iterate_end;
2369 }
2370 
2371 /****************************************************************************
2372   Save '[game]'.
2373 ****************************************************************************/
sg_save_game(struct savedata * saving)2374 static void sg_save_game(struct savedata *saving)
2375 {
2376   int game_version;
2377   const char *user_message;
2378   enum server_states srv_state;
2379   char global_advances[game.control.num_tech_types + 1];
2380   int i;
2381 
2382   /* Check status and return if not OK (sg_success != TRUE). */
2383   sg_check_ret();
2384 
2385   game_version = MAJOR_VERSION *10000 + MINOR_VERSION *100 + PATCH_VERSION;
2386   secfile_insert_int(saving->file, game_version, "game.version");
2387 
2388   /* Game state: once the game is no longer a new game (ie, has been
2389    * started the first time), it should always be considered a running
2390    * game for savegame purposes. */
2391   if (saving->scenario && !game.scenario.players) {
2392     srv_state = S_S_INITIAL;
2393   } else {
2394     srv_state = game.info.is_new_game ? server_state() : S_S_RUNNING;
2395   }
2396   secfile_insert_str(saving->file, server_states_name(srv_state),
2397                      "game.server_state");
2398 
2399   secfile_insert_str(saving->file, get_meta_patches_string(),
2400                      "game.meta_patches");
2401   secfile_insert_bool(saving->file, game.server.meta_info.user_message_set,
2402                       "game.meta_usermessage");
2403   user_message = get_user_meta_message_string();
2404   if (user_message != NULL) {
2405     secfile_insert_str(saving->file, user_message, "game.meta_message");
2406   }
2407   secfile_insert_str(saving->file, meta_addr_port(), "game.meta_server");
2408 
2409   secfile_insert_str(saving->file, server.game_identifier, "game.id");
2410   secfile_insert_str(saving->file, srvarg.serverid, "game.serverid");
2411 
2412   secfile_insert_str(saving->file, ai_level_name(game.info.skill_level),
2413                      "game.level");
2414   secfile_insert_int(saving->file, game.info.phase_mode,
2415                      "game.phase_mode");
2416   secfile_insert_int(saving->file, game.server.phase_mode_stored,
2417                      "game.phase_mode_stored");
2418   secfile_insert_int(saving->file, game.info.phase,
2419                      "game.phase");
2420   secfile_insert_int(saving->file, game.server.scoreturn,
2421                      "game.scoreturn");
2422 
2423   secfile_insert_int(saving->file, game.server.timeoutint,
2424                      "game.timeoutint");
2425   secfile_insert_int(saving->file, game.server.timeoutintinc,
2426                      "game.timeoutintinc");
2427   secfile_insert_int(saving->file, game.server.timeoutinc,
2428                      "game.timeoutinc");
2429   secfile_insert_int(saving->file, game.server.timeoutincmult,
2430                      "game.timeoutincmult");
2431   secfile_insert_int(saving->file, game.server.timeoutcounter,
2432                      "game.timeoutcounter");
2433 
2434   secfile_insert_int(saving->file, game.info.turn, "game.turn");
2435   secfile_insert_int(saving->file, game.info.year32, "game.year");
2436   secfile_insert_bool(saving->file, game.info.year_0_hack,
2437                       "game.year_0_hack");
2438 
2439   secfile_insert_int(saving->file, game.info.globalwarming,
2440                      "game.globalwarming");
2441   secfile_insert_int(saving->file, game.info.heating,
2442                      "game.heating");
2443   secfile_insert_int(saving->file, game.info.warminglevel,
2444                      "game.warminglevel");
2445 
2446   secfile_insert_int(saving->file, game.info.nuclearwinter,
2447                      "game.nuclearwinter");
2448   secfile_insert_int(saving->file, game.info.cooling,
2449                      "game.cooling");
2450   secfile_insert_int(saving->file, game.info.coolinglevel,
2451                      "game.coolinglevel");
2452   /* For debugging purposes only.
2453    * Do not save it if it's 0 (not known);
2454    * this confuses people reading this 'document' less than
2455    * saving 0. */
2456   if (game.server.seed != 0) {
2457     secfile_insert_int(saving->file, game.server.seed,
2458                        "game.random_seed");
2459   }
2460 
2461   /* Global advances. */
2462   for (i = 0; i < game.control.num_tech_types; i++) {
2463     global_advances[i] = game.info.global_advances[i] ? '1' : '0';
2464   }
2465   global_advances[i] = '\0';
2466   secfile_insert_str(saving->file, global_advances, "game.global_advances");
2467 
2468   if (!game_was_started()) {
2469     saving->save_players = FALSE;
2470   } else {
2471     if (saving->scenario) {
2472       saving->save_players = game.scenario.players;
2473     } else {
2474       saving->save_players = TRUE;
2475     }
2476 #ifndef SAVE_DUMMY_TURN_CHANGE_TIME
2477     secfile_insert_int(saving->file, game.server.turn_change_time * 100,
2478                        "game.last_turn_change_time");
2479 #else  /* SAVE_DUMMY_TURN_CHANGE_TIME */
2480     secfile_insert_int(saving->file, game.info.turn * 10,
2481                        "game.last_turn_change_time");
2482 #endif /* SAVE_DUMMY_TURN_CHANGE_TIME */
2483   }
2484   secfile_insert_bool(saving->file, saving->save_players,
2485                       "game.save_players");
2486 }
2487 
2488 /* =======================================================================
2489  * Load / save random status.
2490  * ======================================================================= */
2491 
2492 /****************************************************************************
2493   Load '[random]'.
2494 ****************************************************************************/
sg_load_random(struct loaddata * loading)2495 static void sg_load_random(struct loaddata *loading)
2496 {
2497   /* Check status and return if not OK (sg_success != TRUE). */
2498   sg_check_ret();
2499 
2500   if (secfile_lookup_bool_default(loading->file, FALSE, "random.save")) {
2501     const char *string;
2502     int i;
2503 
2504     /* Since random state was previously saved, save it also when resaving.
2505      * This affects only pre-2.6 scenarios where scenario.save_random
2506      * is not defined.
2507      * - If this is 2.6 or later scenario -> it would have saved random.save = TRUE
2508      *   only if scenario.save_random is already TRUE
2509      *
2510      * Do NOT touch this in case of regular savegame. They always have random.save
2511      * set, but if one starts to make scenario based on a savegame, we want
2512      * default scenario settings in the beginning (default save_random = FALSE).
2513      */
2514     if (game.scenario.is_scenario) {
2515       game.scenario.save_random = TRUE;
2516     }
2517 
2518     sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.j,
2519                                       "random.index_J"), "%s", secfile_error());
2520     sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.k,
2521                                       "random.index_K"), "%s", secfile_error());
2522     sg_failure_ret(secfile_lookup_int(loading->file, &loading->rstate.x,
2523                                       "random.index_X"), "%s", secfile_error());
2524 
2525     for (i = 0; i < 8; i++) {
2526       string = secfile_lookup_str(loading->file, "random.table%d",i);
2527       sg_failure_ret(NULL != string, "%s", secfile_error());
2528       sscanf(string, "%8x %8x %8x %8x %8x %8x %8x", &loading->rstate.v[7*i],
2529              &loading->rstate.v[7*i+1], &loading->rstate.v[7*i+2],
2530              &loading->rstate.v[7*i+3], &loading->rstate.v[7*i+4],
2531              &loading->rstate.v[7*i+5], &loading->rstate.v[7*i+6]);
2532     }
2533     loading->rstate.is_init = TRUE;
2534     fc_rand_set_state(loading->rstate);
2535   } else {
2536     /* No random values - mark the setting. */
2537     (void) secfile_entry_by_path(loading->file, "random.save");
2538 
2539     /* We're loading a game without a seed (which is okay, if it's a scenario).
2540      * We need to generate the game seed now because it will be needed later
2541      * during the load. */
2542     init_game_seed();
2543     loading->rstate = fc_rand_state();
2544   }
2545 }
2546 
2547 /****************************************************************************
2548   Save '[random]'.
2549 ****************************************************************************/
sg_save_random(struct savedata * saving)2550 static void sg_save_random(struct savedata *saving)
2551 {
2552   /* Check status and return if not OK (sg_success != TRUE). */
2553   sg_check_ret();
2554 
2555   if (fc_rand_is_init() && (!saving->scenario || game.scenario.save_random)) {
2556     int i;
2557     RANDOM_STATE rstate = fc_rand_state();
2558 
2559     secfile_insert_bool(saving->file, TRUE, "random.save");
2560     fc_assert(rstate.is_init);
2561 
2562     secfile_insert_int(saving->file, rstate.j, "random.index_J");
2563     secfile_insert_int(saving->file, rstate.k, "random.index_K");
2564     secfile_insert_int(saving->file, rstate.x, "random.index_X");
2565 
2566     for (i = 0; i < 8; i++) {
2567       char vec[100];
2568 
2569       fc_snprintf(vec, sizeof(vec),
2570                   "%8x %8x %8x %8x %8x %8x %8x", rstate.v[7 * i],
2571                   rstate.v[7 * i + 1], rstate.v[7 * i + 2],
2572                   rstate.v[7 * i + 3], rstate.v[7 * i + 4],
2573                   rstate.v[7 * i + 5], rstate.v[7 * i + 6]);
2574       secfile_insert_str(saving->file, vec, "random.table%d", i);
2575     }
2576   } else {
2577     secfile_insert_bool(saving->file, FALSE, "random.save");
2578   }
2579 }
2580 
2581 /* =======================================================================
2582  * Load / save lua script data.
2583  * ======================================================================= */
2584 
2585 /****************************************************************************
2586   Load '[script]'.
2587 ****************************************************************************/
sg_load_script(struct loaddata * loading)2588 static void sg_load_script(struct loaddata *loading)
2589 {
2590   /* Check status and return if not OK (sg_success != TRUE). */
2591   sg_check_ret();
2592 
2593   script_server_state_load(loading->file);
2594 }
2595 
2596 /****************************************************************************
2597   Save '[script]'.
2598 ****************************************************************************/
sg_save_script(struct savedata * saving)2599 static void sg_save_script(struct savedata *saving)
2600 {
2601   /* Check status and return if not OK (sg_success != TRUE). */
2602   sg_check_ret();
2603 
2604   script_server_state_save(saving->file);
2605 }
2606 
2607 /* =======================================================================
2608  * Load / save scenario data.
2609  * ======================================================================= */
2610 
2611 /****************************************************************************
2612   Load '[scenario]'.
2613 ****************************************************************************/
sg_load_scenario(struct loaddata * loading)2614 static void sg_load_scenario(struct loaddata *loading)
2615 {
2616   const char *buf;
2617   bool lake_flood_default;
2618 
2619   /* Check status and return if not OK (sg_success != TRUE). */
2620   sg_check_ret();
2621 
2622   if (NULL == secfile_section_lookup(loading->file, "scenario")) {
2623     game.scenario.is_scenario = FALSE;
2624 
2625     return;
2626   }
2627 
2628   /* Default is that when there's scenario section (which we already checked)
2629    * this is a scenario. Only if it explicitly says that it's not, we consider
2630    * this regular savegame */
2631   game.scenario.is_scenario = secfile_lookup_bool_default(loading->file, TRUE, "scenario.is_scenario");
2632 
2633   if (!game.scenario.is_scenario) {
2634     return;
2635   }
2636 
2637   buf = secfile_lookup_str_default(loading->file, "", "scenario.name");
2638   if (buf[0] != '\0') {
2639     sz_strlcpy(game.scenario.name, buf);
2640   }
2641 
2642   buf = secfile_lookup_str_default(loading->file, "",
2643                                    "scenario.authors");
2644   if (buf[0] != '\0') {
2645     sz_strlcpy(game.scenario.authors, buf);
2646   } else {
2647     game.scenario.authors[0] = '\0';
2648   }
2649 
2650   buf = secfile_lookup_str_default(loading->file, "",
2651                                    "scenario.description");
2652   if (buf[0] != '\0') {
2653     sz_strlcpy(game.scenario_desc.description, buf);
2654   } else {
2655     game.scenario_desc.description[0] = '\0';
2656   }
2657 
2658   game.scenario.save_random
2659     = secfile_lookup_bool_default(loading->file, FALSE, "scenario.save_random");
2660   game.scenario.players
2661     = secfile_lookup_bool_default(loading->file, TRUE, "scenario.players");
2662   game.scenario.startpos_nations
2663     = secfile_lookup_bool_default(loading->file, FALSE,
2664                                   "scenario.startpos_nations");
2665 
2666   game.scenario.prevent_new_cities
2667     = secfile_lookup_bool_default(loading->file, FALSE,
2668                                   "scenario.prevent_new_cities");
2669   if (loading->version < 20599) {
2670     /* Lake flooding may break some old scenarios where rivers made out of
2671      * lake terrains, so play safe there */
2672     lake_flood_default = FALSE;
2673   } else {
2674     /* If lake flooding is a problem for a newer scenario, it could explicitly
2675      * disable it. */
2676     lake_flood_default = TRUE;
2677   }
2678   game.scenario.lake_flooding
2679     = secfile_lookup_bool_default(loading->file, lake_flood_default,
2680                                   "scenario.lake_flooding");
2681   game.scenario.handmade
2682     = secfile_lookup_bool_default(loading->file, FALSE,
2683                                   "scenario.handmade");
2684   game.scenario.allow_ai_type_fallback
2685     = secfile_lookup_bool_default(loading->file, FALSE,
2686                                   "scenario.allow_ai_type_fallback");
2687 
2688   sg_failure_ret(loading->server_state == S_S_INITIAL
2689                  || (loading->server_state == S_S_RUNNING
2690                      && game.scenario.players == TRUE),
2691                  "Invalid scenario definition (server state '%s' and "
2692                  "players are %s).",
2693                  server_states_name(loading->server_state),
2694                  game.scenario.players ? "saved" : "not saved");
2695 
2696   /* Remove all defined players. They are recreated with the skill level
2697    * defined by the scenario. */
2698   (void) aifill(0);
2699 }
2700 
2701 /****************************************************************************
2702   Save '[scenario]'.
2703 ****************************************************************************/
sg_save_scenario(struct savedata * saving)2704 static void sg_save_scenario(struct savedata *saving)
2705 {
2706   struct entry *mod_entry;
2707   int game_version;
2708 
2709   /* Check status and return if not OK (sg_success != TRUE). */
2710   sg_check_ret();
2711 
2712   if (!saving->scenario || !game.scenario.is_scenario) {
2713     secfile_insert_bool(saving->file, FALSE, "scenario.is_scenario");
2714     return;
2715   }
2716 
2717   secfile_insert_bool(saving->file, TRUE, "scenario.is_scenario");
2718 
2719   game_version = MAJOR_VERSION * 10000 + MINOR_VERSION * 100 + PATCH_VERSION;
2720   secfile_insert_int(saving->file, game_version, "scenario.game_version");
2721 
2722   /* Name is mandatory to the level that is saved even if empty. */
2723   mod_entry = secfile_insert_str(saving->file, game.scenario.name, "scenario.name");
2724   entry_str_set_gt_marking(mod_entry, TRUE);
2725 
2726   /* Authors list is saved only if it exist */
2727   if (game.scenario.authors[0] != '\0') {
2728     mod_entry = secfile_insert_str(saving->file, game.scenario.authors,
2729                                    "scenario.authors");
2730     entry_str_set_gt_marking(mod_entry, TRUE);
2731   }
2732 
2733   /* Description is saved only if it exist */
2734   if (game.scenario_desc.description[0] != '\0') {
2735     mod_entry = secfile_insert_str(saving->file, game.scenario_desc.description,
2736                                    "scenario.description");
2737     entry_str_set_gt_marking(mod_entry, TRUE);
2738   }
2739 
2740   secfile_insert_bool(saving->file, game.scenario.save_random, "scenario.save_random");
2741   secfile_insert_bool(saving->file, game.scenario.players, "scenario.players");
2742   secfile_insert_bool(saving->file, game.scenario.startpos_nations,
2743                       "scenario.startpos_nations");
2744   if (game.scenario.prevent_new_cities) {
2745     secfile_insert_bool(saving->file, game.scenario.prevent_new_cities,
2746                         "scenario.prevent_new_cities");
2747   }
2748   secfile_insert_bool(saving->file, game.scenario.lake_flooding,
2749                       "scenario.lake_flooding");
2750   if (game.scenario.handmade) {
2751     secfile_insert_bool(saving->file, game.scenario.handmade,
2752                         "scenario.handmade");
2753   }
2754   if (game.scenario.allow_ai_type_fallback) {
2755     secfile_insert_bool(saving->file, game.scenario.allow_ai_type_fallback,
2756                         "scenario.allow_ai_type_fallback");
2757   }
2758 }
2759 
2760 /* =======================================================================
2761  * Load / save game settings.
2762  * ======================================================================= */
2763 
2764 /****************************************************************************
2765   Load '[settings]'.
2766 ****************************************************************************/
sg_load_settings(struct loaddata * loading)2767 static void sg_load_settings(struct loaddata *loading)
2768 {
2769   /* Check status and return if not OK (sg_success != TRUE). */
2770   sg_check_ret();
2771 
2772   settings_game_load(loading->file, "settings");
2773 
2774   /* Save current status of fogofwar. */
2775   game.server.fogofwar_old = game.info.fogofwar;
2776 
2777   /* Add all compatibility settings here. */
2778 }
2779 
2780 /****************************************************************************
2781   Save [settings].
2782 ****************************************************************************/
sg_save_settings(struct savedata * saving)2783 static void sg_save_settings(struct savedata *saving)
2784 {
2785   enum map_generator real_generator = game.map.server.generator;
2786 
2787   /* Check status and return if not OK (sg_success != TRUE). */
2788   sg_check_ret();
2789 
2790   if (saving->scenario) {
2791     game.map.server.generator = MAPGEN_SCENARIO; /* We want a scenario. */
2792   }
2793 
2794   settings_game_save(saving->file, "settings");
2795   /* Restore real map generator. */
2796   game.map.server.generator = real_generator;
2797 
2798   /* Add all compatibility settings here. */
2799 }
2800 
2801 /* =======================================================================
2802  * Load / save the main map.
2803  * ======================================================================= */
2804 
2805 /****************************************************************************
2806   Load '[map'].
2807 ****************************************************************************/
sg_load_map(struct loaddata * loading)2808 static void sg_load_map(struct loaddata *loading)
2809 {
2810   /* Check status and return if not OK (sg_success != TRUE). */
2811   sg_check_ret();
2812 
2813   /* This defaults to TRUE even if map has not been generated. Also,
2814    * old versions have also explicitly saved TRUE even in pre-game.
2815    * We rely on that
2816    *   1) scenario maps have it explicity right.
2817    *   2) when map is actually generated, it re-initialize this to FALSE. */
2818   game.map.server.have_huts
2819     = secfile_lookup_bool_default(loading->file, TRUE, "map.have_huts");
2820 
2821   if (S_S_INITIAL == loading->server_state
2822       && MAPGEN_SCENARIO == game.map.server.generator) {
2823     /* Generator MAPGEN_SCENARIO is used;
2824      * this map was done with the map editor. */
2825 
2826     /* Load tiles. */
2827     sg_load_map_tiles(loading);
2828     sg_load_map_startpos(loading);
2829 
2830     if (loading->version >= 30) {
2831       /* 2.6.0 or newer */
2832       sg_load_map_tiles_extras(loading);
2833     } else {
2834       sg_load_map_tiles_bases(loading);
2835       if (loading->version >= 20) {
2836         /* 2.5.0 or newer */
2837         sg_load_map_tiles_roads(loading);
2838       }
2839       if (has_capability("specials", loading->secfile_options)) {
2840         /* Load specials. */
2841         sg_load_map_tiles_specials(loading, FALSE);
2842       }
2843     }
2844 
2845     /* have_resources TRUE only if set so by sg_load_map_tiles_resources() */
2846     game.scenario.have_resources = FALSE;
2847     if (has_capability("specials", loading->secfile_options)) {
2848       /* Load resources. */
2849       sg_load_map_tiles_resources(loading);
2850     } else if (has_capability("riversoverlay", loading->secfile_options)) {
2851       /* Load only rivers overlay. */
2852       sg_load_map_tiles_specials(loading, TRUE);
2853     }
2854 
2855     /* Nothing more needed for a scenario. */
2856     return;
2857   }
2858 
2859   if (S_S_INITIAL == loading->server_state) {
2860     /* Nothing more to do if it is not a scenario but in initial state. */
2861     return;
2862   }
2863 
2864   sg_load_map_tiles(loading);
2865   sg_load_map_startpos(loading);
2866   if (loading->version >= 30) {
2867     /* 2.6.0 or newer */
2868     sg_load_map_tiles_extras(loading);
2869   } else {
2870     sg_load_map_tiles_bases(loading);
2871     if (loading->version >= 20) {
2872       /* 2.5.0 or newer */
2873       sg_load_map_tiles_roads(loading);
2874     }
2875     sg_load_map_tiles_specials(loading, FALSE);
2876   }
2877   sg_load_map_tiles_resources(loading);
2878   sg_load_map_known(loading);
2879   sg_load_map_owner(loading);
2880   sg_load_map_worked(loading);
2881 }
2882 
2883 /****************************************************************************
2884   Save 'map'.
2885 ****************************************************************************/
sg_save_map(struct savedata * saving)2886 static void sg_save_map(struct savedata *saving)
2887 {
2888   /* Check status and return if not OK (sg_success != TRUE). */
2889   sg_check_ret();
2890 
2891   if (map_is_empty()) {
2892     /* No map. */
2893     return;
2894   }
2895 
2896   if (saving->scenario) {
2897     secfile_insert_bool(saving->file, game.map.server.have_huts, "map.have_huts");
2898   } else {
2899     secfile_insert_bool(saving->file, TRUE, "map.have_huts");
2900   }
2901 
2902   /* For debugging purposes only.
2903    * Do not save it if it's 0 (not known);
2904    * this confuses people reading this 'document' less than
2905    * saving 0. */
2906   if (game.map.server.seed) {
2907     secfile_insert_int(saving->file, game.map.server.seed,
2908                        "map.random_seed");
2909   }
2910 
2911   sg_save_map_tiles(saving);
2912   sg_save_map_startpos(saving);
2913   sg_save_map_tiles_extras(saving);
2914   if (!saving->scenario || game.scenario.have_resources) {
2915     sg_save_savefile_options(saving, " specials");
2916     sg_save_map_tiles_resources(saving);
2917   }
2918 
2919   sg_save_map_owner(saving);
2920   sg_save_map_worked(saving);
2921   sg_save_map_known(saving);
2922 }
2923 
2924 /****************************************************************************
2925   Load tiles of the map.
2926 ****************************************************************************/
sg_load_map_tiles(struct loaddata * loading)2927 static void sg_load_map_tiles(struct loaddata *loading)
2928 {
2929   /* Check status and return if not OK (sg_success != TRUE). */
2930   sg_check_ret();
2931 
2932   /* Initialize the map for the current topology. 'map.xsize' and
2933    * 'map.ysize' must be set. */
2934   map_init_topology();
2935 
2936   /* Allocate map. */
2937   map_allocate();
2938 
2939   /* get the terrain type */
2940   LOAD_MAP_CHAR(ch, ptile, ptile->terrain = char2terrain(ch), loading->file,
2941                 "map.t%04d");
2942   assign_continent_numbers();
2943 
2944   /* Check for special tile sprites. */
2945   whole_map_iterate(ptile) {
2946     const char *spec_sprite;
2947     const char *label;
2948     int nat_x, nat_y;
2949 
2950     index_to_native_pos(&nat_x, &nat_y, tile_index(ptile));
2951     spec_sprite = secfile_lookup_str(loading->file, "map.spec_sprite_%d_%d",
2952                                      nat_x, nat_y);
2953     label = secfile_lookup_str_default(loading->file, NULL, "map.label_%d_%d",
2954                                        nat_x, nat_y);
2955     if (NULL != ptile->spec_sprite) {
2956       ptile->spec_sprite = fc_strdup(spec_sprite);
2957     }
2958     if (label != NULL) {
2959       tile_set_label(ptile, label);
2960     }
2961   } whole_map_iterate_end;
2962 }
2963 
2964 /****************************************************************************
2965   Save all map tiles
2966 ****************************************************************************/
sg_save_map_tiles(struct savedata * saving)2967 static void sg_save_map_tiles(struct savedata *saving)
2968 {
2969   /* Check status and return if not OK (sg_success != TRUE). */
2970   sg_check_ret();
2971 
2972   /* Save the terrain type. */
2973   SAVE_MAP_CHAR(ptile, terrain2char(ptile->terrain), saving->file,
2974                 "map.t%04d");
2975 
2976   /* Save special tile sprites. */
2977   whole_map_iterate(ptile) {
2978     int nat_x, nat_y;
2979 
2980     index_to_native_pos(&nat_x, &nat_y, tile_index(ptile));
2981     if (ptile->spec_sprite) {
2982       secfile_insert_str(saving->file, ptile->spec_sprite,
2983                          "map.spec_sprite_%d_%d", nat_x, nat_y);
2984     }
2985     if (ptile->label != NULL) {
2986       secfile_insert_str(saving->file, ptile->label,
2987                          "map.label_%d_%d", nat_x, nat_y);
2988     }
2989   } whole_map_iterate_end;
2990 }
2991 
2992 /****************************************************************************
2993   Load extras to map
2994 ****************************************************************************/
sg_load_map_tiles_extras(struct loaddata * loading)2995 static void sg_load_map_tiles_extras(struct loaddata *loading)
2996 {
2997   /* Check status and return if not OK (sg_success != TRUE). */
2998   sg_check_ret();
2999 
3000   /* Load extras. */
3001   halfbyte_iterate_extras(j, loading->extra.size) {
3002     LOAD_MAP_CHAR(ch, ptile, sg_extras_set(&ptile->extras, ch, loading->extra.order + 4 * j),
3003                   loading->file, "map.e%02d_%04d", j);
3004   } halfbyte_iterate_extras_end;
3005 }
3006 
3007 /****************************************************************************
3008   Save information about extras on map
3009 ****************************************************************************/
sg_save_map_tiles_extras(struct savedata * saving)3010 static void sg_save_map_tiles_extras(struct savedata *saving)
3011 {
3012   /* Check status and return if not OK (sg_success != TRUE). */
3013   sg_check_ret();
3014 
3015   /* Save extras. */
3016   halfbyte_iterate_extras(j, game.control.num_extra_types) {
3017     int mod[4];
3018     int l;
3019 
3020     for (l = 0; l < 4; l++) {
3021       if (4 * j + 1 > game.control.num_extra_types) {
3022         mod[l] = -1;
3023       } else {
3024         mod[l] = 4 * j + l;
3025       }
3026     }
3027     SAVE_MAP_CHAR(ptile, sg_extras_get(ptile->extras, mod),
3028                   saving->file, "map.e%02d_%04d", j);
3029   } halfbyte_iterate_extras_end;
3030 }
3031 
3032 /****************************************************************************
3033   Load bases to map
3034 ****************************************************************************/
sg_load_map_tiles_bases(struct loaddata * loading)3035 static void sg_load_map_tiles_bases(struct loaddata *loading)
3036 {
3037   /* Check status and return if not OK (sg_success != TRUE). */
3038   sg_check_ret();
3039 
3040   /* Load bases. */
3041   halfbyte_iterate_bases(j, loading->base.size) {
3042     LOAD_MAP_CHAR(ch, ptile, sg_bases_set(&ptile->extras, ch,
3043                                           loading->base.order + 4 * j),
3044                   loading->file, "map.b%02d_%04d", j);
3045   } halfbyte_iterate_bases_end;
3046 }
3047 
3048 /****************************************************************************
3049   Load roads to map
3050 ****************************************************************************/
sg_load_map_tiles_roads(struct loaddata * loading)3051 static void sg_load_map_tiles_roads(struct loaddata *loading)
3052 {
3053   /* Check status and return if not OK (sg_success != TRUE). */
3054   sg_check_ret();
3055 
3056   /* Load roads. */
3057   halfbyte_iterate_roads(j, loading->road.size) {
3058     LOAD_MAP_CHAR(ch, ptile, sg_roads_set(&ptile->extras, ch,
3059                                           loading->road.order + 4 * j),
3060                   loading->file, "map.r%02d_%04d", j);
3061   } halfbyte_iterate_roads_end;
3062 }
3063 
3064 /****************************************************************************
3065   Load information about specials on map
3066 ****************************************************************************/
sg_load_map_tiles_specials(struct loaddata * loading,bool rivers_overlay)3067 static void sg_load_map_tiles_specials(struct loaddata *loading,
3068                                        bool rivers_overlay)
3069 {
3070   /* Check status and return if not OK (sg_success != TRUE). */
3071   sg_check_ret();
3072 
3073   /* If 'rivers_overlay' is set to TRUE, load only the rivers overlay map
3074    * from the savegame file.
3075    *
3076    * A scenario may define the terrain of the map but not list the specials
3077    * on it (thus allowing users to control the placement of specials).
3078    * However rivers are a special case and must be included in the map along
3079    * with the scenario. Thus in those cases this function should be called
3080    * to load the river information separate from any other special data.
3081    *
3082    * This does not need to be called from map_load(), because map_load()
3083    * loads the rivers overlay along with the rest of the specials.  Call this
3084    * only if you've already called map_load_tiles(), and want to load only
3085    * the rivers overlay but no other specials. Scenarios that encode things
3086    * this way should have the "riversoverlay" capability. */
3087   halfbyte_iterate_special(j, loading->special.size) {
3088     LOAD_MAP_CHAR(ch, ptile, sg_special_set(ptile, &ptile->extras, ch,
3089                                             loading->special.order + 4 * j,
3090                                             rivers_overlay),
3091                   loading->file, "map.spe%02d_%04d", j);
3092   } halfbyte_iterate_special_end;
3093 }
3094 
3095 /****************************************************************************
3096   Load information about resources on map.
3097 ****************************************************************************/
sg_load_map_tiles_resources(struct loaddata * loading)3098 static void sg_load_map_tiles_resources(struct loaddata *loading)
3099 {
3100   /* Check status and return if not OK (sg_success != TRUE). */
3101   sg_check_ret();
3102 
3103   LOAD_MAP_CHAR(ch, ptile, ptile->resource = char2resource(ch),
3104                 loading->file, "map.res%04d");
3105 
3106   /* After the resources are loaded, indicate those currently valid. */
3107   whole_map_iterate(ptile) {
3108     if (NULL == ptile->resource || NULL == ptile->terrain) {
3109       continue;
3110     }
3111 
3112     if (terrain_has_resource(ptile->terrain, ptile->resource)) {
3113       /* cannot use set_special() for internal values */
3114       ptile->resource_valid = TRUE;
3115     }
3116   } whole_map_iterate_end;
3117 
3118   game.map.server.have_resources = TRUE;
3119   game.scenario.have_resources = TRUE;
3120 }
3121 
3122 /****************************************************************************
3123   Save information about resources on map.
3124 ****************************************************************************/
sg_save_map_tiles_resources(struct savedata * saving)3125 static void sg_save_map_tiles_resources(struct savedata *saving)
3126 {
3127   /* Check status and return if not OK (sg_success != TRUE). */
3128   sg_check_ret();
3129 
3130   SAVE_MAP_CHAR(ptile, resource2char(ptile->resource), saving->file,
3131                 "map.res%04d");
3132 }
3133 
3134 /****************************************************************************
3135   Load starting positions for the players from a savegame file. There should
3136   be at least enough for every player.
3137 ****************************************************************************/
sg_load_map_startpos(struct loaddata * loading)3138 static void sg_load_map_startpos(struct loaddata *loading)
3139 {
3140   struct nation_type *pnation;
3141   struct startpos *psp;
3142   struct tile *ptile;
3143   const char SEPARATOR = '#';
3144   const char *nation_names;
3145   int nat_x, nat_y;
3146   bool exclude;
3147   int i, startpos_count;
3148 
3149   /* Check status and return if not OK (sg_success != TRUE). */
3150   sg_check_ret();
3151 
3152   startpos_count
3153     = secfile_lookup_int_default(loading->file, 0, "map.startpos_count");
3154 
3155   if (0 == startpos_count) {
3156     /* Nothing to do. */
3157     return;
3158   }
3159 
3160   for (i = 0; i < startpos_count; i++) {
3161     if (!secfile_lookup_int(loading->file, &nat_x, "map.startpos%d.x", i)
3162         || !secfile_lookup_int(loading->file, &nat_y,
3163                                "map.startpos%d.y", i)) {
3164       log_sg("Warning: Undefined coordinates for startpos %d", i);
3165       continue;
3166     }
3167 
3168     ptile = native_pos_to_tile(nat_x, nat_y);
3169     if (NULL == ptile) {
3170       log_error("Start position native coordinates (%d, %d) do not exist "
3171                 "in this map. Skipping...", nat_x, nat_y);
3172       continue;
3173     }
3174 
3175     exclude = secfile_lookup_bool_default(loading->file, FALSE,
3176                                           "map.startpos%d.exclude", i);
3177 
3178     psp = map_startpos_new(ptile);
3179 
3180     nation_names = secfile_lookup_str(loading->file,
3181                                       "map.startpos%d.nations", i);
3182     if (NULL != nation_names && '\0' != nation_names[0]) {
3183       const size_t size = strlen(nation_names) + 1;
3184       char buf[size], *start, *end;
3185 
3186       memcpy(buf, nation_names, size);
3187       for (start = buf - 1; NULL != start; start = end) {
3188         start++;
3189         if ((end = strchr(start, SEPARATOR))) {
3190           *end = '\0';
3191         }
3192 
3193         pnation = nation_by_rule_name(start);
3194         if (NO_NATION_SELECTED != pnation) {
3195           if (exclude) {
3196             startpos_disallow(psp, pnation);
3197           } else {
3198             startpos_allow(psp, pnation);
3199           }
3200         } else {
3201           log_verbose("Missing nation \"%s\".", start);
3202         }
3203       }
3204     }
3205   }
3206 
3207   if (0 < map_startpos_count()
3208       && loading->server_state == S_S_INITIAL
3209       && map_startpos_count() < game.server.max_players) {
3210     log_verbose("Number of starts (%d) are lower than rules.max_players "
3211                 "(%d), lowering rules.max_players.",
3212                 map_startpos_count(), game.server.max_players);
3213     game.server.max_players = map_startpos_count();
3214   }
3215 
3216   /* Re-initialize nation availability in light of start positions.
3217    * This has to be after loading [scenario] and [map].startpos and
3218    * before we seek nations for players. */
3219   update_nations_with_startpos();
3220 }
3221 
3222 /****************************************************************************
3223   Save the map start positions.
3224 ****************************************************************************/
sg_save_map_startpos(struct savedata * saving)3225 static void sg_save_map_startpos(struct savedata *saving)
3226 {
3227   struct tile *ptile;
3228   const char SEPARATOR = '#';
3229   int i = 0;
3230 
3231   /* Check status and return if not OK (sg_success != TRUE). */
3232   sg_check_ret();
3233 
3234   if (!game.server.save_options.save_starts) {
3235     return;
3236   }
3237 
3238   secfile_insert_int(saving->file, map_startpos_count(),
3239                      "map.startpos_count");
3240 
3241   map_startpos_iterate(psp) {
3242     int nat_x, nat_y;
3243 
3244     ptile = startpos_tile(psp);
3245 
3246     index_to_native_pos(&nat_x, &nat_y, tile_index(ptile));
3247     secfile_insert_int(saving->file, nat_x, "map.startpos%d.x", i);
3248     secfile_insert_int(saving->file, nat_y, "map.startpos%d.y", i);
3249 
3250     secfile_insert_bool(saving->file, startpos_is_excluding(psp),
3251                         "map.startpos%d.exclude", i);
3252     if (startpos_allows_all(psp)) {
3253       secfile_insert_str(saving->file, "", "map.startpos%d.nations", i);
3254     } else {
3255       const struct nation_hash *nations = startpos_raw_nations(psp);
3256       char nation_names[MAX_LEN_NAME * nation_hash_size(nations)];
3257 
3258       nation_names[0] = '\0';
3259       nation_hash_iterate(nations, pnation) {
3260         if ('\0' == nation_names[0]) {
3261           fc_strlcpy(nation_names, nation_rule_name(pnation),
3262                      sizeof(nation_names));
3263         } else {
3264           cat_snprintf(nation_names, sizeof(nation_names),
3265                        "%c%s", SEPARATOR, nation_rule_name(pnation));
3266         }
3267       } nation_hash_iterate_end;
3268       secfile_insert_str(saving->file, nation_names,
3269                          "map.startpos%d.nations", i);
3270     }
3271     i++;
3272   } map_startpos_iterate_end;
3273 
3274   fc_assert(map_startpos_count() == i);
3275 }
3276 
3277 /****************************************************************************
3278   Load tile owner information
3279 ****************************************************************************/
sg_load_map_owner(struct loaddata * loading)3280 static void sg_load_map_owner(struct loaddata *loading)
3281 {
3282   int x, y;
3283   struct player *owner = NULL;
3284   struct tile *claimer = NULL;
3285   struct player *eowner = NULL;
3286 
3287   /* Check status and return if not OK (sg_success != TRUE). */
3288   sg_check_ret();
3289 
3290   if (game.info.is_new_game) {
3291     /* No owner/source information for a new game / scenario. */
3292     return;
3293   }
3294 
3295   /* Owner and ownership source are stored as plain numbers */
3296   for (y = 0; y < game.map.ysize; y++) {
3297     const char *buffer1 = secfile_lookup_str(loading->file,
3298                                              "map.owner%04d", y);
3299     const char *buffer2 = secfile_lookup_str(loading->file,
3300                                              "map.source%04d", y);
3301     const char *buffer3 = secfile_lookup_str(loading->file,
3302                                              "map.eowner%04d", y);
3303     const char *ptr1 = buffer1;
3304     const char *ptr2 = buffer2;
3305     const char *ptr3 = buffer3;
3306 
3307     sg_failure_ret(buffer1 != NULL, "%s", secfile_error());
3308     sg_failure_ret(buffer2 != NULL, "%s", secfile_error());
3309     if (loading->version >= 30) {
3310       sg_failure_ret(buffer3 != NULL, "%s", secfile_error());
3311     }
3312 
3313     for (x = 0; x < game.map.xsize; x++) {
3314       char token1[TOKEN_SIZE];
3315       char token2[TOKEN_SIZE];
3316       char token3[TOKEN_SIZE];
3317       int number;
3318       struct tile *ptile = native_pos_to_tile(x, y);
3319 
3320       scanin(&ptr1, ",", token1, sizeof(token1));
3321       sg_failure_ret(token1[0] != '\0',
3322                      "Map size not correct (map.owner%d).", y);
3323       if (strcmp(token1, "-") == 0) {
3324         owner = NULL;
3325       } else {
3326         sg_failure_ret(str_to_int(token1, &number),
3327                        "Got map owner %s in (%d, %d).", token1, x, y);
3328         owner = player_by_number(number);
3329       }
3330 
3331       scanin(&ptr2, ",", token2, sizeof(token2));
3332       sg_failure_ret(token2[0] != '\0',
3333                      "Map size not correct (map.source%d).", y);
3334       if (strcmp(token2, "-") == 0) {
3335         claimer = NULL;
3336       } else {
3337         sg_failure_ret(str_to_int(token2, &number),
3338                        "Got map source %s in (%d, %d).", token2, x, y);
3339         claimer = index_to_tile(number);
3340       }
3341 
3342       if (loading->version >= 30) {
3343         scanin(&ptr3, ",", token3, sizeof(token3));
3344         sg_failure_ret(token3[0] != '\0',
3345                        "Map size not correct (map.eowner%d).", y);
3346         if (strcmp(token3, "-") == 0) {
3347           eowner = NULL;
3348         } else {
3349           sg_failure_ret(str_to_int(token3, &number),
3350                          "Got base owner %s in (%d, %d).", token3, x, y);
3351           eowner = player_by_number(number);
3352         }
3353       } else {
3354         eowner = owner;
3355       }
3356 
3357       map_claim_ownership(ptile, owner, claimer, FALSE);
3358       tile_claim_bases(ptile, eowner);
3359       log_debug("extras_owner(%d, %d) = %s", TILE_XY(ptile), player_name(eowner));
3360     }
3361   }
3362 }
3363 
3364 /****************************************************************************
3365   Save tile owner information
3366 ****************************************************************************/
sg_save_map_owner(struct savedata * saving)3367 static void sg_save_map_owner(struct savedata *saving)
3368 {
3369   int x, y;
3370 
3371   /* Check status and return if not OK (sg_success != TRUE). */
3372   sg_check_ret();
3373 
3374   if (saving->scenario && !saving->save_players) {
3375     /* Nothing to do for a scenario without saved players. */
3376     return;
3377   }
3378 
3379   /* Store owner and ownership source as plain numbers. */
3380   for (y = 0; y < game.map.ysize; y++) {
3381     char line[game.map.xsize * TOKEN_SIZE];
3382 
3383     line[0] = '\0';
3384     for (x = 0; x < game.map.xsize; x++) {
3385       char token[TOKEN_SIZE];
3386       struct tile *ptile = native_pos_to_tile(x, y);
3387 
3388       if (!saving->save_players || tile_owner(ptile) == NULL) {
3389         strcpy(token, "-");
3390       } else {
3391         fc_snprintf(token, sizeof(token), "%d",
3392                     player_number(tile_owner(ptile)));
3393       }
3394       strcat(line, token);
3395       if (x + 1 < game.map.xsize) {
3396         strcat(line, ",");
3397       }
3398     }
3399     secfile_insert_str(saving->file, line, "map.owner%04d", y);
3400   }
3401 
3402   for (y = 0; y < game.map.ysize; y++) {
3403     char line[game.map.xsize * TOKEN_SIZE];
3404 
3405     line[0] = '\0';
3406     for (x = 0; x < game.map.xsize; x++) {
3407       char token[TOKEN_SIZE];
3408       struct tile *ptile = native_pos_to_tile(x, y);
3409 
3410       if (ptile->claimer == NULL) {
3411         strcpy(token, "-");
3412       } else {
3413         fc_snprintf(token, sizeof(token), "%d", tile_index(ptile->claimer));
3414       }
3415       strcat(line, token);
3416       if (x + 1 < game.map.xsize) {
3417         strcat(line, ",");
3418       }
3419     }
3420     secfile_insert_str(saving->file, line, "map.source%04d", y);
3421   }
3422 
3423   for (y = 0; y < game.map.ysize; y++) {
3424     char line[game.map.xsize * TOKEN_SIZE];
3425 
3426     line[0] = '\0';
3427     for (x = 0; x < game.map.xsize; x++) {
3428       char token[TOKEN_SIZE];
3429       struct tile *ptile = native_pos_to_tile(x, y);
3430 
3431       if (!saving->save_players || extra_owner(ptile) == NULL) {
3432         strcpy(token, "-");
3433       } else {
3434         fc_snprintf(token, sizeof(token), "%d",
3435                     player_number(extra_owner(ptile)));
3436       }
3437       strcat(line, token);
3438       if (x + 1 < game.map.xsize) {
3439         strcat(line, ",");
3440       }
3441     }
3442     secfile_insert_str(saving->file, line, "map.eowner%04d", y);
3443   }
3444 }
3445 
3446 /****************************************************************************
3447   Load worked tiles information
3448 ****************************************************************************/
sg_load_map_worked(struct loaddata * loading)3449 static void sg_load_map_worked(struct loaddata *loading)
3450 {
3451   int x, y;
3452 
3453   /* Check status and return if not OK (sg_success != TRUE). */
3454   sg_check_ret();
3455 
3456   sg_failure_ret(loading->worked_tiles == NULL,
3457                  "City worked map not loaded!");
3458 
3459   loading->worked_tiles = fc_malloc(MAP_INDEX_SIZE *
3460                                     sizeof(*loading->worked_tiles));
3461 
3462   for (y = 0; y < game.map.ysize; y++) {
3463     const char *buffer = secfile_lookup_str(loading->file, "map.worked%04d",
3464                                             y);
3465     const char *ptr = buffer;
3466 
3467     sg_failure_ret(NULL != buffer,
3468                    "Savegame corrupt - map line %d not found.", y);
3469     for (x = 0; x < game.map.xsize; x++) {
3470       char token[TOKEN_SIZE];
3471       int number;
3472       struct tile *ptile = native_pos_to_tile(x, y);
3473 
3474       scanin(&ptr, ",", token, sizeof(token));
3475       sg_failure_ret('\0' != token[0],
3476                      "Savegame corrupt - map size not correct.");
3477       if (strcmp(token, "-") == 0) {
3478         number = -1;
3479       } else {
3480         sg_failure_ret(str_to_int(token, &number) && 0 < number,
3481                        "Savegame corrupt - got tile worked by city "
3482                        "id=%s in (%d, %d).", token, x, y);
3483       }
3484 
3485       loading->worked_tiles[ptile->index] = number;
3486     }
3487   }
3488 }
3489 
3490 /****************************************************************************
3491   Save worked tiles information
3492 ****************************************************************************/
sg_save_map_worked(struct savedata * saving)3493 static void sg_save_map_worked(struct savedata *saving)
3494 {
3495   int x, y;
3496 
3497   /* Check status and return if not OK (sg_success != TRUE). */
3498   sg_check_ret();
3499 
3500   if (saving->scenario && !saving->save_players) {
3501     /* Nothing to do for a scenario without saved players. */
3502     return;
3503   }
3504 
3505   /* additionally save the tiles worked by the cities */
3506   for (y = 0; y < game.map.ysize; y++) {
3507     char line[game.map.xsize * TOKEN_SIZE];
3508 
3509     line[0] = '\0';
3510     for (x = 0; x < game.map.xsize; x++) {
3511       char token[TOKEN_SIZE];
3512       struct tile *ptile = native_pos_to_tile(x, y);
3513       struct city *pcity = tile_worked(ptile);
3514 
3515       if (pcity == NULL) {
3516         strcpy(token, "-");
3517       } else {
3518         fc_snprintf(token, sizeof(token), "%d", pcity->id);
3519       }
3520       strcat(line, token);
3521       if (x < game.map.xsize) {
3522         strcat(line, ",");
3523       }
3524     }
3525     secfile_insert_str(saving->file, line, "map.worked%04d", y);
3526   }
3527 }
3528 
3529 /****************************************************************************
3530   Load tile known status
3531 ****************************************************************************/
sg_load_map_known(struct loaddata * loading)3532 static void sg_load_map_known(struct loaddata *loading)
3533 {
3534   /* Check status and return if not OK (sg_success != TRUE). */
3535   sg_check_ret();
3536 
3537   players_iterate(pplayer) {
3538     /* Allocate player private map here; it is needed in different modules
3539      * besides this one ((i.e. sg_load_player_*()). */
3540     player_map_init(pplayer);
3541   } players_iterate_end;
3542 
3543   if (secfile_lookup_bool_default(loading->file, TRUE,
3544                                   "game.save_known")) {
3545     int lines = player_slot_max_used_number()/32 + 1, j, p, l, i;
3546     unsigned int *known = fc_calloc(lines * MAP_INDEX_SIZE, sizeof(*known));
3547 
3548     for (l = 0; l < lines; l++) {
3549       for (j = 0; j < 8; j++) {
3550         for (i = 0; i < 4; i++) {
3551           /* Only bother trying to load the map for this halfbyte if at least
3552            * one of the corresponding player slots is in use. */
3553           if (player_slot_is_used(player_slot_by_number(l*32 + j*4 + i))) {
3554             LOAD_MAP_CHAR(ch, ptile,
3555                           known[l * MAP_INDEX_SIZE + tile_index(ptile)]
3556                             |= ascii_hex2bin(ch, j),
3557                           loading->file, "map.k%02d_%04d", l * 8 + j);
3558             break;
3559           }
3560         }
3561       }
3562     }
3563 
3564     players_iterate(pplayer) {
3565       dbv_clr_all(&pplayer->tile_known);
3566     } players_iterate_end;
3567 
3568     /* HACK: we read the known data from hex into 32-bit integers, and
3569      * now we convert it to the known tile data of each player. */
3570     whole_map_iterate(ptile) {
3571       players_iterate(pplayer) {
3572         p = player_index(pplayer);
3573         l = player_index(pplayer) / 32;
3574 
3575         if (known[l * MAP_INDEX_SIZE + tile_index(ptile)] & (1u << (p % 32))) {
3576           map_set_known(ptile, pplayer);
3577         }
3578       } players_iterate_end;
3579     } whole_map_iterate_end;
3580 
3581     FC_FREE(known);
3582   }
3583 }
3584 
3585 /****************************************************************************
3586   Save tile known status for whole map and all players
3587 ****************************************************************************/
sg_save_map_known(struct savedata * saving)3588 static void sg_save_map_known(struct savedata *saving)
3589 {
3590   /* Check status and return if not OK (sg_success != TRUE). */
3591   sg_check_ret();
3592 
3593   if (!saving->save_players) {
3594     secfile_insert_bool(saving->file, FALSE, "game.save_known");
3595     return;
3596   } else {
3597     int lines = player_slot_max_used_number()/32 + 1;
3598 
3599     secfile_insert_bool(saving->file, game.server.save_options.save_known,
3600                         "game.save_known");
3601     if (game.server.save_options.save_known) {
3602       int j, p, l, i;
3603       unsigned int *known = fc_calloc(lines * MAP_INDEX_SIZE, sizeof(*known));
3604 
3605       /* HACK: we convert the data into a 32-bit integer, and then save it as
3606        * hex. */
3607 
3608       whole_map_iterate(ptile) {
3609         players_iterate(pplayer) {
3610           if (map_is_known(ptile, pplayer)) {
3611             p = player_index(pplayer);
3612             l = p / 32;
3613             known[l * MAP_INDEX_SIZE + tile_index(ptile)]
3614               |= (1u << (p % 32)); /* "p % 32" = "p - l * 32" */
3615           }
3616         } players_iterate_end;
3617       } whole_map_iterate_end;
3618 
3619       for (l = 0; l < lines; l++) {
3620         for (j = 0; j < 8; j++) {
3621           for (i = 0; i < 4; i++) {
3622             /* Only bother saving the map for this halfbyte if at least one
3623              * of the corresponding player slots is in use */
3624             if (player_slot_is_used(player_slot_by_number(l*32 + j*4 + i))) {
3625               /* put 4-bit segments of the 32-bit "known" field */
3626               SAVE_MAP_CHAR(ptile, bin2ascii_hex(known[l * MAP_INDEX_SIZE
3627                                                        + tile_index(ptile)], j),
3628                             saving->file, "map.k%02d_%04d", l * 8 + j);
3629               break;
3630             }
3631           }
3632         }
3633       }
3634 
3635       FC_FREE(known);
3636     }
3637   }
3638 }
3639 
3640 /* =======================================================================
3641  * Load / save player data.
3642  *
3643  * This is splitted into two parts as some data can only be loaded if the
3644  * number of players is known and the corresponding player slots are
3645  * defined.
3646  * ======================================================================= */
3647 
3648 /****************************************************************************
3649   Load '[player]' (basic data).
3650 ****************************************************************************/
sg_load_players_basic(struct loaddata * loading)3651 static void sg_load_players_basic(struct loaddata *loading)
3652 {
3653   int i, k, nplayers;
3654   const char *string;
3655   bool shuffle_loaded = TRUE;
3656 
3657   /* Check status and return if not OK (sg_success != TRUE). */
3658   sg_check_ret();
3659 
3660   if (S_S_INITIAL == loading->server_state
3661       || game.info.is_new_game) {
3662     /* Nothing more to do. */
3663     return;
3664   }
3665 
3666   /* Load destroyed wonders: */
3667   string = secfile_lookup_str(loading->file,
3668                               "players.destroyed_wonders");
3669   sg_failure_ret(string != NULL, "%s", secfile_error());
3670   sg_failure_ret(strlen(string) == loading->improvement.size,
3671                  "Invalid length for 'players.destroyed_wonders' "
3672                  "(%lu ~= %lu)", (unsigned long) strlen(string),
3673                  (unsigned long) loading->improvement.size);
3674   for (k = 0; k < loading->improvement.size; k++) {
3675     sg_failure_ret(string[k] == '1' || string[k] == '0',
3676                    "Undefined value '%c' within "
3677                    "'players.destroyed_wonders'.", string[k]);
3678 
3679     if (string[k] == '1') {
3680       struct impr_type *pimprove =
3681           improvement_by_rule_name(loading->improvement.order[k]);
3682       if (pimprove) {
3683         game.info.great_wonder_owners[improvement_index(pimprove)]
3684           = WONDER_DESTROYED;
3685       }
3686     }
3687   }
3688 
3689   server.identity_number
3690     = secfile_lookup_int_default(loading->file, server.identity_number,
3691                                  "players.identity_number_used");
3692 
3693   /* First remove all defined players. */
3694   players_iterate(pplayer) {
3695     server_remove_player(pplayer);
3696   } players_iterate_end;
3697 
3698   /* Now, load the players from the savefile. */
3699   player_slots_iterate(pslot) {
3700     struct player *pplayer;
3701     struct rgbcolor *prgbcolor = NULL;
3702     int pslot_id = player_slot_index(pslot);
3703 
3704     if (NULL == secfile_section_lookup(loading->file, "player%d",
3705                                        pslot_id)) {
3706       continue;
3707     }
3708 
3709     /* Get player AI type. */
3710     string = secfile_lookup_str(loading->file, "player%d.ai_type",
3711                                 player_slot_index(pslot));
3712     sg_failure_ret(string != NULL, "%s", secfile_error());
3713 
3714     /* Get player color */
3715     if (!rgbcolor_load(loading->file, &prgbcolor, "player%d.color",
3716                        pslot_id)) {
3717       if (loading->version >= 10 && game_was_started()) {
3718         /* 2.4.0 or later savegame. This is not an error in 2.3 savefiles,
3719          * as they predate the introduction of configurable player colors. */
3720         log_sg("Game has started, yet player %d has no color defined.",
3721                pslot_id);
3722         /* This will be fixed up later */
3723       } else {
3724         log_verbose("No color defined for player %d.", pslot_id);
3725         /* Colors will be assigned on game start, or at end of savefile
3726          * loading if game has already started */
3727       }
3728     }
3729 
3730     /* Create player. */
3731     pplayer = server_create_player(player_slot_index(pslot), string,
3732                                    prgbcolor, game.scenario.allow_ai_type_fallback);
3733     sg_failure_ret(pplayer != NULL, "Invalid AI type: '%s'!", string);
3734 
3735     server_player_init(pplayer, FALSE, FALSE);
3736 
3737     /* Free the color definition. */
3738     rgbcolor_destroy(prgbcolor);
3739 
3740     /* Multipliers (policies) */
3741 
3742     /* First initialise player values with ruleset defaults; this will
3743      * cover any in the ruleset not known when the savefile was created. */
3744     multipliers_iterate(pmul) {
3745       pplayer->multipliers[multiplier_index(pmul)]
3746         = pplayer->multipliers_target[multiplier_index(pmul)] = pmul->def;
3747     } multipliers_iterate_end;
3748 
3749     /* Now override with any values from the savefile. */
3750     for (k = 0; k < loading->multiplier.size; k++) {
3751       const struct multiplier *pmul = loading->multiplier.order[k];
3752 
3753       if (pmul) {
3754         Multiplier_type_id idx = multiplier_index(pmul);
3755         int val =
3756           secfile_lookup_int_default(loading->file, pmul->def,
3757                                      "player%d.multiplier%d.val",
3758                                      player_slot_index(pslot), k);
3759         int rval = (((CLIP(pmul->start, val, pmul->stop)
3760                       - pmul->start) / pmul->step) * pmul->step) + pmul->start;
3761 
3762         if (rval != val) {
3763           log_verbose("Player %d had illegal value for multiplier \"%s\": "
3764                       "was %d, clamped to %d", pslot_id,
3765                       multiplier_rule_name(pmul), val, rval);
3766         }
3767         pplayer->multipliers[idx] = rval;
3768 
3769         val =
3770           secfile_lookup_int_default(loading->file,
3771                                      pplayer->multipliers[idx],
3772                                      "player%d.multiplier%d.target",
3773                                      player_slot_index(pslot), k);
3774         rval = (((CLIP(pmul->start, val, pmul->stop)
3775                   - pmul->start) / pmul->step) * pmul->step) + pmul->start;
3776 
3777         if (rval != val) {
3778           log_verbose("Player %d had illegal value for multiplier_target "
3779                       "\"%s\": was %d, clamped to %d", pslot_id,
3780                       multiplier_rule_name(pmul), val, rval);
3781         }
3782         pplayer->multipliers_target[idx] = rval;
3783       } /* else silently discard multiplier not in current ruleset */
3784     }
3785   } player_slots_iterate_end;
3786 
3787   /* check number of players */
3788   nplayers = secfile_lookup_int_default(loading->file, 0, "players.nplayers");
3789   sg_failure_ret(player_count() == nplayers, "The value of players.nplayers "
3790                  "(%d) from the loaded game does not match the number of "
3791                  "players present (%d).", nplayers, player_count());
3792 
3793   /* Load team informations. */
3794   players_iterate(pplayer) {
3795     int team;
3796     struct team_slot *tslot = NULL;
3797 
3798     sg_failure_ret(secfile_lookup_int(loading->file, &team,
3799                                       "player%d.team_no",
3800                                       player_number(pplayer))
3801                    && (tslot = team_slot_by_number(team)),
3802                    "Invalid team definition for player %s (nb %d).",
3803                    player_name(pplayer), player_number(pplayer));
3804     team_add_player(pplayer, team_new(tslot));
3805   } players_iterate_end;
3806 
3807   /* Loading the shuffle list is quite complex. At the time of saving the
3808    * shuffle data is saved as
3809    *   shuffled_player_<number> = player_slot_id
3810    * where number is an increasing number and player_slot_id is a number
3811    * between 0 and the maximum number of player slots. Now we have to create
3812    * a list
3813    *   shuffler_players[number] = player_slot_id
3814    * where all player slot IDs are used exactly one time. The code below
3815    * handles this ... */
3816   if (secfile_lookup_int_default(loading->file, -1,
3817                                  "players.shuffled_player_%d", 0) >= 0) {
3818     int shuffled_players[player_slot_count()];
3819     bool shuffled_player_set[player_slot_count()];
3820 
3821     player_slots_iterate(pslot) {
3822       int plrid = player_slot_index(pslot);
3823 
3824       /* Array to save used numbers. */
3825       shuffled_player_set[plrid] = FALSE;
3826       /* List of all player IDs (needed for set_shuffled_players()). It is
3827        * initialised with the value -1 to indicate that no value is set. */
3828       shuffled_players[plrid] = -1;
3829     } player_slots_iterate_end;
3830 
3831     /* Load shuffled player list. */
3832     for (i = 0; i < player_count(); i++){
3833       int shuffle
3834         = secfile_lookup_int_default(loading->file, -1,
3835                                      "players.shuffled_player_%d", i);
3836 
3837       if (shuffle == -1) {
3838         log_sg("Missing player shuffle information (index %d) "
3839                "- reshuffle player list!", i);
3840         shuffle_loaded = FALSE;
3841         break;
3842       } else if (shuffled_player_set[shuffle]) {
3843         log_sg("Player shuffle %d used two times "
3844                "- reshuffle player list!", shuffle);
3845         shuffle_loaded = FALSE;
3846         break;
3847       }
3848       /* Set this ID as used. */
3849       shuffled_player_set[shuffle] = TRUE;
3850 
3851       /* Save the player ID in the shuffle list. */
3852       shuffled_players[i] = shuffle;
3853     }
3854 
3855     if (shuffle_loaded) {
3856       /* Insert missing numbers. */
3857       int shuffle_index = player_count();
3858       for (i = 0; i < player_slot_count(); i++){
3859         if (!shuffled_player_set[i]) {
3860           shuffled_players[shuffle_index] = i;
3861           shuffle_index++;
3862         }
3863         /* shuffle_index must not grow behind the size of shuffled_players. */
3864         sg_failure_ret(shuffle_index <= player_slot_count(),
3865                        "Invalid player shuffle data!");
3866       }
3867 
3868 #ifdef DEBUG
3869       log_debug("[load shuffle] player_count() = %d", player_count());
3870       player_slots_iterate(pslot) {
3871         int plrid = player_slot_index(pslot);
3872         log_debug("[load shuffle] id: %3d => slot: %3d | slot %3d: %s",
3873                   plrid, shuffled_players[plrid], plrid,
3874                   shuffled_player_set[plrid] ? "is used" : "-");
3875       } player_slots_iterate_end;
3876 #endif /* DEBUG */
3877 
3878       /* Set shuffle list from savegame. */
3879       set_shuffled_players(shuffled_players);
3880     }
3881   }
3882 
3883   if (!shuffle_loaded) {
3884     /* No shuffled players included or error loading them, so shuffle them
3885      * (this may include scenarios). */
3886     shuffle_players();
3887   }
3888 }
3889 
3890 /****************************************************************************
3891   Load '[player]'.
3892 ****************************************************************************/
sg_load_players(struct loaddata * loading)3893 static void sg_load_players(struct loaddata *loading)
3894 {
3895   /* Check status and return if not OK (sg_success != TRUE). */
3896   sg_check_ret();
3897 
3898   if (game.info.is_new_game) {
3899     /* Nothing to do. */
3900     return;
3901   }
3902 
3903   players_iterate(pplayer) {
3904     sg_load_player_main(loading, pplayer);
3905     sg_load_player_cities(loading, pplayer);
3906     sg_load_player_units(loading, pplayer);
3907     sg_load_player_attributes(loading, pplayer);
3908 
3909     /* Check the sucess of the functions above. */
3910     sg_check_ret();
3911 
3912     /* print out some informations */
3913     if (pplayer->ai_controlled) {
3914       log_normal(_("%s has been added as %s level AI-controlled player "
3915                    "(%s)."), player_name(pplayer),
3916                  ai_level_translated_name(pplayer->ai_common.skill_level),
3917                  ai_name(pplayer->ai));
3918     } else {
3919       log_normal(_("%s has been added as human player."),
3920                  player_name(pplayer));
3921     }
3922   } players_iterate_end;
3923 
3924   /* Also load the transport status of the units here. It must be a special
3925    * case as all units must be known (unit on an allied transporter). */
3926   players_iterate(pplayer) {
3927     /* Load unit transport status. */
3928     sg_load_player_units_transport(loading, pplayer);
3929   } players_iterate_end;
3930 
3931   /* Savegame may contain nation assignments that are incompatible with the
3932    * current nationset -- for instance, if it predates the introduction of
3933    * nationsets. Ensure they are compatible, one way or another. */
3934   fit_nationset_to_players();
3935 
3936   /* Some players may have invalid nations in the ruleset. Once all players
3937    * are loaded, pick one of the remaining nations for them. */
3938   players_iterate(pplayer) {
3939     if (pplayer->nation == NO_NATION_SELECTED) {
3940       player_set_nation(pplayer, pick_a_nation(NULL, FALSE, TRUE,
3941                                                NOT_A_BARBARIAN));
3942       /* TRANS: Minor error message: <Leader> ... <Poles>. */
3943       log_sg(_("%s had invalid nation; changing to %s."),
3944              player_name(pplayer), nation_plural_for_player(pplayer));
3945 
3946       ai_traits_init(pplayer);
3947     }
3948   } players_iterate_end;
3949 
3950   /* Sanity check alliances, prevent allied-with-ally-of-enemy. */
3951   players_iterate_alive(plr) {
3952     players_iterate_alive(aplayer) {
3953       if (pplayers_allied(plr, aplayer)) {
3954         enum dipl_reason can_ally = pplayer_can_make_treaty(plr, aplayer,
3955                                                             DS_ALLIANCE);
3956         if (can_ally == DIPL_ALLIANCE_PROBLEM_US
3957             || can_ally == DIPL_ALLIANCE_PROBLEM_THEM) {
3958           log_sg("Illegal alliance structure detected: "
3959                  "%s alliance to %s reduced to peace treaty.",
3960                  nation_rule_name(nation_of_player(plr)),
3961                  nation_rule_name(nation_of_player(aplayer)));
3962           player_diplstate_get(plr, aplayer)->type = DS_PEACE;
3963           player_diplstate_get(aplayer, plr)->type = DS_PEACE;
3964         }
3965       }
3966     } players_iterate_alive_end;
3967   } players_iterate_alive_end;
3968 
3969   /* Update cached city illness. This can depend on trade routes,
3970    * so can't be calculated until all players have been loaded. */
3971   if (game.info.illness_on) {
3972     cities_iterate(pcity) {
3973       pcity->server.illness
3974         = city_illness_calc(pcity, NULL, NULL,
3975                             &(pcity->illness_trade), NULL);
3976     } cities_iterate_end;
3977   }
3978 
3979   /* Update all city information.  This must come after all cities are
3980    * loaded (in player_load) but before player (dumb) cities are loaded
3981    * in player_load_vision(). */
3982   players_iterate(plr) {
3983     city_list_iterate(plr->cities, pcity) {
3984       city_refresh(pcity);
3985       sanity_check_city(pcity);
3986       CALL_PLR_AI_FUNC(city_got, plr, plr, pcity);
3987     } city_list_iterate_end;
3988   } players_iterate_end;
3989 
3990   /* Since the cities must be placed on the map to put them on the
3991      player map we do this afterwards */
3992   players_iterate(pplayer) {
3993     sg_load_player_vision(loading, pplayer);
3994     /* Check the sucess of the function above. */
3995     sg_check_ret();
3996   } players_iterate_end;
3997 
3998   /* Check shared vision. */
3999   players_iterate(pplayer) {
4000     BV_CLR_ALL(pplayer->gives_shared_vision);
4001     BV_CLR_ALL(pplayer->server.really_gives_vision);
4002   } players_iterate_end;
4003 
4004   players_iterate(pplayer) {
4005     int plr1 = player_index(pplayer);
4006 
4007     players_iterate(pplayer2) {
4008       int plr2 = player_index(pplayer2);
4009       if (secfile_lookup_bool_default(loading->file, FALSE,
4010               "player%d.diplstate%d.gives_shared_vision", plr1, plr2)) {
4011         give_shared_vision(pplayer, pplayer2);
4012       }
4013     } players_iterate_end;
4014   } players_iterate_end;
4015 
4016   initialize_globals();
4017   unit_ordering_apply();
4018 
4019   /* All vision is ready; this calls city_thaw_workers_queue(). */
4020   map_calculate_borders();
4021 
4022   /* Make sure everything is consistent. */
4023   players_iterate(pplayer) {
4024     unit_list_iterate(pplayer->units, punit) {
4025       if (!can_unit_continue_current_activity(punit)) {
4026         log_sg("Unit doing illegal activity in savegame!");
4027         log_sg("Activity: %s, Target: %s",
4028                unit_activity_name(punit->activity),
4029                punit->activity_target ? extra_rule_name(
4030                                           punit->activity_target)
4031                                       : "missing");
4032         punit->activity = ACTIVITY_IDLE;
4033       }
4034     } unit_list_iterate_end;
4035   } players_iterate_end;
4036 
4037   cities_iterate(pcity) {
4038     city_refresh(pcity);
4039     city_thaw_workers(pcity); /* may auto_arrange_workers() */
4040   } cities_iterate_end;
4041 
4042   /* Player colors are always needed once game has started. Pre-2.4 savegames
4043    * lack them. This cannot be in compatibility conversion layer as we need
4044    * all the player data available to be able to assign best colors. */
4045   if (game_was_started()) {
4046     assign_player_colors();
4047   }
4048 }
4049 
4050 /****************************************************************************
4051   Save '[player]'.
4052 ****************************************************************************/
sg_save_players(struct savedata * saving)4053 static void sg_save_players(struct savedata *saving)
4054 {
4055   /* Check status and return if not OK (sg_success != TRUE). */
4056   sg_check_ret();
4057 
4058   if ((saving->scenario && !saving->save_players)
4059       || !game_was_started()) {
4060     /* Nothing to do for a scenario without saved players or a game in
4061      * INITIAL state. */
4062     return;
4063   }
4064 
4065   secfile_insert_int(saving->file, player_count(), "players.nplayers");
4066 
4067   /* Save destroyed wonders as bitvector. Note that improvement order
4068    * is saved in 'savefile.improvement.order'. */
4069   {
4070     char destroyed[B_LAST+1];
4071 
4072     improvement_iterate(pimprove) {
4073       if (is_great_wonder(pimprove)
4074           && great_wonder_is_destroyed(pimprove)) {
4075         destroyed[improvement_index(pimprove)] = '1';
4076       } else {
4077         destroyed[improvement_index(pimprove)] = '0';
4078       }
4079     } improvement_iterate_end;
4080     destroyed[improvement_count()] = '\0';
4081     secfile_insert_str(saving->file, destroyed,
4082                        "players.destroyed_wonders");
4083   }
4084 
4085   secfile_insert_int(saving->file, server.identity_number,
4086                      "players.identity_number_used");
4087 
4088   /* Save player order. */
4089   {
4090     int i = 0;
4091     shuffled_players_iterate(pplayer) {
4092       secfile_insert_int(saving->file, player_number(pplayer),
4093                          "players.shuffled_player_%d", i);
4094       i++;
4095     } shuffled_players_iterate_end;
4096   }
4097 
4098   /* Sort units. */
4099   unit_ordering_calc();
4100 
4101   /* Save players. */
4102   players_iterate(pplayer) {
4103     sg_save_player_main(saving, pplayer);
4104     sg_save_player_cities(saving, pplayer);
4105     sg_save_player_units(saving, pplayer);
4106     sg_save_player_attributes(saving, pplayer);
4107     sg_save_player_vision(saving, pplayer);
4108   } players_iterate_end;
4109 }
4110 
4111 /****************************************************************************
4112   Main player data loading function
4113 ****************************************************************************/
sg_load_player_main(struct loaddata * loading,struct player * plr)4114 static void sg_load_player_main(struct loaddata *loading,
4115                                 struct player *plr)
4116 {
4117   int i, plrno = player_number(plr);
4118   const char *string;
4119   struct government *gov;
4120   const char *level;
4121   const char *barb_str;
4122 
4123   /* Check status and return if not OK (sg_success != TRUE). */
4124   sg_check_ret();
4125 
4126   /* Basic player data. */
4127   string = secfile_lookup_str(loading->file, "player%d.name", plrno);
4128   sg_failure_ret(string != NULL, "%s", secfile_error());
4129   server_player_set_name(plr, string);
4130   sz_strlcpy(plr->username,
4131              secfile_lookup_str_default(loading->file, "",
4132                                         "player%d.username", plrno));
4133   sg_failure_ret(secfile_lookup_bool(loading->file, &plr->unassigned_user,
4134                                      "player%d.unassigned_user", plrno),
4135                  "%s", secfile_error());
4136   sz_strlcpy(plr->server.orig_username,
4137              secfile_lookup_str_default(loading->file, "",
4138                                         "player%d.orig_username",
4139                                         plrno));
4140   sz_strlcpy(plr->ranked_username,
4141              secfile_lookup_str_default(loading->file, "",
4142                                         "player%d.ranked_username",
4143                                         plrno));
4144   sg_failure_ret(secfile_lookup_bool(loading->file, &plr->unassigned_ranked,
4145                                      "player%d.unassigned_ranked", plrno),
4146                  "%s", secfile_error());
4147   string = secfile_lookup_str_default(loading->file, "",
4148                                       "player%d.delegation_username",
4149                                       plrno);
4150   /* Defaults to no delegation. */
4151   if (strlen(string)) {
4152     player_delegation_set(plr, string);
4153   }
4154 
4155   /* Nation */
4156   string = secfile_lookup_str(loading->file, "player%d.nation", plrno);
4157   player_set_nation(plr, nation_by_rule_name(string));
4158   if (plr->nation != NULL) {
4159     ai_traits_init(plr);
4160   }
4161 
4162   /* Government */
4163   string = secfile_lookup_str(loading->file, "player%d.government_name",
4164                               plrno);
4165   gov = government_by_rule_name(string);
4166   sg_failure_ret(gov != NULL, "Player%d: unsupported government \"%s\".",
4167                  plrno, string);
4168   plr->government = gov;
4169 
4170   /* Target government */
4171   string = secfile_lookup_str(loading->file,
4172                               "player%d.target_government_name", plrno);
4173   if (string) {
4174     plr->target_government = government_by_rule_name(string);
4175   } else {
4176     plr->target_government = NULL;
4177   }
4178   plr->revolution_finishes
4179     = secfile_lookup_int_default(loading->file, -1,
4180                                  "player%d.revolution_finishes", plrno);
4181 
4182   sg_failure_ret(secfile_lookup_bool(loading->file,
4183                                      &plr->server.got_first_city,
4184                                      "player%d.got_first_city", plrno),
4185                  "%s", secfile_error());
4186 
4187   sg_failure_ret(secfile_lookup_bool(loading->file, &plr->ai_controlled,
4188                                      "player%d.ai.control", plrno),
4189                  "%s", secfile_error());
4190 
4191   /* Load diplomatic data (diplstate + embassy + vision).
4192    * Shared vision is loaded in sg_load_players(). */
4193   BV_CLR_ALL(plr->real_embassy);
4194   players_iterate(pplayer) {
4195     char buf[32];
4196     int unconverted;
4197     struct player_diplstate *ds = player_diplstate_get(plr, pplayer);
4198     i = player_index(pplayer);
4199 
4200     /* load diplomatic status */
4201     fc_snprintf(buf, sizeof(buf), "player%d.diplstate%d", plrno, i);
4202 
4203     unconverted =
4204       secfile_lookup_int_default(loading->file, -1, "%s.type", buf);
4205     if (unconverted >= 0 && unconverted < loading->ds_t.size) {
4206       /* Look up what state the unconverted number represents. */
4207       ds->type = loading->ds_t.order[unconverted];
4208     } else {
4209       log_sg("No valid diplomatic state type between players %d and %d",
4210              plrno, i);
4211 
4212       ds->type = DS_WAR;
4213     }
4214 
4215     unconverted =
4216       secfile_lookup_int_default(loading->file, -1, "%s.max_state", buf);
4217     if (unconverted >= 0 && unconverted < loading->ds_t.size) {
4218       /* Look up what state the unconverted number represents. */
4219       ds->max_state = loading->ds_t.order[unconverted];
4220     } else {
4221       log_sg("No valid diplomatic max_state between players %d and %d",
4222              plrno, i);
4223 
4224       ds->max_state = DS_WAR;
4225     }
4226 
4227     ds->first_contact_turn =
4228       secfile_lookup_int_default(loading->file, 0,
4229                                  "%s.first_contact_turn", buf);
4230     ds->turns_left =
4231       secfile_lookup_int_default(loading->file, -2, "%s.turns_left", buf);
4232     ds->has_reason_to_cancel =
4233       secfile_lookup_int_default(loading->file, 0,
4234                                  "%s.has_reason_to_cancel", buf);
4235     ds->contact_turns_left =
4236       secfile_lookup_int_default(loading->file, 0,
4237                                  "%s.contact_turns_left", buf);
4238 
4239     if (secfile_lookup_bool_default(loading->file, FALSE, "%s.embassy",
4240                                     buf)) {
4241       BV_SET(plr->real_embassy, i);
4242     }
4243     /* 'gives_shared_vision' is loaded in sg_load_players() as all cities
4244      * must be known. */
4245   } players_iterate_end;
4246 
4247   /* load ai data */
4248   players_iterate(aplayer) {
4249     char buf[32];
4250 
4251     fc_snprintf(buf, sizeof(buf), "player%d.ai%d", plrno,
4252                 player_index(aplayer));
4253 
4254     plr->ai_common.love[player_index(aplayer)] =
4255         secfile_lookup_int_default(loading->file, 1, "%s.love", buf);
4256     CALL_FUNC_EACH_AI(player_load_relations, plr, aplayer, loading->file, plrno);
4257   } players_iterate_end;
4258 
4259   CALL_FUNC_EACH_AI(player_load, plr, loading->file, plrno);
4260 
4261   /* Some sane defaults */
4262   plr->ai_common.fuzzy = 0;
4263   plr->ai_common.expand = 100;
4264   plr->ai_common.science_cost = 100;
4265 
4266 
4267   level = secfile_lookup_str_default(loading->file, NULL,
4268                                      "player%d.ai.level", plrno);
4269   if (level != NULL) {
4270     plr->ai_common.skill_level = ai_level_by_name(level, fc_strcasecmp);
4271 
4272     /* In builds where level "Experimental" is not supported, convert it to "Hard" */
4273     if (!ai_level_is_valid(plr->ai_common.skill_level)
4274         && !fc_strcasecmp(level, "Experimental")) {
4275       plr->ai_common.skill_level = AI_LEVEL_HARD;
4276     }
4277   } else {
4278     plr->ai_common.skill_level = ai_level_invalid();
4279   }
4280 
4281   if (!ai_level_is_valid(plr->ai_common.skill_level)) {
4282     plr->ai_common.skill_level
4283       = ai_level_convert(secfile_lookup_int_default(loading->file,
4284                                                     game.info.skill_level,
4285                                                     "player%d.ai.skill_level",
4286                                                     plrno));
4287   }
4288 
4289   barb_str = secfile_lookup_str_default(loading->file, "None",
4290                                         "player%d.ai.barb_type", plrno);
4291   plr->ai_common.barbarian_type = barbarian_type_by_name(barb_str, fc_strcasecmp);
4292 
4293   if (!barbarian_type_is_valid(plr->ai_common.barbarian_type)) {
4294     log_sg("Player%d: Invalid barbarian type \"%s\". "
4295            "Changed to \"None\".", plrno, barb_str);
4296     plr->ai_common.barbarian_type = NOT_A_BARBARIAN;
4297   }
4298 
4299   if (is_barbarian(plr)) {
4300     server.nbarbarians++;
4301   }
4302 
4303   if (plr->ai_controlled) {
4304     set_ai_level_directer(plr, plr->ai_common.skill_level);
4305     CALL_PLR_AI_FUNC(gained_control, plr, plr);
4306   }
4307 
4308   /* Load nation style. */
4309   {
4310     struct nation_style *style;
4311 
4312     string = secfile_lookup_str(loading->file, "player%d.style_by_name", plrno);
4313 
4314     /* Handle pre-2.6 savegames */
4315     if (string == NULL) {
4316       string = secfile_lookup_str(loading->file, "player%d.city_style_by_name",
4317                                   plrno);
4318     }
4319 
4320     sg_failure_ret(string != NULL, "%s", secfile_error());
4321     style = style_by_rule_name(string);
4322     if (style == NULL) {
4323       style = style_by_number(0);
4324       log_sg("Player%d: unsupported city_style_name \"%s\". "
4325              "Changed to \"%s\".", plrno, string, style_rule_name(style));
4326     }
4327     plr->style = style;
4328   }
4329 
4330   sg_failure_ret(secfile_lookup_int(loading->file, &plr->nturns_idle,
4331                                     "player%d.idle_turns", plrno),
4332                  "%s", secfile_error());
4333   plr->is_male = secfile_lookup_bool_default(loading->file, TRUE,
4334                                              "player%d.is_male", plrno);
4335   sg_failure_ret(secfile_lookup_bool(loading->file, &plr->is_alive,
4336                                      "player%d.is_alive", plrno),
4337                  "%s", secfile_error());
4338   sg_failure_ret(secfile_lookup_int(loading->file, &plr->turns_alive,
4339                                     "player%d.turns_alive", plrno),
4340                  "%s", secfile_error());
4341   sg_failure_ret(secfile_lookup_int(loading->file, &plr->last_war_action,
4342                                     "player%d.last_war", plrno),
4343                  "%s", secfile_error());
4344   plr->phase_done = secfile_lookup_bool_default(loading->file, FALSE,
4345                                                 "player%d.phase_done", plrno);
4346   sg_failure_ret(secfile_lookup_int(loading->file, &plr->economic.gold,
4347                                     "player%d.gold", plrno),
4348                  "%s", secfile_error());
4349   sg_failure_ret(secfile_lookup_int(loading->file, &plr->economic.tax,
4350                                     "player%d.rates.tax", plrno),
4351                  "%s", secfile_error());
4352   sg_failure_ret(secfile_lookup_int(loading->file, &plr->economic.science,
4353                                     "player%d.rates.science", plrno),
4354                  "%s", secfile_error());
4355   sg_failure_ret(secfile_lookup_int(loading->file, &plr->economic.luxury,
4356                                     "player%d.rates.luxury", plrno),
4357                  "%s", secfile_error());
4358   plr->server.bulbs_last_turn =
4359     secfile_lookup_int_default(loading->file, 0,
4360                                "player%d.research.bulbs_last_turn", plrno);
4361 
4362   /* Traits */
4363   if (plr->nation) {
4364     for (i = 0; i < loading->trait.size; i++) {
4365       enum trait tr = trait_by_name(loading->trait.order[i], fc_strcasecmp);
4366 
4367       if (trait_is_valid(tr)) {
4368         int val = secfile_lookup_int_default(loading->file, -1, "player%d.trait%d.val",
4369                                              plrno, i);
4370 
4371         if (val != -1) {
4372           plr->ai_common.traits[tr].val = val;
4373         }
4374 
4375         sg_failure_ret(secfile_lookup_int(loading->file, &val,
4376                                           "player%d.trait%d.mod", plrno, i),
4377                        "%s", secfile_error());
4378         plr->ai_common.traits[tr].mod = val;
4379       }
4380     }
4381   }
4382 
4383   /* Achievements */
4384   {
4385     int count;
4386 
4387     count = secfile_lookup_int_default(loading->file, -1,
4388                                        "player%d.achievement_count", plrno);
4389 
4390     if (count > 0) {
4391       for (i = 0; i < count; i++) {
4392         const char *name;
4393         struct achievement *pach;
4394         bool first;
4395 
4396         name = secfile_lookup_str(loading->file,
4397                                   "player%d.achievement%d.name", plrno, i);
4398         pach = achievement_by_rule_name(name);
4399 
4400         sg_failure_ret(pach != NULL,
4401                        "Unknown achievement \"%s\".", name);
4402 
4403         sg_failure_ret(secfile_lookup_bool(loading->file, &first,
4404                                            "player%d.achievement%d.first",
4405                                            plrno, i),
4406                        "achievement error: %s", secfile_error());
4407 
4408         sg_failure_ret(pach->first == NULL || !first,
4409                        "Multiple players listed as first to get achievement \"%s\".",
4410                        name);
4411 
4412         BV_SET(pach->achievers, player_index(plr));
4413 
4414         if (first) {
4415           pach->first = plr;
4416         }
4417       }
4418     }
4419   }
4420 
4421   /* Player score. */
4422   plr->score.happy =
4423     secfile_lookup_int_default(loading->file, 0,
4424                                "score%d.happy", plrno);
4425   plr->score.content =
4426     secfile_lookup_int_default(loading->file, 0,
4427                                "score%d.content", plrno);
4428   plr->score.unhappy =
4429     secfile_lookup_int_default(loading->file, 0,
4430                                "score%d.unhappy", plrno);
4431   plr->score.angry =
4432     secfile_lookup_int_default(loading->file, 0,
4433                                "score%d.angry", plrno);
4434 
4435   /* Make sure that the score about specialists in current ruleset that
4436    * were not present at saving time are set to zero. */
4437   specialist_type_iterate(sp) {
4438     plr->score.specialists[sp] = 0;
4439   } specialist_type_iterate_end;
4440 
4441   for (i = 0; i < loading->specialist.size; i++) {
4442     plr->score.specialists[specialist_index(loading->specialist.order[i])]
4443       = secfile_lookup_int_default(loading->file, 0,
4444                                    "score%d.specialists%d", plrno, i);
4445   }
4446 
4447   plr->score.wonders =
4448     secfile_lookup_int_default(loading->file, 0,
4449                                "score%d.wonders", plrno);
4450   plr->score.techs =
4451     secfile_lookup_int_default(loading->file, 0,
4452                                "score%d.techs", plrno);
4453   plr->score.techout =
4454     secfile_lookup_int_default(loading->file, 0,
4455                                "score%d.techout", plrno);
4456   plr->score.landarea =
4457     secfile_lookup_int_default(loading->file, 0,
4458                                "score%d.landarea", plrno);
4459   plr->score.settledarea =
4460     secfile_lookup_int_default(loading->file, 0,
4461                                "score%d.settledarea", plrno);
4462   plr->score.population =
4463     secfile_lookup_int_default(loading->file, 0,
4464                                "score%d.population", plrno);
4465   plr->score.cities =
4466     secfile_lookup_int_default(loading->file, 0,
4467                                "score%d.cities", plrno);
4468   plr->score.units =
4469     secfile_lookup_int_default(loading->file, 0,
4470                                "score%d.units", plrno);
4471   plr->score.pollution =
4472     secfile_lookup_int_default(loading->file, 0,
4473                                "score%d.pollution", plrno);
4474   plr->score.literacy =
4475     secfile_lookup_int_default(loading->file, 0,
4476                                "score%d.literacy", plrno);
4477   plr->score.bnp =
4478     secfile_lookup_int_default(loading->file, 0,
4479                                "score%d.bnp", plrno);
4480   plr->score.mfg =
4481     secfile_lookup_int_default(loading->file, 0,
4482                                "score%d.mfg", plrno);
4483   plr->score.spaceship =
4484     secfile_lookup_int_default(loading->file, 0,
4485                                "score%d.spaceship", plrno);
4486   plr->score.units_built =
4487       secfile_lookup_int_default(loading->file, 0,
4488                                  "score%d.units_built", plrno);
4489   plr->score.units_killed =
4490       secfile_lookup_int_default(loading->file, 0,
4491                                  "score%d.units_killed", plrno);
4492   plr->score.units_lost =
4493       secfile_lookup_int_default(loading->file, 0,
4494                                  "score%d.units_lost", plrno);
4495   plr->score.culture =
4496     secfile_lookup_int_default(loading->file, 0,
4497                                "score%d.culture", plrno);
4498   plr->score.game =
4499     secfile_lookup_int_default(loading->file, 0,
4500                                "score%d.total", plrno);
4501 
4502   /* Load space ship data. */
4503   {
4504     struct player_spaceship *ship = &plr->spaceship;
4505     char prefix[32];
4506     const char *st;
4507     int ei;
4508 
4509     fc_snprintf(prefix, sizeof(prefix), "player%d.spaceship", plrno);
4510     spaceship_init(ship);
4511     sg_failure_ret(secfile_lookup_int(loading->file,
4512                                       &ei,
4513                                       "%s.state", prefix),
4514                    "%s", secfile_error());
4515     ship->state = ei;
4516 
4517     if (ship->state != SSHIP_NONE) {
4518       sg_failure_ret(secfile_lookup_int(loading->file, &ship->structurals,
4519                                         "%s.structurals", prefix),
4520                      "%s", secfile_error());
4521       sg_failure_ret(secfile_lookup_int(loading->file, &ship->components,
4522                                  "%s.components", prefix),
4523                      "%s", secfile_error());
4524       sg_failure_ret(secfile_lookup_int(loading->file, &ship->modules,
4525                                  "%s.modules", prefix),
4526                      "%s", secfile_error());
4527       sg_failure_ret(secfile_lookup_int(loading->file, &ship->fuel,
4528                                  "%s.fuel", prefix),
4529                      "%s", secfile_error());
4530       sg_failure_ret(secfile_lookup_int(loading->file, &ship->propulsion,
4531                                  "%s.propulsion", prefix),
4532                      "%s", secfile_error());
4533       sg_failure_ret(secfile_lookup_int(loading->file, &ship->habitation,
4534                                  "%s.habitation", prefix),
4535                      "%s", secfile_error());
4536       sg_failure_ret(secfile_lookup_int(loading->file, &ship->life_support,
4537                                  "%s.life_support", prefix),
4538                      "%s", secfile_error());
4539       sg_failure_ret(secfile_lookup_int(loading->file, &ship->solar_panels,
4540                                  "%s.solar_panels", prefix),
4541                      "%s", secfile_error());
4542 
4543       st = secfile_lookup_str(loading->file, "%s.structure", prefix);
4544       sg_failure_ret(st != NULL, "%s", secfile_error())
4545       for (i = 0; i < NUM_SS_STRUCTURALS && st[i]; i++) {
4546         sg_failure_ret(st[i] == '1' || st[i] == '0',
4547                        "Undefined value '%c' within '%s.structure'.", st[i],
4548                        prefix)
4549 
4550         if (!(st[i] == '0')) {
4551           BV_SET(ship->structure, i);
4552         }
4553       }
4554       if (ship->state >= SSHIP_LAUNCHED) {
4555         sg_failure_ret(secfile_lookup_int(loading->file, &ship->launch_year,
4556                                           "%s.launch_year", prefix),
4557                        "%s", secfile_error());
4558       }
4559       spaceship_calc_derived(ship);
4560     }
4561   }
4562 
4563   /* Load lost wonder data. */
4564   string = secfile_lookup_str(loading->file, "player%d.lost_wonders", plrno);
4565   /* If not present, probably an old savegame; nothing to be done */
4566   if (string) {
4567     int k;
4568     sg_failure_ret(strlen(string) == loading->improvement.size,
4569                    "Invalid length for 'player%d.lost_wonders' "
4570                    "(%lu ~= %lu)", plrno, (unsigned long) strlen(string),
4571                    (unsigned long) loading->improvement.size);
4572     for (k = 0; k < loading->improvement.size; k++) {
4573       sg_failure_ret(string[k] == '1' || string[k] == '0',
4574                      "Undefined value '%c' within "
4575                      "'player%d.lost_wonders'.", plrno, string[k]);
4576 
4577       if (string[k] == '1') {
4578         struct impr_type *pimprove =
4579             improvement_by_rule_name(loading->improvement.order[k]);
4580         if (pimprove) {
4581           plr->wonders[improvement_index(pimprove)] = WONDER_LOST;
4582         }
4583       }
4584     }
4585   }
4586 
4587   plr->history =
4588     secfile_lookup_int_default(loading->file, 0, "player%d.culture", plrno);
4589   plr->server.huts =
4590     secfile_lookup_int_default(loading->file, 0, "player%d.hut_count", plrno);
4591 }
4592 
4593 /****************************************************************************
4594   Main player data saving function.
4595 ****************************************************************************/
sg_save_player_main(struct savedata * saving,struct player * plr)4596 static void sg_save_player_main(struct savedata *saving,
4597                                 struct player *plr)
4598 {
4599   int i, k, plrno = player_number(plr);
4600   struct player_spaceship *ship = &plr->spaceship;
4601 
4602   /* Check status and return if not OK (sg_success != TRUE). */
4603   sg_check_ret();
4604 
4605   secfile_insert_str(saving->file, ai_name(plr->ai),
4606                      "player%d.ai_type", plrno);
4607   secfile_insert_str(saving->file, player_name(plr),
4608                      "player%d.name", plrno);
4609   secfile_insert_str(saving->file, plr->username,
4610                      "player%d.username", plrno);
4611   secfile_insert_bool(saving->file, plr->unassigned_user,
4612                       "player%d.unassigned_user", plrno);
4613   if (plr->rgb != NULL) {
4614     rgbcolor_save(saving->file, plr->rgb, "player%d.color", plrno);
4615   } else {
4616     /* Colorless players are ok in pregame */
4617     if (game_was_started()) {
4618       log_sg("Game has started, yet player %d has no color defined.", plrno);
4619     }
4620   }
4621   secfile_insert_str(saving->file, plr->server.orig_username,
4622                      "player%d.orig_username", plrno);
4623   secfile_insert_str(saving->file, plr->ranked_username,
4624                      "player%d.ranked_username", plrno);
4625   secfile_insert_bool(saving->file, plr->unassigned_ranked,
4626                       "player%d.unassigned_ranked", plrno);
4627   secfile_insert_str(saving->file,
4628                      player_delegation_get(plr) ? player_delegation_get(plr)
4629                                                 : "",
4630                      "player%d.delegation_username", plrno);
4631   secfile_insert_str(saving->file, nation_rule_name(nation_of_player(plr)),
4632                      "player%d.nation", plrno);
4633   secfile_insert_int(saving->file, plr->team ? team_index(plr->team) : -1,
4634                      "player%d.team_no", plrno);
4635 
4636   secfile_insert_str(saving->file,
4637                      government_rule_name(government_of_player(plr)),
4638                      "player%d.government_name", plrno);
4639 
4640   if (plr->target_government) {
4641     secfile_insert_str(saving->file,
4642                        government_rule_name(plr->target_government),
4643                        "player%d.target_government_name", plrno);
4644   }
4645 
4646   secfile_insert_str(saving->file, style_rule_name(plr->style),
4647                       "player%d.style_by_name", plrno);
4648 
4649   secfile_insert_int(saving->file, plr->nturns_idle,
4650                      "player%d.idle_turns", plrno);
4651   secfile_insert_bool(saving->file, plr->is_male,
4652                       "player%d.is_male", plrno);
4653   secfile_insert_bool(saving->file, plr->is_alive,
4654                       "player%d.is_alive", plrno);
4655   secfile_insert_int(saving->file, plr->turns_alive,
4656                      "player%d.turns_alive", plrno);
4657   secfile_insert_int(saving->file, plr->last_war_action,
4658                      "player%d.last_war", plrno);
4659   secfile_insert_bool(saving->file, plr->ai_controlled,
4660                       "player%d.ai.control", plrno);
4661   secfile_insert_bool(saving->file, plr->phase_done,
4662                       "player%d.phase_done", plrno);
4663 
4664   players_iterate(pplayer) {
4665     char buf[32];
4666     struct player_diplstate *ds = player_diplstate_get(plr, pplayer);
4667 
4668     i = player_index(pplayer);
4669 
4670     /* save diplomatic state */
4671     fc_snprintf(buf, sizeof(buf), "player%d.diplstate%d", plrno, i);
4672 
4673     secfile_insert_int(saving->file, ds->type,
4674                        "%s.type", buf);
4675     secfile_insert_int(saving->file, ds->max_state,
4676                        "%s.max_state", buf);
4677     secfile_insert_int(saving->file, ds->first_contact_turn,
4678                        "%s.first_contact_turn", buf);
4679     secfile_insert_int(saving->file, ds->turns_left,
4680                        "%s.turns_left", buf);
4681     secfile_insert_int(saving->file, ds->has_reason_to_cancel,
4682                        "%s.has_reason_to_cancel", buf);
4683     secfile_insert_int(saving->file, ds->contact_turns_left,
4684                        "%s.contact_turns_left", buf);
4685     secfile_insert_bool(saving->file, player_has_real_embassy(plr, pplayer),
4686                         "%s.embassy", buf);
4687     secfile_insert_bool(saving->file, gives_shared_vision(plr, pplayer),
4688                         "%s.gives_shared_vision", buf);
4689   } players_iterate_end;
4690 
4691   players_iterate(aplayer) {
4692     i = player_index(aplayer);
4693     /* save ai data */
4694     secfile_insert_int(saving->file, plr->ai_common.love[i],
4695                        "player%d.ai%d.love", plrno, i);
4696     CALL_FUNC_EACH_AI(player_save_relations, plr, aplayer, saving->file, plrno);
4697   } players_iterate_end;
4698 
4699   CALL_FUNC_EACH_AI(player_save, plr, saving->file, plrno);
4700 
4701   /* Multipliers (policies) */
4702   i = multiplier_count();
4703 
4704   for (k = 0; k < i; k++) {
4705     secfile_insert_int(saving->file, plr->multipliers[k],
4706                        "player%d.multiplier%d.val", plrno, k);
4707     secfile_insert_int(saving->file, plr->multipliers_target[k],
4708                        "player%d.multiplier%d.target", plrno, k);
4709   }
4710 
4711   secfile_insert_str(saving->file, ai_level_name(plr->ai_common.skill_level),
4712                      "player%d.ai.level", plrno);
4713   secfile_insert_str(saving->file, barbarian_type_name(plr->ai_common.barbarian_type),
4714                      "player%d.ai.barb_type", plrno);
4715   secfile_insert_int(saving->file, plr->economic.gold,
4716                      "player%d.gold", plrno);
4717   secfile_insert_int(saving->file, plr->economic.tax,
4718                      "player%d.rates.tax", plrno);
4719   secfile_insert_int(saving->file, plr->economic.science,
4720                      "player%d.rates.science", plrno);
4721   secfile_insert_int(saving->file, plr->economic.luxury,
4722                      "player%d.rates.luxury", plrno);
4723   secfile_insert_int(saving->file, plr->server.bulbs_last_turn,
4724                      "player%d.research.bulbs_last_turn", plrno);
4725 
4726   /* Save traits */
4727   {
4728     enum trait tr;
4729     int j;
4730 
4731     for (tr = trait_begin(), j = 0; tr != trait_end(); tr = trait_next(tr), j++) {
4732       secfile_insert_int(saving->file, plr->ai_common.traits[tr].val,
4733                          "player%d.trait%d.val", plrno, j);
4734       secfile_insert_int(saving->file, plr->ai_common.traits[tr].mod,
4735                          "player%d.trait%d.mod", plrno, j);
4736     }
4737   }
4738 
4739   /* Save achievements */
4740   {
4741     int j = 0;
4742 
4743     achievements_iterate(pach) {
4744       if (achievement_player_has(pach, plr)) {
4745         secfile_insert_str(saving->file, achievement_rule_name(pach),
4746                            "player%d.achievement%d.name", plrno, j);
4747         if (pach->first == plr) {
4748           secfile_insert_bool(saving->file, TRUE,
4749                               "player%d.achievement%d.first", plrno, j);
4750         } else {
4751           secfile_insert_bool(saving->file, FALSE,
4752                               "player%d.achievement%d.first", plrno, j);
4753         }
4754 
4755         j++;
4756       }
4757     } achievements_iterate_end;
4758 
4759     secfile_insert_int(saving->file, j,
4760                        "player%d.achievement_count", plrno);
4761   }
4762 
4763   secfile_insert_bool(saving->file, plr->server.got_first_city,
4764                       "player%d.got_first_city", plrno);
4765   secfile_insert_int(saving->file, plr->revolution_finishes,
4766                      "player%d.revolution_finishes", plrno);
4767 
4768   /* Player score */
4769   secfile_insert_int(saving->file, plr->score.happy,
4770                      "score%d.happy", plrno);
4771   secfile_insert_int(saving->file, plr->score.content,
4772                      "score%d.content", plrno);
4773   secfile_insert_int(saving->file, plr->score.unhappy,
4774                      "score%d.unhappy", plrno);
4775   secfile_insert_int(saving->file, plr->score.angry,
4776                      "score%d.angry", plrno);
4777   specialist_type_iterate(sp) {
4778     secfile_insert_int(saving->file, plr->score.specialists[sp],
4779                        "score%d.specialists%d", plrno, sp);
4780   } specialist_type_iterate_end;
4781   secfile_insert_int(saving->file, plr->score.wonders,
4782                      "score%d.wonders", plrno);
4783   secfile_insert_int(saving->file, plr->score.techs,
4784                      "score%d.techs", plrno);
4785   secfile_insert_int(saving->file, plr->score.techout,
4786                      "score%d.techout", plrno);
4787   secfile_insert_int(saving->file, plr->score.landarea,
4788                      "score%d.landarea", plrno);
4789   secfile_insert_int(saving->file, plr->score.settledarea,
4790                      "score%d.settledarea", plrno);
4791   secfile_insert_int(saving->file, plr->score.population,
4792                      "score%d.population", plrno);
4793   secfile_insert_int(saving->file, plr->score.cities,
4794                      "score%d.cities", plrno);
4795   secfile_insert_int(saving->file, plr->score.units,
4796                      "score%d.units", plrno);
4797   secfile_insert_int(saving->file, plr->score.pollution,
4798                      "score%d.pollution", plrno);
4799   secfile_insert_int(saving->file, plr->score.literacy,
4800                      "score%d.literacy", plrno);
4801   secfile_insert_int(saving->file, plr->score.bnp,
4802                      "score%d.bnp", plrno);
4803   secfile_insert_int(saving->file, plr->score.mfg,
4804                      "score%d.mfg", plrno);
4805   secfile_insert_int(saving->file, plr->score.spaceship,
4806                      "score%d.spaceship", plrno);
4807   secfile_insert_int(saving->file, plr->score.units_built,
4808                      "score%d.units_built", plrno);
4809   secfile_insert_int(saving->file, plr->score.units_killed,
4810                      "score%d.units_killed", plrno);
4811   secfile_insert_int(saving->file, plr->score.units_lost,
4812                      "score%d.units_lost", plrno);
4813   secfile_insert_int(saving->file, plr->score.culture,
4814                      "score%d.culture", plrno);
4815   secfile_insert_int(saving->file, plr->score.game,
4816                      "score%d.total", plrno);
4817 
4818   /* Save space ship status. */
4819   secfile_insert_int(saving->file, ship->state, "player%d.spaceship.state",
4820                      plrno);
4821   if (ship->state != SSHIP_NONE) {
4822     char buf[32];
4823     char st[NUM_SS_STRUCTURALS+1];
4824     int ssi;
4825 
4826     fc_snprintf(buf, sizeof(buf), "player%d.spaceship", plrno);
4827 
4828     secfile_insert_int(saving->file, ship->structurals,
4829                        "%s.structurals", buf);
4830     secfile_insert_int(saving->file, ship->components,
4831                        "%s.components", buf);
4832     secfile_insert_int(saving->file, ship->modules,
4833                        "%s.modules", buf);
4834     secfile_insert_int(saving->file, ship->fuel, "%s.fuel", buf);
4835     secfile_insert_int(saving->file, ship->propulsion, "%s.propulsion", buf);
4836     secfile_insert_int(saving->file, ship->habitation, "%s.habitation", buf);
4837     secfile_insert_int(saving->file, ship->life_support,
4838                        "%s.life_support", buf);
4839     secfile_insert_int(saving->file, ship->solar_panels,
4840                        "%s.solar_panels", buf);
4841 
4842     for(ssi = 0; ssi < NUM_SS_STRUCTURALS; ssi++) {
4843       st[ssi] = BV_ISSET(ship->structure, ssi) ? '1' : '0';
4844     }
4845     st[ssi] = '\0';
4846     secfile_insert_str(saving->file, st, "%s.structure", buf);
4847     if (ship->state >= SSHIP_LAUNCHED) {
4848       secfile_insert_int(saving->file, ship->launch_year,
4849                          "%s.launch_year", buf);
4850     }
4851   }
4852 
4853   /* Save lost wonders info. */
4854   {
4855     char lost[B_LAST+1];
4856 
4857     improvement_iterate(pimprove) {
4858       if (is_wonder(pimprove) && wonder_is_lost(plr, pimprove)) {
4859         lost[improvement_index(pimprove)] = '1';
4860       } else {
4861         lost[improvement_index(pimprove)] = '0';
4862       }
4863     } improvement_iterate_end;
4864     lost[improvement_count()] = '\0';
4865     secfile_insert_str(saving->file, lost,
4866                        "player%d.lost_wonders", plrno);
4867   }
4868 
4869   secfile_insert_int(saving->file, plr->history,
4870                      "player%d.culture", plrno);
4871   secfile_insert_int(saving->file, plr->server.huts,
4872                      "player%d.hut_count", plrno);
4873 }
4874 
4875 /****************************************************************************
4876   Load city data
4877 ****************************************************************************/
sg_load_player_cities(struct loaddata * loading,struct player * plr)4878 static void sg_load_player_cities(struct loaddata *loading,
4879                                   struct player *plr)
4880 {
4881   int ncities, i, plrno = player_number(plr);
4882   bool tasks_handled;
4883 
4884   /* Check status and return if not OK (sg_success != TRUE). */
4885   sg_check_ret();
4886 
4887   sg_failure_ret(secfile_lookup_int(loading->file, &ncities,
4888                                     "player%d.ncities", plrno),
4889                  "%s", secfile_error());
4890 
4891   if (!plr->is_alive && ncities > 0) {
4892     log_sg("'player%d.ncities' = %d for dead player!", plrno, ncities);
4893     ncities = 0;
4894   }
4895 
4896   if (!plr->server.got_first_city && ncities > 0) {
4897     /* Probably barbarians in an old savegame; fix up */
4898     plr->server.got_first_city = TRUE;
4899   }
4900 
4901   /* Load all cities of the player. */
4902   for (i = 0; i < ncities; i++) {
4903     char buf[32];
4904     struct city *pcity;
4905 
4906     fc_snprintf(buf, sizeof(buf), "player%d.c%d", plrno, i);
4907 
4908     /* Create a dummy city. */
4909     pcity = create_city_virtual(plr, NULL, buf);
4910     adv_city_alloc(pcity);
4911     if (!sg_load_player_city(loading, plr, pcity, buf)) {
4912       adv_city_free(pcity);
4913       destroy_city_virtual(pcity);
4914       sg_failure_ret(FALSE, "Error loading city %d of player %d.", i, plrno);
4915     }
4916 
4917     identity_number_reserve(pcity->id);
4918     idex_register_city(pcity);
4919 
4920     /* Load the information about the nationality of citizens. This is done
4921      * here because the city sanity check called by citizens_update() requires
4922      * that the city is registered. */
4923     sg_load_player_city_citizens(loading, plr, pcity, buf);
4924 
4925     /* After everything is loaded, but before vision. */
4926     map_claim_ownership(city_tile(pcity), plr, city_tile(pcity), TRUE);
4927 
4928     /* adding the city contribution to fog-of-war */
4929     pcity->server.vision = vision_new(plr, city_tile(pcity));
4930     vision_reveal_tiles(pcity->server.vision, game.server.vision_reveal_tiles);
4931     city_refresh_vision(pcity);
4932 
4933     city_list_append(plr->cities, pcity);
4934   }
4935 
4936   tasks_handled = FALSE;
4937   for (i = 0; !tasks_handled; i++) {
4938     int city_id;
4939     struct city *pcity = NULL;
4940 
4941     city_id = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.city",
4942                                          plrno, i);
4943 
4944     if (city_id != -1) {
4945       pcity = player_city_by_number(plr, city_id);
4946     }
4947 
4948     if (pcity != NULL) {
4949       const char *str;
4950       int nat_x, nat_y;
4951       struct worker_task *ptask = fc_malloc(sizeof(struct worker_task));
4952 
4953       nat_x = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.x", plrno, i);
4954       nat_y = secfile_lookup_int_default(loading->file, -1, "player%d.task%d.y", plrno, i);
4955 
4956       ptask->ptile = native_pos_to_tile(nat_x, nat_y);
4957 
4958       str = secfile_lookup_str(loading->file, "player%d.task%d.activity", plrno, i);
4959       ptask->act = unit_activity_by_name(str, fc_strcasecmp);
4960 
4961       sg_failure_ret(unit_activity_is_valid(ptask->act),
4962                      "Unknown workertask activity %s", str);
4963 
4964       str = secfile_lookup_str(loading->file, "player%d.task%d.target", plrno, i);
4965 
4966       if (strcmp("-", str)) {
4967         ptask->tgt = extra_type_by_rule_name(str);
4968 
4969         sg_failure_ret(ptask->tgt != NULL,
4970                        "Unknown workertask target %s", str);
4971       } else {
4972         ptask->tgt = NULL;
4973       }
4974 
4975       ptask->want = secfile_lookup_int_default(loading->file, 1,
4976                                                "player%d.task%d.want", plrno, i);
4977 
4978       worker_task_list_append(pcity->task_reqs, ptask);
4979     } else {
4980       tasks_handled = TRUE;
4981     }
4982   }
4983 }
4984 
4985 /****************************************************************************
4986   Load data for one city. sg_save_player_city() is not defined.
4987 ****************************************************************************/
sg_load_player_city(struct loaddata * loading,struct player * plr,struct city * pcity,const char * citystr)4988 static bool sg_load_player_city(struct loaddata *loading, struct player *plr,
4989                                 struct city *pcity, const char *citystr)
4990 {
4991   struct player *past;
4992   const char *kind, *name, *string;
4993   int id, i, repair, sp_count = 0, workers = 0, value;
4994   int nat_x, nat_y;
4995   citizens size;
4996   const char *stylename;
4997 
4998   sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x", citystr),
4999                   FALSE, "%s", secfile_error());
5000   sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y", citystr),
5001                   FALSE, "%s", secfile_error());
5002   pcity->tile = native_pos_to_tile(nat_x, nat_y);
5003   sg_warn_ret_val(NULL != pcity->tile, FALSE,
5004                   "%s has invalid center tile (%d, %d)",
5005                   citystr, nat_x, nat_y);
5006   sg_warn_ret_val(NULL == tile_city(pcity->tile), FALSE,
5007                   "%s duplicates city (%d, %d)", citystr, nat_x, nat_y);
5008 
5009   /* Instead of dying, use 'citystr' string for damaged name. */
5010   sz_strlcpy(pcity->name, secfile_lookup_str_default(loading->file, citystr,
5011                                                      "%s.name", citystr));
5012 
5013   sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->id, "%s.id",
5014                                      citystr), FALSE, "%s", secfile_error());
5015 
5016   id = secfile_lookup_int_default(loading->file, player_number(plr),
5017                                   "%s.original", citystr);
5018   past = player_by_number(id);
5019   if (NULL != past) {
5020     pcity->original = past;
5021   }
5022 
5023   sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.size",
5024                                      citystr), FALSE, "%s", secfile_error());
5025   size = (citizens)value; /* set the correct type */
5026   sg_warn_ret_val(value == (int)size, FALSE,
5027                   "Invalid city size: %d, set to %d", value, size);
5028   city_size_set(pcity, size);
5029 
5030   for (i = 0; i < loading->specialist.size; i++) {
5031     sg_warn_ret_val(secfile_lookup_int(loading->file, &value, "%s.nspe%d",
5032                                        citystr, i),
5033                     FALSE, "%s", secfile_error());
5034     pcity->specialists[specialist_index(loading->specialist.order[i])]
5035       = (citizens)value;
5036     sp_count += value;
5037   }
5038 
5039   for (i = 0; i < MAX_TRADE_ROUTES; i++) {
5040     pcity->trade[i] = secfile_lookup_int_default(loading->file, 0,
5041                                                  "%s.traderoute%d", citystr, i);
5042   }
5043 
5044   sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->food_stock,
5045                                     "%s.food_stock", citystr),
5046                   FALSE, "%s", secfile_error());
5047   sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->shield_stock,
5048                                     "%s.shield_stock", citystr),
5049                   FALSE, "%s", secfile_error());
5050   pcity->history =
5051     secfile_lookup_int_default(loading->file, 0, "%s.history", citystr);
5052 
5053   pcity->airlift =
5054     secfile_lookup_int_default(loading->file, 0, "%s.airlift", citystr);
5055   pcity->was_happy =
5056     secfile_lookup_bool_default(loading->file, FALSE, "%s.was_happy",
5057                                 citystr);
5058 
5059   pcity->turn_plague =
5060     secfile_lookup_int_default(loading->file, 0, "%s.turn_plague", citystr);
5061 
5062   sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->anarchy,
5063                                     "%s.anarchy", citystr),
5064                   FALSE, "%s", secfile_error());
5065   pcity->rapture =
5066     secfile_lookup_int_default(loading->file, 0, "%s.rapture", citystr);
5067   pcity->server.steal =
5068     secfile_lookup_int_default(loading->file, 0, "%s.steal", citystr);
5069 
5070   /* before did_buy for undocumented hack */
5071   pcity->turn_founded =
5072     secfile_lookup_int_default(loading->file, -2, "%s.turn_founded",
5073                                citystr);
5074   sg_warn_ret_val(secfile_lookup_int(loading->file, &i, "%s.did_buy",
5075                                      citystr), FALSE, "%s", secfile_error());
5076   pcity->did_buy = (i != 0);
5077   if (i == -1 && pcity->turn_founded == -2) {
5078     /* undocumented hack */
5079     pcity->turn_founded = game.info.turn;
5080   }
5081 
5082   pcity->did_sell =
5083     secfile_lookup_bool_default(loading->file, FALSE, "%s.did_sell", citystr);
5084 
5085   sg_warn_ret_val(secfile_lookup_int(loading->file, &pcity->turn_last_built,
5086                                     "%s.turn_last_built", citystr),
5087                   FALSE, "%s", secfile_error());
5088 
5089   kind = secfile_lookup_str(loading->file, "%s.currently_building_kind",
5090                             citystr);
5091   name = secfile_lookup_str(loading->file, "%s.currently_building_name",
5092                             citystr);
5093   pcity->production = universal_by_rule_name(kind, name);
5094   sg_warn_ret_val(pcity->production.kind != universals_n_invalid(), FALSE,
5095                   "%s.currently_building: unknown \"%s\" \"%s\".",
5096                   citystr, kind, name);
5097 
5098   kind = secfile_lookup_str(loading->file, "%s.changed_from_kind",
5099                             citystr);
5100   name = secfile_lookup_str(loading->file, "%s.changed_from_name",
5101                             citystr);
5102   pcity->changed_from = universal_by_rule_name(kind, name);
5103   sg_warn_ret_val(pcity->changed_from.kind != universals_n_invalid(), FALSE,
5104                  "%s.changed_from: unknown \"%s\" \"%s\".",
5105                  citystr, kind, name);
5106 
5107   pcity->before_change_shields =
5108     secfile_lookup_int_default(loading->file, pcity->shield_stock,
5109                                "%s.before_change_shields", citystr);
5110   pcity->caravan_shields =
5111     secfile_lookup_int_default(loading->file, 0,
5112                                "%s.caravan_shields", citystr);
5113   pcity->disbanded_shields =
5114     secfile_lookup_int_default(loading->file, 0,
5115                                "%s.disbanded_shields", citystr);
5116   pcity->last_turns_shield_surplus =
5117     secfile_lookup_int_default(loading->file, 0,
5118                                "%s.last_turns_shield_surplus",
5119                                citystr);
5120 
5121   stylename = secfile_lookup_str_default(loading->file, NULL,
5122                                          "%s.style", citystr);
5123   if (stylename != NULL) {
5124     pcity->style = city_style_by_rule_name(stylename);
5125   } else {
5126     pcity->style = 0;
5127   }
5128   if (pcity->style < 0) {
5129     pcity->style = city_style(pcity);
5130   }
5131 
5132   pcity->server.synced = FALSE; /* must re-sync with clients */
5133 
5134   /* Initialise list of city improvements. */
5135   for (i = 0; i < ARRAY_SIZE(pcity->built); i++) {
5136     pcity->built[i].turn = I_NEVER;
5137   }
5138 
5139   /* Load city improvements. */
5140   string = secfile_lookup_str(loading->file, "%s.improvements", citystr);
5141   sg_warn_ret_val(string != NULL, FALSE, "%s", secfile_error());
5142   sg_warn_ret_val(strlen(string) == loading->improvement.size, FALSE,
5143                   "Invalid length of '%s.improvements' (%lu ~= %lu).",
5144                   citystr, (unsigned long) strlen(string),
5145                   (unsigned long) loading->improvement.size);
5146   for (i = 0; i < loading->improvement.size; i++) {
5147     sg_warn_ret_val(string[i] == '1' || string[i] == '0', FALSE,
5148                    "Undefined value '%c' within '%s.improvements'.",
5149                    string[i], citystr)
5150 
5151     if (string[i] == '1') {
5152       struct impr_type *pimprove =
5153           improvement_by_rule_name(loading->improvement.order[i]);
5154       if (pimprove) {
5155         city_add_improvement(pcity, pimprove);
5156       }
5157     }
5158   }
5159 
5160   sg_failure_ret_val(loading->worked_tiles != NULL, FALSE,
5161                      "No worked tiles map defined.");
5162 
5163   city_freeze_workers(pcity);
5164 
5165   /* load new savegame with variable (squared) city radius and worked
5166    * tiles map */
5167 
5168   int radius_sq
5169     = secfile_lookup_int_default(loading->file, -1, "%s.city_radius_sq",
5170                                  citystr);
5171   city_map_radius_sq_set(pcity, radius_sq);
5172 
5173   city_tile_iterate(radius_sq, city_tile(pcity), ptile) {
5174     if (loading->worked_tiles[ptile->index] == pcity->id) {
5175       tile_set_worked(ptile, pcity);
5176       workers++;
5177 
5178 #ifdef FREECIV_DEBUG
5179       /* set this tile to unused; a check for not resetted tiles is
5180        * included in game_load_internal() */
5181       loading->worked_tiles[ptile->index] = -1;
5182 #endif /* FREECIV_DEBUG */
5183     }
5184   } city_tile_iterate_end;
5185 
5186   if (tile_worked(city_tile(pcity)) != pcity) {
5187     struct city *pwork = tile_worked(city_tile(pcity));
5188 
5189     if (NULL != pwork) {
5190       log_sg("[%s] city center of '%s' (%d,%d) [%d] is worked by '%s' "
5191              "(%d,%d) [%d]; repairing ", citystr, city_name_get(pcity),
5192              TILE_XY(city_tile(pcity)), city_size_get(pcity), city_name_get(pwork),
5193              TILE_XY(city_tile(pwork)), city_size_get(pwork));
5194 
5195       tile_set_worked(city_tile(pcity), NULL); /* remove tile from pwork */
5196       pwork->specialists[DEFAULT_SPECIALIST]++;
5197       auto_arrange_workers(pwork);
5198     } else {
5199       log_sg("[%s] city center of '%s' (%d,%d) [%d] is empty; repairing ",
5200              citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)),
5201              city_size_get(pcity));
5202     }
5203 
5204     /* repair pcity */
5205     tile_set_worked(city_tile(pcity), pcity);
5206     city_repair_size(pcity, -1);
5207   }
5208 
5209   repair = city_size_get(pcity) - sp_count - (workers - FREE_WORKED_TILES);
5210   if (0 != repair) {
5211     log_sg("[%s] size mismatch for '%s' (%d,%d): size [%d] != "
5212            "(workers [%d] - free worked tiles [%d]) + specialists [%d]",
5213            citystr, city_name_get(pcity), TILE_XY(city_tile(pcity)), city_size_get(pcity),
5214            workers, FREE_WORKED_TILES, sp_count);
5215 
5216     /* repair pcity */
5217     city_repair_size(pcity, repair);
5218   }
5219 
5220   /* worklist_init() done in create_city_virtual() */
5221   worklist_load(loading->file, &pcity->worklist, "%s", citystr);
5222 
5223   /* Load city options. */
5224   BV_CLR_ALL(pcity->city_options);
5225   for (i = 0; i < CITYO_LAST; i++) {
5226     if (secfile_lookup_bool_default(loading->file, FALSE, "%s.option%d",
5227                                     citystr, i)) {
5228       BV_SET(pcity->city_options, i);
5229     }
5230   }
5231 
5232   CALL_FUNC_EACH_AI(city_load, loading->file, pcity, citystr);
5233 
5234   return TRUE;
5235 }
5236 
5237 /****************************************************************************
5238   Load nationality data for one city.
5239 ****************************************************************************/
sg_load_player_city_citizens(struct loaddata * loading,struct player * plr,struct city * pcity,const char * citystr)5240 static void sg_load_player_city_citizens(struct loaddata *loading,
5241                                          struct player *plr,
5242                                          struct city *pcity,
5243                                          const char *citystr)
5244 {
5245   if (game.info.citizen_nationality) {
5246     citizens size;
5247 
5248     citizens_init(pcity);
5249     player_slots_iterate(pslot) {
5250       int nationality;
5251 
5252       nationality = secfile_lookup_int_default(loading->file, -1,
5253                                                "%s.citizen%d", citystr,
5254                                                player_slot_index(pslot));
5255       if (nationality > 0 && !player_slot_is_used(pslot)) {
5256         log_sg("Citizens of an invalid nation for %s (player slot %d)!",
5257                city_name_get(pcity), player_slot_index(pslot));
5258         continue;
5259       }
5260 
5261       if (nationality != -1 && player_slot_is_used(pslot)) {
5262         sg_warn(nationality >= 0 && nationality <= MAX_CITY_SIZE,
5263                 "Invalid value for citizens of player %d in %s: %d.",
5264                 player_slot_index(pslot), city_name_get(pcity), nationality);
5265         citizens_nation_set(pcity, pslot, nationality);
5266       }
5267     } player_slots_iterate_end;
5268     /* Sanity check. */
5269     size = citizens_count(pcity);
5270     if (size != city_size_get(pcity)) {
5271       if (size != 0) {
5272         /* size == 0 can be result from the fact that ruleset had no
5273          * nationality enabled at saving time, so no citizens at all
5274          * were saved. But something more serious must be going on if
5275          * citizens have been saved partially - if some of them are there. */
5276         log_sg("City size and number of citizens does not match in %s "
5277                "(%d != %d)! Repairing ...", city_name_get(pcity),
5278                city_size_get(pcity), size);
5279       }
5280       citizens_update(pcity, NULL);
5281     }
5282   }
5283 }
5284 
5285 /****************************************************************************
5286   Save cities data
5287 ****************************************************************************/
sg_save_player_cities(struct savedata * saving,struct player * plr)5288 static void sg_save_player_cities(struct savedata *saving,
5289                                   struct player *plr)
5290 {
5291   int wlist_max_length = 0;
5292   int i = 0;
5293   int plrno = player_number(plr);
5294   bool nations[MAX_NUM_PLAYER_SLOTS];
5295 
5296   /* Check status and return if not OK (sg_success != TRUE). */
5297   sg_check_ret();
5298 
5299   secfile_insert_int(saving->file, city_list_size(plr->cities),
5300                      "player%d.ncities", plrno);
5301 
5302   if (game.info.citizen_nationality) {
5303     /* Initialise the nation list for the citizens information. */
5304     player_slots_iterate(pslot) {
5305       nations[player_slot_index(pslot)] = FALSE;
5306     } player_slots_iterate_end;
5307   }
5308 
5309   /* First determine lenght of longest worklist and the nations we have. */
5310   city_list_iterate(plr->cities, pcity) {
5311     /* Check the sanity of the city. */
5312     city_refresh(pcity);
5313     sanity_check_city(pcity);
5314 
5315     if (pcity->worklist.length > wlist_max_length) {
5316       wlist_max_length = pcity->worklist.length;
5317     }
5318 
5319     if (game.info.citizen_nationality) {
5320       /* Find all nations of the citizens,*/
5321       players_iterate(pplayer) {
5322         if (!nations[player_index(pplayer)]
5323             && citizens_nation_get(pcity, pplayer->slot) != 0) {
5324           nations[player_index(pplayer)] = TRUE;
5325         }
5326       } players_iterate_end;
5327     }
5328   } city_list_iterate_end;
5329 
5330   city_list_iterate(plr->cities, pcity) {
5331     struct tile *pcenter = city_tile(pcity);
5332     char impr_buf[MAX_NUM_ITEMS + 1];
5333     char buf[32];
5334     int j, nat_x, nat_y;
5335 
5336     fc_snprintf(buf, sizeof(buf), "player%d.c%d", plrno, i);
5337 
5338 
5339     index_to_native_pos(&nat_x, &nat_y, tile_index(pcenter));
5340     secfile_insert_int(saving->file, nat_y, "%s.y", buf);
5341     secfile_insert_int(saving->file, nat_x, "%s.x", buf);
5342 
5343     secfile_insert_int(saving->file, pcity->id, "%s.id", buf);
5344 
5345     secfile_insert_int(saving->file, player_number(pcity->original),
5346                        "%s.original", buf);
5347     secfile_insert_int(saving->file, city_size_get(pcity), "%s.size", buf);
5348 
5349     j = 0;
5350     specialist_type_iterate(sp) {
5351       secfile_insert_int(saving->file, pcity->specialists[sp], "%s.nspe%d",
5352                          buf, j++);
5353     } specialist_type_iterate_end;
5354 
5355     for (j = 0; j < MAX_TRADE_ROUTES; j++) {
5356       secfile_insert_int(saving->file, pcity->trade[j], "%s.traderoute%d",
5357                          buf, j);
5358     }
5359 
5360     secfile_insert_int(saving->file, pcity->food_stock, "%s.food_stock",
5361                        buf);
5362     secfile_insert_int(saving->file, pcity->shield_stock, "%s.shield_stock",
5363                        buf);
5364     secfile_insert_int(saving->file, pcity->history, "%s.history",
5365                        buf);
5366 
5367     secfile_insert_int(saving->file, pcity->airlift, "%s.airlift",
5368                        buf);
5369     secfile_insert_bool(saving->file, pcity->was_happy, "%s.was_happy",
5370                         buf);
5371     secfile_insert_int(saving->file, pcity->turn_plague, "%s.turn_plague",
5372                        buf);
5373 
5374     secfile_insert_int(saving->file, pcity->anarchy, "%s.anarchy", buf);
5375     secfile_insert_int(saving->file, pcity->rapture, "%s.rapture", buf);
5376     secfile_insert_int(saving->file, pcity->server.steal, "%s.steal", buf);
5377 
5378     secfile_insert_int(saving->file, pcity->turn_founded, "%s.turn_founded",
5379                        buf);
5380     if (pcity->turn_founded == game.info.turn) {
5381       j = -1; /* undocumented hack */
5382     } else {
5383       fc_assert(pcity->did_buy == TRUE || pcity->did_buy == FALSE);
5384       j = pcity->did_buy ? 1 : 0;
5385     }
5386     secfile_insert_int(saving->file, j, "%s.did_buy", buf);
5387     secfile_insert_bool(saving->file, pcity->did_sell, "%s.did_sell", buf);
5388     secfile_insert_int(saving->file, pcity->turn_last_built,
5389                        "%s.turn_last_built", buf);
5390 
5391     /* for visual debugging, variable length strings together here */
5392     secfile_insert_str(saving->file, city_name_get(pcity), "%s.name", buf);
5393 
5394     secfile_insert_str(saving->file, universal_type_rule_name(&pcity->production),
5395                        "%s.currently_building_kind", buf);
5396     secfile_insert_str(saving->file, universal_rule_name(&pcity->production),
5397                        "%s.currently_building_name", buf);
5398 
5399     secfile_insert_str(saving->file, universal_type_rule_name(&pcity->changed_from),
5400                        "%s.changed_from_kind", buf);
5401     secfile_insert_str(saving->file, universal_rule_name(&pcity->changed_from),
5402                        "%s.changed_from_name", buf);
5403 
5404     secfile_insert_int(saving->file, pcity->before_change_shields,
5405                        "%s.before_change_shields", buf);
5406     secfile_insert_int(saving->file, pcity->caravan_shields,
5407                        "%s.caravan_shields", buf);
5408     secfile_insert_int(saving->file, pcity->disbanded_shields,
5409                        "%s.disbanded_shields", buf);
5410     secfile_insert_int(saving->file, pcity->last_turns_shield_surplus,
5411                        "%s.last_turns_shield_surplus", buf);
5412 
5413     secfile_insert_str(saving->file, city_style_rule_name(pcity->style),
5414                        "%s.style", buf);
5415 
5416     /* Save the squared city radius and all tiles within the corresponing
5417      * city map. */
5418     secfile_insert_int(saving->file, pcity->city_radius_sq,
5419                        "player%d.c%d.city_radius_sq", plrno, i);
5420     /* The tiles worked by the city are saved using the main map.
5421      * See also sg_save_map_worked(). */
5422 
5423     /* Save improvement list as bytevector. Note that improvement order
5424      * is saved in savefile.improvement_order. */
5425     improvement_iterate(pimprove) {
5426       impr_buf[improvement_index(pimprove)]
5427         = (pcity->built[improvement_index(pimprove)].turn <= I_NEVER) ? '0'
5428                                                                       : '1';
5429     } improvement_iterate_end;
5430     impr_buf[improvement_count()] = '\0';
5431     sg_failure_ret(strlen(impr_buf) < sizeof(impr_buf),
5432                    "Invalid size of the improvement vector (%s.improvements: "
5433                    "%lu < %lu).", buf, (long unsigned int) strlen(impr_buf),
5434                    (long unsigned int) sizeof(impr_buf));
5435     secfile_insert_str(saving->file, impr_buf, "%s.improvements", buf);
5436 
5437     worklist_save(saving->file, &pcity->worklist, wlist_max_length, "%s",
5438                   buf);
5439 
5440     for (j = 0; j < CITYO_LAST; j++) {
5441       secfile_insert_bool(saving->file, BV_ISSET(pcity->city_options, j),
5442                           "%s.option%d", buf, j);
5443     }
5444 
5445     CALL_FUNC_EACH_AI(city_save, saving->file, pcity, buf);
5446 
5447     if (game.info.citizen_nationality) {
5448       /* Save nationality of the citizens,*/
5449       players_iterate(pplayer) {
5450         if (nations[player_index(pplayer)]) {
5451           secfile_insert_int(saving->file,
5452                              citizens_nation_get(pcity, pplayer->slot),
5453                              "%s.citizen%d", buf, player_index(pplayer));
5454         }
5455       } players_iterate_end;
5456     }
5457 
5458     i++;
5459   } city_list_iterate_end;
5460 
5461   i = 0;
5462   city_list_iterate(plr->cities, pcity) {
5463     worker_task_list_iterate(pcity->task_reqs, ptask) {
5464       int nat_x, nat_y;
5465 
5466       index_to_native_pos(&nat_x, &nat_y, tile_index(ptask->ptile));
5467       secfile_insert_int(saving->file, pcity->id, "player%d.task%d.city",
5468                          plrno, i);
5469       secfile_insert_int(saving->file, nat_y, "player%d.task%d.y", plrno, i);
5470       secfile_insert_int(saving->file, nat_x, "player%d.task%d.x", plrno, i);
5471       secfile_insert_str(saving->file, unit_activity_name(ptask->act),
5472                          "player%d.task%d.activity",
5473                          plrno, i);
5474       if (ptask->tgt != NULL) {
5475         secfile_insert_str(saving->file, extra_rule_name(ptask->tgt),
5476                            "player%d.task%d.target",
5477                            plrno, i);
5478       } else {
5479         secfile_insert_str(saving->file, "-",
5480                            "player%d.task%d.target",
5481                            plrno, i);
5482       }
5483       secfile_insert_int(saving->file, ptask->want, "player%d.task%d.want", plrno, i);
5484 
5485       i++;
5486     } worker_task_list_iterate_end;
5487   } city_list_iterate_end;
5488 }
5489 
5490 /****************************************************************************
5491   Load unit data
5492 ****************************************************************************/
sg_load_player_units(struct loaddata * loading,struct player * plr)5493 static void sg_load_player_units(struct loaddata *loading,
5494                                  struct player *plr)
5495 {
5496   int nunits, i, plrno = player_number(plr);
5497 
5498   /* Check status and return if not OK (sg_success != TRUE). */
5499   sg_check_ret();
5500 
5501   sg_failure_ret(secfile_lookup_int(loading->file, &nunits,
5502                                     "player%d.nunits", plrno),
5503                  "%s", secfile_error());
5504   if (!plr->is_alive && nunits > 0) {
5505     log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
5506     nunits = 0; /* Some old savegames may be buggy. */
5507   }
5508 
5509   for (i = 0; i < nunits; i++) {
5510     struct unit *punit;
5511     struct city *pcity;
5512     const char *name;
5513     char buf[32];
5514     struct unit_type *type;
5515     struct tile *ptile;
5516 
5517     fc_snprintf(buf, sizeof(buf), "player%d.u%d", plrno, i);
5518 
5519     name = secfile_lookup_str(loading->file, "%s.type_by_name", buf);
5520     type = unit_type_by_rule_name(name);
5521     sg_failure_ret(type != NULL, "%s: unknown unit type \"%s\".", buf, name);
5522 
5523     /* Create a dummy unit. */
5524     punit = unit_virtual_create(plr, NULL, type, 0);
5525     if (!sg_load_player_unit(loading, plr, punit, buf)) {
5526       unit_virtual_destroy(punit);
5527       sg_failure_ret(FALSE, "Error loading unit %d of player %d.", i, plrno);
5528     }
5529 
5530     identity_number_reserve(punit->id);
5531     idex_register_unit(punit);
5532 
5533     if ((pcity = game_city_by_number(punit->homecity))) {
5534       unit_list_prepend(pcity->units_supported, punit);
5535     } else if (punit->homecity > IDENTITY_NUMBER_ZERO) {
5536       log_sg("%s: bad home city %d.", buf, punit->homecity);
5537       punit->homecity = IDENTITY_NUMBER_ZERO;
5538     }
5539 
5540     ptile = unit_tile(punit);
5541 
5542     /* allocate the unit's contribution to fog of war */
5543     punit->server.vision = vision_new(unit_owner(punit), ptile);
5544     unit_refresh_vision(punit);
5545     /* NOTE: There used to be some map_set_known calls here.  These were
5546      * unneeded since unfogging the tile when the unit sees it will
5547      * automatically reveal that tile. */
5548 
5549     unit_list_append(plr->units, punit);
5550     unit_list_prepend(unit_tile(punit)->units, punit);
5551 
5552     /* Claim ownership of fortress? */
5553     if ((extra_owner(ptile) == NULL
5554          || pplayers_at_war(extra_owner(ptile), plr))
5555         && tile_has_claimable_base(ptile, unit_type_get(punit))) {
5556       tile_claim_bases(ptile, plr);
5557     }
5558   }
5559 }
5560 
5561 /****************************************************************************
5562   Load one unit. sg_save_player_unit() is not defined.
5563 ****************************************************************************/
sg_load_player_unit(struct loaddata * loading,struct player * plr,struct unit * punit,const char * unitstr)5564 static bool sg_load_player_unit(struct loaddata *loading,
5565                                 struct player *plr, struct unit *punit,
5566                                 const char *unitstr)
5567 {
5568   int j;
5569   enum unit_activity activity;
5570   int nat_x, nat_y;
5571   enum tile_special_type target;
5572   struct extra_type *pextra = NULL;
5573   struct base_type *pbase = NULL;
5574   struct road_type *proad = NULL;
5575   struct tile *ptile;
5576   int extra_id;
5577   int base_id;
5578   int road_id;
5579   int ei;
5580   const char *facing_str;
5581   enum tile_special_type cfspe;
5582   int natnbr;
5583 
5584   sg_warn_ret_val(secfile_lookup_int(loading->file, &punit->id, "%s.id",
5585                                      unitstr), FALSE, "%s", secfile_error());
5586   sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x", unitstr),
5587                   FALSE, "%s", secfile_error());
5588   sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y", unitstr),
5589                   FALSE, "%s", secfile_error());
5590 
5591   ptile = native_pos_to_tile(nat_x, nat_y);
5592   sg_warn_ret_val(NULL != ptile, FALSE, "%s invalid tile (%d, %d)",
5593                   unitstr, nat_x, nat_y);
5594   unit_tile_set(punit, ptile);
5595 
5596   facing_str
5597     = secfile_lookup_str_default(loading->file, "x",
5598                                  "%s.facing", unitstr);
5599   if (facing_str[0] != 'x') {
5600     /* We don't touch punit->facing if savegame does not contain that
5601      * information. Initial orientation set by unit_virtual_create()
5602      * is as good as any. */
5603     enum direction8 facing = char2dir(facing_str[0]);
5604 
5605     if (direction8_is_valid(facing)) {
5606       punit->facing = facing;
5607     } else {
5608       log_error("Illegal unit orientation '%s'", facing_str);
5609     }
5610   }
5611 
5612   /* If savegame has unit nationality, it doesn't hurt to
5613    * internally set it even if nationality rules are disabled. */
5614   natnbr = secfile_lookup_int_default(loading->file,
5615                                       player_number(plr),
5616                                       "%s.nationality", unitstr);
5617 
5618   punit->nationality = player_by_number(natnbr);
5619   if (punit->nationality == NULL) {
5620     punit->nationality = plr;
5621   }
5622 
5623   sg_warn_ret_val(secfile_lookup_int(loading->file, &punit->homecity,
5624                                      "%s.homecity", unitstr), FALSE,
5625                   "%s", secfile_error());
5626   sg_warn_ret_val(secfile_lookup_int(loading->file, &punit->moves_left,
5627                                      "%s.moves", unitstr), FALSE,
5628                   "%s", secfile_error());
5629   sg_warn_ret_val(secfile_lookup_int(loading->file, &punit->fuel,
5630                                      "%s.fuel", unitstr), FALSE,
5631                   "%s", secfile_error());
5632   sg_warn_ret_val(secfile_lookup_int(loading->file, &ei,
5633                                      "%s.activity", unitstr), FALSE,
5634                   "%s", secfile_error());
5635   activity = ei;
5636 
5637   punit->server.birth_turn
5638     = secfile_lookup_int_default(loading->file, game.info.turn,
5639                                  "%s.born", unitstr);
5640 
5641   if (activity == ACTIVITY_PATROL_UNUSED) {
5642     /* Previously ACTIVITY_PATROL and ACTIVITY_GOTO were used for
5643      * client-side goto. Now client-side goto is handled by setting
5644      * a special flag, and units with orders generally have ACTIVITY_IDLE.
5645      * Old orders are lost. Old client-side goto units will still have
5646      * ACTIVITY_GOTO and will goto the correct position via server goto.
5647      * Old client-side patrol units lose their patrol routes and are put
5648      * into idle mode. */
5649     activity = ACTIVITY_IDLE;
5650   }
5651 
5652   extra_id = secfile_lookup_int_default(loading->file, -2,
5653                                         "%s.activity_tgt", unitstr);
5654 
5655   if (extra_id != -2) {
5656     if (extra_id >= 0 && extra_id < loading->extra.size) {
5657       pextra = loading->extra.order[extra_id];
5658       set_unit_activity_targeted(punit, activity, pextra);
5659     } else if (activity == ACTIVITY_IRRIGATE) {
5660       struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
5661                                                    EC_IRRIGATION,
5662                                                    unit_owner(punit),
5663                                                    punit);
5664       if (tgt != NULL) {
5665         set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, tgt);
5666       } else {
5667         set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, NULL);
5668       }
5669     } else if (activity == ACTIVITY_MINE) {
5670       struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
5671                                                    EC_MINE,
5672                                                    unit_owner(punit),
5673                                                    punit);
5674       if (tgt != NULL) {
5675         set_unit_activity_targeted(punit, ACTIVITY_MINE, tgt);
5676       } else {
5677         set_unit_activity_targeted(punit, ACTIVITY_MINE, NULL);
5678       }
5679     } else {
5680       set_unit_activity(punit, activity);
5681     }
5682   } else {
5683     /* extra_id == -2 -> activity_tgt not set */
5684     base_id = secfile_lookup_int_default(loading->file, -1,
5685                                       "%s.activity_base", unitstr);
5686     if (base_id >= 0 && base_id < loading->base.size) {
5687       pbase = loading->base.order[base_id];
5688     }
5689     road_id = secfile_lookup_int_default(loading->file, -1,
5690                                       "%s.activity_road", unitstr);
5691     if (road_id >= 0 && road_id < loading->road.size) {
5692       proad = loading->road.order[road_id];
5693     }
5694 
5695     {
5696       int tgt_no = secfile_lookup_int_default(loading->file,
5697                                               loading->special.size /* S_LAST */,
5698                                               "%s.activity_target", unitstr);
5699       if (tgt_no >= 0 && tgt_no < loading->special.size) {
5700         target = loading->special.order[tgt_no];
5701       } else {
5702         target = S_LAST;
5703       }
5704     }
5705 
5706     if (target == S_OLD_ROAD) {
5707       target = S_LAST;
5708       proad = road_by_compat_special(ROCO_ROAD);
5709     } else if (target == S_OLD_RAILROAD) {
5710       target = S_LAST;
5711       proad = road_by_compat_special(ROCO_RAILROAD);
5712     }
5713 
5714     if (activity == ACTIVITY_OLD_ROAD) {
5715       activity = ACTIVITY_GEN_ROAD;
5716       proad = road_by_compat_special(ROCO_ROAD);
5717     } else if (activity == ACTIVITY_OLD_RAILROAD) {
5718       activity = ACTIVITY_GEN_ROAD;
5719       proad = road_by_compat_special(ROCO_RAILROAD);
5720     }
5721 
5722     /* We need changed_from == ACTIVITY_IDLE by now so that
5723      * set_unit_activity() and friends don't spuriously restore activity
5724      * points -- unit should have been created this way */
5725     fc_assert(punit->changed_from == ACTIVITY_IDLE);
5726 
5727     if (activity == ACTIVITY_BASE) {
5728       if (pbase) {
5729         set_unit_activity_base(punit, base_number(pbase));
5730       } else {
5731         log_sg("Cannot find base %d for %s to build",
5732                base_id, unit_rule_name(punit));
5733         set_unit_activity(punit, ACTIVITY_IDLE);
5734       }
5735     } else if (activity == ACTIVITY_GEN_ROAD) {
5736       if (proad) {
5737         set_unit_activity_road(punit, road_number(proad));
5738       } else {
5739         log_sg("Cannot find road %d for %s to build",
5740                road_id, unit_rule_name(punit));
5741         set_unit_activity(punit, ACTIVITY_IDLE);
5742       }
5743     } else if (activity == ACTIVITY_PILLAGE) {
5744       struct extra_type *a_target;
5745 
5746       if (target != S_LAST) {
5747         a_target = special_extra_get(target);
5748       } else if (pbase != NULL) {
5749         a_target = base_extra_get(pbase);
5750       } else if (proad != NULL) {
5751         a_target = road_extra_get(proad);
5752       } else {
5753         a_target = NULL;
5754       }
5755       /* An out-of-range base number is seen with old savegames. We take
5756        * it as indicating undirected pillaging. We will assign pillage
5757        * targets before play starts. */
5758       set_unit_activity_targeted(punit, activity, a_target);
5759     } else if (activity == ACTIVITY_IRRIGATE) {
5760       struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
5761                                                    EC_IRRIGATION,
5762                                                    unit_owner(punit),
5763                                                    punit);
5764       if (tgt != NULL) {
5765         set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, tgt);
5766       } else {
5767         set_unit_activity_targeted(punit, ACTIVITY_IRRIGATE, NULL);
5768       }
5769     } else if (activity == ACTIVITY_MINE) {
5770       struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
5771                                                    EC_MINE,
5772                                                    unit_owner(punit),
5773                                                    punit);
5774       if (tgt != NULL) {
5775         set_unit_activity_targeted(punit, ACTIVITY_MINE, tgt);
5776       } else {
5777         set_unit_activity_targeted(punit, ACTIVITY_MINE, NULL);
5778       }
5779     } else if (activity == ACTIVITY_POLLUTION) {
5780       struct extra_type *tgt = prev_extra_in_tile(unit_tile(punit),
5781                                                   ERM_CLEANPOLLUTION,
5782                                                   unit_owner(punit),
5783                                                   punit);
5784       if (tgt != NULL) {
5785         set_unit_activity_targeted(punit, ACTIVITY_POLLUTION, tgt);
5786       } else {
5787         set_unit_activity_targeted(punit, ACTIVITY_POLLUTION, NULL);
5788       }
5789     } else if (activity == ACTIVITY_FALLOUT) {
5790       struct extra_type *tgt = prev_extra_in_tile(unit_tile(punit),
5791                                                   ERM_CLEANFALLOUT,
5792                                                   unit_owner(punit),
5793                                                   punit);
5794       if (tgt != NULL) {
5795         set_unit_activity_targeted(punit, ACTIVITY_FALLOUT, tgt);
5796       } else {
5797         set_unit_activity_targeted(punit, ACTIVITY_FALLOUT, NULL);
5798       }
5799     } else {
5800       set_unit_activity_targeted(punit, activity, NULL);
5801     }
5802   } /* activity_tgt == NULL */
5803 
5804   sg_warn_ret_val(secfile_lookup_int(loading->file, &punit->activity_count,
5805                                      "%s.activity_count", unitstr), FALSE,
5806                   "%s", secfile_error());
5807 
5808   punit->changed_from =
5809     secfile_lookup_int_default(loading->file, ACTIVITY_IDLE,
5810                                "%s.changed_from", unitstr);
5811 
5812   extra_id = secfile_lookup_int_default(loading->file, -2,
5813                                         "%s.changed_from_tgt", unitstr);
5814 
5815   if (extra_id != -2) {
5816     if (extra_id >= 0 && extra_id < loading->extra.size) {
5817       punit->changed_from_target = loading->extra.order[extra_id];
5818     } else {
5819       punit->changed_from_target = NULL;
5820     }
5821   } else {
5822     /* extra_id == -2 -> changed_from_tgt not set */
5823 
5824     cfspe =
5825       secfile_lookup_int_default(loading->file, S_LAST,
5826                                  "%s.changed_from_target", unitstr);
5827     base_id =
5828       secfile_lookup_int_default(loading->file, -1,
5829                                  "%s.changed_from_base", unitstr);
5830     road_id =
5831       secfile_lookup_int_default(loading->file, -1,
5832                                  "%s.changed_from_road", unitstr);
5833 
5834     if (road_id == -1) {
5835       if (cfspe == S_OLD_ROAD) {
5836         proad = road_by_compat_special(ROCO_ROAD);
5837         if (proad) {
5838           road_id = road_index(proad);
5839         }
5840       } else if (cfspe == S_OLD_RAILROAD) {
5841         proad = road_by_compat_special(ROCO_RAILROAD);
5842         if (proad) {
5843           road_id = road_index(proad);
5844         }
5845       }
5846     }
5847 
5848     if (base_id >= 0 && base_id < loading->base.size) {
5849       punit->changed_from_target = base_extra_get(loading->base.order[base_id]);
5850     } else if (road_id >= 0 && road_id < loading->road.size) {
5851       punit->changed_from_target = road_extra_get(loading->road.order[road_id]);
5852     } else if (cfspe != S_LAST) {
5853       punit->changed_from_target = special_extra_get(cfspe);
5854     } else {
5855       punit->changed_from_target = NULL;
5856     }
5857 
5858     if (punit->changed_from == ACTIVITY_IRRIGATE) {
5859       struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
5860                                                    EC_IRRIGATION,
5861                                                    unit_owner(punit),
5862                                                    punit);
5863       if (tgt != NULL) {
5864         punit->changed_from_target = tgt;
5865       } else {
5866         punit->changed_from_target = NULL;
5867       }
5868     } else if (punit->changed_from == ACTIVITY_MINE) {
5869       struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
5870                                                    EC_MINE,
5871                                                    unit_owner(punit),
5872                                                    punit);
5873       if (tgt != NULL) {
5874         punit->changed_from_target = tgt;
5875       } else {
5876         punit->changed_from_target = NULL;
5877       }
5878     } else if (punit->changed_from == ACTIVITY_POLLUTION) {
5879       struct extra_type *tgt = prev_extra_in_tile(unit_tile(punit),
5880                                                   ERM_CLEANPOLLUTION,
5881                                                   unit_owner(punit),
5882                                                   punit);
5883       if (tgt != NULL) {
5884         punit->changed_from_target = tgt;
5885       } else {
5886         punit->changed_from_target = NULL;
5887       }
5888     } else if (punit->changed_from == ACTIVITY_FALLOUT) {
5889       struct extra_type *tgt = prev_extra_in_tile(unit_tile(punit),
5890                                                   ERM_CLEANFALLOUT,
5891                                                   unit_owner(punit),
5892                                                   punit);
5893       if (tgt != NULL) {
5894         punit->changed_from_target = tgt;
5895       } else {
5896         punit->changed_from_target = NULL;
5897       }
5898     }
5899   }
5900 
5901   punit->changed_from_count =
5902     secfile_lookup_int_default(loading->file, 0,
5903                                "%s.changed_from_count", unitstr);
5904 
5905   /* Special case: for a long time, we accidentally incremented
5906    * activity_count while a unit was sentried, so it could increase
5907    * without bound (bug #20641) and be saved in old savefiles.
5908    * We zero it to prevent potential trouble overflowing the range
5909    * in network packets, etc. */
5910   if (activity == ACTIVITY_SENTRY) {
5911     punit->activity_count = 0;
5912   }
5913   if (punit->changed_from == ACTIVITY_SENTRY) {
5914     punit->changed_from_count = 0;
5915   }
5916 
5917   punit->veteran
5918     = secfile_lookup_int_default(loading->file, 0, "%s.veteran", unitstr);
5919   {
5920     /* Protect against change in veteran system in ruleset */
5921     const int levels = utype_veteran_levels(unit_type_get(punit));
5922     if (punit->veteran >= levels) {
5923       fc_assert(levels >= 1);
5924       punit->veteran = levels - 1;
5925     }
5926   }
5927   punit->done_moving
5928     = secfile_lookup_bool_default(loading->file, (punit->moves_left == 0),
5929                                   "%s.done_moving", unitstr);
5930   punit->battlegroup
5931     = secfile_lookup_int_default(loading->file, BATTLEGROUP_NONE,
5932                                  "%s.battlegroup", unitstr);
5933 
5934   if (secfile_lookup_bool_default(loading->file, FALSE,
5935                                   "%s.go", unitstr)) {
5936     int gnat_x, gnat_y;
5937 
5938     sg_warn_ret_val(secfile_lookup_int(loading->file, &gnat_x,
5939                                        "%s.goto_x", unitstr), FALSE,
5940                     "%s", secfile_error());
5941     sg_warn_ret_val(secfile_lookup_int(loading->file, &gnat_y,
5942                                        "%s.goto_y", unitstr), FALSE,
5943                     "%s", secfile_error());
5944 
5945     punit->goto_tile = native_pos_to_tile(gnat_x, gnat_y);
5946   } else {
5947     punit->goto_tile = NULL;
5948 
5949     /* These variables are not used but needed for saving the unit table.
5950      * Load them to prevent unused variables errors. */
5951     (void) secfile_entry_lookup(loading->file, "%s.goto_x", unitstr);
5952     (void) secfile_entry_lookup(loading->file, "%s.goto_y", unitstr);
5953   }
5954 
5955   /* Load AI data of the unit. */
5956   CALL_FUNC_EACH_AI(unit_load, loading->file, punit, unitstr);
5957 
5958   sg_warn_ret_val(secfile_lookup_bool(loading->file,
5959                                       &punit->ai_controlled,
5960                                       "%s.ai", unitstr), FALSE,
5961                   "%s", secfile_error());
5962   sg_warn_ret_val(secfile_lookup_int(loading->file, &punit->hp,
5963                                      "%s.hp", unitstr), FALSE,
5964                   "%s", secfile_error());
5965 
5966   punit->server.ord_map
5967     = secfile_lookup_int_default(loading->file, 0, "%s.ord_map", unitstr);
5968   punit->server.ord_city
5969     = secfile_lookup_int_default(loading->file, 0, "%s.ord_city", unitstr);
5970   punit->moved
5971     = secfile_lookup_bool_default(loading->file, FALSE, "%s.moved", unitstr);
5972   punit->paradropped
5973     = secfile_lookup_bool_default(loading->file, FALSE,
5974                                   "%s.paradropped", unitstr);
5975 
5976   /* The transport status (punit->transported_by) is loaded in
5977    * sg_player_units_transport(). */
5978 
5979   /* Initialize upkeep values: these are hopefully initialized
5980    * elsewhere before use (specifically, in city_support(); but
5981    * fixme: check whether always correctly initialized?).
5982    * Below is mainly for units which don't have homecity --
5983    * otherwise these don't get initialized (and AI calculations
5984    * etc may use junk values). */
5985   output_type_iterate(o) {
5986     punit->upkeep[o] = utype_upkeep_cost(unit_type_get(punit), plr, o);
5987   } output_type_iterate_end;
5988 
5989   punit->action_decision_want
5990       = secfile_lookup_enum_default(loading->file,
5991                                     ACT_DEC_NOTHING, action_decision,
5992                                     "%s.action_decision_want", unitstr);
5993 
5994   if (punit->action_decision_want != ACT_DEC_NOTHING) {
5995     /* Load the tile to act against. */
5996     int adwt_x, adwt_y;
5997 
5998     if (secfile_lookup_int(loading->file, &adwt_x,
5999                            "%s.action_decision_tile_x", unitstr)
6000         && secfile_lookup_int(loading->file, &adwt_y,
6001                               "%s.action_decision_tile_y", unitstr)) {
6002       punit->action_decision_tile = native_pos_to_tile(adwt_x, adwt_y);
6003     } else {
6004       punit->action_decision_want = ACT_DEC_NOTHING;
6005       punit->action_decision_tile = NULL;
6006       log_sg("Bad action_decision_tile for unit %d", punit->id);
6007     }
6008   } else {
6009     (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_x", unitstr);
6010     (void) secfile_entry_lookup(loading->file, "%s.action_decision_tile_y", unitstr);
6011     punit->action_decision_tile = NULL;
6012   }
6013 
6014   /* load the unit orders */
6015   {
6016     int len = secfile_lookup_int_default(loading->file, 0,
6017                                          "%s.orders_length", unitstr);
6018     if (len > 0) {
6019       const char *orders_unitstr, *dir_unitstr, *act_unitstr;
6020       const char *tgt_unitstr;
6021       const char *base_unitstr = NULL;
6022       const char *road_unitstr = NULL;
6023       int road_idx = road_index(road_by_compat_special(ROCO_ROAD));
6024       int rail_idx = road_index(road_by_compat_special(ROCO_RAILROAD));
6025 
6026       punit->orders.list = fc_malloc(len * sizeof(*(punit->orders.list)));
6027       punit->orders.length = len;
6028       punit->orders.index
6029         = secfile_lookup_int_default(loading->file, 0,
6030                                      "%s.orders_index", unitstr);
6031       punit->orders.repeat
6032         = secfile_lookup_bool_default(loading->file, FALSE,
6033                                       "%s.orders_repeat", unitstr);
6034       punit->orders.vigilant
6035         = secfile_lookup_bool_default(loading->file, FALSE,
6036                                       "%s.orders_vigilant", unitstr);
6037 
6038       orders_unitstr
6039         = secfile_lookup_str_default(loading->file, "",
6040                                      "%s.orders_list", unitstr);
6041       dir_unitstr
6042         = secfile_lookup_str_default(loading->file, "",
6043                                      "%s.dir_list", unitstr);
6044       act_unitstr
6045         = secfile_lookup_str_default(loading->file, "",
6046                                      "%s.activity_list", unitstr);
6047       tgt_unitstr
6048         = secfile_lookup_str_default(loading->file, NULL, "%s.tgt_list", unitstr);
6049 
6050       if (tgt_unitstr == NULL) {
6051         base_unitstr
6052           = secfile_lookup_str(loading->file, "%s.base_list", unitstr);
6053         road_unitstr
6054           = secfile_lookup_str_default(loading->file, NULL, "%s.road_list", unitstr);
6055       }
6056 
6057       punit->has_orders = TRUE;
6058       for (j = 0; j < len; j++) {
6059         struct unit_order *order = &punit->orders.list[j];
6060 
6061         if (orders_unitstr[j] == '\0' || dir_unitstr[j] == '\0'
6062             || act_unitstr[j] == '\0') {
6063           log_sg("Invalid unit orders.");
6064           free_unit_orders(punit);
6065           break;
6066         }
6067         order->order = char2order(orders_unitstr[j]);
6068         order->dir = char2dir(dir_unitstr[j]);
6069         order->activity = char2activity(act_unitstr[j]);
6070         if (order->order == ORDER_LAST
6071             || (order->order == ORDER_MOVE && !direction8_is_valid(order->dir))
6072             || (order->order == ORDER_ACTION_MOVE
6073                 && !direction8_is_valid(order->dir))
6074             || (order->order == ORDER_ACTIVITY
6075                 && order->activity == ACTIVITY_LAST)) {
6076           /* An invalid order. Just drop the orders for this unit. */
6077           free(punit->orders.list);
6078           punit->orders.list = NULL;
6079           punit->has_orders = FALSE;
6080           break;
6081         }
6082 
6083         if (tgt_unitstr) {
6084           if (tgt_unitstr[j] != '?') {
6085             extra_id = char2num(tgt_unitstr[j]);
6086 
6087             if (extra_id < 0 || extra_id >= loading->extra.size) {
6088               log_sg("Cannot find extra %d for %s to build",
6089                      extra_id, unit_rule_name(punit));
6090               order->target = EXTRA_NONE;
6091             } else {
6092               order->target = extra_id;
6093             }
6094           } else {
6095             order->target = EXTRA_NONE;
6096           }
6097         } else {
6098           /* In pre-2.6 savegames, base_list and road_list were only saved
6099            * for those activities (and not e.g. pillaging) */
6100           if (base_unitstr && base_unitstr[j] != '?'
6101               && order->activity == ACTIVITY_BASE) {
6102             base_id = char2num(base_unitstr[j]);
6103 
6104             if (base_id < 0 || base_id >= loading->base.size) {
6105               log_sg("Cannot find base %d for %s to build",
6106                      base_id, unit_rule_name(punit));
6107               base_id = base_number(get_base_by_gui_type(BASE_GUI_FORTRESS,
6108                                                          NULL, NULL));
6109             }
6110 
6111             order->target
6112               = extra_number(base_extra_get(base_by_number(base_id)));
6113           } else if (road_unitstr && road_unitstr[j] != '?'
6114                      && order->activity == ACTIVITY_GEN_ROAD) {
6115             road_id = char2num(road_unitstr[j]);
6116 
6117             if (road_id < 0 || road_id >= loading->road.size) {
6118               log_sg("Cannot find road %d for %s to build",
6119                      road_id, unit_rule_name(punit));
6120               road_id = 0;
6121             }
6122 
6123             order->target
6124               = extra_number(road_extra_get(road_by_number(road_id)));
6125           } else {
6126             order->target = EXTRA_NONE;
6127           }
6128 
6129           if (order->activity == ACTIVITY_OLD_ROAD) {
6130             order->activity = ACTIVITY_GEN_ROAD;
6131             order->target
6132               = extra_number(road_extra_get(road_by_number(road_idx)));
6133           } else if (order->activity == ACTIVITY_OLD_RAILROAD) {
6134             order->activity = ACTIVITY_GEN_ROAD;
6135             order->target
6136               = extra_number(road_extra_get(road_by_number(rail_idx)));
6137           }
6138         }
6139       }
6140     } else {
6141       punit->has_orders = FALSE;
6142       punit->orders.list = NULL;
6143 
6144       (void) secfile_entry_lookup(loading->file, "%s.orders_index", unitstr);
6145       (void) secfile_entry_lookup(loading->file, "%s.orders_repeat", unitstr);
6146       (void) secfile_entry_lookup(loading->file, "%s.orders_vigilant", unitstr);
6147       (void) secfile_entry_lookup(loading->file, "%s.orders_list", unitstr);
6148       (void) secfile_entry_lookup(loading->file, "%s.dir_list", unitstr);
6149       (void) secfile_entry_lookup(loading->file, "%s.activity_list", unitstr);
6150       (void) secfile_entry_lookup(loading->file, "%s.tgt_list", unitstr);
6151     }
6152   }
6153 
6154   return TRUE;
6155 }
6156 
6157 /*****************************************************************************
6158   Load the transport status of all units. This is seperated from the other
6159   code as all units must be known.
6160 *****************************************************************************/
sg_load_player_units_transport(struct loaddata * loading,struct player * plr)6161 static void sg_load_player_units_transport(struct loaddata *loading,
6162                                            struct player *plr)
6163 {
6164   int nunits, i, plrno = player_number(plr);
6165 
6166   /* Check status and return if not OK (sg_success != TRUE). */
6167   sg_check_ret();
6168 
6169   /* Recheck the number of units for the player. This is a copied from
6170    * sg_load_player_units(). */
6171   sg_failure_ret(secfile_lookup_int(loading->file, &nunits,
6172                                     "player%d.nunits", plrno),
6173                  "%s", secfile_error());
6174   if (!plr->is_alive && nunits > 0) {
6175     log_sg("'player%d.nunits' = %d for dead player!", plrno, nunits);
6176     nunits = 0; /* Some old savegames may be buggy. */
6177   }
6178 
6179   for (i = 0; i < nunits; i++) {
6180     int id_unit, id_trans;
6181     struct unit *punit, *ptrans;
6182 
6183     id_unit = secfile_lookup_int_default(loading->file, -1,
6184                                          "player%d.u%d.id",
6185                                          plrno, i);
6186     punit = player_unit_by_number(plr, id_unit);
6187     fc_assert_action(punit != NULL, continue);
6188 
6189     id_trans = secfile_lookup_int_default(loading->file, -1,
6190                                           "player%d.u%d.transported_by",
6191                                           plrno, i);
6192     if (id_trans == -1) {
6193       /* Not transported. */
6194       continue;
6195     }
6196 
6197     ptrans = game_unit_by_number(id_trans);
6198     fc_assert_action(id_trans == -1 || ptrans != NULL, continue);
6199 
6200     if (ptrans) {
6201       bool load_success = unit_transport_load(punit, ptrans, TRUE);
6202 
6203       fc_assert_action(load_success == TRUE, continue);
6204     }
6205   }
6206 }
6207 
6208 /****************************************************************************
6209   Save unit data
6210 ****************************************************************************/
sg_save_player_units(struct savedata * saving,struct player * plr)6211 static void sg_save_player_units(struct savedata *saving,
6212                                  struct player *plr)
6213 {
6214   int i = 0;
6215 
6216   /* Check status and return if not OK (sg_success != TRUE). */
6217   sg_check_ret();
6218 
6219   secfile_insert_int(saving->file, unit_list_size(plr->units),
6220                      "player%d.nunits", player_number(plr));
6221 
6222   unit_list_iterate(plr->units, punit) {
6223     char buf[32];
6224     char dirbuf[2] = " ";
6225     int nat_x, nat_y;
6226 
6227     fc_snprintf(buf, sizeof(buf), "player%d.u%d", player_number(plr), i);
6228     dirbuf[0] = dir2char(punit->facing);
6229     secfile_insert_int(saving->file, punit->id, "%s.id", buf);
6230 
6231     index_to_native_pos(&nat_x, &nat_y, tile_index(unit_tile(punit)));
6232     secfile_insert_int(saving->file, nat_x, "%s.x", buf);
6233     secfile_insert_int(saving->file, nat_y, "%s.y", buf);
6234 
6235     secfile_insert_str(saving->file, dirbuf, "%s.facing", buf);
6236     if (game.info.citizen_nationality) {
6237       secfile_insert_int(saving->file, player_number(unit_nationality(punit)),
6238                          "%s.nationality", buf);
6239     }
6240     secfile_insert_int(saving->file, punit->veteran, "%s.veteran", buf);
6241     secfile_insert_int(saving->file, punit->hp, "%s.hp", buf);
6242     secfile_insert_int(saving->file, punit->homecity, "%s.homecity", buf);
6243     secfile_insert_str(saving->file, unit_rule_name(punit),
6244                        "%s.type_by_name", buf);
6245 
6246     secfile_insert_int(saving->file, punit->activity, "%s.activity", buf);
6247     secfile_insert_int(saving->file, punit->activity_count,
6248                        "%s.activity_count", buf);
6249     if (punit->activity_target == NULL) {
6250       secfile_insert_int(saving->file, -1, "%s.activity_tgt", buf);
6251     } else {
6252       secfile_insert_int(saving->file, extra_index(punit->activity_target),
6253                          "%s.activity_tgt", buf);
6254     }
6255 
6256     secfile_insert_int(saving->file, punit->changed_from,
6257                        "%s.changed_from", buf);
6258     secfile_insert_int(saving->file, punit->changed_from_count,
6259                        "%s.changed_from_count", buf);
6260     if (punit->changed_from_target == NULL) {
6261       secfile_insert_int(saving->file, -1, "%s.changed_from_tgt", buf);
6262     } else {
6263       secfile_insert_int(saving->file, extra_index(punit->changed_from_target),
6264                          "%s.changed_from_tgt", buf);
6265     }
6266 
6267     secfile_insert_bool(saving->file, punit->done_moving,
6268                         "%s.done_moving", buf);
6269     secfile_insert_int(saving->file, punit->moves_left, "%s.moves", buf);
6270     secfile_insert_int(saving->file, punit->fuel, "%s.fuel", buf);
6271     secfile_insert_int(saving->file, punit->server.birth_turn,
6272                       "%s.born", buf);
6273     secfile_insert_int(saving->file, punit->battlegroup,
6274                        "%s.battlegroup", buf);
6275 
6276     if (punit->goto_tile) {
6277       index_to_native_pos(&nat_x, &nat_y, tile_index(punit->goto_tile));
6278       secfile_insert_bool(saving->file, TRUE, "%s.go", buf);
6279       secfile_insert_int(saving->file, nat_x, "%s.goto_x", buf);
6280       secfile_insert_int(saving->file, nat_y, "%s.goto_y", buf);
6281     } else {
6282       secfile_insert_bool(saving->file, FALSE, "%s.go", buf);
6283       /* Set this values to allow saving it as table. */
6284       secfile_insert_int(saving->file, 0, "%s.goto_x", buf);
6285       secfile_insert_int(saving->file, 0, "%s.goto_y", buf);
6286     }
6287 
6288     secfile_insert_bool(saving->file, punit->ai_controlled,
6289                         "%s.ai", buf);
6290 
6291     /* Save AI data of the unit. */
6292     CALL_FUNC_EACH_AI(unit_save, saving->file, punit, buf);
6293 
6294     secfile_insert_int(saving->file, punit->server.ord_map,
6295                        "%s.ord_map", buf);
6296     secfile_insert_int(saving->file, punit->server.ord_city,
6297                        "%s.ord_city", buf);
6298     secfile_insert_bool(saving->file, punit->moved, "%s.moved", buf);
6299     secfile_insert_bool(saving->file, punit->paradropped,
6300                         "%s.paradropped", buf);
6301     secfile_insert_int(saving->file, unit_transport_get(punit)
6302                                      ? unit_transport_get(punit)->id : -1,
6303                        "%s.transported_by", buf);
6304 
6305     secfile_insert_enum(saving->file, punit->action_decision_want,
6306                         action_decision, "%s.action_decision_want", buf);
6307 
6308     /* Stored as tile rather than direction to make sure the target tile is
6309      * sane. */
6310     if (punit->action_decision_tile) {
6311       index_to_native_pos(&nat_x, &nat_y,
6312                           tile_index(punit->action_decision_tile));
6313       secfile_insert_int(saving->file, nat_x,
6314                          "%s.action_decision_tile_x", buf);
6315       secfile_insert_int(saving->file, nat_y,
6316                          "%s.action_decision_tile_y", buf);
6317     } else {
6318       /* Dummy values to get tabular format. */
6319       secfile_insert_int(saving->file, -1,
6320                          "%s.action_decision_tile_x", buf);
6321       secfile_insert_int(saving->file, -1,
6322                          "%s.action_decision_tile_y", buf);
6323     }
6324 
6325     if (punit->has_orders) {
6326       int len = punit->orders.length, j;
6327       char orders_buf[len + 1], dir_buf[len + 1];
6328       char act_buf[len + 1], tgt_buf[len + 1];
6329 
6330       secfile_insert_int(saving->file, len, "%s.orders_length", buf);
6331       secfile_insert_int(saving->file, punit->orders.index,
6332                          "%s.orders_index", buf);
6333       secfile_insert_bool(saving->file, punit->orders.repeat,
6334                           "%s.orders_repeat", buf);
6335       secfile_insert_bool(saving->file, punit->orders.vigilant,
6336                           "%s.orders_vigilant", buf);
6337 
6338       for (j = 0; j < len; j++) {
6339         orders_buf[j] = order2char(punit->orders.list[j].order);
6340         dir_buf[j] = '?';
6341         act_buf[j] = '?';
6342         tgt_buf[j] = '?';
6343         switch (punit->orders.list[j].order) {
6344         case ORDER_MOVE:
6345         case ORDER_ACTION_MOVE:
6346           dir_buf[j] = dir2char(punit->orders.list[j].dir);
6347           break;
6348         case ORDER_ACTIVITY:
6349           tgt_buf[j] = num2char(punit->orders.list[j].target);
6350           act_buf[j] = activity2char(punit->orders.list[j].activity);
6351           break;
6352         case ORDER_FULL_MP:
6353         case ORDER_BUILD_CITY:
6354         case ORDER_DISBAND:
6355         case ORDER_BUILD_WONDER:
6356         case ORDER_TRADE_ROUTE:
6357         case ORDER_HOMECITY:
6358         case ORDER_LAST:
6359           break;
6360         }
6361       }
6362       orders_buf[len] = dir_buf[len] = act_buf[len] = tgt_buf[len] = '\0';
6363 
6364       secfile_insert_str(saving->file, orders_buf, "%s.orders_list", buf);
6365       secfile_insert_str(saving->file, dir_buf, "%s.dir_list", buf);
6366       secfile_insert_str(saving->file, act_buf, "%s.activity_list", buf);
6367       secfile_insert_str(saving->file, tgt_buf, "%s.tgt_list", buf);
6368     } else {
6369       /* Put all the same fields into the savegame - otherwise the
6370        * registry code can't correctly use a tabular format and the
6371        * savegame will be bigger. */
6372       secfile_insert_int(saving->file, 0, "%s.orders_length", buf);
6373       secfile_insert_int(saving->file, 0, "%s.orders_index", buf);
6374       secfile_insert_bool(saving->file, FALSE, "%s.orders_repeat", buf);
6375       secfile_insert_bool(saving->file, FALSE, "%s.orders_vigilant", buf);
6376       secfile_insert_str(saving->file, "-", "%s.orders_list", buf);
6377       secfile_insert_str(saving->file, "-", "%s.dir_list", buf);
6378       secfile_insert_str(saving->file, "-", "%s.activity_list", buf);
6379       secfile_insert_str(saving->file, "-", "%s.tgt_list", buf);
6380     }
6381 
6382     i++;
6383   } unit_list_iterate_end;
6384 }
6385 
6386 /****************************************************************************
6387   Load player (client) attributes data
6388 ****************************************************************************/
sg_load_player_attributes(struct loaddata * loading,struct player * plr)6389 static void sg_load_player_attributes(struct loaddata *loading,
6390                                       struct player *plr)
6391 {
6392   int plrno = player_number(plr);
6393 
6394   /* Check status and return if not OK (sg_success != TRUE). */
6395   sg_check_ret();
6396 
6397   /* Toss any existing attribute_block (should not exist) */
6398   if (plr->attribute_block.data) {
6399     free(plr->attribute_block.data);
6400     plr->attribute_block.data = NULL;
6401   }
6402 
6403   /* This is a big heap of opaque data for the client, check everything! */
6404   plr->attribute_block.length = secfile_lookup_int_default(
6405       loading->file, 0, "player%d.attribute_v2_block_length", plrno);
6406 
6407   if (0 > plr->attribute_block.length) {
6408     log_sg("player%d.attribute_v2_block_length=%d too small", plrno,
6409            plr->attribute_block.length);
6410     plr->attribute_block.length = 0;
6411   } else if (MAX_ATTRIBUTE_BLOCK < plr->attribute_block.length) {
6412     log_sg("player%d.attribute_v2_block_length=%d too big (max %d)",
6413            plrno, plr->attribute_block.length, MAX_ATTRIBUTE_BLOCK);
6414     plr->attribute_block.length = 0;
6415   } else if (0 < plr->attribute_block.length) {
6416     int part_nr, parts;
6417     size_t actual_length;
6418     int quoted_length;
6419     char *quoted;
6420 
6421     sg_failure_ret(
6422         secfile_lookup_int(loading->file, &quoted_length,
6423                            "player%d.attribute_v2_block_length_quoted",
6424                            plrno), "%s", secfile_error());
6425     sg_failure_ret(
6426         secfile_lookup_int(loading->file, &parts,
6427                            "player%d.attribute_v2_block_parts", plrno),
6428         "%s", secfile_error());
6429 
6430     quoted = fc_malloc(quoted_length + 1);
6431     quoted[0] = '\0';
6432     plr->attribute_block.data = fc_malloc(plr->attribute_block.length);
6433     for (part_nr = 0; part_nr < parts; part_nr++) {
6434       const char *current =
6435           secfile_lookup_str(loading->file,
6436                              "player%d.attribute_v2_block_data.part%d",
6437                              plrno, part_nr);
6438       if (!current) {
6439         log_sg("attribute_v2_block_parts=%d actual=%d", parts, part_nr);
6440         break;
6441       }
6442       log_debug("attribute_v2_block_length_quoted=%lu have=%lu part=%lu",
6443                 (unsigned long) quoted_length,
6444                 (unsigned long) strlen(quoted),
6445                 (unsigned long) strlen(current));
6446       fc_assert(strlen(quoted) + strlen(current) <= quoted_length);
6447       strcat(quoted, current);
6448     }
6449     fc_assert_msg(quoted_length == strlen(quoted),
6450                   "attribute_v2_block_length_quoted=%lu actual=%lu",
6451                   (unsigned long) quoted_length,
6452                   (unsigned long) strlen(quoted));
6453 
6454     actual_length =
6455         unquote_block(quoted,
6456                       plr->attribute_block.data,
6457                       plr->attribute_block.length);
6458     fc_assert(actual_length == plr->attribute_block.length);
6459     free(quoted);
6460   }
6461 }
6462 
6463 /****************************************************************************
6464   Save player (client) attributes data.
6465 ****************************************************************************/
sg_save_player_attributes(struct savedata * saving,struct player * plr)6466 static void sg_save_player_attributes(struct savedata *saving,
6467                                       struct player *plr)
6468 {
6469   int plrno = player_number(plr);
6470 
6471   /* Check status and return if not OK (sg_success != TRUE). */
6472   sg_check_ret();
6473 
6474   /* This is a big heap of opaque data from the client.  Although the binary
6475    * format is not user editable, keep the lines short enough for debugging,
6476    * and hope that data compression will keep the file a reasonable size.
6477    * Note that the "quoted" format is a multiple of 3.
6478    */
6479 #define PART_SIZE (3*256)
6480 #define PART_ADJUST (3)
6481   if (plr->attribute_block.data) {
6482     char part[PART_SIZE + PART_ADJUST];
6483     int parts;
6484     int current_part_nr;
6485     char *quoted = quote_block(plr->attribute_block.data,
6486                                plr->attribute_block.length);
6487     char *quoted_at = strchr(quoted, ':');
6488     size_t bytes_left = strlen(quoted);
6489     size_t bytes_at_colon = 1 + (quoted_at - quoted);
6490     size_t bytes_adjust = bytes_at_colon % PART_ADJUST;
6491 
6492     secfile_insert_int(saving->file, plr->attribute_block.length,
6493                        "player%d.attribute_v2_block_length", plrno);
6494     secfile_insert_int(saving->file, bytes_left,
6495                        "player%d.attribute_v2_block_length_quoted", plrno);
6496 
6497     /* Try to wring some compression efficiencies out of the "quoted" format.
6498      * The first line has a variable length decimal, mis-aligning triples.
6499      */
6500     if ((bytes_left - bytes_adjust) > PART_SIZE) {
6501       /* first line can be longer */
6502       parts = 1 + (bytes_left - bytes_adjust - 1) / PART_SIZE;
6503     } else {
6504       parts = 1;
6505     }
6506 
6507     secfile_insert_int(saving->file, parts,
6508                        "player%d.attribute_v2_block_parts", plrno);
6509 
6510     if (parts > 1) {
6511       size_t size_of_current_part = PART_SIZE + bytes_adjust;
6512 
6513       /* first line can be longer */
6514       memcpy(part, quoted, size_of_current_part);
6515       part[size_of_current_part] = '\0';
6516       secfile_insert_str(saving->file, part,
6517                          "player%d.attribute_v2_block_data.part%d",
6518                          plrno, 0);
6519       bytes_left -= size_of_current_part;
6520       quoted_at = &quoted[size_of_current_part];
6521       current_part_nr = 1;
6522     } else {
6523       quoted_at = quoted;
6524       current_part_nr = 0;
6525     }
6526 
6527     for (; current_part_nr < parts; current_part_nr++) {
6528       size_t size_of_current_part = MIN(bytes_left, PART_SIZE);
6529 
6530       memcpy(part, quoted_at, size_of_current_part);
6531       part[size_of_current_part] = '\0';
6532       secfile_insert_str(saving->file, part,
6533                          "player%d.attribute_v2_block_data.part%d",
6534                          plrno,
6535                          current_part_nr);
6536       bytes_left -= size_of_current_part;
6537       quoted_at = &quoted_at[size_of_current_part];
6538     }
6539     fc_assert(bytes_left == 0);
6540     free(quoted);
6541   }
6542 #undef PART_ADJUST
6543 #undef PART_SIZE
6544 }
6545 
6546 /****************************************************************************
6547   Load vision data
6548 ****************************************************************************/
sg_load_player_vision(struct loaddata * loading,struct player * plr)6549 static void sg_load_player_vision(struct loaddata *loading,
6550                                   struct player *plr)
6551 {
6552   int plrno = player_number(plr);
6553   int total_ncities =
6554       secfile_lookup_int_default(loading->file, -1,
6555                                  "player%d.dc_total", plrno);
6556   int i;
6557 
6558   /* Check status and return if not OK (sg_success != TRUE). */
6559   sg_check_ret();
6560 
6561   if (!plr->is_alive) {
6562     if (game.server.revealmap & REVEAL_MAP_DEAD
6563         && player_list_size(team_members(plr->team)) == 1) {
6564       /* Reveal all for dead players. */
6565       map_know_and_see_all(plr);
6566     }
6567   }
6568 
6569   if (!plr->is_alive
6570       || -1 == total_ncities
6571       || FALSE == game.info.fogofwar
6572       || !secfile_lookup_bool_default(loading->file, TRUE,
6573                                       "game.save_private_map")) {
6574     /* We have:
6575      * - a dead player;
6576      * - fogged cities are not saved for any reason;
6577      * - a savegame with fog of war turned off;
6578      * - or game.save_private_map is not set to FALSE in the scenario /
6579      * savegame. The players private knowledge is set to be what he could
6580      * see without fog of war. */
6581     whole_map_iterate(ptile) {
6582       if (map_is_known(ptile, plr)) {
6583         struct city *pcity = tile_city(ptile);
6584 
6585         update_player_tile_last_seen(plr, ptile);
6586         update_player_tile_knowledge(plr, ptile);
6587 
6588         if (NULL != pcity) {
6589           update_dumb_city(plr, pcity);
6590         }
6591       }
6592     } whole_map_iterate_end;
6593 
6594     /* Nothing more to do; */
6595     return;
6596   }
6597 
6598   /* Load player map (terrain). */
6599   LOAD_MAP_CHAR(ch, ptile,
6600                 map_get_player_tile(ptile, plr)->terrain
6601                   = char2terrain(ch), loading->file,
6602                 "player%d.map_t%04d", plrno);
6603 
6604   /* Load player map (resources). */
6605   LOAD_MAP_CHAR(ch, ptile,
6606                 map_get_player_tile(ptile, plr)->resource
6607                   = char2resource(ch), loading->file,
6608                 "player%d.map_res%04d", plrno);
6609 
6610   if (loading->version >= 30) {
6611     /* 2.6.0 or newer */
6612 
6613     /* Load player map (extras). */
6614     halfbyte_iterate_extras(j, loading->extra.size) {
6615       LOAD_MAP_CHAR(ch, ptile,
6616                     sg_extras_set(&map_get_player_tile(ptile, plr)->extras,
6617                                   ch, loading->extra.order + 4 * j),
6618                     loading->file, "player%d.map_e%02d_%04d", plrno, j);
6619     } halfbyte_iterate_extras_end;
6620   } else {
6621     /* Load player map (specials). */
6622     halfbyte_iterate_special(j, loading->special.size) {
6623       LOAD_MAP_CHAR(ch, ptile,
6624                     sg_special_set(ptile, &map_get_player_tile(ptile, plr)->extras,
6625                                    ch, loading->special.order + 4 * j, FALSE),
6626                     loading->file, "player%d.map_spe%02d_%04d", plrno, j);
6627     } halfbyte_iterate_special_end;
6628 
6629     /* Load player map (bases). */
6630     halfbyte_iterate_bases(j, loading->base.size) {
6631       LOAD_MAP_CHAR(ch, ptile,
6632                     sg_bases_set(&map_get_player_tile(ptile, plr)->extras,
6633                                  ch, loading->base.order + 4 * j),
6634                     loading->file, "player%d.map_b%02d_%04d", plrno, j);
6635     } halfbyte_iterate_bases_end;
6636 
6637     /* Load player map (roads). */
6638     if (loading->version >= 20) {
6639       /* 2.5.0 or newer */
6640       halfbyte_iterate_roads(j, loading->road.size) {
6641         LOAD_MAP_CHAR(ch, ptile,
6642                       sg_roads_set(&map_get_player_tile(ptile, plr)->extras,
6643                                    ch, loading->road.order + 4 * j),
6644                       loading->file, "player%d.map_r%02d_%04d", plrno, j);
6645       } halfbyte_iterate_roads_end;
6646     }
6647   }
6648 
6649   if (game.server.foggedborders) {
6650     /* Load player map (border). */
6651     int x, y;
6652 
6653     for (y = 0; y < game.map.ysize; y++) {
6654       const char *buffer
6655         = secfile_lookup_str(loading->file, "player%d.map_owner%04d",
6656                              plrno, y);
6657       const char *buffer2
6658         = secfile_lookup_str(loading->file, "player%d.extras_owner%04d",
6659                              plrno, y);
6660       const char *ptr = buffer;
6661       const char *ptr2 = buffer2;
6662 
6663       sg_failure_ret(NULL != buffer,
6664                     "Savegame corrupt - map line %d not found.", y);
6665       for (x = 0; x < game.map.xsize; x++) {
6666         char token[TOKEN_SIZE];
6667         char token2[TOKEN_SIZE];
6668         int number;
6669         struct tile *ptile = native_pos_to_tile(x, y);
6670 
6671         scanin(&ptr, ",", token, sizeof(token));
6672         sg_failure_ret('\0' != token[0],
6673                        "Savegame corrupt - map size not correct.");
6674         if (strcmp(token, "-") == 0) {
6675           map_get_player_tile(ptile, plr)->owner = NULL;
6676         } else  {
6677           sg_failure_ret(str_to_int(token, &number),
6678                          "Savegame corrupt - got tile owner=%s in (%d, %d).",
6679                          token, x, y);
6680           map_get_player_tile(ptile, plr)->owner = player_by_number(number);
6681         }
6682 
6683         if (loading->version >= 30) {
6684           scanin(&ptr2, ",", token2, sizeof(token2));
6685           sg_failure_ret('\0' != token2[0],
6686                          "Savegame corrupt - map size not correct.");
6687           if (strcmp(token2, "-") == 0) {
6688             map_get_player_tile(ptile, plr)->extras_owner = NULL;
6689           } else  {
6690             sg_failure_ret(str_to_int(token2, &number),
6691                            "Savegame corrupt - got extras owner=%s in (%d, %d).",
6692                            token, x, y);
6693             map_get_player_tile(ptile, plr)->extras_owner = player_by_number(number);
6694           }
6695         } else {
6696           map_get_player_tile(ptile, plr)->extras_owner
6697             = map_get_player_tile(ptile, plr)->owner;
6698         }
6699       }
6700     }
6701   }
6702 
6703   /* Load player map (update time). */
6704   for (i = 0; i < 4; i++) {
6705     /* put 4-bit segments of 16-bit "updated" field */
6706     if (i == 0) {
6707       LOAD_MAP_CHAR(ch, ptile,
6708                     map_get_player_tile(ptile, plr)->last_updated
6709                       = ascii_hex2bin(ch, i),
6710                     loading->file, "player%d.map_u%02d_%04d", plrno, i);
6711     } else {
6712       LOAD_MAP_CHAR(ch, ptile,
6713                     map_get_player_tile(ptile, plr)->last_updated
6714                       |= ascii_hex2bin(ch, i),
6715                     loading->file, "player%d.map_u%02d_%04d", plrno, i);
6716     }
6717   }
6718 
6719   /* Load player map known cities. */
6720   for (i = 0; i < total_ncities; i++) {
6721     struct vision_site *pdcity;
6722     char buf[32];
6723     fc_snprintf(buf, sizeof(buf), "player%d.dc%d", plrno, i);
6724 
6725     pdcity = vision_site_new(0, NULL, NULL);
6726     if (sg_load_player_vision_city(loading, plr, pdcity, buf)) {
6727       change_playertile_site(map_get_player_tile(pdcity->location, plr),
6728                              pdcity);
6729       identity_number_reserve(pdcity->identity);
6730     } else {
6731       /* Error loading the data. */
6732       log_sg("Skipping seen city %d for player %d.", i, plrno);
6733       if (pdcity != NULL) {
6734         vision_site_destroy(pdcity);
6735       }
6736     }
6737   }
6738 
6739   /* Repair inconsistent player maps. */
6740   whole_map_iterate(ptile) {
6741     if (map_is_known_and_seen(ptile, plr, V_MAIN)) {
6742       struct city *pcity = tile_city(ptile);
6743 
6744       update_player_tile_knowledge(plr, ptile);
6745       reality_check_city(plr, ptile);
6746 
6747       if (NULL != pcity) {
6748         update_dumb_city(plr, pcity);
6749       }
6750     } else if (!game.server.foggedborders && map_is_known(ptile, plr)) {
6751       /* Non fogged borders aren't loaded. See hrm Bug #879084 */
6752       struct player_tile *plrtile = map_get_player_tile(ptile, plr);
6753 
6754       plrtile->owner = tile_owner(ptile);
6755     }
6756   } whole_map_iterate_end;
6757 }
6758 
6759 /****************************************************************************
6760   Load data for one seen city. sg_save_player_vision_city() is not defined.
6761 ****************************************************************************/
sg_load_player_vision_city(struct loaddata * loading,struct player * plr,struct vision_site * pdcity,const char * citystr)6762 static bool sg_load_player_vision_city(struct loaddata *loading,
6763                                        struct player *plr,
6764                                        struct vision_site *pdcity,
6765                                        const char *citystr)
6766 {
6767   const char *string;
6768   int i, id, size;
6769   citizens city_size;
6770   int nat_x, nat_y;
6771   const char *stylename;
6772 
6773   sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_x, "%s.x",
6774                                      citystr),
6775                   FALSE, "%s", secfile_error());
6776   sg_warn_ret_val(secfile_lookup_int(loading->file, &nat_y, "%s.y",
6777                                      citystr),
6778                   FALSE, "%s", secfile_error());
6779   pdcity->location = native_pos_to_tile(nat_x, nat_y);
6780   sg_warn_ret_val(NULL != pdcity->location, FALSE,
6781                   "%s invalid tile (%d,%d)", citystr, nat_x, nat_y);
6782 
6783   sg_warn_ret_val(secfile_lookup_int(loading->file, &id, "%s.owner",
6784                                      citystr),
6785                   FALSE, "%s", secfile_error());
6786   pdcity->owner = player_by_number(id);
6787   sg_warn_ret_val(NULL != pdcity->owner, FALSE,
6788                   "%s has invalid owner (%d); skipping.", citystr, id);
6789 
6790   sg_warn_ret_val(secfile_lookup_int(loading->file, &pdcity->identity,
6791                                      "%s.id", citystr),
6792                   FALSE, "%s", secfile_error());
6793   sg_warn_ret_val(IDENTITY_NUMBER_ZERO < pdcity->identity, FALSE,
6794                   "%s has invalid id (%d); skipping.", citystr, id);
6795 
6796   sg_warn_ret_val(secfile_lookup_int(loading->file, &size,
6797                                      "%s.size", citystr),
6798                   FALSE, "%s", secfile_error());
6799   city_size = (citizens)size; /* set the correct type */
6800   sg_warn_ret_val(size == (int)city_size, FALSE,
6801                   "Invalid city size: %d; set to %d.", size, city_size);
6802   vision_site_size_set(pdcity, city_size);
6803 
6804   /* Initialise list of improvements */
6805   BV_CLR_ALL(pdcity->improvements);
6806   string = secfile_lookup_str(loading->file, "%s.improvements", citystr);
6807   sg_warn_ret_val(string != NULL, FALSE, "%s", secfile_error());
6808   sg_warn_ret_val(strlen(string) == loading->improvement.size, FALSE,
6809                   "Invalid length of '%s.improvements' (%lu ~= %lu).",
6810                   citystr, (unsigned long) strlen(string),
6811                   (unsigned long) loading->improvement.size);
6812   for (i = 0; i < loading->improvement.size; i++) {
6813     sg_warn_ret_val(string[i] == '1' || string[i] == '0', FALSE,
6814                     "Undefined value '%c' within '%s.improvements'.",
6815                     string[i], citystr)
6816 
6817     if (string[i] == '1') {
6818       struct impr_type *pimprove =
6819           improvement_by_rule_name(loading->improvement.order[i]);
6820       if (pimprove) {
6821         BV_SET(pdcity->improvements, improvement_index(pimprove));
6822       }
6823     }
6824   }
6825 
6826   /* Use the section as backup name. */
6827   sz_strlcpy(pdcity->name, secfile_lookup_str_default(loading->file, citystr,
6828                                                       "%s.name", citystr));
6829 
6830   pdcity->occupied = secfile_lookup_bool_default(loading->file, FALSE,
6831                                                  "%s.occupied", citystr);
6832   pdcity->walls = secfile_lookup_bool_default(loading->file, FALSE,
6833                                               "%s.walls", citystr);
6834   pdcity->happy = secfile_lookup_bool_default(loading->file, FALSE,
6835                                               "%s.happy", citystr);
6836   pdcity->unhappy = secfile_lookup_bool_default(loading->file, FALSE,
6837                                                 "%s.unhappy", citystr);
6838   stylename = secfile_lookup_str_default(loading->file, NULL,
6839                                              "%s.style", citystr);
6840   if (stylename != NULL) {
6841     pdcity->style = city_style_by_rule_name(stylename);
6842   } else {
6843     pdcity->style = 0;
6844   }
6845   if (pdcity->style < 0) {
6846     pdcity->style = 0;
6847   }
6848 
6849   pdcity->city_image = secfile_lookup_int_default(loading->file, -100,
6850                                                   "%s.city_image", citystr);
6851 
6852   return TRUE;
6853 }
6854 
6855 /****************************************************************************
6856   Save vision data
6857 ****************************************************************************/
sg_save_player_vision(struct savedata * saving,struct player * plr)6858 static void sg_save_player_vision(struct savedata *saving,
6859                                   struct player *plr)
6860 {
6861   int i, plrno = player_number(plr);
6862 
6863   /* Check status and return if not OK (sg_success != TRUE). */
6864   sg_check_ret();
6865 
6866   if (!game.info.fogofwar || !game.server.save_options.save_private_map) {
6867     /* The player can see all, there's no reason to save the private map. */
6868     return;
6869   }
6870 
6871   if (!plr->is_alive) {
6872     /* Nothing to save. */
6873     return;
6874   }
6875 
6876   /* Save the map (terrain). */
6877   SAVE_MAP_CHAR(ptile,
6878                 terrain2char(map_get_player_tile(ptile, plr)->terrain),
6879                 saving->file, "player%d.map_t%04d", plrno);
6880 
6881   /* Save the map (resources). */
6882   SAVE_MAP_CHAR(ptile,
6883                 resource2char(map_get_player_tile(ptile, plr)->resource),
6884                 saving->file, "player%d.map_res%04d", plrno);
6885 
6886   if (game.server.foggedborders) {
6887     /* Save the map (borders). */
6888     int x, y;
6889 
6890     for (y = 0; y < game.map.ysize; y++) {
6891       char line[game.map.xsize * TOKEN_SIZE];
6892 
6893       line[0] = '\0';
6894       for (x = 0; x < game.map.xsize; x++) {
6895         char token[TOKEN_SIZE];
6896         struct tile *ptile = native_pos_to_tile(x, y);
6897         struct player_tile *plrtile = map_get_player_tile(ptile, plr);
6898 
6899         if (plrtile == NULL || plrtile->owner == NULL) {
6900           strcpy(token, "-");
6901         } else {
6902           fc_snprintf(token, sizeof(token), "%d",
6903                       player_number(plrtile->owner));
6904         }
6905         strcat(line, token);
6906         if (x < game.map.xsize) {
6907           strcat(line, ",");
6908         }
6909       }
6910       secfile_insert_str(saving->file, line, "player%d.map_owner%04d",
6911                          plrno, y);
6912     }
6913 
6914     for (y = 0; y < game.map.ysize; y++) {
6915       char line[game.map.xsize * TOKEN_SIZE];
6916 
6917       line[0] = '\0';
6918       for (x = 0; x < game.map.xsize; x++) {
6919         char token[TOKEN_SIZE];
6920         struct tile *ptile = native_pos_to_tile(x, y);
6921         struct player_tile *plrtile = map_get_player_tile(ptile, plr);
6922 
6923         if (plrtile == NULL || plrtile->extras_owner == NULL) {
6924           strcpy(token, "-");
6925         } else {
6926           fc_snprintf(token, sizeof(token), "%d",
6927                       player_number(plrtile->extras_owner));
6928         }
6929         strcat(line, token);
6930         if (x < game.map.xsize) {
6931           strcat(line, ",");
6932         }
6933       }
6934       secfile_insert_str(saving->file, line, "player%d.extras_owner%04d",
6935                          plrno, y);
6936     }
6937   }
6938 
6939   /* Save the map (extras). */
6940   halfbyte_iterate_extras(j, game.control.num_extra_types) {
6941     int mod[4];
6942     int l;
6943 
6944     for (l = 0; l < 4; l++) {
6945       if (4 * j + 1 > game.control.num_extra_types) {
6946         mod[l] = -1;
6947       } else {
6948         mod[l] = 4 * j + l;
6949       }
6950     }
6951 
6952     SAVE_MAP_CHAR(ptile,
6953                   sg_extras_get(map_get_player_tile(ptile, plr)->extras, mod),
6954                   saving->file, "player%d.map_e%02d_%04d", plrno, j);
6955   } halfbyte_iterate_extras_end;
6956 
6957   /* Save the map (update time). */
6958   for (i = 0; i < 4; i++) {
6959     /* put 4-bit segments of 16-bit "updated" field */
6960     SAVE_MAP_CHAR(ptile,
6961                   bin2ascii_hex(
6962                     map_get_player_tile(ptile, plr)->last_updated, i),
6963                   saving->file, "player%d.map_u%02d_%04d", plrno, i);
6964   }
6965 
6966   /* Save known cities. */
6967   i = 0;
6968   whole_map_iterate(ptile) {
6969     struct vision_site *pdcity = map_get_player_city(ptile, plr);
6970     char impr_buf[MAX_NUM_ITEMS + 1];
6971     char buf[32];
6972 
6973     fc_snprintf(buf, sizeof(buf), "player%d.dc%d", plrno, i);
6974 
6975     if (NULL != pdcity && plr != vision_site_owner(pdcity)) {
6976       int nat_x, nat_y;
6977 
6978       index_to_native_pos(&nat_x, &nat_y, tile_index(ptile));
6979       secfile_insert_int(saving->file, nat_y, "%s.y", buf);
6980       secfile_insert_int(saving->file, nat_x, "%s.x", buf);
6981 
6982       secfile_insert_int(saving->file, pdcity->identity, "%s.id", buf);
6983       secfile_insert_int(saving->file, player_number(vision_site_owner(pdcity)),
6984                          "%s.owner", buf);
6985 
6986       secfile_insert_int(saving->file, vision_site_size_get(pdcity),
6987                          "%s.size", buf);
6988       secfile_insert_bool(saving->file, pdcity->occupied,
6989                           "%s.occupied", buf);
6990       secfile_insert_bool(saving->file, pdcity->walls, "%s.walls", buf);
6991       secfile_insert_bool(saving->file, pdcity->happy, "%s.happy", buf);
6992       secfile_insert_bool(saving->file, pdcity->unhappy, "%s.unhappy", buf);
6993       secfile_insert_str(saving->file, city_style_rule_name(pdcity->style),
6994                          "%s.style", buf);
6995       secfile_insert_int(saving->file, pdcity->city_image, "%s.city_image", buf);
6996 
6997       /* Save improvement list as bitvector. Note that improvement order
6998        * is saved in savefile.improvement.order. */
6999       improvement_iterate(pimprove) {
7000         impr_buf[improvement_index(pimprove)]
7001           = BV_ISSET(pdcity->improvements, improvement_index(pimprove))
7002             ? '1' : '0';
7003       } improvement_iterate_end;
7004       impr_buf[improvement_count()] = '\0';
7005       sg_failure_ret(strlen(impr_buf) < sizeof(impr_buf),
7006                      "Invalid size of the improvement vector (%s.improvements: "
7007                      "%lu < %lu).", buf, (long unsigned int) strlen(impr_buf),
7008                      (long unsigned int) sizeof(impr_buf));
7009       secfile_insert_str(saving->file, impr_buf, "%s.improvements", buf);
7010       secfile_insert_str(saving->file, pdcity->name, "%s.name", buf);
7011 
7012       i++;
7013     }
7014   } whole_map_iterate_end;
7015 
7016   secfile_insert_int(saving->file, i, "player%d.dc_total", plrno);
7017 }
7018 
7019 /* =======================================================================
7020  * Load / save the researches.
7021  * ======================================================================= */
7022 
7023 /****************************************************************************
7024   Load '[research]'.
7025 ****************************************************************************/
sg_load_researches(struct loaddata * loading)7026 static void sg_load_researches(struct loaddata *loading)
7027 {
7028   struct research *presearch;
7029   int count;
7030   int number;
7031   const char *string;
7032   int i, j;
7033 
7034   /* Check status and return if not OK (sg_success != TRUE). */
7035   sg_check_ret();
7036 
7037   /* Initialize all researches. */
7038   researches_iterate(pinitres) {
7039     init_tech(pinitres, FALSE);
7040   } researches_iterate_end;
7041 
7042   /* May be unsaved (e.g. scenario case). */
7043   count = secfile_lookup_int_default(loading->file, 0, "research.count");
7044   for (i = 0; i < count; i++) {
7045     sg_failure_ret(secfile_lookup_int(loading->file, &number,
7046                                       "research.r%d.number", i),
7047                    "%s", secfile_error());
7048     presearch = research_by_number(number);
7049     sg_failure_ret(presearch != NULL,
7050                    "Invalid research number %d in 'research.r%d.number'",
7051                    number, i);
7052 
7053     presearch->tech_goal = technology_load(loading->file,
7054                                            "research.r%d.goal", i);
7055     sg_failure_ret(secfile_lookup_int(loading->file,
7056                                       &presearch->techs_researched,
7057                                       "research.r%d.techs", i),
7058                  "%s", secfile_error());
7059     sg_failure_ret(secfile_lookup_int(loading->file,
7060                                       &presearch->future_tech,
7061                                       "research.r%d.futuretech", i),
7062                    "%s", secfile_error());
7063     sg_failure_ret(secfile_lookup_int(loading->file,
7064                                       &presearch->bulbs_researched,
7065                                       "research.r%d.bulbs", i),
7066                    "%s", secfile_error());
7067     sg_failure_ret(secfile_lookup_int(loading->file,
7068                                       &presearch->bulbs_researching_saved,
7069                                       "research.r%d.bulbs_before", i),
7070                    "%s", secfile_error());
7071     presearch->researching_saved = technology_load(loading->file,
7072                                                    "research.r%d.saved", i);
7073     presearch->researching = technology_load(loading->file,
7074                                              "research.r%d.now", i);
7075     sg_failure_ret(secfile_lookup_bool(loading->file,
7076                                        &presearch->got_tech,
7077                                        "research.r%d.got_tech", i),
7078                    "%s", secfile_error());
7079 
7080     string = secfile_lookup_str(loading->file, "research.r%d.done",
7081                                 i);
7082     sg_failure_ret(string != NULL, "%s", secfile_error());
7083     sg_failure_ret(strlen(string) == loading->technology.size,
7084                    "Invalid length of 'research.r%d.done' (%lu ~= %lu).",
7085                    i, (unsigned long) strlen(string),
7086                    (unsigned long) loading->technology.size);
7087     for (j = 0; j < loading->technology.size; j++) {
7088       sg_failure_ret(string[j] == '1' || string[j] == '0',
7089                      "Undefined value '%c' within 'research.r%d.done'.",
7090                      string[j], i);
7091 
7092       if (string[j] == '1') {
7093         struct advance *padvance =
7094             advance_by_rule_name(loading->technology.order[j]);
7095 
7096         if (padvance) {
7097           research_invention_set(presearch, advance_number(padvance),
7098                                  TECH_KNOWN);
7099         }
7100       }
7101     }
7102   }
7103 
7104   /* In case of tech_leakage, we can update research only after all the
7105    * researches have been loaded */
7106   researches_iterate(pupres) {
7107     research_update(pupres);
7108   } researches_iterate_end;
7109 }
7110 
7111 /****************************************************************************
7112   Save '[research]'.
7113 ****************************************************************************/
sg_save_researches(struct savedata * saving)7114 static void sg_save_researches(struct savedata *saving)
7115 {
7116   char invs[A_LAST];
7117   int i = 0;
7118 
7119   /* Check status and return if not OK (sg_success != TRUE). */
7120   sg_check_ret();
7121 
7122   if (saving->save_players) {
7123     researches_iterate(presearch) {
7124       secfile_insert_int(saving->file, research_number(presearch),
7125                          "research.r%d.number", i);
7126       technology_save(saving->file, "research.r%d.goal",
7127                       i, presearch->tech_goal);
7128       secfile_insert_int(saving->file, presearch->techs_researched,
7129                          "research.r%d.techs", i);
7130       secfile_insert_int(saving->file, presearch->future_tech,
7131                          "research.r%d.futuretech", i);
7132       secfile_insert_int(saving->file, presearch->bulbs_researching_saved,
7133                          "research.r%d.bulbs_before", i);
7134       technology_save(saving->file, "research.r%d.saved",
7135                       i, presearch->researching_saved);
7136       secfile_insert_int(saving->file, presearch->bulbs_researched,
7137                          "research.r%d.bulbs", i);
7138       technology_save(saving->file, "research.r%d.now",
7139                       i, presearch->researching);
7140       secfile_insert_bool(saving->file, presearch->got_tech,
7141                           "research.r%d.got_tech", i);
7142       /* Save technology lists as bytevector. Note that technology order is
7143        * saved in savefile.technology.order */
7144       advance_index_iterate(A_NONE, tech_id) {
7145         invs[tech_id] = (research_invention_state(presearch, tech_id)
7146                          == TECH_KNOWN ? '1' : '0');
7147       } advance_index_iterate_end;
7148       invs[game.control.num_tech_types] = '\0';
7149       secfile_insert_str(saving->file, invs, "research.r%d.done", i);
7150       i++;
7151     } researches_iterate_end;
7152     secfile_insert_int(saving->file, i, "research.count");
7153   }
7154 }
7155 
7156 /* =======================================================================
7157  * Load / save the event cache. Should be the last thing to do.
7158  * ======================================================================= */
7159 
7160 /****************************************************************************
7161   Load '[event_cache]'.
7162 ****************************************************************************/
sg_load_event_cache(struct loaddata * loading)7163 static void sg_load_event_cache(struct loaddata *loading)
7164 {
7165   /* Check status and return if not OK (sg_success != TRUE). */
7166   sg_check_ret();
7167 
7168   event_cache_load(loading->file, "event_cache");
7169 }
7170 
7171 /****************************************************************************
7172   Save '[event_cache]'.
7173 ****************************************************************************/
sg_save_event_cache(struct savedata * saving)7174 static void sg_save_event_cache(struct savedata *saving)
7175 {
7176   /* Check status and return if not OK (sg_success != TRUE). */
7177   sg_check_ret();
7178 
7179   if (saving->scenario) {
7180     /* Do _not_ save events in a scenario. */
7181     return;
7182   }
7183 
7184   event_cache_save(saving->file, "event_cache");
7185 }
7186 
7187 /* =======================================================================
7188  * Load / save the open treaties
7189  * ======================================================================= */
7190 
7191 /****************************************************************************
7192   Load '[treaty_xxx]'.
7193 ****************************************************************************/
sg_load_treaties(struct loaddata * loading)7194 static void sg_load_treaties(struct loaddata *loading)
7195 {
7196   int tidx;
7197   const char *plr0;
7198   struct treaty_list *treaties = get_all_treaties();
7199 
7200   /* Check status and return if not OK (sg_success != TRUE). */
7201   sg_check_ret();
7202 
7203   for (tidx = 0; (plr0 = secfile_lookup_str_default(loading->file, NULL,
7204                                                     "treaty%d.plr0", tidx)) != NULL ;
7205        tidx++) {
7206     const char *plr1;
7207     const char *ct;
7208     int cidx;
7209     struct player *p0, *p1;
7210 
7211     plr1 = secfile_lookup_str(loading->file, "treaty%d.plr1", tidx);
7212 
7213     p0 = player_by_name(plr0);
7214     p1 = player_by_name(plr1);
7215 
7216     if (p0 == NULL || p1 == NULL) {
7217       log_error("Treaty between unknown players %s and %s", plr0, plr1);
7218     } else {
7219       struct Treaty *ptreaty = fc_malloc(sizeof(*ptreaty));
7220 
7221       init_treaty(ptreaty, p0, p1);
7222       treaty_list_prepend(treaties, ptreaty);
7223 
7224       for (cidx = 0; (ct = secfile_lookup_str_default(loading->file, NULL,
7225                                                       "treaty%d.clause%d.type",
7226                                                       tidx, cidx)) != NULL ;
7227            cidx++ ) {
7228         enum clause_type type = clause_type_by_name(ct, fc_strcasecmp);
7229         const char *plrx;
7230 
7231         if (!clause_type_is_valid(type)) {
7232           log_error("Invalid clause type \"%s\"", ct);
7233         } else {
7234           struct player *pgiver = NULL;
7235 
7236           plrx = secfile_lookup_str(loading->file, "treaty%d.clause%d.from",
7237                                     tidx, cidx);
7238 
7239           if (!fc_strcasecmp(plrx, plr0)) {
7240             pgiver = p0;
7241           } else if (!fc_strcasecmp(plrx, plr1)) {
7242             pgiver = p1;
7243           } else {
7244             log_error("Clause giver %s is not participant of the treaty"
7245                       "between %s and %s", plrx, plr0, plr1);
7246           }
7247 
7248           if (pgiver != NULL) {
7249             int value;
7250 
7251             value = secfile_lookup_int_default(loading->file, 0,
7252                                                "treaty%d.clause%d.value",
7253                                                tidx, cidx);
7254 
7255             add_clause(ptreaty, pgiver, type, value);
7256           }
7257         }
7258 
7259         /* These must be after clauses have been added so that acceptance
7260          * does not get cleared by what seems like changes to the treaty. */
7261         ptreaty->accept0 = secfile_lookup_bool_default(loading->file, FALSE,
7262                                                        "treaty%d.accept0", tidx);
7263         ptreaty->accept1 = secfile_lookup_bool_default(loading->file, FALSE,
7264                                                        "treaty%d.accept1", tidx);
7265       }
7266     }
7267   }
7268 }
7269 
7270 /****************************************************************************
7271   Save '[treaty_xxx]'.
7272 ****************************************************************************/
sg_save_treaties(struct savedata * saving)7273 static void sg_save_treaties(struct savedata *saving)
7274 {
7275   struct treaty_list *treaties = get_all_treaties();
7276   int tidx = 0;
7277 
7278   treaty_list_iterate(treaties, ptr) {
7279     char tpath[512];
7280     int cidx = 0;
7281 
7282     fc_snprintf(tpath, sizeof(tpath), "treaty%d", tidx++);
7283 
7284     secfile_insert_str(saving->file, player_name(ptr->plr0), "%s.plr0", tpath);
7285     secfile_insert_str(saving->file, player_name(ptr->plr1), "%s.plr1", tpath);
7286     secfile_insert_bool(saving->file, ptr->accept0, "%s.accept0", tpath);
7287     secfile_insert_bool(saving->file, ptr->accept1, "%s.accept1", tpath);
7288 
7289     clause_list_iterate(ptr->clauses, pclaus) {
7290       char cpath[512];
7291 
7292       fc_snprintf(cpath, sizeof(cpath), "%s.clause%d", tpath, cidx++);
7293 
7294       secfile_insert_str(saving->file, clause_type_name(pclaus->type), "%s.type", cpath);
7295       secfile_insert_str(saving->file, player_name(pclaus->from), "%s.from", cpath);
7296       secfile_insert_int(saving->file, pclaus->value, "%s.value", cpath);
7297     } clause_list_iterate_end;
7298   } treaty_list_iterate_end;
7299 }
7300 
7301 /* =======================================================================
7302  * Load / save the history report
7303  * ======================================================================= */
7304 
7305 /****************************************************************************
7306   Load '[history]'.
7307 ****************************************************************************/
sg_load_history(struct loaddata * loading)7308 static void sg_load_history(struct loaddata *loading)
7309 {
7310   struct history_report *hist = history_report_get();
7311   int turn;
7312 
7313   /* Check status and return if not OK (sg_success != TRUE). */
7314   sg_check_ret();
7315 
7316   turn = secfile_lookup_int_default(loading->file, -2, "history.turn");
7317 
7318   if (turn + 1 >= game.info.turn) {
7319     const char *str;
7320 
7321     hist->turn = turn;
7322     str = secfile_lookup_str(loading->file, "history.title");
7323     sg_failure_ret(str != NULL, "%s", secfile_error());
7324     sz_strlcpy(hist->title, str);
7325     str = secfile_lookup_str(loading->file, "history.body");
7326     sg_failure_ret(str != NULL, "%s", secfile_error());
7327     sz_strlcpy(hist->body, str);
7328   }
7329 }
7330 
7331 /****************************************************************************
7332   Save '[history]'.
7333 ****************************************************************************/
sg_save_history(struct savedata * saving)7334 static void sg_save_history(struct savedata *saving)
7335 {
7336   struct history_report *hist = history_report_get();
7337 
7338   secfile_insert_int(saving->file, hist->turn, "history.turn");
7339 
7340   if (hist->turn + 1 >= game.info.turn) {
7341     secfile_insert_str(saving->file, hist->title, "history.title");
7342     secfile_insert_str(saving->file, hist->body, "history.body");
7343   }
7344 }
7345 
7346 /* =======================================================================
7347  * Load / save the mapimg definitions.
7348  * ======================================================================= */
7349 
7350 /****************************************************************************
7351   Load '[mapimg]'.
7352 ****************************************************************************/
sg_load_mapimg(struct loaddata * loading)7353 static void sg_load_mapimg(struct loaddata *loading)
7354 {
7355   int mapdef_count, i;
7356 
7357   /* Check status and return if not OK (sg_success != TRUE). */
7358   sg_check_ret();
7359 
7360   /* Clear all defined map images. */
7361   while (mapimg_count() > 0) {
7362     mapimg_delete(0);
7363   }
7364 
7365   mapdef_count = secfile_lookup_int_default(loading->file, 0,
7366                                             "mapimg.count");
7367   log_verbose("Saved map image definitions: %d.", mapdef_count);
7368 
7369   if (0 >= mapdef_count) {
7370     return;
7371   }
7372 
7373   for (i = 0; i < mapdef_count; i++) {
7374     const char *p;
7375 
7376     p = secfile_lookup_str(loading->file, "mapimg.mapdef%d", i);
7377     if (NULL == p) {
7378       log_verbose("[Mapimg %4d] Missing definition.", i);
7379       continue;
7380     }
7381 
7382     if (!mapimg_define(p, FALSE)) {
7383       log_error("Invalid map image definition %4d: %s.", i, p);
7384     }
7385 
7386     log_verbose("Mapimg %4d loaded.", i);
7387   }
7388 }
7389 
7390 /****************************************************************************
7391   Save '[mapimg]'.
7392 ****************************************************************************/
sg_save_mapimg(struct savedata * saving)7393 static void sg_save_mapimg(struct savedata *saving)
7394 {
7395   /* Check status and return if not OK (sg_success != TRUE). */
7396   sg_check_ret();
7397 
7398   secfile_insert_int(saving->file, mapimg_count(), "mapimg.count");
7399   if (mapimg_count() > 0) {
7400     int i;
7401 
7402     for (i = 0; i < mapimg_count(); i++) {
7403       char buf[MAX_LEN_MAPDEF];
7404 
7405       mapimg_id2str(i, buf, sizeof(buf));
7406       secfile_insert_str(saving->file, buf, "mapimg.mapdef%d", i);
7407     }
7408   }
7409 }
7410 
7411 /* =======================================================================
7412  * Sanity checks for loading / saving a game.
7413  * ======================================================================= */
7414 
7415 /****************************************************************************
7416   Sanity check for loaded game.
7417 ****************************************************************************/
sg_load_sanitycheck(struct loaddata * loading)7418 static void sg_load_sanitycheck(struct loaddata *loading)
7419 {
7420   int players;
7421 
7422   /* Check status and return if not OK (sg_success != TRUE). */
7423   sg_check_ret();
7424 
7425   if (game.info.is_new_game) {
7426     /* Nothing to do for new games (or not started scenarios). */
7427     return;
7428   }
7429 
7430   /* Old savegames may have maxplayers lower than current player count,
7431    * fix. */
7432   players = normal_player_count();
7433   if (game.server.max_players < players) {
7434     log_verbose("Max players lower than current players, fixing");
7435     game.server.max_players = players;
7436   }
7437 
7438   /* Fix ferrying sanity */
7439   players_iterate(pplayer) {
7440     unit_list_iterate_safe(pplayer->units, punit) {
7441       if (!unit_transport_get(punit)
7442           && !can_unit_exist_at_tile(punit, unit_tile(punit))) {
7443         log_sg("Removing %s unferried %s in %s at (%d, %d)",
7444                nation_rule_name(nation_of_player(pplayer)),
7445                unit_rule_name(punit),
7446                terrain_rule_name(unit_tile(punit)->terrain),
7447                TILE_XY(unit_tile(punit)));
7448         bounce_unit(punit, TRUE);
7449       }
7450     } unit_list_iterate_safe_end;
7451   } players_iterate_end;
7452 
7453   /* Fix stacking issues.  We don't rely on the savegame preserving
7454    * alliance invariants (old savegames often did not) so if there are any
7455    * unallied units on the same tile we just bounce them. */
7456   players_iterate(pplayer) {
7457     players_iterate(aplayer) {
7458       resolve_unit_stacks(pplayer, aplayer, TRUE);
7459     } players_iterate_end;
7460 
7461     /* Backward compatibility: if we had any open-ended orders (pillage)
7462      * in the savegame, assign specific targets now */
7463     unit_list_iterate(pplayer->units, punit) {
7464       unit_assign_specific_activity_target(punit,
7465                                            &punit->activity,
7466                                            &punit->activity_target);
7467     } unit_list_iterate_end;
7468   } players_iterate_end;
7469 
7470   /* Recalculate the potential buildings for each city. Has caused some
7471    * problems with game random state.
7472    * This also changes the game state if you save the game directly after
7473    * loading it and compare the results. */
7474   players_iterate(pplayer) {
7475     bool saved_ai_control = pplayer->ai_controlled;
7476 
7477     /* Recalculate for all players. */
7478     pplayer->ai_controlled = FALSE;
7479 
7480     /* Building advisor needs data phase open in order to work */
7481     adv_data_phase_init(pplayer, FALSE);
7482     building_advisor(pplayer);
7483     /* Close data phase again so it can be opened again when game starts. */
7484     adv_data_phase_done(pplayer);
7485 
7486     pplayer->ai_controlled = saved_ai_control;
7487   } players_iterate_end;
7488 
7489   /* Prevent a buggy or intentionally crafted save game from crashing
7490    * Freeciv. See hrm Bug #887748 */
7491   players_iterate(pplayer) {
7492     city_list_iterate(pplayer->cities, pcity) {
7493       worker_task_list_iterate(pcity->task_reqs, ptask) {
7494         if (!worker_task_is_sane(ptask)) {
7495           log_error("[city id: %d] Bad worker task %d.",
7496                     pcity->id, ptask->act);
7497           worker_task_list_remove(pcity->task_reqs, ptask);
7498           free(ptask);
7499           ptask = NULL;
7500         }
7501       } worker_task_list_iterate_end;
7502     } city_list_iterate_end;
7503   } players_iterate_end;
7504 
7505   /* Check worked tiles map */
7506 #ifdef DEBUG
7507   if (loading->worked_tiles != NULL) {
7508     /* check the entire map for unused worked tiles */
7509     whole_map_iterate(ptile) {
7510       if (loading->worked_tiles[ptile->index] != -1) {
7511         log_error("[city id: %d] Unused worked tile at (%d, %d).",
7512                   loading->worked_tiles[ptile->index], TILE_XY(ptile));
7513       }
7514     } whole_map_iterate_end;
7515   }
7516 #endif /* DEBUG */
7517 
7518   /* Check researching technologies and goals. */
7519   researches_iterate(presearch) {
7520     if (presearch->researching != A_UNSET
7521         && !is_future_tech(presearch->researching)
7522         && (valid_advance_by_number(presearch->researching) == NULL
7523             || (research_invention_state(presearch, presearch->researching)
7524                 != TECH_PREREQS_KNOWN))) {
7525       log_sg(_("%s had invalid researching technology."),
7526              research_name_translation(presearch));
7527       presearch->researching = A_UNSET;
7528     }
7529     if (presearch->tech_goal != A_UNSET
7530         && !is_future_tech(presearch->tech_goal)
7531         && (valid_advance_by_number(presearch->tech_goal) == NULL
7532             || !research_invention_reachable(presearch, presearch->tech_goal)
7533             || (research_invention_state(presearch, presearch->tech_goal)
7534                 == TECH_KNOWN))) {
7535       log_sg(_("%s had invalid technology goal."),
7536              research_name_translation(presearch));
7537       presearch->tech_goal = A_UNSET;
7538     }
7539   } researches_iterate_end;
7540 
7541   if (0 == strlen(server.game_identifier)
7542       || !is_base64url(server.game_identifier)) {
7543     /* This uses fc_rand(), so random state has to be initialized before. */
7544     randomize_base64url_string(server.game_identifier,
7545                                sizeof(server.game_identifier));
7546   }
7547 
7548   /* Check if some player has more than one of some UTYF_UNIQUE unit type */
7549   players_iterate(pplayer) {
7550     int unique_count[U_LAST];
7551 
7552     memset(unique_count, 0, sizeof(unique_count));
7553 
7554     unit_list_iterate(pplayer->units, punit) {
7555       unique_count[utype_index(unit_type_get(punit))]++;
7556     } unit_list_iterate_end;
7557 
7558     unit_type_iterate(ut) {
7559       if (unique_count[utype_index(ut)] > 1 && utype_has_flag(ut, UTYF_UNIQUE)) {
7560         log_sg(_("%s has multiple units of type %s though it should be possible "
7561                  "to have only one."),
7562                player_name(pplayer), utype_name_translation(ut));
7563       }
7564     } unit_type_iterate_end;
7565   } players_iterate_end;
7566 
7567   /* Restore game random state, just in case various initialization code
7568    * inexplicably altered the previously existing state. */
7569   if (!game.info.is_new_game) {
7570     fc_rand_set_state(loading->rstate);
7571 
7572     if (loading->version < 30) {
7573       /* For older savegames we have to recalculate the score with current data,
7574        * instead of using beginning-of-turn saved scores. */
7575       players_iterate(pplayer) {
7576         calc_civ_score(pplayer);
7577       } players_iterate_end;
7578     }
7579   }
7580 
7581   /* At the end do the default sanity checks. */
7582   sanity_check();
7583 }
7584 
7585 /****************************************************************************
7586   Sanity check for saved game.
7587 ****************************************************************************/
sg_save_sanitycheck(struct savedata * saving)7588 static void sg_save_sanitycheck(struct savedata *saving)
7589 {
7590   /* Check status and return if not OK (sg_success != TRUE). */
7591   sg_check_ret();
7592 }
7593