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; gitem_t *item;
int i; int i;
if (!ent)
{
return;
}
if (!ent->classname) if (!ent->classname)
{ {
gi.dprintf ("ED_CallSpawn: NULL classname\n"); gi.dprintf ("ED_CallSpawn: NULL classname\n");
@ -346,6 +351,11 @@ char *ED_NewString (const char *string)
char *newb, *new_p; char *newb, *new_p;
int i,l; int i,l;
if (!string)
{
return NULL;
}
l = strlen(string) + 1; l = strlen(string) + 1;
newb = gi.TagMalloc (l, TAG_LEVEL); newb = gi.TagMalloc (l, TAG_LEVEL);
@ -384,9 +394,14 @@ void ED_ParseField (const char *key, const char *value, edict_t *ent)
float v; float v;
vec3_t vec; vec3_t vec;
if (!ent || !value || !key)
{
return;
}
for (f=fields ; f->name ; f++) for (f=fields ; f->name ; f++)
{ {
if (!Q_stricmp(f->name, key)) if (!(f->flags & FFL_NOSPAWN) && !Q_stricmp(f->name, key))
{ // found it { // found it
if (f->flags & FFL_SPAWNTEMP) if (f->flags & FFL_SPAWNTEMP)
b = (byte *)&st; b = (byte *)&st;
@ -441,6 +456,11 @@ char *ED_ParseEdict (char *data, edict_t *ent)
char keyname[256]; char keyname[256];
const char *com_token; const char *com_token;
if (!ent || !data)
{
return NULL;
}
init = false; init = false;
memset (&st, 0, sizeof(st)); 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); 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; 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 else
{ {
if (((!coop->value) && (ent->spawnflags2 & SPAWNFLAG2_NOT_SINGLE)) || if (((!coop->value) && (ent->spawnflags2 & SPAWNFLAG2_NOT_SINGLE)) ||

View file

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

View file

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

View file

@ -38,6 +38,38 @@
{"origin", FOFS(s.origin), F_VECTOR}, {"origin", FOFS(s.origin), F_VECTOR},
{"angles", FOFS(s.angles), F_VECTOR}, {"angles", FOFS(s.angles), F_VECTOR},
{"angle", FOFS(s.angles), F_ANGLEHACK}, {"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}, {"mangle", FOFS(mangle), F_VECTOR},
{"active", FOFS(active), F_INT}, {"active", FOFS(active), F_INT},
{"spawnflags2", FOFS(spawnflags2), F_INT}, {"spawnflags2", FOFS(spawnflags2), F_INT},