EntityManager: Fix iterator invalidation ()

Tested that servers still start up, and that zones like bons no longer hard crash when all players have left the world.
This commit is contained in:
David Markowitz 2023-10-23 06:55:38 -07:00 committed by GitHub
parent ae349d6b15
commit 5ea06f9bda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -176,8 +176,9 @@ void EntityManager::DestroyEntity(Entity* entity) {
} }
void EntityManager::SerializeEntities() { void EntityManager::SerializeEntities() {
for (auto entry = m_EntitiesToSerialize.begin(); entry != m_EntitiesToSerialize.end(); entry++) { for (int32_t i = 0; i < m_EntitiesToSerialize.size(); i++) {
auto* entity = GetEntity(*entry); const LWOOBJID toSerialize = m_EntitiesToSerialize.at(i);
auto* entity = GetEntity(toSerialize);
if (!entity) continue; if (!entity) continue;
@ -192,7 +193,7 @@ void EntityManager::SerializeEntities() {
if (entity->GetIsGhostingCandidate()) { if (entity->GetIsGhostingCandidate()) {
for (auto* player : Player::GetAllPlayers()) { for (auto* player : Player::GetAllPlayers()) {
if (player->IsObserved(*entry)) { if (player->IsObserved(toSerialize)) {
Game::server->Send(&stream, player->GetSystemAddress(), false); Game::server->Send(&stream, player->GetSystemAddress(), false);
} }
} }
@ -204,11 +205,12 @@ void EntityManager::SerializeEntities() {
} }
void EntityManager::KillEntities() { void EntityManager::KillEntities() {
for (auto entry = m_EntitiesToKill.begin(); entry != m_EntitiesToKill.end(); entry++) { for (int32_t i = 0; i < m_EntitiesToKill.size(); i++) {
auto* entity = GetEntity(*entry); const LWOOBJID toKill = m_EntitiesToKill.at(i);
auto* entity = GetEntity(toKill);
if (!entity) { if (!entity) {
LOG("Attempting to kill null entity %llu", *entry); LOG("Attempting to kill null entity %llu", toKill);
continue; continue;
} }
@ -222,8 +224,9 @@ void EntityManager::KillEntities() {
} }
void EntityManager::DeleteEntities() { void EntityManager::DeleteEntities() {
for (auto entry = m_EntitiesToDelete.begin(); entry != m_EntitiesToDelete.end(); entry++) { for (int32_t i = 0; i < m_EntitiesToDelete.size(); i++) {
auto entityToDelete = GetEntity(*entry); const LWOOBJID toDelete = m_EntitiesToDelete.at(i);
auto entityToDelete = GetEntity(toDelete);
if (entityToDelete) { if (entityToDelete) {
// Get all this info first before we delete the player. // Get all this info first before we delete the player.
auto networkIdToErase = entityToDelete->GetNetworkId(); auto networkIdToErase = entityToDelete->GetNetworkId();
@ -237,9 +240,9 @@ void EntityManager::DeleteEntities() {
if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete); if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete);
} else { } else {
LOG("Attempted to delete non-existent entity %llu", *entry); LOG("Attempted to delete non-existent entity %llu", toDelete);
} }
m_Entities.erase(*entry); m_Entities.erase(toDelete);
} }
m_EntitiesToDelete.clear(); m_EntitiesToDelete.clear();
} }