From 34a888978e50f16e5b5fc42cca8d20aab48c4107 Mon Sep 17 00:00:00 2001 From: EricksOliveira Date: Sun, 27 Apr 2025 07:47:02 -0300 Subject: [PATCH] Fix: Prevent concurrent bot initializations during .playerbot init= commands (#1227) A simple RAII mechanism with std::unordered_set to track GUIDs of init bots. Ensures that multiple threads or calls do not execute PlayerbotFactory::Randomize() logic at the same time for the same bot. --- src/PlayerbotMgr.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/PlayerbotMgr.cpp b/src/PlayerbotMgr.cpp index bc17bc34..13863ecb 100644 --- a/src/PlayerbotMgr.cpp +++ b/src/PlayerbotMgr.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "ChannelMgr.h" #include "CharacterCache.h" @@ -34,6 +35,34 @@ #include "PlayerbotDbStore.h" #include "WorldSessionMgr.h" +class BotInitGuard +{ +public: + BotInitGuard(ObjectGuid guid) : guid(guid), active(false) + { + if (!botsBeingInitialized.contains(guid)) + { + botsBeingInitialized.insert(guid); + active = true; + } + } + + ~BotInitGuard() + { + if (active) + botsBeingInitialized.erase(guid); + } + + bool IsLocked() const { return !active; } + +private: + ObjectGuid guid; + bool active; + static std::unordered_set botsBeingInitialized; +}; + +std::unordered_set BotInitGuard::botsBeingInitialized; + PlayerbotHolder::PlayerbotHolder() : PlayerbotAIBase(false) {} class PlayerbotLoginQueryHolder : public LoginQueryHolder { @@ -696,6 +725,14 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje { return "The command is not allowed, use init=auto instead."; } + + // Use boot guard + BotInitGuard guard(bot->GetGUID()); + if (guard.IsLocked()) + { + return "Initialization already in progress, please wait."; + } + int gs; if (cmd == "init=white" || cmd == "init=common") {