/** Check compatibilities between groups. If group is Matched proposal will be created @param[in] check List of guids to check compatibilities @return LfgCompatibility type of compatibility */ LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check) { std::string strGuids = ConcatenateGuids(check); LfgProposal proposal; LfgDungeonSet proposalDungeons; LfgGroupsMap proposalGroups; LfgRolesMap proposalRoles; // Check for correct size if (check.size() > MAXGROUPSIZE || check.empty()) { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s): Size wrong - Not compatibles", strGuids.c_str()); return LFG_INCOMPATIBLES_WRONG_GROUP_SIZE; } // Check all-but-new compatiblitity if (check.size() > 2) { uint64 frontGuid = check.front(); check.pop_front(); // Check all-but-new compatibilities (New, A, B, C, D) --> check(A, B, C, D) LfgCompatibility child_compatibles = CheckCompatibility(check); if (child_compatibles < LFG_COMPATIBLES_WITH_LESS_PLAYERS) // Group not compatible { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) child %s not compatibles", strGuids.c_str(), ConcatenateGuids(check).c_str()); SetCompatibles(strGuids, child_compatibles); return child_compatibles; } check.push_front(frontGuid); } // Check if more than one LFG group and number of players joining uint8 numPlayers = 0; uint8 numLfgGroups = 0; for (LfgGuidList::const_iterator it = check.begin(); it != check.end() && numLfgGroups < 2 && numPlayers <= MAXGROUPSIZE; ++it) { uint64 guid = (*it); LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(guid); if (itQueue == QueueDataStore.end()) { sLog->outError(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: [" UI64FMTD "] is not queued but listed as queued!", guid); RemoveFromQueue(guid); return LFG_COMPATIBILITY_PENDING; } // Store group so we don't need to call Mgr to get it later (if it's player group will be 0 otherwise would have joined as group) for (LfgRolesMap::const_iterator it2 = itQueue->second.roles.begin(); it2 != itQueue->second.roles.end(); ++it2) proposalGroups[it2->first] = IS_GROUP(itQueue->first) ? itQueue->first : 0; numPlayers += itQueue->second.roles.size(); if (sLFGMgr->IsLfgGroup(guid)) { if (!numLfgGroups) proposal.group = guid; ++numLfgGroups; } } // Group with less that MAXGROUPSIZE members always compatible if (check.size() == 1 && numPlayers != MAXGROUPSIZE) { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) sigle group. Compatibles", strGuids.c_str()); LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(check.front()); LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS); data.roles = itQueue->second.roles; LFGMgr::CheckGroupRoles(data.roles); UpdateBestCompatibleInQueue(itQueue, strGuids, data.roles); SetCompatibilityData(strGuids, data); return LFG_COMPATIBLES_WITH_LESS_PLAYERS; } if (numLfgGroups > 1) { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) More than one Lfggroup (%u)", strGuids.c_str(), numLfgGroups); SetCompatibles(strGuids, LFG_INCOMPATIBLES_MULTIPLE_LFG_GROUPS); return LFG_INCOMPATIBLES_MULTIPLE_LFG_GROUPS; } if (numPlayers > MAXGROUPSIZE) { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Too much players (%u)", strGuids.c_str(), numPlayers); SetCompatibles(strGuids, LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS); return LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS; } // If it's single group no need to check for duplicate players, ignores, bad roles or bad dungeons as it's been checked before joining if (check.size() > 1) { for (LfgGuidList::const_iterator it = check.begin(); it != check.end(); ++it) { const LfgRolesMap &roles = QueueDataStore[(*it)].roles; for (LfgRolesMap::const_iterator itRoles = roles.begin(); itRoles != roles.end(); ++itRoles) { LfgRolesMap::const_iterator itPlayer; for (itPlayer = proposalRoles.begin(); itPlayer != proposalRoles.end(); ++itPlayer) { if (itRoles->first == itPlayer->first) sLog->outError(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: ERROR! Player multiple times in queue! [" UI64FMTD "]", itRoles->first); else if (sLFGMgr->HasIgnore(itRoles->first, itPlayer->first)) break; } if (itPlayer == proposalRoles.end()) proposalRoles[itRoles->first] = itRoles->second; } } if (uint8 playersize = numPlayers - proposalRoles.size()) { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) not compatible, %u players are ignoring each other", strGuids.c_str(), playersize); SetCompatibles(strGuids, LFG_INCOMPATIBLES_HAS_IGNORES); return LFG_INCOMPATIBLES_HAS_IGNORES; } LfgRolesMap debugRoles = proposalRoles; if (!LFGMgr::CheckGroupRoles(proposalRoles)) { std::ostringstream o; for (LfgRolesMap::const_iterator it = debugRoles.begin(); it != debugRoles.end(); ++it) o << ", " << it->first << ": " << sLFGMgr->GetRolesString(it->second); sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Roles not compatible%s", strGuids.c_str(), o.str().c_str()); SetCompatibles(strGuids, LFG_INCOMPATIBLES_NO_ROLES); return LFG_INCOMPATIBLES_NO_ROLES; } LfgGuidList::iterator itguid = check.begin(); proposalDungeons = QueueDataStore[*itguid].dungeons; std::ostringstream o; o << ", " << *itguid << ": (" << sLFGMgr->ConcatenateDungeons(proposalDungeons) << ")"; for (++itguid; itguid != check.end(); ++itguid) { LfgDungeonSet temporal; LfgDungeonSet &dungeons = QueueDataStore[*itguid].dungeons; o << ", " << *itguid << ": (" << sLFGMgr->ConcatenateDungeons(dungeons) << ")"; std::set_intersection(proposalDungeons.begin(), proposalDungeons.end(), dungeons.begin(), dungeons.end(), std::inserter(temporal, temporal.begin())); proposalDungeons = temporal; } if (proposalDungeons.empty()) { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) No compatible dungeons%s", strGuids.c_str(), o.str().c_str()); SetCompatibles(strGuids, LFG_INCOMPATIBLES_NO_DUNGEONS); return LFG_INCOMPATIBLES_NO_DUNGEONS; } } else { uint64 gguid = *check.begin(); const LfgQueueData &queue = QueueDataStore[gguid]; proposalDungeons = queue.dungeons; proposalRoles = queue.roles; LFGMgr::CheckGroupRoles(proposalRoles); // assing new roles } // Enough players? if (numPlayers != MAXGROUPSIZE) { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Compatibles but not enough players(%u)", strGuids.c_str(), numPlayers); LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS); data.roles = proposalRoles; for (LfgGuidList::const_iterator itr = check.begin(); itr != check.end(); ++itr) UpdateBestCompatibleInQueue(QueueDataStore.find(*itr), strGuids, data.roles); SetCompatibilityData(strGuids, data); return LFG_COMPATIBLES_WITH_LESS_PLAYERS; } proposal.queues = check; proposal.isNew = numLfgGroups != 1; if (!sLFGMgr->AllQueued(check)) { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Group MATCH but can't create proposal!", strGuids.c_str()); SetCompatibles(strGuids, LFG_COMPATIBLES_BAD_STATES); return LFG_COMPATIBLES_BAD_STATES; } // Create a new proposal proposal.cancelTime = time(NULL) + LFG_TIME_PROPOSAL; proposal.state = LFG_PROPOSAL_INITIATING; proposal.leader = 0; proposal.dungeonId = Las::Containers::SelectRandomContainerElement(proposalDungeons); bool leader = false; for (LfgRolesMap::const_iterator itRoles = proposalRoles.begin(); itRoles != proposalRoles.end(); ++itRoles) { // Assing new leader if (itRoles->second & PLAYER_ROLE_LEADER) { if (!leader || !proposal.leader || urand(0, 1)) proposal.leader = itRoles->first; leader = true; } else if (!leader && (!proposal.leader || urand(0, 1))) proposal.leader = itRoles->first; // Assing player data and roles LfgProposalPlayer &data = proposal.players[itRoles->first]; data.role = itRoles->second; data.group = proposalGroups.find(itRoles->first)->second; if (!proposal.isNew && data.group && data.group == proposal.group) // Player from existing group, autoaccept data.accept = LFG_ANSWER_AGREE; } // Mark proposal members as not queued (but not remove queue data) for (LfgGuidList::const_iterator itQueue = proposal.queues.begin(); itQueue != proposal.queues.end(); ++itQueue) { uint64 guid = (*itQueue); RemoveFromNewQueue(guid); RemoveFromCurrentQueue(guid); } sLFGMgr->AddProposal(proposal); sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) MATCH! Group formed", strGuids.c_str()); SetCompatibles(strGuids, LFG_COMPATIBLES_MATCH); return LFG_COMPATIBLES_MATCH; }
void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data*/) { uint64 guid = GetPlayer()->GetGUID(); sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); // Get Random dungeons that can be done at a certain level and expansion // FIXME - Should return seasonals (when not disabled) LfgDungeonSet randomDungeons; uint8 level = GetPlayer()->getLevel(); uint8 expansion = GetPlayer()->GetSession()->Expansion(); for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i) { LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(i); if (dungeon && dungeon->type == LFG_TYPE_RANDOM && dungeon->expansion <= expansion && dungeon->minlevel <= level && level <= dungeon->maxlevel) randomDungeons.insert(dungeon->Entry()); if (dungeon && dungeon->grouptype == 11 && dungeon->expansion <= expansion && dungeon->minlevel <= level && level <= dungeon->maxlevel) { uint8 eventEntry = 0; switch (dungeon->ID) { case 285: // The Headless Horseman eventEntry = 12; // Hallow's End break; case 286: // The Frost Lord Ahune eventEntry = 1; // Midsummer Fire Festival break; case 287: // Coren Direbrew eventEntry = 24; // Brewfest break; case 288: // The Crown Chemical Co. eventEntry = 8; // Love is in the Air break; default: break; } if (eventEntry && sGameEventMgr->IsActiveEvent(eventEntry)) randomDungeons.insert(dungeon->Entry()); } } // Get player locked Dungeons LfgLockMap lock = sLFGMgr->GetLockedDungeons(guid); uint32 rsize = uint32(randomDungeons.size()); uint32 lsize = uint32(lock.size()); sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PLAYER_INFO [" UI64FMTD "]", guid); WorldPacket data(SMSG_LFG_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)); data << uint8(randomDungeons.size()); // Random Dungeon count for (LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) { data << uint32(*it); // Dungeon Entry (id + type) LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* qRew = NULL; uint8 done = 0; if (reward) { qRew = sObjectMgr->GetQuestTemplate(reward->reward[0].questId); if (qRew) { done = !GetPlayer()->CanRewardQuest(qRew, false); if (done) qRew = sObjectMgr->GetQuestTemplate(reward->reward[1].questId); } } if (qRew) { data << uint8(done); data << uint32(qRew->GetRewOrReqMoney()); data << uint32(qRew->XPValue(GetPlayer())); data << uint32(reward->reward[done].variableMoney); data << uint32(reward->reward[done].variableXP); data << uint8(qRew->GetRewItemsCount()); if (qRew->GetRewItemsCount()) { ItemTemplate const* iProto = NULL; for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) { if (!qRew->RewItemId[i]) continue; iProto = sObjectMgr->GetItemTemplate(qRew->RewItemId[i]); data << uint32(qRew->RewItemId[i]); data << uint32(iProto ? iProto->DisplayInfoID : 0); data << uint32(qRew->RewItemCount[i]); } } } else { data << uint8(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint8(0); } } BuildPlayerLockDungeonBlock(data, lock); SendPacket(&data); }
void WorldSession::SendLfgUpdateProposal(uint32 proposalId, const LfgProposal* pProp) { if (!pProp) return; uint64 guid = GetPlayer()->GetGUID(); LfgProposalPlayerMap::const_iterator itPlayer = pProp->players.find(guid); if (itPlayer == pProp->players.end()) // Player MUST be in the proposal return; LfgProposalPlayer* ppPlayer = itPlayer->second; uint32 pLowGroupGuid = ppPlayer->groupLowGuid; uint32 dLowGuid = pProp->groupLowGuid; uint32 dungeonId = pProp->dungeonId; bool isSameDungeon = false; bool isContinue = false; Group* grp = dLowGuid ? sGroupMgr->GetGroupByGUID(dLowGuid) : NULL; uint32 completedEncounters = 0; if (grp) { uint64 gguid = grp->GetGUID(); isContinue = grp->isLFGGroup() && sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON; isSameDungeon = GetPlayer()->GetGroup() == grp && isContinue; } sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PROPOSAL_UPDATE [" UI64FMTD "] state: %u", GetPlayer()->GetGUID(), pProp->state); 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 { LfgDungeonSet playerDungeons = sLFGMgr->GetSelectedDungeons(guid); if (playerDungeons.size() == 1) dungeonId = (*playerDungeons.begin()); } if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) { dungeonId = dungeon->Entry(); // Select a player inside to be get completed encounters from if (grp) { for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* groupMember = itr->getSource(); if (groupMember && groupMember->GetMapId() == uint32(dungeon->map)) { if (InstanceScript* instance = groupMember->GetInstanceScript()) completedEncounters = instance->GetCompletedEncounterMask(); break; } } } } data << uint32(dungeonId); // Dungeon data << uint8(pProp->state); // Result state data << uint32(proposalId); // Internal Proposal ID data << uint32(completedEncounters); // Bosses killed data << uint8(isSameDungeon); // Silent (show client window) data << uint8(pProp->players.size()); // Group size for (itPlayer = pProp->players.begin(); itPlayer != pProp->players.end(); ++itPlayer) { ppPlayer = itPlayer->second; data << uint32(ppPlayer->role); // Role data << uint8(itPlayer->first == guid); // Self player if (!ppPlayer->groupLowGuid) // Player not it a group { data << uint8(0); // Not in dungeon data << uint8(0); // Not same group } else { data << uint8(ppPlayer->groupLowGuid == dLowGuid); // In dungeon (silent) data << uint8(ppPlayer->groupLowGuid == pLowGroupGuid); // Same Group than player } data << uint8(ppPlayer->accept != LFG_ANSWER_PENDING); // Answered data << uint8(ppPlayer->accept == LFG_ANSWER_AGREE); // Accepted } SendPacket(&data); }
void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck* pRoleCheck) { ASSERT(pRoleCheck); LfgDungeonSet dungeons; if (pRoleCheck->rDungeonId) dungeons.insert(pRoleCheck->rDungeonId); else dungeons = pRoleCheck->dungeons; ObjectGuid unkGuid = 0; sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_ROLE_CHECK_UPDATE [" UI64FMTD "]", GetPlayer()->GetGUID()); WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + pRoleCheck->roles.size() * (8 + 1 + 4 + 1)); ByteBuffer dataBuffer; data.WriteBit(unkGuid[0]); data.WriteBit(unkGuid[1]); data.WriteBit(unkGuid[6]); data.WriteBits(pRoleCheck->roles.size(), 21); if (!pRoleCheck->roles.empty()) { ObjectGuid guid = pRoleCheck->leader; uint8 roles = pRoleCheck->roles.find(guid)->second; Player* player = ObjectAccessor::FindPlayer(guid); data.WriteBit(guid[4]); data.WriteBit(guid[1]); data.WriteBit(guid[2]); data.WriteBit(guid[6]); data.WriteBit(roles > 0); data.WriteBit(guid[5]); data.WriteBit(guid[7]); data.WriteBit(guid[0]); data.WriteBit(guid[3]); dataBuffer << uint32(roles); // Roles dataBuffer.WriteByteSeq(guid[0]); dataBuffer.WriteByteSeq(guid[2]); dataBuffer.WriteByteSeq(guid[5]); dataBuffer.WriteByteSeq(guid[4]); dataBuffer.WriteByteSeq(guid[7]); dataBuffer.WriteByteSeq(guid[6]); dataBuffer.WriteByteSeq(guid[1]); dataBuffer.WriteByteSeq(guid[3]); dataBuffer << uint8(player ? player->getLevel() : 0); // Level for (LfgRolesMap::const_reverse_iterator it = pRoleCheck->roles.rbegin(); it != pRoleCheck->roles.rend(); ++it) { if (it->first == pRoleCheck->leader) continue; guid = it->first; roles = it->second; player = ObjectAccessor::FindPlayer(guid); data.WriteBit(guid[4]); data.WriteBit(guid[1]); data.WriteBit(guid[2]); data.WriteBit(guid[6]); data.WriteBit(roles > 0); data.WriteBit(guid[5]); data.WriteBit(guid[7]); data.WriteBit(guid[0]); data.WriteBit(guid[3]); dataBuffer << uint32(roles); // Roles dataBuffer.WriteByteSeq(guid[0]); dataBuffer.WriteByteSeq(guid[2]); dataBuffer.WriteByteSeq(guid[5]); dataBuffer.WriteByteSeq(guid[4]); dataBuffer.WriteByteSeq(guid[7]); dataBuffer.WriteByteSeq(guid[6]); dataBuffer.WriteByteSeq(guid[1]); dataBuffer.WriteByteSeq(guid[3]); dataBuffer << uint8(player ? player->getLevel() : 0); // Level } } data.WriteBit(unkGuid[7]); data.WriteBits(dungeons.size(), 22); data.WriteBit(pRoleCheck->state == LFG_ROLECHECK_INITIALITING); data.WriteBit(unkGuid[3]); data.WriteBit(unkGuid[5]); data.WriteBit(unkGuid[4]); data.WriteBit(unkGuid[2]); data.FlushBits(); data.append(dataBuffer); data.WriteByteSeq(unkGuid[4]); if (!dungeons.empty()) { for (LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) { LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(*it); data << uint32(dungeon ? dungeon->Entry() : 0); // Dungeon } } data.WriteByteSeq(unkGuid[6]); data.WriteByteSeq(unkGuid[7]); data.WriteByteSeq(unkGuid[0]); data.WriteByteSeq(unkGuid[3]); data << uint8(1); data.WriteByteSeq(unkGuid[5]); data << uint8(pRoleCheck->state); data.WriteByteSeq(unkGuid[2]); data.WriteByteSeq(unkGuid[1]); SendPacket(&data); }
void WorldSession::SendLfgUpdateProposal(uint32 proposalId, const LfgProposal* pProp) { if (!pProp) return; uint64 guid = GetPlayer()->GetGUID(); LfgProposalPlayerMap::const_iterator itPlayer = pProp->players.find(guid); if (itPlayer == pProp->players.end()) // Player MUST be in the proposal return; LfgProposalPlayer* ppPlayer = itPlayer->second; uint32 pLowGroupGuid = ppPlayer->groupLowGuid; uint32 dLowGuid = pProp->groupLowGuid; uint32 dungeonId = pProp->dungeonId; bool isSameDungeon = false; bool isContinue = false; Group* grp = dLowGuid ? sGroupMgr->GetGroupByGUID(dLowGuid) : NULL; uint32 completedEncounters = 0; if (grp) { uint64 gguid = grp->GetGUID(); isContinue = grp->isLFGGroup() && sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON; isSameDungeon = GetPlayer()->GetGroup() == grp && isContinue; } sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PROPOSAL_UPDATE [" UI64FMTD "] state: %u", GetPlayer()->GetGUID(), pProp->state); 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 { LfgDungeonSet playerDungeons = sLFGMgr->GetSelectedDungeons(guid); if (playerDungeons.size() == 1) dungeonId = (*playerDungeons.begin()); } if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) { dungeonId = dungeon->Entry(); // Select a player inside to be get completed encounters from if (grp) { for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* groupMember = itr->getSource(); if (groupMember && groupMember->GetMapId() == uint32(dungeon->map)) { if (InstanceScript* instance = groupMember->GetInstanceScript()) completedEncounters = instance->GetCompletedEncounterMask(); break; } } } } ObjectGuid playerGUID = guid; ObjectGuid InstanceSaveGUID = MAKE_NEW_GUID(dungeonId, 0, HIGHGUID_INSTANCE_SAVE); data << uint32(0); data << uint32(dungeonId); data << uint32(completedEncounters); data << uint32(0x03); data << uint32(proposalId); data << uint32(getMSTime()); data << uint8(pProp->state); data.WriteBit(playerGUID[4]); data.WriteBit(isSameDungeon); data.WriteBit(playerGUID[2]); data.WriteBit(playerGUID[0]); data.WriteBits(pProp->players.size(), 21); for (itPlayer = pProp->players.begin(); itPlayer != pProp->players.end(); ++itPlayer) { bool inDungeon = false; bool inSameGroup = false; if (itPlayer->second->groupLowGuid) { inDungeon = itPlayer->second->groupLowGuid == dLowGuid; inSameGroup = itPlayer->second->groupLowGuid == pLowGroupGuid; } data.WriteBit(itPlayer->first == guid); // Self player data.WriteBit(itPlayer->second->accept != LFG_ANSWER_PENDING); // Answered data.WriteBit(inDungeon); // In dungeon (silent) data.WriteBit(inSameGroup); // Same Group than player data.WriteBit(itPlayer->second->accept == LFG_ANSWER_AGREE); // Accepted } data.WriteBit(playerGUID[5]); data.WriteBit(InstanceSaveGUID[7]); data.WriteBit(InstanceSaveGUID[4]); data.WriteBit(playerGUID[1]); data.WriteBit(InstanceSaveGUID[6]); data.WriteBit(InstanceSaveGUID[0]); data.WriteBit(InstanceSaveGUID[1]); data.WriteBit(playerGUID[6]); data.WriteBit(playerGUID[3]); data.WriteBit(InstanceSaveGUID[3]); data.WriteBit(InstanceSaveGUID[2]); data.WriteBit(isContinue); data.WriteBit(playerGUID[7]); data.WriteBit(InstanceSaveGUID[5]); data.FlushBits(); data.WriteByteSeq(InstanceSaveGUID[3]); data.WriteByteSeq(InstanceSaveGUID[0]); data.WriteByteSeq(playerGUID[2]); data.WriteByteSeq(playerGUID[3]); data.WriteByteSeq(playerGUID[1]); data.WriteByteSeq(playerGUID[4]); data.WriteByteSeq(InstanceSaveGUID[6]); data.WriteByteSeq(InstanceSaveGUID[4]); data.WriteByteSeq(InstanceSaveGUID[1]); data.WriteByteSeq(InstanceSaveGUID[5]); data.WriteByteSeq(playerGUID[6]); for (itPlayer = pProp->players.begin(); itPlayer != pProp->players.end(); ++itPlayer) data << uint32(itPlayer->second->role); data.WriteByteSeq(InstanceSaveGUID[2]); data.WriteByteSeq(playerGUID[7]); data.WriteByteSeq(playerGUID[0]); data.WriteByteSeq(InstanceSaveGUID[7]); data.WriteByteSeq(playerGUID[5]); SendPacket(&data); }
void WorldSession::HandleLfgLockInfoRequestOpcode(WorldPacket& recvData) { uint8 value; bool groupPacket; recvData >> value; groupPacket = recvData.ReadBit(); ObjectGuid guid = GetPlayer()->GetGUID(); // Get Random dungeons that can be done at a certain level and expansion LfgDungeonSet randomDungeons; uint8 level = GetPlayer()->getLevel(); uint8 expansion = GetPlayer()->GetSession()->Expansion(); for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i) { LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(i); if (dungeon && dungeon->expansion <= expansion && dungeon->minlevel <= level && level <= dungeon->maxlevel) { if (dungeon->flags & LFG_FLAG_SEASONAL) { if (HolidayIds holiday = sLFGMgr->GetDungeonSeason(dungeon->ID)) if (holiday == HOLIDAY_WOTLK_LAUNCH || !IsHolidayActive(holiday)) continue; } else if (dungeon->type != TYPEID_RANDOM_DUNGEON) continue; randomDungeons.insert(dungeon->Entry()); } } // Get player locked Dungeons LfgLockMap lock = sLFGMgr->GetLockedDungeons(guid); uint32 rsize = uint32(randomDungeons.size()); uint32 lsize = uint32(lock.size()); WorldPacket data(SMSG_LFG_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)); bool hasGuid = true; data.WriteBit(hasGuid); if (hasGuid) { uint8 bitOrder[8] = { 0, 6, 7, 5, 2, 4, 1, 3 }; data.WriteBitInOrder(guid, bitOrder); } data.WriteBits(randomDungeons.size(), 17); for (LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) { LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* qRew = NULL; bool done = false; if (reward) { qRew = sObjectMgr->GetQuestTemplate(reward->reward[0].questId); if (qRew) { done = !GetPlayer()->CanRewardQuest(qRew, false); if (done) qRew = sObjectMgr->GetQuestTemplate(reward->reward[1].questId); } } data.WriteBits(0, 21); // Unk count data.WriteBits(qRew ? qRew->GetRewCurrencyCount() : 0, 21); data.WriteBits(0, 19); // Unk count 2 - related to call to Arms data.WriteBit(!done); data.WriteBit(0); // some bit data.WriteBits(qRew ? qRew->GetRewItemsCount() : 0, 20); } data.WriteBits(lock.size(), 20); for (LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) { LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* qRew = NULL; uint8 done = 0; if (reward) { qRew = sObjectMgr->GetQuestTemplate(reward->reward[0].questId); if (qRew) { done = !GetPlayer()->CanRewardQuest(qRew, false); if (done) qRew = sObjectMgr->GetQuestTemplate(reward->reward[1].questId); } } data << uint32(0); // 11 data << uint32(0); // 12 data << uint32(0); // 15 data << uint32(0); // 16 data << uint32(0); // 17 if (qRew) { if (qRew->GetRewItemsCount()) { ItemTemplate const* iProto = NULL; for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) { if (!qRew->RewardItemId[i]) continue; iProto = sObjectMgr->GetItemTemplate(qRew->RewardItemId[i]); data << uint32(iProto ? iProto->DisplayInfoID : 0); data << uint32(qRew->RewardItemIdCount[i]); data << uint32(qRew->RewardItemId[i]); } } if (qRew->GetRewCurrencyCount()) { for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i) { if (!qRew->RewardCurrencyId[i]) continue; CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(qRew->RewardCurrencyId[i]); uint32 countCurrency = qRew->RewardCurrencyCount[i] ? qRew->RewardCurrencyCount[i] : 0; if (currency->Flags & CURRENCY_FLAG_HIGH_PRECISION) countCurrency *= 100; data << uint32(qRew->RewardCurrencyId[i]); data << uint32(countCurrency); } } data << uint32(1); // 23 data << uint32(0); // 24 data << uint32(0); // 25 data << uint32(1); // 26 data << uint32(qRew->XPValue(GetPlayer())); data << uint32(0); // 28 data << uint32(0); // 29 data << uint32(0); // 30 data << uint32(0); // 31 data << uint32(0); // 32 data << uint32(qRew->GetRewOrReqMoney()); data << uint32(*it); } else { data << uint32(0); // 23 data << uint32(0); // 24 data << uint32(0); // 25 data << uint32(0); // 26 data << uint32(0); // 27 data << uint32(0); // 28 data << uint32(0); // 29 data << uint32(0); // 30 data << uint32(0); // 31 data << uint32(0); // 32 data << uint32(0); // 33 data << uint32(0); // 34 } } if (hasGuid) { uint8 byteOrder[8] = { 6, 3, 0, 4, 5, 1, 2, 7 }; data.WriteBytesSeq(guid, byteOrder); } for (LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it) { auto lockData = it->second; data << uint32(it->first); // Dungeon entry (id + type) data << uint32(lockData.itemLevel); data << uint32(lockData.lockstatus); // Lock status data << uint32(GetPlayer()->GetAverageItemLevel()); } /* bool hasGuid = true; data.WriteBit(hasGuid); if (hasGuid) { uint8 bitOrder[8] = {7, 2, 1, 6, 3, 5, 0, 4}; data.WriteBitInOrder(guid, bitOrder); } data.WriteBits(randomDungeons.size(), 17); for (LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) { LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* qRew = NULL; bool done = 0; if (reward) { qRew = sObjectMgr->GetQuestTemplate(reward->reward[0].questId); if (qRew) { done = !GetPlayer()->CanRewardQuest(qRew, false); if (done) qRew = sObjectMgr->GetQuestTemplate(reward->reward[1].questId); } } data.WriteBits(0, 21); // Unk count data.WriteBits(qRew ? qRew->GetRewCurrencyCount() : 0, 21); data.WriteBits(0, 19); // Unk count 2 - related to call to Arms data.WriteBit(!done); data.WriteBits(qRew ? qRew->GetRewItemsCount() : 0, 20); data.WriteBit(0); } data.WriteBits(lock.size(), 20); for (LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) { LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* qRew = NULL; uint8 done = 0; if (reward) { qRew = sObjectMgr->GetQuestTemplate(reward->reward[0].questId); if (qRew) { done = !GetPlayer()->CanRewardQuest(qRew, false); if (done) qRew = sObjectMgr->GetQuestTemplate(reward->reward[1].questId); } } data << uint32(0); data << uint32(1); if (qRew) { if (qRew->GetRewCurrencyCount()) { for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) { if (!qRew->RewardCurrencyId[i]) continue; data << uint32(qRew->RewardCurrencyCount[i]); data << uint32(qRew->RewardCurrencyId[i]); } } data << uint32(0); if (qRew->GetRewItemsCount()) { ItemTemplate const* iProto = NULL; for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) { if (!qRew->RewardItemId[i]) continue; iProto = sObjectMgr->GetItemTemplate(qRew->RewardItemId[i]); data << uint32(iProto ? iProto->DisplayInfoID : 0); data << uint32(qRew->RewardItemId[i]); data << uint32(qRew->RewardItemIdCount[i]); } } data << uint32(1); // 1 in sniff data << uint32(1); // 1 in sniff //for (int j = 0; j < info.Count3; ++j) data << uint32(0); // 0 in sniff data << uint32(0); // related to encounter - encounter progress data << uint32(*it); // Dungeon Entry (id + type) - progress data << uint32(1); // 0 in sniff data << uint32(1); // 0 in sniff data << uint32(0); // 0 in sniff data << uint32(0); // 0 in sniff data << uint32(qRew->XPValue(GetPlayer())); data << uint32(0); // 0 in sniff data << uint32(0); // 0 in sniff data << uint32(0); // 0 in sniff data << uint32(qRew->GetRewOrReqMoney()); //data << uint32(qRew->GetRewOrReqMoney()); //data << uint32(qRew->XPValue(GetPlayer())); //data << uint32(reward->reward[done].variableMoney); //data << uint32(reward->reward[done].variableXP); } else { data << uint32(16); data << uint32(1); // 1 in sniff unk4 data << uint32(1); // 1 in sniff unk5 data << uint32(0); // 0 in sniff unk6 data << uint32(0); //related to encounter - encounter progress data << uint32(*it); data << uint32(1); // 0 in sniff unk9 data << uint32(1); // 0 in sniff unk10 data << uint32(0); // 0 in sniff unk11 data << uint32(0); // 0 in sniff unk12 data << uint32(333); // 0 in sniff unk13 // xp data << uint32(0); // 0 in sniff unk14 data << uint32(0); // 0 in sniff unk15 data << uint32(0); // 0 in sniff unk16 data << uint32(666); // money } } for (LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it) { auto lockData = it->second; data << uint32(lockData.itemLevel); data << uint32(it->first); // Dungeon entry (id + type) data << uint32(lockData.lockstatus); // Lock status data << uint32(GetPlayer()->GetAverageItemLevel()); } if (hasGuid) { uint8 byteOrder[8] = {3, 1, 2, 6, 4, 7, 0, 5}; data.WriteBytesSeq(guid, byteOrder); }*/ SendPacket(&data); }
void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) { uint32 numDungeons; uint32 dungeon; uint32 roles; uint8 length = 0; uint8 unk8 = 0; bool unkbit = false; recvData >> unk8; for (int i = 0; i < 3; ++i) recvData.read_skip<uint32>(); recvData >> roles; numDungeons = recvData.ReadBits(22); length = recvData.ReadBits(8); unkbit = recvData.ReadBit(); recvData.FlushBits(); if (!numDungeons) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_JOIN [" UI64FMTD "] no dungeons selected", GetPlayer()->GetGUID()); recvData.rfinish(); return; } std::string comment = recvData.ReadString(length); LfgDungeonSet newDungeons; for (uint32 i = 0; i < numDungeons; ++i) { recvData >> dungeon; dungeon &= 0xFFFFFF; newDungeons.insert(dungeon); // remove the type from the dungeon entry } const LFGDungeonEntry* entry = sLFGDungeonStore.LookupEntry(*newDungeons.begin() & 0xFFFFFF); uint8 type = TYPEID_DUNGEON; uint8 maxGroupSize = 5; if (entry != NULL) type = entry->type; if (type == LFG_SUBTYPEID_RAID) maxGroupSize = 25; if (type == LFG_SUBTYPEID_SCENARIO) maxGroupSize = 3; if (!sWorld->getBoolConfig(CONFIG_DUNGEON_FINDER_ENABLE) || (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() && (GetPlayer()->GetGroup()->GetMembersCount() == maxGroupSize || !GetPlayer()->GetGroup()->isLFGGroup()))) { recvData.rfinish(); return; } sLog->outDebug(LOG_FILTER_NETWORKIO, "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); }
void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData*/) { ObjectGuid guid = _player->GetObjectGuid(); sLog.outDebug( "CMSG_LFG_PLAYER_LOCK_INFO_REQUEST %s", guid.GetString().c_str()); // Get Random dungeons that can be done at a certain level and expansion LfgDungeonSet randomDungeons; uint8 level = _player->getLevel(); uint8 expansion = _player->GetSession()->Expansion(); LFGDungeonContainer& LfgDungeons = sLFGMgr.GetLFGDungeonMap(); for (LFGDungeonContainer::const_iterator itr = LfgDungeons.begin(); itr != LfgDungeons.end(); ++itr) { LFGDungeonData const& dungeon = itr->second; if ((dungeon.type == LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr.IsSeasonActive(dungeon.id))) && dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel) randomDungeons.insert(dungeon.Entry()); } // Get player locked Dungeons LfgLockMap const& lock = sLFGMgr.GetLockedDungeons(guid); uint32 rsize = uint32(randomDungeons.size()); uint32 lsize = uint32(lock.size()); sLog.outDebug("SMSG_LFG_PLAYER_INFO %s", _player->GetGuidStr().c_str()); WorldPacket data(SMSG_LFG_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)); data << uint8(randomDungeons.size()); // Random Dungeon count for (LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) { data << uint32(*it); // Dungeon Entry (id + type) LfgReward const* reward = sLFGMgr.GetRandomDungeonReward(*it, level); Quest const* quest = NULL; bool done = false; if (reward) { quest = sObjectMgr.GetQuestTemplate(reward->firstQuest); if (quest) { done = !_player->CanRewardQuest(quest, false); if (done) quest = sObjectMgr.GetQuestTemplate(reward->otherQuest); } } if (quest) { data << uint8(done); data << uint32(500); // Times precision data << uint32(500); // Available times per week data << uint32(396); // Unknown 4.3.4 data << uint32(0); // Unknown 4.3.4 data << uint32(100000); // Unknown 4.3.4 data << uint32(0); // Unknown 4.3.4 data << uint32(0); // Unknown 4.3.4 data << uint32(0); // Unknown 4.3.4 data << uint32(100000); // Unknown 4.3.4 data << uint32(70000); // Unknown 4.3.4 data << uint32(80000); // Unknown 4.3.4 data << uint32(90000); // Unknown 4.3.4 data << uint32(50000); // isComplited data << uint8(100); // seasonal ? { for (uint8 i = 0; i < 3; ++i) // 3 - Max roles ? { uint8 callToArmsRoleMask = 0; // TODO Call to arms role check (LfgRoles) Not implemented data << uint32(callToArmsRoleMask); if (callToArmsRoleMask > 0) { /* Call to Arms bonus*/ data << uint32(0); // Call to arms Money data << uint32(0); // Call to arms XP uint8 totalRewardCount = uint8(quest->GetRewCurrencyCount() + quest->GetRewItemsCount()); if (totalRewardCount > 16) totalRewardCount = 16; data << uint8(totalRewardCount); if (totalRewardCount) { for (uint8 j = 0; j < QUEST_REWARD_CURRENCY_COUNT; ++j) { uint32 id = quest->RewCurrencyId[j]; if (!id) continue; uint32 amount = quest->RewCurrencyCount[j]; if (CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id)) amount *= currency->GetPrecision(); data << uint32(id); data << uint32(0); data << uint32(amount); data << uint8(true); // Is currency } ItemPrototype const* iProto = NULL; for (uint8 j = 0; j < QUEST_REWARDS_COUNT; ++j) { if (!quest->RewItemId[j]) continue; iProto = sObjectMgr.GetItemPrototype(quest->RewItemId[j]); data << uint32(quest->RewItemId[j]); data << uint32(iProto ? iProto->DisplayInfoID : 0); data << uint32(quest->RewItemCount[j]); data << uint8(false); // Is currency } } } } } data << uint32(quest->GetRewOrReqMoney()); data << uint32(quest->XPValue(_player)); uint8 totalRewardCount = uint8(quest->GetRewCurrencyCount() + quest->GetRewItemsCount()); if (totalRewardCount > 16) totalRewardCount = 16; data << uint8(totalRewardCount); if (totalRewardCount) { for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i) { uint32 id = quest->RewCurrencyId[i]; if (!id) continue; uint32 amount = quest->RewCurrencyCount[i]; if (CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id)) amount *= currency->GetPrecision(); data << uint32(id); data << uint32(0); data << uint32(amount); data << uint8(true); // Is currency } ItemPrototype const* iProto = NULL; for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) { if (!quest->RewItemId[i]) continue; iProto = sObjectMgr.GetItemPrototype(quest->RewItemId[i]); data << uint32(quest->RewItemId[i]); data << uint32(iProto ? iProto->DisplayInfoID : 0); data << uint32(quest->RewItemCount[i]); data << uint8(false); // Is currency } } } else { data << uint8(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); for (int8 i = 0; i < 9; ++i) data << uint32(0); // Unknown 4.3.4 data << uint8(1); for (int8 i = 0; i < 3; ++i) data << uint32(0); // Unknown 4.3.4 for (int8 i = 0; i < 2; ++i) data << uint32(0); // Unknown 4.3.4 data << uint8(0); } } BuildPlayerLockDungeonBlock(data, lock); SendPacket(&data); }
void WorldSession::HandleLfgJoinOpcode(WorldPacket &recv_data) { if (!sWorld.getBoolConfig(CONFIG_DUNGEON_FINDER_ENABLE)) { recv_data.rpos(recv_data.wpos()); sLog.outDebug("CMSG_LFG_JOIN [" UI64FMTD "] Dungeon finder disabled", GetPlayer()->GetGUID()); return; } if (sLFGMgr.isJoining(GetPlayer()->GetGUID())) { recv_data.rpos(recv_data.wpos()); sLog.outDebug("CMSG_LFG_JOIN [" UI64FMTD "] already Joining. Ignoring", GetPlayer()->GetGUID()); return; } uint8 numDungeons; uint32 dungeon; uint32 roles; std::string comment; LfgDungeonSet newDungeons; recv_data >> roles; recv_data.read_skip<uint8>(); // unk - always 0 recv_data.read_skip<uint8>(); // unk - always 0 recv_data >> numDungeons; if (!numDungeons) { sLog.outDebug("CMSG_LFG_JOIN [" UI64FMTD "] no dungeons selected", GetPlayer()->GetGUID()); recv_data.rpos(recv_data.wpos()); return; } for (int8 i = 0 ; i < numDungeons; ++i) { recv_data >> dungeon; newDungeons.insert((dungeon & 0x00FFFFFF)); // remove the type from the dungeon entry } recv_data >> numDungeons; // unk - always 3 for (int8 i = 0 ; i < numDungeons; ++i) recv_data.read_skip<uint8>(); // unk - always 0 recv_data >> comment; LfgDungeonSet* dungeons = GetPlayer()->GetLfgDungeons(); Group* grp = GetPlayer()->GetGroup(); bool isRandomDungeon = dungeons->size() == 1 && sLFGMgr.isRandomDungeon(*dungeons->begin()); bool isCurrentDungeon = newDungeons.size() == 1 && grp && grp->isLFGGroup() && grp->GetLfgDungeonEntry() == (*newDungeons.begin()); if (!isRandomDungeon || !isCurrentDungeon) // is not offer to continue - clear old dungeons and use new dungeons { dungeons->clear(); for (LfgDungeonSet::const_iterator it = newDungeons.begin(); it != newDungeons.end(); ++it) dungeons->insert(*it); } GetPlayer()->SetLfgRoles(uint8(roles)); GetPlayer()->SetLfgComment(comment); sLog.outDebug("CMSG_LFG_JOIN [" UI64FMTD "] as group: %u - Dungeons: %u", GetPlayer()->GetGUID(), grp ? 1 : 0, uint8(newDungeons.size())); newDungeons.clear(); sLFGMgr.Join(GetPlayer()); }
void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket &/*recv_data*/) { sLog.outDebug("CMSG_LFD_PLAYER_LOCK_INFO_REQUEST [" UI64FMTD "]", GetPlayer()->GetGUID()); uint32 rsize = 0; uint32 lsize = 0; LfgDungeonSet* randomlist = sLFGMgr.GetRandomDungeons(GetPlayer()->getLevel(), GetPlayer()->GetSession()->Expansion()); LfgLockStatusSet* lockSet = sLFGMgr.GetPlayerLockStatusDungeons(GetPlayer()); if (randomlist) rsize = randomlist->size(); if (lockSet) lsize = lockSet->size(); sLog.outDebug("SMSG_LFG_PLAYER_INFO [" UI64FMTD "]", GetPlayer()->GetGUID()); WorldPacket data(SMSG_LFG_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)); if (!randomlist) data << uint8(0); else { LfgReward const* reward = NULL; Quest const* qRew = NULL; uint8 done; data << uint8(randomlist->size()); // Random Dungeon count for (LfgDungeonSet::iterator it = randomlist->begin(); it != randomlist->end(); ++it) { data << uint32(*it); // Entry reward = sLFGMgr.GetRandomDungeonReward(*it, GetPlayer()->getLevel()); qRew = NULL; if (reward) { qRew = sObjectMgr.GetQuestTemplate(reward->reward[0].questId); if (qRew) { done = !GetPlayer()->CanRewardQuest(qRew,false); if (done) qRew = sObjectMgr.GetQuestTemplate(reward->reward[1].questId); } } if (qRew) { data << uint8(done); data << uint32(qRew->GetRewOrReqMoney()); data << uint32(qRew->XPValue(GetPlayer())); data << uint32(reward->reward[done].variableMoney); data << uint32(reward->reward[done].variableXP); data << uint8(qRew->GetRewItemsCount()); if (qRew->GetRewItemsCount()) { ItemPrototype const* iProto = NULL; for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) { if (!qRew->RewItemId[i]) continue; iProto = ObjectMgr::GetItemPrototype(qRew->RewItemId[i]); data << uint32(qRew->RewItemId[i]); data << uint32(iProto ? iProto->DisplayInfoID : 0); data << uint32(qRew->RewItemCount[i]); } } } else { data << uint8(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint8(0); } } randomlist->clear(); delete randomlist; } BuildPlayerLockDungeonBlock(data, lockSet); SendPacket(&data); }
void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData*/) { uint64 guid = GetPlayer()->GetGUID(); sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_PLAYER_LOCK_INFO_REQUEST %s", GetPlayerInfo().c_str()); // Get Random dungeons that can be done at a certain level and expansion LfgDungeonSet randomDungeons; uint8 level = GetPlayer()->getLevel(); uint8 expansion = GetPlayer()->GetSession()->Expansion(); LFGDungeonContainer& LfgDungeons = sLFGMgr->GetLFGDungeonMap(); for (LFGDungeonContainer::const_iterator itr = LfgDungeons.begin(); itr != LfgDungeons.end(); ++itr) { LFGDungeonData const& dungeon = itr->second; if ((dungeon.type == LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) && dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel) randomDungeons.insert(dungeon.Entry()); } // Get player locked Dungeons LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid); uint32 rsize = uint32(randomDungeons.size()); uint32 lsize = uint32(lock.size()); sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PLAYER_INFO %s", GetPlayerInfo().c_str()); WorldPacket data(SMSG_LFG_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)); data << uint8(randomDungeons.size()); // Random Dungeon count for (LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) { data << uint32(*it); // Dungeon Entry (id + type) LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* quest = NULL; bool done = false; if (reward) { quest = sObjectMgr->GetQuestTemplate(reward->firstQuest); if (quest) { done = !GetPlayer()->CanRewardQuest(quest, false); if (done) quest = sObjectMgr->GetQuestTemplate(reward->otherQuest); } } if (quest) { data << uint8(done); data << uint32(quest->GetRewOrReqMoney()); data << uint32(quest->XPValue(GetPlayer())); data << uint32(0); data << uint32(0); data << uint8(quest->GetRewItemsCount()); if (quest->GetRewItemsCount()) { for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) if (uint32 itemId = quest->RewardItemId[i]) { ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId); data << uint32(itemId); data << uint32(item ? item->DisplayInfoID : 0); data << uint32(quest->RewardItemIdCount[i]); } } } else { data << uint8(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); data << uint8(0); } } BuildPlayerLockDungeonBlock(data, lock); SendPacket(&data); }
void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data*/) { uint64 guid = GetPlayer()->GetGUID(); sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); // Get Random dungeons that can be done at a certain level and expansion // FIXME - Should return seasonals (when not disabled) LfgDungeonSet randomDungeons; uint8 level = GetPlayer()->getLevel(); uint8 expansion = GetPlayer()->GetSession()->Expansion(); for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i) { LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(i); if (dungeon && dungeon->type == LFG_TYPE_RANDOM && dungeon->expansion <= expansion && dungeon->minlevel <= -1 && 9999 <= dungeon->maxlevel) randomDungeons.insert(dungeon->Entry()); } // Get player locked Dungeons LfgLockMap lock = sLFGMgr->GetLockedDungeons(guid); uint32 rsize = uint32(randomDungeons.size()); uint32 lsize = uint32(lock.size()); sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PLAYER_INFO [" UI64FMTD "]", guid); WorldPacket data(SMSG_LFG_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)); data << uint8(randomDungeons.size()); // Random Dungeon count for (LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it) { data << uint32(*it); // Dungeon Entry (id + type) LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* qRew = NULL; uint8 done = 0; if (reward) { qRew = sObjectMgr->GetQuestTemplate(reward->reward[0].questId); if (qRew) { done = !GetPlayer()->CanRewardQuest(qRew, false); if (done) qRew = sObjectMgr->GetQuestTemplate(reward->reward[1].questId); } } for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i) { LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(i); if (qRew) { data << uint8(done); data << uint32(qRew->GetRewOrReqMoney()); data << uint32(qRew->XPValue(GetPlayer())); data << uint32(reward->reward[done].variableMoney); data << uint32(reward->reward[done].variableXP); data << uint8(qRew->GetRewItemsCount()); if (qRew->GetRewItemsCount()) { ItemTemplate const* iProto = NULL; for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) { if (!qRew->RewardItemId[i]) continue; iProto = sObjectMgr->GetItemTemplate(qRew->RewardItemId[i]); data << uint32(qRew->RewardItemId[i]); data << uint32(iProto ? iProto->DisplayInfoID : 0); data << uint32(qRew->RewardItemIdCount[i]); } } } } } //隐蔽可取消锁定低级副本 BuildPlayerLockDungeonBlock(data, lock); SendPacket(&data); }