AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
BattlegroundQueue Class Reference

#include "BattlegroundQueue.h"

Classes

class  SelectionPool
 

Public Types

typedef std::map< ObjectGuid, GroupQueueInfo * > QueuedPlayersMap
 
typedef std::list< GroupQueueInfo * > GroupsQueueType
 

Public Member Functions

 BattlegroundQueue ()
 
 ~BattlegroundQueue ()
 
void BattlegroundQueueUpdate (uint32 diff, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType, bool isRated, uint32 arenaRating)
 
void BattlegroundQueueAnnouncerUpdate (uint32 diff, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundBracketId bracket_id)
 
void UpdateEvents (uint32 diff)
 
void FillPlayersToBG (Battleground *bg, BattlegroundBracketId bracket_id)
 
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)
 
GroupQueueInfoAddGroup (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 RemovePlayer (ObjectGuid guid, bool decreaseInvitedCount)
 
bool IsPlayerInvitedToRatedArena (ObjectGuid pl_guid)
 
bool IsPlayerInvited (ObjectGuid pl_guid, uint32 bgInstanceGuid, uint32 removeTime)
 
bool GetPlayerGroupInfoData (ObjectGuid guid, GroupQueueInfo *ginfo)
 
void PlayerInvitedToBGUpdateAverageWaitTime (GroupQueueInfo *ginfo)
 
uint32 GetAverageQueueWaitTime (GroupQueueInfo *ginfo) const
 
void InviteGroupToBG (GroupQueueInfo *ginfo, Battleground *bg, TeamId teamId)
 
uint32 GetPlayersCountInGroupsQueue (BattlegroundBracketId bracketId, BattlegroundQueueGroupTypes bgqueue)
 
bool IsAllQueuesEmpty (BattlegroundBracketId bracket_id)
 
void SendMessageBGQueue (Player *leader, Battleground *bg, PvPDifficultyEntry const *bracketEntry)
 
void SendJoinMessageArenaQueue (Player *leader, GroupQueueInfo *ginfo, PvPDifficultyEntry const *bracketEntry, bool isRated)
 
void SendExitMessageArenaQueue (GroupQueueInfo *ginfo)
 
void AddEvent (BasicEvent *Event, uint64 e_time)
 
void SetQueueAnnouncementTimer (uint32 bracketId, int32 timer, bool isCrossFactionBG=true)
 
int32 GetQueueAnnouncementTimer (uint32 bracketId) const
 

Public Attributes

QueuedPlayersMap m_QueuedPlayers
 
GroupsQueueType m_QueuedGroups [MAX_BATTLEGROUND_BRACKETS][BG_QUEUE_MAX]
 
SelectionPool m_SelectionPools [PVP_TEAMS_COUNT]
 

Private Attributes

uint32 m_WaitTimes [PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME]
 
uint32 m_WaitTimeLastIndex [PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS]
 
EventProcessor m_events
 
std::array< int32, MAX_BATTLEGROUND_BRACKETS_queueAnnouncementTimer
 
bool _queueAnnouncementCrossfactioned
 

Detailed Description

Member Typedef Documentation

◆ GroupsQueueType

◆ QueuedPlayersMap

Constructor & Destructor Documentation

◆ BattlegroundQueue()

BattlegroundQueue::BattlegroundQueue ( )
41{
42 for (uint32 i = 0; i < PVP_TEAMS_COUNT; ++i)
43 {
44 for (uint32 j = 0; j < MAX_BATTLEGROUND_BRACKETS; ++j)
45 {
46 m_WaitTimeLastIndex[i][j] = 0;
48 m_WaitTimes[i][j][k] = 0;
49 }
50 }
51
54}
constexpr auto COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME
Definition BattlegroundQueue.h:28
#define MAX_BATTLEGROUND_BRACKETS
Definition DBCEnums.h:52
std::uint32_t uint32
Definition Define.h:107
uint8 constexpr PVP_TEAMS_COUNT
Definition SharedDefines.h:3701
bool _queueAnnouncementCrossfactioned
Definition BattlegroundQueue.h:143
std::array< int32, MAX_BATTLEGROUND_BRACKETS > _queueAnnouncementTimer
Definition BattlegroundQueue.h:142
uint32 m_WaitTimes[PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME]
Definition BattlegroundQueue.h:136
uint32 m_WaitTimeLastIndex[PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS]
Definition BattlegroundQueue.h:137

References _queueAnnouncementCrossfactioned, _queueAnnouncementTimer, COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME, m_WaitTimeLastIndex, m_WaitTimes, MAX_BATTLEGROUND_BRACKETS, and PVP_TEAMS_COUNT.

◆ ~BattlegroundQueue()

BattlegroundQueue::~BattlegroundQueue ( )
57{
59
60 m_QueuedPlayers.clear();
61 for (auto& m_QueuedGroup : m_QueuedGroups)
62 {
63 for (auto& j : m_QueuedGroup)
64 {
65 for (auto& itr : j)
66 delete itr;
67 j.clear();
68 }
69 }
70}
QueuedPlayersMap m_QueuedPlayers
Definition BattlegroundQueue.h:98
GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_BRACKETS][BG_QUEUE_MAX]
Definition BattlegroundQueue.h:112
EventProcessor m_events
Definition BattlegroundQueue.h:140
void KillAllEvents(bool force)
Definition EventProcessor.cpp:82

References EventProcessor::KillAllEvents(), m_events, m_QueuedGroups, and m_QueuedPlayers.

Member Function Documentation

◆ AddEvent()

void BattlegroundQueue::AddEvent ( BasicEvent Event,
uint64  e_time 
)
383{
385}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
Event
Definition boss_kelthuzad.cpp:77
void AddEventAtOffset(BasicEvent *event, Milliseconds offset, uint8 eventGroup=0)
Definition EventProcessor.h:108

References EventProcessor::AddEventAtOffset(), and m_events.

Referenced by InviteGroupToBG().

◆ AddGroup()

GroupQueueInfo * BattlegroundQueue::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 
)
136{
137 BattlegroundBracketId bracketId = bracketEntry->GetBracketId();
138
139 // create new ginfo
140 auto* ginfo = new GroupQueueInfo;
141 ginfo->BgTypeId = bgTypeId;
142 ginfo->ArenaType = arenaType;
143 ginfo->ArenaTeamId = arenaTeamId;
144 ginfo->IsRated = isRated;
145 ginfo->IsInvitedToBGInstanceGUID = 0;
146 ginfo->JoinTime = GameTime::GetGameTimeMS().count();
147 ginfo->RemoveInviteTime = 0;
148 ginfo->teamId = leader->GetTeamId();
149 ginfo->RealTeamID = leader->GetTeamId(true);
150 ginfo->ArenaTeamRating = arenaRating;
151 ginfo->ArenaMatchmakerRating = matchmakerRating;
152 ginfo->PreviousOpponentsTeamId = opponentsArenaTeamId;
153 ginfo->OpponentsTeamRating = 0;
154 ginfo->OpponentsMatchmakerRating = 0;
155
156 ginfo->Players.clear();
157
158 //compute index (if group is premade or joined a rated match) to queues
159 uint32 index = 0;
160
161 if (!isRated && !isPremade)
162 index += PVP_TEAMS_COUNT;
163
164 if (ginfo->teamId == TEAM_HORDE)
165 index++;
166
167 sScriptMgr->OnAddGroup(this, ginfo, index, leader, group, bgTypeId, bracketEntry,
168 arenaType, isRated, isPremade, arenaRating, matchmakerRating, arenaTeamId, opponentsArenaTeamId);
169
170 LOG_DEBUG("bg.battleground", "Adding Group to BattlegroundQueue bgTypeId: {}, bracket_id: {}, index: {}", bgTypeId, bracketId, index);
171
172 // pussywizard: store indices at which GroupQueueInfo is in m_QueuedGroups
173 ginfo->BracketId = bracketId;
174 ginfo->GroupType = index;
175
176 //add players from group to ginfo
177 if (group)
178 {
179 group->DoForAllMembers([this, ginfo](Player* member)
180 {
181 ASSERT(m_QueuedPlayers.count(member->GetGUID()) == 0);
182 m_QueuedPlayers[member->GetGUID()] = ginfo;
183 ginfo->Players.emplace(member->GetGUID());
184 });
185 }
186 else
187 {
188 ASSERT(m_QueuedPlayers.count(leader->GetGUID()) == 0);
189 m_QueuedPlayers[leader->GetGUID()] = ginfo;
190 ginfo->Players.emplace(leader->GetGUID());
191 }
192
193 //add GroupInfo to m_QueuedGroups
194 m_QueuedGroups[bracketId][index].push_back(ginfo);
195
196 // announce world (this doesn't need mutex)
197 SendJoinMessageArenaQueue(leader, ginfo, bracketEntry, isRated);
198
199 Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId);
200 if (!bg)
201 return ginfo;
202
203 if (!isRated && !isPremade && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
204 SendMessageBGQueue(leader, bg, bracketEntry);
205
206 return ginfo;
207}
#define sBattlegroundMgr
Definition BattlegroundMgr.h:190
BattlegroundBracketId
Definition DBCEnums.h:46
#define ASSERT
Definition Errors.h:68
#define LOG_DEBUG(filterType__,...)
Definition Log.h:157
#define sScriptMgr
Definition ScriptMgr.h:743
@ TEAM_HORDE
Definition SharedDefines.h:749
@ CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE
Definition WorldConfig.h:68
void SendMessageBGQueue(Player *leader, Battleground *bg, PvPDifficultyEntry const *bracketEntry)
Definition BattlegroundQueue.cpp:1119
void SendJoinMessageArenaQueue(Player *leader, GroupQueueInfo *ginfo, PvPDifficultyEntry const *bracketEntry, bool isRated)
Definition BattlegroundQueue.cpp:1171
Definition Battleground.h:303
void DoForAllMembers(std::function< void(Player *)> const &worker)
Definition Group.cpp:2749
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:114
Definition Player.h:1086
TeamId GetTeamId(bool original=false) const
Definition Player.h:2138
#define sWorld
Definition World.h:318
Milliseconds GetGameTimeMS()
Definition GameTime.cpp:43
Definition BattlegroundQueue.h:35
BattlegroundTypeId BgTypeId
Definition BattlegroundQueue.h:39

References ASSERT, GroupQueueInfo::BgTypeId, CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE, Group::DoForAllMembers(), PvPDifficultyEntry::GetBracketId(), GameTime::GetGameTimeMS(), Object::GetGUID(), Player::GetTeamId(), LOG_DEBUG, m_QueuedGroups, m_QueuedPlayers, PVP_TEAMS_COUNT, sBattlegroundMgr, SendJoinMessageArenaQueue(), SendMessageBGQueue(), sScriptMgr, sWorld, and TEAM_HORDE.

Referenced by CheckNormalMatch(), CheckPremadeMatch(), CheckSkirmishForSameFaction(), FillPlayersToBG(), WorldSession::HandleBattlemasterJoinArena(), and WorldSession::HandleBattlemasterJoinOpcode().

◆ BattlegroundQueueAnnouncerUpdate()

void BattlegroundQueue::BattlegroundQueueAnnouncerUpdate ( uint32  diff,
BattlegroundQueueTypeId  bgQueueTypeId,
BattlegroundBracketId  bracket_id 
)
1042{
1043 BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId);
1044 Battleground* bg_template = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
1045 if (!bg_template)
1046 {
1047 return;
1048 }
1049
1050 PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketById(bg_template->GetMapId(), bracket_id);
1051 if (!bracketEntry)
1052 {
1053 return;
1054 }
1055
1056 // Armed per-bracket timer drives both Timed mode and the deferred immediate
1057 // announcement; the spam-window/Limit throttle gates only immediate mode.
1058 bool const isTimed = sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_TIMED);
1059
1060 uint32 qPlayers = 0;
1061
1063 qPlayers = GetPlayersCountInGroupsQueue(bracket_id, BG_QUEUE_CFBG);
1064 else
1066
1067 if (!qPlayers)
1068 {
1069 _queueAnnouncementTimer[bracket_id] = -1;
1070 return;
1071 }
1072
1073 if (_queueAnnouncementTimer[bracket_id] >= 0)
1074 {
1075 if (_queueAnnouncementTimer[bracket_id] <= static_cast<int32>(diff))
1076 {
1077 _queueAnnouncementTimer[bracket_id] = -1;
1078
1079 uint32 q_min_level = std::min(bracketEntry->minLevel, (uint32) 80);
1080
1081 if (!isTimed && !sBGSpam->CanAnnounce(bg_template, bracket_id, q_min_level, qPlayers))
1082 return;
1083
1084 auto bgName = bg_template->GetName();
1085 uint32 MaxPlayers = GetMinPlayersPerTeam(bg_template, bracketEntry) * 2;
1086 uint32 q_max_level = std::min(bracketEntry->maxLevel, (uint32) 80);
1087
1088 ChatHandler(nullptr).SendWorldTextOptional(LANG_BG_QUEUE_ANNOUNCE_WORLD, ANNOUNCER_FLAG_DISABLE_BG_QUEUE, bgName.c_str(), q_min_level, q_max_level, qPlayers, MaxPlayers);
1089 }
1090 else
1091 {
1092 _queueAnnouncementTimer[bracket_id] -= static_cast<int32>(diff);
1093 }
1094 }
1095}
@ BG_QUEUE_NORMAL_ALLIANCE
Definition BattlegroundQueue.h:59
@ BG_QUEUE_CFBG
Definition BattlegroundQueue.h:62
@ BG_QUEUE_NORMAL_HORDE
Definition BattlegroundQueue.h:60
#define sBGSpam
Definition BattlegroundSpamProtect.h:36
uint32 GetMinPlayersPerTeam(Battleground *bg, PvPDifficultyEntry const *bracketEntry)
Definition BattlegroundUtils.cpp:4
PvPDifficultyEntry const * GetBattlegroundBracketById(uint32 mapid, BattlegroundBracketId id)
Definition DBCStores.cpp:815
std::int32_t int32
Definition Define.h:103
@ LANG_BG_QUEUE_ANNOUNCE_WORLD
Definition Language.h:690
@ ANNOUNCER_FLAG_DISABLE_BG_QUEUE
Definition PlayerSettings.h:34
BattlegroundTypeId
Definition SharedDefines.h:3735
@ CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_TIMED
Definition WorldConfig.h:70
static BattlegroundTypeId BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId)
Definition BattlegroundMgr.cpp:709
uint32 GetPlayersCountInGroupsQueue(BattlegroundBracketId bracketId, BattlegroundQueueGroupTypes bgqueue)
Definition BattlegroundQueue.cpp:1097
uint32 GetMapId() const
Definition Battleground.h:441
std::string GetName() const
Definition Battleground.h:328
Definition Chat.h:37
void SendWorldTextOptional(std::string_view str, uint32 flag)
Definition Chat.cpp:151
Definition DBCStructure.h:1431
uint32 maxLevel
Definition DBCStructure.h:1436
uint32 minLevel
Definition DBCStructure.h:1435

References _queueAnnouncementCrossfactioned, _queueAnnouncementTimer, ANNOUNCER_FLAG_DISABLE_BG_QUEUE, BG_QUEUE_CFBG, BG_QUEUE_NORMAL_ALLIANCE, BG_QUEUE_NORMAL_HORDE, BattlegroundMgr::BGTemplateId(), CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_TIMED, GetBattlegroundBracketById(), Battleground::GetMapId(), GetMinPlayersPerTeam(), Battleground::GetName(), GetPlayersCountInGroupsQueue(), LANG_BG_QUEUE_ANNOUNCE_WORLD, PvPDifficultyEntry::maxLevel, PvPDifficultyEntry::minLevel, sBattlegroundMgr, sBGSpam, ChatHandler::SendWorldTextOptional(), and sWorld.

Referenced by BattlegroundMgr::Update().

◆ BattlegroundQueueUpdate()

void BattlegroundQueue::BattlegroundQueueUpdate ( uint32  diff,
BattlegroundTypeId  bgTypeId,
BattlegroundBracketId  bracket_id,
uint8  arenaType,
bool  isRated,
uint32  arenaRating 
)
791{
792 // if no players in queue - do nothing
793 if (IsAllQueuesEmpty(bracket_id))
794 return;
795
796 auto InviteAllGroupsToBg = [this](Battleground* bg)
797 {
798 // invite those selection pools
799 for (uint32 i = 0; i < PVP_TEAMS_COUNT; i++)
800 {
801 for (auto const& citr : m_SelectionPools[TEAM_ALLIANCE + i].SelectedGroups)
802 {
803 InviteGroupToBG(citr, bg, citr->teamId);
804 }
805 }
806 };
807
808 // fill existing joinable battlegrounds, oldest first, before a new instance may form below
809 BGFreeSlotQueueContainer& bgQueues = sBattlegroundMgr->GetBGFreeSlotQueueStore(bgTypeId);
810 for (BGFreeSlotQueueContainer::iterator itr = bgQueues.begin(); itr != bgQueues.end();)
811 {
812 Battleground* bg = *itr; ++itr;
813 // DO NOT allow queue manager to invite new player to rated games
814 if (!bg->isRated() && bg->GetBgTypeID() == bgTypeId && bg->GetBracketId() == bracket_id &&
816 {
817 // clear selection pools
820
821 // call a function that does the job for us
822 FillPlayersToBG(bg, bracket_id);
823
824 // now everything is set, invite players
825 InviteAllGroupsToBg(bg);
826
827 if (!bg->HasFreeSlots())
829 }
830 }
831
832 Battleground* bg_template = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
833 if (!bg_template)
834 {
835 LOG_ERROR("bg.battleground", "Battleground: Update: bg template not found for {}", bgTypeId);
836 return;
837 }
838
839 PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketById(bg_template->GetMapId(), bracket_id);
840 if (!bracketEntry)
841 {
842 LOG_ERROR("bg.battleground", "Battleground: Update: bg bracket entry not found for map {} bracket id {}", bg_template->GetMapId(), bracket_id);
843 return;
844 }
845
846 // get min and max players per team
847 uint32 MinPlayersPerTeam = GetMinPlayersPerTeam(bg_template, bracketEntry);
848 uint32 MaxPlayersPerTeam = bg_template->GetMaxPlayersPerTeam();
849
850 if (bg_template->isArena())
851 {
852 MinPlayersPerTeam = sBattlegroundMgr->isArenaTesting() ? 1 : arenaType;
853 MaxPlayersPerTeam = arenaType;
854 }
855 else if (sBattlegroundMgr->isTesting())
856 MinPlayersPerTeam = 1;
857
858 sScriptMgr->OnQueueUpdate(this, diff, bgTypeId, bracket_id, arenaType, isRated, arenaRating);
859
860 if (!sScriptMgr->OnQueueUpdateValidity(this, diff, bgTypeId, bracket_id, arenaType, isRated, arenaRating))
861 return;
862
865
866 // check if can start new premade battleground
867 if (bg_template->isBattleground() && bgTypeId != BATTLEGROUND_RB && CheckPremadeMatch(bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam))
868 {
869 // create new battleground
870 Battleground* bg = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, 0, false);
871 if (!bg)
872 {
873 LOG_ERROR("bg.battleground", "BattlegroundQueue::Update - Cannot create battleground: {}", bgTypeId);
874 return;
875 }
876
877 // invite those selection pools
878 InviteAllGroupsToBg(bg);
879
880 bg->StartBattleground();
881
882 // clear structures
885 }
886
887 // check if can start new normal battleground or non-rated arena
888 if (!isRated)
889 {
890 if (CheckNormalMatch(bg_template, bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam) ||
891 (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam)))
892 {
893 // create new battleground
894 Battleground* bg = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, false);
895 if (!bg)
896 {
897 LOG_ERROR("bg.battleground", "BattlegroundQueue::Update - Cannot create battleground: {}", bgTypeId);
898 return;
899 }
900
901 // invite players
902 InviteAllGroupsToBg(bg);
903
904 bg->StartBattleground();
905 }
906 }
907 // check if can start new rated arenas (can create many in single queue update)
908 else if (bg_template->isArena())
909 {
910 // found out the minimum and maximum ratings the newly added team should battle against
911 // arenaRating is the rating of the latest joined team, or 0
912 // 0 is on (automatic update call) and we must set it to team's with longest wait time
913 if (!arenaRating)
914 {
915 GroupQueueInfo* front1 = nullptr;
916 GroupQueueInfo* front2 = nullptr;
917
918 if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty())
919 {
920 front1 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].front();
921 arenaRating = front1->ArenaMatchmakerRating;
922 }
923
924 if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty())
925 {
926 front2 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].front();
927 arenaRating = front2->ArenaMatchmakerRating;
928 }
929
930 if (front1 && front2)
931 {
932 if (front1->JoinTime < front2->JoinTime)
933 arenaRating = front1->ArenaMatchmakerRating;
934 }
935 else if (!front1 && !front2)
936 return; // queues are empty
937 }
938
939 //set rating range
940 uint32 arenaMinRating = (arenaRating <= sBattlegroundMgr->GetMaxRatingDifference()) ? 0 : arenaRating - sBattlegroundMgr->GetMaxRatingDifference();
941 uint32 arenaMaxRating = arenaRating + sBattlegroundMgr->GetMaxRatingDifference();
942
943 // if max rating difference is set and the time past since server startup is greater than the rating discard time
944 // (after what time the ratings aren't taken into account when making teams) then
945 // the discard time is current_time - time_to_discard, teams that joined after that, will have their ratings taken into account
946 // else leave the discard time on 0, this way all ratings will be discarded
947 // this has to be signed value - when the server starts, this value would be negative and thus overflow
948 int32 discardTime = GameTime::GetGameTimeMS().count() - sBattlegroundMgr->GetRatingDiscardTimer();
949
950 // timer for previous opponents
951 int32 discardOpponentsTime = GameTime::GetGameTimeMS().count() - sWorld->getIntConfig(CONFIG_ARENA_PREV_OPPONENTS_DISCARD_TIMER);
952
953 // we need to find 2 teams which will play next game
954 GroupsQueueType::iterator itr_teams[PVP_TEAMS_COUNT];
955 uint8 found = 0;
956 uint8 team = 0;
957
959 {
960 // take the group that joined first
961 GroupsQueueType::iterator itr2 = m_QueuedGroups[bracket_id][i].begin();
962 for (; itr2 != m_QueuedGroups[bracket_id][i].end(); ++itr2)
963 {
964 // if group match conditions, then add it to pool
965 if (!(*itr2)->IsInvitedToBGInstanceGUID
966 && (((*itr2)->ArenaMatchmakerRating >= arenaMinRating && (*itr2)->ArenaMatchmakerRating <= arenaMaxRating)
967 || (int32)(*itr2)->JoinTime < discardTime))
968 {
969 itr_teams[found++] = itr2;
970 team = i;
971 break;
972 }
973 }
974 }
975
976 if (!found)
977 return;
978
979 if (found == 1)
980 {
981 for (GroupsQueueType::iterator itr3 = itr_teams[0]; itr3 != m_QueuedGroups[bracket_id][team].end(); ++itr3)
982 {
983 if (!(*itr3)->IsInvitedToBGInstanceGUID
984 && (((*itr3)->ArenaMatchmakerRating >= arenaMinRating && (*itr3)->ArenaMatchmakerRating <= arenaMaxRating) || (int32)(*itr3)->JoinTime < discardTime)
985 && ((*(itr_teams[0]))->ArenaTeamId != (*itr3)->PreviousOpponentsTeamId || ((int32)(*itr3)->JoinTime < discardOpponentsTime))
986 && (*(itr_teams[0]))->ArenaTeamId != (*itr3)->ArenaTeamId)
987 {
988 itr_teams[found++] = itr3;
989 break;
990 }
991 }
992 }
993
994 //if we have 2 teams, then start new arena and invite players!
995 if (found == 2)
996 {
997 GroupQueueInfo* aTeam = *(itr_teams[TEAM_ALLIANCE]);
998 GroupQueueInfo* hTeam = *(itr_teams[TEAM_HORDE]);
999
1000 Battleground* arena = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, true);
1001 if (!arena)
1002 {
1003 LOG_ERROR("bg.battleground", "BattlegroundQueue::Update couldn't create arena instance for rated arena match!");
1004 return;
1005 }
1006
1007 aTeam->OpponentsTeamRating = hTeam->ArenaTeamRating;
1008 hTeam->OpponentsTeamRating = aTeam->ArenaTeamRating;
1011
1012 LOG_DEBUG("bg.battleground", "setting oposite teamrating for team {} to {}", aTeam->ArenaTeamId, aTeam->OpponentsTeamRating);
1013 LOG_DEBUG("bg.battleground", "setting oposite teamrating for team {} to {}", hTeam->ArenaTeamId, hTeam->OpponentsTeamRating);
1014
1015 // 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
1016 if (aTeam->teamId != TEAM_ALLIANCE)
1017 {
1019 m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].push_front(aTeam);
1020 m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].erase(itr_teams[TEAM_ALLIANCE]);
1021 }
1022
1023 if (hTeam->teamId != TEAM_HORDE)
1024 {
1026 m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].push_front(hTeam);
1027 m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].erase(itr_teams[TEAM_HORDE]);
1028 }
1029
1032 InviteGroupToBG(aTeam, arena, TEAM_ALLIANCE);
1033 InviteGroupToBG(hTeam, arena, TEAM_HORDE);
1034
1035 LOG_DEBUG("bg.battleground", "Starting rated arena match!");
1036 arena->StartBattleground();
1037 }
1038 }
1039}
std::list< Battleground * > BGFreeSlotQueueContainer
Definition BattlegroundMgr.h:36
@ BG_QUEUE_PREMADE_HORDE
Definition BattlegroundQueue.h:58
@ BG_QUEUE_PREMADE_ALLIANCE
Definition BattlegroundQueue.h:57
@ STATUS_WAIT_QUEUE
Definition Battleground.h:191
@ STATUS_WAIT_LEAVE
Definition Battleground.h:194
std::uint8_t uint8
Definition Define.h:109
#define LOG_ERROR(filterType__,...)
Definition Log.h:145
@ BATTLEGROUND_RB
Definition SharedDefines.h:3749
@ TEAM_ALLIANCE
Definition SharedDefines.h:748
@ CONFIG_ARENA_PREV_OPPONENTS_DISCARD_TIMER
Definition WorldConfig.h:296
void Init()
Definition BattlegroundQueue.cpp:77
void FillPlayersToBG(Battleground *bg, BattlegroundBracketId bracket_id)
Definition BattlegroundQueue.cpp:410
void InviteGroupToBG(GroupQueueInfo *ginfo, Battleground *bg, TeamId teamId)
Definition BattlegroundQueue.cpp:1302
bool CheckSkirmishForSameFaction(BattlegroundBracketId bracket_id, uint32 minPlayersPerTeam)
Definition BattlegroundQueue.cpp:710
SelectionPool m_SelectionPools[PVP_TEAMS_COUNT]
Definition BattlegroundQueue.h:130
bool IsAllQueuesEmpty(BattlegroundBracketId bracket_id)
Definition BattlegroundQueue.cpp:1108
bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam)
Definition BattlegroundQueue.cpp:569
bool CheckNormalMatch(Battleground *bgTemplate, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers)
Definition BattlegroundQueue.cpp:646
uint32 GetMaxPlayersPerTeam() const
Definition Battleground.h:349
bool isRated() const
Definition Battleground.h:414
void StartBattleground()
Definition Battleground.cpp:1169
bool isArena() const
Definition Battleground.h:412
bool isBattleground() const
Definition Battleground.h:413
BattlegroundStatus GetStatus() const
Definition Battleground.h:332
bool HasFreeSlots() const
Definition Battleground.cpp:1357
void RemoveFromBGFreeSlotQueue()
Definition Battleground.cpp:1296
BattlegroundBracketId GetBracketId() const
Definition Battleground.h:330
BattlegroundTypeId GetBgTypeID(bool GetRandom=false) const
Definition Battleground.h:329
void SetArenaMatchmakerRating(TeamId teamId, uint32 MMR)
Definition Battleground.h:508
uint32 ArenaTeamRating
Definition BattlegroundQueue.h:46
TeamId teamId
Definition BattlegroundQueue.h:37
uint32 JoinTime
Definition BattlegroundQueue.h:43
uint32 OpponentsMatchmakerRating
Definition BattlegroundQueue.h:49
uint32 ArenaTeamId
Definition BattlegroundQueue.h:42
uint32 OpponentsTeamRating
Definition BattlegroundQueue.h:48
uint32 ArenaMatchmakerRating
Definition BattlegroundQueue.h:47
uint8 GroupType
Definition BattlegroundQueue.h:52

References GroupQueueInfo::ArenaMatchmakerRating, GroupQueueInfo::ArenaTeamId, GroupQueueInfo::ArenaTeamRating, BATTLEGROUND_RB, BG_QUEUE_NORMAL_ALLIANCE, BG_QUEUE_PREMADE_ALLIANCE, BG_QUEUE_PREMADE_HORDE, CheckNormalMatch(), CheckPremadeMatch(), CheckSkirmishForSameFaction(), CONFIG_ARENA_PREV_OPPONENTS_DISCARD_TIMER, FillPlayersToBG(), GetBattlegroundBracketById(), Battleground::GetBgTypeID(), Battleground::GetBracketId(), GameTime::GetGameTimeMS(), Battleground::GetMapId(), Battleground::GetMaxPlayersPerTeam(), GetMinPlayersPerTeam(), Battleground::GetStatus(), GroupQueueInfo::GroupType, Battleground::HasFreeSlots(), BattlegroundQueue::SelectionPool::Init(), InviteGroupToBG(), IsAllQueuesEmpty(), Battleground::isArena(), Battleground::isBattleground(), Battleground::isRated(), GroupQueueInfo::JoinTime, LOG_DEBUG, LOG_ERROR, m_QueuedGroups, m_SelectionPools, GroupQueueInfo::OpponentsMatchmakerRating, GroupQueueInfo::OpponentsTeamRating, PVP_TEAMS_COUNT, Battleground::RemoveFromBGFreeSlotQueue(), sBattlegroundMgr, BattlegroundQueue::SelectionPool::SelectedGroups, Battleground::SetArenaMatchmakerRating(), sScriptMgr, Battleground::StartBattleground(), STATUS_WAIT_LEAVE, STATUS_WAIT_QUEUE, sWorld, TEAM_ALLIANCE, TEAM_HORDE, and GroupQueueInfo::teamId.

Referenced by BattlegroundMgr::Update().

◆ CheckNormalMatch()

bool BattlegroundQueue::CheckNormalMatch ( Battleground bgTemplate,
BattlegroundBracketId  bracket_id,
uint32  minPlayers,
uint32  maxPlayers 
)
647{
648 auto CanStartMatch = [this, bgTemplate, minPlayers]()
649 {
650 //allow 1v0 if debug bg
652 return true;
653
654 //return true if there are enough players in selection pools - enable to work .debug bg command correctly
656 };
657
658 if (sScriptMgr->IsCheckNormalMatch(this, bgTemplate, bracket_id, minPlayers, maxPlayers))
659 return CanStartMatch();
660
661 GroupsQueueType::const_iterator itr_team[PVP_TEAMS_COUNT];
662 for (uint32 i = 0; i < PVP_TEAMS_COUNT; i++)
663 {
664 itr_team[i] = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin();
665 for (; itr_team[i] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++(itr_team[i]))
666 {
667 if (!(*(itr_team[i]))->IsInvitedToBGInstanceGUID)
668 {
669 if (sScriptMgr->CanAddGroupToMatchingPool(this, *(itr_team[i]), m_SelectionPools[i].GetPlayerCount(), bgTemplate, bracket_id))
670 {
671 m_SelectionPools[i].AddGroup(*(itr_team[i]), maxPlayers);
672 if (m_SelectionPools[i].GetPlayerCount() >= minPlayers)
673 break;
674 }
675 }
676 }
677 }
678
679 //try to invite same number of players - this cycle may cause longer wait time even if there are enough players in queue, but we want ballanced bg
682 j = TEAM_HORDE;
683
686 {
687 //we will try to invite more groups to team with less players indexed by j
688 ++(itr_team[j]); //this will not cause a crash, because for cycle above reached break;
689 for (; itr_team[j] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j]))
690 {
691 if (!(*(itr_team[j]))->IsInvitedToBGInstanceGUID)
692 {
693 if (!sScriptMgr->CanAddGroupToMatchingPool(this, *(itr_team[j]), m_SelectionPools[j].GetPlayerCount(), bgTemplate, bracket_id))
694 continue;
695
696 if (!m_SelectionPools[j].AddGroup(*(itr_team[j]), m_SelectionPools[(j + 1) % PVP_TEAMS_COUNT].GetPlayerCount()))
697 break;
698 }
699 }
700
701 // do not allow to start bg with more than 2 players more on 1 faction
703 return false;
704 }
705
706 return CanStartMatch();
707}
@ BG_QUEUE_INVITATION_TYPE_NO_BALANCE
Definition Battleground.h:297
@ CONFIG_BATTLEGROUND_INVITATION_TYPE
Definition WorldConfig.h:280
bool AddGroup(GroupQueueInfo *ginfo, uint32 desiredCount)
Definition BattlegroundQueue.cpp:117
uint32 GetPlayerCount() const
Definition BattlegroundQueue.h:122
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)
Definition BattlegroundQueue.cpp:134

References BattlegroundQueue::SelectionPool::AddGroup(), AddGroup(), BG_QUEUE_INVITATION_TYPE_NO_BALANCE, BG_QUEUE_NORMAL_ALLIANCE, CONFIG_BATTLEGROUND_INVITATION_TYPE, BattlegroundQueue::SelectionPool::GetPlayerCount(), Battleground::isBattleground(), m_QueuedGroups, m_SelectionPools, PVP_TEAMS_COUNT, sBattlegroundMgr, sScriptMgr, sWorld, TEAM_ALLIANCE, and TEAM_HORDE.

Referenced by BattlegroundQueueUpdate().

◆ CheckPremadeMatch()

bool BattlegroundQueue::CheckPremadeMatch ( BattlegroundBracketId  bracket_id,
uint32  MinPlayersPerTeam,
uint32  MaxPlayersPerTeam 
)
570{
571 if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && !m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty())
572 {
573 //start premade match
574 //if groups aren't invited
575 GroupsQueueType::const_iterator ali_group, horde_group;
576 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)
577 if (!(*ali_group)->IsInvitedToBGInstanceGUID)
578 break;
579
580 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)
581 if (!(*horde_group)->IsInvitedToBGInstanceGUID)
582 break;
583
584 // if found both groups
585 if (ali_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end())
586 {
587 if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*ali_group), 0, nullptr, bracket_id))
588 return false;
589
590 if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*horde_group), m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount(), nullptr, bracket_id))
591 return false;
592
593 m_SelectionPools[TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam);
594 m_SelectionPools[TEAM_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam);
595
596 //add groups/players from normal queue to size of bigger group
597 uint32 maxPlayers = std::min(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount(), m_SelectionPools[TEAM_HORDE].GetPlayerCount());
598 GroupsQueueType::const_iterator itr;
599
600 for (uint32 i = 0; i < PVP_TEAMS_COUNT; i++)
601 {
602 for (itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr)
603 {
604 if (!(*itr)->IsInvitedToBGInstanceGUID)
605 {
606 if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*itr), m_SelectionPools[i].GetPlayerCount(), nullptr, bracket_id))
607 continue;
608
609 if (!m_SelectionPools[i].AddGroup((*itr), maxPlayers))
610 break;
611 }
612 }
613 }
614
615 //premade selection pools are set
616 return true;
617 }
618 }
619
620 // now check if we can move group from Premade queue to normal queue (timer has expired) or group size lowered!!
621 // this could be 2 cycles but i'm checking only first team in queue - it can cause problem -
622 // if first is invited to BG and seconds timer expired, but we can ignore it, because players have only 80 seconds to click to enter bg
623 // and when they click or after 80 seconds the queue info is removed from queue
625
626 for (uint32 i = 0; i < PVP_TEAMS_COUNT; i++)
627 {
628 if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].empty())
629 {
630 GroupsQueueType::iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].begin();
631 if (!(*itr)->IsInvitedToBGInstanceGUID && ((*itr)->JoinTime < time_before || (*itr)->Players.size() < MinPlayersPerTeam))
632 {
633 //we must insert group to normal queue and erase pointer from premade queue
634 (*itr)->GroupType = BG_QUEUE_NORMAL_ALLIANCE + i; // pussywizard: update GroupQueueInfo internal variable
635 m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].push_front((*itr));
636 m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].erase(itr);
637 }
638 }
639 }
640
641 //selection pools are not set
642 return false;
643}
@ CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH
Definition WorldConfig.h:277

References BattlegroundQueue::SelectionPool::AddGroup(), AddGroup(), BG_QUEUE_NORMAL_ALLIANCE, BG_QUEUE_PREMADE_ALLIANCE, BG_QUEUE_PREMADE_HORDE, CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH, GameTime::GetGameTimeMS(), BattlegroundQueue::SelectionPool::GetPlayerCount(), m_QueuedGroups, m_SelectionPools, PVP_TEAMS_COUNT, sScriptMgr, sWorld, TEAM_ALLIANCE, and TEAM_HORDE.

Referenced by BattlegroundQueueUpdate().

◆ CheckSkirmishForSameFaction()

bool BattlegroundQueue::CheckSkirmishForSameFaction ( BattlegroundBracketId  bracket_id,
uint32  minPlayersPerTeam 
)
711{
712 if (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() < minPlayersPerTeam && m_SelectionPools[TEAM_HORDE].GetPlayerCount() < minPlayersPerTeam)
713 return false;
714
715 TeamId teamIndex = TEAM_ALLIANCE;
716 TeamId otherTeam = TEAM_HORDE;
717
718 if (m_SelectionPools[TEAM_HORDE].GetPlayerCount() == minPlayersPerTeam)
719 {
720 teamIndex = TEAM_HORDE;
721 otherTeam = TEAM_ALLIANCE;
722 }
723
724 //clear other team's selection
725 m_SelectionPools[otherTeam].Init();
726
727 //store last ginfo pointer
728 GroupQueueInfo* ginfo = m_SelectionPools[teamIndex].SelectedGroups.back();
729
730 //set itr_team to group that was added to selection pool latest
731 GroupsQueueType::iterator itr_team = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + static_cast<uint8>(teamIndex)].begin();
732 for (; itr_team != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + static_cast<uint8>(teamIndex)].end(); ++itr_team)
733 if (ginfo == *itr_team)
734 break;
735
736 if (itr_team == m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + static_cast<uint8>(teamIndex)].end())
737 return false;
738
739 GroupsQueueType::iterator itr_team2 = itr_team;
740 ++itr_team2;
741
742 //invite players to other selection pool
743 for (; itr_team2 != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + static_cast<uint8>(teamIndex)].end(); ++itr_team2)
744 {
745 if (!(*itr_team2)->IsInvitedToBGInstanceGUID)
746 {
747 if (!sScriptMgr->CanAddGroupToMatchingPool(this, *itr_team2, m_SelectionPools[otherTeam].GetPlayerCount(), nullptr, bracket_id))
748 continue;
749
750 if (!m_SelectionPools[otherTeam].AddGroup(*itr_team2, minPlayersPerTeam))
751 break;
752 }
753 }
754
755 if (m_SelectionPools[otherTeam].GetPlayerCount() != minPlayersPerTeam)
756 return false;
757
758 //here we have correct 2 selections and we need to change one teams team and move selection pool teams to other team's queue
759 for (GroupsQueueType::iterator itr = m_SelectionPools[otherTeam].SelectedGroups.begin(); itr != m_SelectionPools[otherTeam].SelectedGroups.end(); ++itr)
760 {
761 //set correct team
762 (*itr)->teamId = otherTeam;
763 (*itr)->GroupType = static_cast<uint8>(BG_QUEUE_NORMAL_ALLIANCE) + static_cast<uint8>(otherTeam);
764
765 //add team to other queue
766 m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + static_cast<uint8>(otherTeam)].push_front(*itr);
767
768 //remove team from old queue
769 GroupsQueueType::iterator itr2 = itr_team;
770 ++itr2;
771
772 for (; itr2 != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + static_cast<uint8>(teamIndex)].end(); ++itr2)
773 {
774 if (*itr2 == *itr)
775 {
776 m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + static_cast<uint8>(teamIndex)].erase(itr2);
777 break;
778 }
779 }
780 }
781
782 return true;
783}
TeamId
Definition SharedDefines.h:747
GroupsQueueType SelectedGroups
Definition BattlegroundQueue.h:124

References AddGroup(), BG_QUEUE_NORMAL_ALLIANCE, BattlegroundQueue::SelectionPool::GetPlayerCount(), BattlegroundQueue::SelectionPool::Init(), m_QueuedGroups, m_SelectionPools, BattlegroundQueue::SelectionPool::SelectedGroups, sScriptMgr, TEAM_ALLIANCE, and TEAM_HORDE.

Referenced by BattlegroundQueueUpdate().

◆ FillPlayersToBG()

void BattlegroundQueue::FillPlayersToBG ( Battleground bg,
BattlegroundBracketId  bracket_id 
)
411{
412 if (!sScriptMgr->CanFillPlayersToBG(this, bg, bracket_id))
413 {
414 return;
415 }
416
417 int32 hordeFree = bg->GetFreeSlotsForTeam(TEAM_HORDE);
419 uint32 aliCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size();
420 uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size();
421
422 // try to get even teams
424 {
425 // check if the teams are even
426 if (hordeFree == 1 && aliFree == 1)
427 {
428 // if we are here, the teams have the same amount of players
429 // then we have to allow to join the same amount of players
430 int32 hordeExtra = hordeCount - aliCount;
431 int32 aliExtra = aliCount - hordeCount;
432
433 hordeExtra = std::max(hordeExtra, 0);
434 aliExtra = std::max(aliExtra, 0);
435
436 if (aliCount != hordeCount)
437 {
438 aliFree -= aliExtra;
439 hordeFree -= hordeExtra;
440
441 aliFree = std::max(aliFree, 0);
442 hordeFree = std::max(hordeFree, 0);
443 }
444 }
445 }
446
447 GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].begin();
448 //count of groups in queue - used to stop cycles
449
450 //index to queue which group is current
451 uint32 aliIndex = 0;
452 for (; aliIndex < aliCount; aliIndex++)
453 {
454 if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Ali_itr), m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount(), bg, bracket_id))
455 {
456 ++Ali_itr;
457 continue;
458 }
459
460 if (!m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree))
461 break;
462
463 ++Ali_itr;
464 }
465
466 //the same thing for horde
467 GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].begin();
468
469 uint32 hordeIndex = 0;
470 for (; hordeIndex < hordeCount; hordeIndex++)
471 {
472 if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Horde_itr), m_SelectionPools[TEAM_HORDE].GetPlayerCount(), bg, bracket_id))
473 {
474 ++Horde_itr;
475 continue;
476 }
477
478 if (!m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), hordeFree))
479 break;
480
481 ++Horde_itr;
482 }
483
484 //if ofc like BG queue invitation is set in config, then we are happy
486 return;
487
488 /*
489 if we reached this code, then we have to solve NP - complete problem called Subset sum problem
490 So one solution is to check all possible invitation subgroups, or we can use these conditions:
491 1. Last time when BattlegroundQueue::Update was executed we invited all possible players - so there is only small possibility
492 that we will invite now whole queue, because only 1 change has been made to queues from the last BattlegroundQueue::Update call
493 2. Other thing we should consider is group order in queue
494 */
495
496 // At first we need to compare free space in bg and our selection pool
497 int32 diffAli = aliFree - int32(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount());
498 int32 diffHorde = hordeFree - int32(m_SelectionPools[TEAM_HORDE].GetPlayerCount());
499
500 while (std::abs(diffAli - diffHorde) > 1 && (m_SelectionPools[TEAM_HORDE].GetPlayerCount() > 0 || m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() > 0))
501 {
502 //each cycle execution we need to kick at least 1 group
503 if (diffAli < diffHorde)
504 {
505 //kick alliance group, add to pool new group if needed
506 if (m_SelectionPools[TEAM_ALLIANCE].KickGroup(diffHorde - diffAli))
507 {
508 for (; aliIndex < aliCount; aliIndex++)
509 {
510 if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Ali_itr), m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount(), bg, bracket_id))
511 {
512 ++Ali_itr;
513 continue;
514 }
515
516 if (!m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), (aliFree >= diffHorde) ? aliFree - diffHorde : 0))
517 break;
518
519 ++Ali_itr;
520 }
521 }
522
523 //if ali selection is already empty, then kick horde group, but if there are less horde than ali in bg - break;
524 if (!m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount())
525 {
526 if (aliFree <= diffHorde + 1)
527 break;
528
529 m_SelectionPools[TEAM_HORDE].KickGroup(diffHorde - diffAli);
530 }
531 }
532 else
533 {
534 //kick horde group, add to pool new group if needed
535 if (m_SelectionPools[TEAM_HORDE].KickGroup(diffAli - diffHorde))
536 {
537 for (; hordeIndex < hordeCount; hordeIndex++)
538 {
539 if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Horde_itr), m_SelectionPools[TEAM_HORDE].GetPlayerCount(), bg, bracket_id))
540 {
541 ++Horde_itr;
542 continue;
543 }
544
545 if (!m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), (hordeFree >= diffAli) ? hordeFree - diffAli : 0))
546 break;
547
548 ++Horde_itr;
549 }
550 }
551
552 if (!m_SelectionPools[TEAM_HORDE].GetPlayerCount())
553 {
554 if (hordeFree <= diffAli + 1)
555 break;
556
557 m_SelectionPools[TEAM_ALLIANCE].KickGroup(diffAli - diffHorde);
558 }
559 }
560
561 //count diffs after small update
562 diffAli = aliFree - int32(m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount());
563 diffHorde = hordeFree - int32(m_SelectionPools[TEAM_HORDE].GetPlayerCount());
564 }
565}
@ BG_QUEUE_INVITATION_TYPE_EVEN
Definition Battleground.h:299
bool KickGroup(uint32 size)
Definition BattlegroundQueue.cpp:84
uint32 GetFreeSlotsForTeam(TeamId teamId) const
Definition Battleground.cpp:1305

References AddGroup(), BG_QUEUE_INVITATION_TYPE_EVEN, BG_QUEUE_INVITATION_TYPE_NO_BALANCE, BG_QUEUE_NORMAL_ALLIANCE, BG_QUEUE_NORMAL_HORDE, CONFIG_BATTLEGROUND_INVITATION_TYPE, Battleground::GetFreeSlotsForTeam(), BattlegroundQueue::SelectionPool::GetPlayerCount(), BattlegroundQueue::SelectionPool::KickGroup(), m_QueuedGroups, m_SelectionPools, sScriptMgr, sWorld, TEAM_ALLIANCE, and TEAM_HORDE.

Referenced by BattlegroundQueueUpdate().

◆ GetAverageQueueWaitTime()

uint32 BattlegroundQueue::GetAverageQueueWaitTime ( GroupQueueInfo ginfo) const
236{
237 // team_index: bg alliance - TEAM_ALLIANCE, bg horde - TEAM_HORDE, arena skirmish - TEAM_ALLIANCE, arena rated - TEAM_HORDE
238 uint8 team_index;
239 if (!ginfo->ArenaType)
240 team_index = ginfo->teamId;
241 else
242 team_index = (ginfo->IsRated ? TEAM_HORDE : TEAM_ALLIANCE);
243
244 // just to be sure
245 if (team_index >= TEAM_NEUTRAL)
246 return 0;
247
248 // if there are enough values:
250 {
251 uint32 sum = 0;
253 sum += m_WaitTimes[team_index][ginfo->BracketId][i];
255 }
256 else
257 return 0;
258}
@ TEAM_NEUTRAL
Definition SharedDefines.h:750
uint8 ArenaType
Definition BattlegroundQueue.h:41
uint8 BracketId
Definition BattlegroundQueue.h:51
bool IsRated
Definition BattlegroundQueue.h:40

References GroupQueueInfo::ArenaType, GroupQueueInfo::BracketId, COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME, GroupQueueInfo::IsRated, m_WaitTimes, TEAM_ALLIANCE, TEAM_HORDE, TEAM_NEUTRAL, and GroupQueueInfo::teamId.

Referenced by WorldSession::HandleBattlefieldStatusOpcode(), WorldSession::HandleBattlemasterJoinArena(), and WorldSession::HandleBattlemasterJoinOpcode().

◆ GetPlayerGroupInfoData()

bool BattlegroundQueue::GetPlayerGroupInfoData ( ObjectGuid  guid,
GroupQueueInfo ginfo 
)

◆ GetPlayersCountInGroupsQueue()

uint32 BattlegroundQueue::GetPlayersCountInGroupsQueue ( BattlegroundBracketId  bracketId,
BattlegroundQueueGroupTypes  bgqueue 
)
1098{
1099 uint32 playersCount = 0;
1100
1101 for (auto const& itr : m_QueuedGroups[bracketId][bgqueue])
1102 if (!itr->IsInvitedToBGInstanceGUID)
1103 playersCount += static_cast<uint32>(itr->Players.size());
1104
1105 return playersCount;
1106}

References m_QueuedGroups.

Referenced by BattlegroundQueueAnnouncerUpdate(), SendJoinMessageArenaQueue(), and SendMessageBGQueue().

◆ GetQueueAnnouncementTimer()

int32 BattlegroundQueue::GetQueueAnnouncementTimer ( uint32  bracketId) const
1298{
1299 return _queueAnnouncementTimer[bracketId];
1300}

References _queueAnnouncementTimer.

◆ InviteGroupToBG()

void BattlegroundQueue::InviteGroupToBG ( GroupQueueInfo ginfo,
Battleground bg,
TeamId  teamId 
)
1303{
1304 // An already-invited group keeps the side it was invited under: writing
1305 // teamId here would split a future re-invite's IncreaseInvitedCount from the
1306 // original side's DecreaseInvitedCount at leave, desyncing the ledger.
1307 if (ginfo->IsInvitedToBGInstanceGUID)
1308 return;
1309
1310 // set side if needed
1311 if (teamId != TEAM_NEUTRAL)
1312 ginfo->teamId = teamId;
1313
1314 // set invitation
1316
1317 BattlegroundTypeId bgTypeId = bg->GetBgTypeID();
1319 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
1320
1321 // set ArenaTeamId for rated matches
1322 if (bg->isArena() && bg->isRated())
1323 bg->SetArenaTeamIdForTeam(ginfo->teamId, ginfo->ArenaTeamId);
1324
1326
1327 // loop through the players
1328 for (auto const& itr : ginfo->Players)
1329 {
1330 // get the player
1332 if (!player)
1333 continue;
1334
1335 // update average wait time
1337
1338 // increase invited counter for each invited player
1339 bg->IncreaseInvitedCount(ginfo->teamId);
1340
1341 player->SetInviteForBattlegroundQueueType(bgQueueTypeId, ginfo->IsInvitedToBGInstanceGUID);
1342
1343 // create remind invite events
1344 BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(player->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->ArenaType, ginfo->RemoveInviteTime);
1345 bgQueue.AddEvent(inviteEvent, INVITATION_REMIND_TIME);
1346
1347 // create automatic remove events
1348 BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(player->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo->RemoveInviteTime);
1349 bgQueue.AddEvent(removeEvent, INVITE_ACCEPT_WAIT_TIME);
1350
1351 // Check queueSlot
1352 uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);
1354
1355 LOG_DEBUG("bg.battleground", "Battleground: invited player {} {} to BG instance {} queueindex {} bgtype {}",
1356 player->GetName(), player->GetGUID().ToString(), bg->GetInstanceID(), queueSlot, bgTypeId);
1357
1358 // send status packet
1359 WorldPacket data;
1360 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType, TEAM_NEUTRAL, bg->isRated());
1361 player->SendDirectMessage(&data);
1362
1363 // pussywizard:
1364 if (bg->isArena() && bg->isRated())
1365 bg->ArenaLogEntries[player->GetGUID()].Fill(player->GetName(), player->GetGUID().GetCounter(), player->GetSession()->GetAccountId(), ginfo->ArenaTeamId, player->GetSession()->GetRemoteAddress());
1366 }
1367}
@ INVITE_ACCEPT_WAIT_TIME
Definition Battleground.h:156
@ INVITATION_REMIND_TIME
Definition Battleground.h:155
@ STATUS_WAIT_JOIN
Definition Battleground.h:192
BattlegroundQueueTypeId
Definition SharedDefines.h:3875
#define PLAYER_MAX_BATTLEGROUND_QUEUES
Definition SharedDefines.h:153
Definition BattlegroundQueue.h:151
Definition BattlegroundQueue.h:174
static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType)
Definition BattlegroundMgr.cpp:685
Definition BattlegroundQueue.h:68
void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo *ginfo)
Definition BattlegroundQueue.cpp:209
void AddEvent(BasicEvent *Event, uint64 e_time)
Definition BattlegroundQueue.cpp:382
ArenaLogEntryDataMap ArenaLogEntries
Definition Battleground.h:422
uint32 GetInstanceID() const
Definition Battleground.h:331
void IncreaseInvitedCount(TeamId teamId)
Definition Battleground.h:395
void SetArenaTeamIdForTeam(TeamId teamId, uint32 ArenaTeamId)
Definition Battleground.h:506
LowType GetCounter() const
Definition ObjectGuid.h:149
std::string ToString() const
Definition ObjectGuid.cpp:48
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5852
WorldSession * GetSession() const
Definition Player.h:2030
uint32 GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:12461
void SetInviteForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, uint32 instanceId)
Definition Player.cpp:12521
std::string const & GetName() const
Definition Object.h:529
Definition WorldPacket.h:26
uint32 GetAccountId() const
Definition WorldSession.h:479
std::string const & GetRemoteAddress()
Definition WorldSession.h:489
Player * FindConnectedPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:281
uint32 IsInvitedToBGInstanceGUID
Definition BattlegroundQueue.h:45
uint32 RemoveInviteTime
Definition BattlegroundQueue.h:44

References AddEvent(), Battleground::ArenaLogEntries, GroupQueueInfo::ArenaTeamId, GroupQueueInfo::ArenaType, ASSERT, BattlegroundMgr::BGQueueTypeId(), GroupQueueInfo::BgTypeId, ObjectAccessor::FindConnectedPlayer(), WorldSession::GetAccountId(), Player::GetBattlegroundQueueIndex(), Battleground::GetBgTypeID(), ObjectGuid::GetCounter(), GameTime::GetGameTimeMS(), Object::GetGUID(), Battleground::GetInstanceID(), WorldObject::GetName(), WorldSession::GetRemoteAddress(), Player::GetSession(), Battleground::IncreaseInvitedCount(), INVITATION_REMIND_TIME, INVITE_ACCEPT_WAIT_TIME, Battleground::isArena(), GroupQueueInfo::IsInvitedToBGInstanceGUID, Battleground::isRated(), LOG_DEBUG, PLAYER_MAX_BATTLEGROUND_QUEUES, PlayerInvitedToBGUpdateAverageWaitTime(), GroupQueueInfo::Players, GroupQueueInfo::RemoveInviteTime, sBattlegroundMgr, Player::SendDirectMessage(), Battleground::SetArenaTeamIdForTeam(), Player::SetInviteForBattlegroundQueueType(), STATUS_WAIT_JOIN, TEAM_NEUTRAL, GroupQueueInfo::teamId, and ObjectGuid::ToString().

Referenced by BattlegroundQueueUpdate().

◆ IsAllQueuesEmpty()

bool BattlegroundQueue::IsAllQueuesEmpty ( BattlegroundBracketId  bracket_id)
1109{
1110 uint8 queueEmptyCount = 0;
1111
1112 for (uint8 i = 0; i < BG_QUEUE_MAX; i++)
1113 if (m_QueuedGroups[bracket_id][i].empty())
1114 queueEmptyCount++;
1115
1116 return queueEmptyCount == BG_QUEUE_MAX;
1117}
@ BG_QUEUE_MAX
Definition BattlegroundQueue.h:64

References BG_QUEUE_MAX, and m_QueuedGroups.

Referenced by BattlegroundQueueUpdate().

◆ IsPlayerInvited()

bool BattlegroundQueue::IsPlayerInvited ( ObjectGuid  pl_guid,
uint32  bgInstanceGuid,
uint32  removeTime 
)
395{
396 auto qItr = m_QueuedPlayers.find(pl_guid);
397 return qItr != m_QueuedPlayers.end() && qItr->second->IsInvitedToBGInstanceGUID == bgInstanceGuid && qItr->second->RemoveInviteTime == removeTime;
398}

References m_QueuedPlayers.

Referenced by BGQueueInviteEvent::Execute(), and BGQueueRemoveEvent::Execute().

◆ IsPlayerInvitedToRatedArena()

bool BattlegroundQueue::IsPlayerInvitedToRatedArena ( ObjectGuid  pl_guid)
388{
389 auto qItr = m_QueuedPlayers.find(pl_guid);
390 return qItr != m_QueuedPlayers.end() && qItr->second->IsRated && qItr->second->IsInvitedToBGInstanceGUID;
391}

References m_QueuedPlayers.

Referenced by WorldSession::HandleBattlemasterJoinArena().

◆ PlayerInvitedToBGUpdateAverageWaitTime()

void BattlegroundQueue::PlayerInvitedToBGUpdateAverageWaitTime ( GroupQueueInfo ginfo)
210{
211 uint32 timeInQueue = std::max<uint32>(1, getMSTimeDiff(ginfo->JoinTime, GameTime::GetGameTimeMS().count()));
212
213 // team_index: bg alliance - TEAM_ALLIANCE, bg horde - TEAM_HORDE, arena skirmish - TEAM_ALLIANCE, arena rated - TEAM_HORDE
214 uint8 team_index;
215 if (!ginfo->ArenaType)
216 team_index = ginfo->teamId;
217 else
218 team_index = (ginfo->IsRated ? TEAM_HORDE : TEAM_ALLIANCE);
219
220 // just to be sure
221 if (team_index >= TEAM_NEUTRAL)
222 return;
223
224 // pointer to last index
225 uint32* lastIndex = &m_WaitTimeLastIndex[team_index][ginfo->BracketId];
226
227 // set time at index to new value
228 m_WaitTimes[team_index][ginfo->BracketId][*lastIndex] = timeInQueue;
229
230 // set last index to next one
231 (*lastIndex)++;
233}
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
Definition Timer.h:110

References GroupQueueInfo::ArenaType, GroupQueueInfo::BracketId, COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME, GameTime::GetGameTimeMS(), getMSTimeDiff(), GroupQueueInfo::IsRated, GroupQueueInfo::JoinTime, m_WaitTimeLastIndex, m_WaitTimes, TEAM_ALLIANCE, TEAM_HORDE, TEAM_NEUTRAL, and GroupQueueInfo::teamId.

Referenced by InviteGroupToBG().

◆ RemovePlayer()

void BattlegroundQueue::RemovePlayer ( ObjectGuid  guid,
bool  decreaseInvitedCount 
)
262{
263 //remove player from map, if he's there
264 auto const& itr = m_QueuedPlayers.find(guid);
265 if (itr == m_QueuedPlayers.end())
266 {
267 //This happens if a player logs out while in a bg because WorldSession::LogoutPlayer() notifies the bg twice
268 std::string playerName = "Unknown";
269
270 if (Player* player = ObjectAccessor::FindPlayer(guid))
271 {
272 playerName = player->GetName();
273 }
274
275 LOG_ERROR("bg.battleground", "BattlegroundQueue: couldn't find player {} ({})", playerName, guid.ToString());
276 //ABORT("BattlegroundQueue: couldn't find player {} ({})", playerName, guid.ToString());
277 return;
278 }
279
280 GroupQueueInfo* groupInfo = itr->second;
281
282 uint32 _bracketId = groupInfo->BracketId;
283 uint32 _groupType = groupInfo->GroupType;
284
285 // find iterator
286 auto group_itr = m_QueuedGroups[_bracketId][_groupType].end();
287
288 for (auto k = m_QueuedGroups[_bracketId][_groupType].begin(); k != m_QueuedGroups[_bracketId][_groupType].end(); k++)
289 if ((*k) == groupInfo)
290 {
291 group_itr = k;
292 break;
293 }
294
295 // player can't be in queue without group, but just in case
296 if (group_itr == m_QueuedGroups[_bracketId][_groupType].end())
297 {
298 LOG_ERROR("bg.battleground", "BattlegroundQueue: ERROR Cannot find groupinfo for {}", guid.ToString());
299 //ABORT("BattlegroundQueue: ERROR Cannot find groupinfo for {}", guid.ToString());
300 return;
301 }
302
303 LOG_DEBUG("bg.battleground", "BattlegroundQueue: Removing {}, from bracket_id {}", guid.ToString(), _bracketId);
304
305 // remove player from group queue info
306 auto const& pitr = groupInfo->Players.find(guid);
307 ASSERT(pitr != groupInfo->Players.end());
308 if (pitr != groupInfo->Players.end())
309 groupInfo->Players.erase(pitr);
310
311 // if invited to bg, and should decrease invited count, then do it
312 if (decreaseInvitedCount && groupInfo->IsInvitedToBGInstanceGUID)
313 {
314 if (Battleground* bg = sBattlegroundMgr->GetBattleground(groupInfo->IsInvitedToBGInstanceGUID, groupInfo->BgTypeId))
315 {
316 bg->DecreaseInvitedCount(groupInfo->teamId);
317
318 // re-enqueue BG if free slots reopened due to invite expiration
319 if (bg->HasFreeSlots())
320 {
321 bg->AddToBGFreeSlotQueue();
322
323 BattlegroundQueueTypeId queueTypeId =
324 BattlegroundMgr::BGQueueTypeId(bg->GetBgTypeID(), bg->GetArenaType());
325
326 sBattlegroundMgr->ScheduleQueueUpdate(0, 0, queueTypeId, bg->GetBgTypeID(), bg->GetBracketId());
327 }
328 }
329 }
330
331 // remove player queue info
332 m_QueuedPlayers.erase(itr);
333
334 // announce to world if arena team left queue for rated match, show only once
335 SendExitMessageArenaQueue(groupInfo);
336
337 // if player leaves queue and he is invited to a rated arena match, then count it as he lost
338 if (groupInfo->IsInvitedToBGInstanceGUID && groupInfo->IsRated && decreaseInvitedCount)
339 {
340 if (ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(groupInfo->ArenaTeamId))
341 {
342 LOG_DEBUG("bg.battleground", "UPDATING memberLost's personal arena rating for {} by opponents rating: {}", guid.ToString(), groupInfo->OpponentsTeamRating);
343
345 {
346 at->MemberLost(player, groupInfo->OpponentsMatchmakerRating);
347 }
348
349 at->SaveToDB();
350 }
351 }
352
353 // remove group queue info no players left
354 if (groupInfo->Players.empty())
355 {
356 m_QueuedGroups[_bracketId][_groupType].erase(group_itr);
357 delete groupInfo;
358 return;
359 }
360
361 // group isn't yet empty, so not deleted yet
362 // if it's a rated arena and any member leaves when group not yet invited - everyone from group leaves too!
363 if (groupInfo->IsRated && !groupInfo->IsInvitedToBGInstanceGUID)
364 {
365 if (Player* plr = ObjectAccessor::FindConnectedPlayer(*(groupInfo->Players.begin())))
366 {
367 Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(groupInfo->BgTypeId);
368 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(groupInfo->BgTypeId, groupInfo->ArenaType);
369 uint32 queueSlot = plr->GetBattlegroundQueueIndex(bgQueueTypeId);
370 plr->RemoveBattlegroundQueueId(bgQueueTypeId);
371
372 WorldPacket data;
373 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, TEAM_NEUTRAL);
374 plr->SendDirectMessage(&data);
375 }
376
377 // recursive call
378 RemovePlayer(*groupInfo->Players.begin(), decreaseInvitedCount);
379 }
380}
#define sArenaTeamMgr
Definition ArenaTeamMgr.h:69
@ STATUS_NONE
Definition Battleground.h:190
Definition ArenaTeam.h:137
void SendExitMessageArenaQueue(GroupQueueInfo *ginfo)
Definition BattlegroundQueue.cpp:1251
void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
Definition BattlegroundQueue.cpp:261
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:269
GuidSet Players
Definition BattlegroundQueue.h:36

References GroupQueueInfo::ArenaTeamId, GroupQueueInfo::ArenaType, ASSERT, BattlegroundMgr::BGQueueTypeId(), GroupQueueInfo::BgTypeId, GroupQueueInfo::BracketId, ObjectAccessor::FindConnectedPlayer(), ObjectAccessor::FindPlayer(), GroupQueueInfo::GroupType, GroupQueueInfo::IsInvitedToBGInstanceGUID, GroupQueueInfo::IsRated, LOG_DEBUG, LOG_ERROR, m_QueuedGroups, m_QueuedPlayers, GroupQueueInfo::OpponentsMatchmakerRating, GroupQueueInfo::OpponentsTeamRating, GroupQueueInfo::Players, RemovePlayer(), sArenaTeamMgr, sBattlegroundMgr, SendExitMessageArenaQueue(), STATUS_NONE, TEAM_NEUTRAL, GroupQueueInfo::teamId, and ObjectGuid::ToString().

Referenced by ArenaTeam::DelMember(), BGQueueRemoveEvent::Execute(), WorldSession::HandleBattleFieldPortOpcode(), and RemovePlayer().

◆ SendExitMessageArenaQueue()

void BattlegroundQueue::SendExitMessageArenaQueue ( GroupQueueInfo ginfo)
1252{
1253 if (!sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE))
1254 return;
1255
1256 if (!sScriptMgr->OnBeforeSendExitMessageArenaQueue(this, ginfo))
1257 return;
1258
1259 ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(ginfo->ArenaTeamId);
1260 if (!team)
1261 return;
1262
1263 if (!ginfo->IsRated)
1264 return;
1265
1266 uint8 ArenaType = ginfo->ArenaType;
1267 uint32 ArenaTeamRating = ginfo->ArenaTeamRating;
1268 std::string TeamName = team->GetName();
1269
1270 if (ArenaType && ginfo->Players.empty())
1271 {
1272 uint32 announcementDetail = sWorld->getIntConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_DETAIL);
1273 switch (announcementDetail)
1274 {
1275 case 3:
1277 break;
1278 case 2:
1280 break;
1281 case 1:
1283 break;
1284 default:
1286 break;
1287 }
1288 }
1289}
ArenaType
Definition Battleground.h:207
@ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT
Definition Language.h:742
@ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT_NAME
Definition Language.h:738
@ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT_RATING
Definition Language.h:740
@ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT_NAME_RATING
Definition Language.h:701
@ ANNOUNCER_FLAG_DISABLE_ARENA_QUEUE
Definition PlayerSettings.h:35
@ CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE
Definition WorldConfig.h:75
@ CONFIG_ARENA_QUEUE_ANNOUNCER_DETAIL
Definition WorldConfig.h:304
std::string const & GetName() const
Definition ArenaTeam.h:154

References ANNOUNCER_FLAG_DISABLE_ARENA_QUEUE, GroupQueueInfo::ArenaTeamId, GroupQueueInfo::ArenaTeamRating, GroupQueueInfo::ArenaType, CONFIG_ARENA_QUEUE_ANNOUNCER_DETAIL, CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE, ArenaTeam::GetName(), GroupQueueInfo::IsRated, LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT_NAME, LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT_NAME_RATING, LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT_RATING, GroupQueueInfo::Players, sArenaTeamMgr, ChatHandler::SendWorldTextOptional(), sScriptMgr, and sWorld.

Referenced by RemovePlayer().

◆ SendJoinMessageArenaQueue()

void BattlegroundQueue::SendJoinMessageArenaQueue ( Player leader,
GroupQueueInfo ginfo,
PvPDifficultyEntry const *  bracketEntry,
bool  isRated 
)
1172{
1173 if (!sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE))
1174 return;
1175
1176 if (!sScriptMgr->OnBeforeSendJoinMessageArenaQueue(this, leader, ginfo, bracketEntry, isRated))
1177 return;
1178
1179 if (!isRated)
1180 {
1181 Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId);
1182 if (!bg)
1183 {
1184 LOG_ERROR("bg.arena", "> Not found bg template for bgtype id {}", uint32(ginfo->BgTypeId));
1185 return;
1186 }
1187
1188 if (!bg->isArena())
1189 {
1190 // Skip announce for non arena
1191 return;
1192 }
1193
1194 BattlegroundBracketId bracketId = bracketEntry->GetBracketId();
1195 auto bgName = bg->GetName();
1196 auto arenatype = Acore::StringFormat("{}v{}", ginfo->ArenaType, ginfo->ArenaType);
1197 uint32 playersNeed = ArenaTeam::GetReqPlayersForType(ginfo->ArenaType);
1198 uint32 q_min_level = std::min(bracketEntry->minLevel, (uint32)80);
1199 uint32 q_max_level = std::min(bracketEntry->maxLevel, (uint32)80);
1201
1202 LOG_DEBUG("bg.arena", "> Queue status for {} (skirmish {}) (Lvl: {} to {}) Queued: {} (Need at least {} more)",
1203 bgName, arenatype, q_min_level, q_max_level, qPlayers, playersNeed - qPlayers);
1204
1206 {
1208 bgName, arenatype, q_min_level, q_max_level, qPlayers, playersNeed - qPlayers);
1209 }
1210 else
1211 {
1212 if (!sBGSpam->CanAnnounce(leader, bg, q_min_level, qPlayers))
1213 {
1214 return;
1215 }
1216
1217 ChatHandler(nullptr).SendWorldTextOptional(LANG_ARENA_QUEUE_ANNOUNCE_WORLD, ANNOUNCER_FLAG_DISABLE_ARENA_QUEUE, bgName.c_str(), arenatype.c_str(), q_min_level, q_max_level, qPlayers, playersNeed);
1218 }
1219 }
1220 else
1221 {
1222 ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(ginfo->ArenaTeamId);
1223 if (!team || !ginfo->IsRated)
1224 {
1225 return;
1226 }
1227
1228 uint8 ArenaType = ginfo->ArenaType;
1229 uint32 ArenaTeamRating = ginfo->ArenaTeamRating;
1230 std::string TeamName = team->GetName();
1231
1232 uint32 announcementDetail = sWorld->getIntConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_DETAIL);
1233 switch (announcementDetail)
1234 {
1235 case 3:
1237 break;
1238 case 2:
1240 break;
1241 case 1:
1243 break;
1244 default:
1246 break;
1247 }
1248 }
1249}
@ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN_NAME_RATING
Definition Language.h:700
@ LANG_ARENA_QUEUE_ANNOUNCE_WORLD
Definition Language.h:694
@ LANG_ARENA_QUEUE_ANNOUNCE_SELF
Definition Language.h:693
@ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN_RATING
Definition Language.h:739
@ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN_NAME
Definition Language.h:737
@ LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN
Definition Language.h:741
@ CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY
Definition WorldConfig.h:76
static uint8 GetReqPlayersForType(uint32 type)
Definition ArenaTeam.cpp:1030
void PSendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:219
std::string StringFormat(FormatStringView fmt, Args &&... args)
Default AC string format function.
Definition StringFormat.h:44

References ANNOUNCER_FLAG_DISABLE_ARENA_QUEUE, GroupQueueInfo::ArenaTeamId, GroupQueueInfo::ArenaTeamRating, GroupQueueInfo::ArenaType, BG_QUEUE_NORMAL_ALLIANCE, BG_QUEUE_NORMAL_HORDE, GroupQueueInfo::BgTypeId, CONFIG_ARENA_QUEUE_ANNOUNCER_DETAIL, CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE, CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY, PvPDifficultyEntry::GetBracketId(), ArenaTeam::GetName(), Battleground::GetName(), GetPlayersCountInGroupsQueue(), ArenaTeam::GetReqPlayersForType(), Player::GetSession(), Battleground::isArena(), GroupQueueInfo::IsRated, LANG_ARENA_QUEUE_ANNOUNCE_SELF, LANG_ARENA_QUEUE_ANNOUNCE_WORLD, LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN_NAME, LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN_NAME_RATING, LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN_RATING, LOG_DEBUG, LOG_ERROR, PvPDifficultyEntry::maxLevel, PvPDifficultyEntry::minLevel, ChatHandler::PSendSysMessage(), sArenaTeamMgr, sBattlegroundMgr, sBGSpam, ChatHandler::SendWorldTextOptional(), sScriptMgr, Acore::StringFormat(), and sWorld.

Referenced by AddGroup().

◆ SendMessageBGQueue()

void BattlegroundQueue::SendMessageBGQueue ( Player leader,
Battleground bg,
PvPDifficultyEntry const *  bracketEntry 
)
1120{
1121 if (!sScriptMgr->CanSendMessageBGQueue(this, leader, bg, bracketEntry))
1122 {
1123 return;
1124 }
1125
1126 if (bg->isArena())
1127 {
1128 // Skip announce for arena skirmish
1129 return;
1130 }
1131
1132 BattlegroundBracketId bracketId = bracketEntry->GetBracketId();
1133 auto bgName = bg->GetName();
1134 uint32 MinPlayers = GetMinPlayersPerTeam(bg, bracketEntry);
1135 uint32 MaxPlayers = MinPlayers * 2;
1136 uint32 q_min_level = std::min(bracketEntry->minLevel, (uint32)80);
1137 uint32 q_max_level = std::min(bracketEntry->maxLevel, (uint32)80);
1140 auto qTotal = qHorde + qAlliance;
1141
1142 LOG_DEBUG("bg.battleground", "> Queue status for {} (Lvl: {} to {}) Queued: {} (Need at least {} more)",
1143 bgName, q_min_level, q_max_level, qAlliance + qHorde, MaxPlayers - qTotal);
1144
1145 // Show queue status to player only (when joining battleground queue or Arena and arena world announcer is disabled)
1147 {
1148 ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level,
1149 qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0,
1150 qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
1151 }
1152 else // Show queue status to server (when joining battleground queue)
1153 {
1155 {
1156 if (_queueAnnouncementTimer[bracketId] < 0)
1157 {
1159 }
1160 }
1161 else
1162 {
1163 // Arm the per-bracket debounce; first join arms, rest are no-ops.
1164 // BattlegroundQueueAnnouncerUpdate emits the aggregated line later.
1165 if (_queueAnnouncementTimer[bracketId] < 0)
1167 }
1168 }
1169}
constexpr int32 BG_QUEUE_ANNOUNCER_IMMEDIATE_DEBOUNCE
Definition BattlegroundQueue.h:32
@ LANG_BG_QUEUE_ANNOUNCE_SELF
Definition Language.h:689
@ CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY
Definition WorldConfig.h:69
@ CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_TIMER
Definition WorldConfig.h:275
void SetQueueAnnouncementTimer(uint32 bracketId, int32 timer, bool isCrossFactionBG=true)
Definition BattlegroundQueue.cpp:1291

References _queueAnnouncementTimer, BG_QUEUE_ANNOUNCER_IMMEDIATE_DEBOUNCE, BG_QUEUE_NORMAL_ALLIANCE, BG_QUEUE_NORMAL_HORDE, CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY, CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_TIMED, CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_TIMER, PvPDifficultyEntry::GetBracketId(), GetMinPlayersPerTeam(), Battleground::GetName(), GetPlayersCountInGroupsQueue(), Player::GetSession(), Battleground::isArena(), LANG_BG_QUEUE_ANNOUNCE_SELF, LOG_DEBUG, PvPDifficultyEntry::maxLevel, PvPDifficultyEntry::minLevel, ChatHandler::PSendSysMessage(), SetQueueAnnouncementTimer(), sScriptMgr, and sWorld.

Referenced by AddGroup().

◆ SetQueueAnnouncementTimer()

void BattlegroundQueue::SetQueueAnnouncementTimer ( uint32  bracketId,
int32  timer,
bool  isCrossFactionBG = true 
)
1292{
1293 _queueAnnouncementTimer[bracketId] = timer;
1294 _queueAnnouncementCrossfactioned = isCrossFactionBG;
1295}

References _queueAnnouncementCrossfactioned, and _queueAnnouncementTimer.

Referenced by SendMessageBGQueue().

◆ UpdateEvents()

void BattlegroundQueue::UpdateEvents ( uint32  diff)
786{
787 m_events.Update(diff);
788}
void Update(uint32 p_time)
Definition EventProcessor.cpp:40

References m_events, and EventProcessor::Update().

Member Data Documentation

◆ _queueAnnouncementCrossfactioned

bool BattlegroundQueue::_queueAnnouncementCrossfactioned
private

◆ _queueAnnouncementTimer

◆ m_events

EventProcessor BattlegroundQueue::m_events
private

◆ m_QueuedGroups

◆ m_QueuedPlayers

◆ m_SelectionPools

◆ m_WaitTimeLastIndex

uint32 BattlegroundQueue::m_WaitTimeLastIndex[PVP_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS]
private

◆ m_WaitTimes


The documentation for this class was generated from the following files: