Esempio n. 1
0
void WorldSession::HandleGroupAcceptOpcode( WorldPacket & recv_data )
{
    if (!GetPlayer()->GetPlayerbotAI())
        recv_data.read_skip<uint32>();                          // roles mask?

    Group *group = GetPlayer()->GetGroupInvite();
    if (!group)
        return;

    if (group->GetLeaderGuid() == GetPlayer()->GetObjectGuid())
    {
        sLog.outError("HandleGroupAcceptOpcode: %s tried to accept an invite to his own group",
            GetPlayer()->GetGuidStr().c_str());
        return;
    }

    // remove in from invites in any case
    group->RemoveInvite(GetPlayer());

    /** error handling **/
    /********************/

    // not have place
    if(group->IsFull())
    {
        SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL);
        return;
    }

    Player* leader = sObjectMgr.GetPlayer(group->GetLeaderGuid());

    // forming a new group, create it
    if (!group->IsCreated())
    {
        if (leader)
            group->RemoveInvite(leader);
        if (group->Create(group->GetLeaderGuid(), group->GetLeaderName()))
            sObjectMgr.AddGroup(group);
        else
            return;
    }

    // everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
    if(!group->AddMember(GetPlayer()->GetObjectGuid(), GetPlayer()->GetName()))
        return;

    // Frozen Mod
    group->BroadcastGroupUpdate();
    // Frozen Mod
}
Esempio n. 2
0
void WorldSession::HandleGroupUninviteOpcode(WorldPacket & recv_data)
{
    std::string membername;
    recv_data >> membername;

    // player not found
    if (!normalizePlayerName(membername))
        return;

    // can't uninvite yourself
    if (GetPlayer()->GetName() == membername)
    {
        ERROR_LOG("WorldSession::HandleGroupUninviteOpcode: leader %s tried to uninvite himself from the group.", GetPlayer()->GetGuidStr().c_str());
        return;
    }

    Group* grp = GetPlayer()->GetGroup();
    if (!grp)
        return;

    ObjectGuid guid = grp->GetMemberGuid(membername);

    PartyResult res = GetPlayer()->CanUninviteFromGroup();
    if (res != ERR_PARTY_RESULT_OK)
    {
        SendPartyResult(PARTY_OP_UNINVITE, "", res);
        return;
    }


    if (ObjectGuid guid = grp->GetMemberGuid(membername))
    {
        if (grp->GetLeaderGuid() == guid)
            return;
        Player::RemoveFromGroup(grp, guid);

        return;
    }

    if (Player* plr = grp->GetInvited(membername))
    {
        if (grp->GetLeaderGuid() == plr->GetObjectGuid())
            return;
        plr->UninviteFromGroup();
        return;
    }

    SendPartyResult(PARTY_OP_UNINVITE, membername, ERR_TARGET_NOT_IN_GROUP_S);
}
Esempio n. 3
0
void WorldSession::HandleLootMethodOpcode( WorldPacket & recv_data )
{
    uint32 lootMethod;
    ObjectGuid lootMaster;
    uint32 lootThreshold;
    recv_data >> lootMethod >> lootMaster >> lootThreshold;

    Group *group = GetPlayer()->GetGroup();
    if (!group)
        return;

    /** error handling **/
    if (!group->IsLeader(GetPlayer()->GetObjectGuid()))
        return;
    /********************/

    // everything is fine, do it
    group->SetLootMethod((LootMethod)lootMethod);

    // Assign leader as default looter
    if(lootMethod != MASTER_LOOT && lootMethod != FREE_FOR_ALL)
        group->SetLooterGuid(group->GetLeaderGuid());
    else
        group->SetLooterGuid(lootMaster);

    group->SetLootThreshold((ItemQualities)lootThreshold);
    group->SendUpdate();
}
Esempio n. 4
0
void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data)
{
    ObjectGuid guid;
    std::string reason;

    recv_data >> guid;
    recv_data >> reason;                     // reason

    // can't uninvite yourself
    if (guid == GetPlayer()->GetObjectGuid())
    {
        ERROR_LOG("WorldSession::HandleGroupUninviteGuidOpcode: leader %s tried to uninvite himself from the group.", GetPlayer()->GetGuidStr().c_str());
        return;
    }

    Group* grp = GetPlayer()->GetGroup();
    if(!grp)
        return;

    PartyResult res = GetPlayer()->CanUninviteFromGroup();
    if (res != ERR_PARTY_RESULT_OK)
    {
        SendPartyResult(PARTY_OP_UNINVITE, "", res);
        return;
    }

    if (grp->IsMember(guid))
    {
        if (grp->GetLeaderGuid() == guid)
            return;
        Player::RemoveFromGroup(grp, guid);

        return;
    }

    if (Player* plr = grp->GetInvited(guid))
    {
        if (grp->GetLeaderGuid() == plr->GetObjectGuid())
            return;
        plr->UninviteFromGroup();
        return;
    }

    SendPartyResult(PARTY_OP_UNINVITE, "", ERR_TARGET_NOT_IN_GROUP_S);
}
Esempio n. 5
0
void WorldSession::HandleLfgLeaveOpcode( WorldPacket & /*recv_data*/ )
{
    Group* group = GetPlayer()->GetGroup();

    DEBUG_LOG("CMSG_LFG_LEAVE %u in group: %u", GetPlayer()->GetObjectGuid().GetCounter(), group ? 1 : 0);

    // Check cheating - only leader can leave the queue
    if (!group || group->GetLeaderGuid() == GetPlayer()->GetObjectGuid())
        sLFGMgr.Leave(GetPlayer());

}
Esempio n. 6
0
void WorldSession::HandleGroupRequestJoinUpdates(WorldPacket& recv_data)
{
    Group* group = GetPlayer()->GetGroup();
    if (!group)
        return;

    WorldPacket data(SMSG_REAL_GROUP_UPDATE, 1 + 4 + 8);
    data << uint8(group->GetGroupType());
    data << uint32(group->GetMembersCount() - 1);
    data << ObjectGuid(group->GetLeaderGuid());
    SendPacket(&data);
}
Esempio n. 7
0
void WorldSession::HandleLfgLeaveOpcode(WorldPacket&  recvData)
{
    uint32 roles, time, reason, instanceId;
    recvData >> roles >> time >> reason >> instanceId;

    Group* group = _player->GetGroup();
    ObjectGuid guid = _player->GetObjectGuid();
    ObjectGuid gguid = group ? group->GetObjectGuid() : guid;

    sLog.outDebug("CMSG_LFG_LEAVE %s in group: %u",
        guid.GetString().c_str(), group ? 1 : 0);

    // Check cheating - only leader can leave the queue
    if (!group || group->GetLeaderGuid() == guid)
        sLFGMgr.LeaveLfg(gguid);
}
Esempio n. 8
0
LFGQueueSet LFGMgr::GetDungeonGroupQueue(LFGDungeonEntry const* dungeon, Team team)
{
    LFGQueueSet tmpSet;
    tmpSet.clear();
    LFGType type = LFG_TYPE_NONE;
    uint32 dungeonID = 0;
    uint8 searchEnd = LFG_TYPE_MAX;
    if (dungeon)
    {
        type = LFGType(dungeon->type);
        dungeonID = dungeon->ID;
        searchEnd = type+1;
    }

    for (uint8 i = type; i < searchEnd; ++i)
    {
        for (LFGQueueInfoMap::iterator itr = m_groupQueueInfoMap[i].begin(); itr != m_groupQueueInfoMap[i].end(); ++itr)
        {
            ObjectGuid guid = itr->first;
            if (!guid.IsGroup())
                continue;

            Group* group = sObjectMgr.GetGroup(guid);
            if (!group)
                continue;

            Player* player = sObjectMgr.GetPlayer(group->GetLeaderGuid());
            if (!player)
                continue;

            if (team && player->GetTeam() != team)
                continue;

            if (player->GetLFGState()->GetState() < LFG_STATE_LFR ||
                player->GetLFGState()->GetState() > LFG_STATE_PROPOSAL)
                continue;

            if (player->GetLFGState()->GetDungeons()->find(dungeon) == player->GetLFGState()->GetDungeons()->end())
                continue;

            tmpSet.insert(group->GetObjectGuid());
        }
    }
    return tmpSet;
}
Esempio n. 9
0
void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
{
    Group  *group  = GetPlayer()->GetGroupInvite();
    if (!group)
        return;

    // remember leader if online
    Player *leader = sObjectMgr.GetPlayer(group->GetLeaderGuid());

    // uninvite, group can be deleted
    GetPlayer()->UninviteFromGroup();

    if (!leader || !leader->GetSession())
        return;

    // report
    WorldPacket data( SMSG_GROUP_DECLINE, 10 );             // guess size
    data << GetPlayer()->GetName();
    leader->GetSession()->SendPacket( &data );
}
Esempio n. 10
0
void LFGMgr::Leave(Player* player)
{

    if (!sWorld.getConfig(CONFIG_BOOL_LFG_ENABLE) && !sWorld.getConfig(CONFIG_BOOL_LFR_ENABLE))
        return;

    ObjectGuid guid;
    Group* group = player->GetGroup();

    if (group)
    {
        if (player->GetObjectGuid() != group->GetLeaderGuid())
            return;
        else
            guid = group->GetObjectGuid();
    }
    else
        guid = player->GetObjectGuid();

    if (guid.IsEmpty())
        return;

    LFGType type = player->GetLFGState()->GetType();

    guid.IsGroup() ? _LeaveGroup(guid) : _Leave(guid);

    player->GetLFGState()->Clear();
    if (group)
    {
        group->GetLFGState()->Clear();
        player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_REMOVED_FROM_QUEUE, type);
    }
    player->GetSession()->SendLfgUpdatePlayer(LFG_UPDATETYPE_REMOVED_FROM_QUEUE, type);

    if(sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL) && player->GetSession()->GetSecurity() == SEC_PLAYER )
        player->LeaveLFGChannel();
}
Esempio n. 11
0
void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recv_data)
{
    ObjectGuid guid;
    uint32 bgTypeId_;
    uint32 instanceId;
    uint8 joinAsGroup;
    bool isPremade = false;
    Group* grp;

    recv_data >> instanceId;                                // instance id, 0 if First Available selected
    recv_data.ReadGuidMask<2, 0, 3, 1, 5>(guid);
    joinAsGroup = recv_data.ReadBit();
    recv_data.ReadGuidMask<4, 6, 7>(guid);
    recv_data.ReadGuidBytes<2, 6, 4, 3, 7, 0, 5, 1>(guid);

    bgTypeId_ = guid.GetCounter();
    DEBUG_LOG("WORLD: Received opcode CMSG_BATTLEMASTER_JOIN from %s, typeid: %u, asGroup: %u, bg guid: %s",
        _player->GetGuidStr().c_str(), bgTypeId_, joinAsGroup, guid.GetString().c_str());

    if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
    {
        sLog.outError("Battleground: invalid bgtype (%u) received. possible cheater? player guid %u", bgTypeId_, _player->GetGUIDLow());
        return;
    }

    BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);

    // can do this, since it's battleground, not arena
    BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, ARENA_TYPE_NONE);

    // ignore if player is already in BG
    if (_player->InBattleGround())
        return;

    // get bg instance or bg template if instance not found
    BattleGround* bg = NULL;
    if (instanceId)
        bg = sBattleGroundMgr.GetBattleGroundThroughClientInstance(instanceId, bgTypeId);

    if (!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId)))
    {
        sLog.outError("Battleground: no available bg / template found");
        return;
    }

    // expected bracket entry
    PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel());
    if (!bracketEntry)
        return;

    GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE;

    // check queue conditions
    if (!joinAsGroup)
    {
        // check Deserter debuff
        if (!_player->CanJoinToBattleground())
        {
            WorldPacket data;
            sBattleGroundMgr.BuildBattleGroundStatusFailedPacket(&data, bg, _player, 0, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
            _player->GetSession()->SendPacket(&data);
            return;
        }
        // check if already in queue
        if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
            // player is already in this queue
            return;
        // check if has free queue slots
        if (!_player->HasFreeBattleGroundQueueId())
            return;
    }
    else
    {
        grp = _player->GetGroup();
        // no group found, error
        if (!grp)
            return;
        if (grp->GetLeaderGuid() != _player->GetObjectGuid())
            return;
        err = grp->CanJoinBattleGroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
        isPremade = sWorld.getConfig(CONFIG_UINT32_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH) &&
                    (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam());
    }
    // if we're here, then the conditions to join a bg are met. We can proceed in joining.

    // _player->GetGroup() was already checked, grp is already initialized
    BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
    if (err)
    {
        WorldPacket data;
        sBattleGroundMgr.BuildBattleGroundStatusFailedPacket(&data, bg, _player, 0, err);
        SendPacket(&data);
    }
    else if (joinAsGroup)
    {
        GroupQueueInfo* ginfo = NULL;
        uint32 avgTime = 0;

        DEBUG_LOG("Battleground: the following players are joining as group:");
        ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, ARENA_TYPE_NONE, false, isPremade, 0);
        avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());

        for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
        {
            Player* member = itr->getSource();
            if (!member)
                continue;                                   // this should never happen

            // add to queue
            uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId);

            // send status packet (in queue)
            WorldPacket data;
            sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->arenaType);
            member->GetSession()->SendPacket(&data);
            DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName());
        }
        DEBUG_LOG("Battleground: group end");
    }
    else
    {
        GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, ARENA_TYPE_NONE, false, isPremade, 0);
        uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
        // already checked if queueSlot is valid, now just get it
        uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);

        WorldPacket data;
        // send status packet (in queue)
        sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->arenaType);
        SendPacket(&data);
        DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName());
    }
    sBattleGroundMgr.ScheduleQueueUpdate(0, ARENA_TYPE_NONE, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
}
Esempio n. 12
0
void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recv_data)
{
    DEBUG_LOG("WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
    // recv_data.hexlike();

    uint8 arenaslot;                                        // 2v2, 3v3 or 5v5

    recv_data >> arenaslot;

    // ignore if we already in BG or BG queue
    if (_player->InBattleGround())
        return;

    ArenaType arenatype = ArenaTeam::GetTypeBySlot(arenaslot);
    uint32 arenaRating = 0;

    if (!IsArenaTypeValid(arenatype))
    {
        sLog.outError("Unknown arena slot %u at HandleBattlemasterJoinArena()", arenaslot);
        return;
    }

    // check existence
    BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA);
    if (!bg)
    {
        sLog.outError("Battleground: template bg (all arenas) not found");
        return;
    }

    BattleGroundTypeId bgTypeId = bg->GetTypeID();
    BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype);
    PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel());
    if (!bracketEntry)
        return;

    Group* grp = _player->GetGroup();
    // no group found, error
    if (!grp)
        return;
    if (grp->GetLeaderGuid() != _player->GetObjectGuid())
        return;

    uint32 ateamId = _player->GetArenaTeamId(arenaslot);
    // check real arena team existence only here (if it was moved to group->CanJoin .. () then we would have to get it twice)
    ArenaTeam* at = sObjectMgr.GetArenaTeamById(ateamId);
    if (!at)
    {
        _player->GetSession()->SendNotInArenaTeamPacket(arenatype);
        return;
    }
    // get the team rating for queue
    arenaRating = at->GetRating();
    // the arena team id must match for everyone in the group
    // get the personal ratings for queue
    uint32 avg_pers_rating = 0;

    for (Group::member_citerator citr = grp->GetMemberSlots().begin(); citr != grp->GetMemberSlots().end(); ++citr)
    {
        ArenaTeamMember const* at_member = at->GetMember(citr->guid);
        if (!at_member)                                 // group member joining to arena must be in leader arena team
            return;

        // calc avg personal rating
        avg_pers_rating += at_member->personal_rating;
    }

    avg_pers_rating /= grp->GetMembersCount();

    // if avg personal rating is more than 150 points below the teams rating, the team will be queued against an opponent matching or similar to the average personal rating
    if (avg_pers_rating + 150 < arenaRating)
        arenaRating = avg_pers_rating;

    BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
    uint32 avgTime = 0;

    // may be Group::CanJoinBattleGroundQueue should be moved to player class...
    GroupJoinBattlegroundResult err = grp->CanJoinBattleGroundQueue(bg, bgQueueTypeId, arenatype, arenatype, true, arenaslot);
    if (!err)
    {
        DEBUG_LOG("Battleground: arena join as group start");
        DEBUG_LOG("Battleground: arena team id %u, leader %s queued with rating %u for type %u", _player->GetArenaTeamId(arenaslot), _player->GetName(), arenaRating, arenatype);

        GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, true, false, arenaRating, ateamId);
        avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
    }

    for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
    {
        Player* member = itr->getSource();
        if (!member)
            continue;

        WorldPacket data;

        if (err)
        {
            sBattleGroundMgr.BuildBattleGroundStatusFailedPacket(&data, bg, member, 0, err);
            member->GetSession()->SendPacket(&data);
            continue;
        }

        // add to queue
        uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId);

        // send status packet (in queue)
        sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
        member->GetSession()->SendPacket(&data);
        DEBUG_LOG("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName());
    }
    DEBUG_LOG("Battleground: arena join as group end");

    sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
}
Esempio n. 13
0
void WorldSession::SendLfgRoleCheckUpdate()
{
    if (!sWorld.getConfig(CONFIG_BOOL_LFG_ENABLE))
    {
        DEBUG_LOG("SendLfgRoleCheckUpdate %u failed - Dungeon finder disabled", GetPlayer()->GetObjectGuid().GetCounter());
        return;
    }

    Group* pGroup = GetPlayer()->GetGroup();
    if (!pGroup)
        return;

    LFGDungeonSet const* dungeons = sLFGMgr.GetLFGGroupState(pGroup->GetObjectGuid())->GetDungeons();
    if (!dungeons)
        return;

    DEBUG_LOG("SMSG_LFG_ROLE_CHECK_UPDATE %u, dugeons size " SIZEFMTD, GetPlayer()->GetObjectGuid().GetCounter(), dungeons->size());

    WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons->size() * 4 + 1 + pGroup->GetMembersCount() * (8 + 1 + 4 + 1));

    data << uint32(sLFGMgr.GetLFGGroupState(pGroup->GetObjectGuid())->GetRoleCheckState());                     // Check result
    data << uint8(sLFGMgr.GetLFGGroupState(pGroup->GetObjectGuid())->GetRoleCheckState() == LFG_ROLECHECK_INITIALITING);
    data << uint8(dungeons->size());                                               // Number of dungeons

    if (dungeons->size())
    {
        for (LFGDungeonSet::const_iterator itr = dungeons->begin(); itr != dungeons->end(); ++itr)
        {
            data << uint32(*itr ? (*itr)->Entry() : 0); // Dungeon Entry
        }
    }

    data << uint8(pGroup->GetMembersCount());               // Players in group
    if (pGroup->GetMembersCount())
    {
        // Leader info MUST be sent 1st :S
        ObjectGuid leaderguid = pGroup->GetLeaderGuid();
        Player* pLeader = sObjectMgr.GetPlayer(leaderguid);
        LFGRoleMask roles = LFG_ROLE_MASK_NONE;
        uint8 leaderLevel = 1;
        if (pLeader)
        {
            roles = sLFGMgr.GetLFGPlayerState(pLeader->GetObjectGuid())->GetRoles();
            leaderLevel = pLeader->getLevel();
        }
        data << leaderguid;                                                  // Guid
        data << uint8(roles != LFG_ROLE_MASK_NONE);                          // Ready
        data << uint32(roles);                                               // Roles
        data << uint8(leaderLevel);                                          // Level

        for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
        {
            if (Player* pGroupMember = itr->getSource())
            {
                ObjectGuid guid = pGroupMember->GetObjectGuid();
                // Leader data handle first
                if (guid == leaderguid)
                    continue;

                roles = sLFGMgr.GetLFGPlayerState(pGroupMember->GetObjectGuid())->GetRoles();
                data << guid;                                                    // Guid
                data << uint8(roles != LFG_ROLE_MASK_NONE);                      // Ready
                data << uint32(roles);                                           // Roles
                data << uint8(pGroupMember->getLevel());                         // Level
            }
        }
    }
    SendPacket(&data);
}
Esempio n. 14
0
void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
{
    ObjectGuid guid;
    uint32 bgTypeId_;
    uint32 instanceId;
    uint8 joinAsGroup;
    bool isPremade = false;
    Group * grp;

    recv_data >> guid;                                      // battlemaster guid
    recv_data >> bgTypeId_;                                 // battleground type id (DBC id)
    recv_data >> instanceId;                                // instance id, 0 if First Available selected
    recv_data >> joinAsGroup;                               // join as group

    if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
    {
        sLog.outError("Battleground: invalid bgtype (%u) received. possible cheater? player guid %u",bgTypeId_,_player->GetGUIDLow());
        return;
    }

    BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);

    DEBUG_LOG( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from %s", guid.GetString().c_str());

    // can do this, since it's battleground, not arena
    BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, 0);
    BattleGroundQueueTypeId bgQueueTypeIdRandom = BattleGroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0);

    // ignore if player is already in BG
    if (_player->InBattleGround())
        return;

	// prevent joining from instances
    uint32 mapid = _player->GetMapId();
    if(mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571)
    {
        SendNotification("¡No puedes acceder a un campo de batalla desde aqui!");
        return;
    }

    // get bg instance or bg template if instance not found
    BattleGround *bg = NULL;
    if (instanceId)
        bg = sBattleGroundMgr.GetBattleGroundThroughClientInstance(instanceId, bgTypeId);

    if (!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId)))
    {
        sLog.outError("Battleground: no available bg / template found");
        return;
    }

    // expected bracket entry
    PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel());
    if (!bracketEntry)
        return;

    GroupJoinBattlegroundResult err;

    // check queue conditions
    if (!joinAsGroup)
    {
        // check Deserter debuff
        if (!_player->CanJoinToBattleground())
        {
            WorldPacket data;
            sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
            _player->GetSession()->SendPacket(&data);
            return;
        }

        if (_player->GetBattleGroundQueueIndex(bgQueueTypeIdRandom) < PLAYER_MAX_BATTLEGROUND_QUEUES)
        {
            //player is already in random queue
            WorldPacket data;
            sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_RANDOM_BG);
            _player->GetSession()->SendPacket(&data);
            return;
        }
        
        if(_player->InBattleGroundQueue() && bgTypeId == BATTLEGROUND_RB)
        {
            //player is already in queue, can't start random queue
            WorldPacket data;
            sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_NON_RANDOM_BG);
            _player->GetSession()->SendPacket(&data);
            return;
        }

        // check if already in queue
        if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
            //player is already in this queue
            return;
        // check if has free queue slots
        if (!_player->HasFreeBattleGroundQueueId())
        {
            WorldPacket data;
            sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES);
            _player->GetSession()->SendPacket(&data);
            return;
        }
    }
    else
    {
        grp = _player->GetGroup();
        // no group found, error
        if (!grp)
            return;
        if (grp->GetLeaderGuid() != _player->GetObjectGuid())
            return;
        err = grp->CanJoinBattleGroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
        isPremade = sWorld.getConfig(CONFIG_UINT32_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH) &&
            (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam());
    }
    // if we're here, then the conditions to join a bg are met. We can proceed in joining.

    // _player->GetGroup() was already checked, grp is already initialized
    BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
    if (joinAsGroup)
    {
        GroupQueueInfo * ginfo;
        uint32 avgTime;

        if(err > 0)
        {
            DEBUG_LOG("Battleground: the following players are joining as group:");
            ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0);
            avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
        }

        for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
        {
            Player *member = itr->getSource();
            if(!member)
                continue;                                   // this should never happen

            WorldPacket data;

            if(err <= 0)
            {
                sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, err);
                member->GetSession()->SendPacket(&data);
                continue;
            }

            // add to queue
            uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId);

            // send status packet (in queue)
            sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType);
            member->GetSession()->SendPacket(&data);
            sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, err);
            member->GetSession()->SendPacket(&data);
            DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
        }
        DEBUG_LOG("Battleground: group end");
    }
    else
    {
        GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, 0, false, isPremade, 0);
        uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
        // already checked if queueSlot is valid, now just get it
        uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);

        WorldPacket data;
                                                            // send status packet (in queue)
        sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType);
        SendPacket(&data);
        DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
    }
    sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
}
Esempio n. 15
0
void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
{
    DEBUG_LOG("WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
    //recv_data.hexlike();

    ObjectGuid guid;                                        // arena Battlemaster guid
    uint8 arenaslot;                                        // 2v2, 3v3 or 5v5
    uint8 asGroup;                                          // asGroup
    uint8 isRated;                                          // isRated
    Group * grp;

    recv_data >> guid >> arenaslot >> asGroup >> isRated;

    // ignore if we already in BG or BG queue
    if (_player->InBattleGround())
        return;

    Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
    if (!unit)
        return;

    if(!unit->isBattleMaster())                             // it's not battle master
        return;

    uint8 arenatype = 0;
    uint32 arenaRating = 0;

    switch(arenaslot)
    {
        case 0:
            arenatype = ARENA_TYPE_2v2;
            break;
        case 1:
            arenatype = ARENA_TYPE_3v3;
            break;
        case 2:
            arenatype = ARENA_TYPE_5v5;
            break;
        default:
            sLog.outError("Unknown arena slot %u at HandleBattlemasterJoinArena()", arenaslot);
            return;
    }

    // check existence
    BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA);
    if (!bg)
    {
        sLog.outError("Battleground: template bg (all arenas) not found");
        return;
    }

    BattleGroundTypeId bgTypeId = bg->GetTypeID();
    BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype);
    PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),_player->getLevel());
    if (!bracketEntry)
        return;

    GroupJoinBattlegroundResult err;

    // check queue conditions
    if (!asGroup)
    {
        // check if already in queue
        if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
            //player is already in this queue
            return;
        // check if has free queue slots
        if (!_player->HasFreeBattleGroundQueueId())
            return;
    }
    else
    {
        grp = _player->GetGroup();
        // no group found, error
        if (!grp)
            return;
        if (grp->GetLeaderGuid() != _player->GetObjectGuid())
            return;
        // may be Group::CanJoinBattleGroundQueue should be moved to player class...
        err = grp->CanJoinBattleGroundQueue(bg, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot);
    }

    uint32 ateamId = 0;

    if (isRated)
    {
        ateamId = _player->GetArenaTeamId(arenaslot);
        // check real arena team existence only here (if it was moved to group->CanJoin .. () then we would have to get it twice)
        ArenaTeam * at = sObjectMgr.GetArenaTeamById(ateamId);
        if (!at)
        {
            _player->GetSession()->SendNotInArenaTeamPacket(arenatype);
            return;
        }
        // get the team rating for queue
        arenaRating = at->GetRating();
        // the arena team id must match for everyone in the group
        // get the personal ratings for queue
        uint32 avg_pers_rating = 0;
        for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
        {
            Player *member = itr->getSource();

            // calc avg personal rating
            avg_pers_rating += member->GetArenaPersonalRating(arenaslot);
        }

        if (arenatype)
            avg_pers_rating /= arenatype;

        // if avg personal rating is more than 150 points below the teams rating, the team will be queued against an opponent matching or similar to the average personal rating
        if (avg_pers_rating + 150 < arenaRating)
            arenaRating = avg_pers_rating;
    }

    BattleGroundQueue &bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId];
    if (asGroup)
    {
        uint32 avgTime;

        if(err > 0)
        {
            DEBUG_LOG("Battleground: arena join as group start");
            if (isRated)
                DEBUG_LOG("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(arenaslot),_player->GetName(),arenaRating,arenatype);

            GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, ateamId);
            avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
        }

        for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
        {
            Player *member = itr->getSource();
            if(!member)
                continue;

            WorldPacket data;

            if(err <= 0)
            {
                sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, err);
                member->GetSession()->SendPacket(&data);
                continue;
            }

            // add to queue
            uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId);

            // send status packet (in queue)
            sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
            member->GetSession()->SendPacket(&data);
            sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, err);
            member->GetSession()->SendPacket(&data);
            DEBUG_LOG("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName());
        }
        DEBUG_LOG("Battleground: arena join as group end");
    }
    else
    {
        GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, ateamId);
        uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
        uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);

        WorldPacket data;
        // send status packet (in queue)
        sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
        SendPacket(&data);
        DEBUG_LOG("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
    }
    sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
}
Esempio n. 16
0
void ChatLog::BattleGroundMsg(Player *player, std::string &msg, uint32 type)
{
    if (!_ChatCommon(CHAT_LOG_BATTLEGROUND, player, msg)) return;

    CheckDateSwitch();

    std::string log_str = "";

    log_str.append("[");
    log_str.append(player->GetName());

    switch (type)
    {
        case CHAT_MSG_BATTLEGROUND:
        log_str.append("]->BG:");
        break;

        case CHAT_MSG_BATTLEGROUND_LEADER:
        log_str.append("]->BG_LEADER:");
        break;

        default:
        log_str.append("]->BG_UNKNOWN:");
        break;
    }

    Group *group = player->GetGroup();
    if (!group)
    {
        log_str.append("[unknown group] ");
    }
    else
    {
        // obtain group information
        log_str.append("[");

        ObjectGuid gm_leader_GUID = group->GetLeaderGuid();
        Player *gm_member;

        gm_member = sObjectMgr.GetPlayer(gm_leader_GUID);
        if (gm_member)
        {
            log_str.append(gm_member->GetName());
            log_str.append(",");
        }

        Group::MemberSlotList g_members = group->GetMemberSlots();

        for (Group::member_citerator itr = g_members.begin(); itr != g_members.end(); itr++)
        {
            if (itr->guid == gm_leader_GUID) continue;

            gm_member = sObjectMgr.GetPlayer(itr->guid);
            if (gm_member)
            {
                log_str.append(itr->name);
                log_str.append(",");
            }
        }

        log_str.erase(log_str.length() - 1);
        log_str.append("] ");
    }

    log_str.append(msg);

    log_str.append("\n");

    if (screenflag[CHAT_LOG_BATTLEGROUND]) printf("%s", log_str.c_str());
    if (files[CHAT_LOG_BATTLEGROUND])
    {
        OutTimestamp(files[CHAT_LOG_BATTLEGROUND]);
        fprintf(files[CHAT_LOG_BATTLEGROUND], "%s", log_str.c_str());
        fflush(files[CHAT_LOG_BATTLEGROUND]);
    }
}
Esempio n. 17
0
void ChatLog::PartyMsg(Player *player, std::string &msg)
{
    if (!_ChatCommon(CHAT_LOG_PARTY, player, msg)) return;

    CheckDateSwitch();

    std::string log_str = "";

    log_str.append("[");
    log_str.append(player->GetName());
    log_str.append("]->GROUP:");

    Group *group = player->GetGroup();
    if (!group)
    {
        log_str.append("[unknown group] ");
    }
    else
    {
        // obtain group information
        log_str.append("[");

        ObjectGuid gm_leader_GUID = group->GetLeaderGuid();
        Player *gm_member;

        gm_member = sObjectMgr.GetPlayer(gm_leader_GUID);
        if (gm_member)
        {
            log_str.append(gm_member->GetName());
            log_str.append(",");
        }

        Group::MemberSlotList g_members = group->GetMemberSlots();

        for (Group::member_citerator itr = g_members.begin(); itr != g_members.end(); itr++)
        {
            if (itr->guid == gm_leader_GUID) continue;

            gm_member = sObjectMgr.GetPlayer(itr->guid);
            if (gm_member)
            {
                log_str.append(itr->name);
                log_str.append(",");
            }
        }

        log_str.erase(log_str.length() - 1);
        log_str.append("] ");
    }

    log_str.append(msg);

    log_str.append("\n");

    if (screenflag[CHAT_LOG_PARTY]) printf("%s", log_str.c_str());
    if (files[CHAT_LOG_PARTY])
    {
        OutTimestamp(files[CHAT_LOG_PARTY]);
        fprintf(files[CHAT_LOG_PARTY], "%s", log_str.c_str());
        fflush(files[CHAT_LOG_PARTY]);
    }
}
Esempio n. 18
0
void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recv_data)
{
    bool unk = recv_data.ReadBit();
    bool accepted = recv_data.ReadBit();
    if (unk)
        recv_data.read_skip<uint32>();

    Group* group = GetPlayer()->GetGroupInvite();
    if (!group)
        return;

    if (accepted)
    {
        // remove in from invites in any case
        group->RemoveInvite(GetPlayer());

        if (group->GetLeaderGuid() == GetPlayer()->GetObjectGuid())
        {
            sLog.outError("HandleGroupInviteResponseOpcode: %s tried to accept an invite to his own group",
                          GetPlayer()->GetGuidStr().c_str());
            return;
        }

        /** error handling **/
        /********************/

        // not have place
        if (group->IsFull())
        {
            SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL);
            return;
        }

        Player* leader = sObjectMgr.GetPlayer(group->GetLeaderGuid());

        // forming a new group, create it
        if (!group->IsCreated())
        {
            if (leader)
                group->RemoveInvite(leader);
            if (group->Create(group->GetLeaderGuid(), group->GetLeaderName()))
                sObjectMgr.AddGroup(group);
            else
                return;
        }

        // everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
        if (!group->AddMember(GetPlayer()->GetObjectGuid(), GetPlayer()->GetName()))
            return;
    }
    else
    {
        // uninvite, group can be deleted
        GetPlayer()->UninviteFromGroup();

        // remember leader if online
        Player* leader = sObjectMgr.GetPlayer(group->GetLeaderGuid());
        if (!leader || !leader->GetSession())
            return;

        // report
        WorldPacket data(SMSG_GROUP_DECLINE, 10);               // guess size
        data << GetPlayer()->GetName();
        leader->GetSession()->SendPacket(&data);
    }
}
Esempio n. 19
0
void WorldSession::SendLfgUpdateList(uint32 dungeonEntry)
{
    if (!sWorld.getConfig(CONFIG_BOOL_LFR_ENABLE))
    {
        DEBUG_LOG("SendLfgUpdateList %u failed - Raid finder disabled", GetPlayer()->GetObjectGuid().GetCounter());
        return;
    }

    DEBUG_LOG("SMSG_LFG_SEARCH_RESULTS %u dungeonentry: %u ", GetPlayer()->GetObjectGuid().GetCounter(), dungeonEntry);

    LFGDungeonEntry const* dungeon = sLFGMgr.GetDungeon(dungeonEntry);

    if (!dungeonEntry)
        return;

    Team team = sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP) ? TEAM_NONE : GetPlayer()->GetTeam();

    LFGQueueGroupSet   groups = sLFGMgr.GetDungeonGroupQueue(dungeon, team);
    LFGQueuePlayerSet players = sLFGMgr.GetDungeonPlayerQueue(dungeon, team);

    uint32 groupCount = groups.size();
    uint32 groupSize = 4+4;

    for (LFGQueueGroupSet::const_iterator itr = groups.begin(); itr != groups.end(); ++itr)
    {
        Player* leader = sObjectMgr.GetPlayer((*itr)->GetLeaderGuid());

        if (!leader)
            continue;
        leader->GetLFGState()->AddFlags(LFG_MEMBER_FLAG_CHARINFO |
                                        LFG_MEMBER_FLAG_COMMENT |
                                        LFG_MEMBER_FLAG_GROUPLEADER |
                                        LFG_MEMBER_FLAG_GROUPGUID |
                                        LFG_MEMBER_FLAG_ROLES |
                                        LFG_MEMBER_FLAG_AREA  |
                                        LFG_MEMBER_FLAG_STATUS  |
                                        LFG_MEMBER_FLAG_BIND);

        uint32 flags = leader->GetLFGState()->GetFlags();

        if (flags & LFG_MEMBER_FLAG_COMMENT)
            groupSize += leader->GetLFGState()->GetComment().size()+1;
        if (flags & LFG_MEMBER_FLAG_ROLES)
            groupSize +=3;
        if (flags & LFG_MEMBER_FLAG_BIND)
            groupSize += (8+4);

        players.insert(leader);

        for (GroupReference *itr2 = (*itr)->GetFirstMember(); itr2 != NULL; itr2 = itr2->next())
        {
            Player* player = itr2->getSource();

            if (!player || player == leader)
                continue;

            player->GetLFGState()->AddFlags(LFG_MEMBER_FLAG_GROUPLEADER |
                                        LFG_MEMBER_FLAG_GROUPGUID |
                                        LFG_MEMBER_FLAG_STATUS);

            player->GetLFGState()->RemoveFlags(LFG_MEMBER_FLAG_CHARINFO |
                                        LFG_MEMBER_FLAG_COMMENT |
                                        LFG_MEMBER_FLAG_ROLES |
                                        LFG_MEMBER_FLAG_AREA  |
                                        LFG_MEMBER_FLAG_BIND);
            players.insert(player);
        }

    }

    uint32 playerCount = players.size();
    uint32 playerSize = 4+4;

    uint32 guidsSize = 0;
    LFGQueuePlayerSet playersUpdated;
    playersUpdated.clear();

    for(LFGQueuePlayerSet::const_iterator itr = players.begin(); itr != players.end(); ++itr)
    {
        uint32 flags = (*itr)->GetLFGState()->GetFlags();

        playerSize += (8+4);

        if (flags &  LFG_MEMBER_FLAG_CHARINFO)
            playerSize += (1+1+1+3+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4);

        if (flags & LFG_MEMBER_FLAG_COMMENT)
            playerSize += (*itr)->GetLFGState()->GetComment().size()+1;         // comment

        if (flags & LFG_MEMBER_FLAG_GROUPLEADER)
            playerSize += 1;

        if (flags & LFG_MEMBER_FLAG_GROUPGUID)
            playerSize += 8;

        if (flags & LFG_MEMBER_FLAG_ROLES)
            playerSize += 1;

        if (flags & LFG_MEMBER_FLAG_AREA)
            playerSize += 4;

        if (flags & LFG_MEMBER_FLAG_STATUS)
            playerSize += 1;

        if (flags & LFG_MEMBER_FLAG_BIND)
            playerSize += (8+4);

        if (flags & LFG_MEMBER_FLAG_UPDATE)
        {
            (*itr)->GetLFGState()->RemoveFlags(LFG_MEMBER_FLAG_UPDATE);
            playersUpdated.insert(*itr);
            guidsSize += 8;
        }

    }

    WorldPacket data(SMSG_LFG_SEARCH_RESULTS, 4 + 4 + 1 + groupSize + playerSize + guidsSize);

    data << uint32(dungeon->type);                           // type
    data << uint32(dungeon->Entry());                        // entry from LFGDungeons.dbc

    if (!playersUpdated.empty())
    {
        data << uint8(playersUpdated.size());
        for (LFGQueuePlayerSet::const_iterator itr = playersUpdated.begin(); itr != playersUpdated.end(); ++itr)
        {
            data << (*itr)->GetObjectGuid();                 // player guid
        }
    }
    else
        data << uint8(0);


    if (!groups.empty())
    {
        data << uint32(groupCount);                          // groups count
        data << uint32(groupCount);                          // groups count2

        for (LFGQueueGroupSet::const_iterator itr = groups.begin(); itr != groups.end(); ++itr)
        {
            Group* group = *itr;

            Player* leader = sObjectMgr.GetPlayer(group->GetLeaderGuid());

            uint32 flags = leader->GetLFGState()->GetFlags();

            data << group->GetObjectGuid();

            data << flags;

            if (flags & LFG_MEMBER_FLAG_COMMENT)
            {
                data << leader->GetLFGState()->GetComment().c_str();
            }

            if (flags & LFG_MEMBER_FLAG_ROLES)
            {
                for (int i = 0; i < 3; ++i)
                {
                    data << uint8(group->GetLFGState()->GetRoles(LFGRoles(i+1)));
                }
            }

            if (flags & LFG_MEMBER_FLAG_BIND)
            {
                ObjectGuid instanceGuid;
                uint32 encounters = 0;
                if (InstancePlayerBind* bind = leader->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty)))
                {
                    if (DungeonPersistentState* state = bind->state)
                    {
                        instanceGuid = state->GetInstanceGuid();
                        encounters = state->GetCompletedEncountersMask();
                    }
                }
                data << instanceGuid;
                data << encounters;
            }
        }
    }
    else
    {
        data << uint32(0);
        data << uint32(0);                                       // groups count2
    }


    if (!players.empty())
    {
        data << uint32(playerCount);                           // players count
        data << uint32(playerCount);                           // players count 2

        for(LFGQueuePlayerSet::const_iterator itr = players.begin(); itr != players.end(); ++itr)
        {
            Player* player = *itr;

            uint32 flags = player->GetLFGState()->GetFlags();

            data << player->GetObjectGuid();                      // guid

            data << flags;                                        // flags

            if (flags &  LFG_MEMBER_FLAG_CHARINFO)                // charinfo
            {
                data << uint8(player->getLevel());
                data << uint8(player->getClass());
                data << uint8(player->getRace());

                for(int i = 0; i < 3; ++i)
                    data << uint8(player->GetTalentsCount(i));                                    // spent talents count in specific tab

                data << uint32(player->GetArmor());                                                 // armor
                data << uint32(player->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SPELL));          // spd
                data << uint32(player->SpellBaseHealingBonusDone(SPELL_SCHOOL_MASK_SPELL));         // heal
                data << uint32(player->GetRatingBonusValue(CR_CRIT_MELEE));                        // crit rating melee
                data << uint32(player->GetRatingBonusValue(CR_CRIT_RANGED));                       // crit rating ranged
                data << uint32(player->GetRatingBonusValue(CR_CRIT_SPELL));                        // crit rating spell
                data << float(player->GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER)*5);                             // mp5
                data << float(player->GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER)*5);                 // unk
                data << uint32(player->GetTotalAttackPowerValue(BASE_ATTACK));                      // attack power
                data << uint32(player->GetTotalStatValue(STAT_AGILITY));                            // agility
                data << uint32(player->GetMaxHealth());                                             // health
                data << uint32(player->GetMaxPower(player->getPowerType()));                        // power
                data << uint32(0);                              // unk
                data << float(0);                               // unk
                data << uint32(player->GetRatingBonusValue(CR_DEFENSE_SKILL));                      // defence rating
                data << uint32(player->GetRatingBonusValue(CR_DODGE));                              // dodge rating
                data << uint32(player->GetRatingBonusValue(CR_BLOCK));                              // block rating
                data << uint32(player->GetRatingBonusValue(CR_PARRY));                              // parry rating
                data << uint32(player->GetRatingBonusValue(CR_HASTE_MELEE));                         // crit rating
                data << uint32(player->GetRatingBonusValue(CR_EXPERTISE));                          // expertize
            }

            if (flags & LFG_MEMBER_FLAG_COMMENT)
                data << player->GetLFGState()->GetComment().c_str();         // comment

            if (flags & LFG_MEMBER_FLAG_GROUPLEADER)                         // Group leader flag
            {
                bool isLeader = false;
                if (Group* group = player->GetGroup())
                    if (player->GetObjectGuid() == group->GetLeaderGuid())
                        isLeader = true;

                data << uint8(isLeader);
            }

            if (flags & LFG_MEMBER_FLAG_GROUPGUID)                          // Group guid
            {
                ObjectGuid groupGuid = ObjectGuid();
                if (Group* group = player->GetGroup())
                    groupGuid = group->GetObjectGuid();

                data << groupGuid;
            }

            if (flags & LFG_MEMBER_FLAG_ROLES)                              // rolesMask
                data << uint8(player->GetLFGState()->GetRoles());

            if (flags & LFG_MEMBER_FLAG_AREA)                               // Area
                data << uint32(player->GetAreaId());

            if (flags & LFG_MEMBER_FLAG_STATUS)                             // status
                data << uint8(0);

            if (flags & LFG_MEMBER_FLAG_BIND)
            {
                ObjectGuid instanceGuid;
                uint32 encounters = 0;
                if (InstancePlayerBind* bind = player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty)))
                {
                    if (DungeonPersistentState* state = bind->state)
                    {
                        instanceGuid = state->GetInstanceGuid();
                        encounters = state->GetCompletedEncountersMask();
                    }
                }
                data << instanceGuid;
                data << encounters;
            }

        }
    }
    else
    {
        data << uint32(0);                                          // players count
        data << uint32(0);                                          // unk
    }
    SendPacket(&data);
}
Esempio n. 20
0
void LFGMgr::Join(Player* player)
{
//    LfgDungeonSet* dungeons = NULL;

    if (!sWorld.getConfig(CONFIG_BOOL_LFG_ENABLE) && !sWorld.getConfig(CONFIG_BOOL_LFR_ENABLE))
        return;

    ObjectGuid guid;
    Group* group = player->GetGroup();

    if (group)
    {
        if (player->GetObjectGuid() != group->GetLeaderGuid())
        {
            player->GetSession()->SendLfgJoinResult(ERR_LFG_NO_SLOTS_PLAYER);
            return;
        }
        else
            guid = group->GetObjectGuid();
    }
    else
        guid = player->GetObjectGuid();

    if (guid.IsEmpty())
        return;

    LFGType type = player->GetLFGState()->GetType();

    if (type == LFG_TYPE_NONE)
    {
        DEBUG_LOG("LFGMgr::Join: %u trying to join without dungeon type. Aborting.", guid.GetCounter());
        player->GetSession()->SendLfgJoinResult(ERR_LFG_INVALID_SLOT);
        return;
    }
    else if (group && type == LFG_TYPE_RAID && !group->isRaidGroup())
    {
        DEBUG_LOG("LFGMgr::Join: %u trying to join to raid finder, but group is not raid. Aborting.", guid.GetCounter());
        player->GetSession()->SendLfgJoinResult(ERR_LFG_MISMATCHED_SLOTS);
        return;
    }
    else if (group && type != LFG_TYPE_RAID && group->isRaidGroup())
    {
        DEBUG_LOG("LFGMgr::Join: %u trying to join to dungeon finder, but group is raid. Aborting.", guid.GetCounter());
        player->GetSession()->SendLfgJoinResult(ERR_LFG_MISMATCHED_SLOTS);
        return;
    }

    LFGQueueInfoMap::iterator queue = (guid.IsGroup() ? m_groupQueueInfoMap[type].find(guid) : m_queueInfoMap[type].find(guid));
    LFGJoinResult result            = ERR_LFG_OK;

    if (queue != (guid.IsGroup() ? m_groupQueueInfoMap[type].end() : m_queueInfoMap[type].end()))
    {
        DEBUG_LOG("LFGMgr::Join: %u trying to join but is already in queue!", guid.GetCounter());
        result = ERR_LFG_NO_LFG_OBJECT;
        player->GetSession()->SendLfgJoinResult(result);
        _Leave(guid);
        _LeaveGroup(guid);
        return;
    }

    result = guid.IsGroup() ? GetGroupJoinResult(group) : GetPlayerJoinResult(player);

    if (result != ERR_LFG_OK)                              // Someone can't join. Clear all stuf
    {
        DEBUG_LOG("LFGMgr::Join: %u joining with %u members. result: %u", guid.GetCounter(), group ? group->GetMembersCount() : 1, result);
        player->GetLFGState()->Clear();
        player->GetSession()->SendLfgJoinResult(result);
        player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_ROLECHECK_FAILED, type);
        return;
    }

    if (!guid.IsGroup() && player->GetLFGState()->GetRoles() == LFG_ROLE_MASK_NONE)
    {
        sLog.outError("LFGMgr::Join: %u has no roles", guid.GetCounter());
    }


    // Joining process
    if (guid.IsGroup())
    {
        for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
        {
            if (Player* player = itr->getSource())
                _Leave(player->GetObjectGuid());
        }
        _LeaveGroup(guid, type);
        _JoinGroup(guid, type);
    }
    else
    {
        _Leave(guid, type);
        _Join(guid, type);
    }

    player->GetLFGState()->SetState((type == LFG_TYPE_RAID) ? LFG_STATE_LFR : LFG_STATE_LFG);

    player->GetSession()->SendLfgJoinResult(ERR_LFG_OK, 0);

    if (group)
        player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_JOIN_PROPOSAL, type);
    else
        player->GetSession()->SendLfgUpdatePlayer(LFG_UPDATETYPE_JOIN_PROPOSAL, type);

    if(sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL))
        player->JoinLFGChannel();

}