diff options
author | Spp <spp@jorge.gr> | 2012-10-29 20:13:42 +0100 |
---|---|---|
committer | Spp <spp@jorge.gr> | 2012-10-29 20:13:42 +0100 |
commit | 9074c11a908a84cad0d154c7aea821e0e5bf006e (patch) | |
tree | 3bbdfea18f5e18e44ca7107544cac34f43b734a1 /src | |
parent | 14027262eefa9299298a7b6a532781e48ca60651 (diff) |
Core/Dungeon Finder: Update "Current group roles" according to people in queue.
Core/Dungeon Finder: Properly update internal lfg group structure at server load
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/DungeonFinding/LFG.h | 2 | ||||
-rwxr-xr-x | src/server/game/DungeonFinding/LFGMgr.cpp | 127 | ||||
-rwxr-xr-x | src/server/game/DungeonFinding/LFGMgr.h | 7 | ||||
-rw-r--r-- | src/server/game/DungeonFinding/LFGQueue.cpp | 188 | ||||
-rw-r--r-- | src/server/game/DungeonFinding/LFGQueue.h | 50 | ||||
-rw-r--r-- | src/server/game/DungeonFinding/LFGScripts.cpp | 16 | ||||
-rwxr-xr-x | src/server/game/Groups/Group.cpp | 3 | ||||
-rwxr-xr-x | src/server/game/Handlers/LFGHandler.cpp | 97 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Opcodes.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Server/WorldSession.h | 1 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_lfg.cpp | 8 |
11 files changed, 330 insertions, 171 deletions
diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h index abdb0ffa511..6ad30547670 100755 --- a/src/server/game/DungeonFinding/LFG.h +++ b/src/server/game/DungeonFinding/LFG.h @@ -49,7 +49,7 @@ enum LfgUpdateType LFG_UPDATETYPE_GROUP_FOUND = 10, LFG_UPDATETYPE_ADDED_TO_QUEUE = 12, LFG_UPDATETYPE_PROPOSAL_BEGIN = 13, - LFG_UPDATETYPE_CLEAR_LOCK_LIST = 14, + LFG_UPDATETYPE_UPDATE_STATUS = 14, LFG_UPDATETYPE_GROUP_MEMBER_OFFLINE = 15, LFG_UPDATETYPE_GROUP_DISBAND_UNK16 = 16, // FIXME: Sometimes at group disband }; diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 735d49b7ee5..61c79e62f89 100755 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -52,8 +52,9 @@ void LFGMgr::_LoadFromDB(Field* fields, uint64 guid) if (!IS_GROUP(guid)) return; - uint32 dungeon = fields[16].GetUInt32(); + SetLeader(guid, MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER)); + uint32 dungeon = fields[16].GetUInt32(); uint8 state = fields[17].GetUInt8(); if (!dungeon || !state) @@ -141,7 +142,7 @@ std::string LFGMgr::GetRolesString(uint8 roles) return rolesstr; } -char const * LFGMgr::GetStateString(LfgState state) +std::string LFGMgr::GetStateString(LfgState state) { int32 entry = LANG_LFG_ERROR; switch (state) @@ -171,8 +172,8 @@ char const * LFGMgr::GetStateString(LfgState state) entry = LANG_LFG_STATE_RAIDBROWSER; break; } - char const * const str = sObjectMgr->GetTrinityStringForDBCLocale(entry); - return str; + + return std::string(sObjectMgr->GetTrinityStringForDBCLocale(entry)); } /// Load rewards for completing dungeons @@ -562,7 +563,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const } else // Remove from queue and rejoin { - LfgQueue& queue = GetQueue(gguid); + LFGQueue& queue = GetQueue(gguid); queue.RemoveFromQueue(gguid); } } @@ -711,7 +712,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const { LfgRolesMap rolesMap; rolesMap[guid] = roles; - LfgQueue& queue = GetQueue(gguid); + LFGQueue& queue = GetQueue(gguid); queue.AddQueueData(guid, time_t(time(NULL)), dungeons, rolesMap); if (!isContinue) @@ -757,7 +758,7 @@ void LFGMgr::LeaveLfg(uint64 guid) case LFG_STATE_QUEUED: if (gguid) { - LfgQueue& queue = GetQueue(gguid); + LFGQueue& queue = GetQueue(gguid); queue.RemoveFromQueue(gguid); RestoreState(gguid, "Leave queue"); const LfgGuidSet& players = GetPlayers(gguid); @@ -770,7 +771,7 @@ void LFGMgr::LeaveLfg(uint64 guid) } else { - LfgQueue& queue = GetQueue(guid); + LFGQueue& queue = GetQueue(guid); queue.RemoveFromQueue(guid); SendLfgUpdatePlayer(guid, LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE)); ClearState(guid, "Leave queue"); @@ -884,7 +885,7 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /* if (roleCheck.state == LFG_ROLECHECK_FINISHED) { SetState(gguid, LFG_STATE_QUEUED); - LfgQueue& queue = GetQueue(gguid); + LFGQueue& queue = GetQueue(gguid); queue.AddQueueData(gguid, time_t(time(NULL)), roleCheck.dungeons, roleCheck.roles); m_RoleChecks.erase(itRoleCheck); } @@ -949,19 +950,19 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true if (it->second == PLAYER_ROLE_NONE) return false; - if (it->second & PLAYER_ROLE_TANK) + if (it->second & PLAYER_ROLE_DAMAGE) { - if (it->second != PLAYER_ROLE_TANK) + if (it->second != PLAYER_ROLE_DAMAGE) { - it->second -= PLAYER_ROLE_TANK; + it->second -= PLAYER_ROLE_DAMAGE; if (CheckGroupRoles(groles, false)) return true; - it->second += PLAYER_ROLE_TANK; + it->second += PLAYER_ROLE_DAMAGE; } - else if (tank == LFG_TANKS_NEEDED) + else if (damage == LFG_DPS_NEEDED) return false; else - tank++; + damage++; } if (it->second & PLAYER_ROLE_HEALER) @@ -979,19 +980,19 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true healer++; } - if (it->second & PLAYER_ROLE_DAMAGE) + if (it->second & PLAYER_ROLE_TANK) { - if (it->second != PLAYER_ROLE_DAMAGE) + if (it->second != PLAYER_ROLE_TANK) { - it->second -= PLAYER_ROLE_DAMAGE; + it->second -= PLAYER_ROLE_TANK; if (CheckGroupRoles(groles, false)) return true; - it->second += PLAYER_ROLE_DAMAGE; + it->second += PLAYER_ROLE_TANK; } - else if (damage == LFG_DPS_NEEDED) + else if (tank == LFG_TANKS_NEEDED) return false; else - damage++; + tank++; } } return (tank + healer + damage) == uint8(groles.size()); @@ -1126,7 +1127,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) proposal.state = LFG_PROPOSAL_SUCCESS; time_t joinTime = time_t(time(NULL)); - LfgQueue& queue = GetQueue(guid); + LFGQueue& queue = GetQueue(guid); LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_GROUP_FOUND); for (LfgProposalPlayerMap::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) { @@ -1260,7 +1261,7 @@ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType t } } - LfgQueue& queue = GetQueue(proposal.players.begin()->first); + LFGQueue& queue = GetQueue(proposal.players.begin()->first); // Remove players/groups from queue for (LfgGuidSet::const_iterator it = toRemove.begin(); it != toRemove.end(); ++it) { @@ -1683,18 +1684,27 @@ uint8 LFGMgr::GetKicksLeft(uint64 guid) void LFGMgr::RestoreState(uint64 guid, char const *debugMsg) { LfgGroupData& data = m_Groups[guid]; - char const * const ps = GetStateString(data.GetState()); - char const * const os = GetStateString(data.GetOldState()); - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RestoreState: Group: [" UI64FMTD "] (%s), State: %s, oldState: %s", guid, debugMsg, ps, os); + if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG)) + { + std::string const& ps = GetStateString(data.GetState()); + std::string const& os = GetStateString(data.GetOldState()); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RestoreState: Group: [" UI64FMTD "] (%s) State: %s, oldState: %s", + guid, debugMsg, ps.c_str(), os.c_str()); + } + data.RestoreState(); } void LFGMgr::ClearState(uint64 guid, char const *debugMsg) { LfgPlayerData& data = m_Players[guid]; - char const * const ps = GetStateString(data.GetState()); - char const * const os = GetStateString(data.GetOldState()); - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::ClearState: Player: [" UI64FMTD "] (%s) State: %s, oldState: %s", guid, debugMsg, ps, os); + if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG)) + { + std::string const& ps = GetStateString(data.GetState()); + std::string const& os = GetStateString(data.GetOldState()); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::ClearState: Player: [" UI64FMTD "] (%s) State: %s, oldState: %s", + guid, debugMsg, ps.c_str(), os.c_str()); + } data.ClearState(); } @@ -1703,19 +1713,27 @@ void LFGMgr::SetState(uint64 guid, LfgState state) if (IS_GROUP(guid)) { LfgGroupData& data = m_Groups[guid]; - char const * const ns = GetStateString(state); - char const * const ps = GetStateString(data.GetState()); - char const * const os = GetStateString(data.GetOldState()); - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::SetState: Group: [" UI64FMTD "] newState: %s, previous: %s, oldState: %s", guid, ns, ps, os); + if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG)) + { + std::string const& ns = GetStateString(state); + std::string const& ps = GetStateString(data.GetState()); + std::string const& os = GetStateString(data.GetOldState()); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::SetState: Group: [" UI64FMTD "] newState: %s, previous: %s, oldState: %s", + guid, ns.c_str(), ps.c_str(), os.c_str()); + } data.SetState(state); } else { LfgPlayerData& data = m_Players[guid]; - char const * const ns = GetStateString(state); - char const * const ps = GetStateString(data.GetState()); - char const * const os = GetStateString(data.GetOldState()); - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::SetState: Player: [" UI64FMTD "] newState: %s, previous: %s, oldState: %s", guid, ns, ps, os); + if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG)) + { + std::string const& ns = GetStateString(state); + std::string const& ps = GetStateString(data.GetState()); + std::string const& os = GetStateString(data.GetOldState()); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::SetState: Player: [" UI64FMTD "] newState: %s, previous: %s, oldState: %s", + guid, ns.c_str(), ps.c_str(), os.c_str()); + } data.SetState(state); } } @@ -1840,43 +1858,43 @@ void LFGMgr::SendLfgRoleChosen(uint64 guid, uint64 pguid, uint8 roles) player->GetSession()->SendLfgRoleChosen(pguid, roles); } -void LFGMgr::SendLfgRoleCheckUpdate(uint64 guid, const LfgRoleCheck& roleCheck) +void LFGMgr::SendLfgRoleCheckUpdate(uint64 guid, LfgRoleCheck const& roleCheck) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendLfgRoleCheckUpdate(roleCheck); } -void LFGMgr::SendLfgUpdatePlayer(uint64 guid, const LfgUpdateData& data) +void LFGMgr::SendLfgUpdatePlayer(uint64 guid, LfgUpdateData const& data) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendLfgUpdatePlayer(data); } -void LFGMgr::SendLfgUpdateParty(uint64 guid, const LfgUpdateData& data) +void LFGMgr::SendLfgUpdateParty(uint64 guid, LfgUpdateData const& data) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendLfgUpdateParty(data); } -void LFGMgr::SendLfgJoinResult(uint64 guid, const LfgJoinResultData& data) +void LFGMgr::SendLfgJoinResult(uint64 guid, LfgJoinResultData const& data) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendLfgJoinResult(data); } -void LFGMgr::SendLfgBootProposalUpdate(uint64 guid, const LfgPlayerBoot& boot) +void LFGMgr::SendLfgBootProposalUpdate(uint64 guid, LfgPlayerBoot const& boot) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendLfgBootProposalUpdate(boot); } -void LFGMgr::SendLfgUpdateProposal(uint64 guid, uint32 proposalId, const LfgProposal& proposal) +void LFGMgr::SendLfgUpdateProposal(uint64 guid, uint32 proposalId, LfgProposal const& proposal) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendLfgUpdateProposal(proposalId, proposal); } -void LFGMgr::SendLfgQueueStatus(uint64 guid, const LfgQueueStatusData& data) +void LFGMgr::SendLfgQueueStatus(uint64 guid, LfgQueueStatusData const& data) { if (Player* player = ObjectAccessor::FindPlayer(guid)) player->GetSession()->SendLfgQueueStatus(data); @@ -1887,7 +1905,7 @@ bool LFGMgr::IsLfgGroup(uint64 guid) return guid && IS_GROUP(guid) && m_Groups[guid].IsLfgGroup(); } -LfgQueue& LFGMgr::GetQueue(uint64 guid) +LFGQueue& LFGMgr::GetQueue(uint64 guid) { uint8 queueId = 0; if (IS_GROUP(guid)) @@ -1934,6 +1952,13 @@ void LFGMgr::SetOptions(uint32 options) m_options = options; } +LfgState LFGMgr::GetLfgStatus(uint64 guid, LfgUpdateData& data) +{ + LfgPlayerData& playerData = m_Players[guid]; + data.dungeons = playerData.GetSelectedDungeons(); + return playerData.GetState(); +} + bool LFGMgr::IsSeasonActive(uint32 dungeonId) { switch (dungeonId) @@ -1968,10 +1993,10 @@ std::string LFGMgr::DumpQueueInfo(bool full) void LFGMgr::SetupGroupMember(uint64 guid, uint64 gguid) { - LfgDungeonSet dungeons; - dungeons.insert(GetDungeon(gguid)); - SetSelectedDungeons(guid, dungeons); - SetState(guid, GetState(gguid)); - SetGroup(guid, gguid); - AddPlayerToGroup(gguid, guid); + LfgDungeonSet dungeons; + dungeons.insert(GetDungeon(gguid)); + SetSelectedDungeons(guid, dungeons); + SetState(guid, GetState(gguid)); + SetGroup(guid, gguid); + AddPlayerToGroup(gguid, guid); } diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index c826d6d7e86..32922f137bf 100755 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -129,7 +129,7 @@ struct LfgProposal; struct LfgProposalPlayer; struct LfgPlayerBoot; -typedef std::map<uint8, LfgQueue> LfgQueueMap; +typedef std::map<uint8, LFGQueue> LfgQueueMap; typedef std::multimap<uint32, LfgReward const*> LfgRewardMap; typedef std::pair<LfgRewardMap::const_iterator, LfgRewardMap::const_iterator> LfgRewardMapBounds; typedef std::map<uint8, LfgDungeonSet> LfgCachedDungeonMap; @@ -361,12 +361,13 @@ class LFGMgr bool isOptionEnabled(uint32 option); uint32 GetOptions(); void SetOptions(uint32 options); + LfgState GetLfgStatus(uint64 guid, LfgUpdateData& data); bool IsSeasonActive(uint32 dungeonId); std::string DumpQueueInfo(bool full = false); static std::string ConcatenateDungeons(LfgDungeonSet const& dungeons); static std::string GetRolesString(uint8 roles); - static char const * GetStateString(LfgState state); + static std::string GetStateString(LfgState state); void LoadLFGDungeons(bool reload = false); LFGDungeonData const* GetLFGDungeon(uint32 id); @@ -388,7 +389,7 @@ class LFGMgr void MakeNewGroup(LfgProposal const& proposal); // Generic - LfgQueue &GetQueue(uint64 guid); + LFGQueue &GetQueue(uint64 guid); LfgDungeonSet const& GetDungeonsByRandom(uint32 randomdungeon); LfgType GetDungeonType(uint32 dungeon); diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp index fadafa4da29..b5775bba167 100644 --- a/src/server/game/DungeonFinding/LFGQueue.cpp +++ b/src/server/game/DungeonFinding/LFGQueue.cpp @@ -51,7 +51,7 @@ std::string ConcatenateGuids(LfgGuidList const& check) return o.str(); } -char const * GetCompatibleString(LfgCompatibility compatibles) +char const* GetCompatibleString(LfgCompatibility compatibles) { switch (compatibles) { @@ -80,81 +80,100 @@ char const * GetCompatibleString(LfgCompatibility compatibles) } } -void LfgQueue::AddToQueue(uint64 guid) +void LFGQueue::AddToQueue(uint64 guid) { LfgQueueDataMap::iterator itQueue = m_QueueDataMap.find(guid); if (itQueue == m_QueueDataMap.end()) { - sLog->outError(LOG_FILTER_LFG, "LfgQueue::AddToQueue: Queue data not found for [" UI64FMTD "]", guid); + sLog->outError(LOG_FILTER_LFG, "LFGQueue::AddToQueue: Queue data not found for [" UI64FMTD "]", guid); return; } AddToNewQueue(guid); } -void LfgQueue::RemoveFromQueue(uint64 guid) +void LFGQueue::RemoveFromQueue(uint64 guid) { RemoveFromNewQueue(guid); RemoveFromCurrentQueue(guid); RemoveFromCompatibles(guid); - RemoveQueueData(guid); + + std::ostringstream o; + o << guid; + std::string sguid = o.str(); + + LfgQueueDataMap::iterator itDelete = m_QueueDataMap.end(); + for (LfgQueueDataMap::iterator itr = m_QueueDataMap.begin(); itr != m_QueueDataMap.end(); ++itr) + if (itr->first != guid) + { + if (std::string::npos != itr->second.bestCompatible.find(sguid)) + { + itr->second.bestCompatible.clear(); + FindBestCompatibleInQueue(itr); + } + } + else + itDelete = itr; + + if (itDelete != m_QueueDataMap.end()) + m_QueueDataMap.erase(itDelete); } -void LfgQueue::AddToNewQueue(uint64 guid) +void LFGQueue::AddToNewQueue(uint64 guid) { m_newToQueue.push_back(guid); } -void LfgQueue::RemoveFromNewQueue(uint64 guid) +void LFGQueue::RemoveFromNewQueue(uint64 guid) { m_newToQueue.remove(guid); } -void LfgQueue::AddToCurrentQueue(uint64 guid) +void LFGQueue::AddToCurrentQueue(uint64 guid) { m_currentQueue.push_back(guid); } -void LfgQueue::RemoveFromCurrentQueue(uint64 guid) +void LFGQueue::RemoveFromCurrentQueue(uint64 guid) { m_currentQueue.remove(guid); } -void LfgQueue::AddQueueData(uint64 guid, time_t joinTime, const LfgDungeonSet &dungeons, const LfgRolesMap &rolesMap) +void LFGQueue::AddQueueData(uint64 guid, time_t joinTime, const LfgDungeonSet &dungeons, const LfgRolesMap &rolesMap) { m_QueueDataMap[guid] = LfgQueueData(joinTime, dungeons, rolesMap); AddToQueue(guid); } -void LfgQueue::RemoveQueueData(uint64 guid) +void LFGQueue::RemoveQueueData(uint64 guid) { LfgQueueDataMap::iterator it = m_QueueDataMap.find(guid); if (it != m_QueueDataMap.end()) m_QueueDataMap.erase(it); } -void LfgQueue::UpdateWaitTimeAvg(int32 waitTime, uint32 dungeonId) +void LFGQueue::UpdateWaitTimeAvg(int32 waitTime, uint32 dungeonId) { LfgWaitTime &wt = m_waitTimesAvg[dungeonId]; uint32 old_number = wt.number++; wt.time = int32((wt.time * old_number + waitTime) / wt.number); } -void LfgQueue::UpdateWaitTimeTank(int32 waitTime, uint32 dungeonId) +void LFGQueue::UpdateWaitTimeTank(int32 waitTime, uint32 dungeonId) { LfgWaitTime &wt = m_waitTimesTank[dungeonId]; uint32 old_number = wt.number++; wt.time = int32((wt.time * old_number + waitTime) / wt.number); } -void LfgQueue::UpdateWaitTimeHealer(int32 waitTime, uint32 dungeonId) +void LFGQueue::UpdateWaitTimeHealer(int32 waitTime, uint32 dungeonId) { LfgWaitTime &wt = m_waitTimesHealer[dungeonId]; uint32 old_number = wt.number++; wt.time = int32((wt.time * old_number + waitTime) / wt.number); } -void LfgQueue::UpdateWaitTimeDps(int32 waitTime, uint32 dungeonId) +void LFGQueue::UpdateWaitTimeDps(int32 waitTime, uint32 dungeonId) { LfgWaitTime &wt = m_waitTimesDps[dungeonId]; uint32 old_number = wt.number++; @@ -166,56 +185,71 @@ void LfgQueue::UpdateWaitTimeDps(int32 waitTime, uint32 dungeonId) @param[in] guid Guid to remove from compatible cache */ -void LfgQueue::RemoveFromCompatibles(uint64 guid) +void LFGQueue::RemoveFromCompatibles(uint64 guid) { std::stringstream out; out << guid; std::string strGuid = out.str(); - sLog->outDebug(LOG_FILTER_LFG, "LfgQueue::RemoveFromCompatibles: Removing [" UI64FMTD "]", guid); + sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::RemoveFromCompatibles: Removing [" UI64FMTD "]", guid); for (LfgCompatibleMap::iterator itNext = m_CompatibleMap.begin(); itNext != m_CompatibleMap.end();) { LfgCompatibleMap::iterator it = itNext++; - if (it->first.find(strGuid) != std::string::npos) // Found, remove it + if (std::string::npos != it->first.find(strGuid)) m_CompatibleMap.erase(it); } } - /** Stores the compatibility of a list of guids @param[in] key String concatenation of guids (| used as separator) @param[in] compatibles type of compatibility */ -void LfgQueue::SetCompatibles(const std::string &key, LfgCompatibility compatibles) +void LFGQueue::SetCompatibles(std::string const& key, LfgCompatibility compatibles) +{ + LfgCompatibilityData& data = m_CompatibleMap[key]; + data.compatibility = compatibles; +} + +void LFGQueue::SetCompatibilityData(std::string const& key, LfgCompatibilityData const& data) { - m_CompatibleMap[key] = compatibles; + m_CompatibleMap[key] = data; } + /** Get the compatibility of a group of guids @param[in] key String concatenation of guids (| used as separator) @return LfgCompatibility type of compatibility */ -LfgCompatibility LfgQueue::GetCompatibles(std::string const& key) +LfgCompatibility LFGQueue::GetCompatibles(std::string const& key) { - LfgCompatibleMap::iterator it = m_CompatibleMap.find(key); - if (it != m_CompatibleMap.end()) - return it->second; + LfgCompatibleMap::iterator itr = m_CompatibleMap.find(key); + if (itr != m_CompatibleMap.end()) + return itr->second.compatibility; return LFG_COMPATIBILITY_PENDING; } -uint8 LfgQueue::FindGroups() +LfgCompatibilityData* LFGQueue::GetCompatibilityData(std::string const& key) +{ + LfgCompatibleMap::iterator itr = m_CompatibleMap.find(key); + if (itr != m_CompatibleMap.end()) + return &(itr->second); + + return NULL; +} + +uint8 LFGQueue::FindGroups() { uint8 proposals = 0; LfgGuidList firstNew; while (!m_newToQueue.empty()) { uint64 frontguid = m_newToQueue.front(); - sLog->outDebug(LOG_FILTER_LFG, "LfgQueue::FindGroups: checking [" UI64FMTD "] newToQueue(%u), currentQueue(%u)", frontguid, uint32(m_newToQueue.size()), uint32(m_currentQueue.size())); + sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::FindGroups: checking [" UI64FMTD "] newToQueue(%u), currentQueue(%u)", frontguid, uint32(m_newToQueue.size()), uint32(m_currentQueue.size())); firstNew.clear(); firstNew.push_back(frontguid); RemoveFromNewQueue(frontguid); @@ -238,7 +272,7 @@ uint8 LfgQueue::FindGroups() @param[in] all List of all other guids in main queue to match against @return LfgCompatibility type of compatibility between groups */ -LfgCompatibility LfgQueue::FindNewGroups(LfgGuidList& check, LfgGuidList& all) +LfgCompatibility LFGQueue::FindNewGroups(LfgGuidList& check, LfgGuidList& all) { std::string strGuids = ConcatenateGuids(check); LfgCompatibility compatibles = GetCompatibles(strGuids); @@ -276,7 +310,7 @@ LfgCompatibility LfgQueue::FindNewGroups(LfgGuidList& check, LfgGuidList& all) @param[in] check List of guids to check compatibilities @return LfgCompatibility type of compatibility */ -LfgCompatibility LfgQueue::CheckCompatibility(LfgGuidList check) +LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check) { std::string strGuids = ConcatenateGuids(check); LfgProposal proposal; @@ -291,10 +325,6 @@ LfgCompatibility LfgQueue::CheckCompatibility(LfgGuidList check) return LFG_INCOMPATIBLES_WRONG_GROUP_SIZE; } - // Player joining alone always compatible - if (check.size() == 1 && IS_PLAYER_GUID(check.front())) - return LFG_COMPATIBLES_WITH_LESS_PLAYERS; - // Check all-but-new compatiblitity if (check.size() > 2) { @@ -344,6 +374,14 @@ LfgCompatibility LfgQueue::CheckCompatibility(LfgGuidList check) if (check.size() == 1 && numPlayers != MAXGROUPSIZE) { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) sigle group. Compatibles", strGuids.c_str()); + LfgQueueDataMap::iterator itQueue = m_QueueDataMap.find(check.front()); + + LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS); + data.roles = itQueue->second.roles; + LFGMgr::CheckGroupRoles(data.roles); + + UpdateBestCompatibleInQueue(itQueue, strGuids, data.roles); + SetCompatibilityData(strGuids, data); return LFG_COMPATIBLES_WITH_LESS_PLAYERS; } @@ -389,7 +427,7 @@ LfgCompatibility LfgQueue::CheckCompatibility(LfgGuidList check) return LFG_INCOMPATIBLES_HAS_IGNORES; } - LfgRolesMap debugRoles = proposalRoles; // DEBUG + LfgRolesMap debugRoles = proposalRoles; if (!LFGMgr::CheckGroupRoles(proposalRoles)) { std::ostringstream o; @@ -434,7 +472,15 @@ LfgCompatibility LfgQueue::CheckCompatibility(LfgGuidList check) if (numPlayers != MAXGROUPSIZE) { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Compatibles but not enough players(%u)", strGuids.c_str(), numPlayers); - SetCompatibles(strGuids, LFG_COMPATIBLES_WITH_LESS_PLAYERS); + LfgQueueDataMap::iterator itQueue = m_QueueDataMap.find(check.front()); + + LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS); + data.roles = proposalRoles; + + for (LfgGuidList::const_iterator itr = check.begin(); itr != check.end(); ++itr) + UpdateBestCompatibleInQueue(m_QueueDataMap.find(*itr), strGuids, data.roles); + + SetCompatibilityData(strGuids, data); return LFG_COMPATIBLES_WITH_LESS_PLAYERS; } @@ -495,11 +541,12 @@ LfgCompatibility LfgQueue::CheckCompatibility(LfgGuidList check) return LFG_COMPATIBLES_MATCH; } -void LfgQueue::UpdateQueueTimers(time_t currTime) +void LFGQueue::UpdateQueueTimers(time_t currTime) { - for (LfgQueueDataMap::const_iterator itQueue = m_QueueDataMap.begin(); itQueue != m_QueueDataMap.end(); ++itQueue) + sLog->outTrace(LOG_FILTER_LFG, "Updating queue timers..."); + for (LfgQueueDataMap::iterator itQueue = m_QueueDataMap.begin(); itQueue != m_QueueDataMap.end(); ++itQueue) { - const LfgQueueData &queueinfo = itQueue->second; + LfgQueueData& queueinfo = itQueue->second; uint32 dungeonId = (*queueinfo.dungeons.begin()); uint32 queuedTime = uint32(currTime - queueinfo.joinTime); uint8 role = PLAYER_ROLE_NONE; @@ -532,6 +579,9 @@ void LfgQueue::UpdateQueueTimers(time_t currTime) break; } + if (queueinfo.bestCompatible.empty()) + FindBestCompatibleInQueue(itQueue); + LfgQueueStatusData queueData(dungeonId, waitTime, wtAvg, wtTank, wtHealer, wtDps, queuedTime, queueinfo.tanks, queueinfo.healers, queueinfo.dps); for (LfgRolesMap::const_iterator itPlayer = queueinfo.roles.begin(); itPlayer != queueinfo.roles.end(); ++itPlayer) { @@ -541,17 +591,12 @@ void LfgQueue::UpdateQueueTimers(time_t currTime) } } -time_t LfgQueue::GetJoinTime(uint64 guid) +time_t LFGQueue::GetJoinTime(uint64 guid) { return m_QueueDataMap[guid].joinTime; } -LfgCompatibleMap const& LfgQueue::GetCompatibleMap() -{ - return m_CompatibleMap; -} - -std::string LfgQueue::DumpQueueInfo() const +std::string LFGQueue::DumpQueueInfo() const { uint32 players = 0; uint32 groups = 0; @@ -577,13 +622,62 @@ std::string LfgQueue::DumpQueueInfo() const return o.str(); } -std::string LfgQueue::DumpCompatibleInfo(bool full /* = false */) const +std::string LFGQueue::DumpCompatibleInfo(bool full /* = false */) const { std::ostringstream o; o << "Compatible Map size: " << m_CompatibleMap.size() << "\n"; if (full) for (LfgCompatibleMap::const_iterator itr = m_CompatibleMap.begin(); itr != m_CompatibleMap.end(); ++itr) - o << "(" << itr->first << "): " << GetCompatibleString(itr->second) << "\n"; + o << "(" << itr->first << "): " << GetCompatibleString(itr->second.compatibility) << "\n"; return o.str(); } + +void LFGQueue::FindBestCompatibleInQueue(LfgQueueDataMap::iterator itrQueue) +{ + sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::FindBestCompatibleInQueue: " UI64FMTD, itrQueue->first); + std::ostringstream o; + o << itrQueue->first; + std::string sguid = o.str(); + + for (LfgCompatibleMap::const_iterator itr = m_CompatibleMap.begin(); itr != m_CompatibleMap.end(); ++itr) + if (itr->second.compatibility == LFG_COMPATIBLES_WITH_LESS_PLAYERS && + std::string::npos != itr->first.find(sguid)) + { + UpdateBestCompatibleInQueue(itrQueue, itr->first, itr->second.roles); + } +} + +void LFGQueue::UpdateBestCompatibleInQueue(LfgQueueDataMap::iterator itrQueue, std::string const& key, LfgRolesMap const& roles) +{ + LfgQueueData& queueData = itrQueue->second; + + uint8 storedSize = queueData.bestCompatible.empty() ? 0 : + std::count(queueData.bestCompatible.begin(), queueData.bestCompatible.end(), '|') + 1; + + uint8 size = std::count(key.begin(), key.end(), '|') + 1; + + sLog->outDebug(LOG_FILTER_LFG, "SPP: GUID: " UI64FMTD ", storedSize = %u, size = %u, BestGroup %s", + itrQueue->first, storedSize, size, queueData.bestCompatible.c_str()); + + if (size <= storedSize) + return; + + sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::UpdateBestCompatibleInQueue: Changed (%s) to (%s) as best compatible group for " UI64FMTD, + queueData.bestCompatible.c_str(), key.c_str(), itrQueue->first); + + queueData.bestCompatible = key; + queueData.tanks = LFG_TANKS_NEEDED; + queueData.healers = LFG_HEALERS_NEEDED; + queueData.dps = LFG_DPS_NEEDED; + for (LfgRolesMap::const_iterator it = roles.begin(); it != roles.end(); ++it) + { + uint8 role = it->second; + if (role & PLAYER_ROLE_TANK) + --queueData.tanks; + else if (role & PLAYER_ROLE_HEALER) + --queueData.healers; + else + --queueData.dps; + } +}
\ No newline at end of file diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h index b67431befce..7c47519d79e 100644 --- a/src/server/game/DungeonFinding/LFGQueue.h +++ b/src/server/game/DungeonFinding/LFGQueue.h @@ -34,6 +34,17 @@ enum LfgCompatibility LFG_COMPATIBLES_MATCH // Must be the last one }; +struct LfgCompatibilityData +{ + LfgCompatibilityData(): compatibility(LFG_COMPATIBILITY_PENDING) { } + LfgCompatibilityData(LfgCompatibility _compatibility): compatibility(_compatibility) { } + LfgCompatibilityData(LfgCompatibility _compatibility, LfgRolesMap const& _roles): + compatibility(_compatibility), roles(_roles) { } + + LfgCompatibility compatibility; + LfgRolesMap roles; +}; + /// Stores player or group queue info struct LfgQueueData { @@ -41,26 +52,10 @@ struct LfgQueueData healers(LFG_HEALERS_NEEDED), dps(LFG_DPS_NEEDED) { } - LfgQueueData(time_t _joinTime, const LfgDungeonSet &_dungeons, const LfgRolesMap &_roles) - { - joinTime = _joinTime; - dungeons = _dungeons; - roles = _roles; - tanks = LFG_TANKS_NEEDED; - healers = LFG_HEALERS_NEEDED; - dps = LFG_DPS_NEEDED; - - for (LfgRolesMap::const_iterator it = roles.begin(); it != roles.end(); ++it) - { - uint8 role = it->second; - if (role & PLAYER_ROLE_TANK) - --tanks; - else if (role & PLAYER_ROLE_HEALER) - --healers; - else - --dps; - } - } + LfgQueueData(time_t _joinTime, const LfgDungeonSet &_dungeons, LfgRolesMap const& _roles): + joinTime(_joinTime), tanks(LFG_TANKS_NEEDED), healers(LFG_HEALERS_NEEDED), + dps(LFG_DPS_NEEDED), dungeons(_dungeons), roles(_roles) + { } time_t joinTime; ///< Player queue join time (to calculate wait times) uint8 tanks; ///< Tanks needed @@ -68,6 +63,7 @@ struct LfgQueueData uint8 dps; ///< Dps needed LfgDungeonSet dungeons; ///< Selected Player/Group Dungeon/s LfgRolesMap roles; ///< Selected Player Role/s + std::string bestCompatible; ///< Best compatible combination of people queued }; struct LfgWaitTime @@ -78,13 +74,13 @@ struct LfgWaitTime }; typedef std::map<uint32, LfgWaitTime> LfgWaitTimesMap; -typedef std::map<std::string, LfgCompatibility> LfgCompatibleMap; +typedef std::map<std::string, LfgCompatibilityData> LfgCompatibleMap; typedef std::map<uint64, LfgQueueData> LfgQueueDataMap; /** Stores all data related to queue */ -class LfgQueue +class LFGQueue { public: @@ -108,10 +104,13 @@ class LfgQueue uint8 FindGroups(); // Just for debugging purposes - LfgCompatibleMap const& GetCompatibleMap(); std::string DumpQueueInfo() const; std::string DumpCompatibleInfo(bool full = false) const; + private: + void SetQueueUpdateData(std::string const& strGuids, LfgRolesMap const& proposalRoles); + LfgRolesMap const& RemoveFromQueueUpdateData(uint64 guid); + void AddToNewQueue(uint64 guid); void AddToCurrentQueue(uint64 guid); void RemoveFromNewQueue(uint64 guid); @@ -121,6 +120,11 @@ class LfgQueue LfgCompatibility GetCompatibles(std::string const& key); void RemoveFromCompatibles(uint64 guid); + void SetCompatibilityData(std::string const& key, LfgCompatibilityData const& compatibles); + LfgCompatibilityData* GetCompatibilityData(std::string const& key); + void FindBestCompatibleInQueue(LfgQueueDataMap::iterator itrQueue); + void UpdateBestCompatibleInQueue(LfgQueueDataMap::iterator itrQueue, std::string const& key, LfgRolesMap const& roles); + LfgCompatibility FindNewGroups(LfgGuidList& check, LfgGuidList& all); LfgCompatibility CheckCompatibility(LfgGuidList check); diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 66b7ccec309..91314e64285 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -66,14 +66,14 @@ void LFGPlayerScript::OnLogin(Player* player) if (Group const* group = player->GetGroup()) { - uint64 gguid2 = group->GetGUID(); - if (gguid != gguid2) - { - sLog->outError(LOG_FILTER_LFG, "%s on group %u but LFG has group %u saved... Fixing.", - player->GetSession()->GetPlayerInfo().c_str(), GUID_LOPART(gguid2), GUID_LOPART(gguid)); + uint64 gguid2 = group->GetGUID(); + if (gguid != gguid2) + { + sLog->outError(LOG_FILTER_LFG, "%s on group %u but LFG has group %u saved... Fixing.", + player->GetSession()->GetPlayerInfo().c_str(), GUID_LOPART(gguid2), GUID_LOPART(gguid)); sLFGMgr->SetupGroupMember(guid, group->GetGUID()); - } - } + } + } sLFGMgr->InitializeLockedDungeons(player); sLFGMgr->SetTeam(player->GetGUID(), player->GetTeam()); @@ -109,7 +109,7 @@ void LFGGroupScript::OnAddMember(Group* group, uint64 guid) LfgState gstate = sLFGMgr->GetState(gguid); LfgState state = sLFGMgr->GetState(guid); sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnAddMember [" UI64FMTD "]: added [" UI64FMTD "] leader " UI64FMTD "] gstate: %u, state: %u", gguid, guid, leader, gstate, state); - LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_CLEAR_LOCK_LIST); + LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_UPDATE_STATUS); for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { if (Player* plrg = itr->getSource()) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index ddc04082d86..45473f792c4 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -222,8 +222,7 @@ void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, SubGroupCounterIncrease(subgroup); - if (isLFGGroup()) - sLFGMgr->SetupGroupMember(member.guid, GetGUID()); + sLFGMgr->SetupGroupMember(member.guid, GetGUID()); } void Group::ConvertToLFG() diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 96d21097e71..4d814365dae 100755 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -63,7 +63,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recv_data) recv_data >> numDungeons; if (!numDungeons) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_JOIN [" UI64FMTD "] no dungeons selected", GetPlayer()->GetGUID()); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_JOIN [" UI64FMTD "] no dungeons selected", GetPlayer()->GetGUID()); recv_data.rfinish(); return; } @@ -79,7 +79,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recv_data) std::string comment; recv_data >> comment; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_JOIN [" UI64FMTD "] roles: %u, Dungeons: %u, Comment: %s", GetPlayer()->GetGUID(), roles, uint8(newDungeons.size()), comment.c_str()); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_JOIN [" UI64FMTD "] roles: %u, Dungeons: %u, Comment: %s", GetPlayer()->GetGUID(), roles, uint8(newDungeons.size()), comment.c_str()); sLFGMgr->JoinLfg(GetPlayer(), uint8(roles), newDungeons, comment); } @@ -89,7 +89,7 @@ void WorldSession::HandleLfgLeaveOpcode(WorldPacket& /*recv_data*/) uint64 guid = GetPlayer()->GetGUID(); uint64 gguid = grp ? grp->GetGUID() : guid; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_LEAVE [" UI64FMTD "] in group: %u", guid, grp ? 1 : 0); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_LEAVE [" UI64FMTD "] in group: %u", guid, grp ? 1 : 0); // Check cheating - only leader can leave the queue if (!grp || grp->GetLeaderGUID() == GetPlayer()->GetGUID()) @@ -103,7 +103,7 @@ void WorldSession::HandleLfgProposalResultOpcode(WorldPacket& recv_data) recv_data >> lfgGroupID; recv_data >> accept; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_PROPOSAL_RESULT [" UI64FMTD "] proposal: %u accept: %u", GetPlayer()->GetGUID(), lfgGroupID, accept ? 1 : 0); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_PROPOSAL_RESULT [" UI64FMTD "] proposal: %u accept: %u", GetPlayer()->GetGUID(), lfgGroupID, accept ? 1 : 0); sLFGMgr->UpdateProposal(lfgGroupID, GetPlayer()->GetGUID(), accept); } @@ -115,11 +115,11 @@ void WorldSession::HandleLfgSetRolesOpcode(WorldPacket& recv_data) Group* grp = GetPlayer()->GetGroup(); if (!grp) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_SET_ROLES [" UI64FMTD "] Not in group", guid); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_SET_ROLES [" UI64FMTD "] Not in group", guid); return; } uint64 gguid = grp->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_SET_ROLES: Group [" UI64FMTD "], Player [" UI64FMTD "], Roles: %u", gguid, guid, roles); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_SET_ROLES: Group [" UI64FMTD "], Player [" UI64FMTD "], Roles: %u", gguid, guid, roles); sLFGMgr->UpdateRoleCheck(gguid, guid, roles); } @@ -128,7 +128,7 @@ void WorldSession::HandleLfgSetCommentOpcode(WorldPacket& recv_data) std::string comment; recv_data >> comment; uint64 guid = GetPlayer()->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_SET_COMMENT [" UI64FMTD "] comment: %s", guid, comment.c_str()); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_SET_COMMENT [" UI64FMTD "] comment: %s", guid, comment.c_str()); sLFGMgr->SetComment(guid, comment); } @@ -139,7 +139,7 @@ void WorldSession::HandleLfgSetBootVoteOpcode(WorldPacket& recv_data) recv_data >> agree; uint64 guid = GetPlayer()->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_SET_BOOT_VOTE [" UI64FMTD "] agree: %u", guid, agree ? 1 : 0); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_SET_BOOT_VOTE [" UI64FMTD "] agree: %u", guid, agree ? 1 : 0); sLFGMgr->UpdateBoot(guid, agree); } @@ -148,14 +148,14 @@ void WorldSession::HandleLfgTeleportOpcode(WorldPacket& recv_data) bool out; recv_data >> out; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_TELEPORT [" UI64FMTD "] out: %u", GetPlayer()->GetGUID(), out ? 1 : 0); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_TELEPORT [" UI64FMTD "] out: %u", GetPlayer()->GetGUID(), out ? 1 : 0); sLFGMgr->TeleportPlayer(GetPlayer(), out, true); } void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data*/) { uint64 guid = GetPlayer()->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_PLAYER_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_PLAYER_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); // Get Random dungeons that can be done at a certain level and expansion LfgDungeonSet randomDungeons; @@ -176,7 +176,7 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data uint32 rsize = uint32(randomDungeons.size()); uint32 lsize = uint32(lock.size()); - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PLAYER_INFO [" UI64FMTD "]", guid); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PLAYER_INFO [" UI64FMTD "]", guid); WorldPacket data(SMSG_LFG_PLAYER_INFO, 1 + rsize * (4 + 1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4) + 4 + lsize * (1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4)); data << uint8(randomDungeons.size()); // Random Dungeon count @@ -234,7 +234,7 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recv_data*/) { uint64 guid = GetPlayer()->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_PARTY_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_PARTY_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); Group* grp = GetPlayer()->GetGroup(); if (!grp) @@ -259,7 +259,7 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recv_data for (LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) size += 8 + 4 + uint32(it->second.size()) * (4 + 4); - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PARTY_INFO [" UI64FMTD "]", guid); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PARTY_INFO [" UI64FMTD "]", guid); WorldPacket data(SMSG_LFG_PARTY_INFO, 1 + size); BuildPartyLockDungeonBlock(data, lockMap); SendPacket(&data); @@ -269,7 +269,7 @@ void WorldSession::HandleLfrJoinOpcode(WorldPacket& recv_data) { uint32 entry; // Raid id to search recv_data >> entry; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_LFR_JOIN [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), entry); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_LFR_JOIN [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), entry); //SendLfrUpdateListOpcode(entry); } @@ -277,7 +277,7 @@ void WorldSession::HandleLfrLeaveOpcode(WorldPacket& recv_data) { uint32 dungeonId; // Raid id queue to leave recv_data >> dungeonId; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_LFR_LEAVE [" UI64FMTD "] dungeonId: %u", GetPlayer()->GetGUID(), dungeonId); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_LFR_LEAVE [" UI64FMTD "] dungeonId: %u", GetPlayer()->GetGUID(), dungeonId); //sLFGMgr->LeaveLfr(GetPlayer(), dungeonId); } @@ -295,7 +295,9 @@ void WorldSession::SendLfgUpdatePlayer(const LfgUpdateData& updateData) queued = true; extrainfo = true; break; - //case LFG_UPDATETYPE_CLEAR_LOCK_LIST: // TODO: Sometimes has extrainfo - Check ocurrences... + case LFG_UPDATETYPE_UPDATE_STATUS: + extrainfo = size > 0; + break; case LFG_UPDATETYPE_PROPOSAL_BEGIN: extrainfo = true; break; @@ -303,7 +305,7 @@ void WorldSession::SendLfgUpdatePlayer(const LfgUpdateData& updateData) break; } - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_UPDATE_PLAYER [" UI64FMTD "] updatetype: %u", guid, updateData.updateType); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_UPDATE_PLAYER [" UI64FMTD "] updatetype: %u", guid, updateData.updateType); WorldPacket data(SMSG_LFG_UPDATE_PLAYER, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + size * 4 + updateData.comment.length())); data << uint8(updateData.updateType); // Lfg Update type data << uint8(extrainfo); // Extra info @@ -340,8 +342,9 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) join = true; queued = true; break; - case LFG_UPDATETYPE_CLEAR_LOCK_LIST: - // join = true; // TODO: Sometimes queued and extrainfo - Check ocurrences... + case LFG_UPDATETYPE_UPDATE_STATUS: + extrainfo = size > 0; + join = true; queued = true; break; case LFG_UPDATETYPE_PROPOSAL_BEGIN: @@ -352,7 +355,7 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) break; } - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_UPDATE_PARTY [" UI64FMTD "] updatetype: %u", guid, updateData.updateType); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_UPDATE_PARTY [" UI64FMTD "] updatetype: %u", guid, updateData.updateType); WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + size * 4 + updateData.comment.length())); data << uint8(updateData.updateType); // Lfg Update type data << uint8(extrainfo); // Extra info @@ -376,7 +379,7 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData) void WorldSession::SendLfgRoleChosen(uint64 guid, uint8 roles) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_ROLE_CHOSEN [" UI64FMTD "] guid: [" UI64FMTD "] roles: %u", GetPlayer()->GetGUID(), guid, roles); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_ROLE_CHOSEN [" UI64FMTD "] guid: [" UI64FMTD "] roles: %u", GetPlayer()->GetGUID(), guid, roles); WorldPacket data(SMSG_LFG_ROLE_CHOSEN, 8 + 1 + 4); data << uint64(guid); // Guid @@ -393,7 +396,7 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) else dungeons = roleCheck.dungeons; - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_ROLE_CHECK_UPDATE [" UI64FMTD "]", GetPlayer()->GetGUID()); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_ROLE_CHECK_UPDATE [" UI64FMTD "]", GetPlayer()->GetGUID()); WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1)); data << uint32(roleCheck.state); // Check result @@ -443,7 +446,7 @@ void WorldSession::SendLfgJoinResult(const LfgJoinResultData& joinData) for (LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it) size += 8 + 4 + uint32(it->second.size()) * (4 + 4); - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_JOIN_RESULT [" UI64FMTD "] checkResult: %u checkValue: %u", GetPlayer()->GetGUID(), joinData.result, joinData.state); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_JOIN_RESULT [" UI64FMTD "] checkResult: %u checkValue: %u", GetPlayer()->GetGUID(), joinData.result, joinData.state); WorldPacket data(SMSG_LFG_JOIN_RESULT, 4 + 4 + size); data << uint32(joinData.result); // Check Result data << uint32(joinData.state); // Check Value @@ -454,7 +457,7 @@ void WorldSession::SendLfgJoinResult(const LfgJoinResultData& joinData) void WorldSession::SendLfgQueueStatus(const LfgQueueStatusData& queueData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_QUEUE_STATUS [" UI64FMTD "] dungeon: %u - waitTime: %d - avgWaitTime: %d - waitTimeTanks: %d - waitTimeHealer: %d - waitTimeDps: %d - queuedTime: %u - tanks: %u - healers: %u - dps: %u", + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_QUEUE_STATUS [" UI64FMTD "] dungeon: %u - waitTime: %d - avgWaitTime: %d - waitTimeTanks: %d - waitTimeHealer: %d - waitTimeDps: %d - queuedTime: %u - tanks: %u - healers: %u - dps: %u", GetPlayer()->GetGUID(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, queueData.waitTimeTank, queueData.waitTimeHealer, queueData.waitTimeDps, queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps); WorldPacket data(SMSG_LFG_QUEUE_STATUS, 4 + 4 + 4 + 4 + 4 +4 + 1 + 1 + 1 + 4); @@ -478,7 +481,7 @@ void WorldSession::SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntr uint8 itemNum = uint8(quest ? quest->GetRewItemsCount() : 0); - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PLAYER_REWARD [" UI64FMTD "] rdungeonEntry: %u - sdungeonEntry: %u - done: %u", GetPlayer()->GetGUID(), rdungeonEntry, sdungeonEntry, done); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PLAYER_REWARD [" UI64FMTD "] rdungeonEntry: %u - sdungeonEntry: %u - done: %u", GetPlayer()->GetGUID(), rdungeonEntry, sdungeonEntry, done); WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4)); data << uint32(rdungeonEntry); // Random Dungeon Finished data << uint32(sdungeonEntry); // Dungeon Finished @@ -519,7 +522,7 @@ void WorldSession::SendLfgBootProposalUpdate(const LfgPlayerBoot& boot) ++agreeNum; } } - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_BOOT_PROPOSAL_UPDATE [" UI64FMTD "] inProgress: %u - didVote: %u - agree: %u - victim: [" UI64FMTD "] votes: %u - agrees: %u - left: %u - needed: %u - reason %s", + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_BOOT_PROPOSAL_UPDATE [" UI64FMTD "] inProgress: %u - didVote: %u - agree: %u - victim: [" UI64FMTD "] votes: %u - agrees: %u - left: %u - needed: %u - reason %s", guid, uint8(boot.inProgress), uint8(playerVote != LFG_ANSWER_PENDING), uint8(playerVote == LFG_ANSWER_AGREE), boot.victim, votesNum, agreeNum, secsleft, LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str()); WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length()); data << uint8(boot.inProgress); // Vote in progress @@ -541,7 +544,7 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal const& p bool silent = !proposal.isNew && gguid == proposal.group; uint32 dungeonEntry = proposal.dungeonId; - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PROPOSAL_UPDATE [" UI64FMTD "] state: %u", guid, proposal.state); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PROPOSAL_UPDATE [" UI64FMTD "] state: %u", guid, proposal.state); WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1)); // show random dungeon if player selected random dungeon and it's not lfg group @@ -585,7 +588,7 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal const& p void WorldSession::SendLfgLfrList(bool update) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_LFR_LIST [" UI64FMTD "] update: %u", GetPlayer()->GetGUID(), update ? 1 : 0); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_LFR_LIST [" UI64FMTD "] update: %u", GetPlayer()->GetGUID(), update ? 1 : 0); WorldPacket data(SMSG_LFG_UPDATE_SEARCH, 1); data << uint8(update); // In Lfg Queue? SendPacket(&data); @@ -593,14 +596,14 @@ void WorldSession::SendLfgLfrList(bool update) void WorldSession::SendLfgDisabled() { - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_DISABLED [" UI64FMTD "]", GetPlayer()->GetGUID()); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_DISABLED [" UI64FMTD "]", GetPlayer()->GetGUID()); WorldPacket data(SMSG_LFG_DISABLED, 0); SendPacket(&data); } void WorldSession::SendLfgOfferContinue(uint32 dungeonEntry) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_OFFER_CONTINUE [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), dungeonEntry); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_OFFER_CONTINUE [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), dungeonEntry); WorldPacket data(SMSG_LFG_OFFER_CONTINUE, 4); data << uint32(dungeonEntry); SendPacket(&data); @@ -608,12 +611,44 @@ void WorldSession::SendLfgOfferContinue(uint32 dungeonEntry) void WorldSession::SendLfgTeleportError(uint8 err) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_TELEPORT_DENIED [" UI64FMTD "] reason: %u", GetPlayer()->GetGUID(), err); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_TELEPORT_DENIED [" UI64FMTD "] reason: %u", GetPlayer()->GetGUID(), err); WorldPacket data(SMSG_LFG_TELEPORT_DENIED, 4); data << uint32(err); // Error SendPacket(&data); } +void WorldSession::HandleLfgGetStatus(WorldPacket& /*recv_data*/) +{ + uint64 guid = GetPlayer()->GetGUID(); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_GET_STATUS [" UI64FMTD "]", guid); + + LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_UPDATE_STATUS); + LfgState state = sLFGMgr->GetLfgStatus(guid, updateData); + + if (state == LFG_STATE_NONE || updateData.dungeons.empty()) + { + SendLfgUpdatePlayer(updateData); + SendLfgUpdateParty(updateData); + return; + } + + if (state != LFG_STATE_QUEUED) + return; + + if (GetPlayer()->GetGroup()) + { + SendLfgUpdateParty(updateData); + updateData.dungeons.clear(); + SendLfgUpdatePlayer(updateData); + } + else + { + SendLfgUpdatePlayer(updateData); + updateData.dungeons.clear(); + SendLfgUpdateParty(updateData); + } +} + /* void WorldSession::SendLfrUpdateListOpcode(uint32 dungeonEntry) { diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index af2ff2c6d86..9078f6720a0 100755 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -688,7 +688,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x293*/ { "SMSG_LFG_OFFER_CONTINUE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x294*/ { "CMSG_TEST_DROP_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x295*/ { "SMSG_TEST_DROP_RATE_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x296*/ { "CMSG_LFG_GET_STATUS", STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x296*/ { "CMSG_LFG_GET_STATUS", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleLfgGetStatus }, /*0x297*/ { "SMSG_SHOW_MAILBOX", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x298*/ { "SMSG_RESET_RANGED_COMBAT_TIMER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index e91ef9530c2..caab00d8fc8 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -820,6 +820,7 @@ class WorldSession void HandleLfgTeleportOpcode(WorldPacket& recv_data); void HandleLfrJoinOpcode(WorldPacket& recv_data); void HandleLfrLeaveOpcode(WorldPacket& recv_data); + void HandleLfgGetStatus(WorldPacket& recv_data); void SendLfgUpdatePlayer(const LfgUpdateData& updateData); void SendLfgUpdateParty(const LfgUpdateData& updateData); diff --git a/src/server/scripts/Commands/cs_lfg.cpp b/src/server/scripts/Commands/cs_lfg.cpp index 2556d45a72f..5f1ed59176f 100644 --- a/src/server/scripts/Commands/cs_lfg.cpp +++ b/src/server/scripts/Commands/cs_lfg.cpp @@ -28,9 +28,9 @@ void GetPlayerInfo(ChatHandler* handler, Player* player) uint64 guid = player->GetGUID(); LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(guid); - char const * const state = sLFGMgr->GetStateString(sLFGMgr->GetState(guid)); + std::string const& state = sLFGMgr->GetStateString(sLFGMgr->GetState(guid)); handler->PSendSysMessage(LANG_LFG_PLAYER_INFO, player->GetName().c_str(), - state, uint8(dungeons.size()), sLFGMgr->ConcatenateDungeons(dungeons).c_str(), + state.c_str(), uint8(dungeons.size()), sLFGMgr->ConcatenateDungeons(dungeons).c_str(), sLFGMgr->GetRolesString(sLFGMgr->GetRoles(guid)).c_str(), sLFGMgr->GetComment(guid).c_str()); } @@ -85,9 +85,9 @@ public: } uint64 guid = grp->GetGUID(); - char const * const state = sLFGMgr->GetStateString(sLFGMgr->GetState(guid)); + std::string const& state = sLFGMgr->GetStateString(sLFGMgr->GetState(guid)); handler->PSendSysMessage(LANG_LFG_GROUP_INFO, grp->isLFGGroup(), - state, sLFGMgr->GetDungeon(guid)); + state.c_str(), sLFGMgr->GetDungeon(guid)); for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) GetPlayerInfo(handler, itr->getSource()); |