Пример #1
0
void Group::ChangeLeader(const uint64 &guid)
{
    _setLeader(guid);

    WorldPacket data(SMSG_GROUP_SET_LEADER, (m_members[_getMemberIndex(guid)].name.size()+1));
    data << m_members[_getMemberIndex(guid)].name;
    BroadcastPacket(&data);
    SendUpdate();
}
Пример #2
0
    bool TopologyCoordinatorImpl::_shouldVeto(const BSONObj& cmdObj, string& errmsg) const {
        // don't veto older versions
        if (cmdObj["id"].eoo()) {
            // they won't be looking for the veto field
            return false;
        }

        const int id = cmdObj["id"].Int();
        const int hopefulIndex = _getMemberIndex(id);
        const int highestPriorityIndex = _getHighestPriorityElectableIndex();

        if (hopefulIndex == -1) {
            errmsg = str::stream() << "replSet couldn't find member with id " << id;
            return true;
        }

        if ((_currentPrimaryIndex != -1) && 
            (_commitOkayThrough >= _hbdata[hopefulIndex].getOpTime())) {
            // hbinfo is not updated, so we have to check the primary's last optime separately
            errmsg = str::stream() << "I am already primary, " << 
                _currentConfig.getMemberAt(hopefulIndex).getHostAndPort().toString() << 
                " can try again once I've stepped down";
            return true;
        }

        if (_currentPrimaryIndex != -1 &&
            (_currentConfig.getMemberAt(hopefulIndex).getId() != 
             _currentConfig.getMemberAt(_currentPrimaryIndex).getId()) &&
            (_hbdata[_currentPrimaryIndex].getOpTime() >= 
             _hbdata[hopefulIndex].getOpTime())) {
            // other members might be aware of more up-to-date nodes
            errmsg = str::stream() << 
                _currentConfig.getMemberAt(hopefulIndex).getHostAndPort().toString() <<
                " is trying to elect itself but " << 
                _currentConfig.getMemberAt(_currentPrimaryIndex).getHostAndPort().toString() <<
                " is already primary and more up-to-date";
            return true;
        }

        if ((highestPriorityIndex != -1) &&
            _currentConfig.getMemberAt(highestPriorityIndex).getPriority() > 
            _currentConfig.getMemberAt(hopefulIndex).getPriority()) {
            errmsg = str::stream() << 
                _currentConfig.getMemberAt(hopefulIndex).getHostAndPort().toString() << 
                " has lower priority than " << 
                _currentConfig.getMemberAt(highestPriorityIndex).getHostAndPort().toString();
            return true;
        }

        if (!_electableSet.count(id)) {
            errmsg = str::stream() << "I don't think "
                << _currentConfig.getMemberAt(hopefulIndex).getHostAndPort().toString() <<
                " is electable";
            return true;
        }

        return false;
    }
Пример #3
0
bool Group::_setAssistantFlag(const uint64 &guid, const bool &state)
{
    int8 i = _getMemberIndex(guid);
    if(i < 0)
        return false;

    m_members[i].assistant = state;
    sDatabase.PExecute("UPDATE `group_member` SET `assistant`='%u' WHERE `memberGuid`='%u'", (state==true)?1:0, GUID_LOPART(guid));
    return true;
}
Пример #4
0
bool Group::_setMembersGroup(const uint64 &guid, const uint8 &group)
{
    int8 i = _getMemberIndex(guid);
    if(i < 0)
        return false;

    m_members[i].group = group;
    sDatabase.PExecute("UPDATE `group_member` SET `subgroup`='%u' WHERE `memberGuid`='%u'", group, GUID_LOPART(guid));
    return true;
}
Пример #5
0
void Group::_setLeader(const uint64 &guid)
{
    int8 id = _getMemberIndex(guid);
    if(id < 0)
        return;

    if(isRaidGroup())
    {
        sDatabase.BeginTransaction();
        sDatabase.PExecute("UPDATE `raidgroup` SET `leaderGuid`='%u' WHERE `leaderGuid`='%u'", GUID_LOPART(m_members[id].guid), GUID_LOPART(m_leaderGuid));
        sDatabase.PExecute("UPDATE `raidgroup_member` SET `leaderGuid`='%u' WHERE `leaderGuid`='%u'", GUID_LOPART(m_members[id].guid), GUID_LOPART(m_leaderGuid));
        sDatabase.CommitTransaction();
    }
    m_leaderGuid = m_members[id].guid;
    m_leaderName = m_members[id].name;
}
Пример #6
0
void Group::SendInit(WorldSession *session)
{
    if(!session)
        return;

    int8   myIndex;
    uint8  myFlag;
    uint64 guid;

    guid = session->GetPlayer()->GetGUID();
    myIndex = _getMemberIndex(guid);
    myFlag  = m_members[myIndex].group | (m_members[myIndex].assistant?0x80:0);
    for(int i=1; i<=m_members.size(); i++)
    {
                                                            // guess size
        WorldPacket data(SMSG_GROUP_LIST, (2+4+8+8+1+2+m_members.size()*20));
        data << (uint8)m_groupType;
        data << (uint8)myFlag;

        int count = 0;
        data << uint32(m_members.size()-1);
        for(vector<MemberSlot>::const_iterator citr=m_members.begin(); citr!=m_members.end(); citr++)
        {
            if(citr->guid == guid)
                continue;

            data << ((count<i) ? citr->name : "");
            data << citr->guid;
            data << (uint8)(objmgr.GetPlayer(citr->guid)?1:0);
            data << (uint8)(citr->group | (citr->assistant?0x80:0));
            count++;

            if(count >= i)
                break;
        }

        data << m_leaderGuid;
        data << (uint8)m_lootMethod;
        data << m_looterGuid;
        data << (uint16)2;

        session->SendPacket( &data );
    }
}
Пример #7
0
bool Group::_removeMember(const uint64 &guid)
{
    Player *player = objmgr.GetPlayer(guid);
    if (player)
    {
        player->RemoveAreaAurasByOthers();
        player->RemoveAreaAurasFromGroup();
        player->groupInfo.group = NULL;
    }

    _removeRolls(guid);
    m_members.erase(m_members.begin()+_getMemberIndex(guid));

    sDatabase.PExecute("DELETE FROM `group_member` WHERE `memberGuid`='%u'", GUID_LOPART(guid));

    if(m_leaderGuid == guid)                                // leader was removed
    {
        if(m_members.size() > 0)
            _setLeader(m_members[0].guid);
        return true;
    }

    return false;
}
Пример #8
0
void Group::_setLeader(const uint64 &guid)
{
    int8 id = _getMemberIndex(guid);
    if(id < 0)
        return;

    // instance system leader change process
    if (m_leaderGuid != m_members[id].guid)
    {
        // here we must unbind all instances bound to that leader on group members from the
        // leader, and rebind them on the players
        uint32 old_guid = m_leaderGuid;
        uint32 new_guid = m_members[id].guid;
        std::set< uint32 > changed_bindings;
        Player* player;
        BoundInstancesMap::iterator i_BoundInstances;

        // 1) rebind current associations in memory for group members
        // 2) get current group associations from database (for unbind)
        // combined because of query building in the iteration
        if (m_members.size() > 0)
        {
            std::ostringstream ss;
            ss << "SELECT DISTINCT(`map`) FROM `character_instance` WHERE (`guid` IN (";
            vector<MemberSlot>::const_iterator citr = m_members.begin(); 
            while (citr != m_members.end())
            {
                ss << GUID_LOPART(citr->guid);
                player = objmgr.GetPlayer(citr->guid);
                if(player && (citr->guid != old_guid))
                {
                    for(i_BoundInstances = player->m_BoundInstances.begin(); i_BoundInstances != player->m_BoundInstances.end(); i_BoundInstances++)
                    {
                        if (i_BoundInstances->second.second == GUID_LOPART(old_guid))
                        {
                            
                            i_BoundInstances->second.second = GUID_LOPART(new_guid);
                            changed_bindings.insert(i_BoundInstances->first);
                        }
                    }
                }
                citr++;
                if (citr != m_members.end()) ss << ", ";
            }
            ss << ")) AND (`leader` = '" << GUID_LOPART(old_guid) << "')";
            QueryResult* result = sDatabase.Query(ss.str().c_str());
            if (result)
            {
                do
                {
                    Field* fields = result->Fetch();
                    changed_bindings.insert(fields[0].GetUInt32());
                } while(result->NextRow());
                delete result;
            }
        }

        // rebind changed associations in memory for old leader
        player = objmgr.GetPlayer(old_guid);
        if(player)
        {
            for (std::set< uint32 >::iterator i = changed_bindings.begin(); i != changed_bindings.end(); i++)
            {
                i_BoundInstances = player->m_BoundInstances.find(*i);
                if (i_BoundInstances != player->m_BoundInstances.end()) i_BoundInstances->second.second = GUID_LOPART(new_guid);
            }
        }

        // rebind changed associations in database
        if (changed_bindings.size() > 0)
        {
            std::ostringstream ss;
            ss << "UPDATE `character_instance` SET `leader` = '" << GUID_LOPART(new_guid) << "' WHERE (`map` IN (";
            {
                std::set< uint32 >::iterator i = changed_bindings.begin();
                while (i != changed_bindings.end())
                {
                    ss << "'" << *i << "'";
                    i++;
                    if (i != changed_bindings.end()) ss << ", ";
                }
            }
            ss << ")) AND (`leader` = '" << GUID_LOPART(old_guid) << "')";
            sDatabase.Execute(ss.str().c_str());
        }
    }
    
    sDatabase.BeginTransaction();
    sDatabase.PExecute("UPDATE `group` SET `leaderGuid`='%u' WHERE `leaderGuid`='%u'", GUID_LOPART(m_members[id].guid), GUID_LOPART(m_leaderGuid));
    sDatabase.PExecute("UPDATE `group_member` SET `leaderGuid`='%u' WHERE `leaderGuid`='%u'", GUID_LOPART(m_members[id].guid), GUID_LOPART(m_leaderGuid));
    sDatabase.CommitTransaction();

    m_leaderGuid = m_members[id].guid;
    m_leaderName = m_members[id].name;
}
Пример #9
0
    // produce a reply to a received electCmd
    void TopologyCoordinatorImpl::prepareElectCmdResponse(const Date_t now,
                                                          const BSONObj& cmdObj,
                                                          BSONObjBuilder& result) {

        //TODO: after eric's checkin, add executer stuff and error if cancelled
        DEV log() << "replSet received elect msg " << cmdObj.toString();
        else LOG(2) << "replSet received elect msg " << cmdObj.toString();

        std::string setName = cmdObj["setName"].String();
        int whoid = cmdObj["whoid"].Int();
        long long cfgver = cmdObj["cfgver"].Int();
        OID round = cmdObj["round"].OID();
        long long myver = _currentConfig.getConfigVersion();

        const int hopefulIndex = _getMemberIndex(whoid);
        const int highestPriorityIndex = _getHighestPriorityElectableIndex();

        int vote = 0;
        if ( setName != _currentConfig.getReplSetName() ) {
            log() << "replSet error received an elect request for '" << setName
                  << "' but our setName name is '" << 
                _currentConfig.getReplSetName() << "'";
        }
        else if ( myver < cfgver ) {
            // we are stale.  don't vote
        }
        else if ( myver > cfgver ) {
            // they are stale!
            log() << "replSet electCmdReceived info got stale version # during election";
            vote = -10000;