From fcbb7320a86c5ea5d41b7c446d8cac5726b3def8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 19 Nov 2021 08:58:31 +0100 Subject: [PATCH] - Duke/RR: added all checks needed for not letting Duke crash with noclip when not accepting -1 as a valid sector pointer. All places that were causing a crash are now guared by calling 'insector()'. --- source/core/gameinput.cpp | 2 +- source/games/duke/src/actors.cpp | 4 ++-- source/games/duke/src/game_misc.cpp | 2 +- source/games/duke/src/hudweapon_d.cpp | 2 +- source/games/duke/src/hudweapon_r.cpp | 4 ++-- source/games/duke/src/inlines.h | 2 +- source/games/duke/src/player_d.cpp | 8 ++++---- source/games/duke/src/player_r.cpp | 10 +++++----- source/games/duke/src/sectors_d.cpp | 2 ++ source/games/duke/src/sectors_r.cpp | 2 ++ source/games/duke/src/types.h | 10 ++++++++++ 11 files changed, 31 insertions(+), 17 deletions(-) diff --git a/source/core/gameinput.cpp b/source/core/gameinput.cpp index 8310db3a7..220dac077 100644 --- a/source/core/gameinput.cpp +++ b/source/core/gameinput.cpp @@ -448,7 +448,7 @@ enum void PlayerHorizon::calcviewpitch(vec2_t const pos, binangle const ang, bool const aimmode, bool const canslopetilt, int const cursectnum, double const scaleAdjust, bool const climbing) { - if (cl_slopetilting) + if (cl_slopetilting && cursectnum >= 0) { if (aimmode && canslopetilt) // If the floor is sloped { diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index a77569ba7..fefabd646 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -360,7 +360,7 @@ void movedummyplayers(void) p = act->GetOwner()->PlayerIndex(); auto spri = act->s; - if ((!isRR() && ps[p].on_crane != nullptr) || ps[p].cursector()->lotag != 1 || ps->GetActor()->s->extra <= 0) + if ((!isRR() && ps[p].on_crane != nullptr) || !ps[p].insector() || ps[p].cursector()->lotag != 1 || ps->GetActor()->s->extra <= 0) { ps[p].dummyplayersprite = nullptr; deletesprite(act); @@ -2916,7 +2916,7 @@ void handle_se14(DDukeActor* actor, bool checkstat, int RPG, int JIBS6) for (int p = connecthead; p >= 0; p = connectpoint2[p]) { auto psp = ps[p].GetActor(); - if (ps[p].cursector()->lotag != 2) + if (ps[p].insector() && ps[p].cursector()->lotag != 2) { if (po[p].os == s->sectnum) { diff --git a/source/games/duke/src/game_misc.cpp b/source/games/duke/src/game_misc.cpp index 2f131f971..059dee8fa 100644 --- a/source/games/duke/src/game_misc.cpp +++ b/source/games/duke/src/game_misc.cpp @@ -250,7 +250,7 @@ void drawoverlays(double smoothratio) { fi.displayweapon(screenpeek, smoothratio); if (pp->over_shoulder_on == 0) - fi.displaymasks(screenpeek, pp->GetActor()->s->pal == 1 ? 1 : pp->cursector()->floorpal, smoothratio); + fi.displaymasks(screenpeek, pp->GetActor()->s->pal == 1 || !pp->insector() ? 1 : pp->cursector()->floorpal, smoothratio); } if (!isRR()) moveclouds(smoothratio); diff --git a/source/games/duke/src/hudweapon_d.cpp b/source/games/duke/src/hudweapon_d.cpp index 630e5f92f..0ec879cc4 100644 --- a/source/games/duke/src/hudweapon_d.cpp +++ b/source/games/duke/src/hudweapon_d.cpp @@ -251,7 +251,7 @@ void displayweapon_d(int snum, double smoothratio) shade = p->GetActor()->s->shade; if(shade > 24) shade = 24; - pal = p->GetActor()->s->pal == 1 ? 1 : p->cursector()->floorpal; + pal = !p->insector() ? 0 : p->GetActor()->s->pal == 1 ? 1 : p->cursector()->floorpal; if (pal == 0) pal = p->palookup; diff --git a/source/games/duke/src/hudweapon_r.cpp b/source/games/duke/src/hudweapon_r.cpp index 0f9fd3841..7f6ba4f23 100644 --- a/source/games/duke/src/hudweapon_r.cpp +++ b/source/games/duke/src/hudweapon_r.cpp @@ -144,13 +144,13 @@ void displayweapon_r(int snum, double smoothratio) weapon_xoffset -= bcosf(weapon_sway * 0.5) * (1. / 1536.); weapon_xoffset -= 58 + p->weapon_ang; - if (shadedsector[p->cursectnum] == 1) + if (p->insector() && shadedsector[p->cursectnum] == 1) shade = 16; else shade = p->GetActor()->s->shade; if(shade > 24) shade = 24; - pal = p->GetActor()->s->pal == 1 ? 1 : p->cursector()->floorpal; + pal = !p->insector()? 0 : p->GetActor()->s->pal == 1? 1 : p->cursector()->floorpal; if(p->newOwner != nullptr || ud.cameraactor != nullptr || p->over_shoulder_on > 0 || (p->GetActor()->s->pal != 1 && p->GetActor()->s->extra <= 0)) return; diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index 84b265cdc..93ee4f71e 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -189,7 +189,7 @@ inline bool playrunning() inline void doslopetilting(player_struct* p, double const scaleAdjust = 1) { - bool const canslopetilt = p->on_ground && p->cursector()->lotag != ST_2_UNDERWATER && (p->cursector()->floorstat & 2); + bool const canslopetilt = p->on_ground && p->insector() && p->cursector()->lotag != ST_2_UNDERWATER && (p->cursector()->floorstat & 2); p->horizon.calcviewpitch(p->pos.vec2, p->angle.ang, p->aim_mode == 0, canslopetilt, p->cursectnum, scaleAdjust); } diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 5384cb02e..d9dde50da 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -1576,7 +1576,7 @@ int doincrements_d(struct player_struct* p) } } - if (p->scuba_on == 0 && p->cursector()->lotag == 2) + if (p->scuba_on == 0 && p->insector() && p->cursector()->lotag == 2) { if (p->scuba_amount > 0) { @@ -1813,7 +1813,7 @@ static void movement(int snum, ESyncBits actions, sectortype* psect, int fz, int if ((p->pos.z + p->poszv) >= (fz - (i << 8))) // hit the ground { S_StopSound(DUKE_SCREAM, pact); - if (p->cursector()->lotag != 1) + if (!p->insector() || p->cursector()->lotag != 1) { if (p->falling_counter > 62) quickkill(p); @@ -3023,7 +3023,7 @@ HORIZONLY: if (psectlotag == 1 || p->spritebridge == 1) ii = (4L << 8); else ii = (20L << 8); - if (p->cursector()->lotag == 2) k = 0; + if (p->insector() && p->cursector()->lotag == 2) k = 0; else k = 1; Collision clip{}; @@ -3075,7 +3075,7 @@ HORIZONLY: } } - if (truefdist < gs.playerheight && p->on_ground && psectlotag != 1 && shrunk == 0 && p->cursector()->lotag == 1) + if (truefdist < gs.playerheight && p->on_ground && psectlotag != 1 && shrunk == 0 && p->insector() && p->cursector()->lotag == 1) if (!S_CheckActorSoundPlaying(pact, DUKE_ONWATER)) S_PlayActorSound(DUKE_ONWATER, pact); diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 47c2b9191..b395d7e89 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -1424,7 +1424,7 @@ int doincrements_r(struct player_struct* p) } } - if (p->scuba_on == 0 && p->cursector()->lotag == 2) + if (p->scuba_on == 0 && p->insector() && p->cursector()->lotag == 2) { if (p->scuba_amount > 0) { @@ -2145,10 +2145,10 @@ static void movement(int snum, ESyncBits actions, sectortype* psect, int fz, int if ((p->pos.z + p->poszv) >= (fz - (i << 8))) // hit the ground { S_StopSound(DUKE_SCREAM, pact); - if (p->cursector()->lotag != 1) + if (!p->insector() || p->cursector()->lotag != 1) { if (isRRRA()) p->MotoOnGround = 1; - if (p->falling_counter > 62 || (isRRRA() && p->falling_counter > 2 && p->cursector()->lotag == 802)) + if (p->falling_counter > 62 || (isRRRA() && p->falling_counter > 2 && p->insector() && p->cursector()->lotag == 802)) quickkill(p); else if (p->falling_counter > 9) @@ -3766,7 +3766,7 @@ HORIZONLY: if (psectlotag == 1 || p->spritebridge == 1) i = (4L << 8); else i = (20L << 8); - if (p->cursector()->lotag == 2) k = 0; + if (p->insector() && p->cursector()->lotag == 2) k = 0; else k = 1; Collision clip{}; @@ -3899,7 +3899,7 @@ HORIZONLY: } } - if (truefdist < gs.playerheight && p->on_ground && psectlotag != 1 && shrunk == 0 && p->cursector()->lotag == 1) + if (truefdist < gs.playerheight && p->on_ground && psectlotag != 1 && shrunk == 0 && p->insector() && p->cursector()->lotag == 1) if (!S_CheckActorSoundPlaying(pact, DUKE_ONWATER)) if (!isRRRA() || (!p->OnBoat && !p->OnMotorcycle && p->cursector()->hitag != 321)) S_PlayActorSound(DUKE_ONWATER, pact); diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 80c46152e..d5774d2a6 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -1533,6 +1533,8 @@ void checksectors_d(int snum) p = &ps[snum]; auto pact = p->GetActor(); + if (!p->insector()) return; + switch (p->cursector()->lotag) { diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index d414e2c85..85453711a 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -2452,6 +2452,8 @@ void checksectors_r(int snum) p = &ps[snum]; auto pact = p->GetActor(); + if (!p->insector()) return; + switch (p->cursector()->lotag) { diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index e9ef122f4..ec9d60cd6 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -312,7 +312,17 @@ struct player_struct sectortype* cursector() const { +#ifdef _DEBUG // this is an aid for detecting invalid sector access during development as it will cause the game to crash when sector -1 is being accessed. + return cursectnum < 0 ? nullptr : &::sector[cursectnum]; +#else return &::sector[cursectnum]; +#endif + } + + bool insector() const + { + assert(cursectnum >= -1 && cursectnum < numsectors); // check for truly invalid values. + return validSectorIndex(cursectnum); } };