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(); }
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; }
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; }
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; }
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; }
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 ); } }
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; }
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; }
// 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;