void Guild::DelMember(ObjectGuid guid, bool isDisbanding) { uint32 lowguid = guid.GetCounter(); // guild master can be deleted when loading guild and guid doesn't exist in characters table // or when he is removed from guild by gm command if (m_LeaderGuid == guid && !isDisbanding) { MemberSlot* oldLeader = NULL; MemberSlot* best = NULL; ObjectGuid newLeaderGUID; for (Guild::MemberList::iterator i = members.begin(); i != members.end(); ++i) { if (i->first == lowguid) { oldLeader = &(i->second); continue; } if (!best || best->RankId > i->second.RankId) { best = &(i->second); newLeaderGUID = ObjectGuid(HIGHGUID_PLAYER, i->first); } } if (!best) { Disband(); return; } SetLeader(newLeaderGUID); // If player not online data in data field will be loaded from guild tabs no need to update it !! if (Player *newLeader = sObjectMgr.GetPlayer(newLeaderGUID)) newLeader->SetRank(GR_GUILDMASTER); // when leader non-exist (at guild load with deleted leader only) not send broadcasts if (oldLeader) { BroadcastEvent(GE_LEADER_CHANGED, oldLeader->Name.c_str(), best->Name.c_str()); BroadcastEvent(GE_LEFT, guid, oldLeader->Name.c_str()); } } members.erase(lowguid); Player *player = sObjectMgr.GetPlayer(guid); // If player not online data in data field will be loaded from guild tabs no need to update it !! if (player) { player->SetInGuild(0); player->SetRank(0); } CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guid = '%u'", lowguid); if (!isDisbanding) UpdateAccountsNumber(); }
bool Guild::LoadMembersFromDB(QueryResult* guildMembersResult) { if (!guildMembersResult) { return false; } do { Field* fields = guildMembersResult->Fetch(); // this condition will be true when all rows in QueryResult are processed and new guild without members is going to be loaded - prevent crash if (!fields) { break; } uint32 guildId = fields[0].GetUInt32(); if (guildId < m_Id) { // there is in table guild_member record which doesn't have guildid in guild table, report error sLog.outErrorDb("Guild %u does not exist but it has a record in guild_member table, deleting it!", guildId); CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guildid = '%u'", guildId); continue; } if (guildId > m_Id) // we loaded all members for this guild already, break cycle { break; } MemberSlot newmember; uint32 lowguid = fields[1].GetUInt32(); newmember.guid = ObjectGuid(HIGHGUID_PLAYER, lowguid); newmember.RankId = fields[2].GetUInt32(); // don't allow member to have not existing rank! if (newmember.RankId >= m_Ranks.size()) { newmember.RankId = GetLowestRank(); } newmember.Pnote = fields[3].GetCppString(); newmember.OFFnote = fields[4].GetCppString(); newmember.Name = fields[5].GetCppString(); newmember.Level = fields[6].GetUInt8(); newmember.Class = fields[7].GetUInt8(); newmember.ZoneId = fields[8].GetUInt32(); newmember.LogoutTime = fields[9].GetUInt64(); newmember.accountId = fields[10].GetInt32(); // this code will remove not existing character guids from guild if (newmember.Level < 1 || newmember.Level > STRONG_MAX_LEVEL) // can be at broken `data` field { sLog.outError("%s has a broken data in field `characters`.`data`, deleting him from guild!", newmember.guid.GetString().c_str()); CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guid = '%u'", lowguid); continue; } if (!newmember.ZoneId) { sLog.outError("%s has broken zone-data", newmember.guid.GetString().c_str()); // here it will also try the same, to get the zone from characters-table, but additional it tries to find // the zone through xy coords .. this is a bit redundant, but shouldn't be called often newmember.ZoneId = Player::GetZoneIdFromDB(newmember.guid); } if (!((1 << (newmember.Class - 1)) & CLASSMASK_ALL_PLAYABLE)) // can be at broken `class` field { sLog.outError("%s has a broken data in field `characters`.`class`, deleting him from guild!", newmember.guid.GetString().c_str()); CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guid = '%u'", lowguid); continue; } members[lowguid] = newmember; } while (guildMembersResult->NextRow()); if (members.empty()) { return false; } UpdateAccountsNumber(); return true; }
bool Guild::AddMember(ObjectGuid plGuid, uint32 plRank) { Player* pl = sObjectMgr.GetPlayer(plGuid); if (pl) { if (pl->GetGuildId() != 0) { return false; } } else { if (Player::GetGuildIdFromDB(plGuid) != 0) // player already in guild { return false; } } // remove all player signs from another petitions // this will be prevent attempt joining player to many guilds and corrupt guild data integrity Player::RemovePetitionsAndSigns(plGuid); uint32 lowguid = plGuid.GetCounter(); // fill player data MemberSlot newmember; newmember.guid = plGuid; if (pl) { newmember.accountId = pl->GetSession()->GetAccountId(); newmember.Name = pl->GetName(); newmember.Level = pl->getLevel(); newmember.Class = pl->getClass(); newmember.ZoneId = pl->GetZoneId(); } else { // 0 1 2 3 4 QueryResult* result = CharacterDatabase.PQuery("SELECT name,level,class,zone,account FROM characters WHERE guid = '%u'", lowguid); if (!result) { return false; } // player doesn't exist Field* fields = result->Fetch(); newmember.Name = fields[0].GetCppString(); newmember.Level = fields[1].GetUInt8(); newmember.Class = fields[2].GetUInt8(); newmember.ZoneId = fields[3].GetUInt32(); newmember.accountId = fields[4].GetInt32(); delete result; if (newmember.Level < 1 || newmember.Level > STRONG_MAX_LEVEL || !((1 << (newmember.Class - 1)) & CLASSMASK_ALL_PLAYABLE)) { sLog.outError("%s has a broken data in field `characters` table, can not add him to guild.", plGuid.GetString().c_str()); return false; } } newmember.RankId = plRank; newmember.OFFnote = (std::string)""; newmember.Pnote = (std::string)""; newmember.LogoutTime = time(NULL); members[lowguid] = newmember; std::string dbPnote = newmember.Pnote; std::string dbOFFnote = newmember.OFFnote; CharacterDatabase.escape_string(dbPnote); CharacterDatabase.escape_string(dbOFFnote); CharacterDatabase.PExecute("INSERT INTO guild_member (guildid,guid,rank,pnote,offnote) VALUES ('%u', '%u', '%u','%s','%s')", m_Id, lowguid, newmember.RankId, dbPnote.c_str(), dbOFFnote.c_str()); // If player not in game data in data field will be loaded from guild tables, no need to update it!! if (pl) { pl->SetInGuild(m_Id); pl->SetRank(newmember.RankId); pl->SetGuildIdInvited(0); } UpdateAccountsNumber(); // Used by Eluna #ifdef ENABLE_ELUNA sEluna->OnAddMember(this, pl, newmember.RankId); #endif /* ENABLE_ELUNA */ return true; }