public ArenaTypes BGArenaType(BattlegroundQueueTypeId bgQueueTypeId) { switch (bgQueueTypeId) { case BattlegroundQueueTypeId.Arena2v2: return(ArenaTypes.Team2v2); case BattlegroundQueueTypeId.Arena3v3: return(ArenaTypes.Team3v3); case BattlegroundQueueTypeId.Arena5v5: return(ArenaTypes.Team5v5); default: return(0); } }
public BattlegroundTypeId BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId) { switch (bgQueueTypeId) { case BattlegroundQueueTypeId.WS: return(BattlegroundTypeId.WS); case BattlegroundQueueTypeId.AB: return(BattlegroundTypeId.AB); case BattlegroundQueueTypeId.AV: return(BattlegroundTypeId.AV); case BattlegroundQueueTypeId.EY: return(BattlegroundTypeId.EY); case BattlegroundQueueTypeId.SA: return(BattlegroundTypeId.SA); case BattlegroundQueueTypeId.IC: return(BattlegroundTypeId.IC); case BattlegroundQueueTypeId.TP: return(BattlegroundTypeId.TP); case BattlegroundQueueTypeId.BFG: return(BattlegroundTypeId.BFG); case BattlegroundQueueTypeId.RB: return(BattlegroundTypeId.RB); case BattlegroundQueueTypeId.Arena2v2: case BattlegroundQueueTypeId.Arena3v3: case BattlegroundQueueTypeId.Arena5v5: return(BattlegroundTypeId.AA); default: return(0); // used for unknown template (it existed and do nothing) } }
// create a new Battleground that will really be used to play public Battleground CreateNewBattleground(BattlegroundQueueTypeId queueId, PvpDifficultyRecord bracketEntry) { BattlegroundTypeId bgTypeId = GetRandomBG((BattlegroundTypeId)queueId.BattlemasterListId); // get the template BG Battleground bg_template = GetBattlegroundTemplate(bgTypeId); if (bg_template == null) { Log.outError(LogFilter.Battleground, "Battleground: CreateNewBattleground - bg template not found for {0}", bgTypeId); return(null); } if (bgTypeId == BattlegroundTypeId.RB || bgTypeId == BattlegroundTypeId.AA || bgTypeId == BattlegroundTypeId.RandomEpic) { return(null); } // create a copy of the BG template Battleground bg = bg_template.GetCopy(); bool isRandom = bgTypeId != (BattlegroundTypeId)queueId.BattlemasterListId && !bg.IsArena(); bg.SetQueueId(queueId); bg.SetBracket(bracketEntry); bg.SetInstanceID(Global.MapMgr.GenerateInstanceId()); bg.SetClientInstanceID(CreateClientVisibleInstanceId((BattlegroundTypeId)queueId.BattlemasterListId, bracketEntry.GetBracketId())); bg.Reset(); // reset the new bg (set status to status_wait_queue from status_none) bg.SetStatus(BattlegroundStatus.WaitJoin); // start the joining of the bg bg.SetArenaType((ArenaTypes)queueId.TeamSize); bg.SetRandomTypeID(bgTypeId); bg.SetRated(queueId.Rated); bg.SetRandom(isRandom); return(bg); }
public void LogoutPlayer(bool save) { // finish pending transfers before starting the logout while (_player && _player.IsBeingTeleportedFar()) { HandleMoveWorldportAck(); } m_playerLogout = true; m_playerSave = save; if (_player) { if (!_player.GetLootGUID().IsEmpty()) { DoLootReleaseAll(); } // If the player just died before logging out, make him appear as a ghost //FIXME: logout must be delayed in case lost connection with client in time of combat if (GetPlayer().GetDeathTimer() != 0) { _player.getHostileRefManager().deleteReferences(); _player.BuildPlayerRepop(); _player.RepopAtGraveyard(); } else if (GetPlayer().HasAuraType(AuraType.SpiritOfRedemption)) { // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION _player.RemoveAurasByType(AuraType.ModShapeshift); _player.KillPlayer(); _player.BuildPlayerRepop(); _player.RepopAtGraveyard(); } else if (GetPlayer().HasPendingBind()) { _player.RepopAtGraveyard(); _player.SetPendingBind(0, 0); } //drop a flag if player is carrying it Battleground bg = GetPlayer().GetBattleground(); if (bg) { bg.EventPlayerLoggedOut(GetPlayer()); } // Teleport to home if the player is in an invalid instance if (!_player.m_InstanceValid && !_player.IsGameMaster()) { _player.TeleportTo(_player.GetHomebind()); } Global.OutdoorPvPMgr.HandlePlayerLeaveZone(_player, _player.GetZoneId()); for (uint i = 0; i < SharedConst.MaxPlayerBGQueues; ++i) { BattlegroundQueueTypeId bgQueueTypeId = GetPlayer().GetBattlegroundQueueTypeId(i); if (bgQueueTypeId != 0) { _player.RemoveBattlegroundQueueId(bgQueueTypeId); BattlegroundQueue queue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); queue.RemovePlayer(_player.GetGUID(), true); } } // Repop at GraveYard or other player far teleport will prevent saving player because of not present map // Teleport player immediately for correct player save while (_player.IsBeingTeleportedFar()) { HandleMoveWorldportAck(); } // If the player is in a guild, update the guild roster and broadcast a logout message to other guild members Guild guild = Global.GuildMgr.GetGuildById(_player.GetGuildId()); if (guild) { guild.HandleMemberLogout(this); } // Remove pet _player.RemovePet(null, PetSaveMode.AsCurrent, true); // Clear whisper whitelist _player.ClearWhisperWhiteList(); // empty buyback items and save the player in the database // some save parts only correctly work in case player present in map/player_lists (pets, etc) if (save) { for (int j = InventorySlots.BuyBackStart; j < InventorySlots.BuyBackEnd; ++j) { int eslot = j - InventorySlots.BuyBackStart; _player.SetGuidValue(PlayerFields.InvSlotHead + (j * 4), ObjectGuid.Empty); _player.SetUInt32Value(PlayerFields.BuyBackPrice1 + eslot, 0); _player.SetUInt32Value(PlayerFields.BuyBackTimestamp1 + eslot, 0); } _player.SaveToDB(); } // Leave all channels before player delete... _player.CleanupChannels(); // If the player is in a group (or invited), remove him. If the group if then only 1 person, disband the group. _player.UninviteFromGroup(); // remove player from the group if he is: // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected) if (_player.GetGroup() && !_player.GetGroup().isRaidGroup() && m_Socket[(int)ConnectionType.Realm] != null) { _player.RemoveFromGroup(); } //! Send update to group and reset stored max enchanting level if (_player.GetGroup()) { _player.GetGroup().SendUpdate(); _player.GetGroup().ResetMaxEnchantingLevel(); } //! Broadcast a logout message to the player's friends Global.SocialMgr.SendFriendStatus(_player, FriendsResult.Offline, _player.GetGUID(), true); _player.RemoveSocial(); //! Call script hook before deletion Global.ScriptMgr.OnPlayerLogout(GetPlayer()); //! Remove the player from the world // the player may not be in the world when logging out // e.g if he got disconnected during a transfer to another map // calls to GetMap in this case may cause crashes GetPlayer().CleanupsBeforeDelete(); Log.outInfo(LogFilter.Player, "Account: {0} (IP: {1}) Logout Character:[{2}] (GUID: {3}) Level: {4}", GetAccountId(), GetRemoteAddress(), _player.GetName(), _player.GetGUID().ToString(), _player.getLevel()); Map map = GetPlayer().GetMap(); if (map != null) { map.RemovePlayerFromMap(GetPlayer(), true); } SetPlayer(null); //! Send the 'logout complete' packet to the client //! Client will respond by sending 3x CMSG_CANCEL_TRADE, which we currently dont handle LogoutComplete logoutComplete = new LogoutComplete(); SendPacket(logoutComplete); //! Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_ACCOUNT_ONLINE); stmt.AddValue(0, GetAccountId()); DB.Characters.Execute(stmt); } if (m_Socket[(int)ConnectionType.Instance] != null) { m_Socket[(int)ConnectionType.Instance].CloseSocket(); m_Socket[(int)ConnectionType.Instance] = null; } m_playerLogout = false; m_playerSave = false; m_playerRecentlyLogout = true; SetLogoutStartTime(0); }
void HandleBattlemasterJoin(BattlemasterJoin battlemasterJoin) { bool isPremade = false; Group grp = null; BattlefieldStatusFailed battlefieldStatusFailed; uint bgTypeId_ = (uint)(battlemasterJoin.QueueID & 0xFFFF); if (!CliDB.BattlemasterListStorage.ContainsKey(bgTypeId_)) { Log.outError(LogFilter.Network, "Battleground: invalid bgtype ({0}) received. possible cheater? player guid {1}", bgTypeId_, GetPlayer().GetGUID().ToString()); return; } if (Global.DisableMgr.IsDisabledFor(DisableType.Battleground, bgTypeId_, null)) { GetPlayer().SendSysMessage(CypherStrings.BgDisabled); return; } BattlegroundTypeId bgTypeId = (BattlegroundTypeId)bgTypeId_; // can do this, since it's Battleground, not arena BattlegroundQueueTypeId bgQueueTypeId = Global.BattlegroundMgr.BGQueueTypeId(bgTypeId, 0); BattlegroundQueueTypeId bgQueueTypeIdRandom = Global.BattlegroundMgr.BGQueueTypeId(BattlegroundTypeId.RB, 0); // ignore if player is already in BG if (GetPlayer().InBattleground()) { return; } // get bg instance or bg template if instance not found Battleground bg = Global.BattlegroundMgr.GetBattlegroundTemplate(bgTypeId); if (!bg) { return; } // expected bracket entry PVPDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel()); if (bracketEntry == null) { return; } GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult.None; // check queue conditions if (!battlemasterJoin.JoinAsGroup) { if (GetPlayer().isUsingLfg()) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.LfgCantUseBattleground); SendPacket(battlefieldStatusFailed); return; } // check Deserter debuff if (!GetPlayer().CanJoinToBattleground(bg)) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.Deserters); SendPacket(battlefieldStatusFailed); return; } if (GetPlayer().GetBattlegroundQueueIndex(bgQueueTypeIdRandom) < SharedConst.MaxPlayerBGQueues) { // player is already in random queue Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.InRandomBg); SendPacket(battlefieldStatusFailed); return; } if (GetPlayer().InBattlegroundQueue() && bgTypeId == BattlegroundTypeId.RB) { // player is already in queue, can't start random queue Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.InNonRandomBg); SendPacket(battlefieldStatusFailed); return; } // check if already in queue if (GetPlayer().GetBattlegroundQueueIndex(bgQueueTypeId) < SharedConst.MaxPlayerBGQueues) { return; // player is already in this queue } // check if has free queue slots if (!GetPlayer().HasFreeBattlegroundQueueId()) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.TooManyQueues); SendPacket(battlefieldStatusFailed); return; } // check Freeze debuff if (_player.HasAura(9454)) { return; } BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo ginfo = bgQueue.AddGroup(GetPlayer(), null, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); uint avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); uint queueSlot = GetPlayer().AddBattlegroundQueueId(bgQueueTypeId); BattlefieldStatusQueued battlefieldStatusQueued; Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, GetPlayer(), queueSlot, ginfo.JoinTime, avgTime, ginfo.ArenaType, false); SendPacket(battlefieldStatusQueued); Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for bg queue type {0} bg type {1}: GUID {2}, NAME {3}", bgQueueTypeId, bgTypeId, GetPlayer().GetGUID().ToString(), GetPlayer().GetName()); } else { grp = GetPlayer().GetGroup(); if (!grp) { return; } if (grp.GetLeaderGUID() != GetPlayer().GetGUID()) { return; } ObjectGuid errorGuid; err = grp.CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg.GetMaxPlayersPerTeam(), false, 0, out errorGuid); isPremade = (grp.GetMembersCount() >= bg.GetMinPlayersPerTeam()); BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo ginfo = null; uint avgTime = 0; if (err == 0) { Log.outDebug(LogFilter.Battleground, "Battleground: the following players are joining as group:"); ginfo = bgQueue.AddGroup(GetPlayer(), grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); } for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.next()) { Player member = refe.GetSource(); if (!member) { continue; // this should never happen } if (err != 0) { BattlefieldStatusFailed battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bg, GetPlayer(), 0, 0, err, errorGuid); member.SendPacket(battlefieldStatus); continue; } // add to queue uint queueSlot = member.AddBattlegroundQueueId(bgQueueTypeId); BattlefieldStatusQueued battlefieldStatusQueued; Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, member, queueSlot, ginfo.JoinTime, avgTime, ginfo.ArenaType, true); member.SendPacket(battlefieldStatusQueued); Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for bg queue type {0} bg type {1}: GUID {2}, NAME {3}", bgQueueTypeId, bgTypeId, member.GetGUID().ToString(), member.GetName()); } Log.outDebug(LogFilter.Battleground, "Battleground: group end"); } Global.BattlegroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry.GetBracketId()); }
void HandleBattlemasterJoinArena(BattlemasterJoinArena packet) { // ignore if we already in BG or BG queue if (GetPlayer().InBattleground()) { return; } ArenaTypes arenatype = (ArenaTypes)ArenaTeam.GetTypeBySlot(packet.TeamSizeIndex); //check existence Battleground bg = Global.BattlegroundMgr.GetBattlegroundTemplate(BattlegroundTypeId.AA); if (!bg) { Log.outError(LogFilter.Network, "Battleground: template bg (all arenas) not found"); return; } if (Global.DisableMgr.IsDisabledFor(DisableType.Battleground, (uint)BattlegroundTypeId.AA, null)) { GetPlayer().SendSysMessage(CypherStrings.ArenaDisabled); return; } BattlegroundTypeId bgTypeId = bg.GetTypeID(); BattlegroundQueueTypeId bgQueueTypeId = Global.BattlegroundMgr.BGQueueTypeId(bgTypeId, arenatype); PVPDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel()); if (bracketEntry == null) { return; } Group grp = GetPlayer().GetGroup(); // no group found, error if (!grp) { return; } if (grp.GetLeaderGUID() != GetPlayer().GetGUID()) { return; } uint ateamId = GetPlayer().GetArenaTeamId(packet.TeamSizeIndex); // check real arenateam existence only here (if it was moved to group.CanJoin .. () then we would ahve to get it twice) ArenaTeam at = Global.ArenaTeamMgr.GetArenaTeamById(ateamId); if (at == null) { GetPlayer().GetSession().SendNotInArenaTeamPacket(arenatype); return; } // get the team rating for queuing uint arenaRating = at.GetRating(); uint matchmakerRating = at.GetAverageMMR(grp); // the arenateam id must match for everyone in the group if (arenaRating <= 0) { arenaRating = 1; } BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); uint avgTime = 0; GroupQueueInfo ginfo = null; ObjectGuid errorGuid; var err = grp.CanJoinBattlegroundQueue(bg, bgQueueTypeId, (uint)arenatype, (uint)arenatype, true, packet.TeamSizeIndex, out errorGuid); if (err == 0) { Log.outDebug(LogFilter.Battleground, "Battleground: arena team id {0}, leader {1} queued with matchmaker rating {2} for type {3}", GetPlayer().GetArenaTeamId(packet.TeamSizeIndex), GetPlayer().GetName(), matchmakerRating, arenatype); ginfo = bgQueue.AddGroup(GetPlayer(), grp, bgTypeId, bracketEntry, arenatype, true, false, arenaRating, matchmakerRating, ateamId); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); } for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.next()) { Player member = refe.GetSource(); if (!member) { continue; } if (err != 0) { BattlefieldStatusFailed battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bg, GetPlayer(), 0, arenatype, err, errorGuid); member.SendPacket(battlefieldStatus); continue; } // add to queue uint queueSlot = member.AddBattlegroundQueueId(bgQueueTypeId); BattlefieldStatusQueued battlefieldStatusQueued; Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, member, queueSlot, ginfo.JoinTime, avgTime, arenatype, true); member.SendPacket(battlefieldStatusQueued); Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for arena as group bg queue type {0} bg type {1}: GUID {2}, NAME {3}", bgQueueTypeId, bgTypeId, member.GetGUID().ToString(), member.GetName()); } Global.BattlegroundMgr.ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry.GetBracketId()); }
void HandleRequestBattlefieldStatus(RequestBattlefieldStatus packet) { // we must update all queues here Battleground bg = null; for (byte i = 0; i < SharedConst.MaxPlayerBGQueues; ++i) { BattlegroundQueueTypeId bgQueueTypeId = GetPlayer().GetBattlegroundQueueTypeId(i); if (bgQueueTypeId == 0) { continue; } BattlegroundTypeId bgTypeId = Global.BattlegroundMgr.BGTemplateId(bgQueueTypeId); ArenaTypes arenaType = Global.BattlegroundMgr.BGArenaType(bgQueueTypeId); if (bgTypeId == GetPlayer().GetBattlegroundTypeId()) { bg = GetPlayer().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) { BattlefieldStatusActive battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusActive(out battlefieldStatus, bg, GetPlayer(), i, GetPlayer().GetBattlegroundQueueJoinTime(bgQueueTypeId), arenaType); SendPacket(battlefieldStatus); continue; } } //we are sending update to player about queue - he can be invited there! //get GroupQueueInfo for queue status BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo ginfo; if (!bgQueue.GetPlayerGroupInfoData(GetPlayer().GetGUID(), out ginfo)) { continue; } if (ginfo.IsInvitedToBGInstanceGUID != 0) { bg = Global.BattlegroundMgr.GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId); if (!bg) { continue; } BattlefieldStatusNeedConfirmation battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusNeedConfirmation(out battlefieldStatus, bg, GetPlayer(), i, GetPlayer().GetBattlegroundQueueJoinTime(bgQueueTypeId), Time.GetMSTimeDiff(Time.GetMSTime(), ginfo.RemoveInviteTime), arenaType); SendPacket(battlefieldStatus); } else { bg = Global.BattlegroundMgr.GetBattlegroundTemplate(bgTypeId); if (!bg) { continue; } // expected bracket entry PVPDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel()); if (bracketEntry == null) { continue; } uint avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); BattlefieldStatusQueued battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatus, bg, GetPlayer(), i, GetPlayer().GetBattlegroundQueueJoinTime(bgQueueTypeId), avgTime, arenaType, ginfo.Players.Count > 1); SendPacket(battlefieldStatus); } } }
void HandleBattleFieldPort(BattlefieldPort battlefieldPort) { if (!GetPlayer().InBattlegroundQueue()) { Log.outDebug(LogFilter.Battleground, "CMSG_BATTLEFIELD_PORT {0} Slot: {1}, Unk: {2}, Time: {3}, AcceptedInvite: {4}. Player not in queue!", GetPlayerInfo(), battlefieldPort.Ticket.Id, battlefieldPort.Ticket.Type, battlefieldPort.Ticket.Time, battlefieldPort.AcceptedInvite); return; } BattlegroundQueueTypeId bgQueueTypeId = GetPlayer().GetBattlegroundQueueTypeId(battlefieldPort.Ticket.Id); if (bgQueueTypeId == BattlegroundQueueTypeId.None) { Log.outDebug(LogFilter.Battleground, "CMSG_BATTLEFIELD_PORT {0} Slot: {1}, Unk: {2}, Time: {3}, AcceptedInvite: {4}. Invalid queueSlot!", GetPlayerInfo(), battlefieldPort.Ticket.Id, battlefieldPort.Ticket.Type, battlefieldPort.Ticket.Time, battlefieldPort.AcceptedInvite); return; } BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); //we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattlegroundQueue.RemovePlayer() function GroupQueueInfo ginfo; if (!bgQueue.GetPlayerGroupInfoData(GetPlayer().GetGUID(), out ginfo)) { Log.outDebug(LogFilter.Battleground, "CMSG_BATTLEFIELD_PORT {0} Slot: {1}, Unk: {2}, Time: {3}, AcceptedInvite: {4}. Player not in queue (No player Group Info)!", GetPlayerInfo(), battlefieldPort.Ticket.Id, battlefieldPort.Ticket.Type, battlefieldPort.Ticket.Time, battlefieldPort.AcceptedInvite); return; } // if action == 1, then instanceId is required if (ginfo.IsInvitedToBGInstanceGUID == 0 && battlefieldPort.AcceptedInvite) { Log.outDebug(LogFilter.Battleground, "CMSG_BATTLEFIELD_PORT {0} Slot: {1}, Unk: {2}, Time: {3}, AcceptedInvite: {4}. Player is not invited to any bg!", GetPlayerInfo(), battlefieldPort.Ticket.Id, battlefieldPort.Ticket.Type, battlefieldPort.Ticket.Time, battlefieldPort.AcceptedInvite); return; } BattlegroundTypeId bgTypeId = Global.BattlegroundMgr.BGTemplateId(bgQueueTypeId); // BGTemplateId returns Battleground_AA when it is arena queue. // Do instance id search as there is no AA bg instances. Battleground bg = Global.BattlegroundMgr.GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId == BattlegroundTypeId.AA ? BattlegroundTypeId.None : bgTypeId); if (!bg) { if (battlefieldPort.AcceptedInvite) { Log.outDebug(LogFilter.Battleground, "CMSG_BATTLEFIELD_PORT {0} Slot: {1}, Unk: {2}, Time: {3}, AcceptedInvite: {4}. Cant find BG with id {5}!", GetPlayerInfo(), battlefieldPort.Ticket.Id, battlefieldPort.Ticket.Type, battlefieldPort.Ticket.Time, battlefieldPort.AcceptedInvite, ginfo.IsInvitedToBGInstanceGUID); return; } bg = Global.BattlegroundMgr.GetBattlegroundTemplate(bgTypeId); if (!bg) { Log.outError(LogFilter.Network, "BattlegroundHandler: bg_template not found for type id {0}.", bgTypeId); return; } } // get real bg type bgTypeId = bg.GetTypeID(); // expected bracket entry PVPDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel()); if (bracketEntry == null) { return; } //some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it if (battlefieldPort.AcceptedInvite && ginfo.ArenaType == 0) { //if player is trying to enter Battleground(not arena!) and he has deserter debuff, we must just remove him from queue if (!GetPlayer().CanJoinToBattleground(bg)) { // send bg command result to show nice message BattlefieldStatusFailed battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bg, GetPlayer(), battlefieldPort.Ticket.Id, 0, GroupJoinBattlegroundResult.Deserters); SendPacket(battlefieldStatus); battlefieldPort.AcceptedInvite = false; Log.outDebug(LogFilter.Battleground, "Player {0} ({1}) has a deserter debuff, do not port him to Battleground!", GetPlayer().GetName(), GetPlayer().GetGUID().ToString()); } //if player don't match Battlegroundmax level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue if (GetPlayer().getLevel() > bg.GetMaxLevel()) { Log.outDebug(LogFilter.Network, "Player {0} ({1}) has level ({2}) higher than maxlevel ({3}) of Battleground({4})! Do not port him to Battleground!", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), GetPlayer().getLevel(), bg.GetMaxLevel(), bg.GetTypeID()); battlefieldPort.AcceptedInvite = false; } } if (battlefieldPort.AcceptedInvite) { // check Freeze debuff if (GetPlayer().HasAura(9454)) { return; } if (!GetPlayer().IsInvitedForBattlegroundQueueType(bgQueueTypeId)) { return; // cheating? } if (!GetPlayer().InBattleground()) { GetPlayer().SetBattlegroundEntryPoint(); } // resurrect the player if (!GetPlayer().IsAlive()) { GetPlayer().ResurrectPlayer(1.0f); GetPlayer().SpawnCorpseBones(); } // stop taxi flight at port if (GetPlayer().IsInFlight()) { GetPlayer().GetMotionMaster().MovementExpired(); GetPlayer().CleanupAfterTaxiFlight(); } BattlefieldStatusActive battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusActive(out battlefieldStatus, bg, GetPlayer(), battlefieldPort.Ticket.Id, GetPlayer().GetBattlegroundQueueJoinTime(bgQueueTypeId), bg.GetArenaType()); SendPacket(battlefieldStatus); // remove BattlegroundQueue status from BGmgr bgQueue.RemovePlayer(GetPlayer().GetGUID(), false); // this is still needed here if Battleground"jumping" shouldn't add deserter debuff // also this is required to prevent stuck at old Battlegroundafter SetBattlegroundId set to new Battleground currentBg = GetPlayer().GetBattleground(); if (currentBg) { currentBg.RemovePlayerAtLeave(GetPlayer().GetGUID(), false, true); } // set the destination instance id GetPlayer().SetBattlegroundId(bg.GetInstanceID(), bgTypeId); // set the destination team GetPlayer().SetBGTeam(ginfo.Team); Global.BattlegroundMgr.SendToBattleground(GetPlayer(), ginfo.IsInvitedToBGInstanceGUID, bgTypeId); Log.outDebug(LogFilter.Battleground, "Battleground: player {0} ({1}) joined battle for bg {2}, bgtype {3}, queue type {4}.", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), bg.GetInstanceID(), bg.GetTypeID(), bgQueueTypeId); } else // leave queue { // if player leaves rated arena match before match start, it is counted as he played but he lost if (ginfo.IsRated && ginfo.IsInvitedToBGInstanceGUID != 0) { ArenaTeam at = Global.ArenaTeamMgr.GetArenaTeamById((uint)ginfo.Team); if (at != null) { Log.outDebug(LogFilter.Battleground, "UPDATING memberLost's personal arena rating for {0} by opponents rating: {1}, because he has left queue!", GetPlayer().GetGUID().ToString(), ginfo.OpponentsTeamRating); at.MemberLost(GetPlayer(), ginfo.OpponentsMatchmakerRating); at.SaveToDB(); } } BattlefieldStatusNone battlefieldStatus = new BattlefieldStatusNone(); battlefieldStatus.Ticket = battlefieldPort.Ticket; SendPacket(battlefieldStatus); GetPlayer().RemoveBattlegroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue.removeplayer, it causes bugs bgQueue.RemovePlayer(GetPlayer().GetGUID(), true); // player left queue, we should update it - do not update Arena Queue if (ginfo.ArenaType == 0) { Global.BattlegroundMgr.ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry.GetBracketId()); } Log.outDebug(LogFilter.Battleground, "Battleground: player {0} ({1}) left queue for bgtype {2}, queue type {3}.", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), bg.GetTypeID(), bgQueueTypeId); } }
public bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) { return(GetBattlegroundQueueIndex(bgQueueTypeId) < SharedConst.MaxPlayerBGQueues); }
public void BuildBattlegroundStatusFailed(out BattlefieldStatusFailed battlefieldStatus, BattlegroundQueueTypeId queueId, Player pPlayer, uint ticketId, GroupJoinBattlegroundResult result, ObjectGuid errorGuid = default) { battlefieldStatus = new BattlefieldStatusFailed(); battlefieldStatus.Ticket.RequesterGuid = pPlayer.GetGUID(); battlefieldStatus.Ticket.Id = ticketId; battlefieldStatus.Ticket.Type = RideType.Battlegrounds; battlefieldStatus.Ticket.Time = (int)pPlayer.GetBattlegroundQueueJoinTime(queueId); battlefieldStatus.QueueID = queueId.GetPacked(); battlefieldStatus.Reason = (int)result; if (!errorGuid.IsEmpty() && (result == GroupJoinBattlegroundResult.NotInBattleground || result == GroupJoinBattlegroundResult.JoinTimedOut)) { battlefieldStatus.ClientID = errorGuid; } }
public void ScheduleQueueUpdate(uint arenaMatchmakerRating, ArenaTypes arenaType, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id) { //we will use only 1 number created of bgTypeId and bracket_id ulong scheduleId = ((ulong)arenaMatchmakerRating << 32) | ((uint)arenaType << 24) | ((uint)bgQueueTypeId << 16) | ((uint)bgTypeId << 8) | (uint)bracket_id; if (!m_QueueUpdateScheduler.Contains(scheduleId)) { m_QueueUpdateScheduler.Add(scheduleId); } }
public void AddToBGFreeSlotQueue(BattlegroundQueueTypeId bgTypeId, Battleground bg) { m_BGFreeSlotQueue.Add(bgTypeId, bg); }
public List <Battleground> GetBGFreeSlotQueueStore(BattlegroundQueueTypeId bgTypeId) { return(m_BGFreeSlotQueue[bgTypeId]); }
public bool IsValidQueueId(BattlegroundQueueTypeId bgQueueTypeId) { BattlemasterListRecord battlemasterList = CliDB.BattlemasterListStorage.LookupByKey(bgQueueTypeId.BattlemasterListId); if (battlemasterList == null) { return(false); } switch ((BattlegroundQueueIdType)bgQueueTypeId.BgType) { case BattlegroundQueueIdType.Battleground: if (battlemasterList.InstanceType != (int)MapTypes.Battleground) { return(false); } if (bgQueueTypeId.TeamSize != 0) { return(false); } break; case BattlegroundQueueIdType.Arena: if (battlemasterList.InstanceType != (int)MapTypes.Arena) { return(false); } if (!bgQueueTypeId.Rated) { return(false); } if (bgQueueTypeId.TeamSize == 0) { return(false); } break; case BattlegroundQueueIdType.Wargame: if (bgQueueTypeId.Rated) { return(false); } break; case BattlegroundQueueIdType.ArenaSkirmish: if (battlemasterList.InstanceType != (int)MapTypes.Arena) { return(false); } if (bgQueueTypeId.Rated) { return(false); } if (bgQueueTypeId.TeamSize != 0) { return(false); } break; default: return(false); } return(true); }
public void Update(uint diff) { m_UpdateTimer += diff; if (m_UpdateTimer > 1000) { foreach (var data in bgDataStore.Values) { var bgs = data.m_Battlegrounds; // first one is template and should not be deleted foreach (var pair in bgs.ToList()) { Battleground bg = pair.Value; bg.Update(m_UpdateTimer); if (bg.ToBeDeleted()) { bgs.Remove(pair.Key); var clients = data.m_ClientBattlegroundIds[(int)bg.GetBracketId()]; if (!clients.Empty()) { clients.Remove(bg.GetClientInstanceID()); } bg.Dispose(); } } } m_UpdateTimer = 0; } // update events timer foreach (var pair in m_BattlegroundQueues) { pair.Value.UpdateEvents(diff); } // update scheduled queues if (!m_QueueUpdateScheduler.Empty()) { List <ScheduledQueueUpdate> scheduled = new(); Extensions.Swap(ref scheduled, ref m_QueueUpdateScheduler); for (byte i = 0; i < scheduled.Count; i++) { uint arenaMMRating = scheduled[i].ArenaMatchmakerRating; BattlegroundQueueTypeId bgQueueTypeId = scheduled[i].QueueId; BattlegroundBracketId bracket_id = scheduled[i].BracketId; GetBattlegroundQueue(bgQueueTypeId).BattlegroundQueueUpdate(diff, bracket_id, arenaMMRating); } } // if rating difference counts, maybe force-update queues if (WorldConfig.GetIntValue(WorldCfg.ArenaMaxRatingDifference) != 0 && WorldConfig.GetIntValue(WorldCfg.ArenaRatedUpdateTimer) != 0) { // it's time to force update if (m_NextRatedArenaUpdate < diff) { // forced update for rated arenas (scan all, but skipped non rated) Log.outDebug(LogFilter.Arena, "BattlegroundMgr: UPDATING ARENA QUEUES"); foreach (ArenaTypes teamSize in new[] { ArenaTypes.Team2v2, ArenaTypes.Team3v3, ArenaTypes.Team5v5 }) { BattlegroundQueueTypeId ratedArenaQueueId = BGQueueTypeId((ushort)BattlegroundTypeId.AA, BattlegroundQueueIdType.Arena, true, teamSize); for (var bracket = BattlegroundBracketId.First; bracket < BattlegroundBracketId.Max; ++bracket) { GetBattlegroundQueue(ratedArenaQueueId).BattlegroundQueueUpdate(diff, bracket, 0); } } m_NextRatedArenaUpdate = WorldConfig.GetUIntValue(WorldCfg.ArenaRatedUpdateTimer); } else { m_NextRatedArenaUpdate -= diff; } } }
public void Update(uint diff) { m_UpdateTimer += diff; if (m_UpdateTimer > 1000) { foreach (var data in bgDataStore.Values) { var bgs = data.m_Battlegrounds; // first one is template and should not be deleted foreach (var pair in bgs.ToList()) { Battleground bg = pair.Value; bg.Update(m_UpdateTimer); if (bg.ToBeDeleted()) { bgs.Remove(pair.Key); var clients = data.m_ClientBattlegroundIds[(int)bg.GetBracketId()]; if (!clients.Empty()) { clients.Remove(bg.GetClientInstanceID()); } bg.Dispose(); } } } m_UpdateTimer = 0; } // update events timer for (var qtype = BattlegroundQueueTypeId.None; qtype < BattlegroundQueueTypeId.Max; ++qtype) { m_BattlegroundQueues[(int)qtype].UpdateEvents(diff); } // update scheduled queues if (!m_QueueUpdateScheduler.Empty()) { List <ulong> scheduled = new List <ulong>(); Extensions.Swap(ref scheduled, ref m_QueueUpdateScheduler); for (byte i = 0; i < scheduled.Count; i++) { uint arenaMMRating = (uint)(scheduled[i] >> 32); byte arenaType = (byte)(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[(int)bgQueueTypeId].BattlegroundQueueUpdate(diff, bgTypeId, bracket_id, arenaType, arenaMMRating > 0, arenaMMRating); } } // if rating difference counts, maybe force-update queues if (WorldConfig.GetIntValue(WorldCfg.ArenaMaxRatingDifference) != 0 && WorldConfig.GetIntValue(WorldCfg.ArenaRatedUpdateTimer) != 0) { // it's time to force update if (m_NextRatedArenaUpdate < diff) { // forced update for rated arenas (scan all, but skipped non rated) Log.outDebug(LogFilter.Arena, "BattlegroundMgr: UPDATING ARENA QUEUES"); for (var qtype = BattlegroundQueueTypeId.Arena2v2; qtype <= BattlegroundQueueTypeId.Arena5v5; ++qtype) { for (int bracket = (int)BattlegroundBracketId.First; bracket < (int)BattlegroundBracketId.Max; ++bracket) { m_BattlegroundQueues[(int)qtype].BattlegroundQueueUpdate(diff, BattlegroundTypeId.AA, (BattlegroundBracketId)bracket, (byte)BGArenaType(qtype), true, 0); } } m_NextRatedArenaUpdate = WorldConfig.GetUIntValue(WorldCfg.ArenaRatedUpdateTimer); } else { m_NextRatedArenaUpdate -= diff; } } }
void BuildBattlegroundStatusHeader(BattlefieldStatusHeader header, Battleground bg, Player player, uint ticketId, uint joinTime, BattlegroundQueueTypeId queueId, ArenaTypes arenaType) { header.Ticket = new RideTicket(); header.Ticket.RequesterGuid = player.GetGUID(); header.Ticket.Id = ticketId; header.Ticket.Type = RideType.Battlegrounds; header.Ticket.Time = (int)joinTime; header.QueueID.Add(queueId.GetPacked()); header.RangeMin = (byte)bg.GetMinLevel(); header.RangeMax = (byte)bg.GetMaxLevel(); header.TeamSize = (byte)(bg.IsArena() ? arenaType : 0); header.InstanceID = bg.GetClientInstanceID(); header.RegisteredMatch = bg.IsRated(); header.TournamentRules = false; }
public ScheduledQueueUpdate(uint arenaMatchmakerRating, BattlegroundQueueTypeId queueId, BattlegroundBracketId bracketId) { ArenaMatchmakerRating = arenaMatchmakerRating; QueueId = queueId; BracketId = bracketId; }
public void BuildBattlegroundStatusQueued(out BattlefieldStatusQueued battlefieldStatus, Battleground bg, Player player, uint ticketId, uint joinTime, BattlegroundQueueTypeId queueId, uint avgWaitTime, ArenaTypes arenaType, bool asGroup) { battlefieldStatus = new BattlefieldStatusQueued(); BuildBattlegroundStatusHeader(battlefieldStatus.Hdr, bg, player, ticketId, joinTime, queueId, arenaType); battlefieldStatus.AverageWaitTime = avgWaitTime; battlefieldStatus.AsGroup = asGroup; battlefieldStatus.SuspendedQueue = false; battlefieldStatus.EligibleForMatchmaking = true; battlefieldStatus.WaitTime = Time.GetMSTimeDiffToNow(joinTime); }
public BattlegroundQueue GetBattlegroundQueue(BattlegroundQueueTypeId bgQueueTypeId) { return(m_BattlegroundQueues[(int)bgQueueTypeId]); }
void HandleBattlemasterJoin(BattlemasterJoin battlemasterJoin) { bool isPremade = false; if (battlemasterJoin.QueueIDs.Empty()) { Log.outError(LogFilter.Network, $"Battleground: no bgtype received. possible cheater? {_player.GetGUID()}"); return; } BattlegroundQueueTypeId bgQueueTypeId = BattlegroundQueueTypeId.FromPacked(battlemasterJoin.QueueIDs[0]); if (!Global.BattlegroundMgr.IsValidQueueId(bgQueueTypeId)) { Log.outError(LogFilter.Network, $"Battleground: invalid bg queue {bgQueueTypeId} received. possible cheater? {_player.GetGUID()}"); return; } BattlemasterListRecord battlemasterListEntry = CliDB.BattlemasterListStorage.LookupByKey(bgQueueTypeId.BattlemasterListId); if (Global.DisableMgr.IsDisabledFor(DisableType.Battleground, bgQueueTypeId.BattlemasterListId, null) || battlemasterListEntry.Flags.HasAnyFlag(BattlemasterListFlags.Disabled)) { GetPlayer().SendSysMessage(CypherStrings.BgDisabled); return; } BattlegroundTypeId bgTypeId = (BattlegroundTypeId)bgQueueTypeId.BattlemasterListId; // ignore if player is already in BG if (GetPlayer().InBattleground()) { return; } // get bg instance or bg template if instance not found Battleground bg = Global.BattlegroundMgr.GetBattlegroundTemplate(bgTypeId); if (!bg) { return; } // expected bracket entry PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().GetLevel()); if (bracketEntry == null) { return; } GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult.None; Group grp = _player.GetGroup(); BattlefieldStatusFailed battlefieldStatusFailed; // check queue conditions if (grp == null) { if (GetPlayer().IsUsingLfg()) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, GroupJoinBattlegroundResult.LfgCantUseBattleground); SendPacket(battlefieldStatusFailed); return; } // check Deserter debuff if (!GetPlayer().CanJoinToBattleground(bg)) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, GroupJoinBattlegroundResult.Deserters); SendPacket(battlefieldStatusFailed); return; } bool isInRandomBgQueue = _player.InBattlegroundQueueForBattlegroundQueueType(Global.BattlegroundMgr.BGQueueTypeId((ushort)BattlegroundTypeId.RB, BattlegroundQueueIdType.Battleground, false, 0)) || _player.InBattlegroundQueueForBattlegroundQueueType(Global.BattlegroundMgr.BGQueueTypeId((ushort)BattlegroundTypeId.RandomEpic, BattlegroundQueueIdType.Battleground, false, 0)); if (bgTypeId != BattlegroundTypeId.RB && bgTypeId != BattlegroundTypeId.RandomEpic && isInRandomBgQueue) { // player is already in random queue Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, GroupJoinBattlegroundResult.InRandomBg); SendPacket(battlefieldStatusFailed); return; } if (_player.InBattlegroundQueue() && !isInRandomBgQueue && (bgTypeId == BattlegroundTypeId.RB || bgTypeId == BattlegroundTypeId.RandomEpic)) { // player is already in queue, can't start random queue Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, GroupJoinBattlegroundResult.InNonRandomBg); SendPacket(battlefieldStatusFailed); return; } // check if already in queue if (GetPlayer().GetBattlegroundQueueIndex(bgQueueTypeId) < SharedConst.MaxPlayerBGQueues) { return; // player is already in this queue } // check if has free queue slots if (!GetPlayer().HasFreeBattlegroundQueueId()) { Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, GroupJoinBattlegroundResult.TooManyQueues); SendPacket(battlefieldStatusFailed); return; } // check Freeze debuff if (_player.HasAura(9454)) { return; } BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo ginfo = bgQueue.AddGroup(GetPlayer(), null, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); uint avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); uint queueSlot = GetPlayer().AddBattlegroundQueueId(bgQueueTypeId); Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out BattlefieldStatusQueued battlefieldStatusQueued, bg, GetPlayer(), queueSlot, ginfo.JoinTime, bgQueueTypeId, avgTime, ginfo.ArenaType, false); SendPacket(battlefieldStatusQueued); Log.outDebug(LogFilter.Battleground, $"Battleground: player joined queue for bg queue {bgQueueTypeId}, {_player.GetGUID()}, NAME {_player.GetName()}"); } else { if (grp.GetLeaderGUID() != GetPlayer().GetGUID()) { return; } ObjectGuid errorGuid; err = grp.CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg.GetMaxPlayersPerTeam(), false, 0, out errorGuid); isPremade = (grp.GetMembersCount() >= bg.GetMinPlayersPerTeam()); BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo ginfo = null; uint avgTime = 0; if (err == 0) { Log.outDebug(LogFilter.Battleground, "Battleground: the following players are joining as group:"); ginfo = bgQueue.AddGroup(GetPlayer(), grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); } for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.Next()) { Player member = refe.GetSource(); if (!member) { continue; // this should never happen } if (err != 0) { BattlefieldStatusFailed battlefieldStatus; Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bg, GetPlayer(), 0, err, errorGuid); member.SendPacket(battlefieldStatus); continue; } // add to queue uint queueSlot = member.AddBattlegroundQueueId(bgQueueTypeId); Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out BattlefieldStatusQueued battlefieldStatusQueued, bg, member, queueSlot, ginfo.JoinTime, bgQueueTypeId, avgTime, ginfo.ArenaType, true); member.SendPacket(battlefieldStatusQueued); Log.outDebug(LogFilter.Battleground, $"Battleground: player joined queue for bg queue {bgQueueTypeId}, {member.GetGUID()}, NAME {member.GetName()}"); } Log.outDebug(LogFilter.Battleground, "Battleground: group end"); } Global.BattlegroundMgr.ScheduleQueueUpdate(0, bgQueueTypeId, bracketEntry.GetBracketId()); }