From 68ae16d93aed41bce86f75476222e1f1940d5d21 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sat, 18 Feb 2023 13:21:31 +0100 Subject: [PATCH] Fix bug in 'Detour_LevelShutdown' Pointer in array never got nulled after getting freed, causing undefined behavior. Also made a dedicated function for clearing a NavMesh slot by hull. --- r5dev/game/server/ai_networkmanager.h | 4 ++-- r5dev/game/server/ai_utility.cpp | 34 +++++++++++++++++++-------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/r5dev/game/server/ai_networkmanager.h b/r5dev/game/server/ai_networkmanager.h index 5f8e4113..afe754df 100644 --- a/r5dev/game/server/ai_networkmanager.h +++ b/r5dev/game/server/ai_networkmanager.h @@ -69,9 +69,9 @@ class VAI_NetworkManager : public IDetour LogFunAdr("CAI_NetworkManager::ShouldRebuild", p_CAI_NetworkManager__ShouldRebuild.GetPtr()); LogFunAdr("CAI_NetworkBuilder::Build", p_CAI_NetworkBuilder__Build.GetPtr()); LogVarAdr("g_nAiNodeClusters", reinterpret_cast(g_nAiNodeClusters)); - LogVarAdr("g_pppAiNodeClusters", reinterpret_cast(g_pppAiNodeClusters)); + LogVarAdr("g_pAiNodeClusters", reinterpret_cast(g_pppAiNodeClusters)); LogVarAdr("g_nAiNodeClusterLinks", reinterpret_cast(g_nAiNodeClusterLinks)); - LogVarAdr("g_pppAiNodeClusterLinks", reinterpret_cast(g_pppAiNodeClusterLinks)); + LogVarAdr("g_pAiNodeClusterLinks", reinterpret_cast(g_pppAiNodeClusterLinks)); } virtual void GetFun(void) const { diff --git a/r5dev/game/server/ai_utility.cpp b/r5dev/game/server/ai_utility.cpp index 4f8c4ec0..c76edc15 100644 --- a/r5dev/game/server/ai_utility.cpp +++ b/r5dev/game/server/ai_utility.cpp @@ -10,7 +10,7 @@ #include "game/server/detour_impl.h" #include "game/server/ai_networkmanager.h" -inline uint32_t g_pHullMasks[10] = // Hull mask table [r5apex_ds.exe + 131a2f8]. +inline uint32_t g_HullMasks[10] = // Hull mask table [r5apex_ds.exe + 131a2f8]. { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xfffffffb, 0xfffffffa, 0xfffffff9, 0xfffffff8, 0x00040200 @@ -27,6 +27,25 @@ dtNavMesh* GetNavMeshForHull(int hullSize) return g_pNavMesh[hullSize]; } +//----------------------------------------------------------------------------- +// Purpose: gets the navmesh by hull from global array [small, med_short, medium, large, extra_large] +// input : hull - +// Output : pointer to navmesh +//----------------------------------------------------------------------------- +void ClearNavMeshForHull(int hullSize) +{ + Assert(hullSize >= NULL && hullSize < MAX_HULLS); // Programmer error. + dtNavMesh* nav = g_pNavMesh[hullSize]; + + if (nav) // Only free if NavMesh for hull is loaded. + { + v_Detour_FreeNavMesh(nav); // Frees tiles, polys, tris, etc. + MemAllocSingleton()->Free(nav); // Frees the main navmesh memory. + + g_pNavMesh[hullSize] = nullptr; + } +} + //----------------------------------------------------------------------------- // Purpose: gets hull mask by id // input : hullId - @@ -35,7 +54,7 @@ dtNavMesh* GetNavMeshForHull(int hullSize) uint32_t GetHullMaskById(int hullId) { Assert(hullId >= NULL && hullId < SDK_ARRAYSIZE(g_pHullMasks)); // Programmer error. - return (hullId + g_pHullMasks[hullId]); + return (hullId + g_HullMasks[hullId]); } //----------------------------------------------------------------------------- @@ -48,8 +67,8 @@ uint32_t GetHullMaskById(int hullId) //----------------------------------------------------------------------------- uint8_t IsGoalPolyReachable(dtNavMesh* nav, dtPolyRef fromRef, dtPolyRef goalRef, int hullId) { - if (navmesh_always_reachable->GetBool()) - return true; + if (navmesh_always_reachable->GetBool()) + return true; return v_dtNavMesh__isPolyReachable(nav, fromRef, goalRef, hullId); } @@ -70,12 +89,7 @@ void Detour_LevelShutdown() { for (int i = 0; i < MAX_HULLS; i++) { - dtNavMesh* nav = GetNavMeshForHull(i); - if (nav) // Only free if NavMesh for hull is loaded. - { - v_Detour_FreeNavMesh(nav); - MemAllocSingleton()->Free(nav); - } + ClearNavMeshForHull(i); } }