Merge pull request #367 from liyunfan1223/self-command

Fix .playerbot bot self
This commit is contained in:
Yunfan Li
2024-07-24 12:27:56 +08:00
committed by GitHub
13 changed files with 68 additions and 43 deletions

View File

@@ -125,12 +125,12 @@ AiPlayerbot.BotAutologin = 0
# Default: 0 (disabled) # Default: 0 (disabled)
AiPlayerbot.AllowPlayerBots = 0 AiPlayerbot.AllowPlayerBots = 0
# Bots will be summoned to player when accept group invitation
AiPlayerbot.SummonWhenGroup = 1
# Allow/deny bots from your guild # Allow/deny bots from your guild
AiPlayerbot.AllowGuildBots = 1 AiPlayerbot.AllowGuildBots = 1
# Bots will be summoned to player when accept group invitation
AiPlayerbot.SummonWhenGroup = 1
# Added following config # Added following config
# Selfbot permission level (0 = disabled, 1 = gm only (default), 2 = all players, 3 = activate on login) # Selfbot permission level (0 = disabled, 1 = gm only (default), 2 = all players, 3 = activate on login)
AiPlayerbot.SelfBotLevel = 1 AiPlayerbot.SelfBotLevel = 1
@@ -541,7 +541,7 @@ AiPlayerbot.EquipmentPersistence = 0
# default: 80 # default: 80
AiPlayerbot.EquipmentPersistenceLevel = 80 AiPlayerbot.EquipmentPersistenceLevel = 80
# Bot automatically upgrade equipments on levelup # Randombots automatically upgrade equipments on levelup
# Default: 1 (enabled) # Default: 1 (enabled)
AiPlayerbot.AutoUpgradeEquip = 1 AiPlayerbot.AutoUpgradeEquip = 1
@@ -578,15 +578,15 @@ AiPlayerbot.RandomBotQuestItems = "6948,5175,5176,5177,5178,16309,12382,13704,11
# #
# #
# Bots automatically learn classquest reward spells on levelup # Randombots automatically learn classquest reward spells on levelup
# Default: 0 (disabled) # Default: 0 (disabled)
AiPlayerbot.AutoLearnQuestSpells = 0 AiPlayerbot.AutoLearnQuestSpells = 0
# Bots automatically learn trainable spells on levelup # Randombots automatically learn trainable spells on levelup
# Default: 1 (enabled) # Default: 1 (enabled)
AiPlayerbot.AutoLearnTrainerSpells = 1 AiPlayerbot.AutoLearnTrainerSpells = 1
# Bot automatically picks talent points on levelup # Randombots automatically picks talent points on levelup
# Default: 1 (enabled) # Default: 1 (enabled)
AiPlayerbot.AutoPickTalents = 1 AiPlayerbot.AutoPickTalents = 1
@@ -635,7 +635,6 @@ AiPlayerbot.RandomBotTeleLowerLevel = 3
AiPlayerbot.RandomBotTeleHigherLevel = 1 AiPlayerbot.RandomBotTeleHigherLevel = 1
# Bots automatically teleport to another place for leveling on levelup # Bots automatically teleport to another place for leveling on levelup
# Only for random bots
# Default: 1 (enabled) # Default: 1 (enabled)
AiPlayerbot.AutoTeleportForLevel = 1 AiPlayerbot.AutoTeleportForLevel = 1

View File

@@ -553,7 +553,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
if (sPlayerbotAIConfig->autoSaveMana) { if (sPlayerbotAIConfig->autoSaveMana) {
nonCombatEngine->addStrategy("auto save mana"); nonCombatEngine->addStrategy("auto save mana");
} }
if ((facade->IsRealPlayer() || sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground()) if ((sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground())
{ {
Player* master = facade->GetMaster(); Player* master = facade->GetMaster();

View File

@@ -191,7 +191,7 @@ PlayerbotAI::~PlayerbotAI()
delete aiObjectContext; delete aiObjectContext;
if (bot) if (bot)
sPlayerbotsMgr->RemovePlayerBotData(bot->GetGUID()); sPlayerbotsMgr->RemovePlayerBotData(bot->GetGUID(), true);
} }
void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal) void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)

View File

@@ -644,6 +644,7 @@ void PlayerbotFactory::InitPetTalents()
spells_row.erase(spells_row.begin() + index); spells_row.erase(spells_row.begin() + index);
} }
} }
bot->SendTalentsInfoData(true);
} }
void PlayerbotFactory::InitPet() void PlayerbotFactory::InitPet()
@@ -870,6 +871,7 @@ void PlayerbotFactory::InitTalentsTree(bool increment/*false*/, bool use_templat
if (bot->GetFreeTalentPoints()) if (bot->GetFreeTalentPoints())
InitTalents((specTab + 1) % 3); InitTalents((specTab + 1) % 3);
} }
bot->SendTalentsInfoData(false);
} }
void PlayerbotFactory::InitTalentsBySpecNo(Player* bot, int specNo, bool reset) void PlayerbotFactory::InitTalentsBySpecNo(Player* bot, int specNo, bool reset)
@@ -933,6 +935,7 @@ void PlayerbotFactory::InitTalentsBySpecNo(Player* bot, int specNo, bool reset)
break; break;
} }
} }
bot->SendTalentsInfoData(false);
} }
void PlayerbotFactory::InitTalentsByParsedSpecLink(Player* bot, std::vector<std::vector<uint32>> parsedSpecLink, bool reset) void PlayerbotFactory::InitTalentsByParsedSpecLink(Player* bot, std::vector<std::vector<uint32>> parsedSpecLink, bool reset)
@@ -983,6 +986,7 @@ void PlayerbotFactory::InitTalentsByParsedSpecLink(Player* bot, std::vector<std:
break; break;
} }
} }
bot->SendTalentsInfoData(false);
} }
class DestroyItemsVisitor : public IterateItemsVisitor class DestroyItemsVisitor : public IterateItemsVisitor
@@ -1734,7 +1738,7 @@ void PlayerbotFactory::InitBags(bool destroyOld)
bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true); bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true);
} }
if (old_bag) { if (old_bag) {
return; continue;
} }
Item* newItem = bot->EquipNewItem(dest, newItemId, true); Item* newItem = bot->EquipNewItem(dest, newItemId, true);
if (newItem) if (newItem)
@@ -2983,6 +2987,7 @@ void PlayerbotFactory::InitGlyphs(bool increment)
} }
} }
} }
bot->SendTalentsInfoData(false);
} }
void PlayerbotFactory::CancelAuras() void PlayerbotFactory::CancelAuras()

View File

@@ -842,7 +842,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
if (GET_PLAYERBOT_AI(master)) if (GET_PLAYERBOT_AI(master))
{ {
messages.push_back("Disable player botAI"); messages.push_back("Disable player botAI");
DisablePlayerBot(master->GetGUID()); delete GET_PLAYERBOT_AI(master);
} }
else if (sPlayerbotAIConfig->selfBotLevel == 0) else if (sPlayerbotAIConfig->selfBotLevel == 0)
messages.push_back("Self-bot is disabled"); messages.push_back("Self-bot is disabled");
@@ -851,7 +851,8 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
else else
{ {
messages.push_back("Enable player botAI"); messages.push_back("Enable player botAI");
OnBotLogin(master); sPlayerbotsMgr->AddPlayerbotData(master, true);
GET_PLAYERBOT_AI(master)->SetMaster(master);
} }
return messages; return messages;
@@ -938,20 +939,22 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
race_limit = "2, 5, 6, 8, 10"; race_limit = "2, 5, 6, 8, 10";
break; break;
} }
uint32 maxAccountId = sPlayerbotAIConfig->randomBotAccounts.back();
// find a bot fit conditions and not in any guild // find a bot fit conditions and not in any guild
QueryResult results = CharacterDatabase.Query("SELECT guid FROM characters " QueryResult results = CharacterDatabase.Query("SELECT guid FROM characters "
"WHERE name IN (SELECT name FROM playerbots_names) AND class = '{}' AND online = 0 AND race IN ({}) AND guid NOT IN ( SELECT guid FROM guild_member ) " "WHERE name IN (SELECT name FROM playerbots_names) AND class = '{}' AND online = 0 AND race IN ({}) AND guid NOT IN ( SELECT guid FROM guild_member ) "
"ORDER BY account DESC LIMIT 1", claz, race_limit); "AND account <= {} "
"ORDER BY account DESC LIMIT 1", claz, race_limit, maxAccountId);
if (results) if (results)
{ {
Field* fields = results->Fetch(); Field* fields = results->Fetch();
ObjectGuid guid = ObjectGuid(HighGuid::Player, fields[0].Get<uint32>()); ObjectGuid guid = ObjectGuid(HighGuid::Player, fields[0].Get<uint32>());
AddPlayerBot(guid, master->GetSession()->GetAccountId()); AddPlayerBot(guid, master->GetSession()->GetAccountId());
messages.push_back("addclass " + std::string(charname) + " ok"); messages.push_back("Add class " + std::string(charname));
return messages; return messages;
} }
messages.push_back("addclass failed."); messages.push_back("Add class failed.");
return messages; return messages;
} }
@@ -1214,7 +1217,7 @@ PlayerbotMgr::PlayerbotMgr(Player* const master) : PlayerbotHolder(), master(ma
PlayerbotMgr::~PlayerbotMgr() PlayerbotMgr::~PlayerbotMgr()
{ {
if (master) if (master)
sPlayerbotsMgr->RemovePlayerBotData(master->GetGUID()); sPlayerbotsMgr->RemovePlayerBotData(master->GetGUID(), false);
} }
void PlayerbotMgr::UpdateAIInternal(uint32 elapsed, bool /*minimal*/) void PlayerbotMgr::UpdateAIInternal(uint32 elapsed, bool /*minimal*/)
@@ -1427,31 +1430,45 @@ void PlayerbotsMgr::AddPlayerbotData(Player* player, bool isBotAI)
return; return;
} }
// If the guid already exists in the map, remove it // If the guid already exists in the map, remove it
std::unordered_map<ObjectGuid, PlayerbotAIBase*>::iterator itr = _playerbotsMap.find(player->GetGUID());
if (itr != _playerbotsMap.end())
{
_playerbotsMap.erase(itr);
}
if (!isBotAI) if (!isBotAI)
{ {
std::unordered_map<ObjectGuid, PlayerbotAIBase*>::iterator itr = _playerbotsMgrMap.find(player->GetGUID());
if (itr != _playerbotsMgrMap.end())
{
_playerbotsMgrMap.erase(itr);
}
PlayerbotMgr* playerbotMgr = new PlayerbotMgr(player); PlayerbotMgr* playerbotMgr = new PlayerbotMgr(player);
ASSERT(_playerbotsMap.emplace(player->GetGUID(), playerbotMgr).second); ASSERT(_playerbotsMgrMap.emplace(player->GetGUID(), playerbotMgr).second);
playerbotMgr->OnPlayerLogin(player); playerbotMgr->OnPlayerLogin(player);
} }
else else
{ {
std::unordered_map<ObjectGuid, PlayerbotAIBase*>::iterator itr = _playerbotsAIMap.find(player->GetGUID());
if (itr != _playerbotsAIMap.end())
{
_playerbotsAIMap.erase(itr);
}
PlayerbotAI* botAI = new PlayerbotAI(player); PlayerbotAI* botAI = new PlayerbotAI(player);
ASSERT(_playerbotsMap.emplace(player->GetGUID(), botAI).second); ASSERT(_playerbotsAIMap.emplace(player->GetGUID(), botAI).second);
} }
} }
void PlayerbotsMgr::RemovePlayerBotData(ObjectGuid const& guid) void PlayerbotsMgr::RemovePlayerBotData(ObjectGuid const& guid, bool is_AI)
{ {
std::unordered_map<ObjectGuid, PlayerbotAIBase*>::iterator itr = _playerbotsMap.find(guid); if (is_AI) {
if (itr != _playerbotsMap.end()) std::unordered_map<ObjectGuid, PlayerbotAIBase*>::iterator itr = _playerbotsAIMap.find(guid);
{ if (itr != _playerbotsAIMap.end())
_playerbotsMap.erase(itr); {
_playerbotsAIMap.erase(itr);
}
} else {
std::unordered_map<ObjectGuid, PlayerbotAIBase*>::iterator itr = _playerbotsMgrMap.find(guid);
if (itr != _playerbotsMgrMap.end())
{
_playerbotsMgrMap.erase(itr);
}
} }
} }
@@ -1464,8 +1481,8 @@ PlayerbotAI* PlayerbotsMgr::GetPlayerbotAI(Player* player)
// if (player->GetSession()->isLogingOut() || player->IsDuringRemoveFromWorld()) { // if (player->GetSession()->isLogingOut() || player->IsDuringRemoveFromWorld()) {
// return nullptr; // return nullptr;
// } // }
auto itr = _playerbotsMap.find(player->GetGUID()); auto itr = _playerbotsAIMap.find(player->GetGUID());
if (itr != _playerbotsMap.end()) if (itr != _playerbotsAIMap.end())
{ {
if (itr->second->IsBotAI()) if (itr->second->IsBotAI())
return reinterpret_cast<PlayerbotAI*>(itr->second); return reinterpret_cast<PlayerbotAI*>(itr->second);
@@ -1480,8 +1497,8 @@ PlayerbotMgr* PlayerbotsMgr::GetPlayerbotMgr(Player* player)
{ {
return nullptr; return nullptr;
} }
auto itr = _playerbotsMap.find(player->GetGUID()); auto itr = _playerbotsMgrMap.find(player->GetGUID());
if (itr != _playerbotsMap.end()) if (itr != _playerbotsMgrMap.end())
{ {
if (!itr->second->IsBotAI()) if (!itr->second->IsBotAI())
return reinterpret_cast<PlayerbotMgr*>(itr->second); return reinterpret_cast<PlayerbotMgr*>(itr->second);

View File

@@ -99,13 +99,14 @@ class PlayerbotsMgr
} }
void AddPlayerbotData(Player* player, bool isBotAI); void AddPlayerbotData(Player* player, bool isBotAI);
void RemovePlayerBotData(ObjectGuid const& guid); void RemovePlayerBotData(ObjectGuid const& guid, bool is_AI);
PlayerbotAI* GetPlayerbotAI(Player* player); PlayerbotAI* GetPlayerbotAI(Player* player);
PlayerbotMgr* GetPlayerbotMgr(Player* player); PlayerbotMgr* GetPlayerbotMgr(Player* player);
private: private:
std::unordered_map<ObjectGuid, PlayerbotAIBase*> _playerbotsMap; std::unordered_map<ObjectGuid, PlayerbotAIBase*> _playerbotsAIMap;
std::unordered_map<ObjectGuid, PlayerbotAIBase*> _playerbotsMgrMap;
}; };
#define sPlayerbotsMgr PlayerbotsMgr::instance() #define sPlayerbotsMgr PlayerbotsMgr::instance()

View File

@@ -299,7 +299,7 @@ class PlayerbotsScript : public PlayerbotScript
{ {
botAI->HandleBotOutgoingPacket(*packet); botAI->HandleBotOutgoingPacket(*packet);
} }
else if (PlayerbotMgr* playerbotMgr = GET_PLAYERBOT_MGR(player)) if (PlayerbotMgr* playerbotMgr = GET_PLAYERBOT_MGR(player))
{ {
playerbotMgr->HandleMasterOutgoingPacket(*packet); playerbotMgr->HandleMasterOutgoingPacket(*packet);
} }

View File

@@ -19,7 +19,7 @@ bool InviteToGroupAction::Execute(Event event)
bool InviteToGroupAction::Invite(Player* player) bool InviteToGroupAction::Invite(Player* player)
{ {
if (!player) if (!player || !player->IsInWorld())
return false; return false;
if (!GET_PLAYERBOT_AI(player) && !botAI->GetSecurity()->CheckLevelFor(PLAYERBOT_SECURITY_INVITE, true, player)) if (!GET_PLAYERBOT_AI(player) && !botAI->GetSecurity()->CheckLevelFor(PLAYERBOT_SECURITY_INVITE, true, player))

View File

@@ -74,7 +74,7 @@ bool SellAction::Execute(Event event)
return true; return true;
} }
if (text == "all") if (text != "")
{ {
std::vector<Item *> items = parseItems(text, ITERATE_ITEMS_IN_BAGS); std::vector<Item *> items = parseItems(text, ITERATE_ITEMS_IN_BAGS);
for (Item *item : items) for (Item *item : items)
@@ -84,7 +84,7 @@ bool SellAction::Execute(Event event)
return true; return true;
} }
botAI->TellError("Usage: s gray/*/vendor/all"); botAI->TellError("Usage: s gray/*/vendor/[item link]");
return false; return false;
} }

View File

@@ -172,6 +172,7 @@ bool MaintenanceAction::Execute(Event event)
factory.ApplyEnchantAndGemsNew(); factory.ApplyEnchantAndGemsNew();
} }
bot->DurabilityRepairAll(false, 1.0f, false); bot->DurabilityRepairAll(false, 1.0f, false);
bot->SendTalentsInfoData(false);
return true; return true;
} }
@@ -181,6 +182,7 @@ bool RemoveGlyphAction::Execute(Event event)
{ {
bot->SetGlyph(slotIndex, 0, true); bot->SetGlyph(slotIndex, 0, true);
} }
bot->SendTalentsInfoData(false);
return true; return true;
} }

View File

@@ -88,10 +88,10 @@ class FreezingTrapTrigger : public HasCcTargetTrigger
FreezingTrapTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "freezing trap") { } FreezingTrapTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "freezing trap") { }
}; };
class RapidFireTrigger : public BuffTrigger class RapidFireTrigger : public BoostTrigger
{ {
public: public:
RapidFireTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "rapid fire") { } RapidFireTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "rapid fire") { }
}; };
class TrueshotAuraTrigger : public BuffTrigger class TrueshotAuraTrigger : public BuffTrigger

View File

@@ -180,7 +180,7 @@ void MageBoostStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(new TriggerNode("icy veins", NextAction::array(0, new NextAction("icy veins", 50.0f), nullptr))); triggers.push_back(new TriggerNode("icy veins", NextAction::array(0, new NextAction("icy veins", 50.0f), nullptr)));
triggers.push_back(new TriggerNode("presence of mind", NextAction::array(0, new NextAction("presence of mind", 42.0f), nullptr))); triggers.push_back(new TriggerNode("presence of mind", NextAction::array(0, new NextAction("presence of mind", 42.0f), nullptr)));
// triggers.push_back(new TriggerNode("arcane power", NextAction::array(0, new NextAction("arcane power", 41.0f), nullptr))); // triggers.push_back(new TriggerNode("arcane power", NextAction::array(0, new NextAction("arcane power", 41.0f), nullptr)));
// triggers.push_back(new TriggerNode("mirror image", NextAction::array(0, new NextAction("mirror image", 41.0f), nullptr))); triggers.push_back(new TriggerNode("mirror image", NextAction::array(0, new NextAction("mirror image", 41.0f), nullptr)));
} }
void MageCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void MageCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)

View File

@@ -6,6 +6,7 @@
#include "ChatHelper.h" #include "ChatHelper.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "World.h"
SpellIdValue::SpellIdValue(PlayerbotAI* botAI) : CalculatedValue<uint32>(botAI, "spell id", 20 * 1000) SpellIdValue::SpellIdValue(PlayerbotAI* botAI) : CalculatedValue<uint32>(botAI, "spell id", 20 * 1000)
{ {
@@ -34,7 +35,7 @@ uint32 SpellIdValue::Calculate()
char firstSymbol = tolower(namepart[0]); char firstSymbol = tolower(namepart[0]);
int spellLength = wnamepart.length(); int spellLength = wnamepart.length();
LocaleConstant loc = bot->GetSession()->GetSessionDbcLocale(); LocaleConstant loc = LOCALE_enUS;
std::set<uint32> spellIds; std::set<uint32> spellIds;
for (PlayerSpellMap::iterator itr = bot->GetSpellMap().begin(); itr != bot->GetSpellMap().end(); ++itr) for (PlayerSpellMap::iterator itr = bot->GetSpellMap().begin(); itr != bot->GetSpellMap().end(); ++itr)