1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
|
/*
* Copyright (C) 2008-2012 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 _LFGMGR_H
#define _LFGMGR_H
#include "Common.h"
#include <ace/Singleton.h>
#include "LFG.h"
class LfgGroupData;
class LfgPlayerData;
class Group;
class Player;
enum LFGenum
{
LFG_TIME_ROLECHECK = 2*MINUTE,
LFG_TIME_BOOT = 2*MINUTE,
LFG_TIME_PROPOSAL = 2*MINUTE,
LFG_TANKS_NEEDED = 1,
LFG_HEALERS_NEEDED = 1,
LFG_DPS_NEEDED = 3,
LFG_QUEUEUPDATE_INTERVAL = 15*IN_MILLISECONDS,
LFG_SPELL_DUNGEON_COOLDOWN = 71328,
LFG_SPELL_DUNGEON_DESERTER = 71041,
LFG_SPELL_LUCK_OF_THE_DRAW = 72221
};
/// Determines the type of instance
enum LfgType
{
LFG_TYPE_NONE = 0, // Internal use only
LFG_TYPE_DUNGEON = 1,
LFG_TYPE_RAID = 2,
LFG_TYPE_QUEST = 3,
LFG_TYPE_ZONE = 4,
LFG_TYPE_HEROIC = 5,
LFG_TYPE_RANDOM = 6
};
/// Proposal states
enum LfgProposalState
{
LFG_PROPOSAL_INITIATING = 0,
LFG_PROPOSAL_FAILED = 1,
LFG_PROPOSAL_SUCCESS = 2
};
/// Teleport errors
enum LfgTeleportError
{
// 3, 7, 8 = "You can't do that right now" | 5 = No client reaction
LFG_TELEPORTERROR_OK = 0, // Internal use
LFG_TELEPORTERROR_PLAYER_DEAD = 1,
LFG_TELEPORTERROR_FALLING = 2,
LFG_TELEPORTERROR_DONT_REPORT = 3,
LFG_TELEPORTERROR_FATIGUE = 4,
LFG_TELEPORTERROR_INVALID_LOCATION = 6
};
/// Queue join results
enum LfgJoinResult
{
// 3 = No client reaction | 18 = "Rolecheck failed"
LFG_JOIN_OK = 0, // Joined (no client msg)
LFG_JOIN_FAILED = 1, // RoleCheck Failed
LFG_JOIN_GROUPFULL = 2, // Your group is full
LFG_JOIN_INTERNAL_ERROR = 4, // Internal LFG Error
LFG_JOIN_NOT_MEET_REQS = 5, // You do not meet the requirements for the chosen dungeons
LFG_JOIN_PARTY_NOT_MEET_REQS = 6, // One or more party members do not meet the requirements for the chosen dungeons
LFG_JOIN_MIXED_RAID_DUNGEON = 7, // You cannot mix dungeons, raids, and random when picking dungeons
LFG_JOIN_MULTI_REALM = 8, // The dungeon you chose does not support players from multiple realms
LFG_JOIN_DISCONNECTED = 9, // One or more party members are pending invites or disconnected
LFG_JOIN_PARTY_INFO_FAILED = 10, // Could not retrieve information about some party members
LFG_JOIN_DUNGEON_INVALID = 11, // One or more dungeons was not valid
LFG_JOIN_DESERTER = 12, // You can not queue for dungeons until your deserter debuff wears off
LFG_JOIN_PARTY_DESERTER = 13, // One or more party members has a deserter debuff
LFG_JOIN_RANDOM_COOLDOWN = 14, // You can not queue for random dungeons while on random dungeon cooldown
LFG_JOIN_PARTY_RANDOM_COOLDOWN = 15, // One or more party members are on random dungeon cooldown
LFG_JOIN_TOO_MUCH_MEMBERS = 16, // You can not enter dungeons with more that 5 party members
LFG_JOIN_USING_BG_SYSTEM = 17 // You can not use the dungeon system while in BG or arenas
};
/// Role check states
enum LfgRoleCheckState
{
LFG_ROLECHECK_DEFAULT = 0, // Internal use = Not initialized.
LFG_ROLECHECK_FINISHED = 1, // Role check finished
LFG_ROLECHECK_INITIALITING = 2, // Role check begins
LFG_ROLECHECK_MISSING_ROLE = 3, // Someone didn't selected a role after 2 mins
LFG_ROLECHECK_WRONG_ROLES = 4, // Can't form a group with that role selection
LFG_ROLECHECK_ABORTED = 5, // Someone leave the group
LFG_ROLECHECK_NO_ROLE = 6 // Someone selected no role
};
/// Answer state (Also used to check compatibilites)
enum LfgAnswer
{
LFG_ANSWER_PENDING = -1,
LFG_ANSWER_DENY = 0,
LFG_ANSWER_AGREE = 1
};
// Forward declaration (just to have all typedef together)
struct LfgReward;
struct LfgLockStatus;
struct LfgQueueInfo;
struct LfgRoleCheck;
struct LfgProposal;
struct LfgProposalPlayer;
struct LfgPlayerBoot;
typedef std::set<uint64> LfgGuidSet;
typedef std::list<uint64> LfgGuidList;
typedef std::map<uint8, LfgGuidList> LfgGuidListMap;
typedef std::set<Player*> PlayerSet;
typedef std::list<Player*> LfgPlayerList;
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::map<uint64, uint8> LfgRolesMap;
typedef std::map<uint64, LfgAnswer> LfgAnswerMap;
typedef std::map<uint64, LfgRoleCheck*> LfgRoleCheckMap;
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;
// Data needed by SMSG_LFG_JOIN_RESULT
struct LfgJoinResultData
{
LfgJoinResultData(LfgJoinResult _result = LFG_JOIN_OK, LfgRoleCheckState _state = LFG_ROLECHECK_DEFAULT):
result(_result), state(_state) {}
LfgJoinResult result;
LfgRoleCheckState state;
LfgLockPartyMap lockmap;
};
// Data needed by SMSG_LFG_UPDATE_PARTY and SMSG_LFG_UPDATE_PLAYER
struct LfgUpdateData
{
LfgUpdateData(LfgUpdateType _type = LFG_UPDATETYPE_DEFAULT): updateType(_type), comment("") {}
LfgUpdateData(LfgUpdateType _type, const LfgDungeonSet& _dungeons, std::string _comment):
updateType(_type), dungeons(_dungeons), comment(_comment) {}
LfgUpdateType updateType;
LfgDungeonSet dungeons;
std::string comment;
};
/// Reward info
struct LfgReward
{
uint32 maxLevel;
struct
{
uint32 questId;
uint32 variableMoney;
uint32 variableXP;
} reward[2];
LfgReward(uint32 _maxLevel = 0, uint32 firstQuest = 0, uint32 firstVarMoney = 0, uint32 firstVarXp = 0, uint32 otherQuest = 0, uint32 otherVarMoney = 0, uint32 otherVarXp = 0)
: maxLevel(_maxLevel)
{
reward[0].questId = firstQuest;
reward[0].variableMoney = firstVarMoney;
reward[0].variableXP = firstVarXp;
reward[1].questId = otherQuest;
reward[1].variableMoney = otherVarMoney;
reward[1].variableXP = otherVarXp;
}
};
/// Stores player or group queue info
struct LfgQueueInfo
{
LfgQueueInfo(): joinTime(0), tanks(LFG_TANKS_NEEDED), healers(LFG_HEALERS_NEEDED), dps(LFG_DPS_NEEDED) {};
time_t joinTime; ///< Player queue join time (to calculate wait times)
uint8 tanks; ///< Tanks needed
uint8 healers; ///< Healers needed
uint8 dps; ///< Dps needed
LfgDungeonSet dungeons; ///< Selected Player/Group Dungeon/s
LfgRolesMap roles; ///< Selected Player Role/s
};
/// Stores player data related to proposal to join
struct LfgProposalPlayer
{
LfgProposalPlayer(): role(0), accept(LFG_ANSWER_PENDING), groupLowGuid(0) {};
uint8 role; ///< Proposed role
LfgAnswer accept; ///< Accept status (-1 not answer | 0 Not agree | 1 agree)
uint32 groupLowGuid; ///< Original group guid (Low guid) 0 if no original group
};
/// Stores group data related to proposal to join
struct LfgProposal
{
LfgProposal(uint32 dungeon = 0): dungeonId(dungeon), state(LFG_PROPOSAL_INITIATING), groupLowGuid(0), leader(0), cancelTime(0) {}
~LfgProposal()
{
for (LfgProposalPlayerMap::iterator it = players.begin(); it != players.end(); ++it)
delete it->second;
};
uint32 dungeonId; ///< Dungeon to join
LfgProposalState state; ///< State of the proposal
uint32 groupLowGuid; ///< Proposal group (0 if new)
uint64 leader; ///< Leader guid.
time_t cancelTime; ///< Time when we will cancel this proposal
LfgGuidList queues; ///< Queue Ids to remove/readd
LfgProposalPlayerMap players; ///< Players data
};
/// Stores all rolecheck info of a group that wants to join
struct LfgRoleCheck
{
time_t cancelTime; ///< Time when the rolecheck will fail
LfgRolesMap roles; ///< Player selected roles
LfgRoleCheckState state; ///< State of the rolecheck
LfgDungeonSet dungeons; ///< Dungeons group is applying for (expanded random dungeons)
uint32 rDungeonId; ///< Random Dungeon Id.
uint64 leader; ///< Leader of the group
};
/// Stores information of a current vote to kick someone from a group
struct LfgPlayerBoot
{
time_t cancelTime; ///< Time left to vote
bool inProgress; ///< Vote in progress
LfgAnswerMap votes; ///< Player votes (-1 not answer | 0 Not agree | 1 agree)
uint64 victim; ///< Player guid to be kicked (can't vote)
uint8 votedNeeded; ///< Votes needed to kick the player
std::string reason; ///< kick reason
};
class LFGMgr
{
friend class ACE_Singleton<LFGMgr, ACE_Null_Mutex>;
private:
LFGMgr();
~LFGMgr();
public:
void Update(uint32 diff);
// Reward
void LoadRewards();
void RewardDungeonDoneFor(const uint32 dungeonId, Player* player);
LfgReward const* GetRandomDungeonReward(uint32 dungeon, uint8 level);
// Queue
void Join(Player* player, uint8 roles, const LfgDungeonSet& dungeons, const std::string& comment);
void Leave(Player* player, Group* grp = NULL);
// Role Check
void UpdateRoleCheck(uint64 gguid, uint64 guid = 0, uint8 roles = ROLE_NONE);
// Proposals
void UpdateProposal(uint32 proposalId, uint64 guid, bool accept);
// Teleportation
void TeleportPlayer(Player* player, bool out, bool fromOpcode = false);
// Vote kick
void InitBoot(Group* grp, uint64 kguid, uint64 vguid, std::string reason);
void UpdateBoot(Player* player, bool accept);
void OfferContinue(Group* grp);
void InitializeLockedDungeons(Player* player);
void _LoadFromDB(Field* fields, uint64 guid);
void _SaveToDB(uint64 guid, uint32 db_guid);
void SetComment(uint64 guid, const std::string& comment);
const LfgLockMap& GetLockedDungeons(uint64 guid);
LfgState GetState(uint64 guid);
const LfgDungeonSet& GetSelectedDungeons(uint64 guid);
uint32 GetDungeon(uint64 guid, bool asId = true);
void SetState(uint64 guid, LfgState state);
void ClearState(uint64 guid);
void RemovePlayerData(uint64 guid);
void RemoveGroupData(uint64 guid);
uint8 GetKicksLeft(uint64 gguid);
uint8 GetVotesNeeded(uint64 gguid);
bool IsTeleported(uint64 pguid);
void SetRoles(uint64 guid, uint8 roles);
void SetSelectedDungeons(uint64 guid, const LfgDungeonSet& dungeons);
private:
uint8 GetRoles(uint64 guid);
const std::string& GetComment(uint64 gguid);
void RestoreState(uint64 guid);
void SetDungeon(uint64 guid, uint32 dungeon);
void SetLockedDungeons(uint64 guid, const LfgLockMap& lock);
void DecreaseKicksLeft(uint64 guid);
// Queue
void AddToQueue(uint64 guid, uint8 queueId);
bool RemoveFromQueue(uint64 guid);
// Proposals
void RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType type);
// Group Matching
LfgProposal* FindNewGroups(LfgGuidList& check, LfgGuidList& all);
bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true);
bool CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal);
void GetCompatibleDungeons(LfgDungeonSet& dungeons, const PlayerSet& players, LfgLockPartyMap& lockMap);
void SetCompatibles(std::string concatenatedGuids, bool compatibles);
LfgAnswer GetCompatibles(std::string concatenatedGuids);
void RemoveFromCompatibles(uint64 guid);
// Generic
const LfgDungeonSet& GetDungeonsByRandom(uint32 randomdungeon);
LfgType GetDungeonType(uint32 dungeon);
std::string ConcatenateGuids(LfgGuidList check);
// General variables
bool m_update; ///< Doing an update?
uint32 m_QueueTimer; ///< used to check interval of update
uint32 m_lfgProposalId; ///< used as internal counter for proposals
int32 m_WaitTimeAvg; ///< Average wait time to find a group queuing as multiple roles
int32 m_WaitTimeTank; ///< Average wait time to find a group queuing as tank
int32 m_WaitTimeHealer; ///< Average wait time to find a group queuing as healer
int32 m_WaitTimeDps; ///< Average wait time to find a group queuing as dps
uint32 m_NumWaitTimeAvg; ///< Num of players used to calc avs wait time
uint32 m_NumWaitTimeTank; ///< Num of players used to calc tank wait time
uint32 m_NumWaitTimeHealer; ///< Num of players used to calc healers wait time
uint32 m_NumWaitTimeDps; ///< Num of players used to calc dps wait time
LfgDungeonMap m_CachedDungeonMap; ///< Stores all dungeons by groupType
// Reward System
LfgRewardMap m_RewardMap; ///< Stores rewards for random dungeons
// Queue
LfgQueueInfoMap m_QueueInfoMap; ///< Queued groups
LfgGuidListMap m_currentQueue; ///< Ordered list. Used to find groups
LfgGuidListMap m_newToQueue; ///< New groups to add to queue
LfgCompatibleMap m_CompatibleMap; ///< Compatible dungeons
LfgGuidList m_teleport; ///< Players being teleported
// Rolecheck - Proposal - Vote Kicks
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()
#endif
|