From 83459d0d899786378e8304c92a5b79ddca92c62f Mon Sep 17 00:00:00 2001 From: LogicParrot Date: Sun, 7 Feb 2016 19:07:14 +0200 Subject: Proper entity destruction in non-ticking chunks --- src/ClientHandle.cpp | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'src/ClientHandle.cpp') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index fca29c65d..6fb2033f4 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -120,14 +120,15 @@ cClientHandle::~cClientHandle() cWorld * World = m_Player->GetWorld(); if (World != nullptr) { + RemoveFromAllChunks(); + m_Player->GetWorld()->RemoveClientFromChunkSender(this); + m_Player->SetIsTicking(false); if (!m_Username.empty()) { // Send the Offline PlayerList packet: World->BroadcastPlayerListRemovePlayer(*m_Player, this); } - - World->RemovePlayer(m_Player, true); // Must be called before cPlayer::Destroy() as otherwise cChunk tries to delete the player, and then we do it again - m_Player->Destroy(); + m_Player->DestroyNoScheduling(true); } delete m_Player; m_Player = nullptr; @@ -164,18 +165,18 @@ void cClientHandle::Destroy(void) m_State = csDestroying; } - // DEBUG: LOGD("%s: client %p, \"%s\"", __FUNCTION__, static_cast(this), m_Username.c_str()); - if ((m_Player != nullptr) && (m_Player->GetWorld() != nullptr)) - { - RemoveFromAllChunks(); - m_Player->GetWorld()->RemoveClientFromChunkSender(this); - } if (m_Player != nullptr) { + cWorld * World = m_Player->GetWorld(); + if (World != nullptr) + { + World->RemovePlayer(m_Player, true); // TODO this is NOT thread safe. + } m_Player->RemoveClientHandle(); } + m_State = csDestroyed; } @@ -384,7 +385,7 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, cRoot::Get()->BroadcastPlayerListsAddPlayer(*m_Player); cRoot::Get()->SendPlayerLists(m_Player); - m_Player->Initialize(*World); + m_Player->SetWorld(World); m_State = csAuthenticated; // Query player team @@ -2020,7 +2021,7 @@ void cClientHandle::ServerTick(float a_Dt) // Add the player to the world (start ticking from there): m_State = csDownloadingWorld; - m_Player->GetWorld()->AddPlayer(m_Player); + m_Player->Initialize(*(m_Player->GetWorld())); return; } @@ -3032,14 +3033,6 @@ void cClientHandle::SocketClosed(void) LOGD("Client %s @ %s disconnected", m_Username.c_str(), m_IPString.c_str()); cRoot::Get()->GetPluginManager()->CallHookDisconnect(*this, "Player disconnected"); } - if ((m_State < csDestroying) && (m_Player != nullptr)) - { - cWorld * World = m_Player->GetWorld(); - if (World != nullptr) - { - World->RemovePlayer(m_Player, true); // Must be called before cPlayer::Destroy() as otherwise cChunk tries to delete the player, and then we do it again - } - } Destroy(); } -- cgit v1.2.3