Improve login and init permission for rndbots and addclass bots (#930)

* Improve login and init permission for rndbots and addclass-bots

* Add AllowAcountBots config

* Update config description
This commit is contained in:
Yunfan Li
2025-02-03 19:46:49 +08:00
committed by GitHub
parent f5a8b3017e
commit fef67081ec
5 changed files with 95 additions and 103 deletions

View File

@@ -107,12 +107,9 @@ AiPlayerbot.DeleteRandomBotAccounts = 0
# #
# #
# Maximum number of bots added by one account # The maximum number of bots that a player can control simultaneously
AiPlayerbot.MaxAddedBots = 40 AiPlayerbot.MaxAddedBots = 40
# Maximum number of bots per class added by one account
AiPlayerbot.MaxAddedBotsPerClass = 40
# Enable/Disable create bot by addclass command (0 = GM only, 1 = enable) # Enable/Disable create bot by addclass command (0 = GM only, 1 = enable)
# default: 1 (enable) # default: 1 (enable)
AiPlayerbot.AddClassCommand = 1 AiPlayerbot.AddClassCommand = 1
@@ -128,11 +125,10 @@ AiPlayerbot.GroupInvitationPermission = 1
# auto-login all player alts as bots on player login # auto-login all player alts as bots on player login
AiPlayerbot.BotAutologin = 0 AiPlayerbot.BotAutologin = 0
# Allow login other players' characters as bots # Allow/deny bots from the player's account
# Default: 0 (disabled) AiPlayerbot.AllowAccountBots = 1
AiPlayerbot.AllowPlayerBots = 0
# Allow/deny bots from your guild # Allow/deny bots in the player's guild
AiPlayerbot.AllowGuildBots = 1 AiPlayerbot.AllowGuildBots = 1
# Randombots will invite nearby bots to guilds # Randombots will invite nearby bots to guilds
@@ -860,8 +856,8 @@ AiPlayerbot.FastReactInBG = 1
AiPlayerbot.RandomBotUpdateInterval = 20 AiPlayerbot.RandomBotUpdateInterval = 20
AiPlayerbot.RandomBotCountChangeMinInterval = 1800 AiPlayerbot.RandomBotCountChangeMinInterval = 1800
AiPlayerbot.RandomBotCountChangeMaxInterval = 7200 AiPlayerbot.RandomBotCountChangeMaxInterval = 7200
AiPlayerbot.MinRandomBotInWorldTime = 3600 AiPlayerbot.MinRandomBotInWorldTime = 600
AiPlayerbot.MaxRandomBotInWorldTime = 1209600 AiPlayerbot.MaxRandomBotInWorldTime = 28800
AiPlayerbot.MinRandomBotRandomizeTime = 7200 AiPlayerbot.MinRandomBotRandomizeTime = 7200
AiPlayerbot.MaxRandomBotRandomizeTime = 1209600 AiPlayerbot.MaxRandomBotRandomizeTime = 1209600
AiPlayerbot.RandomBotsPerInterval = 60 AiPlayerbot.RandomBotsPerInterval = 60

View File

@@ -125,11 +125,11 @@ bool PlayerbotAIConfig::Initialize()
iterationsPerTick = sConfigMgr->GetOption<int32>("AiPlayerbot.IterationsPerTick", 100); iterationsPerTick = sConfigMgr->GetOption<int32>("AiPlayerbot.IterationsPerTick", 100);
allowAccountBots = sConfigMgr->GetOption<bool>("AiPlayerbot.AllowAccountBots", true);
allowGuildBots = sConfigMgr->GetOption<bool>("AiPlayerbot.AllowGuildBots", true); allowGuildBots = sConfigMgr->GetOption<bool>("AiPlayerbot.AllowGuildBots", true);
randomBotGuildNearby = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotGuildNearby", false); randomBotGuildNearby = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotGuildNearby", false);
randomBotInvitePlayer = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotInvitePlayer", false); randomBotInvitePlayer = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotInvitePlayer", false);
inviteChat = sConfigMgr->GetOption<bool>("AiPlayerbot.InviteChat", false); inviteChat = sConfigMgr->GetOption<bool>("AiPlayerbot.InviteChat", false);
allowPlayerBots = sConfigMgr->GetOption<bool>("AiPlayerbot.AllowPlayerBots", false);
randomBotMapsAsString = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotMaps", "0,1,530,571"); randomBotMapsAsString = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotMaps", "0,1,530,571");
LoadList<std::vector<uint32>>(randomBotMapsAsString, randomBotMaps); LoadList<std::vector<uint32>>(randomBotMapsAsString, randomBotMaps);
@@ -329,9 +329,7 @@ bool PlayerbotAIConfig::Initialize()
useFlyMountAtMinLevel = sConfigMgr->GetOption<int32>("AiPlayerbot.UseFlyMountAtMinLevel", 60); useFlyMountAtMinLevel = sConfigMgr->GetOption<int32>("AiPlayerbot.UseFlyMountAtMinLevel", 60);
useFastFlyMountAtMinLevel = sConfigMgr->GetOption<int32>("AiPlayerbot.UseFastFlyMountAtMinLevel", 70); useFastFlyMountAtMinLevel = sConfigMgr->GetOption<int32>("AiPlayerbot.UseFastFlyMountAtMinLevel", 70);
LOG_INFO("server.loading", "---------------------------------------"); LOG_INFO("server.loading", "Loading TalentSpecs...");
LOG_INFO("server.loading", " Loading TalentSpecs ");
LOG_INFO("server.loading", "---------------------------------------");
for (uint32 cls = 1; cls < MAX_CLASSES; ++cls) for (uint32 cls = 1; cls < MAX_CLASSES; ++cls)
{ {
@@ -474,7 +472,6 @@ bool PlayerbotAIConfig::Initialize()
autoInitEquipLevelLimitRatio = sConfigMgr->GetOption<float>("AiPlayerbot.AutoInitEquipLevelLimitRatio", 1.0); autoInitEquipLevelLimitRatio = sConfigMgr->GetOption<float>("AiPlayerbot.AutoInitEquipLevelLimitRatio", 1.0);
maxAddedBots = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxAddedBots", 40); maxAddedBots = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxAddedBots", 40);
maxAddedBotsPerClass = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxAddedBotsPerClass", 10);
addClassCommand = sConfigMgr->GetOption<int32>("AiPlayerbot.AddClassCommand", 1); addClassCommand = sConfigMgr->GetOption<int32>("AiPlayerbot.AddClassCommand", 1);
addClassAccountPoolSize = sConfigMgr->GetOption<int32>("AiPlayerbot.AddClassAccountPoolSize", 50); addClassAccountPoolSize = sConfigMgr->GetOption<int32>("AiPlayerbot.AddClassAccountPoolSize", 50);
maintenanceCommand = sConfigMgr->GetOption<int32>("AiPlayerbot.MaintenanceCommand", 1); maintenanceCommand = sConfigMgr->GetOption<int32>("AiPlayerbot.MaintenanceCommand", 1);

View File

@@ -54,7 +54,7 @@ public:
bool IsInPvpProhibitedArea(uint32 id); bool IsInPvpProhibitedArea(uint32 id);
bool enabled; bool enabled;
bool allowGuildBots, allowPlayerBots; bool allowAccountBots, allowGuildBots;
bool randomBotGuildNearby, randomBotInvitePlayer, inviteChat; bool randomBotGuildNearby, randomBotInvitePlayer, inviteChat;
uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, maxMovementSearchTime, expireActionTime, uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, maxMovementSearchTime, expireActionTime,
dispelAuraDuration, passiveDelay, repeatDelay, errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay; dispelAuraDuration, passiveDelay, repeatDelay, errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay;
@@ -334,7 +334,7 @@ public:
bool botRepairWhenSummon; bool botRepairWhenSummon;
bool autoInitOnly; bool autoInitOnly;
float autoInitEquipLevelLimitRatio; float autoInitEquipLevelLimitRatio;
int32 maxAddedBots, maxAddedBotsPerClass; int32 maxAddedBots;
int32 addClassCommand; int32 addClassCommand;
int32 addClassAccountPoolSize; int32 addClassAccountPoolSize;
int32 maintenanceCommand; int32 maintenanceCommand;

View File

@@ -17,6 +17,7 @@
#include "Define.h" #include "Define.h"
#include "Group.h" #include "Group.h"
#include "GroupMgr.h" #include "GroupMgr.h"
#include "GuildMgr.h"
#include "ObjectAccessor.h" #include "ObjectAccessor.h"
#include "ObjectGuid.h" #include "ObjectGuid.h"
#include "ObjectMgr.h" #include "ObjectMgr.h"
@@ -37,18 +38,18 @@ class PlayerbotLoginQueryHolder : public LoginQueryHolder
private: private:
uint32 masterAccountId; uint32 masterAccountId;
PlayerbotHolder* playerbotHolder; PlayerbotHolder* playerbotHolder;
public: public:
PlayerbotLoginQueryHolder(PlayerbotHolder* playerbotHolder, uint32 masterAccount, uint32 accountId, ObjectGuid guid) PlayerbotLoginQueryHolder(PlayerbotHolder* playerbotHolder, uint32 masterAccount, uint32 accountId, ObjectGuid guid, bool byAddClass)
: LoginQueryHolder(accountId, guid), masterAccountId(masterAccount), playerbotHolder(playerbotHolder) : LoginQueryHolder(accountId, guid), masterAccountId(masterAccount), playerbotHolder(playerbotHolder), byAddClass(byAddClass)
{ {
} }
uint32 GetMasterAccountId() const { return masterAccountId; } uint32 GetMasterAccountId() const { return masterAccountId; }
PlayerbotHolder* GetPlayerbotHolder() { return playerbotHolder; } PlayerbotHolder* GetPlayerbotHolder() { return playerbotHolder; }
bool byAddClass;
}; };
void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId) void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId, bool byAddClass)
{ {
// bot is loading // bot is loading
if (botLoading.find(playerGuid) != botLoading.end()) if (botLoading.find(playerGuid) != botLoading.end())
@@ -63,8 +64,49 @@ void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId
if (!accountId) if (!accountId)
return; return;
WorldSession* masterSession = masterAccountId ? sWorld->FindSession(masterAccountId) : nullptr;
Player* masterPlayer = masterSession ? masterSession->GetPlayer() : nullptr;
bool isRndbot = !masterAccountId;
bool sameAccount = sPlayerbotAIConfig->allowAccountBots && accountId == masterAccountId;
Guild* guild = masterPlayer ? sGuildMgr->GetGuildById(masterPlayer->GetGuildId()) : nullptr;
bool sameGuild = sPlayerbotAIConfig->allowGuildBots && guild && guild->GetMember(playerGuid);
bool allowed = true;
std::ostringstream out;
std::string botName;
sCharacterCache->GetCharacterNameByGuid(playerGuid, botName);
if (!isRndbot && !sameAccount && !sameGuild && !byAddClass)
{
allowed = false;
out << "Failure: You are not allowed to control bot " << botName.c_str();
}
if (masterAccountId && masterPlayer)
{
PlayerbotMgr* mgr = GET_PLAYERBOT_MGR(masterPlayer);
if (!mgr)
{
LOG_DEBUG("playerbots", "PlayerbotMgr not found for master player with GUID: {}", masterPlayer->GetGUID().GetRawValue());
return;
}
uint32 count = mgr->GetPlayerbotsCount();
if (count >= sPlayerbotAIConfig->maxAddedBots)
{
allowed = false;
out << "Failure: You have added too many bots (more than " << sPlayerbotAIConfig->maxAddedBots << ")";
}
}
if (!allowed)
{
if (masterSession)
{
ChatHandler ch(masterSession);
ch.SendSysMessage(out.str());
}
return;
}
std::shared_ptr<PlayerbotLoginQueryHolder> holder = std::shared_ptr<PlayerbotLoginQueryHolder> holder =
std::make_shared<PlayerbotLoginQueryHolder>(this, masterAccountId, accountId, playerGuid); std::make_shared<PlayerbotLoginQueryHolder>(this, masterAccountId, accountId, playerGuid, byAddClass);
if (!holder->Initialize()) if (!holder->Initialize())
{ {
return; return;
@@ -89,7 +131,7 @@ void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId
void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder const& holder) void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder const& holder)
{ {
uint32 botAccountId = holder.GetAccountId(); uint32 botAccountId = holder.GetAccountId();
bool byAddClass = holder.byAddClass;
// At login DBC locale should be what the server is set to use by default (as spells etc are hardcoded to ENUS this // At login DBC locale should be what the server is set to use by default (as spells etc are hardcoded to ENUS this
// allows channels to work as intended) // allows channels to work as intended)
WorldSession* botSession = new WorldSession(botAccountId, "", nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING, WorldSession* botSession = new WorldSession(botAccountId, "", nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING,
@@ -118,64 +160,9 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
LOG_DEBUG("mod-playerbots", "Master session found but no player is associated for master account ID: {}", masterAccount); LOG_DEBUG("mod-playerbots", "Master session found but no player is associated for master account ID: {}", masterAccount);
} }
std::ostringstream out;
bool allowed = false;
if (botAccountId == masterAccount)
{
allowed = true;
}
else if (masterSession && sPlayerbotAIConfig->allowGuildBots && bot->GetGuildId() != 0 &&
bot->GetGuildId() == masterPlayer->GetGuildId())
{
allowed = true;
}
else if (sPlayerbotAIConfig->IsInRandomAccountList(botAccountId))
{
allowed = true;
}
else
{
allowed = false;
out << "Failure: You are not allowed to control bot " << bot->GetName().c_str();
}
if (allowed && masterSession && masterPlayer)
{
PlayerbotMgr* mgr = GET_PLAYERBOT_MGR(masterPlayer);
if (!mgr)
{
LOG_DEBUG("mod-playerbots", "PlayerbotMgr not found for master player with GUID: {}", masterPlayer->GetGUID().GetRawValue());
}
uint32 count = mgr->GetPlayerbotsCount();
uint32 cls_count = mgr->GetPlayerbotsCountByClass(bot->getClass());
if (count >= sPlayerbotAIConfig->maxAddedBots)
{
allowed = false;
out << "Failure: You have added too many bots";
}
else if (cls_count >= sPlayerbotAIConfig->maxAddedBotsPerClass)
{
allowed = false;
out << "Failure: You have added too many bots for this class";
}
}
if (allowed)
{
sRandomPlayerbotMgr->OnPlayerLogin(bot); sRandomPlayerbotMgr->OnPlayerLogin(bot);
OnBotLogin(bot); OnBotLogin(bot, byAddClass);
}
else
{
if (masterSession)
{
ChatHandler ch(masterSession);
ch.SendSysMessage(out.str());
}
botSession->LogoutPlayer(true);
delete botSession;
}
botLoading.erase(holder.GetGuid()); botLoading.erase(holder.GetGuid());
} }
@@ -352,7 +339,7 @@ void PlayerbotHolder::LogoutPlayerBot(ObjectGuid guid)
botWorldSessionPtr->HandleLogoutRequestOpcode(data); botWorldSessionPtr->HandleLogoutRequestOpcode(data);
if (!bot) if (!bot)
{ {
playerBots.erase(guid); RemoveFromPlayerbotsMap(guid);
delete botWorldSessionPtr; delete botWorldSessionPtr;
if (target) if (target)
delete target; delete target;
@@ -361,7 +348,7 @@ void PlayerbotHolder::LogoutPlayerBot(ObjectGuid guid)
} }
else else
{ {
playerBots.erase(guid); // deletes bot player ptr inside this WorldSession PlayerBotMap RemoveFromPlayerbotsMap(guid); // deletes bot player ptr inside this WorldSession PlayerBotMap
delete botWorldSessionPtr; // finally delete the bot's WorldSession delete botWorldSessionPtr; // finally delete the bot's WorldSession
if (target) if (target)
delete target; delete target;
@@ -371,7 +358,7 @@ void PlayerbotHolder::LogoutPlayerBot(ObjectGuid guid)
else if (bot && (logout || !botWorldSessionPtr->isLogingOut())) else if (bot && (logout || !botWorldSessionPtr->isLogingOut()))
{ {
botAI->TellMaster("Goodbye!"); botAI->TellMaster("Goodbye!");
playerBots.erase(guid); // deletes bot player ptr inside this WorldSession PlayerBotMap RemoveFromPlayerbotsMap(guid); // deletes bot player ptr inside this WorldSession PlayerBotMap
botWorldSessionPtr->LogoutPlayer(true); // this will delete the bot Player object and PlayerbotAI object botWorldSessionPtr->LogoutPlayer(true); // this will delete the bot Player object and PlayerbotAI object
delete botWorldSessionPtr; // finally delete the bot's WorldSession delete botWorldSessionPtr; // finally delete the bot's WorldSession
} }
@@ -408,12 +395,19 @@ void PlayerbotHolder::DisablePlayerBot(ObjectGuid guid)
delete target; delete target;
} }
playerBots.erase(guid); // deletes bot player ptr inside this WorldSession PlayerBotMap RemoveFromPlayerbotsMap(guid); // deletes bot player ptr inside this WorldSession PlayerBotMap
delete botAI; delete botAI;
} }
} }
void PlayerbotHolder::RemoveFromPlayerbotsMap(ObjectGuid guid)
{
playerBots.erase(guid);
if (addClassBots.find(guid) != addClassBots.end())
addClassBots.erase(guid);
}
Player* PlayerbotHolder::GetPlayerBot(ObjectGuid playerGuid) const Player* PlayerbotHolder::GetPlayerBot(ObjectGuid playerGuid) const
{ {
PlayerBotMap::const_iterator it = playerBots.find(playerGuid); PlayerBotMap::const_iterator it = playerBots.find(playerGuid);
@@ -427,7 +421,7 @@ Player* PlayerbotHolder::GetPlayerBot(ObjectGuid::LowType lowGuid) const
return (it == playerBots.end()) ? 0 : it->second; return (it == playerBots.end()) ? 0 : it->second;
} }
void PlayerbotHolder::OnBotLogin(Player* const bot) void PlayerbotHolder::OnBotLogin(Player* const bot, bool byAddClass)
{ {
// Prevent duplicate login // Prevent duplicate login
if (playerBots.find(bot->GetGUID()) != playerBots.end()) if (playerBots.find(bot->GetGUID()) != playerBots.end())
@@ -437,6 +431,9 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
sPlayerbotsMgr->AddPlayerbotData(bot, true); sPlayerbotsMgr->AddPlayerbotData(bot, true);
playerBots[bot->GetGUID()] = bot; playerBots[bot->GetGUID()] = bot;
if (byAddClass)
addClassBots.insert(bot->GetGUID());
OnBotLoginInternal(bot); OnBotLoginInternal(bot);
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
@@ -560,7 +557,7 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
} }
bot->SaveToDB(false, false); bot->SaveToDB(false, false);
if (master && isRandomAccount && master->GetLevel() < bot->GetLevel()) if (byAddClass && master && isRandomAccount && master->GetLevel() < bot->GetLevel())
{ {
// PlayerbotFactory factory(bot, master->GetLevel()); // PlayerbotFactory factory(bot, master->GetLevel());
// factory.Randomize(false); // factory.Randomize(false);
@@ -647,22 +644,11 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
bool isRandomAccount = sPlayerbotAIConfig->IsInRandomAccountList(botAccount); bool isRandomAccount = sPlayerbotAIConfig->IsInRandomAccountList(botAccount);
bool isMasterAccount = (masterAccountId == botAccount); bool isMasterAccount = (masterAccountId == botAccount);
if (!isRandomAccount && !isMasterAccount && !admin && masterguid)
{
Player* master = ObjectAccessor::FindConnectedPlayer(masterguid);
if (master && (!sPlayerbotAIConfig->allowGuildBots || !masterGuildId ||
(masterGuildId && sCharacterCache->GetCharacterGuildIdByGuid(guid) != masterGuildId)))
return "not in your guild or account";
}
if (cmd == "add" || cmd == "login") if (cmd == "add" || cmd == "login")
{ {
if (ObjectAccessor::FindPlayer(guid)) if (ObjectAccessor::FindPlayer(guid))
return "player already logged in"; return "player already logged in";
if (!sPlayerbotAIConfig->allowPlayerBots && !isRandomAccount && !isMasterAccount)
return "You cannot login another player's character as bot.";
AddPlayerBot(guid, masterAccountId); AddPlayerBot(guid, masterAccountId);
return "ok"; return "ok";
} }
@@ -687,11 +673,22 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
if (!bot) if (!bot)
return "bot not found"; return "bot not found";
bool addClassBot = true;
if (!isRandomAccount || isRandomBot) if (!isRandomAccount || isRandomBot)
{ {
return "ERROR: You can not use this command on non-summoned random bot."; addClassBot = false;
} }
if (Player* master = GET_PLAYERBOT_AI(bot)->GetMaster())
{
PlayerbotMgr* masterMgr = GET_PLAYERBOT_MGR(master);
if (masterMgr && masterMgr->addClassBots.find(guid) == masterMgr->addClassBots.end())
addClassBot = false;
}
if (!addClassBot)
return "ERROR: You can not use this command on non-addclass random bot.";
if (!admin) if (!admin)
{ {
Player* master = ObjectAccessor::FindConnectedPlayer(masterguid); Player* master = ObjectAccessor::FindConnectedPlayer(masterguid);
@@ -1077,7 +1074,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
continue; continue;
if (ObjectAccessor::FindConnectedPlayer(guid)) if (ObjectAccessor::FindConnectedPlayer(guid))
continue; continue;
AddPlayerBot(guid, master->GetSession()->GetAccountId()); AddPlayerBot(guid, master->GetSession()->GetAccountId(), true);
messages.push_back("Add class " + std::string(charname)); messages.push_back("Add class " + std::string(charname));
return messages; return messages;
} }

View File

@@ -27,11 +27,12 @@ public:
PlayerbotHolder(); PlayerbotHolder();
virtual ~PlayerbotHolder(){}; virtual ~PlayerbotHolder(){};
void AddPlayerBot(ObjectGuid guid, uint32 masterAccountId); void AddPlayerBot(ObjectGuid guid, uint32 masterAccountId, bool byAddClass = false);
void HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder const& holder); void HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder const& holder);
void LogoutPlayerBot(ObjectGuid guid); void LogoutPlayerBot(ObjectGuid guid);
void DisablePlayerBot(ObjectGuid guid); void DisablePlayerBot(ObjectGuid guid);
void RemoveFromPlayerbotsMap(ObjectGuid guid);
Player* GetPlayerBot(ObjectGuid guid) const; Player* GetPlayerBot(ObjectGuid guid) const;
Player* GetPlayerBot(ObjectGuid::LowType lowGuid) const; Player* GetPlayerBot(ObjectGuid::LowType lowGuid) const;
PlayerBotMap::const_iterator GetPlayerBotsBegin() const { return playerBots.begin(); } PlayerBotMap::const_iterator GetPlayerBotsBegin() const { return playerBots.begin(); }
@@ -42,7 +43,7 @@ public:
void HandleBotPackets(WorldSession* session); void HandleBotPackets(WorldSession* session);
void LogoutAllBots(); void LogoutAllBots();
void OnBotLogin(Player* const bot); void OnBotLogin(Player* const bot, bool byAddClass = false);
std::vector<std::string> HandlePlayerbotCommand(char const* args, Player* master = nullptr); std::vector<std::string> HandlePlayerbotCommand(char const* args, Player* master = nullptr);
std::string const ProcessBotCommand(std::string const cmd, ObjectGuid guid, ObjectGuid masterguid, bool admin, std::string const ProcessBotCommand(std::string const cmd, ObjectGuid guid, ObjectGuid masterguid, bool admin,
@@ -58,6 +59,7 @@ protected:
virtual void OnBotLoginInternal(Player* const bot) = 0; virtual void OnBotLoginInternal(Player* const bot) = 0;
PlayerBotMap playerBots; PlayerBotMap playerBots;
std::unordered_set<ObjectGuid> addClassBots;
std::unordered_set<ObjectGuid> botLoading; std::unordered_set<ObjectGuid> botLoading;
}; };