Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
LFGHandler.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Group.h"
7#include "LFGMgr.h"
8#include "ObjectMgr.h"
9#include "Opcodes.h"
10#include "Player.h"
11#include "WorldPacket.h"
12#include "WorldSession.h"
13
14#include <vector>
15
16namespace
17{
18 bool HasPacketBytes(WorldPacket const& packet, size_t bytes)
19 {
20 return packet.rpos() + bytes <= packet.size();
21 }
22
23 void SendLfrRemovedFromQueue(WorldSession* session)
24 {
25 session->SendLfgClearStatus();
26 }
27}
28
30{
31 for (lfg::LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it)
32 {
33 data << uint32(it->second.currentItemLevel); // Current itemLevel
34 data << uint32(it->first); // Dungeon entry (id + type)
35 data << uint32(it->second.requiredItemLevel); // Required itemLevel
36 data << uint32(it->second.lockStatus); // Lock status
37 }
38}
39
41{
42 data.WriteBits(lockMap.size(), 22);
43 for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it)
44 {
45 bool hasGuid = true;
46 ObjectGuid PlayerGUID = it->first;
47
48 data.WriteBit(hasGuid);
49 data.WriteGuidMask(PlayerGUID, 3, 6, 0, 5, 2, 7, 4, 1);
50 data.WriteBits(it->second.size(), 20); // Size of lock dungeons
51
52 data.FlushBits();
53
54 BuildPlayerLockDungeonBlock(data, it->second);
55 data.WriteGuidBytes(PlayerGUID, 0, 3, 1, 4, 6, 2, 5, 7);
56 }
57}
58
59void BuildQuestReward(WorldPacket& data, Quest const* quest, Player* player)
60{
61 uint8 rewCount = quest->GetRewItemsCount() + quest->GetRewCurrencyCount();
62
63 data << uint32(quest->GetRewMoney());
64 data << uint32(quest->XPValue(player));
65 data << uint8(rewCount);
66 if (rewCount)
67 {
68 for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
69 {
70 if (uint32 currencyId = quest->RewardCurrencyId[i])
71 {
72 data << uint32(currencyId);
73 data << uint32(0);
74 data << uint32(quest->RewardCurrencyCount[i]);
75 data << uint8(1); // Is currency
76 }
77 }
78
79 for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
80 {
81 if (uint32 itemId = quest->RewardItemId[i])
82 {
83 ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
84 data << uint32(itemId);
85 data << uint32(item ? item->DisplayInfoID : 0);
86 data << uint32(quest->RewardItemIdCount[i]);
87 data << uint8(0); // Is currency
88 }
89 }
90 }
91}
92
94{
96 {
97 recvData.rfinish();
98 return;
99 }
100 uint32 roles;
101 bool QueueAsGroup;
102 uint8 PartyIndex;
103
104 recvData >> PartyIndex; // PartyIndex
105 for (int32 i = 0; i < 3; ++i)
106 recvData.read_skip<uint32>(); // Needs
107 recvData >> roles; // Roles
108 uint32 numDungeons = recvData.ReadBits(22);
109 uint32 commentLen = recvData.ReadBits(8);
110 QueueAsGroup = recvData.ReadBit(); // QueueAsGroup
111
112 if (!numDungeons)
113 {
114 SF_LOG_DEBUG("lfg", "CMSG_LFD_JOIN %s no dungeons selected", GetPlayerInfo().c_str());
115 recvData.rfinish();
116 return;
117 }
118
119 lfg::LfgDungeonSet newDungeons;
120 for (uint32 i = 0; i < numDungeons; ++i)
121 {
122 uint32 dungeon;
123 recvData >> dungeon;
124 newDungeons.insert((dungeon & 0x00FFFFFF)); // remove the type from the dungeon entry
125 }
126
127 std::string comment = recvData.ReadString(commentLen);
128
129 SF_LOG_DEBUG("lfg", "CMSG_LFD_JOIN %s roles: %u, Dungeons: %u, Comment: %s",
130 GetPlayerInfo().c_str(), roles, uint8(newDungeons.size()), comment.c_str());
131
132 if (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() == GetPlayer()->GetGUID())
133 {
134 if (!GetPlayer()->GetGroup()->RoleCheckAllResponded())
135 {
136 SendRolePollInform(GetPlayer()->GetObjectGUID(), PartyIndex);
137 return;
138 }
139 }
140
141 sLFGMgr->JoinLfg(GetPlayer(), uint8(roles), newDungeons, comment);
142}
143
145{
146 ObjectGuid RequesterGUID;
147 Group* group = GetPlayer()->GetGroup();
148 if (!HasPacketBytes(recvData, sizeof(uint32) * 4))
149 {
150 SF_LOG_DEBUG("lfg.leave", "CMSG_LFD_LEAVE %s malformed packet size: %u",
151 GetPlayerInfo().c_str(), uint32(recvData.size()));
153 return;
154 }
155
156 uint32 ticketType = recvData.read<uint32>();
157 uint32 ticketId = recvData.read<uint32>();
158 uint32 ticketTime = recvData.read<uint32>();
159 uint32 slotOrQueueId = recvData.read<uint32>();
160 uint8 queueID = uint8(slotOrQueueId);
161 bool const clientTicketLeave = ticketType == 3 && ticketId <= 0xFF;
162
163 if (clientTicketLeave)
164 queueID = uint8(ticketId);
165
166 recvData.ReadGuidMask(RequesterGUID, 6, 0, 2, 3, 1, 5, 4, 7);
167 recvData.ReadGuidBytes(RequesterGUID, 2, 0, 4, 6, 3, 1, 5, 7);
168
169 if (!group)
170 {
171 uint64 guid = GetPlayer()->GetGUID();
172 uint8 activeQueueId = sLFGMgr->GetQueueId(guid);
173 if (uint64(RequesterGUID) && uint64(RequesterGUID) != guid)
174 SF_LOG_DEBUG("lfg.leave", "CMSG_LFD_LEAVE %s ignored requester guid %lu for solo queue leave.",
175 GetPlayerInfo().c_str(), uint64(RequesterGUID));
176 if (queueID != activeQueueId)
177 SF_LOG_DEBUG("lfg.leave", "CMSG_LFD_LEAVE %s requested queue %u but active queue is %u.",
178 GetPlayerInfo().c_str(), queueID, activeQueueId);
179
180 SF_LOG_DEBUG("lfg.leave", "CMSG_LFD_LEAVE Player: %lu left solo queue ticket type %u id %u time %u slot %u.",
181 guid, ticketType, ticketId, ticketTime, slotOrQueueId);
182 sLFGMgr->LeaveSoloLfg(guid, activeQueueId);
183 SendLfgClearStatus(0, queueID, clientTicketLeave);
184 return;
185 }
186
187 uint64 guid = GetPlayer()->GetGUID();
188 uint64 leaderGuid = group->GetLeaderGUID();
189 uint64 groupGuid = group->GetGUID();
190
191 if (uint64(RequesterGUID) && uint64(RequesterGUID) != guid && uint64(RequesterGUID) != leaderGuid)
192 SF_LOG_DEBUG("lfg.leave", "CMSG_LFD_LEAVE %s ignored requester guid %lu for group queue leave.",
193 GetPlayerInfo().c_str(), uint64(RequesterGUID));
194 if (queueID != sLFGMgr->GetQueueId(groupGuid))
195 SF_LOG_DEBUG("lfg.leave", "CMSG_LFD_LEAVE %s requested queue %u but active group queue is %u.",
196 GetPlayerInfo().c_str(), queueID, sLFGMgr->GetQueueId(groupGuid));
197
198 lfg::LfgState const groupState = sLFGMgr->GetState(groupGuid);
199 bool const disbandDungeonGroup = group->isLFGGroup() &&
200 (groupState == lfg::LFG_STATE_DUNGEON || groupState == lfg::LFG_STATE_FINISHED_DUNGEON);
201
202 if (disbandDungeonGroup)
203 {
204 group->Disband();
205 return;
206 }
207
208 // Check cheating - only leader can leave the queue
209 if (leaderGuid != guid)
210 {
211 SF_LOG_DEBUG("lfg.leave", "CMSG_LFD_LEAVE %s ignored non-leader group queue leave.",
212 GetPlayerInfo().c_str());
213 return;
214 }
215
216 SF_LOG_DEBUG("lfg.leave", "CMSG_LFD_LEAVE GroupLeader: %lu left group queue.", guid);
217 sLFGMgr->LeaveLfg(groupGuid);
218 SendLfgClearStatus(0, queueID, clientTicketLeave);
219}
220
222{
223 uint32 ProposalID;
224 bool Accepted;
225
226 ObjectGuid guid1, guid2;
227
228 recvData >> ProposalID; // ProposalID
229 recvData.read_skip<uint32>(); // Id
230 recvData.read_skip<uint32>(); // Type
231 recvData.read_skip<uint32>(); // UnixTime
232
233 Accepted = recvData.ReadBit();
234 recvData.ReadGuidMask(guid1, 6, 0, 2, 4);
235 recvData.ReadGuidMask(guid2, 6, 7);
236 recvData.ReadGuidMask(guid1, 3);
237 recvData.ReadGuidMask(guid2, 4);
238 recvData.ReadGuidMask(guid1, 7);
239 recvData.ReadGuidMask(guid2, 1);
240 recvData.ReadGuidMask(guid1, 5);
241 recvData.ReadGuidMask(guid2, 0);
242 recvData.ReadGuidMask(guid1, 1);
243 recvData.ReadGuidMask(guid2, 2, 3, 5);
244
245 recvData.ReadGuidBytes(guid1, 3, 6, 4, 1);
246 recvData.ReadGuidBytes(guid2, 7, 0);
247 recvData.ReadGuidBytes(guid1, 7);
248 recvData.ReadGuidBytes(guid2, 6);
249 recvData.ReadGuidBytes(guid1, 5);
250 recvData.ReadGuidBytes(guid2, 3, 1, 5, 4);
251 recvData.ReadGuidBytes(guid1, 0, 2);
252 recvData.ReadGuidBytes(guid2, 2);
253
254 SF_LOG_DEBUG("lfg", "CMSG_LFD_PROPOSAL_RESULT %s proposal: %u accept: %u",
255 GetPlayerInfo().c_str(), ProposalID, Accepted ? 1 : 0);
256 sLFGMgr->UpdateProposal(ProposalID, GetPlayer()->GetGUID(), Accepted);
257}
258
260{
261 uint32 roles = recvData.read<uint32>();
262 recvData.read_skip<uint8>();
263 uint64 guid = GetPlayer()->GetGUID();
264 Group* group = GetPlayer()->GetGroup();
265 if (!group)
266 {
267 SF_LOG_DEBUG("lfg", "CMSG_LFG_SET_ROLES %s Not in group",
268 GetPlayerInfo().c_str());
269 return;
270 }
271 uint64 gguid = group->GetGUID();
272 SF_LOG_DEBUG("lfg", "CMSG_LFG_SET_ROLES: Group %u, Player %s, Roles: %u",
273 GUID_LOPART(gguid), GetPlayerInfo().c_str(), roles);
274 sLFGMgr->UpdateRoleCheck(gguid, guid, roles);
275}
276
278{
279 std::string comment;
280 recvData >> comment;
281
282 SF_LOG_DEBUG("lfg", "CMSG_LFG_SET_COMMENT %s comment: %s",
283 GetPlayerInfo().c_str(), comment.c_str());
284
285 sLFGMgr->SetComment(GetPlayer()->GetGUID(), comment);
286}
287
289{
290 bool agree; // Agree to kick player
291 recvData >> agree;
292
293 uint64 guid = GetPlayer()->GetGUID();
294 SF_LOG_DEBUG("lfg", "CMSG_LFD_SET_BOOT_VOTE %s agree: %u",
295 GetPlayerInfo().c_str(), agree ? 1 : 0);
296 sLFGMgr->UpdateBoot(guid, agree);
297}
298
300{
301 bool out;
302 recvData >> out;
303
304 SF_LOG_DEBUG("lfg", "CMSG_LFD_TELEPORT %s out: %u",
305 GetPlayerInfo().c_str(), out ? 1 : 0);
306 sLFGMgr->TeleportPlayer(GetPlayer(), out, true);
307}
308
310{
311 uint8 partyIndex = 0;
312 recvData >> partyIndex; // partyIndex NYI
313 bool forPlayer = recvData.ReadBit();
314 SF_LOG_DEBUG("lfg", "CMSG_LFD_LOCK_INFO_REQUEST %s for %s", GetPlayerInfo().c_str(), (forPlayer ? "player" : "party"));
315
316 if (forPlayer)
318 else
320}
321
323{
324 if (!GetPlayer())
325 return;
326
327 uint64 guid = GetPlayer()->GetGUID();
328 ObjectGuid playerGuid = guid;
329 bool const hasPlayerGuid = true;
330
331 // Get Random dungeons that can be done at a certain level and expansion
332 uint8 level = GetPlayer()->getLevel();
333 lfg::LfgDungeonSet const& randomDungeons =
334 sLFGMgr->GetRandomAndSeasonalDungeons(level, GetPlayer()->GetSession()->Expansion());
335
336 // Get player locked Dungeons
337 lfg::LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid);
338 uint32 rsize = uint32(randomDungeons.size());
339 uint32 lsize = uint32(lock.size());
340
341 SF_LOG_DEBUG("lfg", "SMSG_LFD_PLAYER_INFO %s", GetPlayerInfo().c_str());
342 WorldPacket data(SMSG_LFD_PLAYER_INFO, 1 + rsize * (4 + 1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4) + 4 + lsize * (1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4));
343 ByteBuffer rewardData;
344
345 data.WriteBits(lock.size(), 20); // locksize count
346 data.WriteBit(hasPlayerGuid);
347 data.WriteBits(randomDungeons.size(), 17);
348
349 for (lfg::LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it)
350 {
351 lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level);
352 Quest const* quest = NULL;
353 bool firstReward = false;
354
355 if (reward)
356 {
357 quest = sObjectMgr->GetQuestTemplate(reward->firstQuest);
358 if (quest)
359 {
360 bool done = !GetPlayer()->CanRewardQuest(quest, false);
361 if (done)
362 quest = sObjectMgr->GetQuestTemplate(reward->otherQuest);
363
364 firstReward = !done;
365 }
366 }
367
368 bool const shortageEligible = !GetPlayer()->GetGroup();
369 uint8 const shortageCount = shortageEligible ? lfg::LFG_ROLE_SHORTAGE_MAX : 0;
370
371 data.WriteBit(firstReward);
372 data.WriteBit(shortageEligible);
373 data.WriteBits(0, 21); // Additional currency count
374 data.WriteBits(shortageCount, 19);
375 data.WriteBits(quest ? quest->GetRewItemsCount() : 0, 20);
376
377 for (uint8 i = 0; i < shortageCount; ++i)
378 {
379 data.WriteBits(0, 21); // Shortage currency count
380 data.WriteBits(0, 20); // Shortage item count
381 data.WriteBits(0, 21); // Extra shortage currency count
382 }
383
384 data.WriteBits(quest ? quest->GetRewCurrencyCount() : 0, 21);
385
386 rewardData << uint32(quest ? quest->XPValue(GetPlayer()) : 0);
387
388 for (uint8 i = 0; i < shortageCount; ++i)
389 {
390 rewardData << uint32(0); // Shortage reward money
392 rewardData << uint32(0);
393 }
394
395 rewardData << uint32(0); // SpecificQuantity
396 rewardData << uint32(0); // PurseLimit
397 rewardData << uint32(quest ? quest->GetRewMoney() : 0);
398
399 if (quest && quest->GetRewItemsCount())
400 {
401 for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
402 {
403 if (!quest->RewardItemId[i])
404 continue;
405
406 ItemTemplate const* item = sObjectMgr->GetItemTemplate(quest->RewardItemId[i]);
407 rewardData << uint32(quest->RewardItemIdCount[i]);
408 rewardData << uint32(quest->RewardItemId[i]);
409 rewardData << uint32(item ? item->DisplayInfoID : 0);
410 }
411 }
412
413 rewardData << uint32(0); // OverallQuantity
414 rewardData << uint32(0); // PurseWeeklyQuantity
415 rewardData << uint32(1); // OverallLimit
416 rewardData << uint32(1); // Quantity
417 rewardData << uint32(0); // CompletionCurrencyID
418 rewardData << uint32(*it); // Dungeon Entry (id + type)
419
420 if (quest && quest->GetRewCurrencyCount())
421 {
422 for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
423 {
424 if (!quest->RewardCurrencyId[i])
425 continue;
426
427 rewardData << uint32(quest->RewardCurrencyId[i]);
428 rewardData << uint32(quest->RewardCurrencyCount[i] * 100);
429 }
430 }
431
432 rewardData << uint32(0); // PurseWeeklyLimit
433 rewardData << uint32(0); // Mask
434 rewardData << uint32(0); // PurseQuantity
435 rewardData << uint32(1); // CompletionLimit
436 rewardData << uint32(1); // SpecificLimit
437 rewardData << uint32(0); // CompletedMask
438 rewardData << uint32(1); // CompletionQuantity
439 }
440
441 if (hasPlayerGuid)
442 data.WriteGuidMask(playerGuid, 5, 1, 2, 7, 3, 0, 6, 4);
443
444 data.FlushBits();
445
446 if (hasPlayerGuid)
447 data.WriteGuidBytes(playerGuid, 7, 2, 3, 0, 4, 5, 6, 1);
448
449 data.append(rewardData);
450
451 for (lfg::LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it)
452 {
453 data << uint32(it->first); // Dungeon entry (id + type)
454 data << uint32(it->second.lockStatus); // Lock status
455 data << uint32(it->second.currentItemLevel); // Current itemLevel
456 data << uint32(it->second.requiredItemLevel); // Required itemLevel
457 }
458 SendPacket(&data);
459}
460
462{
463 uint64 guid = GetPlayer()->GetGUID();
464 Group* group = GetPlayer()->GetGroup();
465 if (!group)
466 return;
467
468 // Get the locked dungeons of the other party members
469 lfg::LfgLockPartyMap lockMap;
470 for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
471 {
472 Player* plrg = itr->GetSource();
473 if (!plrg)
474 continue;
475
476 uint64 pguid = plrg->GetGUID();
477 if (pguid == guid)
478 continue;
479
480 lockMap[pguid] = sLFGMgr->GetLockedDungeons(pguid);
481 }
482
483 uint32 size = 0;
484 for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it)
485 size += 8 + 4 + uint32(it->second.size()) * (4 + 4 + 4 + 4);
486
487 SF_LOG_DEBUG("lfg", "SMSG_LFD_PARTY_INFO %s", GetPlayerInfo().c_str());
488 WorldPacket data(SMSG_LFD_PARTY_INFO, 1 + size);
489 BuildPartyLockDungeonBlock(data, lockMap);
490 SendPacket(&data);
491}
492
494{
495 if (!HasPacketBytes(recvData, sizeof(uint32)))
496 {
497 SF_LOG_DEBUG("lfg.lfr", "CMSG_LFG_LFR_JOIN %s malformed packet size: %u",
498 GetPlayerInfo().c_str(), uint32(recvData.size()));
500 SendLfrRemovedFromQueue(this);
501 return;
502 }
503
504 uint32 entry; // Raid id to search
505 recvData >> entry;
506 bool const isRaidFinderDungeon = sLFGMgr->IsRaidFinderDungeon(entry);
507
508 SF_LOG_DEBUG("lfg.lfr", "CMSG_LFG_LFR_JOIN %s dungeon entry: %u isRaid: %u size: %u",
509 GetPlayerInfo().c_str(), entry, isRaidFinderDungeon ? 1 : 0, uint32(recvData.size()));
510
511 if (!isRaidFinderDungeon)
512 {
514 SendLfrRemovedFromQueue(this);
515 return;
516 }
517
518 // Matching is intentionally not enabled in the scaffolding slice.
520 SendLfrRemovedFromQueue(this);
521}
522
524{
525 if (!HasPacketBytes(recvData, sizeof(uint32)))
526 {
527 SF_LOG_DEBUG("lfg.lfr", "CMSG_LFG_LFR_LEAVE %s malformed packet size: %u",
528 GetPlayerInfo().c_str(), uint32(recvData.size()));
529 SendLfrRemovedFromQueue(this);
530 return;
531 }
532
533 uint32 dungeonId; // Raid id queue to leave
534 recvData >> dungeonId;
535 bool const isRaidFinderDungeon = sLFGMgr->IsRaidFinderDungeon(dungeonId);
536
537 SF_LOG_DEBUG("lfg.lfr", "CMSG_LFG_LFR_LEAVE %s dungeonId: %u isRaid: %u size: %u",
538 GetPlayerInfo().c_str(), dungeonId, isRaidFinderDungeon ? 1 : 0, uint32(recvData.size()));
539
540 SendLfrRemovedFromQueue(this);
541}
542
544{
545 SF_LOG_DEBUG("lfg", "CMSG_LFG_GET_STATUS %s", GetPlayerInfo().c_str());
546
547 uint64 guid = GetPlayer()->GetGUID();
548 lfg::LfgUpdateData updateData = sLFGMgr->GetLfgStatus(guid);
549 bool hasActiveProposal = updateData.state == lfg::LFG_STATE_PROPOSAL;
550
551 if (Group* group = GetPlayer()->GetGroup())
552 {
553 if (group->isLFGGroup() && sLFGMgr->GetState(group->GetGUID()) == lfg::LFG_STATE_NONE)
554 {
555 uint64 const groupGuid = group->GetGUID();
556 SF_LOG_DEBUG("lfg.status", "CMSG_LFG_GET_STATUS %s found stale LFG group %u with no finder state; disbanding group.",
557 GetPlayerInfo().c_str(), GUID_LOPART(groupGuid));
558 group->Disband();
559 SendLfgLfrList(false);
560 return;
561 }
562 }
563
564 if (updateData.state == lfg::LFG_STATE_NONE)
565 {
566 SendLfgLfrList(false);
567 return;
568 }
569
570 if (GetPlayer()->GetGroup())
571 {
572 SendLfgUpdateStatus(updateData, true);
573
574 bool const inDungeonStatus = updateData.updateType == lfg::LFG_UPDATETYPE_UPDATE_STATUS &&
575 (updateData.state == lfg::LFG_STATE_DUNGEON || updateData.state == lfg::LFG_STATE_FINISHED_DUNGEON);
576 if (!inDungeonStatus)
577 {
578 updateData.dungeons.clear();
579 SendLfgUpdateStatus(updateData, false);
580 }
581 }
582 else
583 {
584 SendLfgUpdateStatus(updateData, false);
585 updateData.dungeons.clear();
586 SendLfgUpdateStatus(updateData, true);
587 }
588
589 if (hasActiveProposal)
590 sLFGMgr->SendActiveProposal(guid);
591}
592
593void WorldSession::SendLfgUpdateStatus(lfg::LfgUpdateData const& updateData, bool party, uint64 queueGuidOverride, uint8 queueIdOverride)
594{
595 bool join = false;
596 bool queued = false;
597 uint8 size = uint8(updateData.dungeons.size());
598 ObjectGuid guid = _player->GetGUID();
599 uint64 queueGuid = _player->GetGUID();
600 if (queueGuidOverride)
601 {
602 guid = queueGuidOverride;
603 queueGuid = queueGuidOverride;
604 }
605 else if (party)
606 if (Group* group = _player->GetGroup())
607 {
608 guid = group->GetGUID();
609 queueGuid = group->GetGUID();
610 }
611
612 time_t joinTime = sLFGMgr->GetQueueJoinTime(queueGuid);
613 uint32 queueId = sLFGMgr->GetActiveQueueId(queueGuid);
614 if (!queueId && (updateData.updateType != lfg::LFG_UPDATETYPE_REMOVED_FROM_QUEUE || !updateData.dungeons.empty()))
615 queueId = sLFGMgr->GetQueueId(queueGuid);
616 if (queueIdOverride)
617 queueId = queueIdOverride;
618 uint8 dungeonCategory = 0;
619 std::vector<uint32> dungeonEntries;
620 dungeonEntries.reserve(updateData.dungeons.size());
621
622 for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
623 {
624 uint32 const dungeonId = (*it & 0xFF000000) ? (*it & 0x00FFFFFF) : *it;
625 uint32 const dungeonEntry = sLFGMgr->GetLFGDungeonEntry(dungeonId);
626 if (dungeonEntry)
627 dungeonEntries.push_back(dungeonEntry);
628 else
629 dungeonEntries.push_back(*it);
630
631 if (!dungeonCategory)
632 dungeonCategory = sLFGMgr->GetLFGDungeonCategory(dungeonId);
633 }
634
635 switch (updateData.updateType)
636 {
637 case lfg::LFG_UPDATETYPE_JOIN_QUEUE_INITIAL: // Joined queue outside the dungeon
638 join = true;
639 break;
641 case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success
642 join = true;
643 queued = true;
644 break;
646 join = true;
647 break;
649 queued = updateData.state == lfg::LFG_STATE_QUEUED;
650 join = queued;
651 break;
652 default:
653 break;
654 }
655
656 SF_LOG_DEBUG("lfg", "SMSG_LFD_UPDATE_STATUS %s updatetype: %u, party %s",
657 GetPlayerInfo().c_str(), updateData.updateType, party ? "true" : "false");
658
659 WorldPacket data(SMSG_LFD_UPDATE_STATUS, 1 + 8 + 3 + 2 + 1 + updateData.comment.length() + 4 + 4 + 1 + 1 + 1 + 4 + (4 * size));
660
661 data.WriteBits(updateData.comment.length(), 8); // CommentLen
662 data.WriteBit(true); // IsParty
663 data.WriteBit(join); // Joined
664 data.WriteBits(size, 22); // Slots
665 data.WriteGuidMask(guid, 2, 3, 1);
666 data.WriteBit(join); // Joined
667 data.WriteGuidMask(guid, 7, 6, 0);
668 data.WriteBit(true); // NotifyUI
669 data.WriteBit(queued); // Queued
670 data.WriteBits(0, 24); // SuspendedPlayers
671 data.WriteGuidMask(guid, 5);
672 //forloop 75 SuspendedPlayers
673 data.WriteGuidMask(guid, 4);
674
675 data.FlushBits();
676
677 data.WriteGuidBytes(guid, 3);
678 for (uint8 i = 0; i < 3; ++i)
679 data << uint8(0); // Needs
680
681 data.WriteGuidBytes(guid, 4);
682 //forloop 75 SuspendedPlayers
683 data.WriteGuidBytes(guid, 6);
684 data << uint8(updateData.updateType); // SubType
685 data << uint32(sLFGMgr->GetRoles(_player->GetGUID())); // RequestedRoles
686 data << uint32(queueId); // Id
687 data.WriteGuidBytes(guid, 5);
688 data.WriteString(updateData.comment); // Comment
689 data.WriteGuidBytes(guid, 2);
690 for (std::vector<uint32>::const_iterator it = dungeonEntries.begin(); it != dungeonEntries.end(); ++it)
691 data << uint32(*it);
692 data.WriteGuidBytes(guid, 0, 1);
693 data << uint32(joinTime); // UnixTime
694 data << uint8(dungeonCategory); // LFG category
695 data << uint32(3); // Type
696 data.WriteGuidBytes(guid, 7);
697 SendPacket(&data);
698}
699
701{
702 SF_LOG_DEBUG("lfg", "SMSG_LFG_ROLE_CHOSEN %s guid: %u roles: %u",
703 GetPlayerInfo().c_str(), GUID_LOPART(guid), roles);
704
705 ObjectGuid objGuid = guid;
706 WorldPacket data(SMSG_LFG_ROLE_CHOSEN, 8 + 1 + 4);
707 data.WriteGuidMask(objGuid, 6, 2, 1, 7, 0);
708 data.WriteBit(roles > 0); // Accepted
709 data.WriteGuidMask(objGuid, 3, 5, 4);
710 data.FlushBits();
711
712 data.WriteGuidBytes(objGuid, 0, 3, 6);
713 data << uint32(roles); // RoleMask
714 data.WriteGuidBytes(objGuid, 5, 1, 4, 2, 7);
715 SendPacket(&data);
716}
717
719{
720 lfg::LfgDungeonSet dungeons;
721 if (roleCheck.rDungeonId)
722 dungeons.insert(roleCheck.rDungeonId);
723 else
724 dungeons = roleCheck.dungeons;
725
726 ObjectGuid guid = roleCheck.leader;
727 lfg::LfgRolesMap::const_iterator itLeaderRoles = roleCheck.roles.find(guid);
728 uint8 roles = itLeaderRoles != roleCheck.roles.end() ? itLeaderRoles->second : 0;
729 Player* player = ObjectAccessor::FindPlayer(guid);
730
731 SF_LOG_DEBUG("lfg", "SMSG_LFD_ROLE_CHECK_UPDATE %s", GetPlayerInfo().c_str());
732 WorldPacket data(SMSG_LFD_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1));
733
734 data << uint8(roleCheck.state); // RoleCheckStatus
735 data << uint8(0); // PartyIndex
736 data.WriteBits(roleCheck.roles.size(), 21); // Members
737 if (!roleCheck.roles.empty())
738 {
739 // Leader info MUST be sent 1st :S
740 data.WriteBit(roleCheck.state == lfg::LFG_ROLECHECK_FINISHED); // RoleCheckComplete
741 data.WriteGuidMask(guid, 3, 0, 5, 2, 7, 1, 4, 6);
742
743 for (lfg::LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it)
744 {
745 if (it->first == roleCheck.leader)
746 continue;
747
748 guid = it->first;
749 data.WriteBit(roleCheck.state == lfg::LFG_ROLECHECK_FINISHED); // RoleCheckComplete
750 data.WriteGuidMask(guid, 3, 0, 5, 2, 7, 1, 4, 6);
751 }
752 }
753 data.WriteGuidMask(guid, 3, 5);
754 data.WriteBits(dungeons.size(), 22); // JoinSlots
755 data.WriteGuidMask(guid, 0, 7, 6, 1, 4, 2);
756 data.WriteBit(roleCheck.state == lfg::LFG_ROLECHECK_INITIALITING); // IsBeginning
757
758 data.FlushBits();
759
760 data.WriteGuidBytes(guid, 0);
761 if (!roleCheck.roles.empty())
762 {
763 // Leader info MUST be sent 1st :S
764 data << uint8(player ? player->getLevel() : 0); // Level
765 data.WriteGuidBytes(guid, 3, 6);
766 data << uint32(roles); // RolesDesired
767 data.WriteGuidBytes(guid, 2, 4, 0, 1, 5, 7);
768
769 for (lfg::LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it)
770 {
771 if (it->first == roleCheck.leader)
772 continue;
773
774 guid = it->first;
775 Player* member = ObjectAccessor::FindPlayer(guid);
776 data << uint8(member ? member->getLevel() : 0); // Level
777 data.WriteGuidBytes(guid, 3, 6);
778 data << uint32(it->second); // RolesDesired
779 data.WriteGuidBytes(guid, 2, 4, 0, 1, 5, 7);
780 }
781 }
782 data.WriteGuidBytes(guid, 1, 7, 6, 4, 3, 2, 5);
783 if (!dungeons.empty())
784 for (lfg::LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it)
785 data << uint32(sLFGMgr->GetLFGDungeonEntry(*it)); // Dungeon
786
787 SendPacket(&data);
788}
789
791{
792 uint32 size = 0;
793 ObjectGuid guid = GetPlayer()->GetGUID();
794 uint32 queueId = sLFGMgr->GetQueueId(_player->GetGUID());
795 for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it)
796 size += 8 + 4 + uint32(it->second.size()) * (4 + 4 + 4 + 4);
797
798 SF_LOG_DEBUG("lfg", "SMSG_LFD_JOIN_RESULT %s checkResult: %u checkValue: %u",
799 GetPlayerInfo().c_str(), joinData.result, joinData.state);
800
801 WorldPacket data(SMSG_LFD_JOIN_RESULT, 4 + 4 + size);
802
803 data.WriteGuidMask(guid, 7, 6, 3, 0);
804 data.WriteBits(joinData.lockmap.size(), 22); // BlackList
805
806 for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it)
807 {
808 ObjectGuid playerGuid = it->first;
809 data.WriteGuidMask(playerGuid, 3);
810 data.WriteBits(it->second.size(), 20); // Slots
811 data.WriteGuidMask(playerGuid, 6, 1, 4, 7, 2, 0, 5);
812 }
813
814 data.WriteGuidMask(guid, 5, 1, 4, 2);
815 data.FlushBits();
816 data << uint8(joinData.result); // Result
817
818 for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it)
819 {
820 ObjectGuid playerGuid = it->first;
821 data.WriteGuidBytes(playerGuid, 4);
822
823 for (lfg::LfgLockMap::const_iterator itr = it->second.begin(); itr != it->second.end(); ++itr)
824 {
825 data << uint32(itr->second.requiredItemLevel); // SubReason2
826 data << uint32(itr->second.currentItemLevel); // SubReason1
827 data << uint32(itr->second.lockStatus); // Reason
828 data << uint32(itr->first); // Slot
829 }
830 data.WriteGuidBytes(playerGuid, 1, 0, 5, 7, 3, 6, 2);
831 }
832
833 data << uint8(joinData.state); // ResultDetail
834 data.WriteGuidBytes(guid, 2);
835 data << uint32(time(NULL)); // UnixTime
836 data << uint32(queueId); // Id
837 data << uint32(3); // Type
838 data.WriteGuidBytes(guid, 6, 4, 1, 0, 5, 7, 3);
839 SendPacket(&data);
840}
841
843{
844 SF_LOG_DEBUG("lfg", "SMSG_LFD_QUEUE_STATUS %s dungeon: %u, waitTime: %d, "
845 "avgWaitTime: %d, waitTimeTanks: %d, waitTimeHealer: %d, waitTimeDps: %d, "
846 "queuedTime: %u, tanks: %u, healers: %u, dps: %u",
847 GetPlayerInfo().c_str(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg,
848 queueData.waitTimeTank, queueData.waitTimeHealer, queueData.waitTimeDps,
849 queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps);
850
851 ObjectGuid guid = _player->GetGUID();
852 WorldPacket data(SMSG_LFD_QUEUE_STATUS, 8 + (10 * 4) + (3 * 1));
853 data.WriteGuidMask(guid, 4, 3, 5, 1, 2, 0, 6, 7);
854 data << uint32(queueData.dungeonId); // Dungeon
855 data.WriteGuidBytes(guid, 0);
856 data << uint32(queueData.queuedTime); // Player wait time in queue
857 data.WriteGuidBytes(guid, 4);
858 data << uint32(queueData.joinTime); // Join time
859 data << int32(queueData.waitTimeTank); // Wait Tanks
860 data << uint8(queueData.tanks); // Tanks needed
861 data << int32(queueData.waitTimeHealer); // Wait Healers
862 data << uint8(queueData.healers); // Healers needed
863 data << int32(queueData.waitTimeDps); // Wait Dps
864 data << uint8(queueData.dps); // Dps needed
865 data << int32(queueData.waitTime); // Wait Time
866 data << int32(queueData.waitTimeAvg); // Average Wait time
867 data.WriteGuidBytes(guid, 1);
868 data << uint32(queueData.queueId); // Queue Id
869 data.WriteGuidBytes(guid, 7, 2);
870 data << uint32(3);
871 data.WriteGuidBytes(guid, 5, 3, 6);
872 SendPacket(&data);
873}
874
876{
877 if (!rewardData.rdungeonEntry || !rewardData.sdungeonEntry || !rewardData.quest)
878 return;
879
880 SF_LOG_DEBUG("lfg", "SMSG_LFG_PLAYER_REWARD %s rdungeonEntry: %u, sdungeonEntry: %u, done: %u",
881 GetPlayerInfo().c_str(), rewardData.rdungeonEntry, rewardData.sdungeonEntry, rewardData.done);
882
883 uint8 itemNum = rewardData.quest->GetRewItemsCount() + rewardData.quest->GetRewCurrencyCount();
884
885 WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4));
886 data << uint32(rewardData.rdungeonEntry); // Random Dungeon Finished
887 data << uint32(rewardData.sdungeonEntry); // Dungeon Finished
888 BuildQuestReward(data, rewardData.quest, GetPlayer());
889 SendPacket(&data);
890}
891
893{
894 uint64 guid = GetPlayer()->GetGUID();
895 lfg::LfgAnswerContainer::const_iterator itVote = boot.votes.find(guid);
896 lfg::LfgAnswer playerVote = itVote != boot.votes.end() ? itVote->second : lfg::LFG_ANSWER_PENDING;
897 uint8 votesNum = 0;
898 uint8 agreeNum = 0;
899 time_t now = time(NULL);
900 uint32 secsleft = boot.cancelTime > now ? uint32(boot.cancelTime - now) : 0;
901 for (lfg::LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it)
902 {
903 if (it->second != lfg::LFG_ANSWER_PENDING)
904 {
905 ++votesNum;
906 if (it->second == lfg::LFG_ANSWER_AGREE)
907 ++agreeNum;
908 }
909 }
910 SF_LOG_DEBUG("lfg", "SMSG_LFG_BOOT_PROPOSAL_UPDATE %s inProgress: %u - "
911 "didVote: %u - agree: %u - victim: %u votes: %u - agrees: %u - left: %u - "
912 "needed: %u - reason %s",
913 GetPlayerInfo().c_str(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING),
914 uint8(playerVote == lfg::LFG_ANSWER_AGREE), GUID_LOPART(boot.victim), votesNum, agreeNum,
915 secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str());
916 WorldPacket data(SMSG_LFD_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length());
917
918 ObjectGuid TargetGUID = boot.victim;
919
920 data.WriteBit(boot.reason.size() > 0);
921 data.WriteGuidMask(TargetGUID, 3);
922 data.WriteBit(playerVote != lfg::LFG_ANSWER_PENDING); // MyVoteCompleted
923 data.WriteBit(agreeNum >= lfg::LFG_GROUP_KICK_VOTES_NEEDED); // VotePassed
924 data.WriteBit(playerVote == lfg::LFG_ANSWER_AGREE); // MyVote
925 data.WriteGuidMask(TargetGUID, 6);
926 if (boot.reason.size() > 0)
927 {
928 data.WriteBits(boot.reason.size(), 8);
929 }
930 data.WriteBit(boot.inProgress); // VoteInProgress
931 data.WriteGuidMask(TargetGUID, 1, 7, 5, 2, 0, 4);
932
933 data.FlushBits();
934
935 data.WriteGuidBytes(TargetGUID, 2, 4, 3, 6);
936 data << uint32(lfg::LFG_GROUP_KICK_VOTES_NEEDED); // VotesNeeded
937 data << uint32(secsleft); // TimeLeft
938 if (boot.reason.size() > 0)
939 {
940 data.WriteString(boot.reason.c_str());
941 }
942 data.WriteGuidBytes(TargetGUID, 5, 0);
943 data << uint32(agreeNum); // BootVotes
944 data.WriteGuidBytes(TargetGUID, 7);
945 data << uint32(votesNum); // TotalVotes
946 data.WriteGuidBytes(TargetGUID, 1);
947 SendPacket(&data);
948}
949
951{
952 uint64 playerGuid = GetPlayer()->GetGUID();
953 lfg::LfgProposalPlayerContainer::const_iterator itSelf = proposal.players.find(playerGuid);
954 if (itSelf == proposal.players.end())
955 return;
956
957 uint64 originalGroup = itSelf->second.group;
958 bool silent = !proposal.isNew && originalGroup && originalGroup == proposal.group;
959 uint32 dungeonEntry = proposal.dungeonId;
960 uint64 queueGuid = originalGroup ? originalGroup : playerGuid;
961 uint32 queueId = sLFGMgr->GetQueueId(queueGuid);
962 time_t joinTime = sLFGMgr->GetQueueJoinTime(queueGuid);
963 if (!joinTime && queueGuid != playerGuid)
964 joinTime = sLFGMgr->GetQueueJoinTime(playerGuid);
965
966 SF_LOG_DEBUG("lfg", "SMSG_LFD_PROPOSAL_UPDATE %s state: %u",
967 GetPlayerInfo().c_str(), proposal.state);
968
969 // show random dungeon if player selected random dungeon and it's not lfg group
970 if (!silent)
971 {
972 lfg::LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(playerGuid);
973 if (!playerDungeons.empty() && playerDungeons.find(proposal.dungeonId) == playerDungeons.end())
974 dungeonEntry = (*playerDungeons.begin());
975 }
976
977 dungeonEntry = sLFGMgr->GetLFGDungeonEntry(dungeonEntry);
978
979 ObjectGuid queueGuidObject = queueGuid;
980 ObjectGuid slotGuid = uint64(dungeonEntry) | (uint64(0x1F45) << 48);
981 ByteBuffer roleData;
982
983 WorldPacket data(SMSG_LFD_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 + 1));
984 data.WriteGuidMask(slotGuid, 6, 0);
985 data.WriteGuidMask(queueGuidObject, 1, 7, 5);
986 data.WriteGuidMask(slotGuid, 5);
987 data.WriteGuidMask(queueGuidObject, 4);
988 data.WriteBit(silent); // ProposalSilent
989 data.WriteGuidMask(slotGuid, 2);
990 data.WriteGuidMask(queueGuidObject, 6);
991 data.WriteGuidMask(slotGuid, 3, 7);
992 data.WriteGuidMask(queueGuidObject, 3);
993 data.WriteBits(proposal.players.size(), 21); // Players
994 for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it)
995 {
996 data.WriteBit(it->second.group && it->second.group == proposal.group); // MyParty
997 data.WriteBit(it->first == playerGuid); // Me
998 data.WriteBit(it->second.accept != lfg::LFG_ANSWER_PENDING); // Responded
999 data.WriteBit(it->second.accept == lfg::LFG_ANSWER_AGREE); // Accepted
1000 data.WriteBit(it->second.group && it->second.group == originalGroup); // SameParty
1001
1002 uint8 role = it->second.role;
1003 if (proposal.leader != it->first)
1004 role &= ~lfg::PLAYER_ROLE_LEADER;
1005
1006 roleData << uint32(role);
1007 }
1008 data.WriteGuidMask(queueGuidObject, 2);
1009 data.WriteGuidMask(slotGuid, 4);
1010 data.WriteBit(0); // Unk
1011 data.WriteGuidMask(queueGuidObject, 0);
1012 data.WriteGuidMask(slotGuid, 1);
1013 data.FlushBits();
1014
1015 data.WriteGuidBytes(slotGuid, 1);
1016 data.WriteGuidBytes(queueGuidObject, 4);
1017 data.WriteGuidBytes(slotGuid, 4);
1018 data.WriteGuidBytes(queueGuidObject, 7);
1019 data.WriteGuidBytes(queueGuidObject, 2);
1020 data.WriteGuidBytes(queueGuidObject, 0);
1021 data << uint32(dungeonEntry); // Slot
1022 data << uint8(proposal.state); // State
1023 data << uint32(queueId); // Id
1024 data.WriteGuidBytes(slotGuid, 6);
1025 data << uint32(proposal.id); // ProposalID
1026 data.WriteGuidBytes(queueGuidObject, 5, 3);
1027 data << uint32(joinTime); // UnixTime
1028 data.WriteGuidBytes(slotGuid, 5);
1029 data.WriteGuidBytes(queueGuidObject, 6);
1030 data.append(roleData);
1031 data << uint32(proposal.encounters); // CompletedMask
1032 data.WriteGuidBytes(queueGuidObject, 7, 1);
1033 data.WriteGuidBytes(slotGuid, 0, 2);
1034 data << uint32(3); // Type
1035 data.WriteGuidBytes(slotGuid, 3);
1036 SendPacket(&data);
1037}
1038
1040{
1041 SF_LOG_DEBUG("lfg", "SMSG_LFG_LFR_LIST %s update: %u",
1042 GetPlayerInfo().c_str(), update ? 1 : 0);
1044 data << uint8(update); // In Lfg Queue?
1045 SendPacket(&data);
1046}
1047
1048void WorldSession::SendLfgClearStatus(uint64 lfgGroupGuid, uint8 queueIdOverride, bool groupLeave)
1049{
1050 if (groupLeave)
1051 SendLfgUpdateStatus(lfg::LfgUpdateData(lfg::LFG_UPDATETYPE_LEADER_UNK1), true, lfgGroupGuid, queueIdOverride);
1052
1054 SendLfgUpdateStatus(removed, false, 0, queueIdOverride);
1055 SendLfgUpdateStatus(removed, true, lfgGroupGuid, queueIdOverride);
1056 SendLfgLfrList(false);
1057}
1058
1060{
1061 SF_LOG_DEBUG("lfg", "SMSG_LFD_DISABLED %s", GetPlayerInfo().c_str());
1063 SendPacket(&data);
1064}
1065
1067{
1068 SF_LOG_DEBUG("lfg", "SMSG_LFD_OFFER_CONTINUE %s dungeon entry: %u",
1069 GetPlayerInfo().c_str(), dungeonEntry);
1071 data << uint32(dungeonEntry);
1072 SendPacket(&data);
1073}
1074
1076{
1077 SF_LOG_DEBUG("lfg", "SMSG_LFD_TELEPORT_DENIED %s reason: %u",
1078 GetPlayerInfo().c_str(), err);
1080 data.WriteBits(err, 4); // Reason
1081 data.FlushBits();
1082 SendPacket(&data);
1083}
1084
1085/*
1086void WorldSession::SendLfrUpdateListOpcode(uint32 dungeonEntry)
1087{
1088 SF_LOG_DEBUG("network", "SMSG_LFG_UPDATE_LIST %s dungeon entry: %u",
1089 GetPlayerInfo().c_str(), dungeonEntry);
1090 WorldPacket data(SMSG_LFG_UPDATE_LIST);
1091 SendPacket(&data);
1092}
1093*/
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
void BuildPartyLockDungeonBlock(WorldPacket &data, lfg::LfgLockPartyMap const &lockMap)
void BuildQuestReward(WorldPacket &data, Quest const *quest, Player *player)
void BuildPlayerLockDungeonBlock(WorldPacket &data, lfg::LfgLockMap const &lock)
#define sLFGMgr
Definition LFGMgr.h:518
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
uint32 GUID_LOPART(uint64 x)
#define sObjectMgr
Definition ObjectMgr.h:1617
#define QUEST_REWARDS_COUNT
Definition QuestDef.h:26
#define QUEST_REWARD_CURRENCY_COUNT
Definition QuestDef.h:30
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void read_skip()
Definition ByteBuffer.h:502
size_t rpos() const
Definition ByteBuffer.h:470
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void WriteString(std::string const &str)
Definition ByteBuffer.h:578
uint32 ReadBits(size_t bits)
Definition ByteBuffer.h:198
void ReadGuidBytes(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:256
void append(T value)
Definition ByteBuffer.h:147
void rfinish()
Definition ByteBuffer.h:478
std::string ReadString(size_t length)
Definition ByteBuffer.h:565
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:240
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
size_t size() const
Definition ByteBuffer.h:609
void FlushBits()
Definition ByteBuffer.h:154
bool ReadBit()
Definition ByteBuffer.h:180
Definition Group.h:147
bool isLFGGroup() const
Definition Group.cpp:2543
void Disband(bool hideDestroy=false)
Definition Group.cpp:700
uint64 GetGUID() const
Definition Group.cpp:2573
GroupReference * GetFirstMember()
Definition Group.h:225
uint64 GetLeaderGUID() const
Definition Group.cpp:2568
GroupReference * next()
static Player * FindPlayer(uint64)
uint64 GetGUID() const
Definition Object.h:119
bool CanRewardQuest(Quest const *quest, bool msg)
Group * GetGroup()
Definition Player.h:2972
uint32 RewardCurrencyCount[QUEST_REWARD_CURRENCY_COUNT]
Definition QuestDef.h:364
uint32 XPValue(Player *player) const
Definition QuestDef.cpp:150
uint32 RewardItemIdCount[QUEST_REWARDS_COUNT]
Definition QuestDef.h:354
int32 GetRewMoney() const
Definition QuestDef.cpp:181
uint32 RewardCurrencyId[QUEST_REWARD_CURRENCY_COUNT]
Definition QuestDef.h:363
uint32 GetRewItemsCount() const
Definition QuestDef.h:367
uint32 GetRewCurrencyCount() const
Definition QuestDef.h:368
uint32 RewardItemId[QUEST_REWARDS_COUNT]
Definition QuestDef.h:353
uint8 getLevel() const
Definition Unit.h:1528
Player session in the World.
void SendLfgPartyLockInfo()
void HandleLfgJoinOpcode(WorldPacket &recvData)
void SendLfgJoinResult(lfg::LfgJoinResultData const &joinData)
void HandleLfgLeaveOpcode(WorldPacket &recvData)
uint8 Expansion() const
void HandleLfgSetCommentOpcode(WorldPacket &recvData)
void SendLfgQueueStatus(lfg::LfgQueueStatusData const &queueData)
void SendLfgRoleChosen(uint64 guid, uint8 roles)
void SendLfgClearStatus(uint64 lfgGroupGuid=0, uint8 queueIdOverride=0, bool groupLeave=false)
void SendLfgTeleportError(uint8 err)
void HandleLFDSetBootVoteOpcode(WorldPacket &recvData)
void SendLfgLfrList(bool update)
std::string GetPlayerInfo() const
void SendLfgPlayerReward(lfg::LfgPlayerRewardData const &lfgPlayerRewardData)
Player * GetPlayer() const
void HandleLfgGetStatus(WorldPacket &recvData)
void SendLfgUpdateStatus(lfg::LfgUpdateData const &updateData, bool party, uint64 queueGuidOverride=0, uint8 queueIdOverride=0)
void SendLfgOfferContinue(uint32 dungeonEntry)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void HandleLfrLeaveOpcode(WorldPacket &recvData)
void SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const &pRoleCheck)
void SendLfgDisabled()
Player * _player
void HandleLFDTeleportOpcode(WorldPacket &recvData)
void HandleLfgSetRolesOpcode(WorldPacket &recvData)
void HandleLfgProposalResultOpcode(WorldPacket &recvData)
void HandleLFDGetLockInfoOpcode(WorldPacket &recvData)
void SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const &boot)
void HandleLfrJoinOpcode(WorldPacket &recvData)
void SendLfgPlayerLockInfo()
void SendRolePollInform(ObjectGuid guid, uint8 Index)
void SendLfgUpdateProposal(lfg::LfgProposal const &proposal)
@ SMSG_LFD_UPDATE_STATUS
Definition Opcodes.h:747
@ SMSG_LFD_DISABLED
Definition Opcodes.h:738
@ SMSG_LFD_BOOT_PROPOSAL_UPDATE
Definition Opcodes.h:737
@ SMSG_LFD_QUEUE_STATUS
Definition Opcodes.h:744
@ SMSG_LFD_JOIN_RESULT
Definition Opcodes.h:739
@ SMSG_LFD_PLAYER_INFO
Definition Opcodes.h:742
@ SMSG_LFG_ROLE_CHOSEN
Definition Opcodes.h:749
@ SMSG_LFD_TELEPORT_DENIED
Definition Opcodes.h:746
@ SMSG_LFD_PROPOSAL_UPDATE
Definition Opcodes.h:743
@ SMSG_LFD_ROLE_CHECK_UPDATE
Definition Opcodes.h:745
@ SMSG_LFG_PLAYER_REWARD
Definition Opcodes.h:748
@ SMSG_LFD_OFFER_CONTINUE
Definition Opcodes.h:740
@ SMSG_LFG_UPDATE_SEARCH
Definition Opcodes.h:750
@ SMSG_LFD_PARTY_INFO
Definition Opcodes.h:741
Definition LFG.cpp:11
@ LFG_OPTION_ENABLE_DUNGEON_FINDER
Definition LFGMgr.h:26
@ LFG_OPTION_ENABLE_RAID_BROWSER
Definition LFGMgr.h:27
@ LFG_ROLE_SHORTAGE_MAX
Definition LFG.h:35
LfgState
Definition LFG.h:61
@ LFG_STATE_FINISHED_DUNGEON
Definition LFG.h:68
@ LFG_STATE_DUNGEON
Definition LFG.h:67
@ LFG_STATE_PROPOSAL
Definition LFG.h:65
@ LFG_STATE_NONE
Definition LFG.h:62
@ LFG_STATE_QUEUED
Definition LFG.h:64
@ LFG_UPDATETYPE_ADDED_TO_QUEUE
Definition LFG.h:49
@ LFG_UPDATETYPE_UPDATE_STATUS
Definition LFG.h:51
@ LFG_UPDATETYPE_REMOVED_FROM_QUEUE
Definition LFG.h:45
@ LFG_UPDATETYPE_LEADER_UNK1
Definition LFG.h:41
@ LFG_UPDATETYPE_PROPOSAL_BEGIN
Definition LFG.h:50
@ LFG_UPDATETYPE_JOIN_QUEUE
Definition LFG.h:43
@ LFG_UPDATETYPE_JOIN_QUEUE_INITIAL
Definition LFG.h:54
@ LFG_GROUP_KICK_VOTES_NEEDED
Definition LFGMgr.h:39
LfgAnswer
Answer state (Also used to check compatibilites).
Definition LFG.h:91
@ LFG_ANSWER_AGREE
Definition LFG.h:94
@ LFG_ANSWER_PENDING
Definition LFG.h:92
std::map< uint32, LfgLockData > LfgLockMap
Definition LFG.h:108
std::set< uint32 > LfgDungeonSet
Definition LFG.h:107
@ LFG_ROLECHECK_FINISHED
Definition LFGMgr.h:118
@ LFG_ROLECHECK_INITIALITING
Definition LFGMgr.h:119
@ PLAYER_ROLE_DAMAGE
Definition LFG.h:27
@ PLAYER_ROLE_TANK
Definition LFG.h:25
@ PLAYER_ROLE_HEALER
Definition LFG.h:26
std::map< uint64, LfgLockMap > LfgLockPartyMap
Definition LFG.h:109
@ LFG_JOIN_DUNGEON_INVALID
Definition LFGMgr.h:104
@ LFG_JOIN_INTERNAL_ERROR
Definition LFGMgr.h:98
uint32 DisplayInfoID
LfgRoleCheckState state
Definition LFGMgr.h:154
LfgJoinResult result
Definition LFGMgr.h:153
LfgLockPartyMap lockmap
Definition LFGMgr.h:155
Stores information of a current vote to kick someone from a group.
Definition LFGMgr.h:258
uint64 victim
Player guid to be kicked (can't vote).
Definition LFGMgr.h:262
std::string reason
kick reason
Definition LFGMgr.h:263
time_t cancelTime
Time left to vote.
Definition LFGMgr.h:259
LfgAnswerContainer votes
Player votes (-1 not answer | 0 Not agree | 1 agree).
Definition LFGMgr.h:261
bool inProgress
Vote in progress.
Definition LFGMgr.h:260
Quest const * quest
Definition LFGMgr.h:202
Stores group data related to proposal to join.
Definition LFGMgr.h:227
uint32 dungeonId
Dungeon to join.
Definition LFGMgr.h:233
uint64 group
Proposal group (0 if new).
Definition LFGMgr.h:235
uint32 id
Proposal Id.
Definition LFGMgr.h:232
uint32 encounters
Dungeon Encounters.
Definition LFGMgr.h:238
uint64 leader
Leader guid.
Definition LFGMgr.h:236
LfgProposalPlayerContainer players
Players data.
Definition LFGMgr.h:242
bool isNew
Determines if it's new group or not.
Definition LFGMgr.h:239
LfgProposalState state
State of the proposal.
Definition LFGMgr.h:234
Reward info.
Definition LFGMgr.h:207
uint32 firstQuest
Definition LFGMgr.h:212
uint32 otherQuest
Definition LFGMgr.h:213
Stores all rolecheck info of a group that wants to join.
Definition LFGMgr.h:247
LfgDungeonSet dungeons
Dungeons group is applying for (expanded random dungeons).
Definition LFGMgr.h:251
LfgRolesMap roles
Player selected roles.
Definition LFGMgr.h:249
uint64 leader
Leader of the group.
Definition LFGMgr.h:253
LfgRoleCheckState state
State of the rolecheck.
Definition LFGMgr.h:250
uint32 rDungeonId
Random Dungeon Id.
Definition LFGMgr.h:252
LfgDungeonSet dungeons
Definition LFGMgr.h:169
LfgUpdateType updateType
Definition LFGMgr.h:167
std::string comment
Definition LFGMgr.h:170
LfgState state
Definition LFGMgr.h:168