mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Fix: Prevent concurrent bot initializations during .playerbot init= commands (#1227)
A simple RAII mechanism with std::unordered_set<ObjectGuid> 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.
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "ChannelMgr.h"
|
#include "ChannelMgr.h"
|
||||||
#include "CharacterCache.h"
|
#include "CharacterCache.h"
|
||||||
@@ -34,6 +35,34 @@
|
|||||||
#include "PlayerbotDbStore.h"
|
#include "PlayerbotDbStore.h"
|
||||||
#include "WorldSessionMgr.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<ObjectGuid> botsBeingInitialized;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_set<ObjectGuid> BotInitGuard::botsBeingInitialized;
|
||||||
|
|
||||||
PlayerbotHolder::PlayerbotHolder() : PlayerbotAIBase(false) {}
|
PlayerbotHolder::PlayerbotHolder() : PlayerbotAIBase(false) {}
|
||||||
class PlayerbotLoginQueryHolder : public LoginQueryHolder
|
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.";
|
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;
|
int gs;
|
||||||
if (cmd == "init=white" || cmd == "init=common")
|
if (cmd == "init=white" || cmd == "init=common")
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user