From 8cb77796bb287111d2b0d943920cd875f4b1477f Mon Sep 17 00:00:00 2001 From: Dustin Hendrickson Date: Sat, 5 Jul 2025 12:27:37 -0700 Subject: [PATCH] Exclusion list --- README.md | 1 + conf/mod_player_bot_level_brackets.conf.dist | 5 ++ src/mod-player-bot-level-brackets.cpp | 59 ++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/README.md b/README.md index 2690c36..261861e 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ BotLevelBrackets.Dynamic.SyncFactions | Enables synchronized brackets and w BotLevelBrackets.IgnoreFriendListed | Ignores bots that are on real players' friend lists from any bracket calculations. | 1 | 0 (off) / 1 (on) BotLevelBrackets.IgnoreGuildBotsWithRealPlayers | Excludes bots in a guild with at least one real (non-bot) player online from adjustments. | 1 | 0 (disabled) / 1 (enabled) BotLevelBrackets.NumRanges | Number of level brackets used for bot distribution. Both factions must have the same number defined. | 9 | Positive Integer +BotLevelBrackets.ExcludeNames | Comma-separated list of case insensitive bot names to exclude from all bracket checks. | | String **IMPORTANT:** If you extend the number of brackets beyond the default 9, you must update both your `mod_player_bot_level_brackets.conf` file and the accompanying `mod_player_bot_level_brackets.conf.dist` file to include configuration lines for the additional ranges (e.g. Range10, Range11, etc.), ensuring that the sum of the Pct values remains 100. diff --git a/conf/mod_player_bot_level_brackets.conf.dist b/conf/mod_player_bot_level_brackets.conf.dist index 9ed2d3a..4310747 100644 --- a/conf/mod_player_bot_level_brackets.conf.dist +++ b/conf/mod_player_bot_level_brackets.conf.dist @@ -57,6 +57,11 @@ BotLevelBrackets.IgnoreGuildBotsWithRealPlayers = 1 # Valid values: 0 (off) / 1 (on) BotLevelBrackets.IgnoreFriendListed = 1 +# BotLevelBrackets.ExcludeNames +# Description: Comma-separated list of case insensitive bot names to exclude from all bracket checks. +# Default: "" +BotLevelBrackets.ExcludeNames = + # # BotLevelBrackets.NumRanges # Description: The number of level brackets used for bot distribution. diff --git a/src/mod-player-bot-level-brackets.cpp b/src/mod-player-bot-level-brackets.cpp index 2a6da8c..47ba74a 100644 --- a/src/mod-player-bot-level-brackets.cpp +++ b/src/mod-player-bot-level-brackets.cpp @@ -71,6 +71,9 @@ static bool g_SyncFactions = false; // Array for character social list friends std::vector g_SocialFriendsList; +// Array for excluded bot names. +static std::vector g_ExcludeBotNames; + // Array for real player guild IDs. std::unordered_set g_RealPlayerGuildIds; @@ -111,6 +114,17 @@ static void LoadBotLevelBracketsConfig() g_IgnoreFriendListed = sConfigMgr->GetOption("BotLevelBrackets.IgnoreFriendListed", true); g_FlaggedProcessLimit = sConfigMgr->GetOption("BotLevelBrackets.FlaggedProcessLimit", 5); + std::string excludeNames = sConfigMgr->GetOption("BotLevelBrackets.ExcludeNames", ""); + g_ExcludeBotNames.clear(); + std::istringstream f(excludeNames); + std::string s; + while (getline(f, s, ',')) { + s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end()); + if (!s.empty()) { + g_ExcludeBotNames.push_back(s); + } + } + // Load the bot level restrictions. g_RandomBotMinLevel = static_cast(sConfigMgr->GetOption("AiPlayerbot.RandomBotMinLevel", 1)); g_RandomBotMaxLevel = static_cast(sConfigMgr->GetOption("AiPlayerbot.RandomBotMaxLevel", 80)); @@ -737,6 +751,32 @@ static bool IsBotSafeForLevelReset(Player* bot) return true; } +/** + * @brief Checks if a given bot is in the exclusion list for bracket processing. + * + * This function determines whether the provided bot's name matches any entry in the global + * exclusion list `g_ExcludeBotNames`, which is populated from the BotLevelBrackets.ExcludeNames config. + * If a match is found, this bot will not be considered for any bracket checks or level resets. + * + * @param bot Pointer to the Player object representing the bot to check. + * @return true if the bot is excluded from bracket processing, false otherwise. + */ +static bool IsBotExcluded(Player* bot) +{ + if (!bot) + { + return false; + } + const std::string& name = bot->GetName(); + for (const auto& excluded : g_ExcludeBotNames) + { + if (excluded == name) + { + return true; + } + } + return false; +} /** * @brief Processes the pending level reset requests for player bots. @@ -788,6 +828,12 @@ static void ProcessPendingLevelResets() continue; } + if (IsBotExcluded(bot)) + { + it = g_PendingLevelResets.erase(it); + continue; + } + int targetRange = it->targetRange; if (g_IgnoreGuildBotsWithRealPlayers && BotInGuildWithRealPlayer(bot)) { @@ -831,6 +877,11 @@ static void ProcessPendingLevelResets() */ static int GetOrFlagPlayerBracket(Player* player) { + if (IsPlayerBot(player) && IsBotExcluded(player)) + { + return -1; + } + int rangeIndex = GetLevelRangeIndex(player->GetLevel(), player->GetTeamId()); if (rangeIndex >= 0) { @@ -1172,6 +1223,14 @@ public: } continue; } + if (IsBotExcluded(player)) + { + if (g_BotDistFullDebugMode) + { + LOG_INFO("server.loading", "[BotLevelBrackets] Skipping excluded bot '{}'.", player->GetName()); + } + continue; + } if (g_IgnoreGuildBotsWithRealPlayers && BotInGuildWithRealPlayer(player)) { continue;