void LfgGroup::SendUpdate() { Player *player; for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { player = sObjectMgr.GetPlayer(citr->guid); if (!player || !player->GetSession() || player->GetGroup() != this ) continue; // guess size WorldPacket data(SMSG_GROUP_LIST, (1+1+1+1+8+4+GetMembersCount()*20)); data << uint8(m_groupType); // group type (flags in 3.3) data << uint8(citr->group); // groupid data << uint8(GetFlags(*citr)); // group flags data << uint8(GetPlayerRole(citr->guid)); // 2.0.x, isBattleGroundGroup? <--- Its flags or maybe more likely roles....? data << uint8(m_instanceStatus); // Instance status 0= not saved, 1= saved, 2 = completed data << uint32(GetDungeonInfo(IsFromRnd(citr->guid))->Entry());// dungeon entry data << uint64(0x1F54000004D3B000); // related to voice chat? data << uint32(0); // 3.3, this value increments every time SMSG_GROUP_LIST is sent data << uint32(GetMembersCount()-1); for(member_citerator citr2 = m_memberSlots.begin(); citr2 != m_memberSlots.end(); ++citr2) { if (citr->guid == citr2->guid) continue; Player* member = sObjectMgr.GetPlayer(citr2->guid); uint8 onlineState = (member) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; onlineState = onlineState | ((isBGGroup()) ? MEMBER_STATUS_PVP : 0); if(member) { if(member->isAFK()) onlineState |= MEMBER_STATUS_AFK; if(member->isDND()) onlineState |= MEMBER_STATUS_DND; } data << citr2->name; data << uint64(citr2->guid); data << uint8(onlineState); // online-state data << uint8(citr2->group); // groupid data << uint8(GetFlags(*citr2)); // group flags data << uint8(GetPlayerRole(citr2->guid)); // 3.3, role? } data << uint64(m_leaderGuid); // leader guid if (GetMembersCount()-1) { data << uint8(m_lootMethod); // loot method data << uint64(m_looterGuid); // looter guid data << uint8(m_lootThreshold); // loot threshold data << uint8(m_dungeonDifficulty); // Dungeon Difficulty data << uint8(m_raidDifficulty); // Raid Difficulty data << uint8(0); // 3.3, dynamic difficulty? } player->GetSession()->SendPacket( &data ); } }
void Group::SendUpdate() { for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player* player = sObjectMgr.GetPlayer(citr->guid); if (!player || !player->GetSession() || player->GetGroup() != this) continue; // guess size WorldPacket data(SMSG_GROUP_LIST, (1 + 1 + 1 + 1 + 8 + 4 + GetMembersCount() * 20)); data << uint8(m_groupType); // group type (flags in 3.3) data << uint8(citr->group); // groupid data << uint8(GetFlags(*citr)); // group flags data << uint8(isBGGroup() ? 1 : 0); // 2.0.x, isBattleGroundGroup? if (m_groupType & GROUPTYPE_LFD) { data << uint8(0); data << uint32(0); } data << GetObjectGuid(); // group guid data << uint32(0); // 3.3, this value increments every time SMSG_GROUP_LIST is sent data << uint32(GetMembersCount() - 1); for (member_citerator citr2 = m_memberSlots.begin(); citr2 != m_memberSlots.end(); ++citr2) { if (citr->guid == citr2->guid) continue; Player* member = sObjectMgr.GetPlayer(citr2->guid); uint8 onlineState = (member && member->GetSession() && !member->GetSession()->PlayerLogout()) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; onlineState = onlineState | ((isBGGroup()) ? MEMBER_STATUS_PVP : 0); data << citr2->name; data << citr2->guid; data << uint8(onlineState); data << uint8(citr2->group); // groupid data << uint8(GetFlags(*citr2)); // group flags data << uint8(0); // 3.3, role? } ObjectGuid masterLootGuid = (m_lootMethod == MASTER_LOOT) ? m_masterLooterGuid : ObjectGuid(); data << m_leaderGuid; // leader guid if (GetMembersCount() - 1) { data << uint8(m_lootMethod); // loot method data << masterLootGuid; // master loot guid data << uint8(m_lootThreshold); // loot threshold data << uint8(m_dungeonDifficulty); // Dungeon Difficulty data << uint8(m_raidDifficulty); // Raid Difficulty data << uint8(0); // 3.3, dynamic difficulty? } player->GetSession()->SendPacket(&data); } }
uint32 Group::RemoveInvite(Player* player) { m_invitees.erase(player); player->SetGroupInvite(NULL); return GetMembersCount(); }
bool LfgGroup::UpdateCheckTimer(uint32 time) { m_readycheckTimer += time; if (m_readycheckTimer >= LFG_TIMER_READY_CHECK || GetMembersCount() != LFG_GROUP) return false; return true; }
bool LfgGroup::RemoveOfflinePlayers() // Return true if group is empty after check { sLfgMgr.LfgLog("Remove Offline %u, premade %u", GetId(), premadePlayers.empty() ? 0 : 1); if (m_memberSlots.empty()) { sLfgMgr.LfgLog("Group %u add to delete", GetId()); sLfgMgr.AddGroupToDelete(this); return true; } PlayerList toRemove; for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { sLfgMgr.LfgLog("guid %u", citr->guid); Player *plr = sObjectMgr.GetPlayer(citr->guid); if (!plr || (!plr->GetSession() && !plr->IsBeingTeleported()) || (plr->GetGroup() && plr->GetGroup() != this && plr->GetGroup()->isLfgGroup() && ((LfgGroup*)plr->GetGroup())->IsInDungeon())) { sLfgMgr.LfgLog("Add to remove"); toRemove.insert(citr->guid); } } for(PlayerList::iterator itr = toRemove.begin(); itr != toRemove.end(); ++itr) { sLfgMgr.LfgLog("Check for premade %u", *itr); PlayerList::iterator premade = premadePlayers.find(*itr); if(premade != premadePlayers.end()) { sLfgMgr.LfgLog("premade yes"); for(PlayerList::iterator prm = premadePlayers.begin(); prm != premadePlayers.end(); ++prm) { Player *plr = sObjectMgr.GetPlayer(*prm); if(!plr || !plr->GetSession()) continue; Group* group = plr->GetGroup(); if(group) { sLfgMgr.RemoveFromQueue(plr, false); return true; } } for(PlayerList::iterator prm = premadePlayers.begin(); prm != premadePlayers.end(); ++prm) RemoveMember(*prm, 0); } } for(PlayerList::iterator itr = toRemove.begin(); itr != toRemove.end(); ++itr) { sLfgMgr.LfgLog("Remove %u", *itr); RemoveMember(*itr, 0); } toRemove.clear(); //flush empty group if (GetMembersCount() == 0) { sLfgMgr.LfgLog("Group %u add to delete 2", GetId()); sLfgMgr.AddGroupToDelete(this); return true; } return false; }
bool LfgGroup::AddMember(const uint64 &guid, const char* name) { Player *player = sObjectMgr.GetPlayer(guid); if (!player) return false; if (GetMembersCount() == 0) m_baseLevel = player->getLevel(); sLfgMgr.LfgLog("Add member %u , guid %u", GetId(), guid); member_witerator slot = _getMemberWSlot(guid); if (slot != m_memberSlots.end()) { sLfgMgr.LfgLog("Player already in group, aborting!"); return true; } MemberSlot member; member.guid = guid; member.name = name; member.group = 0; member.assistant = false; m_memberSlots.push_back(member); UpdateItemLevelValues(); if (!GetDungeonInfo(true)) SetOriginalDungeonInfo(GetDungeonInfo()); player->m_lookingForGroup.groups.insert(std::pair<uint32, uint32>(GetDungeonInfo(true)->ID,GetId())); return true; }
void LfgGroup::InitVoteKick(uint64 who, Player *initiator, std::string reason) { //Checks first PartyResult error = ERR_PARTY_RESULT_OK; if (GetMembersCount() <= 3) error = ERR_PARTY_LFG_BOOT_TOO_FEW_PLAYERS; else if (m_instanceStatus == INSTANCE_COMPLETED) error = ERR_PARTY_LFG_BOOT_DUNGEON_COMPLETE; else if (m_voteToKick.isInProggres) error = ERR_PARTY_LFG_BOOT_IN_PROGRESS; if (error != ERR_PARTY_RESULT_OK) { initiator->GetSession()->SendPartyResult(PARTY_OP_LEAVE, "", error); return; } m_voteToKick.Reset(); m_voteToKick.isInProggres = true; m_voteToKick.victim = who; m_voteToKick.beginTime = getMSTime(); m_voteToKick.reason = reason; m_voteToKick.votes[initiator->GetGUID()] = 1; // initiator agrees automatically m_voteKickTimer = 0; for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *member = sObjectMgr.GetPlayer(citr->guid); if (!member || !member->GetSession()) continue; SendBootPlayer(member); } sLfgMgr.AddVoteKickGroup(this); }
uint32 Group::RemoveMember(ObjectGuid guid, uint8 method) { //Playerbot mod - if master leaves group, all bots leave group { Player* const player = sObjectMgr.GetPlayer(guid); if (player && player->GetPlayerbotMgr()) player->GetPlayerbotMgr()->RemoveAllBotsFromGroup(); } //END Playerbot mod // remove member and change leader (if need) only if strong more 2 members _before_ member remove if (GetMembersCount() > uint32(isBGGroup() ? 1 : 2)) // in BG group case allow 1 members group { bool leaderChanged = _removeMember(guid); if (Player* player = sObjectMgr.GetPlayer(guid)) { // quest related GO state dependent from raid membership if (isRaidGroup()) player->UpdateForQuestWorldObjects(); WorldPacket data; if (method == 1) { data.Initialize(SMSG_GROUP_UNINVITE, 0); player->GetSession()->SendPacket(&data); } // we already removed player from group and in player->GetGroup() is his original group! if (Group* group = player->GetGroup()) { group->SendUpdate(); } else { data.Initialize(SMSG_GROUP_LIST, 24); data << uint64(0) << uint64(0) << uint64(0); player->GetSession()->SendPacket(&data); } _homebindIfInstance(player); } if (leaderChanged) { WorldPacket data(SMSG_GROUP_SET_LEADER, (m_memberSlots.front().name.size() + 1)); data << m_memberSlots.front().name; BroadcastPacket(&data, true); } SendUpdate(); } // if group before remove <= 2 disband it else Disband(true); return m_memberSlots.size(); }
GroupJoinBattlegroundResult Group::CanJoinBattleGroundQueue(BattleGround const* bgOrTemplate, BattleGroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 /*MaxPlayerCount*/, bool isRated, uint32 arenaSlot) { BattlemasterListEntry const* bgEntry = sBattlemasterListStore.LookupEntry(bgOrTemplate->GetTypeID()); if (!bgEntry) return ERR_GROUP_JOIN_BATTLEGROUND_FAIL; // shouldn't happen // check for min / max count uint32 memberscount = GetMembersCount(); // only check for MinPlayerCount since MinPlayerCount == MaxPlayerCount for arenas... if (bgOrTemplate->isArena() && memberscount != MinPlayerCount) return ERR_ARENA_TEAM_PARTY_SIZE; if (memberscount > bgEntry->maxGroupSize) // no MinPlayerCount for battlegrounds return ERR_BATTLEGROUND_NONE; // ERR_GROUP_JOIN_BATTLEGROUND_TOO_MANY handled on client side // get a player as reference, to compare other players' stats to (arena team id, queue id based on level, etc.) Player* reference = GetFirstMember()->getSource(); // no reference found, can't join this way if (!reference) return ERR_BATTLEGROUND_JOIN_FAILED; PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgOrTemplate->GetMapId(), reference->getLevel()); if (!bracketEntry) return ERR_BATTLEGROUND_JOIN_FAILED; uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot); Team team = reference->GetTeam(); // check every member of the group to be able to join for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->getSource(); // offline member? don't let join if (!member) return ERR_BATTLEGROUND_JOIN_FAILED; // don't allow cross-faction join as group if (member->GetTeam() != team) return ERR_BATTLEGROUND_JOIN_TIMED_OUT; // not in the same battleground level bracket, don't let join PvPDifficultyEntry const* memberBracketEntry = GetBattlegroundBracketByLevel(bracketEntry->mapId, member->getLevel()); if (memberBracketEntry != bracketEntry) return ERR_BATTLEGROUND_JOIN_RANGE_INDEX; // don't let join rated matches if the arena team id doesn't match if (isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId) return ERR_BATTLEGROUND_JOIN_FAILED; // don't let join if someone from the group is already in that bg queue if (member->InBattleGroundQueueForBattleGroundQueueType(bgQueueTypeId)) return ERR_BATTLEGROUND_JOIN_FAILED; // not blizz-like // check for deserter debuff in case not arena queue if (bgOrTemplate->GetTypeID() != BATTLEGROUND_AA && !member->CanJoinToBattleground()) return ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS; // check if member can join any more battleground queues if (!member->HasFreeBattleGroundQueueId()) return ERR_BATTLEGROUND_TOO_MANY_QUEUES; // not blizz-like } return GroupJoinBattlegroundResult(bgOrTemplate->GetTypeID()); }
void Group::SendUpdate() { for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player* player = sObjectMgr.GetPlayer(citr->guid); if (!player || !player->GetSession() || player->GetGroup() != this) continue; // guess size WorldPacket data(SMSG_GROUP_LIST, (1 + 1 + 1 + 1 + 8 + 4 + GetMembersCount() * 20)); data << uint8(m_groupType); // group type data << uint8(isBGGroup() ? 1 : 0); // 2.0.x, isBattleGroundGroup? data << uint8(citr->group); // groupid data << uint8(citr->assistant ? 0x01 : 0); // 0x2 main assist, 0x4 main tank data << GetObjectGuid(); // group guid data << uint32(GetMembersCount() - 1); for (member_citerator citr2 = m_memberSlots.begin(); citr2 != m_memberSlots.end(); ++citr2) { if (citr->guid == citr2->guid) continue; Player* member = sObjectMgr.GetPlayer(citr2->guid); uint8 onlineState = (member) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; onlineState = onlineState | ((isBGGroup()) ? MEMBER_STATUS_PVP : 0); data << citr2->name; data << citr2->guid; // online-state data << uint8(sObjectMgr.GetPlayer(citr2->guid) ? 1 : 0); data << uint8(citr2->group); // groupid data << uint8(citr2->assistant ? 0x01 : 0); // 0x2 main assist, 0x4 main tank } ObjectGuid masterLootGuid = (m_lootMethod == MASTER_LOOT) ? m_masterLooterGuid : ObjectGuid(); data << m_leaderGuid; // leader guid if (GetMembersCount() - 1) { data << uint8(m_lootMethod); // loot method data << masterLootGuid; // master loot guid data << uint8(m_lootThreshold); // loot threshold data << uint8(m_difficulty); // Heroic Mod Group } player->GetSession()->SendPacket(&data); } }
void Group::SendUpdate() { Player* player; for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { player = sObjectMgr.GetPlayer(citr->guid); if (!player || !player->GetSession() || player->GetGroup() != this) continue; // guess size WorldPacket data(SMSG_GROUP_LIST, (1 + 1 + 1 + 4 + GetMembersCount() * 20) + 8 + 1 + 8 + 1); data << (uint8)m_groupType; // group type data << (uint8)(citr->group | (citr->assistant ? 0x80 : 0)); // own flags (groupid | (assistant?0x80:0)) data << uint32(GetMembersCount() - 1); for (member_citerator citr2 = m_memberSlots.begin(); citr2 != m_memberSlots.end(); ++citr2) { if (citr->guid == citr2->guid) continue; Player* member = sObjectMgr.GetPlayer(citr2->guid); uint8 onlineState = (member) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; onlineState = onlineState | ((isBGGroup()) ? MEMBER_STATUS_PVP : 0); data << citr2->name; data << citr2->guid; // online-state data << uint8(sObjectMgr.GetPlayer(citr2->guid) ? 1 : 0); data << (uint8)(citr2->group | (citr2->assistant ? 0x80 : 0)); } ObjectGuid masterLootGuid = (m_lootMethod == MASTER_LOOT) ? m_masterLooterGuid : ObjectGuid(); data << m_leaderGuid; // leader guid if (GetMembersCount() - 1) { data << uint8(m_lootMethod); // loot method data << masterLootGuid; // master loot guid data << uint8(m_lootThreshold); // loot threshold } player->GetSession()->SendPacket(&data); } }
uint32 Group::GetMemberCountForXPAtKill(Unit const* victim) { uint32 count = 0; for (uint32 i = 0; i < GetMembersCount(); i++) { Player* member = GetMemberForXPAtKill(i,victim); if(member) ++count; } return count; }
void Group::SendUpdate() { for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player* player = sObjectMgr.GetPlayer(citr->guid); if (!player || !player->GetSession() || player->GetGroup() != this) continue; // guess size WorldPacket data(SMSG_GROUP_LIST, (1 + 1 + 1 + 1 + 8 + 4 + GetMembersCount() * 20)); data << uint8(m_groupType); // group type data << uint8(isBattleGroup() ? 1 : 0); // 2.0.x, isBattleGroundGroup? data << uint8(citr->group); // groupid data << uint8(GetFlags(*citr)); // group flags data << GetObjectGuid(); // group guid data << uint32(GetMembersCount() - 1); for (member_citerator citr2 = m_memberSlots.begin(); citr2 != m_memberSlots.end(); ++citr2) { if (citr->guid == citr2->guid) continue; data << citr2->name; data << citr2->guid; data << uint8(GetGroupMemberStatus(sObjectMgr.GetPlayer(citr2->guid))); data << uint8(citr2->group); // groupid data << uint8(GetFlags(*citr2)); // group flags } ObjectGuid masterLootGuid = (m_lootMethod == MASTER_LOOT) ? m_masterLooterGuid : ObjectGuid(); data << m_leaderGuid; // leader guid if (GetMembersCount() - 1) { data << uint8(m_lootMethod); // loot method data << masterLootGuid; // master loot guid data << uint8(m_lootThreshold); // loot threshold data << uint8(m_difficulty); // Heroic Mod Group } player->GetSession()->SendPacket(data); } }
uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot) { // check for min / max count uint32 memberscount = GetMembersCount(); if (memberscount < MinPlayerCount) return BG_JOIN_ERR_GROUP_NOT_ENOUGH; if (memberscount > MaxPlayerCount) return BG_JOIN_ERR_GROUP_TOO_MANY; // get a player as reference, to compare other players' stats to (arena team id, queue id based on level, etc.) Player* reference = GetFirstMember()->getSource(); // no reference found, can't join this way if (!reference) return BG_JOIN_ERR_OFFLINE_MEMBER; BattleGroundBracketId bracket_id = reference->GetBattleGroundBracketIdFromLevel(bgTypeId); uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot); Team team = reference->GetTeam(); // check every member of the group to be able to join for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->getSource(); // offline member? don't let join if (!member) return BG_JOIN_ERR_OFFLINE_MEMBER; // don't allow cross-faction join as group if (member->GetTeam() != team) return BG_JOIN_ERR_MIXED_FACTION; // not in the same battleground level bracket, don't let join if (member->GetBattleGroundBracketIdFromLevel(bgTypeId) != bracket_id) return BG_JOIN_ERR_MIXED_LEVELS; // don't let join rated matches if the arena team id doesn't match if (isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId) return BG_JOIN_ERR_MIXED_ARENATEAM; // don't let join if someone from the group is already in that bg queue if (member->InBattleGroundQueueForBattleGroundQueueType(bgQueueTypeId)) return BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_QUEUE; // check for deserter debuff in case not arena queue if (bgTypeId != BATTLEGROUND_AA && !member->CanJoinToBattleground()) return BG_JOIN_ERR_GROUP_DESERTER; // check if member can join any more battleground queues if (!member->HasFreeBattleGroundQueueId()) return BG_JOIN_ERR_ALL_QUEUES_USED; } return BG_JOIN_ERR_OK; }
void Group::_chooseLeader(bool offline /*= false*/) { if (GetMembersCount() < GetMembersMinCount()) return; ObjectGuid first = ObjectGuid(); // First available: if no suitable canditates are found ObjectGuid chosen = ObjectGuid(); // Player matching prio creteria for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { if (citr->guid == m_leaderGuid) continue; // Prioritize online players Player* player = sObjectMgr.GetPlayer(citr->guid); if (!player || !player->GetSession() || player->GetGroup() != this) continue; // Prioritize assistants for raids if (isRaidGroup() && !citr->assistant) { if (first.IsEmpty()) first = citr->guid; continue; } chosen = citr->guid; break; } if (chosen.IsEmpty()) chosen = first; // If we are choosing a new leader due to inactivity, check if everyone is offline first if (offline && chosen.IsEmpty()) return; // Still nobody online... if (chosen.IsEmpty()) chosen = m_memberSlots.front().guid; // Do announce if we are choosing a new leader due to old one being offline return (offline ? ChangeLeader(chosen) : _setLeader(chosen)); }
bool Group::_removeMember(ObjectGuid guid) { Player* player = sObjectMgr.GetPlayer(guid); if (player) { // if we are removing player from battleground raid if (isBGGroup()) player->RemoveFromBattleGroundRaid(); else { // we can remove player who is in battleground from his original group if (player->GetOriginalGroup() == this) player->SetOriginalGroup(nullptr); else player->SetGroup(nullptr); } } member_witerator slot = _getMemberWSlot(guid); if (slot != m_memberSlots.end()) { SubGroupCounterDecrease(slot->group); m_memberSlots.erase(slot); } if (!isBGGroup()) CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid='%u'", guid.GetCounter()); if (m_leaderGuid == guid) // leader was removed { _updateLeaderFlag(true); if (GetMembersCount() > 0) _setLeader(m_memberSlots.front().guid); return true; } return false; }
uint32 Group::RemoveMember(ObjectGuid guid, uint8 method) { Player* player = sObjectMgr.GetPlayer(guid); #ifdef BUILD_PLAYERBOT // if master leaves group, all bots leave group if (player && player->GetPlayerbotMgr()) player->GetPlayerbotMgr()->RemoveAllBotsFromGroup(); #endif for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { if (Player* groupMember = itr->getSource()) { if (groupMember->GetObjectGuid() == guid) continue; groupMember->RemoveAllGroupBuffsFromCaster(guid); if (player) player->RemoveAllGroupBuffsFromCaster(groupMember->GetObjectGuid()); } } // remove member and change leader (if need) only if strong more 2 members _before_ member remove if (GetMembersCount() > GetMembersMinCount()) { bool leaderChanged = _removeMember(guid); if (player) { // quest related GO state dependent from raid membership if (isRaidGroup()) player->UpdateForQuestWorldObjects(); WorldPacket data; if (method == 1) { data.Initialize(SMSG_GROUP_UNINVITE, 0); player->GetSession()->SendPacket(data); } // we already removed player from group and in player->GetGroup() is his original group! if (Group* group = player->GetGroup()) { group->SendUpdate(); } else { data.Initialize(SMSG_GROUP_LIST, 24); data << uint64(0) << uint64(0) << uint64(0); player->GetSession()->SendPacket(data); } _homebindIfInstance(player); } if (leaderChanged) { WorldPacket data(SMSG_GROUP_SET_LEADER, (m_leaderName.size() + 1)); data << m_leaderName; BroadcastPacket(data, true); } SendUpdate(); } // if group before remove <= 2 disband it else Disband(true); return m_memberSlots.size(); }
void LfgGroup::TeleportToDungeon() { if (IsInDungeon()) { for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *plr = sObjectMgr.GetPlayer(citr->guid); if (!plr || !plr->GetSession()) continue; plr->m_lookingForGroup.queuedDungeons.clear(); if (plr->GetMapId() == m_dungeonInfo->map) { sLfgMgr.SendLfgUpdatePlayer(plr, LFG_UPDATETYPE_REMOVED_FROM_QUEUE); sLfgMgr.SendLfgUpdateParty(plr, LFG_UPDATETYPE_REMOVED_FROM_QUEUE); continue; } DungeonInfo* dungeonInfo = sLfgMgr.GetDungeonInfo(m_dungeonInfo->ID); plr->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, GetMembersCount()-1); TeleportPlayer(plr, dungeonInfo, m_dungeonInfo->ID); } return; } //If random, then select here if (m_dungeonInfo->type == LFG_TYPE_RANDOM && !SelectRandomDungeon()) return; DungeonInfo* dungeonInfo = sLfgMgr.GetDungeonInfo(m_dungeonInfo->ID); //Set Leader m_leaderGuid = 0; for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *plr = sObjectMgr.GetPlayer(citr->guid); if (!plr || !plr->GetSession()) continue; if (IsPremade() && plr->GetGroup()) { plr->GetGroup()->UnbindInstance(dungeonInfo->start_map, m_dungeonInfo->isHeroic() ? DUNGEON_DIFFICULTY_HEROIC : DUNGEON_DIFFICULTY_NORMAL); m_leaderGuid = plr->GetGroup()->GetLeaderGUID(); m_leaderName = plr->GetGroup()->GetLeaderName(); break; } else if (plr->m_lookingForGroup.roles & LEADER) { m_leaderGuid = plr->GetGUID(); m_leaderName = plr->GetName(); break; } } if (m_leaderGuid == 0) { m_leaderGuid = m_memberSlots.begin()->guid; m_leaderName = m_memberSlots.begin()->name; } m_lootMethod = GROUP_LOOT; m_lootThreshold = ITEM_QUALITY_UNCOMMON; m_looterGuid = m_leaderGuid; m_dungeonDifficulty = m_dungeonInfo->isHeroic() ? DUNGEON_DIFFICULTY_HEROIC : DUNGEON_DIFFICULTY_NORMAL; m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; //sort group members... UnbindInstance(dungeonInfo->start_map, m_dungeonInfo->isHeroic() ? DUNGEON_DIFFICULTY_HEROIC : DUNGEON_DIFFICULTY_NORMAL); CharacterDatabase.PExecute("DELETE FROM group_member WHERE groupId ='%u'", m_Id); ResetInstances(INSTANCE_RESET_ALL, true, NULL); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL); for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *plr = sObjectMgr.GetPlayer(citr->guid); if (!plr || !plr->GetSession()) continue; plr->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, GetMembersCount()-1); TeleportPlayer(plr, dungeonInfo, GetDungeonInfo(true)->ID); } m_lfgFlags |= LFG_GRP_IN_DUNGEON; //Save to DB CharacterDatabase.PExecute("DELETE FROM groups WHERE groupId ='%u' OR leaderGuid='%u'", m_Id, GUID_LOPART(m_leaderGuid)); CharacterDatabase.PExecute("INSERT INTO groups (groupId,leaderGuid,mainTank,mainAssistant,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,groupType,difficulty,raiddifficulty,healGuid,LfgId,LfgRandomEntry,LfgInstanceStatus,LfgFlags) " "VALUES ('%u','%u','%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u','%u','%u','%u','%u','%u','%u')", m_Id, GUID_LOPART(m_leaderGuid), GUID_LOPART(m_tank), GUID_LOPART(m_mainAssistant), uint32(m_lootMethod), GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7], uint8(m_groupType), uint32(m_dungeonDifficulty), uint32(m_raidDifficulty), GUID_LOPART(m_heal), m_dungeonInfo->ID, GetDungeonInfo(true)->ID, m_instanceStatus, uint8(m_lfgFlags)); }
void LfgGroup::UpdateRoleCheck(uint32 diff) { sLfgMgr.LfgLog("Updaterolecheck %u, diff %u", GetId(), diff); if (diff != 0) { m_readycheckTimer += diff; if (m_readycheckTimer >= LFG_TIMER_READY_CHECK && m_roleCheck.m_beforeCheck != m_roleCheck.m_rolesProposal.size()) { SendRoleCheckFail(LFG_ROLECHECK_MISSING_ROLE); return; } } //offline check bool offline = false; for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *player = sObjectMgr.GetPlayer(citr->guid); if (!player) { offline = true; break; } } if (GetMembersCount() != m_roleCheck.m_beforeCheck || offline) { SendRoleCheckFail(LFG_ROLECHECK_ABORTED); return; } // add answers for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *player = sObjectMgr.GetPlayer(citr->guid); if (m_roleCheck.m_rolesProposal.find(citr->guid) != m_roleCheck.m_rolesProposal.end() || !player || !player->GetSession() || player->m_lookingForGroup.roles == 0) continue; m_roleCheck.m_rolesProposal[player->GetGUID()] = player->m_lookingForGroup.roles; WorldPacket data(SMSG_LFG_ROLE_CHOSEN, 13); data << uint64(player->GetGUID()); data << uint8(1); data << uint32(player->m_lookingForGroup.roles); BroadcastPacket(&data, false); } //Offline members checked at join //Check roles if (m_roleCheck.m_beforeCheck > m_roleCheck.m_rolesProposal.size()) return; Player *leader = sObjectMgr.GetPlayer(GetLeaderGUID()); if(!leader || !leader->IsInWorld() || !m_roleCheck.TryRoles(this)) { SendRoleCheckFail(LFG_ROLECHECK_WRONG_ROLES); return; } SetAsRole(TANK, m_roleCheck.tank); SetAsRole(HEALER, m_roleCheck.heal); dps.clear(); dps = m_roleCheck.dps; //Move group to queue SendRoleCheckUpdate(LFG_ROLECHECK_FINISHED); for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *player = sObjectMgr.GetPlayer(citr->guid); if (!player || !player->GetSession()) continue; if (player->GetGUID() == GetLeaderGUID()) sLfgMgr.SendJoinResult(player, LFG_JOIN_OK); else { //player->m_lookingForGroup.roles = GetPlayerRole(player->GetGUID()); player->m_lookingForGroup.comment = ""; player->m_lookingForGroup.joinTime = getMSTime(); player->m_lookingForGroup.queuedDungeons = leader->m_lookingForGroup.queuedDungeons; } if (IsInDungeon()) premadePlayers.insert(player->GetGUID()); } m_lfgFlags &= ~LFG_GRP_ROLECHECK; SendUpdate(); sLfgMgr.RemoveRoleCheckGroup(this); if(GetMembersCount() == LFG_GROUP) TeleportToDungeon(); else sLfgMgr.AddCheckedGroup(this, true); }
void LfgGroup::SendRoleCheckUpdate(uint8 state) { if (state == LFG_ROLECHECK_INITIALITING) { m_lfgFlags |= LFG_GRP_ROLECHECK; ResetGroup(); if (IsInDungeon()) premadePlayers.clear(); m_roleCheck.Reset(); m_roleCheck.m_beforeCheck = GetMembersCount(); } Player *leader = sObjectMgr.GetPlayer(GetLeaderGUID()); if (!leader) return; WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 6 + leader->m_lookingForGroup.queuedDungeons.size() * 4 + 1 + GetMembersCount() * 14); data << uint32(state); data << uint8(state == LFG_ROLECHECK_INITIALITING); // begining data << uint8(leader->m_lookingForGroup.queuedDungeons.size()); for (LfgDungeonList::const_iterator it = leader->m_lookingForGroup.queuedDungeons.begin(); it != leader->m_lookingForGroup.queuedDungeons.end(); ++it) data << uint32((*it)->Entry()); data << uint8(GetMembersCount()); //leader first data << uint64(GetLeaderGUID()); ProposalAnswersMap::iterator itr = m_roleCheck.m_rolesProposal.find(GetLeaderGUID()); if (itr != m_roleCheck.m_rolesProposal.end()) { data << uint8(1); //ready data << uint32(itr->second); //roles } else { data << uint8(0); //ready data << uint32(0); //roles } data << uint8(leader->getLevel()); for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *member = sObjectMgr.GetPlayer(citr->guid); if (!member || !member->GetSession() || member->GetGUID() == GetLeaderGUID()) continue; itr = m_roleCheck.m_rolesProposal.find(citr->guid); data << uint64(member->GetGUID()); if(itr != m_roleCheck.m_rolesProposal.end()) { data << uint8(1); data << uint32(itr->second); }else data << uint8(0) << uint32(0); data << uint8(member->getLevel()); } for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *plr = sObjectMgr.GetPlayer(citr->guid); if (!plr || !plr->GetSession()) continue; if(state == LFG_ROLECHECK_INITIALITING) plr->m_lookingForGroup.roles = 0; plr->GetSession()->SendPacket(&data); } }