18 bool HasPacketBytes(
WorldPacket const& packet,
size_t bytes)
20 return packet.
rpos() + bytes <= packet.
size();
31 for (lfg::LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it)
33 data <<
uint32(it->second.currentItemLevel);
35 data <<
uint32(it->second.requiredItemLevel);
36 data <<
uint32(it->second.lockStatus);
43 for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it)
65 data <<
uint8(rewCount);
72 data <<
uint32(currencyId);
104 recvData >> PartyIndex;
105 for (
int32 i = 0; i < 3; ++i)
110 QueueAsGroup = recvData.
ReadBit();
120 for (
uint32 i = 0; i < numDungeons; ++i)
124 newDungeons.insert((dungeon & 0x00FFFFFF));
127 std::string comment = recvData.
ReadString(commentLen);
129 SF_LOG_DEBUG(
"lfg",
"CMSG_LFD_JOIN %s roles: %u, Dungeons: %u, Comment: %s",
134 if (!
GetPlayer()->GetGroup()->RoleCheckAllResponded())
148 if (!HasPacketBytes(recvData,
sizeof(
uint32) * 4))
150 SF_LOG_DEBUG(
"lfg.leave",
"CMSG_LFD_LEAVE %s malformed packet size: %u",
161 bool const clientTicketLeave = ticketType == 3 && ticketId <= 0xFF;
163 if (clientTicketLeave)
164 queueID =
uint8(ticketId);
166 recvData.
ReadGuidMask(RequesterGUID, 6, 0, 2, 3, 1, 5, 4, 7);
167 recvData.
ReadGuidBytes(RequesterGUID, 2, 0, 4, 6, 3, 1, 5, 7);
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.",
176 if (queueID != activeQueueId)
177 SF_LOG_DEBUG(
"lfg.leave",
"CMSG_LFD_LEAVE %s requested queue %u but active queue is %u.",
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);
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.",
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.",
199 bool const disbandDungeonGroup = group->
isLFGGroup() &&
202 if (disbandDungeonGroup)
209 if (leaderGuid != guid)
211 SF_LOG_DEBUG(
"lfg.leave",
"CMSG_LFD_LEAVE %s ignored non-leader group queue leave.",
216 SF_LOG_DEBUG(
"lfg.leave",
"CMSG_LFD_LEAVE GroupLeader: %lu left group queue.", guid);
228 recvData >> ProposalID;
254 SF_LOG_DEBUG(
"lfg",
"CMSG_LFD_PROPOSAL_RESULT %s proposal: %u accept: %u",
267 SF_LOG_DEBUG(
"lfg",
"CMSG_LFG_SET_ROLES %s Not in group",
272 SF_LOG_DEBUG(
"lfg",
"CMSG_LFG_SET_ROLES: Group %u, Player %s, Roles: %u",
274 sLFGMgr->UpdateRoleCheck(gguid, guid, roles);
282 SF_LOG_DEBUG(
"lfg",
"CMSG_LFG_SET_COMMENT %s comment: %s",
294 SF_LOG_DEBUG(
"lfg",
"CMSG_LFD_SET_BOOT_VOTE %s agree: %u",
296 sLFGMgr->UpdateBoot(guid, agree);
311 uint8 partyIndex = 0;
312 recvData >> partyIndex;
313 bool forPlayer = recvData.
ReadBit();
329 bool const hasPlayerGuid =
true;
347 data.
WriteBits(randomDungeons.size(), 17);
349 for (lfg::LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it)
352 Quest const* quest = NULL;
353 bool firstReward =
false;
377 for (
uint8 i = 0; i < shortageCount; ++i)
388 for (
uint8 i = 0; i < shortageCount; ++i)
418 rewardData <<
uint32(*it);
451 for (lfg::LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it)
453 data <<
uint32(it->first);
454 data <<
uint32(it->second.lockStatus);
455 data <<
uint32(it->second.currentItemLevel);
456 data <<
uint32(it->second.requiredItemLevel);
472 Player* plrg = itr->GetSource();
480 lockMap[pguid] =
sLFGMgr->GetLockedDungeons(pguid);
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);
495 if (!HasPacketBytes(recvData,
sizeof(
uint32)))
497 SF_LOG_DEBUG(
"lfg.lfr",
"CMSG_LFG_LFR_JOIN %s malformed packet size: %u",
500 SendLfrRemovedFromQueue(
this);
506 bool const isRaidFinderDungeon =
sLFGMgr->IsRaidFinderDungeon(entry);
508 SF_LOG_DEBUG(
"lfg.lfr",
"CMSG_LFG_LFR_JOIN %s dungeon entry: %u isRaid: %u size: %u",
511 if (!isRaidFinderDungeon)
514 SendLfrRemovedFromQueue(
this);
520 SendLfrRemovedFromQueue(
this);
525 if (!HasPacketBytes(recvData,
sizeof(
uint32)))
527 SF_LOG_DEBUG(
"lfg.lfr",
"CMSG_LFG_LFR_LEAVE %s malformed packet size: %u",
529 SendLfrRemovedFromQueue(
this);
534 recvData >> dungeonId;
535 bool const isRaidFinderDungeon =
sLFGMgr->IsRaidFinderDungeon(dungeonId);
537 SF_LOG_DEBUG(
"lfg.lfr",
"CMSG_LFG_LFR_LEAVE %s dungeonId: %u isRaid: %u size: %u",
540 SendLfrRemovedFromQueue(
this);
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.",
576 if (!inDungeonStatus)
589 if (hasActiveProposal)
590 sLFGMgr->SendActiveProposal(guid);
600 if (queueGuidOverride)
602 guid = queueGuidOverride;
603 queueGuid = queueGuidOverride;
608 guid = group->GetGUID();
609 queueGuid = group->GetGUID();
612 time_t joinTime =
sLFGMgr->GetQueueJoinTime(queueGuid);
615 queueId =
sLFGMgr->GetQueueId(queueGuid);
617 queueId = queueIdOverride;
618 uint8 dungeonCategory = 0;
619 std::vector<uint32> dungeonEntries;
620 dungeonEntries.reserve(updateData.
dungeons.size());
622 for (lfg::LfgDungeonSet::const_iterator it = updateData.
dungeons.begin(); it != updateData.
dungeons.end(); ++it)
624 uint32 const dungeonId = (*it & 0xFF000000) ? (*it & 0x00FFFFFF) : *it;
625 uint32 const dungeonEntry =
sLFGMgr->GetLFGDungeonEntry(dungeonId);
627 dungeonEntries.push_back(dungeonEntry);
629 dungeonEntries.push_back(*it);
631 if (!dungeonCategory)
632 dungeonCategory =
sLFGMgr->GetLFGDungeonCategory(dungeonId);
656 SF_LOG_DEBUG(
"lfg",
"SMSG_LFD_UPDATE_STATUS %s updatetype: %u, party %s",
678 for (
uint8 i = 0; i < 3; ++i)
690 for (std::vector<uint32>::const_iterator it = dungeonEntries.begin(); it != dungeonEntries.end(); ++it)
694 data <<
uint8(dungeonCategory);
702 SF_LOG_DEBUG(
"lfg",
"SMSG_LFG_ROLE_CHOSEN %s guid: %u roles: %u",
727 lfg::LfgRolesMap::const_iterator itLeaderRoles = roleCheck.
roles.find(guid);
728 uint8 roles = itLeaderRoles != roleCheck.
roles.end() ? itLeaderRoles->second : 0;
737 if (!roleCheck.
roles.empty())
743 for (lfg::LfgRolesMap::const_iterator it = roleCheck.
roles.begin(); it != roleCheck.
roles.end(); ++it)
745 if (it->first == roleCheck.
leader)
761 if (!roleCheck.
roles.empty())
769 for (lfg::LfgRolesMap::const_iterator it = roleCheck.
roles.begin(); it != roleCheck.
roles.end(); ++it)
771 if (it->first == roleCheck.
leader)
778 data <<
uint32(it->second);
783 if (!dungeons.empty())
784 for (lfg::LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it)
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);
798 SF_LOG_DEBUG(
"lfg",
"SMSG_LFD_JOIN_RESULT %s checkResult: %u checkValue: %u",
806 for (lfg::LfgLockPartyMap::const_iterator it = joinData.
lockmap.begin(); it != joinData.
lockmap.end(); ++it)
818 for (lfg::LfgLockPartyMap::const_iterator it = joinData.
lockmap.begin(); it != joinData.
lockmap.end(); ++it)
823 for (lfg::LfgLockMap::const_iterator itr = it->second.begin(); itr != it->second.end(); ++itr)
825 data <<
uint32(itr->second.requiredItemLevel);
826 data <<
uint32(itr->second.currentItemLevel);
827 data <<
uint32(itr->second.lockStatus);
828 data <<
uint32(itr->first);
835 data <<
uint32(time(NULL));
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",
880 SF_LOG_DEBUG(
"lfg",
"SMSG_LFG_PLAYER_REWARD %s rdungeonEntry: %u, sdungeonEntry: %u, done: %u",
895 lfg::LfgAnswerContainer::const_iterator itVote = boot.
votes.find(guid);
899 time_t now = time(NULL);
901 for (lfg::LfgAnswerContainer::const_iterator it = boot.
votes.begin(); it != boot.
votes.end(); ++it)
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",
926 if (boot.
reason.size() > 0)
938 if (boot.
reason.size() > 0)
953 lfg::LfgProposalPlayerContainer::const_iterator itSelf = proposal.
players.find(playerGuid);
954 if (itSelf == proposal.
players.end())
957 uint64 originalGroup = itSelf->second.group;
958 bool silent = !proposal.
isNew && originalGroup && originalGroup == proposal.
group;
960 uint64 queueGuid = originalGroup ? originalGroup : playerGuid;
962 time_t joinTime =
sLFGMgr->GetQueueJoinTime(queueGuid);
963 if (!joinTime && queueGuid != playerGuid)
964 joinTime =
sLFGMgr->GetQueueJoinTime(playerGuid);
966 SF_LOG_DEBUG(
"lfg",
"SMSG_LFD_PROPOSAL_UPDATE %s state: %u",
973 if (!playerDungeons.empty() && playerDungeons.find(proposal.
dungeonId) == playerDungeons.end())
974 dungeonEntry = (*playerDungeons.begin());
977 dungeonEntry =
sLFGMgr->GetLFGDungeonEntry(dungeonEntry);
994 for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.
players.begin(); it != proposal.
players.end(); ++it)
996 data.
WriteBit(it->second.group && it->second.group == proposal.
group);
997 data.
WriteBit(it->first == playerGuid);
1000 data.
WriteBit(it->second.group && it->second.group == originalGroup);
1002 uint8 role = it->second.role;
1003 if (proposal.
leader != it->first)
1004 role &=
~lfg::PLAYER_ROLE_LEADER;
1006 roleData <<
uint32(role);
1021 data <<
uint32(dungeonEntry);
1027 data <<
uint32(joinTime);
1044 data <<
uint8(update);
1068 SF_LOG_DEBUG(
"lfg",
"SMSG_LFD_OFFER_CONTINUE %s dungeon entry: %u",
1071 data <<
uint32(dungeonEntry);
1077 SF_LOG_DEBUG(
"lfg",
"SMSG_LFD_TELEPORT_DENIED %s reason: %u",
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 SF_LOG_DEBUG(filterType__,...)
uint32 GUID_LOPART(uint64 x)
#define QUEST_REWARDS_COUNT
#define QUEST_REWARD_CURRENCY_COUNT
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
bool WriteBit(uint32 bit)
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
void WriteString(std::string const &str)
uint32 ReadBits(size_t bits)
void ReadGuidBytes(ObjectGuid &guid, Offsets... offsets)
std::string ReadString(size_t length)
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
void WriteBits(T value, size_t bits)
void Disband(bool hideDestroy=false)
GroupReference * GetFirstMember()
uint64 GetLeaderGUID() const
static Player * FindPlayer(uint64)
bool CanRewardQuest(Quest const *quest, bool msg)
uint32 RewardCurrencyCount[QUEST_REWARD_CURRENCY_COUNT]
uint32 XPValue(Player *player) const
uint32 RewardItemIdCount[QUEST_REWARDS_COUNT]
int32 GetRewMoney() const
uint32 RewardCurrencyId[QUEST_REWARD_CURRENCY_COUNT]
uint32 GetRewItemsCount() const
uint32 GetRewCurrencyCount() const
uint32 RewardItemId[QUEST_REWARDS_COUNT]
Player session in the World.
void SendLfgPartyLockInfo()
void HandleLfgJoinOpcode(WorldPacket &recvData)
void SendLfgJoinResult(lfg::LfgJoinResultData const &joinData)
void HandleLfgLeaveOpcode(WorldPacket &recvData)
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 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_BOOT_PROPOSAL_UPDATE
@ SMSG_LFD_TELEPORT_DENIED
@ SMSG_LFD_PROPOSAL_UPDATE
@ SMSG_LFD_ROLE_CHECK_UPDATE
@ SMSG_LFD_OFFER_CONTINUE
@ LFG_OPTION_ENABLE_DUNGEON_FINDER
@ LFG_OPTION_ENABLE_RAID_BROWSER
@ LFG_STATE_FINISHED_DUNGEON
@ LFG_UPDATETYPE_ADDED_TO_QUEUE
@ LFG_UPDATETYPE_UPDATE_STATUS
@ LFG_UPDATETYPE_REMOVED_FROM_QUEUE
@ LFG_UPDATETYPE_LEADER_UNK1
@ LFG_UPDATETYPE_PROPOSAL_BEGIN
@ LFG_UPDATETYPE_JOIN_QUEUE
@ LFG_UPDATETYPE_JOIN_QUEUE_INITIAL
@ LFG_GROUP_KICK_VOTES_NEEDED
LfgAnswer
Answer state (Also used to check compatibilites).
std::map< uint32, LfgLockData > LfgLockMap
std::set< uint32 > LfgDungeonSet
@ LFG_ROLECHECK_INITIALITING
std::map< uint64, LfgLockMap > LfgLockPartyMap
@ LFG_JOIN_DUNGEON_INVALID
@ LFG_JOIN_INTERNAL_ERROR
Stores information of a current vote to kick someone from a group.
uint64 victim
Player guid to be kicked (can't vote).
std::string reason
kick reason
time_t cancelTime
Time left to vote.
LfgAnswerContainer votes
Player votes (-1 not answer | 0 Not agree | 1 agree).
bool inProgress
Vote in progress.
Stores group data related to proposal to join.
uint32 dungeonId
Dungeon to join.
uint64 group
Proposal group (0 if new).
uint32 encounters
Dungeon Encounters.
uint64 leader
Leader guid.
LfgProposalPlayerContainer players
Players data.
bool isNew
Determines if it's new group or not.
LfgProposalState state
State of the proposal.
Stores all rolecheck info of a group that wants to join.
LfgDungeonSet dungeons
Dungeons group is applying for (expanded random dungeons).
LfgRolesMap roles
Player selected roles.
uint64 leader
Leader of the group.
LfgRoleCheckState state
State of the rolecheck.
uint32 rDungeonId
Random Dungeon Id.