/// <summary> /// Build and Send LFG lock player info and reward /// </summary> /// <param name="plr">Player</param> void LFGMgr::SendLfgPlayerInfo(Player *plr) { uint32 rsize = 0; uint32 lsize = 0; LfgDungeonSet *randomlist = GetRandomDungeons(plr->getLevel(), plr->GetSession()->Expansion()); LfgLockStatusSet *lockSet = GetPlayerLockStatusDungeons(plr, m_DungeonsMap[LFG_ALL_DUNGEONS]); if (randomlist) rsize = randomlist->size(); if (lockSet) lsize = lockSet->size(); sLog.outDebug("SMSG_LFG_PLAYER_INFO"); WorldPacket data(SMSG_LFG_PLAYER_INFO, 1 + rsize * (4 + 1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4) + 4 + lsize * (4 + 4)); if (!randomlist) { data << uint8(0); } else { data << uint8(randomlist->size()); // Random Dungeon count for (LfgDungeonSet::iterator it = randomlist->begin(); it != randomlist->end(); ++it) { data << uint32(*it); // Entry BuildRewardBlock(data, *it, plr); } randomlist->clear(); delete randomlist; } BuildPlayerLockDungeonBlock(data, lockSet); plr->GetSession()->SendPacket(&data); }
void WorldSession::SendLfgUpdateParty(uint8 updateType) { if (!GetPlayer()->GetLfgUpdate()) { sLog.outDebug("SMSG_LFG_UPDATE_PARTY [" UI64FMTD "] updatetype: %u not sent! player flag: false", GetPlayer()->GetGUID(), updateType); return; } bool join = false; bool extrainfo = false; bool queued = false; switch(updateType) { case LFG_UPDATETYPE_JOIN_PROPOSAL: extrainfo = true; break; case LFG_UPDATETYPE_ADDED_TO_QUEUE: extrainfo = true; join = true; queued = true; break; case LFG_UPDATETYPE_CLEAR_LOCK_LIST: // join = true; // TODO: Sometimes queued and extrainfo - Check ocurrences... queued = true; break; case LFG_UPDATETYPE_PROPOSAL_BEGIN: extrainfo = true; join = true; break; } LfgDungeonSet* dungeons = GetPlayer()->GetLfgDungeons(); uint8 size = dungeons->size(); std::string comment = GetPlayer()->GetLfgComment(); sLog.outDebug("SMSG_LFG_UPDATE_PARTY [" UI64FMTD "] updatetype: %u", GetPlayer()->GetGUID(), updateType); WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + size * 4 + comment.length())); data << uint8(updateType); // Lfg Update type data << uint8(extrainfo); // Extra info if (extrainfo) { data << uint8(join); // LFG Join data << uint8(queued); // Join the queue data << uint8(0); // unk - Always 0 data << uint8(0); // unk - Always 0 for (uint8 i = 0; i < 3; ++i) data << uint8(0); // unk - Always 0 data << uint8(size); for (LfgDungeonSet::const_iterator it = dungeons->begin(); it != dungeons->end(); ++it) data << uint32(*it); data << comment; } SendPacket(&data); }
void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck* pRoleCheck) { ASSERT(pRoleCheck); LfgDungeonSet dungeons; if (pRoleCheck->rDungeonId) dungeons.insert(pRoleCheck->rDungeonId); else dungeons = pRoleCheck->dungeons; Log.Debug("LfgHandler", "SMSG_LFG_ROLE_CHECK_UPDATE %u", GetPlayer()->GetGUID()); WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + pRoleCheck->roles.size() * (8 + 1 + 4 + 1)); data << uint32(pRoleCheck->state); // Check result data << uint8(pRoleCheck->state == LFG_ROLECHECK_INITIALITING); data << uint8(dungeons.size()); // Number of dungeons if (!dungeons.empty()) { for (LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) { DBC::Structures::LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(*it); data << uint32(dungeon ? dungeon->Entry() : 0); // Dungeon } } data << uint8(pRoleCheck->roles.size()); // Players in group if (!pRoleCheck->roles.empty()) { // Leader info MUST be sent 1st :S uint64 guid = pRoleCheck->leader; uint8 roles = pRoleCheck->roles.find(guid)->second; data << uint64(guid); // Guid data << uint8(roles > 0); // Ready data << uint32(roles); // Roles Player* player = objmgr.GetPlayer(GET_LOWGUID_PART(guid)); data << uint8(player ? player->getLevel() : 0); // Level for (LfgRolesMap::const_iterator it = pRoleCheck->roles.begin(); it != pRoleCheck->roles.end(); ++it) { if (it->first == pRoleCheck->leader) continue; guid = it->first; roles = it->second; data << uint64(guid); // Guid data << uint8(roles > 0); // Ready data << uint32(roles); // Roles player = objmgr.GetPlayer(GET_LOWGUID_PART(guid)); data << uint8(player ? player->getLevel() : 0); // Level } } SendPacket(&data); }
void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck* pRoleCheck) { ASSERT(pRoleCheck); LfgDungeonSet dungeons; if (pRoleCheck->rDungeonId) dungeons.insert(pRoleCheck->rDungeonId); else dungeons = pRoleCheck->dungeons; 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)); data << uint32(pRoleCheck->state); // Check result data << uint8(pRoleCheck->state == LFG_ROLECHECK_INITIALITING); data << uint8(dungeons.size()); // Number of dungeons 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 << uint8(pRoleCheck->roles.size()); // Players in group if (!pRoleCheck->roles.empty()) { // Leader info MUST be sent 1st :S uint64 guid = pRoleCheck->leader; uint8 roles = pRoleCheck->roles.find(guid)->second; data << uint64(guid); // Guid data << uint8(roles > 0); // Ready data << uint32(roles); // Roles Player* plr = ObjectAccessor::FindPlayer(guid); data << uint8(plr ? plr->getLevel() : 0); // Level for (LfgRolesMap::const_iterator it = pRoleCheck->roles.begin(); it != pRoleCheck->roles.end(); ++it) { if (it->first == pRoleCheck->leader) continue; guid = it->first; roles = it->second; data << uint64(guid); // Guid data << uint8(roles > 0); // Ready data << uint32(roles); // Roles plr = ObjectAccessor::FindPlayer(guid); data << uint8(plr ? plr->getLevel() : 0); // Level } } SendPacket(&data); }
void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) { LfgDungeonSet dungeons; if (roleCheck.rDungeonId) dungeons.insert(roleCheck.rDungeonId); else dungeons = roleCheck.dungeons; sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_ROLE_CHECK_UPDATE %s", GetPlayerInfo().c_str()); WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1)); data << uint32(roleCheck.state); // Check result data << uint8(roleCheck.state == LFG_ROLECHECK_INITIALITING); data << uint8(dungeons.size()); // Number of dungeons if (!dungeons.empty()) { for (LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) { LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*it); data << uint32(dungeon ? dungeon->Entry() : 0); // Dungeon } } data << uint8(roleCheck.roles.size()); // Players in group if (!roleCheck.roles.empty()) { // Leader info MUST be sent 1st :S uint64 guid = roleCheck.leader; uint8 roles = roleCheck.roles.find(guid)->second; data << uint64(guid); // Guid data << uint8(roles > 0); // Ready data << uint32(roles); // Roles Player* player = ObjectAccessor::FindPlayer(guid); data << uint8(player ? player->getLevel() : 0); // Level for (LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it) { if (it->first == roleCheck.leader) continue; guid = it->first; roles = it->second; data << uint64(guid); // Guid data << uint8(roles > 0); // Ready data << uint32(roles); // Roles player = ObjectAccessor::FindPlayer(guid); data << uint8(player ? player->getLevel() : 0);// Level } } SendPacket(&data); }
std::string ConcatenateDungeons(LfgDungeonSet const& dungeons) { std::string dungeonstr = ""; if (!dungeons.empty()) { std::ostringstream o; LfgDungeonSet::const_iterator it = dungeons.begin(); o << (*it); for (++it; it != dungeons.end(); ++it) o << ", " << uint32(*it); dungeonstr = o.str(); } return dungeonstr; }
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; uint8 done = 0; if (reward) { quest = sObjectMgr->GetQuestTemplate(reward->reward[0].questId); if (quest) { done = !GetPlayer()->CanRewardQuest(quest, false); if (done) quest = sObjectMgr->GetQuestTemplate(reward->reward[1].questId); } } if (quest) { data << uint8(done); data << uint32(quest->GetRewOrReqMoney()); data << uint32(quest->XPValue(GetPlayer())); data << uint32(reward->reward[done].variableMoney); data << uint32(reward->reward[done].variableXP); 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); }
/** 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()) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%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 { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%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()) { TC_LOG_ERROR("lfg.queue.match.compatibility.check", "Guid: [" 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_GUID(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) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%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) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%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) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%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) TC_LOG_ERROR("lfg.queue.match.compatibility.check", "Guids: 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()) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%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 << ": " << GetRolesString(it->second); TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%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 << ": (" << ConcatenateDungeons(proposalDungeons) << ")"; for (++itguid; itguid != check.end(); ++itguid) { LfgDungeonSet temporal; LfgDungeonSet &dungeons = QueueDataStore[*itguid].dungeons; o << ", " << *itguid << ": (" << ConcatenateDungeons(dungeons) << ")"; std::set_intersection(proposalDungeons.begin(), proposalDungeons.end(), dungeons.begin(), dungeons.end(), std::inserter(temporal, temporal.begin())); proposalDungeons = temporal; } if (proposalDungeons.empty()) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%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) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%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; } uint64 gguid = *check.begin(); proposal.queues = check; proposal.isNew = numLfgGroups != 1 || sLFGMgr->GetOldState(gguid) != LFG_STATE_DUNGEON; if (!sLFGMgr->AllQueued(check)) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%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 = Trinity::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); TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%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()); // Dungeons Seleccionables con el evento en el server correspondiente. (En Dungeon Finder) if (dungeon && dungeon->grouptype == 11 && dungeon->expansion <= expansion && dungeon->minlevel <= level && level <= dungeon->maxlevel) { QueryResult result = WorldDatabase.Query("SELECT dungeonId, eventEntry FROM lfg_dungeon_event"); if (!result) return; Field* fields = NULL; do { fields = result->Fetch(); uint32 dungeonId = fields[0].GetUInt32(); uint32 eventEntry = fields[1].GetUInt32(); if (dungeonId != dungeon->ID ) continue; if (eventEntry && sGameEventMgr->IsActiveEvent(eventEntry)) randomDungeons.insert(dungeon->Entry()); } while (result->NextRow()); } } // 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()) { 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); } } BuildPlayerLockDungeonBlock(data, lock); SendPacket(&data); }
void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& recv_data) { Log.Debug("LfgHandler", "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST"); uint64 guid = GetPlayer()->GetGUID(); Log.Debug("LfgHandler", "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST %u", 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()->GetFlags(); for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i) { DBC::Structures::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()); } // Get player locked Dungeons LfgLockMap lock = sLfgMgr.GetLockedDungeons(guid); uint32 rsize = uint32(randomDungeons.size()); uint32 lsize = uint32(lock.size()); Log.Debug("LfgHandler", "SMSG_LFG_PLAYER_INFO %u", 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* qRew = NULL; uint8 done = 0; if (reward) { qRew = QuestStorage.LookupEntry(reward->reward[0].questId); if (qRew) { done = GetPlayer()->HasFinishedQuest(qRew->id); if (done) qRew = QuestStorage.LookupEntry(reward->reward[1].questId); } } if (qRew) { data << uint8(done); data << uint32(qRew->reward_money); data << uint32(qRew->reward_xp); data << uint32(reward->reward[done].variableMoney); data << uint32(reward->reward[done].variableXP); ///\todo FIXME Linux: error: cast from const uint32* {aka const unsigned int*} to uint8 {aka unsigned char} loses precision /// can someone check this now ? data << uint8(qRew->GetRewardItemCount()); for (uint8 i = 0; i < 4; ++i) if (qRew->reward_item[i] != 0) { ItemPrototype* item = ItemPrototypeStorage.LookupEntry(qRew->reward_item[i]); data << uint32(qRew->reward_item[i]); data << uint32(item ? item->DisplayInfoID : 0); data << uint32(qRew->reward_itemcount[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::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::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::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*/) { 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->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]); } } } 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 <= level && level <= 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); } } 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::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); }