From 4f8a847085f909813b1c11b009ebe8c923f8bd63 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sun, 26 Oct 2025 10:28:41 +0100 Subject: [PATCH] Guard new object from being added at shutdown (#16610) --- src/serverenvironment.cpp | 17 +++++++++++++++-- src/serverenvironment.h | 6 ++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index c7ce34069..118f36bdf 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -278,8 +278,12 @@ void ServerEnvironment::init() void ServerEnvironment::deactivateBlocksAndObjects() { + // Prevent any funny business from happening in case further callbacks + // try to add new objects. + m_shutting_down = true; + // Clear active block list. - // This makes the next one delete all active objects. + // This makes the next code delete all active objects. m_active_blocks.clear(); deactivateFarObjects(true); @@ -287,6 +291,7 @@ void ServerEnvironment::deactivateBlocksAndObjects() ServerEnvironment::~ServerEnvironment() { + m_script = nullptr; assert(m_active_blocks.size() == 0); // deactivateBlocksAndObjects does this // Drop/delete map @@ -301,9 +306,12 @@ ServerEnvironment::~ServerEnvironment() for (RemotePlayer *m_player : m_players) { delete m_player; } + m_players.clear(); delete m_player_database; + m_player_database = nullptr; delete m_auth_database; + m_auth_database = nullptr; } Map & ServerEnvironment::getMap() @@ -1208,6 +1216,11 @@ void ServerEnvironment::deleteParticleSpawner(u32 id, bool remove_from_object) u16 ServerEnvironment::addActiveObject(std::unique_ptr object) { assert(object); // Pre-condition + if (m_shutting_down) { + warningstream << "ServerEnvironment: refusing to add active object " + "during shutdown: " << object->getDescription() << std::endl; + return 0; + } m_added_objects++; u16 id = addActiveObjectRaw(std::move(object), nullptr, 0); return id; @@ -1569,7 +1582,7 @@ std::unique_ptr ServerEnvironment::createSAO(ActiveObjectTyp */ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s) { - if (block == NULL) + if (!block || m_shutting_down) return; if (!block->onObjectsActivation()) diff --git a/src/serverenvironment.h b/src/serverenvironment.h index 92205bd57..d7c1f987c 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -357,9 +357,9 @@ private: // The map std::unique_ptr m_map; // Lua state - ServerScripting* m_script; + ServerScripting *m_script = nullptr; // Server definition - Server *m_server; + Server *m_server = nullptr; // Active Object Manager server::ActiveObjectMgr m_ao_manager; // on_mapblocks_changed map event receiver @@ -378,6 +378,8 @@ private: IntervalLimiter m_active_blocks_nodemetadata_interval; // Whether the variables below have been read from file yet bool m_meta_loaded = false; + // Are we shutting down? + bool m_shutting_down = false; // Time from the beginning of the game in seconds. // Incremented in step(). u32 m_game_time = 0;