OpenTTD
saveload.cpp
Go to the documentation of this file.
1 /* $Id: saveload.cpp 27709 2016-12-25 13:26:15Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8  */
9 
24 #include "../stdafx.h"
25 #include "../debug.h"
26 #include "../station_base.h"
27 #include "../thread/thread.h"
28 #include "../town.h"
29 #include "../network/network.h"
30 #include "../window_func.h"
31 #include "../strings_func.h"
32 #include "../core/endian_func.hpp"
33 #include "../vehicle_base.h"
34 #include "../company_func.h"
35 #include "../date_func.h"
36 #include "../autoreplace_base.h"
37 #include "../roadstop_base.h"
38 #include "../linkgraph/linkgraph.h"
39 #include "../linkgraph/linkgraphjob.h"
40 #include "../statusbar_gui.h"
41 #include "../fileio_func.h"
42 #include "../gamelog.h"
43 #include "../string_func.h"
44 #include "../fios.h"
45 #include "../error.h"
46 
47 #include "table/strings.h"
48 
49 #include "saveload_internal.h"
50 #include "saveload_filter.h"
51 
52 #include "../safeguards.h"
53 
54 /*
55  * Previous savegame versions, the trunk revision where they were
56  * introduced and the released version that had that particular
57  * savegame version.
58  * Up to savegame version 18 there is a minor version as well.
59  *
60  * 1.0 0.1.x, 0.2.x
61  * 2.0 0.3.0
62  * 2.1 0.3.1, 0.3.2
63  * 3.x lost
64  * 4.0 1
65  * 4.1 122 0.3.3, 0.3.4
66  * 4.2 1222 0.3.5
67  * 4.3 1417
68  * 4.4 1426
69  * 5.0 1429
70  * 5.1 1440
71  * 5.2 1525 0.3.6
72  * 6.0 1721
73  * 6.1 1768
74  * 7.0 1770
75  * 8.0 1786
76  * 9.0 1909
77  * 10.0 2030
78  * 11.0 2033
79  * 11.1 2041
80  * 12.1 2046
81  * 13.1 2080 0.4.0, 0.4.0.1
82  * 14.0 2441
83  * 15.0 2499
84  * 16.0 2817
85  * 16.1 3155
86  * 17.0 3212
87  * 17.1 3218
88  * 18 3227
89  * 19 3396
90  * 20 3403
91  * 21 3472 0.4.x
92  * 22 3726
93  * 23 3915
94  * 24 4150
95  * 25 4259
96  * 26 4466
97  * 27 4757
98  * 28 4987
99  * 29 5070
100  * 30 5946
101  * 31 5999
102  * 32 6001
103  * 33 6440
104  * 34 6455
105  * 35 6602
106  * 36 6624
107  * 37 7182
108  * 38 7195
109  * 39 7269
110  * 40 7326
111  * 41 7348 0.5.x
112  * 42 7573
113  * 43 7642
114  * 44 8144
115  * 45 8501
116  * 46 8705
117  * 47 8735
118  * 48 8935
119  * 49 8969
120  * 50 8973
121  * 51 8978
122  * 52 9066
123  * 53 9316
124  * 54 9613
125  * 55 9638
126  * 56 9667
127  * 57 9691
128  * 58 9762
129  * 59 9779
130  * 60 9874
131  * 61 9892
132  * 62 9905
133  * 63 9956
134  * 64 10006
135  * 65 10210
136  * 66 10211
137  * 67 10236
138  * 68 10266
139  * 69 10319
140  * 70 10541
141  * 71 10567
142  * 72 10601
143  * 73 10903
144  * 74 11030
145  * 75 11107
146  * 76 11139
147  * 77 11172
148  * 78 11176
149  * 79 11188
150  * 80 11228
151  * 81 11244
152  * 82 11410
153  * 83 11589
154  * 84 11822
155  * 85 11874
156  * 86 12042
157  * 87 12129
158  * 88 12134
159  * 89 12160
160  * 90 12293
161  * 91 12347
162  * 92 12381 0.6.x
163  * 93 12648
164  * 94 12816
165  * 95 12924
166  * 96 13226
167  * 97 13256
168  * 98 13375
169  * 99 13838
170  * 100 13952
171  * 101 14233
172  * 102 14332
173  * 103 14598
174  * 104 14735
175  * 105 14803
176  * 106 14919
177  * 107 15027
178  * 108 15045
179  * 109 15075
180  * 110 15148
181  * 111 15190
182  * 112 15290
183  * 113 15340
184  * 114 15601
185  * 115 15695
186  * 116 15893 0.7.x
187  * 117 16037
188  * 118 16129
189  * 119 16242
190  * 120 16439
191  * 121 16694
192  * 122 16855
193  * 123 16909
194  * 124 16993
195  * 125 17113
196  * 126 17433
197  * 127 17439
198  * 128 18281
199  * 129 18292
200  * 130 18404
201  * 131 18481
202  * 132 18522
203  * 133 18674
204  * 134 18703
205  * 135 18719
206  * 136 18764
207  * 137 18912
208  * 138 18942 1.0.x
209  * 139 19346
210  * 140 19382
211  * 141 19799
212  * 142 20003
213  * 143 20048
214  * 144 20334
215  * 145 20376
216  * 146 20446
217  * 147 20621
218  * 148 20659
219  * 149 20832
220  * 150 20857
221  * 151 20918
222  * 152 21171
223  * 153 21263
224  * 154 21426
225  * 155 21453
226  * 156 21728
227  * 157 21862
228  * 158 21933
229  * 159 21962
230  * 160 21974 1.1.x
231  * 161 22567
232  * 162 22713
233  * 163 22767
234  * 164 23290
235  * 165 23304
236  * 166 23415
237  * 167 23504
238  * 168 23637
239  * 169 23816
240  * 170 23826
241  * 171 23835
242  * 172 23947
243  * 173 23967 1.2.0-RC1
244  * 174 23973 1.2.x
245  * 175 24136
246  * 176 24446
247  * 177 24619
248  * 178 24789
249  * 179 24810
250  * 180 24998 1.3.x
251  * 181 25012
252  * 182 25296
253  * 183 25363
254  * 184 25508
255  * 185 25620
256  * 186 25833
257  * 187 25899
258  * 188 26169 1.4.x
259  * 189 26450
260  * 190 26547
261  * 191 26646
262  * 192 26700
263  * 193 26802
264  * 194 26881 1.5.x, 1.6.0
265  * 195 27572 1.6.x
266  */
267 extern const uint16 SAVEGAME_VERSION = 195;
268 
271 
273 uint16 _sl_version;
277 
285 };
286 
288  NL_NONE = 0,
291 };
292 
294 static const size_t MEMORY_CHUNK_SIZE = 128 * 1024;
295 
297 struct ReadBuffer {
299  byte *bufp;
300  byte *bufe;
302  size_t read;
303 
308  ReadBuffer(LoadFilter *reader) : bufp(NULL), bufe(NULL), reader(reader), read(0)
309  {
310  }
311 
312  inline byte ReadByte()
313  {
314  if (this->bufp == this->bufe) {
315  size_t len = this->reader->Read(this->buf, lengthof(this->buf));
316  if (len == 0) SlErrorCorrupt("Unexpected end of chunk");
317 
318  this->read += len;
319  this->bufp = this->buf;
320  this->bufe = this->buf + len;
321  }
322 
323  return *this->bufp++;
324  }
325 
330  size_t GetSize() const
331  {
332  return this->read - (this->bufe - this->bufp);
333  }
334 };
335 
336 
338 struct MemoryDumper {
340  byte *buf;
341  byte *bufe;
342 
344  MemoryDumper() : buf(NULL), bufe(NULL)
345  {
346  }
347 
352  inline void WriteByte(byte b)
353  {
354  /* Are we at the end of this chunk? */
355  if (this->buf == this->bufe) {
356  this->buf = CallocT<byte>(MEMORY_CHUNK_SIZE);
357  *this->blocks.Append() = this->buf;
358  this->bufe = this->buf + MEMORY_CHUNK_SIZE;
359  }
360 
361  *this->buf++ = b;
362  }
363 
368  void Flush(SaveFilter *writer)
369  {
370  uint i = 0;
371  size_t t = this->GetSize();
372 
373  while (t > 0) {
374  size_t to_write = min(MEMORY_CHUNK_SIZE, t);
375 
376  writer->Write(this->blocks[i++], to_write);
377  t -= to_write;
378  }
379 
380  writer->Finish();
381  }
382 
387  size_t GetSize() const
388  {
389  return this->blocks.Length() * MEMORY_CHUNK_SIZE - (this->bufe - this->buf);
390  }
391 };
392 
397  byte block_mode;
398  bool error;
399 
400  size_t obj_len;
401  int array_index, last_array_index;
402 
405 
408 
410  char *extra_msg;
411 
412  byte ff_state;
414 };
415 
417 
418 /* these define the chunks */
419 extern const ChunkHandler _gamelog_chunk_handlers[];
420 extern const ChunkHandler _map_chunk_handlers[];
421 extern const ChunkHandler _misc_chunk_handlers[];
422 extern const ChunkHandler _name_chunk_handlers[];
423 extern const ChunkHandler _cheat_chunk_handlers[] ;
424 extern const ChunkHandler _setting_chunk_handlers[];
425 extern const ChunkHandler _company_chunk_handlers[];
426 extern const ChunkHandler _engine_chunk_handlers[];
427 extern const ChunkHandler _veh_chunk_handlers[];
428 extern const ChunkHandler _waypoint_chunk_handlers[];
429 extern const ChunkHandler _depot_chunk_handlers[];
430 extern const ChunkHandler _order_chunk_handlers[];
431 extern const ChunkHandler _town_chunk_handlers[];
432 extern const ChunkHandler _sign_chunk_handlers[];
433 extern const ChunkHandler _station_chunk_handlers[];
434 extern const ChunkHandler _industry_chunk_handlers[];
435 extern const ChunkHandler _economy_chunk_handlers[];
436 extern const ChunkHandler _subsidy_chunk_handlers[];
438 extern const ChunkHandler _goal_chunk_handlers[];
439 extern const ChunkHandler _story_page_chunk_handlers[];
440 extern const ChunkHandler _ai_chunk_handlers[];
441 extern const ChunkHandler _game_chunk_handlers[];
443 extern const ChunkHandler _newgrf_chunk_handlers[];
444 extern const ChunkHandler _group_chunk_handlers[];
446 extern const ChunkHandler _autoreplace_chunk_handlers[];
447 extern const ChunkHandler _labelmaps_chunk_handlers[];
448 extern const ChunkHandler _linkgraph_chunk_handlers[];
449 extern const ChunkHandler _airport_chunk_handlers[];
450 extern const ChunkHandler _object_chunk_handlers[];
451 extern const ChunkHandler _persistent_storage_chunk_handlers[];
452 
454 static const ChunkHandler * const _chunk_handlers[] = {
455  _gamelog_chunk_handlers,
456  _map_chunk_handlers,
457  _misc_chunk_handlers,
458  _name_chunk_handlers,
459  _cheat_chunk_handlers,
460  _setting_chunk_handlers,
461  _veh_chunk_handlers,
462  _waypoint_chunk_handlers,
463  _depot_chunk_handlers,
464  _order_chunk_handlers,
465  _industry_chunk_handlers,
466  _economy_chunk_handlers,
467  _subsidy_chunk_handlers,
468  _cargomonitor_chunk_handlers,
469  _goal_chunk_handlers,
470  _story_page_chunk_handlers,
471  _engine_chunk_handlers,
472  _town_chunk_handlers,
473  _sign_chunk_handlers,
474  _station_chunk_handlers,
475  _company_chunk_handlers,
476  _ai_chunk_handlers,
477  _game_chunk_handlers,
478  _animated_tile_chunk_handlers,
479  _newgrf_chunk_handlers,
480  _group_chunk_handlers,
481  _cargopacket_chunk_handlers,
482  _autoreplace_chunk_handlers,
483  _labelmaps_chunk_handlers,
484  _linkgraph_chunk_handlers,
485  _airport_chunk_handlers,
486  _object_chunk_handlers,
487  _persistent_storage_chunk_handlers,
488  NULL,
489 };
490 
495 #define FOR_ALL_CHUNK_HANDLERS(ch) \
496  for (const ChunkHandler * const *chsc = _chunk_handlers; *chsc != NULL; chsc++) \
497  for (const ChunkHandler *ch = *chsc; ch != NULL; ch = (ch->flags & CH_LAST) ? NULL : ch + 1)
498 
500 static void SlNullPointers()
501 {
502  _sl.action = SLA_NULL;
503 
504  /* We don't want any savegame conversion code to run
505  * during NULLing; especially those that try to get
506  * pointers from other pools. */
508 
509  DEBUG(sl, 1, "Nulling pointers");
510 
512  if (ch->ptrs_proc != NULL) {
513  DEBUG(sl, 2, "Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
514  ch->ptrs_proc();
515  }
516  }
517 
518  DEBUG(sl, 1, "All pointers nulled");
519 
520  assert(_sl.action == SLA_NULL);
521 }
522 
531 void NORETURN SlError(StringID string, const char *extra_msg)
532 {
533  /* Distinguish between loading into _load_check_data vs. normal save/load. */
534  if (_sl.action == SLA_LOAD_CHECK) {
535  _load_check_data.error = string;
537  _load_check_data.error_data = (extra_msg == NULL) ? NULL : stredup(extra_msg);
538  } else {
539  _sl.error_str = string;
540  free(_sl.extra_msg);
541  _sl.extra_msg = (extra_msg == NULL) ? NULL : stredup(extra_msg);
542  }
543 
544  /* We have to NULL all pointers here; we might be in a state where
545  * the pointers are actually filled with indices, which means that
546  * when we access them during cleaning the pool dereferences of
547  * those indices will be made with segmentation faults as result. */
548  if (_sl.action == SLA_LOAD || _sl.action == SLA_PTRS) SlNullPointers();
549  throw std::exception();
550 }
551 
559 void NORETURN SlErrorCorrupt(const char *msg)
560 {
561  SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, msg);
562 }
563 
564 
565 typedef void (*AsyncSaveFinishProc)();
568 
574 {
575  if (_exit_game) return;
576  while (_async_save_finish != NULL) CSleep(10);
577 
578  _async_save_finish = proc;
579 }
580 
585 {
586  if (_async_save_finish == NULL) return;
587 
589 
590  _async_save_finish = NULL;
591 
592  if (_save_thread != NULL) {
593  _save_thread->Join();
594  delete _save_thread;
595  _save_thread = NULL;
596  }
597 }
598 
604 {
605  return _sl.reader->ReadByte();
606 }
607 
612 void SlWriteByte(byte b)
613 {
614  _sl.dumper->WriteByte(b);
615 }
616 
617 static inline int SlReadUint16()
618 {
619  int x = SlReadByte() << 8;
620  return x | SlReadByte();
621 }
622 
623 static inline uint32 SlReadUint32()
624 {
625  uint32 x = SlReadUint16() << 16;
626  return x | SlReadUint16();
627 }
628 
629 static inline uint64 SlReadUint64()
630 {
631  uint32 x = SlReadUint32();
632  uint32 y = SlReadUint32();
633  return (uint64)x << 32 | y;
634 }
635 
636 static inline void SlWriteUint16(uint16 v)
637 {
638  SlWriteByte(GB(v, 8, 8));
639  SlWriteByte(GB(v, 0, 8));
640 }
641 
642 static inline void SlWriteUint32(uint32 v)
643 {
644  SlWriteUint16(GB(v, 16, 16));
645  SlWriteUint16(GB(v, 0, 16));
646 }
647 
648 static inline void SlWriteUint64(uint64 x)
649 {
650  SlWriteUint32((uint32)(x >> 32));
651  SlWriteUint32((uint32)x);
652 }
653 
659 static inline void SlSkipBytes(size_t length)
660 {
661  for (; length != 0; length--) SlReadByte();
662 }
663 
673 static uint SlReadSimpleGamma()
674 {
675  uint i = SlReadByte();
676  if (HasBit(i, 7)) {
677  i &= ~0x80;
678  if (HasBit(i, 6)) {
679  i &= ~0x40;
680  if (HasBit(i, 5)) {
681  i &= ~0x20;
682  if (HasBit(i, 4)) {
683  i &= ~0x10;
684  if (HasBit(i, 3)) {
685  SlErrorCorrupt("Unsupported gamma");
686  }
687  i = SlReadByte(); // 32 bits only.
688  }
689  i = (i << 8) | SlReadByte();
690  }
691  i = (i << 8) | SlReadByte();
692  }
693  i = (i << 8) | SlReadByte();
694  }
695  return i;
696 }
697 
715 static void SlWriteSimpleGamma(size_t i)
716 {
717  if (i >= (1 << 7)) {
718  if (i >= (1 << 14)) {
719  if (i >= (1 << 21)) {
720  if (i >= (1 << 28)) {
721  assert(i <= UINT32_MAX); // We can only support 32 bits for now.
722  SlWriteByte((byte)(0xF0));
723  SlWriteByte((byte)(i >> 24));
724  } else {
725  SlWriteByte((byte)(0xE0 | (i >> 24)));
726  }
727  SlWriteByte((byte)(i >> 16));
728  } else {
729  SlWriteByte((byte)(0xC0 | (i >> 16)));
730  }
731  SlWriteByte((byte)(i >> 8));
732  } else {
733  SlWriteByte((byte)(0x80 | (i >> 8)));
734  }
735  }
736  SlWriteByte((byte)i);
737 }
738 
740 static inline uint SlGetGammaLength(size_t i)
741 {
742  return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21)) + (i >= (1 << 28));
743 }
744 
745 static inline uint SlReadSparseIndex()
746 {
747  return SlReadSimpleGamma();
748 }
749 
750 static inline void SlWriteSparseIndex(uint index)
751 {
752  SlWriteSimpleGamma(index);
753 }
754 
755 static inline uint SlReadArrayLength()
756 {
757  return SlReadSimpleGamma();
758 }
759 
760 static inline void SlWriteArrayLength(size_t length)
761 {
762  SlWriteSimpleGamma(length);
763 }
764 
765 static inline uint SlGetArrayLength(size_t length)
766 {
767  return SlGetGammaLength(length);
768 }
769 
776 static inline uint SlCalcConvMemLen(VarType conv)
777 {
778  static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
779  byte length = GB(conv, 4, 4);
780 
781  switch (length << 4) {
782  case SLE_VAR_STRB:
783  case SLE_VAR_STRBQ:
784  case SLE_VAR_STR:
785  case SLE_VAR_STRQ:
786  return SlReadArrayLength();
787 
788  default:
789  assert(length < lengthof(conv_mem_size));
790  return conv_mem_size[length];
791  }
792 }
793 
800 static inline byte SlCalcConvFileLen(VarType conv)
801 {
802  static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
803  byte length = GB(conv, 0, 4);
804  assert(length < lengthof(conv_file_size));
805  return conv_file_size[length];
806 }
807 
809 static inline size_t SlCalcRefLen()
810 {
811  return IsSavegameVersionBefore(69) ? 2 : 4;
812 }
813 
814 void SlSetArrayIndex(uint index)
815 {
817  _sl.array_index = index;
818 }
819 
820 static size_t _next_offs;
821 
827 {
828  int index;
829 
830  /* After reading in the whole array inside the loop
831  * we must have read in all the data, so we must be at end of current block. */
832  if (_next_offs != 0 && _sl.reader->GetSize() != _next_offs) SlErrorCorrupt("Invalid chunk size");
833 
834  for (;;) {
835  uint length = SlReadArrayLength();
836  if (length == 0) {
837  _next_offs = 0;
838  return -1;
839  }
840 
841  _sl.obj_len = --length;
842  _next_offs = _sl.reader->GetSize() + length;
843 
844  switch (_sl.block_mode) {
845  case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break;
846  case CH_ARRAY: index = _sl.array_index++; break;
847  default:
848  DEBUG(sl, 0, "SlIterateArray error");
849  return -1; // error
850  }
851 
852  if (length != 0) return index;
853  }
854 }
855 
860 {
861  while (SlIterateArray() != -1) {
862  SlSkipBytes(_next_offs - _sl.reader->GetSize());
863  }
864 }
865 
871 void SlSetLength(size_t length)
872 {
873  assert(_sl.action == SLA_SAVE);
874 
875  switch (_sl.need_length) {
876  case NL_WANTLENGTH:
877  _sl.need_length = NL_NONE;
878  switch (_sl.block_mode) {
879  case CH_RIFF:
880  /* Ugly encoding of >16M RIFF chunks
881  * The lower 24 bits are normal
882  * The uppermost 4 bits are bits 24:27 */
883  assert(length < (1 << 28));
884  SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
885  break;
886  case CH_ARRAY:
887  assert(_sl.last_array_index <= _sl.array_index);
888  while (++_sl.last_array_index <= _sl.array_index) {
889  SlWriteArrayLength(1);
890  }
891  SlWriteArrayLength(length + 1);
892  break;
893  case CH_SPARSE_ARRAY:
894  SlWriteArrayLength(length + 1 + SlGetArrayLength(_sl.array_index)); // Also include length of sparse index.
895  SlWriteSparseIndex(_sl.array_index);
896  break;
897  default: NOT_REACHED();
898  }
899  break;
900 
901  case NL_CALCLENGTH:
902  _sl.obj_len += (int)length;
903  break;
904 
905  default: NOT_REACHED();
906  }
907 }
908 
915 static void SlCopyBytes(void *ptr, size_t length)
916 {
917  byte *p = (byte *)ptr;
918 
919  switch (_sl.action) {
920  case SLA_LOAD_CHECK:
921  case SLA_LOAD:
922  for (; length != 0; length--) *p++ = SlReadByte();
923  break;
924  case SLA_SAVE:
925  for (; length != 0; length--) SlWriteByte(*p++);
926  break;
927  default: NOT_REACHED();
928  }
929 }
930 
933 {
934  return _sl.obj_len;
935 }
936 
944 int64 ReadValue(const void *ptr, VarType conv)
945 {
946  switch (GetVarMemType(conv)) {
947  case SLE_VAR_BL: return (*(const bool *)ptr != 0);
948  case SLE_VAR_I8: return *(const int8 *)ptr;
949  case SLE_VAR_U8: return *(const byte *)ptr;
950  case SLE_VAR_I16: return *(const int16 *)ptr;
951  case SLE_VAR_U16: return *(const uint16*)ptr;
952  case SLE_VAR_I32: return *(const int32 *)ptr;
953  case SLE_VAR_U32: return *(const uint32*)ptr;
954  case SLE_VAR_I64: return *(const int64 *)ptr;
955  case SLE_VAR_U64: return *(const uint64*)ptr;
956  case SLE_VAR_NULL:return 0;
957  default: NOT_REACHED();
958  }
959 }
960 
968 void WriteValue(void *ptr, VarType conv, int64 val)
969 {
970  switch (GetVarMemType(conv)) {
971  case SLE_VAR_BL: *(bool *)ptr = (val != 0); break;
972  case SLE_VAR_I8: *(int8 *)ptr = val; break;
973  case SLE_VAR_U8: *(byte *)ptr = val; break;
974  case SLE_VAR_I16: *(int16 *)ptr = val; break;
975  case SLE_VAR_U16: *(uint16*)ptr = val; break;
976  case SLE_VAR_I32: *(int32 *)ptr = val; break;
977  case SLE_VAR_U32: *(uint32*)ptr = val; break;
978  case SLE_VAR_I64: *(int64 *)ptr = val; break;
979  case SLE_VAR_U64: *(uint64*)ptr = val; break;
980  case SLE_VAR_NAME: *(char**)ptr = CopyFromOldName(val); break;
981  case SLE_VAR_NULL: break;
982  default: NOT_REACHED();
983  }
984 }
985 
994 static void SlSaveLoadConv(void *ptr, VarType conv)
995 {
996  switch (_sl.action) {
997  case SLA_SAVE: {
998  int64 x = ReadValue(ptr, conv);
999 
1000  /* Write the value to the file and check if its value is in the desired range */
1001  switch (GetVarFileType(conv)) {
1002  case SLE_FILE_I8: assert(x >= -128 && x <= 127); SlWriteByte(x);break;
1003  case SLE_FILE_U8: assert(x >= 0 && x <= 255); SlWriteByte(x);break;
1004  case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);break;
1005  case SLE_FILE_STRINGID:
1006  case SLE_FILE_U16:assert(x >= 0 && x <= 65535); SlWriteUint16(x);break;
1007  case SLE_FILE_I32:
1008  case SLE_FILE_U32: SlWriteUint32((uint32)x);break;
1009  case SLE_FILE_I64:
1010  case SLE_FILE_U64: SlWriteUint64(x);break;
1011  default: NOT_REACHED();
1012  }
1013  break;
1014  }
1015  case SLA_LOAD_CHECK:
1016  case SLA_LOAD: {
1017  int64 x;
1018  /* Read a value from the file */
1019  switch (GetVarFileType(conv)) {
1020  case SLE_FILE_I8: x = (int8 )SlReadByte(); break;
1021  case SLE_FILE_U8: x = (byte )SlReadByte(); break;
1022  case SLE_FILE_I16: x = (int16 )SlReadUint16(); break;
1023  case SLE_FILE_U16: x = (uint16)SlReadUint16(); break;
1024  case SLE_FILE_I32: x = (int32 )SlReadUint32(); break;
1025  case SLE_FILE_U32: x = (uint32)SlReadUint32(); break;
1026  case SLE_FILE_I64: x = (int64 )SlReadUint64(); break;
1027  case SLE_FILE_U64: x = (uint64)SlReadUint64(); break;
1028  case SLE_FILE_STRINGID: x = RemapOldStringID((uint16)SlReadUint16()); break;
1029  default: NOT_REACHED();
1030  }
1031 
1032  /* Write The value to the struct. These ARE endian safe. */
1033  WriteValue(ptr, conv, x);
1034  break;
1035  }
1036  case SLA_PTRS: break;
1037  case SLA_NULL: break;
1038  default: NOT_REACHED();
1039  }
1040 }
1041 
1051 static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
1052 {
1053  if (ptr == NULL) return 0;
1054  return min(strlen(ptr), length - 1);
1055 }
1056 
1066 static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType conv)
1067 {
1068  size_t len;
1069  const char *str;
1070 
1071  switch (GetVarMemType(conv)) {
1072  default: NOT_REACHED();
1073  case SLE_VAR_STR:
1074  case SLE_VAR_STRQ:
1075  str = *(const char * const *)ptr;
1076  len = SIZE_MAX;
1077  break;
1078  case SLE_VAR_STRB:
1079  case SLE_VAR_STRBQ:
1080  str = (const char *)ptr;
1081  len = length;
1082  break;
1083  }
1084 
1085  len = SlCalcNetStringLen(str, len);
1086  return len + SlGetArrayLength(len); // also include the length of the index
1087 }
1088 
1095 static void SlString(void *ptr, size_t length, VarType conv)
1096 {
1097  switch (_sl.action) {
1098  case SLA_SAVE: {
1099  size_t len;
1100  switch (GetVarMemType(conv)) {
1101  default: NOT_REACHED();
1102  case SLE_VAR_STRB:
1103  case SLE_VAR_STRBQ:
1104  len = SlCalcNetStringLen((char *)ptr, length);
1105  break;
1106  case SLE_VAR_STR:
1107  case SLE_VAR_STRQ:
1108  ptr = *(char **)ptr;
1109  len = SlCalcNetStringLen((char *)ptr, SIZE_MAX);
1110  break;
1111  }
1112 
1113  SlWriteArrayLength(len);
1114  SlCopyBytes(ptr, len);
1115  break;
1116  }
1117  case SLA_LOAD_CHECK:
1118  case SLA_LOAD: {
1119  size_t len = SlReadArrayLength();
1120 
1121  switch (GetVarMemType(conv)) {
1122  default: NOT_REACHED();
1123  case SLE_VAR_STRB:
1124  case SLE_VAR_STRBQ:
1125  if (len >= length) {
1126  DEBUG(sl, 1, "String length in savegame is bigger than buffer, truncating");
1127  SlCopyBytes(ptr, length);
1128  SlSkipBytes(len - length);
1129  len = length - 1;
1130  } else {
1131  SlCopyBytes(ptr, len);
1132  }
1133  break;
1134  case SLE_VAR_STR:
1135  case SLE_VAR_STRQ: // Malloc'd string, free previous incarnation, and allocate
1136  free(*(char **)ptr);
1137  if (len == 0) {
1138  *(char **)ptr = NULL;
1139  return;
1140  } else {
1141  *(char **)ptr = MallocT<char>(len + 1); // terminating '\0'
1142  ptr = *(char **)ptr;
1143  SlCopyBytes(ptr, len);
1144  }
1145  break;
1146  }
1147 
1148  ((char *)ptr)[len] = '\0'; // properly terminate the string
1150  if ((conv & SLF_ALLOW_CONTROL) != 0) {
1151  settings = settings | SVS_ALLOW_CONTROL_CODE;
1152  if (IsSavegameVersionBefore(169)) {
1153  str_fix_scc_encoded((char *)ptr, (char *)ptr + len);
1154  }
1155  }
1156  if ((conv & SLF_ALLOW_NEWLINE) != 0) {
1157  settings = settings | SVS_ALLOW_NEWLINE;
1158  }
1159  str_validate((char *)ptr, (char *)ptr + len, settings);
1160  break;
1161  }
1162  case SLA_PTRS: break;
1163  case SLA_NULL: break;
1164  default: NOT_REACHED();
1165  }
1166 }
1167 
1173 static inline size_t SlCalcArrayLen(size_t length, VarType conv)
1174 {
1175  return SlCalcConvFileLen(conv) * length;
1176 }
1177 
1184 void SlArray(void *array, size_t length, VarType conv)
1185 {
1186  if (_sl.action == SLA_PTRS || _sl.action == SLA_NULL) return;
1187 
1188  /* Automatically calculate the length? */
1189  if (_sl.need_length != NL_NONE) {
1190  SlSetLength(SlCalcArrayLen(length, conv));
1191  /* Determine length only? */
1192  if (_sl.need_length == NL_CALCLENGTH) return;
1193  }
1194 
1195  /* NOTICE - handle some buggy stuff, in really old versions everything was saved
1196  * as a byte-type. So detect this, and adjust array size accordingly */
1197  if (_sl.action != SLA_SAVE && _sl_version == 0) {
1198  /* all arrays except difficulty settings */
1199  if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
1200  conv == SLE_INT32 || conv == SLE_UINT32) {
1201  SlCopyBytes(array, length * SlCalcConvFileLen(conv));
1202  return;
1203  }
1204  /* used for conversion of Money 32bit->64bit */
1205  if (conv == (SLE_FILE_I32 | SLE_VAR_I64)) {
1206  for (uint i = 0; i < length; i++) {
1207  ((int64*)array)[i] = (int32)BSWAP32(SlReadUint32());
1208  }
1209  return;
1210  }
1211  }
1212 
1213  /* If the size of elements is 1 byte both in file and memory, no special
1214  * conversion is needed, use specialized copy-copy function to speed up things */
1215  if (conv == SLE_INT8 || conv == SLE_UINT8) {
1216  SlCopyBytes(array, length);
1217  } else {
1218  byte *a = (byte*)array;
1219  byte mem_size = SlCalcConvMemLen(conv);
1220 
1221  for (; length != 0; length --) {
1222  SlSaveLoadConv(a, conv);
1223  a += mem_size; // get size
1224  }
1225  }
1226 }
1227 
1228 
1239 static size_t ReferenceToInt(const void *obj, SLRefType rt)
1240 {
1241  assert(_sl.action == SLA_SAVE);
1242 
1243  if (obj == NULL) return 0;
1244 
1245  switch (rt) {
1246  case REF_VEHICLE_OLD: // Old vehicles we save as new ones
1247  case REF_VEHICLE: return ((const Vehicle*)obj)->index + 1;
1248  case REF_STATION: return ((const Station*)obj)->index + 1;
1249  case REF_TOWN: return ((const Town*)obj)->index + 1;
1250  case REF_ORDER: return ((const Order*)obj)->index + 1;
1251  case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
1252  case REF_ENGINE_RENEWS: return ((const EngineRenew*)obj)->index + 1;
1253  case REF_CARGO_PACKET: return ((const CargoPacket*)obj)->index + 1;
1254  case REF_ORDERLIST: return ((const OrderList*)obj)->index + 1;
1255  case REF_STORAGE: return ((const PersistentStorage*)obj)->index + 1;
1256  case REF_LINK_GRAPH: return ((const LinkGraph*)obj)->index + 1;
1257  case REF_LINK_GRAPH_JOB: return ((const LinkGraphJob*)obj)->index + 1;
1258  default: NOT_REACHED();
1259  }
1260 }
1261 
1272 static void *IntToReference(size_t index, SLRefType rt)
1273 {
1274  assert_compile(sizeof(size_t) <= sizeof(void *));
1275 
1276  assert(_sl.action == SLA_PTRS);
1277 
1278  /* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
1279  * and should be loaded like that */
1280  if (rt == REF_VEHICLE_OLD && !IsSavegameVersionBefore(4, 4)) {
1281  rt = REF_VEHICLE;
1282  }
1283 
1284  /* No need to look up NULL pointers, just return immediately */
1285  if (index == (rt == REF_VEHICLE_OLD ? 0xFFFF : 0)) return NULL;
1286 
1287  /* Correct index. Old vehicles were saved differently:
1288  * invalid vehicle was 0xFFFF, now we use 0x0000 for everything invalid. */
1289  if (rt != REF_VEHICLE_OLD) index--;
1290 
1291  switch (rt) {
1292  case REF_ORDERLIST:
1293  if (OrderList::IsValidID(index)) return OrderList::Get(index);
1294  SlErrorCorrupt("Referencing invalid OrderList");
1295 
1296  case REF_ORDER:
1297  if (Order::IsValidID(index)) return Order::Get(index);
1298  /* in old versions, invalid order was used to mark end of order list */
1299  if (IsSavegameVersionBefore(5, 2)) return NULL;
1300  SlErrorCorrupt("Referencing invalid Order");
1301 
1302  case REF_VEHICLE_OLD:
1303  case REF_VEHICLE:
1304  if (Vehicle::IsValidID(index)) return Vehicle::Get(index);
1305  SlErrorCorrupt("Referencing invalid Vehicle");
1306 
1307  case REF_STATION:
1308  if (Station::IsValidID(index)) return Station::Get(index);
1309  SlErrorCorrupt("Referencing invalid Station");
1310 
1311  case REF_TOWN:
1312  if (Town::IsValidID(index)) return Town::Get(index);
1313  SlErrorCorrupt("Referencing invalid Town");
1314 
1315  case REF_ROADSTOPS:
1316  if (RoadStop::IsValidID(index)) return RoadStop::Get(index);
1317  SlErrorCorrupt("Referencing invalid RoadStop");
1318 
1319  case REF_ENGINE_RENEWS:
1320  if (EngineRenew::IsValidID(index)) return EngineRenew::Get(index);
1321  SlErrorCorrupt("Referencing invalid EngineRenew");
1322 
1323  case REF_CARGO_PACKET:
1324  if (CargoPacket::IsValidID(index)) return CargoPacket::Get(index);
1325  SlErrorCorrupt("Referencing invalid CargoPacket");
1326 
1327  case REF_STORAGE:
1328  if (PersistentStorage::IsValidID(index)) return PersistentStorage::Get(index);
1329  SlErrorCorrupt("Referencing invalid PersistentStorage");
1330 
1331  case REF_LINK_GRAPH:
1332  if (LinkGraph::IsValidID(index)) return LinkGraph::Get(index);
1333  SlErrorCorrupt("Referencing invalid LinkGraph");
1334 
1335  case REF_LINK_GRAPH_JOB:
1336  if (LinkGraphJob::IsValidID(index)) return LinkGraphJob::Get(index);
1337  SlErrorCorrupt("Referencing invalid LinkGraphJob");
1338 
1339  default: NOT_REACHED();
1340  }
1341 }
1342 
1347 static inline size_t SlCalcListLen(const void *list)
1348 {
1349  const std::list<void *> *l = (const std::list<void *> *) list;
1350 
1351  int type_size = IsSavegameVersionBefore(69) ? 2 : 4;
1352  /* Each entry is saved as type_size bytes, plus type_size bytes are used for the length
1353  * of the list */
1354  return l->size() * type_size + type_size;
1355 }
1356 
1357 
1363 static void SlList(void *list, SLRefType conv)
1364 {
1365  /* Automatically calculate the length? */
1366  if (_sl.need_length != NL_NONE) {
1367  SlSetLength(SlCalcListLen(list));
1368  /* Determine length only? */
1369  if (_sl.need_length == NL_CALCLENGTH) return;
1370  }
1371 
1372  typedef std::list<void *> PtrList;
1373  PtrList *l = (PtrList *)list;
1374 
1375  switch (_sl.action) {
1376  case SLA_SAVE: {
1377  SlWriteUint32((uint32)l->size());
1378 
1379  PtrList::iterator iter;
1380  for (iter = l->begin(); iter != l->end(); ++iter) {
1381  void *ptr = *iter;
1382  SlWriteUint32((uint32)ReferenceToInt(ptr, conv));
1383  }
1384  break;
1385  }
1386  case SLA_LOAD_CHECK:
1387  case SLA_LOAD: {
1388  size_t length = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
1389 
1390  /* Load each reference and push to the end of the list */
1391  for (size_t i = 0; i < length; i++) {
1392  size_t data = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
1393  l->push_back((void *)data);
1394  }
1395  break;
1396  }
1397  case SLA_PTRS: {
1398  PtrList temp = *l;
1399 
1400  l->clear();
1401  PtrList::iterator iter;
1402  for (iter = temp.begin(); iter != temp.end(); ++iter) {
1403  void *ptr = IntToReference((size_t)*iter, conv);
1404  l->push_back(ptr);
1405  }
1406  break;
1407  }
1408  case SLA_NULL:
1409  l->clear();
1410  break;
1411  default: NOT_REACHED();
1412  }
1413 }
1414 
1415 
1417 static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
1418 {
1419  if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
1420  if (sld->conv & SLF_NOT_IN_SAVE) return false;
1421 
1422  return true;
1423 }
1424 
1430 static inline bool SlSkipVariableOnLoad(const SaveLoad *sld)
1431 {
1432  if ((sld->conv & SLF_NO_NETWORK_SYNC) && _sl.action != SLA_SAVE && _networking && !_network_server) {
1433  SlSkipBytes(SlCalcConvMemLen(sld->conv) * sld->length);
1434  return true;
1435  }
1436 
1437  return false;
1438 }
1439 
1446 size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
1447 {
1448  size_t length = 0;
1449 
1450  /* Need to determine the length and write a length tag. */
1451  for (; sld->cmd != SL_END; sld++) {
1452  length += SlCalcObjMemberLength(object, sld);
1453  }
1454  return length;
1455 }
1456 
1457 size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
1458 {
1459  assert(_sl.action == SLA_SAVE);
1460 
1461  switch (sld->cmd) {
1462  case SL_VAR:
1463  case SL_REF:
1464  case SL_ARR:
1465  case SL_STR:
1466  case SL_LST:
1467  /* CONDITIONAL saveload types depend on the savegame version */
1468  if (!SlIsObjectValidInSavegame(sld)) break;
1469 
1470  switch (sld->cmd) {
1471  case SL_VAR: return SlCalcConvFileLen(sld->conv);
1472  case SL_REF: return SlCalcRefLen();
1473  case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
1474  case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
1475  case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
1476  default: NOT_REACHED();
1477  }
1478  break;
1479  case SL_WRITEBYTE: return 1; // a byte is logically of size 1
1480  case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
1481  case SL_ST_INCLUDE: return SlCalcObjLength(object, GetBaseStationDescription());
1482  default: NOT_REACHED();
1483  }
1484  return 0;
1485 }
1486 
1487 #ifdef OTTD_ASSERT
1488 
1494 static bool IsVariableSizeRight(const SaveLoad *sld)
1495 {
1496  switch (sld->cmd) {
1497  case SL_VAR:
1498  switch (GetVarMemType(sld->conv)) {
1499  case SLE_VAR_BL:
1500  return sld->size == sizeof(bool);
1501  case SLE_VAR_I8:
1502  case SLE_VAR_U8:
1503  return sld->size == sizeof(int8);
1504  case SLE_VAR_I16:
1505  case SLE_VAR_U16:
1506  return sld->size == sizeof(int16);
1507  case SLE_VAR_I32:
1508  case SLE_VAR_U32:
1509  return sld->size == sizeof(int32);
1510  case SLE_VAR_I64:
1511  case SLE_VAR_U64:
1512  return sld->size == sizeof(int64);
1513  default:
1514  return sld->size == sizeof(void *);
1515  }
1516  case SL_REF:
1517  /* These should all be pointer sized. */
1518  return sld->size == sizeof(void *);
1519 
1520  case SL_STR:
1521  /* These should be pointer sized, or fixed array. */
1522  return sld->size == sizeof(void *) || sld->size == sld->length;
1523 
1524  default:
1525  return true;
1526  }
1527 }
1528 
1529 #endif /* OTTD_ASSERT */
1530 
1531 bool SlObjectMember(void *ptr, const SaveLoad *sld)
1532 {
1533 #ifdef OTTD_ASSERT
1534  assert(IsVariableSizeRight(sld));
1535 #endif
1536 
1537  VarType conv = GB(sld->conv, 0, 8);
1538  switch (sld->cmd) {
1539  case SL_VAR:
1540  case SL_REF:
1541  case SL_ARR:
1542  case SL_STR:
1543  case SL_LST:
1544  /* CONDITIONAL saveload types depend on the savegame version */
1545  if (!SlIsObjectValidInSavegame(sld)) return false;
1546  if (SlSkipVariableOnLoad(sld)) return false;
1547 
1548  switch (sld->cmd) {
1549  case SL_VAR: SlSaveLoadConv(ptr, conv); break;
1550  case SL_REF: // Reference variable, translate
1551  switch (_sl.action) {
1552  case SLA_SAVE:
1553  SlWriteUint32((uint32)ReferenceToInt(*(void **)ptr, (SLRefType)conv));
1554  break;
1555  case SLA_LOAD_CHECK:
1556  case SLA_LOAD:
1557  *(size_t *)ptr = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
1558  break;
1559  case SLA_PTRS:
1560  *(void **)ptr = IntToReference(*(size_t *)ptr, (SLRefType)conv);
1561  break;
1562  case SLA_NULL:
1563  *(void **)ptr = NULL;
1564  break;
1565  default: NOT_REACHED();
1566  }
1567  break;
1568  case SL_ARR: SlArray(ptr, sld->length, conv); break;
1569  case SL_STR: SlString(ptr, sld->length, sld->conv); break;
1570  case SL_LST: SlList(ptr, (SLRefType)conv); break;
1571  default: NOT_REACHED();
1572  }
1573  break;
1574 
1575  /* SL_WRITEBYTE translates a value of a variable to another one upon
1576  * saving or loading.
1577  * XXX - variable renaming abuse
1578  * game_value: the value of the variable ingame is abused by sld->version_from
1579  * file_value: the value of the variable in the savegame is abused by sld->version_to */
1580  case SL_WRITEBYTE:
1581  switch (_sl.action) {
1582  case SLA_SAVE: SlWriteByte(sld->version_to); break;
1583  case SLA_LOAD_CHECK:
1584  case SLA_LOAD: *(byte *)ptr = sld->version_from; break;
1585  case SLA_PTRS: break;
1586  case SLA_NULL: break;
1587  default: NOT_REACHED();
1588  }
1589  break;
1590 
1591  /* SL_VEH_INCLUDE loads common code for vehicles */
1592  case SL_VEH_INCLUDE:
1593  SlObject(ptr, GetVehicleDescription(VEH_END));
1594  break;
1595 
1596  case SL_ST_INCLUDE:
1598  break;
1599 
1600  default: NOT_REACHED();
1601  }
1602  return true;
1603 }
1604 
1610 void SlObject(void *object, const SaveLoad *sld)
1611 {
1612  /* Automatically calculate the length? */
1613  if (_sl.need_length != NL_NONE) {
1614  SlSetLength(SlCalcObjLength(object, sld));
1615  if (_sl.need_length == NL_CALCLENGTH) return;
1616  }
1617 
1618  for (; sld->cmd != SL_END; sld++) {
1619  void *ptr = sld->global ? sld->address : GetVariableAddress(object, sld);
1620  SlObjectMember(ptr, sld);
1621  }
1622 }
1623 
1629 {
1630  SlObject(NULL, (const SaveLoad*)sldg);
1631 }
1632 
1638 void SlAutolength(AutolengthProc *proc, void *arg)
1639 {
1640  size_t offs;
1641 
1642  assert(_sl.action == SLA_SAVE);
1643 
1644  /* Tell it to calculate the length */
1645  _sl.need_length = NL_CALCLENGTH;
1646  _sl.obj_len = 0;
1647  proc(arg);
1648 
1649  /* Setup length */
1650  _sl.need_length = NL_WANTLENGTH;
1651  SlSetLength(_sl.obj_len);
1652 
1653  offs = _sl.dumper->GetSize() + _sl.obj_len;
1654 
1655  /* And write the stuff */
1656  proc(arg);
1657 
1658  if (offs != _sl.dumper->GetSize()) SlErrorCorrupt("Invalid chunk size");
1659 }
1660 
1665 static void SlLoadChunk(const ChunkHandler *ch)
1666 {
1667  byte m = SlReadByte();
1668  size_t len;
1669  size_t endoffs;
1670 
1671  _sl.block_mode = m;
1672  _sl.obj_len = 0;
1673 
1674  switch (m) {
1675  case CH_ARRAY:
1676  _sl.array_index = 0;
1677  ch->load_proc();
1678  if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
1679  break;
1680  case CH_SPARSE_ARRAY:
1681  ch->load_proc();
1682  if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
1683  break;
1684  default:
1685  if ((m & 0xF) == CH_RIFF) {
1686  /* Read length */
1687  len = (SlReadByte() << 16) | ((m >> 4) << 24);
1688  len += SlReadUint16();
1689  _sl.obj_len = len;
1690  endoffs = _sl.reader->GetSize() + len;
1691  ch->load_proc();
1692  if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
1693  } else {
1694  SlErrorCorrupt("Invalid chunk type");
1695  }
1696  break;
1697  }
1698 }
1699 
1705 static void SlLoadCheckChunk(const ChunkHandler *ch)
1706 {
1707  byte m = SlReadByte();
1708  size_t len;
1709  size_t endoffs;
1710 
1711  _sl.block_mode = m;
1712  _sl.obj_len = 0;
1713 
1714  switch (m) {
1715  case CH_ARRAY:
1716  _sl.array_index = 0;
1717  if (ch->load_check_proc) {
1718  ch->load_check_proc();
1719  } else {
1720  SlSkipArray();
1721  }
1722  break;
1723  case CH_SPARSE_ARRAY:
1724  if (ch->load_check_proc) {
1725  ch->load_check_proc();
1726  } else {
1727  SlSkipArray();
1728  }
1729  break;
1730  default:
1731  if ((m & 0xF) == CH_RIFF) {
1732  /* Read length */
1733  len = (SlReadByte() << 16) | ((m >> 4) << 24);
1734  len += SlReadUint16();
1735  _sl.obj_len = len;
1736  endoffs = _sl.reader->GetSize() + len;
1737  if (ch->load_check_proc) {
1738  ch->load_check_proc();
1739  } else {
1740  SlSkipBytes(len);
1741  }
1742  if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
1743  } else {
1744  SlErrorCorrupt("Invalid chunk type");
1745  }
1746  break;
1747  }
1748 }
1749 
1754 static ChunkSaveLoadProc *_stub_save_proc;
1755 
1761 static inline void SlStubSaveProc2(void *arg)
1762 {
1763  _stub_save_proc();
1764 }
1765 
1771 static void SlStubSaveProc()
1772 {
1774 }
1775 
1781 static void SlSaveChunk(const ChunkHandler *ch)
1782 {
1783  ChunkSaveLoadProc *proc = ch->save_proc;
1784 
1785  /* Don't save any chunk information if there is no save handler. */
1786  if (proc == NULL) return;
1787 
1788  SlWriteUint32(ch->id);
1789  DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
1790 
1791  if (ch->flags & CH_AUTO_LENGTH) {
1792  /* Need to calculate the length. Solve that by calling SlAutoLength in the save_proc. */
1793  _stub_save_proc = proc;
1794  proc = SlStubSaveProc;
1795  }
1796 
1797  _sl.block_mode = ch->flags & CH_TYPE_MASK;
1798  switch (ch->flags & CH_TYPE_MASK) {
1799  case CH_RIFF:
1800  _sl.need_length = NL_WANTLENGTH;
1801  proc();
1802  break;
1803  case CH_ARRAY:
1804  _sl.last_array_index = 0;
1805  SlWriteByte(CH_ARRAY);
1806  proc();
1807  SlWriteArrayLength(0); // Terminate arrays
1808  break;
1809  case CH_SPARSE_ARRAY:
1810  SlWriteByte(CH_SPARSE_ARRAY);
1811  proc();
1812  SlWriteArrayLength(0); // Terminate arrays
1813  break;
1814  default: NOT_REACHED();
1815  }
1816 }
1817 
1819 static void SlSaveChunks()
1820 {
1822  SlSaveChunk(ch);
1823  }
1824 
1825  /* Terminator */
1826  SlWriteUint32(0);
1827 }
1828 
1835 static const ChunkHandler *SlFindChunkHandler(uint32 id)
1836 {
1837  FOR_ALL_CHUNK_HANDLERS(ch) if (ch->id == id) return ch;
1838  return NULL;
1839 }
1840 
1842 static void SlLoadChunks()
1843 {
1844  uint32 id;
1845  const ChunkHandler *ch;
1846 
1847  for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
1848  DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
1849 
1850  ch = SlFindChunkHandler(id);
1851  if (ch == NULL) SlErrorCorrupt("Unknown chunk type");
1852  SlLoadChunk(ch);
1853  }
1854 }
1855 
1857 static void SlLoadCheckChunks()
1858 {
1859  uint32 id;
1860  const ChunkHandler *ch;
1861 
1862  for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
1863  DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
1864 
1865  ch = SlFindChunkHandler(id);
1866  if (ch == NULL) SlErrorCorrupt("Unknown chunk type");
1867  SlLoadCheckChunk(ch);
1868  }
1869 }
1870 
1872 static void SlFixPointers()
1873 {
1874  _sl.action = SLA_PTRS;
1875 
1876  DEBUG(sl, 1, "Fixing pointers");
1877 
1879  if (ch->ptrs_proc != NULL) {
1880  DEBUG(sl, 2, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
1881  ch->ptrs_proc();
1882  }
1883  }
1884 
1885  DEBUG(sl, 1, "All pointers fixed");
1886 
1887  assert(_sl.action == SLA_PTRS);
1888 }
1889 
1890 
1893  FILE *file;
1894  long begin;
1895 
1900  FileReader(FILE *file) : LoadFilter(NULL), file(file), begin(ftell(file))
1901  {
1902  }
1903 
1906  {
1907  if (this->file != NULL) fclose(this->file);
1908  this->file = NULL;
1909 
1910  /* Make sure we don't double free. */
1911  _sl.sf = NULL;
1912  }
1913 
1914  /* virtual */ size_t Read(byte *buf, size_t size)
1915  {
1916  /* We're in the process of shutting down, i.e. in "failure" mode. */
1917  if (this->file == NULL) return 0;
1918 
1919  return fread(buf, 1, size, this->file);
1920  }
1921 
1922  /* virtual */ void Reset()
1923  {
1924  clearerr(this->file);
1925  if (fseek(this->file, this->begin, SEEK_SET)) {
1926  DEBUG(sl, 1, "Could not reset the file reading");
1927  }
1928  }
1929 };
1930 
1933  FILE *file;
1934 
1939  FileWriter(FILE *file) : SaveFilter(NULL), file(file)
1940  {
1941  }
1942 
1945  {
1946  this->Finish();
1947 
1948  /* Make sure we don't double free. */
1949  _sl.sf = NULL;
1950  }
1951 
1952  /* virtual */ void Write(byte *buf, size_t size)
1953  {
1954  /* We're in the process of shutting down, i.e. in "failure" mode. */
1955  if (this->file == NULL) return;
1956 
1957  if (fwrite(buf, 1, size, this->file) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
1958  }
1959 
1960  /* virtual */ void Finish()
1961  {
1962  if (this->file != NULL) fclose(this->file);
1963  this->file = NULL;
1964  }
1965 };
1966 
1967 /*******************************************
1968  ********** START OF LZO CODE **************
1969  *******************************************/
1970 
1971 #ifdef WITH_LZO
1972 #include <lzo/lzo1x.h>
1973 
1975 static const uint LZO_BUFFER_SIZE = 8192;
1976 
1984  {
1985  if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
1986  }
1987 
1988  /* virtual */ size_t Read(byte *buf, size_t ssize)
1989  {
1990  assert(ssize >= LZO_BUFFER_SIZE);
1991 
1992  /* Buffer size is from the LZO docs plus the chunk header size. */
1993  byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32) * 2];
1994  uint32 tmp[2];
1995  uint32 size;
1996  lzo_uint len;
1997 
1998  /* Read header*/
1999  if (this->chain->Read((byte*)tmp, sizeof(tmp)) != sizeof(tmp)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE, "File read failed");
2000 
2001  /* Check if size is bad */
2002  ((uint32*)out)[0] = size = tmp[1];
2003 
2004  if (_sl_version != 0) {
2005  tmp[0] = TO_BE32(tmp[0]);
2006  size = TO_BE32(size);
2007  }
2008 
2009  if (size >= sizeof(out)) SlErrorCorrupt("Inconsistent size");
2010 
2011  /* Read block */
2012  if (this->chain->Read(out + sizeof(uint32), size) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
2013 
2014  /* Verify checksum */
2015  if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlErrorCorrupt("Bad checksum");
2016 
2017  /* Decompress */
2018  lzo1x_decompress_safe(out + sizeof(uint32) * 1, size, buf, &len, NULL);
2019  return len;
2020  }
2021 };
2022 
2030  LZOSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
2031  {
2032  if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
2033  }
2034 
2035  /* virtual */ void Write(byte *buf, size_t size)
2036  {
2037  const lzo_bytep in = buf;
2038  /* Buffer size is from the LZO docs plus the chunk header size. */
2039  byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32) * 2];
2040  byte wrkmem[LZO1X_1_MEM_COMPRESS];
2041  lzo_uint outlen;
2042 
2043  do {
2044  /* Compress up to LZO_BUFFER_SIZE bytes at once. */
2045  lzo_uint len = size > LZO_BUFFER_SIZE ? LZO_BUFFER_SIZE : (lzo_uint)size;
2046  lzo1x_1_compress(in, len, out + sizeof(uint32) * 2, &outlen, wrkmem);
2047  ((uint32*)out)[1] = TO_BE32((uint32)outlen);
2048  ((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out + sizeof(uint32), outlen + sizeof(uint32)));
2049  this->chain->Write(out, outlen + sizeof(uint32) * 2);
2050 
2051  /* Move to next data chunk. */
2052  size -= len;
2053  in += len;
2054  } while (size > 0);
2055  }
2056 };
2057 
2058 #endif /* WITH_LZO */
2059 
2060 /*********************************************
2061  ******** START OF NOCOMP CODE (uncompressed)*
2062  *********************************************/
2063 
2071  {
2072  }
2073 
2074  /* virtual */ size_t Read(byte *buf, size_t size)
2075  {
2076  return this->chain->Read(buf, size);
2077  }
2078 };
2079 
2087  NoCompSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
2088  {
2089  }
2090 
2091  /* virtual */ void Write(byte *buf, size_t size)
2092  {
2093  this->chain->Write(buf, size);
2094  }
2095 };
2096 
2097 /********************************************
2098  ********** START OF ZLIB CODE **************
2099  ********************************************/
2100 
2101 #if defined(WITH_ZLIB)
2102 #include <zlib.h>
2103 
2106  z_stream z;
2108 
2114  {
2115  memset(&this->z, 0, sizeof(this->z));
2116  if (inflateInit(&this->z) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
2117  }
2118 
2121  {
2122  inflateEnd(&this->z);
2123  }
2124 
2125  /* virtual */ size_t Read(byte *buf, size_t size)
2126  {
2127  this->z.next_out = buf;
2128  this->z.avail_out = (uint)size;
2129 
2130  do {
2131  /* read more bytes from the file? */
2132  if (this->z.avail_in == 0) {
2133  this->z.next_in = this->fread_buf;
2134  this->z.avail_in = (uint)this->chain->Read(this->fread_buf, sizeof(this->fread_buf));
2135  }
2136 
2137  /* inflate the data */
2138  int r = inflate(&this->z, 0);
2139  if (r == Z_STREAM_END) break;
2140 
2141  if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "inflate() failed");
2142  } while (this->z.avail_out != 0);
2143 
2144  return size - this->z.avail_out;
2145  }
2146 };
2147 
2150  z_stream z;
2151 
2157  ZlibSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
2158  {
2159  memset(&this->z, 0, sizeof(this->z));
2160  if (deflateInit(&this->z, compression_level) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
2161  }
2162 
2165  {
2166  deflateEnd(&this->z);
2167  }
2168 
2175  void WriteLoop(byte *p, size_t len, int mode)
2176  {
2177  byte buf[MEMORY_CHUNK_SIZE]; // output buffer
2178  uint n;
2179  this->z.next_in = p;
2180  this->z.avail_in = (uInt)len;
2181  do {
2182  this->z.next_out = buf;
2183  this->z.avail_out = sizeof(buf);
2184 
2192  int r = deflate(&this->z, mode);
2193 
2194  /* bytes were emitted? */
2195  if ((n = sizeof(buf) - this->z.avail_out) != 0) {
2196  this->chain->Write(buf, n);
2197  }
2198  if (r == Z_STREAM_END) break;
2199 
2200  if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "zlib returned error code");
2201  } while (this->z.avail_in || !this->z.avail_out);
2202  }
2203 
2204  /* virtual */ void Write(byte *buf, size_t size)
2205  {
2206  this->WriteLoop(buf, size, 0);
2207  }
2208 
2209  /* virtual */ void Finish()
2210  {
2211  this->WriteLoop(NULL, 0, Z_FINISH);
2212  this->chain->Finish();
2213  }
2214 };
2215 
2216 #endif /* WITH_ZLIB */
2217 
2218 /********************************************
2219  ********** START OF LZMA CODE **************
2220  ********************************************/
2221 
2222 #if defined(WITH_LZMA)
2223 #include <lzma.h>
2224 
2231 static const lzma_stream _lzma_init = LZMA_STREAM_INIT;
2232 
2235  lzma_stream lzma;
2237 
2243  {
2244  /* Allow saves up to 256 MB uncompressed */
2245  if (lzma_auto_decoder(&this->lzma, 1 << 28, 0) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
2246  }
2247 
2250  {
2251  lzma_end(&this->lzma);
2252  }
2253 
2254  /* virtual */ size_t Read(byte *buf, size_t size)
2255  {
2256  this->lzma.next_out = buf;
2257  this->lzma.avail_out = size;
2258 
2259  do {
2260  /* read more bytes from the file? */
2261  if (this->lzma.avail_in == 0) {
2262  this->lzma.next_in = this->fread_buf;
2263  this->lzma.avail_in = this->chain->Read(this->fread_buf, sizeof(this->fread_buf));
2264  }
2265 
2266  /* inflate the data */
2267  lzma_ret r = lzma_code(&this->lzma, LZMA_RUN);
2268  if (r == LZMA_STREAM_END) break;
2269  if (r != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "liblzma returned error code");
2270  } while (this->lzma.avail_out != 0);
2271 
2272  return size - this->lzma.avail_out;
2273  }
2274 };
2275 
2278  lzma_stream lzma;
2279 
2285  LZMASaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain), lzma(_lzma_init)
2286  {
2287  if (lzma_easy_encoder(&this->lzma, compression_level, LZMA_CHECK_CRC32) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
2288  }
2289 
2292  {
2293  lzma_end(&this->lzma);
2294  }
2295 
2302  void WriteLoop(byte *p, size_t len, lzma_action action)
2303  {
2304  byte buf[MEMORY_CHUNK_SIZE]; // output buffer
2305  size_t n;
2306  this->lzma.next_in = p;
2307  this->lzma.avail_in = len;
2308  do {
2309  this->lzma.next_out = buf;
2310  this->lzma.avail_out = sizeof(buf);
2311 
2312  lzma_ret r = lzma_code(&this->lzma, action);
2313 
2314  /* bytes were emitted? */
2315  if ((n = sizeof(buf) - this->lzma.avail_out) != 0) {
2316  this->chain->Write(buf, n);
2317  }
2318  if (r == LZMA_STREAM_END) break;
2319  if (r != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "liblzma returned error code");
2320  } while (this->lzma.avail_in || !this->lzma.avail_out);
2321  }
2322 
2323  /* virtual */ void Write(byte *buf, size_t size)
2324  {
2325  this->WriteLoop(buf, size, LZMA_RUN);
2326  }
2327 
2328  /* virtual */ void Finish()
2329  {
2330  this->WriteLoop(NULL, 0, LZMA_FINISH);
2331  this->chain->Finish();
2332  }
2333 };
2334 
2335 #endif /* WITH_LZMA */
2336 
2337 /*******************************************
2338  ************* END OF CODE *****************
2339  *******************************************/
2340 
2343  const char *name;
2344  uint32 tag;
2345 
2346  LoadFilter *(*init_load)(LoadFilter *chain);
2347  SaveFilter *(*init_write)(SaveFilter *chain, byte compression);
2348 
2352 };
2353 
2356 #if defined(WITH_LZO)
2357  /* Roughly 75% larger than zlib level 6 at only ~7% of the CPU usage. */
2358  {"lzo", TO_BE32X('OTTD'), CreateLoadFilter<LZOLoadFilter>, CreateSaveFilter<LZOSaveFilter>, 0, 0, 0},
2359 #else
2360  {"lzo", TO_BE32X('OTTD'), NULL, NULL, 0, 0, 0},
2361 #endif
2362  /* Roughly 5 times larger at only 1% of the CPU usage over zlib level 6. */
2363  {"none", TO_BE32X('OTTN'), CreateLoadFilter<NoCompLoadFilter>, CreateSaveFilter<NoCompSaveFilter>, 0, 0, 0},
2364 #if defined(WITH_ZLIB)
2365  /* After level 6 the speed reduction is significant (1.5x to 2.5x slower per level), but the reduction in filesize is
2366  * fairly insignificant (~1% for each step). Lower levels become ~5-10% bigger by each level than level 6 while level
2367  * 1 is "only" 3 times as fast. Level 0 results in uncompressed savegames at about 8 times the cost of "none". */
2368  {"zlib", TO_BE32X('OTTZ'), CreateLoadFilter<ZlibLoadFilter>, CreateSaveFilter<ZlibSaveFilter>, 0, 6, 9},
2369 #else
2370  {"zlib", TO_BE32X('OTTZ'), NULL, NULL, 0, 0, 0},
2371 #endif
2372 #if defined(WITH_LZMA)
2373  /* Level 2 compression is speed wise as fast as zlib level 6 compression (old default), but results in ~10% smaller saves.
2374  * Higher compression levels are possible, and might improve savegame size by up to 25%, but are also up to 10 times slower.
2375  * The next significant reduction in file size is at level 4, but that is already 4 times slower. Level 3 is primarily 50%
2376  * slower while not improving the filesize, while level 0 and 1 are faster, but don't reduce savegame size much.
2377  * It's OTTX and not e.g. OTTL because liblzma is part of xz-utils and .tar.xz is preferred over .tar.lzma. */
2378  {"lzma", TO_BE32X('OTTX'), CreateLoadFilter<LZMALoadFilter>, CreateSaveFilter<LZMASaveFilter>, 0, 2, 9},
2379 #else
2380  {"lzma", TO_BE32X('OTTX'), NULL, NULL, 0, 0, 0},
2381 #endif
2382 };
2383 
2391 static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level)
2392 {
2393  const SaveLoadFormat *def = lastof(_saveload_formats);
2394 
2395  /* find default savegame format, the highest one with which files can be written */
2396  while (!def->init_write) def--;
2397 
2398  if (!StrEmpty(s)) {
2399  /* Get the ":..." of the compression level out of the way */
2400  char *complevel = strrchr(s, ':');
2401  if (complevel != NULL) *complevel = '\0';
2402 
2403  for (const SaveLoadFormat *slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) {
2404  if (slf->init_write != NULL && strcmp(s, slf->name) == 0) {
2405  *compression_level = slf->default_compression;
2406  if (complevel != NULL) {
2407  /* There is a compression level in the string.
2408  * First restore the : we removed to do proper name matching,
2409  * then move the the begin of the actual version. */
2410  *complevel = ':';
2411  complevel++;
2412 
2413  /* Get the version and determine whether all went fine. */
2414  char *end;
2415  long level = strtol(complevel, &end, 10);
2416  if (end == complevel || level != Clamp(level, slf->min_compression, slf->max_compression)) {
2417  SetDParamStr(0, complevel);
2418  ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL, WL_CRITICAL);
2419  } else {
2420  *compression_level = level;
2421  }
2422  }
2423  return slf;
2424  }
2425  }
2426 
2427  SetDParamStr(0, s);
2428  SetDParamStr(1, def->name);
2429  ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM, WL_CRITICAL);
2430 
2431  /* Restore the string by adding the : back */
2432  if (complevel != NULL) *complevel = ':';
2433  }
2434  *compression_level = def->default_compression;
2435  return def;
2436 }
2437 
2438 /* actual loader/saver function */
2439 void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings);
2440 extern bool AfterLoadGame();
2441 extern bool LoadOldSaveGame(const char *file);
2442 
2446 static inline void ClearSaveLoadState()
2447 {
2448  delete _sl.dumper;
2449  _sl.dumper = NULL;
2450 
2451  delete _sl.sf;
2452  _sl.sf = NULL;
2453 
2454  delete _sl.reader;
2455  _sl.reader = NULL;
2456 
2457  delete _sl.lf;
2458  _sl.lf = NULL;
2459 }
2460 
2466 static void SaveFileStart()
2467 {
2468  _sl.ff_state = _fast_forward;
2469  _fast_forward = 0;
2470  SetMouseCursorBusy(true);
2471 
2473  _sl.saveinprogress = true;
2474 }
2475 
2477 static void SaveFileDone()
2478 {
2479  if (_game_mode != GM_MENU) _fast_forward = _sl.ff_state;
2480  SetMouseCursorBusy(false);
2481 
2483  _sl.saveinprogress = false;
2484 }
2485 
2488 {
2489  _sl.error_str = str;
2490 }
2491 
2494 {
2495  SetDParam(0, _sl.error_str);
2496  SetDParamStr(1, _sl.extra_msg);
2497 
2498  static char err_str[512];
2499  GetString(err_str, _sl.action == SLA_SAVE ? STR_ERROR_GAME_SAVE_FAILED : STR_ERROR_GAME_LOAD_FAILED, lastof(err_str));
2500  return err_str;
2501 }
2502 
2504 static void SaveFileError()
2505 {
2507  ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
2508  SaveFileDone();
2509 }
2510 
2515 static SaveOrLoadResult SaveFileToDisk(bool threaded)
2516 {
2517  try {
2518  byte compression;
2519  const SaveLoadFormat *fmt = GetSavegameFormat(_savegame_format, &compression);
2520 
2521  /* We have written our stuff to memory, now write it to file! */
2522  uint32 hdr[2] = { fmt->tag, TO_BE32(SAVEGAME_VERSION << 16) };
2523  _sl.sf->Write((byte*)hdr, sizeof(hdr));
2524 
2525  _sl.sf = fmt->init_write(_sl.sf, compression);
2526  _sl.dumper->Flush(_sl.sf);
2527 
2529 
2530  if (threaded) SetAsyncSaveFinish(SaveFileDone);
2531 
2532  return SL_OK;
2533  } catch (...) {
2535 
2537 
2538  /* We don't want to shout when saving is just
2539  * cancelled due to a client disconnecting. */
2540  if (_sl.error_str != STR_NETWORK_ERROR_LOSTCONNECTION) {
2541  /* Skip the "colour" character */
2542  DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
2543  asfp = SaveFileError;
2544  }
2545 
2546  if (threaded) {
2547  SetAsyncSaveFinish(asfp);
2548  } else {
2549  asfp();
2550  }
2551  return SL_ERROR;
2552  }
2553 }
2554 
2556 static void SaveFileToDiskThread(void *arg)
2557 {
2558  SaveFileToDisk(true);
2559 }
2560 
2561 void WaitTillSaved()
2562 {
2563  if (_save_thread == NULL) return;
2564 
2565  _save_thread->Join();
2566  delete _save_thread;
2567  _save_thread = NULL;
2568 
2569  /* Make sure every other state is handled properly as well. */
2571 }
2572 
2581 static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded)
2582 {
2583  assert(!_sl.saveinprogress);
2584 
2585  _sl.dumper = new MemoryDumper();
2586  _sl.sf = writer;
2587 
2589 
2590  SaveViewportBeforeSaveGame();
2591  SlSaveChunks();
2592 
2593  SaveFileStart();
2594  if (!threaded || !ThreadObject::New(&SaveFileToDiskThread, NULL, &_save_thread, "ottd:savegame")) {
2595  if (threaded) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
2596 
2597  SaveOrLoadResult result = SaveFileToDisk(false);
2598  SaveFileDone();
2599 
2600  return result;
2601  }
2602 
2603  return SL_OK;
2604 }
2605 
2613 {
2614  try {
2615  _sl.action = SLA_SAVE;
2616  return DoSave(writer, threaded);
2617  } catch (...) {
2619  return SL_ERROR;
2620  }
2621 }
2622 
2629 static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
2630 {
2631  _sl.lf = reader;
2632 
2633  if (load_check) {
2634  /* Clear previous check data */
2636  /* Mark SL_LOAD_CHECK as supported for this savegame. */
2637  _load_check_data.checkable = true;
2638  }
2639 
2640  uint32 hdr[2];
2641  if (_sl.lf->Read((byte*)hdr, sizeof(hdr)) != sizeof(hdr)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
2642 
2643  /* see if we have any loader for this type. */
2644  const SaveLoadFormat *fmt = _saveload_formats;
2645  for (;;) {
2646  /* No loader found, treat as version 0 and use LZO format */
2647  if (fmt == endof(_saveload_formats)) {
2648  DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
2649  _sl.lf->Reset();
2650  _sl_version = 0;
2651  _sl_minor_version = 0;
2652 
2653  /* Try to find the LZO savegame format; it uses 'OTTD' as tag. */
2654  fmt = _saveload_formats;
2655  for (;;) {
2656  if (fmt == endof(_saveload_formats)) {
2657  /* Who removed LZO support? Bad bad boy! */
2658  NOT_REACHED();
2659  }
2660  if (fmt->tag == TO_BE32X('OTTD')) break;
2661  fmt++;
2662  }
2663  break;
2664  }
2665 
2666  if (fmt->tag == hdr[0]) {
2667  /* check version number */
2668  _sl_version = TO_BE32(hdr[1]) >> 16;
2669  /* Minor is not used anymore from version 18.0, but it is still needed
2670  * in versions before that (4 cases) which can't be removed easy.
2671  * Therefore it is loaded, but never saved (or, it saves a 0 in any scenario). */
2672  _sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
2673 
2674  DEBUG(sl, 1, "Loading savegame version %d", _sl_version);
2675 
2676  /* Is the version higher than the current? */
2677  if (_sl_version > SAVEGAME_VERSION) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
2678  break;
2679  }
2680 
2681  fmt++;
2682  }
2683 
2684  /* loader for this savegame type is not implemented? */
2685  if (fmt->init_load == NULL) {
2686  char err_str[64];
2687  seprintf(err_str, lastof(err_str), "Loader for '%s' is not available.", fmt->name);
2688  SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
2689  }
2690 
2691  _sl.lf = fmt->init_load(_sl.lf);
2692  _sl.reader = new ReadBuffer(_sl.lf);
2693  _next_offs = 0;
2694 
2695  if (!load_check) {
2696  /* Old maps were hardcoded to 256x256 and thus did not contain
2697  * any mapsize information. Pre-initialize to 256x256 to not to
2698  * confuse old games */
2699  InitializeGame(256, 256, true, true);
2700 
2701  GamelogReset();
2702 
2703  if (IsSavegameVersionBefore(4)) {
2704  /*
2705  * NewGRFs were introduced between 0.3,4 and 0.3.5, which both
2706  * shared savegame version 4. Anything before that 'obviously'
2707  * does not have any NewGRFs. Between the introduction and
2708  * savegame version 41 (just before 0.5) the NewGRF settings
2709  * were not stored in the savegame and they were loaded by
2710  * using the settings from the main menu.
2711  * So, to recap:
2712  * - savegame version < 4: do not load any NewGRFs.
2713  * - savegame version >= 41: load NewGRFs from savegame, which is
2714  * already done at this stage by
2715  * overwriting the main menu settings.
2716  * - other savegame versions: use main menu settings.
2717  *
2718  * This means that users *can* crash savegame version 4..40
2719  * savegames if they set incompatible NewGRFs in the main menu,
2720  * but can't crash anymore for savegame version < 4 savegames.
2721  *
2722  * Note: this is done here because AfterLoadGame is also called
2723  * for TTO/TTD/TTDP savegames which have their own NewGRF logic.
2724  */
2726  }
2727  }
2728 
2729  if (load_check) {
2730  /* Load chunks into _load_check_data.
2731  * No pools are loaded. References are not possible, and thus do not need resolving. */
2733  } else {
2734  /* Load chunks and resolve references */
2735  SlLoadChunks();
2736  SlFixPointers();
2737  }
2738 
2740 
2742 
2743  if (load_check) {
2744  /* The only part from AfterLoadGame() we need */
2746  } else {
2748 
2749  /* After loading fix up savegame for any internal changes that
2750  * might have occurred since then. If it fails, load back the old game. */
2751  if (!AfterLoadGame()) {
2753  return SL_REINIT;
2754  }
2755 
2757  }
2758 
2759  return SL_OK;
2760 }
2761 
2768 {
2769  try {
2770  _sl.action = SLA_LOAD;
2771  return DoLoad(reader, false);
2772  } catch (...) {
2774  return SL_REINIT;
2775  }
2776 }
2777 
2787 SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
2788 {
2789  /* An instance of saving is already active, so don't go saving again */
2790  if (_sl.saveinprogress && fop == SLO_SAVE && dft == DFT_GAME_FILE && threaded) {
2791  /* if not an autosave, but a user action, show error message */
2792  if (!_do_autosave) ShowErrorMessage(STR_ERROR_SAVE_STILL_IN_PROGRESS, INVALID_STRING_ID, WL_ERROR);
2793  return SL_OK;
2794  }
2795  WaitTillSaved();
2796 
2797  try {
2798  /* Load a TTDLX or TTDPatch game */
2799  if (fop == SLO_LOAD && dft == DFT_OLD_GAME_FILE) {
2800  InitializeGame(256, 256, true, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused
2801 
2802  /* TTD/TTO savegames have no NewGRFs, TTDP savegame have them
2803  * and if so a new NewGRF list will be made in LoadOldSaveGame.
2804  * Note: this is done here because AfterLoadGame is also called
2805  * for OTTD savegames which have their own NewGRF logic. */
2807  GamelogReset();
2808  if (!LoadOldSaveGame(filename)) return SL_REINIT;
2809  _sl_version = 0;
2810  _sl_minor_version = 0;
2812  if (!AfterLoadGame()) {
2814  return SL_REINIT;
2815  }
2817  return SL_OK;
2818  }
2819 
2820  assert(dft == DFT_GAME_FILE);
2821  switch (fop) {
2822  case SLO_CHECK:
2823  _sl.action = SLA_LOAD_CHECK;
2824  break;
2825 
2826  case SLO_LOAD:
2827  _sl.action = SLA_LOAD;
2828  break;
2829 
2830  case SLO_SAVE:
2831  _sl.action = SLA_SAVE;
2832  break;
2833 
2834  default: NOT_REACHED();
2835  }
2836 
2837  FILE *fh = (fop == SLO_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
2838 
2839  /* Make it a little easier to load savegames from the console */
2840  if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", SAVE_DIR);
2841  if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", BASE_DIR);
2842  if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", SCENARIO_DIR);
2843 
2844  if (fh == NULL) {
2845  SlError(fop == SLO_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
2846  }
2847 
2848  if (fop == SLO_SAVE) { // SAVE game
2849  DEBUG(desync, 1, "save: %08x; %02x; %s", _date, _date_fract, filename);
2850  if (_network_server || !_settings_client.gui.threaded_saves) threaded = false;
2851 
2852  return DoSave(new FileWriter(fh), threaded);
2853  }
2854 
2855  /* LOAD game */
2856  assert(fop == SLO_LOAD || fop == SLO_CHECK);
2857  DEBUG(desync, 1, "load: %s", filename);
2858  return DoLoad(new FileReader(fh), fop == SLO_CHECK);
2859  } catch (...) {
2860  /* This code may be executed both for old and new save games. */
2862 
2863  /* Skip the "colour" character */
2864  if (fop != SLO_CHECK) DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
2865 
2866  /* A saver/loader exception!! reinitialize all variables to prevent crash! */
2867  return (fop == SLO_LOAD) ? SL_REINIT : SL_ERROR;
2868  }
2869 }
2870 
2873 {
2875 }
2876 
2882 void GenerateDefaultSaveName(char *buf, const char *last)
2883 {
2884  /* Check if we have a name for this map, which is the name of the first
2885  * available company. When there's no company available we'll use
2886  * 'Spectator' as "company" name. */
2887  CompanyID cid = _local_company;
2888  if (!Company::IsValidID(cid)) {
2889  const Company *c;
2890  FOR_ALL_COMPANIES(c) {
2891  cid = c->index;
2892  break;
2893  }
2894  }
2895 
2896  SetDParam(0, cid);
2897 
2898  /* Insert current date */
2900  case 0: SetDParam(1, STR_JUST_DATE_LONG); break;
2901  case 1: SetDParam(1, STR_JUST_DATE_TINY); break;
2902  case 2: SetDParam(1, STR_JUST_DATE_ISO); break;
2903  default: NOT_REACHED();
2904  }
2905  SetDParam(2, _date);
2906 
2907  /* Get the correct string (special string for when there's not company) */
2908  GetString(buf, !Company::IsValidID(cid) ? STR_SAVEGAME_NAME_SPECTATOR : STR_SAVEGAME_NAME_DEFAULT, last);
2909  SanitizeFilename(buf);
2910 }
2911 
2917 {
2919 }
2920 
2928 {
2929  if (aft == FT_INVALID || aft == FT_NONE) {
2930  this->file_op = SLO_INVALID;
2931  this->detail_ftype = DFT_INVALID;
2932  this->abstract_ftype = FT_INVALID;
2933  return;
2934  }
2935 
2936  this->file_op = fop;
2937  this->detail_ftype = dft;
2938  this->abstract_ftype = aft;
2939 }
2940 
2945 void FileToSaveLoad::SetName(const char *name)
2946 {
2947  strecpy(this->name, name, lastof(this->name));
2948 }
2949 
2954 void FileToSaveLoad::SetTitle(const char *title)
2955 {
2956  strecpy(this->title, title, lastof(this->title));
2957 }
2958 
2959 #if 0
2960 
2966 int GetSavegameType(char *file)
2967 {
2968  const SaveLoadFormat *fmt;
2969  uint32 hdr;
2970  FILE *f;
2971  int mode = SL_OLD_LOAD;
2972 
2973  f = fopen(file, "rb");
2974  if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
2975  DEBUG(sl, 0, "Savegame is obsolete or invalid format");
2976  mode = SL_LOAD; // don't try to get filename, just show name as it is written
2977  } else {
2978  /* see if we have any loader for this type. */
2979  for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) {
2980  if (fmt->tag == hdr) {
2981  mode = SL_LOAD; // new type of savegame
2982  break;
2983  }
2984  }
2985  }
2986 
2987  fclose(f);
2988  return mode;
2989 }
2990 #endif