Fix crashes when loading savegame

savegame/tables/fields.h was missing some fields with FFL_NOSPAWN
and FFL_NOSPAWN handling in g_spawn.c was missing

Because of that after loading a savegame some pointers were invalid
and dereferencing them resulted in segfaults.
This commit is contained in:
Daniel Gibson 2015-05-19 04:19:41 +02:00
parent aa5ccc1770
commit 0e4e1b7285
4 changed files with 93 additions and 2 deletions

View file

@ -306,6 +306,11 @@ void ED_CallSpawn (edict_t *ent)
gitem_t *item;
int i;
if (!ent)
{
return;
}
if (!ent->classname)
{
gi.dprintf ("ED_CallSpawn: NULL classname\n");
@ -346,6 +351,11 @@ char *ED_NewString (const char *string)
char *newb, *new_p;
int i,l;
if (!string)
{
return NULL;
}
l = strlen(string) + 1;
newb = gi.TagMalloc (l, TAG_LEVEL);
@ -384,9 +394,14 @@ void ED_ParseField (const char *key, const char *value, edict_t *ent)
float v;
vec3_t vec;
if (!ent || !value || !key)
{
return;
}
for (f=fields ; f->name ; f++)
{
if (!Q_stricmp(f->name, key))
if (!(f->flags & FFL_NOSPAWN) && !Q_stricmp(f->name, key))
{ // found it
if (f->flags & FFL_SPAWNTEMP)
b = (byte *)&st;
@ -441,6 +456,11 @@ char *ED_ParseEdict (char *data, edict_t *ent)
char keyname[256];
const char *com_token;
if (!ent || !data)
{
return NULL;
}
init = false;
memset (&st, 0, sizeof(st));
@ -530,6 +550,8 @@ void G_FindTeams (void)
}
}
// FIXME: DG: G_FixTeams(); like rogue?
gi.dprintf ("%i teams with %i entities\n", c, c2);
}
@ -610,6 +632,32 @@ void SpawnEntities (const char *mapname, char *entities, const char *spawnpoint)
continue;
}
}
#if 0 // FIXME: DG: coop stuff from rogue
else if (coop->value)
{
if (ent->spawnflags & SPAWNFLAG_NOT_COOP)
{
G_FreeEdict(ent);
inhibit++;
continue;
}
/* stuff marked !easy & !med & !hard are coop only, all levels */
if (!((ent->spawnflags & SPAWNFLAG_NOT_EASY) &&
(ent->spawnflags & SPAWNFLAG_NOT_MEDIUM) &&
(ent->spawnflags & SPAWNFLAG_NOT_HARD)))
{
if (((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) ||
((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) ||
(((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD)))
{
G_FreeEdict(ent);
inhibit++;
continue;
}
}
}
#endif // 0
else
{
if (((!coop->value) && (ent->spawnflags2 & SPAWNFLAG2_NOT_SINGLE)) ||

View file

@ -615,6 +615,7 @@ extern cvar_t *bettyammo;
// and saving / loading games
//
#define FFL_SPAWNTEMP 1
#define FFL_NOSPAWN 2
typedef enum {
F_INT,

View file

@ -54,7 +54,7 @@
* in tables/ are changed, otherwise
* strange things may happen.
*/
#define SAVEGAMEVER "YQ2-1"
#define SAVEGAMEVER "YQ2-2"
/*
* This macros are used to
@ -66,8 +66,14 @@
*/
#if defined(__FreeBSD__)
#define OS "FreeBSD"
#elif defined(__APPLE__)
#define OS "MacOS X"
#elif defined(__OpenBSD__)
#define OS "OpenBSD"
#elif defined(__linux__)
#define OS "Linux"
#elif defined(_WIN32)
#define OS "Windows"
#else
#define OS "Unknown"
#endif
@ -76,6 +82,10 @@
#define ARCH "i386"
#elif defined(__x86_64__)
#define ARCH "amd64"
#elif defined(__sparc__)
#define ARCH "sparc64"
#elif defined(__ia64__)
#define ARCH "ia64"
#else
#define ARCH "unknown"
#endif

View file

@ -38,6 +38,38 @@
{"origin", FOFS(s.origin), F_VECTOR},
{"angles", FOFS(s.angles), F_VECTOR},
{"angle", FOFS(s.angles), F_ANGLEHACK},
{"goalentity", FOFS(goalentity), F_EDICT, FFL_NOSPAWN},
{"movetarget", FOFS(movetarget), F_EDICT, FFL_NOSPAWN},
{"enemy", FOFS(enemy), F_EDICT, FFL_NOSPAWN},
{"oldenemy", FOFS(oldenemy), F_EDICT, FFL_NOSPAWN},
{"activator", FOFS(activator), F_EDICT, FFL_NOSPAWN},
{"groundentity", FOFS(groundentity), F_EDICT, FFL_NOSPAWN},
{"teamchain", FOFS(teamchain), F_EDICT, FFL_NOSPAWN},
{"teammaster", FOFS(teammaster), F_EDICT, FFL_NOSPAWN},
{"owner", FOFS(owner), F_EDICT, FFL_NOSPAWN},
{"mynoise", FOFS(mynoise), F_EDICT, FFL_NOSPAWN},
{"mynoise2", FOFS(mynoise2), F_EDICT, FFL_NOSPAWN},
{"target_ent", FOFS(target_ent), F_EDICT, FFL_NOSPAWN},
{"chain", FOFS(chain), F_EDICT, FFL_NOSPAWN},
{"prethink", FOFS(prethink), F_FUNCTION, FFL_NOSPAWN},
{"think", FOFS(think), F_FUNCTION, FFL_NOSPAWN},
{"blocked", FOFS(blocked), F_FUNCTION, FFL_NOSPAWN},
{"touch", FOFS(touch), F_FUNCTION, FFL_NOSPAWN},
{"use", FOFS(use), F_FUNCTION, FFL_NOSPAWN},
{"pain", FOFS(pain), F_FUNCTION, FFL_NOSPAWN},
{"die", FOFS(die), F_FUNCTION, FFL_NOSPAWN},
{"stand", FOFS(monsterinfo.stand), F_FUNCTION, FFL_NOSPAWN},
{"idle", FOFS(monsterinfo.idle), F_FUNCTION, FFL_NOSPAWN},
{"search", FOFS(monsterinfo.search), F_FUNCTION, FFL_NOSPAWN},
{"walk", FOFS(monsterinfo.walk), F_FUNCTION, FFL_NOSPAWN},
{"run", FOFS(monsterinfo.run), F_FUNCTION, FFL_NOSPAWN},
{"dodge", FOFS(monsterinfo.dodge), F_FUNCTION, FFL_NOSPAWN},
{"attack", FOFS(monsterinfo.attack), F_FUNCTION, FFL_NOSPAWN},
{"melee", FOFS(monsterinfo.melee), F_FUNCTION, FFL_NOSPAWN},
{"sight", FOFS(monsterinfo.sight), F_FUNCTION, FFL_NOSPAWN},
{"checkattack", FOFS(monsterinfo.checkattack), F_FUNCTION, FFL_NOSPAWN},
{"currentmove", FOFS(monsterinfo.currentmove), F_MMOVE, FFL_NOSPAWN},
{"endfunc", FOFS(moveinfo.endfunc), F_FUNCTION, FFL_NOSPAWN},
{"mangle", FOFS(mangle), F_VECTOR},
{"active", FOFS(active), F_INT},
{"spawnflags2", FOFS(spawnflags2), F_INT},