From 4519469547c0f8befe74e3e80a94efb0e076ba34 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 22 Sep 2020 21:21:47 +0100 Subject: Do not call into things we don't own in destructors - Remove improper accesses in cChunk destructor * Fixes #4894 --- src/Chunk.cpp | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'src/Chunk.cpp') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 8f72d7c0f..df9292fae 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -103,24 +103,9 @@ cChunk::cChunk( cChunk::~cChunk() { - cPluginManager::Get()->CallHookChunkUnloaded(*m_World, m_PosX, m_PosZ); - // LOGINFO("### delete cChunk() (%i, %i) from %p, thread 0x%x ###", m_PosX, m_PosZ, this, GetCurrentThreadId()); - m_BlockEntities.clear(); - - // Remove and destroy all entities that are not players: - cEntityList Entities; - std::swap(Entities, m_Entities); // Need another list because cEntity destructors check if they've been removed from chunk - for (auto & Entity : Entities) - { - if (!Entity->IsPlayer()) - { - // Scheduling a normal destruction is neither possible (Since this chunk will be gone till the schedule occurs) nor necessary. - Entity->DestroyNoScheduling(false); // No point in broadcasting in an unloading chunk. Chunks unload when no one is nearby. - } - } - + // Inform our neighbours that we're no longer valid: if (m_NeighborXM != nullptr) { m_NeighborXM->m_NeighborXP = nullptr; @@ -137,6 +122,7 @@ cChunk::~cChunk() { m_NeighborZP->m_NeighborZM = nullptr; } + delete m_WaterSimulatorData; m_WaterSimulatorData = nullptr; delete m_LavaSimulatorData; @@ -221,6 +207,25 @@ bool cChunk::CanUnloadAfterSaving(void) const +void cChunk::OnUnload() +{ + // Note: this is only called during normal operation, not during shutdown + + // Notify all entities of imminent unload: + for (auto & Entity : m_Entities) + { + // Chunks cannot be unloaded when they still contain players: + ASSERT(!Entity->IsPlayer()); + + // Notify the entity: + Entity->OnRemoveFromWorld(*Entity->GetWorld()); + } +} + + + + + void cChunk::MarkSaving(void) { m_IsSaving = true; -- cgit v1.2.3