aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game')
-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
14 files changed, 1113 insertions, 27 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; }