EnablePeriodicOnlineOffline config and modify CalculateTotalAccountCount (#1043)

* EnablePeriodicOnlineOffline config

* Add Comments on PeriodicOnlineOfflineRatio
This commit is contained in:
Yunfan Li
2025-03-01 21:05:43 +08:00
committed by GitHub
parent 9ff0e8e94d
commit fbfcbbcddc
6 changed files with 68 additions and 30 deletions

View File

@@ -509,13 +509,6 @@ AiPlayerbot.RandomBotRandomPassword = 0
# Accounts to create for random bots
AiPlayerbot.RandomBotAccountPrefix = "rndbot"
# Enable/Disable rotation of bots (randomly select a bot from the bots pool to go online and rotate them periodically)
# default: 0 (disable, the online bots are fixed)
AiPlayerbot.EnableRotation = 0
# Bots pool size for rotation (should be higher than MaxRandomBots)
AiPlayerbot.RotationPoolSize = 100
AiPlayerbot.RandomBotMinLevel = 1
AiPlayerbot.RandomBotMaxLevel = 80
@@ -529,6 +522,16 @@ AiPlayerbot.PreQuests = 0
# Enable LFG for random bots
AiPlayerbot.RandomBotJoinLfg = 1
# Enable/Disable periodic online - offline to mimic the real-world scenario where not all players are online simultaneously
# When enabled, bots are randomly selected to go online or offline periodically from a larger set
# Default: 0 (disabled, the set of online bots remains fixed)
AiPlayerbot.EnablePeriodicOnlineOffline = 0
# Defines the ratio between the total number of bots (including offline ones) and the number of bots currently online (MaxRandomBots)
# This setting must greater than 1.0 and only applies when EnablePeriodicOnlineOffline
# Default: 2.0 (total number of bots is twice the number of MaxRandomBots)
AiPlayerbot.PeriodicOnlineOfflineRatio = 2.0
# Percentage ratio of alliance and horde
AiPlayerbot.RandomBotAllianceRatio = 50
AiPlayerbot.RandomBotHordeRatio = 50
@@ -877,7 +880,7 @@ AiPlayerbot.MinRandomBotReviveTime = 60
AiPlayerbot.MaxRandomBotReviveTime = 300
AiPlayerbot.MinRandomBotTeleportInterval = 3600
AiPlayerbot.MaxRandomBotTeleportInterval = 18000
AiPlayerbot.RandomBotInWorldWithRotationDisabled = 31104000
AiPlayerbot.PermanantlyInWorldTime = 31104000
#
#

View File

@@ -173,8 +173,8 @@ bool PlayerbotAIConfig::Initialize()
maxRandomBotReviveTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotReviveTime", 5 * MINUTE);
minRandomBotTeleportInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotTeleportInterval", 1 * HOUR);
maxRandomBotTeleportInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotTeleportInterval", 5 * HOUR);
randomBotInWorldWithRotationDisabled =
sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotInWorldWithRotationDisabled", 1 * YEAR);
permanantlyInWorldTime =
sConfigMgr->GetOption<int32>("AiPlayerbot.PermanantlyInWorldTime", 1 * YEAR);
randomBotTeleportDistance = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotTeleportDistance", 100);
randomBotsPerInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotsPerInterval", 60);
minRandomBotsPriceChangeInterval =
@@ -504,8 +504,8 @@ bool PlayerbotAIConfig::Initialize()
limitEnchantExpansion = sConfigMgr->GetOption<int32>("AiPlayerbot.LimitEnchantExpansion", 1);
limitGearExpansion = sConfigMgr->GetOption<int32>("AiPlayerbot.LimitGearExpansion", 1);
randombotStartingLevel = sConfigMgr->GetOption<int32>("AiPlayerbot.RandombotStartingLevel", 5);
enableRotation = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableRotation", false);
rotationPoolSize = sConfigMgr->GetOption<int32>("AiPlayerbot.RotationPoolSize", 100);
enablePeriodicOnlineOffline = sConfigMgr->GetOption<bool>("AiPlayerbot.EnablePeriodicOnlineOffline", false);
periodicOnlineOfflineRatio = sConfigMgr->GetOption<float>("AiPlayerbot.PeriodicOnlineOfflineRatio", 2.0);
gearscorecheck = sConfigMgr->GetOption<bool>("AiPlayerbot.GearScoreCheck", false);
randomBotPreQuests = sConfigMgr->GetOption<bool>("AiPlayerbot.PreQuests", true);

View File

@@ -95,7 +95,7 @@ public:
uint32 minRandomBotChangeStrategyTime, maxRandomBotChangeStrategyTime;
uint32 minRandomBotReviveTime, maxRandomBotReviveTime;
uint32 minRandomBotTeleportInterval, maxRandomBotTeleportInterval;
uint32 randomBotInWorldWithRotationDisabled;
uint32 permanantlyInWorldTime;
uint32 minRandomBotPvpTime, maxRandomBotPvpTime;
uint32 randomBotsPerInterval;
uint32 minRandomBotsPriceChangeInterval, maxRandomBotsPriceChangeInterval;
@@ -235,8 +235,8 @@ public:
uint32 limitEnchantExpansion;
uint32 limitGearExpansion;
uint32 randombotStartingLevel;
bool enableRotation;
uint32 rotationPoolSize;
bool enablePeriodicOnlineOffline;
float periodicOnlineOfflineRatio;
bool gearscorecheck;
bool randomBotPreQuests;

View File

@@ -411,19 +411,45 @@ uint32 RandomPlayerbotFactory::CalculateTotalAccountCount()
bool isWOTLK = sWorld->getIntConfig(CONFIG_EXPANSION) == EXPANSION_WRATH_OF_THE_LICH_KING;
// Determine divisor based on WOTLK condition
int divisor = isWOTLK ? 10 : 9;
int divisor = CalculateAvailableCharsPerAccount();
// Calculate max bots or rotation pool size
int maxBotsOrRotation = std::max(
sPlayerbotAIConfig->maxRandomBots,
sPlayerbotAIConfig->enableRotation ? sPlayerbotAIConfig->rotationPoolSize : 0
);
// Calculate max bots
int maxBots = sPlayerbotAIConfig->maxRandomBots;
// Take perodic online - offline into account
if (sPlayerbotAIConfig->enablePeriodicOnlineOffline)
{
maxBots *= sPlayerbotAIConfig->periodicOnlineOfflineRatio;
}
// Calculate base accounts, add class account pool size, and add 1 as a fixed offset
uint32 baseAccounts = maxBotsOrRotation / divisor;
uint32 baseAccounts = maxBots / divisor;
return baseAccounts + sPlayerbotAIConfig->addClassAccountPoolSize + 1;
}
uint32 RandomPlayerbotFactory::CalculateAvailableCharsPerAccount()
{
bool noDK = sPlayerbotAIConfig->disableDeathKnightLogin || sWorld->getIntConfig(CONFIG_EXPANSION) != EXPANSION_WRATH_OF_THE_LICH_KING;
uint32 availableChars = noDK ? 9 : 10;
uint32 hordeRatio = sPlayerbotAIConfig->randomBotHordeRatio;
uint32 allianceRatio = sPlayerbotAIConfig->randomBotAllianceRatio;
// horde : alliance = 50 : 50 -> 0%
// horde : alliance = 0 : 50 -> 50%
// horde : alliance = 10 : 50 -> 40%
float unavailableRatio = static_cast<float>((std::max(hordeRatio, allianceRatio) - std::min(hordeRatio, allianceRatio))) /
(std::max(hordeRatio, allianceRatio) * 2);
if (unavailableRatio != 0)
{
// conservative floor to ensure enough chars (may result in more accounts than needed)
availableChars = availableChars - availableChars * unavailableRatio;
}
return availableChars;
}
void RandomPlayerbotFactory::CreateRandomBots()
{
/* multi-thread here is meaningless? since the async db operations */

View File

@@ -54,13 +54,14 @@ public:
static void CreateRandomGuilds();
static void CreateRandomArenaTeams(ArenaType slot, uint32 count);
static std::string const CreateRandomGuildName();
static uint32 CalculateTotalAccountCount();
static uint32 CalculateAvailableCharsPerAccount();
private:
std::string const CreateRandomBotName(NameRaceAndGender raceAndGender);
static std::string const CreateRandomArenaTeamName();
uint32 accountId;
static uint32 CalculateTotalAccountCount();
static std::map<uint8, std::vector<uint8>> availableRaces;
};

View File

@@ -47,6 +47,7 @@
#include "Unit.h"
#include "UpdateTime.h"
#include "World.h"
#include "RandomPlayerbotFactory.h"
void PrintStatsThread() { sRandomPlayerbotMgr->PrintStats(); }
@@ -464,18 +465,25 @@ uint32 RandomPlayerbotMgr::AddRandomBots()
maxAllowedBotCount -= currentBots.size();
maxAllowedBotCount = std::min(sPlayerbotAIConfig->randomBotsPerInterval, maxAllowedBotCount);
uint32 allowedAllianceCount = maxAllowedBotCount * (sPlayerbotAIConfig->randomBotAllianceRatio) / (sPlayerbotAIConfig->randomBotAllianceRatio + sPlayerbotAIConfig->randomBotHordeRatio);
uint32 allowedAllianceCount = maxAllowedBotCount * (sPlayerbotAIConfig->randomBotAllianceRatio) /
(sPlayerbotAIConfig->randomBotAllianceRatio + sPlayerbotAIConfig->randomBotHordeRatio);
uint32 allowedHordeCount = maxAllowedBotCount - allowedAllianceCount;
for (std::vector<uint32>::iterator i = sPlayerbotAIConfig->randomBotAccounts.begin();
i != sPlayerbotAIConfig->randomBotAccounts.end(); i++)
{
uint32 accountId = *i;
if (sPlayerbotAIConfig->enableRotation)
if (sPlayerbotAIConfig->enablePeriodicOnlineOffline)
{
uint32 limit = std::min((uint32)sPlayerbotAIConfig->randomBotAccounts.size(),
sPlayerbotAIConfig->rotationPoolSize / 10 + 1);
uint32 index = urand(0, limit);
// minus addclass bots account
int32 baseAccount = RandomPlayerbotFactory::CalculateTotalAccountCount() - sPlayerbotAIConfig->addClassAccountPoolSize;
if (baseAccount <= 0 || baseAccount > sPlayerbotAIConfig->randomBotAccounts.size())
{
LOG_ERROR("playerbots", "Account calculation error with PeriodicOnlineOffline");
return 0;
}
uint32 index = urand(0, baseAccount - 1);
accountId = sPlayerbotAIConfig->randomBotAccounts[index];
}
CharacterDatabasePreparedStatement* stmt =
@@ -535,10 +543,10 @@ uint32 RandomPlayerbotMgr::AddRandomBots()
for (uint32& guid : guids)
{
uint32 add_time = sPlayerbotAIConfig->enableRotation
uint32 add_time = sPlayerbotAIConfig->enablePeriodicOnlineOffline
? urand(sPlayerbotAIConfig->minRandomBotInWorldTime,
sPlayerbotAIConfig->maxRandomBotInWorldTime)
: sPlayerbotAIConfig->randomBotInWorldWithRotationDisabled;
: sPlayerbotAIConfig->permanantlyInWorldTime;
SetEventValue(guid, "add", 1, add_time);
SetEventValue(guid, "logout", 0, 0);