2
0
mirror of https://github.com/rehlds/rehlds.git synced 2025-01-01 01:25:38 +03:00

Allow to modify triggers collection while iterating it (prevent crash).

This commit is contained in:
Lev 2017-03-19 08:00:58 +05:00
parent f943efbbfa
commit 48bb47d2dc
5 changed files with 52 additions and 32 deletions

View File

@ -113,7 +113,7 @@ void EXT_FUNC SetMinMaxSize(edict_t *e, const float *min, const float *max, qboo
e->v.size[0] = max[0] - min[0]; e->v.size[0] = max[0] - min[0];
e->v.size[1] = max[1] - min[1]; e->v.size[1] = max[1] - min[1];
e->v.size[2] = max[2] - min[2]; e->v.size[2] = max[2] - min[2];
SV_LinkEdict(e, 0); SV_LinkEdict(e, FALSE);
} }
void EXT_FUNC PF_setsize_I(edict_t *e, const float *rgflMin, const float *rgflMax) void EXT_FUNC PF_setsize_I(edict_t *e, const float *rgflMin, const float *rgflMax)
@ -1687,7 +1687,7 @@ int EXT_FUNC PF_droptofloor_I(edict_t *ent)
ent->v.origin[0] = trace.endpos[0]; ent->v.origin[0] = trace.endpos[0];
ent->v.origin[1] = trace.endpos[1]; ent->v.origin[1] = trace.endpos[1];
ent->v.origin[2] = trace.endpos[2]; ent->v.origin[2] = trace.endpos[2];
SV_LinkEdict(ent, 0); SV_LinkEdict(ent, FALSE);
ent->v.flags |= FL_ONGROUND; ent->v.flags |= FL_ONGROUND;
ent->v.groundentity = trace.ent; ent->v.groundentity = trace.ent;

View File

@ -147,7 +147,7 @@ qboolean SV_movetest(edict_t *ent, vec_t *move, qboolean relink)
ent->v.origin[1] = ent->v.origin[1] + move[1]; ent->v.origin[1] = ent->v.origin[1] + move[1];
ent->v.origin[2] = ent->v.origin[2] + move[2]; ent->v.origin[2] = ent->v.origin[2] + move[2];
if (relink) if (relink)
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
ent->v.flags &= ~FL_ONGROUND; ent->v.flags &= ~FL_ONGROUND;
return 1; return 1;
@ -178,7 +178,7 @@ qboolean SV_movetest(edict_t *ent, vec_t *move, qboolean relink)
} }
if (relink) if (relink)
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
return 1; return 1;
} }
@ -240,7 +240,7 @@ qboolean SV_movestep(edict_t *ent, vec_t *move, qboolean relink)
ent->v.origin[1] = trace.endpos[1]; ent->v.origin[1] = trace.endpos[1];
ent->v.origin[2] = trace.endpos[2]; ent->v.origin[2] = trace.endpos[2];
if (relink) if (relink)
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
return 1; return 1;
} }
@ -285,7 +285,7 @@ qboolean SV_movestep(edict_t *ent, vec_t *move, qboolean relink)
} }
if (relink) if (relink)
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
return 1; return 1;
} }
@ -297,7 +297,7 @@ qboolean SV_movestep(edict_t *ent, vec_t *move, qboolean relink)
ent->v.origin[1] += move[1]; ent->v.origin[1] += move[1];
ent->v.origin[2] += move[2]; ent->v.origin[2] += move[2];
if (relink) if (relink)
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
ent->v.flags &= ~FL_ONGROUND; ent->v.flags &= ~FL_ONGROUND;
return 1; return 1;
@ -312,12 +312,12 @@ qboolean SV_StepDirection(edict_t *ent, float yaw, float dist)
move[2] = 0; move[2] = 0;
if (SV_movestep(ent, move, 0)) if (SV_movestep(ent, move, 0))
{ {
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
return 1; return 1;
} }
else else
{ {
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
return 0; return 0;
} }
} }
@ -326,12 +326,12 @@ qboolean SV_FlyDirection(edict_t *ent, vec_t *direction)
{ {
if (SV_movestep(ent, direction, 0)) if (SV_movestep(ent, direction, 0))
{ {
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
return 1; return 1;
} }
else else
{ {
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
return 0; return 0;
} }
} }

View File

@ -425,7 +425,7 @@ trace_t SV_PushEntity(edict_t *ent, vec_t *push)
ent->v.origin[2] = trace.endpos[2]; ent->v.origin[2] = trace.endpos[2];
} }
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
if (trace.ent) if (trace.ent)
SV_Impact(ent, trace.ent, &trace); SV_Impact(ent, trace.ent, &trace);
@ -459,7 +459,7 @@ void SV_PushMove(edict_t *pusher, float movetime)
} }
pusher->v.ltime = movetime + pusher->v.ltime; pusher->v.ltime = movetime + pusher->v.ltime;
SV_LinkEdict(pusher, 0); SV_LinkEdict(pusher, FALSE);
if (pusher->v.solid == SOLID_NOT) if (pusher->v.solid == SOLID_NOT)
return; return;
@ -524,12 +524,12 @@ void SV_PushMove(edict_t *pusher, float movetime)
check->v.origin[0] = entorigin[0]; check->v.origin[0] = entorigin[0];
check->v.origin[1] = entorigin[1]; check->v.origin[1] = entorigin[1];
check->v.origin[2] = entorigin[2]; check->v.origin[2] = entorigin[2];
SV_LinkEdict(check, 1); SV_LinkEdict(check, TRUE);
pusher->v.origin[0] = pushorig[0]; pusher->v.origin[0] = pushorig[0];
pusher->v.origin[1] = pushorig[1]; pusher->v.origin[1] = pushorig[1];
pusher->v.origin[2] = pushorig[2]; pusher->v.origin[2] = pushorig[2];
SV_LinkEdict(pusher, 0); SV_LinkEdict(pusher, FALSE);
pusher->v.ltime = pusher->v.ltime - movetime; pusher->v.ltime = pusher->v.ltime - movetime;
gEntityInterface.pfnBlocked(pusher, check); gEntityInterface.pfnBlocked(pusher, check);
@ -540,7 +540,7 @@ void SV_PushMove(edict_t *pusher, float movetime)
g_moved_edict[e]->v.origin[1] = g_moved_from[e][1]; g_moved_edict[e]->v.origin[1] = g_moved_from[e][1];
g_moved_edict[e]->v.origin[2] = g_moved_from[e][2]; g_moved_edict[e]->v.origin[2] = g_moved_from[e][2];
SV_LinkEdict(g_moved_edict[e], 0); SV_LinkEdict(g_moved_edict[e], FALSE);
} }
return; return;
} }
@ -580,7 +580,7 @@ int SV_PushRotate(edict_t *pusher, float movetime)
AngleVectorsTranspose(pusher->v.angles, forwardNow, rightNow, upNow); AngleVectorsTranspose(pusher->v.angles, forwardNow, rightNow, upNow);
pusher->v.ltime = movetime + pusher->v.ltime; pusher->v.ltime = movetime + pusher->v.ltime;
SV_LinkEdict(pusher, 0); SV_LinkEdict(pusher, FALSE);
if (pusher->v.solid == SOLID_NOT) if (pusher->v.solid == SOLID_NOT)
return 1; return 1;
@ -687,12 +687,12 @@ int SV_PushRotate(edict_t *pusher, float movetime)
check->v.origin[0] = entorig[0]; check->v.origin[0] = entorig[0];
check->v.origin[1] = entorig[1]; check->v.origin[1] = entorig[1];
check->v.origin[2] = entorig[2]; check->v.origin[2] = entorig[2];
SV_LinkEdict(check, 1); SV_LinkEdict(check, TRUE);
pusher->v.angles[0] = pushorig[0]; pusher->v.angles[0] = pushorig[0];
pusher->v.angles[1] = pushorig[1]; pusher->v.angles[1] = pushorig[1];
pusher->v.angles[2] = pushorig[2]; pusher->v.angles[2] = pushorig[2];
SV_LinkEdict(pusher, 0); SV_LinkEdict(pusher, FALSE);
pusher->v.ltime = pusher->v.ltime - movetime; pusher->v.ltime = pusher->v.ltime - movetime;
gEntityInterface.pfnBlocked(pusher, check); gEntityInterface.pfnBlocked(pusher, check);
@ -715,7 +715,7 @@ int SV_PushRotate(edict_t *pusher, float movetime)
//movedEnt->v.angles[2] = movedEnt->v.angles[2]; //TODO: V570 The 'movedEnt->v.angles[2]' variable is assigned to itself. //movedEnt->v.angles[2] = movedEnt->v.angles[2]; //TODO: V570 The 'movedEnt->v.angles[2]' variable is assigned to itself.
} }
} }
SV_LinkEdict(movedEnt, 0); SV_LinkEdict(movedEnt, FALSE);
} }
return 0; return 0;
@ -916,7 +916,7 @@ void SV_Physics_Follow(edict_t *ent)
ent->v.origin[0] = ent->v.aiment->v.origin[0] + ent->v.v_angle[0]; ent->v.origin[0] = ent->v.aiment->v.origin[0] + ent->v.v_angle[0];
ent->v.origin[1] = ent->v.aiment->v.origin[1] + ent->v.v_angle[1]; ent->v.origin[1] = ent->v.aiment->v.origin[1] + ent->v.v_angle[1];
ent->v.origin[2] = ent->v.aiment->v.origin[2] + ent->v.v_angle[2]; ent->v.origin[2] = ent->v.aiment->v.origin[2] + ent->v.v_angle[2];
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
} }
else else
{ {
@ -932,7 +932,7 @@ void SV_Physics_Noclip(edict_t *ent)
{ {
VectorMA(ent->v.angles, (float)host_frametime, ent->v.avelocity, ent->v.angles); VectorMA(ent->v.angles, (float)host_frametime, ent->v.avelocity, ent->v.angles);
VectorMA(ent->v.origin, (float)host_frametime, ent->v.velocity, ent->v.origin); VectorMA(ent->v.origin, (float)host_frametime, ent->v.velocity, ent->v.origin);
SV_LinkEdict(ent, 0); SV_LinkEdict(ent, FALSE);
} }
} }
@ -1314,7 +1314,7 @@ void SV_Physics_Step(edict_t *ent)
} }
} }
}; };
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
} }
SV_RunThink(ent); SV_RunThink(ent);
SV_CheckWaterTransition(ent); SV_CheckWaterTransition(ent);
@ -1331,7 +1331,7 @@ void SV_Physics(void)
continue; continue;
if (gGlobalVariables.force_retouch != 0.0) if (gGlobalVariables.force_retouch != 0.0)
SV_LinkEdict(ent, 1); SV_LinkEdict(ent, TRUE);
if (i > 0 && i <= g_psvs.maxclients) if (i > 0 && i <= g_psvs.maxclients)
continue; continue;

View File

@ -962,7 +962,7 @@ void SV_RunCmd(usercmd_t *ucmd, int random_seed)
SetMinMaxSize(sv_player, player_mins[pmove->usehull], player_maxs[pmove->usehull], 0); SetMinMaxSize(sv_player, player_mins[pmove->usehull], player_maxs[pmove->usehull], 0);
if (host_client->edict->v.solid) if (host_client->edict->v.solid)
{ {
SV_LinkEdict(sv_player, 1); SV_LinkEdict(sv_player, TRUE);
vec3_t vel; vec3_t vel;
vel[0] = sv_player->v.velocity[0]; vel[0] = sv_player->v.velocity[0];
@ -1345,7 +1345,7 @@ void SV_SetupMove(client_t *_host_client)
cl->edict->v.origin[0] = origin[0]; cl->edict->v.origin[0] = origin[0];
cl->edict->v.origin[1] = origin[1]; cl->edict->v.origin[1] = origin[1];
cl->edict->v.origin[2] = origin[2]; cl->edict->v.origin[2] = origin[2];
SV_LinkEdict(cl->edict, 0); SV_LinkEdict(cl->edict, FALSE);
pos->needrelink = 1; pos->needrelink = 1;
} }
} }
@ -1393,7 +1393,7 @@ void SV_RestoreMove(client_t *_host_client)
cli->edict->v.origin[0] = pos->oldorg[0]; cli->edict->v.origin[0] = pos->oldorg[0];
cli->edict->v.origin[1] = pos->oldorg[1]; cli->edict->v.origin[1] = pos->oldorg[1];
cli->edict->v.origin[2] = pos->oldorg[2]; cli->edict->v.origin[2] = pos->oldorg[2];
SV_LinkEdict(cli->edict, 0); SV_LinkEdict(cli->edict, FALSE);
} }
} }
} }

View File

@ -35,6 +35,9 @@ box_planes_t box_planes;
beam_planes_t beam_planes; beam_planes_t beam_planes;
areanode_t sv_areanodes[32]; areanode_t sv_areanodes[32];
int sv_numareanodes; int sv_numareanodes;
#ifdef REHLDS_FIXES
static link_t *touchLinksNext = NULL;
#endif // REHLDS_FIXES
cvar_t sv_force_ent_intersection = { "sv_force_ent_intersection", "0", 0, 0.0f, NULL }; cvar_t sv_force_ent_intersection = { "sv_force_ent_intersection", "0", 0, 0.0f, NULL };
@ -46,6 +49,12 @@ void ClearLink(link_t *l)
void RemoveLink(link_t *l) void RemoveLink(link_t *l)
{ {
#ifdef REHLDS_FIXES
if (touchLinksNext == l)
{
touchLinksNext = l->next;
}
#endif // REHLDS_FIXES
l->next->prev = l->prev; l->next->prev = l->prev;
l->prev->next = l->next; l->prev->next = l->next;
} }
@ -56,6 +65,12 @@ void InsertLinkBefore(link_t *l, link_t *before)
l->prev = before->prev; l->prev = before->prev;
l->next->prev = l; l->next->prev = l;
l->prev->next = l; l->prev->next = l;
#ifdef REHLDS_FIXES
if (touchLinksNext == before)
{
touchLinksNext = l;
}
#endif // REHLDS_FIXES
} }
NOXREF void InsertLinkAfter(link_t *l, link_t *after) NOXREF void InsertLinkAfter(link_t *l, link_t *after)
@ -308,11 +323,13 @@ void SV_UnlinkEdict(edict_t *ent)
void SV_TouchLinks(edict_t *ent, areanode_t *node) void SV_TouchLinks(edict_t *ent, areanode_t *node)
{ {
edict_t *touch; edict_t *touch;
link_t *next; #ifndef REHLDS_FIXES
link_t *touchLinksNext;
#endif // REHLDS_FIXES
for (link_t *l = node->trigger_edicts.next; l != &node->trigger_edicts; l = next) for (link_t *l = node->trigger_edicts.next; l != &node->trigger_edicts; l = touchLinksNext)
{ {
next = l->next; touchLinksNext = l->next;
touch = (edict_t *)((char *)l - offsetof(edict_t, area)); touch = (edict_t *)((char *)l - offsetof(edict_t, area));
if (touch == ent) if (touch == ent)
continue; continue;
@ -363,6 +380,9 @@ void SV_TouchLinks(edict_t *ent, areanode_t *node)
gEntityInterface.pfnTouch(touch, ent); gEntityInterface.pfnTouch(touch, ent);
} }
} }
#ifdef REHLDS_FIXES
touchLinksNext = NULL;
#endif // REHLDS_FIXES
if (node->axis != -1) if (node->axis != -1)
{ {
@ -562,7 +582,7 @@ void SV_LinkEdict(edict_t *ent, qboolean touch_triggers)
} }
node = sv_areanodes; node = sv_areanodes;
while (1) while (true)
{ {
if (node->axis == -1) if (node->axis == -1)
break; break;
@ -625,7 +645,7 @@ int SV_LinkContents(areanode_t *node, const vec_t *pos)
#ifdef REHLDS_OPT_PEDANTIC #ifdef REHLDS_OPT_PEDANTIC
// unroll tail recursion // unroll tail recursion
while (1) while (true)
#endif #endif
{ {
for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next)