Loading the botnames from a cache

This commit is contained in:
bash
2024-08-21 18:11:19 +00:00
parent 1aa9145902
commit 63e7b227d8
2 changed files with 52 additions and 19 deletions

View File

@@ -150,7 +150,7 @@ RandomPlayerbotFactory::RandomPlayerbotFactory(uint32 accountId) : accountId(acc
}
}
Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls)
Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls, std::unordered_map<NameRaceAndGender, std::vector<std::string>>& nameCache)
{
LOG_DEBUG("playerbots", "Creating new random bot for class {}", cls);
@@ -168,14 +168,28 @@ Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls
const auto raceAndGender = CombineRaceAndGender(gender, race);
std::string name = CreateRandomBotName(raceAndGender);
std::string name;
if (nameCache.empty())
{
name = CreateRandomBotName(raceAndGender);
}
else
{
if (nameCache[raceAndGender].empty())
{
LOG_ERROR("playerbots", "No name found for race and gender: {}", raceAndGender);
return nullptr;
}
uint32 i = urand(0, nameCache[raceAndGender].size() - 1);
name = nameCache[raceAndGender][i];
swap(nameCache[raceAndGender][i], nameCache[raceAndGender].back());
nameCache[raceAndGender].pop_back();
}
if (name.empty())
{
LOG_ERROR("playerbots", "Unable to get random bot name!");
return nullptr;
}
CharacterDatabase.DirectExecute("UPDATE playerbots_names SET in_use=1 WHERE name='{}'", name);
std::vector<uint8> skinColors, facialHairTypes;
std::vector<std::pair<uint8, uint8>> faces, hairs;
@@ -242,22 +256,26 @@ Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls
std::string const RandomPlayerbotFactory::CreateRandomBotName(NameRaceAndGender raceAndGender)
{
std::string botName = "";
int tries = 10;
int tries = 3;
while (--tries)
{
QueryResult result = CharacterDatabase.Query(
"SELECT name FROM playerbots_names "
"WHERE in_use = 0 AND gender = {} ORDER BY RAND() LIMIT 1",
"SELECT n.name "
"FROM playerbots_names n "
"LEFT OUTER JOIN characters c ON c.name = n.name "
"WHERE c.guid IS NULL and n.gender = '{}' "
"ORDER BY RAND() LIMIT 1",
static_cast<uint8>(raceAndGender));
if (!result)
{
break;
}
Field* fields = result->Fetch();
std::string ret = fields[0].Get<std::string>();
if (ObjectMgr::CheckPlayerName(ret) == CHAR_NAME_SUCCESS) // Checks for reservation & profanity, too
botName = fields[0].Get<std::string>();
if (ObjectMgr::CheckPlayerName(botName) == CHAR_NAME_SUCCESS) // Checks for reservation & profanity, too
{
return ret;
return botName;
}
}
@@ -379,7 +397,6 @@ void RandomPlayerbotFactory::CreateRandomBots()
}
PlayerbotsDatabase.Execute(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_RANDOM_BOTS));
CharacterDatabase.DirectExecute("UPDATE playerbots_names SET in_use = 0 WHERE in_use = 1");
/* TODO(yunfan): we need to sleep here to wait for async account deleted, or the newly account won't be created
correctly the better way is turning the async db operation to sync db operation */
std::this_thread::sleep_for(10ms * sPlayerbotAIConfig->randomBotAccountCount);
@@ -389,12 +406,28 @@ void RandomPlayerbotFactory::CreateRandomBots()
return;
}
uint32 totalAccCount = sPlayerbotAIConfig->randomBotAccountCount;
LOG_INFO("playerbots", "Creating random bot accounts...");
std::unordered_map<NameRaceAndGender, std::vector<std::string>> nameCache;
uint32 totalAccCount = sPlayerbotAIConfig->randomBotAccountCount;
std::vector<std::future<void>> account_creations;
int account_creation = 0;
LOG_INFO("playerbots", "Creating cache for names, gender and race.");
QueryResult result = CharacterDatabase.Query("SELECT name, gender FROM playerbots_names");
if (!result)
{
LOG_ERROR("playerbots", "No more unused names left");
return;
}
do
{
Field* fields = result->Fetch();
std::string name = fields[0].Get<std::string>();
NameRaceAndGender raceAndGender = static_cast<NameRaceAndGender>(fields[1].Get<uint8>());
nameCache[raceAndGender].push_back(name);
} while (result->NextRow());
for (uint32 accountNumber = 0; accountNumber < sPlayerbotAIConfig->randomBotAccountCount; ++accountNumber)
{
std::ostringstream out;
@@ -435,10 +468,10 @@ void RandomPlayerbotFactory::CreateRandomBots()
LOG_INFO("playerbots", "Creating random bot characters...");
uint32 totalRandomBotChars = 0;
uint32 totalCharCount = sPlayerbotAIConfig->randomBotAccountCount * 10;
std::vector<std::pair<Player*, uint32>> playerBots;
std::vector<WorldSession*> sessionBots;
int bot_creation = 0;
for (uint32 accountNumber = 0; accountNumber < sPlayerbotAIConfig->randomBotAccountCount; ++accountNumber)
{
std::ostringstream out;
@@ -483,7 +516,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
if (cls != 10)
{
if (Player* playerBot = factory.CreateRandomBot(session, cls))
if (Player* playerBot = factory.CreateRandomBot(session, cls, nameCache))
{
playerBot->SaveToDB(true, false);
sCharacterCache->AddCharacterCacheEntry(playerBot->GetGUID(), accountId, playerBot->GetName(),

View File

@@ -49,7 +49,7 @@ public:
RandomPlayerbotFactory(uint32 accountId);
virtual ~RandomPlayerbotFactory() {}
Player* CreateRandomBot(WorldSession* session, uint8 cls);
Player* CreateRandomBot(WorldSession* session, uint8 cls, std::unordered_map<NameRaceAndGender, std::vector<std::string>>& names);
static void CreateRandomBots();
static void CreateRandomGuilds();
static void CreateRandomArenaTeams(ArenaType slot, uint32 count);