mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Loading the botnames from a cache
This commit is contained in:
@@ -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(),
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user