Fix ACCESS_VIOLATION in mod-playerbots: purge stale AIs, add thread-safety, and harden HasRealPlayerMaster (#1507)

This commit is contained in:
Alex Dcnh
2025-08-07 00:31:00 +02:00
committed by GitHub
parent 0afcf29490
commit f5ef5bd1c2
4 changed files with 76 additions and 13 deletions

View File

@@ -38,6 +38,8 @@
#include "WorldSessionMgr.h"
#include "DatabaseEnv.h" // Added for gender choice
#include <algorithm> // Added for gender choice
#include "Log.h" // removes a long-standing crash (0xC0000005 ACCESS_VIOLATION)
#include <shared_mutex> // removes a long-standing crash (0xC0000005 ACCESS_VIOLATION)
class BotInitGuard
{
@@ -1726,23 +1728,55 @@ void PlayerbotsMgr::RemovePlayerBotData(ObjectGuid const& guid, bool is_AI)
PlayerbotAI* PlayerbotsMgr::GetPlayerbotAI(Player* player)
{
if (!(sPlayerbotAIConfig->enabled) || !player)
{
return nullptr;
}
// if (player->GetSession()->isLogingOut() || player->IsDuringRemoveFromWorld()) {
// if (!(sPlayerbotAIConfig->enabled) || !player)
// {
// return nullptr;
// }
auto itr = _playerbotsAIMap.find(player->GetGUID());
if (itr != _playerbotsAIMap.end())
{
if (itr->second->IsBotAI())
// // if (player->GetSession()->isLogingOut() || player->IsDuringRemoveFromWorld()) {
// // return nullptr;
// // }
// auto itr = _playerbotsAIMap.find(player->GetGUID());
// if (itr != _playerbotsAIMap.end())
// {
// if (itr->second->IsBotAI())
// return reinterpret_cast<PlayerbotAI*>(itr->second);
// }
//
// return nullptr;
// removes a long-standing crash (0xC0000005 ACCESS_VIOLATION)
if (!sPlayerbotAIConfig->enabled || !player)
return nullptr;
{ // protected read
std::shared_lock lock(_aiMutex);
auto itr = _playerbotsAIMap.find(player->GetGUID());
if (itr != _playerbotsAIMap.end() && itr->second->IsBotAI())
return reinterpret_cast<PlayerbotAI*>(itr->second);
}
// does the player still exist?
if (!ObjectAccessor::FindPlayer(player->GetGUID()))
RemovePlayerbotAI(player->GetGUID()); // orphaned AI -> cleanup
return nullptr;
}
// removes a long-standing crash (0xC0000005 ACCESS_VIOLATION)
void PlayerbotsMgr::RemovePlayerbotAI(ObjectGuid const& guid)
{
std::unique_lock lock(_aiMutex);
if (auto itr = _playerbotsAIMap.find(guid); itr != _playerbotsAIMap.end())
{
delete itr->second;
_playerbotsAIMap.erase(itr);
LOG_DEBUG("playerbots", "Removed stale AI entry for GUID {}", static_cast<uint64>(guid.GetRawValue()));
}
_playerbotsMgrMap.erase(guid);
}
PlayerbotMgr* PlayerbotsMgr::GetPlayerbotMgr(Player* player)
{
if (!(sPlayerbotAIConfig->enabled) || !player)