aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/server/game/DungeonFinding/LFG.h19
-rw-r--r--src/server/game/DungeonFinding/LFGGroupData.cpp82
-rw-r--r--src/server/game/DungeonFinding/LFGGroupData.h67
-rwxr-xr-xsrc/server/game/DungeonFinding/LFGMgr.cpp326
-rwxr-xr-xsrc/server/game/DungeonFinding/LFGMgr.h31
-rw-r--r--src/server/game/DungeonFinding/LFGPlayerData.cpp97
-rw-r--r--src/server/game/DungeonFinding/LFGPlayerData.h63
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.cpp25
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp17
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h32
-rwxr-xr-xsrc/server/game/Groups/Group.cpp49
-rwxr-xr-xsrc/server/game/Groups/Group.h17
-rwxr-xr-xsrc/server/game/Miscellaneous/SharedDefines.h12
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/LFGHandler.cpp33
-rwxr-xr-xsrc/server/game/Server/WorldSession.h4
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);