diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c1e4a0b2b..e664c21a3 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5524,7 +5524,7 @@ void Player::SendMessageToSetInRange_OwnTeam(WorldPacket* data, float dist, bool Cell::VisitWorldObjects(this, notifier, dist); } -void Player::SendDirectMessage(WorldPacket* data) +void Player::SendDirectMessage(WorldPacket const* data) const { m_session->SendPacket(data); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 690983189..6d00af4ae 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2175,7 +2175,7 @@ public: void SendInitWorldStates(uint32 zone, uint32 area); void SendUpdateWorldState(uint32 Field, uint32 Value); - void SendDirectMessage(WorldPacket* data); + void SendDirectMessage(WorldPacket const* data) const; void SendBGWeekendWorldStates(); void SendBattlefieldWorldStates(); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 4d255c522..63fd918d9 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -7649,7 +7649,7 @@ void ObjectMgr::LoadReservedPlayersNames() LOG_INFO("server.loading", " "); } -bool ObjectMgr::IsReservedName(const std::string& name) const +bool ObjectMgr::IsReservedName(std::string_view name) const { // pussywizard if (name.size() >= 2 && (name[name.size() - 2] == 'G' || name[name.size() - 2] == 'g') && (name[name.size() - 1] == 'M' || name[name.size() - 1] == 'm')) @@ -7757,7 +7757,7 @@ bool isValidString(std::wstring wstr, uint32 strictMask, bool numericOrSpace, bo return false; } -uint8 ObjectMgr::CheckPlayerName(const std::string& name, bool create) +uint8 ObjectMgr::CheckPlayerName(std::string_view name, bool create) { std::wstring wname; if (!Utf8toWStr(name, wname)) @@ -7782,7 +7782,7 @@ uint8 ObjectMgr::CheckPlayerName(const std::string& name, bool create) return CHAR_NAME_SUCCESS; } -bool ObjectMgr::IsValidCharterName(const std::string& name) +bool ObjectMgr::IsValidCharterName(std::string_view name) { std::wstring wname; if (!Utf8toWStr(name, wname)) @@ -7814,7 +7814,7 @@ bool ObjectMgr::IsValidChannelName(const std::string& name) return isValidString(wname, strictMask, true); } -PetNameInvalidReason ObjectMgr::CheckPetName(const std::string& name) +PetNameInvalidReason ObjectMgr::CheckPetName(std::string_view name) { std::wstring wname; if (!Utf8toWStr(name, wname)) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 7b5cde498..9f2c71927 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1266,13 +1266,13 @@ public: // reserved names void LoadReservedPlayersNames(); - [[nodiscard]] bool IsReservedName(std::string const& name) const; + [[nodiscard]] bool IsReservedName(std::string_view name) const; void AddReservedPlayerName(std::string const& name); // name with valid structure and symbols - static uint8 CheckPlayerName(std::string const& name, bool create = false); - static PetNameInvalidReason CheckPetName(std::string const& name); - static bool IsValidCharterName(std::string const& name); + static uint8 CheckPlayerName(std::string_view name, bool create = false); + static PetNameInvalidReason CheckPetName(std::string_view name); + static bool IsValidCharterName(std::string_view name); static bool IsValidChannelName(std::string const& name); static bool CheckDeclinedNames(std::wstring w_ownname, DeclinedName const& names); diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index d8729f9a8..47e7d01db 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -16,17 +16,26 @@ */ #include "Guild.h" +#include "AccountMgr.h" +#include "Bag.h" #include "CalendarMgr.h" #include "CharacterCache.h" #include "Chat.h" #include "Config.h" #include "DatabaseEnv.h" #include "GuildMgr.h" +#include "GuildPackets.h" #include "Language.h" #include "Log.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "Opcodes.h" +#include "Player.h" #include "ScriptMgr.h" #include "SocialMgr.h" +#include "World.h" +#include "WorldSession.h" +#include #define MAX_GUILD_BANK_TAB_TEXT_LEN 500 #define EMBLEM_PRICE 10 * GOLD @@ -102,68 +111,56 @@ inline uint32 _GetGuildBankTabPrice(uint8 tabId) } } -void Guild::SendCommandResult(WorldSession* session, GuildCommandType type, GuildCommandError errCode, std::string const& param) +void Guild::SendCommandResult(WorldSession* session, GuildCommandType type, GuildCommandError errCode, std::string_view param) { - WorldPacket data(SMSG_GUILD_COMMAND_RESULT, 8 + param.size() + 1); - data << uint32(type); - data << param; - data << uint32(errCode); - session->SendPacket(&data); + WorldPackets::Guild::GuildCommandResult resultPacket; + resultPacket.Command = type; + resultPacket.Result = errCode; + resultPacket.Name = param; + session->SendPacket(resultPacket.Write()); - LOG_DEBUG("guild", "SMSG_GUILD_COMMAND_RESULT [%s]: Type: %u, code: %u, param: %s", session->GetPlayerInfo().c_str(), type, errCode, param.c_str()); + LOG_DEBUG("guild", "SMSG_GUILD_COMMAND_RESULT [%s]: Type: %u, code: %u, param: %s", session->GetPlayerInfo().c_str(), type, errCode, resultPacket.Name.c_str()); } void Guild::SendSaveEmblemResult(WorldSession* session, GuildEmblemError errCode) { - WorldPacket data(MSG_SAVE_GUILD_EMBLEM, 4); - data << uint32(errCode); - session->SendPacket(&data); + WorldPackets::Guild::PlayerSaveGuildEmblem saveResponse; + saveResponse.Error = int32(errCode); + session->SendPacket(saveResponse.Write()); LOG_DEBUG("guild", "MSG_SAVE_GUILD_EMBLEM [%s] Code: %u", session->GetPlayerInfo().c_str(), errCode); } // LogHolder -Guild::LogHolder::~LogHolder() -{ - // Cleanup - for (GuildLog::iterator itr = m_log.begin(); itr != m_log.end(); ++itr) - delete (*itr); -} +template +Guild::LogHolder::LogHolder() + : m_maxRecords(sWorld->getIntConfig(std::is_same_v ? CONFIG_GUILD_BANK_EVENT_LOG_COUNT : CONFIG_GUILD_EVENT_LOG_COUNT)), m_nextGUID(uint32(GUILD_EVENT_LOG_GUID_UNDEFINED)) +{ } -// Adds event loaded from database to collection -inline void Guild::LogHolder::LoadEvent(LogEntry* entry) +template template +void Guild::LogHolder::LoadEvent(Ts&&... args) { + Entry const& newEntry = m_log.emplace_front(std::forward(args)...); if (m_nextGUID == uint32(GUILD_EVENT_LOG_GUID_UNDEFINED)) - m_nextGUID = entry->GetGUID(); - m_log.push_front(entry); + m_nextGUID = newEntry.GetGUID(); } -// Adds new event happened in game. -// If maximum number of events is reached, oldest event is removed from collection. -inline void Guild::LogHolder::AddEvent(CharacterDatabaseTransaction trans, LogEntry* entry) +template template +void Guild::LogHolder::AddEvent(CharacterDatabaseTransaction trans, Ts&&... args) { // Check max records limit - if (m_log.size() >= m_maxRecords) + if (!CanInsert()) { - LogEntry* oldEntry = m_log.front(); - delete oldEntry; m_log.pop_front(); } // Add event to list - m_log.push_back(entry); + Entry const& entry = m_log.emplace_back(std::forward(args)...); // Save to DB - entry->SaveToDB(trans); + entry.SaveToDB(trans); } -// Writes information about all events into packet. -inline void Guild::LogHolder::WritePacket(WorldPacket& data) const -{ - data << uint8(m_log.size()); - for (GuildLog::const_iterator itr = m_log.begin(); itr != m_log.end(); ++itr) - (*itr)->WritePacket(data); -} - -inline uint32 Guild::LogHolder::GetNextGUID() +template +inline uint32 Guild::LogHolder::GetNextGUID() { // Next guid was not initialized. It means there are no records for this holder in DB yet. // Start from the beginning. @@ -195,20 +192,18 @@ void Guild::EventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) const CharacterDatabase.ExecuteOrAppend(trans, stmt); } -void Guild::EventLogEntry::WritePacket(WorldPacket& data) const +void Guild::EventLogEntry::WritePacket(WorldPackets::Guild::GuildEventLogQueryResults& packet) const { - // Event type - data << uint8(m_eventType); - // Player 1 - data << m_playerGuid1; - // Player 2 not for left/join guild events - if (m_eventType != GUILD_EVENT_LOG_JOIN_GUILD && m_eventType != GUILD_EVENT_LOG_LEAVE_GUILD) - data << m_playerGuid2; - // New Rank - only for promote/demote guild events - if (m_eventType == GUILD_EVENT_LOG_PROMOTE_PLAYER || m_eventType == GUILD_EVENT_LOG_DEMOTE_PLAYER) - data << uint8(m_newRank); - // Event timestamp - data << uint32(::time(nullptr) - m_timestamp); + ObjectGuid playerGUID = ObjectGuid::Create(m_playerGuid1.GetCounter()); + ObjectGuid otherGUID = ObjectGuid::Create(m_playerGuid2.GetCounter()); + + WorldPackets::Guild::GuildEventEntry eventEntry; + eventEntry.PlayerGUID = playerGUID; + eventEntry.OtherGUID = otherGUID; + eventEntry.TransactionType = uint8(m_eventType); + eventEntry.TransactionDate = uint32(::time(nullptr) - m_timestamp); + eventEntry.RankID = uint8(m_newRank); + packet.Entry.push_back(eventEntry); } // BankEventLogEntry @@ -236,29 +231,31 @@ void Guild::BankEventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) cons CharacterDatabase.ExecuteOrAppend(trans, stmt); } -void Guild::BankEventLogEntry::WritePacket(WorldPacket& data) const +void Guild::BankEventLogEntry::WritePacket(WorldPackets::Guild::GuildBankLogQueryResults& packet) const { - data << uint8(m_eventType); - data << m_playerGuid; + WorldPackets::Guild::GuildBankLogEntry bankLogEntry; + bankLogEntry.PlayerGUID = ObjectGuid::Create(m_playerGuid.GetCounter()); + bankLogEntry.TimeOffset = int32(::time(nullptr) - m_timestamp); + bankLogEntry.EntryType = int8(m_eventType); switch(m_eventType) { case GUILD_BANK_LOG_DEPOSIT_ITEM: case GUILD_BANK_LOG_WITHDRAW_ITEM: - data << uint32(m_itemOrMoney); - data << uint32(m_itemStackCount); + bankLogEntry.ItemID = int32(m_itemOrMoney); + bankLogEntry.Count = int32(m_itemStackCount); break; case GUILD_BANK_LOG_MOVE_ITEM: case GUILD_BANK_LOG_MOVE_ITEM2: - data << uint32(m_itemOrMoney); - data << uint32(m_itemStackCount); - data << uint8(m_destTabId); + bankLogEntry.ItemID = int32(m_itemOrMoney); + bankLogEntry.Count = int32(m_itemStackCount); + bankLogEntry.OtherTab = int8(m_destTabId); break; default: - data << uint32(m_itemOrMoney); + bankLogEntry.Money = uint32(m_itemOrMoney); } - data << uint32(time(nullptr) - m_timestamp); + packet.Entry.push_back(bankLogEntry); } // RankInfo @@ -308,21 +305,7 @@ void Guild::RankInfo::CreateMissingTabsIfNeeded(uint8 tabs, CharacterDatabaseTra } } -void Guild::RankInfo::WritePacket(WorldPacket& data) const -{ - data << uint32(m_rights); - if (m_bankMoneyPerDay == GUILD_WITHDRAW_MONEY_UNLIMITED) - data << uint32(GUILD_WITHDRAW_MONEY_UNLIMITED); - else - data << uint32(m_bankMoneyPerDay); - for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; ++i) - { - data << uint32(m_bankTabRightsAndSlots[i].GetRights()); - data << uint32(m_bankTabRightsAndSlots[i].GetSlots()); - } -} - -void Guild::RankInfo::SetName(std::string const& name) +void Guild::RankInfo::SetName(std::string_view name) { if (m_name == name) return; @@ -450,66 +433,9 @@ void Guild::BankTab::Delete(CharacterDatabaseTransaction trans, bool removeItems } } -inline void Guild::BankTab::WritePacket(WorldPacket& data) const +void Guild::BankTab::SetInfo(std::string_view name, std::string_view icon) { - uint8 count = 0; - - size_t pos = data.wpos(); - data << uint8(0); - - for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId) - if (WriteSlotPacket(data, slotId)) - ++count; - - data.put(pos, count); -} - -// Writes information about contents of specified slot into packet. -bool Guild::BankTab::WriteSlotPacket(WorldPacket& data, uint8 slotId, bool ignoreEmpty /* = true */) const -{ - Item* pItem = GetItem(slotId); - uint32 itemEntry = pItem ? pItem->GetEntry() : 0; - - if (!itemEntry && ignoreEmpty) - return false; - - data << uint8(slotId); - data << uint32(itemEntry); - if (itemEntry) - { - data << uint32(0); // 3.3.0 (0x00018020, 0x00018000) - - if (int32 random = pItem->GetItemRandomPropertyId()) - { - data << int32(random); // Random item property id - data << uint32(pItem->GetItemSuffixFactor()); // SuffixFactor - } - else - data << int32(0); - - data << uint32(pItem->GetCount()); // ITEM_FIELD_STACK_COUNT - data << uint32(0); - data << uint8(abs(pItem->GetSpellCharges())); // Spell charges - - uint8 enchCount = 0; - size_t enchCountPos = data.wpos(); - - data << uint8(enchCount); // Number of enchantments - for (uint32 i = PERM_ENCHANTMENT_SLOT; i < MAX_ENCHANTMENT_SLOT; ++i) - if (uint32 enchId = pItem->GetEnchantmentId(EnchantmentSlot(i))) - { - data << uint8(i); - data << uint32(enchId); - ++enchCount; - } - data.put(enchCountPos, enchCount); - } - return true; -} - -void Guild::BankTab::SetInfo(std::string const& name, std::string const& icon) -{ - if (m_name == name && m_icon == icon) + if ((m_name == name) && (m_icon == icon)) return; m_name = name; @@ -523,7 +449,7 @@ void Guild::BankTab::SetInfo(std::string const& name, std::string const& icon) CharacterDatabase.Execute(stmt); } -void Guild::BankTab::SetText(std::string const& text) +void Guild::BankTab::SetText(std::string_view text) { if (m_text == text) return; @@ -572,20 +498,20 @@ bool Guild::BankTab::SetItem(CharacterDatabaseTransaction trans, uint8 slotId, I void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const { - WorldPacket data(MSG_QUERY_GUILD_BANK_TEXT, 1 + m_text.size() + 1); - data << uint8(m_tabId); - data << m_text; + WorldPackets::Guild::GuildBankTextQueryResult textQuery; + textQuery.Tab = m_tabId; + textQuery.Text = m_text; if (session) { LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [%s]: Tabid: %u, Text: %s" , session->GetPlayerInfo().c_str(), m_tabId, m_text.c_str()); - session->SendPacket(&data); + session->SendPacket(textQuery.Write()); } else { LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [Broadcast]: Tabid: %u, Text: %s", m_tabId, m_text.c_str()); - guild->BroadcastPacket(&data); + guild->BroadcastPacket(textQuery.Write()); } } @@ -600,7 +526,7 @@ void Guild::Member::SetStats(Player* player) m_accountId = player->GetSession()->GetAccountId(); } -void Guild::Member::SetStats(std::string const& name, uint8 level, uint8 _class, uint8 gender, uint32 zoneId, uint32 accountId) +void Guild::Member::SetStats(std::string_view name, uint8 level, uint8 _class, uint8 gender, uint32 zoneId, uint32 accountId) { m_name = name; m_level = level; @@ -610,7 +536,7 @@ void Guild::Member::SetStats(std::string const& name, uint8 level, uint8 _class, m_accountId = accountId; } -void Guild::Member::SetPublicNote(std::string const& publicNote) +void Guild::Member::SetPublicNote(std::string_view publicNote) { if (m_publicNote == publicNote) return; @@ -618,12 +544,12 @@ void Guild::Member::SetPublicNote(std::string const& publicNote) m_publicNote = publicNote; CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_MEMBER_PNOTE); - stmt->setString(0, publicNote); + stmt->setString(0, m_publicNote); stmt->setUInt32(1, m_guid.GetCounter()); CharacterDatabase.Execute(stmt); } -void Guild::Member::SetOfficerNote(std::string const& officerNote) +void Guild::Member::SetOfficerNote(std::string_view officerNote) { if (m_officerNote == officerNote) return; @@ -631,7 +557,7 @@ void Guild::Member::SetOfficerNote(std::string const& officerNote) m_officerNote = officerNote; CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_MEMBER_OFFNOTE); - stmt->setString(0, officerNote); + stmt->setString(0, m_officerNote); stmt->setUInt32(1, m_guid.GetCounter()); CharacterDatabase.Execute(stmt); } @@ -709,28 +635,6 @@ bool Guild::Member::CheckStats() const return true; } -void Guild::Member::WritePacket(WorldPacket& data, bool sendOfficerNote) const -{ - data << m_guid - << uint8(m_flags) - << m_name - << uint32(m_rankId) - << uint8(m_level) - << uint8(m_class) - << uint8(m_gender) - << uint32(m_zoneId); - - if (!m_flags) - data << float(float(::time(nullptr) - m_logoutTime) / DAY); - - data << m_publicNote; - - if (sendOfficerNote) - data << m_officerNote; - else - data << ""; -} - // Decreases amount of money/slots left for today. // If (tabId == GUILD_BANK_MAX_TABS) decrease money amount. // Otherwise decrease remaining items amount for specified tab. @@ -768,9 +672,13 @@ int32 Guild::Member::GetBankWithdrawValue(uint8 tabId) const } // EmblemInfo -void EmblemInfo::ReadPacket(WorldPacket& recv) +void EmblemInfo::ReadPacket(WorldPackets::Guild::SaveGuildEmblem& packet) { - recv >> m_style >> m_color >> m_borderStyle >> m_borderColor >> m_backgroundColor; + m_style = packet.EStyle; + m_color = packet.EColor; + m_borderStyle = packet.BStyle; + m_borderColor = packet.BColor; + m_backgroundColor = packet.Bg; } void EmblemInfo::LoadFromDB(Field* fields) @@ -782,15 +690,6 @@ void EmblemInfo::LoadFromDB(Field* fields) m_backgroundColor = fields[7].GetUInt8(); } -void EmblemInfo::WritePacket(WorldPacket& data) const -{ - data << uint32(m_style); - data << uint32(m_color); - data << uint32(m_borderStyle); - data << uint32(m_borderColor); - data << uint32(m_backgroundColor); -} - void EmblemInfo::SaveToDB(uint32 guildId) const { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_EMBLEM_INFO); @@ -934,7 +833,7 @@ bool Guild::BankMoveItemData::HasWithdrawRights(MoveItemData* pOther) const int32 slots = 0; if (Member const* member = m_pGuild->GetMember(m_pPlayer->GetGUID())) - slots = m_pGuild->_GetMemberRemainingSlots(member, m_container); + slots = m_pGuild->_GetMemberRemainingSlots(*member, m_container); return slots != 0; } @@ -1124,36 +1023,18 @@ Guild::Guild(): m_id(0), m_createdDate(0), m_accountsNumber(0), - m_bankMoney(0), - m_eventLog(nullptr) + m_bankMoney(0) { - memset(&m_bankEventLog, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(LogHolder*)); } Guild::~Guild() { CharacterDatabaseTransaction temp(nullptr); _DeleteBankItems(temp); - - // Cleanup - delete m_eventLog; - m_eventLog = nullptr; - - for (uint8 tabId = 0; tabId <= GUILD_BANK_MAX_TABS; ++tabId) - { - delete m_bankEventLog[tabId]; - m_bankEventLog[tabId] = nullptr; - } - - for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - { - delete itr->second; - itr->second = nullptr; - } } // Creates new guild with default data and saves it to database. -bool Guild::Create(Player* pLeader, std::string const& name) +bool Guild::Create(Player* pLeader, std::string_view name) { // Check if guild with such name already exists if (sGuildMgr->GetGuildByName(name)) @@ -1170,10 +1051,9 @@ bool Guild::Create(Player* pLeader, std::string const& name) m_motd = "No message set."; m_bankMoney = 0; m_createdDate = sWorld->GetGameTime(); - _CreateLogHolders(); LOG_DEBUG("guild", "GUILD: creating guild [%s] for leader %s (%s)", - name.c_str(), pLeader->GetName().c_str(), m_leaderGuid.ToString().c_str()); + m_name.c_str(), pLeader->GetName().c_str(), m_leaderGuid.ToString().c_str()); CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); @@ -1184,7 +1064,7 @@ bool Guild::Create(Player* pLeader, std::string const& name) uint8 index = 0; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD); stmt->setUInt32( index, m_id); - stmt->setString(++index, name); + stmt->setString(++index, m_name); stmt->setUInt32(++index, m_leaderGuid.GetCounter()); stmt->setString(++index, m_info); stmt->setString(++index, m_motd); @@ -1207,7 +1087,7 @@ bool Guild::Create(Player* pLeader, std::string const& name) } if (ret) - sScriptMgr->OnGuildCreate(this, pLeader, name); + sScriptMgr->OnGuildCreate(this, pLeader, m_name); return ret; } @@ -1222,8 +1102,8 @@ void Guild::Disband() // Remove all members while (!m_members.empty()) { - Members::const_iterator itr = m_members.begin(); - DeleteMember(itr->second->GetGUID(), true); + auto itr = m_members.begin(); + DeleteMember(itr->second.GetGUID(), true); } CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); @@ -1295,46 +1175,72 @@ void Guild::OnPlayerStatusChange(Player* player, uint32 flag, bool state) void Guild::HandleRoster(WorldSession* session) { - // Guess size - WorldPacket data(SMSG_GUILD_ROSTER, (4 + m_motd.length() + 1 + m_info.length() + 1 + 4 + _GetRanksSize() * (4 + 4 + GUILD_BANK_MAX_TABS * (4 + 4)) + m_members.size() * 50)); - data << uint32(m_members.size()); - data << m_motd; - data << m_info; + WorldPackets::Guild::GuildRoster roster; - data << uint32(_GetRanksSize()); - for (Ranks::const_iterator ritr = m_ranks.begin(); ritr != m_ranks.end(); ++ritr) - ritr->WritePacket(data); + for (RankInfo const& rank : m_ranks) + { + WorldPackets::Guild::GuildRankData& rankData = roster.RankData.emplace_back(); - for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - itr->second->WritePacket(data, _HasRankRight(session->GetPlayer(), GR_RIGHT_VIEWOFFNOTE)); + rankData.Flags = rank.GetRights(); + rankData.WithdrawGoldLimit = rank.GetBankMoneyPerDay(); + for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; ++i) + { + rankData.TabFlags[i] = rank.GetBankTabRights(i); + rankData.TabWithdrawItemLimit[i] = rank.GetBankTabSlotsPerDay(i); + } + } + + bool sendOfficerNote = _HasRankRight(session->GetPlayer(), GR_RIGHT_VIEWOFFNOTE); + for (auto const& [guid, member] : m_members) + { + WorldPackets::Guild::GuildRosterMemberData& memberData = roster.MemberData.emplace_back(); + + memberData.Guid = member.GetGUID(); + memberData.RankID = int32(member.GetRankId()); + memberData.AreaID = int32(member.GetZoneId()); + memberData.LastSave = float(float(::time(nullptr) - member.GetLogoutTime()) / DAY); + + memberData.Status = member.GetFlags(); + memberData.Level = member.GetLevel(); + memberData.ClassID = member.GetClass(); + memberData.Gender = member.GetGender(); + + memberData.Name = member.GetName(); + memberData.Note = member.GetPublicNote(); + if (sendOfficerNote) + memberData.OfficerNote = member.GetOfficerNote(); + } + + roster.WelcomeText = m_motd; + roster.InfoText = m_info; LOG_DEBUG("guild", "SMSG_GUILD_ROSTER [%s]", session->GetPlayerInfo().c_str()); - session->SendPacket(&data); + session->SendPacket(roster.Write()); } void Guild::HandleQuery(WorldSession* session) { - WorldPacket data(SMSG_GUILD_QUERY_RESPONSE, 8 * 32 + 200); // Guess size - data << uint32(m_id); - data << m_name; + WorldPackets::Guild::QueryGuildInfoResponse response; + response.GuildId = m_id; - // Rank name - for (uint8 i = 0; i < GUILD_RANKS_MAX_COUNT; ++i) // Always show 10 ranks - { - if (i < _GetRanksSize()) - data << m_ranks[i].GetName(); - else - data << uint8(0); // Empty string - } + response.Info.EmblemStyle = m_emblemInfo.GetStyle(); + response.Info.EmblemColor = m_emblemInfo.GetColor(); + response.Info.BorderStyle = m_emblemInfo.GetBorderStyle(); + response.Info.BorderColor = m_emblemInfo.GetBorderColor(); + response.Info.BackgroundColor = m_emblemInfo.GetBackgroundColor(); - m_emblemInfo.WritePacket(data); - data << uint32(_GetRanksSize()); // Number of ranks used + for (uint8 i = 0; i < _GetRanksSize(); ++i) + response.Info.Ranks[i] = m_ranks[i].GetName(); - session->SendPacket(&data); + response.Info.RankCount = _GetRanksSize(); + + response.Info.GuildName = m_name; + + session->SendPacket(response.Write()); LOG_DEBUG("guild", "SMSG_GUILD_QUERY_RESPONSE [%s]", session->GetPlayerInfo().c_str()); } -void Guild::HandleSetMOTD(WorldSession* session, std::string const& motd) +void Guild::HandleSetMOTD(WorldSession* session, std::string_view motd) { if (m_motd == motd) return; @@ -1346,18 +1252,18 @@ void Guild::HandleSetMOTD(WorldSession* session, std::string const& motd) { m_motd = motd; - sScriptMgr->OnGuildMOTDChanged(this, motd); + sScriptMgr->OnGuildMOTDChanged(this, m_motd); CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_MOTD); - stmt->setString(0, motd); + stmt->setString(0, m_motd); stmt->setUInt32(1, m_id); CharacterDatabase.Execute(stmt); - _BroadcastEvent(GE_MOTD, ObjectGuid::Empty, motd.c_str()); + _BroadcastEvent(GE_MOTD, ObjectGuid::Empty, m_motd); } } -void Guild::HandleSetInfo(WorldSession* session, std::string const& info) +void Guild::HandleSetInfo(WorldSession* session, std::string_view info) { if (m_info == info) return; @@ -1367,10 +1273,10 @@ void Guild::HandleSetInfo(WorldSession* session, std::string const& info) { m_info = info; - sScriptMgr->OnGuildInfoChanged(this, info); + sScriptMgr->OnGuildInfoChanged(this, m_info); CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_INFO); - stmt->setString(0, info); + stmt->setString(0, m_info); stmt->setUInt32(1, m_id); CharacterDatabase.Execute(stmt); } @@ -1396,7 +1302,7 @@ void Guild::HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo) } } -void Guild::HandleSetLeader(WorldSession* session, std::string const& name) +void Guild::HandleSetLeader(WorldSession* session, std::string_view name) { Player* player = session->GetPlayer(); // Only leader can assign new leader @@ -1408,14 +1314,14 @@ void Guild::HandleSetLeader(WorldSession* session, std::string const& name) // New leader must be a member of guild if (Member* pNewLeader = GetMember(name)) { - _SetLeaderGUID(pNewLeader); + _SetLeaderGUID(*pNewLeader); pOldLeader->ChangeRank(GR_OFFICER); - _BroadcastEvent(GE_LEADER_CHANGED, ObjectGuid::Empty, player->GetName().c_str(), name.c_str()); + _BroadcastEvent(GE_LEADER_CHANGED, ObjectGuid::Empty, player->GetName(), pNewLeader->GetName()); } } } -void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string const& name, std::string const& icon) +void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string_view name, std::string_view icon) { BankTab* tab = GetBankTab(tabId); if (!tab) @@ -1426,10 +1332,10 @@ void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string } tab->SetInfo(name, icon); - _BroadcastEvent(GE_BANK_TAB_UPDATED, ObjectGuid::Empty, std::to_string(tabId).c_str(), name.c_str(), icon.c_str()); + _BroadcastEvent(GE_BANK_TAB_UPDATED, ObjectGuid::Empty, std::to_string(tabId), tab->GetName(), tab->GetIcon()); } -void Guild::HandleSetMemberNote(WorldSession* session, std::string const& name, std::string const& note, bool isPublic) +void Guild::HandleSetMemberNote(WorldSession* session, std::string_view name, std::string_view note, bool isPublic) { // Player must have rights to set public/officer note if (!_HasRankRight(session->GetPlayer(), isPublic ? GR_RIGHT_EPNOTE : GR_RIGHT_EOFFNOTE)) @@ -1445,23 +1351,23 @@ void Guild::HandleSetMemberNote(WorldSession* session, std::string const& name, } } -void Guild::HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec rightsAndSlots) +void Guild::HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string_view name, uint32 rights, uint32 moneyPerDay, std::array const& rightsAndSlots) { // Only leader can modify ranks if (!_IsLeader(session->GetPlayer())) SendCommandResult(session, GUILD_COMMAND_CHANGE_RANK, ERR_GUILD_PERMISSIONS); else if (RankInfo* rankInfo = GetRankInfo(rankId)) { - LOG_DEBUG("guild", "Changed RankName to '%s', rights to 0x%08X", name.c_str(), rights); - rankInfo->SetName(name); rankInfo->SetRights(rights); _SetRankBankMoneyPerDay(rankId, moneyPerDay); - for (GuildBankRightsAndSlotsVec::const_iterator itr = rightsAndSlots.begin(); itr != rightsAndSlots.end(); ++itr) - _SetRankBankTabRightsAndSlots(rankId, *itr); + for (auto rightsAndSlot : rightsAndSlots) + _SetRankBankTabRightsAndSlots(rankId, rightsAndSlot); - _BroadcastEvent(GE_RANK_UPDATED, ObjectGuid::Empty, std::to_string(rankId).c_str(), name.c_str()); + _BroadcastEvent(GE_RANK_UPDATED, ObjectGuid::Empty, std::to_string(rankId), rankInfo->GetName(), std::to_string(m_ranks.size())); + + LOG_DEBUG("guild", "Changed RankName to '%s', rights to 0x%08X", rankInfo->GetName().c_str(), rights); } } @@ -1514,7 +1420,6 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name) SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_NOT_ALLIED, name); return; } - // Invited player cannot be in another guild if (pInvitee->GetGuildId()) { @@ -1536,15 +1441,17 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name) SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_COMMAND_SUCCESS, name); - LOG_DEBUG("guild", "Player %s invited %s to join his Guild", player->GetName().c_str(), name.c_str()); + LOG_DEBUG("guild", "Player %s invited %s to join his Guild", player->GetName().c_str(), pInvitee->GetName().c_str()); pInvitee->SetGuildIdInvited(m_id); _LogEvent(GUILD_EVENT_LOG_INVITE_PLAYER, player->GetGUID(), pInvitee->GetGUID()); - WorldPacket data(SMSG_GUILD_INVITE, 8 + 10); // Guess size - data << player->GetName(); - data << m_name; - pInvitee->GetSession()->SendPacket(&data); + WorldPackets::Guild::GuildInvite invite; + + invite.InviterName = player->GetName(); + invite.GuildName = GetName(); + + pInvitee->SendDirectMessage(invite.Write()); LOG_DEBUG("guild", "SMSG_GUILD_INVITE [%s]", pInvitee->GetName().c_str()); } @@ -1582,7 +1489,7 @@ void Guild::HandleLeaveMember(WorldSession* session) DeleteMember(player->GetGUID(), false, false); _LogEvent(GUILD_EVENT_LOG_LEAVE_GUILD, player->GetGUID()); - _BroadcastEvent(GE_LEFT, player->GetGUID(), player->GetName().c_str()); + _BroadcastEvent(GE_LEFT, player->GetGUID(), player->GetName()); SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_COMMAND_SUCCESS, m_name); } @@ -1593,7 +1500,7 @@ void Guild::HandleLeaveMember(WorldSession* session) delete this; } -void Guild::HandleRemoveMember(WorldSession* session, std::string const& name) +void Guild::HandleRemoveMember(WorldSession* session, std::string_view name) { Player* player = session->GetPlayer(); // Player must have rights to remove members @@ -1616,13 +1523,13 @@ void Guild::HandleRemoveMember(WorldSession* session, std::string const& name) // After call to DeleteMember pointer to member becomes invalid DeleteMember(guid, false, true); _LogEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, player->GetGUID(), guid); - _BroadcastEvent(GE_REMOVED, ObjectGuid::Empty, name.c_str(), player->GetName().c_str()); + _BroadcastEvent(GE_REMOVED, ObjectGuid::Empty, member->GetName(), player->GetName()); } } } } -void Guild::HandleUpdateMemberRank(WorldSession* session, std::string const& name, bool demote) +void Guild::HandleUpdateMemberRank(WorldSession* session, std::string_view name, bool demote) { Player* player = session->GetPlayer(); GuildCommandType type = demote ? GUILD_COMMAND_DEMOTE : GUILD_COMMAND_PROMOTE; @@ -1670,11 +1577,11 @@ void Guild::HandleUpdateMemberRank(WorldSession* session, std::string const& nam uint32 newRankId = member->GetRankId() + (demote ? 1 : -1); member->ChangeRank(newRankId); _LogEvent(demote ? GUILD_EVENT_LOG_DEMOTE_PLAYER : GUILD_EVENT_LOG_PROMOTE_PLAYER, player->GetGUID(), member->GetGUID(), newRankId); - _BroadcastEvent(demote ? GE_DEMOTION : GE_PROMOTION, ObjectGuid::Empty, player->GetName().c_str(), name.c_str(), _GetRankName(newRankId).c_str()); + _BroadcastEvent(demote ? GE_DEMOTION : GE_PROMOTION, ObjectGuid::Empty, player->GetName(), member->GetName(), _GetRankName(newRankId)); } } -void Guild::HandleAddNewRank(WorldSession* session, std::string const& name) +void Guild::HandleAddNewRank(WorldSession* session, std::string_view name) { uint8 size = _GetRanksSize(); if (size >= GUILD_RANKS_MAX_COUNT) @@ -1683,7 +1590,7 @@ void Guild::HandleAddNewRank(WorldSession* session, std::string const& name) // Only leader can add new rank if (_IsLeader(session->GetPlayer())) if (_CreateRank(name, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK)) - _BroadcastEvent(GE_RANK_UPDATED, ObjectGuid::Empty, std::to_string(size).c_str(), name.c_str()); + _BroadcastEvent(GE_RANK_UPDATED, ObjectGuid::Empty, std::to_string(size), name, std::to_string(m_ranks.size())); } void Guild::HandleRemoveLowestRank(WorldSession* session) @@ -1708,9 +1615,10 @@ void Guild::HandleRemoveRank(WorldSession* session, uint8 rankId) stmt->setUInt8(1, rankId); CharacterDatabase.Execute(stmt); - m_ranks.pop_back(); + // match what the sql statement does + m_ranks.erase(m_ranks.begin() + rankId, m_ranks.end()); - _BroadcastEvent(GE_RANK_DELETED); + _BroadcastEvent(GE_RANK_DELETED, ObjectGuid::Empty, std::to_string(m_ranks.size())); } void Guild::HandleMemberDepositMoney(WorldSession* session, uint32 amount) @@ -1751,7 +1659,7 @@ bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool if (!member) return false; - if (uint32(_GetMemberRemainingMoney(member)) < amount) // Check if we have enough slot/money today + if (uint32(_GetMemberRemainingMoney(*member)) < amount) // Check if we have enough slot/money today return false; // Call script after validation and before money transfer. @@ -1794,7 +1702,7 @@ void Guild::HandleMemberLogout(WorldSession* session) member->UpdateLogoutTime(); member->ResetFlags(); } - _BroadcastEvent(GE_SIGNED_OFF, player->GetGUID(), player->GetName().c_str()); + _BroadcastEvent(GE_SIGNED_OFF, player->GetGUID(), player->GetName()); } void Guild::HandleDisband(WorldSession* session) @@ -1811,21 +1719,27 @@ void Guild::HandleDisband(WorldSession* session) // Send data to client void Guild::SendInfo(WorldSession* session) const { - WorldPacket data(SMSG_GUILD_INFO, m_name.size() + 4 + 4 + 4); - data << m_name; - data.AppendPackedTime(m_createdDate); // 3.x (prev. year + month + day) - data << uint32(m_members.size()); // Number of members - data << m_accountsNumber; // Number of accounts + WorldPackets::Guild::GuildInfoResponse guildInfo; + guildInfo.GuildName = m_name; + guildInfo.CreateDate = m_createdDate; + guildInfo.NumMembers = int32(m_members.size()); + guildInfo.NumAccounts = m_accountsNumber; - session->SendPacket(&data); + session->SendPacket(guildInfo.Write()); LOG_DEBUG("guild", "SMSG_GUILD_INFO [%s]", session->GetPlayerInfo().c_str()); } void Guild::SendEventLog(WorldSession* session) const { - WorldPacket data(MSG_GUILD_EVENT_LOG_QUERY, 1 + m_eventLog->GetSize() * (1 + 8 + 4)); - m_eventLog->WritePacket(data); - session->SendPacket(&data); + std::list const& eventLog = m_eventLog.GetGuildLog(); + + WorldPackets::Guild::GuildEventLogQueryResults packet; + packet.Entry.reserve(eventLog.size()); + + for (EventLogEntry const& entry : eventLog) + entry.WritePacket(packet); + + session->SendPacket(packet.Write()); LOG_DEBUG("guild", "MSG_GUILD_EVENT_LOG_QUERY [%s]", session->GetPlayerInfo().c_str()); } @@ -1834,19 +1748,24 @@ void Guild::SendBankLog(WorldSession* session, uint8 tabId) const // GUILD_BANK_MAX_TABS send by client for money log if (tabId < _GetPurchasedTabsSize() || tabId == GUILD_BANK_MAX_TABS) { - const LogHolder* pLog = m_bankEventLog[tabId]; - WorldPacket data(MSG_GUILD_BANK_LOG_QUERY, pLog->GetSize() * (4 * 4 + 1) + 1 + 1); - data << uint8(tabId); - pLog->WritePacket(data); - session->SendPacket(&data); + std::list const& bankEventLog = m_bankEventLog[tabId].GetGuildLog(); + + WorldPackets::Guild::GuildBankLogQueryResults packet; + packet.Tab = tabId; + + packet.Entry.reserve(bankEventLog.size()); + for (BankEventLogEntry const& entry : bankEventLog) + entry.WritePacket(packet); + + session->SendPacket(packet.Write()); LOG_DEBUG("guild", "MSG_GUILD_BANK_LOG_QUERY [%s]", session->GetPlayerInfo().c_str()); } } -void Guild::SendBankTabData(WorldSession* session, uint8 tabId) const +void Guild::SendBankTabData(WorldSession* session, uint8 tabId, bool sendAllSlots) const { if (tabId < _GetPurchasedTabsSize()) - _SendBankContent(session, tabId); + _SendBankContent(session, tabId, sendAllSlots); } void Guild::SendBankTabsInfo(WorldSession* session, bool sendAllSlots /*= false*/) const @@ -1868,18 +1787,19 @@ void Guild::SendPermissions(WorldSession* session) const uint8 rankId = member->GetRankId(); - WorldPacket data(MSG_GUILD_PERMISSIONS, 4 * 15 + 1); - data << uint32(rankId); - data << uint32(_GetRankRights(rankId)); - data << uint32(_GetMemberRemainingMoney(member)); - data << uint8(_GetPurchasedTabsSize()); + WorldPackets::Guild::GuildPermissionsQueryResults queryResult; + queryResult.RankID = rankId; + queryResult.WithdrawGoldLimit = _GetRankBankMoneyPerDay(rankId); + queryResult.Flags = _GetRankRights(rankId); + queryResult.NumTabs = _GetPurchasedTabsSize(); + for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId) { - data << uint32(_GetRankBankTabRights(rankId, tabId)); - data << uint32(_GetMemberRemainingSlots(member, tabId)); + queryResult.Tab[tabId].Flags = _GetRankBankTabRights(rankId, tabId); + queryResult.Tab[tabId].WithdrawItemLimit = _GetMemberRemainingSlots(*member, tabId); } - session->SendPacket(&data); + session->SendPacket(queryResult.Write()); LOG_DEBUG("guild", "MSG_GUILD_PERMISSIONS [%s] Rank: %u", session->GetPlayerInfo().c_str(), rankId); } @@ -1889,20 +1809,21 @@ void Guild::SendMoneyInfo(WorldSession* session) const if (!member) return; - int32 amount = _GetMemberRemainingMoney(member); - WorldPacket data(MSG_GUILD_BANK_MONEY_WITHDRAWN, 4); - data << int32(amount); - session->SendPacket(&data); + int32 amount = _GetMemberRemainingMoney(*member); + + WorldPackets::Guild::GuildBankRemainingWithdrawMoney packet; + packet.RemainingWithdrawMoney = amount; + session->SendPacket(packet.Write()); + LOG_DEBUG("guild", "MSG_GUILD_BANK_MONEY_WITHDRAWN [%s] Money: %u", session->GetPlayerInfo().c_str(), amount); } void Guild::SendLoginInfo(WorldSession* session) { - WorldPacket data(SMSG_GUILD_EVENT, 1 + 1 + m_motd.size() + 1); - data << uint8(GE_MOTD); - data << uint8(1); - data << m_motd; - session->SendPacket(&data); + WorldPackets::Guild::GuildEvent motd; + motd.Type = GE_MOTD; + motd.Params.emplace_back(m_motd); + session->SendPacket(motd.Write()); LOG_DEBUG("guild", "SMSG_GUILD_EVENT [%s] MOTD", session->GetPlayerInfo().c_str()); @@ -1911,7 +1832,7 @@ void Guild::SendLoginInfo(WorldSession* session) Player* player = session->GetPlayer(); HandleRoster(session); - _BroadcastEvent(GE_SIGNED_ON, player->GetGUID(), player->GetName().c_str()); + _BroadcastEvent(GE_SIGNED_ON, player->GetGUID(), player->GetName()); if (Member* member = GetMember(player->GetGUID())) { @@ -1936,11 +1857,10 @@ bool Guild::LoadFromDB(Field* fields) if (purchasedTabs > GUILD_BANK_MAX_TABS) purchasedTabs = GUILD_BANK_MAX_TABS; - m_bankTabs.resize(purchasedTabs); + m_bankTabs.clear(); + m_bankTabs.reserve(purchasedTabs); for (uint8 i = 0; i < purchasedTabs; ++i) - m_bankTabs[i] = new BankTab(m_id, i); - - _CreateLogHolders(); + m_bankTabs.emplace_back(m_id, i); return true; } @@ -1955,17 +1875,25 @@ void Guild::LoadRankFromDB(Field* fields) bool Guild::LoadMemberFromDB(Field* fields) { - ObjectGuid memberGUID = ObjectGuid::Create(fields[1].GetUInt32()); + ObjectGuid::LowType lowguid = fields[1].GetUInt32(); + ObjectGuid playerGuid(HighGuid::Player, lowguid); - Member* member = new Member(m_id, memberGUID, fields[2].GetUInt8()); - if (!member->LoadFromDB(fields)) + auto [memberIt, isNew] = m_members.try_emplace(lowguid, m_id, playerGuid, fields[2].GetUInt8()); + if (!isNew) { - _DeleteMemberFromDB(memberGUID.GetCounter()); - delete member; + LOG_ERROR("guild", "Tried to add %s to guild '%s'. Member already exists.", playerGuid.ToString().c_str(), m_name.c_str()); return false; } - m_members[memberGUID] = member; - sCharacterCache->UpdateCharacterGuildId(memberGUID, GetId()); + + Member& member = memberIt->second; + if (!member.LoadFromDB(fields)) + { + _DeleteMemberFromDB(lowguid); + m_members.erase(memberIt); + return false; + } + + sCharacterCache->UpdateCharacterGuildId(playerGuid, GetId()); return true; } @@ -1979,16 +1907,16 @@ void Guild::LoadBankRightFromDB(Field* fields) bool Guild::LoadEventLogFromDB(Field* fields) { - if (m_eventLog->CanInsert()) + if (m_eventLog.CanInsert()) { - m_eventLog->LoadEvent(new EventLogEntry( + m_eventLog.LoadEvent( m_id, // guild id fields[1].GetUInt32(), // guid time_t(fields[6].GetUInt32()), // timestamp GuildEventLogTypes(fields[2].GetUInt8()), // event type ObjectGuid::Create(fields[3].GetUInt32()), // player guid 1 ObjectGuid::Create(fields[4].GetUInt32()), // player guid 2 - fields[5].GetUInt8())); // rank + fields[5].GetUInt8()); // rank return true; } return false; @@ -2001,8 +1929,8 @@ bool Guild::LoadBankEventLogFromDB(Field* fields) if (dbTabId < _GetPurchasedTabsSize() || isMoneyTab) { uint8 tabId = isMoneyTab ? uint8(GUILD_BANK_MAX_TABS) : dbTabId; - LogHolder* pLog = m_bankEventLog[tabId]; - if (pLog->CanInsert()) + LogHolder& bankLog = m_bankEventLog[tabId]; + if (bankLog.CanInsert()) { ObjectGuid::LowType guid = fields[2].GetUInt32(); GuildBankEventLogTypes eventType = GuildBankEventLogTypes(fields[3].GetUInt8()); @@ -2019,7 +1947,7 @@ bool Guild::LoadBankEventLogFromDB(Field* fields) LOG_ERROR("guild", "GuildBankEventLog ERROR: non-money event (LogGuid: %u, Guild: %u) belongs to money tab, ignoring...", guid, m_id); return false; } - pLog->LoadEvent(new BankEventLogEntry( + bankLog.LoadEvent( m_id, // guild id guid, // guid time_t(fields[8].GetUInt32()), // timestamp @@ -2028,7 +1956,7 @@ bool Guild::LoadBankEventLogFromDB(Field* fields) ObjectGuid::Create(fields[4].GetUInt32()), // player guid fields[5].GetUInt32(), // item or money fields[6].GetUInt16(), // itam stack count - fields[7].GetUInt8())); // dest tab id + fields[7].GetUInt8()); // dest tab id } } return true; @@ -2040,7 +1968,7 @@ void Guild::LoadBankTabFromDB(Field* fields) if (tabId >= _GetPurchasedTabsSize()) LOG_ERROR("guild", "Invalid tab (tabId: %u) in guild bank, skipped.", tabId); else - m_bankTabs[tabId]->LoadFromDB(fields); + m_bankTabs[tabId].LoadFromDB(fields); } bool Guild::LoadBankItemFromDB(Field* fields) @@ -2052,7 +1980,7 @@ bool Guild::LoadBankItemFromDB(Field* fields) fields[14].GetUInt32(), fields[15].GetUInt32()); return false; } - return m_bankTabs[tabId]->LoadItemFromDB(fields); + return m_bankTabs[tabId].LoadItemFromDB(fields); } // Validates guild data loaded from database. Returns false if guild should be deleted. @@ -2096,9 +2024,9 @@ bool Guild::Validate() } // Validate members' data - for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->second->GetRankId() > _GetRanksSize()) - itr->second->ChangeRank(_GetLowestRankId()); + for (auto& [guid, member] : m_members) + if (member.GetRankId() > _GetRanksSize()) + member.ChangeRank(_GetLowestRankId()); // Repair the structure of the guild. // If the guildmaster doesn't exist or isn't member of the guild @@ -2115,44 +2043,44 @@ bool Guild::Validate() } } else if (!pLeader->IsRank(GR_GUILDMASTER)) - _SetLeaderGUID(pLeader); + _SetLeaderGUID(*pLeader); // Check config if multiple guildmasters are allowed if (!sConfigMgr->GetOption("Guild.AllowMultipleGuildMaster", 0)) - for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->second->GetRankId() == GR_GUILDMASTER && !itr->second->IsSamePlayer(m_leaderGuid)) - itr->second->ChangeRank(GR_OFFICER); + for (auto& [guid, member] : m_members) + if ((member.GetRankId() == GR_GUILDMASTER) && !member.IsSamePlayer(m_leaderGuid)) + member.ChangeRank(GR_OFFICER); _UpdateAccountsNumber(); return true; } // Broadcasts -void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::string const& msg, uint32 language) const +void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::string_view msg, uint32 language) const { if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { WorldPacket data; ChatHandler::BuildChatPacket(data, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), nullptr, msg); - for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (Player* player = itr->second->FindPlayer()) + for (auto const& [guid, member] : m_members) + if (Player* player = member.FindPlayer()) if (_HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) && !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUID())) player->GetSession()->SendPacket(&data); } } -void Guild::BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const +void Guild::BroadcastPacketToRank(WorldPacket const* packet, uint8 rankId) const { - for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->second->IsRank(rankId)) - if (Player* player = itr->second->FindPlayer()) + for (auto const& [guid, member] : m_members) + if (member.IsRank(rankId)) + if (Player* player = member.FindPlayer()) player->GetSession()->SendPacket(packet); } -void Guild::BroadcastPacket(WorldPacket* packet) const +void Guild::BroadcastPacket(WorldPacket const* packet) const { - for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (Player* player = itr->second->FindPlayer()) + for (auto const& [guid, member] : m_members) + if (Player* player = member.FindPlayer()) player->GetSession()->SendPacket(packet); } @@ -2163,7 +2091,7 @@ void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 max WorldPacket data(SMSG_CALENDAR_FILTER_GUILD); data << uint32(count); // count placeholder - for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + for (auto const& [guid, member] : m_members) { // not sure if needed, maybe client checks it as well if (count >= CALENDAR_MAX_INVITES) @@ -2173,12 +2101,11 @@ void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 max return; } - Member* member = itr->second; - uint32 level = sCharacterCache->GetCharacterLevelByGuid(member->GetGUID()); + uint32 level = sCharacterCache->GetCharacterLevelByGuid(member.GetGUID()); - if (member->GetGUID() != session->GetPlayer()->GetGUID() && level >= minLevel && level <= maxLevel && member->IsRankNotLower(minRank)) + if (member.GetGUID() != session->GetPlayer()->GetGUID() && level >= minLevel && level <= maxLevel && member.IsRankNotLower(minRank)) { - data.appendPackGUID(member->GetGUID().GetRawValue()); + data.appendPackGUID(member.GetGUID().GetRawValue()); data << uint8(0); // unk ++count; } @@ -2206,25 +2133,33 @@ bool Guild::AddMember(ObjectGuid guid, uint8 rankId) // This will be prevent attempt to join many guilds and corrupt guild data integrity Player::RemovePetitionsAndSigns(guid, GUILD_CHARTER_TYPE); + ObjectGuid::LowType lowguid = guid.GetCounter(); + // If rank was not passed, assign lowest possible rank if (rankId == GUILD_RANK_NONE) rankId = _GetLowestRankId(); - Member* member = new Member(m_id, guid, rankId); + auto [memberIt, isNew] = m_members.try_emplace(lowguid, m_id, guid, rankId); + if (!isNew) + { + LOG_ERROR("guild", "Tried to add %s to guild '%s'. Member already exists.", guid.ToString().c_str(), m_name.c_str()); + return false; + } + + Member& member = memberIt->second; std::string name; if (player) { - m_members[guid] = member; player->SetInGuild(m_id); player->SetGuildIdInvited(0); player->SetRank(rankId); - member->SetStats(player); + member.SetStats(player); SendLoginInfo(player->GetSession()); name = player->GetName(); } else { - member->ResetFlags(); + member.ResetFlags(); bool ok = false; // xinef: sync query @@ -2235,7 +2170,7 @@ bool Guild::AddMember(ObjectGuid guid, uint8 rankId) { Field* fields = result->Fetch(); name = fields[0].GetString(); - member->SetStats( + member.SetStats( name, fields[1].GetUInt8(), fields[2].GetUInt8(), @@ -2243,23 +2178,22 @@ bool Guild::AddMember(ObjectGuid guid, uint8 rankId) fields[4].GetUInt16(), fields[5].GetUInt32()); - ok = member->CheckStats(); + ok = member.CheckStats(); } if (!ok) { - delete member; + m_members.erase(memberIt); return false; } - m_members[guid] = member; sCharacterCache->UpdateCharacterGuildId(guid, m_id); } CharacterDatabaseTransaction trans(nullptr); - member->SaveToDB(trans); + member.SaveToDB(trans); _UpdateAccountsNumber(); _LogEvent(GUILD_EVENT_LOG_JOIN_GUILD, guid); - _BroadcastEvent(GE_JOINED, guid, name.c_str()); + _BroadcastEvent(GE_JOINED, guid, name); // Call scripts if member was succesfully added (and stored to database) sScriptMgr->OnGuildAddMember(this, player, rankId); @@ -2269,6 +2203,7 @@ bool Guild::AddMember(ObjectGuid guid, uint8 rankId) void Guild::DeleteMember(ObjectGuid guid, bool isDisbanding, bool isKicked, bool canDeleteGuild) { + ObjectGuid::LowType lowguid = guid.GetCounter(); Player* player = ObjectAccessor::FindConnectedPlayer(guid); // Guild master can be deleted when loading guild and guid doesn't exist in characters table @@ -2277,12 +2212,12 @@ void Guild::DeleteMember(ObjectGuid guid, bool isDisbanding, bool isKicked, bool { Member* oldLeader = nullptr; Member* newLeader = nullptr; - for (Guild::Members::iterator i = m_members.begin(); i != m_members.end(); ++i) + for (auto& [guid, member] : m_members) { - if (i->first == guid) - oldLeader = i->second; - else if (!newLeader || newLeader->GetRankId() > i->second->GetRankId()) - newLeader = i->second; + if (guid == lowguid) + oldLeader = &member; + else if (!newLeader || newLeader->GetRankId() > member.GetRankId()) + newLeader = &member; } if (!newLeader) @@ -2293,7 +2228,7 @@ void Guild::DeleteMember(ObjectGuid guid, bool isDisbanding, bool isKicked, bool return; } - _SetLeaderGUID(newLeader); + _SetLeaderGUID(*newLeader); // If player not online data in data field will be loaded from guild tabs no need to update it !! if (Player* newLeaderPlayer = newLeader->FindPlayer()) @@ -2302,19 +2237,14 @@ void Guild::DeleteMember(ObjectGuid guid, bool isDisbanding, bool isKicked, bool // If leader does not exist (at guild loading with deleted leader) do not send broadcasts if (oldLeader) { - _BroadcastEvent(GE_LEADER_CHANGED, ObjectGuid::Empty, oldLeader->GetName().c_str(), newLeader->GetName().c_str()); - _BroadcastEvent(GE_LEFT, guid, oldLeader->GetName().c_str()); + _BroadcastEvent(GE_LEADER_CHANGED, ObjectGuid::Empty, oldLeader->GetName(), newLeader->GetName()); + _BroadcastEvent(GE_LEFT, guid, oldLeader->GetName()); } } // Call script on remove before member is actually removed from guild (and database) sScriptMgr->OnGuildRemoveMember(this, player, isDisbanding, isKicked); - auto memberItr = m_members.find(guid); - if (memberItr != m_members.end()) - { - delete memberItr->second; - m_members.erase(memberItr); - } + m_members.erase(lowguid); // If player not online data in data field will be loaded from guild tabs no need to update it !! if (player) @@ -2372,7 +2302,7 @@ void Guild::SwapItemsWithInventory(Player* player, bool toChar, uint8 tabId, uin } // Bank tabs -void Guild::SetBankTabText(uint8 tabId, std::string const& text) +void Guild::SetBankTabText(uint8 tabId, std::string_view text) { if (BankTab* pTab = GetBankTab(tabId)) { @@ -2382,17 +2312,10 @@ void Guild::SetBankTabText(uint8 tabId, std::string const& text) } // Private methods -void Guild::_CreateLogHolders() -{ - m_eventLog = new LogHolder(m_id, sWorld->getIntConfig(CONFIG_GUILD_EVENT_LOG_COUNT)); - for (uint8 tabId = 0; tabId <= GUILD_BANK_MAX_TABS; ++tabId) - m_bankEventLog[tabId] = new LogHolder(m_id, sWorld->getIntConfig(CONFIG_GUILD_BANK_EVENT_LOG_COUNT)); -} - void Guild::_CreateNewBankTab() { uint8 tabId = _GetPurchasedTabsSize(); // Next free id - m_bankTabs.push_back(new BankTab(m_id, tabId)); + m_bankTabs.emplace_back(m_id, tabId); CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); @@ -2407,8 +2330,8 @@ void Guild::_CreateNewBankTab() trans->Append(stmt); ++tabId; - for (Ranks::iterator itr = m_ranks.begin(); itr != m_ranks.end(); ++itr) - (*itr).CreateMissingTabsIfNeeded(tabId, trans, false); + for (auto & m_rank : m_ranks) + m_rank.CreateMissingTabsIfNeeded(tabId, trans, false); CharacterDatabase.CommitTransaction(trans); } @@ -2430,7 +2353,7 @@ void Guild::_CreateDefaultGuildRanks(LocaleConstant loc) _CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_INITIATE, loc), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); } -bool Guild::_CreateRank(std::string const& name, uint32 rights) +bool Guild::_CreateRank(std::string_view name, uint32 rights) { uint8 newRankId = _GetRanksSize(); if (newRankId >= GUILD_RANKS_MAX_COUNT) @@ -2453,9 +2376,9 @@ bool Guild::_CreateRank(std::string const& name, uint32 rights) void Guild::_UpdateAccountsNumber() { // We use a set to be sure each element will be unique - std::set accountsIdSet; - for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - accountsIdSet.insert(itr->second->GetAccountId()); + std::unordered_set accountsIdSet; + for (auto const& [guid, member] : m_members) + accountsIdSet.insert(member.GetAccountId()); m_accountsNumber = accountsIdSet.size(); } @@ -2476,9 +2399,7 @@ void Guild::_DeleteBankItems(CharacterDatabaseTransaction trans, bool removeItem { for (uint8 tabId = 0; tabId < _GetPurchasedTabsSize(); ++tabId) { - m_bankTabs[tabId]->Delete(trans, removeItemsFromDB); - delete m_bankTabs[tabId]; - m_bankTabs[tabId] = nullptr; + m_bankTabs[tabId].Delete(trans, removeItemsFromDB); } m_bankTabs.clear(); } @@ -2502,13 +2423,10 @@ bool Guild::_ModifyBankMoney(CharacterDatabaseTransaction trans, uint64 amount, return true; } -void Guild::_SetLeaderGUID(Member* pLeader) +void Guild::_SetLeaderGUID(Member& pLeader) { - if (!pLeader) - return; - - m_leaderGuid = pLeader->GetGUID(); - pLeader->ChangeRank(GR_GUILDMASTER); + m_leaderGuid = pLeader.GetGUID(); + pLeader.ChangeRank(GR_GUILDMASTER); CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_LEADER); stmt->setUInt32(0, m_leaderGuid.GetCounter()); @@ -2567,37 +2485,31 @@ inline int8 Guild::_GetRankBankTabRights(uint8 rankId, uint8 tabId) const return 0; } -inline int32 Guild::_GetMemberRemainingSlots(Member const* member, uint8 tabId) const +inline int32 Guild::_GetMemberRemainingSlots(Member const& member, uint8 tabId) const { - if (member) + uint8 rankId = member.GetRankId(); + if (rankId == GR_GUILDMASTER) + return static_cast(GUILD_WITHDRAW_SLOT_UNLIMITED); + if ((_GetRankBankTabRights(rankId, tabId) & GUILD_BANK_RIGHT_VIEW_TAB) != 0) { - uint8 rankId = member->GetRankId(); - if (rankId == GR_GUILDMASTER) - return GUILD_WITHDRAW_SLOT_UNLIMITED; - if ((_GetRankBankTabRights(rankId, tabId) & GUILD_BANK_RIGHT_VIEW_TAB) != 0) - { - int32 remaining = _GetRankBankTabSlotsPerDay(rankId, tabId) - member->GetBankWithdrawValue(tabId); - if (remaining > 0) - return remaining; - } + int32 remaining = _GetRankBankTabSlotsPerDay(rankId, tabId) - member.GetBankWithdrawValue(tabId); + if (remaining > 0) + return remaining; } return 0; } -inline int32 Guild::_GetMemberRemainingMoney(Member const* member) const +inline int32 Guild::_GetMemberRemainingMoney(Member const& member) const { - if (member) - { - uint8 rankId = member->GetRankId(); - if (rankId == GR_GUILDMASTER) - return GUILD_WITHDRAW_MONEY_UNLIMITED; + uint8 rankId = member.GetRankId(); + if (rankId == GR_GUILDMASTER) + return static_cast(GUILD_WITHDRAW_MONEY_UNLIMITED); - if ((_GetRankRights(rankId) & (GR_RIGHT_WITHDRAW_REPAIR | GR_RIGHT_WITHDRAW_GOLD)) != 0) - { - int32 remaining = _GetRankBankMoneyPerDay(rankId) - member->GetBankWithdrawValue(GUILD_BANK_MAX_TABS); - if (remaining > 0) - return remaining; - } + if ((_GetRankRights(rankId) & (GR_RIGHT_WITHDRAW_REPAIR | GR_RIGHT_WITHDRAW_GOLD)) != 0) + { + int32 remaining = _GetRankBankMoneyPerDay(rankId) - member.GetBankWithdrawValue(GUILD_BANK_MAX_TABS); + if (remaining > 0) + return remaining; } return 0; } @@ -2629,7 +2541,7 @@ inline bool Guild::_MemberHasTabRights(ObjectGuid guid, uint8 tabId, uint32 righ inline void Guild::_LogEvent(GuildEventLogTypes eventType, ObjectGuid playerGuid1, ObjectGuid playerGuid2, uint8 newRank) { CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); - m_eventLog->AddEvent(trans, new EventLogEntry(m_id, m_eventLog->GetNextGUID(), eventType, playerGuid1, playerGuid2, newRank)); + m_eventLog.AddEvent(trans, m_id, m_eventLog.GetNextGUID(), eventType, playerGuid1, playerGuid2, newRank); CharacterDatabase.CommitTransaction(trans); sScriptMgr->OnGuildEvent(this, uint8(eventType), playerGuid1.GetCounter(), playerGuid2.GetCounter(), newRank); @@ -2651,8 +2563,8 @@ void Guild::_LogBankEvent(CharacterDatabaseTransaction trans, GuildBankEventLogT tabId = GUILD_BANK_MAX_TABS; dbTabId = GUILD_BANK_MONEY_LOGS_TAB; } - LogHolder* pLog = m_bankEventLog[tabId]; - pLog->AddEvent(trans, new BankEventLogEntry(m_id, pLog->GetNextGUID(), eventType, dbTabId, guid, itemOrMoney, itemStackCount, destTabId)); + LogHolder& pLog = m_bankEventLog[tabId]; + pLog.AddEvent(trans, m_id, pLog.GetNextGUID(), eventType, dbTabId, guid, itemOrMoney, itemStackCount, destTabId); sScriptMgr->OnGuildBankEvent(this, uint8(eventType), tabId, guid.GetCounter(), itemOrMoney, itemStackCount, destTabId); } @@ -2767,13 +2679,13 @@ bool Guild::_DoItemsMove(MoveItemData* pSrc, MoveItemData* pDest, bool sendError return true; } -void Guild::_SendBankContent(WorldSession* session, uint8 tabId) const +void Guild::_SendBankContent(WorldSession* session, uint8 tabId, bool sendAllSlots) const { ObjectGuid guid = session->GetPlayer()->GetGUID(); if (!_MemberHasTabRights(guid, tabId, GUILD_BANK_RIGHT_VIEW_TAB)) return; - _SendBankList(session, tabId, true); + _SendBankList(session, tabId, sendAllSlots); } void Guild::_SendBankMoneyUpdate(WorldSession* session) const @@ -2818,94 +2730,134 @@ void Guild::_SendBankContentUpdate(uint8 tabId, SlotIds slots) const _SendBankList(nullptr, tabId, false, &slots); } -void Guild::_BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid, const char* param1, const char* param2, const char* param3) const +void Guild::_BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid, + Optional param1 /*= {}*/, Optional param2 /*= {}*/, Optional param3 /*= {}*/) const { - uint8 count = !param3 ? (!param2 ? (!param1 ? 0 : 1) : 2) : 3; + WorldPackets::Guild::GuildEvent event; + event.Type = guildEvent; + if (param1) + event.Params.push_back(*param1); - WorldPacket data(SMSG_GUILD_EVENT, 1 + 1 + count + (guid ? 8 : 0)); - data << uint8(guildEvent); - data << uint8(count); + if (param2) + { + event.Params.resize(2); + event.Params[1] = *param2; + } if (param3) - data << param1 << param2 << param3; - else if (param2) - data << param1 << param2; - else if (param1) - data << param1; - - if (guid) - data << guid; - - BroadcastPacket(&data); + { + event.Params.resize(3); + event.Params[2] = *param3; + } + event.Guid = guid; + BroadcastPacket(event.Write()); LOG_DEBUG("guild", "SMSG_GUILD_EVENT [Broadcast] Event: %u", guildEvent); } -void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= 0*/, bool sendAllSlots /*= false*/, SlotIds* slots /*= nullptr*/) const +void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= 0*/, bool sendAllSlots /*= false*/, SlotIds *slots /*= nullptr*/) const { if (!sScriptMgr->CanGuildSendBankList(this, session, tabId, sendAllSlots)) return; - WorldPacket data(SMSG_GUILD_BANK_LIST, 500); - data << uint64(m_bankMoney); - data << uint8(tabId); - size_t rempos = data.wpos(); - data << uint32(0); - data << uint8(sendAllSlots); + WorldPackets::Guild::GuildBankQueryResults packet; + + packet.Money = m_bankMoney; + packet.Tab = int32(tabId); + packet.FullUpdate = sendAllSlots; if (sendAllSlots && !tabId) { - data << uint8(_GetPurchasedTabsSize()); // Number of tabs + packet.TabInfo.reserve(_GetPurchasedTabsSize()); for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i) - m_bankTabs[i]->WriteInfoPacket(data); + { + WorldPackets::Guild::GuildBankTabInfo tabInfo; + tabInfo.Name = m_bankTabs[i].GetName(); + tabInfo.Icon = m_bankTabs[i].GetIcon(); + packet.TabInfo.push_back(tabInfo); + } } - BankTab const* tab = GetBankTab(tabId); - if (!tab) - data << uint8(0); - else if (sendAllSlots) - tab->WritePacket(data); - else if (slots && !slots->empty()) + if (BankTab const* tab = GetBankTab(tabId)) { - data << uint8(slots->size()); - for (SlotIds::const_iterator itr = slots->begin(); itr != slots->end(); ++itr) - tab->WriteSlotPacket(data, *itr, false); + auto fillItems = [&](auto begin, auto end, bool skipEmpty) + { + for (auto itr = begin; itr != end; ++itr) + { + if (Item* tabItem = tab->GetItem(*itr)) + { + WorldPackets::Guild::GuildBankItemInfo itemInfo; + + itemInfo.Slot = *itr; + itemInfo.ItemID = tabItem->GetEntry(); + itemInfo.Count = int32(tabItem->GetCount()); + itemInfo.Charges = int32(abs(tabItem->GetSpellCharges())); + itemInfo.EnchantmentID = int32(tabItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)); + itemInfo.Flags = tabItem->GetInt32Value(ITEM_FIELD_FLAGS); + + for (uint32 socketSlot = 0; socketSlot < MAX_GEM_SOCKETS; ++socketSlot) + { + if (uint32 enchId = tabItem->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + socketSlot))) + { + WorldPackets::Guild::GuildBankSocketEnchant gem; + gem.SocketIndex = socketSlot; + gem.SocketEnchantID = int32(enchId); + itemInfo.SocketEnchant.push_back(gem); + } + } + + packet.ItemInfo.push_back(itemInfo); + } + else if (!skipEmpty) + { + WorldPackets::Guild::GuildBankItemInfo itemInfo; + + itemInfo.Slot = *itr; + itemInfo.ItemID = 0; + + packet.ItemInfo.push_back(itemInfo); + } + } + + }; + + if (sendAllSlots) + fillItems(boost::make_counting_iterator(uint8(0)), boost::make_counting_iterator(uint8(GUILD_BANK_MAX_SLOTS)), true); + else if (slots && !slots->empty()) + fillItems(slots->begin(), slots->end(), false); } - else - data << uint8(0); if (session) { - int32 numSlots = 0; if (Member const* member = GetMember(session->GetPlayer()->GetGUID())) - numSlots = _GetMemberRemainingSlots(member, tabId); - data.put(rempos, numSlots); - session->SendPacket(&data); + packet.WithdrawalsRemaining = _GetMemberRemainingSlots(*member, tabId); + + session->SendPacket(packet.Write()); LOG_DEBUG("guild", "SMSG_GUILD_BANK_LIST [%s]: TabId: %u, FullSlots: %u, slots: %d", - session->GetPlayerInfo().c_str(), tabId, sendAllSlots, numSlots); + session->GetPlayerInfo().c_str(), tabId, sendAllSlots, packet.WithdrawalsRemaining); } - else // TODO - Probably this is just sent to session + those that have sent CMSG_GUILD_BANKER_ACTIVATE + else /// @todo - Probably this is just sent to session + those that have sent CMSG_GUILD_BANKER_ACTIVATE { - for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + packet.Write(); + for (auto const& [guid, member] : m_members) { - if (!_MemberHasTabRights(itr->second->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB)) + if (!_MemberHasTabRights(member.GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB)) continue; - Player* player = itr->second->FindPlayer(); + Player* player = member.FindPlayer(); if (!player) continue; - uint32 numSlots = _GetMemberRemainingSlots(itr->second, tabId); - data.put(rempos, numSlots); - player->GetSession()->SendPacket(&data); + packet.SetWithdrawalsRemaining(_GetMemberRemainingSlots(member, tabId)); + player->SendDirectMessage(packet.GetRawPacket()); LOG_DEBUG("guild", "SMSG_GUILD_BANK_LIST [%s]: TabId: %u, FullSlots: %u, slots: %u" - , player->GetName().c_str(), tabId, sendAllSlots, numSlots); + , player->GetName().c_str(), tabId, sendAllSlots, packet.WithdrawalsRemaining); } } } void Guild::ResetTimes() { - for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - itr->second->ResetValues(); + for (auto& [guid, member] : m_members) + member.ResetValues(); - _BroadcastEvent(GE_BANK_TAB_AND_MONEY_UPDATED); + _BroadcastEvent(GE_BANK_TAB_AND_MONEY_UPDATED, ObjectGuid::Empty); } diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index ff046f567..988c9f477 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -21,11 +21,25 @@ #include "Item.h" #include "ObjectMgr.h" #include "Player.h" +#include "Optional.h" #include "World.h" #include "WorldPacket.h" +#include +#include +#include class Item; +namespace WorldPackets +{ + namespace Guild + { + class GuildBankLogQueryResults; + class GuildEventLogQueryResults; + class SaveGuildEmblem; + } +} + enum GuildMisc { GUILD_BANK_MAX_TABS = 6, // send by client for money log also @@ -229,8 +243,7 @@ public: void LoadFromDB(Field* fields); void SaveToDB(uint32 guildId) const; - void ReadPacket(WorldPacket& recv); - void WritePacket(WorldPacket& data) const; + void ReadPacket(WorldPackets::Guild::SaveGuildEmblem& packet); uint32 GetStyle() const { return m_style; } uint32 GetColor() const { return m_color; } @@ -274,9 +287,7 @@ private: uint32 slots; }; -typedef std::vector GuildBankRightsAndSlotsVec; - -typedef std::set SlotIds; +using SlotIds = std::set; class Guild { @@ -296,15 +307,14 @@ public: // pussywizard: public class Member m_accountId(0), m_rankId(rankId) { - memset(m_bankWithdraw, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(int32)); } void SetStats(Player* player); - void SetStats(std::string const& name, uint8 level, uint8 _class, uint8 gender, uint32 zoneId, uint32 accountId); + void SetStats(std::string_view name, uint8 level, uint8 _class, uint8 gender, uint32 zoneId, uint32 accountId); bool CheckStats() const; - void SetPublicNote(std::string const& publicNote); - void SetOfficerNote(std::string const& officerNote); + void SetPublicNote(std::string_view publicNote); + void SetOfficerNote(std::string_view officerNote); void SetZoneID(uint32 id) { m_zoneId = id; } void SetLevel(uint8 var) { m_level = var; } @@ -314,7 +324,6 @@ public: // pussywizard: public class Member bool LoadFromDB(Field* fields); void SaveToDB(CharacterDatabaseTransaction trans) const; - void WritePacket(WorldPacket& data, bool sendOfficerNote) const; ObjectGuid GetGUID() const { return m_guid; } std::string const& GetName() const { return m_name; } @@ -360,25 +369,25 @@ public: // pussywizard: public class Member std::string m_publicNote; std::string m_officerNote; - int32 m_bankWithdraw[GUILD_BANK_MAX_TABS + 1]; + std::array m_bankWithdraw = {}; }; // pussywizard: public GetMember inline const Member* GetMember(ObjectGuid guid) const { - Members::const_iterator itr = m_members.find(guid); - return itr != m_members.end() ? itr->second : nullptr; + auto itr = m_members.find(guid.GetCounter()); + return (itr != m_members.end()) ? &itr->second : nullptr; } inline Member* GetMember(ObjectGuid guid) { - Members::iterator itr = m_members.find(guid); - return itr != m_members.end() ? itr->second : nullptr; + auto itr = m_members.find(guid.GetCounter()); + return (itr != m_members.end()) ? &itr->second : nullptr; } - inline Member* GetMember(std::string const& name) + inline Member* GetMember(std::string_view name) { - for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->second->GetName() == name) - return itr->second; + for (auto & m_member : m_members) + if (m_member.second.GetName() == name) + return &m_member.second; return nullptr; } @@ -396,7 +405,6 @@ private: uint64 GetTimestamp() const { return m_timestamp; } virtual void SaveToDB(CharacterDatabaseTransaction trans) const = 0; - virtual void WritePacket(WorldPacket& data) const = 0; protected: uint32 m_guildId; @@ -417,7 +425,7 @@ private: ~EventLogEntry() override { } void SaveToDB(CharacterDatabaseTransaction trans) const override; - void WritePacket(WorldPacket& data) const override; + void WritePacket(WorldPackets::Guild::GuildEventLogQueryResults& packet) const; private: GuildEventLogTypes m_eventType; @@ -438,6 +446,11 @@ private: eventType == GUILD_BANK_LOG_REPAIR_MONEY; } + bool IsMoneyEvent() const + { + return IsMoneyEvent(m_eventType); + } + BankEventLogEntry(uint32 guildId, ObjectGuid::LowType guid, GuildBankEventLogTypes eventType, uint8 tabId, ObjectGuid playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) : LogEntry(guildId, guid), m_eventType(eventType), m_bankTabId(tabId), m_playerGuid(playerGuid), m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) { } @@ -449,7 +462,7 @@ private: ~BankEventLogEntry() override { } void SaveToDB(CharacterDatabaseTransaction trans) const override; - void WritePacket(WorldPacket& data) const override; + void WritePacket(WorldPackets::Guild::GuildBankLogQueryResults& packet) const; private: GuildBankEventLogTypes m_eventType; @@ -461,30 +474,29 @@ private: }; // Class encapsulating work with events collection - typedef std::list GuildLog; - + template class LogHolder { public: - LogHolder(uint32 guildId, uint32 maxRecords) : m_guildId(guildId), m_maxRecords(maxRecords), m_nextGUID(uint32(GUILD_EVENT_LOG_GUID_UNDEFINED)) { } - ~LogHolder(); + LogHolder(); - uint8 GetSize() const { return uint8(m_log.size()); } uint32 GetGuildId() const { return m_guildId; } - // Checks if new log entry can be added to holder when loading from DB - inline bool CanInsert() const { return m_log.size() < m_maxRecords; } + // Checks if new log entry can be added to holder + bool CanInsert() const { return m_log.size() < m_maxRecords; } // Adds event from DB to collection - void LoadEvent(LogEntry* entry); + template + void LoadEvent(Ts&&... args); // Adds new event to collection and saves it to DB - void AddEvent(CharacterDatabaseTransaction trans, LogEntry* entry); - // Writes information about all events to packet - void WritePacket(WorldPacket& data) const; + template + void AddEvent(CharacterDatabaseTransaction trans, Ts&&... args); uint32 GetNextGUID(); + std::list& GetGuildLog() { return m_log; } + std::list const& GetGuildLog() const { return m_log; } private: - GuildLog m_log; uint32 m_guildId; - uint32 m_maxRecords; + std::list m_log; + uint32 const m_maxRecords; uint32 m_nextGUID; }; @@ -494,18 +506,17 @@ private: public: RankInfo(): m_guildId(0), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { } RankInfo(uint32 guildId) : m_guildId(guildId), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { } - RankInfo(uint32 guildId, uint8 rankId, std::string const& name, uint32 rights, uint32 money) : + RankInfo(uint32 guildId, uint8 rankId, std::string_view name, uint32 rights, uint32 money) : m_guildId(guildId), m_rankId(rankId), m_name(name), m_rights(rights), m_bankMoneyPerDay(rankId != GR_GUILDMASTER ? money : GUILD_WITHDRAW_MONEY_UNLIMITED) { } void LoadFromDB(Field* fields); void SaveToDB(CharacterDatabaseTransaction trans) const; - void WritePacket(WorldPacket& data) const; uint8 GetId() const { return m_rankId; } std::string const& GetName() const { return m_name; } - void SetName(std::string const& name); + void SetName(std::string_view name); uint32 GetRights() const { return m_rights; } void SetRights(uint32 rights); @@ -534,7 +545,7 @@ private: std::string m_name; uint32 m_rights; uint32 m_bankMoneyPerDay; - GuildBankRightsAndSlots m_bankTabRightsAndSlots[GUILD_BANK_MAX_TABS]; + std::array m_bankTabRightsAndSlots = {}; }; class BankTab @@ -542,25 +553,20 @@ private: public: BankTab(uint32 guildId, uint8 tabId) : m_guildId(guildId), m_tabId(tabId) { - memset(m_items, 0, GUILD_BANK_MAX_SLOTS * sizeof(Item*)); } void LoadFromDB(Field* fields); bool LoadItemFromDB(Field* fields); void Delete(CharacterDatabaseTransaction trans, bool removeItemsFromDB = false); - void WritePacket(WorldPacket& data) const; - bool WriteSlotPacket(WorldPacket& data, uint8 slotId, bool ignoreEmpty = true) const; - void WriteInfoPacket(WorldPacket& data) const - { - data << m_name; - data << m_icon; - } - - void SetInfo(std::string const& name, std::string const& icon); - void SetText(std::string const& text); + void SetInfo(std::string_view name, std::string_view icon); + void SetText(std::string_view text); void SendText(const Guild* guild, WorldSession* session) const; + std::string const& GetName() const { return m_name; } + std::string const& GetIcon() const { return m_icon; } + std::string const& GetText() const { return m_text; } + inline Item* GetItem(uint8 slotId) const { return slotId < GUILD_BANK_MAX_SLOTS ? m_items[slotId] : nullptr; } bool SetItem(CharacterDatabaseTransaction trans, uint8 slotId, Item* pItem); @@ -568,7 +574,7 @@ private: uint32 m_guildId; uint8 m_tabId; - Item* m_items[GUILD_BANK_MAX_SLOTS]; + std::array m_items = {}; std::string m_name; std::string m_icon; std::string m_text; @@ -661,18 +667,14 @@ private: void CanStoreItemInTab(Item* pItem, uint8 skipSlotId, bool merge, uint32& count); }; - typedef std::unordered_map Members; - typedef std::vector Ranks; - typedef std::vector BankTabs; - public: - static void SendCommandResult(WorldSession* session, GuildCommandType type, GuildCommandError errCode, std::string const& param = ""); + static void SendCommandResult(WorldSession* session, GuildCommandType type, GuildCommandError errCode, std::string_view param = {}); static void SendSaveEmblemResult(WorldSession* session, GuildEmblemError errCode); Guild(); ~Guild(); - bool Create(Player* pLeader, std::string const& name); + bool Create(Player* pLeader, std::string_view name); void Disband(); // Getters @@ -685,20 +687,20 @@ public: // Handle client commands void HandleRoster(WorldSession* session); void HandleQuery(WorldSession* session); - void HandleSetMOTD(WorldSession* session, std::string const& motd); - void HandleSetInfo(WorldSession* session, std::string const& info); + void HandleSetMOTD(WorldSession* session, std::string_view motd); + void HandleSetInfo(WorldSession* session, std::string_view info); void HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo); - void HandleSetLeader(WorldSession* session, std::string const& name); - void HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string const& name, std::string const& icon); - void HandleSetMemberNote(WorldSession* session, std::string const& name, std::string const& note, bool officer); - void HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec rightsAndSlots); + void HandleSetLeader(WorldSession* session, std::string_view name); + void HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string_view name, std::string_view icon); + void HandleSetMemberNote(WorldSession* session, std::string_view name, std::string_view note, bool officer); + void HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string_view name, uint32 rights, uint32 moneyPerDay, std::array const& rightsAndSlots); void HandleBuyBankTab(WorldSession* session, uint8 tabId); void HandleInviteMember(WorldSession* session, std::string const& name); void HandleAcceptMember(WorldSession* session); void HandleLeaveMember(WorldSession* session); - void HandleRemoveMember(WorldSession* session, std::string const& name); - void HandleUpdateMemberRank(WorldSession* session, std::string const& name, bool demote); - void HandleAddNewRank(WorldSession* session, std::string const& name); + void HandleRemoveMember(WorldSession* session, std::string_view name); + void HandleUpdateMemberRank(WorldSession* session, std::string_view name, bool demote); + void HandleAddNewRank(WorldSession* session, std::string_view name); void HandleRemoveRank(WorldSession* session, uint8 rankId); void HandleRemoveLowestRank(WorldSession* session); void HandleMemberDepositMoney(WorldSession* session, uint32 amount); @@ -714,7 +716,7 @@ public: void SendEventLog(WorldSession* session) const; void SendBankLog(WorldSession* session, uint8 tabId) const; void SendBankTabsInfo(WorldSession* session, bool showTabs = false) const; - void SendBankTabData(WorldSession* session, uint8 tabId) const; + void SendBankTabData(WorldSession* session, uint8 tabId, bool sendAllSlots) const; void SendBankTabText(WorldSession* session, uint8 tabId) const; void SendPermissions(WorldSession* session) const; void SendMoneyInfo(WorldSession* session) const; @@ -732,17 +734,17 @@ public: bool Validate(); // Broadcasts - void BroadcastToGuild(WorldSession* session, bool officerOnly, std::string const& msg, uint32 language = LANG_UNIVERSAL) const; - void BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const; - void BroadcastPacket(WorldPacket* packet) const; + void BroadcastToGuild(WorldSession* session, bool officerOnly, std::string_view msg, uint32 language = LANG_UNIVERSAL) const; + void BroadcastPacketToRank(WorldPacket const* packet, uint8 rankId) const; + void BroadcastPacket(WorldPacket const* packet) const; void MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, uint32 minRank); template void BroadcastWorker(Do& _do, Player* except = nullptr) { - for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (Player* player = itr->second->FindPlayer()) + for (auto const& m_member : m_members) + if (Player* player = m_member.second.FindPlayer()) if (player != except) _do(player); } @@ -763,7 +765,7 @@ public: time_t GetCreatedDate() const { return m_createdDate; } // Bank tabs - void SetBankTabText(uint8 tabId, std::string const& text); + void SetBankTabText(uint8 tabId, std::string_view text); void ResetTimes(); @@ -782,13 +784,13 @@ protected: uint32 m_accountsNumber; uint64 m_bankMoney; - Ranks m_ranks; - Members m_members; - BankTabs m_bankTabs; + std::vector m_ranks; + std::unordered_map m_members; + std::vector m_bankTabs; // These are actually ordered lists. The first element is the oldest entry. - LogHolder* m_eventLog; - LogHolder* m_bankEventLog[GUILD_BANK_MAX_TABS + 1]; + LogHolder m_eventLog; + std::array, GUILD_BANK_MAX_TABS + 1> m_bankEventLog = {}; private: inline uint8 _GetRanksSize() const { return uint8(m_ranks.size()); } @@ -805,8 +807,8 @@ private: inline uint8 _GetLowestRankId() const { return uint8(m_ranks.size() - 1); } inline uint8 _GetPurchasedTabsSize() const { return uint8(m_bankTabs.size()); } - inline BankTab* GetBankTab(uint8 tabId) { return tabId < m_bankTabs.size() ? m_bankTabs[tabId] : nullptr; } - inline const BankTab* GetBankTab(uint8 tabId) const { return tabId < m_bankTabs.size() ? m_bankTabs[tabId] : nullptr; } + inline BankTab* GetBankTab(uint8 tabId) { return tabId < m_bankTabs.size() ? &m_bankTabs[tabId] : nullptr; } + inline BankTab const* GetBankTab(uint8 tabId) const { return tabId < m_bankTabs.size() ? &m_bankTabs[tabId] : nullptr; } inline void _DeleteMemberFromDB(ObjectGuid::LowType lowguid) const { @@ -815,20 +817,18 @@ private: CharacterDatabase.Execute(stmt); } - // Creates log holders (either when loading or when creating guild) - void _CreateLogHolders(); // Tries to create new bank tab void _CreateNewBankTab(); // Creates default guild ranks with names in given locale void _CreateDefaultGuildRanks(LocaleConstant loc); // Creates new rank - bool _CreateRank(std::string const& name, uint32 rights); + bool _CreateRank(std::string_view name, uint32 rights); // Update account number when member added/removed from guild void _UpdateAccountsNumber(); bool _IsLeader(Player* player) const; void _DeleteBankItems(CharacterDatabaseTransaction trans, bool removeItemsFromDB = false); bool _ModifyBankMoney(CharacterDatabaseTransaction trans, uint64 amount, bool add); - void _SetLeaderGUID(Member* pLeader); + void _SetLeaderGUID(Member& pLeader); void _SetRankBankMoneyPerDay(uint8 rankId, uint32 moneyPerDay); void _SetRankBankTabRightsAndSlots(uint8 rankId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB = true); @@ -838,8 +838,8 @@ private: int32 _GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const; std::string _GetRankName(uint8 rankId) const; - int32 _GetMemberRemainingSlots(Member const* member, uint8 tabId) const; - int32 _GetMemberRemainingMoney(Member const* member) const; + int32 _GetMemberRemainingSlots(Member const& member, uint8 tabId) const; + int32 _GetMemberRemainingMoney(Member const& member) const; void _UpdateMemberWithdrawSlots(CharacterDatabaseTransaction trans, ObjectGuid guid, uint8 tabId); bool _MemberHasTabRights(ObjectGuid guid, uint8 tabId, uint32 rights) const; @@ -851,12 +851,12 @@ private: void _MoveItems(MoveItemData* pSrc, MoveItemData* pDest, uint32 splitedAmount); bool _DoItemsMove(MoveItemData* pSrc, MoveItemData* pDest, bool sendError, uint32 splitedAmount = 0); - void _SendBankContent(WorldSession* session, uint8 tabId) const; + void _SendBankContent(WorldSession* session, uint8 tabId, bool sendAllSlots) const; void _SendBankMoneyUpdate(WorldSession* session) const; void _SendBankContentUpdate(MoveItemData* pSrc, MoveItemData* pDest) const; void _SendBankContentUpdate(uint8 tabId, SlotIds slots) const; void _SendBankList(WorldSession* session = nullptr, uint8 tabId = 0, bool sendFullSlots = false, SlotIds* slots = nullptr) const; - void _BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid = ObjectGuid::Empty, const char* param1 = nullptr, const char* param2 = nullptr, const char* param3 = nullptr) const; + void _BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid = ObjectGuid::Empty, Optional param1 = {}, Optional param2 = {}, Optional param3 = {}) const; }; #endif diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp index 24c7d204f..4ac1dd69b 100644 --- a/src/server/game/Guilds/GuildMgr.cpp +++ b/src/server/game/Guilds/GuildMgr.cpp @@ -63,17 +63,12 @@ Guild* GuildMgr::GetGuildById(uint32 guildId) const return nullptr; } -Guild* GuildMgr::GetGuildByName(const std::string& guildName) const +Guild* GuildMgr::GetGuildByName(std::string_view guildName) const { - std::string search = guildName; - std::transform(search.begin(), search.end(), search.begin(), ::toupper); - for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr) - { - std::string gname = itr->second->GetName(); - std::transform(gname.begin(), gname.end(), gname.begin(), ::toupper); - if (search == gname) - return itr->second; - } + for (auto const& [id, guild] : GuildStore) + if (StringEqualI(guild->GetName(), guildName)) + return guild; + return nullptr; } diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h index 53510696f..ad645d7b6 100644 --- a/src/server/game/Guilds/GuildMgr.h +++ b/src/server/game/Guilds/GuildMgr.h @@ -31,7 +31,7 @@ public: Guild* GetGuildByLeader(ObjectGuid guid) const; Guild* GetGuildById(uint32 guildId) const; - Guild* GetGuildByName(std::string const& guildName) const; + Guild* GetGuildByName(std::string_view guildName) const; std::string GetGuildNameById(uint32 guildId) const; void LoadGuilds(); diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index 820e86dec..ead94c270 100644 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -17,6 +17,7 @@ #include "Guild.h" #include "GuildMgr.h" +#include "GuildPackets.h" #include "Log.h" #include "ObjectMgr.h" #include "Opcodes.h" @@ -31,51 +32,39 @@ void cleanStr(std::string& str) str.erase(remove(str.begin(), str.end(), '|'), str.end()); } -void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildQueryOpcode(WorldPackets::Guild::QueryGuildInfo& query) { - uint32 guildId; - recvPacket >> guildId; - - LOG_DEBUG("guild", "CMSG_GUILD_QUERY [%s]: Guild: %u", GetPlayerInfo().c_str(), guildId); - if (!guildId) + LOG_DEBUG("guild", "CMSG_GUILD_QUERY [%s]: Guild: %u", GetPlayerInfo().c_str(), query.GuildId); + if (!query.GuildId) return; - if (Guild* guild = sGuildMgr->GetGuildById(guildId)) + if (Guild* guild = sGuildMgr->GetGuildById(query.GuildId)) guild->HandleQuery(this); } -void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildCreateOpcode(WorldPackets::Guild::GuildCreate& packet) { - std::string name; - recvPacket >> name; - - LOG_ERROR("network.opcode", "CMSG_GUILD_CREATE: Possible hacking-attempt: %s tried to create a guild [Name: %s] using cheats", GetPlayerInfo().c_str(), name.c_str()); + LOG_ERROR("network.opcode", "CMSG_GUILD_CREATE: Possible hacking-attempt: %s tried to create a guild [Name: %s] using cheats", GetPlayerInfo().c_str(), packet.GuildName.c_str()); } -void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildInviteOpcode(WorldPackets::Guild::GuildInviteByName& packet) { - std::string invitedName; - recvPacket >> invitedName; - - LOG_DEBUG("guild", "CMSG_GUILD_INVITE [%s]: Invited: %s", GetPlayerInfo().c_str(), invitedName.c_str()); - if (normalizePlayerName(invitedName)) + LOG_DEBUG("guild", "CMSG_GUILD_INVITE [%s]: Invited: %s", GetPlayerInfo().c_str(), packet.Name.c_str()); + if (normalizePlayerName(packet.Name)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleInviteMember(this, invitedName); + guild->HandleInviteMember(this, packet.Name); } -void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildRemoveOpcode(WorldPackets::Guild::GuildOfficerRemoveMember& packet) { - std::string playerName; - recvPacket >> playerName; + LOG_DEBUG("guild", "CMSG_GUILD_REMOVE [%s]: Target: %s", GetPlayerInfo().c_str(), packet.Removee.c_str()); - LOG_DEBUG("guild", "CMSG_GUILD_REMOVE [%s]: Target: %s", GetPlayerInfo().c_str(), playerName.c_str()); - - if (normalizePlayerName(playerName)) + if (normalizePlayerName(packet.Removee)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleRemoveMember(this, playerName); + guild->HandleRemoveMember(this, packet.Removee); } -void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/) +void WorldSession::HandleGuildAcceptOpcode(WorldPackets::Guild::AcceptGuildInvite& /*invite*/) { LOG_DEBUG("guild", "CMSG_GUILD_ACCEPT [%s]", GetPlayer()->GetName().c_str()); @@ -84,7 +73,7 @@ void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/) guild->HandleAcceptMember(this); } -void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/) +void WorldSession::HandleGuildDeclineOpcode(WorldPackets::Guild::GuildDeclineInvitation& /*decline*/) { LOG_DEBUG("guild", "CMSG_GUILD_DECLINE [%s]", GetPlayerInfo().c_str()); @@ -97,7 +86,7 @@ void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/) GetPlayer()->SetInGuild(0); } -void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/) +void WorldSession::HandleGuildInfoOpcode(WorldPackets::Guild::GuildGetInfo& /*packet*/) { LOG_DEBUG("guild", "CMSG_GUILD_INFO [%s]", GetPlayerInfo().c_str()); @@ -105,7 +94,7 @@ void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/) guild->SendInfo(this); } -void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/) +void WorldSession::HandleGuildRosterOpcode(WorldPackets::Guild::GuildGetRoster& /*packet*/) { LOG_DEBUG("guild", "CMSG_GUILD_ROSTER [%s]", GetPlayerInfo().c_str()); @@ -115,31 +104,25 @@ void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/) Guild::SendCommandResult(this, GUILD_COMMAND_ROSTER, ERR_GUILD_PLAYER_NOT_IN_GUILD); } -void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildPromoteOpcode(WorldPackets::Guild::GuildPromoteMember& promote) { - std::string playerName; - recvPacket >> playerName; + LOG_DEBUG("guild", "CMSG_GUILD_PROMOTE [%s]: Target: %s", GetPlayerInfo().c_str(), promote.Promotee.c_str()); - LOG_DEBUG("guild", "CMSG_GUILD_PROMOTE [%s]: Target: %s", GetPlayerInfo().c_str(), playerName.c_str()); - - if (normalizePlayerName(playerName)) + if (normalizePlayerName(promote.Promotee)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleUpdateMemberRank(this, playerName, false); + guild->HandleUpdateMemberRank(this, promote.Promotee, false); } -void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildDemoteOpcode(WorldPackets::Guild::GuildDemoteMember& demote) { - std::string playerName; - recvPacket >> playerName; + LOG_DEBUG("guild", "CMSG_GUILD_DEMOTE [%s]: Target: %s", GetPlayerInfo().c_str(), demote.Demotee.c_str()); - LOG_DEBUG("guild", "CMSG_GUILD_DEMOTE [%s]: Target: %s", GetPlayerInfo().c_str(), playerName.c_str()); - - if (normalizePlayerName(playerName)) + if (normalizePlayerName(demote.Demotee)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleUpdateMemberRank(this, playerName, true); + guild->HandleUpdateMemberRank(this, demote.Demotee, true); } -void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/) +void WorldSession::HandleGuildLeaveOpcode(WorldPackets::Guild::GuildLeave& /*leave*/) { LOG_DEBUG("guild", "CMSG_GUILD_LEAVE [%s]", GetPlayerInfo().c_str()); @@ -147,7 +130,7 @@ void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/) guild->HandleLeaveMember(this); } -void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/) +void WorldSession::HandleGuildDisbandOpcode(WorldPackets::Guild::GuildDelete& /*packet*/) { LOG_DEBUG("guild", "CMSG_GUILD_DISBAND [%s]", GetPlayerInfo().c_str()); @@ -155,142 +138,71 @@ void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/) guild->HandleDisband(this); } -void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildLeaderOpcode(WorldPackets::Guild::GuildSetGuildMaster& packet) { - std::string name; - recvPacket >> name; + LOG_DEBUG("guild", "CMSG_GUILD_LEADER [%s]: Target: %s", GetPlayerInfo().c_str(), packet.NewMasterName.c_str()); - LOG_DEBUG("guild", "CMSG_GUILD_LEADER [%s]: Target: %s", GetPlayerInfo().c_str(), name.c_str()); - - if (normalizePlayerName(name)) + if (normalizePlayerName(packet.NewMasterName)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleSetLeader(this, name); + guild->HandleSetLeader(this, packet.NewMasterName); } -void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildMOTDOpcode(WorldPackets::Guild::GuildUpdateMotdText& packet) { - std::string motd; - recvPacket >> motd; - - LOG_DEBUG("guild", "CMSG_GUILD_MOTD [%s]: MOTD: %s", GetPlayerInfo().c_str(), motd.c_str()); - - // Check for overflow - if (motd.length() > 128) - return; - - // Cleanup bad characters - cleanStr(motd); + LOG_DEBUG("guild", "CMSG_GUILD_MOTD [%s]: MOTD: %s", GetPlayerInfo().c_str(), packet.MotdText.c_str()); if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleSetMOTD(this, motd); + guild->HandleSetMOTD(this, packet.MotdText); } -void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPackets::Guild::GuildSetMemberNote& packet) { - std::string playerName; - std::string note; - recvPacket >> playerName >> note; + LOG_DEBUG("guild", "CMSG_GUILD_SET_PUBLIC_NOTE [%s]: Target: %s, Note: %s", GetPlayerInfo().c_str(), packet.NoteeName.c_str(), packet.Note.c_str()); - LOG_DEBUG("guild", "CMSG_GUILD_SET_PUBLIC_NOTE [%s]: Target: %s, Note: %s", GetPlayerInfo().c_str(), playerName.c_str(), note.c_str()); - - // Check for overflow - if (note.length() > 31) - return; - - // Cleanup bad characters - cleanStr(note); - - if (normalizePlayerName(playerName)) + if (normalizePlayerName(packet.NoteeName)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleSetMemberNote(this, playerName, note, true); + guild->HandleSetMemberNote(this, packet.NoteeName, packet.Note, true); } -void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPackets::Guild::GuildSetMemberNote& packet) { - std::string playerName; - std::string note; - recvPacket >> playerName >> note; - LOG_DEBUG("guild", "CMSG_GUILD_SET_OFFICER_NOTE [%s]: Target: %s, Note: %s", - GetPlayerInfo().c_str(), playerName.c_str(), note.c_str()); + GetPlayerInfo().c_str(), packet.NoteeName.c_str(), packet.Note.c_str()); - // Check for overflow - if (note.length() > 31) - return; - - // Cleanup bad characters - cleanStr(note); - - if (normalizePlayerName(playerName)) + if (normalizePlayerName(packet.NoteeName)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleSetMemberNote(this, playerName, note, false); + guild->HandleSetMemberNote(this, packet.NoteeName, packet.Note, false); } -void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildRankOpcode(WorldPackets::Guild::GuildSetRankPermissions& packet) { - uint32 rankId; - recvPacket >> rankId; - - uint32 rights; - recvPacket >> rights; - - std::string rankName; - recvPacket >> rankName; - - uint32 money; - recvPacket >> money; - - LOG_DEBUG("guild", "CMSG_GUILD_RANK [%s]: Rank: %s (%u)", GetPlayerInfo().c_str(), rankName.c_str(), rankId); - Guild* guild = GetPlayer()->GetGuild(); if (!guild) { - recvPacket.rpos(recvPacket.wpos()); return; } - // Check for overflow - if (rankName.length() > 15) - return; - - // Cleanup bad characters - cleanStr(rankName); - - GuildBankRightsAndSlotsVec rightsAndSlots(GUILD_BANK_MAX_TABS); + std::array rightsAndSlots; for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId) { - uint32 bankRights; - uint32 slots; - - recvPacket >> bankRights; - recvPacket >> slots; - - rightsAndSlots[tabId] = GuildBankRightsAndSlots(tabId, bankRights, slots); + rightsAndSlots[tabId] = GuildBankRightsAndSlots(tabId, uint8(packet.TabFlags[tabId]), uint8(packet.TabWithdrawItemLimit[tabId])); } - guild->HandleSetRankInfo(this, rankId, rankName, rights, money, rightsAndSlots); + LOG_DEBUG("guild", "CMSG_GUILD_RANK [%s]: Rank: %s (%u)", GetPlayerInfo().c_str(), packet.RankName.c_str(), packet.RankID); + + guild->HandleSetRankInfo(this, packet.RankID, packet.RankName, packet.Flags, packet.WithdrawGoldLimit, rightsAndSlots); } -void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildAddRankOpcode(WorldPackets::Guild::GuildAddRank& packet) { - std::string rankName; - recvPacket >> rankName; - - LOG_DEBUG("guild", "CMSG_GUILD_ADD_RANK [%s]: Rank: %s", GetPlayerInfo().c_str(), rankName.c_str()); - - // Check for overflow - if (rankName.length() > 15) - return; - - // Cleanup bad characters - cleanStr(rankName); + LOG_DEBUG("guild", "CMSG_GUILD_ADD_RANK [%s]: Rank: %s", GetPlayerInfo().c_str(), packet.Name.c_str()); if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleAddNewRank(this, rankName); + guild->HandleAddNewRank(this, packet.Name); } -void WorldSession::HandleGuildDelRankOpcode(WorldPacket& /*recvPacket*/) +void WorldSession::HandleGuildDelRankOpcode(WorldPackets::Guild::GuildDeleteRank& /*packet*/) { LOG_DEBUG("guild", "CMSG_GUILD_DEL_RANK [%s]", GetPlayerInfo().c_str()); @@ -298,37 +210,24 @@ void WorldSession::HandleGuildDelRankOpcode(WorldPacket& /*recvPacket*/) guild->HandleRemoveLowestRank(this); } -void WorldSession::HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildChangeInfoTextOpcode(WorldPackets::Guild::GuildUpdateInfoText& packet) { - std::string info; - recvPacket >> info; - - LOG_DEBUG("guild", "CMSG_GUILD_INFO_TEXT [%s]: %s", GetPlayerInfo().c_str(), info.c_str()); - - // Check for overflow - if (info.length() > 500) - return; - - // Cleanup bad characters - cleanStr(info); + LOG_DEBUG("guild", "CMSG_GUILD_INFO_TEXT [%s]: %s", GetPlayerInfo().c_str(), packet.InfoText.c_str()); if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleSetInfo(this, info); + guild->HandleSetInfo(this, packet.InfoText); } -void WorldSession::HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket) +void WorldSession::HandleSaveGuildEmblemOpcode(WorldPackets::Guild::SaveGuildEmblem& packet) { - ObjectGuid vendorGuid; - recvPacket >> vendorGuid; - EmblemInfo emblemInfo; - emblemInfo.ReadPacket(recvPacket); + emblemInfo.ReadPacket(packet); LOG_DEBUG("guild", "MSG_SAVE_GUILD_EMBLEM [%s]: Guid: [%s] Style: %d, Color: %d, BorderStyle: %d, BorderColor: %d, BackgroundColor: %d" - , GetPlayerInfo().c_str(), vendorGuid.ToString().c_str(), emblemInfo.GetStyle() + , GetPlayerInfo().c_str(), packet.Vendor.ToString().c_str(), emblemInfo.GetStyle() , emblemInfo.GetColor(), emblemInfo.GetBorderStyle() , emblemInfo.GetBorderColor(), emblemInfo.GetBackgroundColor()); - if (GetPlayer()->GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_TABARDDESIGNER)) + if (GetPlayer()->GetNPCIfCanInteractWith(packet.Vendor, UNIT_NPC_FLAG_TABARDDESIGNER)) { // Remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) @@ -343,7 +242,7 @@ void WorldSession::HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket) Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_INVALIDVENDOR); // "That's not an emblem vendor!" } -void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */) +void WorldSession::HandleGuildEventLogQueryOpcode(WorldPackets::Guild::GuildEventLogQuery& /*packet*/) { LOG_DEBUG("guild", "MSG_GUILD_EVENT_LOG_QUERY [%s]", GetPlayerInfo().c_str()); @@ -351,7 +250,7 @@ void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */) guild->SendEventLog(this); } -void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPacket& /* recvData */) +void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery& /*packet*/) { LOG_DEBUG("guild", "MSG_GUILD_BANK_MONEY_WITHDRAWN [%s]", GetPlayerInfo().c_str()); @@ -359,23 +258,22 @@ void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPacket& /* recvData */) guild->SendMoneyInfo(this); } -void WorldSession::HandleGuildPermissions(WorldPacket& /* recvData */) +void WorldSession::HandleGuildPermissions(WorldPackets::Guild::GuildPermissionsQuery& /* packet */) { - LOG_DEBUG("guild", "MSG_GUILD_PERMISSIONS [%s]", GetPlayerInfo().c_str()); - if (Guild* guild = GetPlayer()->GetGuild()) guild->SendPermissions(this); } // Called when clicking on Guild bank gameobject -void WorldSession::HandleGuildBankerActivate(WorldPacket& recvData) +void WorldSession::HandleGuildBankerActivate(WorldPackets::Guild::GuildBankActivate& packet) { - ObjectGuid guid; - bool sendAllSlots; - recvData >> guid >> sendAllSlots; - LOG_DEBUG("guild", "CMSG_GUILD_BANKER_ACTIVATE [%s]: Go: [%s] AllSlots: %u" - , GetPlayerInfo().c_str(), guid.ToString().c_str(), sendAllSlots); + , GetPlayerInfo().c_str(), packet.Banker.ToString().c_str(), packet.FullUpdate); + + GameObject const* const go = GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK); + if (!go) + return; + Guild* const guild = GetPlayer()->GetGuild(); if (!guild) { @@ -383,122 +281,68 @@ void WorldSession::HandleGuildBankerActivate(WorldPacket& recvData) return; } - guild->SendBankTabsInfo(this, sendAllSlots); + guild->SendBankTabsInfo(this, packet.FullUpdate); } // Called when opening guild bank tab only (first one) -void WorldSession::HandleGuildBankQueryTab(WorldPacket& recvData) +void WorldSession::HandleGuildBankQueryTab(WorldPackets::Guild::GuildBankQueryTab& packet) { - ObjectGuid guid; - uint8 tabId; - bool full; - - recvData >> guid >> tabId >> full; - LOG_DEBUG("guild", "CMSG_GUILD_BANK_QUERY_TAB [%s]: Go: [%s], TabId: %u, ShowTabs: %u" - , GetPlayerInfo().c_str(), guid.ToString().c_str(), tabId, full); - if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK)) + , GetPlayerInfo().c_str(), packet.Banker.ToString().c_str(), packet.Tab, packet.FullUpdate); + + if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->SendBankTabData(this, tabId); + guild->SendBankTabData(this, packet.Tab, packet.FullUpdate); } -void WorldSession::HandleGuildBankDepositMoney(WorldPacket& recvData) +void WorldSession::HandleGuildBankDepositMoney(WorldPackets::Guild::GuildBankDepositMoney& packet) { - ObjectGuid guid; - uint32 money; - recvData >> guid >> money; - LOG_DEBUG("guild", "CMSG_GUILD_BANK_DEPOSIT_MONEY [%s]: Go: [%s], money: %u", - GetPlayerInfo().c_str(), guid.ToString().c_str(), money); - if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK)) - if (money && GetPlayer()->HasEnoughMoney(money)) + GetPlayerInfo().c_str(), packet.Banker.ToString().c_str(), packet.Money); + + if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK)) + if (packet.Money && GetPlayer()->HasEnoughMoney(packet.Money)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleMemberDepositMoney(this, money); + guild->HandleMemberDepositMoney(this, packet.Money); } -void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket& recvData) +void WorldSession::HandleGuildBankWithdrawMoney(WorldPackets::Guild::GuildBankWithdrawMoney& packet) { - ObjectGuid guid; - uint32 money; - recvData >> guid >> money; - LOG_DEBUG("guild", "CMSG_GUILD_BANK_WITHDRAW_MONEY [%s]: Go: [%s], money: %u", - GetPlayerInfo().c_str(), guid.ToString().c_str(), money); - if (money && GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK)) + GetPlayerInfo().c_str(), packet.Banker.ToString().c_str(), packet.Money); + if (packet.Money && GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleMemberWithdrawMoney(this, money); + guild->HandleMemberWithdrawMoney(this, packet.Money); } -void WorldSession::HandleGuildBankSwapItems(WorldPacket& recvData) +void WorldSession::HandleGuildBankSwapItems(WorldPackets::Guild::GuildBankSwapItems& packet) { - LOG_DEBUG("guild", "CMSG_GUILD_BANK_SWAP_ITEMS [%s]", GetPlayerInfo().c_str()); - - ObjectGuid GoGuid; - recvData >> GoGuid; - - if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) + if (!GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK)) { - recvData.rfinish(); // Prevent additional spam at rejected packet return; } Guild* guild = GetPlayer()->GetGuild(); if (!guild) { - recvData.rfinish(); // Prevent additional spam at rejected packet return; } - uint8 bankToBank; - recvData >> bankToBank; - - uint8 tabId; - uint8 slotId; - uint32 itemEntry; - uint32 splitedAmount = 0; - - if (bankToBank) - { - uint8 destTabId; - recvData >> destTabId; - - uint8 destSlotId; - recvData >> destSlotId; - recvData.read_skip(); // Always 0 - - recvData >> tabId; - recvData >> slotId; - recvData >> itemEntry; - recvData.read_skip(); // Always 0 - - recvData >> splitedAmount; - - guild->SwapItems(GetPlayer(), tabId, slotId, destTabId, destSlotId, splitedAmount); - } + if (packet.BankOnly) + guild->SwapItems(GetPlayer(), packet.BankTab1, packet.BankSlot1, packet.BankTab, packet.BankSlot, packet.BankItemCount); else { uint8 playerBag = NULL_BAG; uint8 playerSlotId = NULL_SLOT; uint8 toChar = 1; + uint32 splitedAmount = 0; - recvData >> tabId; - recvData >> slotId; - recvData >> itemEntry; - - uint8 autoStore; - recvData >> autoStore; - if (autoStore) + if (!packet.AutoStore) { - recvData.read_skip(); // autoStoreCount - recvData.read_skip(); // ToChar (?), always and expected to be 1 (autostore only triggered in Bank -> Char) - recvData.read_skip(); // Always 0 - } - else - { - recvData >> playerBag; - recvData >> playerSlotId; - recvData >> toChar; - recvData >> splitedAmount; + playerBag = packet.ContainerSlot; + playerSlotId = packet.ContainerItemSlot; + toChar = packet.ToSlot; + splitedAmount = packet.StackCount; } // Player <-> Bank @@ -506,85 +350,50 @@ void WorldSession::HandleGuildBankSwapItems(WorldPacket& recvData) if (!Player::IsInventoryPos(playerBag, playerSlotId) && !(playerBag == NULL_BAG && playerSlotId == NULL_SLOT)) GetPlayer()->SendEquipError(EQUIP_ERR_NONE, nullptr); else - guild->SwapItemsWithInventory(GetPlayer(), toChar, tabId, slotId, playerBag, playerSlotId, splitedAmount); + guild->SwapItemsWithInventory(GetPlayer(), toChar != 0, packet.BankTab, packet.BankSlot, playerBag, playerSlotId, splitedAmount); } } -void WorldSession::HandleGuildBankBuyTab(WorldPacket& recvData) +void WorldSession::HandleGuildBankBuyTab(WorldPackets::Guild::GuildBankBuyTab& packet) { - ObjectGuid guid; - uint8 tabId; + LOG_DEBUG("guild", "CMSG_GUILD_BANK_BUY_TAB [%s]: [%s[, TabId: %u", GetPlayerInfo().c_str(), packet.Banker .ToString().c_str(), packet.BankTab); - recvData >> guid >> tabId; - - LOG_DEBUG("guild", "CMSG_GUILD_BANK_BUY_TAB [%s]: Go: [%s], TabId: %u", GetPlayerInfo().c_str(), guid.ToString().c_str(), tabId); - - if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK)) + if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleBuyBankTab(this, tabId); + guild->HandleBuyBankTab(this, packet.BankTab); } -void WorldSession::HandleGuildBankUpdateTab(WorldPacket& recvData) +void WorldSession::HandleGuildBankUpdateTab(WorldPackets::Guild::GuildBankUpdateTab& packet) { - ObjectGuid guid; - uint8 tabId; - std::string name, icon; - - recvData >> guid >> tabId >> name >> icon; - LOG_DEBUG("guild", "CMSG_GUILD_BANK_UPDATE_TAB [%s]: Go: [%s], TabId: %u, Name: %s, Icon: %s" - , GetPlayerInfo().c_str(), guid.ToString().c_str(), tabId, name.c_str(), icon.c_str()); + , GetPlayerInfo().c_str(), packet.Banker.ToString().c_str(), packet.BankTab, packet.Name.c_str(), packet.Icon.c_str()); - // Check for overflow - if (name.length() > 16 || icon.length() > 128) - return; - - // Cleanup bad characters - cleanStr(name); - - if (!name.empty() && !icon.empty()) - if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK)) + if (!packet.Name.empty() && !packet.Icon.empty()) + if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK)) if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleSetBankTabInfo(this, tabId, name, icon); + guild->HandleSetBankTabInfo(this, packet.BankTab, packet.Name, packet.Icon); } -void WorldSession::HandleGuildBankLogQuery(WorldPacket& recvData) +void WorldSession::HandleGuildBankLogQuery(WorldPackets::Guild::GuildBankLogQuery& packet) { - uint8 tabId; - recvData >> tabId; - - LOG_DEBUG("guild", "MSG_GUILD_BANK_LOG_QUERY [%s]: TabId: %u", GetPlayerInfo().c_str(), tabId); + LOG_DEBUG("guild", "MSG_GUILD_BANK_LOG_QUERY [%s]: TabId: %u", GetPlayerInfo().c_str(), packet.Tab); if (Guild* guild = GetPlayer()->GetGuild()) - guild->SendBankLog(this, tabId); + guild->SendBankLog(this, packet.Tab); } -void WorldSession::HandleQueryGuildBankTabText(WorldPacket& recvData) +void WorldSession::HandleQueryGuildBankTabText(WorldPackets::Guild::GuildBankTextQuery& packet) { - uint8 tabId; - recvData >> tabId; - - LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [%s]: TabId: %u", GetPlayerInfo().c_str(), tabId); + LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [%s]: TabId: %u", GetPlayerInfo().c_str(), packet.Tab); if (Guild* guild = GetPlayer()->GetGuild()) - guild->SendBankTabText(this, tabId); + guild->SendBankTabText(this, packet.Tab); } -void WorldSession::HandleSetGuildBankTabText(WorldPacket& recvData) +void WorldSession::HandleSetGuildBankTabText(WorldPackets::Guild::GuildBankSetTabText& packet) { - uint8 tabId; - std::string text; - recvData >> tabId >> text; - - LOG_DEBUG("guild", "CMSG_SET_GUILD_BANK_TEXT [%s]: TabId: %u, Text: %s", GetPlayerInfo().c_str(), tabId, text.c_str()); - - // Check for overflow - if (text.length() > 500) - return; - - // Cleanup bad characters - cleanStr(text); + LOG_DEBUG("guild", "CMSG_SET_GUILD_BANK_TEXT [%s]: TabId: %u, Text: %s", GetPlayerInfo().c_str(), packet.Tab, packet.TabText.c_str()); if (Guild* guild = GetPlayer()->GetGuild()) - guild->SetBankTabText(tabId, text); + guild->SetBankTabText(packet.Tab, packet.TabText); } diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index c03922b66..a31f459e1 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -18,4 +18,6 @@ #ifndef AllPackets_h__ #define AllPackets_h__ +#include "GuildPackets.h" + #endif // AllPackets_h__ diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp new file mode 100644 index 000000000..cbb1aeeb5 --- /dev/null +++ b/src/server/game/Server/Packets/GuildPackets.cpp @@ -0,0 +1,458 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 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 Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "GuildPackets.h" + +void WorldPackets::Guild::QueryGuildInfo::Read() +{ + _worldPacket >> GuildId; +} + +WorldPackets::Guild::QueryGuildInfoResponse::QueryGuildInfoResponse() + : ServerPacket(SMSG_GUILD_QUERY_RESPONSE) { } + +WorldPacket const* WorldPackets::Guild::QueryGuildInfoResponse::Write() +{ + _worldPacket << GuildId; + _worldPacket << Info.GuildName; + for (std::string const& rankName : Info.Ranks) + _worldPacket << rankName; + + _worldPacket << uint32(Info.EmblemStyle); + _worldPacket << uint32(Info.EmblemColor); + _worldPacket << uint32(Info.BorderStyle); + _worldPacket << uint32(Info.BorderColor); + _worldPacket << uint32(Info.BackgroundColor); + _worldPacket << uint32(Info.RankCount); + + return &_worldPacket; +} + +void WorldPackets::Guild::GuildCreate::Read() +{ + _worldPacket >> GuildName; +} + +WorldPacket const* WorldPackets::Guild::GuildInfoResponse::Write() +{ + _worldPacket << GuildName; + _worldPacket.AppendPackedTime(CreateDate); + _worldPacket << int32(NumMembers); + _worldPacket << int32(NumAccounts); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Guild::GuildRoster::Write() +{ + _worldPacket << uint32(MemberData.size()); + _worldPacket << WelcomeText; + _worldPacket << InfoText; + _worldPacket << uint32(RankData.size()); + + for (GuildRankData const& rank : RankData) + _worldPacket << rank; + + for (GuildRosterMemberData const& member : MemberData) + _worldPacket << member; + + return &_worldPacket; +} + +void WorldPackets::Guild::GuildUpdateMotdText::Read() +{ + _worldPacket >> MotdText; +} + +WorldPacket const* WorldPackets::Guild::GuildCommandResult::Write() +{ + _worldPacket << int32(Command); + _worldPacket << Name; + _worldPacket << int32(Result); + + return &_worldPacket; +} + +void WorldPackets::Guild::GuildInviteByName::Read() +{ + _worldPacket >> Name; +} + +WorldPacket const* WorldPackets::Guild::GuildInvite::Write() +{ + _worldPacket << InviterName; + _worldPacket << GuildName; + + return &_worldPacket; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRosterMemberData const& rosterMemberData) +{ + data << rosterMemberData.Guid; + data << uint8(rosterMemberData.Status); + data << rosterMemberData.Name; + data << int32(rosterMemberData.RankID); + data << uint8(rosterMemberData.Level); + data << uint8(rosterMemberData.ClassID); + data << uint8(rosterMemberData.Gender); + data << int32(rosterMemberData.AreaID); + if (!rosterMemberData.Status) + data << float(rosterMemberData.LastSave); + + data << rosterMemberData.Note; + data << rosterMemberData.OfficerNote; + + return data; +} + +WorldPacket const* WorldPackets::Guild::GuildEvent::Write() +{ + _worldPacket << uint8(Type); + _worldPacket << uint8(Params.size()); + for (std::string_view param : Params) + _worldPacket << param; + + switch (Type) + { + case GE_JOINED: + case GE_LEFT: + case GE_SIGNED_ON: + case GE_SIGNED_OFF: + _worldPacket << Guid; + break; + default: + break; + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Guild::GuildEventLogQueryResults::Write() +{ + _worldPacket.reserve(1 + Entry.size() * sizeof(GuildEventEntry)); + + _worldPacket << uint8(Entry.size()); + + for (GuildEventEntry const& entry : Entry) + { + _worldPacket << uint8(entry.TransactionType); + _worldPacket << entry.PlayerGUID; + if (entry.TransactionType != GUILD_EVENT_LOG_JOIN_GUILD && entry.TransactionType != GUILD_EVENT_LOG_LEAVE_GUILD) + _worldPacket << entry.OtherGUID; + if (entry.TransactionType == GUILD_EVENT_LOG_PROMOTE_PLAYER || entry.TransactionType == GUILD_EVENT_LOG_DEMOTE_PLAYER) + _worldPacket << uint8(entry.RankID); + _worldPacket << uint32(entry.TransactionDate); + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Guild::GuildPermissionsQueryResults::Write() +{ + _worldPacket << uint32(RankID); + _worldPacket << int32(Flags); + _worldPacket << int32(WithdrawGoldLimit); + _worldPacket << int8(NumTabs); + + for (GuildRankTabPermissions const& tab : Tab) + { + _worldPacket << int32(tab.Flags); + _worldPacket << int32(tab.WithdrawItemLimit); + } + + return &_worldPacket; +} + +void WorldPackets::Guild::GuildSetRankPermissions::Read() +{ + _worldPacket >> RankID; + _worldPacket >> Flags; + _worldPacket >> RankName; + _worldPacket >> WithdrawGoldLimit; + + for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; i++) + { + _worldPacket >> TabFlags[i]; + _worldPacket >> TabWithdrawItemLimit[i]; + } +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRankData const& rankData) +{ + data << uint32(rankData.Flags); + data << uint32(rankData.WithdrawGoldLimit); + + for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; i++) + { + data << uint32(rankData.TabFlags[i]); + data << uint32(rankData.TabWithdrawItemLimit[i]); + } + + return data; +} + +void WorldPackets::Guild::GuildAddRank::Read() +{ + _worldPacket >> Name; +} + +void WorldPackets::Guild::GuildUpdateInfoText::Read() +{ + _worldPacket >> InfoText; +} + +void WorldPackets::Guild::GuildSetMemberNote::Read() +{ + _worldPacket >> NoteeName; + _worldPacket >> Note; +} + +void WorldPackets::Guild::GuildDemoteMember::Read() +{ + _worldPacket >> Demotee; +} + +void WorldPackets::Guild::GuildPromoteMember::Read() +{ + _worldPacket >> Promotee; +} + +void WorldPackets::Guild::GuildOfficerRemoveMember::Read() +{ + _worldPacket >> Removee; +} + +void WorldPackets::Guild::GuildBankActivate::Read() +{ + _worldPacket >> Banker; + _worldPacket >> FullUpdate; +} + +void WorldPackets::Guild::GuildBankBuyTab::Read() +{ + _worldPacket >> Banker; + _worldPacket >> BankTab; +} + +void WorldPackets::Guild::GuildBankUpdateTab::Read() +{ + _worldPacket >> Banker; + _worldPacket >> BankTab; + _worldPacket >> Name; + _worldPacket >> Icon; +} + +void WorldPackets::Guild::GuildBankDepositMoney::Read() +{ + _worldPacket >> Banker; + _worldPacket >> Money; +} + +void WorldPackets::Guild::GuildBankQueryTab::Read() +{ + _worldPacket >> Banker; + _worldPacket >> Tab; + _worldPacket >> FullUpdate; +} + +WorldPacket const* WorldPackets::Guild::GuildBankRemainingWithdrawMoney::Write() +{ + _worldPacket << RemainingWithdrawMoney; + + return &_worldPacket; +} + +void WorldPackets::Guild::GuildBankWithdrawMoney::Read() +{ + _worldPacket >> Banker; + _worldPacket >> Money; +} + +WorldPacket const* WorldPackets::Guild::GuildBankQueryResults::Write() +{ + _worldPacket << uint64(Money); + _worldPacket << uint8(Tab); + _withdrawalsRemainingPos = _worldPacket.wpos(); + _worldPacket << int32(WithdrawalsRemaining); + _worldPacket << uint8(FullUpdate); + + if (!Tab && FullUpdate) + { + _worldPacket << uint8(TabInfo.size()); + for (GuildBankTabInfo const& tab : TabInfo) + { + _worldPacket << tab.Name; + _worldPacket << tab.Icon; + } + } + + _worldPacket << uint8(ItemInfo.size()); + for (GuildBankItemInfo const& item : ItemInfo) + { + _worldPacket << uint8(item.Slot); + _worldPacket << uint32(item.ItemID); + if (item.ItemID) + { + _worldPacket << int32(item.Flags); + _worldPacket << int32(item.RandomPropertiesID); + if (item.RandomPropertiesID) + _worldPacket << int32(item.RandomPropertiesSeed); + + _worldPacket << int32(item.Count); + _worldPacket << int32(item.EnchantmentID); + _worldPacket << uint8(item.Charges); + _worldPacket << uint8(item.SocketEnchant.size()); + + for (GuildBankSocketEnchant const& socketEnchant : item.SocketEnchant) + { + _worldPacket << uint8(socketEnchant.SocketIndex); + _worldPacket << int32(socketEnchant.SocketEnchantID); + } + } + } + + return &_worldPacket; +} + +void WorldPackets::Guild::GuildBankQueryResults::SetWithdrawalsRemaining(int32 withdrawalsRemaining) +{ + WithdrawalsRemaining = withdrawalsRemaining; + _worldPacket.put(_withdrawalsRemainingPos, withdrawalsRemaining); +} + +void WorldPackets::Guild::GuildBankSwapItems::Read() +{ + _worldPacket >> Banker; + _worldPacket >> BankOnly; + + if (BankOnly) + { + // dest + _worldPacket >> BankTab; + _worldPacket >> BankSlot; + _worldPacket >> ItemID; + + // src + _worldPacket >> BankTab1; + _worldPacket >> BankSlot1; + _worldPacket >> ItemID1; + + _worldPacket >> AutoStore; + _worldPacket >> BankItemCount; + } + else + { + _worldPacket >> BankTab; + _worldPacket >> BankSlot; + _worldPacket >> ItemID; + + _worldPacket >> AutoStore; + if (AutoStore) + { + _worldPacket >> BankItemCount; + _worldPacket >> ToSlot; + _worldPacket >> StackCount; + } + else + { + _worldPacket >> ContainerSlot; + _worldPacket >> ContainerItemSlot; + _worldPacket >> ToSlot; + _worldPacket >> StackCount; + } + } +} + +void WorldPackets::Guild::GuildBankLogQuery::Read() +{ + _worldPacket >> Tab; +} + +WorldPacket const* WorldPackets::Guild::GuildBankLogQueryResults::Write() +{ + _worldPacket << uint8(Tab); + _worldPacket << uint8(Entry.size()); + + for (GuildBankLogEntry const& logEntry : Entry) + { + _worldPacket << int8(logEntry.EntryType); + _worldPacket << logEntry.PlayerGUID; + + switch (logEntry.EntryType) + { + case GUILD_BANK_LOG_DEPOSIT_ITEM: + case GUILD_BANK_LOG_WITHDRAW_ITEM: + _worldPacket << uint32(logEntry.ItemID); + _worldPacket << uint32(logEntry.Count); + break; + case GUILD_BANK_LOG_MOVE_ITEM: + case GUILD_BANK_LOG_MOVE_ITEM2: + _worldPacket << uint32(logEntry.ItemID); + _worldPacket << uint32(logEntry.Count); + _worldPacket << uint8(logEntry.OtherTab); + break; + default: + _worldPacket << uint32(logEntry.Money); + break; + } + + _worldPacket << uint32(logEntry.TimeOffset); + } + + return &_worldPacket; +} + +void WorldPackets::Guild::GuildBankTextQuery::Read() +{ + _worldPacket >> Tab; +} + +WorldPacket const* WorldPackets::Guild::GuildBankTextQueryResult::Write() +{ + _worldPacket << uint8(Tab); + _worldPacket << Text; + + return &_worldPacket; +} + +void WorldPackets::Guild::GuildBankSetTabText::Read() +{ + _worldPacket >> Tab; + _worldPacket >> TabText; +} + +void WorldPackets::Guild::GuildSetGuildMaster::Read() +{ + _worldPacket >> NewMasterName; +} + +void WorldPackets::Guild::SaveGuildEmblem::Read() +{ + _worldPacket >> Vendor; + _worldPacket >> EStyle; + _worldPacket >> EColor; + _worldPacket >> BStyle; + _worldPacket >> BColor; + _worldPacket >> Bg; +} + +WorldPacket const* WorldPackets::Guild::PlayerSaveGuildEmblem::Write() +{ + _worldPacket << int32(Error); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/GuildPackets.h b/src/server/game/Server/Packets/GuildPackets.h new file mode 100644 index 000000000..8d57839c3 --- /dev/null +++ b/src/server/game/Server/Packets/GuildPackets.h @@ -0,0 +1,628 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 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 Affero 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 . + */ +#ifndef GuildPackets_h__ +#define GuildPackets_h__ + +#include "Packet.h" +#include "Guild.h" +#include "ObjectGuid.h" +#include "PacketUtilities.h" +#include +#include + +namespace WorldPackets +{ + namespace Guild + { + class QueryGuildInfo final : public ClientPacket + { + public: + QueryGuildInfo(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_QUERY, std::move(packet)) { } + + void Read() override; + + uint32 GuildId = 0; + }; + + struct GuildInfo + { + std::string GuildName; + + std::array Ranks; + uint32 RankCount = 0; + + uint32 EmblemStyle = 0; + uint32 EmblemColor = 0; + uint32 BorderStyle = 0; + uint32 BorderColor = 0; + uint32 BackgroundColor = 0; + }; + + class QueryGuildInfoResponse final : public ServerPacket + { + public: + QueryGuildInfoResponse(); + + WorldPacket const* Write() override; + + uint32 GuildId = 0; + GuildInfo Info; + }; + + class GuildCreate final : public ClientPacket + { + public: + GuildCreate(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_CREATE, std::move(packet)) { } + + void Read() override; + + std::string GuildName; + }; + + class GuildGetInfo final : ClientPacket + { + public: + GuildGetInfo(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_INFO, std::move(packet)) { } + + void Read() override { } + }; + + class GuildInfoResponse final : ServerPacket + { + public: + GuildInfoResponse() : ServerPacket(SMSG_GUILD_INFO, 123) { } + + WorldPacket const* Write() override; + + std::string GuildName; + time_t CreateDate = time_t(0); + int32 NumMembers = 0; + int32 NumAccounts = 0; + }; + + class GuildGetRoster final : public ClientPacket + { + public: + GuildGetRoster(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_ROSTER, std::move(packet)) { } + + void Read() override { } + }; + + struct GuildRosterMemberData + { + ObjectGuid Guid; + int64 WeeklyXP = 0; + int64 TotalXP = 0; + int32 RankID = 0; + int32 AreaID = 0; + float LastSave = 0.0f; + std::string Name; + std::string Note; + std::string OfficerNote; + uint8 Status = 0; + uint8 Level = 0; + uint8 ClassID = 0; + uint8 Gender = 0; + }; + + struct GuildRankData + { + uint32 Flags = 0; + uint32 WithdrawGoldLimit = 0; + uint32 TabFlags[GUILD_BANK_MAX_TABS]; + uint32 TabWithdrawItemLimit[GUILD_BANK_MAX_TABS]; + }; + + class GuildRoster final : public ServerPacket + { + public: + GuildRoster() : ServerPacket(SMSG_GUILD_ROSTER, 4 + 4 + 4 + 4) { } + + WorldPacket const* Write() override; + + std::vector MemberData; + std::vector RankData; + std::string WelcomeText; + std::string InfoText; + }; + + class GuildUpdateMotdText final : public ClientPacket + { + public: + GuildUpdateMotdText(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_MOTD, std::move(packet)) { } + + void Read() override; + + String<128, Strings::NoHyperlinks> MotdText; + }; + + class GuildCommandResult final : public ServerPacket + { + public: + GuildCommandResult() : ServerPacket(SMSG_GUILD_COMMAND_RESULT, 9) { } + + WorldPacket const* Write() override; + + std::string Name; + int32 Result = 0; + int32 Command = 0; + }; + + class AcceptGuildInvite final : public ClientPacket + { + public: + AcceptGuildInvite(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_ACCEPT, std::move(packet)) { } + + void Read() override { } + }; + + class GuildDeclineInvitation final : public ClientPacket + { + public: + GuildDeclineInvitation(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_DECLINE, std::move(packet)) { } + + void Read() override { } + }; + + class GuildInviteByName final : public ClientPacket + { + public: + GuildInviteByName(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_INVITE, std::move(packet)) { } + + void Read() override; + + String<48> Name; + }; + + class GuildInvite final : public ServerPacket + { + public: + GuildInvite() : ServerPacket(SMSG_GUILD_INVITE, 144) { } + + WorldPacket const* Write() override; + + std::string InviterName; + std::string GuildName; + }; + + class GuildEvent final : public ServerPacket + { + public: + GuildEvent() : ServerPacket(SMSG_GUILD_EVENT) { } + + WorldPacket const* Write() override; + + uint8 Type = 0; + boost::container::static_vector Params; + ObjectGuid Guid; + }; + + struct GuildEventEntry + { + ObjectGuid PlayerGUID; + ObjectGuid OtherGUID; + uint8 TransactionType = 0; + uint8 RankID = 0; + uint32 TransactionDate = 0; + }; + + class GuildEventLogQuery final : public ClientPacket + { + public: + GuildEventLogQuery(WorldPacket&& packet) : ClientPacket(MSG_GUILD_EVENT_LOG_QUERY, std::move(packet)) { } + + void Read() override { } + }; + + class GuildEventLogQueryResults final : public ServerPacket + { + public: + GuildEventLogQueryResults() : ServerPacket(MSG_GUILD_EVENT_LOG_QUERY, 4) { } + + WorldPacket const* Write() override; + + std::vector Entry; + }; + + class GuildPermissionsQuery final : public ClientPacket + { + public: + GuildPermissionsQuery(WorldPacket&& packet) : ClientPacket(MSG_GUILD_PERMISSIONS, std::move(packet)) { } + + void Read() override { } + }; + + class GuildPermissionsQueryResults final : public ServerPacket + { + public: + struct GuildRankTabPermissions + { + int32 Flags = 0; + int32 WithdrawItemLimit = 0; + }; + + GuildPermissionsQueryResults() : ServerPacket(MSG_GUILD_PERMISSIONS, 20) { } + + WorldPacket const* Write() override; + + int8 NumTabs = 0; + int32 WithdrawGoldLimit = 0; + int32 Flags = 0; + uint32 RankID = 0; + std::array Tab; + }; + + class GuildSetRankPermissions final : public ClientPacket + { + public: + GuildSetRankPermissions(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_RANK, std::move(packet)) { } + + void Read() override; + + uint32 RankID = 0; + uint32 WithdrawGoldLimit = 0; + uint32 Flags = 0; + uint32 TabFlags[GUILD_BANK_MAX_TABS]; + uint32 TabWithdrawItemLimit[GUILD_BANK_MAX_TABS]; + String<15, Strings::NoHyperlinks> RankName; + }; + + class GuildAddRank final : public ClientPacket + { + public: + GuildAddRank(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_ADD_RANK, std::move(packet)) { } + + void Read() override; + + String<15, Strings::NoHyperlinks> Name; + }; + + class GuildDeleteRank final : public ClientPacket + { + public: + GuildDeleteRank(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_DEL_RANK, std::move(packet)) { } + + void Read() override { } + }; + + class GuildUpdateInfoText final : public ClientPacket + { + public: + GuildUpdateInfoText(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_INFO_TEXT, std::move(packet)) { } + + void Read() override; + + String<500, Strings::NoHyperlinks> InfoText; + }; + + class GuildSetMemberNote final : public ClientPacket + { + public: + GuildSetMemberNote(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + + void Read() override; + + std::string NoteeName; + String<31, Strings::NoHyperlinks> Note; + }; + + class GuildDelete final : public ClientPacket + { + public: + GuildDelete(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_DISBAND, std::move(packet)) { } + + void Read() override { } + }; + + class GuildDemoteMember final : public ClientPacket + { + public: + GuildDemoteMember(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_DEMOTE, std::move(packet)) { } + + void Read() override; + + std::string Demotee; + }; + + class GuildPromoteMember final : public ClientPacket + { + public: + GuildPromoteMember(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_PROMOTE, std::move(packet)) { } + + void Read() override; + + std::string Promotee; + }; + + class GuildOfficerRemoveMember : public ClientPacket + { + public: + GuildOfficerRemoveMember(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_REMOVE, std::move(packet)) { } + + void Read() override; + + std::string Removee; + }; + + class GuildLeave final : public ClientPacket + { + public: + GuildLeave(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_LEAVE, std::move(packet)) { } + + void Read() override { } + }; + + class GuildBankActivate final : public ClientPacket + { + public: + GuildBankActivate(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANKER_ACTIVATE, std::move(packet)) { } + + void Read() override; + + ObjectGuid Banker; + bool FullUpdate = false; + }; + + class GuildBankBuyTab final : public ClientPacket + { + public: + GuildBankBuyTab(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_BUY_TAB, std::move(packet)) { } + + void Read() override; + + ObjectGuid Banker; + uint8 BankTab = 0; + }; + + class GuildBankUpdateTab final : public ClientPacket + { + public: + GuildBankUpdateTab(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_UPDATE_TAB, std::move(packet)) { } + + void Read() override; + + ObjectGuid Banker; + uint8 BankTab = 0; + String<16, Strings::NoHyperlinks> Name; + String<100> Icon; + }; + + class GuildBankDepositMoney final : public ClientPacket + { + public: + GuildBankDepositMoney(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_DEPOSIT_MONEY, std::move(packet)) { } + + void Read() override; + + ObjectGuid Banker; + uint32 Money = 0; + }; + + class GuildBankQueryTab final : public ClientPacket + { + public: + GuildBankQueryTab(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_QUERY_TAB, std::move(packet)) { } + + void Read() override; + + ObjectGuid Banker; + uint8 Tab = 0; + bool FullUpdate = false; + }; + + class GuildBankRemainingWithdrawMoneyQuery final : public ClientPacket + { + public: + GuildBankRemainingWithdrawMoneyQuery(WorldPacket&& packet) : ClientPacket(MSG_GUILD_BANK_MONEY_WITHDRAWN, std::move(packet)) { } + + void Read() override { } + }; + + class GuildBankRemainingWithdrawMoney final : public ServerPacket + { + public: + GuildBankRemainingWithdrawMoney() : ServerPacket(MSG_GUILD_BANK_MONEY_WITHDRAWN, 8) { } + + WorldPacket const* Write() override; + + int32 RemainingWithdrawMoney = 0; + }; + + class GuildBankWithdrawMoney final : public ClientPacket + { + public: + GuildBankWithdrawMoney(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_WITHDRAW_MONEY, std::move(packet)) { } + + void Read() override; + + ObjectGuid Banker; + uint32 Money = 0; + }; + + struct GuildBankSocketEnchant + { + uint8 SocketIndex = 0; + int32 SocketEnchantID = 0; + }; + + struct GuildBankItemInfo + { + uint32 ItemID = 0; + int32 RandomPropertiesSeed = 0; + int32 RandomPropertiesID = 0; + uint8 Slot = 0; + int32 Count = 0; + int32 EnchantmentID = 0; + int32 Charges = 0; + int32 Flags = 0; + std::vector SocketEnchant; + }; + + struct GuildBankTabInfo + { + std::string Name; + std::string Icon; + }; + + class GuildBankQueryResults final : public ServerPacket + { + public: + GuildBankQueryResults() : ServerPacket(SMSG_GUILD_BANK_LIST, 25) { } + + WorldPacket const* Write() override; + + std::vector ItemInfo; + std::vector TabInfo; + int32 WithdrawalsRemaining = 0; + uint8 Tab = 0; + uint64 Money = 0; + bool FullUpdate = false; + + void SetWithdrawalsRemaining(int32 withdrawalsRemaining); + + private: + std::size_t _withdrawalsRemainingPos = 0; + }; + + class GuildBankSwapItems final : public ClientPacket + { + public: + GuildBankSwapItems(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_BANK_SWAP_ITEMS, std::move(packet)) { } + + void Read() override; + + ObjectGuid Banker; + int32 StackCount = 0; + int32 BankItemCount = 0; + uint32 ItemID = 0; + uint32 ItemID1 = 0; + uint8 ToSlot = 0; + uint8 BankSlot = 0; + uint8 BankSlot1 = 0; + uint8 BankTab = 0; + uint8 BankTab1 = 0; + uint8 ContainerSlot = 0; + uint8 ContainerItemSlot = 0; + bool AutoStore = false; + bool BankOnly = false; + }; + + class GuildBankLogQuery final : public ClientPacket + { + public: + GuildBankLogQuery(WorldPacket&& packet) : ClientPacket(MSG_GUILD_BANK_LOG_QUERY, std::move(packet)) { } + + void Read() override; + + uint8 Tab = 0; + }; + + struct GuildBankLogEntry + { + ObjectGuid PlayerGUID; + uint32 TimeOffset = 0; + int8 EntryType = 0; + uint32 Money = 0; + int32 ItemID = 0; + int32 Count = 0; + int8 OtherTab = 0; + }; + + class GuildBankLogQueryResults final : public ServerPacket + { + public: + GuildBankLogQueryResults() : ServerPacket(MSG_GUILD_BANK_LOG_QUERY, 25) { } + + WorldPacket const* Write() override; + + uint8 Tab = 0; + std::vector Entry; + }; + + class GuildBankTextQuery final : public ClientPacket + { + public: + GuildBankTextQuery(WorldPacket&& packet) : ClientPacket(MSG_QUERY_GUILD_BANK_TEXT, std::move(packet)) { } + + void Read() override; + + uint8 Tab = 0; + }; + + class GuildBankTextQueryResult : public ServerPacket + { + public: + GuildBankTextQueryResult() : ServerPacket(MSG_QUERY_GUILD_BANK_TEXT, 4 + 2) { } + + WorldPacket const* Write() override; + + uint8 Tab = 0; + std::string Text; + }; + + class GuildBankSetTabText final : public ClientPacket + { + public: + GuildBankSetTabText(WorldPacket&& packet) : ClientPacket(CMSG_SET_GUILD_BANK_TEXT, std::move(packet)) { } + + void Read() override; + + uint8 Tab = 0; + String<500, Strings::NoHyperlinks> TabText; + }; + + class GuildSetGuildMaster final : public ClientPacket + { + public: + GuildSetGuildMaster(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_LEADER, std::move(packet)) { } + + void Read() override; + + std::string NewMasterName; + }; + + class SaveGuildEmblem final : public ClientPacket + { + public: + SaveGuildEmblem(WorldPacket&& packet) : ClientPacket(MSG_SAVE_GUILD_EMBLEM, std::move(packet)) { } + + void Read() override; + + ObjectGuid Vendor; + int32 BStyle = 0; + int32 EStyle = 0; + int32 BColor = 0; + int32 EColor = 0; + int32 Bg = 0; + }; + + class PlayerSaveGuildEmblem final : public ServerPacket + { + public: + PlayerSaveGuildEmblem() : ServerPacket(MSG_SAVE_GUILD_EMBLEM, 4) { } + + WorldPacket const* Write() override; + + int32 Error = 0; + }; + } +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRosterMemberData const& rosterMemberData); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRankData const& rankData); + +#endif // GuildPackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 532b10c66..7a0530571 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -20,7 +20,7 @@ #include "WorldSession.h" #include #include -//#include "Packets/AllPackets.h" +#include "Packets/AllPackets.h" template class PacketHandler : public ClientOpcodeHandler diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 1b3250a01..668cb9a5d 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -71,6 +71,42 @@ namespace lfg namespace WorldPackets { + namespace Guild + { + class QueryGuildInfo; + class GuildCreate; + class GuildInviteByName; + class AcceptGuildInvite; + class GuildDeclineInvitation; + class GuildGetInfo; + class GuildGetRoster; + class GuildPromoteMember; + class GuildDemoteMember; + class GuildOfficerRemoveMember; + class GuildLeave; + class GuildDelete; + class GuildUpdateMotdText; + class GuildAddRank; + class GuildDeleteRank; + class GuildUpdateInfoText; + class GuildSetMemberNote; + class GuildEventLogQuery; + class GuildBankRemainingWithdrawMoneyQuery; + class GuildPermissionsQuery; + class GuildSetRankPermissions; + class GuildBankActivate; + class GuildBankQueryTab; + class GuildBankDepositMoney; + class GuildBankWithdrawMoney; + class GuildBankSwapItems; + class GuildBankBuyTab; + class GuildBankUpdateTab; + class GuildBankLogQuery; + class GuildBankTextQuery; + class GuildBankSetTabText; + class GuildSetGuildMaster; + class SaveGuildEmblem; + } } enum AccountDataType @@ -602,28 +638,28 @@ public: // opcodes handlers void HandleOfferPetitionOpcode(WorldPacket& recvData); void HandleTurnInPetitionOpcode(WorldPacket& recvData); - void HandleGuildQueryOpcode(WorldPacket& recvPacket); - void HandleGuildCreateOpcode(WorldPacket& recvPacket); - void HandleGuildInviteOpcode(WorldPacket& recvPacket); - void HandleGuildRemoveOpcode(WorldPacket& recvPacket); - void HandleGuildAcceptOpcode(WorldPacket& recvPacket); - void HandleGuildDeclineOpcode(WorldPacket& recvPacket); - void HandleGuildInfoOpcode(WorldPacket& recvPacket); - void HandleGuildEventLogQueryOpcode(WorldPacket& recvPacket); - void HandleGuildRosterOpcode(WorldPacket& recvPacket); - void HandleGuildPromoteOpcode(WorldPacket& recvPacket); - void HandleGuildDemoteOpcode(WorldPacket& recvPacket); - void HandleGuildLeaveOpcode(WorldPacket& recvPacket); - void HandleGuildDisbandOpcode(WorldPacket& recvPacket); - void HandleGuildLeaderOpcode(WorldPacket& recvPacket); - void HandleGuildMOTDOpcode(WorldPacket& recvPacket); - void HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket); - void HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket); - void HandleGuildRankOpcode(WorldPacket& recvPacket); - void HandleGuildAddRankOpcode(WorldPacket& recvPacket); - void HandleGuildDelRankOpcode(WorldPacket& recvPacket); - void HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket); - void HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket); + void HandleGuildQueryOpcode(WorldPackets::Guild::QueryGuildInfo& query); + void HandleGuildCreateOpcode(WorldPackets::Guild::GuildCreate& packet); + void HandleGuildInviteOpcode(WorldPackets::Guild::GuildInviteByName& packet); + void HandleGuildRemoveOpcode(WorldPackets::Guild::GuildOfficerRemoveMember& packet); + void HandleGuildAcceptOpcode(WorldPackets::Guild::AcceptGuildInvite& invite); + void HandleGuildDeclineOpcode(WorldPackets::Guild::GuildDeclineInvitation& decline); + void HandleGuildInfoOpcode(WorldPackets::Guild::GuildGetInfo& packet); + void HandleGuildEventLogQueryOpcode(WorldPackets::Guild::GuildEventLogQuery& packet); + void HandleGuildRosterOpcode(WorldPackets::Guild::GuildGetRoster& packet); + void HandleGuildPromoteOpcode(WorldPackets::Guild::GuildPromoteMember& promote); + void HandleGuildDemoteOpcode(WorldPackets::Guild::GuildDemoteMember& demote); + void HandleGuildLeaveOpcode(WorldPackets::Guild::GuildLeave& leave); + void HandleGuildDisbandOpcode(WorldPackets::Guild::GuildDelete& packet); + void HandleGuildLeaderOpcode(WorldPackets::Guild::GuildSetGuildMaster& packet); + void HandleGuildMOTDOpcode(WorldPackets::Guild::GuildUpdateMotdText& packet); + void HandleGuildSetPublicNoteOpcode(WorldPackets::Guild::GuildSetMemberNote& packet); + void HandleGuildSetOfficerNoteOpcode(WorldPackets::Guild::GuildSetMemberNote& packet); + void HandleGuildRankOpcode(WorldPackets::Guild::GuildSetRankPermissions& packet); + void HandleGuildAddRankOpcode(WorldPackets::Guild::GuildAddRank& packet); + void HandleGuildDelRankOpcode(WorldPackets::Guild::GuildDeleteRank& packet); + void HandleGuildChangeInfoTextOpcode(WorldPackets::Guild::GuildUpdateInfoText& packet); + void HandleSaveGuildEmblemOpcode(WorldPackets::Guild::SaveGuildEmblem& packet); void HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvPacket); void HandleTaxiQueryAvailableNodes(WorldPacket& recvPacket); @@ -913,19 +949,19 @@ public: // opcodes handlers void HandleSetTaxiBenchmarkOpcode(WorldPacket& recvData); // Guild Bank - void HandleGuildPermissions(WorldPacket& recvData); - void HandleGuildBankMoneyWithdrawn(WorldPacket& recvData); - void HandleGuildBankerActivate(WorldPacket& recvData); - void HandleGuildBankQueryTab(WorldPacket& recvData); - void HandleGuildBankLogQuery(WorldPacket& recvData); - void HandleGuildBankDepositMoney(WorldPacket& recvData); - void HandleGuildBankWithdrawMoney(WorldPacket& recvData); - void HandleGuildBankSwapItems(WorldPacket& recvData); + void HandleGuildPermissions(WorldPackets::Guild::GuildPermissionsQuery& packet); + void HandleGuildBankMoneyWithdrawn(WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery& packet); + void HandleGuildBankerActivate(WorldPackets::Guild::GuildBankActivate& packet); + void HandleGuildBankQueryTab(WorldPackets::Guild::GuildBankQueryTab& packet); + void HandleGuildBankLogQuery(WorldPackets::Guild::GuildBankLogQuery& packet); + void HandleGuildBankDepositMoney(WorldPackets::Guild::GuildBankDepositMoney& packet); + void HandleGuildBankWithdrawMoney(WorldPackets::Guild::GuildBankWithdrawMoney& packet); + void HandleGuildBankSwapItems(WorldPackets::Guild::GuildBankSwapItems& packet); - void HandleGuildBankUpdateTab(WorldPacket& recvData); - void HandleGuildBankBuyTab(WorldPacket& recvData); - void HandleQueryGuildBankTabText(WorldPacket& recvData); - void HandleSetGuildBankTabText(WorldPacket& recvData); + void HandleGuildBankUpdateTab(WorldPackets::Guild::GuildBankUpdateTab& packet); + void HandleGuildBankBuyTab(WorldPackets::Guild::GuildBankBuyTab& packet); + void HandleQueryGuildBankTabText(WorldPackets::Guild::GuildBankTextQuery& packet); + void HandleSetGuildBankTabText(WorldPackets::Guild::GuildBankSetTabText& packet); // Refer-a-Friend void HandleGrantLevel(WorldPacket& recvData);