/* * Copyright (C) 2008-2015 TrinityCore * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "ObjectMgr.h" #include "GuildFinderMgr.h" #include "GuildMgr.h" #include "GuildFinderPackets.h" #include "World.h" GuildFinderMgr::GuildFinderMgr() { } GuildFinderMgr::~GuildFinderMgr() { } void GuildFinderMgr::LoadFromDB() { LoadGuildSettings(); LoadMembershipRequests(); } void GuildFinderMgr::LoadGuildSettings() { TC_LOG_INFO("server.loading", "Loading guild finder guild-related settings..."); // 0 1 2 3 4 5 6 7 QueryResult result = CharacterDatabase.Query("SELECT gfgs.guildId, gfgs.availability, gfgs.classRoles, gfgs.interests, gfgs.level, gfgs.listed, gfgs.comment, c.race " "FROM guild_finder_guild_settings gfgs " "LEFT JOIN guild_member gm ON gm.guildid=gfgs.guildId " "LEFT JOIN characters c ON c.guid = gm.guid LIMIT 1"); if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 guild finder guild-related settings. Table `guild_finder_guild_settings` is empty."); return; } uint32 count = 0; uint32 oldMSTime = getMSTime(); do { Field* fields = result->Fetch(); ObjectGuid guildId = ObjectGuid::Create(fields[0].GetUInt64()); uint8 availability = fields[1].GetUInt8(); uint8 classRoles = fields[2].GetUInt8(); uint8 interests = fields[3].GetUInt8(); uint8 level = fields[4].GetUInt8(); bool listed = (fields[5].GetUInt8() != 0); std::string comment = fields[6].GetString(); TeamId guildTeam = TEAM_NEUTRAL; if (ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(fields[7].GetUInt8())) guildTeam = (TeamId)raceEntry->TeamID; LFGuildSettings settings(listed, guildTeam, guildId, classRoles, availability, interests, level, comment); _guildSettings[guildId] = settings; ++count; } while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u guild finder guild-related settings in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); } void GuildFinderMgr::LoadMembershipRequests() { TC_LOG_INFO("server.loading", "Loading guild finder membership requests..."); // 0 1 2 3 4 5 6 QueryResult result = CharacterDatabase.Query("SELECT guildId, playerGuid, availability, classRole, interests, comment, submitTime " "FROM guild_finder_applicant"); if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 guild finder membership requests. Table `guild_finder_applicant` is empty."); return; } uint32 count = 0; uint32 oldMSTime = getMSTime(); do { Field* fields = result->Fetch(); ObjectGuid guildId = ObjectGuid::Create(fields[0].GetUInt64()); ObjectGuid playerId = ObjectGuid::Create(fields[1].GetUInt64()); uint8 availability = fields[2].GetUInt8(); uint8 classRoles = fields[3].GetUInt8(); uint8 interests = fields[4].GetUInt8(); std::string comment = fields[5].GetString(); uint32 submitTime = fields[6].GetUInt32(); MembershipRequest request(playerId, guildId, availability, classRoles, interests, comment, time_t(submitTime)); _membershipRequestsByGuild[guildId][playerId] = request; _membershipRequestsByPlayer[playerId][guildId] = request; ++count; } while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u guild finder membership requests in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); } void GuildFinderMgr::AddMembershipRequest(ObjectGuid const& guildGuid, MembershipRequest const& request) { _membershipRequestsByGuild[guildGuid][request.GetPlayerGUID()] = request; _membershipRequestsByPlayer[request.GetPlayerGUID()][guildGuid] = request; SQLTransaction trans = CharacterDatabase.BeginTransaction(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GUILD_FINDER_APPLICANT); stmt->setUInt64(0, request.GetGuildGuid().GetCounter()); stmt->setUInt64(1, request.GetPlayerGUID().GetCounter()); stmt->setUInt8(2, request.GetAvailability()); stmt->setUInt8(3, request.GetClassRoles()); stmt->setUInt8(4, request.GetInterests()); stmt->setString(5, request.GetComment()); stmt->setUInt32(6, request.GetSubmitTime()); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); // Notify the applicant his submittion has been added if (Player* player = ObjectAccessor::FindPlayer(request.GetPlayerGUID())) SendMembershipRequestListUpdate(player); // Notify the guild master and officers the list changed if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid)) SendApplicantListUpdate(guild); } void GuildFinderMgr::RemoveAllMembershipRequestsFromPlayer(ObjectGuid const& playerId) { auto playerItr = _membershipRequestsByPlayer.find(playerId); if (playerItr == _membershipRequestsByPlayer.end()) return; SQLTransaction trans = CharacterDatabase.BeginTransaction(); for (auto& guildRequestPair : playerItr->second) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_APPLICANT); stmt->setUInt64(0, guildRequestPair.first.GetCounter()); stmt->setUInt64(1, playerId.GetCounter()); trans->Append(stmt); // Notify the guild master and officers the list changed if (Guild* guild = sGuildMgr->GetGuildByGuid(guildRequestPair.first)) SendApplicantListUpdate(guild); auto guildItr = _membershipRequestsByGuild.find(guildRequestPair.first); if (guildItr == _membershipRequestsByGuild.end()) continue; guildItr->second.erase(playerId); if (guildItr->second.empty()) _membershipRequestsByGuild.erase(guildItr); } CharacterDatabase.CommitTransaction(trans); _membershipRequestsByPlayer.erase(playerItr); } void GuildFinderMgr::RemoveMembershipRequest(ObjectGuid const& playerId, ObjectGuid const& guildId) { auto guildItr = _membershipRequestsByGuild.find(guildId); if (guildItr != _membershipRequestsByGuild.end()) { guildItr->second.erase(playerId); if (guildItr->second.empty()) _membershipRequestsByGuild.erase(guildItr); } auto playerItr = _membershipRequestsByPlayer.find(playerId); if (playerItr != _membershipRequestsByPlayer.end()) { playerItr->second.erase(guildId); if (playerItr->second.empty()) _membershipRequestsByPlayer.erase(playerItr); } SQLTransaction trans = CharacterDatabase.BeginTransaction(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_APPLICANT); stmt->setUInt64(0, guildId.GetCounter()); stmt->setUInt64(1, playerId.GetCounter()); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); // Notify the applicant his submittion has been removed if (Player* player = ObjectAccessor::FindPlayer(playerId)) SendMembershipRequestListUpdate(player); // Notify the guild master and officers the list changed if (Guild* guild = sGuildMgr->GetGuildByGuid(guildId)) SendApplicantListUpdate(guild); } std::vector GuildFinderMgr::GetAllMembershipRequestsForPlayer(ObjectGuid const& playerGuid) { std::vector resultSet; auto playerItr = _membershipRequestsByPlayer.find(playerGuid); if (playerItr == _membershipRequestsByPlayer.end()) return resultSet; resultSet.reserve(playerItr->second.size()); for (auto const& guildRequestPair : playerItr->second) resultSet.push_back(&guildRequestPair.second); return resultSet; } uint8 GuildFinderMgr::CountRequestsFromPlayer(ObjectGuid const& playerId) { auto playerItr = _membershipRequestsByPlayer.find(playerId); return playerItr != _membershipRequestsByPlayer.end() ? playerItr->second.size() : 0; } std::vector GuildFinderMgr::GetGuildsMatchingSetting(LFGuildPlayer& settings, TeamId faction) { std::vector resultSet; for (LFGuildStore::const_iterator itr = _guildSettings.begin(); itr != _guildSettings.end(); ++itr) { LFGuildSettings const& guildSettings = itr->second; if (!guildSettings.IsListed()) continue; if (guildSettings.GetTeam() != faction) continue; if (!(guildSettings.GetAvailability() & settings.GetAvailability())) continue; if (!(guildSettings.GetClassRoles() & settings.GetClassRoles())) continue; if (!(guildSettings.GetInterests() & settings.GetInterests())) continue; if (!(guildSettings.GetLevel() & settings.GetLevel())) continue; resultSet.push_back(&itr->second); } return resultSet; } bool GuildFinderMgr::HasRequest(ObjectGuid const& playerId, ObjectGuid const& guildId) { auto guildItr = _membershipRequestsByGuild.find(guildId); if (guildItr == _membershipRequestsByGuild.end()) return false; return guildItr->second.count(playerId) > 0; } void GuildFinderMgr::SetGuildSettings(ObjectGuid const& guildGuid, LFGuildSettings const& settings) { _guildSettings[guildGuid] = settings; SQLTransaction trans = CharacterDatabase.BeginTransaction(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GUILD_FINDER_GUILD_SETTINGS); stmt->setUInt64(0, settings.GetGUID().GetCounter()); stmt->setUInt8(1, settings.GetAvailability()); stmt->setUInt8(2, settings.GetClassRoles()); stmt->setUInt8(3, settings.GetInterests()); stmt->setUInt8(4, settings.GetLevel()); stmt->setUInt8(5, settings.IsListed()); stmt->setString(6, settings.GetComment()); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); } void GuildFinderMgr::DeleteGuild(ObjectGuid const& guildId) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); auto guildItr = _membershipRequestsByGuild.find(guildId); if (guildItr != _membershipRequestsByGuild.end()) { for (auto playerRequestPair : guildItr->second) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_APPLICANT); stmt->setUInt64(0, guildId.GetCounter()); stmt->setUInt64(1, playerRequestPair.first.GetCounter()); trans->Append(stmt); auto playerItr = _membershipRequestsByPlayer.find(playerRequestPair.first); if (playerItr != _membershipRequestsByPlayer.end()) { playerItr->second.erase(guildId); if (playerItr->second.empty()) _membershipRequestsByPlayer.erase(playerItr); } // Notify the applicant his submition has been removed if (Player* player = ObjectAccessor::FindPlayer(playerRequestPair.first)) SendMembershipRequestListUpdate(player); } } PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_GUILD_SETTINGS); stmt->setUInt64(0, guildId.GetCounter()); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); _membershipRequestsByGuild.erase(guildId); _guildSettings.erase(guildId); // Notify the guild master the list changed (even if he's not a GM any more, not sure if needed) if (Guild* guild = sGuildMgr->GetGuildByGuid(guildId)) SendApplicantListUpdate(guild); } void GuildFinderMgr::SendApplicantListUpdate(Guild* guild) { WorldPackets::GuildFinder::LFGuildApplicantListChanged applicantListChanged; guild->BroadcastPacketToRank(applicantListChanged.Write(), GR_OFFICER); if (Player* player = ObjectAccessor::FindPlayer(guild->GetLeaderGUID())) player->SendDirectMessage(applicantListChanged.GetRawPacket()); } void GuildFinderMgr::SendMembershipRequestListUpdate(Player* player) { player->SendDirectMessage(WorldPackets::GuildFinder::LFGuildApplicationsListChanged().Write()); }