aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Battlefield/Battlefield.cpp10
-rw-r--r--src/server/game/Battlegrounds/Arena.cpp34
-rw-r--r--src/server/game/Battlegrounds/ArenaScore.h11
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.cpp7
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp110
-rw-r--r--src/server/game/Battlegrounds/Battleground.h6
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp181
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.h29
-rw-r--r--src/server/game/Battlegrounds/BattlegroundQueue.cpp27
-rw-r--r--src/server/game/Battlegrounds/BattlegroundScore.h9
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp8
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAB.h6
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp10
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAV.h12
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp7
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.h4
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp8
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundIC.h6
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp8
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundSA.h6
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp7
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundWS.h6
-rw-r--r--src/server/game/Entities/Object/Object.cpp13
-rw-r--r--src/server/game/Entities/Player/Player.cpp17
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp16
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Groups/Group.cpp9
-rw-r--r--src/server/game/Groups/Group.h2
-rw-r--r--src/server/game/Handlers/BattleGroundHandler.cpp505
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp69
-rw-r--r--src/server/game/Server/Packets/AllPackets.h1
-rw-r--r--src/server/game/Server/Packets/BattlegroundPackets.cpp272
-rw-r--r--src/server/game/Server/Packets/BattlegroundPackets.h372
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h45
36 files changed, 1190 insertions, 648 deletions
diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp
index bd01ad5850b..3f668392fcf 100644
--- a/src/server/game/Battlefield/Battlefield.cpp
+++ b/src/server/game/Battlefield/Battlefield.cpp
@@ -18,6 +18,7 @@
#include "Battlefield.h"
#include "BattlefieldMgr.h"
#include "Battleground.h"
+#include "BattlegroundPackets.h"
#include "CellImpl.h"
#include "CreatureTextMgr.h"
#include "DBCStores.h"
@@ -630,11 +631,10 @@ void Battlefield::RemovePlayerFromResurrectQueue(ObjectGuid playerGuid)
void Battlefield::SendAreaSpiritHealerQueryOpcode(Player* player, ObjectGuid guid)
{
- WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12);
- uint32 time = m_LastResurrectTimer; // resurrect every 30 seconds
-
- data << guid << time;
- player->SendDirectMessage(&data);
+ WorldPackets::Battleground::AreaSpiritHealerTime areaSpiritHealerTime;
+ areaSpiritHealerTime.HealerGuid = guid;
+ areaSpiritHealerTime.TimeLeft = m_LastResurrectTimer;
+ player->SendDirectMessage(areaSpiritHealerTime.Write());
}
// ----------------------
diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp
index 6d5ebc28e4d..fb4143bd70b 100644
--- a/src/server/game/Battlegrounds/Arena.cpp
+++ b/src/server/game/Battlegrounds/Arena.cpp
@@ -18,6 +18,7 @@
#include "Arena.h"
#include "ArenaScore.h"
#include "ArenaTeamMgr.h"
+#include "BattlegroundPackets.h"
#include "Log.h"
#include "ObjectAccessor.h"
#include "Player.h"
@@ -25,37 +26,20 @@
#include "WorldSession.h"
#include "WorldStatePackets.h"
-void ArenaScore::AppendToPacket(WorldPacket& data)
+void ArenaScore::AppendToPacket(WorldPackets::Battleground::PVPLogData_Player& playerData)
{
- data << uint64(PlayerGuid);
+ playerData.PlayerGUID = PlayerGuid;
- data << uint32(KillingBlows);
- data << uint8(TeamId);
- data << uint32(DamageDone);
- data << uint32(HealingDone);
+ playerData.Kills = KillingBlows;
+ playerData.HonorOrFaction = TeamId;
+ playerData.DamageDone = DamageDone;
+ playerData.HealingDone = HealingDone;
- BuildObjectivesBlock(data);
+ BuildObjectivesBlock(playerData);
}
-void ArenaScore::BuildObjectivesBlock(WorldPacket& data)
+void ArenaScore::BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& /*playerData*/)
{
- data << uint32(0); // Objectives Count
-}
-
-void ArenaTeamScore::BuildRatingInfoBlock(WorldPacket& data)
-{
- uint32 ratingLost = std::abs(std::min(RatingChange, 0));
- uint32 ratingWon = std::max(RatingChange, 0);
-
- // should be old rating, new rating, and client will calculate rating change itself
- data << uint32(ratingLost);
- data << uint32(ratingWon);
- data << uint32(MatchmakerRating);
-}
-
-void ArenaTeamScore::BuildTeamInfoBlock(WorldPacket& data)
-{
- data << TeamName;
}
Arena::Arena()
diff --git a/src/server/game/Battlegrounds/ArenaScore.h b/src/server/game/Battlegrounds/ArenaScore.h
index a8dbcefe127..63552a36215 100644
--- a/src/server/game/Battlegrounds/ArenaScore.h
+++ b/src/server/game/Battlegrounds/ArenaScore.h
@@ -21,15 +21,15 @@
#include "BattlegroundScore.h"
#include <sstream>
-struct TC_GAME_API ArenaScore : public BattlegroundScore
+struct TC_GAME_API ArenaScore final : public BattlegroundScore
{
friend class Arena;
protected:
ArenaScore(ObjectGuid playerGuid, uint32 team) : BattlegroundScore(playerGuid), TeamId(team == ALLIANCE ? PVP_TEAM_ALLIANCE : PVP_TEAM_HORDE) { }
- void AppendToPacket(WorldPacket& data) final override;
- void BuildObjectivesBlock(WorldPacket& data) final override;
+ void AppendToPacket(WorldPackets::Battleground::PVPLogData_Player& playerData) override;
+ void BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData) override;
// For Logging purpose
std::string ToString() const override
@@ -50,8 +50,6 @@ struct TC_GAME_API ArenaTeamScore
protected:
ArenaTeamScore() : RatingChange(0), MatchmakerRating(0) { }
- virtual ~ArenaTeamScore() { }
-
void Reset()
{
RatingChange = 0;
@@ -66,9 +64,6 @@ struct TC_GAME_API ArenaTeamScore
TeamName = teamName;
}
- void BuildRatingInfoBlock(WorldPacket& data);
- void BuildTeamInfoBlock(WorldPacket& data);
-
int32 RatingChange;
uint32 MatchmakerRating;
std::string TeamName;
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index 4883281f00b..7bb47cc75e2 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -18,6 +18,7 @@
#include "ArenaTeam.h"
#include "ArenaTeamMgr.h"
#include "BattlegroundMgr.h"
+#include "BattlegroundPackets.h"
#include "CalendarPackets.h"
#include "CharacterCache.h"
#include "DatabaseEnv.h"
@@ -337,11 +338,11 @@ void ArenaTeam::DelMember(ObjectGuid guid, bool cleanDb)
if (queue.GetPlayerGroupInfoData(playerMember->GetGUID(), &ginfo))
if (!ginfo.IsInvitedToBGInstanceGUID)
{
- WorldPacket data;
playerMember->RemoveBattlegroundQueueId(bgQueue);
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, nullptr, i, STATUS_NONE, 0, 0, 0, 0);
+ WorldPackets::Battleground::BattlefieldStatusNone battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusNone(&battlefieldStatus, i);
queue.RemovePlayer(playerMember->GetGUID(), true);
- playerMember->GetSession()->SendPacket(&data);
+ playerMember->SendDirectMessage(battlefieldStatus.Write());
}
}
}
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 503317d0a5f..bb08efda239 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -18,6 +18,7 @@
#include "Battleground.h"
#include "ArenaScore.h"
#include "BattlegroundMgr.h"
+#include "BattlegroundPackets.h"
#include "BattlegroundScore.h"
#include "ChatTextBuilder.h"
#include "Creature.h"
@@ -42,18 +43,21 @@
#include "WorldStatePackets.h"
#include <cstdarg>
-void BattlegroundScore::AppendToPacket(WorldPacket& data)
+void BattlegroundScore::AppendToPacket(WorldPackets::Battleground::PVPLogData_Player& playerData)
{
- data << uint64(PlayerGuid);
+ playerData.PlayerGUID = PlayerGuid;
- data << uint32(KillingBlows);
- data << uint32(HonorableKills);
- data << uint32(Deaths);
- data << uint32(BonusHonor);
- data << uint32(DamageDone);
- data << uint32(HealingDone);
+ playerData.Kills = KillingBlows;
+ playerData.HonorOrFaction = WorldPackets::Battleground::PVPLogData_Honor
+ {
+ .HonorKills = HonorableKills,
+ .Deaths = Deaths,
+ .ContributionPoints = BonusHonor
+ };
+ playerData.DamageDone = DamageDone;
+ playerData.HealingDone = HealingDone;
- BuildObjectivesBlock(data);
+ BuildObjectivesBlock(playerData);
}
template<class Do>
@@ -461,11 +465,10 @@ inline void Battleground::_ProcessJoin(uint32 diff)
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
{
// BG Status packet
- WorldPacket status;
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(m_TypeID, GetBracketId(), GetArenaType());
- uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetBGTeam());
- player->SendDirectMessage(&status);
+ WorldPackets::Battleground::BattlefieldStatusActive battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusActive(&battlefieldStatus, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), bgQueueTypeId);
+ player->SendDirectMessage(battlefieldStatus.Write());
player->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
player->ResetAllPowers();
@@ -716,8 +719,9 @@ void Battleground::EndBattleground(uint32 winner)
//we must set it this way, because end time is sent in packet!
m_EndTime = TIME_TO_AUTOREMOVE;
- WorldPacket pvpLogData;
- BuildPvPLogDataPacket(pvpLogData);
+ WorldPackets::Battleground::PVPMatchStatistics pvpMatchStatistics;
+ BuildPvPLogDataPacket(pvpMatchStatistics);
+ pvpMatchStatistics.Write();
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetBracketId(), GetArenaType());
@@ -798,11 +802,12 @@ void Battleground::EndBattleground(uint32 winner)
BlockMovement(player);
- player->SendDirectMessage(&pvpLogData);
+ player->SendDirectMessage(pvpMatchStatistics.GetRawPacket());
+
+ WorldPackets::Battleground::BattlefieldStatusActive battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusActive(&battlefieldStatus, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), bgQueueTypeId);
+ player->SendDirectMessage(battlefieldStatus.Write());
- WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetBGTeam());
- player->SendDirectMessage(&data);
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, player->GetMapId());
}
}
@@ -886,9 +891,9 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen
if (SendPacket)
{
- WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0, 0, 0);
- player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusNone battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusNone(&battlefieldStatus, player->GetBattlegroundQueueIndex(bgQueueTypeId));
+ player->SendDirectMessage(battlefieldStatus.Write());
}
// this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg
@@ -910,9 +915,9 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen
sBattlegroundMgr->ScheduleQueueUpdate(0, bgQueueTypeId);
}
// Let others know
- WorldPacket data;
- sBattlegroundMgr->BuildPlayerLeftBattlegroundPacket(&data, guid);
- SendPacketToTeam(team, &data, player, false);
+ WorldPackets::Battleground::BattlegroundPlayerLeft playerLeft;
+ playerLeft.Guid = guid;
+ SendPacketToTeam(team, playerLeft.Write(), player, false);
}
if (player)
@@ -1001,9 +1006,9 @@ void Battleground::AddPlayer(Player* player)
if (!isInBattleground)
UpdatePlayersCountByTeam(team, false); // +1 player
- WorldPacket data;
- sBattlegroundMgr->BuildPlayerJoinedBattlegroundPacket(&data, player);
- SendPacketToTeam(team, &data, player, false);
+ WorldPackets::Battleground::BattlegroundPlayerJoined playerJoined;
+ playerJoined.Guid = player->GetGUID();
+ SendPacketToTeam(team, playerJoined.Write(), player, false);
player->RemoveAurasByType(SPELL_AURA_MOUNTED);
@@ -1200,33 +1205,33 @@ bool Battleground::HasFreeSlots() const
return GetPlayersSize() < GetMaxPlayers();
}
-void Battleground::BuildPvPLogDataPacket(WorldPacket& data)
+void Battleground::BuildPvPLogDataPacket(WorldPackets::Battleground::PVPMatchStatistics& pvpLogData)
{
- uint8 type = (isArena() ? 1 : 0);
-
- data.Initialize(MSG_PVP_LOG_DATA, 1 + 1 + 4 + 40 * GetPlayerScoresSize());
- data << uint8(type); // type (battleground = 0 / arena = 1)
-
- if (type) // arena
+ if (isArena())
{
- for (uint8 i = 0; i < PVP_TEAMS_COUNT; ++i)
- _arenaTeamScores[i].BuildRatingInfoBlock(data);
+ WorldPackets::Battleground::PVPLogData_Arena& arena = pvpLogData.Arena.emplace();
for (uint8 i = 0; i < PVP_TEAMS_COUNT; ++i)
- _arenaTeamScores[i].BuildTeamInfoBlock(data);
+ {
+ ArenaTeamScore const& score = _arenaTeamScores[i];
+
+ uint32 ratingLost = std::abs(std::min(score.RatingChange, 0));
+ uint32 ratingWon = std::max(score.RatingChange, 0);
+
+ // should be old rating, new rating, and client will calculate rating change itself
+ arena.Ratings.Prematch[i] = ratingLost;
+ arena.Ratings.Postmatch[i] = ratingWon;
+ arena.Ratings.PrematchMMR[i] = score.MatchmakerRating;
+
+ arena.TeamName[i] = score.TeamName;
+ }
}
if (GetStatus() == STATUS_WAIT_LEAVE)
- {
- data << uint8(1); // bg ended
- data << uint8(GetWinner()); // who win
- }
- else
- data << uint8(0); // bg not ended
+ pvpLogData.Winner = GetWinner();
- data << uint32(GetPlayerScoresSize());
- for (auto const& score : PlayerScores)
- score.second->AppendToPacket(data);
+ for (auto const& [_, score] : PlayerScores)
+ score->AppendToPacket(pvpLogData.Players.emplace_back());
}
bool Battleground::UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor)
@@ -1729,16 +1734,17 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player)
if (GetStatus() != STATUS_WAIT_LEAVE)
return;
- WorldPacket data;
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetBracketId(), GetArenaType());
BlockMovement(player);
- BuildPvPLogDataPacket(data);
- player->SendDirectMessage(&data);
+ WorldPackets::Battleground::PVPMatchStatistics pvpMatchStatistics;
+ BuildPvPLogDataPacket(pvpMatchStatistics);
+ player->SendDirectMessage(pvpMatchStatistics.Write());
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetBGTeam());
- player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusActive battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusActive(&battlefieldStatus, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), bgQueueTypeId);
+ player->SendDirectMessage(battlefieldStatus.Write());
}
uint32 Battleground::GetAlivePlayersCountByTeam(uint32 Team) const
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index 814c359da31..e22e749aae6 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -29,6 +29,10 @@
namespace WorldPackets
{
+ namespace Battleground
+ {
+ class PVPMatchStatistics;
+ }
namespace WorldState
{
class InitWorldStates;
@@ -399,7 +403,7 @@ class TC_GAME_API Battleground
Group* GetBgRaid(uint32 TeamID) const { return TeamID == ALLIANCE ? m_BgRaids[TEAM_ALLIANCE] : m_BgRaids[TEAM_HORDE]; }
void SetBgRaid(uint32 TeamID, Group* bg_raid);
- void BuildPvPLogDataPacket(WorldPacket& data);
+ void BuildPvPLogDataPacket(WorldPackets::Battleground::PVPMatchStatistics& pvpLogData);
virtual bool UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true);
static TeamId GetTeamIndexByTeamId(uint32 Team) { return Team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 5659e75fe04..9dc3abf8328 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -28,6 +28,7 @@
#include "BattlegroundDS.h"
#include "BattlegroundRV.h"
#include "BattlegroundIC.h"
+#include "BattlegroundPackets.h"
#include "Common.h"
#include "Containers.h"
#include "Chat.h"
@@ -169,77 +170,64 @@ void BattlegroundMgr::Update(uint32 diff)
}
}
-void BattlegroundMgr::BuildBattlegroundStatusPacket(WorldPacket* data, Battleground* bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype, uint32 arenaFaction)
+void BattlegroundMgr::BuildBattlegroundStatusHeader(WorldPackets::Battleground::BattlefieldStatusHeader* header, Battleground const* bg, uint32 queueSlot, BattlegroundQueueTypeId queueId)
{
- // we can be in 2 queues in same time...
+ header->QueueSlot = queueSlot;
+ header->QueueID = queueId.GetPacked();
+ header->RangeMin = bg->GetMinLevel();
+ header->RangeMax = bg->GetMaxLevel();
+ header->InstanceID = bg->GetClientInstanceID();
+ header->RegisteredMatch = bg->isRated();
+}
- if (StatusID == 0 || !bg)
- {
- data->Initialize(SMSG_BATTLEFIELD_STATUS, 4+8);
- *data << uint32(QueueSlot); // queue id (0...1)
- *data << uint64(0);
- return;
- }
+void BattlegroundMgr::BuildBattlegroundStatusNone(WorldPackets::Battleground::BattlefieldStatusNone* battlefieldStatus, uint32 queueSlot)
+{
+ battlefieldStatus->QueueSlot = queueSlot;
+}
+
+void BattlegroundMgr::BuildBattlegroundStatusNeedConfirmation(WorldPackets::Battleground::BattlefieldStatusNeedConfirmation* battlefieldStatus, Battleground const* bg, uint32 queueSlot, uint32 timeout, BattlegroundQueueTypeId queueId)
+{
+ BuildBattlegroundStatusHeader(&battlefieldStatus->Hdr, bg, queueSlot, queueId);
+ battlefieldStatus->Mapid = bg->GetMapId();
+ battlefieldStatus->Timeout = timeout;
+}
- data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+8+1+1+4+1+4+4+4));
- *data << uint32(QueueSlot); // queue id (0...1) - player can be in 2 queues in time
- // The following segment is read as uint64 in client but can be appended as their original type.
- *data << uint8(arenatype);
- TC_LOG_DEBUG("network", "BattlegroundMgr::BuildBattlegroundStatusPacket: arenatype = {} for bg instanceID {}, TypeID {}.", arenatype, bg->GetClientInstanceID(), bg->GetTypeID());
- *data << uint8(bg->GetBracketId());
- *data << uint32(bg->GetTypeID());
- *data << uint16(0x1F90);
- // End of uint64 segment, decomposed this way for simplicity
- *data << uint8(bg->GetMinLevel());
- *data << uint8(bg->GetMaxLevel());
- *data << uint32(bg->GetClientInstanceID());
- // alliance/horde for BG and skirmish/rated for Arenas
- // following displays the minimap-icon 0 = faction icon 1 = arenaicon
- *data << uint8(bg->isRated()); // 1 for rated match, 0 for bg or non rated match
-
- *data << uint32(StatusID); // status
- switch (StatusID)
+void BattlegroundMgr::BuildBattlegroundStatusActive(WorldPackets::Battleground::BattlefieldStatusActive* battlefieldStatus, Battleground const* bg, Player const* player, uint32 queueSlot, BattlegroundQueueTypeId queueId)
+{
+ BuildBattlegroundStatusHeader(&battlefieldStatus->Hdr, bg, queueSlot, queueId);
+ battlefieldStatus->ShutdownTimer = bg->GetEndTime();
+ battlefieldStatus->ArenaFaction = player->GetBGTeam() == HORDE ? PVP_TEAM_HORDE : PVP_TEAM_ALLIANCE;
+ battlefieldStatus->StartTimer = bg->GetStartTime();
+ battlefieldStatus->Mapid = bg->GetMapId();
+ if (bg->IsRandom())
{
- case STATUS_WAIT_QUEUE: // status_in_queue
- *data << uint32(Time1); // average wait time, milliseconds
- *data << uint32(Time2); // time in queue, updated every minute!, milliseconds
- break;
- case STATUS_WAIT_JOIN: // status_invite
- *data << uint32(bg->GetMapId()); // map id
- *data << uint64(0); // 3.3.5, unknown
- *data << uint32(Time1); // time to remove from queue, milliseconds
- break;
- case STATUS_IN_PROGRESS: // status_in_progress
- *data << uint32(bg->GetMapId()); // map id
- *data << uint64(0); // 3.3.5, unknown
- *data << uint32(Time1); // time to bg auto leave, 0 at bg start, 120000 after bg end, milliseconds
- *data << uint32(Time2); // time from bg start, milliseconds
- *data << uint8(arenaFaction == ALLIANCE ? 1 : 0); // arenafaction (0 for horde, 1 for alliance)
- break;
- default:
- TC_LOG_ERROR("bg.battleground", "Unknown BG status!");
- break;
+ BattlegroundTemplate const* realTemplate = sBattlegroundMgr->GetBattlegroundTemplateByTypeId(bg->GetTypeID(true));
+ if (PvPDifficultyEntry const* realBracket = GetBattlegroundBracketByLevel(realTemplate->MapIDs.front(), DEFAULT_MAX_LEVEL))
+ battlefieldStatus->RandomQueueID = BattlegroundQueueTypeId{
+ .BattlemasterListId = uint16(realTemplate->Id),
+ .BracketId = uint8(realBracket->GetBracketId()),
+ .TeamSize = 0
+ }.GetPacked();
}
}
-void BattlegroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket* data, GroupJoinBattlegroundResult result)
+void BattlegroundMgr::BuildBattlegroundStatusQueued(WorldPackets::Battleground::BattlefieldStatusQueued* battlefieldStatus, Battleground const* bg, uint32 queueSlot, uint32 joinTime, BattlegroundQueueTypeId queueId, uint32 avgWaitTime)
{
- data->Initialize(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
- *data << int32(result);
- if (result == ERR_BATTLEGROUND_JOIN_TIMED_OUT || result == ERR_BATTLEGROUND_JOIN_FAILED)
- *data << uint64(0); // player guid
+ BuildBattlegroundStatusHeader(&battlefieldStatus->Hdr, bg, queueSlot, queueId);
+ battlefieldStatus->AverageWaitTime = avgWaitTime;
+ battlefieldStatus->WaitTime = GetMSTimeDiffToNow(joinTime);
}
-void BattlegroundMgr::BuildPlayerLeftBattlegroundPacket(WorldPacket* data, ObjectGuid guid)
+void BattlegroundMgr::BuildBattlegroundStatusFailed(WorldPackets::Battleground::BattlefieldStatusFailed* battlefieldStatus, GroupJoinBattlegroundResult result, ObjectGuid const* errorGuid /*= nullptr*/)
{
- data->Initialize(SMSG_BATTLEGROUND_PLAYER_LEFT, 8);
- *data << uint64(guid);
+ battlefieldStatus->Reason = result;
+ if (errorGuid && (result == ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND || result == ERR_BATTLEGROUND_JOIN_TIMED_OUT))
+ battlefieldStatus->ClientID = *errorGuid;
}
-void BattlegroundMgr::BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, Player* player)
+void BattlegroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPackets::Battleground::GroupJoinedBattleground* groupJoinedBattleground, BattlegroundTypeId bgTypeId)
{
- data->Initialize(SMSG_BATTLEGROUND_PLAYER_JOINED, 8);
- *data << uint64(player->GetGUID());
+ groupJoinedBattleground->Reason = bgTypeId;
}
Battleground* BattlegroundMgr::GetBattlegroundThroughClientInstance(uint32 instanceId, BattlegroundTypeId bgTypeId)
@@ -622,7 +610,7 @@ void BattlegroundMgr::InitAutomaticArenaPointDistribution()
TC_LOG_DEBUG("bg.battleground", "Automatic Arena Point Distribution initialized.");
}
-void BattlegroundMgr::BuildBattlegroundListPacket(WorldPacket* data, ObjectGuid guid, Player* player, BattlegroundTypeId bgTypeId, uint8 fromWhere)
+void BattlegroundMgr::SendBattlegroundList(Player* player, ObjectGuid const& guid, BattlegroundTypeId bgTypeId)
{
if (!player)
return;
@@ -634,56 +622,34 @@ void BattlegroundMgr::BuildBattlegroundListPacket(WorldPacket* data, ObjectGuid
winner_kills = Trinity::Honor::hk_honor_at_level(player->GetLevel(), float(winner_kills));
loser_kills = Trinity::Honor::hk_honor_at_level(player->GetLevel(), float(loser_kills));
- data->Initialize(SMSG_BATTLEFIELD_LIST);
- *data << uint64(guid); // battlemaster guid
- *data << uint8(fromWhere); // from where you joined
- *data << uint32(bgTypeId); // battleground id
- *data << uint8(0); // unk
- *data << uint8(0); // unk
-
- // Rewards
- *data << uint8(player->GetRandomWinner()); // 3.3.3 hasWin
- *data << uint32(winner_kills); // 3.3.3 winHonor
- *data << uint32(winner_arena); // 3.3.3 winArena
- *data << uint32(loser_kills); // 3.3.3 lossHonor
+ WorldPackets::Battleground::BattlefieldList battlefieldList;
+ battlefieldList.BattlemasterGuid = guid;
+ battlefieldList.PvpAnywhere = guid.IsEmpty();
+ battlefieldList.BattlemasterListID = bgTypeId;
+ battlefieldList.MinLevel = 0;
+ battlefieldList.MaxLevel = 0;
- uint8 isRandom = bgTypeId == BATTLEGROUND_RB;
+ battlefieldList.HasHolidayWinToday = player->GetRandomWinner();
+ battlefieldList.HolidayWinHonorCurrencyBonus = winner_kills;
+ battlefieldList.HolidayFirstWinArenaCurrencyBonus = winner_arena;
+ battlefieldList.HolidayLossHonorCurrencyBonus = loser_kills;
- *data << uint8(isRandom); // 3.3.3 isRandom
- if (isRandom)
- {
- // Rewards (random)
- *data << uint8(player->GetRandomWinner()); // 3.3.3 hasWin_Random
- *data << uint32(winner_kills); // 3.3.3 winHonor_Random
- *data << uint32(winner_arena); // 3.3.3 winArena_Random
- *data << uint32(loser_kills); // 3.3.3 lossHonor_Random
- }
+ battlefieldList.HasRandomWinToday = player->GetRandomWinner();
+ battlefieldList.RandomWinHonorCurrencyBonus = winner_kills;
+ battlefieldList.RandomFirstWinArenaCurrencyBonus = winner_arena;
+ battlefieldList.RandomLossHonorCurrencyBonus = loser_kills;
- if (bgTypeId == BATTLEGROUND_AA) // arena
- *data << uint32(0); // unk (count?)
- else // battleground
+ if (bgTypeId != BATTLEGROUND_AA)
{
- size_t count_pos = data->wpos();
- *data << uint32(0); // number of bg instances
-
- BattlegroundDataContainer::iterator it = bgDataStore.find(bgTypeId);
- if (it != bgDataStore.end())
+ if (BattlegroundData const* battlegrounds = Trinity::Containers::MapGetValuePtr(bgDataStore, bgTypeId))
{
// expected bracket entry
- if (PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(it->second.m_Battlegrounds.begin()->second->GetMapId(), player->GetLevel()))
- {
- uint32 count = 0;
- BattlegroundBracketId bracketId = bracketEntry->GetBracketId();
- BattlegroundClientIdsContainer& clientIds = it->second.m_ClientBattlegroundIds[bracketId];
- for (BattlegroundClientIdsContainer::const_iterator itr = clientIds.begin(); itr != clientIds.end(); ++itr)
- {
- *data << uint32(*itr);
- ++count;
- }
- data->put<uint32>(count_pos, count);
- }
+ if (PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(battlegrounds->m_Battlegrounds.begin()->second->GetMapId(), player->GetLevel()))
+ battlefieldList.Battlefields = &battlegrounds->m_ClientBattlegroundIds[bracketEntry->GetBracketId()];
}
}
+
+ player->SendDirectMessage(battlefieldList.Write());
}
void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, BattlegroundTypeId bgTypeId)
@@ -705,12 +671,10 @@ void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, Batt
void BattlegroundMgr::SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, ObjectGuid guid)
{
- WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12);
- uint32 time_ = 30000 - bg->GetLastResurrectTime(); // resurrect every 30 seconds
- if (time_ == uint32(-1))
- time_ = 0;
- data << guid << time_;
- player->SendDirectMessage(&data);
+ WorldPackets::Battleground::AreaSpiritHealerTime areaSpiritHealerTime;
+ areaSpiritHealerTime.HealerGuid = guid;
+ areaSpiritHealerTime.TimeLeft = std::max(30000 - int32(bg->GetLastResurrectTime()), 0);
+ player->SendDirectMessage(areaSpiritHealerTime.Write());
}
bool BattlegroundMgr::IsArenaType(BattlegroundTypeId bgTypeId)
@@ -723,6 +687,11 @@ bool BattlegroundMgr::IsArenaType(BattlegroundTypeId bgTypeId)
|| bgTypeId == BATTLEGROUND_RL;
}
+bool BattlegroundMgr::IsRandomBattleground(uint32 battlemasterListId)
+{
+ return battlemasterListId == BATTLEGROUND_RB;
+}
+
BattlegroundQueueTypeId BattlegroundMgr::BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 bracketId, uint8 arenaType)
{
return { .BattlemasterListId = uint16(bgTypeId), .BracketId = bracketId, .TeamSize = arenaType };
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h
index 4b3ab9f03c2..d32366f90c1 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.h
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.h
@@ -63,6 +63,20 @@ struct BattlegroundTemplate
bool IsArena() const;
};
+namespace WorldPackets
+{
+ namespace Battleground
+ {
+ struct BattlefieldStatusHeader;
+ class BattlefieldStatusNone;
+ class BattlefieldStatusNeedConfirmation;
+ class BattlefieldStatusActive;
+ class BattlefieldStatusQueued;
+ class GroupJoinedBattleground;
+ using BattlefieldStatusFailed = GroupJoinedBattleground;
+ }
+}
+
class TC_GAME_API BattlegroundMgr
{
private:
@@ -80,11 +94,15 @@ class TC_GAME_API BattlegroundMgr
void Update(uint32 diff);
/* Packet Building */
- void BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, Player* player);
- void BuildPlayerLeftBattlegroundPacket(WorldPacket* data, ObjectGuid guid);
- void BuildBattlegroundListPacket(WorldPacket* data, ObjectGuid guid, Player* player, BattlegroundTypeId bgTypeId, uint8 fromWhere);
- void BuildGroupJoinedBattlegroundPacket(WorldPacket* data, GroupJoinBattlegroundResult result);
- void BuildBattlegroundStatusPacket(WorldPacket* data, Battleground* bg, uint8 queueSlot, uint8 statusId, uint32 time1, uint32 time2, uint8 arenaType, uint32 arenaFaction);
+ static void BuildBattlegroundStatusHeader(WorldPackets::Battleground::BattlefieldStatusHeader* header, Battleground const* bg, uint32 queueSlot, BattlegroundQueueTypeId queueId);
+ static void BuildBattlegroundStatusNone(WorldPackets::Battleground::BattlefieldStatusNone* battlefieldStatus, uint32 queueSlot);
+ static void BuildBattlegroundStatusNeedConfirmation(WorldPackets::Battleground::BattlefieldStatusNeedConfirmation* battlefieldStatus, Battleground const* bg, uint32 queueSlot, uint32 timeout, BattlegroundQueueTypeId queueId);
+ static void BuildBattlegroundStatusActive(WorldPackets::Battleground::BattlefieldStatusActive* battlefieldStatus, Battleground const* bg, Player const* player, uint32 queueSlot, BattlegroundQueueTypeId queueId);
+ static void BuildBattlegroundStatusQueued(WorldPackets::Battleground::BattlefieldStatusQueued* battlefieldStatus, Battleground const* bg, uint32 queueSlot, uint32 joinTime, BattlegroundQueueTypeId queueId, uint32 avgWaitTime);
+ static void BuildBattlegroundStatusFailed(WorldPackets::Battleground::BattlefieldStatusFailed* battlefieldStatus, GroupJoinBattlegroundResult result, ObjectGuid const* errorGuid = nullptr);
+ static void BuildGroupJoinedBattlegroundPacket(WorldPackets::Battleground::GroupJoinedBattleground* groupJoinedBattleground, BattlegroundTypeId bgTypeId);
+
+ void SendBattlegroundList(Player* player, ObjectGuid const& guid, BattlegroundTypeId bgTypeId);
void SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, ObjectGuid guid);
/* Battlegrounds */
@@ -118,6 +136,7 @@ class TC_GAME_API BattlegroundMgr
bool isArenaTesting() const { return m_ArenaTesting; }
bool isTesting() const { return m_Testing; }
+ static bool IsRandomBattleground(uint32 battlemasterListId);
static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 bracketId, uint8 arenaType);
static HolidayIds BGTypeToWeekendHolidayId(BattlegroundTypeId bgTypeId);
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
index 4807b67b2be..8ba8a152012 100644
--- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
@@ -19,6 +19,7 @@
#include "ArenaTeam.h"
#include "ArenaTeamMgr.h"
#include "BattlegroundMgr.h"
+#include "BattlegroundPackets.h"
#include "Chat.h"
#include "DatabaseEnv.h"
#include "DBCStores.h"
@@ -381,9 +382,10 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
plr2->RemoveBattlegroundQueueId(m_queueId); // must be called this way, because if you move this call to
// queue->removeplayer, it causes bugs
- WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, nullptr, queueSlot, STATUS_NONE, 0, 0, 0, 0);
- plr2->SendDirectMessage(&data);
+
+ WorldPackets::Battleground::BattlefieldStatusNone battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusNone(&battlefieldStatus, queueSlot);
+ plr2->SendDirectMessage(battlefieldStatus.Write());
}
// then actually delete, this may delete the group as well!
RemovePlayer(group->Players.begin()->first, decreaseInvitedCount);
@@ -465,9 +467,9 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg,
TC_LOG_DEBUG("bg.battleground", "Battleground: invited player {} {} to BG instance {} queueindex {} bgtype {}",
player->GetName(), player->GetGUID().ToString(), bg->GetInstanceID(), queueSlot, bg->GetTypeID());
- // send status packet
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, m_queueId.TeamSize, 0);
- player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusNeedConfirmation battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusNeedConfirmation(&battlefieldStatus, bg, queueSlot, INVITE_ACCEPT_WAIT_TIME, bgQueueTypeId);
+ player->SendDirectMessage(battlefieldStatus.Write());
}
return true;
}
@@ -1020,10 +1022,9 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(m_QueueId);
if (bgQueue.IsPlayerInvited(m_PlayerGuid, m_BgInstanceGUID, m_RemoveTime))
{
- WorldPacket data;
- //we must send remaining time in queue
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, m_QueueId.TeamSize, 0);
- player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusNeedConfirmation battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusNeedConfirmation(&battlefieldStatus, bg, queueSlot, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, m_QueueId);
+ player->SendDirectMessage(battlefieldStatus.Write());
}
}
return true; //event will be deleted
@@ -1079,9 +1080,9 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
if (bg && bg->isBattleground() && bg->GetStatus() != STATUS_WAIT_LEAVE)
sBattlegroundMgr->ScheduleQueueUpdate(0, m_BgQueueTypeId);
- WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, 0);
- player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusNone battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusNone(&battlefieldStatus, queueSlot);
+ player->SendDirectMessage(battlefieldStatus.Write());
}
}
diff --git a/src/server/game/Battlegrounds/BattlegroundScore.h b/src/server/game/Battlegrounds/BattlegroundScore.h
index f4c19320678..999e8c4133d 100644
--- a/src/server/game/Battlegrounds/BattlegroundScore.h
+++ b/src/server/game/Battlegrounds/BattlegroundScore.h
@@ -22,6 +22,11 @@
#include "ObjectGuid.h"
#include "SharedDefines.h"
+namespace WorldPackets::Battleground
+{
+struct PVPLogData_Player;
+}
+
class WorldPacket;
enum ScoreType
@@ -92,8 +97,8 @@ struct BattlegroundScore
}
}
- virtual void AppendToPacket(WorldPacket& data);
- virtual void BuildObjectivesBlock(WorldPacket& /*data*/) = 0;
+ virtual void AppendToPacket(WorldPackets::Battleground::PVPLogData_Player& playerData);
+ virtual void BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData) = 0;
// For Logging purpose
virtual std::string ToString() const { return ""; }
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
index 2f0320c55c3..c9353d29e3c 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
@@ -17,6 +17,7 @@
#include "BattlegroundAB.h"
#include "BattlegroundMgr.h"
+#include "BattlegroundPackets.h"
#include "Creature.h"
#include "DBCStores.h"
#include "GameObject.h"
@@ -25,15 +26,12 @@
#include "Player.h"
#include "Random.h"
#include "Util.h"
-#include "WorldPacket.h"
#include "WorldSession.h"
#include "WorldStatePackets.h"
-void BattlegroundABScore::BuildObjectivesBlock(WorldPacket& data)
+void BattlegroundABScore::BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData)
{
- data << uint32(2);
- data << uint32(BasesAssaulted);
- data << uint32(BasesDefended);
+ playerData.Stats = { BasesAssaulted, BasesDefended };
}
BattlegroundAB::BattlegroundAB()
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h
index c30958d9c19..a57c38e435f 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h
@@ -288,10 +288,10 @@ struct BattlegroundABScore final : public BattlegroundScore
}
}
- void BuildObjectivesBlock(WorldPacket& data) final override;
+ void BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData) override;
- uint32 GetAttr1() const final override { return BasesAssaulted; }
- uint32 GetAttr2() const final override { return BasesDefended; }
+ uint32 GetAttr1() const override { return BasesAssaulted; }
+ uint32 GetAttr2() const override { return BasesDefended; }
uint32 BasesAssaulted;
uint32 BasesDefended;
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
index 8d258d34075..6f272a874d4 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
@@ -16,6 +16,7 @@
*/
#include "BattlegroundAV.h"
+#include "BattlegroundPackets.h"
#include "Creature.h"
#include "CreatureAI.h"
#include "DBCStores.h"
@@ -27,14 +28,9 @@
#include "WorldSession.h"
#include "WorldStatePackets.h"
-void BattlegroundAVScore::BuildObjectivesBlock(WorldPacket& data)
+void BattlegroundAVScore::BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData)
{
- data << uint32(5); // Objectives Count
- data << uint32(GraveyardsAssaulted);
- data << uint32(GraveyardsDefended);
- data << uint32(TowersAssaulted);
- data << uint32(TowersDefended);
- data << uint32(MinesCaptured);
+ playerData.Stats = { GraveyardsAssaulted, GraveyardsDefended, TowersAssaulted, TowersDefended, MinesCaptured };
}
BattlegroundAV::BattlegroundAV()
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
index 249cb0dfb73..8e40f65a6a6 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
@@ -1597,13 +1597,13 @@ struct BattlegroundAVScore final : public BattlegroundScore
}
}
- void BuildObjectivesBlock(WorldPacket& data) final override;
+ void BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData) override;
- uint32 GetAttr1() const final override { return GraveyardsAssaulted; }
- uint32 GetAttr2() const final override { return GraveyardsDefended; }
- uint32 GetAttr3() const final override { return TowersAssaulted; }
- uint32 GetAttr4() const final override { return TowersDefended; }
- uint32 GetAttr5() const final override { return MinesCaptured; }
+ uint32 GetAttr1() const override { return GraveyardsAssaulted; }
+ uint32 GetAttr2() const override { return GraveyardsDefended; }
+ uint32 GetAttr3() const override { return TowersAssaulted; }
+ uint32 GetAttr4() const override { return TowersDefended; }
+ uint32 GetAttr5() const override { return MinesCaptured; }
uint32 GraveyardsAssaulted;
uint32 GraveyardsDefended;
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
index f230ec277a8..a9e55f5cc33 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
@@ -17,6 +17,7 @@
#include "BattlegroundEY.h"
#include "BattlegroundMgr.h"
+#include "BattlegroundPackets.h"
#include "Creature.h"
#include "DBCStores.h"
#include "GameObject.h"
@@ -26,7 +27,6 @@
#include "Player.h"
#include "Random.h"
#include "Util.h"
-#include "WorldPacket.h"
#include "WorldStatePackets.h"
// these variables aren't used outside of this file, so declare them only here
@@ -36,10 +36,9 @@ uint32 BG_EY_HonorScoreTicks[BG_HONOR_MODE_NUM] =
160 // holiday
};
-void BattlegroundEYScore::BuildObjectivesBlock(WorldPacket& data)
+void BattlegroundEYScore::BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData)
{
- data << uint32(1); // Objectives Count
- data << uint32(FlagCaptures);
+ playerData.Stats = { FlagCaptures };
}
BattlegroundEY::BattlegroundEY()
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
index e45a09a7a13..81b3d897cab 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
@@ -370,9 +370,9 @@ struct BattlegroundEYScore final : public BattlegroundScore
}
}
- void BuildObjectivesBlock(WorldPacket& data) final override;
+ void BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData) override;
- uint32 GetAttr1() const final override { return FlagCaptures; }
+ uint32 GetAttr1() const override { return FlagCaptures; }
uint32 FlagCaptures;
};
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp
index 15cdbe8eaac..cf71d03db3e 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp
@@ -16,6 +16,7 @@
*/
#include "BattlegroundIC.h"
+#include "BattlegroundPackets.h"
#include "GameObject.h"
#include "Log.h"
#include "Map.h"
@@ -23,14 +24,11 @@
#include "ScriptedCreature.h"
#include "Transport.h"
#include "Vehicle.h"
-#include "WorldPacket.h"
#include "WorldStatePackets.h"
-void BattlegroundICScore::BuildObjectivesBlock(WorldPacket& data)
+void BattlegroundICScore::BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData)
{
- data << uint32(2); // Objectives Count
- data << uint32(BasesAssaulted);
- data << uint32(BasesDefended);
+ playerData.Stats = { BasesAssaulted, BasesDefended };
}
BattlegroundIC::BattlegroundIC()
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h
index c2192e28c53..e70d5555817 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h
@@ -930,10 +930,10 @@ struct BattlegroundICScore final : public BattlegroundScore
}
}
- void BuildObjectivesBlock(WorldPacket& data) final override;
+ void BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData) override;
- uint32 GetAttr1() const final override { return BasesAssaulted; }
- uint32 GetAttr2() const final override { return BasesDefended; }
+ uint32 GetAttr1() const override { return BasesAssaulted; }
+ uint32 GetAttr2() const override { return BasesDefended; }
uint32 BasesAssaulted;
uint32 BasesDefended;
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
index 3477a18ebf7..3de916ca0e2 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
@@ -16,6 +16,7 @@
*/
#include "BattlegroundSA.h"
+#include "BattlegroundPackets.h"
#include "DBCStores.h"
#include "GameObject.h"
#include "GameTime.h"
@@ -26,14 +27,11 @@
#include "Player.h"
#include "ScriptedCreature.h"
#include "UpdateData.h"
-#include "WorldPacket.h"
#include "WorldStatePackets.h"
-void BattlegroundSAScore::BuildObjectivesBlock(WorldPacket& data)
+void BattlegroundSAScore::BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData)
{
- data << uint32(2); // Objectives Count
- data << uint32(DemolishersDestroyed);
- data << uint32(GatesDestroyed);
+ playerData.Stats = { DemolishersDestroyed, GatesDestroyed };
}
BattlegroundSA::BattlegroundSA()
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h
index 1f2c2e53af0..17b5b9dd041 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h
@@ -539,10 +539,10 @@ struct BattlegroundSAScore final : public BattlegroundScore
}
}
- void BuildObjectivesBlock(WorldPacket& data) final override;
+ void BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData) override;
- uint32 GetAttr1() const final override { return DemolishersDestroyed; }
- uint32 GetAttr2() const final override { return GatesDestroyed; }
+ uint32 GetAttr1() const override { return DemolishersDestroyed; }
+ uint32 GetAttr2() const override { return GatesDestroyed; }
uint32 DemolishersDestroyed;
uint32 GatesDestroyed;
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
index 7c00dd59992..90d2d5ef106 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
@@ -17,6 +17,7 @@
#include "BattlegroundWS.h"
#include "BattlegroundMgr.h"
+#include "BattlegroundPackets.h"
#include "DBCStores.h"
#include "GameObject.h"
#include "Log.h"
@@ -71,11 +72,9 @@ BattlegroundWS::BattlegroundWS()
_minutesElapsed = 0;
}
-void BattlegroundWGScore::BuildObjectivesBlock(WorldPacket& data)
+void BattlegroundWGScore::BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData)
{
- data << uint32(2); // Objectives Count
- data << uint32(FlagCaptures);
- data << uint32(FlagReturns);
+ playerData.Stats = { FlagCaptures, FlagReturns };
}
BattlegroundWS::~BattlegroundWS() { }
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
index aa120ab8f3a..1d034b30cbf 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
@@ -186,10 +186,10 @@ struct BattlegroundWGScore final : public BattlegroundScore
}
}
- void BuildObjectivesBlock(WorldPacket& data) final override;
+ void BuildObjectivesBlock(WorldPackets::Battleground::PVPLogData_Player& playerData) override;
- uint32 GetAttr1() const final override { return FlagCaptures; }
- uint32 GetAttr2() const final override { return FlagReturns; }
+ uint32 GetAttr1() const override { return FlagCaptures; }
+ uint32 GetAttr2() const override { return FlagReturns; }
uint32 FlagCaptures;
uint32 FlagReturns;
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index df73ba3c1d7..060f3e25e61 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -233,19 +233,6 @@ void Object::DestroyForPlayer(Player* target, bool onDeath) const
{
ASSERT(target);
- if (IsUnit())
- {
- if (Battleground* bg = target->GetBattleground())
- {
- if (bg->isArena())
- {
- WorldPacket data(SMSG_ARENA_UNIT_DESTROYED, 8);
- data << uint64(GetGUID());
- target->SendDirectMessage(&data);
- }
- }
- }
-
WorldPacket data(SMSG_DESTROY_OBJECT, 8 + 1);
data << uint64(GetGUID());
//! If the following bool is true, the client will call "void CGUnit_C::OnDeath()" for this object.
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 7892f4e0ae5..497c803a8be 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -25,6 +25,7 @@
#include "BattlefieldMgr.h"
#include "Battleground.h"
#include "BattlegroundMgr.h"
+#include "BattlegroundPackets.h"
#include "BattlegroundScore.h"
#include "CellImpl.h"
#include "Channel.h"
@@ -14369,7 +14370,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
return;
}
- GetSession()->SendBattleGroundList(guid, bgTypeId);
+ sBattlegroundMgr->SendBattlegroundList(this, guid, bgTypeId);
break;
}
}
@@ -22191,23 +22192,33 @@ bool Player::CanReportAfkDueToLimit()
///This player has been blamed to be inactive in a battleground
void Player::ReportedAfkBy(Player* reporter)
{
+ WorldPackets::Battleground::ReportPvPPlayerAFKResult reportAfkResult;
+ reportAfkResult.Offender = GetGUID();
Battleground* bg = GetBattleground();
// Battleground also must be in progress!
if (!bg || bg != reporter->GetBattleground() || GetTeam() != reporter->GetTeam() || bg->GetStatus() != STATUS_IN_PROGRESS)
+ {
+ reporter->SendDirectMessage(reportAfkResult.Write());
return;
+ }
// check if player has 'Idle' or 'Inactive' debuff
- if (m_bgData.bgAfkReporter.find(reporter->GetGUID().GetCounter()) == m_bgData.bgAfkReporter.end() && !HasAura(43680) && !HasAura(43681) && reporter->CanReportAfkDueToLimit())
+ if (m_bgData.bgAfkReporter.find(reporter->GetGUID()) == m_bgData.bgAfkReporter.end() && !HasAura(43680) && !HasAura(43681) && reporter->CanReportAfkDueToLimit())
{
- m_bgData.bgAfkReporter.insert(reporter->GetGUID().GetCounter());
+ m_bgData.bgAfkReporter.insert(reporter->GetGUID());
// by default 3 players have to complain to apply debuff
if (m_bgData.bgAfkReporter.size() >= sWorld->getIntConfig(CONFIG_BATTLEGROUND_REPORT_AFK))
{
// cast 'Idle' spell
CastSpell(this, 43680, true);
m_bgData.bgAfkReporter.clear();
+ reportAfkResult.NumBlackMarksOnOffender = m_bgData.bgAfkReporter.size();
+ reportAfkResult.NumPlayersIHaveReported = reporter->m_bgData.bgAfkReportedCount;
+ reportAfkResult.Result = WorldPackets::Battleground::ReportPvPPlayerAFKResult::PVP_REPORT_AFK_SUCCESS;
}
}
+
+ reporter->SendDirectMessage(reportAfkResult.Write());
}
WorldLocation Player::GetStartPosition() const
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 23915ad87cf..cc4df35f6a9 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -831,7 +831,7 @@ struct BGData
/// when player is teleported to BG - (it is battleground's GUID)
BattlegroundTypeId bgTypeID;
- std::set<uint32> bgAfkReporter;
+ GuidSet bgAfkReporter;
uint8 bgAfkReportedCount;
time_t bgAfkReportedTimer;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 715b79f477d..bac4222cf4d 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -20,6 +20,7 @@
#include "Battlefield.h"
#include "BattlefieldMgr.h"
#include "Battleground.h"
+#include "BattlegroundPackets.h"
#include "BattlegroundScore.h"
#include "CellImpl.h"
#include "CharacterCache.h"
@@ -13584,6 +13585,21 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player const* t
data->append(fieldBuffer);
}
+void Unit::DestroyForPlayer(Player* target, bool onDeath) const
+{
+ if (Battleground* bg = target->GetBattleground())
+ {
+ if (bg->isArena())
+ {
+ WorldPackets::Battleground::DestroyArenaUnit destroyArenaUnit;
+ destroyArenaUnit.Guid = GetGUID();
+ target->GetSession()->SendPacket(destroyArenaUnit.Write());
+ }
+ }
+
+ WorldObject::DestroyForPlayer(target, onDeath);
+}
+
int32 Unit::GetHighestExclusiveSameEffectSpellGroupValue(AuraEffect const* aurEff, AuraType auraType, bool checkMiscValue /*= false*/, int32 miscValue /*= 0*/) const
{
int32 val = 0;
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index e5495134252..5991b268b87 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1833,6 +1833,7 @@ class TC_GAME_API Unit : public WorldObject
explicit Unit (bool isWorldObject);
void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player const* target) const override;
+ void DestroyForPlayer(Player* target, bool onDeath) const override;
void _UpdateSpells(uint32 time);
void _DeleteRemovedAuras();
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 135fee4c58d..7c17d794c0e 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -2013,8 +2013,10 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
}
}
-GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 /*MaxPlayerCount*/, bool isRated, uint32 arenaSlot)
+GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 /*MaxPlayerCount*/, bool isRated, uint32 arenaSlot, ObjectGuid& errorGuid) const
{
+ errorGuid = ObjectGuid::Empty;
+
// check if this group is LFG group
if (isLFGGroup())
return ERR_LFG_CANT_USE_BATTLEGROUND;
@@ -2044,12 +2046,13 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
// check every member of the group to be able to join
memberscount = 0;
- for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next(), ++memberscount)
+ for (GroupReference const* itr = GetFirstMember(); itr != nullptr; itr = itr->next(), ++memberscount)
{
Player* member = itr->GetSource();
// offline member? don't let join
if (!member)
return ERR_BATTLEGROUND_JOIN_FAILED;
+ errorGuid = member->GetGUID();
// rbac permissions
if (!member->CanJoinToBattleground(bgOrTemplate))
return ERR_BATTLEGROUND_JOIN_TIMED_OUT;
@@ -2087,6 +2090,8 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
return ERR_BATTLEGROUND_JOIN_FAILED;
}
+ errorGuid = ObjectGuid::Empty;
+
// only check for MinPlayerCount since MinPlayerCount == MaxPlayerCount for arenas...
if (bgOrTemplate->isArena() && memberscount != MinPlayerCount)
return ERR_ARENA_TEAM_PARTY_SIZE;
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index f03a2fc44fa..8c43bba5301 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -257,7 +257,7 @@ class TC_GAME_API Group
void SetBattlegroundGroup(Battleground* bg);
void SetBattlefieldGroup(Battlefield* bf);
- GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot);
+ GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot, ObjectGuid& errorGuid) const;
void ChangeMembersGroup(ObjectGuid guid, uint8 group);
void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid);
diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp
index 658c42ef0a5..81f3591dc98 100644
--- a/src/server/game/Handlers/BattleGroundHandler.cpp
+++ b/src/server/game/Handlers/BattleGroundHandler.cpp
@@ -18,8 +18,11 @@
#include "WorldSession.h"
#include "ArenaTeam.h"
#include "ArenaTeamMgr.h"
+#include "Battlefield.h"
+#include "BattlefieldMgr.h"
#include "Battleground.h"
#include "BattlegroundMgr.h"
+#include "BattlegroundPackets.h"
#include "Chat.h"
#include "Common.h"
#include "Creature.h"
@@ -30,21 +33,15 @@
#include "Group.h"
#include "Language.h"
#include "Log.h"
+#include "NPCPackets.h"
#include "Object.h"
#include "ObjectAccessor.h"
-#include "ObjectMgr.h"
-#include "Opcodes.h"
#include "Player.h"
#include "World.h"
-#include "WorldPacket.h"
-void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData)
+void WorldSession::HandleBattlemasterHelloOpcode(WorldPackets::NPC::Hello& hello)
{
- ObjectGuid guid;
- recvData >> guid;
- TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from {}", guid.ToString());
-
- Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BATTLEMASTER);
+ Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(hello.Unit, UNIT_NPC_FLAG_BATTLEMASTER);
if (!unit)
return;
@@ -62,45 +59,25 @@ void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData)
return;
}
- SendBattleGroundList(guid, bgTypeId);
-}
-
-void WorldSession::SendBattleGroundList(ObjectGuid guid, BattlegroundTypeId bgTypeId)
-{
- WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId, 0);
- SendPacket(&data);
+ sBattlegroundMgr->SendBattlegroundList(_player, hello.Unit, bgTypeId);
}
-void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
+void WorldSession::HandleBattlemasterJoinOpcode(WorldPackets::Battleground::BattlemasterJoin& battlemasterJoin)
{
- ObjectGuid guid;
- uint32 bgTypeId_;
- uint32 instanceId;
- uint8 joinAsGroup;
bool isPremade = false;
- Group* grp = nullptr;
-
- recvData >> guid; // battlemaster guid
- recvData >> bgTypeId_; // battleground type id (DBC id)
- recvData >> instanceId; // instance id, 0 if First Available selected
- recvData >> joinAsGroup; // join as group
-
- if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
+ if (!sBattlemasterListStore.LookupEntry(battlemasterJoin.BattlemasterListID))
{
- TC_LOG_ERROR("network", "Battleground: invalid bgtype ({}) received. possible cheater? player {}", bgTypeId_, _player->GetGUID().ToString());
+ TC_LOG_ERROR("network", "Battleground: invalid bgtype ({}) received. possible cheater? player {}", battlemasterJoin.BattlemasterListID, _player->GetGUID().ToString());
return;
}
- if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, nullptr))
+ if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, battlemasterJoin.BattlemasterListID, nullptr))
{
ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED);
return;
}
- BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
-
- TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from {}", guid.ToString());
+ BattlegroundTypeId bgTypeId = BattlegroundTypeId(battlemasterJoin.BattlemasterListID);
// ignore if player is already in BG
if (_player->InBattleground())
@@ -108,8 +85,8 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
// get bg instance or bg template if instance not found
Battleground* bg = nullptr;
- if (instanceId)
- bg = sBattlegroundMgr->GetBattlegroundThroughClientInstance(instanceId, bgTypeId);
+ if (battlemasterJoin.InstanceID)
+ bg = sBattlegroundMgr->GetBattlegroundThroughClientInstance(battlemasterJoin.InstanceID, bgTypeId);
if (!bg)
bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
@@ -123,55 +100,62 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
// can do this, since it's battleground, not arena
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, bracketEntry->GetBracketId(), 0);
- BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, bracketEntry->GetBracketId(), 0);
- GroupJoinBattlegroundResult err;
+ GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE;
+
+ Group const* grp = _player->GetGroup();
// check queue conditions
- if (!joinAsGroup)
+ if (!battlemasterJoin.JoinAsGroup)
{
if (GetPlayer()->isUsingLfg())
{
- // player is using dungeon finder or raid finder
- WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_LFG_CANT_USE_BATTLEGROUND);
- GetPlayer()->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, ERR_LFG_CANT_USE_BATTLEGROUND);
+ SendPacket(battlefieldStatus.Write());
return;
}
// check RBAC permissions
if (!_player->CanJoinToBattleground(bg))
{
- WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_JOIN_TIMED_OUT);
- GetPlayer()->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, ERR_BATTLEGROUND_JOIN_TIMED_OUT);
+ SendPacket(battlefieldStatus.Write());
return;
}
// check Deserter debuff
if (_player->IsDeserter())
{
- WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
- _player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
+ SendPacket(battlefieldStatus.Write());
return;
}
- if (_player->GetBattlegroundQueueIndex(bgQueueTypeIdRandom) < PLAYER_MAX_BATTLEGROUND_QUEUES)
+ bool isInRandomBgQueue = [&]
+ {
+ for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
+ if (_player->GetBattlegroundQueueTypeId(i).BattlemasterListId == BATTLEGROUND_RB)
+ return true;
+ return false;
+ }();
+ if (!BattlegroundMgr::IsRandomBattleground(bgTypeId) && isInRandomBgQueue)
{
// player is already in random queue
- WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_RANDOM_BG);
- _player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, ERR_IN_RANDOM_BG);
+ SendPacket(battlefieldStatus.Write());
return;
}
- if (_player->InBattlegroundQueue(true) && bgTypeId == BATTLEGROUND_RB)
+ if (_player->InBattlegroundQueue(true) && !isInRandomBgQueue && BattlegroundMgr::IsRandomBattleground(bgTypeId))
{
// player is already in queue, can't start random queue
- WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_NON_RANDOM_BG);
- _player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, ERR_IN_NON_RANDOM_BG);
+ SendPacket(battlefieldStatus.Write());
return;
}
@@ -183,9 +167,9 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
// check if has free queue slots
if (!_player->HasFreeBattlegroundQueueId())
{
- WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES);
- _player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, ERR_BATTLEGROUND_TOO_MANY_QUEUES);
+ SendPacket(battlefieldStatus.Write());
return;
}
@@ -194,29 +178,27 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
return;
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
-
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bracketEntry, false, isPremade, 0, 0);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo);
- // already checked if queueSlot is valid, now just get it
uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
- WorldPacket data;
- // send status packet (in queue)
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, 0, 0);
- SendPacket(&data);
+ WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusQueued(&battlefieldStatus, bg, queueSlot, ginfo->JoinTime, bgQueueTypeId, avgTime);
+ SendPacket(battlefieldStatus.Write());
+
TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}, {}, NAME {}",
bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize),
_player->GetGUID().ToString(), _player->GetName());
}
else
{
- grp = _player->GetGroup();
- // no group found, error
if (!grp)
return;
if (grp->GetLeaderGUID() != _player->GetGUID())
return;
- err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
+
+ ObjectGuid errorGuid;
+ err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0, errorGuid);
isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam());
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
@@ -230,29 +212,30 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
avgTime = bgQueue.GetAverageQueueWaitTime(ginfo);
}
- for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
+ for (GroupReference const* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* member = itr->GetSource();
if (!member)
continue; // this should never happen
- WorldPacket data;
-
if (err <= 0)
{
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
- member->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, err, &errorGuid);
+ member->SendDirectMessage(battlefieldStatus.Write());
continue;
}
// add to queue
uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
- // send status packet (in queue)
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, 0, 0);
- member->SendDirectMessage(&data);
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
- member->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusQueued(&battlefieldStatus, bg, queueSlot, ginfo->JoinTime, bgQueueTypeId, avgTime);
+ member->SendDirectMessage(battlefieldStatus.Write());
+
+ WorldPackets::Battleground::GroupJoinedBattleground groupJoinedBattleground;
+ BattlegroundMgr::BuildGroupJoinedBattlegroundPacket(&groupJoinedBattleground, BattlegroundTypeId(err));
+ member->SendDirectMessage(battlefieldStatus.Write());
TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}, {}, NAME {}",
bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize),
member->GetGUID().ToString(), member->GetName());
@@ -262,61 +245,26 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
sBattlegroundMgr->ScheduleQueueUpdate(0, bgQueueTypeId);
}
-void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvData*/)
+void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPackets::Battleground::BattlegroundPlayerPositionsRequest& /*battlegroundPlayerPositionsRequest*/)
{
- TC_LOG_DEBUG("network", "WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message");
-
Battleground* bg = _player->GetBattleground();
if (!bg) // can't be received if player not in battleground
return;
- uint32 flagCarrierCount = 0;
- Player* allianceFlagCarrier = nullptr;
- Player* hordeFlagCarrier = nullptr;
-
+ WorldPackets::Battleground::BattlegroundPlayerPositions playerPositions;
if (ObjectGuid guid = bg->GetFlagPickerGUID(TEAM_ALLIANCE))
- {
- allianceFlagCarrier = ObjectAccessor::FindPlayer(guid);
- if (allianceFlagCarrier)
- ++flagCarrierCount;
- }
+ if (Player* allianceFlagCarrier = ObjectAccessor::GetPlayer(*_player, guid))
+ playerPositions.FlagCarriers.emplace_back(guid, allianceFlagCarrier->GetPosition());
if (ObjectGuid guid = bg->GetFlagPickerGUID(TEAM_HORDE))
- {
- hordeFlagCarrier = ObjectAccessor::FindPlayer(guid);
- if (hordeFlagCarrier)
- ++flagCarrierCount;
- }
-
- WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, 4 + 4 + 16 * flagCarrierCount);
- // Used to send several player positions (found used in AV)
- data << 0; // CGBattlefieldInfo__m_numPlayerPositions
- /*
- for (CGBattlefieldInfo__m_numPlayerPositions)
- data << guid << posx << posy;
- */
- data << flagCarrierCount;
- if (allianceFlagCarrier)
- {
- data << uint64(allianceFlagCarrier->GetGUID());
- data << float(allianceFlagCarrier->GetPositionX());
- data << float(allianceFlagCarrier->GetPositionY());
- }
-
- if (hordeFlagCarrier)
- {
- data << uint64(hordeFlagCarrier->GetGUID());
- data << float(hordeFlagCarrier->GetPositionX());
- data << float(hordeFlagCarrier->GetPositionY());
- }
+ if (Player* hordeFlagCarrier = ObjectAccessor::GetPlayer(*_player, guid))
+ playerPositions.FlagCarriers.emplace_back(guid, hordeFlagCarrier->GetPosition());
- SendPacket(&data);
+ SendPacket(playerPositions.Write());
}
-void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recvData*/)
+void WorldSession::HandlePVPLogDataOpcode(WorldPackets::Battleground::PVPLogDataRequest& /*pvpLogDataRequest*/)
{
- TC_LOG_DEBUG("network", "WORLD: Recvd MSG_PVP_LOG_DATA Message");
-
Battleground* bg = _player->GetBattleground();
if (!bg)
return;
@@ -325,103 +273,73 @@ void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recvData*/)
if (bg->isArena())
return;
- WorldPacket data;
- bg->BuildPvPLogDataPacket(data);
- SendPacket(&data);
-
- TC_LOG_DEBUG("network", "WORLD: Sent MSG_PVP_LOG_DATA Message");
+ WorldPackets::Battleground::PVPMatchStatistics pvpMatchStatistics;
+ bg->BuildPvPLogDataPacket(pvpMatchStatistics);
+ SendPacket(pvpMatchStatistics.Write());
}
-void WorldSession::HandleBattlefieldListOpcode(WorldPacket &recvData)
+void WorldSession::HandleBattlefieldListOpcode(WorldPackets::Battleground::BattlefieldListRequest& battlefieldList)
{
- TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_LIST Message");
-
- uint32 bgTypeId;
- recvData >> bgTypeId; // id from DBC
-
- uint8 fromWhere;
- recvData >> fromWhere; // 0 - battlemaster (lua: ShowBattlefieldList), 1 - UI (lua: RequestBattlegroundInstanceInfo)
-
- uint8 canGainXP;
- recvData >> canGainXP; // players with locked xp have their own bg queue on retail
-
- BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
- if (!bl)
+ BattlemasterListEntry const* battlemasterListEntry = sBattlemasterListStore.LookupEntry(battlefieldList.ListID);
+ if (!battlemasterListEntry)
{
- TC_LOG_DEBUG("bg.battleground", "BattlegroundHandler: invalid bgtype ({}) with player (Name: {}, {}) received.", bgTypeId, _player->GetName(), _player->GetGUID().ToString());
+ TC_LOG_DEBUG("bg.battleground", "BattlegroundHandler: invalid bgtype ({}) with player (Name: {}, {}) received.", battlefieldList.ListID, _player->GetName(), _player->GetGUID().ToString());
return;
}
- WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundListPacket(&data, ObjectGuid::Empty, _player, BattlegroundTypeId(bgTypeId), fromWhere);
- SendPacket(&data);
+ sBattlegroundMgr->SendBattlegroundList(_player, ObjectGuid::Empty, BattlegroundTypeId(battlefieldList.ListID));
}
-void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
+void WorldSession::HandleBattleFieldPortOpcode(WorldPackets::Battleground::BattlefieldPort& battlefieldPort)
{
- uint64 packedQueueId;
- uint8 action; // enter battle 0x1, leave queue 0x0
-
- recvData >> packedQueueId >> action;
-
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundQueueTypeId::FromPacked(packedQueueId);
- uint8 type = bgQueueTypeId.TeamSize;
- uint8 unk2 = bgQueueTypeId.BracketId;
- uint32 bgTypeId_ = bgQueueTypeId.BattlemasterListId;
- if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
- {
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Invalid BgType!",
- GetPlayerInfo(), type, unk2, bgTypeId_, action);
- return;
- }
-
- if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) == PLAYER_MAX_BATTLEGROUND_QUEUES)
+ BattlegroundQueueTypeId bgQueueTypeId = BattlegroundQueueTypeId::FromPacked(battlefieldPort.QueueID);
+ uint32 queueSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId);
+ if (queueSlot >= PLAYER_MAX_BATTLEGROUND_QUEUES)
{
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue!",
- GetPlayerInfo(), type, unk2, bgTypeId_, action);
+ TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}, AcceptedInvite: {}. Invalid queueSlot.",
+ GetPlayerInfo(), bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize), battlefieldPort.AcceptedInvite);
return;
}
- //get GroupQueueInfo from BattlegroundQueue
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
//we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattlegroundQueue::RemovePlayer() function
GroupQueueInfo ginfo;
if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
{
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue (No player Group Info)!",
- GetPlayerInfo(), type, unk2, bgTypeId_, action);
+ TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}, AcceptedInvite: {}. Player not in queue (No player Group Info)!",
+ GetPlayerInfo(), bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize), battlefieldPort.AcceptedInvite);
return;
}
- // if action == 1, then instanceId is required
- if (!ginfo.IsInvitedToBGInstanceGUID && action == 1)
+ // if action == 1, then player must have been invited to join
+ if (!ginfo.IsInvitedToBGInstanceGUID && battlefieldPort.AcceptedInvite)
{
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player is not invited to any bg!",
- GetPlayerInfo(), type, unk2, bgTypeId_, action);
+ TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}, AcceptedInvite: {}. Player is not invited to any bg!",
+ GetPlayerInfo(), bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize), battlefieldPort.AcceptedInvite);
return;
}
- BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
+ BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgQueueTypeId.BattlemasterListId);
Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
if (!bg)
{
- if (action)
+ if (battlefieldPort.AcceptedInvite)
{
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Cant find BG with id {}!",
- GetPlayerInfo(), type, unk2, bgTypeId_, action, ginfo.IsInvitedToBGInstanceGUID);
+ TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}, AcceptedInvite: {}. Cant find BG with id {}!",
+ GetPlayerInfo(), bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize), battlefieldPort.AcceptedInvite, ginfo.IsInvitedToBGInstanceGUID);
return;
}
bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
if (!bg)
{
- TC_LOG_ERROR("network", "BattlegroundHandler: bg_template not found for type id {}.", bgTypeId);
+ TC_LOG_ERROR("network", "BattlegroundHandler: BattlegroundTemplate not found for type id {}.", bgTypeId);
return;
}
}
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}.",
- GetPlayerInfo(), type, unk2, bgTypeId_, action);
+ TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}, AcceptedInvite: {}.",
+ GetPlayerInfo(), bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize), battlefieldPort.AcceptedInvite);
// expected bracket entry
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->GetLevel());
@@ -429,16 +347,16 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
return;
//some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it
- if (action == 1 && bgQueue.GetQueueId().TeamSize == 0)
+ if (battlefieldPort.AcceptedInvite && bgQueue.GetQueueId().TeamSize == 0)
{
//if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue
if (_player->IsDeserter())
{
//send bg command result to show nice message
- WorldPacket data2;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data2, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
- _player->SendDirectMessage(&data2);
- action = 0;
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
+ SendPacket(battlefieldStatus.Write());
+ battlefieldPort.AcceptedInvite = false;
TC_LOG_DEBUG("bg.battleground", "Player {} {} has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUID().ToString());
}
//if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue
@@ -446,12 +364,11 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
{
TC_LOG_ERROR("network", "Player {} {} has level ({}) higher than maxlevel ({}) of battleground ({})! Do not port him to battleground!",
_player->GetName(), _player->GetGUID().ToString(), _player->GetLevel(), bg->GetMaxLevel(), bg->GetTypeID());
- action = 0;
+ battlefieldPort.AcceptedInvite = false;
}
}
- uint32 queueSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId);
- WorldPacket data;
- if (action)
+
+ if (battlefieldPort.AcceptedInvite)
{
// check Freeze debuff
if (_player->HasAura(9454))
@@ -472,8 +389,9 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
// stop taxi flight at port
_player->FinishTaxiFlight();
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), ginfo.Team);
- _player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusActive battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusActive(&battlefieldStatus, bg, _player, queueSlot, bgQueueTypeId);
+ SendPacket(battlefieldStatus.Write());
// remove battleground queue status from BGmgr
bgQueue.RemovePlayer(_player->GetGUID(), false);
@@ -511,13 +429,17 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
at->SaveToDB();
}
}
+
+ WorldPackets::Battleground::BattlefieldStatusNone battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusNone(&battlefieldStatus, queueSlot);
+ SendPacket(battlefieldStatus.Write());
+
_player->RemoveBattlegroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, 0);
bgQueue.RemovePlayer(_player->GetGUID(), true);
// player left queue, we should update it - do not update Arena Queue
if (!bgQueue.GetQueueId().TeamSize)
sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, bgQueueTypeId);
- SendPacket(&data);
+
TC_LOG_DEBUG("bg.battleground", "Battleground: player {} ({}) left queue for bgtype {}, queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}.",
_player->GetName(), _player->GetGUID().ToString(), bg->GetTypeID(),
bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize));
@@ -534,15 +456,8 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
}
}
-void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& recvData)
+void WorldSession::HandleBattlefieldLeaveOpcode(WorldPackets::Battleground::BattlefieldLeave& /*battlefieldLeave*/)
{
- TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message");
-
- recvData.read_skip<uint8>(); // unk1
- recvData.read_skip<uint8>(); // unk2
- recvData.read_skip<uint32>(); // BattlegroundTypeId
- recvData.read_skip<uint16>(); // unk3
-
// not allow leave battleground in combat
if (_player->IsInCombat())
if (Battleground* bg = _player->GetBattleground())
@@ -552,12 +467,8 @@ void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& recvData)
_player->LeaveBattleground();
}
-void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/)
+void WorldSession::HandleRequestBattlefieldStatusOpcode(WorldPackets::Battleground::RequestBattlefieldStatus& /*requestBattlefieldStatus*/)
{
- // empty opcode
- TC_LOG_DEBUG("network", "WORLD: Battleground status");
-
- WorldPacket data;
// we must update all queues here
Battleground* bg = nullptr;
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
@@ -567,7 +478,6 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/)
continue;
BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgQueueTypeId.BattlemasterListId);
bg = _player->GetBattleground();
- uint8 arenaType = bgQueueTypeId.TeamSize;
if (bg)
{
BattlegroundPlayer const* bgPlayer = bg->GetBattlegroundPlayerData(_player->GetGUID());
@@ -575,8 +485,9 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/)
{
//i cannot check any variable from player class because player class doesn't know if player is in 2v2 / 3v3 or 5v5 arena
//so i must use bg pointer to get that information
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam());
- SendPacket(&data);
+ WorldPackets::Battleground::BattlefieldStatusActive battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusActive(&battlefieldStatus, bg, _player, i, bgQueueTypeId);
+ SendPacket(battlefieldStatus.Write());
continue;
}
}
@@ -592,10 +503,10 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/)
bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
if (!bg)
continue;
- uint32 remainingTime = getMSTimeDiff(GameTime::GetGameTimeMS(), ginfo.RemoveInviteTime);
- // send status invited to Battleground
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType, 0);
- SendPacket(&data);
+
+ WorldPackets::Battleground::BattlefieldStatusNeedConfirmation battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusNeedConfirmation(&battlefieldStatus, bg, i, getMSTimeDiff(GameTime::GetGameTimeMS(), ginfo.RemoveInviteTime), bgQueueTypeId);
+ SendPacket(battlefieldStatus.Write());
}
else
{
@@ -609,43 +520,33 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/)
continue;
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo);
- // send status in Battleground Queue
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, GameTime::GetGameTimeMS()), arenaType, 0);
- SendPacket(&data);
+ WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusQueued(&battlefieldStatus, bg, i, 0, bgQueueTypeId, avgTime);
+ SendPacket(battlefieldStatus.Write());
}
}
}
-void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
+void WorldSession::HandleBattlemasterJoinArena(WorldPackets::Battleground::BattlemasterJoinArena& packet)
{
- TC_LOG_DEBUG("network", "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
-
- ObjectGuid guid; // arena Battlemaster guid
- uint8 arenaslot; // 2v2, 3v3 or 5v5
- uint8 asGroup; // asGroup
- uint8 isRated; // isRated
- Group* grp = nullptr;
-
- recvData >> guid >> arenaslot >> asGroup >> isRated;
-
// ignore if rated but queued solo
- if (isRated && !asGroup)
+ if (packet.IsRated && !packet.JoinAsGroup)
return;
// ignore if we already in BG or BG queue
if (_player->InBattleground())
return;
- Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BATTLEMASTER);
+ Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.BattlemasterGuid, UNIT_NPC_FLAG_BATTLEMASTER);
if (!unit)
return;
- uint8 arenatype = ArenaTeam::GetTypeBySlot(arenaslot);
+ uint8 arenatype = ArenaTeam::GetTypeBySlot(packet.TeamSizeIndex);
uint32 arenaRating = 0;
uint32 matchmakerRating = 0;
uint32 previousOpponents = 0;
- //check existance
+ //check existence
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA);
if (!bg)
{
@@ -659,30 +560,29 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
return;
}
+ BattlegroundTypeId bgTypeId = bg->GetTypeID();
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->GetLevel());
if (!bracketEntry)
return;
- BattlegroundTypeId bgTypeId = bg->GetTypeID();
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, bracketEntry->GetBracketId(), arenatype);
- GroupJoinBattlegroundResult err = ERR_GROUP_JOIN_BATTLEGROUND_FAIL;
-
- if (!asGroup)
+ Group* grp = _player->GetGroup();
+ if (!packet.JoinAsGroup)
{
if (_player->isUsingLfg())
{
// player is using dungeon finder or raid finder
- WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_LFG_CANT_USE_BATTLEGROUND);
- _player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, ERR_LFG_CANT_USE_BATTLEGROUND);
+ SendPacket(battlefieldStatus.Write());
return;
}
if (!_player->CanJoinToBattleground(bg))
{
- WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_JOIN_FAILED);
- _player->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, ERR_BATTLEGROUND_JOIN_FAILED);
+ SendPacket(battlefieldStatus.Write());
return;
}
@@ -696,27 +596,26 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
}
else
{
- grp = _player->GetGroup();
// no group found, error
if (!grp)
return;
if (grp->GetLeaderGUID() != _player->GetGUID())
return;
- err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, arenatype, arenatype, isRated != 0, arenaslot);
}
uint32 ateamId = 0;
- if (isRated)
+ if (packet.IsRated)
{
- ateamId = _player->GetArenaTeamId(arenaslot);
+ ateamId = _player->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 = sArenaTeamMgr->GetArenaTeamById(ateamId);
if (!at)
{
- _player->GetSession()->SendNotInArenaTeamPacket(arenatype);
+ SendNotInArenaTeamPacket(arenatype);
return;
}
+
// get the team rating for queueing
arenaRating = at->GetRating();
matchmakerRating = at->GetAverageMMR(grp);
@@ -728,23 +627,25 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
previousOpponents = at->GetPreviousOpponents();
}
- BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
- if (asGroup)
+ BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
+ if (packet.JoinAsGroup)
{
uint32 avgTime = 0;
+ GroupQueueInfo* ginfo = nullptr;
+ ObjectGuid errorGuid;
+ GroupJoinBattlegroundResult err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, arenatype, arenatype, true, packet.TeamSizeIndex, errorGuid);
if (err > 0)
{
- TC_LOG_DEBUG("bg.battleground", "Battleground: arena join as group start");
- if (isRated)
+ if (packet.IsRated)
{
- TC_LOG_DEBUG("bg.battleground", "Battleground: arena team id {}, leader {} queued with matchmaker rating {} for type {}", _player->GetArenaTeamId(arenaslot), _player->GetName(), matchmakerRating, arenatype);
+ TC_LOG_DEBUG("bg.battleground", "Battleground: arena team id {}, leader {} queued with matchmaker rating {} for type {}", _player->GetArenaTeamId(packet.TeamSizeIndex), _player->GetName(), matchmakerRating, arenatype);
bg->SetRated(true);
}
else
bg->SetRated(false);
- GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bracketEntry, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
+ ginfo = bgQueue.AddGroup(_player, grp, bracketEntry, packet.IsRated, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
avgTime = bgQueue.GetAverageQueueWaitTime(ginfo);
}
@@ -754,23 +655,32 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
if (!member)
continue;
- WorldPacket data;
-
if (err <= 0)
{
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
- member->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, err, &errorGuid);
+ member->SendDirectMessage(battlefieldStatus.Write());
continue;
}
+ if (!_player->CanJoinToBattleground(bg))
+ {
+ WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusFailed(&battlefieldStatus, ERR_BATTLEGROUND_JOIN_FAILED, &errorGuid);
+ member->SendDirectMessage(battlefieldStatus.Write());
+ return;
+ }
+
// add to queue
uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
- // send status packet (in queue)
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, 0);
- member->SendDirectMessage(&data);
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
- member->SendDirectMessage(&data);
+ WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusQueued(&battlefieldStatus, bg, queueSlot, ginfo->JoinTime, bgQueueTypeId, avgTime);
+ member->SendDirectMessage(battlefieldStatus.Write());
+
+ WorldPackets::Battleground::GroupJoinedBattleground groupJoinedBattleground;
+ BattlegroundMgr::BuildGroupJoinedBattlegroundPacket(&groupJoinedBattleground, BattlegroundTypeId(err));
+ member->SendDirectMessage(groupJoinedBattleground.Write());
TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}, {}, NAME {}",
bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize),
member->GetGUID().ToString(), member->GetName());
@@ -778,30 +688,28 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
}
else
{
- GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bracketEntry, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
+ GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bracketEntry, packet.IsRated, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo);
uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
- WorldPacket data;
- // send status packet (in queue)
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, 0);
- SendPacket(&data);
+ WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus;
+ BattlegroundMgr::BuildBattlegroundStatusQueued(&battlefieldStatus, bg, queueSlot, ginfo->JoinTime, bgQueueTypeId, avgTime);
+ SendPacket(battlefieldStatus.Write());
+
TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena, skirmish, bg queue type {{ BattlemasterListId: {}, BracketId: {}, TeamSize: {} }}: {}, NAME {}",
bgQueueTypeId.BattlemasterListId, uint32(bgQueueTypeId.BracketId), uint32(bgQueueTypeId.TeamSize),
_player->GetGUID().ToString(), _player->GetName());
}
+
sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, bgQueueTypeId);
}
-void WorldSession::HandleReportPvPAFK(WorldPacket& recvData)
+void WorldSession::HandleReportPvPAFK(WorldPackets::Battleground::ReportPvPPlayerAFK& reportPvPPlayerAFK)
{
- ObjectGuid playerGuid;
- recvData >> playerGuid;
- Player* reportedPlayer = ObjectAccessor::FindPlayer(playerGuid);
-
+ Player* reportedPlayer = ObjectAccessor::FindPlayer(reportPvPPlayerAFK.Offender);
if (!reportedPlayer)
{
- TC_LOG_INFO("bg.reportpvpafk", "WorldSession::HandleReportPvPAFK: {} [IP: {}] reported {}", _player->GetName(), _player->GetSession()->GetRemoteAddress(), playerGuid.ToString());
+ TC_LOG_INFO("bg.reportpvpafk", "WorldSession::HandleReportPvPAFK: {} [IP: {}] reported {}", _player->GetName(), _player->GetSession()->GetRemoteAddress(), reportPvPPlayerAFK.Offender.ToString());
return;
}
@@ -809,3 +717,56 @@ void WorldSession::HandleReportPvPAFK(WorldPacket& recvData)
reportedPlayer->ReportedAfkBy(_player);
}
+
+void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPackets::Battleground::AreaSpiritHealerQuery& areaSpiritHealerQuery)
+{
+ Player* player = GetPlayer();
+ Creature* spiritHealer = ObjectAccessor::GetCreature(*player, areaSpiritHealerQuery.HealerGuid);
+ if (!spiritHealer)
+ return;
+
+ if (!spiritHealer->IsSpiritService())
+ return;
+
+ if (Battleground* bg = _player->GetBattleground())
+ sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, areaSpiritHealerQuery.HealerGuid);
+
+ if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
+ bf->SendAreaSpiritHealerQueryOpcode(_player, areaSpiritHealerQuery.HealerGuid);
+}
+
+void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPackets::Battleground::AreaSpiritHealerQueue& areaSpiritHealerQueue)
+{
+ Creature* spiritHealer = ObjectAccessor::GetCreature(*GetPlayer(), areaSpiritHealerQueue.HealerGuid);
+ if (!spiritHealer)
+ return;
+
+ if (!spiritHealer->IsSpiritService())
+ return;
+
+ if (Battleground* bg = _player->GetBattleground())
+ bg->AddPlayerToResurrectQueue(areaSpiritHealerQueue.HealerGuid, _player->GetGUID());
+
+ if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
+ bf->AddPlayerToResurrectQueue(areaSpiritHealerQueue.HealerGuid, _player->GetGUID());
+}
+
+void WorldSession::HandleHearthAndResurrect(WorldPackets::Battleground::HearthAndResurrect& /*hearthAndResurrect*/)
+{
+ if (_player->IsInFlight())
+ return;
+
+ if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
+ {
+ bf->PlayerAskToLeave(_player);
+ return;
+ }
+
+ AreaTableEntry const* atEntry = sAreaTableStore.LookupEntry(_player->GetAreaId());
+ if (!atEntry || !(atEntry->Flags & AREA_FLAG_WINTERGRASP_2))
+ return;
+
+ _player->BuildPlayerRepop();
+ _player->ResurrectPlayer(1.0f);
+ _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation());
+}
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index eda9900a26e..29d61b64340 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -17,9 +17,6 @@
#include "WorldSession.h"
#include "AccountMgr.h"
-#include "Battlefield.h"
-#include "BattlefieldMgr.h"
-#include "Battleground.h"
#include "BattlegroundMgr.h"
#include "CharacterPackets.h"
#include "Chat.h"
@@ -1327,72 +1324,6 @@ void WorldSession::SendSetPhaseShift(uint32 PhaseShift)
data << uint32(PhaseShift);
SendPacket(&data);
}
-// Battlefield and Battleground
-void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket& recvData)
-{
- TC_LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY");
-
- Battleground* bg = _player->GetBattleground();
-
- ObjectGuid guid;
- recvData >> guid;
-
- Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
- if (!unit)
- return;
-
- if (!unit->IsSpiritService()) // it's not spirit service
- return;
-
- if (bg)
- sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, guid);
-
- if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
- bf->SendAreaSpiritHealerQueryOpcode(_player, guid);
-}
-
-void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPacket& recvData)
-{
- TC_LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE");
-
- Battleground* bg = _player->GetBattleground();
-
- ObjectGuid guid;
- recvData >> guid;
-
- Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
- if (!unit)
- return;
-
- if (!unit->IsSpiritService()) // it's not spirit service
- return;
-
- if (bg)
- bg->AddPlayerToResurrectQueue(guid, _player->GetGUID());
-
- if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
- bf->AddPlayerToResurrectQueue(guid, _player->GetGUID());
-}
-
-void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recvData*/)
-{
- if (_player->IsInFlight())
- return;
-
- if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
- {
- bf->PlayerAskToLeave(_player);
- return;
- }
-
- AreaTableEntry const* atEntry = sAreaTableStore.LookupEntry(_player->GetAreaId());
- if (!atEntry || !(atEntry->Flags & AREA_FLAG_WINTERGRASP_2))
- return;
-
- _player->BuildPlayerRepop();
- _player->ResurrectPlayer(1.0f);
- _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation());
-}
void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket)
{
diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h
index 041ea5b7599..de8cc0b7524 100644
--- a/src/server/game/Server/Packets/AllPackets.h
+++ b/src/server/game/Server/Packets/AllPackets.h
@@ -19,6 +19,7 @@
#define AllPackets_h__
#include "BankPackets.h"
+#include "BattlegroundPackets.h"
#include "CalendarPackets.h"
#include "CharacterPackets.h"
#include "ChatPackets.h"
diff --git a/src/server/game/Server/Packets/BattlegroundPackets.cpp b/src/server/game/Server/Packets/BattlegroundPackets.cpp
new file mode 100644
index 00000000000..460820e900a
--- /dev/null
+++ b/src/server/game/Server/Packets/BattlegroundPackets.cpp
@@ -0,0 +1,272 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "BattlegroundPackets.h"
+#include "Battleground.h"
+
+void WorldPackets::Battleground::AreaSpiritHealerQuery::Read()
+{
+ _worldPacket >> HealerGuid;
+}
+
+void WorldPackets::Battleground::AreaSpiritHealerQueue::Read()
+{
+ _worldPacket >> HealerGuid;
+}
+
+WorldPacket const* WorldPackets::Battleground::AreaSpiritHealerTime::Write()
+{
+ _worldPacket << HealerGuid;
+ _worldPacket << int32(TimeLeft);
+
+ return &_worldPacket;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::PVPLogData_RatingData const& ratingData)
+{
+ for (std::size_t i = 0; i < 2; ++i)
+ {
+ data << int32(ratingData.Prematch[i]);
+ data << int32(ratingData.Postmatch[i]);
+ data << int32(ratingData.PrematchMMR[i]);
+ }
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::PVPLogData_Arena const& arena)
+{
+ data << arena.Ratings;
+ for (std::string_view const& teamName : arena.TeamName)
+ data << teamName;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::PVPLogData_Honor const& honorData)
+{
+ data << uint32(honorData.HonorKills);
+ data << uint32(honorData.Deaths);
+ data << uint32(honorData.ContributionPoints);
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::PVPLogData_Player const& playerData)
+{
+ data << playerData.PlayerGUID;
+ data << uint32(playerData.Kills);
+ std::visit([&](auto const& v) { return data << v; }, playerData.HonorOrFaction);
+ data << uint32(playerData.DamageDone);
+ data << uint32(playerData.HealingDone);
+ data << uint32(playerData.Stats.size());
+ for (uint32 pvpStat : playerData.Stats)
+ data << uint32(pvpStat);
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Battleground::PVPMatchStatistics::Write()
+{
+ _worldPacket.reserve(sizeof(PVPLogData_Arena) + 1 + 1 + 4 + Players.size() * sizeof(PVPLogData_Player));
+
+ _worldPacket << uint8(Arena.has_value());
+ if (Arena)
+ _worldPacket << *Arena;
+
+ _worldPacket << uint8(Winner.has_value());
+ if (Winner)
+ _worldPacket << uint8(*Winner);
+
+ _worldPacket << uint32(Players.size());
+ for (PVPLogData_Player const& player : Players)
+ _worldPacket << player;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Battleground::BattlemasterJoin::Read()
+{
+ _worldPacket >> BattlemasterGuid;
+ _worldPacket >> BattlemasterListID;
+ _worldPacket >> InstanceID;
+ _worldPacket >> JoinAsGroup;
+}
+
+void WorldPackets::Battleground::BattlemasterJoinArena::Read()
+{
+ _worldPacket >> BattlemasterGuid;
+ _worldPacket >> TeamSizeIndex;
+ _worldPacket >> JoinAsGroup;
+ _worldPacket >> IsRated;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::BattlefieldStatusHeader const& header)
+{
+ data << uint32(header.QueueSlot);
+ data << uint64(header.QueueID);
+ data << uint8(header.RangeMin);
+ data << uint8(header.RangeMax);
+ data << uint32(header.InstanceID);
+ data << uint8(header.RegisteredMatch);
+ return data;
+}
+
+WorldPacket const* WorldPackets::Battleground::BattlefieldStatusNone::Write()
+{
+ _worldPacket << uint32(QueueSlot);
+ _worldPacket << uint64(0);
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battleground::BattlefieldStatusNeedConfirmation::Write()
+{
+ _worldPacket << Hdr;
+ _worldPacket << uint32(STATUS_WAIT_JOIN);
+ _worldPacket << uint32(Mapid);
+ _worldPacket << uint64(RandomQueueID);
+ _worldPacket << uint32(Timeout);
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battleground::BattlefieldStatusActive::Write()
+{
+ _worldPacket << Hdr;
+ _worldPacket << uint32(STATUS_IN_PROGRESS);
+ _worldPacket << uint32(Mapid);
+ _worldPacket << uint64(RandomQueueID);
+ _worldPacket << uint32(ShutdownTimer);
+ _worldPacket << uint32(StartTimer);
+ _worldPacket << uint8(ArenaFaction);
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battleground::BattlefieldStatusQueued::Write()
+{
+ _worldPacket << Hdr;
+ _worldPacket << uint32(STATUS_WAIT_QUEUE);
+ _worldPacket << uint32(AverageWaitTime);
+ _worldPacket << uint32(WaitTime);
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battleground::GroupJoinedBattleground::Write()
+{
+ _worldPacket << uint32(Reason);
+ if (Reason == ERR_BATTLEGROUND_JOIN_TIMED_OUT || Reason == ERR_BATTLEGROUND_JOIN_FAILED)
+ _worldPacket << ClientID;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Battleground::BattlefieldLeave::Read()
+{
+ _worldPacket >> QueueID;
+}
+
+void WorldPackets::Battleground::BattlefieldPort::Read()
+{
+ _worldPacket >> QueueID;
+ _worldPacket >> AcceptedInvite;
+}
+
+void WorldPackets::Battleground::BattlefieldListRequest::Read()
+{
+ _worldPacket >> ListID;
+ _worldPacket >> PvpAnywhere;
+ _worldPacket >> NoXpGain;
+}
+
+WorldPacket const* WorldPackets::Battleground::BattlefieldList::Write()
+{
+ _worldPacket << BattlemasterGuid;
+ _worldPacket << uint8(PvpAnywhere);
+ _worldPacket << int32(BattlemasterListID);
+ _worldPacket << uint8(MinLevel);
+ _worldPacket << uint8(MaxLevel);
+
+ _worldPacket << uint8(HasHolidayWinToday);
+ _worldPacket << uint32(HolidayWinHonorCurrencyBonus);
+ _worldPacket << uint32(HolidayFirstWinArenaCurrencyBonus);
+ _worldPacket << uint32(HolidayLossHonorCurrencyBonus);
+
+ _worldPacket << uint8(BattlemasterListID == BATTLEGROUND_RB);
+ if (BattlemasterListID == BATTLEGROUND_RB)
+ {
+ _worldPacket << uint8(HasRandomWinToday);
+ _worldPacket << uint32(RandomWinHonorCurrencyBonus);
+ _worldPacket << uint32(RandomFirstWinArenaCurrencyBonus);
+ _worldPacket << uint32(RandomLossHonorCurrencyBonus);
+ }
+
+ _worldPacket << uint32(Battlefields ? Battlefields->size() : 0);
+ if (Battlefields)
+ for (uint32 battlefield : *Battlefields)
+ _worldPacket << uint32(battlefield);
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Battleground::ReportPvPPlayerAFK::Read()
+{
+ _worldPacket >> Offender;
+}
+
+WorldPacket const* WorldPackets::Battleground::ReportPvPPlayerAFKResult::Write()
+{
+ _worldPacket << uint8(Result);
+ _worldPacket << uint8(NumBlackMarksOnOffender);
+ _worldPacket << uint8(NumPlayersIHaveReported);
+ _worldPacket << Offender;
+ return &_worldPacket;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::BattlegroundPlayerPosition const& playerPosition)
+{
+ data << playerPosition.Guid;
+ data << playerPosition.Pos;
+ return data;
+}
+
+WorldPacket const* WorldPackets::Battleground::BattlegroundPlayerPositions::Write()
+{
+ _worldPacket << uint32(Players.size());
+ for (BattlegroundPlayerPosition const& pos : Players)
+ _worldPacket << pos;
+
+ _worldPacket << uint32(FlagCarriers.size());
+ for (BattlegroundPlayerPosition const& pos : FlagCarriers)
+ _worldPacket << pos;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battleground::BattlegroundPlayerJoined::Write()
+{
+ _worldPacket << Guid;
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battleground::BattlegroundPlayerLeft::Write()
+{
+ _worldPacket << Guid;
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battleground::DestroyArenaUnit::Write()
+{
+ _worldPacket << Guid;
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/BattlegroundPackets.h b/src/server/game/Server/Packets/BattlegroundPackets.h
new file mode 100644
index 00000000000..ce143b83ad0
--- /dev/null
+++ b/src/server/game/Server/Packets/BattlegroundPackets.h
@@ -0,0 +1,372 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef BattlegroundPackets_h__
+#define BattlegroundPackets_h__
+
+#include "Packet.h"
+#include "ObjectGuid.h"
+#include "Optional.h"
+#include "Position.h"
+#include <array>
+#include <variant>
+
+namespace WorldPackets
+{
+ namespace Battleground
+ {
+ class AreaSpiritHealerQuery final : public ClientPacket
+ {
+ public:
+ AreaSpiritHealerQuery(WorldPacket&& packet) : ClientPacket(CMSG_AREA_SPIRIT_HEALER_QUERY, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid HealerGuid;
+ };
+
+ class AreaSpiritHealerQueue final : public ClientPacket
+ {
+ public:
+ AreaSpiritHealerQueue(WorldPacket&& packet) : ClientPacket(CMSG_AREA_SPIRIT_HEALER_QUEUE, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid HealerGuid;
+ };
+
+ class AreaSpiritHealerTime final : public ServerPacket
+ {
+ public:
+ AreaSpiritHealerTime() : ServerPacket(SMSG_AREA_SPIRIT_HEALER_TIME, 8 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid HealerGuid;
+ int32 TimeLeft = 0;
+ };
+
+ class HearthAndResurrect final : public ClientPacket
+ {
+ public:
+ HearthAndResurrect(WorldPacket&& packet) : ClientPacket(CMSG_HEARTH_AND_RESURRECT, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class PVPLogDataRequest final : public ClientPacket
+ {
+ public:
+ PVPLogDataRequest(WorldPacket&& packet) : ClientPacket(MSG_PVP_LOG_DATA, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ struct PVPLogData_RatingData
+ {
+ std::array<int32,2 > Prematch = { };
+ std::array<int32,2 > Postmatch = { };
+ std::array<int32,2 > PrematchMMR = { };
+ };
+
+ struct PVPLogData_Arena
+ {
+ PVPLogData_RatingData Ratings;
+ std::array<std::string_view, 2> TeamName;
+ };
+
+ struct PVPLogData_Honor
+ {
+ uint32 HonorKills = 0;
+ uint32 Deaths = 0;
+ uint32 ContributionPoints = 0;
+ };
+
+ struct PVPLogData_Player
+ {
+ ObjectGuid PlayerGUID;
+ uint32 Kills = 0;
+ std::variant<PVPLogData_Honor, uint8> HonorOrFaction;
+ uint32 DamageDone = 0;
+ uint32 HealingDone = 0;
+ std::vector<uint32> Stats;
+ };
+
+ class PVPMatchStatistics final : public ServerPacket
+ {
+ public:
+ PVPMatchStatistics() : ServerPacket(MSG_PVP_LOG_DATA, 0) { }
+
+ WorldPacket const* Write() override;
+
+ Optional<uint8> Winner;
+ std::vector<PVPLogData_Player> Players;
+ Optional<PVPLogData_Arena> Arena;
+ };
+
+ struct BattlefieldStatusHeader
+ {
+ uint32 QueueSlot = 0;
+ uint64 QueueID = 0;
+ uint8 RangeMin = 0;
+ uint8 RangeMax = 0;
+ uint32 InstanceID = 0;
+ bool RegisteredMatch = false;
+ };
+
+ class BattlefieldStatusNone final : public ServerPacket
+ {
+ public:
+ BattlefieldStatusNone() : ServerPacket(SMSG_BATTLEFIELD_STATUS, 4 + 8) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 QueueSlot = 0;
+ };
+
+ class BattlefieldStatusNeedConfirmation final : public ServerPacket
+ {
+ public:
+ BattlefieldStatusNeedConfirmation() : ServerPacket(SMSG_BATTLEFIELD_STATUS, 4 + 4 + sizeof(BattlefieldStatusHeader) + 8) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 Timeout = 0;
+ uint32 Mapid = 0;
+ BattlefieldStatusHeader Hdr;
+ uint64 RandomQueueID = 0;
+ };
+
+ class BattlefieldStatusActive final : public ServerPacket
+ {
+ public:
+ BattlefieldStatusActive() : ServerPacket(SMSG_BATTLEFIELD_STATUS, sizeof(BattlefieldStatusHeader) + 4 + 1 + 4 + 4 + 8) { }
+
+ WorldPacket const* Write() override;
+
+ BattlefieldStatusHeader Hdr;
+ uint32 ShutdownTimer = 0;
+ uint8 ArenaFaction = 0;
+ uint32 StartTimer = 0;
+ uint32 Mapid = 0;
+ uint64 RandomQueueID = 0;
+ };
+
+ class BattlefieldStatusQueued final : public ServerPacket
+ {
+ public:
+ BattlefieldStatusQueued() : ServerPacket(SMSG_BATTLEFIELD_STATUS, 4 + sizeof(BattlefieldStatusHeader) + 4) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 AverageWaitTime = 0;
+ BattlefieldStatusHeader Hdr;
+ uint32 WaitTime = 0;
+ };
+
+ class GroupJoinedBattleground final : public ServerPacket
+ {
+ public:
+ GroupJoinedBattleground() : ServerPacket(SMSG_GROUP_JOINED_BATTLEGROUND, 8 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid ClientID;
+ int32 Reason = 0;
+ };
+
+ using BattlefieldStatusFailed = GroupJoinedBattleground;
+
+ class BattlemasterJoin final : public ClientPacket
+ {
+ public:
+ BattlemasterJoin(WorldPacket&& packet) : ClientPacket(CMSG_BATTLEMASTER_JOIN, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid BattlemasterGuid;
+ uint32 BattlemasterListID = 0;
+ uint32 InstanceID = 0;
+ bool JoinAsGroup = false;
+ };
+
+ class BattlemasterJoinArena final : public ClientPacket
+ {
+ public:
+ BattlemasterJoinArena(WorldPacket&& packet) : ClientPacket(CMSG_BATTLEMASTER_JOIN_ARENA, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid BattlemasterGuid;
+ uint8 TeamSizeIndex = 0;
+ bool JoinAsGroup = false;
+ bool IsRated = false;
+ };
+
+ class BattlefieldLeave final : public ClientPacket
+ {
+ public:
+ BattlefieldLeave(WorldPacket&& packet) : ClientPacket(CMSG_LEAVE_BATTLEFIELD, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 QueueID = 0;
+ };
+
+ class BattlefieldPort final : public ClientPacket
+ {
+ public:
+ BattlefieldPort(WorldPacket&& packet) : ClientPacket(CMSG_BATTLEFIELD_PORT, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 QueueID = 0;
+ bool AcceptedInvite = false;
+ };
+
+ class BattlefieldListRequest final : public ClientPacket
+ {
+ public:
+ BattlefieldListRequest(WorldPacket&& packet) : ClientPacket(CMSG_BATTLEFIELD_LIST, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 ListID = 0;
+ bool PvpAnywhere = false;
+ bool NoXpGain = false;
+ };
+
+ class BattlefieldList final : public ServerPacket
+ {
+ public:
+ BattlefieldList() : ServerPacket(SMSG_BATTLEFIELD_LIST, 8 + 1 + 4 + 1 + 1 + 1 + 4 + 4 + 4 + 1 + 1 + 4 + 4 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid BattlemasterGuid;
+ int32 BattlemasterListID = 0;
+ uint8 MinLevel = 0;
+ uint8 MaxLevel = 0;
+ std::set<uint32> const* Battlefields = nullptr;
+ bool PvpAnywhere = false;
+ bool HasHolidayWinToday = false;
+ uint32 HolidayWinHonorCurrencyBonus = 0;
+ uint32 HolidayFirstWinArenaCurrencyBonus = 0;
+ uint32 HolidayLossHonorCurrencyBonus = 0;
+ bool HasRandomWinToday = false;
+ uint32 RandomWinHonorCurrencyBonus = 0;
+ uint32 RandomFirstWinArenaCurrencyBonus = 0;
+ uint32 RandomLossHonorCurrencyBonus = 0;
+ };
+
+ class RequestBattlefieldStatus final : public ClientPacket
+ {
+ public:
+ RequestBattlefieldStatus(WorldPacket&& packet) : ClientPacket(CMSG_BATTLEFIELD_STATUS, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class ReportPvPPlayerAFK final : public ClientPacket
+ {
+ public:
+ ReportPvPPlayerAFK(WorldPacket&& packet) : ClientPacket(CMSG_REPORT_PVP_AFK, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Offender;
+ };
+
+ class ReportPvPPlayerAFKResult final : public ServerPacket
+ {
+ public:
+ ReportPvPPlayerAFKResult() : ServerPacket(SMSG_REPORT_PVP_AFK_RESULT, 8 + 1 + 1 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ enum ResultCode : uint8
+ {
+ PVP_REPORT_AFK_SUCCESS = 0,
+ PVP_REPORT_AFK_GENERIC_FAILURE = 1, // there are more error codes but they are impossible to receive without modifying the client
+ PVP_REPORT_AFK_SYSTEM_ENABLED = 5,
+ PVP_REPORT_AFK_SYSTEM_DISABLED = 6
+ };
+
+ ObjectGuid Offender;
+ uint8 NumPlayersIHaveReported = 0;
+ uint8 NumBlackMarksOnOffender = 0;
+ uint8 Result = PVP_REPORT_AFK_GENERIC_FAILURE;
+ };
+
+ class BattlegroundPlayerPositionsRequest final : public ClientPacket
+ {
+ public:
+ BattlegroundPlayerPositionsRequest(WorldPacket&& packet) : ClientPacket(MSG_BATTLEGROUND_PLAYER_POSITIONS, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ struct BattlegroundPlayerPosition
+ {
+ ObjectGuid Guid;
+ TaggedPosition<Position::XY> Pos;
+ };
+
+ class BattlegroundPlayerPositions final : public ServerPacket
+ {
+ public:
+ BattlegroundPlayerPositions() : ServerPacket(MSG_BATTLEGROUND_PLAYER_POSITIONS, 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<BattlegroundPlayerPosition> Players;
+ std::vector<BattlegroundPlayerPosition> FlagCarriers;
+ };
+
+ class BattlegroundPlayerJoined final : public ServerPacket
+ {
+ public:
+ BattlegroundPlayerJoined() : ServerPacket(SMSG_BATTLEGROUND_PLAYER_JOINED, 8) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Guid;
+ };
+
+ class BattlegroundPlayerLeft final : public ServerPacket
+ {
+ public:
+ BattlegroundPlayerLeft() : ServerPacket(SMSG_BATTLEGROUND_PLAYER_LEFT, 8) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Guid;
+ };
+
+ class DestroyArenaUnit final : public ServerPacket
+ {
+ public:
+ DestroyArenaUnit() : ServerPacket(SMSG_ARENA_UNIT_DESTROYED, 8) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Guid;
+ };
+ }
+}
+
+#endif // BattlegroundPackets_h__
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 34710741eca..4b10b53f56f 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -851,7 +851,7 @@ void OpcodeTable::Initialize()
/*0x2D0*/ DEFINE_HANDLER(CMSG_MOVE_WATER_WALK_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveWaterWalkAck );
/*0x2D1*/ DEFINE_HANDLER(CMSG_MOVE_NOT_ACTIVE_MOVER, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveNotActiveMover );
/*0x2D2*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SOUND, STATUS_NEVER);
- /*0x2D3*/ DEFINE_HANDLER(CMSG_BATTLEFIELD_STATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldStatusOpcode );
+ /*0x2D3*/ DEFINE_HANDLER(CMSG_BATTLEFIELD_STATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestBattlefieldStatusOpcode);
/*0x2D4*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS, STATUS_NEVER);
/*0x2D5*/ DEFINE_HANDLER(CMSG_BATTLEFIELD_PORT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattleFieldPortOpcode );
/*0x2D6*/ DEFINE_HANDLER(MSG_INSPECT_HONOR_STATS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleInspectHonorStatsOpcode );
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 8b34a4ee0bf..a8c5a892f87 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -88,6 +88,22 @@ namespace WorldPackets
class BuyBankSlot;
}
+ namespace Battleground
+ {
+ class AreaSpiritHealerQuery;
+ class AreaSpiritHealerQueue;
+ class HearthAndResurrect;
+ class PVPLogDataRequest;
+ class BattlemasterJoin;
+ class BattlemasterJoinArena;
+ class BattlefieldLeave;
+ class BattlefieldPort;
+ class BattlefieldListRequest;
+ class RequestBattlefieldStatus;
+ class ReportPvPPlayerAFK;
+ class BattlegroundPlayerPositionsRequest;
+ }
+
namespace Calendar
{
class CalendarAddEvent;
@@ -541,8 +557,6 @@ class TC_GAME_API WorldSession
void SendAttackStop(Unit const* enemy);
- void SendBattleGroundList(ObjectGuid guid, BattlegroundTypeId bgTypeId = BATTLEGROUND_RB);
-
void SendTradeStatus(TradeStatusInfo const& status);
void SendUpdateTrade(bool trader_data = true);
void SendCancelTrade(TradeStatus status);
@@ -789,8 +803,6 @@ class TC_GAME_API WorldSession
void HandleRequestRaidInfoOpcode(WorldPacket& recvData);
- void HandleBattlefieldStatusOpcode(WorldPacket& recvData);
-
void HandleGroupInviteOpcode(WorldPackets::Party::PartyInviteClient& packet);
void HandleGroupAcceptOpcode(WorldPacket& recvPacket);
void HandleGroupDeclineOpcode(WorldPacket& recvPacket);
@@ -1023,15 +1035,19 @@ class TC_GAME_API WorldSession
void HandleDismissCritter(WorldPackets::Pet::DismissCritter& dismissCritter);
//Battleground
- void HandleBattlemasterHelloOpcode(WorldPacket& recvData);
- void HandleBattlemasterJoinOpcode(WorldPacket& recvData);
- void HandleBattlegroundPlayerPositionsOpcode(WorldPacket& recvData);
- void HandlePVPLogDataOpcode(WorldPacket& recvData);
- void HandleBattleFieldPortOpcode(WorldPacket& recvData);
- void HandleBattlefieldListOpcode(WorldPacket& recvData);
- void HandleBattlefieldLeaveOpcode(WorldPacket& recvData);
- void HandleBattlemasterJoinArena(WorldPacket& recvData);
- void HandleReportPvPAFK(WorldPacket& recvData);
+ void HandleBattlemasterHelloOpcode(WorldPackets::NPC::Hello& hello);
+ void HandleBattlemasterJoinOpcode(WorldPackets::Battleground::BattlemasterJoin& battlemasterJoin);
+ void HandleBattlegroundPlayerPositionsOpcode(WorldPackets::Battleground::BattlegroundPlayerPositionsRequest& battlegroundPlayerPositionsRequest);
+ void HandlePVPLogDataOpcode(WorldPackets::Battleground::PVPLogDataRequest& pvpLogDataRequest);
+ void HandleBattleFieldPortOpcode(WorldPackets::Battleground::BattlefieldPort& battlefieldPort);
+ void HandleBattlefieldListOpcode(WorldPackets::Battleground::BattlefieldListRequest& battlefieldList);
+ void HandleBattlefieldLeaveOpcode(WorldPackets::Battleground::BattlefieldLeave& battlefieldLeave);
+ void HandleBattlemasterJoinArena(WorldPackets::Battleground::BattlemasterJoinArena& packet);
+ void HandleReportPvPAFK(WorldPackets::Battleground::ReportPvPPlayerAFK& reportPvPPlayerAFK);
+ void HandleAreaSpiritHealerQueryOpcode(WorldPackets::Battleground::AreaSpiritHealerQuery& areaSpiritHealerQuery);
+ void HandleAreaSpiritHealerQueueOpcode(WorldPackets::Battleground::AreaSpiritHealerQueue& areaSpiritHealerQueue);
+ void HandleHearthAndResurrect(WorldPackets::Battleground::HearthAndResurrect& hearthAndResurrect);
+ void HandleRequestBattlefieldStatusOpcode(WorldPackets::Battleground::RequestBattlefieldStatus& requestBattlefieldStatus);
// Battlefield
void SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint32 time);
@@ -1055,7 +1071,6 @@ class TC_GAME_API WorldSession
void HandleTimeSyncResponse(WorldPacket& recvData);
void HandleWhoIsOpcode(WorldPacket& recvData);
void HandleResetInstancesOpcode(WorldPacket& recvData);
- void HandleHearthAndResurrect(WorldPacket& recvData);
void HandleInstanceLockResponse(WorldPacket& recvPacket);
// Looking for Dungeon/Raid
@@ -1098,8 +1113,6 @@ class TC_GAME_API WorldSession
void HandleArenaTeamDisbandOpcode(WorldPacket& recvData);
void HandleArenaTeamLeaderOpcode(WorldPacket& recvData);
- void HandleAreaSpiritHealerQueryOpcode(WorldPacket& recvData);
- void HandleAreaSpiritHealerQueueOpcode(WorldPacket& recvData);
void HandleSelfResOpcode(WorldPacket& recvData);
void HandleComplainOpcode(WorldPacket& recvData);
void HandleRequestPetInfo(WorldPackets::Pet::RequestPetInfo& packet);