aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Entities/Object/ObjectDefines.h1
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp3
-rw-r--r--src/server/game/Guilds/Guild.cpp5
-rwxr-xr-xsrc/server/game/Guilds/Guild.h2
-rw-r--r--src/server/game/Guilds/GuildFinderMgr.cpp333
-rw-r--r--src/server/game/Guilds/GuildFinderMgr.h274
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp6
-rw-r--r--src/server/game/Handlers/GuildFinderHandler.cpp442
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp32
-rwxr-xr-xsrc/server/game/Server/Protocol/Opcodes.h2
-rwxr-xr-xsrc/server/game/Server/WorldSession.h11
-rw-r--r--src/server/game/Tools/PlayerDump.cpp4
-rw-r--r--src/server/game/World/World.cpp19
-rwxr-xr-xsrc/server/game/World/World.h6
-rw-r--r--src/server/scripts/Commands/cs_character.cpp2
-rw-r--r--[-rwxr-xr-x]src/server/shared/Database/Implementation/CharacterDatabase.cpp8
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.h5
17 files changed, 1126 insertions, 29 deletions
diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h
index b971943954e..46baee4a284 100755
--- a/src/server/game/Entities/Object/ObjectDefines.h
+++ b/src/server/game/Entities/Object/ObjectDefines.h
@@ -57,6 +57,7 @@ enum HighGuid
#define IS_CRE_OR_VEH_GUID(Guid) (IS_CREATURE_GUID(Guid) || IS_VEHICLE_GUID(Guid))
#define IS_CRE_OR_VEH_OR_PET_GUID(Guid)(IS_CRE_OR_VEH_GUID(Guid) || IS_PET_GUID(Guid))
#define IS_PLAYER_GUID(Guid) (GUID_HIPART(Guid) == HIGHGUID_PLAYER && Guid != 0)
+#define IS_GUILD_GUID(Guid) (GUID_HIPART(Guid) == HIGHGUID_GUILD && Guid != 0)
#define IS_UNIT_GUID(Guid) (IS_CRE_OR_VEH_OR_PET_GUID(Guid) || IS_PLAYER_GUID(Guid))
// special case for empty guid need check
#define IS_ITEM_GUID(Guid) (GUID_HIPART(Guid) == HIGHGUID_ITEM)
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 7d1734ee204..7886c0354f5 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -12780,6 +12780,9 @@ void Unit::SetLevel(uint8 lvl)
// group update
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetGroup())
ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_LEVEL);
+
+ if (GetTypeId() == TYPEID_PLAYER)
+ sWorld->UpdateCharacterNameDataLevel(ToPlayer()->GetGUIDLow(), lvl);
}
void Unit::SetHealth(uint32 val)
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index e7121b0fa81..92191551858 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -19,6 +19,7 @@
#include "DatabaseEnv.h"
#include "Guild.h"
#include "GuildMgr.h"
+#include "GuildFinderMgr.h"
#include "ScriptMgr.h"
#include "Chat.h"
#include "Config.h"
@@ -1190,6 +1191,9 @@ void Guild::Disband()
trans->Append(stmt);
CharacterDatabase.CommitTransaction(trans);
+
+ sGuildFinderMgr->DeleteGuild(m_id);
+
sGuildMgr->RemoveGuild(m_id);
}
@@ -1665,6 +1669,7 @@ void Guild::HandleAcceptMember(WorldSession* session)
{
_LogEvent(GUILD_EVENT_LOG_JOIN_GUILD, player->GetGUIDLow());
_BroadcastEvent(GE_JOINED, player->GetGUID(), player->GetName());
+ sGuildFinderMgr->RemoveMembershipRequest(player->GetGUIDLow(), GUID_LOPART(this->GetGUID()));
}
}
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index f3e18d8998b..f644e5d3592 100755
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -787,6 +787,8 @@ public:
void ResetDailyExperience();
GuildNewsLog& GetNewsLog() { return _newsLog; }
+ EmblemInfo const& GetEmblemInfo() const { return m_emblemInfo; }
+
protected:
uint32 m_id;
std::string m_name;
diff --git a/src/server/game/Guilds/GuildFinderMgr.cpp b/src/server/game/Guilds/GuildFinderMgr.cpp
new file mode 100644
index 00000000000..c81abeec47a
--- /dev/null
+++ b/src/server/game/Guilds/GuildFinderMgr.cpp
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "ObjectMgr.h"
+#include "GuildFinderMgr.h"
+#include "GuildMgr.h"
+#include "World.h"
+
+GuildFinderMgr::GuildFinderMgr()
+{
+}
+
+GuildFinderMgr::~GuildFinderMgr()
+{
+}
+
+void GuildFinderMgr::LoadFromDB()
+{
+ LoadGuildSettings();
+ LoadMembershipRequests();
+}
+
+void GuildFinderMgr::LoadGuildSettings()
+{
+ sLog->outInfo(LOG_FILTER_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)
+ {
+ sLog->outInfo(LOG_FILTER_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();
+ uint32 guildId = fields[0].GetUInt32();
+ 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_ALLIANCE;
+ if (ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(fields[7].GetUInt8()))
+ if (raceEntry->TeamID == 1)
+ guildTeam = TEAM_HORDE;
+
+ LFGuildSettings settings(listed, guildTeam, guildId, classRoles, availability, interests, level, comment);
+ _guildSettings[guildId] = settings;
+
+ ++count;
+ } while (result->NextRow());
+
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u guild finder guild-related settings in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
+void GuildFinderMgr::LoadMembershipRequests()
+{
+ sLog->outInfo(LOG_FILTER_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)
+ {
+ sLog->outInfo(LOG_FILTER_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();
+ uint32 guildId = fields[0].GetUInt32();
+ uint32 playerId = fields[1].GetUInt32();
+ 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));
+
+ _membershipRequests[guildId].push_back(request);
+
+ ++count;
+ } while (result->NextRow());
+
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u guild finder membership requests in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
+void GuildFinderMgr::AddMembershipRequest(uint32 guildGuid, MembershipRequest const& request)
+{
+ _membershipRequests[guildGuid].push_back(request);
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GUILD_FINDER_APPLICANT);
+ stmt->setUInt32(0, request.GetGuildId());
+ stmt->setUInt32(1, request.GetPlayerGUID());
+ 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(MAKE_NEW_GUID(request.GetPlayerGUID(), 0, HIGHGUID_PLAYER)))
+ SendMembershipRequestListUpdate(*player);
+
+ // Notify the guild master and officers the list changed
+ if (Guild* guild = sGuildMgr->GetGuildById(guildGuid))
+ SendApplicantListUpdate(*guild);
+}
+
+void GuildFinderMgr::RemoveAllMembershipRequestsFromPlayer(uint32 playerId)
+{
+ for (MembershipRequestStore::iterator itr = _membershipRequests.begin(); itr != _membershipRequests.end(); ++itr)
+ {
+ std::vector<MembershipRequest>::iterator itr2 = itr->second.begin();
+ for(; itr2 != itr->second.end(); ++itr2)
+ if (itr2->GetPlayerGUID() == playerId)
+ break;
+
+ if (itr2 == itr->second.end())
+ return;
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_APPLICANT);
+ stmt->setUInt32(0, itr2->GetGuildId());
+ stmt->setUInt32(1, itr2->GetPlayerGUID());
+ trans->Append(stmt);
+
+ CharacterDatabase.CommitTransaction(trans);
+ itr->second.erase(itr2);
+
+ // Notify the guild master and officers the list changed
+ if (Guild* guild = sGuildMgr->GetGuildById(itr->first))
+ SendApplicantListUpdate(*guild);
+ }
+}
+
+void GuildFinderMgr::RemoveMembershipRequest(uint32 playerId, uint32 guildId)
+{
+ std::vector<MembershipRequest>::iterator itr = _membershipRequests[guildId].begin();
+ for(; itr != _membershipRequests[guildId].end(); ++itr)
+ if (itr->GetPlayerGUID() == playerId)
+ break;
+
+ if (itr == _membershipRequests[guildId].end())
+ return;
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_APPLICANT);
+ stmt->setUInt32(0, itr->GetGuildId());
+ stmt->setUInt32(1, itr->GetPlayerGUID());
+ trans->Append(stmt);
+
+ CharacterDatabase.CommitTransaction(trans);
+
+ _membershipRequests[guildId].erase(itr);
+
+ // Notify the applicant his submittion has been removed
+ if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(playerId, 0, HIGHGUID_PLAYER)))
+ SendMembershipRequestListUpdate(*player);
+
+ // Notify the guild master and officers the list changed
+ if (Guild* guild = sGuildMgr->GetGuildById(guildId))
+ SendApplicantListUpdate(*guild);
+}
+
+std::list<MembershipRequest> GuildFinderMgr::GetAllMembershipRequestsForPlayer(uint32 playerGuid)
+{
+ std::list<MembershipRequest> resultSet;
+ for (MembershipRequestStore::const_iterator itr = _membershipRequests.begin(); itr != _membershipRequests.end(); ++itr)
+ {
+ std::vector<MembershipRequest> const& guildReqs = itr->second;
+ for (std::vector<MembershipRequest>::const_iterator itr2 = guildReqs.begin(); itr2 != guildReqs.end(); ++itr2)
+ {
+ if (itr2->GetPlayerGUID() == playerGuid)
+ {
+ resultSet.push_back(*itr2);
+ break;
+ }
+ }
+ }
+ return resultSet;
+}
+
+uint8 GuildFinderMgr::CountRequestsFromPlayer(uint32 playerId)
+{
+ uint8 result = 0;
+ for (MembershipRequestStore::const_iterator itr = _membershipRequests.begin(); itr != _membershipRequests.end(); ++itr)
+ {
+ for (std::vector<MembershipRequest>::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
+ {
+ if (itr2->GetPlayerGUID() != playerId)
+ continue;
+ ++result;
+ break;
+ }
+ }
+ return result;
+}
+
+LFGuildStore GuildFinderMgr::GetGuildsMatchingSetting(LFGuildPlayer& settings, TeamId faction)
+{
+ LFGuildStore resultSet;
+ for (LFGuildStore::const_iterator itr = _guildSettings.begin(); itr != _guildSettings.end(); ++itr)
+ {
+ LFGuildSettings const& guildSettings = itr->second;
+
+ 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.insert(std::make_pair(itr->first, guildSettings));
+ }
+
+ return resultSet;
+}
+
+bool GuildFinderMgr::HasRequest(uint32 playerId, uint32 guildId)
+{
+ for (std::vector<MembershipRequest>::const_iterator itr = _membershipRequests[guildId].begin(); itr != _membershipRequests[guildId].end(); ++itr)
+ if (itr->GetPlayerGUID() == playerId)
+ return true;
+ return false;
+}
+
+void GuildFinderMgr::SetGuildSettings(uint32 guildGuid, LFGuildSettings const& settings)
+{
+ _guildSettings[guildGuid] = settings;
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GUILD_FINDER_GUILD_SETTINGS);
+ stmt->setUInt32(0, settings.GetGUID());
+ 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(uint32 guildId)
+{
+ std::vector<MembershipRequest>::iterator itr = _membershipRequests[guildId].begin();
+ while (itr != _membershipRequests[guildId].end())
+ {
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ uint32 applicant = itr->GetPlayerGUID();
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_APPLICANT);
+ stmt->setUInt32(0, itr->GetGuildId());
+ stmt->setUInt32(1, applicant);
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_GUILD_SETTINGS);
+ stmt->setUInt32(0, itr->GetGuildId());
+ trans->Append(stmt);
+
+ CharacterDatabase.CommitTransaction(trans);
+ _membershipRequests[guildId].erase(itr);
+
+ // Notify the applicant his submition has been removed
+ if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(applicant, 0, HIGHGUID_PLAYER)))
+ SendMembershipRequestListUpdate(*player);
+ }
+
+ _membershipRequests.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->GetGuildById(guildId))
+ SendApplicantListUpdate(*guild);
+}
+
+void GuildFinderMgr::SendApplicantListUpdate(Guild& guild)
+{
+ WorldPacket data(SMSG_LF_GUILD_APPLICANT_LIST_UPDATED, 0);
+ if (Player* player = ObjectAccessor::FindPlayer(guild.GetLeaderGUID()))
+ player->SendDirectMessage(&data);
+ guild.BroadcastPacketToRank(&data, GR_OFFICER);
+}
+
+void GuildFinderMgr::SendMembershipRequestListUpdate(Player& player)
+{
+ WorldPacket data(SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED, 0);
+ player.SendDirectMessage(&data);
+}
diff --git a/src/server/game/Guilds/GuildFinderMgr.h b/src/server/game/Guilds/GuildFinderMgr.h
new file mode 100644
index 00000000000..169b42740aa
--- /dev/null
+++ b/src/server/game/Guilds/GuildFinderMgr.h
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TRINITY_GUILDFINDER_H
+#define __TRINITY_GUILDFINDER_H
+
+#include <ace/Singleton.h>
+#include "Common.h"
+#include "World.h"
+#include "GuildMgr.h"
+
+enum GuildFinderOptionsInterest
+{
+ INTEREST_QUESTING = 0x01,
+ INTEREST_DUNGEONS = 0x02,
+ INTEREST_RAIDS = 0x04,
+ INTEREST_PVP = 0x08,
+ INTEREST_ROLE_PLAYING = 0x10,
+ ALL_INTERESTS = INTEREST_QUESTING | INTEREST_DUNGEONS | INTEREST_RAIDS | INTEREST_PVP | INTEREST_ROLE_PLAYING
+};
+
+enum GuildFinderOptionsAvailability
+{
+ AVAILABILITY_WEEKDAYS = 0x1,
+ AVAILABILITY_WEEKENDS = 0x2,
+ ALL_WEEK = AVAILABILITY_WEEKDAYS | AVAILABILITY_WEEKENDS
+};
+
+enum GuildFinderOptionsRoles
+{
+ GUILDFINDER_ROLE_TANK = 0x1,
+ GUILDFINDER_ROLE_HEALER = 0x2,
+ GUILDFINDER_ROLE_DPS = 0x4,
+ GUILDFINDER_ALL_ROLES = GUILDFINDER_ROLE_TANK | GUILDFINDER_ROLE_HEALER | GUILDFINDER_ROLE_DPS
+};
+
+enum GuildFinderOptionsLevel
+{
+ ANY_FINDER_LEVEL = 0x1,
+ MAX_FINDER_LEVEL = 0x2,
+ ALL_GUILDFINDER_LEVELS = ANY_FINDER_LEVEL | MAX_FINDER_LEVEL
+};
+
+/// Holds all required informations about a membership request
+struct MembershipRequest
+{
+ public:
+ MembershipRequest(MembershipRequest const& settings) : _comment(settings.GetComment())
+ {
+ _availability = settings.GetAvailability();
+ _classRoles = settings.GetClassRoles();
+ _interests = settings.GetInterests();
+ _guildId = settings.GetGuildId();
+ _playerGUID = settings.GetPlayerGUID();
+ _time = settings.GetSubmitTime();
+ }
+
+ MembershipRequest(uint32 playerGUID, uint32 guildId, uint32 availability, uint32 classRoles, uint32 interests, std::string& comment, time_t submitTime) :
+ _playerGUID(playerGUID), _guildId(guildId), _availability(availability), _classRoles(classRoles),
+ _interests(interests), _time(submitTime), _comment(comment) {}
+
+ MembershipRequest() : _playerGUID(0), _guildId(0), _availability(0), _classRoles(0),
+ _interests(0), _time(time(NULL)) {}
+
+ uint32 GetGuildId() const { return _guildId; }
+ uint32 GetPlayerGUID() const { return _playerGUID; }
+ uint8 GetAvailability() const { return _availability; }
+ uint8 GetClassRoles() const { return _classRoles; }
+ uint8 GetInterests() const { return _interests; }
+ uint8 GetClass() const { return sWorld->GetCharacterNameData(GetPlayerGUID())->m_class; }
+ uint8 GetLevel() const { return sWorld->GetCharacterNameData(GetPlayerGUID())->m_level; }
+ time_t GetSubmitTime() const { return _time; }
+ time_t GetExpiryTime() const { return time_t(_time + 30 * 24 * 3600); } // Adding 30 days
+ std::string const& GetComment() const { return _comment; }
+ std::string const& GetName() const { return sWorld->GetCharacterNameData(GetPlayerGUID())->m_name; }
+ private:
+ std::string _comment;
+
+ uint32 _guildId;
+ uint32 _playerGUID;
+
+ uint8 _availability;
+ uint8 _classRoles;
+ uint8 _interests;
+
+ time_t _time;
+};
+
+/// Holds all informations about a player's finder settings. _NOT_ stored in database.
+struct LFGuildPlayer
+{
+ public:
+ LFGuildPlayer()
+ {
+ _guid = 0;
+ _roles = 0;
+ _availability = 0;
+ _interests = 0;
+ _level = 0;
+ }
+
+ LFGuildPlayer(uint32 guid, uint8 role, uint8 availability, uint8 interests, uint8 level)
+ {
+ _guid = guid;
+ _roles = role;
+ _availability = availability;
+ _interests = interests;
+ _level = level;
+ }
+
+ LFGuildPlayer(uint32 guid, uint8 role, uint8 availability, uint8 interests, uint8 level, std::string& comment) : _comment(comment)
+ {
+ _guid = guid;
+ _roles = role;
+ _availability = availability;
+ _interests = interests;
+ _level = level;
+ }
+
+ LFGuildPlayer(LFGuildPlayer const& settings) : _comment(settings.GetComment())
+ {
+ _guid = settings.GetGUID();
+ _roles = settings.GetClassRoles();
+ _availability = settings.GetAvailability();
+ _interests = settings.GetInterests();
+ _level = settings.GetLevel();
+ }
+
+ uint32 GetGUID() const { return _guid; }
+ uint8 GetClassRoles() const { return _roles; }
+ uint8 GetAvailability() const { return _availability; }
+ uint8 GetInterests() const { return _interests; }
+ uint8 GetLevel() const { return _level; }
+ std::string const& GetComment() const { return _comment; }
+
+ private:
+ std::string _comment;
+ uint32 _guid;
+ uint8 _roles;
+ uint8 _availability;
+ uint8 _interests;
+ uint8 _level;
+};
+
+/// Holds settings for a guild in the finder system. Saved to database.
+struct LFGuildSettings : public LFGuildPlayer
+{
+ public:
+ LFGuildSettings() : LFGuildPlayer(), _listed(false), _team(TEAM_ALLIANCE) {}
+
+ LFGuildSettings(bool listed, TeamId team) : LFGuildPlayer(), _listed(listed), _team(team) {}
+
+ LFGuildSettings(bool listed, TeamId team, uint32 guid, uint8 role, uint8 availability, uint8 interests, uint8 level) : _listed(listed),
+ LFGuildPlayer(guid, role, availability, interests, level), _team(team) {}
+
+ LFGuildSettings(bool listed, TeamId team, uint32 guid, uint8 role, uint8 availability, uint8 interests, uint8 level, std::string& comment) : _listed(listed),
+ LFGuildPlayer(guid, role, availability, interests, level, comment), _team(team) {}
+
+ LFGuildSettings(LFGuildSettings const& settings) : _listed(settings.IsListed()), _team(settings.GetTeam()),
+ LFGuildPlayer(settings) {}
+
+
+ bool IsListed() const { return _listed; }
+ void SetListed(bool state) { _listed = state; }
+
+ TeamId GetTeam() const { return _team; }
+ private:
+ TeamId _team;
+ bool _listed;
+};
+
+typedef std::map<uint32 /* guildGuid */, LFGuildSettings> LFGuildStore;
+typedef std::map<uint32 /* guildGuid */, std::vector<MembershipRequest> > MembershipRequestStore;
+
+class GuildFinderMgr
+{
+ friend class ACE_Singleton<GuildFinderMgr, ACE_Null_Mutex>;
+
+ private:
+ GuildFinderMgr();
+ ~GuildFinderMgr();
+
+ LFGuildStore _guildSettings;
+
+ MembershipRequestStore _membershipRequests;
+
+ void LoadGuildSettings();
+ void LoadMembershipRequests();
+
+ public:
+ void LoadFromDB();
+
+ /**
+ * @brief Stores guild settings and begins an asynchronous database insert
+ * @param guildGuid The guild's database guid.
+ * @param LFGuildSettings The guild's settings storage.
+ */
+ void SetGuildSettings(uint32 guildGuid, LFGuildSettings const& settings);
+
+ /**
+ * @brief Returns settings for a guild.
+ * @param guildGuid The guild's database guid.
+ */
+ LFGuildSettings GetGuildSettings(uint32 guildGuid) { return _guildSettings[guildGuid]; }
+
+ /**
+ * @brief Files a membership request to a guild
+ * @param guildGuid The guild's database GUID.
+ * @param MembershipRequest An object storing all data related to the request.
+ */
+ void AddMembershipRequest(uint32 guildGuid, MembershipRequest const& request);
+
+ /**
+ * @brief Removes all membership request from a player.
+ * @param playerId The player's database guid whose application shall be deleted.
+ */
+ void RemoveAllMembershipRequestsFromPlayer(uint32 playerId);
+
+ /**
+ * @brief Removes a membership request to a guild.
+ * @param playerId The player's database guid whose application shall be deleted.
+ * @param guildId The guild's database guid
+ */
+ void RemoveMembershipRequest(uint32 playerId, uint32 guildId);
+
+ /// wipes everything related to a guild. Used when that guild is disbanded
+ void DeleteGuild(uint32 guildId);
+
+ /**
+ * @brief Returns a set of membership requests for a guild
+ * @param guildGuid The guild's database guid.
+ */
+ std::vector<MembershipRequest> GetAllMembershipRequestsForGuild(uint32 guildGuid) { return _membershipRequests[guildGuid]; }
+
+ /**
+ * @brief Returns a list of membership requests for a player.
+ * @param playerGuid The player's database guid.
+ */
+ std::list<MembershipRequest> GetAllMembershipRequestsForPlayer(uint32 playerGuid);
+
+ /**
+ * @brief Returns a store of guilds matching the settings provided, using bitmask operators.
+ * @param settings The player's finder settings
+ * @param teamId The player's faction (TEAM_ALLIANCE or TEAM_HORDE)
+ */
+ LFGuildStore GetGuildsMatchingSetting(LFGuildPlayer& settings, TeamId faction);
+
+ /// Provided a player DB guid and a guild DB guid, determines if a pending request is filed with these keys.
+ bool HasRequest(uint32 playerId, uint32 guildId);
+
+ /// Counts the amount of pending membership requests, given the player's db guid.
+ uint8 CountRequestsFromPlayer(uint32 playerId);
+
+ void SendApplicantListUpdate(Guild& guild);
+ void SendMembershipRequestListUpdate(Player& player);
+};
+
+#define sGuildFinderMgr ACE_Singleton<GuildFinderMgr, ACE_Null_Mutex>::instance()
+
+#endif // __TRINITY_GUILDFINDER_H
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 32ed1d2b27f..70c1bc5955b 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -30,6 +30,7 @@
#include "Chat.h"
#include "Group.h"
#include "Guild.h"
+#include "GuildFinderMgr.h"
#include "Language.h"
#include "Log.h"
#include "Opcodes.h"
@@ -685,7 +686,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
std::string IP_str = GetRemoteAddress();
sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), IP_str.c_str(), createInfo->Name.c_str(), newChar.GetGUIDLow());
sScriptMgr->OnPlayerCreate(&newChar);
- sWorld->AddCharacterNameData(newChar.GetGUIDLow(), std::string(newChar.GetName()), newChar.getGender(), newChar.getRace(), newChar.getClass());
+ sWorld->AddCharacterNameData(newChar.GetGUIDLow(), std::string(newChar.GetName()), newChar.getGender(), newChar.getRace(), newChar.getClass(), newChar.getLevel());
newChar.CleanupsBeforeDelete();
delete createInfo;
@@ -742,7 +743,7 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket & recvData)
std::string IP_str = GetRemoteAddress();
sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Delete Character:[%s] (GUID: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), GUID_LOPART(guid));
sScriptMgr->OnPlayerDelete(guid);
- sWorld->DeleteCharaceterNameData(GUID_LOPART(guid));
+ sWorld->DeleteCharacterNameData(GUID_LOPART(guid));
if (sLog->ShouldLog(LOG_FILTER_PLAYER_DUMP, LOG_LEVEL_INFO)) // optimize GetPlayerDump call
{
@@ -751,6 +752,7 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket & recvData)
sLog->outCharDump(dump.c_str(), GetAccountId(), GUID_LOPART(guid), name.c_str());
}
+ sGuildFinderMgr->RemoveAllMembershipRequestsFromPlayer(guid);
Player::DeleteFromDB(guid, GetAccountId());
WorldPacket data(SMSG_CHAR_DELETE, 1);
diff --git a/src/server/game/Handlers/GuildFinderHandler.cpp b/src/server/game/Handlers/GuildFinderHandler.cpp
new file mode 100644
index 00000000000..facbd98ffac
--- /dev/null
+++ b/src/server/game/Handlers/GuildFinderHandler.cpp
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "WorldSession.h"
+#include "WorldPacket.h"
+#include "Object.h"
+#include "SharedDefines.h"
+#include "GuildFinderMgr.h"
+#include "GuildMgr.h"
+
+void WorldSession::HandleGuildFinderAddRecruit(WorldPacket& recvPacket)
+{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_LF_GUILD_ADD_RECRUIT");
+
+ if (sGuildFinderMgr->GetAllMembershipRequestsForPlayer(GetPlayer()->GetGUIDLow()).size() == 10)
+ return;
+
+ uint32 classRoles = 0;
+ uint32 availability = 0;
+ uint32 guildInterests = 0;
+
+ recvPacket >> classRoles >> guildInterests >> availability;
+
+ ObjectGuid guid;
+ guid[3] = recvPacket.ReadBit();
+ guid[0] = recvPacket.ReadBit();
+ guid[6] = recvPacket.ReadBit();
+ guid[1] = recvPacket.ReadBit();
+ uint16 commentLength = recvPacket.ReadBits(11);
+ guid[5] = recvPacket.ReadBit();
+ guid[4] = recvPacket.ReadBit();
+ guid[7] = recvPacket.ReadBit();
+ uint8 nameLength = recvPacket.ReadBits(7);
+ guid[2] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guid[4]);
+ recvPacket.ReadByteSeq(guid[5]);
+ std::string comment = recvPacket.ReadString(commentLength);
+ std::string playerName = recvPacket.ReadString(nameLength);
+ recvPacket.ReadByteSeq(guid[7]);
+ recvPacket.ReadByteSeq(guid[2]);
+ recvPacket.ReadByteSeq(guid[0]);
+ recvPacket.ReadByteSeq(guid[6]);
+ recvPacket.ReadByteSeq(guid[1]);
+ recvPacket.ReadByteSeq(guid[3]);
+
+ uint32 guildLowGuid = GUID_LOPART(uint64(guid));
+
+ if (!IS_GUILD_GUID(guid))
+ return;
+ if (!(classRoles & GUILDFINDER_ALL_ROLES) || classRoles > GUILDFINDER_ALL_ROLES)
+ return;
+ if (!(availability & ALL_WEEK) || availability > ALL_WEEK)
+ return;
+ if (!(guildInterests & ALL_INTERESTS) || guildInterests > ALL_INTERESTS)
+ return;
+
+ MembershipRequest request = MembershipRequest(GetPlayer()->GetGUIDLow(), guildLowGuid, availability, classRoles, guildInterests, comment, time(NULL));
+ sGuildFinderMgr->AddMembershipRequest(guildLowGuid, request);
+}
+
+void WorldSession::HandleGuildFinderBrowse(WorldPacket& recvPacket)
+{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_LF_GUILD_BROWSE");
+ uint32 classRoles = 0;
+ uint32 availability = 0;
+ uint32 guildInterests = 0;
+ uint32 playerLevel = 0; // Raw player level (1-85), do they use MAX_FINDER_LEVEL when on level 85 ?
+
+ recvPacket >> classRoles >> availability >> guildInterests >> playerLevel;
+
+ if (!(classRoles & GUILDFINDER_ALL_ROLES) || classRoles > GUILDFINDER_ALL_ROLES)
+ return;
+ if (!(availability & ALL_WEEK) || availability > ALL_WEEK)
+ return;
+ if (!(guildInterests & ALL_INTERESTS) || guildInterests > ALL_INTERESTS)
+ return;
+ if (playerLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) || playerLevel < 1)
+ return;
+
+ Player* player = GetPlayer();
+
+ LFGuildPlayer settings(player->GetGUIDLow(), classRoles, availability, guildInterests, ANY_FINDER_LEVEL);
+ LFGuildStore guildList = sGuildFinderMgr->GetGuildsMatchingSetting(settings, player->GetTeamId());
+ uint32 guildCount = guildList.size();
+
+ if (guildCount == 0)
+ {
+ WorldPacket packet(SMSG_LF_GUILD_BROWSE_UPDATED, 0);
+ player->SendDirectMessage(&packet);
+ return;
+ }
+
+ ByteBuffer bufferData(65 * guildCount);
+ WorldPacket data(SMSG_LF_GUILD_BROWSE_UPDATED, 3 + guildCount * 65); // Estimated size
+ data.WriteBits(guildCount, 19);
+
+ for (LFGuildStore::const_iterator itr = guildList.begin(); itr != guildList.end(); ++itr)
+ {
+ LFGuildSettings guildSettings = itr->second;
+ Guild* guild = sGuildMgr->GetGuildById(itr->first);
+
+ ObjectGuid guildGUID = ObjectGuid(guild->GetGUID());
+
+ data.WriteBit(guildGUID[7]);
+ data.WriteBit(guildGUID[5]);
+ data.WriteBits(guild->GetName().size(), 8);
+ data.WriteBit(guildGUID[0]);
+ data.WriteBits(guildSettings.GetComment().size(), 11);
+ data.WriteBit(guildGUID[4]);
+ data.WriteBit(guildGUID[1]);
+ data.WriteBit(guildGUID[2]);
+ data.WriteBit(guildGUID[6]);
+ data.WriteBit(guildGUID[3]);
+
+ bufferData << int32(guild->GetEmblemInfo().GetColor());
+ bufferData << int32(guild->GetEmblemInfo().GetBorderStyle()); // Guessed
+ bufferData << int32(guild->GetEmblemInfo().GetStyle());
+
+ bufferData.WriteString(guildSettings.GetComment());
+
+ bufferData << uint8(0); // Cached ? Idk
+
+ bufferData.WriteByteSeq(guildGUID[5]);
+
+ bufferData << uint32(guildSettings.GetInterests()); // Guild Interests
+
+ bufferData.WriteByteSeq(guildGUID[6]);
+ bufferData.WriteByteSeq(guildGUID[4]);
+
+ bufferData << guild->GetLevel();
+
+ bufferData.WriteString(guild->GetName());
+
+ bufferData << int32(0); // guild->GetAchievementMgr().GetAchievementPoints()
+
+ bufferData.WriteByteSeq(guildGUID[7]);
+
+ bufferData << uint8(sGuildFinderMgr->HasRequest(player->GetGUIDLow(), guild->GetGUID())); // Request pending
+
+ bufferData.WriteByteSeq(guildGUID[2]);
+ bufferData.WriteByteSeq(guildGUID[0]);
+
+ bufferData << uint32(guildSettings.GetAvailability());
+
+ bufferData.WriteByteSeq(guildGUID[1]);
+
+ bufferData << int32(guild->GetEmblemInfo().GetBackgroundColor());
+ bufferData << uint32(0); // Unk Int 2 (+ 128) // Always 0 or 1
+ bufferData << int32(guild->GetEmblemInfo().GetBorderColor());
+ bufferData << uint32(guildSettings.GetClassRoles());
+
+ bufferData.WriteByteSeq(guildGUID[3]);
+ bufferData << int32(guild->GetMembersCount());
+ }
+
+ data.FlushBits();
+ data.append(bufferData);
+
+ player->SendDirectMessage(&data);
+}
+
+void WorldSession::HandleGuildFinderDeclineRecruit(WorldPacket& recvPacket)
+{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_LF_GUILD_DECLINE_RECRUIT");
+
+ ObjectGuid playerGuid;
+
+ playerGuid[1] = recvPacket.ReadBit();
+ playerGuid[4] = recvPacket.ReadBit();
+ playerGuid[5] = recvPacket.ReadBit();
+ playerGuid[2] = recvPacket.ReadBit();
+ playerGuid[6] = recvPacket.ReadBit();
+ playerGuid[7] = recvPacket.ReadBit();
+ playerGuid[0] = recvPacket.ReadBit();
+ playerGuid[3] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(playerGuid[5]);
+ recvPacket.ReadByteSeq(playerGuid[7]);
+ recvPacket.ReadByteSeq(playerGuid[2]);
+ recvPacket.ReadByteSeq(playerGuid[3]);
+ recvPacket.ReadByteSeq(playerGuid[4]);
+ recvPacket.ReadByteSeq(playerGuid[1]);
+ recvPacket.ReadByteSeq(playerGuid[0]);
+ recvPacket.ReadByteSeq(playerGuid[6]);
+
+ if (!IS_PLAYER_GUID(playerGuid))
+ return;
+
+ sGuildFinderMgr->RemoveMembershipRequest(GUID_LOPART(playerGuid), GetPlayer()->GetGuildId());
+}
+
+void WorldSession::HandleGuildFinderGetApplications(WorldPacket& /*recvPacket*/)
+{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_LF_GUILD_GET_APPLICATIONS"); // Empty opcode
+
+ std::list<MembershipRequest> applicatedGuilds = sGuildFinderMgr->GetAllMembershipRequestsForPlayer(GetPlayer()->GetGUIDLow());
+ uint32 applicationsCount = applicatedGuilds.size();
+ WorldPacket data(SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED, 7 + 54 * applicationsCount);
+ data.WriteBits(applicationsCount, 20);
+
+ if (applicationsCount > 0)
+ {
+ ByteBuffer bufferData(54 * applicationsCount);
+ for (std::list<MembershipRequest>::const_iterator itr = applicatedGuilds.begin(); itr != applicatedGuilds.end(); ++itr)
+ {
+ Guild* guild = sGuildMgr->GetGuildById(itr->GetGuildId());
+ LFGuildSettings guildSettings = sGuildFinderMgr->GetGuildSettings(itr->GetGuildId());
+ MembershipRequest request = *itr;
+
+ ObjectGuid guildGuid = ObjectGuid(guild->GetGUID());
+
+ data.WriteBit(guildGuid[1]);
+ data.WriteBit(guildGuid[0]);
+ data.WriteBit(guildGuid[5]);
+ data.WriteBits(request.GetComment().size(), 11);
+ data.WriteBit(guildGuid[3]);
+ data.WriteBit(guildGuid[7]);
+ data.WriteBit(guildGuid[4]);
+ data.WriteBit(guildGuid[6]);
+ data.WriteBit(guildGuid[2]);
+ data.WriteBits(guild->GetName().size(), 8);
+
+ bufferData.WriteByteSeq(guildGuid[2]);
+ bufferData.WriteString(request.GetComment());
+ bufferData.WriteByteSeq(guildGuid[5]);
+ bufferData.WriteString(guild->GetName());
+
+ bufferData << uint32(guildSettings.GetAvailability());
+ bufferData << uint32(request.GetExpiryTime() - time(NULL)); // Time left to application expiry (seconds)
+
+ bufferData.WriteByteSeq(guildGuid[0]);
+ bufferData.WriteByteSeq(guildGuid[6]);
+ bufferData.WriteByteSeq(guildGuid[3]);
+ bufferData.WriteByteSeq(guildGuid[7]);
+
+ bufferData << uint32(guildSettings.GetClassRoles());
+
+ bufferData.WriteByteSeq(guildGuid[4]);
+ bufferData.WriteByteSeq(guildGuid[1]);
+
+ bufferData << uint32(time(NULL) - request.GetSubmitTime()); // Time since application (seconds)
+ bufferData << uint32(guildSettings.GetInterests());
+ }
+
+ data.FlushBits();
+ data.append(bufferData);
+ }
+ data << uint32(10 - sGuildFinderMgr->CountRequestsFromPlayer(GetPlayer()->GetGUIDLow())); // Applications count left
+
+ GetPlayer()->SendDirectMessage(&data);
+}
+
+// Lists all recruits for a guild - Misses times
+void WorldSession::HandleGuildFinderGetRecruits(WorldPacket& recvPacket)
+{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_LF_GUILD_GET_RECRUITS");
+
+ uint32 unkTime = 0;
+ recvPacket >> unkTime;
+
+ Player* player = GetPlayer();
+ if (!player->GetGuildId())
+ return;
+
+ std::vector<MembershipRequest> recruitsList = sGuildFinderMgr->GetAllMembershipRequestsForGuild(player->GetGuildId());
+ uint32 recruitCount = recruitsList.size();
+
+ ByteBuffer dataBuffer(53 * recruitCount);
+ WorldPacket data(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED, 7 + 26 * recruitCount + 53 * recruitCount);
+ data.WriteBits(recruitCount, 20);
+
+ for (std::vector<MembershipRequest>::const_iterator itr = recruitsList.begin(); itr != recruitsList.end(); ++itr)
+ {
+ MembershipRequest request = *itr;
+ ObjectGuid playerGuid(MAKE_NEW_GUID(request.GetPlayerGUID(), 0, HIGHGUID_PLAYER));
+
+ data.WriteBits(request.GetComment().size(), 11);
+ data.WriteBit(playerGuid[2]);
+ data.WriteBit(playerGuid[4]);
+ data.WriteBit(playerGuid[3]);
+ data.WriteBit(playerGuid[7]);
+ data.WriteBit(playerGuid[0]);
+ data.WriteBits(request.GetName().size(), 7);
+ data.WriteBit(playerGuid[5]);
+ data.WriteBit(playerGuid[1]);
+ data.WriteBit(playerGuid[6]);
+
+ dataBuffer.WriteByteSeq(playerGuid[4]);
+
+ dataBuffer << int32(time(NULL) <= request.GetExpiryTime());
+
+ dataBuffer.WriteByteSeq(playerGuid[3]);
+ dataBuffer.WriteByteSeq(playerGuid[0]);
+ dataBuffer.WriteByteSeq(playerGuid[1]);
+
+ dataBuffer << int32(request.GetLevel());
+
+ dataBuffer.WriteByteSeq(playerGuid[6]);
+ dataBuffer.WriteByteSeq(playerGuid[7]);
+ dataBuffer.WriteByteSeq(playerGuid[2]);
+
+ dataBuffer << int32(time(NULL) - request.GetSubmitTime()); // Time in seconds since application submitted.
+ dataBuffer << int32(request.GetAvailability());
+ dataBuffer << int32(request.GetClassRoles());
+ dataBuffer << int32(request.GetInterests());
+ dataBuffer << int32(request.GetExpiryTime() - time(NULL)); // TIme in seconds until application expires.
+
+ dataBuffer.WriteString(request.GetName());
+ dataBuffer.WriteString(request.GetComment());
+
+ dataBuffer << int32(request.GetClass());
+
+ dataBuffer.WriteByteSeq(playerGuid[5]);
+ }
+
+ data.FlushBits();
+ data.append(dataBuffer);
+ data << uint32(time(NULL)); // Unk time
+
+ player->SendDirectMessage(&data);
+}
+
+void WorldSession::HandleGuildFinderPostRequest(WorldPacket& /*recvPacket*/)
+{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_LF_GUILD_POST_REQUEST"); // Empty opcode
+
+ Player* player = GetPlayer();
+
+ if (!player->GetGuildId()) // Player must be in guild
+ return;
+
+ bool isGuildMaster = true;
+ if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId()))
+ if (guild->GetLeaderGUID() != player->GetGUID())
+ isGuildMaster = false;
+
+ LFGuildSettings settings = sGuildFinderMgr->GetGuildSettings(player->GetGuildId());
+
+ WorldPacket data(SMSG_LF_GUILD_POST_UPDATED, 35);
+ data.WriteBit(isGuildMaster); // Guessed
+
+ if (isGuildMaster)
+ {
+ data.WriteBit(settings.IsListed());
+ data.WriteBits(settings.GetComment().size(), 11);
+ data << uint32(settings.GetLevel());
+ data.WriteString(settings.GetComment());
+ data << uint32(0); // Unk Int32
+ data << uint32(settings.GetAvailability());
+ data << uint32(settings.GetClassRoles());
+ data << uint32(settings.GetInterests());
+ }
+ else
+ data.FlushBits();
+ player->SendDirectMessage(&data);
+}
+
+void WorldSession::HandleGuildFinderRemoveRecruit(WorldPacket& recvPacket)
+{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_LF_GUILD_REMOVE_RECRUIT");
+
+ ObjectGuid guildGuid;
+
+ guildGuid[0] = recvPacket.ReadBit();
+ guildGuid[4] = recvPacket.ReadBit();
+ guildGuid[3] = recvPacket.ReadBit();
+ guildGuid[5] = recvPacket.ReadBit();
+ guildGuid[7] = recvPacket.ReadBit();
+ guildGuid[6] = recvPacket.ReadBit();
+ guildGuid[2] = recvPacket.ReadBit();
+ guildGuid[1] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guildGuid[4]);
+ recvPacket.ReadByteSeq(guildGuid[0]);
+ recvPacket.ReadByteSeq(guildGuid[3]);
+ recvPacket.ReadByteSeq(guildGuid[6]);
+ recvPacket.ReadByteSeq(guildGuid[5]);
+ recvPacket.ReadByteSeq(guildGuid[1]);
+ recvPacket.ReadByteSeq(guildGuid[2]);
+ recvPacket.ReadByteSeq(guildGuid[7]);
+
+ if (!IS_GUILD_GUID(guildGuid))
+ return;
+
+ sGuildFinderMgr->RemoveMembershipRequest(GetPlayer()->GetGUIDLow(), GUID_LOPART(guildGuid));
+}
+
+// Sent any time a guild master sets an option in the interface and when listing / unlisting his guild
+void WorldSession::HandleGuildFinderSetGuildPost(WorldPacket& recvPacket)
+{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_LF_GUILD_SET_GUILD_POST");
+
+ uint32 classRoles = 0;
+ uint32 availability = 0;
+ uint32 guildInterests = 0;
+ uint32 level = 0;
+
+ recvPacket >> level >> availability >> guildInterests >> classRoles;
+ // Level sent is zero if untouched, force to any (from interface). Idk why
+ if (!level)
+ level = ANY_FINDER_LEVEL;
+
+ uint16 length = recvPacket.ReadBits(11);
+ bool listed = recvPacket.ReadBit();
+ std::string comment = recvPacket.ReadString(length);
+
+ if (!(classRoles & GUILDFINDER_ALL_ROLES) || classRoles > GUILDFINDER_ALL_ROLES)
+ return;
+ if (!(availability & ALL_WEEK) || availability > ALL_WEEK)
+ return;
+ if (!(guildInterests & ALL_INTERESTS) || guildInterests > ALL_INTERESTS)
+ return;
+ if (!(level & ALL_GUILDFINDER_LEVELS) || level > ALL_GUILDFINDER_LEVELS)
+ return;
+
+ Player* player = GetPlayer();
+
+ if (!player->GetGuildId()) // Player must be in guild
+ return;
+
+ if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) // Player must be guild master
+ if (guild->GetLeaderGUID() != player->GetGUID())
+ return;
+
+ LFGuildSettings settings(listed, player->GetTeamId(), player->GetGuildId(), classRoles, availability, guildInterests, level, comment);
+ sGuildFinderMgr->SetGuildSettings(player->GetGuildId(), settings);
+}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 3ed5c0fe7f8..b1ef5bcb704 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -261,7 +261,7 @@ void InitOpcodes()
DEFINE_OPCODE_HANDLER(CMSG_GUILD_DECLINE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDeclineOpcode );
DEFINE_OPCODE_HANDLER(CMSG_GUILD_DEL_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDelRankOpcode );
DEFINE_OPCODE_HANDLER(CMSG_GUILD_DEMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDemoteOpcode );
- DEFINE_OPCODE_HANDLER(CMSG_GUILD_DISBAND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDisbandOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_DISBAND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDisbandOpcode );
DEFINE_OPCODE_HANDLER(CMSG_GUILD_EVENT_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildEventLogQueryOpcode );
DEFINE_OPCODE_HANDLER(CMSG_GUILD_INFO_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildChangeInfoTextOpcode );
DEFINE_OPCODE_HANDLER(CMSG_GUILD_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildInviteOpcode );
@@ -310,14 +310,14 @@ void InitOpcodes()
DEFINE_OPCODE_HANDLER(CMSG_LFG_SET_COMMENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER(CMSG_LFG_SET_ROLES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetRolesOpcode );
DEFINE_OPCODE_HANDLER(CMSG_LFG_TELEPORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgTeleportOpcode );
- DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_ADD_RECRUIT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_BROWSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_DECLINE_RECRUIT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_GET_APPLICATIONS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_GET_RECRUITS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_POST_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_REMOVE_RECRUIT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_SET_GUILD_POST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_ADD_RECRUIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderAddRecruit );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_BROWSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderBrowse );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_DECLINE_RECRUIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderDeclineRecruit );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_GET_APPLICATIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderGetApplications);
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_GET_RECRUITS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderGetRecruits );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_POST_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderPostRequest );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_REMOVE_RECRUIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderRemoveRecruit );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_SET_GUILD_POST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderSetGuildPost );
DEFINE_OPCODE_HANDLER(CMSG_LIST_INVENTORY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleListInventoryOpcode );
DEFINE_OPCODE_HANDLER(CMSG_LOAD_SCREEN, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleLoadScreenOpcode );
DEFINE_OPCODE_HANDLER(CMSG_LOGOUT_CANCEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutCancelOpcode );
@@ -940,13 +940,13 @@ void InitOpcodes()
DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_SEARCH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_STATUS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_STATUS_NONE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICANT_LIST_UPDATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_BROWSE_UPDATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_COMMAND_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_POST_UPDATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICANT_LIST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_BROWSE_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_POST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_LIST_INVENTORY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_LOGIN_SETTIMESPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index b948ce76ca6..a9594fa44a6 100755
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -312,7 +312,6 @@ enum Opcodes
CMSG_LF_GUILD_DECLINE_RECRUIT = 0x1031,
CMSG_LF_GUILD_GET_APPLICATIONS = 0x1230,
CMSG_LF_GUILD_GET_RECRUITS = 0x3230,
- CMSG_LF_GUILD_JOIN = 0x0000,
CMSG_LF_GUILD_POST_REQUEST = 0x3237,
CMSG_LF_GUILD_REMOVE_RECRUIT = 0x3027,
CMSG_LF_GUILD_SET_GUILD_POST = 0x0448,
@@ -1024,7 +1023,6 @@ enum Opcodes
SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED = 0x1CA5,
SMSG_LF_GUILD_POST_UPDATED = 0x35B7,
SMSG_LF_GUILD_RECRUIT_LIST_UPDATED = 0x1CB2,
- SMSG_LF_GUILD_SEARCH_RESULT = 0x0000,
SMSG_LIST_INVENTORY = 0x7CB0,
SMSG_LOAD_CUF_PROFILES = 0x50B1,
SMSG_LOGIN_SETTIMESPEED = 0x4D15,
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index a7ab19f393a..1db1399e45f 100755
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -245,7 +245,7 @@ class WorldSession
bool IsAddonRegistered(const std::string& prefix) const;
void ReadMovementInfo(WorldPacket& data, MovementInfo* mi);
- void WriteMovementInfo(WorldPacket &data, MovementInfo* mi);
+ void WriteMovementInfo(WorldPacket& data, MovementInfo* mi);
void SendPacket(WorldPacket const* packet, bool forced = false);
void SendNotification(const char *format, ...) ATTR_PRINTF(2, 3);
@@ -597,6 +597,15 @@ class WorldSession
void HandleGuildRequestMaxDailyXP(WorldPacket& recvPacket);
void HandleAutoDeclineGuildInvites(WorldPacket& recvPacket);
+ void HandleGuildFinderAddRecruit(WorldPacket& recvPacket);
+ void HandleGuildFinderBrowse(WorldPacket& recvPacket);
+ void HandleGuildFinderDeclineRecruit(WorldPacket& recvPacket);
+ void HandleGuildFinderGetApplications(WorldPacket& recvPacket);
+ void HandleGuildFinderGetRecruits(WorldPacket& recvPacket);
+ void HandleGuildFinderPostRequest(WorldPacket& recvPacket);
+ void HandleGuildFinderRemoveRecruit(WorldPacket& recvPacket);
+ void HandleGuildFinderSetGuildPost(WorldPacket& recvPacket);
+
void HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvPacket);
void HandleTaxiQueryAvailableNodes(WorldPacket& recvPacket);
void HandleActivateTaxiOpcode(WorldPacket& recvPacket);
diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp
index ae05cb4e8eb..86cc42fba42 100644
--- a/src/server/game/Tools/PlayerDump.cpp
+++ b/src/server/game/Tools/PlayerDump.cpp
@@ -462,6 +462,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
uint8 gender = GENDER_NONE;
uint8 race = RACE_NONE;
uint8 playerClass = 0;
+ uint8 level = 1;
SQLTransaction trans = CharacterDatabase.BeginTransaction();
while (!feof(fin))
@@ -536,6 +537,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
race = uint8(atol(getnth(line, 4).c_str()));
playerClass = uint8(atol(getnth(line, 5).c_str()));
gender = uint8(atol(getnth(line, 6).c_str()));
+ level = uint8(atol(getnth(line, 7).c_str()));
if (name == "")
{
// check if the original name already exists
@@ -679,7 +681,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
CharacterDatabase.CommitTransaction(trans);
// in case of name conflict player has to rename at login anyway
- sWorld->AddCharacterNameData(guid, name, gender, race, playerClass);
+ sWorld->AddCharacterNameData(guid, name, gender, race, playerClass, level);
sObjectMgr->_hiItemGuid += items.size();
sObjectMgr->_mailId += mails.size();
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 92dd103f79d..204e90053ad 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -39,6 +39,7 @@
#include "ObjectMgr.h"
#include "ArenaTeamMgr.h"
#include "GuildMgr.h"
+#include "GuildFinderMgr.h"
#include "TicketMgr.h"
#include "SpellMgr.h"
#include "GroupMgr.h"
@@ -1572,6 +1573,8 @@ void World::SetInitialWorldSettings()
sGuildMgr->LoadGuilds();
+ sGuildFinderMgr->LoadFromDB();
+
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading ArenaTeams...");
sArenaTeamMgr->LoadArenaTeams();
@@ -2955,7 +2958,7 @@ void World::LoadCharacterNameData()
{
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading character name data");
- QueryResult result = CharacterDatabase.Query("SELECT guid, name, race, gender, class FROM characters WHERE deleteDate IS NULL");
+ QueryResult result = CharacterDatabase.Query("SELECT guid, name, race, gender, class, level FROM characters WHERE deleteDate IS NULL");
if (!result)
{
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "No character name data loaded, empty query");
@@ -2968,20 +2971,21 @@ void World::LoadCharacterNameData()
{
Field* fields = result->Fetch();
AddCharacterNameData(fields[0].GetUInt32(), fields[1].GetString(),
- fields[3].GetUInt8() /*gender*/, fields[2].GetUInt8() /*race*/, fields[4].GetUInt8() /*class*/);
+ fields[3].GetUInt8() /*gender*/, fields[2].GetUInt8() /*race*/, fields[4].GetUInt8() /*class*/, fields[5].GetUInt8());
++count;
} while (result->NextRow());
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loaded name data for %u characters", count);
}
-void World::AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass)
+void World::AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass, uint8 level)
{
CharacterNameData& data = _characterNameDataMap[guid];
data.m_name = name;
data.m_race = race;
data.m_gender = gender;
data.m_class = playerClass;
+ data.m_level = level;
}
void World::UpdateCharacterNameData(uint32 guid, std::string const& name, uint8 gender /*= GENDER_NONE*/, uint8 race /*= RACE_NONE*/)
@@ -2999,6 +3003,15 @@ void World::UpdateCharacterNameData(uint32 guid, std::string const& name, uint8
itr->second.m_race = race;
}
+void World::UpdateCharacterNameDataLevel(uint32 guid, uint8 level)
+{
+ std::map<uint32, CharacterNameData>::iterator itr = _characterNameDataMap.find(guid);
+ if (itr == _characterNameDataMap.end())
+ return;
+
+ itr->second.m_level = level;
+}
+
CharacterNameData const* World::GetCharacterNameData(uint32 guid) const
{
std::map<uint32, CharacterNameData>::const_iterator itr = _characterNameDataMap.find(guid);
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index f0f5e3f723b..b8243cb0531 100755
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -555,6 +555,7 @@ struct CharacterNameData
uint8 m_class;
uint8 m_race;
uint8 m_gender;
+ uint8 m_level;
};
/// The World
@@ -776,9 +777,10 @@ class World
bool isEventKillStart;
CharacterNameData const* GetCharacterNameData(uint32 guid) const;
- void AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass);
+ void AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass, uint8 level);
void UpdateCharacterNameData(uint32 guid, std::string const& name, uint8 gender = GENDER_NONE, uint8 race = RACE_NONE);
- void DeleteCharaceterNameData(uint32 guid) { _characterNameDataMap.erase(guid); }
+ void UpdateCharacterNameDataLevel(uint32 guid, uint8 level);
+ void DeleteCharacterNameData(uint32 guid) { _characterNameDataMap.erase(guid); }
uint32 GetCleaningFlags() const { return m_CleaningFlags; }
void SetCleaningFlags(uint32 flags) { m_CleaningFlags = flags; }
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index 87948391500..9f910cbaf75 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -224,7 +224,7 @@ public:
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME_DATA);
stmt->setUInt32(0, delInfo.lowGuid);
if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
- sWorld->AddCharacterNameData(delInfo.lowGuid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8());
+ sWorld->AddCharacterNameData(delInfo.lowGuid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8(), (*result)[2].GetUInt8());
}
static void HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel, ChatHandler* handler)
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index 3d848f94c00..a335d8bc4fe 100755..100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -49,7 +49,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_SEL_CHAR_RACE, "SELECT race FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PREPARE_STATEMENT(CHAR_SEL_CHAR_LEVEL, "SELECT level FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PREPARE_STATEMENT(CHAR_SEL_CHAR_ZONE, "SELECT zone FROM characters WHERE guid = ?", CONNECTION_SYNCH);
- PREPARE_STATEMENT(CHAR_SEL_CHARACTER_NAME_DATA, "SELECT race, class, gender FROM characters WHERE guid = ?", CONNECTION_SYNCH);
+ PREPARE_STATEMENT(CHAR_SEL_CHARACTER_NAME_DATA, "SELECT race, class, gender, level FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PREPARE_STATEMENT(CHAR_SEL_CHAR_POSITION_XYZ, "SELECT map, position_x, position_y, position_z FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PREPARE_STATEMENT(CHAR_SEL_CHAR_POSITION, "SELECT position_x, position_y, position_z, orientation, map, taxi_path FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_DAILY, "DELETE FROM character_queststatus_daily", CONNECTION_ASYNC);
@@ -580,4 +580,10 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_SEL_CHAR_CUF_PROFILES, "SELECT id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154 FROM character_cuf_profiles WHERE guid = ?", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_REP_CHAR_CUF_PROFILES, "REPLACE INTO character_cuf_profiles (guid, id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_DEL_CHAR_CUF_PROFILES, "DELETE FROM character_cuf_profiles WHERE guid = ? and id = ?", CONNECTION_ASYNC);
+
+ // Guild Finder
+ PREPARE_STATEMENT(CHAR_REP_GUILD_FINDER_APPLICANT, "REPLACE INTO guild_finder_applicant (guildId, playerGuid, availability, classRole, interests, comment, submitTime) VALUES(?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_GUILD_FINDER_APPLICANT, "DELETE FROM guild_finder_applicant WHERE guildId = ? AND playerGuid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_REP_GUILD_FINDER_GUILD_SETTINGS, "REPLACE INTO guild_finder_guild_settings (guildId, availability, classRoles, interests, level, listed, comment) VALUES(?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_GUILD_FINDER_GUILD_SETTINGS, "DELETE FROM guild_finder_guild_settings WHERE guildId = ?", CONNECTION_ASYNC);
}
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 20454798f98..93bcb1d70ab 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -541,6 +541,11 @@ enum CharacterDatabaseStatements
CHAR_REP_CHAR_CUF_PROFILES,
CHAR_DEL_CHAR_CUF_PROFILES,
+ CHAR_REP_GUILD_FINDER_APPLICANT,
+ CHAR_DEL_GUILD_FINDER_APPLICANT,
+ CHAR_REP_GUILD_FINDER_GUILD_SETTINGS,
+ CHAR_DEL_GUILD_FINDER_GUILD_SETTINGS,
+
MAX_CHARACTERDATABASE_STATEMENTS,
};