Ejemplo n.º 1
0
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 );
    }
}
Ejemplo n.º 2
0
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);
    }
}
Ejemplo n.º 3
0
uint32 Group::RemoveInvite(Player* player)
{
    m_invitees.erase(player);

    player->SetGroupInvite(NULL);
    return GetMembersCount();
}
Ejemplo n.º 4
0
bool LfgGroup::UpdateCheckTimer(uint32 time)
{
    m_readycheckTimer += time;
    if (m_readycheckTimer >= LFG_TIMER_READY_CHECK || GetMembersCount() != LFG_GROUP)
        return false;
    return true;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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);   
}
Ejemplo n.º 8
0
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();
}
Ejemplo n.º 9
0
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());
}
Ejemplo n.º 10
0
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);
    }
}
Ejemplo n.º 11
0
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);
    }
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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);
    }
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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));
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
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();
}
Ejemplo n.º 18
0
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));  
}
Ejemplo n.º 19
0
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);
}
Ejemplo n.º 20
0
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);
    }
}