Skip to content

Commit

Permalink
Alt login: Improved the bot selection logic to properly handle criter…
Browse files Browse the repository at this point in the history
…ia dropping after attempts and skipping previous checked criteria which will still be the same.
  • Loading branch information
mostlikely4r committed Dec 7, 2024
1 parent 661ea92 commit acce405
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 34 deletions.
2 changes: 1 addition & 1 deletion playerbot/PlayerbotAIConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::vector<std::string> >(config.GetStringDefault("AiPlayerbot.LoginCriteria", "classrace"), loginCriteria);

Expand Down
47 changes: 29 additions & 18 deletions playerbot/PlayerbotLoginMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand All @@ -506,6 +504,7 @@ LoginCriteria PlayerBotLoginMgr::GetLoginCriteria(const uint8 attempt) const

std::vector<std::string> 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")
Expand Down Expand Up @@ -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<uint8, std::unordered_map<LoginCriterionFailType, uint32>> loginFails;
std::unordered_map<uint32, LoginCriterionFailType> loginFails;

std::vector<PlayerBotInfo*> 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)
{
Expand All @@ -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;
}
Expand All @@ -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()));
}

Expand Down
19 changes: 10 additions & 9 deletions playerbot/PlayerbotLoginMgr.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "WorldPosition.h"

class PlayerBotInfo;

struct LoginSpace
{
int32 currentSpace;
Expand Down Expand Up @@ -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<LoginCriterionFailType, std::string> failName = {
{LoginCriterionFailType::LOGIN_OK, "LOGIN_OK"}
,{LoginCriterionFailType::LOGOUT_NOK, "LOGOUT_NOK" }
static const std::unordered_map<LoginCriterionFailType, std::string> 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 <std::pair<LoginCriterionFailType, std::function<bool(const PlayerBotInfo&, const LoginSpace&)>>> LoginCriteria;

Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions playerbot/aiplayerbot.conf.dist.in
Original file line number Diff line number Diff line change
Expand Up @@ -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.<level> = <number> #Probability Randombots will be allowed to login with this level. (default 100)
# AiPlayerbot.LevelProbability.1 = 100
Expand Down
4 changes: 2 additions & 2 deletions playerbot/aiplayerbot.conf.dist.in.tbc
Original file line number Diff line number Diff line change
Expand Up @@ -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.<level> = <number> #Probability Randombots will be allowed to login with this level. (default 100)
# AiPlayerbot.LevelProbability.1 = 100
Expand Down
4 changes: 2 additions & 2 deletions playerbot/aiplayerbot.conf.dist.in.wotlk
Original file line number Diff line number Diff line change
Expand Up @@ -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.<level> = <number> #Probability Randombots will be allowed to login with this level. (default 100)
# AiPlayerbot.LevelProbability.1 = 100
Expand Down

0 comments on commit acce405

Please sign in to comment.