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);
|
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);
|
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())
|
if (name.empty())
|
||||||
{
|
{
|
||||||
LOG_ERROR("playerbots", "Unable to get random bot name!");
|
LOG_ERROR("playerbots", "Unable to get random bot name!");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
CharacterDatabase.DirectExecute("UPDATE playerbots_names SET in_use=1 WHERE name='{}'", name);
|
|
||||||
|
|
||||||
std::vector<uint8> skinColors, facialHairTypes;
|
std::vector<uint8> skinColors, facialHairTypes;
|
||||||
std::vector<std::pair<uint8, uint8>> faces, hairs;
|
std::vector<std::pair<uint8, uint8>> faces, hairs;
|
||||||
@@ -242,23 +256,27 @@ Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls
|
|||||||
std::string const RandomPlayerbotFactory::CreateRandomBotName(NameRaceAndGender raceAndGender)
|
std::string const RandomPlayerbotFactory::CreateRandomBotName(NameRaceAndGender raceAndGender)
|
||||||
{
|
{
|
||||||
std::string botName = "";
|
std::string botName = "";
|
||||||
int tries = 10;
|
int tries = 3;
|
||||||
while (--tries)
|
while (--tries)
|
||||||
{
|
{
|
||||||
QueryResult result = CharacterDatabase.Query(
|
QueryResult result = CharacterDatabase.Query(
|
||||||
"SELECT name FROM playerbots_names "
|
"SELECT n.name "
|
||||||
"WHERE in_use = 0 AND gender = {} ORDER BY RAND() LIMIT 1",
|
"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));
|
static_cast<uint8>(raceAndGender));
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Field* fields = result->Fetch();
|
Field* fields = result->Fetch();
|
||||||
std::string ret = fields[0].Get<std::string>();
|
botName = fields[0].Get<std::string>();
|
||||||
if (ObjectMgr::CheckPlayerName(ret) == CHAR_NAME_SUCCESS) // Checks for reservation & profanity, too
|
if (ObjectMgr::CheckPlayerName(botName) == CHAR_NAME_SUCCESS) // Checks for reservation & profanity, too
|
||||||
{
|
{
|
||||||
return ret;
|
return botName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CONLANG NAME GENERATION
|
// CONLANG NAME GENERATION
|
||||||
@@ -379,7 +397,6 @@ void RandomPlayerbotFactory::CreateRandomBots()
|
|||||||
}
|
}
|
||||||
|
|
||||||
PlayerbotsDatabase.Execute(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_RANDOM_BOTS));
|
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
|
/* 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 */
|
correctly the better way is turning the async db operation to sync db operation */
|
||||||
std::this_thread::sleep_for(10ms * sPlayerbotAIConfig->randomBotAccountCount);
|
std::this_thread::sleep_for(10ms * sPlayerbotAIConfig->randomBotAccountCount);
|
||||||
@@ -389,12 +406,28 @@ void RandomPlayerbotFactory::CreateRandomBots()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 totalAccCount = sPlayerbotAIConfig->randomBotAccountCount;
|
|
||||||
|
|
||||||
LOG_INFO("playerbots", "Creating random bot accounts...");
|
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;
|
std::vector<std::future<void>> account_creations;
|
||||||
int account_creation = 0;
|
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)
|
for (uint32 accountNumber = 0; accountNumber < sPlayerbotAIConfig->randomBotAccountCount; ++accountNumber)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
@@ -435,10 +468,10 @@ void RandomPlayerbotFactory::CreateRandomBots()
|
|||||||
LOG_INFO("playerbots", "Creating random bot characters...");
|
LOG_INFO("playerbots", "Creating random bot characters...");
|
||||||
uint32 totalRandomBotChars = 0;
|
uint32 totalRandomBotChars = 0;
|
||||||
uint32 totalCharCount = sPlayerbotAIConfig->randomBotAccountCount * 10;
|
uint32 totalCharCount = sPlayerbotAIConfig->randomBotAccountCount * 10;
|
||||||
|
|
||||||
std::vector<std::pair<Player*, uint32>> playerBots;
|
std::vector<std::pair<Player*, uint32>> playerBots;
|
||||||
std::vector<WorldSession*> sessionBots;
|
std::vector<WorldSession*> sessionBots;
|
||||||
int bot_creation = 0;
|
int bot_creation = 0;
|
||||||
|
|
||||||
for (uint32 accountNumber = 0; accountNumber < sPlayerbotAIConfig->randomBotAccountCount; ++accountNumber)
|
for (uint32 accountNumber = 0; accountNumber < sPlayerbotAIConfig->randomBotAccountCount; ++accountNumber)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
@@ -462,7 +495,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LOG_INFO("playerbots", "Creating random bot characters for account: [{}/{}]", accountNumber + 1,
|
LOG_INFO("playerbots", "Creating random bot characters for account: [{}/{}]", accountNumber + 1,
|
||||||
sPlayerbotAIConfig->randomBotAccountCount);
|
sPlayerbotAIConfig->randomBotAccountCount);
|
||||||
RandomPlayerbotFactory factory(accountId);
|
RandomPlayerbotFactory factory(accountId);
|
||||||
|
|
||||||
WorldSession* session = new WorldSession(accountId, "", nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING,
|
WorldSession* session = new WorldSession(accountId, "", nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING,
|
||||||
@@ -483,7 +516,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
|
|||||||
|
|
||||||
if (cls != 10)
|
if (cls != 10)
|
||||||
{
|
{
|
||||||
if (Player* playerBot = factory.CreateRandomBot(session, cls))
|
if (Player* playerBot = factory.CreateRandomBot(session, cls, nameCache))
|
||||||
{
|
{
|
||||||
playerBot->SaveToDB(true, false);
|
playerBot->SaveToDB(true, false);
|
||||||
sCharacterCache->AddCharacterCacheEntry(playerBot->GetGUID(), accountId, playerBot->GetName(),
|
sCharacterCache->AddCharacterCacheEntry(playerBot->GetGUID(), accountId, playerBot->GetName(),
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public:
|
|||||||
RandomPlayerbotFactory(uint32 accountId);
|
RandomPlayerbotFactory(uint32 accountId);
|
||||||
virtual ~RandomPlayerbotFactory() {}
|
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 CreateRandomBots();
|
||||||
static void CreateRandomGuilds();
|
static void CreateRandomGuilds();
|
||||||
static void CreateRandomArenaTeams(ArenaType slot, uint32 count);
|
static void CreateRandomArenaTeams(ArenaType slot, uint32 count);
|
||||||
|
|||||||
Reference in New Issue
Block a user