bugfix(contain): Prevent objects from being added to destroyed container object#2746
bugfix(contain): Prevent objects from being added to destroyed container object#2746Caball009 wants to merge 7 commits into
Conversation
|
| Filename | Overview |
|---|---|
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp | Adds early-return guard and DEBUG_CRASH for destroyed container in addToContain (non-retail), wraps destroyed-rider guard in braces with matching assertion, and makes occupants visible in debug builds when container is dead during addOrRemoveObjFromWorld. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/TransportContain.cpp | Wraps createPayload() call in !RETAIL_COMPATIBLE_CRC guard that skips payload creation if the transport container is already destroyed, preventing invalid-state infantry units from being spawned. |
Sequence Diagram
sequenceDiagram
participant Plane as Reinforcement Plane
participant TC as TransportContain::update()
participant OC as OpenContain::addToContain()
participant Obj as Infantry Object
Plane->>Plane: Destroyed mid-flight
TC->>TC: "m_payloadCreated == FALSE"
Note over TC: RETAIL_COMPATIBLE_CRC path
TC->>OC: createPayload() always called
OC->>Obj: Spawn infantry
OC->>OC: addToContain — container destroyed
OC-->>Obj: Infantry in invalid state
Note over TC: Non-retail path (this PR)
TC->>TC: "getObject()->isDestroyed()?"
TC--xTC: Skip createPayload()
Note over OC: Fallback guard non-retail
OC->>OC: "getObject()->isDestroyed()?"
OC-->>OC: DEBUG_CRASH + early return
Note over OC: RTS_DEBUG visibility fix
OC->>Obj: setDrawableHidden skipped
Obj-->>Obj: Infantry remains visible
Reviews (7): Last reviewed commit: "Changed macro." | Re-trigger Greptile
0d39be3 to
735d827
Compare
f2480a5 to
6544358
Compare
| { | ||
| #if RTS_DEBUG | ||
| // TheSuperHackers @tweak This shouldn't happen but don't make the occupant invisible if it does. | ||
| if (!(getObject()->isEffectivelyDead() || getObject()->isDestroyed())) |
There was a problem hiding this comment.
Do we really need this visual deviance in Debug as well? I suggest turn this into a regular assert. It will be far more obvious in debug.
DEBUG_ASSERTCRASH(!getObject()->isEffectivelyDead() && !getObject()->isDestroyed(), ("..."));
But check if this is already covered by earlier asserts. Maybe it is not necessary to assert here.
When a reinforcement plane with an Infantry General Troop Crawler is destroyed en route, the plane and vehicle are destroyed, but the infantry spawned and remains in an invalid state (see issue for more details).
Beside being a gameplay and logic bug, there's also another issue because the infantry objects will hold on the container pointer even though that object has been destroyed. This can lead to use-after-free bugs and a crash (see related PR).
This PR makes 4 changes:
OpenContain::addToContainto prevent units from being added to a destroyed object (non-retail only).TODO: