From 618cfc72202633669fa2a8ffcdc8164f2e5f90bb Mon Sep 17 00:00:00 2001 From: killerwife Date: Sat, 17 Aug 2024 10:02:02 +0200 Subject: [PATCH] BattleGround: Wave 1 of safeguards against race conditions BattleGround handler and BattleGround class still need to be massively reworked but this makes it a little bette --- src/game/BattleGround/BattleGround.cpp | 16 ++++-- src/game/BattleGround/BattleGround.h | 3 +- src/game/BattleGround/BattleGroundAB.cpp | 2 +- src/game/BattleGround/BattleGroundAV.cpp | 4 +- src/game/BattleGround/BattleGroundDefines.h | 55 +++++++++++++++++++ src/game/BattleGround/BattleGroundHandler.cpp | 2 +- src/game/BattleGround/BattleGroundMgr.cpp | 50 +++++++++++++---- src/game/BattleGround/BattleGroundMgr.h | 35 +++++++----- src/game/Chat/Level3.cpp | 20 +++++-- src/game/Chat/debugcmds.cpp | 10 +++- src/game/Entities/Creature.cpp | 2 +- src/game/Entities/Player.cpp | 2 - src/game/Globals/SharedDefines.h | 30 ---------- src/game/Grids/GridNotifiers.cpp | 6 +- src/game/Maps/Map.cpp | 5 +- src/game/Maps/MapDataContainer.cpp | 47 +++++++++++++++- src/game/Maps/MapDataContainer.h | 19 +++++++ src/game/Server/WorldSession.cpp | 5 +- src/game/Server/WorldSession.h | 1 + src/game/World/World.cpp | 4 +- 20 files changed, 239 insertions(+), 79 deletions(-) create mode 100644 src/game/BattleGround/BattleGroundDefines.h diff --git a/src/game/BattleGround/BattleGround.cpp b/src/game/BattleGround/BattleGround.cpp index e4dc7011c5b..4865e71eb8e 100644 --- a/src/game/BattleGround/BattleGround.cpp +++ b/src/game/BattleGround/BattleGround.cpp @@ -294,7 +294,12 @@ BattleGround::~BattleGround() // skip template bgs as they were never added to visible bg list BattleGroundBracketId bracketId = GetBracketId(); if (bracketId != BG_BRACKET_ID_TEMPLATE) - sBattleGroundMgr.DeleteClientVisibleInstanceId(GetTypeId(), bracketId, GetClientInstanceId()); + { + sBattleGroundMgr.GetMessager().AddMessage([typeId = GetTypeId(), bracketId, clientInstanceId = GetClientInstanceId()](BattleGroundMgr* mgr) + { + mgr->DeleteClientVisibleInstanceId(typeId, bracketId, clientInstanceId); + }); + } // unload map // map can be null at bg destruction @@ -1368,7 +1373,10 @@ void BattleGround::RemovePlayerAtLeave(ObjectGuid playerGuid, bool isOnTransport { // a player has left the battleground, so there are free slots -> add to queue AddToBgFreeSlotQueue(); - sBattleGroundMgr.ScheduleQueueUpdate(0, ARENA_TYPE_NONE, bgQueueTypeId, bgTypeId, GetBracketId()); + sBattleGroundMgr.GetMessager().AddMessage([bgQueueTypeId, bgTypeId, bracketId = GetBracketId()](BattleGroundMgr* mgr) + { + mgr->ScheduleQueueUpdate(0, ARENA_TYPE_NONE, bgQueueTypeId, bgTypeId, bracketId); + }); } // Let others know @@ -1845,7 +1853,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; @@ -1876,7 +1884,7 @@ uint32 BattleGround::GetSingleCreatureGuid(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; diff --git a/src/game/BattleGround/BattleGround.h b/src/game/BattleGround/BattleGround.h index e5591414867..853a05d6366 100644 --- a/src/game/BattleGround/BattleGround.h +++ b/src/game/BattleGround/BattleGround.h @@ -24,6 +24,7 @@ #include "Maps/Map.h" #include "Util/ByteBuffer.h" #include "Entities/ObjectGuid.h" +#include "BattleGround/BattleGroundDefines.h" // magic event-numbers #define BG_EVENT_NONE 255 @@ -642,7 +643,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 diff --git a/src/game/BattleGround/BattleGroundAB.cpp b/src/game/BattleGround/BattleGroundAB.cpp index 646905d0ee6..c79b6ff155c 100644 --- a/src/game/BattleGround/BattleGroundAB.cpp +++ b/src/game/BattleGround/BattleGroundAB.cpp @@ -309,7 +309,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; diff --git a/src/game/BattleGround/BattleGroundAV.cpp b/src/game/BattleGround/BattleGroundAV.cpp index 0f8b18690e8..3744285700b 100644 --- a/src/game/BattleGround/BattleGroundAV.cpp +++ b/src/game/BattleGround/BattleGroundAV.cpp @@ -650,12 +650,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); diff --git a/src/game/BattleGround/BattleGroundDefines.h b/src/game/BattleGround/BattleGroundDefines.h new file mode 100644 index 00000000000..6d80970b39b --- /dev/null +++ b/src/game/BattleGround/BattleGroundDefines.h @@ -0,0 +1,55 @@ +/* + * This file is part of the CMaNGOS Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MANGOSSERVER_BATTLEGROUND_DEFINES_H +#define MANGOSSERVER_BATTLEGROUND_DEFINES_H + +#include "Common.h" + +// indexes of BattlemasterList.dbc +enum BattleGroundTypeId +{ + BATTLEGROUND_TYPE_NONE = 0, + BATTLEGROUND_AV = 1, + BATTLEGROUND_WS = 2, + BATTLEGROUND_AB = 3, + BATTLEGROUND_NA = 4, + BATTLEGROUND_BE = 5, + BATTLEGROUND_AA = 6, // all arenas + BATTLEGROUND_EY = 7, + BATTLEGROUND_RL = 8, + BATTLEGROUND_SA = 9, + BATTLEGROUND_DS = 10, + BATTLEGROUND_RV = 11, + BATTLEGROUND_IC = 30, + BATTLEGROUND_RB = 32 // random battleground +}; +#define MAX_BATTLEGROUND_TYPE_ID 33 + +enum ArenaType +{ + ARENA_TYPE_NONE = 0, // used for mark non-arenas or problematic cases + ARENA_TYPE_2v2 = 2, + ARENA_TYPE_3v3 = 3, + ARENA_TYPE_5v5 = 5 +}; + +inline bool IsArenaTypeValid(ArenaType type) { return type == ARENA_TYPE_2v2 || type == ARENA_TYPE_3v3 || type == ARENA_TYPE_5v5; } + +#endif // MANGOSSERVER_BATTLEGROUND_DEFINES_H + diff --git a/src/game/BattleGround/BattleGroundHandler.cpp b/src/game/BattleGround/BattleGroundHandler.cpp index 2c691057413..2589c7e5c21 100644 --- a/src/game/BattleGround/BattleGroundHandler.cpp +++ b/src/game/BattleGround/BattleGroundHandler.cpp @@ -54,7 +54,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; diff --git a/src/game/BattleGround/BattleGroundMgr.cpp b/src/game/BattleGround/BattleGroundMgr.cpp index 3290864a6b2..24ac5e97a3f 100644 --- a/src/game/BattleGround/BattleGroundMgr.cpp +++ b/src/game/BattleGround/BattleGroundMgr.cpp @@ -1295,6 +1295,8 @@ void BattleGroundMgr::DeleteAllBattleGrounds() */ void BattleGroundMgr::Update(uint32 diff) { + m_messager.Execute(this); + // update scheduled queues if (!m_queueUpdateScheduler.empty()) { @@ -2658,9 +2660,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 newBattleMastersMap = std::make_shared(); auto queryResult = WorldDatabase.Query("SELECT entry,bg_template FROM battlemaster_entry"); @@ -2692,10 +2694,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(); } @@ -2749,15 +2764,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(-1)] = events; - m_creatureBattleEventIndexMap.clear(); // need for reload case - m_creatureBattleEventIndexMap[static_cast(-1)] = events; + std::shared_ptr newGameObjectIndexes = std::make_shared(); + (*newGameObjectIndexes)[static_cast(-1)] = events; + std::shared_ptr newCreatureIndexes = std::make_shared(); + (*newCreatureIndexes)[static_cast(-1)] = events; uint32 count = 0; @@ -2846,14 +2861,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(); } diff --git a/src/game/BattleGround/BattleGroundMgr.h b/src/game/BattleGround/BattleGroundMgr.h index 5f5ee75ff25..45cfa80b356 100644 --- a/src/game/BattleGround/BattleGroundMgr.h +++ b/src/game/BattleGround/BattleGroundMgr.h @@ -248,35 +248,40 @@ class BattleGroundMgr void ToggleArenaTesting(); 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 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(-1))->second; + return m_creatureBattleEventIndexMap->find(static_cast(-1))->second; } + std::shared_ptr 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(-1))->second; + return m_gameObjectBattleEventIndexMap->find(static_cast(-1))->second; } + std::shared_ptr GetGameObjectEventIndexes() const { return m_gameObjectBattleEventIndexMap; } + bool IsArenaTesting() const { return m_arenaTesting; } bool IsTesting() const { return m_testing; } @@ -291,11 +296,13 @@ class BattleGroundMgr static bool IsBgWeekend(BattleGroundTypeId /*bgTypeId*/); std::set const& GetUsedRefLootIds() const { return m_usedRefloot; } + + Messager& GetMessager() { return m_messager; } private: std::mutex schedulerLock; - BattleMastersMap m_battleMastersMap; - CreatureBattleEventIndexesMap m_creatureBattleEventIndexMap; - GameObjectBattleEventIndexesMap m_gameObjectBattleEventIndexMap; + std::shared_ptr m_battleMastersMap; + std::shared_ptr m_creatureBattleEventIndexMap; + std::shared_ptr m_gameObjectBattleEventIndexMap; /* Battlegrounds */ BattleGroundSet m_battleGrounds[MAX_BATTLEGROUND_TYPE_ID]; @@ -308,6 +315,8 @@ class BattleGroundMgr bool m_arenaTesting; bool m_testing; std::set m_usedRefloot; + + Messager m_messager; }; #define sBattleGroundMgr MaNGOS::Singleton::Instance() diff --git a/src/game/Chat/Level3.cpp b/src/game/Chat/Level3.cpp index 443393d0042..5f3a0582a01 100644 --- a/src/game/Chat/Level3.cpp +++ b/src/game/Chat/Level3.cpp @@ -836,7 +836,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; } @@ -7224,7 +7227,10 @@ bool ChatHandler::HandleSendMessageCommand(char* args) bool ChatHandler::HandleArenaFlushPointsCommand(char* /*args*/) { - sBattleGroundMgr.DistributeArenaPoints(); + sBattleGroundMgr.GetMessager().AddMessage([](BattleGroundMgr* mgr) + { + mgr->DistributeArenaPoints(); + }); return true; } @@ -7237,7 +7243,10 @@ bool ChatHandler::HandleArenaSeasonRewardsCommand(char* args) if (seasonId > 4 || seasonId == 0) return false; - sBattleGroundMgr.RewardArenaSeason(seasonId); + sBattleGroundMgr.GetMessager().AddMessage([seasonId](BattleGroundMgr* mgr) + { + mgr->RewardArenaSeason(seasonId); + }); return true; } @@ -7251,7 +7260,10 @@ bool ChatHandler::HandleArenaDataReset(char* args) } PSendSysMessage("Resetting all arena data."); - sBattleGroundMgr.ResetAllArenaData(); + sBattleGroundMgr.GetMessager().AddMessage([](BattleGroundMgr* mgr) + { + mgr->ResetAllArenaData(); + }); return true; } diff --git a/src/game/Chat/debugcmds.cpp b/src/game/Chat/debugcmds.cpp index 1e5014d404d..9c59c69805e 100644 --- a/src/game/Chat/debugcmds.cpp +++ b/src/game/Chat/debugcmds.cpp @@ -741,13 +741,19 @@ bool ChatHandler::HandleDebugGetItemStateCommand(char* args) bool ChatHandler::HandleDebugBattlegroundCommand(char* /*args*/) { - sBattleGroundMgr.ToggleTesting(); + sBattleGroundMgr.GetMessager().AddMessage([](BattleGroundMgr* mgr) + { + mgr->ToggleTesting(); + }); return true; } bool ChatHandler::HandleDebugArenaCommand(char* /*args*/) { - sBattleGroundMgr.ToggleArenaTesting(); + sBattleGroundMgr.GetMessager().AddMessage([](BattleGroundMgr* mgr) + { + mgr->ToggleArenaTesting(); + }); return true; } diff --git a/src/game/Entities/Creature.cpp b/src/game/Entities/Creature.cpp index 37373258a15..233d0edcd03 100644 --- a/src/game/Entities/Creature.cpp +++ b/src/game/Entities/Creature.cpp @@ -1058,7 +1058,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; diff --git a/src/game/Entities/Player.cpp b/src/game/Entities/Player.cpp index c10aca18edf..5825914d726 100644 --- a/src/game/Entities/Player.cpp +++ b/src/game/Entities/Player.cpp @@ -16397,8 +16397,6 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder) _LoadBGData(holder->GetResult(PLAYER_LOGIN_QUERY_LOADBGDATA)); - - if (m_bgData.bgInstanceID) // saved in BattleGround { BattleGround* currentBg = sBattleGroundMgr.GetBattleGround(m_bgData.bgInstanceID, BATTLEGROUND_TYPE_NONE); diff --git a/src/game/Globals/SharedDefines.h b/src/game/Globals/SharedDefines.h index 256bf2aae96..1402cae091d 100644 --- a/src/game/Globals/SharedDefines.h +++ b/src/game/Globals/SharedDefines.h @@ -2067,36 +2067,6 @@ enum BanReturn BAN_NOTFOUND }; -// indexes of BattlemasterList.dbc -enum BattleGroundTypeId -{ - BATTLEGROUND_TYPE_NONE = 0, - BATTLEGROUND_AV = 1, - BATTLEGROUND_WS = 2, - BATTLEGROUND_AB = 3, - BATTLEGROUND_NA = 4, - BATTLEGROUND_BE = 5, - BATTLEGROUND_AA = 6, // all arenas - BATTLEGROUND_EY = 7, - BATTLEGROUND_RL = 8, - BATTLEGROUND_SA = 9, - BATTLEGROUND_DS = 10, - BATTLEGROUND_RV = 11, - BATTLEGROUND_IC = 30, - BATTLEGROUND_RB = 32 // random battleground -}; -#define MAX_BATTLEGROUND_TYPE_ID 33 - -enum ArenaType -{ - ARENA_TYPE_NONE = 0, // used for mark non-arenas or problematic cases - ARENA_TYPE_2v2 = 2, - ARENA_TYPE_3v3 = 3, - ARENA_TYPE_5v5 = 5 -}; - -inline bool IsArenaTypeValid(ArenaType type) { return type == ARENA_TYPE_2v2 || type == ARENA_TYPE_3v3 || type == ARENA_TYPE_5v5; } - enum MailResponseType { MAIL_SEND = 0, diff --git a/src/game/Grids/GridNotifiers.cpp b/src/game/Grids/GridNotifiers.cpp index 82f020924d5..e0cc387898a 100644 --- a/src/game/Grids/GridNotifiers.cpp +++ b/src/game/Grids/GridNotifiers.cpp @@ -270,7 +270,7 @@ void MaNGOS::RespawnDo::operator()(Creature* u) const Map* map = u->GetMap(); if (map->IsBattleGroundOrArena()) { - BattleGroundEventIdx eventId = sBattleGroundMgr.GetCreatureEventIndex(u->GetDbGuid()); + BattleGroundEventIdx eventId = map->GetMapDataContainer().GetCreatureEventIndex(u->GetDbGuid()); if (!((BattleGroundMap*)map)->GetBG()->IsActiveEvent(eventId.event1, eventId.event2)) return; } @@ -295,8 +295,8 @@ void MaNGOS::RespawnDo::operator()(GameObject* u) const Map* map = u->GetMap(); if (map->IsBattleGroundOrArena()) { - 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(map)->GetBG()->IsActiveEvent(eventId.event1, eventId.event2)) return; } diff --git a/src/game/Maps/Map.cpp b/src/game/Maps/Map.cpp index dd24ae0f98a..aaab8b73a59 100644 --- a/src/game/Maps/Map.cpp +++ b/src/game/Maps/Map.cpp @@ -2126,7 +2126,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; } } diff --git a/src/game/Maps/MapDataContainer.cpp b/src/game/Maps/MapDataContainer.cpp index 652a3ec715b..63c5bc48b3c 100644 --- a/src/game/Maps/MapDataContainer.cpp +++ b/src/game/Maps/MapDataContainer.cpp @@ -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))); @@ -143,6 +146,48 @@ std::shared_ptr> 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(-1))->second; +} + +void MapDataContainer::SetCreatureEventIndexes(std::shared_ptr 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(-1))->second; +} + +void MapDataContainer::SetGameObjectEventIndexes(std::shared_ptr 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 battleMasters) +{ + m_battleMastersMap = battleMasters; +} + void MapDataContainer::SetStringIdMaps(std::shared_ptr stringIds, std::shared_ptr stringIdsByString) { m_stringIds = stringIds; diff --git a/src/game/Maps/MapDataContainer.h b/src/game/Maps/MapDataContainer.h index cd25db6e4d3..8f7f46cc2a7 100644 --- a/src/game/Maps/MapDataContainer.h +++ b/src/game/Maps/MapDataContainer.h @@ -21,6 +21,7 @@ #include "Platform/Define.h" #include "DBScripts/ScriptMgrDefines.h" +#include "BattleGround/BattleGroundDefines.h" #include #include #include @@ -36,6 +37,7 @@ struct ScriptInfo; struct UnitConditionEntry; struct WorldStateExpressionEntry; struct CombatConditionEntry; +struct BattleGroundEventIdx; // Event_Map typedef std::vector CreatureEventAI_Event_Vec; @@ -47,6 +49,11 @@ typedef std::multimap < uint32 /*delay*/, std::shared_ptr> ScriptMap typedef std::map < uint32 /*id*/, ScriptMap > ScriptMapMap; typedef std::pair ScriptMapMapName; +// Battleground +typedef std::unordered_map BattleMastersMap; +typedef std::unordered_map CreatureBattleEventIndexesMap; +typedef std::unordered_map GameObjectBattleEventIndexesMap; + class MapDataContainer { public: @@ -74,6 +81,14 @@ class MapDataContainer std::shared_ptr> GetUnitConditions() const; std::shared_ptr> GetWorldStateExpressions() const; std::shared_ptr> GetCombatConditions() const; + + const BattleGroundEventIdx GetCreatureEventIndex(uint32 dbGuid) const; + void SetCreatureEventIndexes(std::shared_ptr indexes); + const BattleGroundEventIdx GetGameObjectEventIndex(uint32 dbGuid) const; + void SetGameObjectEventIndexes(std::shared_ptr indexes); + + BattleGroundTypeId GetBattleMasterBG(uint32 entry) const; + void SetBattleMastersMap(std::shared_ptr battleMasters); private: std::shared_ptr m_spellListContainer; std::shared_ptr m_spawnGroupContainer; @@ -91,6 +106,10 @@ class MapDataContainer std::shared_ptr> m_unitConditions; std::shared_ptr> m_worldStateExpressions; std::shared_ptr> m_combatConditions; + + std::shared_ptr m_creatureBattleEventIndexMap; + std::shared_ptr m_gameObjectBattleEventIndexMap; + std::shared_ptr m_battleMastersMap; }; #endif \ No newline at end of file diff --git a/src/game/Server/WorldSession.cpp b/src/game/Server/WorldSession.cpp index 95d24297949..cbe973ecaaf 100644 --- a/src/game/Server/WorldSession.cpp +++ b/src/game/Server/WorldSession.cpp @@ -651,7 +651,10 @@ void WorldSession::LogoutPlayer() if (BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i)) { _player->RemoveBattleGroundQueueId(bgQueueTypeId); - sBattleGroundMgr.m_battleGroundQueues[ bgQueueTypeId ].RemovePlayer(_player->GetObjectGuid(), true); + sBattleGroundMgr.GetMessager().AddMessage([bgQueueTypeId, playerGuid = _player->GetObjectGuid()](BattleGroundMgr* mgr) + { + mgr->m_battleGroundQueues[bgQueueTypeId].RemovePlayer(playerGuid, true); + }); } } diff --git a/src/game/Server/WorldSession.h b/src/game/Server/WorldSession.h index 815a8167089..109617efaad 100644 --- a/src/game/Server/WorldSession.h +++ b/src/game/Server/WorldSession.h @@ -32,6 +32,7 @@ #include "Server/WorldSocket.h" #include "Multithreading/Messager.h" #include "LFG/LFGDefines.h" +#include "BattleGround/BattleGroundDefines.h" #include #include diff --git a/src/game/World/World.cpp b/src/game/World/World.cpp index 4490be18234..65b5538f6f9 100644 --- a/src/game/World/World.cpp +++ b/src/game/World/World.cpp @@ -1355,10 +1355,10 @@ void World::SetInitialWorldSettings() sObjectMgr.LoadGameObjectForQuests(); sLog.outString("Loading BattleMasters..."); - sBattleGroundMgr.LoadBattleMastersEntry(); + sBattleGroundMgr.LoadBattleMastersEntry(false); sLog.outString("Loading BattleGround event indexes..."); - sBattleGroundMgr.LoadBattleEventIndexes(); + sBattleGroundMgr.LoadBattleEventIndexes(false); sLog.outString("Loading GameTeleports..."); sObjectMgr.LoadGameTele();