diff --git a/src/game/BattleGround/BattleGround.cpp b/src/game/BattleGround/BattleGround.cpp index 639fd6b1e9..e6e9b9d9e4 100644 --- a/src/game/BattleGround/BattleGround.cpp +++ b/src/game/BattleGround/BattleGround.cpp @@ -1529,9 +1529,9 @@ void BattleGround::RemovedFromBgFreeSlotQueue(bool removeFromQueue) // set to be able to re-add if needed if (m_hasBgFreeSlotQueue && removeFromQueue) { - sWorld.GetBGQueue().GetMessager().AddMessage([instanceId = GetInstanceId()](BattleGroundQueue* queue) + sWorld.GetBGQueue().GetMessager().AddMessage([bgTypeId = GetTypeId(), instanceId = GetInstanceId()](BattleGroundQueue* queue) { - queue->RemoveBgFromFreeSlots(instanceId); + queue->RemoveBgFromFreeSlots(bgTypeId, instanceId); }); } m_hasBgFreeSlotQueue = false; diff --git a/src/game/BattleGround/BattleGroundHandler.cpp b/src/game/BattleGround/BattleGroundHandler.cpp index 3df8066248..7d43462a28 100644 --- a/src/game/BattleGround/BattleGroundHandler.cpp +++ b/src/game/BattleGround/BattleGroundHandler.cpp @@ -90,7 +90,8 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recv_data) uint32 instanceId; uint8 joinAsGroup; bool isPremade = false; - Group* grp = nullptr; + Group* group = nullptr; + uint32 mapId = 0; recv_data >> guid; // battlemaster guid recv_data >> receivedBgTypeId; // battleground type id (DBC id) @@ -135,7 +136,9 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recv_data) return; } - BattleGroundBracketId bgBracketId = _player->GetBattleGroundBracketIdFromLevel(bgTypeId); + mapId = bg->GetMapId(); + + BattleGroundBracketId bgBracketId = sBattleGroundMgr.GetBattleGroundBracketIdFromLevel(bgTypeId, _player->GetLevel()); // check queue conditions if (!joinAsGroup) @@ -163,13 +166,13 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recv_data) } else { - grp = _player->GetGroup(); + group = _player->GetGroup(); // no group found, error - if (!grp) + if (!group) return; - uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0); + uint32 err = group->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0); isPremade = sWorld.getConfig(CONFIG_UINT32_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH) && - (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam()); + (group->GetMembersCount() >= bg->GetMinPlayersPerTeam()); if (err != BG_JOIN_ERR_OK) { SendBattleGroundOrArenaJoinError(err); @@ -178,51 +181,77 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recv_data) } // if we're here, then the conditions to join a bg are met. We can proceed in joining. - // _player->GetGroup() was already checked, grp is already initialized - BattleGroundQueue& bgQueue = sBattleGroundMgr.m_battleGroundQueues[bgQueueTypeId]; + // _player->GetGroup() was already checked, group is already initialized + AddGroupToQueueInfo info; + info.team = _player->GetTeam(); + info.clientInstanceId = instanceId; + info.mapId = mapId; if (joinAsGroup) { + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) + if (Player* member = itr->getSource()) + info.members.push_back(member->GetObjectGuid()); DEBUG_LOG("Battleground: the following players are joining as group:"); - GroupQueueInfo* queueInfo = bgQueue.AddGroup(_player, grp, bgTypeId, bgBracketId, ARENA_TYPE_NONE, false, isPremade, instanceId, 0); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(queueInfo, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); - for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next()) + sWorld.GetBGQueue().GetMessager().AddMessage([bgQueueTypeId, leaderGuid = group->GetLeaderGuid(), info, bgTypeId, bgBracketId, isPremade, instanceId, mapId](BattleGroundQueue* queue) { - Player* member = itr->getSource(); - if (!member) - continue; // this should never happen - - uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId); // add to queue + BattleGroundQueueItem& queueItem = queue->GetBattleGroundQueue(bgQueueTypeId); + GroupQueueInfo* groupInfo = queueItem.AddGroup(leaderGuid, info, bgTypeId, bgBracketId, ARENA_TYPE_NONE, false, isPremade, instanceId, 0); + uint32 avgTime = queueItem.GetAverageQueueWaitTime(groupInfo, bgBracketId); - // store entry point coords (same as leader entry point) - member->SetBattleGroundEntryPoint(_player); + sWorld.GetMessager().AddMessage([leaderGuid, members = info.members, bgQueueTypeId, bgTypeId, bgClientInstanceId = instanceId, avgTime, arenaType = groupInfo->arenaType, isRated = groupInfo->isRated, mapId](World* world) + { + Player* leader = sObjectMgr.GetPlayer(leaderGuid); + for (ObjectGuid guid : members) + { + Player* member = sObjectMgr.GetPlayer(guid); + if (!member) + continue; + + uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId); // add to queue + + // store entry point coords (same as leader entry point) + member->SetBattleGroundEntryPoint(leader); + + // send status packet (in queue) + WorldPacket data; + sBattleGroundMgr.BuildBattleGroundStatusPacket(data, true, bgTypeId, bgClientInstanceId, isRated, mapId, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenaType, TEAM_NONE); + member->GetSession()->SendPacket(data); + sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(data, bgTypeId, BG_GROUP_JOIN_STATUS_SUCCESS); + member->GetSession()->SendPacket(data); + DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName()); + } - // send status packet (in queue) - WorldPacket data; - sBattleGroundMgr.BuildBattleGroundStatusPacket(data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, queueInfo->arenaType, TEAM_NONE); - member->GetSession()->SendPacket(data); - sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(data, bgTypeId, BG_GROUP_JOIN_STATUS_SUCCESS); - member->GetSession()->SendPacket(data); - DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName()); - } - DEBUG_LOG("Battleground: group end"); + DEBUG_LOG("Battleground: group end"); + }); + queue->ScheduleQueueUpdate(0, ARENA_TYPE_NONE, bgQueueTypeId, bgTypeId, bgBracketId); + }); } else { - GroupQueueInfo* queueInfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bgBracketId, ARENA_TYPE_NONE, false, isPremade, instanceId, 0); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(queueInfo, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); - // already checked if queueSlot is valid, now just get it - uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); - // store entry point coords - _player->SetBattleGroundEntryPoint(); - - WorldPacket data; - // send status packet (in queue) - sBattleGroundMgr.BuildBattleGroundStatusPacket(data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, queueInfo->arenaType, TEAM_NONE); - SendPacket(data); - DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName()); + sWorld.GetBGQueue().GetMessager().AddMessage([bgQueueTypeId, playerGuid = _player->GetObjectGuid(), info, bgTypeId, bgBracketId, isPremade, instanceId, mapId](BattleGroundQueue* queue) + { + BattleGroundQueueItem& queueItem = queue->GetBattleGroundQueue(bgQueueTypeId); + GroupQueueInfo* groupInfo = queueItem.AddGroup(playerGuid, info, bgTypeId, bgBracketId, ARENA_TYPE_NONE, false, isPremade, instanceId, 0); + uint32 avgTime = queueItem.GetAverageQueueWaitTime(groupInfo, bgBracketId); + sWorld.GetMessager().AddMessage([playerGuid, bgQueueTypeId, bgTypeId, bgClientInstanceId = instanceId, avgTime, arenaType = groupInfo->arenaType, isRated = groupInfo->isRated, mapId](World* world) + { + if (Player* player = sObjectMgr.GetPlayer(playerGuid)) + { + // already checked if queueSlot is valid, now just get it + uint32 queueSlot = player->AddBattleGroundQueueId(bgQueueTypeId); + // store entry point coords + player->SetBattleGroundEntryPoint(); + + WorldPacket data; + // send status packet (in queue) + sBattleGroundMgr.BuildBattleGroundStatusPacket(data, true, bgTypeId, bgClientInstanceId, isRated, mapId, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenaType, TEAM_NONE); + player->GetSession()->SendPacket(data); + DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, player->GetGUIDLow(), player->GetName()); + } + }); + queue->ScheduleQueueUpdate(0, ARENA_TYPE_NONE, bgQueueTypeId, bgTypeId, bgBracketId); + }); } - - sBattleGroundMgr.ScheduleQueueUpdate(0, ARENA_TYPE_NONE, bgQueueTypeId, bgTypeId, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); } // Sent by client while inside battleground; depends on the battleground type @@ -387,142 +416,151 @@ void WorldSession::HandleBattlefieldPortOpcode(WorldPacket& recv_data) // get GroupQueueInfo from BattleGroundQueue BattleGroundTypeId bgTypeId = BattleGroundTypeId(receivedBgTypeId); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BgQueueTypeId(bgTypeId, ArenaType(type)); - BattleGroundQueue& bgQueue = sBattleGroundMgr.m_battleGroundQueues[bgQueueTypeId]; - - // we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattleGroundQueue::RemovePlayer() function - GroupQueueInfo queueInfo; - if (!bgQueue.GetPlayerGroupInfoData(_player->GetObjectGuid(), &queueInfo)) - { - sLog.outError("BattlegroundHandler: itrplayerstatus not found."); - return; - } - - // if action == 1, then instanceId is required - if (!queueInfo.isInvitedToBgInstanceGuid && action == 1) - { - sLog.outError("BattlegroundHandler: instance not found."); - return; - } - - BattleGround* bg = sBattleGroundMgr.GetBattleGround(queueInfo.isInvitedToBgInstanceGuid, bgTypeId); - - // bg template might and must be used in case of leaving queue, when instance is not created yet - if (!bg && action == 0) - bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); - if (!bg) - { - sLog.outError("BattlegroundHandler: bg_template not found for type id %u.", bgTypeId); - return; - } + bool canJoinToBg = _player->CanJoinToBattleground(); + uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId); - // some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it - if (action == 1 && queueInfo.arenaType == ARENA_TYPE_NONE) + sWorld.GetBGQueue().GetMessager().AddMessage([bgQueueTypeId, playerGuid = _player->GetObjectGuid(), actionTemp = action, canJoinToBg, bgTypeId, playerLevel = _player->GetLevel(), queueSlot](BattleGroundQueue* queue) { - // if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue - if (!_player->CanJoinToBattleground()) + uint8 action = actionTemp; + BattleGroundQueueItem& queueItem = queue->GetBattleGroundQueue(bgQueueTypeId); + GroupQueueInfo queueInfo; + if (!queueItem.GetPlayerGroupInfoData(playerGuid, &queueInfo)) { - // send bg command result to show nice message - WorldPacket data2; - sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(data2, bgTypeId, BG_GROUP_JOIN_STATUS_DESERTERS); - _player->GetSession()->SendPacket(data2); - action = 0; - - DEBUG_LOG("Battleground: player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUIDLow()); + sLog.outError("BattlegroundHandler: itrplayerstatus not found."); + return; } - // 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()) + + if (!queueInfo.isInvitedToBgInstanceGuid && action == 1) { - sLog.outError("Battleground: Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!", - _player->GetName(), _player->GetGUIDLow(), _player->GetLevel(), bg->GetMaxLevel(), bg->GetTypeId()); - action = 0; + sLog.outError("BattlegroundHandler: instance not found."); + return; } - } - uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId); - WorldPacket data; + // some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it + if (action == 1 && queueInfo.arenaType == ARENA_TYPE_NONE) + { + // if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue + if (!canJoinToBg) + { + // send bg command result to show nice message + WorldPacket data2; + sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(data2, bgTypeId, BG_GROUP_JOIN_STATUS_DESERTERS); + sWorld.GetMessager().AddMessage([playerGuid, data2](World* world) + { + if (Player* player = sObjectMgr.GetPlayer(playerGuid)) + { + player->GetSession()->SendPacket(data2); + } + }); - switch (action) - { - case 1: // port to battleground - if (!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId)) - return; // cheating? + action = 0; + } + } - // resurrect the player - if (!_player->IsAlive()) + switch (action) + { + case 1: // port to battleground { - _player->ResurrectPlayer(1.0f); - _player->SpawnCorpseBones(); - } + BattleGroundInQueueInfo* bgInQueue = queue->GetFreeSlotInstance(bgTypeId, queueInfo.isInvitedToBgInstanceGuid); + MANGOS_ASSERT(bgInQueue); // at this point must always exist - _player->TaxiFlightInterrupt(); + // remove battleground queue status from BGmgr + queueItem.RemovePlayer(playerGuid, false); - sBattleGroundMgr.BuildBattleGroundStatusPacket(data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), _player->GetBGTeam()); - _player->GetSession()->SendPacket(data); + sWorld.GetMessager().AddMessage([playerGuid, invitedTo = queueInfo.isInvitedToBgInstanceGuid, bgTypeId, bgQueueTypeId, groupTeam = queueInfo.groupTeam, queueSlot, bgClientInstanceId = bgInQueue->GetClientInstanceId(), isRated = bgInQueue->IsRated(), mapId = bgInQueue->GetMapId(), arenaType = bgInQueue->GetArenaType()](World* world) + { + Player* player = sObjectMgr.GetPlayer(playerGuid); + if (!player) + return; - // remove battleground queue status from BGmgr - bgQueue.RemovePlayer(_player->GetObjectGuid(), false); + // resurrect the player + if (!player->IsAlive()) + { + player->ResurrectPlayer(1.0f); + player->SpawnCorpseBones(); + } - // this is still needed here if battleground "jumping" shouldn't add deserter debuff - // also this is required to prevent stuck at old battleground after SetBattleGroundId set to new - if (BattleGround* currentBg = _player->GetBattleGround()) - currentBg->RemovePlayerAtLeave(_player->GetObjectGuid(), false, true); + player->TaxiFlightInterrupt(); - // set the destination instance id - _player->SetBattleGroundId(bg->GetInstanceId(), bgTypeId); - // set the destination team - _player->SetBGTeam(queueInfo.groupTeam); - // bg->HandleBeforeTeleportToBattleGround(_player); - sBattleGroundMgr.SendToBattleGround(_player, queueInfo.isInvitedToBgInstanceGuid, bgTypeId); - // add only in HandleMoveWorldPortAck() - // bg->AddPlayer(_player,team); + uint32 startTime = 0; + if (BattleGround* bg = sBattleGroundMgr.GetBattleGround(invitedTo, bgTypeId)) + startTime = bg->GetStartTime(); - DEBUG_LOG("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetInstanceId(), bg->GetTypeId(), bgQueueTypeId); + WorldPacket data; + sBattleGroundMgr.BuildBattleGroundStatusPacket(data, true, bgTypeId, bgClientInstanceId, isRated, mapId, queueSlot, STATUS_IN_PROGRESS, 0, startTime, arenaType, player->GetBGTeam()); + player->GetSession()->SendPacket(data); - break; - case 0: // leave queue - // if player leaves rated arena match before match start, it is counted as he played but he lost - if (queueInfo.isRated && queueInfo.isInvitedToBgInstanceGuid) - { - ArenaTeam* at = sObjectMgr.GetArenaTeamById(queueInfo.arenaTeamId); - if (at) - { - DEBUG_LOG("UPDATING memberLost's personal arena rating for %s by opponents rating: %u, because he has left queue!", _player->GetGuidStr().c_str(), queueInfo.opponentsTeamRating); - at->MemberLost(_player, queueInfo.opponentsTeamRating); - at->SaveToDB(); - } - } + // this is still needed here if battleground "jumping" shouldn't add deserter debuff + // also this is required to prevent stuck at old battleground after SetBattleGroundId set to new + if (BattleGround* currentBg = player->GetBattleGround()) + currentBg->RemovePlayerAtLeave(player->GetObjectGuid(), false, true); - _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, ARENA_TYPE_NONE, TEAM_NONE); - bgQueue.RemovePlayer(_player->GetObjectGuid(), true); + // set the destination instance id + player->SetBattleGroundId(invitedTo, bgTypeId); + // set the destination team + player->SetBGTeam(groupTeam); - // player left queue, we should update it - do not update Arena Queue - if (queueInfo.arenaType == ARENA_TYPE_NONE) - sBattleGroundMgr.ScheduleQueueUpdate(queueInfo.arenaTeamRating, queueInfo.arenaType, bgQueueTypeId, bgTypeId, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); + sBattleGroundMgr.SendToBattleGround(player, invitedTo, bgTypeId); - SendPacket(data); - - DEBUG_LOG("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetTypeId(), bgQueueTypeId); + DEBUG_LOG("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", player->GetName(), player->GetGUIDLow(), invitedTo, bgTypeId, bgQueueTypeId); + }); - break; - default: - sLog.outError("Battleground port: unknown action %u", action); - break; - } + break; + } + case 0: // leave queue + // if player leaves rated arena match before match start, it is counted as he played but he lost + if (queueInfo.isRated && queueInfo.isInvitedToBgInstanceGuid) + { + sWorld.GetMessager().AddMessage([arenaTeamId = queueInfo.arenaTeamId, playerGuid, opponentRating = queueInfo.opponentsTeamRating](World* world) + { + ArenaTeam* at = sObjectMgr.GetArenaTeamById(arenaTeamId); + if (at) + { + Player* player = sObjectMgr.GetPlayer(playerGuid); + if (player) + at->MemberLost(player, opponentRating); + else + at->OfflineMemberLost(playerGuid, opponentRating); + at->SaveToDB(); + } + }); + + queueItem.RemovePlayer(playerGuid, true); + sWorld.GetMessager().AddMessage([playerGuid, bgQueueTypeId, queueSlot, bgTypeId, bgClientInstanceId = queueInfo.clientInstanceId, isRated = queueInfo.isRated, mapId = queueInfo.mapId](World* world) + { + Player* player = sObjectMgr.GetPlayer(playerGuid); + if (!player) + return; + player->RemoveBattleGroundQueueId(bgQueueTypeId); + WorldPacket data; + sBattleGroundMgr.BuildBattleGroundStatusPacket(data, true, bgTypeId, bgClientInstanceId, isRated, mapId, queueSlot, STATUS_NONE, 0, 0, ARENA_TYPE_NONE, TEAM_NONE); + player->GetSession()->SendPacket(data); + }); + + if (queueInfo.arenaType == ARENA_TYPE_NONE) + queue->ScheduleQueueUpdate(queueInfo.arenaTeamRating, queueInfo.arenaType, bgQueueTypeId, bgTypeId, queueInfo.bgBracketId); + } + break; + default: + sLog.outError("Battleground port: unknown action %u", action); + break; + } + }); } // Sent by client when leaving the battleground void WorldSession::HandleLeaveBattlefieldOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Received opcode CMSG_LEAVE_BATTLEFIELD"); + uint64 guid; - recv_data.read_skip(); // unk1 - recv_data.read_skip(); // unk2 - recv_data.read_skip(); // BattleGroundTypeId - recv_data.read_skip(); // unk3 + // Essentially a BG guid - uint64 + recv_data >> guid; - // if(bgTypeId >= MAX_BATTLEGROUND_TYPES) // cheating? but not important in this case - // return; + uint32 bgTypeId = (guid & 0x0000FFFFFFFF0000) >> 16; // TODO: Test + + if (bgTypeId >= MAX_BATTLEGROUND_TYPE_ID) // cheating - but not important in this case + return; // not allow leave battleground in combat if (_player->IsInCombat()) @@ -542,6 +580,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket& /*recv_data*/) WorldPacket data; // we must update all queues here BattleGround* bg; + std::vector> idsToCheck; for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i); @@ -561,41 +600,50 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket& /*recv_data*/) { // this line is checked, i only don't know if GetStartTime 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, bg->GetTypeId(), bg->GetClientInstanceId(), bg->IsRated(), bg->GetMapId(), i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam()); SendPacket(data); continue; } } + + idsToCheck.push_back({i, bgQueueTypeId}); // we are sending update to player about queue - he can be invited there! - // get GroupQueueInfo for queue status - BattleGroundQueue& bgQueue = sBattleGroundMgr.m_battleGroundQueues[bgQueueTypeId]; - GroupQueueInfo queueInfo; - if (!bgQueue.GetPlayerGroupInfoData(_player->GetObjectGuid(), &queueInfo)) - continue; + } - if (queueInfo.isInvitedToBgInstanceGuid) + sWorld.GetBGQueue().GetMessager().AddMessage([idsToCheck, playerGuid = _player->GetObjectGuid(), playerLevel = _player->GetLevel()](BattleGroundQueue* queue) + { + for (auto& data : idsToCheck) { - bg = sBattleGroundMgr.GetBattleGround(queueInfo.isInvitedToBgInstanceGuid, bgTypeId); - if (!bg) + auto queueSlot = data.first; + BattleGroundQueueTypeId bgQueueTypeId = data.second; + BattleGroundQueueItem& queueItem = queue->GetBattleGroundQueue(bgQueueTypeId); + GroupQueueInfo queueInfo; + if (!queueItem.GetPlayerGroupInfoData(playerGuid, &queueInfo)) continue; - uint32 remainingTime = WorldTimer::getMSTimeDiff(WorldTimer::getMSTime(), queueInfo.removeInviteTime); - // send status invited to BattleGround - sBattleGroundMgr.BuildBattleGroundStatusPacket(data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType, TEAM_NONE); - SendPacket(data); + WorldPacket data; + if (queueInfo.isInvitedToBgInstanceGuid) + { + uint32 remainingTime = WorldTimer::getMSTimeDiff(WorldTimer::getMSTime(), queueInfo.removeInviteTime); + // send status invited to BattleGround + sBattleGroundMgr.BuildBattleGroundStatusPacket(data, true, queueInfo.bgTypeId, queueInfo.clientInstanceId, queueInfo.isRated, queueInfo.mapId, queueSlot, STATUS_WAIT_JOIN, remainingTime, 0, queueInfo.arenaType, TEAM_NONE); + } + else + { + uint32 avgTime = queueItem.GetAverageQueueWaitTime(&queueInfo, sBattleGroundMgr.GetBattleGroundBracketIdFromLevel(queueInfo.bgTypeId, playerLevel)); + // send status in BattleGround Queue + sBattleGroundMgr.BuildBattleGroundStatusPacket(data, true, queueInfo.bgTypeId, queueInfo.clientInstanceId, queueInfo.isRated, queueInfo.mapId, queueSlot, STATUS_WAIT_QUEUE, avgTime, WorldTimer::getMSTimeDiff(queueInfo.joinTime, WorldTimer::getMSTime()), queueInfo.arenaType, TEAM_NONE); + } + sWorld.GetMessager().AddMessage([playerGuid, data](World* world) + { + if (Player* player = sObjectMgr.GetPlayer(playerGuid)) + { + player->GetSession()->SendPacket(data); + } + }); } - else - { - bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); - if (!bg) - continue; + }); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&queueInfo, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); - // send status in BattleGround Queue - sBattleGroundMgr.BuildBattleGroundStatusPacket(data, bg, i, STATUS_WAIT_QUEUE, avgTime, WorldTimer::getMSTimeDiff(queueInfo.joinTime, WorldTimer::getMSTime()), arenaType, TEAM_NONE); - SendPacket(data); - } - } } // Sent by client when requesting the spirit healer @@ -695,7 +743,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recv_data) BattleGroundTypeId bgTypeId = bg->GetTypeId(); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BgQueueTypeId(bgTypeId, arenatype); - BattleGroundBracketId bgBracketId = _player->GetBattleGroundBracketIdFromLevel(bgTypeId); + BattleGroundBracketId bgBracketId = sBattleGroundMgr.GetBattleGroundBracketIdFromLevel(bgTypeId, _player->GetLevel()); Group* group = nullptr; @@ -788,56 +836,79 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recv_data) arenaRating = avg_pers_rating; } - BattleGroundQueue& bgQueue = sBattleGroundMgr.m_battleGroundQueues[bgQueueTypeId]; + AddGroupToQueueInfo info; + info.team = _player->GetTeam(); + info.clientInstanceId = 0; + info.mapId = bg->GetMapId(); if (asGroup) { - DEBUG_LOG("Battleground: arena join as group start"); - if (isRated) - DEBUG_LOG("Battleground: arena team id %u, leader %s queued with rating %u for type %u", _player->GetArenaTeamId(arenaslot), _player->GetName(), arenaRating, arenatype); + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) + if (Player* member = itr->getSource()) + info.members.push_back(member->GetObjectGuid()); + } - // set arena rated type to show correct minimap arena icon - bg->SetRated(isRated != 0); + sWorld.GetBGQueue().GetMessager().AddMessage([playerGuid = _player->GetObjectGuid(), bgQueueTypeId, bgTypeId, bgBracketId, ateamId, asGroup, isRated, arenaTeamId = _player->GetArenaTeamId(arenaslot), playerName = _player->GetName(), info, arenaRating, arenatype](BattleGroundQueue* queue) + { + BattleGroundQueueItem& bgQueue = queue->GetBattleGroundQueue(bgQueueTypeId); + if (asGroup) + { + DEBUG_LOG("Battleground: arena join as group start"); + if (isRated) + DEBUG_LOG("Battleground: arena team id %u, leader %s queued with rating %u for type %u", arenaTeamId, playerName, arenaRating, arenatype); - GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, group, bgTypeId, bgBracketId, arenatype, isRated != 0, false, 0, arenaRating, ateamId); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); - for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) + GroupQueueInfo* groupInfo = bgQueue.AddGroup(playerGuid, info, bgTypeId, bgBracketId, arenatype, isRated != 0, false, 0, arenaRating, ateamId); + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(groupInfo, groupInfo->bgBracketId); + sWorld.GetMessager().AddMessage([playerGuid, members = info.members, bgQueueTypeId, bgTypeId, bgClientInstanceId = groupInfo->clientInstanceId, mapId = groupInfo->mapId, avgTime, arenaType = groupInfo->arenaType, isRated = groupInfo->isRated](World* world) + { + Player* leader = sObjectMgr.GetPlayer(playerGuid); + for (ObjectGuid guid : members) + { + Player* member = sObjectMgr.GetPlayer(guid); + if (!member) + continue; + + // add to queue + uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId); + + // store entry point coords (same as leader entry point) + member->SetBattleGroundEntryPoint(leader); + + WorldPacket data; + // send status packet (in queue) + sBattleGroundMgr.BuildBattleGroundStatusPacket(data, true, bgTypeId, bgClientInstanceId, isRated, mapId, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenaType, TEAM_NONE); + member->GetSession()->SendPacket(data); + sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(data, bgTypeId, BG_GROUP_JOIN_STATUS_SUCCESS); + member->GetSession()->SendPacket(data); + DEBUG_LOG("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()); + } + + DEBUG_LOG("Battleground: arena join as group end"); + }); + } + else { - Player* member = itr->getSource(); - if (!member) - continue; + GroupQueueInfo* groupInfo = bgQueue.AddGroup(playerGuid, info, bgTypeId, bgBracketId, arenatype, isRated != 0, false, 0, arenaRating, ateamId); + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(groupInfo, bgBracketId); - // add to queue - uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId); + sWorld.GetMessager().AddMessage([playerGuid, bgQueueTypeId, bgTypeId, bgClientInstanceId = groupInfo->clientInstanceId, avgTime, arenaType = groupInfo->arenaType, isRated = groupInfo->isRated, mapId = groupInfo->mapId](World* world) + { + if (Player* player = sObjectMgr.GetPlayer(playerGuid)) + { + uint32 queueSlot = player->AddBattleGroundQueueId(bgQueueTypeId); - // store entry point coords (same as leader entry point) - member->SetBattleGroundEntryPoint(_player); + // store entry point coords + player->SetBattleGroundEntryPoint(); - WorldPacket data; - // send status packet (in queue) - sBattleGroundMgr.BuildBattleGroundStatusPacket(data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, TEAM_NONE); - member->GetSession()->SendPacket(data); - sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(data, bgTypeId, BG_GROUP_JOIN_STATUS_SUCCESS); - member->GetSession()->SendPacket(data); - DEBUG_LOG("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()); + WorldPacket data; + // send status packet (in queue) + sBattleGroundMgr.BuildBattleGroundStatusPacket(data, true, bgTypeId, bgClientInstanceId, isRated, mapId, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenaType, TEAM_NONE); + player->GetSession()->SendPacket(data); + DEBUG_LOG("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, playerGuid.GetCounter(), player->GetName()); + } + }); } - DEBUG_LOG("Battleground: arena join as group end"); - } - else - { - GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bgBracketId, arenatype, isRated != 0, false, 0, arenaRating, ateamId); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); - uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); - - // store entry point coords - _player->SetBattleGroundEntryPoint(); - - WorldPacket data; - // send status packet (in queue) - sBattleGroundMgr.BuildBattleGroundStatusPacket(data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, TEAM_NONE); - SendPacket(data); - DEBUG_LOG("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName()); - } - sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); + queue->ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, sBattleGroundMgr.GetBattleGroundBracketIdFromLevel(bgTypeId, bgBracketId)); + }); } // Sent by client when reporting AFK diff --git a/src/game/BattleGround/BattleGroundQueue.cpp b/src/game/BattleGround/BattleGroundQueue.cpp index b239e5f8c8..8cb5379e9b 100644 --- a/src/game/BattleGround/BattleGroundQueue.cpp +++ b/src/game/BattleGround/BattleGroundQueue.cpp @@ -149,15 +149,18 @@ bool BattleGroundQueueItem::SelectionPool::AddGroup(GroupQueueInfo* queueInfo, u @param arena rating @param arena team id */ -GroupQueueInfo* BattleGroundQueueItem::AddGroup(ObjectGuid leader, AddGroupToQueueInfo& groupInfo, BattleGroundTypeId bgTypeId, BattleGroundBracketId bracketId, ArenaType arenaType, bool isRated, bool isPremade, uint32 instanceId, uint32 arenaRating, uint32 arenaTeamId) +GroupQueueInfo* BattleGroundQueueItem::AddGroup(ObjectGuid leader, AddGroupToQueueInfo const& groupInfo, BattleGroundTypeId bgTypeId, BattleGroundBracketId bracketId, ArenaType arenaType, bool isRated, bool isPremade, uint32 instanceId, uint32 arenaRating, uint32 arenaTeamId) { // create new ginfo GroupQueueInfo* queueInfo = new GroupQueueInfo; queueInfo->bgTypeId = bgTypeId; + queueInfo->bgBracketId = bracketId; queueInfo->arenaType = arenaType; queueInfo->arenaTeamId = arenaTeamId; queueInfo->isRated = isRated; queueInfo->isInvitedToBgInstanceGuid = 0; + queueInfo->mapId = groupInfo.mapId; + queueInfo->clientInstanceId = groupInfo.clientInstanceId; queueInfo->joinTime = WorldTimer::getMSTime(); queueInfo->removeInviteTime = 0; queueInfo->groupTeam = groupInfo.team; @@ -187,7 +190,6 @@ GroupQueueInfo* BattleGroundQueueItem::AddGroup(ObjectGuid leader, AddGroupToQue // add players from group to ginfo { - // std::lock_guard guard(m_Lock); if (!groupInfo.members.empty()) { for (ObjectGuid member : groupInfo.members) @@ -329,9 +331,6 @@ uint32 BattleGroundQueueItem::GetAverageQueueWaitTime(GroupQueueInfo* queueInfo, */ void BattleGroundQueueItem::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) { - // Player *plr = sObjectMgr.GetPlayer(guid); - // std::lock_guard guard(m_Lock); - int32 bracketId = -1; // signed for proper for-loop finish // remove player from map, if he's there @@ -466,7 +465,6 @@ void BattleGroundQueueItem::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCo */ bool BattleGroundQueueItem::IsPlayerInvited(ObjectGuid playerGuid, const uint32 bgInstanceGuid, const uint32 removeTime) { - // std::lock_guard g(m_Lock); QueuedPlayersMap::const_iterator qItr = m_queuedPlayers.find(playerGuid); return (qItr != m_queuedPlayers.end() && qItr->second.groupInfo->isInvitedToBgInstanceGuid == bgInstanceGuid @@ -509,6 +507,8 @@ bool BattleGroundQueueItem::InviteGroupToBg(GroupQueueInfo* groupInfo, BattleGro // not yet invited // set invitation groupInfo->isInvitedToBgInstanceGuid = queueInfo.GetInstanceId(); + groupInfo->mapId = queueInfo.GetMapId(); + groupInfo->clientInstanceId = queueInfo.GetClientInstanceId(); BattleGroundTypeId bgTypeId = queueInfo.GetTypeId(); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BgQueueTypeId(bgTypeId, queueInfo.GetArenaType()); BattleGroundBracketId bracket_id = queueInfo.GetBracketId(); @@ -852,7 +852,6 @@ bool BattleGroundQueueItem::CheckSkirmishForSameFaction(BattleGroundBracketId br */ void BattleGroundQueueItem::Update(BattleGroundQueue& queue, BattleGroundTypeId bgTypeId, BattleGroundBracketId bracketId, ArenaType arenaType, bool isRated, uint32 arenaRating) { - // std::lock_guard guard(m_Lock); // if no players in queue - do nothing if (m_queuedGroups[bracketId][BG_QUEUE_PREMADE_ALLIANCE].empty() && m_queuedGroups[bracketId][BG_QUEUE_PREMADE_HORDE].empty() && @@ -1301,8 +1300,7 @@ void BgQueueRemoveEvent::Abort(uint64 /*e_time*/) BattleGroundQueue::BattleGroundQueue() { - TimePoint now = std::chrono::time_point_cast(Clock::now());; - m_nextRatingDiscardUpdate = now + std::chrono::milliseconds(sWorld.getConfig(CONFIG_UINT32_ARENA_RATING_DISCARD_TIMER)); + } void BattleGroundQueue::Update() @@ -1452,12 +1450,21 @@ void BattleGroundQueue::ScheduleQueueUpdate(uint32 arenaRating, ArenaType arenaT void BattleGroundQueue::AddBgToFreeSlots(BattleGroundInQueueInfo const& info) { - // TODO: + auto& typeIdQueue = m_bgFreeSlotQueue[info.GetTypeId()]; + typeIdQueue.emplace_front(info); } -void BattleGroundQueue::RemoveBgFromFreeSlots(uint32 instanceId) +void BattleGroundQueue::RemoveBgFromFreeSlots(BattleGroundTypeId typeId, uint32 instanceId) { - // TODO: + auto& typeIdQueue = m_bgFreeSlotQueue[typeId]; + for (auto itr = typeIdQueue.begin(); itr != typeIdQueue.end(); ++itr) + { + if (itr->GetInstanceId() == instanceId) + { + typeIdQueue.erase(itr); + return; + } + } } BgFreeSlotQueueType& BattleGroundQueue::GetFreeSlotQueueItem(BattleGroundTypeId bgTypeId) @@ -1465,6 +1472,29 @@ BgFreeSlotQueueType& BattleGroundQueue::GetFreeSlotQueueItem(BattleGroundTypeId return m_bgFreeSlotQueue[bgTypeId]; } +BattleGroundInQueueInfo* BattleGroundQueue::GetFreeSlotInstance(BattleGroundTypeId bgTypeId, uint32 instanceId) +{ + auto& queueItem = GetFreeSlotQueueItem(bgTypeId); + auto itr = std::find_if(queueItem.begin(), queueItem.end(), [instanceId](BattleGroundInQueueInfo const& bgInQueue) + { + return bgInQueue.instanceId == instanceId; + }); + if (itr == queueItem.end()) + return nullptr; + return &(*itr); +} + +BattleGroundQueueItem& BattleGroundQueue::GetBattleGroundQueue(BattleGroundQueueTypeId bgQueueTypeId) +{ + return m_battleGroundQueues[bgQueueTypeId]; +} + +void BattleGroundQueue::SetNextRatingDiscardUpdate(std::chrono::milliseconds& timePoint) +{ + TimePoint now = std::chrono::time_point_cast(Clock::now());; + m_nextRatingDiscardUpdate = now + timePoint; +} + void BattleGroundQueue::RemovePlayer(BattleGroundQueueTypeId bgQueueTypeId, ObjectGuid player, bool decreaseInvitedCount) { m_battleGroundQueues[bgQueueTypeId].RemovePlayer(player, decreaseInvitedCount); diff --git a/src/game/BattleGround/BattleGroundQueue.h b/src/game/BattleGround/BattleGroundQueue.h index 0662028b96..6908264d72 100644 --- a/src/game/BattleGround/BattleGroundQueue.h +++ b/src/game/BattleGround/BattleGroundQueue.h @@ -35,6 +35,8 @@ struct AddGroupToQueueInfo { Team team; std::vector members; // empty when not in group + uint32 clientInstanceId; + uint32 mapId; }; struct GroupQueueInfo // stores information about the group in queue (also used when joined as solo!) @@ -42,7 +44,10 @@ struct GroupQueueInfo // stores informatio GroupQueueInfoPlayers players; // player queue info map Team groupTeam; // Player team (ALLIANCE/HORDE) BattleGroundTypeId bgTypeId; // battleground type id + BattleGroundBracketId bgBracketId; // battleground bracked id bool isRated; // rated + uint32 mapId; // invited to mapId + uint32 clientInstanceId; // invited to client instance id ArenaType arenaType; // 2v2, 3v3, 5v5 or 0 when BG uint32 arenaTeamId; // team id if rated match uint32 joinTime; // time when group was added @@ -127,18 +132,14 @@ class BattleGroundQueueItem bool CheckPremadeMatch(BattleGroundBracketId /*bracketId*/, uint32 /*minPlayersPerTeam*/, uint32 /*maxPlayersPerTeam*/); bool CheckNormalMatch(BattleGround* /*bgTemplate*/, BattleGroundBracketId /*bracketId*/, uint32 /*minPlayers*/, uint32 /*maxPlayers*/); bool CheckSkirmishForSameFaction(BattleGroundBracketId /*bracketId*/, uint32 /*minPlayersPerTeam*/); - GroupQueueInfo* AddGroup(ObjectGuid leader, AddGroupToQueueInfo& /*groupInfo*/, BattleGroundTypeId /*bgTypeId*/, BattleGroundBracketId /*bracketEntry*/, ArenaType /*arenaType*/, bool /*isRated*/, bool /*isPremade*/, uint32 /*instanceId*/, uint32 /*arenaRating*/, uint32 arenaTeamId = 0); - void RemovePlayer(ObjectGuid /*guid*/, bool /*decreaseInvitedCount*/); + GroupQueueInfo* AddGroup(ObjectGuid leader, AddGroupToQueueInfo const& /*groupInfo*/, BattleGroundTypeId /*bgTypeId*/, BattleGroundBracketId /*bracketEntry*/, ArenaType /*arenaType*/, bool /*isRated*/, bool /*isPremade*/, uint32 /*instanceId*/, uint32 /*arenaRating*/, uint32 arenaTeamId = 0); + void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount); bool IsPlayerInvited(ObjectGuid /*playerGuid*/, const uint32 /*bgInstanceGuid*/, const uint32 /*removeTime*/); bool GetPlayerGroupInfoData(ObjectGuid /*guid*/, GroupQueueInfo* /*groupInfo*/); void PlayerInvitedToBgUpdateAverageWaitTime(GroupQueueInfo* /*groupInfo*/, BattleGroundBracketId /*bracketId*/); uint32 GetAverageQueueWaitTime(GroupQueueInfo* /*groupInfo*/, BattleGroundBracketId /*bracketId*/); private: - // mutex that should not allow changing private data, nor allowing to update Queue during private data change. - std::recursive_mutex m_lock; - - typedef std::map QueuedPlayersMap; QueuedPlayersMap m_queuedPlayers; @@ -245,13 +246,17 @@ class BattleGroundQueue void ScheduleQueueUpdate(uint32 /*arenaRating*/, ArenaType /*arenaType*/, BattleGroundQueueTypeId /*bgQueueTypeId*/, BattleGroundTypeId /*bgTypeId*/, BattleGroundBracketId /*bracketId*/); void AddBgToFreeSlots(BattleGroundInQueueInfo const& info); - void RemoveBgFromFreeSlots(uint32 instanceId); + void RemoveBgFromFreeSlots(BattleGroundTypeId typeId, uint32 instanceId); void RemovePlayer(BattleGroundQueueTypeId bgQueueTypeId, ObjectGuid player, bool decreaseInvitedCount); BgFreeSlotQueueType& GetFreeSlotQueueItem(BattleGroundTypeId bgTypeId); + BattleGroundInQueueInfo* GetFreeSlotInstance(BattleGroundTypeId bgTypeId, uint32 instanceId); + BattleGroundQueueItem& GetBattleGroundQueue(BattleGroundQueueTypeId bgQueueTypeId); + + void SetNextRatingDiscardUpdate(std::chrono::milliseconds& timePoint); private: - BattleGroundQueueItem m_battleGroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES]; // public, because we need to access them in BG handler code + BattleGroundQueueItem m_battleGroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES]; BgFreeSlotQueueType m_bgFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID]; diff --git a/src/game/World/World.cpp b/src/game/World/World.cpp index 8358e8f200..164a2fb094 100644 --- a/src/game/World/World.cpp +++ b/src/game/World/World.cpp @@ -925,6 +925,8 @@ void World::SetInitialWorldSettings() ///- Remove the bones (they should not exist in DB though) and old corpses after a restart CharacterDatabase.PExecute("DELETE FROM corpse WHERE corpse_type = '0' OR time < (" _UNIXTIME_ "-'%u')", 3 * DAY); + m_bgQueue.SetNextRatingDiscardUpdate(std::chrono::milliseconds(sWorld.getConfig(CONFIG_UINT32_ARENA_RATING_DISCARD_TIMER))); + /// load spell_dbc first! dbc's need them sLog.outString("Loading spell_template..."); sObjectMgr.LoadSpellTemplate();