From 3716de4c967f604e2d90c5b95f6e930a074462c8 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 19 Jul 2024 13:42:25 +0800 Subject: [PATCH 01/10] [Command] Fix sell item command --- src/strategy/actions/SellAction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/strategy/actions/SellAction.cpp b/src/strategy/actions/SellAction.cpp index cafe91920..9bcf8dac4 100644 --- a/src/strategy/actions/SellAction.cpp +++ b/src/strategy/actions/SellAction.cpp @@ -74,7 +74,7 @@ bool SellAction::Execute(Event event) return true; } - if (text == "all") + if (text != "") { std::vector items = parseItems(text, ITERATE_ITEMS_IN_BAGS); for (Item *item : items) @@ -84,7 +84,7 @@ bool SellAction::Execute(Event event) return true; } - botAI->TellError("Usage: s gray/*/vendor/all"); + botAI->TellError("Usage: s gray/*/vendor/[item link]"); return false; } From fce0f431e14dc99e818502de8687f133fe5637db Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 19 Jul 2024 13:43:18 +0800 Subject: [PATCH 02/10] [Command] Enable to cancel self command --- conf/playerbots.conf.dist | 15 +++++++------- src/PlayerbotAI.cpp | 2 +- src/PlayerbotMgr.cpp | 43 +++++++++++++++++++++++++-------------- src/PlayerbotMgr.h | 5 +++-- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index d10f03486..5f0e64d30 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -125,12 +125,12 @@ AiPlayerbot.BotAutologin = 0 # Default: 0 (disabled) AiPlayerbot.AllowPlayerBots = 0 -# Bots will be summoned to player when accept group invitation -AiPlayerbot.SummonWhenGroup = 1 - # Allow/deny bots from your guild AiPlayerbot.AllowGuildBots = 1 +# Bots will be summoned to player when accept group invitation +AiPlayerbot.SummonWhenGroup = 1 + # Added following config # Selfbot permission level (0 = disabled, 1 = gm only (default), 2 = all players, 3 = activate on login) AiPlayerbot.SelfBotLevel = 1 @@ -541,7 +541,7 @@ AiPlayerbot.EquipmentPersistence = 0 # default: 80 AiPlayerbot.EquipmentPersistenceLevel = 80 -# Bot automatically upgrade equipments on levelup +# Randombots automatically upgrade equipments on levelup # Default: 1 (enabled) 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) AiPlayerbot.AutoLearnQuestSpells = 0 -# Bots automatically learn trainable spells on levelup +# Randombots automatically learn trainable spells on levelup # Default: 1 (enabled) AiPlayerbot.AutoLearnTrainerSpells = 1 -# Bot automatically picks talent points on levelup +# Randombots automatically picks talent points on levelup # Default: 1 (enabled) AiPlayerbot.AutoPickTalents = 1 @@ -635,7 +635,6 @@ AiPlayerbot.RandomBotTeleLowerLevel = 3 AiPlayerbot.RandomBotTeleHigherLevel = 1 # Bots automatically teleport to another place for leveling on levelup -# Only for random bots # Default: 1 (enabled) AiPlayerbot.AutoTeleportForLevel = 1 diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 712351568..2210b263f 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -191,7 +191,7 @@ PlayerbotAI::~PlayerbotAI() delete aiObjectContext; if (bot) - sPlayerbotsMgr->RemovePlayerBotData(bot->GetGUID()); + sPlayerbotsMgr->RemovePlayerBotData(bot->GetGUID(), true); } void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal) diff --git a/src/PlayerbotMgr.cpp b/src/PlayerbotMgr.cpp index 2429e3693..3a36dbd8e 100644 --- a/src/PlayerbotMgr.cpp +++ b/src/PlayerbotMgr.cpp @@ -1214,7 +1214,7 @@ PlayerbotMgr::PlayerbotMgr(Player* const master) : PlayerbotHolder(), master(ma PlayerbotMgr::~PlayerbotMgr() { if (master) - sPlayerbotsMgr->RemovePlayerBotData(master->GetGUID()); + sPlayerbotsMgr->RemovePlayerBotData(master->GetGUID(), false); } void PlayerbotMgr::UpdateAIInternal(uint32 elapsed, bool /*minimal*/) @@ -1427,31 +1427,44 @@ void PlayerbotsMgr::AddPlayerbotData(Player* player, bool isBotAI) return; } // If the guid already exists in the map, remove it - std::unordered_map::iterator itr = _playerbotsMap.find(player->GetGUID()); - if (itr != _playerbotsMap.end()) + std::unordered_map::iterator itr = _playerbotsAIMap.find(player->GetGUID()); + if (itr != _playerbotsAIMap.end()) { - _playerbotsMap.erase(itr); + _playerbotsAIMap.erase(itr); + } + itr = _playerbotsMgrMap.find(player->GetGUID()); + if (itr != _playerbotsMgrMap.end()) + { + _playerbotsMgrMap.erase(itr); } if (!isBotAI) { PlayerbotMgr* playerbotMgr = new PlayerbotMgr(player); - ASSERT(_playerbotsMap.emplace(player->GetGUID(), playerbotMgr).second); + ASSERT(_playerbotsAIMap.emplace(player->GetGUID(), playerbotMgr).second); playerbotMgr->OnPlayerLogin(player); } else { PlayerbotAI* botAI = new PlayerbotAI(player); - ASSERT(_playerbotsMap.emplace(player->GetGUID(), botAI).second); + ASSERT(_playerbotsMgrMap.emplace(player->GetGUID(), botAI).second); } } -void PlayerbotsMgr::RemovePlayerBotData(ObjectGuid const& guid) +void PlayerbotsMgr::RemovePlayerBotData(ObjectGuid const& guid, bool is_AI) { - std::unordered_map::iterator itr = _playerbotsMap.find(guid); - if (itr != _playerbotsMap.end()) - { - _playerbotsMap.erase(itr); + if (is_AI) { + std::unordered_map::iterator itr = _playerbotsAIMap.find(guid); + if (itr != _playerbotsAIMap.end()) + { + _playerbotsAIMap.erase(itr); + } + } else { + std::unordered_map::iterator itr = _playerbotsMgrMap.find(guid); + if (itr != _playerbotsMgrMap.end()) + { + _playerbotsMgrMap.erase(itr); + } } } @@ -1464,8 +1477,8 @@ PlayerbotAI* PlayerbotsMgr::GetPlayerbotAI(Player* player) // if (player->GetSession()->isLogingOut() || player->IsDuringRemoveFromWorld()) { // return nullptr; // } - auto itr = _playerbotsMap.find(player->GetGUID()); - if (itr != _playerbotsMap.end()) + auto itr = _playerbotsAIMap.find(player->GetGUID()); + if (itr != _playerbotsAIMap.end()) { if (itr->second->IsBotAI()) return reinterpret_cast(itr->second); @@ -1480,8 +1493,8 @@ PlayerbotMgr* PlayerbotsMgr::GetPlayerbotMgr(Player* player) { return nullptr; } - auto itr = _playerbotsMap.find(player->GetGUID()); - if (itr != _playerbotsMap.end()) + auto itr = _playerbotsMgrMap.find(player->GetGUID()); + if (itr != _playerbotsMgrMap.end()) { if (!itr->second->IsBotAI()) return reinterpret_cast(itr->second); diff --git a/src/PlayerbotMgr.h b/src/PlayerbotMgr.h index d430d414b..c8297c0aa 100644 --- a/src/PlayerbotMgr.h +++ b/src/PlayerbotMgr.h @@ -99,13 +99,14 @@ class PlayerbotsMgr } void AddPlayerbotData(Player* player, bool isBotAI); - void RemovePlayerBotData(ObjectGuid const& guid); + void RemovePlayerBotData(ObjectGuid const& guid, bool is_AI); PlayerbotAI* GetPlayerbotAI(Player* player); PlayerbotMgr* GetPlayerbotMgr(Player* player); private: - std::unordered_map _playerbotsMap; + std::unordered_map _playerbotsAIMap; + std::unordered_map _playerbotsMgrMap; }; #define sPlayerbotsMgr PlayerbotsMgr::instance() From 2f93eeedc9c4a5bffd3791d759dbf254c681062f Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 19 Jul 2024 13:43:30 +0800 Subject: [PATCH 03/10] [Crash fix] Fix a possible crash --- src/strategy/actions/InviteToGroupAction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strategy/actions/InviteToGroupAction.cpp b/src/strategy/actions/InviteToGroupAction.cpp index 0b7b5e8ad..8c8bd74bc 100644 --- a/src/strategy/actions/InviteToGroupAction.cpp +++ b/src/strategy/actions/InviteToGroupAction.cpp @@ -19,7 +19,7 @@ bool InviteToGroupAction::Execute(Event event) bool InviteToGroupAction::Invite(Player* player) { - if (!player) + if (!player || !player->IsInWorld()) return false; if (!GET_PLAYERBOT_AI(player) && !botAI->GetSecurity()->CheckLevelFor(PLAYERBOT_SECURITY_INVITE, true, player)) From cdd4ab70800036bff2a4ff204b815f3aef67eaa0 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 19 Jul 2024 14:52:19 +0800 Subject: [PATCH 04/10] [Command] Fix self command --- src/PlayerbotMgr.cpp | 30 ++++++++++++++++-------------- src/Playerbots.cpp | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/PlayerbotMgr.cpp b/src/PlayerbotMgr.cpp index 3a36dbd8e..3aea6da07 100644 --- a/src/PlayerbotMgr.cpp +++ b/src/PlayerbotMgr.cpp @@ -842,7 +842,7 @@ std::vector PlayerbotHolder::HandlePlayerbotCommand(char const* arg if (GET_PLAYERBOT_AI(master)) { messages.push_back("Disable player botAI"); - DisablePlayerBot(master->GetGUID()); + delete GET_PLAYERBOT_AI(master); } else if (sPlayerbotAIConfig->selfBotLevel == 0) messages.push_back("Self-bot is disabled"); @@ -851,7 +851,8 @@ std::vector PlayerbotHolder::HandlePlayerbotCommand(char const* arg else { messages.push_back("Enable player botAI"); - OnBotLogin(master); + sPlayerbotsMgr->AddPlayerbotData(master, true); + GET_PLAYERBOT_AI(master)->SetMaster(master); } return messages; @@ -1427,27 +1428,28 @@ void PlayerbotsMgr::AddPlayerbotData(Player* player, bool isBotAI) return; } // If the guid already exists in the map, remove it - std::unordered_map::iterator itr = _playerbotsAIMap.find(player->GetGUID()); - if (itr != _playerbotsAIMap.end()) - { - _playerbotsAIMap.erase(itr); - } - itr = _playerbotsMgrMap.find(player->GetGUID()); - if (itr != _playerbotsMgrMap.end()) - { - _playerbotsMgrMap.erase(itr); - } + if (!isBotAI) { + std::unordered_map::iterator itr = _playerbotsMgrMap.find(player->GetGUID()); + if (itr != _playerbotsMgrMap.end()) + { + _playerbotsMgrMap.erase(itr); + } PlayerbotMgr* playerbotMgr = new PlayerbotMgr(player); - ASSERT(_playerbotsAIMap.emplace(player->GetGUID(), playerbotMgr).second); + ASSERT(_playerbotsMgrMap.emplace(player->GetGUID(), playerbotMgr).second); playerbotMgr->OnPlayerLogin(player); } else { + std::unordered_map::iterator itr = _playerbotsAIMap.find(player->GetGUID()); + if (itr != _playerbotsAIMap.end()) + { + _playerbotsAIMap.erase(itr); + } PlayerbotAI* botAI = new PlayerbotAI(player); - ASSERT(_playerbotsMgrMap.emplace(player->GetGUID(), botAI).second); + ASSERT(_playerbotsAIMap.emplace(player->GetGUID(), botAI).second); } } diff --git a/src/Playerbots.cpp b/src/Playerbots.cpp index 6b6462cca..ad519e13e 100644 --- a/src/Playerbots.cpp +++ b/src/Playerbots.cpp @@ -299,7 +299,7 @@ class PlayerbotsScript : public PlayerbotScript { botAI->HandleBotOutgoingPacket(*packet); } - else if (PlayerbotMgr* playerbotMgr = GET_PLAYERBOT_MGR(player)) + if (PlayerbotMgr* playerbotMgr = GET_PLAYERBOT_MGR(player)) { playerbotMgr->HandleMasterOutgoingPacket(*packet); } From e7fe79d946bf638318adac2ec86eead9f4b72136 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 19 Jul 2024 15:40:31 +0800 Subject: [PATCH 05/10] [Initialization] Send talent packet after intialization --- src/AiFactory.cpp | 2 +- src/PlayerbotFactory.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/AiFactory.cpp b/src/AiFactory.cpp index d6baa1eb1..54d189dce 100644 --- a/src/AiFactory.cpp +++ b/src/AiFactory.cpp @@ -553,7 +553,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const if (sPlayerbotAIConfig->autoSaveMana) { nonCombatEngine->addStrategy("auto save mana"); } - if ((facade->IsRealPlayer() || sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground()) + if ((sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground()) { Player* master = facade->GetMaster(); diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index 26f9e3a69..c6f78887a 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -644,6 +644,7 @@ void PlayerbotFactory::InitPetTalents() spells_row.erase(spells_row.begin() + index); } } + bot->SendTalentsInfoData(true); } void PlayerbotFactory::InitPet() @@ -870,6 +871,7 @@ void PlayerbotFactory::InitTalentsTree(bool increment/*false*/, bool use_templat if (bot->GetFreeTalentPoints()) InitTalents((specTab + 1) % 3); } + bot->SendTalentsInfoData(false); } void PlayerbotFactory::InitTalentsBySpecNo(Player* bot, int specNo, bool reset) @@ -933,6 +935,7 @@ void PlayerbotFactory::InitTalentsBySpecNo(Player* bot, int specNo, bool reset) break; } } + bot->SendTalentsInfoData(false); } void PlayerbotFactory::InitTalentsByParsedSpecLink(Player* bot, std::vector> parsedSpecLink, bool reset) @@ -983,6 +986,7 @@ void PlayerbotFactory::InitTalentsByParsedSpecLink(Player* bot, std::vectorSendTalentsInfoData(false); } class DestroyItemsVisitor : public IterateItemsVisitor @@ -2983,6 +2987,7 @@ void PlayerbotFactory::InitGlyphs(bool increment) } } } + bot->SendTalentsInfoData(false); } void PlayerbotFactory::CancelAuras() From b4201e1d84df3bd38f7aae7e0b1c0f7cf45b017a Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 19 Jul 2024 16:59:00 +0800 Subject: [PATCH 06/10] [Misc] Init bag, hunter spell --- src/PlayerbotFactory.cpp | 2 +- src/strategy/hunter/HunterTriggers.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index c6f78887a..200402d3d 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -1738,7 +1738,7 @@ void PlayerbotFactory::InitBags(bool destroyOld) bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true); } if (old_bag) { - return; + continue; } Item* newItem = bot->EquipNewItem(dest, newItemId, true); if (newItem) diff --git a/src/strategy/hunter/HunterTriggers.h b/src/strategy/hunter/HunterTriggers.h index b64c4b650..6896fd321 100644 --- a/src/strategy/hunter/HunterTriggers.h +++ b/src/strategy/hunter/HunterTriggers.h @@ -88,10 +88,10 @@ class FreezingTrapTrigger : public HasCcTargetTrigger FreezingTrapTrigger(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, "freezing trap") { } }; -class RapidFireTrigger : public BuffTrigger +class RapidFireTrigger : public BoostTrigger { public: - RapidFireTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "rapid fire") { } + RapidFireTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "rapid fire") { } }; class TrueshotAuraTrigger : public BuffTrigger From 400f9821019a486c1b497d9f8f4f85f53b821108 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Sun, 21 Jul 2024 22:20:59 +0800 Subject: [PATCH 07/10] [Class spell] Mirror image --- src/strategy/mage/GenericMageStrategy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strategy/mage/GenericMageStrategy.cpp b/src/strategy/mage/GenericMageStrategy.cpp index e6bff447d..793ad49a2 100644 --- a/src/strategy/mage/GenericMageStrategy.cpp +++ b/src/strategy/mage/GenericMageStrategy.cpp @@ -153,7 +153,7 @@ void MageBoostStrategy::InitTriggers(std::vector& triggers) 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("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& triggers) From 00e24b2681ad932176ef26fa6f55c23c674c54d2 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Sun, 21 Jul 2024 22:23:03 +0800 Subject: [PATCH 08/10] [Command] Send talents info data after glyph changed --- src/strategy/actions/TrainerAction.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/strategy/actions/TrainerAction.cpp b/src/strategy/actions/TrainerAction.cpp index 231dea7d9..151792343 100644 --- a/src/strategy/actions/TrainerAction.cpp +++ b/src/strategy/actions/TrainerAction.cpp @@ -172,6 +172,7 @@ bool MaintenanceAction::Execute(Event event) factory.ApplyEnchantAndGemsNew(); } bot->DurabilityRepairAll(false, 1.0f, false); + bot->SendTalentsInfoData(false); return true; } @@ -181,6 +182,7 @@ bool RemoveGlyphAction::Execute(Event event) { bot->SetGlyph(slotIndex, 0, true); } + bot->SendTalentsInfoData(false); return true; } From dd942bf4493d06180c4e8b95ba49381169e2ea43 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Sun, 21 Jul 2024 23:04:16 +0800 Subject: [PATCH 09/10] Addclass command account id check --- src/PlayerbotMgr.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/PlayerbotMgr.cpp b/src/PlayerbotMgr.cpp index 3aea6da07..bd93a8f87 100644 --- a/src/PlayerbotMgr.cpp +++ b/src/PlayerbotMgr.cpp @@ -939,20 +939,22 @@ std::vector PlayerbotHolder::HandlePlayerbotCommand(char const* arg race_limit = "2, 5, 6, 8, 10"; break; } + uint32 maxAccountId = sPlayerbotAIConfig->randomBotAccounts.back(); // find a bot fit conditions and not in any guild 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 ) " - "ORDER BY account DESC LIMIT 1", claz, race_limit); + "AND account <= {} " + "ORDER BY account DESC LIMIT 1", claz, race_limit, maxAccountId); if (results) { Field* fields = results->Fetch(); ObjectGuid guid = ObjectGuid(HighGuid::Player, fields[0].Get()); AddPlayerBot(guid, master->GetSession()->GetAccountId()); - messages.push_back("addclass " + std::string(charname) + " ok"); + messages.push_back("Add class " + std::string(charname)); return messages; } - messages.push_back("addclass failed."); + messages.push_back("Add class failed."); return messages; } From 5ebba9cdb3941180cae425b7fc3c97ca1bd9ae04 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Sun, 21 Jul 2024 23:53:47 +0800 Subject: [PATCH 10/10] Fix spell cast after self bot --- src/strategy/values/SpellIdValue.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/strategy/values/SpellIdValue.cpp b/src/strategy/values/SpellIdValue.cpp index 0e7eef384..beb445f8e 100644 --- a/src/strategy/values/SpellIdValue.cpp +++ b/src/strategy/values/SpellIdValue.cpp @@ -6,6 +6,7 @@ #include "ChatHelper.h" #include "Playerbots.h" #include "Vehicle.h" +#include "World.h" SpellIdValue::SpellIdValue(PlayerbotAI* botAI) : CalculatedValue(botAI, "spell id", 20 * 1000) { @@ -34,7 +35,7 @@ uint32 SpellIdValue::Calculate() char firstSymbol = tolower(namepart[0]); int spellLength = wnamepart.length(); - LocaleConstant loc = bot->GetSession()->GetSessionDbcLocale(); + LocaleConstant loc = LOCALE_enUS; std::set spellIds; for (PlayerSpellMap::iterator itr = bot->GetSpellMap().begin(); itr != bot->GetSpellMap().end(); ++itr)