diff --git a/conf/mod_player_bot_level_brackets.conf.dist b/conf/mod_player_bot_level_brackets.conf.dist index 9d2d7e2..9c81f37 100644 --- a/conf/mod_player_bot_level_brackets.conf.dist +++ b/conf/mod_player_bot_level_brackets.conf.dist @@ -52,6 +52,13 @@ BotLevelBrackets.UseDynamicDistribution = 0 # Default: 1.0 BotLevelBrackets.RealPlayerWeight = 1.0 +# +# BotLevelBrackets.IgnoreFriendListed +# Description: Ignore bots that are on real players friend's lists from any brackets +# Default: 1 (enabled) +# Valid values: 0 (off) / 1 (on) +BotLevelBrackets.IgnoreFriendListed = 1 + # # Alliance Level Brackets Configuration # The percentages below must sum to 100. diff --git a/src/mod-player-bot-level-brackets.cpp b/src/mod-player-bot-level-brackets.cpp index cedb73d..d364320 100644 --- a/src/mod-player-bot-level-brackets.cpp +++ b/src/mod-player-bot-level-brackets.cpp @@ -15,6 +15,9 @@ #include #include #include "PlayerbotFactory.h" +#include "DatabaseEnv.h" +#include "QueryResult.h" + static bool IsAlliancePlayerBot(Player* bot); static bool IsHordePlayerBot(Player* bot); @@ -52,10 +55,14 @@ static uint32 g_BotDistFlaggedCheckFrequency = 15; // in seconds static bool g_BotDistFullDebugMode = false; static bool g_BotDistLiteDebugMode = false; static bool g_UseDynamicDistribution = false; +static bool g_IgnoreFriendListed = true; // Real player weight to boost bracket contributions. static float g_RealPlayerWeight = 1.0f; +// Array for character social list friends +std::vector SocialFriendsList; + // ----------------------------------------------------------------------------- // Loads the configuration from the config file. // ----------------------------------------------------------------------------- @@ -71,6 +78,7 @@ static void LoadBotLevelBracketsConfig() g_BotDistFlaggedCheckFrequency = sConfigMgr->GetOption("BotLevelBrackets.CheckFlaggedFrequency", 15); g_UseDynamicDistribution = sConfigMgr->GetOption("BotLevelBrackets.UseDynamicDistribution", false); g_RealPlayerWeight = sConfigMgr->GetOption("BotLevelBrackets.RealPlayerWeight", 1.0f); + g_IgnoreFriendListed = sConfigMgr->GetOption("BotLevelBrackets.IgnoreFriendListed", true); // Load the bot level restrictions. g_RandomBotMinLevel = static_cast(sConfigMgr->GetOption("AiPlayerbot.RandomBotMinLevel", 1)); @@ -101,6 +109,37 @@ static void LoadBotLevelBracketsConfig() ClampAndBalanceBrackets(); } +// ----------------------------------------------------------------------------- +// Loads the friend guid(s) from character_social into array +// ----------------------------------------------------------------------------- +static void LoadSocialFriendList() +{ + SocialFriendsList.clear(); + QueryResult result = CharacterDatabase.Query("SELECT friend FROM character_social WHERE flags = 1"); + + if (!result) + return; + + if (result->GetRowCount() == 0) + return; + + if (g_BotDistFullDebugMode) + { + LOG_INFO("server.loading", "[BotLevelBrackets] Fetching Social Friend List GUIDs into array"); + } + + do + { + uint32 socialFriendGUID = result->Fetch()->Get(); + SocialFriendsList.push_back(socialFriendGUID); + if (g_BotDistFullDebugMode) + { + LOG_INFO("server.load", "[BotLevelBrackets] Adding GUID {} to Social Friend List", socialFriendGUID); + } + } while (result->NextRow()); + +} + // Returns the index of the level range bracket that the given level belongs to. // If the bot is out of range, it returns -1 static int GetLevelRangeIndex(uint8 level, uint8 teamID) @@ -415,6 +454,27 @@ static bool IsBotSafeForLevelReset(Player* bot) } } } + // Lets ignore bots that have human friends + if (g_IgnoreFriendListed) + { + for(auto i = 0; i < SocialFriendsList.size(); i++) + { + if (g_BotDistFullDebugMode) + { + LOG_INFO("server.loading", "[BotLevelBrackets] Check bot {} against SocialFriendsList Array Character GUID {}", bot->GetName(), SocialFriendsList[i]); + } + + if (SocialFriendsList[i] == bot->GetGUID().GetRawValue()) + { + if (g_BotDistFullDebugMode) + { + LOG_INFO("server.loading", "[BotLevelBrackets] Bot {} (Level {}) is on a Real Player's friends list", bot->GetName(), bot->GetLevel()); + } + return false; + } + } + } + return true; } @@ -535,6 +595,7 @@ public: void OnStartup() override { LoadBotLevelBracketsConfig(); + LoadSocialFriendList(); if (!g_BotLevelBracketsEnabled) { LOG_INFO("server.loading", "[BotLevelBrackets] Module disabled via configuration."); @@ -560,7 +621,7 @@ public: { if (!g_BotLevelBracketsEnabled) return; - + m_timer += diff; m_flaggedTimer += diff; @@ -570,7 +631,7 @@ public: if (g_BotDistFullDebugMode) { LOG_INFO("server.loading", "[BotLevelBrackets] Pending Level Resets Triggering."); - } + } ProcessPendingLevelResets(); m_flaggedTimer = 0; } @@ -580,6 +641,9 @@ public: return; m_timer = 0; + // Refresh Social Friends List Array + LoadSocialFriendList(); + // Dynamic distribution: recalc desired percentages based on non-bot players. if (g_UseDynamicDistribution) {