diff options
Diffstat (limited to 'src/server/game/DungeonFinding/LFGMgr.cpp')
-rw-r--r-- | src/server/game/DungeonFinding/LFGMgr.cpp | 253 |
1 files changed, 126 insertions, 127 deletions
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 2550f909a8b..9d5d8e40b54 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -188,7 +188,7 @@ void LFGMgr::LoadRewards() RewardMapStore.clear(); // ORDER BY is very important for GetRandomDungeonReward! - QueryResult result = WorldDatabase.Query("SELECT dungeonId, maxLevel, firstQuestId, firstMoneyVar, firstXPVar, otherQuestId, otherMoneyVar, otherXPVar FROM lfg_dungeon_rewards ORDER BY dungeonId, maxLevel ASC"); + QueryResult result = WorldDatabase.Query("SELECT dungeonId, maxLevel, firstQuestId, otherQuestId FROM lfg_dungeon_rewards ORDER BY dungeonId, maxLevel ASC"); if (!result) { @@ -205,11 +205,7 @@ void LFGMgr::LoadRewards() uint32 dungeonId = fields[0].GetUInt32(); uint32 maxLevel = fields[1].GetUInt8(); uint32 firstQuestId = fields[2].GetUInt32(); - uint32 firstMoneyVar = fields[3].GetUInt32(); - uint32 firstXPVar = fields[4].GetUInt32(); - uint32 otherQuestId = fields[5].GetUInt32(); - uint32 otherMoneyVar = fields[6].GetUInt32(); - uint32 otherXPVar = fields[7].GetUInt32(); + uint32 otherQuestId = fields[3].GetUInt32(); if (!GetLFGDungeon(dungeonId)) { @@ -223,10 +219,10 @@ void LFGMgr::LoadRewards() maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); } - if (firstQuestId && !sObjectMgr->GetQuestTemplate(firstQuestId)) + if (!firstQuestId || !sObjectMgr->GetQuestTemplate(firstQuestId)) { sLog->outError(LOG_FILTER_SQL, "First quest %u specified for dungeon %u in table `lfg_dungeon_rewards` does not exist!", firstQuestId, dungeonId); - firstQuestId = 0; + continue; } if (otherQuestId && !sObjectMgr->GetQuestTemplate(otherQuestId)) @@ -235,9 +231,10 @@ void LFGMgr::LoadRewards() otherQuestId = 0; } - RewardMapStore.insert(LfgRewardContainer::value_type(dungeonId, new LfgReward(maxLevel, firstQuestId, firstMoneyVar, firstXPVar, otherQuestId, otherMoneyVar, otherXPVar))); + RewardMapStore.insert(LfgRewardContainer::value_type(dungeonId, new LfgReward(maxLevel, firstQuestId, otherQuestId))); ++count; - } while (result->NextRow()); + } + while (result->NextRow()); sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u lfg dungeon rewards in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } @@ -434,7 +431,7 @@ void LFGMgr::Update(uint32 diff) } else SendLfgUpdatePlayer(guid, LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, GetSelectedDungeons(guid), GetComment(guid))); - SendLfgUpdateProposal(guid, m_lfgProposalId, proposal); + SendLfgUpdateProposal(guid, proposal); } if (proposal.state == LFG_PROPOSAL_SUCCESS) @@ -552,27 +549,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const LfgState state = GetState(gguid); if (state == LFG_STATE_QUEUED) { - LfgDungeonSet const& playerDungeons = GetSelectedDungeons(guid); - if (playerDungeons == dungeons) // Joining the same dungeons -- Send OK - { - player->GetSession()->SendLfgJoinResult(joinData); // Default value of joinData.result = LFG_JOIN_OK - if (grp) - { - LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, dungeons, comment); - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) - if (itr->getSource() && itr->getSource()->GetSession()) - itr->getSource()->GetSession()->SendLfgUpdateParty(updateData); - } - else - player->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_JOIN_QUEUE, dungeons, comment)); - - return; - } - else // Remove from queue and rejoin - { - LFGQueue& queue = GetQueue(gguid); - queue.RemoveFromQueue(gguid); - } + LFGQueue& queue = GetQueue(gguid); + queue.RemoveFromQueue(gguid); } // Check player or group member restrictions @@ -620,7 +598,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const bool isDungeon = false; for (LfgDungeonSet::const_iterator it = dungeons.begin(); it != dungeons.end() && joinData.result == LFG_JOIN_OK; ++it) { - switch (GetDungeonType(*it)) + LfgType type = GetDungeonType(*it); + switch (type) { case LFG_TYPE_RANDOM: if (dungeons.size() > 1) // Only allow 1 random dungeon @@ -640,6 +619,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const isRaid = true; break; default: + sLog->outError(LOG_FILTER_LFG, "Wrong dungeon type %u for dungeon %u", type, *it); joinData.result = LFG_JOIN_DUNGEON_INVALID; break; } @@ -719,8 +699,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const { LfgRolesMap rolesMap; rolesMap[guid] = roles; - LFGQueue& queue = GetQueue(gguid); - queue.AddQueueData(guid, time_t(time(NULL)), dungeons, rolesMap); + LFGQueue& queue = GetQueue(guid); + queue.AddQueueData(guid, time(NULL), dungeons, rolesMap); if (!isContinue) { @@ -873,7 +853,7 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /* { uint64 pguid = it->first; - if (!sendRoleChosen) + if (sendRoleChosen) SendLfgRoleChosen(pguid, guid, roles); SendLfgRoleCheckUpdate(pguid, roleCheck); @@ -916,7 +896,7 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /* @param[in] players Set of players to check their dungeon restrictions @param[out] lockMap Map of players Lock status info of given dungeons (Empty if dungeons is not empty) */ -void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, const LfgGuidSet& players, LfgLockPartyMap& lockMap) +void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap) { lockMap.clear(); for (LfgGuidSet::const_iterator it = players.begin(); it != players.end() && !dungeons.empty(); ++it) @@ -1083,9 +1063,10 @@ void LFGMgr::MakeNewGroup(LfgProposal const& proposal) grp->SendUpdate(); } -uint32 LFGMgr::AddProposal(LfgProposal const& proposal) +uint32 LFGMgr::AddProposal(LfgProposal& proposal) { - ProposalsStore[++m_lfgProposalId] = proposal; + proposal.id = ++m_lfgProposalId; + ProposalsStore[m_lfgProposalId] = proposal; return m_lfgProposalId; } @@ -1129,16 +1110,14 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) if (!allAnswered) { for (LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) - { - uint64 guid = it->first; - SendLfgUpdateProposal(guid, proposalId, proposal); - } + SendLfgUpdateProposal(it->first, proposal); + return; } bool sendUpdate = proposal.state != LFG_PROPOSAL_SUCCESS; proposal.state = LFG_PROPOSAL_SUCCESS; - time_t joinTime = time_t(time(NULL)); + time_t joinTime = time(NULL); LFGQueue& queue = GetQueue(guid); LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_GROUP_FOUND); @@ -1149,7 +1128,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) uint32 dungeonId = (*GetSelectedDungeons(pguid).begin()); int32 waitTime = -1; if (sendUpdate) - SendLfgUpdateProposal(pguid, proposalId, proposal); + SendLfgUpdateProposal(pguid, proposal); if (gguid) { @@ -1236,7 +1215,7 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate uint64 guid = it->first; uint64 gguid = it->second.group ? it->second.group : guid; - SendLfgUpdateProposal(guid, itProposal->first, proposal); + SendLfgUpdateProposal(guid, proposal); if (toRemove.find(gguid) != toRemove.end()) // Didn't accept or in same group that someone that didn't accept { @@ -1465,106 +1444,126 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* } } - if (error == LFG_TELEPORTERROR_OK) - { - if (!player->GetMap()->IsDungeon()) - player->SetBattlegroundEntryPoint(); - - if (player->isInFlight()) - { - player->GetMotionMaster()->MovementExpired(); - player->CleanupAfterTaxiFlight(); - } + if (!player->GetMap()->IsDungeon()) + player->SetBattlegroundEntryPoint(); - if (!player->TeleportTo(mapid, x, y, z, orientation)) - { - error = LFG_TELEPORTERROR_INVALID_LOCATION; - sLog->outError(LOG_FILTER_LFG, "TeleportPlayer: Failed to teleport [" UI64FMTD "] to map %u (x: %f, y: %f, z: %f)", player->GetGUID(), mapid, x, y, z); - } + if (player->isInFlight()) + { + player->GetMotionMaster()->MovementExpired(); + player->CleanupAfterTaxiFlight(); } + + if (!player->TeleportTo(mapid, x, y, z, orientation)) + error = LFG_TELEPORTERROR_INVALID_LOCATION; } + else + error = LFG_TELEPORTERROR_INVALID_LOCATION; if (error != LFG_TELEPORTERROR_OK) player->GetSession()->SendLfgTeleportError(uint8(error)); - sLog->outDebug(LOG_FILTER_LFG, "TeleportPlayer: Player %s is being teleported in. Result: %u", - player->GetName().c_str(), error); + sLog->outDebug(LOG_FILTER_LFG, "TeleportPlayer: Player %s is being teleported in to map %u " + "(x: %f, y: %f, z: %f) Result: %u", player->GetName().c_str(), dungeon->map, + dungeon->x, dungeon->y, dungeon->z, error); } /** - Give completion reward to player + Finish a dungeon and give reward, if any. - @param[in] dungeonId Id of the dungeon finished - @param[in] player Player to reward + @param[in] guid Group guid + @param[in] dungeonId Dungeonid */ -void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player) +void LFGMgr::FinishDungeon(uint64 gguid, const uint32 dungeonId) { - Group* group = player->GetGroup(); - if (!group || !group->isLFGGroup()) - { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] is not in a group or not a LFGGroup. Ignoring", player->GetGUID()); - return; - } - - uint64 guid = player->GetGUID(); - uint64 gguid = player->GetGroup()->GetGUID(); uint32 gDungeonId = GetDungeon(gguid); if (gDungeonId != dungeonId) { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] Finished dungeon %u but group queued for %u. Ignoring", guid, dungeonId, gDungeonId); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] Finished dungeon %u but group queued for %u. Ignoring", gguid, dungeonId, gDungeonId); return; } - if (GetState(guid) == LFG_STATE_FINISHED_DUNGEON) + if (GetState(gguid) == LFG_STATE_FINISHED_DUNGEON) // Shouldn't happen. Do not reward multiple times { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] Already rewarded player. Ignoring", guid); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] Already rewarded group. Ignoring", gguid); return; } - // Mark dungeon as finished SetState(gguid, LFG_STATE_FINISHED_DUNGEON); - // Clear player related lfg stuff - uint32 rDungeonId = (*GetSelectedDungeons(guid).begin()); - SetState(guid, LFG_STATE_FINISHED_DUNGEON); - - // Give rewards only if its a random or seasonal dungeon - LFGDungeonData const* dungeon = GetLFGDungeon(rDungeonId); - if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !dungeon->seasonal)) + const LfgGuidSet& players = GetPlayers(gguid); + for (LfgGuidSet::const_iterator it = players.begin(); it != players.end(); ++it) { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] dungeon %u is not random nor seasonal", guid, rDungeonId); - return; - } + uint64 guid = (*it); + if (GetState(guid) == LFG_STATE_FINISHED_DUNGEON) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] Already rewarded player. Ignoring", guid); + continue; + } - // Update achievements - if (dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC) - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1); + uint32 rDungeonId = 0; + const LfgDungeonSet& dungeons = GetSelectedDungeons(guid); + if (!dungeons.empty()) + rDungeonId = (*dungeons.begin()); - LfgReward const* reward = GetRandomDungeonReward(rDungeonId, player->getLevel()); - if (!reward) - return; + SetState(guid, LFG_STATE_FINISHED_DUNGEON); - uint8 index = 0; - Quest const* qReward = sObjectMgr->GetQuestTemplate(reward->reward[index].questId); - if (!qReward) - return; + // Give rewards only if its a random dungeon + LFGDungeonData const* dungeon = GetLFGDungeon(rDungeonId); - // if we can take the quest, means that we haven't done this kind of "run", IE: First Heroic Random of Day. - if (player->CanRewardQuest(qReward, false)) - player->RewardQuest(qReward, 0, NULL, false); - else - { - index = 1; - qReward = sObjectMgr->GetQuestTemplate(reward->reward[index].questId); - if (!qReward) - return; - // we give reward without informing client (retail does this) - player->RewardQuest(qReward, 0, NULL, false); - } + if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !dungeon->seasonal)) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] dungeon %u is not random or seasonal", guid, rDungeonId); + continue; + } + + Player* player = ObjectAccessor::FindPlayer(guid); + if (!player || !player->IsInWorld()) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] not found in world", guid); + continue; + } + + LFGDungeonData const* dungeonDone = GetLFGDungeon(dungeonId); + uint32 mapId = dungeonDone ? uint32(dungeonDone->map) : 0; - // Give rewards - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] done dungeon %u, %s previously done.", player->GetGUID(), GetDungeon(gguid), index > 0 ? " " : " not"); - player->GetSession()->SendLfgPlayerReward(dungeon->Entry(), GetDungeon(gguid, false), index, reward, qReward); + if (player->GetMapId() != mapId) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] is in map %u and should be in %u to get reward", guid, player->GetMapId(), mapId); + continue; + } + + // Update achievements + if (dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC) + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1); + + LfgReward const* reward = GetRandomDungeonReward(rDungeonId, player->getLevel()); + if (!reward) + continue; + + bool done = false; + Quest const* quest = sObjectMgr->GetQuestTemplate(reward->firstQuest); + if (!quest) + continue; + + // if we can take the quest, means that we haven't done this kind of "run", IE: First Heroic Random of Day. + if (player->CanRewardQuest(quest, false)) + player->RewardQuest(quest, 0, NULL, false); + else + { + done = true; + quest = sObjectMgr->GetQuestTemplate(reward->otherQuest); + if (!quest) + continue; + // we give reward without informing client (retail does this) + player->RewardQuest(quest, 0, NULL, false); + } + + // Give rewards + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] done dungeon %u, %s previously done.", player->GetGUID(), GetDungeon(gguid), done? " " : " not"); + LfgPlayerRewardData data = LfgPlayerRewardData(dungeon->Entry(), GetDungeon(gguid, false), done, quest); + player->GetSession()->SendLfgPlayerReward(data); + } + SetDungeon(gguid, 0); } // --------------------------------------------------------------------------// @@ -1577,7 +1576,7 @@ void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player) @param[in] randomdungeon Random dungeon id (if value = 0 will return all dungeons) @returns Set of dungeons that can be done. */ -const LfgDungeonSet& LFGMgr::GetDungeonsByRandom(uint32 randomdungeon) +LfgDungeonSet const& LFGMgr::GetDungeonsByRandom(uint32 randomdungeon) { LFGDungeonData const* dungeon = GetLFGDungeon(randomdungeon); uint32 group = dungeon ? dungeon->group : 0; @@ -1675,13 +1674,13 @@ bool LFGMgr::IsTeleported(uint64 pguid) return false; } -const LfgDungeonSet& LFGMgr::GetSelectedDungeons(uint64 guid) +LfgDungeonSet const& LFGMgr::GetSelectedDungeons(uint64 guid) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::GetSelectedDungeons: [" UI64FMTD "]", guid); return PlayersStore[guid].GetSelectedDungeons(); } -const LfgLockMap& LFGMgr::GetLockedDungeons(uint64 guid) +LfgLockMap const& LFGMgr::GetLockedDungeons(uint64 guid) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::GetLockedDungeons: [" UI64FMTD "]", guid); return PlayersStore[guid].GetLockedDungeons(); @@ -1728,7 +1727,7 @@ void LFGMgr::SetState(uint64 guid, LfgState state) if (IS_GROUP_GUID(guid)) { LfgGroupData& data = GroupsStore[guid]; - if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG)) + if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_TRACE)) { std::string const& ns = GetStateString(state); std::string const& ps = GetStateString(data.GetState()); @@ -1741,7 +1740,7 @@ void LFGMgr::SetState(uint64 guid, LfgState state) else { LfgPlayerData& data = PlayersStore[guid]; - if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG)) + if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_TRACE)) { std::string const& ns = GetStateString(state); std::string const& ps = GetStateString(data.GetState()); @@ -1765,19 +1764,19 @@ void LFGMgr::SetRoles(uint64 guid, uint8 roles) PlayersStore[guid].SetRoles(roles); } -void LFGMgr::SetComment(uint64 guid, const std::string& comment) +void LFGMgr::SetComment(uint64 guid, std::string const& comment) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetComment: [" UI64FMTD "] comment: %s", guid, comment.c_str()); PlayersStore[guid].SetComment(comment); } -void LFGMgr::SetSelectedDungeons(uint64 guid, const LfgDungeonSet& dungeons) +void LFGMgr::SetSelectedDungeons(uint64 guid, LfgDungeonSet const& dungeons) { - sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetSelectedDungeons: [" UI64FMTD "]", guid); + sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetSelectedDungeons: [" UI64FMTD "] Dungeons: %s", guid, ConcatenateDungeons(dungeons).c_str()); PlayersStore[guid].SetSelectedDungeons(dungeons); } -void LFGMgr::SetLockedDungeons(uint64 guid, const LfgLockMap& lock) +void LFGMgr::SetLockedDungeons(uint64 guid, LfgLockMap const& lock) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetLockedDungeons: [" UI64FMTD "]", guid); PlayersStore[guid].SetLockedDungeons(lock); @@ -1918,10 +1917,10 @@ void LFGMgr::SendLfgBootProposalUpdate(uint64 guid, LfgPlayerBoot const& boot) player->GetSession()->SendLfgBootProposalUpdate(boot); } -void LFGMgr::SendLfgUpdateProposal(uint64 guid, uint32 proposalId, LfgProposal const& proposal) +void LFGMgr::SendLfgUpdateProposal(uint64 guid, LfgProposal const& proposal) { if (Player* player = ObjectAccessor::FindPlayer(guid)) - player->GetSession()->SendLfgUpdateProposal(proposalId, proposal); + player->GetSession()->SendLfgUpdateProposal(proposal); } void LFGMgr::SendLfgQueueStatus(uint64 guid, LfgQueueStatusData const& data) @@ -1940,7 +1939,7 @@ LFGQueue& LFGMgr::GetQueue(uint64 guid) uint8 queueId = 0; if (IS_GROUP_GUID(guid)) { - const LfgGuidSet& players = GetPlayers(guid); + LfgGuidSet const& players = GetPlayers(guid); uint64 pguid = players.empty() ? 0 : (*players.begin()); if (pguid) queueId = GetTeam(pguid); |