From 52ab0204c6a31562463d44bbbb39c60574aa3df0 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Fri, 10 Apr 2026 22:12:48 +0200 Subject: [PATCH 1/2] fix(pathfinder): Fix CRC computation of PathFinder::m_wallPieces. --- Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp index 39829e9ec33..a7eda5e623a 100644 --- a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp +++ b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp @@ -11338,10 +11338,20 @@ void Pathfinder::crc( Xfer *xfer ) xfer->xferInt(&m_numWallPieces); CRCDEBUG_LOG(("m_numWallPieces: %8.8X", ((XferCRC *)xfer)->getCRC())); - for (Int i=0; ixferObjectID(&m_wallPieces[MAX_WALL_PIECES]); +#if RETAIL_COMPATIBLE_CRC + // TheSuperHackers @info The original code effectively wrote m_numWallPieces 128 times, + // because it used &m_wallPieces[MAX_WALL_PIECES] which is out-of-bounds and points to m_numWallPieces. + static_assert(sizeof(Int) == sizeof(ObjectID)); + + xfer->xferInt(&m_numWallPieces); +#else + xfer->xferObjectID(&m_wallPieces[i]); +#endif } + CRCDEBUG_LOG(("m_wallPieces: %8.8X", ((XferCRC *)xfer)->getCRC())); xfer->xferReal(&m_wallHeight); From 9ed1c035e27ae404e0664cd219ba38204f703138 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Sun, 12 Apr 2026 02:40:43 +0200 Subject: [PATCH 2/2] Tweaked code and comment. --- Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp index a7eda5e623a..bb7a6c4fe24 100644 --- a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp +++ b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp @@ -11339,18 +11339,18 @@ void Pathfinder::crc( Xfer *xfer ) xfer->xferInt(&m_numWallPieces); CRCDEBUG_LOG(("m_numWallPieces: %8.8X", ((XferCRC *)xfer)->getCRC())); - for (Int i = 0; i < MAX_WALL_PIECES; ++i) - { #if RETAIL_COMPATIBLE_CRC - // TheSuperHackers @info The original code effectively wrote m_numWallPieces 128 times, - // because it used &m_wallPieces[MAX_WALL_PIECES] which is out-of-bounds and points to m_numWallPieces. - static_assert(sizeof(Int) == sizeof(ObjectID)); + // TheSuperHackers @fix The original code effectively accessed m_numWallPieces 128 times, + // because it used &m_wallPieces[MAX_WALL_PIECES] which is out-of-bounds and points to m_numWallPieces. + static_assert(sizeof(Int) == sizeof(ObjectID), "Type sizes must be equal for correct xfer"); + for (Int i = 0; i < MAX_WALL_PIECES; ++i) + { xfer->xferInt(&m_numWallPieces); + } #else - xfer->xferObjectID(&m_wallPieces[i]); + xfer->xferUser(m_wallPieces, sizeof(m_wallPieces)); #endif - } CRCDEBUG_LOG(("m_wallPieces: %8.8X", ((XferCRC *)xfer)->getCRC()));