bugfix(tunnel): Restore retail compatibility after changes to TunnelTracker::onTunnelDestroyed() and TunnelContain::onCapture() - #3242
Conversation
PR Summary by QodoRestore retail-compatible tunnel lifecycle and passenger cleanup
AI Description
Diagram
High-Level Assessment
Files changed (8)
|
Code Review by Qodo
1. Tunnel creation assertion inverted
|
|
| Filename | Overview |
|---|---|
| Generals/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp | Splits retail and non-retail tunnel lifecycle bookkeeping, guards empty-list access, and versions serialization consistently. |
| GeneralsMD/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp | Mirrors the tunnel lifecycle and serialization changes while correcting the three previously reported assertion and iterator defects. |
| Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp | Conditionally excludes the capture override from the retail-compatible Generals configuration. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp | Applies the matching capture-override compatibility guard to Zero Hour. |
| Generals/Code/GameEngine/Include/Common/TunnelTracker.h | Retains the explicit tunnel counter only for retail-compatible builds and derives the non-retail count from the ID list. |
| GeneralsMD/Code/GameEngine/Include/Common/TunnelTracker.h | Mirrors the conditional tunnel-count representation for Zero Hour. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Tunnel destroyed] --> B{Retail-compatible CRC?}
B -- Yes --> C[Remove matching tunnel ID]
C --> D[Decrement retail tunnel count]
D --> E{Count is zero?}
E -- Yes --> F[Destroy contained units and clear list]
E -- No --> G[Choose remaining tunnel or nullptr]
G --> H[Redirect occupants linked to dead tunnel]
B -- No --> I[Find and erase matching list entry]
I --> J{Tunnel ID list empty?}
J -- Yes --> F
J -- No --> K[Redirect occupants to remaining tunnel]
Reviews (16): Last reviewed commit: "Added complete retail incompatible versi..." | Re-trigger Greptile
1d42639 to
001ee15
Compare
001ee15 to
342ce12
Compare
|
Code review by qodo was updated up to the latest commit 342ce12 |
…mpatibility macro.
342ce12 to
a3b7cb8
Compare
a3b7cb8 to
a34726c
Compare
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
3d34f16 to
ddc9b76
Compare
ddc9b76 to
8545c86
Compare
8545c86 to
4faa5ea
Compare
|
Code review by qodo was updated up to the latest commit 4faa5ea |
4faa5ea to
f7a763e
Compare
|
Code review by qodo was updated up to the latest commit 4faa5ea |
f7a763e to
d77b627
Compare
d77b627 to
322dbfd
Compare
5c19dc9 to
e30337a
Compare
e30337a to
290e63c
Compare
|
Code replicated to Generals (manually), PR description updated, and verified that the mismatching Generals replays are working again. Ready to be merged. |
This PR makes 3 changes (one commit for each):
TunnelContain::onCaptureto Generals is not retail compatible so this needs to be behind theRETAIL_COMPATIBLE_CRCmacro.TunnelTracker::onTunnelDestroyedis not retail compatible so this had to be changed.m_containList) hold on to a pointer to their container. This can lead to use-after-free bugs and crashes. The early return is removed.TunnelTracker::onTunnelDestroyedthat only relies onm_tunnelIDsand doesn't usem_tunnelCount. It's also removed fromTunnelTracker::xfer.The
m_tunnelCountinteger underflow cannot be fixed with retail compatibility enabled, but the code should be well-defined and safe now.See commits for cleaner diffs; third commit partially changes code from second commit.
Object *validTunnel = TheGameLogic->findObjectByID( m_tunnelIDs.front() );I'm not entirely familiar with the STLPort implementation of
std::list<T>, but accessing the front element of an emptystd::listappears to result reliably inT{}for trivial types;INVALID_IDin this context. As a result, all contained objects have their container pointer updated tonullptr, neatly avoiding the use-after-free bugs and resulting crash.Crash reproduction with the current main branch (VC6 / VS22, RETAIL_COMPATIBLE_CRC == 1), using Zero Hour GLA campaign mission 3:
Video and call stack
gen_zh_md_gla03_campaign_tunnel_crash.mp4
TODO: