From 16aeb84cd35996a6b41f10cbc48a677eeccc911c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 2 Jan 2021 13:50:34 +0000 Subject: Fix potential destruction crashes (#5095) * Fix potential destruction crashes * Fix destructors accessing destroyted objects * Fix cPlayer not destroying windows (Destroyed never called) * Tentatively fixes #4608, fixes #3236, fixes #3262 - Remove cEntity::Destroyed() and replace with cEntity::OnRemoveFromWorld() * Add missing call to OnRemoveFromWorld --- src/Entities/Entity.cpp | 71 +++++++++++++++++++------------------------------ 1 file changed, 27 insertions(+), 44 deletions(-) (limited to 'src/Entities/Entity.cpp') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 579541dd3..438117650 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -80,32 +80,6 @@ cEntity::cEntity(eEntityType a_EntityType, Vector3d a_Pos, double a_Width, doubl -cEntity::~cEntity() -{ - /* - // DEBUG: - FLOGD("Deleting entity {0} at pos {1:.2f} ~ [{2}, {3}]; ptr {4}", - m_UniqueID, - m_Pos, - GetChunkX(), GetChunkZ(), - static_cast(this) - ); - */ - - if (m_AttachedTo != nullptr) - { - Detach(); - } - if (m_Attachee != nullptr) - { - m_Attachee->Detach(); - } -} - - - - - const char * cEntity::GetClass(void) const { return "cEntity"; @@ -174,7 +148,22 @@ void cEntity::OnAddToWorld(cWorld & a_World) void cEntity::OnRemoveFromWorld(cWorld & a_World) { - RemoveAllLeashedMobs(); + // Remove all mobs from the leashed list of mobs: + while (!m_LeashedMobs.empty()) + { + m_LeashedMobs.front()->Unleash(false, true); + } + + if (m_AttachedTo != nullptr) + { + Detach(); + } + + if (m_Attachee != nullptr) + { + m_Attachee->Detach(); + } + a_World.BroadcastDestroyEntity(*this); } @@ -244,7 +233,6 @@ void cEntity::Destroy() // Also, not storing the returned pointer means automatic destruction VERIFY(a_World.RemoveEntity(*this)); }); - Destroyed(); } @@ -813,10 +801,17 @@ void cEntity::KilledBy(TakeDamageInfo & a_TDI) cRoot::Get()->GetPluginManager()->CallHookKilled(*this, a_TDI, emptystring); } - // Drop loot: - cItems Drops; - GetDrops(Drops, a_TDI.Attacker); - m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ()); + // Drop loot, unless the attacker was a creative mode player: + if ( + (a_TDI.Attacker == nullptr) || + !a_TDI.Attacker->IsPlayer() || + !static_cast(a_TDI.Attacker)->IsGameModeCreative() + ) + { + cItems Drops; + GetDrops(Drops, a_TDI.Attacker); + m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ()); + } m_World->BroadcastEntityStatus(*this, esGenericDead); } @@ -2328,18 +2323,6 @@ void cEntity::RemoveLeashedMob(cMonster * a_Monster) -void cEntity::RemoveAllLeashedMobs() -{ - while (!m_LeashedMobs.empty()) - { - m_LeashedMobs.front()->Unleash(false, true); - } -} - - - - - void cEntity::BroadcastLeashedMobs() { // If has any mob leashed broadcast every leashed entity to this -- cgit v1.2.3