diff options
author | Shauren <shauren.trinity@gmail.com> | 2025-02-08 19:58:34 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2025-02-08 19:58:34 +0100 |
commit | de9340ccec2d53d4b090bc6ebfadd67cc77d7f5a (patch) | |
tree | ab3a8dd6c8e3395b6519820cead0d793ac8dcb40 | |
parent | b4adab5515f4c9445957184d48e3cd2da9b9f0f1 (diff) |
Core/Battlegrounds: Port BattlegroundQueueTypeId changes from master branch
-rw-r--r-- | src/server/game/Battlegrounds/ArenaTeam.cpp | 22 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/ArenaTeam.h | 1 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/Battleground.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/Battleground.h | 9 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/BattlegroundMgr.cpp | 173 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/BattlegroundMgr.h | 22 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/BattlegroundQueue.cpp | 240 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/BattlegroundQueue.h | 49 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Groups/Group.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Handlers/ArenaTeamHandler.cpp | 18 | ||||
-rw-r--r-- | src/server/game/Handlers/BattleGroundHandler.cpp | 126 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 3 | ||||
-rw-r--r-- | src/server/shared/SharedDefines.h | 39 |
14 files changed, 353 insertions, 375 deletions
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index f9901f3c422..4883281f00b 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -326,8 +326,12 @@ void ArenaTeam::DelMember(ObjectGuid guid, bool cleanDb) { if (group && playerMember->GetGroup() && group->GetGUID() == playerMember->GetGroup()->GetGUID()) { - if (BattlegroundQueueTypeId bgQueue = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_AA, GetType())) + for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { + BattlegroundQueueTypeId bgQueue = playerMember->GetBattlegroundQueueTypeId(i); + if (bgQueue.BattlemasterListId != BATTLEGROUND_AA || bgQueue.TeamSize != GetType()) + continue; + GroupQueueInfo ginfo; BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue); if (queue.GetPlayerGroupInfoData(playerMember->GetGUID(), &ginfo)) @@ -335,7 +339,7 @@ void ArenaTeam::DelMember(ObjectGuid guid, bool cleanDb) { WorldPacket data; playerMember->RemoveBattlegroundQueueId(bgQueue); - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, nullptr, playerMember->GetBattlegroundQueueIndex(bgQueue), STATUS_NONE, 0, 0, 0, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, nullptr, i, STATUS_NONE, 0, 0, 0, 0); queue.RemovePlayer(playerMember->GetGUID(), true); playerMember->GetSession()->SendPacket(&data); } @@ -604,6 +608,20 @@ uint8 ArenaTeam::GetSlotByType(uint32 type) return 0xFF; } +uint8 ArenaTeam::GetTypeBySlot(uint8 slot) +{ + switch (slot) + { + case 0: return ARENA_TEAM_2v2; + case 1: return ARENA_TEAM_3v3; + case 2: return ARENA_TEAM_5v5; + default: + break; + } + TC_LOG_ERROR("bg.arena", "FATAL: Unknown arena team slot {} for some arena team", slot); + return 0xFF; +} + bool ArenaTeam::IsMember(ObjectGuid guid) const { for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h index 9495218980c..c6ee45a5125 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.h +++ b/src/server/game/Battlegrounds/ArenaTeam.h @@ -129,6 +129,7 @@ class TC_GAME_API ArenaTeam uint32 GetType() const { return Type; } uint8 GetSlot() const { return GetSlotByType(GetType()); } static uint8 GetSlotByType(uint32 type); + static uint8 GetTypeBySlot(uint8 slot); ObjectGuid GetCaptain() const { return CaptainGuid; } std::string const& GetName() const { return TeamName; } ArenaTeamStats const& GetStats() const { return Stats; } diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index b8fdda378f1..503317d0a5f 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -462,7 +462,7 @@ inline void Battleground::_ProcessJoin(uint32 diff) { // BG Status packet WorldPacket status; - BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType()); + BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(m_TypeID, GetBracketId(), GetArenaType()); uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetBGTeam()); player->SendDirectMessage(&status); @@ -719,7 +719,7 @@ void Battleground::EndBattleground(uint32 winner) WorldPacket pvpLogData; BuildPvPLogDataPacket(pvpLogData); - BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); + BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetBracketId(), GetArenaType()); for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { @@ -869,8 +869,7 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen if (participant) // if the player was a match participant, remove auras, calc rating, update queue { - BattlegroundTypeId bgTypeId = GetTypeID(); - BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); + BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetBracketId(), GetArenaType()); if (player) { player->ClearAfkReports(); @@ -878,7 +877,7 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen // if arena, remove the specific arena auras if (isArena()) { - bgTypeId = BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing) + bgQueueTypeId.BattlemasterListId = BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing) // unsummon current and summon old pet if there was one and there isn't a current pet player->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT); @@ -908,7 +907,7 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen { // a player has left the battleground, so there are free slots -> add to queue AddToBGFreeSlotQueue(); - sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, GetBracketId()); + sBattlegroundMgr->ScheduleQueueUpdate(0, bgQueueTypeId); } // Let others know WorldPacket data; @@ -1731,7 +1730,7 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player) return; WorldPacket data; - BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); + BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetBracketId(), GetArenaType()); BlockMovement(player); diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 76c98c3f6c2..814c359da31 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -497,6 +497,15 @@ class TC_GAME_API Battleground // because BattleGrounds with different types and same level range has different m_BracketId uint8 GetUniqueBracketId() const; + BattlegroundPlayer const* GetBattlegroundPlayerData(ObjectGuid const& playerGuid) const + { + auto itr = m_Players.find(playerGuid); + if (itr == m_Players.end()) + return nullptr; + + return &itr->second; + } + Trinity::unique_weak_ptr<Battleground> GetWeakPtr() const { return m_weakRef; } void SetWeakPtr(Trinity::unique_weak_ptr<Battleground> weakRef) { m_weakRef = std::move(weakRef); } diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index e5af279050c..5659e75fe04 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -113,24 +113,17 @@ void BattlegroundMgr::Update(uint32 diff) } // update events timer - for (int qtype = BATTLEGROUND_QUEUE_NONE; qtype < MAX_BATTLEGROUND_QUEUE_TYPES; ++qtype) - m_BattlegroundQueues[qtype].UpdateEvents(diff); + for (std::pair<BattlegroundQueueTypeId const, BattlegroundQueue>& pair : m_BattlegroundQueues) + pair.second.UpdateEvents(diff); // update scheduled queues if (!m_QueueUpdateScheduler.empty()) { - std::vector<uint64> scheduled; + std::vector<ScheduledQueueUpdate> scheduled; std::swap(scheduled, m_QueueUpdateScheduler); - for (uint8 i = 0; i < scheduled.size(); i++) - { - uint32 arenaMMRating = scheduled[i] >> 32; - uint8 arenaType = scheduled[i] >> 24 & 255; - BattlegroundQueueTypeId bgQueueTypeId = BattlegroundQueueTypeId(scheduled[i] >> 16 & 255); - BattlegroundTypeId bgTypeId = BattlegroundTypeId((scheduled[i] >> 8) & 255); - BattlegroundBracketId bracket_id = BattlegroundBracketId(scheduled[i] & 255); - m_BattlegroundQueues[bgQueueTypeId].BattlegroundQueueUpdate(diff, bgTypeId, bracket_id, arenaType, arenaMMRating > 0, arenaMMRating); - } + for (auto& [arenaMMRating, bgQueueTypeId] : scheduled) + GetBattlegroundQueue(bgQueueTypeId).BattlegroundQueueUpdate(diff, arenaMMRating > 0, arenaMMRating); } // if rating difference counts, maybe force-update queues @@ -141,11 +134,15 @@ void BattlegroundMgr::Update(uint32 diff) { // forced update for rated arenas (scan all, but skipped non rated) TC_LOG_TRACE("bg.arena", "BattlegroundMgr: UPDATING ARENA QUEUES"); - for (int qtype = BATTLEGROUND_QUEUE_2v2; qtype <= BATTLEGROUND_QUEUE_5v5; ++qtype) + for (uint8 teamSize : { ARENA_TYPE_2v2, ARENA_TYPE_3v3, ARENA_TYPE_5v5 }) + { for (int bracket = BG_BRACKET_ID_FIRST; bracket < MAX_BATTLEGROUND_BRACKETS; ++bracket) - m_BattlegroundQueues[qtype].BattlegroundQueueUpdate(diff, - BATTLEGROUND_AA, BattlegroundBracketId(bracket), - BattlegroundMgr::BGArenaType(BattlegroundQueueTypeId(qtype)), true, 0); + { + BattlegroundQueueTypeId ratedArenaQueueId = BGQueueTypeId(BATTLEGROUND_AA, bracket, teamSize); + if (BattlegroundQueue* arenaQueue = Trinity::Containers::MapGetValuePtr(m_BattlegroundQueues, ratedArenaQueueId)) + arenaQueue->BattlegroundQueueUpdate(diff, true, 0); + } + } m_NextRatedArenaUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER); } @@ -488,7 +485,7 @@ bool BattlegroundMgr::CreateBattleground(BattlegroundTemplate const* bgTemplate) AddBattleground(bg); } - bg->SetMapId(bgTemplate->BattlemasterEntry->MapID[0]); + bg->SetMapId(!bgTemplate->MapIDs.empty() ? bgTemplate->MapIDs.front() : -1); bg->SetName(bgTemplate->BattlemasterEntry->Name[sWorld->GetDefaultDbcLocale()]); bg->SetArenaorBGType(bgTemplate->IsArena()); bg->SetMinPlayersPerTeam(bgTemplate->MinPlayersPerTeam); @@ -549,6 +546,9 @@ void BattlegroundMgr::LoadBattlegroundTemplates() bgTemplate.Weight = fields[10].GetUInt8(); bgTemplate.ScriptId = sObjectMgr->GetScriptId(fields[11].GetString()); bgTemplate.BattlemasterEntry = bl; + for (int32 mapId : bl->MapID) + if (sMapStore.LookupEntry(mapId)) + bgTemplate.MapIDs.push_back(mapId); if (bgTemplate.MaxPlayersPerTeam == 0 || bgTemplate.MinPlayersPerTeam > bgTemplate.MaxPlayersPerTeam) { @@ -594,8 +594,8 @@ void BattlegroundMgr::LoadBattlegroundTemplates() _battlegroundTemplates[bgTypeId] = bgTemplate; - if (bgTemplate.BattlemasterEntry->MapID[1] == -1) // in this case we have only one mapId - _battlegroundMapTemplates[bgTemplate.BattlemasterEntry->MapID[0]] = &_battlegroundTemplates[bgTypeId]; + if (bgTemplate.MapIDs.size() == 1) + _battlegroundMapTemplates[bgTemplate.MapIDs[0]] = &_battlegroundTemplates[bgTypeId]; ++count; } @@ -723,86 +723,9 @@ bool BattlegroundMgr::IsArenaType(BattlegroundTypeId bgTypeId) || bgTypeId == BATTLEGROUND_RL; } -BattlegroundQueueTypeId BattlegroundMgr::BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType) +BattlegroundQueueTypeId BattlegroundMgr::BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 bracketId, uint8 arenaType) { - switch (bgTypeId) - { - case BATTLEGROUND_AB: - return BATTLEGROUND_QUEUE_AB; - case BATTLEGROUND_AV: - return BATTLEGROUND_QUEUE_AV; - case BATTLEGROUND_EY: - return BATTLEGROUND_QUEUE_EY; - case BATTLEGROUND_IC: - return BATTLEGROUND_QUEUE_IC; - case BATTLEGROUND_RB: - return BATTLEGROUND_QUEUE_RB; - case BATTLEGROUND_SA: - return BATTLEGROUND_QUEUE_SA; - case BATTLEGROUND_WS: - return BATTLEGROUND_QUEUE_WS; - case BATTLEGROUND_AA: - case BATTLEGROUND_BE: - case BATTLEGROUND_DS: - case BATTLEGROUND_NA: - case BATTLEGROUND_RL: - case BATTLEGROUND_RV: - switch (arenaType) - { - case ARENA_TYPE_2v2: - return BATTLEGROUND_QUEUE_2v2; - case ARENA_TYPE_3v3: - return BATTLEGROUND_QUEUE_3v3; - case ARENA_TYPE_5v5: - return BATTLEGROUND_QUEUE_5v5; - default: - return BATTLEGROUND_QUEUE_NONE; - } - default: - return BATTLEGROUND_QUEUE_NONE; - } -} - -BattlegroundTypeId BattlegroundMgr::BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId) -{ - switch (bgQueueTypeId) - { - case BATTLEGROUND_QUEUE_WS: - return BATTLEGROUND_WS; - case BATTLEGROUND_QUEUE_AB: - return BATTLEGROUND_AB; - case BATTLEGROUND_QUEUE_AV: - return BATTLEGROUND_AV; - case BATTLEGROUND_QUEUE_EY: - return BATTLEGROUND_EY; - case BATTLEGROUND_QUEUE_SA: - return BATTLEGROUND_SA; - case BATTLEGROUND_QUEUE_IC: - return BATTLEGROUND_IC; - case BATTLEGROUND_QUEUE_RB: - return BATTLEGROUND_RB; - case BATTLEGROUND_QUEUE_2v2: - case BATTLEGROUND_QUEUE_3v3: - case BATTLEGROUND_QUEUE_5v5: - return BATTLEGROUND_AA; - default: - return BattlegroundTypeId(0); // used for unknown template (it exists and does nothing) - } -} - -uint8 BattlegroundMgr::BGArenaType(BattlegroundQueueTypeId bgQueueTypeId) -{ - switch (bgQueueTypeId) - { - case BATTLEGROUND_QUEUE_2v2: - return ARENA_TYPE_2v2; - case BATTLEGROUND_QUEUE_3v3: - return ARENA_TYPE_3v3; - case BATTLEGROUND_QUEUE_5v5: - return ARENA_TYPE_5v5; - default: - return 0; - } + return { .BattlemasterListId = uint16(bgTypeId), .BracketId = bracketId, .TeamSize = arenaType }; } void BattlegroundMgr::ToggleTesting() @@ -830,11 +753,40 @@ void BattlegroundMgr::SetHolidayActive(uint32 battlegroundId) bg->SetHoliday(true); } -void BattlegroundMgr::ScheduleQueueUpdate(uint32 arenaMatchmakerRating, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id) +bool BattlegroundMgr::IsValidQueueId(BattlegroundQueueTypeId bgQueueTypeId) +{ + BattlegroundTemplate const* battlemasterList = GetBattlegroundTemplateByTypeId(BattlegroundTypeId(bgQueueTypeId.BattlemasterListId)); + if (!battlemasterList) + return false; + + switch (battlemasterList->BattlemasterEntry->InstanceType) + { + case MAP_BATTLEGROUND: + if (bgQueueTypeId.TeamSize) + return false; + break; + case MAP_ARENA: + if (!bgQueueTypeId.TeamSize) + return false; + break; + default: + break; + } + + if (battlemasterList->MapIDs.empty()) + return false; + + if (!GetBattlegroundBracketById(battlemasterList->MapIDs[0], BattlegroundBracketId(bgQueueTypeId.BracketId))) + return false; + + return true; +} + +void BattlegroundMgr::ScheduleQueueUpdate(uint32 arenaMatchmakerRating, BattlegroundQueueTypeId bgQueueTypeId) { //This method must be atomic, @todo add mutex //we will use only 1 number created of bgTypeId and bracket_id - uint64 const scheduleId = ((uint64)arenaMatchmakerRating << 32) | ((uint64)arenaType << 24) | ((uint64)bgQueueTypeId << 16) | ((uint64)bgTypeId << 8) | (uint64)bracket_id; + ScheduledQueueUpdate scheduleId{ arenaMatchmakerRating, bgQueueTypeId }; if (std::find(m_QueueUpdateScheduler.begin(), m_QueueUpdateScheduler.end(), scheduleId) == m_QueueUpdateScheduler.end()) m_QueueUpdateScheduler.push_back(scheduleId); } @@ -958,23 +910,14 @@ BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId) { if (BattlegroundTemplate const* bgTemplate = GetBattlegroundTemplateByTypeId(bgTypeId)) { - std::vector<BattlegroundTypeId> ids; - ids.reserve(16); - std::vector<double> weights; - weights.reserve(16); - for (int32 mapId : bgTemplate->BattlemasterEntry->MapID) - { - if (mapId == -1) - break; - + std::vector<BattlegroundTemplate const*> ids; + ids.reserve(bgTemplate->MapIDs.size()); + for (int32 mapId : bgTemplate->MapIDs) if (BattlegroundTemplate const* bg = GetBattlegroundTemplateByMapId(mapId)) - { - ids.push_back(bg->Id); - weights.push_back(bg->Weight); - } - } + ids.push_back(bg); - return *Trinity::Containers::SelectRandomWeightedContainerElement(ids, weights); + if (!ids.empty()) + return (*Trinity::Containers::SelectRandomWeightedContainerElement(ids, [](BattlegroundTemplate const* bg) { return bg->Weight; }))->Id; } return BATTLEGROUND_TYPE_NONE; diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index 939d3ef87b1..4b3ab9f03c2 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -58,6 +58,7 @@ struct BattlegroundTemplate uint8 Weight; uint32 ScriptId; BattlemasterListEntry const* BattlemasterEntry; + std::vector<int32> MapIDs; bool IsArena() const; }; @@ -103,8 +104,9 @@ class TC_GAME_API BattlegroundMgr void SendToBattleground(Player* player, uint32 InstanceID, BattlegroundTypeId bgTypeId); /* Battleground queues */ - BattlegroundQueue& GetBattlegroundQueue(BattlegroundQueueTypeId bgQueueTypeId) { return m_BattlegroundQueues[bgQueueTypeId]; } - void ScheduleQueueUpdate(uint32 arenaMatchmakerRating, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id); + bool IsValidQueueId(BattlegroundQueueTypeId bgQueueTypeId); + BattlegroundQueue& GetBattlegroundQueue(BattlegroundQueueTypeId bgQueueTypeId) { return m_BattlegroundQueues.emplace(bgQueueTypeId, bgQueueTypeId).first->second; } + void ScheduleQueueUpdate(uint32 arenaMatchmakerRating, BattlegroundQueueTypeId bgQueueTypeId); uint32 GetPrematureFinishTime() const; void ToggleArenaTesting(); @@ -116,9 +118,7 @@ class TC_GAME_API BattlegroundMgr bool isArenaTesting() const { return m_ArenaTesting; } bool isTesting() const { return m_Testing; } - static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType); - static BattlegroundTypeId BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId); - static uint8 BGArenaType(BattlegroundQueueTypeId bgQueueTypeId); + static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 bracketId, uint8 arenaType); static HolidayIds BGTypeToWeekendHolidayId(BattlegroundTypeId bgTypeId); static BattlegroundTypeId WeekendHolidayIdToBGType(HolidayIds holiday); @@ -146,9 +146,17 @@ class TC_GAME_API BattlegroundMgr typedef std::map<BattlegroundTypeId, BattlegroundData> BattlegroundDataContainer; BattlegroundDataContainer bgDataStore; - BattlegroundQueue m_BattlegroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES]; + std::map<BattlegroundQueueTypeId, BattlegroundQueue> m_BattlegroundQueues; - std::vector<uint64> m_QueueUpdateScheduler; + struct ScheduledQueueUpdate + { + uint32 ArenaMatchmakerRating; + BattlegroundQueueTypeId QueueId; + + bool operator==(ScheduledQueueUpdate const& right) const = default; + }; + + std::vector<ScheduledQueueUpdate> m_QueueUpdateScheduler; uint32 m_NextRatedArenaUpdate; time_t m_NextAutoDistributionTime; uint32 m_AutoDistributionTimeChecker; diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 6ac695a46bb..4807b67b2be 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -34,17 +34,14 @@ /*** BATTLEGROUND QUEUE SYSTEM ***/ /*********************************************************/ -BattlegroundQueue::BattlegroundQueue() +BattlegroundQueue::BattlegroundQueue(BattlegroundQueueTypeId queueId) : m_queueId(queueId) { for (uint32 i = 0; i < PVP_TEAMS_COUNT; ++i) { - for (uint32 j = 0; j < MAX_BATTLEGROUND_BRACKETS; ++j) - { - m_SumOfWaitTimes[i][j] = 0; - m_WaitTimeLastPlayer[i][j] = 0; - for (uint32 k = 0; k < COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; ++k) - m_WaitTimes[i][j][k] = 0; - } + m_SumOfWaitTimes[i] = 0; + m_WaitTimeLastPlayer[i] = 0; + for (uint32 k = 0; k < COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; ++k) + m_WaitTimes[i][k] = 0; } } @@ -52,14 +49,9 @@ BattlegroundQueue::~BattlegroundQueue() { m_events.KillAllEvents(false); - for (int i = 0; i < MAX_BATTLEGROUND_BRACKETS; ++i) - { - for (uint32 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; ++j) - { - for (GroupsQueueType::iterator itr = m_QueuedGroups[i][j].begin(); itr!= m_QueuedGroups[i][j].end(); ++itr) - delete (*itr); - } - } + for (uint32 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; ++j) + for (GroupsQueueType::iterator itr = m_QueuedGroups[j].begin(); itr!= m_QueuedGroups[j].end(); ++itr) + delete (*itr); } /*********************************************************/ @@ -130,20 +122,16 @@ bool BattlegroundQueue::SelectionPool::AddGroup(GroupQueueInfo* ginfo, uint32 de /*********************************************************/ // add group or player (grp == NULL) to bg queue with the given leader and bg specifications -GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, BattlegroundTypeId BgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating, uint32 arenateamid, uint32 PreviousOpponentsArenaTeamId) +GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group const* group, PvPDifficultyEntry const* bracketEntry, bool isRated, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating, uint32 arenateamid, uint32 PreviousOpponentsArenaTeamId) { - BattlegroundBracketId bracketId = bracketEntry->GetBracketId(); - // create new ginfo GroupQueueInfo* ginfo = new GroupQueueInfo; - ginfo->BgTypeId = BgTypeId; - ginfo->ArenaType = ArenaType; ginfo->ArenaTeamId = arenateamid; ginfo->IsRated = isRated; ginfo->IsInvitedToBGInstanceGUID = 0; ginfo->JoinTime = GameTime::GetGameTimeMS(); ginfo->RemoveInviteTime = 0; - ginfo->Team = leader->GetTeam(); + ginfo->Team = Team(leader->GetTeam()); ginfo->ArenaTeamRating = ArenaRating; ginfo->ArenaMatchmakerRating = MatchmakerRating; ginfo->PreviousOpponentsTeamId = PreviousOpponentsArenaTeamId; @@ -158,7 +146,7 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr index += PVP_TEAMS_COUNT; if (ginfo->Team == HORDE) index++; - TC_LOG_DEBUG("bg.battleground", "Adding Group to BattlegroundQueue bgTypeId : {}, bracket_id : {}, index : {}", BgTypeId, bracketId, index); + TC_LOG_DEBUG("bg.battleground", "Adding Group to BattlegroundQueue bgTypeId : {}, bracket_id : {}, index : {}", m_queueId.BattlemasterListId, m_queueId.BracketId, index); uint32 lastOnlineTime = GameTime::GetGameTimeMS(); @@ -167,13 +155,13 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr { ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(arenateamid); if (team) - sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, team->GetName().c_str(), ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating); + sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, team->GetName().c_str(), m_queueId.TeamSize, m_queueId.TeamSize, ginfo->ArenaTeamRating); } //add players from group to ginfo - if (grp) + if (group) { - for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next()) + for (GroupReference const* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) @@ -195,12 +183,12 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr //add GroupInfo to m_QueuedGroups { - m_QueuedGroups[bracketId][index].push_back(ginfo); + m_QueuedGroups[index].push_back(ginfo); //announce to world, this code needs mutex if (!isRated && !isPremade && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE)) { - if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId)) + if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BattlegroundTypeId(m_queueId.BattlemasterListId))) { uint32 MinPlayers = bg->GetMinPlayersPerTeam(); uint32 qHorde = 0; @@ -208,10 +196,10 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr uint32 q_min_level = bracketEntry->MinLevel; uint32 q_max_level = bracketEntry->MaxLevel; GroupsQueueType::const_iterator itr; - for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr) + for (itr = m_QueuedGroups[BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr) if (!(*itr)->IsInvitedToBGInstanceGUID) qAlliance += (*itr)->Players.size(); - for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr) + for (itr = m_QueuedGroups[BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[BG_QUEUE_NORMAL_HORDE].end(); ++itr) if (!(*itr)->IsInvitedToBGInstanceGUID) qHorde += (*itr)->Players.size(); @@ -235,11 +223,11 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr return ginfo; } -void BattlegroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BattlegroundBracketId bracket_id) +void BattlegroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo) { uint32 timeInQueue = getMSTimeDiff(ginfo->JoinTime, GameTime::GetGameTimeMS()); uint8 team_index = TEAM_ALLIANCE; //default set to TEAM_ALLIANCE - or non rated arenas! - if (!ginfo->ArenaType) + if (!m_queueId.TeamSize) { if (ginfo->Team == HORDE) team_index = TEAM_HORDE; @@ -251,22 +239,22 @@ void BattlegroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* g } //store pointer to arrayindex of player that was added first - uint32* lastPlayerAddedPointer = &(m_WaitTimeLastPlayer[team_index][bracket_id]); + uint32* lastPlayerAddedPointer = &(m_WaitTimeLastPlayer[team_index]); //remove his time from sum - m_SumOfWaitTimes[team_index][bracket_id] -= m_WaitTimes[team_index][bracket_id][(*lastPlayerAddedPointer)]; + m_SumOfWaitTimes[team_index] -= m_WaitTimes[team_index][(*lastPlayerAddedPointer)]; //set average time to new - m_WaitTimes[team_index][bracket_id][(*lastPlayerAddedPointer)] = timeInQueue; + m_WaitTimes[team_index][(*lastPlayerAddedPointer)] = timeInQueue; //add new time to sum - m_SumOfWaitTimes[team_index][bracket_id] += timeInQueue; + m_SumOfWaitTimes[team_index] += timeInQueue; //set index of last player added to next one (*lastPlayerAddedPointer)++; (*lastPlayerAddedPointer) %= COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; } -uint32 BattlegroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BattlegroundBracketId bracket_id) const +uint32 BattlegroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo) const { uint8 team_index = TEAM_ALLIANCE; //default set to TEAM_ALLIANCE - or non rated arenas! - if (!ginfo->ArenaType) + if (!m_queueId.TeamSize) { if (ginfo->Team == HORDE) team_index = TEAM_HORDE; @@ -277,8 +265,8 @@ uint32 BattlegroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, Battleg team_index = TEAM_HORDE; //for rated arenas use TEAM_HORDE } //check if there is enought values(we always add values > 0) - if (m_WaitTimes[team_index][bracket_id][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME - 1]) - return (m_SumOfWaitTimes[team_index][bracket_id] / COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME); + if (m_WaitTimes[team_index][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME - 1]) + return (m_SumOfWaitTimes[team_index] / COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME); else //if there aren't enough values return 0 - not available return 0; @@ -309,23 +297,20 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) uint32 index = (group->Team == HORDE) ? BG_QUEUE_PREMADE_HORDE : BG_QUEUE_PREMADE_ALLIANCE; - for (int32 bracket_id_tmp = MAX_BATTLEGROUND_BRACKETS - 1; bracket_id_tmp >= 0 && bracket_id == -1; --bracket_id_tmp) + //we must check premade and normal team's queue - because when players from premade are joining bg, + //they leave groupinfo so we can't use its players size to find out index + for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += PVP_TEAMS_COUNT) { - //we must check premade and normal team's queue - because when players from premade are joining bg, - //they leave groupinfo so we can't use its players size to find out index - for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += PVP_TEAMS_COUNT) + GroupsQueueType::iterator k = m_QueuedGroups[j].begin(); + for (; k != m_QueuedGroups[j].end(); ++k) { - GroupsQueueType::iterator k = m_QueuedGroups[bracket_id_tmp][j].begin(); - for (; k != m_QueuedGroups[bracket_id_tmp][j].end(); ++k) + if ((*k) == group) { - if ((*k) == group) - { - bracket_id = bracket_id_tmp; - group_itr = k; - //we must store index to be able to erase iterator - index = j; - break; - } + bracket_id = m_queueId.BracketId; + group_itr = k; + //we must store index to be able to erase iterator + index = j; + break; } } } @@ -350,16 +335,16 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) // if invited to bg, and should decrease invited count, then do it if (decreaseInvitedCount && group->IsInvitedToBGInstanceGUID) - if (Battleground* bg = sBattlegroundMgr->GetBattleground(group->IsInvitedToBGInstanceGUID, group->BgTypeId)) + if (Battleground* bg = sBattlegroundMgr->GetBattleground(group->IsInvitedToBGInstanceGUID, BattlegroundTypeId(m_queueId.BattlemasterListId))) bg->DecreaseInvitedCount(group->Team); // remove player queue info m_QueuedPlayers.erase(itr); // announce to world if arena team left queue for rated match, show only once - if (group->ArenaType && group->IsRated && group->Players.empty() && sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE)) + if (m_queueId.TeamSize && group->IsRated && group->Players.empty() && sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE)) if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(group->ArenaTeamId)) - sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, team->GetName().c_str(), group->ArenaType, group->ArenaType, group->ArenaTeamRating); + sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, team->GetName().c_str(), m_queueId.TeamSize, m_queueId.TeamSize, group->ArenaTeamRating); // if player leaves queue and he is invited to rated arena match, then he have to lose if (group->IsInvitedToBGInstanceGUID && group->IsRated && decreaseInvitedCount) @@ -378,7 +363,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) // remove group queue info if needed if (group->Players.empty()) { - m_QueuedGroups[bracket_id][index].erase(group_itr); + m_QueuedGroups[index].erase(group_itr); delete group; return; } @@ -392,13 +377,12 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) // first send removal information if (Player* plr2 = ObjectAccessor::FindConnectedPlayer(group->Players.begin()->first)) { - Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(group->BgTypeId); - BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(group->BgTypeId, group->ArenaType); - uint32 queueSlot = plr2->GetBattlegroundQueueIndex(bgQueueTypeId); - plr2->RemoveBattlegroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to + uint32 queueSlot = plr2->GetBattlegroundQueueIndex(m_queueId); + + plr2->RemoveBattlegroundQueueId(m_queueId); // must be called this way, because if you move this call to // queue->removeplayer, it causes bugs WorldPacket data; - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, nullptr, queueSlot, STATUS_NONE, 0, 0, 0, 0); plr2->SendDirectMessage(&data); } // then actually delete, this may delete the group as well! @@ -429,7 +413,7 @@ uint32 BattlegroundQueue::GetPlayersInQueue(TeamId id) return m_SelectionPools[id].GetPlayerCount(); } -bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, uint32 side) +bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, Team side) { // set side if needed if (side) @@ -440,9 +424,8 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, // not yet invited // set invitation ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID(); - BattlegroundTypeId bgTypeId = bg->GetTypeID(); - BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType()); - BattlegroundBracketId bracket_id = bg->GetBracketId(); + BattlegroundTypeId bgTypeId = BattlegroundTypeId(m_queueId.BattlemasterListId); + BattlegroundQueueTypeId bgQueueTypeId = m_queueId; // set ArenaTeamId for rated matches if (bg->isArena() && bg->isRated()) @@ -460,7 +443,7 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, continue; // invite the player - PlayerInvitedToBGUpdateAverageWaitTime(ginfo, bracket_id); + PlayerInvitedToBGUpdateAverageWaitTime(ginfo); //sBattlegroundMgr->InvitePlayer(player, bg, ginfo->Team); // set invited player counters @@ -469,10 +452,10 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, player->SetInviteForBattlegroundQueueType(bgQueueTypeId, ginfo->IsInvitedToBGInstanceGUID); // create remind invite events - BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(player->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->ArenaType, ginfo->RemoveInviteTime); + BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(player->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->RemoveInviteTime, bgQueueTypeId); m_events.AddEvent(inviteEvent, m_events.CalculateTime(Milliseconds(INVITATION_REMIND_TIME))); // create automatic remove events - BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(player->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo->RemoveInviteTime); + BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(player->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgQueueTypeId, ginfo->RemoveInviteTime); m_events.AddEvent(removeEvent, m_events.CalculateTime(Milliseconds(INVITE_ACCEPT_WAIT_TIME))); WorldPacket data; @@ -483,7 +466,7 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, player->GetName(), player->GetGUID().ToString(), bg->GetInstanceID(), queueSlot, bg->GetTypeID()); // send status packet - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, m_queueId.TeamSize, 0); player->SendDirectMessage(&data); } return true; @@ -497,12 +480,12 @@ This function is inviting players to already running battlegrounds Invitation type is based on config file large groups are disadvantageous, because they will be kicked first if invitation type = 1 */ -void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId bracket_id) +void BattlegroundQueue::FillPlayersToBG(Battleground* bg) { int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE); int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE); - uint32 aliCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size(); - uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size(); + uint32 aliCount = m_QueuedGroups[BG_QUEUE_NORMAL_ALLIANCE].size(); + uint32 hordeCount = m_QueuedGroups[BG_QUEUE_NORMAL_HORDE].size(); // try to get even teams if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == BG_QUEUE_INVITATION_TYPE_EVEN) @@ -530,7 +513,7 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId } //iterator for iterating through bg queue - GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); + GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[BG_QUEUE_NORMAL_ALLIANCE].begin(); //count of groups in queue - used to stop cycles //index to queue which group is current @@ -538,7 +521,7 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId for (; aliIndex < aliCount && m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); aliIndex++) ++Ali_itr; //the same thing for horde - GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].begin(); + GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[BG_QUEUE_NORMAL_HORDE].begin(); uint32 hordeIndex = 0; for (; hordeIndex < hordeCount && m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++) @@ -602,22 +585,22 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId // this method checks if premade versus premade battleground is possible // then after 30 mins (default) in queue it moves premade group to normal queue // it tries to invite as much players as it can - to MaxPlayersPerTeam, because premade groups have more than MinPlayersPerTeam players -bool BattlegroundQueue::CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam) +bool BattlegroundQueue::CheckPremadeMatch(uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam) { //check match - if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && !m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty()) + if (!m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE].empty() && !m_QueuedGroups[BG_QUEUE_PREMADE_HORDE].empty()) { //start premade match //if groups aren't invited GroupsQueueType::const_iterator ali_group, horde_group; - for (ali_group = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].begin(); ali_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++ali_group) + for (ali_group = m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE].begin(); ali_group != m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE].end(); ++ali_group) if (!(*ali_group)->IsInvitedToBGInstanceGUID) break; - for (horde_group = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].begin(); horde_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end(); ++horde_group) + for (horde_group = m_QueuedGroups[BG_QUEUE_PREMADE_HORDE].begin(); horde_group != m_QueuedGroups[BG_QUEUE_PREMADE_HORDE].end(); ++horde_group) if (!(*horde_group)->IsInvitedToBGInstanceGUID) break; - if (ali_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end()) + if (ali_group != m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[BG_QUEUE_PREMADE_HORDE].end()) { m_SelectionPools[TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam); m_SelectionPools[TEAM_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam); @@ -626,7 +609,7 @@ bool BattlegroundQueue::CheckPremadeMatch(BattlegroundBracketId bracket_id, uint GroupsQueueType::const_iterator itr; for (uint32 i = 0; i < PVP_TEAMS_COUNT; i++) { - for (itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr) + for (itr = m_QueuedGroups[BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr) { //if itr can join BG and player count is less that maxPlayers, then add group to selectionpool if (!(*itr)->IsInvitedToBGInstanceGUID && !m_SelectionPools[i].AddGroup((*itr), maxPlayers)) @@ -644,14 +627,14 @@ bool BattlegroundQueue::CheckPremadeMatch(BattlegroundBracketId bracket_id, uint uint32 time_before = GameTime::GetGameTimeMS() - sWorld->getIntConfig(CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH); for (uint32 i = 0; i < PVP_TEAMS_COUNT; i++) { - if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].empty()) + if (!m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE + i].empty()) { - GroupsQueueType::iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].begin(); + GroupsQueueType::iterator itr = m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE + i].begin(); if (!(*itr)->IsInvitedToBGInstanceGUID && ((*itr)->JoinTime < time_before || (*itr)->Players.size() < MinPlayersPerTeam)) { //we must insert group to normal queue and erase pointer from premade queue - m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].push_front((*itr)); - m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].erase(itr); + m_QueuedGroups[BG_QUEUE_NORMAL_ALLIANCE + i].push_front((*itr)); + m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE + i].erase(itr); } } } @@ -660,13 +643,13 @@ bool BattlegroundQueue::CheckPremadeMatch(BattlegroundBracketId bracket_id, uint } // this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam -bool BattlegroundQueue::CheckNormalMatch(Battleground* bg_template, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers) +bool BattlegroundQueue::CheckNormalMatch(Battleground* bg_template, uint32 minPlayers, uint32 maxPlayers) { GroupsQueueType::const_iterator itr_team[PVP_TEAMS_COUNT]; for (uint32 i = 0; i < PVP_TEAMS_COUNT; i++) { - itr_team[i] = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); - for (; itr_team[i] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++(itr_team[i])) + itr_team[i] = m_QueuedGroups[BG_QUEUE_NORMAL_ALLIANCE + i].begin(); + for (; itr_team[i] != m_QueuedGroups[BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++(itr_team[i])) { if (!(*(itr_team[i]))->IsInvitedToBGInstanceGUID) { @@ -685,7 +668,7 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground* bg_template, Battleground { //we will try to invite more groups to team with less players indexed by j ++(itr_team[j]); //this will not cause a crash, because for cycle above reached break; - for (; itr_team[j] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j])) + for (; itr_team[j] != m_QueuedGroups[BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j])) { if (!(*(itr_team[j]))->IsInvitedToBGInstanceGUID) if (!m_SelectionPools[j].AddGroup(*(itr_team[j]), m_SelectionPools[(j + 1) % PVP_TEAMS_COUNT].GetPlayerCount())) @@ -703,13 +686,13 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground* bg_template, Battleground } // this method will check if we can invite players to same faction skirmish match -bool BattlegroundQueue::CheckSkirmishForSameFaction(BattlegroundBracketId bracket_id, uint32 minPlayersPerTeam) +bool BattlegroundQueue::CheckSkirmishForSameFaction(uint32 minPlayersPerTeam) { if (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() < minPlayersPerTeam && m_SelectionPools[TEAM_HORDE].GetPlayerCount() < minPlayersPerTeam) return false; - uint32 teamIndex = TEAM_ALLIANCE; - uint32 otherTeam = TEAM_HORDE; - uint32 otherTeamId = HORDE; + TeamId teamIndex = TEAM_ALLIANCE; + TeamId otherTeam = TEAM_HORDE; + Team otherTeamId = HORDE; if (m_SelectionPools[TEAM_HORDE].GetPlayerCount() == minPlayersPerTeam) { teamIndex = TEAM_HORDE; @@ -721,16 +704,16 @@ bool BattlegroundQueue::CheckSkirmishForSameFaction(BattlegroundBracketId bracke //store last ginfo pointer GroupQueueInfo* ginfo = m_SelectionPools[teamIndex].SelectedGroups.back(); //set itr_team to group that was added to selection pool latest - GroupsQueueType::iterator itr_team = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].begin(); - for (; itr_team != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team) + GroupsQueueType::iterator itr_team = m_QueuedGroups[uint8(BG_QUEUE_NORMAL_ALLIANCE) + uint8(teamIndex)].begin(); + for (; itr_team != m_QueuedGroups[uint8(BG_QUEUE_NORMAL_ALLIANCE) + uint8(teamIndex)].end(); ++itr_team) if (ginfo == *itr_team) break; - if (itr_team == m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end()) + if (itr_team == m_QueuedGroups[uint8(BG_QUEUE_NORMAL_ALLIANCE) + uint8(teamIndex)].end()) return false; GroupsQueueType::iterator itr_team2 = itr_team; ++itr_team2; //invite players to other selection pool - for (; itr_team2 != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team2) + for (; itr_team2 != m_QueuedGroups[uint8(BG_QUEUE_NORMAL_ALLIANCE) + uint8(teamIndex)].end(); ++itr_team2) { //if selection pool is full then break; if (!(*itr_team2)->IsInvitedToBGInstanceGUID && !m_SelectionPools[otherTeam].AddGroup(*itr_team2, minPlayersPerTeam)) @@ -745,15 +728,15 @@ bool BattlegroundQueue::CheckSkirmishForSameFaction(BattlegroundBracketId bracke //set correct team (*itr)->Team = otherTeamId; //add team to other queue - m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + otherTeam].push_front(*itr); + m_QueuedGroups[uint8(BG_QUEUE_NORMAL_ALLIANCE) + uint8(teamIndex)].push_front(*itr); //remove team from old queue GroupsQueueType::iterator itr2 = itr_team; ++itr2; - for (; itr2 != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr2) + for (; itr2 != m_QueuedGroups[uint8(BG_QUEUE_NORMAL_ALLIANCE) + uint8(teamIndex)].end(); ++itr2) { if (*itr2 == *itr) { - m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].erase(itr2); + m_QueuedGroups[uint8(BG_QUEUE_NORMAL_ALLIANCE) + uint8(teamIndex)].erase(itr2); break; } } @@ -771,13 +754,17 @@ this method is called when group is inserted, or player / group is removed from it must be called after fully adding the members of a group to ensure group joining should be called from Battleground::RemovePlayer function in some cases */ -void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType, bool isRated, uint32 arenaRating) +void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, bool isRated, uint32 arenaRating) { + BattlegroundTypeId bgTypeId = BattlegroundTypeId(m_queueId.BattlemasterListId); + BattlegroundBracketId bracket_id = BattlegroundBracketId(m_queueId.BracketId); + uint8 arenaType = m_queueId.TeamSize; + //if no players in queue - do nothing - if (m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && - m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty() && - m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].empty() && - m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty()) + if (m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE].empty() && + m_QueuedGroups[BG_QUEUE_PREMADE_HORDE].empty() && + m_QueuedGroups[BG_QUEUE_NORMAL_ALLIANCE].empty() && + m_QueuedGroups[BG_QUEUE_NORMAL_HORDE].empty()) return; // battleground with free slot for player should be always in the beggining of the queue @@ -795,7 +782,7 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp m_SelectionPools[TEAM_HORDE].Init(); // call a function that does the job for us - FillPlayersToBG(bg, bracket_id); + FillPlayersToBG(bg); // now everything is set, invite players for (GroupsQueueType::const_iterator citr = m_SelectionPools[TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[TEAM_ALLIANCE].SelectedGroups.end(); ++citr) @@ -842,7 +829,7 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp if (bg_template->isBattleground()) { - if (CheckPremadeMatch(bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam)) + if (CheckPremadeMatch(MinPlayersPerTeam, MaxPlayersPerTeam)) { // create new battleground Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, 0, false); @@ -867,8 +854,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp if (!isRated) { // if there are enough players in pools, start new battleground or non rated arena - if (CheckNormalMatch(bg_template, bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam) - || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam))) + if (CheckNormalMatch(bg_template, MinPlayersPerTeam, MaxPlayersPerTeam) + || (bg_template->isArena() && CheckSkirmishForSameFaction(MinPlayersPerTeam))) { // we successfully created a pool Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, false); @@ -895,14 +882,14 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp { GroupQueueInfo* front1 = nullptr; GroupQueueInfo* front2 = nullptr; - if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty()) + if (!m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE].empty()) { - front1 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].front(); + front1 = m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE].front(); arenaRating = front1->ArenaMatchmakerRating; } - if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty()) + if (!m_QueuedGroups[BG_QUEUE_PREMADE_HORDE].empty()) { - front2 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].front(); + front2 = m_QueuedGroups[BG_QUEUE_PREMADE_HORDE].front(); arenaRating = front2->ArenaMatchmakerRating; } if (front1 && front2) @@ -935,8 +922,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp for (uint8 i = BG_QUEUE_PREMADE_ALLIANCE; i < BG_QUEUE_NORMAL_ALLIANCE; i++) { // take the group that joined first - GroupsQueueType::iterator itr2 = m_QueuedGroups[bracket_id][i].begin(); - for (; itr2 != m_QueuedGroups[bracket_id][i].end(); ++itr2) + GroupsQueueType::iterator itr2 = m_QueuedGroups[i].begin(); + for (; itr2 != m_QueuedGroups[i].end(); ++itr2) { // if group match conditions, then add it to pool if (!(*itr2)->IsInvitedToBGInstanceGUID @@ -955,7 +942,7 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp if (found == 1) { - for (GroupsQueueType::iterator itr3 = itr_teams[0]; itr3 != m_QueuedGroups[bracket_id][team].end(); ++itr3) + for (GroupsQueueType::iterator itr3 = itr_teams[0]; itr3 != m_QueuedGroups[team].end(); ++itr3) { if (!(*itr3)->IsInvitedToBGInstanceGUID && (((*itr3)->ArenaMatchmakerRating >= arenaMinRating && (*itr3)->ArenaMatchmakerRating <= arenaMaxRating) || (int32)(*itr3)->JoinTime < discardTime) @@ -990,13 +977,13 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp // now we must move team if we changed its faction to another faction queue, because then we will spam log by errors in Queue::RemovePlayer if (aTeam->Team != ALLIANCE) { - m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].push_front(aTeam); - m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].erase(itr_teams[TEAM_ALLIANCE]); + m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE].push_front(aTeam); + m_QueuedGroups[BG_QUEUE_PREMADE_HORDE].erase(itr_teams[TEAM_ALLIANCE]); } if (hTeam->Team != HORDE) { - m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].push_front(hTeam); - m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].erase(itr_teams[TEAM_HORDE]); + m_QueuedGroups[BG_QUEUE_PREMADE_HORDE].push_front(hTeam); + m_QueuedGroups[BG_QUEUE_PREMADE_ALLIANCE].erase(itr_teams[TEAM_HORDE]); } arena->SetArenaMatchmakerRating(ALLIANCE, aTeam->ArenaMatchmakerRating); @@ -1026,17 +1013,16 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) if (!bg) return true; - BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); - uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); + uint32 queueSlot = player->GetBattlegroundQueueIndex(m_QueueId); if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue or in battleground { // check if player is invited to this bg - BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); + BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(m_QueueId); if (bgQueue.IsPlayerInvited(m_PlayerGuid, m_BgInstanceGUID, m_RemoveTime)) { WorldPacket data; //we must send remaining time in queue - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, m_ArenaType, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, m_QueueId.TeamSize, 0); player->SendDirectMessage(&data); } } @@ -1064,7 +1050,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) // player logged off (we should do nothing, he is correctly removed from queue in another procedure) return true; - Battleground* bg = sBattlegroundMgr->GetBattleground(m_BgInstanceGUID, m_BgTypeId); + Battleground* bg = sBattlegroundMgr->GetBattleground(m_BgInstanceGUID, BattlegroundTypeId(m_BgQueueTypeId.BattlemasterListId)); //battleground can be deleted already when we are removing queue info //bg pointer can be NULL! so use it carefully! @@ -1091,7 +1077,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) bgQueue.RemovePlayer(m_PlayerGuid, true); //update queues if battleground isn't ended if (bg && bg->isBattleground() && bg->GetStatus() != STATUS_WAIT_LEAVE) - sBattlegroundMgr->ScheduleQueueUpdate(0, 0, m_BgQueueTypeId, m_BgTypeId, bg->GetBracketId()); + sBattlegroundMgr->ScheduleQueueUpdate(0, m_BgQueueTypeId); WorldPacket data; sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, 0); diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h index b7cad6f5d44..7dfa68a4309 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.h +++ b/src/server/game/Battlegrounds/BattlegroundQueue.h @@ -23,8 +23,6 @@ #include "Battleground.h" #include "EventProcessor.h" -#include <deque> - //this container can't be deque, because deque doesn't like removing the last element - if you remove it, it invalidates next iterator and crash appears typedef std::list<Battleground*> BGFreeSlotQueueContainer; @@ -40,10 +38,8 @@ struct PlayerQueueInfo // stores informatio struct GroupQueueInfo // stores information about the group in queue (also used when joined as solo!) { std::map<ObjectGuid, PlayerQueueInfo*> Players; // player queue info map - uint32 Team; // Player team (ALLIANCE/HORDE) - BattlegroundTypeId BgTypeId; // battleground type id + ::Team Team; // Player team (ALLIANCE/HORDE) bool IsRated; // rated - uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG uint32 ArenaTeamId; // team id if rated match uint32 JoinTime; // time when group was added uint32 RemoveInviteTime; // time when we will remove invite for players in group @@ -75,22 +71,22 @@ class Battleground; class TC_GAME_API BattlegroundQueue { public: - BattlegroundQueue(); + BattlegroundQueue(BattlegroundQueueTypeId queueId); ~BattlegroundQueue(); - void BattlegroundQueueUpdate(uint32 diff, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0); + void BattlegroundQueueUpdate(uint32 diff, bool isRated = false, uint32 minRating = 0); void UpdateEvents(uint32 diff); - void FillPlayersToBG(Battleground* bg, BattlegroundBracketId bracket_id); - bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam); - bool CheckNormalMatch(Battleground* bg_template, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers); - bool CheckSkirmishForSameFaction(BattlegroundBracketId bracket_id, uint32 minPlayersPerTeam); - GroupQueueInfo* AddGroup(Player* leader, Group* group, BattlegroundTypeId bgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating, uint32 ArenaTeamId = 0, uint32 OpponentsArenaTeamId = 0); + void FillPlayersToBG(Battleground* bg); + bool CheckPremadeMatch(uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam); + bool CheckNormalMatch(Battleground* bg_template, uint32 minPlayers, uint32 maxPlayers); + bool CheckSkirmishForSameFaction(uint32 minPlayersPerTeam); + GroupQueueInfo* AddGroup(Player* leader, Group const* group, PvPDifficultyEntry const* bracketEntry, bool isRated, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating, uint32 ArenaTeamId = 0, uint32 OpponentsArenaTeamId = 0); void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount); bool IsPlayerInvited(ObjectGuid pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime); bool GetPlayerGroupInfoData(ObjectGuid guid, GroupQueueInfo* ginfo); - void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BattlegroundBracketId bracket_id); - uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BattlegroundBracketId bracket_id) const; + void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo); + uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo) const; typedef std::map<ObjectGuid, PlayerQueueInfo> QueuedPlayersMap; QueuedPlayersMap m_QueuedPlayers; @@ -107,7 +103,7 @@ class TC_GAME_API BattlegroundQueue BG_QUEUE_NORMAL_ALLIANCE is used for normal (or small) alliance groups or non-rated arena matches BG_QUEUE_NORMAL_HORDE is used for normal (or small) horde groups or non-rated arena matches */ - GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_BRACKETS][BG_QUEUE_GROUP_TYPES_COUNT]; + GroupsQueueType m_QueuedGroups[BG_QUEUE_GROUP_TYPES_COUNT]; // class to select and invite groups to bg class SelectionPool @@ -127,12 +123,16 @@ class TC_GAME_API BattlegroundQueue //one selection pool for horde, other one for alliance SelectionPool m_SelectionPools[PVP_TEAMS_COUNT]; uint32 GetPlayersInQueue(TeamId id); + + BattlegroundQueueTypeId GetQueueId() const { return m_queueId; } private: - bool InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, uint32 side); - uint32 m_WaitTimes[PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME]; - uint32 m_WaitTimeLastPlayer[PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS]; - uint32 m_SumOfWaitTimes[PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS]; + BattlegroundQueueTypeId m_queueId; + + bool InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, Team side); + uint32 m_WaitTimes[PVP_TEAMS_COUNT][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME]; + uint32 m_WaitTimeLastPlayer[PVP_TEAMS_COUNT]; + uint32 m_SumOfWaitTimes[PVP_TEAMS_COUNT]; // Event handler EventProcessor m_events; @@ -145,8 +145,8 @@ class TC_GAME_API BattlegroundQueue class TC_GAME_API BGQueueInviteEvent : public BasicEvent { public: - BGQueueInviteEvent(ObjectGuid pl_guid, uint32 BgInstanceGUID, BattlegroundTypeId BgTypeId, uint8 arenaType, uint32 removeTime) : - m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId), m_ArenaType(arenaType), m_RemoveTime(removeTime) + BGQueueInviteEvent(ObjectGuid pl_guid, uint32 BgInstanceGUID, BattlegroundTypeId BgTypeId, uint32 removeTime, BattlegroundQueueTypeId queueId) : + m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId), m_RemoveTime(removeTime), m_QueueId(queueId) { } virtual ~BGQueueInviteEvent() { } @@ -156,8 +156,8 @@ class TC_GAME_API BGQueueInviteEvent : public BasicEvent ObjectGuid m_PlayerGuid; uint32 m_BgInstanceGUID; BattlegroundTypeId m_BgTypeId; - uint8 m_ArenaType; uint32 m_RemoveTime; + BattlegroundQueueTypeId m_QueueId; }; /* @@ -168,8 +168,8 @@ class TC_GAME_API BGQueueInviteEvent : public BasicEvent class TC_GAME_API BGQueueRemoveEvent : public BasicEvent { public: - BGQueueRemoveEvent(ObjectGuid pl_guid, uint32 bgInstanceGUID, BattlegroundTypeId BgTypeId, BattlegroundQueueTypeId bgQueueTypeId, uint32 removeTime) - : m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_RemoveTime(removeTime), m_BgTypeId(BgTypeId), m_BgQueueTypeId(bgQueueTypeId) + BGQueueRemoveEvent(ObjectGuid pl_guid, uint32 bgInstanceGUID, BattlegroundQueueTypeId bgQueueTypeId, uint32 removeTime) + : m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_RemoveTime(removeTime), m_BgQueueTypeId(bgQueueTypeId) { } virtual ~BGQueueRemoveEvent() { } @@ -180,7 +180,6 @@ class TC_GAME_API BGQueueRemoveEvent : public BasicEvent ObjectGuid m_PlayerGuid; uint32 m_BgInstanceGUID; uint32 m_RemoveTime; - BattlegroundTypeId m_BgTypeId; BattlegroundQueueTypeId m_BgQueueTypeId; }; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 18bb4c05abf..7892f4e0ae5 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -17257,7 +17257,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol { map = currentBg->GetBgMap(); - BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(currentBg->GetTypeID(), currentBg->GetArenaType()); + BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(currentBg->GetTypeID(), currentBg->GetBracketId(), currentBg->GetArenaType()); AddBattlegroundQueueId(bgQueueTypeId); m_bgData.bgTypeID = currentBg->GetTypeID(); @@ -23225,10 +23225,8 @@ Battleground* Player::GetBattleground() const bool Player::InBattlegroundQueue(bool ignoreArena) const { for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) - if (m_bgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_NONE && (!ignoreArena || - (m_bgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_2v2 && - m_bgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_3v3 && - m_bgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_5v5))) + if (m_bgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_NONE + && (!ignoreArena || m_bgBattlegroundQueueID[i].bgQueueTypeId.BattlemasterListId != BATTLEGROUND_AA)) return true; return false; } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index e3b870cba51..135fee4c58d 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -2042,8 +2042,6 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot); uint32 team = reference->GetTeam(); - BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0); - // check every member of the group to be able to join memberscount = 0; for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next(), ++memberscount) @@ -2069,7 +2067,8 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId)) return ERR_BATTLEGROUND_JOIN_FAILED; // not blizz-like // don't let join if someone from the group is in bg queue random - if (bgOrTemplate->GetTypeID() != BATTLEGROUND_AA && member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) + bool isInRandomBgQueue = member->InBattlegroundQueueForBattlegroundQueueType(BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, memberBracketEntry->GetBracketId(), 0)); + if (bgOrTemplate->GetTypeID() != BATTLEGROUND_AA && isInRandomBgQueue) return ERR_IN_RANDOM_BG; // don't let join to bg queue random if someone from the group is already in bg queue if (bgOrTemplate->GetTypeID() == BATTLEGROUND_RB && member->InBattlegroundQueue(true)) diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp index 58d7b4c692d..077a8e18805 100644 --- a/src/server/game/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Handlers/ArenaTeamHandler.cpp @@ -234,8 +234,12 @@ void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket& recvData) } // Player cannot be removed during queues - if (BattlegroundQueueTypeId bgQueue = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_AA, arenaTeam->GetType())) + for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { + BattlegroundQueueTypeId bgQueue = _player->GetBattlegroundQueueTypeId(i); + if (bgQueue.BattlemasterListId != BATTLEGROUND_AA || bgQueue.TeamSize != arenaTeam->GetType()) + continue; + GroupQueueInfo ginfo; BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue); if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo)) @@ -277,8 +281,12 @@ void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket& recvData) return; // Teams cannot be disbanded during queues - if (BattlegroundQueueTypeId bgQueue = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_AA, arenaTeam->GetType())) + for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { + BattlegroundQueueTypeId bgQueue = _player->GetBattlegroundQueueTypeId(i); + if (bgQueue.BattlemasterListId != BATTLEGROUND_AA || bgQueue.TeamSize != arenaTeam->GetType()) + continue; + GroupQueueInfo ginfo; BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue); if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo)) @@ -336,8 +344,12 @@ void WorldSession::HandleArenaTeamRemoveOpcode(WorldPacket& recvData) } // Team cannot be removed during queues - if (BattlegroundQueueTypeId bgQueue = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_AA, arenaTeam->GetType())) + for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { + BattlegroundQueueTypeId bgQueue = _player->GetBattlegroundQueueTypeId(i); + if (bgQueue.BattlemasterListId != BATTLEGROUND_AA || bgQueue.TeamSize != arenaTeam->GetType()) + continue; + GroupQueueInfo ginfo; BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue); if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo)) diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index 3facbdaa57d..658c42ef0a5 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -102,10 +102,6 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from {}", guid.ToString()); - // can do this, since it's battleground, not arena - BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0); - BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0); - // ignore if player is already in BG if (_player->InBattleground()) return; @@ -125,6 +121,10 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) if (!bracketEntry) return; + // can do this, since it's battleground, not arena + BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, bracketEntry->GetBracketId(), 0); + BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, bracketEntry->GetBracketId(), 0); + GroupJoinBattlegroundResult err; // check queue conditions @@ -195,17 +195,18 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); - GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); + GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bracketEntry, false, isPremade, 0, 0); + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo); // already checked if queueSlot is valid, now just get it uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); WorldPacket data; // send status packet (in queue) - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, 0, 0); SendPacket(&data); - TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type {} bg type {}: GUID {}, NAME {}", - bgQueueTypeId, bgTypeId, _player->GetGUID().ToString(), _player->GetName()); + TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}, {}, NAME {}", + bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize), + _player->GetGUID().ToString(), _player->GetName()); } else { @@ -225,8 +226,8 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) if (err > 0) { TC_LOG_DEBUG("bg.battleground", "Battleground: the following players are joining as group:"); - ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); - avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); + ginfo = bgQueue.AddGroup(_player, grp, bracketEntry, false, isPremade, 0, 0); + avgTime = bgQueue.GetAverageQueueWaitTime(ginfo); } for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next()) @@ -248,16 +249,17 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); // send status packet (in queue) - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, 0, 0); member->SendDirectMessage(&data); sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->SendDirectMessage(&data); - TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type {} bg type {}: GUID {}, NAME {}", - bgQueueTypeId, bgTypeId, member->GetGUID().ToString(), member->GetName()); + TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}, {}, NAME {}", + bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize), + member->GetGUID().ToString(), member->GetName()); } TC_LOG_DEBUG("bg.battleground", "Battleground: group end"); } - sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); + sBattlegroundMgr->ScheduleQueueUpdate(0, bgQueueTypeId); } void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvData*/) @@ -357,13 +359,15 @@ void WorldSession::HandleBattlefieldListOpcode(WorldPacket &recvData) void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) { - uint8 type; // arenatype if arena - uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1 - uint32 bgTypeId_; // type id from dbc - uint16 unk; // 0x1F90 constant? + uint64 packedQueueId; uint8 action; // enter battle 0x1, leave queue 0x0 - recvData >> type >> unk2 >> bgTypeId_ >> unk >> action; + recvData >> packedQueueId >> action; + + BattlegroundQueueTypeId bgQueueTypeId = BattlegroundQueueTypeId::FromPacked(packedQueueId); + uint8 type = bgQueueTypeId.TeamSize; + uint8 unk2 = bgQueueTypeId.BracketId; + uint32 bgTypeId_ = bgQueueTypeId.BattlemasterListId; if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Invalid BgType!", @@ -371,7 +375,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) return; } - if (!_player->InBattlegroundQueue()) + if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) == PLAYER_MAX_BATTLEGROUND_QUEUES) { TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue!", GetPlayerInfo(), type, unk2, bgTypeId_, action); @@ -379,9 +383,8 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) } //get GroupQueueInfo from BattlegroundQueue - BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_); - BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, type); BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); + //we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattlegroundQueue::RemovePlayer() function GroupQueueInfo ginfo; if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo)) @@ -398,6 +401,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) return; } + BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_); Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId); if (!bg) { @@ -425,7 +429,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) return; //some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it - if (action == 1 && ginfo.ArenaType == 0) + if (action == 1 && bgQueue.GetQueueId().TeamSize == 0) { //if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue if (_player->IsDeserter()) @@ -487,7 +491,9 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId); // add only in HandleMoveWorldPortAck() // bg->AddPlayer(_player, team); - TC_LOG_DEBUG("bg.battleground", "Battleground: player {} {} joined battle for bg {}, bgtype {}, queue type {}.", _player->GetName(), _player->GetGUID().ToString(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId); + TC_LOG_DEBUG("bg.battleground", "Battleground: player {} ({}) joined battle for bg {}, bgtype {}, queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}.", + _player->GetName(), _player->GetGUID().ToString(), bg->GetInstanceID(), bg->GetTypeID(), + bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize)); } else // leave queue { @@ -509,10 +515,12 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, 0); bgQueue.RemovePlayer(_player->GetGUID(), true); // player left queue, we should update it - do not update Arena Queue - if (!ginfo.ArenaType) - sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); + if (!bgQueue.GetQueueId().TeamSize) + sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, bgQueueTypeId); SendPacket(&data); - TC_LOG_DEBUG("bg.battleground", "Battleground: player {} {} left queue for bgtype {}, queue type {}.", _player->GetName(), _player->GetGUID().ToString(), bg->GetTypeID(), bgQueueTypeId); + TC_LOG_DEBUG("bg.battleground", "Battleground: player {} ({}) left queue for bgtype {}, queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}.", + _player->GetName(), _player->GetGUID().ToString(), bg->GetTypeID(), + bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize)); // track if player refuses to join the BG after being invited if (bg->isBattleground() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_TRACK_DESERTERS) && @@ -555,24 +563,24 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i); - if (!bgQueueTypeId) + if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE) continue; - BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId); - uint8 arenaType = BattlegroundMgr::BGArenaType(bgQueueTypeId); - if (bgTypeId == _player->GetBattlegroundTypeId()) + BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgQueueTypeId.BattlemasterListId); + bg = _player->GetBattleground(); + uint8 arenaType = bgQueueTypeId.TeamSize; + if (bg) { - bg = _player->GetBattleground(); - //i cannot check any variable from player class because player class doesn't know if player is in 2v2 / 3v3 or 5v5 arena - //so i must use bg pointer to get that information - if (bg && bg->GetArenaType() == arenaType) + BattlegroundPlayer const* bgPlayer = bg->GetBattlegroundPlayerData(_player->GetGUID()); + if (bgPlayer) { - // this line is checked, i only don't know if GetStartTime is changing itself after bg end! - // send status in Battleground + //i cannot check any variable from player class because player class doesn't know if player is in 2v2 / 3v3 or 5v5 arena + //so i must use bg pointer to get that information sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam()); SendPacket(&data); continue; } } + //we are sending update to player about queue - he can be invited there! //get GroupQueueInfo for queue status BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); @@ -600,7 +608,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) if (!bracketEntry) continue; - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, bracketEntry->GetBracketId()); + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo); // send status in Battleground Queue sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, GameTime::GetGameTimeMS()), arenaType, 0); SendPacket(&data); @@ -632,27 +640,11 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) if (!unit) return; - uint8 arenatype = 0; + uint8 arenatype = ArenaTeam::GetTypeBySlot(arenaslot); uint32 arenaRating = 0; uint32 matchmakerRating = 0; uint32 previousOpponents = 0; - switch (arenaslot) - { - case 0: - arenatype = ARENA_TYPE_2v2; - break; - case 1: - arenatype = ARENA_TYPE_3v3; - break; - case 2: - arenatype = ARENA_TYPE_5v5; - break; - default: - TC_LOG_ERROR("network", "Unknown arena slot {} at HandleBattlemasterJoinArena()", arenaslot); - return; - } - //check existance Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA); if (!bg) @@ -667,12 +659,12 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) return; } - BattlegroundTypeId bgTypeId = bg->GetTypeID(); - BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype); PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->GetLevel()); if (!bracketEntry) return; + BattlegroundTypeId bgTypeId = bg->GetTypeID(); + BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, bracketEntry->GetBracketId(), arenatype); GroupJoinBattlegroundResult err = ERR_GROUP_JOIN_BATTLEGROUND_FAIL; if (!asGroup) @@ -752,8 +744,8 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) else bg->SetRated(false); - GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents); - avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); + GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bracketEntry, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents); + avgTime = bgQueue.GetAverageQueueWaitTime(ginfo); } for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next()) @@ -779,22 +771,26 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) member->SendDirectMessage(&data); sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->SendDirectMessage(&data); - TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type {} bg type {}: {}, NAME {}", bgQueueTypeId, bgTypeId, member->GetGUID().ToString(), member->GetName()); + TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}, {}, NAME {}", + bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize), + member->GetGUID().ToString(), member->GetName()); } } else { - GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); + GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bracketEntry, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents); + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo); uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); WorldPacket data; // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, 0); SendPacket(&data); - TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena, skirmish, bg queue type {} bg type {}: {}, NAME {}", bgQueueTypeId, bgTypeId, _player->GetGUID().ToString(), _player->GetName()); + TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena, skirmish, bg queue type {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}: {}, NAME {}", + bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize), + _player->GetGUID().ToString(), _player->GetName()); } - sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); + sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, bgQueueTypeId); } void WorldSession::HandleReportPvPAFK(WorldPacket& recvData) diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 15cb8e3830d..52ac6f7452d 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -531,7 +531,8 @@ void WorldSession::LogoutPlayer(bool save) for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { - if (BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i)) + BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i); + if (bgQueueTypeId != BATTLEGROUND_QUEUE_NONE) { // track if player logs out after invited to join BG if (_player->IsInvitedForBattlegroundQueueType(bgQueueTypeId) && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_TRACK_DESERTERS)) diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index e2f6fc37774..f6f2e4e7045 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -3670,23 +3670,32 @@ enum DuelCompleteType : uint8 DUEL_FLED = 2 }; -// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time -enum BattlegroundQueueTypeId -{ - BATTLEGROUND_QUEUE_NONE = 0, - BATTLEGROUND_QUEUE_AV = 1, - BATTLEGROUND_QUEUE_WS = 2, - BATTLEGROUND_QUEUE_AB = 3, - BATTLEGROUND_QUEUE_EY = 4, - BATTLEGROUND_QUEUE_SA = 5, - BATTLEGROUND_QUEUE_IC = 6, - BATTLEGROUND_QUEUE_RB = 7, - BATTLEGROUND_QUEUE_2v2 = 8, - BATTLEGROUND_QUEUE_3v3 = 9, - BATTLEGROUND_QUEUE_5v5 = 10, - MAX_BATTLEGROUND_QUEUE_TYPES +struct BattlegroundQueueTypeId +{ + uint16 BattlemasterListId; + uint8 BracketId; + uint8 TeamSize; + + static constexpr BattlegroundQueueTypeId FromPacked(uint64 packedQueueId) + { + return { .BattlemasterListId = uint16((packedQueueId >> 16) & 0xFFFF), .BracketId = uint8((packedQueueId >> 8) & 0x7F), .TeamSize = uint8(packedQueueId & 0x7F) }; + } + + constexpr uint64 GetPacked() const + { + return (uint64(BattlemasterListId) << 16) + | (uint64(BracketId & 0xFF) << 8) + | (uint64(TeamSize & 0x3F)) + | UI64LIT(0x1F90000000000000); + } + + constexpr bool operator==(BattlegroundQueueTypeId const& right) const = default; + + constexpr std::strong_ordering operator<=>(BattlegroundQueueTypeId const& right) const = default; }; +constexpr BattlegroundQueueTypeId BATTLEGROUND_QUEUE_NONE = { 0, 0, 0 }; + enum GroupJoinBattlegroundResult { // positive values are indexes in BattlemasterList.dbc |