From acce405ed7b2705c66198ffbf63e89d373b29f8d Mon Sep 17 00:00:00 2001 From: mostlikely4r Date: Sat, 7 Dec 2024 19:47:10 +0100 Subject: [PATCH] Alt login: Improved the bot selection logic to properly handle criteria dropping after attempts and skipping previous checked criteria which will still be the same. --- playerbot/PlayerbotAIConfig.cpp | 2 +- playerbot/PlayerbotLoginMgr.cpp | 47 +++++++++++++++--------- playerbot/PlayerbotLoginMgr.h | 19 +++++----- playerbot/aiplayerbot.conf.dist.in | 4 +- playerbot/aiplayerbot.conf.dist.in.tbc | 4 +- playerbot/aiplayerbot.conf.dist.in.wotlk | 4 +- 6 files changed, 46 insertions(+), 34 deletions(-) diff --git a/playerbot/PlayerbotAIConfig.cpp b/playerbot/PlayerbotAIConfig.cpp index cd95f02a..2e9a8814 100644 --- a/playerbot/PlayerbotAIConfig.cpp +++ b/playerbot/PlayerbotAIConfig.cpp @@ -266,7 +266,7 @@ bool PlayerbotAIConfig::Initialize() asyncBotLogin = config.GetBoolDefault("AiPlayerbot.AsyncBotLogin", false); freeRoomForNonSpareBots = config.GetIntDefault("AiPlayerbot.FreeRoomForNonSpareBots", 1); - loginBotsNearPlayerRange = config.GetIntDefault("AiPlayerbot.LoginBotsNearPlayerRange", 0); + loginBotsNearPlayerRange = config.GetIntDefault("AiPlayerbot.LoginBotsNearPlayerRange", 1000); LoadListString >(config.GetStringDefault("AiPlayerbot.LoginCriteria", "classrace"), loginCriteria); diff --git a/playerbot/PlayerbotLoginMgr.cpp b/playerbot/PlayerbotLoginMgr.cpp index 690955da..5e987682 100644 --- a/playerbot/PlayerbotLoginMgr.cpp +++ b/playerbot/PlayerbotLoginMgr.cpp @@ -493,10 +493,8 @@ LoginCriteria PlayerBotLoginMgr::GetLoginCriteria(const uint8 attempt) const ADD_CRITERIA(MAX_BOTS, space.totalSpace <= int(0)); - if(attempt == 0) - ADD_CRITERIA(LOGOUT_NOK, info.GetLoginState() == LoginState::BOT_ONLINE && space.currentSpace > (int32)sPlayerbotAIConfig.freeRoomForNonSpareBots); - else - ADD_CRITERIA(SPARE_ROOM, info.GetLoginState() == LoginState::BOT_OFFLINE && space.totalSpace <= (int32)sPlayerbotAIConfig.freeRoomForNonSpareBots); + if (attempt > 0) + ADD_CRITERIA(SPARE_ROOM, info.GetLoginState() == LoginState::BOT_OFFLINE && space.totalSpace <= (int32)sPlayerbotAIConfig.freeRoomForNonSpareBots); if (sPlayerbotAIConfig.randomBotTimedLogout) ADD_CRITERIA(RANDOM_TIMED_LOGOUT, info.GetLoginState() == LoginState::BOT_ONLINE && !sRandomPlayerbotMgr.GetValue(info.GetId(), "add")); @@ -506,6 +504,7 @@ LoginCriteria PlayerBotLoginMgr::GetLoginCriteria(const uint8 attempt) const std::vector configCriteria = sPlayerbotAIConfig.loginCriteria; + if(configCriteria.size() >= attempt) for (uint8 i = 0; i < std::min(uint8(configCriteria.size() - attempt), uint8(configCriteria.size())); i++) { if (configCriteria[i] == "classrace") @@ -546,26 +545,48 @@ void PlayerBotLoginMgr::FillLoginSpace(LoginSpace& space, FillStep step) } } +bool PlayerBotLoginMgr::CriteriaStillValid(const LoginCriterionFailType oldFailType, const LoginCriteria& criteria) const +{ + switch (oldFailType) //These depends on previous bots accepted/rejected so need to be recalculated. + { + case LoginCriterionFailType::UNKNOWN: + case LoginCriterionFailType::MAX_BOTS: + case LoginCriterionFailType::SPARE_ROOM: + case LoginCriterionFailType::CLASSRACE: + case LoginCriterionFailType::LEVEL: + return false; + }; + + for (auto& [criterionfail, criterion] : criteria) + if (criterionfail == oldFailType) + return true; + + return false; +} + void PlayerBotLoginMgr::FillLoginLogoutQueue() { LoginSpace loginSpace; FillLoginSpace(loginSpace, FillStep::NEXT_STEP); - std::unordered_map> loginFails; + std::unordered_map loginFails; std::vector logins, logouts; - for (uint8 attempt = 0; attempt < sPlayerbotAIConfig.loginCriteria.size(); attempt++) + for (uint8 attempt = 0; attempt <= sPlayerbotAIConfig.loginCriteria.size(); attempt++) { LoginCriteria criteria = GetLoginCriteria(attempt); for (auto& [guid, botInfo] : botPool) { + if (CriteriaStillValid(loginFails[guid], criteria)) + continue; + botInfo.EmptyLoginSpace(loginSpace, FillStep::NEXT_STEP); //Pretend the bot isn't logged in for a moment. - LoginCriterionFailType LoginFail = botInfo.MatchNoCriteria(loginSpace, criteria); + loginFails[guid] = botInfo.MatchNoCriteria(loginSpace, criteria); botInfo.FillLoginSpace(loginSpace, FillStep::NEXT_STEP); - bool wantedOnline = (LoginFail == LoginCriterionFailType::LOGIN_OK || LoginFail == LoginCriterionFailType::LOGOUT_NOK); + bool wantedOnline = (loginFails[guid] == LoginCriterionFailType::LOGIN_OK); if (wantedOnline) { @@ -580,8 +601,6 @@ void PlayerBotLoginMgr::FillLoginLogoutQueue() logouts.push_back(&botInfo); } - loginFails[attempt][LoginFail]++; - if (attempt > 0 && loginSpace.totalSpace < (int32)sPlayerbotAIConfig.freeRoomForNonSpareBots) loginSpace.totalSpace = 0; } @@ -598,14 +617,6 @@ void PlayerBotLoginMgr::FillLoginLogoutQueue() for (auto& login : logins) loginQueue.push(login); - for (auto& [attempt, fails] : loginFails) - { - for (auto& [fail, nr] : fails) - { - sLog.outDebug("PlayerbotLoginMgr attempt: %d fail %s: %d", attempt, failName.find(fail)->second.c_str(), nr); - } - } - sLog.outDebug("PlayerbotLoginMgr: Queued to log in: %d, out: %d", uint32(loginQueue.size()), uint32(logoutQueue.size())); } diff --git a/playerbot/PlayerbotLoginMgr.h b/playerbot/PlayerbotLoginMgr.h index 23939d8a..2ec060e5 100644 --- a/playerbot/PlayerbotLoginMgr.h +++ b/playerbot/PlayerbotLoginMgr.h @@ -1,5 +1,7 @@ #include "WorldPosition.h" +class PlayerBotInfo; + struct LoginSpace { int32 currentSpace; @@ -33,29 +35,27 @@ enum class FillStep : uint8 enum class LoginCriterionFailType : uint8 { - LOGIN_OK = 0, - LOGOUT_NOK = 1, + UNKNOWN = 0, MAX_BOTS = 2, SPARE_ROOM = 3, RANDOM_TIMED_LOGOUT = 4, RANDOM_TIMED_OFFLINE = 5, CLASSRACE = 6, LEVEL = 7, - RANGE = 8 + RANGE = 8, + LOGIN_OK = 10 }; -static const std::unordered_map failName = { - {LoginCriterionFailType::LOGIN_OK, "LOGIN_OK"} - ,{LoginCriterionFailType::LOGOUT_NOK, "LOGOUT_NOK" } +static const std::unordered_map failName = { + {LoginCriterionFailType::UNKNOWN, "UNKNOWN"} ,{LoginCriterionFailType::MAX_BOTS, "MAX_BOTS"} ,{LoginCriterionFailType::SPARE_ROOM, "SPARE_ROOM"} ,{LoginCriterionFailType::RANDOM_TIMED_LOGOUT, "RANDOM_TIMED_LOGOUT"} ,{LoginCriterionFailType::RANDOM_TIMED_OFFLINE , "RANDOM_TIMED_OFFLINE"} ,{LoginCriterionFailType::CLASSRACE, "CLASSRACE"} ,{LoginCriterionFailType::LEVEL, "LEVEL"} - ,{LoginCriterionFailType::RANGE , "RANGE"} }; - -class PlayerBotInfo; + ,{LoginCriterionFailType::RANGE , "RANGE"} + ,{LoginCriterionFailType::LOGIN_OK, "LOGIN_OK"} }; typedef std::vector >> LoginCriteria; @@ -126,6 +126,7 @@ class PlayerBotLoginMgr LoginCriteria GetLoginCriteria(const uint8 attempt) const; void FillLoginSpace(LoginSpace& space, FillStep step); + bool CriteriaStillValid(const LoginCriterionFailType oldFailType, const LoginCriteria& criteria) const; uint32 GetMaxOnlineBotCount() const; uint32 GetMaxLevel() const; uint32 GetClassRaceBucketSize(uint8 cls, uint8 race) const; diff --git a/playerbot/aiplayerbot.conf.dist.in b/playerbot/aiplayerbot.conf.dist.in index 35bd72e0..8ee3f81f 100644 --- a/playerbot/aiplayerbot.conf.dist.in +++ b/playerbot/aiplayerbot.conf.dist.in @@ -991,8 +991,8 @@ AiPlayerbot.PerfMonEnabled = 0 # When bots are logged in that do not fully match all criteria selected it will do so up to xxx spaces below the maximum. Bots that suddenly match all the criteria will then have room to use this to log in. # AiPlayerbot.FreeRoomForNonSpareBots = 0 -# Only log in bots within this distance from a real player. 0 = Ignore range. -# AiPlayerbot.LoginBotsNearPlayerRange = 0 +# Only log in bots within this distance from a real player. +# AiPlayerbot.LoginBotsNearPlayerRange = 1000 # AiPlayerbot.LevelProbability. = #Probability Randombots will be allowed to login with this level. (default 100) # AiPlayerbot.LevelProbability.1 = 100 diff --git a/playerbot/aiplayerbot.conf.dist.in.tbc b/playerbot/aiplayerbot.conf.dist.in.tbc index a3669c97..6fd2aa58 100644 --- a/playerbot/aiplayerbot.conf.dist.in.tbc +++ b/playerbot/aiplayerbot.conf.dist.in.tbc @@ -1010,8 +1010,8 @@ AiPlayerbot.PerfMonEnabled = 0 # When bots are logged in that do not fully match all criteria selected it will do so up to xxx spaces below the maximum. Bots that suddenly match all the criteria will then have room to use this to log in. # AiPlayerbot.FreeRoomForNonSpareBots = 0 -# Only log in bots within this distance from a real player. 0 = Ignore range. -# AiPlayerbot.LoginBotsNearPlayerRange = 0 +# Only log in bots within this distance from a real player. +# AiPlayerbot.LoginBotsNearPlayerRange = 1000 # AiPlayerbot.LevelProbability. = #Probability Randombots will be allowed to login with this level. (default 100) # AiPlayerbot.LevelProbability.1 = 100 diff --git a/playerbot/aiplayerbot.conf.dist.in.wotlk b/playerbot/aiplayerbot.conf.dist.in.wotlk index a2b2d0f7..1624f134 100644 --- a/playerbot/aiplayerbot.conf.dist.in.wotlk +++ b/playerbot/aiplayerbot.conf.dist.in.wotlk @@ -950,8 +950,8 @@ AiPlayerbot.PerfMonEnabled = 0 # When bots are logged in that do not fully match all criteria selected it will do so up to xxx spaces below the maximum. Bots that suddenly match all the criteria will then have room to use this to log in. # AiPlayerbot.FreeRoomForNonSpareBots = 0 -# Only log in bots within this distance from a real player. 0 = Ignore range. -# AiPlayerbot.LoginBotsNearPlayerRange = 0 +# Only log in bots within this distance from a real player. +# AiPlayerbot.LoginBotsNearPlayerRange = 1000 # AiPlayerbot.LevelProbability. = #Probability Randombots will be allowed to login with this level. (default 100) # AiPlayerbot.LevelProbability.1 = 100