Quake II RTX doxygen  1.0 dev
save.c File Reference
#include "server.h"

Go to the source code of this file.

Macros

#define SAVE_MAGIC1   (('2'<<24)|('V'<<16)|('S'<<8)|'S')
 
#define SAVE_MAGIC2   (('2'<<24)|('V'<<16)|('A'<<8)|'S')
 
#define SAVE_VERSION   1
 
#define SAVE_CURRENT   ".current"
 
#define SAVE_AUTO   "save0"
 

Functions

static int write_server_file (qboolean autosave)
 
static int write_level_file (void)
 
static int copy_file (const char *src, const char *dst, const char *name)
 
static int remove_file (const char *dir, const char *name)
 
static void ** list_save_dir (const char *dir, int *count)
 
static int wipe_save_dir (const char *dir)
 
static int copy_save_dir (const char *src, const char *dst)
 
static int read_binary_file (const char *name)
 
char * SV_GetSaveInfo (const char *dir)
 
static void abort_func (void *arg)
 
static int read_server_file (void)
 
static int read_level_file (void)
 
int SV_NoSaveGames (void)
 
void SV_AutoSaveBegin (mapcmd_t *cmd)
 
void SV_AutoSaveEnd (void)
 
void SV_CheckForSavegame (mapcmd_t *cmd)
 
static void SV_Savegame_c (genctx_t *ctx, int argnum)
 
static void SV_Loadgame_f (void)
 
static void SV_Savegame_f (void)
 
void SV_RegisterSavegames (void)
 

Variables

cvar_t * sv_savedir = NULL
 
static const cmdreg_t c_savegames []
 

Macro Definition Documentation

◆ SAVE_AUTO

#define SAVE_AUTO   "save0"

Definition at line 26 of file save.c.

◆ SAVE_CURRENT

#define SAVE_CURRENT   ".current"

Definition at line 25 of file save.c.

◆ SAVE_MAGIC1

#define SAVE_MAGIC1   (('2'<<24)|('V'<<16)|('S'<<8)|'S')

Definition at line 21 of file save.c.

◆ SAVE_MAGIC2

#define SAVE_MAGIC2   (('2'<<24)|('V'<<16)|('A'<<8)|'S')

Definition at line 22 of file save.c.

◆ SAVE_VERSION

#define SAVE_VERSION   1

Definition at line 23 of file save.c.

Function Documentation

◆ abort_func()

static void abort_func ( void arg)
static

Definition at line 311 of file save.c.

312 {
313  CM_FreeMap(arg);
314 }

Referenced by read_server_file().

◆ copy_file()

static int copy_file ( const char *  src,
const char *  dst,
const char *  name 
)
static

Definition at line 139 of file save.c.

140 {
141  char path[MAX_OSPATH];
142  byte buf[0x10000];
143  FILE *ifp, *ofp;
144  size_t len, res;
145  int ret = -1;
146 
147  len = Q_snprintf(path, MAX_OSPATH, "%s/%s/%s/%s", fs_gamedir, sv_savedir->string, src, name);
148  if (len >= MAX_OSPATH)
149  goto fail0;
150 
151  ifp = fopen(path, "rb");
152  if (!ifp)
153  goto fail0;
154 
155  len = Q_snprintf(path, MAX_OSPATH, "%s/%s/%s/%s", fs_gamedir, sv_savedir->string, dst, name);
156  if (len >= MAX_OSPATH)
157  goto fail1;
158 
159  if (FS_CreatePath(path))
160  goto fail1;
161 
162  ofp = fopen(path, "wb");
163  if (!ofp)
164  goto fail1;
165 
166  do {
167  len = fread(buf, 1, sizeof(buf), ifp);
168  res = fwrite(buf, 1, len, ofp);
169  } while (len == sizeof(buf) && res == len);
170 
171  if (ferror(ifp))
172  goto fail2;
173 
174  if (ferror(ofp))
175  goto fail2;
176 
177  ret = 0;
178 fail2:
179  fclose(ofp);
180 fail1:
181  fclose(ifp);
182 fail0:
183  return ret;
184 }

Referenced by copy_save_dir().

◆ copy_save_dir()

static int copy_save_dir ( const char *  src,
const char *  dst 
)
static

Definition at line 219 of file save.c.

220 {
221  void **list;
222  int i, count, ret = 0;
223 
224  if ((list = list_save_dir(src, &count)) == NULL)
225  return -1;
226 
227  for (i = 0; i < count; i++)
228  ret |= copy_file(src, dst, list[i]);
229 
230  FS_FreeList(list);
231  return ret;
232 }

Referenced by SV_AutoSaveEnd(), SV_Loadgame_f(), and SV_Savegame_f().

◆ list_save_dir()

static void** list_save_dir ( const char *  dir,
int count 
)
static

Definition at line 198 of file save.c.

199 {
200  return FS_ListFiles(va("%s/%s", sv_savedir->string, dir), ".ssv;.sav;.sv2",
201  FS_TYPE_REAL | FS_PATH_GAME, count);
202 }

Referenced by copy_save_dir(), and wipe_save_dir().

◆ read_binary_file()

static int read_binary_file ( const char *  name)
static

Definition at line 234 of file save.c.

235 {
236  qhandle_t f;
237  size_t len;
238 
239  len = FS_FOpenFile(name, &f, FS_MODE_READ | FS_TYPE_REAL | FS_PATH_GAME);
240  if (!f)
241  return -1;
242 
243  if (len > MAX_MSGLEN)
244  goto fail;
245 
246  if (FS_Read(msg_read_buffer, len, f) != len)
247  goto fail;
248 
250  msg_read.cursize = len;
251 
252  FS_FCloseFile(f);
253  return 0;
254 
255 fail:
256  FS_FCloseFile(f);
257  return -1;
258 }

Referenced by read_level_file(), read_server_file(), and SV_GetSaveInfo().

◆ read_level_file()

static int read_level_file ( void  )
static

Definition at line 403 of file save.c.

404 {
405  char name[MAX_OSPATH];
406  size_t len, maxlen;
407  int index;
408 
409  len = Q_snprintf(name, MAX_QPATH, "%s/%s/%s.sv2", sv_savedir->string, SAVE_CURRENT, sv.name);
410  if (len >= MAX_QPATH)
411  return -1;
412 
413  if (read_binary_file(name))
414  return -1;
415 
416  if (MSG_ReadLong() != SAVE_MAGIC2)
417  return -1;
418 
419  if (MSG_ReadLong() != SAVE_VERSION)
420  return -1;
421 
422  // any error will drop from this point
423 
424  // the rest can't underflow
425  msg_read.allowunderflow = qfalse;
426 
427  // read all configstrings
428  while (1) {
429  index = MSG_ReadShort();
430  if (index == MAX_CONFIGSTRINGS)
431  break;
432 
433  if (index < 0 || index > MAX_CONFIGSTRINGS)
434  Com_Error(ERR_DROP, "Bad savegame configstring index");
435 
436  maxlen = CS_SIZE(index);
437  len = MSG_ReadString(sv.configstrings[index], maxlen);
438  if (len >= maxlen)
439  Com_Error(ERR_DROP, "Savegame configstring too long");
440  }
441 
442  len = MSG_ReadByte();
443  if (len > MAX_MAP_PORTAL_BYTES)
444  Com_Error(ERR_DROP, "Savegame portalbits too long");
445 
446  SV_ClearWorld();
447 
448  CM_SetPortalStates(&sv.cm, MSG_ReadData(len), len);
449 
450  // read game level
451  len = Q_snprintf(name, MAX_OSPATH, "%s/%s/%s/%s.sav",
453  if (len >= MAX_OSPATH)
454  Com_Error(ERR_DROP, "Savegame path too long");
455 
456  ge->ReadLevel(name);
457  return 0;
458 }

Referenced by SV_CheckForSavegame().

◆ read_server_file()

static int read_server_file ( void  )
static

Definition at line 316 of file save.c.

317 {
318  char name[MAX_OSPATH], string[MAX_STRING_CHARS];
319  mapcmd_t cmd;
320  size_t len;
321 
322  // errors like missing file, bad version, etc are
323  // non-fatal and just return to the command handler
324 
325  Q_snprintf(name, MAX_OSPATH, "%s/%s/server.ssv", sv_savedir->string, SAVE_CURRENT);
326  if (read_binary_file(name))
327  return -1;
328 
329  if (MSG_ReadLong() != SAVE_MAGIC1)
330  return -1;
331 
332  if (MSG_ReadLong() != SAVE_VERSION)
333  return -1;
334 
335  memset(&cmd, 0, sizeof(cmd));
336 
337  // read the comment field
338  MSG_ReadLong();
339  MSG_ReadLong();
340  if (MSG_ReadByte())
341  cmd.loadgame = 2; // autosave
342  else
343  cmd.loadgame = 1; // regular savegame
344  MSG_ReadString(NULL, 0);
345 
346  // read the mapcmd
347  len = MSG_ReadString(cmd.buffer, sizeof(cmd.buffer));
348  if (len >= sizeof(cmd.buffer))
349  return -1;
350 
351  // now try to load the map
352  if (!SV_ParseMapCmd(&cmd))
353  return -1;
354 
355  // save pending CM to be freed later if ERR_DROP is thrown
356  Com_AbortFunc(abort_func, &cmd.cm);
357 
358  // any error will drop from this point
359  SV_Shutdown("Server restarted\n", ERR_RECONNECT);
360 
361  // the rest can't underflow
362  msg_read.allowunderflow = qfalse;
363 
364  // read all CVAR_LATCH cvars
365  // these will be things like coop, skill, deathmatch, etc
366  while (1) {
367  len = MSG_ReadString(name, MAX_QPATH);
368  if (!len)
369  break;
370  if (len >= MAX_QPATH)
371  Com_Error(ERR_DROP, "Savegame cvar name too long");
372 
373  len = MSG_ReadString(string, sizeof(string));
374  if (len >= sizeof(string))
375  Com_Error(ERR_DROP, "Savegame cvar value too long");
376 
377  Cvar_UserSet(name, string);
378  }
379 
380  // start a new game fresh with new cvars
382 
383  // error out immediately if game doesn't support safe savegames
384  if (!(g_features->integer & GMF_ENHANCED_SAVEGAMES))
385  Com_Error(ERR_DROP, "Game does not support enhanced savegames");
386 
387  // read game state
388  len = Q_snprintf(name, MAX_OSPATH,
389  "%s/%s/%s/game.ssv", fs_gamedir, sv_savedir->string, SAVE_CURRENT);
390  if (len >= MAX_OSPATH)
391  Com_Error(ERR_DROP, "Savegame path too long");
392 
393  ge->ReadGame(name);
394 
395  // clear pending CM
396  Com_AbortFunc(NULL, NULL);
397 
398  // go to the map
399  SV_SpawnServer(&cmd);
400  return 0;
401 }

Referenced by SV_Loadgame_f().

◆ remove_file()

static int remove_file ( const char *  dir,
const char *  name 
)
static

Definition at line 186 of file save.c.

187 {
188  char path[MAX_OSPATH];
189  size_t len;
190 
191  len = Q_snprintf(path, MAX_OSPATH, "%s/%s/%s/%s", fs_gamedir, sv_savedir->string, dir, name);
192  if (len >= MAX_OSPATH)
193  return -1;
194 
195  return remove(path);
196 }

Referenced by wipe_save_dir().

◆ SV_AutoSaveBegin()

void SV_AutoSaveBegin ( mapcmd_t cmd)

Definition at line 474 of file save.c.

475 {
476  byte bitmap[MAX_CLIENTS / CHAR_BIT];
477  edict_t *ent;
478  int i;
479 
480  // check for clearing the current savegame
481  if (cmd->endofunit) {
483  return;
484  }
485 
486  if (sv.state != ss_game)
487  return;
488 
489  if (SV_NoSaveGames())
490  return;
491 
492  memset(bitmap, 0, sizeof(bitmap));
493 
494  // clear all the client inuse flags before saving so that
495  // when the level is re-entered, the clients will spawn
496  // at spawn points instead of occupying body shells
497  for (i = 0; i < sv_maxclients->integer; i++) {
498  ent = EDICT_NUM(i + 1);
499  if (ent->inuse) {
500  Q_SetBit(bitmap, i);
501  ent->inuse = qfalse;
502  }
503  }
504 
505  // save the map just exited
506  if (write_level_file())
507  Com_EPrintf("Couldn't write level file.\n");
508 
509  // we must restore these for clients to transfer over correctly
510  for (i = 0; i < sv_maxclients->integer; i++) {
511  ent = EDICT_NUM(i + 1);
512  ent->inuse = Q_IsBitSet(bitmap, i);
513  }
514 }

Referenced by SV_Map().

◆ SV_AutoSaveEnd()

void SV_AutoSaveEnd ( void  )

Definition at line 516 of file save.c.

517 {
518  if (sv.state != ss_game)
519  return;
520 
521  if (SV_NoSaveGames())
522  return;
523 
524  // save the map just entered to include the player position (client edict shell)
525  if (write_level_file())
526  {
527  Com_EPrintf("Couldn't write level file.\n");
528  return;
529  }
530 
531  // save server state
532  if (write_server_file(qtrue)) {
533  Com_EPrintf("Couldn't write server file.\n");
534  return;
535  }
536 
537  // clear whatever savegames are there
538  if (wipe_save_dir(SAVE_AUTO)) {
539  Com_EPrintf("Couldn't wipe '%s' directory.\n", SAVE_AUTO);
540  return;
541  }
542 
543  // copy off the level to the autosave slot
545  Com_EPrintf("Couldn't write '%s' directory.\n", SAVE_AUTO);
546  return;
547  }
548 }

Referenced by SV_Begin_f(), and SV_Map().

◆ SV_CheckForSavegame()

void SV_CheckForSavegame ( mapcmd_t cmd)

Definition at line 550 of file save.c.

551 {
552  if (SV_NoSaveGames())
553  return;
554 
555  if (read_level_file()) {
556  // only warn when loading a regular savegame. autosave without level
557  // file is ok and simply starts the map from the beginning.
558  if (cmd->loadgame == 1)
559  Com_EPrintf("Couldn't read level file.\n");
560  return;
561  }
562 
563  if (cmd->loadgame) {
564  // called from SV_Loadgame_f
565  ge->RunFrame();
566  ge->RunFrame();
567  } else {
568  int i;
569 
570  // coming back to a level after being in a different
571  // level, so run it for ten seconds
572  for (i = 0; i < 100; i++)
573  ge->RunFrame();
574  }
575 }

Referenced by SV_SpawnServer().

◆ SV_GetSaveInfo()

char* SV_GetSaveInfo ( const char *  dir)

Definition at line 260 of file save.c.

261 {
262  char name[MAX_QPATH], date[MAX_QPATH];
263  size_t len;
264  uint64_t timestamp;
265  int autosave, year;
266  time_t t;
267  struct tm *tm;
268 
269  len = Q_snprintf(name, MAX_QPATH, "%s/%s/server.ssv", sv_savedir->string, dir);
270  if (len >= MAX_QPATH)
271  return NULL;
272 
273  if (read_binary_file(name))
274  return NULL;
275 
276  if (MSG_ReadLong() != SAVE_MAGIC1)
277  return NULL;
278 
279  if (MSG_ReadLong() != SAVE_VERSION)
280  return NULL;
281 
282  // read the comment field
283  timestamp = (uint64_t)MSG_ReadLong();
284  timestamp |= (uint64_t)MSG_ReadLong() << 32;
285  autosave = MSG_ReadByte();
286  MSG_ReadString(name, sizeof(name));
287 
288  if (autosave)
289  return Z_CopyString(va("ENTERING %s", name));
290 
291  // get current year
292  t = time(NULL);
293  tm = localtime(&t);
294  year = tm ? tm->tm_year : -1;
295 
296  // format savegame date
297  t = (time_t)timestamp;
298  len = 0;
299  if ((tm = localtime(&t)) != NULL) {
300  if (tm->tm_year == year)
301  len = strftime(date, sizeof(date), "%b %d %H:%M", tm);
302  else
303  len = strftime(date, sizeof(date), "%b %d %Y", tm);
304  }
305  if (!len)
306  strcpy(date, "???");
307 
308  return Z_CopyString(va("%s %s", date, name));
309 }

Referenced by Savegame_Push().

◆ SV_Loadgame_f()

static void SV_Loadgame_f ( void  )
static

Definition at line 584 of file save.c.

585 {
586  char *dir;
587 
588  if (Cmd_Argc() != 2) {
589  Com_Printf("Usage: %s <directory>\n", Cmd_Argv(0));
590  return;
591  }
592 
593  if (dedicated->integer) {
594  Com_Printf("Savegames are for listen servers only.\n");
595  return;
596  }
597 
598  dir = Cmd_Argv(1);
599  if (!COM_IsPath(dir)) {
600  Com_Printf("Bad savedir.\n");
601  return;
602  }
603 
604  // make sure the server files exist
605  if (!FS_FileExistsEx(va("%s/%s/server.ssv", sv_savedir->string, dir), FS_TYPE_REAL | FS_PATH_GAME) ||
606  !FS_FileExistsEx(va("%s/%s/game.ssv", sv_savedir->string, dir), FS_TYPE_REAL | FS_PATH_GAME)) {
607  Com_Printf ("No such savegame: %s\n", dir);
608  return;
609  }
610 
611  // clear whatever savegames are there
613  Com_Printf("Couldn't wipe '%s' directory.\n", SAVE_CURRENT);
614  return;
615  }
616 
617  // copy it off
618  if (copy_save_dir(dir, SAVE_CURRENT)) {
619  Com_Printf("Couldn't read '%s' directory.\n", dir);
620  return;
621  }
622 
623  // read server state
624  if (read_server_file()) {
625  Com_Printf("Couldn't read server file.\n");
626  return;
627  }
628 }

◆ SV_NoSaveGames()

int SV_NoSaveGames ( void  )

Definition at line 460 of file save.c.

461 {
462  if (dedicated->integer && !Cvar_VariableInteger("coop"))
463  return 1;
464 
465  if (!(g_features->integer & GMF_ENHANCED_SAVEGAMES))
466  return 1;
467 
468  if (Cvar_VariableInteger("deathmatch"))
469  return 1;
470 
471  return 0;
472 }

Referenced by SV_AutoSaveBegin(), SV_AutoSaveEnd(), SV_CheckForSavegame(), SV_Map(), and SV_SpawnServer().

◆ SV_RegisterSavegames()

void SV_RegisterSavegames ( void  )

Definition at line 706 of file save.c.

707 {
709  sv_savedir = Cvar_Get("sv_savedir", "save", 0);
710 }

Referenced by SV_Init().

◆ SV_Savegame_c()

static void SV_Savegame_c ( genctx_t *  ctx,
int  argnum 
)
static

Definition at line 577 of file save.c.

578 {
579  if (argnum == 1) {
580  FS_File_g("save", NULL, FS_SEARCH_DIRSONLY | FS_TYPE_REAL | FS_PATH_GAME, ctx);
581  }
582 }

◆ SV_Savegame_f()

static void SV_Savegame_f ( void  )
static

Definition at line 630 of file save.c.

631 {
632  char *dir;
633 
634  if (sv.state != ss_game) {
635  Com_Printf("You must be in a game to save.\n");
636  return;
637  }
638 
639  if (dedicated->integer) {
640  Com_Printf("Savegames are for listen servers only.\n");
641  return;
642  }
643 
644  // don't bother saving if we can't read them back!
645  if (!(g_features->integer & GMF_ENHANCED_SAVEGAMES)) {
646  Com_Printf("Game does not support enhanced savegames.\n");
647  return;
648  }
649 
650  if (Cvar_VariableInteger("deathmatch")) {
651  Com_Printf("Can't savegame in a deathmatch.\n");
652  return;
653  }
654 
655  if (sv_maxclients->integer == 1 && svs.client_pool[0].edict->client->ps.stats[STAT_HEALTH] <= 0) {
656  Com_Printf("Can't savegame while dead!\n");
657  return;
658  }
659 
660  if (Cmd_Argc() != 2) {
661  Com_Printf("Usage: %s <directory>\n", Cmd_Argv(0));
662  return;
663  }
664 
665  dir = Cmd_Argv(1);
666  if (!COM_IsPath(dir)) {
667  Com_Printf("Bad savedir.\n");
668  return;
669  }
670 
671  // archive current level, including all client edicts.
672  // when the level is reloaded, they will be shells awaiting
673  // a connecting client
674  if (write_level_file()) {
675  Com_Printf("Couldn't write level file.\n");
676  return;
677  }
678 
679  // save server state
680  if (write_server_file(qfalse)) {
681  Com_Printf("Couldn't write server file.\n");
682  return;
683  }
684 
685  // clear whatever savegames are there
686  if (wipe_save_dir(dir)) {
687  Com_Printf("Couldn't wipe '%s' directory.\n", dir);
688  return;
689  }
690 
691  // copy it off
692  if (copy_save_dir(SAVE_CURRENT, dir)) {
693  Com_Printf("Couldn't write '%s' directory.\n", dir);
694  return;
695  }
696 
697  Com_Printf("Game saved.\n");
698 }

◆ wipe_save_dir()

static int wipe_save_dir ( const char *  dir)
static

Definition at line 204 of file save.c.

205 {
206  void **list;
207  int i, count, ret = 0;
208 
209  if ((list = list_save_dir(dir, &count)) == NULL)
210  return 0;
211 
212  for (i = 0; i < count; i++)
213  ret |= remove_file(dir, list[i]);
214 
215  FS_FreeList(list);
216  return ret;
217 }

Referenced by SV_AutoSaveBegin(), SV_AutoSaveEnd(), SV_Loadgame_f(), and SV_Savegame_f().

◆ write_level_file()

static int write_level_file ( void  )
static

Definition at line 85 of file save.c.

86 {
87  char name[MAX_OSPATH];
88  int i;
89  char *s;
90  size_t len;
91  byte portalbits[MAX_MAP_PORTAL_BYTES];
92  qerror_t ret;
93 
94  // write magic
97 
98  // write configstrings
99  for (i = 0; i < MAX_CONFIGSTRINGS; i++) {
100  s = sv.configstrings[i];
101  if (!s[0])
102  continue;
103 
104  len = strlen(s);
105  if (len > MAX_QPATH)
106  len = MAX_QPATH;
107 
108  MSG_WriteShort(i);
109  MSG_WriteData(s, len);
110  MSG_WriteByte(0);
111  }
112  MSG_WriteShort(MAX_CONFIGSTRINGS);
113 
114  len = CM_WritePortalBits(&sv.cm, portalbits);
115  MSG_WriteByte(len);
116  MSG_WriteData(portalbits, len);
117 
118  len = Q_snprintf(name, MAX_QPATH, "%s/%s/%s.sv2", sv_savedir->string, SAVE_CURRENT, sv.name);
119  if (len >= MAX_QPATH)
120  ret = -1;
121  else
122  ret = FS_WriteFile(name, msg_write.data, msg_write.cursize);
123 
125 
126  if (ret < 0)
127  return -1;
128 
129  // write game level
130  len = Q_snprintf(name, MAX_OSPATH,
131  "%s/%s/%s/%s.sav", fs_gamedir, sv_savedir->string, SAVE_CURRENT, sv.name);
132  if (len >= MAX_OSPATH)
133  return -1;
134 
135  ge->WriteLevel(name);
136  return 0;
137 }

Referenced by SV_AutoSaveBegin(), SV_AutoSaveEnd(), and SV_Savegame_f().

◆ write_server_file()

static int write_server_file ( qboolean  autosave)
static

Definition at line 31 of file save.c.

32 {
33  char name[MAX_OSPATH];
34  cvar_t *var;
35  size_t len;
36  qerror_t ret;
37  uint64_t timestamp;
38 
39  // write magic
42 
43  timestamp = (uint64_t)time(NULL);
44 
45  // write the comment field
46  MSG_WriteLong(timestamp & 0xffffffff);
47  MSG_WriteLong(timestamp >> 32);
48  MSG_WriteByte(autosave);
50 
51  // write the mapcmd
53 
54  // write all CVAR_LATCH cvars
55  // these will be things like coop, skill, deathmatch, etc
56  for (var = cvar_vars; var; var = var->next) {
57  if (!(var->flags & CVAR_LATCH))
58  continue;
59  if (var->flags & CVAR_PRIVATE)
60  continue;
61  MSG_WriteString(var->name);
62  MSG_WriteString(var->string);
63  }
64  MSG_WriteString(NULL);
65 
66  // write server state
67  Q_snprintf(name, MAX_OSPATH, "%s/%s/server.ssv", sv_savedir->string, SAVE_CURRENT);
68  ret = FS_WriteFile(name, msg_write.data, msg_write.cursize);
69 
71 
72  if (ret < 0)
73  return -1;
74 
75  // write game state
76  len = Q_snprintf(name, MAX_OSPATH,
77  "%s/%s/%s/game.ssv", fs_gamedir, sv_savedir->string, SAVE_CURRENT);
78  if (len >= MAX_OSPATH)
79  return -1;
80 
81  ge->WriteGame(name, autosave);
82  return 0;
83 }

Referenced by SV_AutoSaveEnd(), and SV_Savegame_f().

Variable Documentation

◆ c_savegames

const cmdreg_t c_savegames[]
static
Initial value:
= {
{ NULL }
}

Definition at line 700 of file save.c.

Referenced by SV_RegisterSavegames().

◆ sv_savedir

SAVE_MAGIC2
#define SAVE_MAGIC2
Definition: save.c:22
SV_Shutdown
void SV_Shutdown(const char *finalmsg, error_type_t type)
Definition: main.c:2252
MVD_SPAWN_DISABLED
#define MVD_SPAWN_DISABLED
Definition: server.h:94
cvar_vars
cvar_t * cvar_vars
Definition: cvar.c:30
CM_FreeMap
void CM_FreeMap(cm_t *cm)
Definition: cmodel.c:47
msg_read
sizebuf_t msg_read
Definition: msg.c:37
msg_read_buffer
byte msg_read_buffer[MAX_MSGLEN]
Definition: msg.c:38
svs
server_static_t svs
Definition: init.c:21
Q_snprintf
size_t Q_snprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:846
FS_Read
ssize_t FS_Read(void *buf, size_t len, qhandle_t f)
Definition: files.c:1547
COM_IsPath
qboolean COM_IsPath(const char *s)
Definition: shared.c:348
c_savegames
static const cmdreg_t c_savegames[]
Definition: save.c:700
copy_save_dir
static int copy_save_dir(const char *src, const char *dst)
Definition: save.c:219
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
FS_FreeList
void FS_FreeList(void **list)
Definition: files.c:2939
SV_ClearWorld
void SV_ClearWorld(void)
Definition: world.c:101
Com_AbortFunc
void Com_AbortFunc(void(*func)(void *), void *arg)
Definition: common.c:588
server_t::mapcmd
char mapcmd[MAX_QPATH]
Definition: server.h:158
read_level_file
static int read_level_file(void)
Definition: save.c:403
FS_WriteFile
qerror_t FS_WriteFile(const char *path, const void *data, size_t len)
Definition: files.c:1932
SAVE_MAGIC1
#define SAVE_MAGIC1
Definition: save.c:21
MSG_WriteByte
void MSG_WriteByte(int c)
Definition: msg.c:107
Cmd_Argv
char * Cmd_Argv(int arg)
Definition: cmd.c:899
SZ_Init
void SZ_Init(sizebuf_t *buf, void *data, size_t size)
Definition: sizebuf.c:31
SAVE_AUTO
#define SAVE_AUTO
Definition: save.c:26
sv_savedir
cvar_t * sv_savedir
Definition: save.c:28
Cmd_Argc
int Cmd_Argc(void)
Definition: cmd.c:889
mapcmd_t::loadgame
int loadgame
Definition: server.h:442
SV_Savegame_f
static void SV_Savegame_f(void)
Definition: save.c:630
wipe_save_dir
static int wipe_save_dir(const char *dir)
Definition: save.c:204
FS_FOpenFile
ssize_t FS_FOpenFile(const char *name, qhandle_t *f, unsigned mode)
Definition: files.c:1692
Com_Error
void Com_Error(error_type_t type, const char *fmt,...)
Definition: g_main.c:258
dedicated
cvar_t * dedicated
Definition: g_main.c:46
MSG_ReadData
byte * MSG_ReadData(size_t len)
Definition: msg.c:1443
sv
server_t sv
Definition: init.c:22
SV_ParseMapCmd
qboolean SV_ParseMapCmd(mapcmd_t *cmd)
Definition: init.c:285
msg_write
sizebuf_t msg_write
Definition: msg.c:34
SV_SpawnServer
void SV_SpawnServer(mapcmd_t *cmd)
Definition: init.c:139
copy_file
static int copy_file(const char *src, const char *dst, const char *name)
Definition: save.c:139
va
char * va(const char *format,...)
Definition: shared.c:429
FS_File_g
void FS_File_g(const char *path, const char *ext, unsigned flags, genctx_t *ctx)
Definition: files.c:2954
server_static_s::client_pool
client_t * client_pool
Definition: server.h:456
remove_file
static int remove_file(const char *dir, const char *name)
Definition: save.c:186
CM_WritePortalBits
int CM_WritePortalBits(cm_t *cm, byte *buffer)
Definition: cmodel.c:955
Cmd_Register
void Cmd_Register(const cmdreg_t *reg)
Definition: cmd.c:1572
MSG_ReadLong
int MSG_ReadLong(void)
Definition: msg.c:1517
FS_ListFiles
void ** FS_ListFiles(const char *path, const char *filter, unsigned flags, int *count_p)
Definition: files.c:2716
SV_Loadgame_f
static void SV_Loadgame_f(void)
Definition: save.c:584
write_server_file
static int write_server_file(qboolean autosave)
Definition: save.c:31
read_server_file
static int read_server_file(void)
Definition: save.c:316
Cvar_VariableInteger
int Cvar_VariableInteger(const char *var_name)
Definition: cvar.c:105
MSG_WriteShort
void MSG_WriteShort(int c)
Definition: msg.c:125
ge
game_export_t * ge
Definition: game.c:22
mapcmd_t
Definition: server.h:437
SAVE_VERSION
#define SAVE_VERSION
Definition: save.c:23
Cvar_UserSet
cvar_t * Cvar_UserSet(const char *var_name, const char *value)
Definition: cvar.c:476
abort_func
static void abort_func(void *arg)
Definition: save.c:311
server_t::cm
cm_t cm
Definition: server.h:161
MSG_WriteString
void MSG_WriteString(const char *string)
Definition: msg.c:160
mapcmd_t::cm
cm_t cm
Definition: server.h:444
mapcmd_t::endofunit
qboolean endofunit
Definition: server.h:443
MSG_WriteLong
void MSG_WriteLong(int c)
Definition: msg.c:144
SV_Savegame_c
static void SV_Savegame_c(genctx_t *ctx, int argnum)
Definition: save.c:577
SAVE_CURRENT
#define SAVE_CURRENT
Definition: save.c:25
SV_InitGame
void SV_InitGame(unsigned mvd_spawn)
Definition: init.c:361
g_features
cvar_t * g_features
Definition: main.c:99
MSG_ReadString
size_t MSG_ReadString(char *dest, size_t size)
Definition: msg.c:1531
server_t::state
server_state_t state
Definition: server.h:146
mapcmd_t::buffer
char buffer[MAX_QPATH]
Definition: server.h:438
SV_NoSaveGames
int SV_NoSaveGames(void)
Definition: save.c:460
FS_CreatePath
qerror_t FS_CreatePath(char *path)
Definition: files.c:605
FS_FCloseFile
void FS_FCloseFile(qhandle_t f)
Definition: files.c:759
MSG_ReadByte
int MSG_ReadByte(void)
Definition: msg.c:1475
EDICT_NUM
#define EDICT_NUM(n)
Definition: server.h:173
server_t::configstrings
char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH]
Definition: server.h:164
write_level_file
static int write_level_file(void)
Definition: save.c:85
list_save_dir
static void ** list_save_dir(const char *dir, int *count)
Definition: save.c:198
CM_SetPortalStates
void CM_SetPortalStates(cm_t *cm, byte *buffer, int bytes)
Definition: cmodel.c:982
fs_gamedir
char fs_gamedir[MAX_OSPATH]
Definition: files.c:171
read_binary_file
static int read_binary_file(const char *name)
Definition: save.c:234
server_t::name
char name[MAX_QPATH]
Definition: server.h:160
SZ_Clear
void SZ_Clear(sizebuf_t *buf)
Definition: sizebuf.c:40
MSG_ReadShort
int MSG_ReadShort(void)
Definition: msg.c:1489
client_s::edict
edict_t * edict
Definition: server.h:261
sv_maxclients
cvar_t * sv_maxclients
Definition: main.c:58