Skip to content

Commit

Permalink
BattleGround: Wave 1 of safeguards against race conditions
Browse files Browse the repository at this point in the history
BattleGround handler and BattleGround class still need to be massively reworked but this makes it a little bette
  • Loading branch information
killerwife committed Nov 14, 2024
1 parent b29fd6e commit e402036
Show file tree
Hide file tree
Showing 15 changed files with 151 additions and 41 deletions.
4 changes: 2 additions & 2 deletions src/game/BattleGround/BattleGround.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1477,7 +1477,7 @@ Team BattleGround::GetPrematureWinner()
*/
void BattleGround::OnObjectDBLoad(Creature* creature)
{
const BattleGroundEventIdx eventId = sBattleGroundMgr.GetCreatureEventIndex(creature->GetDbGuid());
const BattleGroundEventIdx eventId = GetBgMap()->GetMapDataContainer().GetCreatureEventIndex(creature->GetDbGuid());
if (eventId.event1 == BG_EVENT_NONE)
return;

Expand Down Expand Up @@ -1525,7 +1525,7 @@ uint32 BattleGround::GetSingleGameObjectGuid(uint8 event1, uint8 event2)
*/
void BattleGround::OnObjectDBLoad(GameObject* obj)
{
const BattleGroundEventIdx eventId = sBattleGroundMgr.GetGameObjectEventIndex(obj->GetDbGuid());
const BattleGroundEventIdx eventId = GetBgMap()->GetMapDataContainer().GetGameObjectEventIndex(obj->GetDbGuid());
if (eventId.event1 == BG_EVENT_NONE)
return;

Expand Down
2 changes: 1 addition & 1 deletion src/game/BattleGround/BattleGround.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ class BattleGround
// returns the other team index
static PvpTeamIndex GetOtherTeamIndex(PvpTeamIndex teamIdx) { return teamIdx == TEAM_INDEX_ALLIANCE ? TEAM_INDEX_HORDE : TEAM_INDEX_ALLIANCE; }

// checke if player is inside battleground
// check if player is inside battleground
bool IsPlayerInBattleGround(ObjectGuid /*playerGuid*/);

// Handle script condition fulfillment
Expand Down
2 changes: 1 addition & 1 deletion src/game/BattleGround/BattleGroundAB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ void BattleGroundAB::HandlePlayerClickedOnFlag(Player* player, GameObject* go)
uint32 factionStrig = 0;

// process battleground event
uint8 event = (sBattleGroundMgr.GetGameObjectEventIndex(go->GetDbGuid())).event1;
uint8 event = (GetBgMap()->GetMapDataContainer().GetGameObjectEventIndex(go->GetDbGuid())).event1;
if (event >= BG_AB_MAX_NODES) // not a node
return;

Expand Down
4 changes: 2 additions & 2 deletions src/game/BattleGround/BattleGroundAV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -616,12 +616,12 @@ void BattleGroundAV::HandlePlayerClickedOnFlag(Player* player, GameObject* go)

DEBUG_LOG("BattleGroundAV: Player from team %u clicked on gameobject entry %u", player->GetTeam(), go->GetEntry());

uint8 event = (sBattleGroundMgr.GetGameObjectEventIndex(go->GetDbGuid())).event1;
uint8 event = (GetBgMap()->GetMapDataContainer().GetGameObjectEventIndex(go->GetDbGuid())).event1;
if (event >= BG_AV_MAX_NODES) // not a node
return;
AVNodeIds node = AVNodeIds(event);

switch ((sBattleGroundMgr.GetGameObjectEventIndex(go->GetDbGuid())).event2 % BG_AV_MAX_STATES)
switch ((GetBgMap()->GetMapDataContainer().GetGameObjectEventIndex(go->GetDbGuid())).event2 % BG_AV_MAX_STATES)
{
case POINT_CONTROLLED:
ProcessPlayerAssaultsPoint(player, node);
Expand Down
2 changes: 1 addition & 1 deletion src/game/BattleGround/BattleGroundHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recv_data)
if (uint32 pauseTimer = pCreature->GetInteractionPauseTimer())
pCreature->GetMotionMaster()->PauseWaypoints(pauseTimer);

BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(pCreature->GetEntry());
BattleGroundTypeId bgTypeId = GetPlayer()->GetMap()->GetMapDataContainer().GetBattleMasterBG(pCreature->GetEntry());

if (bgTypeId == BATTLEGROUND_TYPE_NONE)
return;
Expand Down
50 changes: 39 additions & 11 deletions src/game/BattleGround/BattleGroundMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ void BattleGroundMgr::DeleteAllBattleGrounds()
*/
void BattleGroundMgr::Update(uint32 /*diff*/)
{

m_messager.Execute(this);
}

/**
Expand Down Expand Up @@ -623,9 +623,9 @@ uint32 BattleGroundMgr::GetPrematureFinishTime() const
/**
Method that loads battlemaster entries from DB
*/
void BattleGroundMgr::LoadBattleMastersEntry()
void BattleGroundMgr::LoadBattleMastersEntry(bool reload)
{
m_battleMastersMap.clear(); // need for reload case
std::shared_ptr<BattleMastersMap> newBattleMastersMap = std::make_shared<BattleMastersMap>();

auto queryResult = WorldDatabase.Query("SELECT entry,bg_template FROM battlemaster_entry");

Expand Down Expand Up @@ -657,10 +657,23 @@ void BattleGroundMgr::LoadBattleMastersEntry()
continue;
}

m_battleMastersMap[entry] = BattleGroundTypeId(bgTypeId);
(*newBattleMastersMap)[entry] = BattleGroundTypeId(bgTypeId);
}
while (queryResult->NextRow());

m_battleMastersMap = newBattleMastersMap;

if (reload)
{
sMapMgr.DoForAllMaps([battleMasters = newBattleMastersMap](Map* map)
{
map->GetMessager().AddMessage([battleMasters](Map* map)
{
map->GetMapDataContainer().SetBattleMastersMap(battleMasters);
});
});
}

sLog.outString(">> Loaded %u battlemaster entries", count);
sLog.outString();
}
Expand Down Expand Up @@ -710,15 +723,15 @@ bool BattleGroundMgr::IsBgWeekend(BattleGroundTypeId bgTypeId)
/**
Method that loads battleground events used in battleground scripts
*/
void BattleGroundMgr::LoadBattleEventIndexes()
void BattleGroundMgr::LoadBattleEventIndexes(bool reload)
{
BattleGroundEventIdx events;
events.event1 = BG_EVENT_NONE;
events.event2 = BG_EVENT_NONE;
m_gameObjectBattleEventIndexMap.clear(); // need for reload case
m_gameObjectBattleEventIndexMap[static_cast<uint32>(-1)] = events;
m_creatureBattleEventIndexMap.clear(); // need for reload case
m_creatureBattleEventIndexMap[static_cast<uint32>(-1)] = events;
std::shared_ptr<GameObjectBattleEventIndexesMap> newGameObjectIndexes = std::make_shared<GameObjectBattleEventIndexesMap>();
(*newGameObjectIndexes)[static_cast<uint32>(-1)] = events;
std::shared_ptr<CreatureBattleEventIndexesMap> newCreatureIndexes = std::make_shared<CreatureBattleEventIndexesMap>();
(*newCreatureIndexes)[static_cast<uint32>(-1)] = events;

uint32 count = 0;

Expand Down Expand Up @@ -807,14 +820,29 @@ void BattleGroundMgr::LoadBattleEventIndexes()
}

if (gameobject)
m_gameObjectBattleEventIndexMap[dbTableGuidLow] = events;
(*newGameObjectIndexes)[dbTableGuidLow] = events;
else
m_creatureBattleEventIndexMap[dbTableGuidLow] = events;
(*newCreatureIndexes)[dbTableGuidLow] = events;

++count;
}
while (queryResult->NextRow());

m_gameObjectBattleEventIndexMap = newGameObjectIndexes;
m_creatureBattleEventIndexMap = newCreatureIndexes;

if (reload)
{
sMapMgr.DoForAllMaps([gameobjects = newGameObjectIndexes, creatures = newCreatureIndexes](Map* map)
{
map->GetMessager().AddMessage([gameobjects, creatures](Map* map)
{
map->GetMapDataContainer().SetGameObjectEventIndexes(gameobjects);
map->GetMapDataContainer().SetCreatureEventIndexes(creatures);
});
});
}

sLog.outString(">> Loaded %u battleground eventindexes", count);
sLog.outString();
}
Expand Down
35 changes: 22 additions & 13 deletions src/game/BattleGround/BattleGroundMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,35 +73,40 @@ class BattleGroundMgr

void ToggleTesting();

void LoadBattleMastersEntry();
void LoadBattleMastersEntry(bool reload);
BattleGroundTypeId GetBattleMasterBG(uint32 entry) const
{
BattleMastersMap::const_iterator itr = m_battleMastersMap.find(entry);
if (itr != m_battleMastersMap.end())
BattleMastersMap::const_iterator itr = m_battleMastersMap->find(entry);
if (itr != m_battleMastersMap->end())
return itr->second;

return BATTLEGROUND_TYPE_NONE;
}
std::shared_ptr<BattleMastersMap> GetBattleMastersMap() const { return m_battleMastersMap; }

void LoadBattleEventIndexes();
void LoadBattleEventIndexes(bool reload);
const BattleGroundEventIdx GetCreatureEventIndex(uint32 dbGuid) const
{
CreatureBattleEventIndexesMap::const_iterator itr = m_creatureBattleEventIndexMap.find(dbGuid);
if (itr != m_creatureBattleEventIndexMap.end())
CreatureBattleEventIndexesMap::const_iterator itr = m_creatureBattleEventIndexMap->find(dbGuid);
if (itr != m_creatureBattleEventIndexMap->end())
return itr->second;

return m_creatureBattleEventIndexMap.find(static_cast<uint32>(-1))->second;
return m_creatureBattleEventIndexMap->find(static_cast<uint32>(-1))->second;
}

std::shared_ptr<CreatureBattleEventIndexesMap> GetCreatureEventIndexes() const { return m_creatureBattleEventIndexMap; }

const BattleGroundEventIdx GetGameObjectEventIndex(uint32 dbGuid) const
{
GameObjectBattleEventIndexesMap::const_iterator itr = m_gameObjectBattleEventIndexMap.find(dbGuid);
if (itr != m_gameObjectBattleEventIndexMap.end())
GameObjectBattleEventIndexesMap::const_iterator itr = m_gameObjectBattleEventIndexMap->find(dbGuid);
if (itr != m_gameObjectBattleEventIndexMap->end())
return itr->second;

return m_gameObjectBattleEventIndexMap.find(static_cast<uint32>(-1))->second;
return m_gameObjectBattleEventIndexMap->find(static_cast<uint32>(-1))->second;
}

std::shared_ptr<GameObjectBattleEventIndexesMap> GetGameObjectEventIndexes() const { return m_gameObjectBattleEventIndexMap; }

bool IsTesting() const { return m_testing; }

static BattleGroundQueueTypeId BgQueueTypeId(BattleGroundTypeId /*bgTypeId*/);
Expand All @@ -116,16 +121,20 @@ class BattleGroundMgr
uint32 GetMinLevelForBattleGroundBracketId(BattleGroundBracketId bracket_id, BattleGroundTypeId bgTypeId) const;
uint32 GetMaxLevelForBattleGroundBracketId(BattleGroundBracketId bracket_id, BattleGroundTypeId bgTypeId) const;
BattleGroundBracketId GetBattleGroundBracketIdFromLevel(BattleGroundTypeId bgTypeId, uint32 playerLevel) const;

Messager<BattleGroundMgr>& GetMessager() { return m_messager; }
private:
std::mutex schedulerLock;
BattleMastersMap m_battleMastersMap;
CreatureBattleEventIndexesMap m_creatureBattleEventIndexMap;
GameObjectBattleEventIndexesMap m_gameObjectBattleEventIndexMap;
std::shared_ptr<BattleMastersMap> m_battleMastersMap;
std::shared_ptr<CreatureBattleEventIndexesMap> m_creatureBattleEventIndexMap;
std::shared_ptr<GameObjectBattleEventIndexesMap> m_gameObjectBattleEventIndexMap;

/* Battlegrounds */
BattleGroundSet m_battleGrounds[MAX_BATTLEGROUND_TYPE_ID];
bool m_testing;
std::set<uint32> m_usedRefloot;

Messager<BattleGroundMgr> m_messager;
};

#define sBattleGroundMgr MaNGOS::Singleton<BattleGroundMgr>::Instance()
Expand Down
5 changes: 4 additions & 1 deletion src/game/Chat/Level3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,10 @@ bool ChatHandler::HandleReloadItemRequiredTragetCommand(char* /*args*/)
bool ChatHandler::HandleReloadBattleEventCommand(char* /*args*/)
{
sLog.outString("Re-Loading BattleGround Eventindexes...");
sBattleGroundMgr.LoadBattleEventIndexes();
sBattleGroundMgr.GetMessager().AddMessage([](BattleGroundMgr* mgr)
{
mgr->LoadBattleEventIndexes(true);
});
SendGlobalSysMessage("DB table `gameobject_battleground` and `creature_battleground` reloaded.");
return true;
}
Expand Down
5 changes: 4 additions & 1 deletion src/game/Chat/debugcmds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,10 @@ bool ChatHandler::HandleDebugGetItemStateCommand(char* args)

bool ChatHandler::HandleDebugBattlegroundCommand(char* /*args*/)
{
sBattleGroundMgr.ToggleTesting();
sBattleGroundMgr.GetMessager().AddMessage([](BattleGroundMgr* mgr)
{
mgr->ToggleTesting();
});
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion src/game/Entities/Creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1015,7 +1015,7 @@ bool Creature::CanInteractWithBattleMaster(Player* pPlayer, bool msg) const
if (!isBattleMaster())
return false;

BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(GetEntry());
BattleGroundTypeId bgTypeId = GetMap()->GetMapDataContainer().GetBattleMasterBG(GetEntry());
if (bgTypeId == BATTLEGROUND_TYPE_NONE)
return false;

Expand Down
6 changes: 3 additions & 3 deletions src/game/Grids/GridNotifiers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ void MaNGOS::RespawnDo::operator()(Creature* u) const
Map* map = u->GetMap();
if (map->IsBattleGround())
{
BattleGroundEventIdx eventId = sBattleGroundMgr.GetCreatureEventIndex(u->GetDbGuid());
BattleGroundEventIdx eventId = map->GetMapDataContainer().GetCreatureEventIndex(u->GetDbGuid());
if (!((BattleGroundMap*)map)->GetBG()->IsActiveEvent(eventId.event1, eventId.event2))
return;
}
Expand All @@ -234,8 +234,8 @@ void MaNGOS::RespawnDo::operator()(GameObject* u) const
Map* map = u->GetMap();
if (map->IsBattleGround())
{
BattleGroundEventIdx eventId = sBattleGroundMgr.GetGameObjectEventIndex(u->GetDbGuid());
if (!((BattleGroundMap*)map)->GetBG()->IsActiveEvent(eventId.event1, eventId.event2))
BattleGroundEventIdx eventId = map->GetMapDataContainer().GetGameObjectEventIndex(u->GetDbGuid());
if (!static_cast<BattleGroundMap*>(map)->GetBG()->IsActiveEvent(eventId.event1, eventId.event2))
return;
}

Expand Down
5 changes: 4 additions & 1 deletion src/game/Maps/Map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2069,7 +2069,10 @@ void BattleGroundMap::Update(const uint32& diff)
// BattleGround Template instance cannot be updated, because it would be deleted
if (!m_bg->GetInvitedCount(HORDE) && !m_bg->GetInvitedCount(ALLIANCE))
{
sBattleGroundMgr.RemoveBattleGround(GetInstanceId(), m_bg->GetTypeId());
sBattleGroundMgr.GetMessager().AddMessage([instanceId = GetInstanceId(), typeId = m_bg->GetTypeId()](BattleGroundMgr* mgr)
{
mgr->RemoveBattleGround(instanceId, typeId);
});
m_bg = nullptr;
}
}
Expand Down
47 changes: 46 additions & 1 deletion src/game/Maps/MapDataContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@
#include "Globals/UnitCondition.h"
#include "World/WorldStateExpression.h"
#include "Globals/CombatCondition.h"
#include "BattleGround/BattleGroundMgr.h"

MapDataContainer::MapDataContainer() : m_spellListContainer(sObjectMgr.GetCreatureSpellListContainer()),
m_spawnGroupContainer(sObjectMgr.GetSpawnGroupContainer()), m_CreatureEventAIEventEntryMap(sEventAIMgr.GetCreatureEventEntryAIMap()),
m_CreatureEventAIEventGuidMap(sEventAIMgr.GetCreatureEventGuidAIMap()), m_creatureEventAIComputedDataMap(sEventAIMgr.GetEAIComputedDataMap()),
m_stringIds(sScriptMgr.GetStringIdMap()), m_stringIdsByString(sScriptMgr.GetStringIdByStringMap()),
m_unitConditions(sObjectMgr.GetUnitConditions()), m_worldStateExpressions(sObjectMgr.GetWorldStateExpressions()), m_combatConditions(sObjectMgr.GetCombatConditions())
m_unitConditions(sObjectMgr.GetUnitConditions()), m_worldStateExpressions(sObjectMgr.GetWorldStateExpressions()), m_combatConditions(sObjectMgr.GetCombatConditions()),
m_creatureBattleEventIndexMap(sBattleGroundMgr.GetCreatureEventIndexes()), m_gameObjectBattleEventIndexMap(sBattleGroundMgr.GetGameObjectEventIndexes()),
m_battleMastersMap(sBattleGroundMgr.GetBattleMastersMap())
{
for (uint32 i = 0; i < SCRIPT_TYPE_MAX; ++i)
SetScriptMap(ScriptMapType(i), sScriptMgr.GetScriptMap(ScriptMapType(i)));
Expand Down Expand Up @@ -143,6 +146,48 @@ std::shared_ptr<std::map<int32, CombatConditionEntry>> MapDataContainer::GetComb
return m_combatConditions;
}

const BattleGroundEventIdx MapDataContainer::GetCreatureEventIndex(uint32 dbGuid) const
{
CreatureBattleEventIndexesMap::const_iterator itr = m_creatureBattleEventIndexMap->find(dbGuid);
if (itr != m_creatureBattleEventIndexMap->end())
return itr->second;

return m_creatureBattleEventIndexMap->find(static_cast<uint32>(-1))->second;
}

void MapDataContainer::SetCreatureEventIndexes(std::shared_ptr<CreatureBattleEventIndexesMap> indexes)
{
m_creatureBattleEventIndexMap = indexes;
}

const BattleGroundEventIdx MapDataContainer::GetGameObjectEventIndex(uint32 dbGuid) const
{
GameObjectBattleEventIndexesMap::const_iterator itr = m_gameObjectBattleEventIndexMap->find(dbGuid);
if (itr != m_gameObjectBattleEventIndexMap->end())
return itr->second;

return m_gameObjectBattleEventIndexMap->find(static_cast<uint32>(-1))->second;
}

void MapDataContainer::SetGameObjectEventIndexes(std::shared_ptr<GameObjectBattleEventIndexesMap> indexes)
{
m_gameObjectBattleEventIndexMap = indexes;
}

BattleGroundTypeId MapDataContainer::GetBattleMasterBG(uint32 entry) const
{
BattleMastersMap::const_iterator itr = m_battleMastersMap->find(entry);
if (itr != m_battleMastersMap->end())
return itr->second;

return BATTLEGROUND_TYPE_NONE;
}

void MapDataContainer::SetBattleMastersMap(std::shared_ptr<BattleMastersMap> battleMasters)
{
m_battleMastersMap = battleMasters;
}

void MapDataContainer::SetStringIdMaps(std::shared_ptr<StringIdMap> stringIds, std::shared_ptr<StringIdMapByString> stringIdsByString)
{
m_stringIds = stringIds;
Expand Down
Loading

0 comments on commit e402036

Please sign in to comment.