diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp index 6e7abbf11..c1948ad9a 100644 --- a/src/game/Guild.cpp +++ b/src/game/Guild.cpp @@ -29,6 +29,7 @@ #include "Util.h" #include "Language.h" #include "World.h" +#include "Calendar.h" //// MemberSlot //////////////////////////////////////////// void MemberSlot::SetMemberStats(Player* player) @@ -79,6 +80,7 @@ void MemberSlot::ChangeRank(uint32 newRank) Guild::Guild() { m_Id = 0; + m_Level = 1; m_Name = ""; GINFO = MOTD = ""; m_EmblemStyle = 0; @@ -173,7 +175,7 @@ bool Guild::AddMember(ObjectGuid plGuid, uint32 plRank) // remove all player signs from another petitions // this will be prevent attempt joining player to many guilds and corrupt guild data integrity - Player::RemovePetitionsAndSigns(plGuid, 9); + Player::RemovePetitionsAndSigns(plGuid); uint32 lowguid = plGuid.GetCounter(); @@ -234,8 +236,9 @@ bool Guild::AddMember(ObjectGuid plGuid, uint32 plRank) if (pl) { pl->SetInGuild(m_Id); + pl->SetGuildLevel(GetLevel()); pl->SetRank(newmember.RankId); - pl->SetGuildIdInvited(0); + pl->SetGuildInvited(0); } UpdateAccountsNumber(); @@ -465,7 +468,6 @@ bool Guild::LoadMembersFromDB(QueryResult* guildMembersResult) } members[lowguid] = newmember; - } while (guildMembersResult->NextRow()); @@ -547,6 +549,7 @@ bool Guild::DelMember(ObjectGuid guid, bool isDisbanding) if (player) { player->SetInGuild(0); + player->SetGuildLevel(0); player->SetRank(0); } @@ -649,6 +652,39 @@ void Guild::BroadcastPacketToRank(WorldPacket* packet, uint32 rankId) } } +// add new event to all already connected guild memebers +void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, uint32 minRank) +{ + uint32 count = 0; + + WorldPacket data(SMSG_CALENDAR_FILTER_GUILD); + data << uint32(count); // count placeholder + + for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) + { + // not sure if needed, maybe client checks it as well + if (count >= CALENDAR_MAX_INVITES) + { + sCalendarMgr.SendCalendarCommandResult(session->GetPlayer(), CALENDAR_ERROR_INVITES_EXCEEDED); + return; + } + + MemberSlot const* member = &itr->second; + uint32 level = Player::GetLevelFromDB(member->guid); + + if (member->guid != session->GetPlayer()->GetObjectGuid() && level >= minLevel && level <= maxLevel && member->RankId <= minRank) + { + data << member->guid.WriteAsPacked(); + data << uint8(level); + ++count; + } + } + + data.put(0, count); + + session->SendPacket(&data); +} + void Guild::CreateRank(std::string name_, uint32 rights) { if (m_Ranks.size() >= GUILD_RANKS_MAX_COUNT) @@ -676,18 +712,59 @@ void Guild::AddRank(const std::string& name_, uint32 rights, uint32 money) m_Ranks.push_back(RankInfo(name_, rights, money)); } -void Guild::DelRank() +void Guild::DelRank(uint32 rankId) { - // client won't allow to have less than GUILD_RANKS_MIN_COUNT ranks in guild - if (m_Ranks.size() <= GUILD_RANKS_MIN_COUNT) + if (rankId >= m_Ranks.size()) return; - // delete lowest guild_rank - uint32 rank = GetLowestRank(); - CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE rid>='%u' AND guildid='%u'", rank, m_Id); - CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE rid>='%u' AND guildid='%u'", rank, m_Id); + // client won't allow to have less than GUILD_RANKS_MIN_COUNT ranks in guild + if (m_Ranks.size() <= GUILD_RANKS_MIN_COUNT || rankId < GUILD_RANKS_MIN_COUNT) + return; - m_Ranks.pop_back(); + RankList::iterator itr = m_Ranks.erase(m_Ranks.begin() + rankId); + // delete lowest guild_rank + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE rid ='%u' AND guildid='%u'", rankId, m_Id); + CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE rid ='%u' AND guildid='%u'", rankId, m_Id); + CharacterDatabase.PExecute("UPDATE guild_rank SET rid = rid - 1 WHERE rid > '%u' AND guildid='%u'", rankId, m_Id); + CharacterDatabase.PExecute("UPDATE guild_bank_right SET rid = rid - 1 WHERE rid > '%u' AND guildid='%u'", rankId, m_Id); + CharacterDatabase.CommitTransaction(); +} + +void Guild::SwitchRank(uint32 rankId, bool up) +{ + if (rankId >= m_Ranks.size()) + return; + + if (rankId == GR_GUILDMASTER && up || rankId == GetLowestRank() && !up) + return; + + uint32 otherRankId = rankId + (up ? -1 : 1); + DEBUG_LOG("rank: %u otherrank %u", rankId, otherRankId); + + std::swap(m_Ranks[rankId], m_Ranks[otherRankId]); + + CharacterDatabase.BeginTransaction(); + for (uint32 i = 0; i < uint32(GetPurchasedTabs()); ++i) + { + CharacterDatabase.PExecute("REPLACE INTO guild_bank_right (guildid,TabId,rid,gbright,SlotPerDay) " + "VALUES ('%u','%u','%u','%u','%u')", m_Id, i, rankId, m_Ranks[rankId].TabRight[i], m_Ranks[rankId].TabSlotPerDay[i]); + CharacterDatabase.PExecute("REPLACE INTO guild_bank_right (guildid,TabId,rid,gbright,SlotPerDay) " + "VALUES ('%u','%u','%u','%u','%u')", m_Id, i, otherRankId, m_Ranks[otherRankId].TabRight[i], m_Ranks[otherRankId].TabSlotPerDay[i]); + } + + CharacterDatabase.PExecute("REPLACE INTO guild_rank (guildid,rid,rname,rights,BankMoneyPerDay) " + "VALUES ('%u', '%u', '%s', '%u', '%u')", m_Id, rankId, m_Ranks[rankId].Name.c_str(),m_Ranks[rankId].Rights,m_Ranks[rankId].BankMoneyPerDay); + CharacterDatabase.PExecute("REPLACE INTO guild_rank (guildid,rid,rname,rights,BankMoneyPerDay) " + "VALUES ('%u', '%u', '%s', '%u', '%u')", m_Id, otherRankId, m_Ranks[otherRankId].Name.c_str(),m_Ranks[otherRankId].Rights,m_Ranks[otherRankId].BankMoneyPerDay); + + for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) + if (itr->second.RankId == rankId) + itr->second.ChangeRank(otherRankId); + else if (itr->second.RankId == otherRankId) + itr->second.ChangeRank(rankId); + + CharacterDatabase.CommitTransaction(); } std::string Guild::GetRankName(uint32 rankId) @@ -761,53 +838,85 @@ void Guild::Disband() void Guild::Roster(WorldSession* session /*= NULL*/) { - // we can only guess size - WorldPacket data(SMSG_GUILD_ROSTER, (4 + MOTD.length() + 1 + GINFO.length() + 1 + 4 + m_Ranks.size() * (4 + 4 + GUILD_BANK_MAX_TABS * (4 + 4)) + members.size() * 50)); - data << uint32(members.size()); - data << MOTD; - data << GINFO; + ByteBuffer buffer; + + // we can only guess size + WorldPacket data(SMSG_GUILD_ROSTER, (4 + MOTD.length() + 1 + GINFO.length() + 1 + 4 + members.size() * 50)); + data.WriteBits(MOTD.length(), 11); + data.WriteBits(members.size(), 18); - data << uint32(m_Ranks.size()); - for (RankList::const_iterator ritr = m_Ranks.begin(); ritr != m_Ranks.end(); ++ritr) - { - data << uint32(ritr->Rights); - data << uint32(ritr->BankMoneyPerDay); // count of: withdraw gold(gold/day) Note: in game set gold, in packet set bronze. - for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i) - { - data << uint32(ritr->TabRight[i]); // for TAB_i rights: view tabs = 0x01, deposit items =0x02 - data << uint32(ritr->TabSlotPerDay[i]); // for TAB_i count of: withdraw items(stack/day) - } - } for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { - if (Player* pl = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first))) + MemberSlot const member = itr->second; + Player* player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)); + + ObjectGuid guid = member.guid; + data.WriteGuidMask<3, 4>(guid); + data.WriteBit(false); // Has Authenticator + data.WriteBit(false); // Can Scroll of Ressurect + data.WriteBits(member.Pnote.length(), 8); + data.WriteBits(member.OFFnote.length(), 8); + data.WriteGuidMask<0>(guid); + data.WriteBits(member.Name.length(), 7); + data.WriteGuidMask<1, 2, 6, 5, 7>(guid); + + uint8 flags = GUILDMEMBER_STATUS_NONE; + if (player) { - data << pl->GetObjectGuid(); - data << uint8(1); - data << pl->GetName(); - data << uint32(itr->second.RankId); - data << uint8(pl->getLevel()); - data << uint8(pl->getClass()); - data << uint8(0); // new 2.4.0 - data << uint32(pl->GetZoneId()); - data << itr->second.Pnote; - data << itr->second.OFFnote; - } - else - { - data << ObjectGuid(HIGHGUID_PLAYER, itr->first); - data << uint8(0); - data << itr->second.Name; - data << uint32(itr->second.RankId); - data << uint8(itr->second.Level); - data << uint8(itr->second.Class); - data << uint8(0); // new 2.4.0 - data << uint32(itr->second.ZoneId); - data << float(float(time(NULL) - itr->second.LogoutTime) / DAY); - data << itr->second.Pnote; - data << itr->second.OFFnote; + flags |= GUILDMEMBER_STATUS_ONLINE; + if (player->isAFK()) + flags |= GUILDMEMBER_STATUS_AFK; + if (player->isDND()) + flags |= GUILDMEMBER_STATUS_DND; } + + buffer << uint8(member.Class); + buffer << int32(0); // unk + buffer.WriteGuidBytes<0>(guid); + buffer << uint64(0); // weekly activity + buffer << uint32(member.RankId); + buffer << uint32(0); // achievement points + + // professions: id, value, rank + buffer << uint32(0) << uint32(0) << uint32(0); + buffer << uint32(0) << uint32(0) << uint32(0); + + buffer.WriteGuidBytes<2>(guid); + buffer << uint8(flags); + buffer << uint32(player ? player->GetZoneId() : member.ZoneId); + buffer << uint64(0); // Total activity + buffer.WriteGuidBytes<7>(guid); + buffer << uint32(0); // Remaining guild week Rep + + buffer.WriteStringData(member.Pnote); + + buffer.WriteGuidBytes<3>(guid); + buffer << uint8(player ? player->getLevel() : member.Level); + buffer << int32(0); // unk + buffer.WriteGuidBytes<5, 4>(guid); + buffer << uint8(0); // unk + buffer.WriteGuidBytes<1>(guid); + buffer << float(player ? 0.0f : float(time(NULL) - itr->second.LogoutTime) / DAY); + + buffer.WriteStringData(member.OFFnote); + + buffer.WriteGuidBytes<6>(guid); + buffer.WriteStringData(member.Name); } + + data.WriteBits(GINFO.length(), 12); + + data.FlushBits(); + data.append(buffer); + + data.WriteStringData(GINFO); + data.WriteStringData(MOTD); + + data << uint32(m_accountsNumber); + data << uint32(0); // weekly rep cap + data << secsToTimeBitFields(m_CreatedDate); + data << uint32(0); + if (session) session->SendPacket(&data); else @@ -817,9 +926,9 @@ void Guild::Roster(WorldSession* session /*= NULL*/) void Guild::Query(WorldSession* session) { - WorldPacket data(SMSG_GUILD_QUERY_RESPONSE, (8 * 32 + 200)); // we can only guess size + WorldPacket data(SMSG_GUILD_QUERY_RESPONSE, 8 * 32 + 200); // we can only guess size - data << uint32(m_Id); + data << GetObjectGuid(); data << m_Name; for (size_t i = 0 ; i < GUILD_RANKS_MAX_COUNT; ++i) // show always 10 ranks @@ -830,17 +939,65 @@ void Guild::Query(WorldSession* session) data << uint8(0); // null string } + // Rank order of creation + for (uint8 i = 0; i < GUILD_RANKS_MAX_COUNT; ++i) + { + if (i < m_Ranks.size()) + data << uint32(i); + else + data << uint32(0); + } + + // Rank order of "importance" (sorting by rights) + for (uint8 i = 0; i < GUILD_RANKS_MAX_COUNT; ++i) + { + if (i < m_Ranks.size()) + data << uint32(i); + else + data << uint32(0); + } + data << uint32(m_EmblemStyle); data << uint32(m_EmblemColor); data << uint32(m_BorderStyle); data << uint32(m_BorderColor); data << uint32(m_BackgroundColor); - data << uint32(0); // probably real ranks count + data << uint32(m_Ranks.size()); session->SendPacket(&data); DEBUG_LOG("WORLD: Sent (SMSG_GUILD_QUERY_RESPONSE)"); } +void Guild::QueryRanks(WorldSession* session) +{ + WorldPacket data(SMSG_GUILD_QUERY_RANKS_RESULT, (4 * 2 * 8 + 4 * 3 + 1) * m_Ranks.size()); // we can only guess size + + data.WriteBits(m_Ranks.size(), 18); + + for (uint8 i = 0; i < m_Ranks.size(); ++i) + data.WriteBits(m_Ranks[i].Name.length(), 7); + + for (uint8 i = 0; i < m_Ranks.size(); ++i) + { + data << uint32(i); + + for (uint8 j = 0; j < GUILD_BANK_MAX_TABS; ++j) + { + data << uint32(m_Ranks[i].TabSlotPerDay[j]); + data << uint32(m_Ranks[i].TabRight[j]); + } + + data << uint32(m_Ranks[i].BankMoneyPerDay); + data << uint32(m_Ranks[i].Rights); + + data.WriteStringData(m_Ranks[i].Name); + + data << uint32(i); // rank id + } + + session->SendPacket(&data); +} + void Guild::SetEmblem(uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor, uint32 backgroundColor) { m_EmblemStyle = emblemStyle; @@ -879,26 +1036,19 @@ uint32 Guild::GetAccountsNumber() void Guild::DisplayGuildEventLog(WorldSession* session) { // Sending result - WorldPacket data(MSG_GUILD_EVENT_LOG_QUERY, 0); + ByteBuffer buffer; + WorldPacket data(SMSG_GUILD_EVENT_LOG, 0); // count, max count == 100 - data << uint8(m_GuildEventLog.size()); - for (GuildEventLog::const_iterator itr = m_GuildEventLog.begin(); itr != m_GuildEventLog.end(); ++itr) + data.WriteBits(m_GuildEventLog.size(), 23); + for (GuildEventLog::iterator itr = m_GuildEventLog.begin(); itr != m_GuildEventLog.end(); ++itr) + itr->WriteData(data, buffer); + if (!buffer.empty()) { - // Event type - data << uint8(itr->EventType); - // Player 1 - data << ObjectGuid(HIGHGUID_PLAYER, itr->PlayerGuid1); - // Player 2 not for left/join guild events - if (itr->EventType != GUILD_EVENT_LOG_JOIN_GUILD && itr->EventType != GUILD_EVENT_LOG_LEAVE_GUILD) - data << ObjectGuid(HIGHGUID_PLAYER, itr->PlayerGuid2); - // New Rank - only for promote/demote guild events - if (itr->EventType == GUILD_EVENT_LOG_PROMOTE_PLAYER || itr->EventType == GUILD_EVENT_LOG_DEMOTE_PLAYER) - data << uint8(itr->NewRank); - // Event timestamp - data << uint32(time(NULL) - itr->TimeStamp); + data.FlushBits(); + data.append(buffer); } session->SendPacket(&data); - DEBUG_LOG("WORLD: Sent (MSG_GUILD_EVENT_LOG_QUERY)"); + DEBUG_LOG("WORLD: Sent (SMSG_GUILD_EVENT_LOG)"); } // Load guild eventlog from DB @@ -933,7 +1083,6 @@ void Guild::LoadGuildEventLogFromDB() // Add entry to list m_GuildEventLog.push_front(NewEvent); - } while (result->NextRow()); delete result; @@ -968,38 +1117,51 @@ void Guild::LogGuildEvent(uint8 EventType, ObjectGuid playerGuid1, ObjectGuid pl // Bank content related void Guild::DisplayGuildBankContent(WorldSession* session, uint8 TabId) { + if (TabId >= GetPurchasedTabs()) + return; + GuildBankTab const* tab = m_TabListMap[TabId]; if (!IsMemberHaveRights(session->GetPlayer()->GetGUIDLow(), TabId, GUILD_BANK_RIGHT_VIEW_TAB)) return; WorldPacket data(SMSG_GUILD_BANK_LIST, 1200); - - data << uint64(GetGuildBankMoney()); - data << uint8(TabId); - // remaining slots for today - data << uint32(GetMemberSlotWithdrawRem(session->GetPlayer()->GetGUIDLow(), TabId)); - data << uint8(0); // Tell client that there's no tab info in this packet - - data << uint8(GUILD_BANK_MAX_SLOTS); - + ByteBuffer buffer; + data.WriteBit(0); + uint32 itemCount = 0; for (int i = 0; i < GUILD_BANK_MAX_SLOTS; ++i) - AppendDisplayGuildBankSlot(data, tab, i); + if (tab->Slots[i]) + ++itemCount; + + data.WriteBits(itemCount, 20); + data.WriteBits(0, 22); // Tell client that there's no tab info in this packet + for (int i = 0; i < GUILD_BANK_MAX_SLOTS; ++i) + if (tab->Slots[i]) + AppendDisplayGuildBankSlot(data, buffer, tab, i); + + data << uint64(m_GuildBankMoney); + if (!buffer.empty()) + data.append(buffer); + + data << uint32(TabId); + data << uint32(GetMemberSlotWithdrawRem(session->GetPlayer()->GetObjectGuid(), TabId)); session->SendPacket(&data); - DEBUG_LOG("WORLD: Sent (SMSG_GUILD_BANK_LIST)"); + DEBUG_LOG("WORLD: Sent (SMSG_GUILD_BANK_LIST), tabid %u itemCount %u", TabId, itemCount); } void Guild::DisplayGuildBankMoneyUpdate(WorldSession* session) { WorldPacket data(SMSG_GUILD_BANK_LIST, 8 + 1 + 4 + 1 + 1); + data.WriteBit(0); + data.WriteBits(0, 20); // not send items + data.WriteBits(0, 22); // Tell that there's no tab info in this packet data << uint64(GetGuildBankMoney()); - data << uint8(0); // TabId, default 0 - data << uint32(GetMemberSlotWithdrawRem(session->GetPlayer()->GetGUIDLow(), 0)); - data << uint8(0); // Tell that there's no tab info in this packet - data << uint8(0); // not send items + data << uint32(0); // TabId, default 0 + data << uint32(GetMemberSlotWithdrawRem(session->GetPlayer()->GetObjectGuid(), 0)); + BroadcastPacket(&data); DEBUG_LOG("WORLD: Sent (SMSG_GUILD_BANK_LIST)"); @@ -1009,32 +1171,35 @@ void Guild::DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2) { GuildBankTab const* tab = m_TabListMap[TabId]; + ByteBuffer buffer; WorldPacket data(SMSG_GUILD_BANK_LIST, 1200); - data << uint64(GetGuildBankMoney()); - data << uint8(TabId); - - size_t rempos = data.wpos(); - data << uint32(0); // item withdraw amount, will be filled later - data << uint8(0); // Tell client that there's no tab info in this packet - + data.WriteBit(0); if (slot2 == -1) // single item in slot1 - { - data << uint8(1); // item count - - AppendDisplayGuildBankSlot(data, tab, slot1); - } + data.WriteBits(1, 20); // item count else // 2 items (in slot1 and slot2) - { - data << uint8(2); // item count + data.WriteBits(2, 20); // item count + data.WriteBits(0, 22); // Tell client that there's no tab info in this packet + if (slot2 == -1) + AppendDisplayGuildBankSlot(data, buffer, tab, slot1); + else + { if (slot1 > slot2) std::swap(slot1, slot2); - AppendDisplayGuildBankSlot(data, tab, slot1); - AppendDisplayGuildBankSlot(data, tab, slot2); + AppendDisplayGuildBankSlot(data, buffer, tab, slot1); + AppendDisplayGuildBankSlot(data, buffer, tab, slot2); } + data << uint64(GetGuildBankMoney()); + if (!buffer.empty()) + data.append(buffer); + data << uint32(TabId); + + size_t rempos = data.wpos(); + data << uint32(0); // item withdraw amount, will be filled later + for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { Player* player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)); @@ -1056,19 +1221,23 @@ void Guild::DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec cons { GuildBankTab const* tab = m_TabListMap[TabId]; + ByteBuffer buffer; WorldPacket data(SMSG_GUILD_BANK_LIST, 1200); + data.WriteBit(0); + data.WriteBits(slots.size(), 20); // updates count + data.WriteBits(0, 22); // Tell client that there's no tab info in this packet + + for (GuildItemPosCountVec::const_iterator itr = slots.begin(); itr != slots.end(); ++itr) + AppendDisplayGuildBankSlot(data, buffer, tab, itr->Slot); data << uint64(GetGuildBankMoney()); - data << uint8(TabId); + if (!buffer.empty()) + data.append(buffer); + + data << uint32(TabId); size_t rempos = data.wpos(); data << uint32(0); // item withdraw amount, will be filled later - data << uint8(0); // Tell client that there's no tab info in this packet - - data << uint8(slots.size()); // updates count - - for (GuildItemPosCountVec::const_iterator itr = slots.begin(); itr != slots.end(); ++itr) - AppendDisplayGuildBankSlot(data, tab, itr->Slot); for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { @@ -1100,23 +1269,32 @@ Item* Guild::GetItem(uint8 TabId, uint8 SlotId) void Guild::DisplayGuildBankTabsInfo(WorldSession* session) { WorldPacket data(SMSG_GUILD_BANK_LIST, 500); - - data << uint64(GetGuildBankMoney()); - data << uint8(0); // TabInfo packet must be for TabId 0 - data << uint32(GetMemberSlotWithdrawRem(session->GetPlayer()->GetGUIDLow(), 0)); - data << uint8(1); // Tell client that this packet includes tab info - - data << uint8(GetPurchasedTabs()); // here is the number of tabs + data.WriteBit(0); + data.WriteBits(0, 20); // Do not send tab content + data.WriteBits(GetPurchasedTabs(), 22); // here is the number of tabs for (uint8 i = 0; i < GetPurchasedTabs(); ++i) { - data << m_TabListMap[i]->Name.c_str(); - data << m_TabListMap[i]->Icon.c_str(); + data.WriteBits(m_TabListMap[i]->Icon.length(), 9); + data.WriteBits(m_TabListMap[i]->Name.length(), 7); } - data << uint8(0); // Do not send tab content + + data.FlushBits(); + + for (uint8 i = 0; i < GetPurchasedTabs(); ++i) + { + data.WriteStringData(m_TabListMap[i]->Icon); + data << uint32(i); + data.WriteStringData(m_TabListMap[i]->Name); + } + + data << uint64(GetGuildBankMoney()); + data << uint32(0); // TabInfo packet must be for TabId 0 + data << uint32(GetMemberSlotWithdrawRem(session->GetPlayer()->GetGUIDLow(), 0)); + session->SendPacket(&data); - DEBUG_LOG("WORLD: Sent (SMSG_GUILD_BANK_LIST)"); + DEBUG_LOG("WORLD: Sent SMSG_GUILD_BANK_LIST (Guild::DisplayGuildBankTabsInfo)"); } void Guild::CreateNewBankTab() @@ -1246,15 +1424,15 @@ void Guild::LoadGuildBankFromDB() void Guild::SendMoneyInfo(WorldSession* session, uint32 LowGuid) { - WorldPacket data(MSG_GUILD_BANK_MONEY_WITHDRAWN, 4); - data << uint32(GetMemberMoneyWithdrawRem(LowGuid)); + WorldPacket data(SMSG_GUILD_BANK_MONEY_WITHDRAWN, 8); + data << uint64(GetMemberMoneyWithdrawRem(LowGuid)); session->SendPacket(&data); - DEBUG_LOG("WORLD: Sent MSG_GUILD_BANK_MONEY_WITHDRAWN"); + DEBUG_LOG("WORLD: Sent SMSG_GUILD_BANK_MONEY_WITHDRAWN"); } -bool Guild::MemberMoneyWithdraw(uint32 amount, uint32 LowGuid) +bool Guild::MemberMoneyWithdraw(uint64 amount, uint32 LowGuid) { - uint32 MoneyWithDrawRight = GetMemberMoneyWithdrawRem(LowGuid); + uint64 MoneyWithDrawRight = GetMemberMoneyWithdrawRem(LowGuid); if (MoneyWithDrawRight < amount || GetGuildBankMoney() < amount) return false; @@ -1339,7 +1517,7 @@ uint32 Guild::GetMemberSlotWithdrawRem(uint32 LowGuid, uint8 TabId) return itr->second.BankRemSlotsTab[TabId]; } -uint32 Guild::GetMemberMoneyWithdrawRem(uint32 LowGuid) +uint64 Guild::GetMemberMoneyWithdrawRem(uint32 LowGuid) { MemberList::iterator itr = members.find(LowGuid); if (itr == members.end()) @@ -1462,7 +1640,6 @@ bool Guild::LoadBankRightsFromDB(QueryResult* guildBankTabRightsResult) uint16 SlotPerDay = fields[4].GetUInt16(); SetBankRightsAndSlots(rankId, TabId, right, SlotPerDay, false); - } while (guildBankTabRightsResult->NextRow()); @@ -1554,7 +1731,6 @@ void Guild::LoadGuildBankEventLogFromDB() // add event to list // events are ordered from oldest (in beginning) to latest (in the end) m_GuildBankEventLog_Money.push_front(NewEvent); - } while (result->NextRow()); delete result; @@ -1565,66 +1741,39 @@ void Guild::DisplayGuildBankLogs(WorldSession* session, uint8 TabId) if (TabId > GUILD_BANK_MAX_TABS) return; + ByteBuffer buffer; + bool hasCashFlow = GetLevel() >= 5 && TabId == GUILD_BANK_MAX_TABS; // has Cash Flow perk + WorldPacket data(SMSG_GUILD_BANK_LOG_QUERY_RESULT, m_GuildBankEventLog_Money.size() * (4 * 4 + 1) + 1 + 1); + data.WriteBit(hasCashFlow); + if (TabId == GUILD_BANK_MAX_TABS) { // Here we display money logs - WorldPacket data(MSG_GUILD_BANK_LOG_QUERY, m_GuildBankEventLog_Money.size() * (4 * 4 + 1) + 1 + 1); - data << uint8(TabId); // Here GUILD_BANK_MAX_TABS - data << uint8(m_GuildBankEventLog_Money.size()); // number of log entries - for (GuildBankEventLog::const_iterator itr = m_GuildBankEventLog_Money.begin(); itr != m_GuildBankEventLog_Money.end(); ++itr) - { - data << uint8(itr->EventType); - data << ObjectGuid(HIGHGUID_PLAYER, itr->PlayerGuid); - if (itr->EventType == GUILD_BANK_LOG_DEPOSIT_MONEY || - itr->EventType == GUILD_BANK_LOG_WITHDRAW_MONEY || - itr->EventType == GUILD_BANK_LOG_REPAIR_MONEY || - itr->EventType == GUILD_BANK_LOG_UNK1 || - itr->EventType == GUILD_BANK_LOG_UNK2) - { - data << uint32(itr->ItemOrMoney); - } - else - { - data << uint32(itr->ItemOrMoney); - data << uint32(itr->ItemStackCount); - if (itr->EventType == GUILD_BANK_LOG_MOVE_ITEM || itr->EventType == GUILD_BANK_LOG_MOVE_ITEM2) - data << uint8(itr->DestTabId); // moved tab - } - data << uint32(time(NULL) - itr->TimeStamp); - } - session->SendPacket(&data); + data.WriteBits(m_GuildBankEventLog_Money.size(), 23); + for (GuildBankEventLog::iterator itr = m_GuildBankEventLog_Money.begin(); itr != m_GuildBankEventLog_Money.end(); ++itr) + itr->WriteData(data, buffer); } else { // here we display current tab logs - WorldPacket data(MSG_GUILD_BANK_LOG_QUERY, m_GuildBankEventLog_Item[TabId].size() * (4 * 4 + 1 + 1) + 1 + 1); - data << uint8(TabId); // Here a real Tab Id // number of log entries - data << uint8(m_GuildBankEventLog_Item[TabId].size()); - for (GuildBankEventLog::const_iterator itr = m_GuildBankEventLog_Item[TabId].begin(); itr != m_GuildBankEventLog_Item[TabId].end(); ++itr) - { - data << uint8(itr->EventType); - data << ObjectGuid(HIGHGUID_PLAYER, itr->PlayerGuid); - if (itr->EventType == GUILD_BANK_LOG_DEPOSIT_MONEY || - itr->EventType == GUILD_BANK_LOG_WITHDRAW_MONEY || - itr->EventType == GUILD_BANK_LOG_REPAIR_MONEY || - itr->EventType == GUILD_BANK_LOG_UNK1 || - itr->EventType == GUILD_BANK_LOG_UNK2) - { - data << uint32(itr->ItemOrMoney); - } - else - { - data << uint32(itr->ItemOrMoney); - data << uint32(itr->ItemStackCount); - if (itr->EventType == GUILD_BANK_LOG_MOVE_ITEM || itr->EventType == GUILD_BANK_LOG_MOVE_ITEM2) - data << uint8(itr->DestTabId); // moved tab - } - data << uint32(time(NULL) - itr->TimeStamp); - } - session->SendPacket(&data); + data.WriteBits(m_GuildBankEventLog_Item[TabId].size(), 23); + for (GuildBankEventLog::iterator itr = m_GuildBankEventLog_Item[TabId].begin(); itr != m_GuildBankEventLog_Item[TabId].end(); ++itr) + itr->WriteData(data, buffer); } - DEBUG_LOG("WORLD: Sent (MSG_GUILD_BANK_LOG_QUERY)"); + if (!buffer.empty()) + { + data.FlushBits(); + data.append(buffer); + } + + data << uint32(TabId); + if (hasCashFlow) + data << uint64(0); // cash flow contribution + + session->SendPacket(&data); + + DEBUG_LOG("WORLD: Sent (SMSG_GUILD_BANK_LOG_QUERY_RESULT)"); } void Guild::LogBankEvent(uint8 EventType, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount, uint8 DestTabId) @@ -1676,40 +1825,38 @@ bool Guild::AddGBankItemToDB(uint32 GuildId, uint32 BankTab , uint32 BankTabSlot return true; } -void Guild::AppendDisplayGuildBankSlot(WorldPacket& data, GuildBankTab const* tab, int slot) +void Guild::AppendDisplayGuildBankSlot(WorldPacket& data, ByteBuffer& buffer, GuildBankTab const* tab, int slot) { Item* pItem = tab->Slots[slot]; uint32 entry = pItem ? pItem->GetEntry() : 0; - data << uint8(slot); - data << uint32(entry); + uint32 enchCount = 0; if (entry) { - data << uint32(0); // 3.3.0 (0x8000, 0x8020) - data << uint32(pItem->GetItemRandomPropertyId()); // random item property id + 8 - - if (pItem->GetItemRandomPropertyId()) - data << uint32(pItem->GetItemSuffixFactor()); // SuffixFactor + 4 - - data << uint32(pItem->GetCount()); // +12 ITEM_FIELD_STACK_COUNT - data << uint32(0); // +16 Unknown value - data << uint8(0); // +20 - - 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); + buffer << uint32(enchId); + buffer << uint32(i); ++enchCount; } } - data.put(enchCountPos, enchCount); } + + data.WriteBit(0); // unk + data.WriteBits(enchCount, 23); // number of enchantments + + buffer << uint32(0); + buffer << uint32(0); + buffer << uint32(0); + buffer << uint32(entry ? pItem->GetCount() : 0); // ITEM_FIELD_STACK_COUNT + buffer << uint32(slot); + buffer << uint32(0); + buffer << uint32(entry); + buffer << uint32(entry ? pItem->GetItemRandomPropertyId() : 0); // random item property id + buffer << uint32(entry ? abs(pItem->GetSpellCharges()) : 0); // Spell charges + buffer << uint32(entry ? pItem->GetItemSuffixFactor() : 0); // SuffixFactor } Item* Guild::StoreItem(uint8 tabId, GuildItemPosCountVec const& dest, Item* pItem) @@ -1963,9 +2110,10 @@ void Guild::SendGuildBankTabText(WorldSession* session, uint8 TabId) { GuildBankTab const* tab = m_TabListMap[TabId]; - WorldPacket data(MSG_QUERY_GUILD_BANK_TEXT, 1 + tab->Text.size() + 1); - data << uint8(TabId); - data << tab->Text; + WorldPacket data(SMSG_GUILD_BANK_TEXT, 1 + tab->Text.size() + 1); + data.WriteBits(tab->Text.length(), 14); + data << uint32(TabId); + data.WriteStringData(tab->Text); if (session) session->SendPacket(&data); @@ -2097,7 +2245,6 @@ void Guild::SwapItems(Player* pl, uint8 BankTab, uint8 BankTabSlot, uint8 BankTa DisplayGuildBankContentUpdate(BankTabDst, BankTabSlotDst); } - void Guild::MoveFromBankToChar(Player* pl, uint8 BankTab, uint8 BankTabSlot, uint8 PlayerBag, uint8 PlayerSlot, uint32 SplitedAmount) { Item* pItemBank = GetItem(BankTab, BankTabSlot); @@ -2246,7 +2393,6 @@ void Guild::MoveFromBankToChar(Player* pl, uint8 BankTab, uint8 BankTabSlot, uin DisplayGuildBankContentUpdate(BankTab, BankTabSlot); } - void Guild::MoveFromCharToBank(Player* pl, uint8 PlayerBag, uint8 PlayerSlot, uint8 BankTab, uint8 BankTabSlot, uint32 SplitedAmount) { Item* pItemBank = GetItem(BankTab, BankTabSlot); @@ -2455,3 +2601,76 @@ bool GuildItemPosCount::isContainedIn(GuildItemPosCountVec const& vec) const return false; } + +void GuildEventLogEntry::WriteData(WorldPacket& data, ByteBuffer& buffer) +{ + // Player 1 + ObjectGuid guid1 = ObjectGuid(HIGHGUID_PLAYER, PlayerGuid1); + // Player 2 not for left/join guild events + ObjectGuid guid2 = ObjectGuid(HIGHGUID_PLAYER, PlayerGuid2); + data.WriteGuidMask<2, 4>(guid1); + data.WriteGuidMask<7, 6>(guid2); + data.WriteGuidMask<3>(guid1); + data.WriteGuidMask<3, 5>(guid2); + data.WriteGuidMask<7, 5, 0>(guid1); + data.WriteGuidMask<4, 2, 0, 1>(guid2); + data.WriteGuidMask<1, 6>(guid1); + + buffer.WriteGuidBytes<3, 2, 5>(guid2); + + // New Rank - only for promote/demote guild events + buffer << uint8(NewRank); + + buffer.WriteGuidBytes<4>(guid2); + buffer.WriteGuidBytes<0, 4>(guid1); + + // Event timestamp + buffer << uint32(time(NULL) - TimeStamp); + + buffer.WriteGuidBytes<7, 3>(guid1); + buffer.WriteGuidBytes<0, 6, 7>(guid2); + buffer.WriteGuidBytes<5>(guid1); + + // Event type + buffer << uint8(EventType); + + buffer.WriteGuidBytes<1>(guid2); + buffer.WriteGuidBytes<2, 6, 1>(guid1); +} + +void GuildBankEventLogEntry::WriteData(WorldPacket& data, ByteBuffer& buffer) +{ + ObjectGuid logGuid = ObjectGuid(HIGHGUID_PLAYER, PlayerGuid); + + bool hasItem = EventType == GUILD_BANK_LOG_DEPOSIT_ITEM || EventType == GUILD_BANK_LOG_WITHDRAW_ITEM || + EventType == GUILD_BANK_LOG_MOVE_ITEM || EventType == GUILD_BANK_LOG_MOVE_ITEM2; + + bool itemMoved = EventType == GUILD_BANK_LOG_MOVE_ITEM || EventType == GUILD_BANK_LOG_MOVE_ITEM2; + + bool hasStack = hasItem && ItemStackCount > 1 || itemMoved; + + data.WriteBit(isMoneyEvent()); + data.WriteGuidMask<4, 1>(logGuid); + data.WriteBit(hasItem); + data.WriteBit(hasStack); + data.WriteGuidMask<2, 5, 3, 6, 0>(logGuid); + data.WriteBit(itemMoved); + data.WriteGuidMask<7>(logGuid); + + buffer.WriteGuidBytes<6, 1, 5>(logGuid); + if (hasStack) + buffer << uint32(ItemStackCount); + + buffer << uint8(EventType); + buffer.WriteGuidBytes<2, 4, 0, 7, 3>(logGuid); + if (hasItem) + buffer << uint32(ItemOrMoney); + + buffer << uint32(time(NULL) - TimeStamp); + + if (isMoneyEvent()) + buffer << uint64(ItemOrMoney); + + if (itemMoved) + buffer << uint8(DestTabId); // moved tab +} diff --git a/src/game/Guild.h b/src/game/Guild.h index 66c35aca8..ba9e88bf1 100644 --- a/src/game/Guild.h +++ b/src/game/Guild.h @@ -19,7 +19,7 @@ #ifndef MANGOSSERVER_GUILD_H #define MANGOSSERVER_GUILD_H -#define WITHDRAW_MONEY_UNLIMITED 0xFFFFFFFF +#define WITHDRAW_MONEY_UNLIMITED UI64LIT(0xFFFFFFFFFFFFFFFF) #define WITHDRAW_SLOT_UNLIMITED 0xFFFFFFFF #include "Common.h" @@ -29,9 +29,6 @@ class Item; -#define GUILD_RANKS_MIN_COUNT 5 -#define GUILD_RANKS_MAX_COUNT 10 - enum GuildDefaultRanks { // these ranks can be modified, but they cannot be deleted @@ -46,25 +43,28 @@ enum GuildDefaultRanks enum GuildRankRights { - GR_RIGHT_EMPTY = 0x00000040, - GR_RIGHT_GCHATLISTEN = 0x00000041, - GR_RIGHT_GCHATSPEAK = 0x00000042, - GR_RIGHT_OFFCHATLISTEN = 0x00000044, - GR_RIGHT_OFFCHATSPEAK = 0x00000048, - GR_RIGHT_PROMOTE = 0x000000C0, - GR_RIGHT_DEMOTE = 0x00000140, - GR_RIGHT_INVITE = 0x00000050, - GR_RIGHT_REMOVE = 0x00000060, - GR_RIGHT_SETMOTD = 0x00001040, - GR_RIGHT_EPNOTE = 0x00002040, - GR_RIGHT_VIEWOFFNOTE = 0x00004040, - GR_RIGHT_EOFFNOTE = 0x00008040, - GR_RIGHT_MODIFY_GUILD_INFO = 0x00010040, - GR_RIGHT_WITHDRAW_GOLD_LOCK = 0x00020000, // remove money withdraw capacity - GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair - GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold - GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk - GR_RIGHT_ALL = 0x001DF1FF + GR_RIGHT_EMPTY = 0x00000040, + GR_RIGHT_GCHATLISTEN = 0x00000041, + GR_RIGHT_GCHATSPEAK = 0x00000042, + GR_RIGHT_OFFCHATLISTEN = 0x00000044, + GR_RIGHT_OFFCHATSPEAK = 0x00000048, + GR_RIGHT_PROMOTE = 0x000000C0, + GR_RIGHT_DEMOTE = 0x00000140, + GR_RIGHT_INVITE = 0x00000050, + GR_RIGHT_REMOVE = 0x00000060, + GR_RIGHT_SETMOTD = 0x00001040, + GR_RIGHT_EPNOTE = 0x00002040, + GR_RIGHT_VIEWOFFNOTE = 0x00004040, + GR_RIGHT_EOFFNOTE = 0x00008040, + GR_RIGHT_MODIFY_GUILD_INFO = 0x00010040, + GR_RIGHT_WITHDRAW_GOLD_LOCK = 0x00020000, // remove money withdraw capacity + GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair + GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold + GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk + GR_RIGHT_REQUIRES_AUTHENTICATOR = 0x00200000, + GR_RIGHT_MODIFY_BANK_TABS = 0x00400000, // cata? + GR_RIGHT_REMOVE_GUILD_EVENT = 0x00800000, // wotlk + GR_RIGHT_ALL = 0x00DDF1FF, }; enum Typecommand @@ -74,36 +74,44 @@ enum Typecommand GUILD_QUIT_S = 0x03, // 0x05? GUILD_FOUNDER_S = 0x0E, - GUILD_UNK1 = 0x13, - GUILD_UNK2 = 0x14 + GUILD_UNK1 = 0x14, + GUILD_UNK2 = 0x15, }; enum CommandErrors { - ERR_PLAYER_NO_MORE_IN_GUILD = 0x00, - ERR_GUILD_INTERNAL = 0x01, - ERR_ALREADY_IN_GUILD = 0x02, - ERR_ALREADY_IN_GUILD_S = 0x03, - ERR_INVITED_TO_GUILD = 0x04, - ERR_ALREADY_INVITED_TO_GUILD_S = 0x05, - ERR_GUILD_NAME_INVALID = 0x06, - ERR_GUILD_NAME_EXISTS_S = 0x07, - ERR_GUILD_LEADER_LEAVE = 0x08, - ERR_GUILD_PERMISSIONS = 0x08, - ERR_GUILD_PLAYER_NOT_IN_GUILD = 0x09, - ERR_GUILD_PLAYER_NOT_IN_GUILD_S = 0x0A, - ERR_GUILD_PLAYER_NOT_FOUND_S = 0x0B, - ERR_GUILD_NOT_ALLIED = 0x0C, - ERR_GUILD_RANK_TOO_HIGH_S = 0x0D, - ERR_GUILD_RANK_TOO_LOW_S = 0x0E, - ERR_GUILD_RANKS_LOCKED = 0x11, - ERR_GUILD_RANK_IN_USE = 0x12, - ERR_GUILD_IGNORING_YOU_S = 0x13, - ERR_GUILD_UNK1 = 0x14, - ERR_GUILD_WITHDRAW_LIMIT = 0x19, - ERR_GUILD_NOT_ENOUGH_MONEY = 0x1A, - ERR_GUILD_BANK_FULL = 0x1C, - ERR_GUILD_ITEM_NOT_FOUND = 0x1D + ERR_PLAYER_NO_MORE_IN_GUILD = 0x00, + ERR_GUILD_INTERNAL = 0x01, + ERR_ALREADY_IN_GUILD = 0x02, + ERR_ALREADY_IN_GUILD_S = 0x03, + ERR_INVITED_TO_GUILD = 0x04, + ERR_ALREADY_INVITED_TO_GUILD_S = 0x05, + ERR_GUILD_NAME_INVALID = 0x06, + ERR_GUILD_NAME_EXISTS_S = 0x07, + ERR_GUILD_LEADER_LEAVE = 0x08, + ERR_GUILD_PERMISSIONS = 0x08, + ERR_GUILD_PLAYER_NOT_IN_GUILD = 0x09, + ERR_GUILD_PLAYER_NOT_IN_GUILD_S = 0x0A, + ERR_GUILD_PLAYER_NOT_FOUND_S = 0x0B, + ERR_GUILD_NOT_ALLIED = 0x0C, + ERR_GUILD_RANK_TOO_HIGH_S = 0x0D, + ERR_GUILD_RANK_TOO_LOW_S = 0x0E, + ERR_GUILD_RANKS_LOCKED = 0x11, + ERR_GUILD_RANK_IN_USE = 0x12, + ERR_GUILD_IGNORING_YOU_S = 0x13, + ERR_GUILD_UNK1 = 0x14, + ERR_GUILD_WITHDRAW_LIMIT = 0x19, + ERR_GUILD_NOT_ENOUGH_MONEY = 0x1A, + ERR_GUILD_BANK_FULL = 0x1C, + ERR_GUILD_ITEM_NOT_FOUND = 0x1D, + ERR_GUILD_TOO_MUCH_MONEY = 0x1F, + ERR_GUILD_BANK_WRONG_TAB = 0x20, + ERR_RANK_REQUIRES_AUTHENTICATOR = 0x22, + ERR_GUILD_BANK_VOUCHER_FAILED = 0x23, + ERR_GUILD_TRIAL_ACCOUNT = 0x24, + ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL = 0x25, + ERR_GUILD_MOVE_STARTING = 0x26, + ERR_GUILD_REP_TOO_LOW = 0x27, }; enum GuildEvents @@ -117,7 +125,7 @@ enum GuildEvents GE_LEADER_IS = 0x07, GE_LEADER_CHANGED = 0x08, GE_DISBANDED = 0x09, - GE_TABARDCHANGE = 0x0A, + //GE_TABARDCHANGE = 0x0A, // not exists in 4.3.4 GE_UPDATE_RANK = 0x0B, // string, string EVENT_GUILD_ROSTER_UPDATE tab content change? GE_CREATE_RANK = 0x0C, // EVENT_GUILD_ROSTER_UPDATE GE_DELETE_RANK = 0x0D, @@ -129,7 +137,7 @@ enum GuildEvents GE_BANKTAB_PURCHASED = 0x13, // EVENT_GUILDBANK_UPDATE_TABS GE_BANKTAB_UPDATED = 0x14, // EVENT_GUILDBANK_UPDATE_TABS GE_GUILDBANK_UPDATE_MONEY = 0x15, // EVENT_GUILDBANK_UPDATE_MONEY, string 0000000000002710 is 1 gold - GE_GUILD_BANK_MONEY_WITHDRAWN = 0x16, // MSG_GUILD_BANK_MONEY_WITHDRAWN + //GE_GUILD_BANK_MONEY_WITHDRAWN = 0x16, // not exists in 4.3.4 GE_GUILDBANK_TEXT_CHANGED = 0x17 // EVENT_GUILDBANK_TEXT_CHANGED }; @@ -138,15 +146,20 @@ enum PetitionTurns PETITION_TURN_OK = 0, PETITION_TURN_ALREADY_IN_GUILD = 2, PETITION_TURN_NEED_MORE_SIGNATURES = 4, + PETITION_TURN_GUILD_PERMISSIONS = 11, + PETITION_TURN_GUILD_NAME_INVALID = 12, }; enum PetitionSigns { - PETITION_SIGN_OK = 0, - PETITION_SIGN_ALREADY_SIGNED = 1, - PETITION_SIGN_ALREADY_IN_GUILD = 2, - PETITION_SIGN_CANT_SIGN_OWN = 3, - PETITION_SIGN_NOT_SERVER = 4, + PETITION_SIGN_OK = 0, + PETITION_SIGN_ALREADY_SIGNED = 1, + PETITION_SIGN_ALREADY_IN_GUILD = 2, + PETITION_SIGN_CANT_SIGN_OWN = 3, + PETITION_SIGN_NOT_SAME_SERVER = 5, + PETITION_SIGN_PETITION_FULL = 8, + PETITION_SIGN_ALREADY_SIGNED_OTHER = 10, + PETITION_SIGN_RESTRICTED_ACCOUNT = 11, }; enum GuildBankRights @@ -161,15 +174,16 @@ enum GuildBankRights enum GuildBankEventLogTypes { - GUILD_BANK_LOG_DEPOSIT_ITEM = 1, - GUILD_BANK_LOG_WITHDRAW_ITEM = 2, - GUILD_BANK_LOG_MOVE_ITEM = 3, - GUILD_BANK_LOG_DEPOSIT_MONEY = 4, - GUILD_BANK_LOG_WITHDRAW_MONEY = 5, - GUILD_BANK_LOG_REPAIR_MONEY = 6, - GUILD_BANK_LOG_MOVE_ITEM2 = 7, - GUILD_BANK_LOG_UNK1 = 8, - GUILD_BANK_LOG_UNK2 = 9, + GUILD_BANK_LOG_DEPOSIT_ITEM = 1, + GUILD_BANK_LOG_WITHDRAW_ITEM = 2, + GUILD_BANK_LOG_MOVE_ITEM = 3, + GUILD_BANK_LOG_DEPOSIT_MONEY = 4, + GUILD_BANK_LOG_WITHDRAW_MONEY = 5, + GUILD_BANK_LOG_REPAIR_MONEY = 6, + GUILD_BANK_LOG_MOVE_ITEM2 = 7, + GUILD_BANK_LOG_UNK1 = 8, + GUILD_BANK_LOG_BUY_SLOT = 9, + GUILD_BANK_LOG_CASH_FLOW_DEPOSIT = 10, }; enum GuildEventLogTypes @@ -192,7 +206,16 @@ enum GuildEmblem ERR_GUILDEMBLEM_INVALIDVENDOR = 5 }; -inline uint32 GetGuildBankTabPrice(uint8 Index) +enum GuildMemberFlags +{ + GUILDMEMBER_STATUS_NONE = 0x0000, + GUILDMEMBER_STATUS_ONLINE = 0x0001, + GUILDMEMBER_STATUS_AFK = 0x0002, + GUILDMEMBER_STATUS_DND = 0x0004, + GUILDMEMBER_STATUS_MOBILE = 0x0008, +}; + +inline uint64 GetGuildBankTabPrice(uint8 Index) { switch (Index) { @@ -214,6 +237,8 @@ struct GuildEventLogEntry uint32 PlayerGuid2; uint8 NewRank; uint64 TimeStamp; + + void WriteData(WorldPacket& data, ByteBuffer& buffer); }; struct GuildBankEventLogEntry @@ -231,6 +256,8 @@ struct GuildBankEventLogEntry EventType == GUILD_BANK_LOG_WITHDRAW_MONEY || EventType == GUILD_BANK_LOG_REPAIR_MONEY; } + + void WriteData(WorldPacket& data, ByteBuffer& buffer); }; struct GuildBankTab @@ -310,7 +337,9 @@ class Guild typedef UNORDERED_MAP MemberList; typedef std::vector RankList; - uint32 GetId() { return m_Id; } + uint32 GetId() const { return m_Id; } + uint32 GetLevel() const { return m_Level; } + ObjectGuid GetObjectGuid() const { return ObjectGuid(HIGHGUID_GUILD, 0, m_Id); } ObjectGuid GetLeaderGuid() const { return m_LeaderGuid; } std::string const& GetName() const { return m_Name; } std::string const& GetMOTD() const { return MOTD; } @@ -348,6 +377,8 @@ class Guild void BroadcastAddonToOfficers(WorldSession* session, const std::string& msg, const std::string& prefix); void BroadcastPacketToRank(WorldPacket* packet, uint32 rankId); void BroadcastPacket(WorldPacket* packet); + // for calendar + void MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, uint32 minRank); void BroadcastEvent(GuildEvents event, ObjectGuid guid, char const* str1 = NULL, char const* str2 = NULL, char const* str3 = NULL); void BroadcastEvent(GuildEvents event, char const* str1 = NULL, char const* str2 = NULL, char const* str3 = NULL) @@ -365,7 +396,8 @@ class Guild } void CreateRank(std::string name, uint32 rights); - void DelRank(); + void DelRank(uint32 rankId); + void SwitchRank(uint32 rankId, bool up); std::string GetRankName(uint32 rankId); uint32 GetRankRights(uint32 rankId); uint32 GetRanksSize() const { return m_Ranks.size(); } @@ -377,6 +409,15 @@ class Guild return ((GetRankRights(rankId) & right) != GR_RIGHT_EMPTY) ? true : false; } + bool HasMembersWithRank(uint32 rankId) const + { + for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr) + if (itr->second.RankId == rankId) + return true; + + return false; + } + int32 GetRank(ObjectGuid guid) { MemberSlot* slot = GetMemberSlot(guid); @@ -400,6 +441,7 @@ class Guild void Roster(WorldSession* session = NULL); // NULL = broadcast void Query(WorldSession* session); + void QueryRanks(WorldSession* session); // Guild EventLog void LoadGuildEventLogFromDB(); @@ -429,13 +471,13 @@ class Guild void LoadGuildBankFromDB(); // Money deposit/withdraw void SendMoneyInfo(WorldSession* session, uint32 LowGuid); - bool MemberMoneyWithdraw(uint32 amount, uint32 LowGuid); + bool MemberMoneyWithdraw(uint64 amount, uint32 LowGuid); uint64 GetGuildBankMoney() { return m_GuildBankMoney; } void SetBankMoney(int64 money); // per days bool MemberItemWithdraw(uint8 TabId, uint32 LowGuid); uint32 GetMemberSlotWithdrawRem(uint32 LowGuid, uint8 TabId); - uint32 GetMemberMoneyWithdrawRem(uint32 LowGuid); + uint64 GetMemberMoneyWithdrawRem(uint32 LowGuid); void SetBankMoneyPerDay(uint32 rankId, uint32 money); void SetBankRightsAndSlots(uint32 rankId, uint8 TabId, uint32 right, uint32 SlotPerDay, bool db); uint32 GetBankMoneyPerDay(uint32 rankId); @@ -452,6 +494,7 @@ class Guild void AddRank(const std::string& name, uint32 rights, uint32 money); uint32 m_Id; + uint32 m_Level; std::string m_Name; ObjectGuid m_LeaderGuid; std::string MOTD; @@ -498,7 +541,7 @@ class Guild void DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec const& slots); // internal common parts for CanStore/StoreItem functions - void AppendDisplayGuildBankSlot(WorldPacket& data, GuildBankTab const* tab, int32 slot); + void AppendDisplayGuildBankSlot(WorldPacket& data, ByteBuffer& buffer, GuildBankTab const* tab, int32 slot); InventoryResult _CanStoreItem_InSpecificSlot(uint8 tab, uint8 slot, GuildItemPosCountVec& dest, uint32& count, bool swap, Item* pSrcItem) const; InventoryResult _CanStoreItem_InTab(uint8 tab, GuildItemPosCountVec& dest, uint32& count, bool merge, Item* pSrcItem, uint8 skip_slot) const; Item* _StoreItem(uint8 tab, uint8 slot, Item* pItem, uint32 count, bool clone); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c3a53680e..a8a6efd6b 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "12641" + #define REVISION_NR "12642" #endif // __REVISION_NR_H__