Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,17 @@ void OpenContain::addOrRemoveObjFromWorld(Object* obj, Bool add)
// remove rider from partition manager
ThePartitionManager->unRegisterObject( obj );

// hide the drawable associated with rider
if( obj->getDrawable() )
obj->getDrawable()->setDrawableHidden( true );
if (Drawable* drawable = obj->getDrawable())
{
#if RETAIL_COMPATIBLE_CRC
// TheSuperHackers @tweak This shouldn't happen but don't make the occupant invisible if it does.
if (!(getObject()->isEffectivelyDead() || getObject()->isDestroyed()))
#endif
{
// hide the drawable associated with rider
drawable->setDrawableHidden(true);
}
}

// remove object from pathfind map
TheAI->pathfinder()->removeObjectFromPathfindMap( obj );
Expand Down Expand Up @@ -292,11 +300,26 @@ void OpenContain::addToContain( Object *rider )
if( rider == nullptr )
return;

#if !RETAIL_COMPATIBLE_CRC
// TheSuperHackers @bugfix Caball009 25/05/2026 Ensure the occupant is only added to a non-destroyed
// container to avoid an invalid state and use-after-free bugs when accessing the contained by pointer.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contained == containee (rider) or container?

Copy link
Copy Markdown
Author

@Caball009 Caball009 May 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Object* m_containedBy ?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

containedBy refers to the container.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you're asking then.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh ok I did not realize "contained by" refers to "m_containedBy".

if (getObject()->isDestroyed())
{
DEBUG_CRASH(("'%s' is about to be added to '%s', which is destroyed",
rider->getTemplate()->getName().str(), getObject()->getTemplate()->getName().str()));
return;
}
#endif

// TheSuperHackers @bugfix Stubbjax 06/02/2026 Ensure the rider is not destroyed to prevent a
// likely crash if it enters the container on the same frame. If this occurs with an unpatched
// client present in a match, the game has a small chance to mismatch.
if (rider->isDestroyed())
{
DEBUG_CRASH(("'%s', which is destroyed, is about to be added to '%s'",
rider->getTemplate()->getName().str(), getObject()->getTemplate()->getName().str()));
return;
}

Drawable *riderDraw = rider->getDrawable();
Bool wasSelected = FALSE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,19 @@ UpdateSleepTime TransportContain::update()
{
const TransportContainModuleData *moduleData = getTransportContainModuleData();

if( m_payloadCreated == FALSE )
if (m_payloadCreated == FALSE)
{
#if RETAIL_COMPATIBLE_CRC
createPayload();
#else
// TheSuperHackers @bugfix Caball009 25/05/2026 Don't create payload
// for destroyed object to avoid leaving the payload in an invalid state.
if (!getObject()->isDestroyed())
{
createPayload();
}
#endif
}

if( moduleData && moduleData->m_healthRegen )
{
Expand Down
Loading