EntityManager: Fix iterator invalidation (#1234)

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

View File

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