1
0

Do not call into things we don't own in destructors

- Remove improper accesses in cChunk destructor
* Fixes #4894
This commit is contained in:
Tiger Wang
2020-09-22 21:21:47 +01:00
parent 10bd15a11e
commit 4519469547
9 changed files with 35 additions and 55 deletions

View File

@@ -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;