From f2b55804957221c15e88356dfbbf7705e6a1b411 Mon Sep 17 00:00:00 2001 From: IainD92 Date: Fri, 3 Oct 2025 10:56:16 +0100 Subject: [PATCH 1/3] Maintenance config for altbots (#1693) * Maintenance config controls bools in config * Update TrainerAction.cpp removed some note-to-selfs (personal config preferences) * Set default to true Also tidied up some comments * Update playerbots.conf.dist * Reorganised Changed the description in conf to be less conversational. Rearranged the order that options are arranged, grouping by what made sense to me (the type of gameplay made easier/skipped by the option being enabled). Rearranged the order the variables and method calls are listed in the code to match the order they are presented in the conf to make future maintenance of maintenance (:P) more intuitive. * Update playerbots.conf.dist Revert previous commit (change to call order in MaintenanceAction::Execute) conf settings grouped --- conf/playerbots.conf.dist | 28 +++++++ src/PlayerbotAIConfig.cpp | 21 +++++ src/PlayerbotAIConfig.h | 19 +++++ src/strategy/actions/TrainerAction.cpp | 103 ++++++++++++++++++++----- 4 files changed, 151 insertions(+), 20 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 19761738..bf576384 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -488,6 +488,34 @@ AiPlayerbot.RPWarningCooldown = 30 # Default: 1 (enabled) AiPlayerbot.MaintenanceCommand = 1 +# Enable/Disable specific maintenance command functionality for alt bots +# Disable to prevent players from giving free bags, spells, skill levels etc to their alt bots +# Default: 1 (enabled) +AiPlayerbot.AltMaintenanceAmmo = 1 +AiPlayerbot.AltMaintenanceFood = 1 +AiPlayerbot.AltMaintenanceReagents = 1 +AiPlayerbot.AltMaintenanceConsumables = 1 +AiPlayerbot.AltMaintenancePotions = 1 + +AiPlayerbot.AltMaintenanceBags = 1 +AiPlayerbot.AltMaintenanceMounts = 1 +AiPlayerbot.AltMaintenanceSkills = 1 + +AiPlayerbot.AltMaintenanceClassSpells = 1 # Spells from quests (tame/summon pets, totems, druid forms, etc) +AiPlayerbot.AltMaintenanceAvailableSpells = 1 # Spells learnable from trainer +AiPlayerbot.AltMaintenanceSpecialSpells = 1 # Leave DK starting area +AiPlayerbot.AltMaintenanceTalentTree = 1 +AiPlayerbot.AltMaintenanceGlyphs = 1 +AiPlayerbot.AltMaintenanceGemsEnchants = 1 + +AiPlayerbot.AltMaintenancePet = 1 +AiPlayerbot.AltMaintenancePetTalents = 1 + +AiPlayerbot.AltMaintenanceReputation = 1 +AiPlayerbot.AltMaintenanceAttunementQuests = 1 +AiPlayerbot.AltMaintenanceKeyring = 1 + + # Enable/Disable autogear command, which automatically upgrades bots' gear; the quality is limited by AutoGearQualityLimit and AutoGearScoreLimit # Default: 1 (enabled) AiPlayerbot.AutoGearCommand = 1 diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index 80cdeb97..0343be52 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -553,6 +553,27 @@ bool PlayerbotAIConfig::Initialize() addClassCommand = sConfigMgr->GetOption("AiPlayerbot.AddClassCommand", 1); addClassAccountPoolSize = sConfigMgr->GetOption("AiPlayerbot.AddClassAccountPoolSize", 50); maintenanceCommand = sConfigMgr->GetOption("AiPlayerbot.MaintenanceCommand", 1); + + altMaintenanceAttunementQs = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceAttunementQuests", true); + altMaintenanceBags = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceBags", true); + altMaintenanceAmmo = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceAmmo", true); + altMaintenanceFood = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceFood", true); + altMaintenanceReagents = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceReagents", true); + altMaintenanceConsumables = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceConsumables", true); + altMaintenancePotions = sConfigMgr->GetOption("AiPlayerbot.AltMaintenancePotions", true); + altMaintenanceTalentTree = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceTalentTree", true); + altMaintenancePet = sConfigMgr->GetOption("AiPlayerbot.AltMaintenancePet", true); + altMaintenancePetTalents = sConfigMgr->GetOption("AiPlayerbot.AltMaintenancePetTalents", true); + altMaintenanceClassSpells = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceClassSpells", true); + altMaintenanceAvailableSpells = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceAvailableSpells", true); + altMaintenanceSkills = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceSkills", true); + altMaintenanceReputation = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceReputation", true); + altMaintenanceSpecialSpells = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceSpecialSpells", true); + altMaintenanceMounts = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceMounts", true); + altMaintenanceGlyphs = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceGlyphs", true); + altMaintenanceKeyring = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceKeyring", true); + altMaintenanceGemsEnchants = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceGemsEnchants", true); + autoGearCommand = sConfigMgr->GetOption("AiPlayerbot.AutoGearCommand", 1); autoGearCommandAltBots = sConfigMgr->GetOption("AiPlayerbot.AutoGearCommandAltBots", 1); autoGearQualityLimit = sConfigMgr->GetOption("AiPlayerbot.AutoGearQualityLimit", 3); diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index e7b404d8..c20f16dd 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -393,6 +393,25 @@ public: int32 addClassCommand; int32 addClassAccountPoolSize; int32 maintenanceCommand; + bool altMaintenanceAttunementQs, + altMaintenanceBags, + altMaintenanceAmmo, + altMaintenanceFood, + altMaintenanceReagents, + altMaintenanceConsumables, + altMaintenancePotions, + altMaintenanceTalentTree, + altMaintenancePet, + altMaintenancePetTalents, + altMaintenanceClassSpells, + altMaintenanceAvailableSpells, + altMaintenanceSkills, + altMaintenanceReputation, + altMaintenanceSpecialSpells, + altMaintenanceMounts, + altMaintenanceGlyphs, + altMaintenanceKeyring, + altMaintenanceGemsEnchants; int32 autoGearCommand, autoGearCommandAltBots, autoGearQualityLimit, autoGearScoreLimit; uint32 useGroundMountAtMinLevel; diff --git a/src/strategy/actions/TrainerAction.cpp b/src/strategy/actions/TrainerAction.cpp index 2de9d283..c5509cf8 100644 --- a/src/strategy/actions/TrainerAction.cpp +++ b/src/strategy/actions/TrainerAction.cpp @@ -170,26 +170,89 @@ bool MaintenanceAction::Execute(Event event) botAI->TellMaster("I'm maintaining"); PlayerbotFactory factory(bot, bot->GetLevel()); - factory.InitAttunementQuests(); - factory.InitBags(false); - factory.InitAmmo(); - factory.InitFood(); - factory.InitReagents(); - factory.InitConsumables(); - factory.InitPotions(); - factory.InitTalentsTree(true); - factory.InitPet(); - factory.InitPetTalents(); - factory.InitClassSpells(); - factory.InitAvailableSpells(); - factory.InitSkills(); - factory.InitReputation(); - factory.InitSpecialSpells(); - factory.InitMounts(); - factory.InitGlyphs(false); - factory.InitKeyring(); - if (bot->GetLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel) - factory.ApplyEnchantAndGemsNew(); + + if (!botAI->IsAlt()) + { + factory.InitAttunementQuests(); + factory.InitBags(false); + factory.InitAmmo(); + factory.InitFood(); + factory.InitReagents(); + factory.InitConsumables(); + factory.InitPotions(); + factory.InitTalentsTree(true); + factory.InitPet(); + factory.InitPetTalents(); + factory.InitClassSpells(); + factory.InitAvailableSpells(); + factory.InitSkills(); + factory.InitReputation(); + factory.InitSpecialSpells(); + factory.InitMounts(); + factory.InitGlyphs(false); + factory.InitKeyring(); + if (bot->GetLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel) + factory.ApplyEnchantAndGemsNew(); + } + else + { + if (sPlayerbotAIConfig->altMaintenanceAttunementQs) + factory.InitAttunementQuests(); + + if (sPlayerbotAIConfig->altMaintenanceBags) + factory.InitBags(false); + + if (sPlayerbotAIConfig->altMaintenanceAmmo) + factory.InitAmmo(); + + if (sPlayerbotAIConfig->altMaintenanceFood) + factory.InitFood(); + + if (sPlayerbotAIConfig->altMaintenanceReagents) + factory.InitReagents(); + + if (sPlayerbotAIConfig->altMaintenanceConsumables) + factory.InitConsumables(); + + if (sPlayerbotAIConfig->altMaintenancePotions) + factory.InitPotions(); + + if (sPlayerbotAIConfig->altMaintenanceTalentTree) + factory.InitTalentsTree(true); + + if (sPlayerbotAIConfig->altMaintenancePet) + factory.InitPet(); + + if (sPlayerbotAIConfig->altMaintenancePetTalents) + factory.InitPetTalents(); + + if (sPlayerbotAIConfig->altMaintenanceClassSpells) + factory.InitClassSpells(); + + if (sPlayerbotAIConfig->altMaintenanceAvailableSpells) + factory.InitAvailableSpells(); + + if (sPlayerbotAIConfig->altMaintenanceSkills) + factory.InitSkills(); + + if (sPlayerbotAIConfig->altMaintenanceReputation) + factory.InitReputation(); + + if (sPlayerbotAIConfig->altMaintenanceSpecialSpells) + factory.InitSpecialSpells(); + + if (sPlayerbotAIConfig->altMaintenanceMounts) + factory.InitMounts(); + + if (sPlayerbotAIConfig->altMaintenanceGlyphs) + factory.InitGlyphs(false); + + if (sPlayerbotAIConfig->altMaintenanceKeyring) + factory.InitKeyring(); + + if (sPlayerbotAIConfig->altMaintenanceGemsEnchants && bot->GetLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel) + factory.ApplyEnchantAndGemsNew(); + } bot->DurabilityRepairAll(false, 1.0f, false); bot->SendTalentsInfoData(false); From 2a340ce68f65eedd7670e1d3e77a8308d9f01de9 Mon Sep 17 00:00:00 2001 From: IainD92 Date: Fri, 3 Oct 2025 13:19:17 +0100 Subject: [PATCH 2/3] Update playerbots.conf.dist (#1698) Removed comments from the end of lines (results in bad value) --- conf/playerbots.conf.dist | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index bf576384..67a13c9d 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -501,9 +501,9 @@ AiPlayerbot.AltMaintenanceBags = 1 AiPlayerbot.AltMaintenanceMounts = 1 AiPlayerbot.AltMaintenanceSkills = 1 -AiPlayerbot.AltMaintenanceClassSpells = 1 # Spells from quests (tame/summon pets, totems, druid forms, etc) -AiPlayerbot.AltMaintenanceAvailableSpells = 1 # Spells learnable from trainer -AiPlayerbot.AltMaintenanceSpecialSpells = 1 # Leave DK starting area +AiPlayerbot.AltMaintenanceClassSpells = 1 +AiPlayerbot.AltMaintenanceAvailableSpells = 1 +AiPlayerbot.AltMaintenanceSpecialSpells = 1 AiPlayerbot.AltMaintenanceTalentTree = 1 AiPlayerbot.AltMaintenanceGlyphs = 1 AiPlayerbot.AltMaintenanceGemsEnchants = 1 From 377ac199a7e6f7e583bc095fe0ab7d5148fc7e97 Mon Sep 17 00:00:00 2001 From: bash <31279994+hermensbas@users.noreply.github.com> Date: Fri, 3 Oct 2025 22:58:30 +0200 Subject: [PATCH 3/3] Revert "Feat: Filter bot logins by level range" (#1705) --- conf/playerbots.conf.dist | 13 +-- src/PlayerbotAIConfig.cpp | 3 - src/PlayerbotAIConfig.h | 2 - src/Playerbots.cpp | 30 +---- src/RandomPlayerbotMgr.cpp | 231 ++++++------------------------------- src/RandomPlayerbotMgr.h | 18 --- 6 files changed, 40 insertions(+), 257 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 67a13c9d..244fa991 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -597,21 +597,10 @@ AiPlayerbot.RandomBotRandomPassword = 0 # Prefix for account names to create for randombots AiPlayerbot.RandomBotAccountPrefix = "rndbot" -# Minimum and maximum initialization levels for randombots +# Minimum and maximum levels for randombots AiPlayerbot.RandomBotMinLevel = 1 AiPlayerbot.RandomBotMaxLevel = 80 -# Minimum and maximum level range for randombots allowed to login -# If level filtration is used, minRandomBots and maxRandomBots might be automatically adjusted to lower values, -# depending on available eligible bots in the database -# Default Min,Max: 1,80 (no level filtration) -AiPlayerbot.RandomBotMinLoginLevel = 1 -AiPlayerbot.RandomBotMaxLoginLevel = 80 - -# log-out randombots if they they level outside the allowed login range -# Default: 0 (disabled) -AiPlayerbot.RandomBotLogoutOutsideLoginRange = 0 - # Sync max randombot level with max level of online players # Default: 0 (disabled) AiPlayerbot.SyncLevelWithPlayers = 0 diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index 0343be52..65b6f5bc 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -86,9 +86,6 @@ bool PlayerbotAIConfig::Initialize() rpWarningCooldown = sConfigMgr->GetOption("AiPlayerbot.RPWarningCooldown", 30); disabledWithoutRealPlayerLoginDelay = sConfigMgr->GetOption("AiPlayerbot.DisabledWithoutRealPlayerLoginDelay", 30); disabledWithoutRealPlayerLogoutDelay = sConfigMgr->GetOption("AiPlayerbot.DisabledWithoutRealPlayerLogoutDelay", 300); - randomBotMinLoginLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotMinLoginLevel", 1); - randomBotMaxLoginLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotMaxLoginLevel", 80); - randomBotLogoutOutsideLoginRange = sConfigMgr->GetOption("AiPlayerbot.RandomBotLogoutOutsideLoginRange", false); farDistance = sConfigMgr->GetOption("AiPlayerbot.FarDistance", 20.0f); sightDistance = sConfigMgr->GetOption("AiPlayerbot.SightDistance", 75.0f); diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index c20f16dd..391b991a 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -247,8 +247,6 @@ public: std::string randomBotCombatStrategies, randomBotNonCombatStrategies; bool applyInstanceStrategies; uint32 randomBotMinLevel, randomBotMaxLevel; - uint32 randomBotMinLoginLevel, randomBotMaxLoginLevel; - bool randomBotLogoutOutsideLoginRange; float randomChangeMultiplier; // std::string premadeLevelSpec[MAX_CLASSES][10][91]; //lvl 10 - 100 diff --git a/src/Playerbots.cpp b/src/Playerbots.cpp index 926e1f4e..b5334ba7 100644 --- a/src/Playerbots.cpp +++ b/src/Playerbots.cpp @@ -87,8 +87,7 @@ public: PLAYERHOOK_ON_BEFORE_CRITERIA_PROGRESS, PLAYERHOOK_ON_BEFORE_ACHI_COMPLETE, PLAYERHOOK_CAN_PLAYER_USE_PRIVATE_CHAT, - PLAYERHOOK_ON_GIVE_EXP, - PLAYERHOOK_ON_LEVEL_CHANGED + PLAYERHOOK_ON_GIVE_EXP }) {} void OnPlayerLogin(Player* player) override @@ -122,33 +121,6 @@ public: } } - void OnPlayerLevelChanged(Player* player, uint8 oldLevel) override - { - // Check if feature is enabled and required objects are valid - if (!sPlayerbotAIConfig || !sPlayerbotAIConfig->randomBotLogoutOutsideLoginRange || !sRandomPlayerbotMgr) - return; - - // Only apply to bots from rndBotTypeAccounts (type 1) - uint32 accountId = player->GetSession()->GetAccountId(); - if (!sRandomPlayerbotMgr->IsAccountType(accountId, 1)) - return; - - uint32 newLevel = player->GetLevel(); - - // Check if the new level is outside the allowed login range - if (newLevel < sPlayerbotAIConfig->randomBotMinLoginLevel || - newLevel > sPlayerbotAIConfig->randomBotMaxLoginLevel) - { - LOG_INFO("playerbots", "Bot {} changed levels from {} to {}, outside login range ({}-{}). Marking for logout", - player->GetName(), oldLevel, newLevel, - sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel); - - // Mark the bot for removal in the next update cycle - sRandomPlayerbotMgr->MarkBotForLogout(player->GetGUID().GetCounter()); - sRandomPlayerbotMgr->ForceRecount(); - } - } - void OnPlayerAfterUpdate(Player* player, uint32 diff) override { if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(player)) diff --git a/src/RandomPlayerbotMgr.cpp b/src/RandomPlayerbotMgr.cpp index 557450d0..ab28c25d 100644 --- a/src/RandomPlayerbotMgr.cpp +++ b/src/RandomPlayerbotMgr.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include "AccountMgr.h" #include "AiFactory.h" @@ -375,76 +374,13 @@ void RandomPlayerbotMgr::UpdateAIInternal(uint32 elapsed, bool /*minimal*/) }*/ uint32 maxAllowedBotCount = GetEventValue(0, "bot_count"); - - // Check if level filtering is active and populate eligible bots - if (!levelFilterAdjusted && IsLevelFilterActive()) + if (!maxAllowedBotCount || (maxAllowedBotCount < sPlayerbotAIConfig->minRandomBots || + maxAllowedBotCount > sPlayerbotAIConfig->maxRandomBots)) { - PopulateEligibleBots(); - - // Count total eligible bots from RNDbot accounts - uint32 eligibleBotCount = 0; - - for (uint32 accountId : rndBotTypeAccounts) - { - QueryResult result = CharacterDatabase.Query( - "SELECT COUNT(*) FROM characters WHERE account = {} AND level >= {} AND level <= {}", - accountId, sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel - ); - - if (result) - { - Field* fields = result->Fetch(); - eligibleBotCount += fields[0].Get(); - } - } - - if (eligibleBotCount > 0) - { - // Cap eligible bots by maxRandomBots - uint32 effectiveMaxBots = std::min(eligibleBotCount, sPlayerbotAIConfig->maxRandomBots); - - LOG_INFO("playerbots", "Level filter active: {} eligible bots found in range {}-{}. Effective maximum: {} bots.", - eligibleBotCount, sPlayerbotAIConfig->randomBotMinLoginLevel, - sPlayerbotAIConfig->randomBotMaxLoginLevel, effectiveMaxBots); - - if (effectiveMaxBots >= sPlayerbotAIConfig->minRandomBots) - { - maxAllowedBotCount = urand(sPlayerbotAIConfig->minRandomBots, effectiveMaxBots); - } - else - { - maxAllowedBotCount = effectiveMaxBots; - } - - SetEventValue(0, "bot_count", maxAllowedBotCount, - urand(sPlayerbotAIConfig->randomBotCountChangeMinInterval, - sPlayerbotAIConfig->randomBotCountChangeMaxInterval)); - - currentBots.clear(); - levelFilterAdjusted = true; - } - else - { - LOG_ERROR("playerbots", "No eligible bots found with level filter {}-{}. Change the level range.", - sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel); - SetEventValue(0, "bot_count", 0, INT_MAX); - maxAllowedBotCount = 0; - currentBots.clear(); - levelFilterAdjusted = true; - } - } - else if (!levelFilterAdjusted) - { - // Normal bot count logic (no level filtering) - if (!maxAllowedBotCount || (maxAllowedBotCount < sPlayerbotAIConfig->minRandomBots || - maxAllowedBotCount > sPlayerbotAIConfig->maxRandomBots)) - { - maxAllowedBotCount = urand(sPlayerbotAIConfig->minRandomBots, sPlayerbotAIConfig->maxRandomBots); - SetEventValue(0, "bot_count", maxAllowedBotCount, - urand(sPlayerbotAIConfig->randomBotCountChangeMinInterval, - sPlayerbotAIConfig->randomBotCountChangeMaxInterval)); - } - levelFilterAdjusted = true; + maxAllowedBotCount = urand(sPlayerbotAIConfig->minRandomBots, sPlayerbotAIConfig->maxRandomBots); + SetEventValue(0, "bot_count", maxAllowedBotCount, + urand(sPlayerbotAIConfig->randomBotCountChangeMinInterval, + sPlayerbotAIConfig->randomBotCountChangeMaxInterval)); } GetBots(); @@ -836,41 +772,23 @@ uint32 RandomPlayerbotMgr::AddRandomBots() for (uint32 accountId : accountsToUse) { - // Lambda to process results regardless of query type - auto processResults = [&](auto result) - { - if (!result) - return; + CharacterDatabasePreparedStatement* stmt = + CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID); + stmt->SetData(0, accountId); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) + continue; - do - { - Field* fields = result->Fetch(); - CharacterInfo info; - info.guid = fields[0].Get(); - info.rClass = fields[1].Get(); - info.rRace = fields[2].Get(); - info.accountId = accountId; - allCharacters.push_back(info); - } while (result->NextRow()); - }; - - if (IsLevelFilterActive()) + do { - // Custom query with level filtering - auto result = CharacterDatabase.Query( - "SELECT guid, class, race FROM characters WHERE account = {} AND level >= {} AND level <= {}", - accountId, sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel - ); - processResults(result); - } - else - { - CharacterDatabasePreparedStatement* stmt = - CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID); - stmt->SetData(0, accountId); - auto result = CharacterDatabase.Query(stmt); - processResults(result); - } + Field* fields = result->Fetch(); + CharacterInfo info; + info.guid = fields[0].Get(); + info.rClass = fields[1].Get(); + info.rRace = fields[2].Get(); + info.accountId = accountId; + allCharacters.push_back(info); + } while (result->NextRow()); } // Shuffle for class balance @@ -2752,55 +2670,17 @@ void RandomPlayerbotMgr::GetBots() stmt->SetData(0, 0); stmt->SetData(1, "add"); uint32 maxAllowedBotCount = GetEventValue(0, "bot_count"); - if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt)) { do { Field* fields = result->Fetch(); uint32 bot = fields[0].Get(); - if (GetEventValue(bot, "add")) - { - // Single query to get both account and level - QueryResult charResult = CharacterDatabase.Query("SELECT account, level FROM characters WHERE guid = {}", bot); - if (!charResult) - continue; - - Field* charFields = charResult->Fetch(); - uint32 botAccountId = charFields[0].Get(); - uint32 botLevel = charFields[1].Get(); - - // Skip if not an RNDbot account - bool isRndBotAccount = false; - for (uint32 accountId : rndBotTypeAccounts) - { - if (accountId == botAccountId) - { - isRndBotAccount = true; - break; - } - } - - if (!isRndBotAccount) - continue; - - // If level filtering is active, check bot level - if (IsLevelFilterActive()) - { - // Skip bots outside the allowed level range - if (botLevel < sPlayerbotAIConfig->randomBotMinLoginLevel || - botLevel > sPlayerbotAIConfig->randomBotMaxLoginLevel) - { - continue; - } - } - currentBots.push_back(bot); - if (currentBots.size() >= maxAllowedBotCount) - break; - } + if (currentBots.size() >= maxAllowedBotCount) + break; } while (result->NextRow()); } } @@ -2828,51 +2708,6 @@ std::vector RandomPlayerbotMgr::GetBgBots(uint32 bracket) return std::move(BgBots); } -void RandomPlayerbotMgr::PopulateEligibleBots() -{ - if (!sPlayerbotAIConfig || !(sPlayerbotAIConfig->randomBotMinLoginLevel > 1 || - sPlayerbotAIConfig->randomBotMaxLoginLevel < 80)) - return; - - LOG_INFO("playerbots", "Populating eligible bots for level filter ({}-{})...", - sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel); - - bool botsAdded = false; - - // Use only RNDbot type accounts (type 1) - for (uint32 accountId : rndBotTypeAccounts) - { - QueryResult result = CharacterDatabase.Query( - "SELECT guid, level, online FROM characters WHERE account = {} AND level >= {} AND level <= {}", - accountId, sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel - ); - - if (result) - { - do - { - Field* fields = result->Fetch(); - uint32 botGuid = fields[0].Get(); - bool isOnline = fields[2].Get(); - - // Skip bots that are already online or already have "add" event - if (isOnline || GetEventValue(botGuid, "add")) - continue; - - uint32 add_time = urand(sPlayerbotAIConfig->minRandomBotInWorldTime, - sPlayerbotAIConfig->maxRandomBotInWorldTime); - SetEventValue(botGuid, "add", 1, add_time); - botsAdded = true; - } while (result->NextRow()); - } - } - - if (botsAdded) - { - currentBots.clear(); // Force reload - } -} - uint32 RandomPlayerbotMgr::GetEventValue(uint32 bot, std::string const event) { // load all events at once on first event load @@ -2900,13 +2735,23 @@ uint32 RandomPlayerbotMgr::GetEventValue(uint32 bot, std::string const event) } CachedEvent& e = eventCache[bot][event]; + /*if (e.IsEmpty()) + { + QueryResult results = PlayerbotsDatabase.Query("SELECT `value`, `time`, validIn, `data` FROM + playerbots_random_bots WHERE owner = 0 AND bot = {} AND event = {}", bot, event.c_str()); - bool shouldExpire = (time(0) - e.lastChangeTime) >= e.validIn && - event != "specNo" && - event != "specLink" && - !(event == "bot_count" && IsLevelFilterActive()); // Don't expire bot_count when level filtering is active + if (results) + { + Field* fields = results->Fetch(); + e.value = fields[0].Get(); + e.lastChangeTime = fields[1].Get(); + e.validIn = fields[2].Get(); + e.data = fields[3].Get(); + } + } + */ - if (shouldExpire) + if ((time(0) - e.lastChangeTime) >= e.validIn && event != "specNo" && event != "specLink") e.value = 0; return e.value; diff --git a/src/RandomPlayerbotMgr.h b/src/RandomPlayerbotMgr.h index 0906ef54..be624328 100644 --- a/src/RandomPlayerbotMgr.h +++ b/src/RandomPlayerbotMgr.h @@ -193,14 +193,6 @@ public: void AssignAccountTypes(); bool IsAccountType(uint32 accountId, uint8 accountType); - // Allowed login range management - void ForceRecount() { SetEventValue(0, "bot_count", 0, 0); } - void MarkBotForLogout(uint32 bot) - { - SetEventValue(bot, "add", 0, 0); // Clear the "add" event to trigger logout - SetEventValue(bot, "logout", 1, 1); // Also set logout for clarity - } - protected: void OnBotLoginInternal(Player* const bot) override; @@ -245,16 +237,6 @@ private: std::vector rndBotTypeAccounts; // Accounts marked as RNDbot (type 1) std::vector addClassTypeAccounts; // Accounts marked as AddClass (type 2) - // Login level filtering - bool levelFilterAdjusted = false; - void PopulateEligibleBots(); - bool IsLevelFilterActive() const - { - return sPlayerbotAIConfig && - (sPlayerbotAIConfig->randomBotMinLoginLevel > 1 || - sPlayerbotAIConfig->randomBotMaxLoginLevel < 80); - } - //void ScaleBotActivity(); // Deprecated function };