diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 8608eca18..3f98b1ab9 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -396,7 +396,7 @@ class Battleground void SetMaxPlayersPerTeam(uint32 MaxPlayers) { m_MaxPlayersPerTeam = MaxPlayers; } void SetMinPlayersPerTeam(uint32 MinPlayers) { m_MinPlayersPerTeam = MinPlayers; } - void DecreaseInvitedCount(TeamId teamId) { ASSERT(m_BgInvitedPlayers[teamId] > 0); --m_BgInvitedPlayers[teamId]; } + void DecreaseInvitedCount(TeamId teamId) { if (m_BgInvitedPlayers[teamId]) --m_BgInvitedPlayers[teamId]; } void IncreaseInvitedCount(TeamId teamId) { ++m_BgInvitedPlayers[teamId]; } uint32 GetInvitedCount(TeamId teamId) const { return m_BgInvitedPlayers[teamId]; } diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index 42478156d..c1b9d82f4 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -923,7 +923,8 @@ void BattlegroundMgr::RemoveBattleground(BattlegroundTypeId bgTypeId, uint32 ins void BattlegroundMgr::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, TeamId teamId) { - ASSERT(!ginfo->IsInvitedToBGInstanceGUID); + if (ginfo->IsInvitedToBGInstanceGUID) + return; // set side if needed if (teamId != TEAM_NEUTRAL) @@ -942,13 +943,12 @@ void BattlegroundMgr::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, T ginfo->RemoveInviteTime = World::GetGameTimeMS() + INVITE_ACCEPT_WAIT_TIME; // loop through the players - for (std::set::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr) + for (auto itr : ginfo->Players) { // get the player - Player* player = ObjectAccessor::FindPlayerInOrOutOfWorld(*itr); - - // player is removed from queue when logging out - ASSERT(player); + Player* player = ObjectAccessor::FindPlayerInOrOutOfWorld(itr); + if (!player) + continue; // update average wait time bgQueue.PlayerInvitedToBGUpdateAverageWaitTime(ginfo); @@ -963,12 +963,12 @@ void BattlegroundMgr::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, T BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(player->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgQueueTypeId, ginfo->RemoveInviteTime); bgQueue.AddEvent(removeEvent, INVITE_ACCEPT_WAIT_TIME); - WorldPacket data; - + // Check queueSlot uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); ASSERT(queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES); // send status packet + WorldPacket data; sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType, TEAM_NEUTRAL, bg->isRated(), ginfo->BgTypeId); player->GetSession()->SendPacket(&data); diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index c5f52e8cf..64e58878e 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -49,7 +49,7 @@ BattlegroundQueue::~BattlegroundQueue() m_QueuedPlayers.clear(); for (int i = 0; i < MAX_BATTLEGROUND_BRACKETS; ++i) { - for (uint32 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; ++j) + for (uint32 j = 0; j < BG_QUEUE_MAX; ++j) { for (GroupsQueueType::iterator itr = m_QueuedGroups[i][j].begin(); itr != m_QueuedGroups[i][j].end(); ++itr) delete (*itr); @@ -126,26 +126,29 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player * leader, Group * grp, PvPDif BattlegroundBracketId bracketId = bracketEntry->GetBracketId(); // create new ginfo - GroupQueueInfo* ginfo = new GroupQueueInfo; - ginfo->BgTypeId = m_bgTypeId; - ginfo->ArenaType = m_arenaType; - ginfo->ArenaTeamId = arenateamid; - ginfo->IsRated = isRated; - ginfo->IsInvitedToBGInstanceGUID = 0; - ginfo->JoinTime = World::GetGameTimeMS(); - ginfo->RemoveInviteTime = 0; - ginfo->teamId = leader->GetTeamId(); - ginfo->ArenaTeamRating = ArenaRating; - ginfo->ArenaMatchmakerRating = MatchmakerRating; - ginfo->OpponentsTeamRating = 0; - ginfo->OpponentsMatchmakerRating = 0; + GroupQueueInfo* ginfo = new GroupQueueInfo; + ginfo->BgTypeId = m_bgTypeId; + ginfo->ArenaType = m_arenaType; + ginfo->ArenaTeamId = arenateamid; + ginfo->IsRated = isRated; + ginfo->IsInvitedToBGInstanceGUID = 0; + ginfo->JoinTime = World::GetGameTimeMS(); + ginfo->RemoveInviteTime = 0; + ginfo->teamId = leader->GetTeamId(); + ginfo->RealTeamID = leader->GetTeamId(true); + ginfo->ArenaTeamRating = ArenaRating; + ginfo->ArenaMatchmakerRating = MatchmakerRating; + ginfo->OpponentsTeamRating = 0; + ginfo->OpponentsMatchmakerRating = 0; ginfo->Players.clear(); //compute index (if group is premade or joined a rated match) to queues uint32 index = 0; + if (!isRated && !isPremade) index += BG_TEAMS_COUNT; + if (ginfo->teamId == TEAM_HORDE) index++; @@ -155,11 +158,8 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player * leader, Group * grp, PvPDif // announce world (this doesn't need mutex) if (isRated && sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE)) - { - ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(arenateamid); - if (team) + if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(arenateamid)) sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, team->GetName().c_str(), ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating); - } //add players from group to ginfo if (grp) @@ -194,15 +194,8 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player * leader, Group * grp, PvPDif uint32 MaxPlayers = MinPlayers * 2; uint32 q_min_level = std::min(bracketEntry->minLevel, (uint32)80); uint32 q_max_level = std::min(bracketEntry->maxLevel, (uint32)80); - uint32 qHorde = 0; - uint32 qAlliance = 0; - GroupsQueueType::const_iterator itr; - for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][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) - if (!(*itr)->IsInvitedToBGInstanceGUID) - qHorde += (*itr)->Players.size(); + uint32 qHorde = GetPlayersCountInGroupsQueue(bracketId, BG_QUEUE_NORMAL_HORDE); + uint32 qAlliance = GetPlayersCountInGroupsQueue(bracketId, BG_QUEUE_NORMAL_ALLIANCE); // Show queue status to player only (when joining battleground queue or Arena and arena world announcer is disabled) if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY) || (bgt->isArena() && !sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE))) @@ -210,8 +203,7 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player * leader, Group * grp, PvPDif ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); } - // Show queue status to server (when joining battleground queue) - else if (!bgt->isArena()) + else if (!bgt->isArena()) // Show queue status to server (when joining battleground queue) { if (BGSpamProtection[leader->GetGUID()].last_queue == 0) { @@ -226,7 +218,6 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player * leader, Group * grp, PvPDif qAlliance + qHorde, MaxPlayers); } } - } return ginfo; @@ -407,8 +398,10 @@ bool BattlegroundQueue::GetPlayerGroupInfoData(uint64 guid, GroupQueueInfo * gin } // this function is filling pools given free slots on both sides, result is ballanced -void BattlegroundQueue::FillPlayersToBG(const int32 aliFree, const int32 hordeFree, BattlegroundBracketId bracket_id) +void BattlegroundQueue::FillPlayersToBG(Battleground* bg, const int32 aliFree, const int32 hordeFree, BattlegroundBracketId bracket_id) { + UNUSED(bg); + // clear selection pools m_SelectionPools[TEAM_ALLIANCE].Init(); m_SelectionPools[TEAM_HORDE].Init(); @@ -463,8 +456,10 @@ void BattlegroundQueue::FillPlayersToBG(const int32 aliFree, const int32 hordeFr } } -void BattlegroundQueue::FillPlayersToBGWithSpecific(const int32 aliFree, const int32 hordeFree, BattlegroundBracketId thisBracketId, BattlegroundQueue * specificQueue, BattlegroundBracketId specificBracketId) +void BattlegroundQueue::FillPlayersToBGWithSpecific(Battleground* bg, const int32 aliFree, const int32 hordeFree, BattlegroundBracketId thisBracketId, BattlegroundQueue * specificQueue, BattlegroundBracketId specificBracketId) { + UNUSED(bg); + // clear selection pools m_SelectionPools[TEAM_ALLIANCE].Init(); m_SelectionPools[TEAM_HORDE].Init(); @@ -600,7 +595,7 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground * bgTemplate, Battleground // specific queue BattlegroundQueue & specificQueue = sBattlegroundMgr->GetBattlegroundQueue(BattlegroundMgr::BGQueueTypeId(sBattlegroundMgr->RandomSystem.GetCurrentRandomBg(), 0)); - FillPlayersToBGWithSpecific(specificTemplate->GetMaxPlayersPerTeam(), specificTemplate->GetMaxPlayersPerTeam(), bracket_id, &specificQueue, BattlegroundBracketId(specificBracket->bracketId)); + FillPlayersToBGWithSpecific(specificTemplate, specificTemplate->GetMaxPlayersPerTeam(), specificTemplate->GetMaxPlayersPerTeam(), bracket_id, &specificQueue, BattlegroundBracketId(specificBracket->bracketId)); //allow 1v0 if debug bg if (sBattlegroundMgr->isTesting() && bgTemplate->isBattleground() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount())) @@ -611,7 +606,7 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground * bgTemplate, Battleground // if this is not random bg queue - use players only from this queue else { - FillPlayersToBG(maxPlayers, maxPlayers, bracket_id); + FillPlayersToBG(bgTemplate, maxPlayers, maxPlayers, bracket_id); //allow 1v0 if debug bg if (sBattlegroundMgr->isTesting() && bgTemplate->isBattleground() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount())) @@ -682,10 +677,7 @@ typedef std::set BattlegroundNeedSet; void BattlegroundQueue::BattlegroundQueueUpdate(BattlegroundBracketId bracket_id, uint8 actionMask, bool isRated, uint32 arenaRatedTeamId) { // 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 (IsAllQueuesEmpty(bracket_id)) return; Battleground* bg_template = sBattlegroundMgr->GetBattlegroundTemplate(m_bgTypeId); @@ -717,12 +709,12 @@ void BattlegroundQueue::BattlegroundQueueUpdate(BattlegroundBracketId bracket_id Battleground* bg = *itr; // call a function that fills whatever we can from normal queues - FillPlayersToBG(bg->GetFreeSlotsForTeam(TEAM_ALLIANCE), bg->GetFreeSlotsForTeam(TEAM_HORDE), bracket_id); + FillPlayersToBG(bg, bg->GetFreeSlotsForTeam(TEAM_ALLIANCE), bg->GetFreeSlotsForTeam(TEAM_HORDE), bracket_id); // invite players for (uint32 i = 0; i < BG_TEAMS_COUNT; i++) - for (GroupsQueueType::const_iterator citr = m_SelectionPools[TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr) - BattlegroundMgr::InviteGroupToBG((*citr), bg, (*citr)->teamId); + for (auto itr : m_SelectionPools[TEAM_ALLIANCE + i].SelectedGroups) + BattlegroundMgr::InviteGroupToBG(itr, bg, itr->RealTeamID); } } @@ -760,7 +752,7 @@ void BattlegroundQueue::BattlegroundQueueUpdate(BattlegroundBracketId bracket_id if (bg->HasFreeSlots()) { // call a function that fills whatever we can from normal queues - FillPlayersToBG(bg->GetFreeSlotsForTeam(TEAM_ALLIANCE), bg->GetFreeSlotsForTeam(TEAM_HORDE), bracket_id); + FillPlayersToBG(bg, bg->GetFreeSlotsForTeam(TEAM_ALLIANCE), bg->GetFreeSlotsForTeam(TEAM_HORDE), bracket_id); // invite players for (uint32 i = 0; i < BG_TEAMS_COUNT; i++) @@ -839,7 +831,7 @@ void BattlegroundQueue::BattlegroundQueueUpdate(BattlegroundBracketId bracket_id uint32 MMR1 = std::min((*itr)->ArenaMatchmakerRating, maxCountedMMR); GroupsQueueType::iterator oponentItr; - uint8 oponentQueue = BG_QUEUE_GROUP_TYPES_COUNT; + uint8 oponentQueue = BG_QUEUE_MAX; uint32 minOponentMMRDiff = 0xffffffff; uint8 oponentValid = 0; @@ -905,7 +897,7 @@ void BattlegroundQueue::BattlegroundQueueUpdate(BattlegroundBracketId bracket_id break; } - if (oponentQueue != BG_QUEUE_GROUP_TYPES_COUNT) + if (oponentQueue != BG_QUEUE_MAX) { if (oponentValid) { @@ -963,6 +955,31 @@ void BattlegroundQueue::BattlegroundQueueUpdate(BattlegroundBracketId bracket_id } } +uint32 BattlegroundQueue::GetPlayersCountInGroupsQueue(BattlegroundBracketId bracketId, BattlegroundQueueGroupTypes bgqueue) +{ + uint32 playersCount = 0; + + for (auto const& itr : m_QueuedGroups[bracketId][bgqueue]) + if (!itr->IsInvitedToBGInstanceGUID) + playersCount += static_cast(itr->Players.size()); + + return playersCount; +} + +bool BattlegroundQueue::IsAllQueuesEmpty(BattlegroundBracketId bracket_id) +{ + uint32 queueEmptyCount = 0; + + for (uint8 i = 0; i < BG_QUEUE_MAX; i++) + if (m_QueuedGroups[bracket_id][i].empty()) + queueEmptyCount++; + + if (queueEmptyCount == BG_QUEUE_MAX) + return true; + + return false; +} + /*********************************************************/ /*** BATTLEGROUND QUEUE EVENTS ***/ /*********************************************************/ diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h index 327cb2e1b..cddb207c6 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.h +++ b/src/server/game/Battlegrounds/BattlegroundQueue.h @@ -20,6 +20,7 @@ struct GroupQueueInfo // stores informatio { std::set Players; // player guid set TeamId teamId; // Player team (TEAM_ALLIANCE/TEAM_HORDE) + TeamId RealTeamID; // Realm player team (TEAM_ALLIANCE/TEAM_HORDE) BattlegroundTypeId BgTypeId; // battleground type id bool IsRated; // rated uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG @@ -39,12 +40,13 @@ struct GroupQueueInfo // stores informatio enum BattlegroundQueueGroupTypes { - BG_QUEUE_PREMADE_ALLIANCE = 0, - BG_QUEUE_PREMADE_HORDE = 1, - BG_QUEUE_NORMAL_ALLIANCE = 2, - BG_QUEUE_NORMAL_HORDE = 3 + BG_QUEUE_PREMADE_ALLIANCE, + BG_QUEUE_PREMADE_HORDE, + BG_QUEUE_NORMAL_ALLIANCE, + BG_QUEUE_NORMAL_HORDE, + + BG_QUEUE_MAX }; -#define BG_QUEUE_GROUP_TYPES_COUNT 4 class Battleground; class BattlegroundQueue @@ -56,8 +58,8 @@ class BattlegroundQueue void BattlegroundQueueUpdate(BattlegroundBracketId bracket_id, uint8 actionMask, bool isRated, uint32 arenaRatedTeamId); void UpdateEvents(uint32 diff); - void FillPlayersToBG(const int32 aliFree, const int32 hordeFree, BattlegroundBracketId bracket_id); - void FillPlayersToBGWithSpecific(const int32 aliFree, const int32 hordeFree, BattlegroundBracketId thisBracketId, BattlegroundQueue* specificQueue, BattlegroundBracketId specificBracketId); + void FillPlayersToBG(Battleground* bg, const int32 aliFree, const int32 hordeFree, BattlegroundBracketId bracket_id); + void FillPlayersToBGWithSpecific(Battleground* bg, const int32 aliFree, const int32 hordeFree, BattlegroundBracketId thisBracketId, BattlegroundQueue* specificQueue, BattlegroundBracketId specificBracketId); bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam); bool CheckNormalMatch(Battleground* bgTemplate, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers); bool CheckSkirmishForSameFaction(BattlegroundBracketId bracket_id, uint32 minPlayersPerTeam); @@ -68,6 +70,8 @@ class BattlegroundQueue bool GetPlayerGroupInfoData(uint64 guid, GroupQueueInfo* ginfo); void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo); uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo) const; + uint32 GetPlayersCountInGroupsQueue(BattlegroundBracketId bracketId, BattlegroundQueueGroupTypes bgqueue); + bool IsAllQueuesEmpty(BattlegroundBracketId bracket_id); void SetBgTypeIdAndArenaType(BattlegroundTypeId b, uint8 a) { m_bgTypeId = b; m_arenaType = ArenaType(a); } // pussywizard void AddEvent(BasicEvent* Event, uint64 e_time); @@ -87,7 +91,7 @@ class 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[MAX_BATTLEGROUND_BRACKETS][BG_QUEUE_MAX]; // class to select and invite groups to bg class SelectionPool