diff options
| -rwxr-xr-x | src/server/game/DungeonFinding/LFG.h | 19 | ||||
| -rw-r--r-- | src/server/game/DungeonFinding/LFGGroupData.cpp | 82 | ||||
| -rw-r--r-- | src/server/game/DungeonFinding/LFGGroupData.h | 67 | ||||
| -rwxr-xr-x | src/server/game/DungeonFinding/LFGMgr.cpp | 326 | ||||
| -rwxr-xr-x | src/server/game/DungeonFinding/LFGMgr.h | 31 | ||||
| -rw-r--r-- | src/server/game/DungeonFinding/LFGPlayerData.cpp | 97 | ||||
| -rw-r--r-- | src/server/game/DungeonFinding/LFGPlayerData.h | 63 | ||||
| -rw-r--r-- | src/server/game/DungeonFinding/LFGScripts.cpp | 25 | ||||
| -rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 17 | ||||
| -rwxr-xr-x | src/server/game/Entities/Player/Player.h | 32 | ||||
| -rwxr-xr-x | src/server/game/Groups/Group.cpp | 49 | ||||
| -rwxr-xr-x | src/server/game/Groups/Group.h | 17 | ||||
| -rwxr-xr-x | src/server/game/Miscellaneous/SharedDefines.h | 12 | ||||
| -rwxr-xr-x | src/server/game/Server/Protocol/Handlers/LFGHandler.cpp | 33 | ||||
| -rwxr-xr-x | src/server/game/Server/WorldSession.h | 4 |
15 files changed, 615 insertions, 259 deletions
diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h index cc5bb0e481b..31c40b2bcfe 100755 --- a/src/server/game/DungeonFinding/LFG.h +++ b/src/server/game/DungeonFinding/LFG.h @@ -19,7 +19,6 @@ #define _LFG_H #include "Common.h" -#include "SharedDefines.h" enum LfgRoles { @@ -49,15 +48,19 @@ enum LfgUpdateType }; typedef std::set<uint32> LfgDungeonSet; +typedef std::set<LfgLockStatus*> LfgLockStatusSet; +typedef std::map<uint64, LfgLockStatusSet*> LfgLockStatusMap; -struct LookingForGroup +enum LfgState { - LookingForGroup(): roles(0), state(LFG_STATE_NONE), oldState(LFG_STATE_NONE) {} - uint8 roles; - LfgState state; - LfgState oldState; - LfgDungeonSet applyDungeons; // Dungeons the player have applied for - std::string comment; + LFG_STATE_NONE, // Not using LFG / LFR + LFG_STATE_ROLECHECK, // Rolecheck active + LFG_STATE_QUEUED, // Queued + LFG_STATE_PROPOSAL, // Proposal active + LFG_STATE_BOOT, // Vote kick active + LFG_STATE_DUNGEON, // In LFG Group, in a Dungeon + LFG_STATE_FINISHED_DUNGEON, // In LFG Group, in a finished Dungeon + LFG_STATE_RAIDBROWSER, // Using Raid finder }; #endif diff --git a/src/server/game/DungeonFinding/LFGGroupData.cpp b/src/server/game/DungeonFinding/LFGGroupData.cpp new file mode 100644 index 00000000000..2fa9865442d --- /dev/null +++ b/src/server/game/DungeonFinding/LFGGroupData.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "LFG.h" +#include "LFGGroupData.h" + +LfgGroupData::LfgGroupData(): +m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), m_Dungeon(0), +m_VotesNeeded(0), m_KicksLeft(LFG_GROUP_MAX_KICKS) +{ +} + +LfgGroupData::~LfgGroupData() +{ +} + +void LfgGroupData::SetState(LfgState state) +{ + switch(state) + { + case LFG_STATE_NONE: + case LFG_STATE_DUNGEON: + case LFG_STATE_FINISHED_DUNGEON: + m_OldState = state; + // No break on purpose + default: + m_State = state; + } +} + +void LfgGroupData::RestoreState() +{ + m_State = m_OldState; +} + +void LfgGroupData::SetDungeon(uint32 dungeon) +{ + m_Dungeon = dungeon; +} + +void LfgGroupData::DecreaseKicksLeft() +{ + if (m_KicksLeft) + --m_KicksLeft; +} + +LfgState LfgGroupData::GetState() const +{ + return m_State; +} + +uint32 LfgGroupData::GetDungeon(bool asId /* = true */) const +{ + if (asId) + return (m_Dungeon & 0x00FFFFFF); + else + return m_Dungeon; +} + +uint8 LfgGroupData::GetVotesNeeded() const +{ + return m_VotesNeeded; +} + +uint8 LfgGroupData::GetKicksLeft() const +{ + return m_KicksLeft; +} diff --git a/src/server/game/DungeonFinding/LFGGroupData.h b/src/server/game/DungeonFinding/LFGGroupData.h new file mode 100644 index 00000000000..4259ad2253e --- /dev/null +++ b/src/server/game/DungeonFinding/LFGGroupData.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _LFGGROUPDATA_H +#define _LFGGROUPDATA_H + +#include "Common.h" +#include "LFG.h" + +enum LfgGroupEnum +{ + LFG_GROUP_MAX_KICKS = 3, + LFG_GROUP_KICK_VOTES_NEEDED = 3, +}; + +/** + Stores all lfg data needed about a group. +*/ +class LfgGroupData +{ + public: + LfgGroupData(); + ~LfgGroupData(); + + // General + void SetState(LfgState state); + void RestoreState(); + // Dungeon + void SetDungeon(uint32 dungeon); + // VoteKick + void SetVotesNeeded(uint8 votes); + void DecreaseKicksLeft(); + + // General + LfgState GetState() const; + // Dungeon + uint32 GetDungeon(bool asId = true) const; + // VoteKick + uint8 GetVotesNeeded() const; + uint8 GetKicksLeft() const; + + private: + // General + LfgState m_State; ///< State if group in LFG + LfgState m_OldState; ///< Old State + // Dungeon + uint32 m_Dungeon; ///< Dungeon entry + // Vote Kick + uint8 m_VotesNeeded; ///< Votes need to kick success + uint8 m_KicksLeft; ///< Number of kicks left +}; + +#endif diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index ee48fa2feb5..2b14f147d2c 100755 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -25,6 +25,8 @@ #include "SocialMgr.h" #include "LFGMgr.h" #include "LFGScripts.h" +#include "LFGGroupData.h" +#include "LFGPlayerData.h" #include "Group.h" #include "Player.h" @@ -218,14 +220,17 @@ void LFGMgr::Update(uint32 diff) pRoleCheck->state = LFG_ROLECHECK_MISSING_ROLE; for (LfgRolesMap::const_iterator itRoles = pRoleCheck->roles.begin(); itRoles != pRoleCheck->roles.end(); ++itRoles) - if (Player* plr = sObjectMgr.GetPlayer(itRoles->first)) + { + uint64 guid = itRoles->first; + ClearState(guid); + if (Player* plr = sObjectMgr.GetPlayer(guid)) { plr->GetSession()->SendLfgRoleCheckUpdate(pRoleCheck); - plr->ClearLfgState(); - + if (itRoles->first == pRoleCheck->leader) plr->GetSession()->SendLfgJoinResult(joinData); } + } delete pRoleCheck; m_RoleChecks.erase(itRoleCheck); } @@ -280,13 +285,15 @@ void LFGMgr::Update(uint32 diff) for (LfgProposalPlayerMap::const_iterator itPlayers = pProposal->players.begin(); itPlayers != pProposal->players.end(); ++itPlayers) { guid = itPlayers->first; + SetState(guid, LFG_STATE_PROPOSAL); if (Player* plr = sObjectMgr.GetPlayer(itPlayers->first)) { - plr->SetLfgState(LFG_STATE_PROPOSAL); - LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, plr->GetLfgDungeons(), plr->GetLfgComment()); - if (plr->GetGroup()) - { - plr->GetGroup()->SetLfgState(LFG_STATE_PROPOSAL); + Group *grp = plr->GetGroup(); + LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, &GetSelectedDungeons(guid), GetComment(guid)); + if (grp) + { + uint64 gguid = grp->GetGUID(); + SetState(gguid, LFG_STATE_PROPOSAL); plr->GetSession()->SendLfgUpdateParty(updateData); } else @@ -433,30 +440,26 @@ void LFGMgr::Join(Player* plr, uint8 roles, LfgDungeonSet& dungeons, std::string LfgJoinResultData joinData; PlayerSet players; uint32 rDungeonId = 0; - bool isContinue = grp && grp->isLFGGroup() && grp->GetLfgState() != LFG_STATE_FINISHED_DUNGEON; + bool isContinue = grp && grp->isLFGGroup() && GetState(gguid) != LFG_STATE_FINISHED_DUNGEON; // Do not allow to change dungeon in the middle of a current dungeon if (isContinue) { dungeons.clear(); - dungeons.insert(grp->GetLfgDungeonEntry()); + dungeons.insert(GetDungeon(gguid)); } // Already in queue? LfgQueueInfoMap::iterator itQueue = m_QueueInfoMap.find(gguid); if (itQueue != m_QueueInfoMap.end()) { - bool sameDungeons = true; - for (LfgDungeonSet::const_iterator it = plr->GetLfgDungeons()->begin(); it != plr->GetLfgDungeons()->end() && sameDungeons; ++it) - if (dungeons.find(*it) == dungeons.end()) - sameDungeons = false; - - if (sameDungeons) // Joining the same dungeons -- Send OK - { + LfgDungeonSet playerDungeons = GetSelectedDungeons(guid); + if (playerDungeons == dungeons) // Joining the same dungeons -- Send OK + { + LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, &dungeons, comment); plr->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); @@ -579,8 +582,7 @@ void LFGMgr::Join(Player* plr, uint8 roles, LfgDungeonSet& dungeons, std::string return; } - plr->SetLfgComment(comment); - plr->SetLfgRoles(roles); + SetComment(guid, comment); if (grp) // Begin rolecheck { @@ -599,21 +601,18 @@ void LFGMgr::Join(Player* plr, uint8 roles, LfgDungeonSet& dungeons, std::string dungeons.insert(rDungeonId); } - grp->SetLfgState(LFG_STATE_ROLECHECK); + SetState(gguid, LFG_STATE_ROLECHECK); // Send update to player LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_JOIN_PROPOSAL, &dungeons, comment); for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { if (Player* plrg = itr->getSource()) { + uint64 pguid = plrg->GetGUID(); plrg->GetSession()->SendLfgUpdateParty(updateData); - plrg->SetLfgState(LFG_STATE_ROLECHECK); + SetState(pguid, LFG_STATE_ROLECHECK); if (!isContinue) - { - plrg->GetLfgDungeons()->clear(); - for (LfgDungeonSet::const_iterator it = dungeons.begin(); it != dungeons.end(); ++it) - plrg->GetLfgDungeons()->insert(*it); - } + SetSelectedDungeons(pguid, dungeons); pRoleCheck->roles[plrg->GetGUID()] = 0; } } @@ -623,18 +622,18 @@ void LFGMgr::Join(Player* plr, uint8 roles, LfgDungeonSet& dungeons, std::string else // Add player to queue { // Send update to player - LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_JOIN_PROPOSAL, &dungeons, comment); plr->GetSession()->SendLfgJoinResult(joinData); - plr->GetSession()->SendLfgUpdatePlayer(updateData); - plr->SetLfgState(LFG_STATE_QUEUED); + plr->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_JOIN_PROPOSAL, &dungeons, comment)); + SetState(gguid, LFG_STATE_QUEUED); + SetRoles(guid, roles); if (!isContinue) { - plr->GetLfgDungeons()->clear(); if (rDungeonId) - plr->GetLfgDungeons()->insert(rDungeonId); - else - for (LfgDungeonSet::const_iterator it = dungeons.begin(); it != dungeons.end(); ++it) - plr->GetLfgDungeons()->insert(*it); + { + dungeons.clear(); + dungeons.insert(rDungeonId); + } + SetSelectedDungeons(guid, dungeons); } // Queue player @@ -667,19 +666,8 @@ void LFGMgr::Leave(Player* plr, Group* grp /* = NULL*/) if (!plr && !grp) return; - uint64 guid = 0; - LfgState state; - - if (grp) - { - guid = grp->GetGUID(); - state = grp->GetLfgState(); - } - else - { - guid = plr->GetGUID(); - state = plr->GetLfgState(); - } + uint64 guid = grp ? grp->GetGUID() : plr->GetGUID(); + LfgState state = GetState(guid); sLog.outDebug("LFGMgr::Leave: [" UI64FMTD "]", guid); switch(state) @@ -690,18 +678,19 @@ void LFGMgr::Leave(Player* plr, Group* grp /* = NULL*/) LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE); if (grp) { - grp->RestoreLfgState(); + RestoreState(guid); for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) if (Player* plrg = itr->getSource()) { plrg->GetSession()->SendLfgUpdateParty(updateData); - plrg->ClearLfgState(); + uint64 pguid = plrg->GetGUID(); + ClearState(pguid); } } else { plr->GetSession()->SendLfgUpdatePlayer(updateData); - plr->ClearLfgState(); + ClearState(guid); } } break; @@ -743,9 +732,12 @@ void LFGMgr::Leave(Player* plr, Group* grp /* = NULL*/) */ void LFGMgr::OfferContinue(Group* grp) { - Player* leader = grp ? sObjectMgr.GetPlayer(grp->GetLeaderGUID()) : NULL; - if (leader) - leader->GetSession()->SendLfgOfferContinue(grp->GetLfgDungeonEntry(false)); + if (grp) + { + uint64 gguid = grp->GetGUID(); + if (Player* leader = sObjectMgr.GetPlayer(grp->GetLeaderGUID())) + leader->GetSession()->SendLfgOfferContinue(GetDungeon(gguid, false)); + } } /** @@ -889,7 +881,7 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal) { Player* plr = sObjectMgr.GetPlayer(it->first); if (!plr) - sLog.outDebug("LFGMgr::CheckCompatibility: (%s) Warning! %u offline! Marking as not compatibles!", strGuids.c_str(), it->first); + sLog.outDebug("LFGMgr::CheckCompatibility: (%s) Warning! [" UI64FMTD "] offline! Marking as not compatibles!", strGuids.c_str(), it->first); else { for (PlayerSet::const_iterator itPlayer = players.begin(); itPlayer != players.end() && plr; ++itPlayer) @@ -1016,14 +1008,16 @@ void LFGMgr::UpdateRoleCheck(Group* grp, Player* plr /* = NULL*/, bool newRoleCh if (itRoleCheck == m_RoleChecks.end()) return; + uint64 guid = plr ? plr->GetGUID() : 0; + uint8 roles = guid ? GetRoles(guid) : 0; LfgRoleCheck* pRoleCheck = itRoleCheck->second; - if (!plr) + if (!guid) pRoleCheck->state = LFG_ROLECHECK_ABORTED; - else if (plr->GetLfgRoles() < ROLE_TANK) // Player selected no role. + else if (roles < ROLE_TANK) // Player selected no role. pRoleCheck->state = LFG_ROLECHECK_NO_ROLE; else { - pRoleCheck->roles[plr->GetGUID()] = plr->GetLfgRoles(); + pRoleCheck->roles[guid] = roles; // Check if all players have selected a role LfgRolesMap::const_iterator itRoles = pRoleCheck->roles.begin(); @@ -1045,19 +1039,17 @@ void LFGMgr::UpdateRoleCheck(Group* grp, Player* plr /* = NULL*/, bool newRoleCh else dungeons = pRoleCheck->dungeons; - LfgJoinResultData joinData; - joinData.result = LFG_JOIN_FAILED; - joinData.state = pRoleCheck->state; + LfgJoinResultData joinData = LfgJoinResultData(LFG_JOIN_FAILED, pRoleCheck->state); for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* plrg = itr->getSource(); if (!plrg) continue; - + uint64 pguid = plrg->GetGUID(); team = plrg->GetTeam(); WorldSession* session = plrg->GetSession(); if (!newRoleCheck && plr) - session->SendLfgRoleChosen(plr->GetGUID(), plr->GetLfgRoles()); + session->SendLfgRoleChosen(guid, roles); session->SendLfgRoleCheckUpdate(pRoleCheck); switch(pRoleCheck->state) @@ -1065,27 +1057,23 @@ void LFGMgr::UpdateRoleCheck(Group* grp, Player* plr /* = NULL*/, bool newRoleCh case LFG_ROLECHECK_INITIALITING: continue; case LFG_ROLECHECK_FINISHED: - { - plrg->SetLfgState(LFG_STATE_QUEUED); - LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, &dungeons, plrg->GetLfgComment()); - session->SendLfgUpdateParty(updateData); - } + SetState(pguid, LFG_STATE_QUEUED); + session->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, &dungeons, GetComment(pguid))); break; default: - { - if (grp->GetLeaderGUID() == plrg->GetGUID()) - session->SendLfgJoinResult(joinData); - LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ROLECHECK_FAILED); - session->SendLfgUpdateParty(updateData); - plrg->ClearLfgState(); - } + if (grp->GetLeaderGUID() == pguid) + session->SendLfgJoinResult(joinData); + session->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_ROLECHECK_FAILED)); + ClearState(pguid); break; } } + uint64 gguid = grp->GetGUID(); if (pRoleCheck->state == LFG_ROLECHECK_FINISHED) { - grp->SetLfgState(LFG_STATE_QUEUED); + + SetState(gguid, LFG_STATE_QUEUED); LfgQueueInfo* pqInfo = new LfgQueueInfo(); pqInfo->joinTime = time_t(time(NULL)); pqInfo->roles = pRoleCheck->roles; @@ -1103,15 +1091,14 @@ void LFGMgr::UpdateRoleCheck(Group* grp, Player* plr /* = NULL*/, bool newRoleCh --pqInfo->dps; } - uint64 guid = grp->GetGUID(); - m_QueueInfoMap[guid] = pqInfo; - AddToQueue(guid, team); + m_QueueInfoMap[gguid] = pqInfo; + AddToQueue(gguid, team); } if (pRoleCheck->state != LFG_ROLECHECK_INITIALITING) { if (pRoleCheck->state != LFG_ROLECHECK_FINISHED) - grp->RestoreLfgState(); + RestoreState(gguid); delete pRoleCheck; m_RoleChecks.erase(itRoleCheck); } @@ -1323,7 +1310,8 @@ void LFGMgr::UpdateProposal(uint32 proposalId, const uint64& guid, bool accept) // Only teleport new players Group* grp = plr->GetGroup(); - if (!grp || !grp->isLFGGroup() || grp->GetLfgState() == LFG_STATE_FINISHED_DUNGEON) + uint64 gguid = grp ? grp->GetGUID() : 0; + if (!gguid || !grp->isLFGGroup() || GetState(gguid) == LFG_STATE_FINISHED_DUNGEON) playersToTeleport.push_back(plr); } @@ -1367,6 +1355,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, const uint64& guid, bool accept) for (LfgPlayerList::const_iterator it = players.begin(); it != players.end(); ++it) { Player* plr = (*it); + uint64 pguid = plr->GetGUID(); Group* group = plr->GetGroup(); if (sendUpdate) plr->GetSession()->SendLfgUpdateProposal(proposalId, pProposal); @@ -1382,16 +1371,17 @@ void LFGMgr::UpdateProposal(uint32 proposalId, const uint64& guid, bool accept) if (!grp) { grp = new Group(); - grp->Create(plr->GetGUID(), plr->GetName()); + grp->Create(pguid, plr->GetName()); grp->ConvertToLFG(); - grp->SetLfgState(LFG_STATE_PROPOSAL); + uint64 gguid = grp->GetGUID(); + SetState(gguid, LFG_STATE_PROPOSAL); sObjectMgr.AddGroup(grp); } else if (group != grp) - grp->AddMember(plr->GetGUID(), plr->GetName()); + grp->AddMember(pguid, plr->GetName()); // Update timers - uint8 role = plr->GetLfgRoles(); + uint8 role = GetRoles(pguid); role &= ~ROLE_LEADER; switch(role) { @@ -1408,16 +1398,17 @@ void LFGMgr::UpdateProposal(uint32 proposalId, const uint64& guid, bool accept) m_WaitTimeAvg = int32((m_WaitTimeAvg * m_NumWaitTimeAvg + waitTimesMap[plr->GetGUID()]) / ++m_NumWaitTimeAvg); break; } - grp->SetLfgRoles(plr->GetGUID(), pProposal->players[plr->GetGUID()]->role); - plr->SetLfgState(LFG_STATE_DUNGEON); + grp->SetLfgRoles(pguid, pProposal->players[pguid]->role); + SetState(pguid, LFG_STATE_DUNGEON); } // Set the dungeon difficulty LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(pProposal->dungeonId); ASSERT(dungeon); grp->SetDungeonDifficulty(Difficulty(dungeon->difficulty)); - grp->SetLfgDungeonEntry(dungeon->Entry()); - grp->SetLfgState(LFG_STATE_DUNGEON); + uint64 gguid = grp->GetGUID(); + SetDungeon(gguid, dungeon->Entry()); + SetState(gguid, LFG_STATE_DUNGEON); // Remove players/groups from Queue for (LfgGuidList::const_iterator it = pProposal->queues.begin(); it != pProposal->queues.end(); ++it) @@ -1500,10 +1491,10 @@ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType t updateData.updateType = LFG_UPDATETYPE_REMOVED_FROM_QUEUE; sLog.outDebug("LFGMgr::RemoveProposal: [" UI64FMTD "] in same group that someone that didn't accept. Removing from queue and compatible cache", guid); } - plr->ClearLfgState(); + ClearState(guid); if (grp) { - grp->RestoreLfgState(); + RestoreState(gguid); plr->GetSession()->SendLfgUpdateParty(updateData); } else @@ -1511,12 +1502,12 @@ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType t } else { - LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, plr->GetLfgDungeons(), plr->GetLfgComment()); + LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, &GetSelectedDungeons(guid), GetComment(guid)); sLog.outDebug("LFGMgr::RemoveProposal: Readding [" UI64FMTD "] to queue.", guid); - plr->SetLfgState(LFG_STATE_QUEUED); + SetState(guid, LFG_STATE_QUEUED); if (grp) { - grp->SetLfgState(LFG_STATE_QUEUED); + SetState(gguid, LFG_STATE_QUEUED); plr->GetSession()->SendLfgUpdateParty(updateData); } else @@ -1555,15 +1546,15 @@ void LFGMgr::InitBoot(Group* grp, uint64& kicker, uint64& victim, std::string re { if (!grp) return; - - grp->SetLfgState(LFG_STATE_BOOT); + uint64 gguid = grp->GetGUID(); + SetState(gguid, LFG_STATE_BOOT); LfgPlayerBoot* pBoot = new LfgPlayerBoot(); pBoot->inProgress = true; pBoot->cancelTime = time_t(time(NULL)) + LFG_TIME_BOOT; pBoot->reason = reason; pBoot->victim = victim; - pBoot->votedNeeded = GROUP_LFG_KICK_VOTES_NEEDED; + pBoot->votedNeeded = GetVotesNeeded(gguid); PlayerSet players; // Set votes @@ -1571,8 +1562,8 @@ void LFGMgr::InitBoot(Group* grp, uint64& kicker, uint64& victim, std::string re { if (Player* plrg = itr->getSource()) { - plrg->SetLfgState(LFG_STATE_BOOT); uint64 guid = plrg->GetGUID(); + SetState(guid, LFG_STATE_BOOT); if (guid == victim) pBoot->votes[victim] = LFG_ANSWER_DENY; // Victim auto vote NO else if (guid == kicker) @@ -1639,25 +1630,28 @@ void LFGMgr::UpdateBoot(Player* plr, bool accept) // Send update info to all players pBoot->inProgress = false; for (LfgAnswerMap::const_iterator itVotes = pBoot->votes.begin(); itVotes != pBoot->votes.end(); ++itVotes) - if (Player* plrg = sObjectMgr.GetPlayer(itVotes->first)) - if (plrg->GetGUID() != pBoot->victim) - { - plrg->SetLfgState(LFG_STATE_DUNGEON); + { + uint64 pguid = itVotes->first; + if (pguid != pBoot->victim) + { + SetState(pguid, LFG_STATE_DUNGEON); + if (Player* plrg = sObjectMgr.GetPlayer(pguid)) plrg->GetSession()->SendLfgBootPlayer(pBoot); - } + } + } - grp->SetLfgState(LFG_STATE_DUNGEON); + uint64 gguid = grp->GetGUID(); + SetState(gguid, LFG_STATE_DUNGEON); if (agreeNum == pBoot->votedNeeded) // Vote passed - Kick player { Player::RemoveFromGroup(grp, pBoot->victim); if (Player* victim = sObjectMgr.GetPlayer(pBoot->victim)) { TeleportPlayer(victim, true, false); - victim->SetLfgState(LFG_STATE_NONE); + SetState(pBoot->victim, LFG_STATE_NONE); } OfferContinue(grp); - grp->SetLfgKicks(grp->GetLfgKicks() + 1); - + DecreaseKicksLeft(gguid); } delete pBoot; m_Boots.erase(itBoot); @@ -1693,7 +1687,8 @@ void LFGMgr::TeleportPlayer(Player* plr, bool out, bool fromOpcode /*= false*/) error = LFG_TELEPORTERROR_FALLING; else { - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(grp->GetLfgDungeonEntry()); + uint64 gguid = grp->GetGUID(); + LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(GetDungeon(gguid)); if (!dungeon) error = LFG_TELEPORTERROR_INVALID_LOCATION; @@ -1783,25 +1778,28 @@ void LFGMgr::RewardDungeonDoneFor(const uint32 /*dungeonId*/, Player* player) return; } - if (player->GetLfgState() == LFG_STATE_FINISHED_DUNGEON) + uint64 guid = player->GetGUID(); + uint64 gguid = player->GetGroup()->GetGUID(); + + if (GetState(guid) == LFG_STATE_FINISHED_DUNGEON) { - sLog.outDebug("LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] Already rewarded player. Ignoring", player->GetGUID()); + sLog.outDebug("LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] Already rewarded player. Ignoring", guid); return; } // Mark dungeon as finished - group->SetLfgState(LFG_STATE_FINISHED_DUNGEON); + SetState(gguid, LFG_STATE_FINISHED_DUNGEON); // Clear player related lfg stuff - uint32 rDungeonId = (*player->GetLfgDungeons()->begin()); - player->ClearLfgState(); - player->SetLfgState(LFG_STATE_FINISHED_DUNGEON); + uint32 rDungeonId = (*GetSelectedDungeons(guid).begin()); + ClearState(guid); + SetState(guid, LFG_STATE_FINISHED_DUNGEON); // Give rewards only if its a random dungeon LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(rDungeonId); if (!dungeon || dungeon->type != LFG_TYPE_RANDOM) { - sLog.outDebug("LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] dungeon %u is not random. Queued for %u dungeons", player->GetGUID(), rDungeonId, uint8(player->GetLfgDungeons()->size())); + sLog.outDebug("LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] dungeon %u is not random", guid, rDungeonId); return; } @@ -1832,8 +1830,8 @@ void LFGMgr::RewardDungeonDoneFor(const uint32 /*dungeonId*/, Player* player) } // Give rewards - sLog.outDebug("LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] done dungeon %u,%s previously done.", player->GetGUID(), group->GetLfgDungeonEntry(), index > 0 ? " " : " not"); - player->GetSession()->SendLfgPlayerReward(dungeon->Entry(), group->GetLfgDungeonEntry(false), index, reward, qReward); + sLog.outDebug("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); } // --------------------------------------------------------------------------// @@ -2057,3 +2055,97 @@ std::string LFGMgr::ConcatenateGuids(LfgGuidList check) o << "|" << (*it); return o.str(); } + + +LfgState LFGMgr::GetState(uint64& guid) +{ + return m_Players[guid].GetState(); +} + +uint32 LFGMgr::GetDungeon(uint64& guid, bool asId /*= true*/) +{ + return m_Groups[guid].GetDungeon(asId); +} + +uint8 LFGMgr::GetRoles(uint64& guid) +{ + return m_Players[guid].GetRoles(); +} + +const std::string& LFGMgr::GetComment(uint64& guid) +{ + return m_Players[guid].GetComment(); +} + +LfgDungeonSet& LFGMgr::GetSelectedDungeons(uint64& guid) +{ + return m_Players[guid].GetSelectedDungeons(); +} + +uint8 LFGMgr::GetKicksLeft(uint64& guid) +{ + return m_Groups[guid].GetKicksLeft(); +} + +uint8 LFGMgr::GetVotesNeeded(uint64& guid) +{ + return m_Groups[guid].GetVotesNeeded(); +} + + +void LFGMgr::RestoreState(uint64& guid) +{ + m_Groups[guid].RestoreState(); +} + +void LFGMgr::ClearState(uint64& guid) +{ + m_Players[guid].ClearState(); +} + +void LFGMgr::SetState(uint64& guid, LfgState state) +{ + if (IS_GROUP(guid)) + m_Groups[guid].SetState(state); + else + m_Players[guid].SetState(state); +} + +void LFGMgr::SetDungeon(uint64& guid, uint32 dungeon) +{ + m_Groups[guid].SetDungeon(dungeon); +} + +void LFGMgr::SetRoles(uint64& guid, uint8 roles) +{ + m_Players[guid].SetRoles(roles); +} + +void LFGMgr::SetComment(uint64& guid, std::string& comment) +{ + m_Players[guid].SetComment(comment); +} + +void LFGMgr::SetSelectedDungeons(uint64& guid, LfgDungeonSet dungeons) +{ + m_Players[guid].SetSelectedDungeons(dungeons); +} + +void LFGMgr::DecreaseKicksLeft(uint64& guid) +{ + m_Groups[guid].DecreaseKicksLeft(); +} + +void LFGMgr::RemovePlayerData(uint64& guid) +{ + LfgPlayerDataMap::iterator it = m_Players.find(guid); + if (it != m_Players.end()) + m_Players.erase(it); +} + +void LFGMgr::RemoveGroupData(uint64& guid) +{ + LfgGroupDataMap::iterator it = m_Groups.find(guid); + if (it != m_Groups.end()) + m_Groups.erase(it); +} diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index e56764543d8..4a391914b5f 100755 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -22,6 +22,8 @@ #include <ace/Singleton.h> #include "LFG.h" +class LfgGroupData; +class LfgPlayerData; class Group; class Player; @@ -149,8 +151,6 @@ typedef std::multimap<uint32, LfgReward const*> LfgRewardMap; typedef std::pair<LfgRewardMap::const_iterator, LfgRewardMap::const_iterator> LfgRewardMapBounds; typedef std::map<std::string, LfgAnswer> LfgCompatibleMap; typedef std::map<uint64, LfgDungeonSet> LfgDungeonMap; -typedef std::set<LfgLockStatus*> LfgLockStatusSet; -typedef std::map<uint64, LfgLockStatusSet*> LfgLockStatusMap; typedef std::map<uint64, uint8> LfgRolesMap; typedef std::map<uint64, LfgAnswer> LfgAnswerMap; typedef std::map<uint32, LfgRoleCheck*> LfgRoleCheckMap; @@ -158,6 +158,8 @@ typedef std::map<uint64, LfgQueueInfo*> LfgQueueInfoMap; typedef std::map<uint32, LfgProposal*> LfgProposalMap; typedef std::map<uint64, LfgProposalPlayer*> LfgProposalPlayerMap; typedef std::map<uint32, LfgPlayerBoot*> LfgPlayerBootMap; +typedef std::map<uint64, LfgGroupData> LfgGroupDataMap; +typedef std::map<uint64, LfgPlayerData> LfgPlayerDataMap; /// Dungeon and reason why player can't join struct LfgLockStatus @@ -169,7 +171,8 @@ struct LfgLockStatus // Data needed by SMSG_LFG_JOIN_RESULT struct LfgJoinResultData { - LfgJoinResultData(): result(LFG_JOIN_OK), state(LFG_ROLECHECK_DEFAULT), lockmap(NULL) {} + LfgJoinResultData(LfgJoinResult _result = LFG_JOIN_OK, LfgRoleCheckState _state = LFG_ROLECHECK_DEFAULT, LfgLockStatusMap* _lockmap = NULL): + result(_result), state(_state), lockmap(_lockmap) {} LfgJoinResult result; LfgRoleCheckState state; LfgLockStatusMap* lockmap; @@ -312,6 +315,26 @@ class LFGMgr LfgLockStatusMap* GetPartyLockStatusDungeons(Player* plr); LfgLockStatusSet* GetPlayerLockStatusDungeons(Player* plr); + + LfgState GetState(uint64& guid); + uint32 GetDungeon(uint64& guid, bool asId = true); + uint8 GetRoles(uint64& guid); + const std::string& GetComment(uint64& gguid); + LfgDungeonSet& GetSelectedDungeons(uint64& guid); + uint8 GetKicksLeft(uint64& gguid); + uint8 GetVotesNeeded(uint64& gguid); + + void RestoreState(uint64& guid); + void ClearState(uint64& guid); + void SetState(uint64& guid, LfgState state); + void SetDungeon(uint64& guid, uint32 dungeon); + void SetRoles(uint64& guid, uint8 roles); + void SetComment(uint64& guid, std::string& comment); + void SetSelectedDungeons(uint64& guid, LfgDungeonSet dungeons); + void DecreaseKicksLeft(uint64& guid); + void RemovePlayerData(uint64& guid); + void RemoveGroupData(uint64& guid); + private: // Queue void AddToQueue(uint64& guid, uint8 queueId); @@ -363,6 +386,8 @@ class LFGMgr LfgRoleCheckMap m_RoleChecks; ///< Current Role checks LfgProposalMap m_Proposals; ///< Current Proposals LfgPlayerBootMap m_Boots; ///< Current player kicks + LfgPlayerDataMap m_Players; ///< Player data + LfgGroupDataMap m_Groups; ///< Group data }; #define sLFGMgr (*ACE_Singleton<LFGMgr, ACE_Null_Mutex>::instance()) diff --git a/src/server/game/DungeonFinding/LFGPlayerData.cpp b/src/server/game/DungeonFinding/LFGPlayerData.cpp new file mode 100644 index 00000000000..02654d54f39 --- /dev/null +++ b/src/server/game/DungeonFinding/LFGPlayerData.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "LFGPlayerData.h" + +LfgPlayerData::LfgPlayerData(): +m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), m_Roles(ROLE_NONE), m_Comment("") +{} + +LfgPlayerData::~LfgPlayerData() +{ +} + +void LfgPlayerData::SetState(LfgState state) +{ + switch(state) + { + case LFG_STATE_NONE: + case LFG_STATE_DUNGEON: + case LFG_STATE_FINISHED_DUNGEON: + m_OldState = state; + // No break on purpose + default: + m_State = state; + } +} + +void LfgPlayerData::ClearState() +{ + m_SelectedDungeons.clear(); + m_Roles = ROLE_NONE; + m_State = m_OldState; +} + +void LfgPlayerData::SetDungeonsLockStatus(LfgLockStatusSet& lockStatus) +{ + m_LockedDungeons = lockStatus; +} + +void LfgPlayerData::SetRoles(uint8 roles) +{ + m_Roles = roles; +} + +void LfgPlayerData::SetComment(std::string& comment) +{ + m_Comment = comment; +} + +void LfgPlayerData::SetSelectedDungeons(LfgDungeonSet& dungeons) +{ + m_SelectedDungeons = dungeons; +} + +void LfgPlayerData::ClearSelectedDungeons() +{ + m_SelectedDungeons.clear(); +} + +LfgState LfgPlayerData::GetState() const +{ + return m_State; +} + +LfgLockStatusSet& LfgPlayerData::GetDungeonsLockStatus() +{ + return m_LockedDungeons; +} + +uint8 LfgPlayerData::GetRoles() const +{ + return m_Roles; +} + +const std::string& LfgPlayerData::GetComment() const +{ + return m_Comment; +} + +LfgDungeonSet& LfgPlayerData::GetSelectedDungeons() +{ + return m_SelectedDungeons; +} diff --git a/src/server/game/DungeonFinding/LFGPlayerData.h b/src/server/game/DungeonFinding/LFGPlayerData.h new file mode 100644 index 00000000000..4572cdc95ba --- /dev/null +++ b/src/server/game/DungeonFinding/LFGPlayerData.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _LFGPLAYERDATA_H +#define _LFGPLAYERDATA_H + +#include "Common.h" +#include "LFG.h" + +/** + Stores all lfg data needed about the player. +*/ +class LfgPlayerData +{ + public: + LfgPlayerData(); + ~LfgPlayerData(); + + // General + void SetState(LfgState state); + void ClearState(); + void SetDungeonsLockStatus(LfgLockStatusSet& lockStatus); + // Queue + void SetRoles(uint8 roles); + void SetComment(std::string& comment); + void SetSelectedDungeons(LfgDungeonSet& dungeons); + void ClearSelectedDungeons(); + + // General + LfgState GetState() const; + LfgLockStatusSet& GetDungeonsLockStatus(); + // Queue + uint8 GetRoles() const; + const std::string& GetComment() const; + LfgDungeonSet& GetSelectedDungeons(); + + private: + // General + LfgState m_State; ///< State if group in LFG + LfgState m_OldState; ///< Old State + // Player + LfgLockStatusSet m_LockedDungeons; ///< Dungeons player can't do and reason + // Queue + uint8 m_Roles; ///< Roles the player selected when joined LFG + std::string m_Comment; ///< Player comment used when joined LFG + LfgDungeonSet m_SelectedDungeons; ///< Selected Dungeons when joined LFG +}; + +#endif diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index d3c32b5364c..5a1310de01e 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -47,12 +47,12 @@ void LFGScripts::OnAddMember(Group* group, uint64 guid) } // TODO - if group is queued and new player is added convert to rolecheck without notify the current players queued - if (group->GetLfgState() == LFG_STATE_QUEUED) + if (sLFGMgr.GetState(gguid) == LFG_STATE_QUEUED) sLFGMgr.Leave(NULL, group); - Player *plr = sObjectMgr.GetPlayer(guid); - if (plr && plr->GetLfgState() == LFG_STATE_QUEUED) - sLFGMgr.Leave(plr); + if (sLFGMgr.GetState(guid) == LFG_STATE_QUEUED) + if (Player *plr = sObjectMgr.GetPlayer(guid)) + sLFGMgr.Leave(plr); } void LFGScripts::OnRemoveMember(Group* group, uint64 guid, RemoveMethod& method, uint64 kicker, const char* reason) @@ -62,7 +62,7 @@ void LFGScripts::OnRemoveMember(Group* group, uint64 guid, RemoveMethod& method, return; sLog.outDebug("LFGScripts::OnRemoveMember [" UI64FMTD "]: remove [" UI64FMTD "] Method: %d Kicker: [" UI64FMTD "] Reason: %s", gguid, guid, method, kicker, (reason ? reason : "")); - if (group->GetLfgState() == LFG_STATE_QUEUED) + if (sLFGMgr.GetState(gguid) == LFG_STATE_QUEUED) { // TODO - Do not remove, just remove the one leaving and rejoin queue with all other data sLFGMgr.Leave(NULL, group); @@ -81,6 +81,7 @@ void LFGScripts::OnRemoveMember(Group* group, uint64 guid, RemoveMethod& method, return; } + sLFGMgr.ClearState(guid); if (Player *plr = sObjectMgr.GetPlayer(guid)) { /* @@ -89,20 +90,23 @@ void LFGScripts::OnRemoveMember(Group* group, uint64 guid, RemoveMethod& method, else if (group->isLfgKickActive()) // Update internal kick cooldown of kicked */ - - plr->ClearLfgState(); + LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_LEADER); plr->GetSession()->SendLfgUpdateParty(updateData); if (plr->GetMap()->IsDungeon()) // Teleport player out the dungeon sLFGMgr.TeleportPlayer(plr, true); } - if (group->GetLfgState() != LFG_STATE_FINISHED_DUNGEON)// Need more players to finish the dungeon + if (sLFGMgr.GetState(gguid) != LFG_STATE_FINISHED_DUNGEON)// Need more players to finish the dungeon sLFGMgr.OfferContinue(group); } -void LFGScripts::OnDisband(Group* /*group*/) +void LFGScripts::OnDisband(Group* group) { + uint64 gguid = group->GetGUID(); + sLog.outError("LFGScripts::OnDisband [" UI64FMTD "]", gguid); + + sLFGMgr.RemoveGroupData(gguid); } void LFGScripts::OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid) @@ -149,6 +153,9 @@ void LFGScripts::OnLogout(Player* player) player->GetSession()->SendLfgUpdateParty(updateData); player->GetSession()->SendLfgUpdatePlayer(updateData); player->GetSession()->SendLfgUpdateSearch(false); + uint64 guid = player->GetGUID(); + // TODO - Do not remove, add timer before deleting + sLFGMgr.RemovePlayerData(guid); } void LFGScripts::OnLogin(Player* /*player*/) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 41b5338b873..9ed4bb35252 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -66,6 +66,7 @@ #include "ConditionMgr.h" #include "DisableMgr.h" #include "WeatherMgr.h" +#include "LFGMgr.h" #include <cmath> #define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS) @@ -22202,16 +22203,18 @@ PartyResult Player::CanUninviteFromGroup() const if (grp->isLFGGroup()) { - if (grp->GetLfgKicks() == GROUP_MAX_LFG_KICKS) + uint64 gguid = grp->GetGUID(); + if (!sLFGMgr.GetKicksLeft(gguid)) return ERR_PARTY_LFG_BOOT_LIMIT; - if (GetLfgState() == LFG_STATE_BOOT) + LfgState state = sLFGMgr.GetState(gguid); + if (state == LFG_STATE_BOOT) return ERR_PARTY_LFG_BOOT_IN_PROGRESS; - if (grp->GetMembersCount() <= GROUP_LFG_KICK_VOTES_NEEDED) + if (grp->GetMembersCount() <= sLFGMgr.GetVotesNeeded(gguid)) return ERR_PARTY_LFG_BOOT_TOO_FEW_PLAYERS; - if (GetLfgState() == LFG_STATE_FINISHED_DUNGEON) + if (state == LFG_STATE_FINISHED_DUNGEON) return ERR_PARTY_LFG_BOOT_DUNGEON_COMPLETE; if (grp->isRollLootActive()) @@ -22235,6 +22238,12 @@ PartyResult Player::CanUninviteFromGroup() const return ERR_PARTY_RESULT_OK; } +bool Player::isUsingLfg() +{ + uint64 guid = GetGUID(); + return sLFGMgr.GetState(guid) != LFG_STATE_NONE; +} + void Player::SetBattlegroundRaid(Group* group, int8 subgroup) { //we must move references from m_group to m_originalGroup diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 4e0fde259db..e8e3bb9328c 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -28,7 +28,6 @@ #include "GroupReference.h" #include "ItemPrototype.h" #include "Item.h" -#include "LFG.h" #include "MapReference.h" #include "NPCHandler.h" #include "Pet.h" @@ -2255,34 +2254,7 @@ class Player : public Unit, public GridObject<Player> void SetAtLoginFlag(AtLoginFlags f) { m_atLoginFlags |= f; } void RemoveAtLoginFlag(AtLoginFlags f, bool in_db_also = false); - // Dungeon Finder - LfgDungeonSet *GetLfgDungeons() { return &m_LookingForGroup.applyDungeons; } - std::string GetLfgComment() { return m_LookingForGroup.comment; } - void SetLfgComment(std::string _comment) { m_LookingForGroup.comment = _comment; } - uint8 GetLfgRoles() { return m_LookingForGroup.roles; } - void SetLfgRoles(uint8 _roles) { m_LookingForGroup.roles = _roles; } - LfgState GetLfgState() const { return m_LookingForGroup.state; } - void SetLfgState(LfgState state) - { - - switch(state) - { - case LFG_STATE_NONE: - case LFG_STATE_DUNGEON: - case LFG_STATE_FINISHED_DUNGEON: - m_LookingForGroup.oldState = state; - // No break on purpose - default: - m_LookingForGroup.state = state; - } - } - void ClearLfgState() - { - m_LookingForGroup.applyDungeons.clear(); - m_LookingForGroup.roles = ROLE_NONE; - m_LookingForGroup.state = m_LookingForGroup.oldState; - } - bool isUsingLfg() { return GetLfgState() != LFG_STATE_NONE; } + bool isUsingLfg(); typedef std::set<uint32> DFQuestsDoneList; DFQuestsDoneList m_DFQuests; @@ -2711,8 +2683,6 @@ class Player : public Unit, public GridObject<Player> uint32 m_timeSyncTimer; uint32 m_timeSyncClient; uint32 m_timeSyncServer; - - LookingForGroup m_LookingForGroup; }; void AddItemsSetItem(Player*player,Item *item); diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 555c4b0cee6..2641e9d6149 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -32,6 +32,7 @@ #include "InstanceSaveMgr.h" #include "MapInstanced.h" #include "Util.h" +#include "LFGMgr.h" Roll::Roll(uint64 _guid, LootItem const& li) : itemGUID(_guid), itemid(li.itemid), itemRandomPropId(li.randomPropertyId), itemRandomSuffix(li.randomSuffix), itemCount(li.count), @@ -56,8 +57,7 @@ Loot* Roll::getLoot() Group::Group() : m_leaderGuid(0), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL), m_dungeonDifficulty(DUNGEON_DIFFICULTY_NORMAL), m_raidDifficulty(RAID_DIFFICULTY_10MAN_NORMAL), m_bgGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(0), -m_subGroupsCounts(NULL), m_guid(0), m_counter(0), m_maxEnchantingLevel(0), -m_LfgState(LFG_STATE_NONE), m_LfgOldState(LFG_STATE_NONE), m_LfgDungeonEntry(0), m_Lfgkicks(0) +m_subGroupsCounts(NULL), m_guid(0), m_counter(0), m_maxEnchantingLevel(0) { for (uint8 i = 0; i < TARGETICONCOUNT; ++i) m_targetIcons[i] = 0; @@ -1106,8 +1106,8 @@ void Group::SendUpdate() data << uint8(citr->roles); if (isLFGGroup()) { - data << uint8(m_LfgState == LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done - data << uint32(m_LfgDungeonEntry); + data << uint8(sLFGMgr.GetState(m_guid) == LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done + data << uint32(sLFGMgr.GetDungeon(m_guid)); } data << uint64(m_guid); @@ -1923,46 +1923,7 @@ void Group::SetLootThreshold(ItemQualities threshold) m_lootThreshold = threshold; } -void Group::SetLfgState(LfgState state) -{ - m_LfgState = state; -} - -LfgState Group::GetLfgState() const -{ - return m_LfgState; -} - -void Group::RestoreLfgState() -{ - m_LfgState = m_LfgOldState; -} - - -void Group::SetLfgDungeonEntry(uint32 dungeonEntry) -{ - m_LfgDungeonEntry = dungeonEntry; -} - -uint32 Group::GetLfgDungeonEntry(bool id /* = true*/) const -{ - if (id) - return (m_LfgDungeonEntry & 0x00FFFFFF); - else - return m_LfgDungeonEntry; -} - -uint8 Group::GetLfgKicks() const -{ - return m_Lfgkicks; -} - -void Group::SetLfgKicks(uint8 kicks) -{ - m_Lfgkicks = kicks; -} - -void Group::SetLfgRoles(uint64 guid, const uint8 roles) +void Group::SetLfgRoles(uint64& guid, const uint8 roles) { member_witerator slot = _getMemberWSlot(guid); if (slot == m_memberSlots.end()) diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 584c2f3489d..58a18ea1a8d 100755 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -42,8 +42,6 @@ struct MapEntry; #define MAXRAIDSIZE 40 #define MAX_RAID_SUBGROUPS MAXRAIDSIZE/MAXGROUPSIZE #define TARGETICONCOUNT 8 -#define GROUP_MAX_LFG_KICKS 3 -#define GROUP_LFG_KICK_VOTES_NEEDED 3 enum RollVote { @@ -193,16 +191,7 @@ class Group void UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed = false); void SetLootThreshold(ItemQualities threshold); void Disband(bool hideDestroy=false); - - // Dungeon Finder - void SetLfgState(LfgState state); - LfgState GetLfgState() const; - void RestoreLfgState(); - void SetLfgDungeonEntry(uint32 dungeonEntry); - uint32 GetLfgDungeonEntry(bool id = true) const; - uint8 GetLfgKicks() const; - void SetLfgKicks(uint8 kicks); - void SetLfgRoles(uint64 guid, const uint8 roles); + void SetLfgRoles(uint64& guid, const uint8 roles); // properties accessories bool IsFull() const; @@ -346,9 +335,5 @@ class Group uint64 m_guid; uint32 m_counter; // used only in SMSG_GROUP_LIST uint32 m_maxEnchantingLevel; - LfgState m_LfgState; - LfgState m_LfgOldState; - uint32 m_LfgDungeonEntry; - uint8 m_Lfgkicks; }; #endif diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index c7e82516bdf..a08e5a74cfd 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -2874,16 +2874,4 @@ enum RemoveMethod GROUP_REMOVEMETHOD_LEAVE = 2, }; -enum LfgState -{ - LFG_STATE_NONE, // Not using LFG / LFR - LFG_STATE_ROLECHECK, // Rolecheck active - LFG_STATE_QUEUED, // Queued - LFG_STATE_PROPOSAL, // Proposal active - LFG_STATE_BOOT, // Vote kick active - LFG_STATE_DUNGEON, // In LFG Group, in a Dungeon - LFG_STATE_FINISHED_DUNGEON, // In LFG Group, in a finished Dungeon - LFG_STATE_RAIDBROWSER, // Using Raid finder -}; - #endif diff --git a/src/server/game/Server/Protocol/Handlers/LFGHandler.cpp b/src/server/game/Server/Protocol/Handlers/LFGHandler.cpp index fb5423a1d7e..b9021c68c0e 100755 --- a/src/server/game/Server/Protocol/Handlers/LFGHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/LFGHandler.cpp @@ -91,7 +91,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket &recv_data) std::string comment; recv_data >> comment; sLog.outDebug("CMSG_LFG_JOIN [" UI64FMTD "] roles: %u, Dungeons: %u, Comment: %s", GetPlayer()->GetGUID(), roles, uint8(newDungeons.size()), comment.c_str()); - sLFGMgr.Join(GetPlayer(), uint8(roles), newDungeons, comment); + sLFGMgr.Join(GetPlayer(), LfgRoles(roles), newDungeons, comment); } void WorldSession::HandleLfgLeaveOpcode(WorldPacket & /*recv_data*/) @@ -120,25 +120,25 @@ void WorldSession::HandleLfgSetRolesOpcode(WorldPacket &recv_data) { uint8 roles; recv_data >> roles; // Player Group Roles - + uint64 guid = GetPlayer()->GetGUID(); Group* grp = GetPlayer()->GetGroup(); if (!grp) { - sLog.outDebug("CMSG_LFG_SET_ROLES [" UI64FMTD "] Not in group", GetPlayer()->GetGUID()); + sLog.outDebug("CMSG_LFG_SET_ROLES [" UI64FMTD "] Not in group", guid); return; } - sLog.outDebug("CMSG_LFG_SET_ROLES [" UI64FMTD "] Roles: %u", GetPlayer()->GetGUID(), roles); - GetPlayer()->SetLfgRoles(roles); - sLFGMgr.UpdateRoleCheck(grp, GetPlayer()); + sLog.outDebug("CMSG_LFG_SET_ROLES [" UI64FMTD "] Roles: %u", guid, roles); + sLFGMgr.UpdateRoleCheck(grp, GetPlayer(), LfgRoles(roles)); } void WorldSession::HandleLfgSetCommentOpcode(WorldPacket & recv_data) { std::string comment; recv_data >> comment; - - sLog.outDebug("CMSG_SET_LFG_COMMENT [" UI64FMTD "] comment: %s", GetPlayer()->GetGUID(), comment.c_str()); - GetPlayer()->SetLfgComment(comment); + uint64 guid = GetPlayer()->GetGUID(); + sLog.outDebug("CMSG_SET_LFG_COMMENT [" UI64FMTD "] comment: %s", guid, comment.c_str()); + + sLFGMgr.SetComment(guid, comment); } void WorldSession::HandleLfgSetBootVoteOpcode(WorldPacket &recv_data) @@ -276,7 +276,7 @@ void WorldSession::HandleLfrLeaveOpcode(WorldPacket &recv_data) //sLFGMgr.LeaveLfr(GetPlayer(), dungeonId); } -void WorldSession::SendLfgUpdatePlayer(LfgUpdateData& updateData) +void WorldSession::SendLfgUpdatePlayer(LfgUpdateData updateData) { bool queued = false; bool extrainfo = false; @@ -318,7 +318,7 @@ void WorldSession::SendLfgUpdatePlayer(LfgUpdateData& updateData) SendPacket(&data); } -void WorldSession::SendLfgUpdateParty(LfgUpdateData& updateData) +void WorldSession::SendLfgUpdateParty(LfgUpdateData updateData) { bool join = false; bool extrainfo = false; @@ -546,6 +546,8 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal* pProp) return; uint32 pLogGuid = GetPlayer()->GetGUIDLow(); + uint64 guid = GetPlayer()->GetGUID(); + LfgProposalPlayerMap::const_iterator itPlayer = pProp->players.find(pLogGuid); if (itPlayer == pProp->players.end()) // Player MUST be in the proposal return; @@ -559,7 +561,8 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal* pProp) Group* grp = dLowGuid ? sObjectMgr.GetGroupByGUID(dLowGuid) : NULL; if (grp) { - isContinue = grp->isLFGGroup() && grp->GetLfgState() != LFG_STATE_FINISHED_DUNGEON; + uint64 gguid = grp->GetGUID(); + isContinue = grp->isLFGGroup() && sLFGMgr.GetState(gguid) != LFG_STATE_FINISHED_DUNGEON; isSameDungeon = GetPlayer()->GetGroup() == grp && isContinue; } @@ -567,7 +570,11 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal* pProp) WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + pProp->players.size() * (4 + 1 + 1 + 1 + 1 +1)); if (!isContinue) // Only show proposal dungeon if it's continue - dungeonId = (*GetPlayer()->GetLfgDungeons()->begin()); + { + LfgDungeonSet playerDungeons = sLFGMgr.GetSelectedDungeons(guid); + if (playerDungeons.size()) + dungeonId = (*playerDungeons.begin()); + } if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) dungeonId = dungeon->Entry(); data << uint32(dungeonId); // Dungeon diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index ebb4c045f3f..c2476ec467d 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -768,8 +768,8 @@ class WorldSession void HandleLfrSearchOpcode(WorldPacket &recv_data); void HandleLfrLeaveOpcode(WorldPacket &recv_data); - void SendLfgUpdatePlayer(LfgUpdateData& updateData); - void SendLfgUpdateParty(LfgUpdateData& updateData); + void SendLfgUpdatePlayer(LfgUpdateData updateData); + void SendLfgUpdateParty(LfgUpdateData updateData); void SendLfgRoleChosen(uint64 guid, uint8 roles); void SendLfgRoleCheckUpdate(LfgRoleCheck *pRoleCheck); void SendLfgUpdateSearch(bool update); |
