[c12642] Fix client crash on guild bank display

This commit is contained in:
Dramacydal 2013-06-17 10:51:21 +01:00 committed by Antz
parent 5c21144f6b
commit c3eccda44d
3 changed files with 539 additions and 277 deletions

View file

@ -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<uint32>(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<uint8>(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
}

View file

@ -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<uint32, MemberSlot> MemberList;
typedef std::vector<RankInfo> 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);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "12641"
#define REVISION_NR "12642"
#endif // __REVISION_NR_H__