diff options
Diffstat (limited to 'src/server/game/Handlers/BattleGroundHandler.cpp')
-rw-r--r-- | src/server/game/Handlers/BattleGroundHandler.cpp | 546 |
1 files changed, 320 insertions, 226 deletions
diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index 0213df31630..9955879d37a 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -66,23 +66,41 @@ void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData) void WorldSession::SendBattleGroundList(uint64 guid, BattlegroundTypeId bgTypeId) { WorldPacket data; - sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId, 0); + sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId); SendPacket(&data); } void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) { - uint64 guid; uint32 bgTypeId_; uint32 instanceId; - uint8 joinAsGroup; + uint8 asGroup; bool isPremade = false; Group* grp = NULL; - - 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 + ObjectGuid guid; + + recvData >> instanceId; // Instance Id + guid[2] = recvData.ReadBit(); + guid[0] = recvData.ReadBit(); + guid[3] = recvData.ReadBit(); + guid[1] = recvData.ReadBit(); + guid[5] = recvData.ReadBit(); + asGroup = recvData.ReadBit(); // As Group + guid[4] = recvData.ReadBit(); + guid[6] = recvData.ReadBit(); + guid[7] = recvData.ReadBit(); + + recvData.ReadByteSeq(guid[2]); + recvData.ReadByteSeq(guid[6]); + recvData.ReadByteSeq(guid[4]); + recvData.ReadByteSeq(guid[3]); + recvData.ReadByteSeq(guid[7]); + recvData.ReadByteSeq(guid[0]); + recvData.ReadByteSeq(guid[5]); + recvData.ReadByteSeq(guid[1]); + + //extract from guid + bgTypeId_ = GUID_LOPART(guid); if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { @@ -95,10 +113,9 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED); return; } - BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_); - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid))); + //sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID:"UI64FMTD" TypeId:%u)", guid, bgTypeId_); // can do this, since it's battleground, not arena BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0); @@ -123,16 +140,15 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) if (!bracketEntry) return; - GroupJoinBattlegroundResult err; + GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE; // check queue conditions - if (!joinAsGroup) + if (!asGroup) { if (GetPlayer()->isUsingLfg()) { - // player is using dungeon finder or raid finder WorldPacket data; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_LFG_CANT_USE_BATTLEGROUND); + sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_LFG_CANT_USE_BATTLEGROUND); GetPlayer()->GetSession()->SendPacket(&data); return; } @@ -141,7 +157,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) if (!_player->CanJoinToBattleground(bg)) { WorldPacket data; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); + sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); _player->GetSession()->SendPacket(&data); return; } @@ -150,7 +166,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) { // player is already in random queue WorldPacket data; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_RANDOM_BG); + sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_IN_RANDOM_BG); _player->GetSession()->SendPacket(&data); return; } @@ -159,7 +175,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) { // player is already in queue, can't start random queue WorldPacket data; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_NON_RANDOM_BG); + sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_IN_NON_RANDOM_BG); _player->GetSession()->SendPacket(&data); return; } @@ -173,33 +189,37 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) if (!_player->HasFreeBattlegroundQueueId()) { WorldPacket data; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES); + sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_BATTLEGROUND_TOO_MANY_QUEUES); _player->GetSession()->SendPacket(&data); return; } BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); - GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); - // already checked if queueSlot is valid, now just get it uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); - WorldPacket data; - // send status packet (in queue) - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType, 0); + // add joined time data + _player->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime); + + WorldPacket data; // send status packet (in queue) + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, ginfo->ArenaType); SendPacket(&data); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName().c_str()); } 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); isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam()); @@ -207,7 +227,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) GroupQueueInfo* ginfo = NULL; uint32 avgTime = 0; - if (err > 0) + if (!err) { sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: the following players are joining as group:"); ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); @@ -220,11 +240,10 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) if (!member) continue; // this should never happen - WorldPacket data; - - if (err <= 0) + if (err) { - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); + WorldPacket data; + sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, err); member->GetSession()->SendPacket(&data); continue; } @@ -232,65 +251,107 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) // add to queue uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); - // send status packet (in queue) - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType, 0); - member->GetSession()->SendPacket(&data); - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); + // add joined time data + member->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime); + + WorldPacket data; // send status packet (in queue) + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, ginfo->ArenaType); member->GetSession()->SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str()); } sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: group end"); } + sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); } void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvData*/) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_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 = NULL; - Player* hordeFlagCarrier = NULL; + uint32 acount = 0; + uint32 hcount = 0; + Player* aplr = NULL; + Player* hplr = NULL; if (uint64 guid = bg->GetFlagPickerGUID(TEAM_ALLIANCE)) { - allianceFlagCarrier = ObjectAccessor::FindPlayer(guid); - if (allianceFlagCarrier) - ++flagCarrierCount; + aplr = ObjectAccessor::FindPlayer(guid); + if (aplr) + ++acount; } if (uint64 guid = bg->GetFlagPickerGUID(TEAM_HORDE)) { - hordeFlagCarrier = ObjectAccessor::FindPlayer(guid); - if (hordeFlagCarrier) - ++flagCarrierCount; + hplr = ObjectAccessor::FindPlayer(guid); + if (hplr) + ++hcount; } - 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) + ObjectGuid aguid = aplr ? aplr->GetGUID() : 0; + ObjectGuid hguid = hplr ? hplr->GetGUID() : 0; + + WorldPacket data(SMSG_BATTLEFIELD_PLAYER_POSITIONS); + + data.WriteBits(acount, 22); + for (uint8 i = 0; i < acount; i++) + { + data.WriteBit(aguid[3]); + data.WriteBit(aguid[5]); + data.WriteBit(aguid[1]); + data.WriteBit(aguid[6]); + data.WriteBit(aguid[7]); + data.WriteBit(aguid[0]); + data.WriteBit(aguid[2]); + data.WriteBit(aguid[4]); + } + + data.WriteBits(hcount, 22); + for (uint8 i = 0; i < hcount; i++) + { + data.WriteBit(hguid[6]); + data.WriteBit(hguid[5]); + data.WriteBit(hguid[4]); + data.WriteBit(hguid[7]); + data.WriteBit(hguid[2]); + data.WriteBit(hguid[1]); + data.WriteBit(hguid[0]); + data.WriteBit(hguid[3]); + } + + data.FlushBits(); + + for (uint8 i = 0; i < hcount; i++) { - data << uint64(allianceFlagCarrier->GetGUID()); - data << float(allianceFlagCarrier->GetPositionX()); - data << float(allianceFlagCarrier->GetPositionY()); + data.WriteByteSeq(hguid[2]); + data.WriteByteSeq(hguid[1]); + data << float(hplr->GetPositionY()); + data.WriteByteSeq(hguid[5]); + data.WriteByteSeq(hguid[4]); + data.WriteByteSeq(hguid[7]); + data.WriteByteSeq(hguid[0]); + data.WriteByteSeq(hguid[6]); + data.WriteByteSeq(hguid[3]); + data << float(hplr->GetPositionX()); } - if (hordeFlagCarrier) + for (uint8 i = 0; i < acount; i++) { - data << uint64(hordeFlagCarrier->GetGUID()); - data << float(hordeFlagCarrier->GetPositionX()); - data << float(hordeFlagCarrier->GetPositionY()); + data.WriteByteSeq(aguid[6]); + data << float(aplr->GetPositionX()); + data.WriteByteSeq(aguid[5]); + data.WriteByteSeq(aguid[3]); + data << float(aplr->GetPositionY()); + data.WriteByteSeq(aguid[1]); + data.WriteByteSeq(aguid[7]); + data.WriteByteSeq(aguid[0]); + data.WriteByteSeq(aguid[2]); + data.WriteByteSeq(aguid[4]); } SendPacket(&data); @@ -298,7 +359,7 @@ void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvDa void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recvData*/) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd MSG_PVP_LOG_DATA Message"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_PVP_LOG_DATA Message"); Battleground* bg = _player->GetBattleground(); if (!bg) @@ -312,22 +373,16 @@ void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recvData*/) sBattlegroundMgr->BuildPvpLogDataPacket(&data, bg); SendPacket(&data); - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent MSG_PVP_LOG_DATA Message"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_PVP_LOG_DATA Message"); } -void WorldSession::HandleBattlefieldListOpcode(WorldPacket &recvData) +void WorldSession::HandleBattlefieldListOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "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) { @@ -336,60 +391,87 @@ void WorldSession::HandleBattlefieldListOpcode(WorldPacket &recvData) } WorldPacket data; - sBattlegroundMgr->BuildBattlegroundListPacket(&data, 0, _player, BattlegroundTypeId(bgTypeId), fromWhere); + sBattlegroundMgr->BuildBattlegroundListPacket(&data, 0, _player, BattlegroundTypeId(bgTypeId)); SendPacket(&data); } void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) { - uint8 type; // arenatype if arena - uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1 - uint32 bgTypeId_; // type id from dbc - uint16 unk; // 0x1F90 constant? - uint8 action; // enter battle 0x1, leave queue 0x0 + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEFIELD_PORT Message"); + + uint32 time; + uint32 queueSlot; + uint32 unk; + uint8 action; // enter battle 0x1, leave queue 0x0 + ObjectGuid guid; + + recvData >> time; + recvData >> queueSlot; + recvData >> unk; + + guid[0] = recvData.ReadBit(); + guid[1] = recvData.ReadBit(); + guid[5] = recvData.ReadBit(); + guid[6] = recvData.ReadBit(); + guid[7] = recvData.ReadBit(); + guid[4] = recvData.ReadBit(); + guid[3] = recvData.ReadBit(); + guid[2] = recvData.ReadBit(); + + action = recvData.ReadBit(); + + recvData.ReadByteSeq(guid[1]); + recvData.ReadByteSeq(guid[3]); + recvData.ReadByteSeq(guid[5]); + recvData.ReadByteSeq(guid[7]); + recvData.ReadByteSeq(guid[0]); + recvData.ReadByteSeq(guid[2]); + recvData.ReadByteSeq(guid[6]); + recvData.ReadByteSeq(guid[4]); - recvData >> type >> unk2 >> bgTypeId_ >> unk >> action; - if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) + if (!_player->InBattlegroundQueue()) { - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u. Invalid BgType!", - GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player not in queue!", + GetPlayerInfo().c_str(), queueSlot, unk, time, action); return; } - if (!_player->InBattlegroundQueue()) + BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(queueSlot); + if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE) { - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u. Player not in queue!", - GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Invalid queueSlot!", + GetPlayerInfo().c_str(), queueSlot, unk, time, action); return; } - //get GroupQueueInfo from BattlegroundQueue - BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_); - BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, type); BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); + //we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattlegroundQueue::RemovePlayer() function GroupQueueInfo ginfo; if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo)) { - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u. Player not in queue (No player Group Info)!", - GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player not in queue (No player Group Info)!", + GetPlayerInfo().c_str(), queueSlot, unk, time, action); return; } // if action == 1, then instanceId is required if (!ginfo.IsInvitedToBGInstanceGUID && action == 1) { - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u. Player is not invited to any bg!", - GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player is not invited to any bg!", + GetPlayerInfo().c_str(), queueSlot, unk, time, action); return; } - Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId); + BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId); + // BGTemplateId returns BATTLEGROUND_AA when it is arena queue. + // Do instance id search as there is no AA bg instances. + Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId == BATTLEGROUND_AA ? BATTLEGROUND_TYPE_NONE : bgTypeId); if (!bg) { if (action) { - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u. Cant find BG with id %u!", - GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action, ginfo.IsInvitedToBGInstanceGUID); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Cant find BG with id %u!", + GetPlayerInfo().c_str(), queueSlot, unk, time, action, ginfo.IsInvitedToBGInstanceGUID); return; } @@ -401,8 +483,11 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) } } - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u.", - GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u.", + GetPlayerInfo().c_str(), queueSlot, unk, time, action); + + // get real bg type + bgTypeId = bg->GetTypeID(); // expected bracket entry PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel()); @@ -417,7 +502,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) { //send bg command result to show nice message WorldPacket data2; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data2, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); + sBattlegroundMgr->BuildStatusFailedPacket(&data2, bg, _player, 0, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); _player->GetSession()->SendPacket(&data2); action = 0; sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName().c_str(), _player->GetGUIDLow()); @@ -425,12 +510,12 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) //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 if (_player->getLevel() > bg->GetMaxLevel()) { - sLog->outError(LOG_FILTER_NETWORKIO, "Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!", + sLog->outDebug(LOG_FILTER_NETWORKIO, "Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!", _player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel(), bg->GetMaxLevel(), bg->GetTypeID()); action = 0; } } - uint32 queueSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId); + WorldPacket data; if (action) { @@ -453,7 +538,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) _player->CleanupAfterTaxiFlight(); } - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), ginfo.Team); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_IN_PROGRESS, _player->GetBattlegroundQueueJoinTime(bgTypeId), bg->GetElapsedTime(), bg->GetArenaType()); _player->GetSession()->SendPacket(&data); // remove battleground queue status from BGmgr @@ -476,9 +561,6 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) } else // leave queue { - if (bg->isArena() && bg->GetStatus() > STATUS_WAIT_QUEUE) - return; - // if player leaves rated arena match before match start, it is counted as he played but he lost if (ginfo.IsRated && ginfo.IsInvitedToBGInstanceGUID) { @@ -490,25 +572,22 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) at->SaveToDB(); } } + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_NONE, _player->GetBattlegroundQueueJoinTime(bgTypeId), 0, 0); + SendPacket(&data); + _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 (!ginfo.ArenaType) sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); - SendPacket(&data); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId); } } -void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& recvData) +void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& /*recvData*/) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "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 + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEFIELD_LEAVE Message"); // not allow leave battleground in combat if (_player->isInCombat()) @@ -522,7 +601,7 @@ void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& recvData) void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) { // empty opcode - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Battleground status"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEFIELD_STATUS Message"); WorldPacket data; // we must update all queues here @@ -541,13 +620,14 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) //so i must use bg pointer to get that information if (bg && bg->GetArenaType() == arenaType) { - // this line is checked, i only don't know if GetStartTime is changing itself after bg end! + // this line is checked, i only don't know if GetElapsedTime() is changing itself after bg end! // send status in Battleground - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam()); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_IN_PROGRESS, _player->GetBattlegroundQueueJoinTime(bgTypeId), bg->GetElapsedTime(), arenaType); SendPacket(&data); continue; } } + //we are sending update to player about queue - he can be invited there! //get GroupQueueInfo for queue status BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); @@ -559,9 +639,9 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId); if (!bg) continue; - uint32 remainingTime = getMSTimeDiff(getMSTime(), ginfo.RemoveInviteTime); + // send status invited to Battleground - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_WAIT_JOIN, getMSTimeDiff(getMSTime(), ginfo.RemoveInviteTime), _player->GetBattlegroundQueueJoinTime(bgTypeId), arenaType); SendPacket(&data); } else @@ -577,7 +657,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, bracketEntry->GetBracketId()); // send status in Battleground Queue - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, getMSTime()), arenaType, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_WAIT_QUEUE, avgTime, _player->GetBattlegroundQueueJoinTime(bgTypeId), arenaType); SendPacket(&data); } } @@ -587,44 +667,18 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA"); - uint64 guid; // arena Battlemaster guid uint8 arenaslot; // 2v2, 3v3 or 5v5 - uint8 asGroup; // asGroup - uint8 isRated; // isRated - Group* grp = NULL; - recvData >> guid >> arenaslot >> asGroup >> isRated; + recvData >> arenaslot; // ignore if we already in BG or BG queue if (_player->InBattleground()) return; - Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); - if (!unit) - return; - - if (!unit->isBattleMaster()) // it's not battle master - return; - - uint8 arenatype = 0; uint32 arenaRating = 0; uint32 matchmakerRating = 0; - switch (arenaslot) - { - case 0: - arenatype = ARENA_TYPE_2v2; - break; - case 1: - arenatype = ARENA_TYPE_3v3; - break; - case 2: - arenatype = ARENA_TYPE_5v5; - break; - default: - sLog->outError(LOG_FILTER_NETWORKIO, "Unknown arena slot %u at HandleBattlemasterJoinArena()", arenaslot); - return; - } + uint8 arenatype = ArenaTeam::GetTypeBySlot(arenaslot); //check existance Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA); @@ -646,108 +700,73 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) if (!bracketEntry) return; - GroupJoinBattlegroundResult err = ERR_GROUP_JOIN_BATTLEGROUND_FAIL; + GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE; - if (!asGroup) - { - // check if already in queue - if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) - //player is already in this queue - return; - // check if has free queue slots - if (!_player->HasFreeBattlegroundQueueId()) - return; - } - else + Group* grp = _player->GetGroup(); + // no group found, error + if (!grp) + return; + if (grp->GetLeaderGUID() != _player->GetGUID()) + return; + + uint32 ateamId = _player->GetArenaTeamId(arenaslot); + // 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) { - grp = _player->GetGroup(); - // no group found, error - if (!grp) - return; - if (grp->GetLeaderGUID() != _player->GetGUID()) - return; - err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot); + _player->GetSession()->SendNotInArenaTeamPacket(arenatype); + return; } - uint32 ateamId = 0; + // get the team rating for queueing + arenaRating = at->GetRating(); + matchmakerRating = at->GetAverageMMR(grp); + // the arenateam id must match for everyone in the group + + if (arenaRating <= 0) + arenaRating = 1; + + BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); - if (isRated) + uint32 avgTime = 0; + GroupQueueInfo* ginfo = NULL; + + err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, arenatype, arenatype, true, arenaslot); + if (!err) { - ateamId = _player->GetArenaTeamId(arenaslot); - // 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); - return; - } - // get the team rating for queueing - arenaRating = at->GetRating(); - matchmakerRating = at->GetAverageMMR(grp); - // the arenateam id must match for everyone in the group + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: arena team id %u, leader %s queued with matchmaker rating %u for type %u", _player->GetArenaTeamId(arenaslot), _player->GetName().c_str(), matchmakerRating, arenatype); - if (arenaRating <= 0) - arenaRating = 1; + ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, true, false, arenaRating, matchmakerRating, ateamId); + avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); } - BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); - if (asGroup) + for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { - uint32 avgTime = 0; + Player* member = itr->getSource(); + if (!member) + continue; - if (err > 0) + if (err) { - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: arena join as group start"); - if (isRated) - { - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: arena team id %u, leader %s queued with matchmaker rating %u for type %u", _player->GetArenaTeamId(arenaslot), _player->GetName().c_str(), matchmakerRating, arenatype); - bg->SetRated(true); - } - else - bg->SetRated(false); - - GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, matchmakerRating, ateamId); - avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); + WorldPacket data; + sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, err); + member->GetSession()->SendPacket(&data); + continue; } - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) - { - Player* member = itr->getSource(); - if (!member) - continue; - - WorldPacket data; + // add to queue + uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); - if (err <= 0) - { - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); - member->GetSession()->SendPacket(&data); - continue; - } + // add joined time data + member->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime); - // add to queue - uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); + WorldPacket data; // send status packet (in queue) + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, arenatype); + member->GetSession()->SendPacket(&data); - // send status packet (in queue) - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, 0); - member->GetSession()->SendPacket(&data); - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); - member->GetSession()->SendPacket(&data); - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str()); - } + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str()); } - else - { - GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, matchmakerRating, ateamId); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); - 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); - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName().c_str()); - } sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); } @@ -767,3 +786,78 @@ void WorldSession::HandleReportPvPAFK(WorldPacket& recvData) reportedPlayer->ReportedAfkBy(_player); } + +void WorldSession::HandleRequestRatedBgInfo(WorldPacket & recvData) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_REQUEST_RATED_BG_INFO"); + + uint8 unk; + recvData >> unk; + + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "WorldSession::HandleRequestRatedBgInfo: unk = %u", unk); + + /// @Todo: perfome research in this case + /// The unk fields are related to arenas + WorldPacket data(SMSG_RATED_BG_STATS, 72); + data << uint32(0); // BgWeeklyWins20vs20 + data << uint32(0); // BgWeeklyPlayed20vs20 + data << uint32(0); // BgWeeklyPlayed15vs15 + data << uint32(0); + data << uint32(0); // BgWeeklyWins10vs10 + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); // BgWeeklyWins15vs15 + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); // BgWeeklyPlayed10vs10 + data << uint32(0); + data << uint32(0); + + SendPacket(&data); +} + +void WorldSession::HandleRequestPvpOptions(WorldPacket& /*recvData*/) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_REQUEST_PVP_OPTIONS_ENABLED"); + + /// @Todo: perfome research in this case + WorldPacket data(SMSG_PVP_OPTIONS_ENABLED, 1); + data.WriteBit(1); + data.WriteBit(1); // WargamesEnabled + data.WriteBit(1); + data.WriteBit(1); // RatedBGsEnabled + data.WriteBit(1); // RatedArenasEnabled + + data.FlushBits(); + + SendPacket(&data); +} + +void WorldSession::HandleRequestPvpReward(WorldPacket& /*recvData*/) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_REQUEST_PVP_REWARDS"); + + _player->SendPvpRewards(); +} + +void WorldSession::HandleRequestRatedBgStats(WorldPacket& /*recvData*/) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_REQUEST_RATED_BG_STATS"); + + WorldPacket data(SMSG_BATTLEFIELD_RATED_INFO, 29); + data << uint32(0); // Reward + data << uint8(3); // unk + data << uint32(0); // unk + data << uint32(0); // unk + data << _player->GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_RBG, true); + data << uint32(0); // unk + data << uint32(0); // unk + data << _player->GetCurrency(CURRENCY_TYPE_CONQUEST_POINTS, true); + + SendPacket(&data); +} |