diff options
Diffstat (limited to 'src/game/Guild.cpp')
| -rw-r--r-- | src/game/Guild.cpp | 591 |
1 files changed, 307 insertions, 284 deletions
diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp index 6f627c4f986..37d5db941f7 100644 --- a/src/game/Guild.cpp +++ b/src/game/Guild.cpp @@ -29,22 +29,34 @@ #include "SocialMgr.h" #include "Util.h" #include "Language.h" +#include "World.h" Guild::Guild() { - Id = 0; - name = ""; - leaderGuid = 0; + m_Id = 0; + m_Name = ""; + m_LeaderGuid = 0; GINFO = MOTD = ""; - EmblemStyle = 0; - EmblemColor = 0; - BorderStyle = 0; - BorderColor = 0; - BackgroundColor = 0; + m_EmblemStyle = 0; + m_EmblemColor = 0; + m_BorderStyle = 0; + m_BorderColor = 0; + m_BackgroundColor = 0; - CreatedYear = 0; - CreatedMonth = 0; - CreatedDay = 0; + m_CreatedYear = 0; + m_CreatedMonth = 0; + m_CreatedDay = 0; + + m_EventLogLoaded = false; + m_GuildBankLoaded = false; + m_OnlineMembers = 0; + m_GuildBankMoney = 0; + m_PurchasedTabs = 0; + + m_GuildEventLogNextGuid = 0; + m_GuildBankEventLogNextGuid_Money = 0; + for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; i++) + m_GuildBankEventLogNextGuid_Item[i] = 0; } Guild::~Guild() @@ -52,7 +64,7 @@ Guild::~Guild() } -bool Guild::create(Player* leader, std::string gname) +bool Guild::Create(Player* leader, std::string gname) { if(objmgr.GetGuildByName(gname)) return false; @@ -61,15 +73,15 @@ bool Guild::create(Player* leader, std::string gname) if(!lSession) return false; - leaderGuid = leader->GetGUID(); - name = gname; + m_LeaderGuid = leader->GetGUID(); + m_Name = gname; GINFO = ""; MOTD = "No message set."; - guildbank_money = 0; - purchased_tabs = 0; - Id = objmgr.GenerateGuildId(); + m_GuildBankMoney = 0; + m_PurchasedTabs = 0; + m_Id = objmgr.GenerateGuildId(); - sLog.outDebug("GUILD: creating guild %s to leader: %u", gname.c_str(), GUID_LOPART(leaderGuid)); + sLog.outDebug("GUILD: creating guild %s to leader: %u", gname.c_str(), GUID_LOPART(m_LeaderGuid)); // gname already assigned to Guild::name, use it to encode string for DB CharacterDatabase.escape_string(gname); @@ -81,11 +93,11 @@ bool Guild::create(Player* leader, std::string gname) CharacterDatabase.BeginTransaction(); // CharacterDatabase.PExecute("DELETE FROM guild WHERE guildid='%u'", Id); - MAX(guildid)+1 not exist - CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid='%u'", Id); - CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guildid='%u'", Id); + CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid='%u'", m_Id); + CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guildid='%u'", m_Id); CharacterDatabase.PExecute("INSERT INTO guild (guildid,name,leaderguid,info,motd,createdate,EmblemStyle,EmblemColor,BorderStyle,BorderColor,BackgroundColor,BankMoney) " "VALUES('%u','%s','%u', '%s', '%s', NOW(),'%u','%u','%u','%u','%u','" UI64FMTD "')", - Id, gname.c_str(), GUID_LOPART(leaderGuid), dbGINFO.c_str(), dbMOTD.c_str(), EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor, guildbank_money); + m_Id, gname.c_str(), GUID_LOPART(m_LeaderGuid), dbGINFO.c_str(), dbMOTD.c_str(), m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor, m_BackgroundColor, m_GuildBankMoney); CharacterDatabase.CommitTransaction(); CreateRank(lSession->GetMangosString(LANG_GUILD_MASTER), GR_RIGHT_ALL); @@ -94,7 +106,7 @@ bool Guild::create(Player* leader, std::string gname) CreateRank(lSession->GetMangosString(LANG_GUILD_MEMBER), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); CreateRank(lSession->GetMangosString(LANG_GUILD_INITIATE),GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); - return AddMember(leaderGuid, (uint32)GR_GUILDMASTER); + return AddMember(m_LeaderGuid, (uint32)GR_GUILDMASTER); } bool Guild::AddMember(uint64 plGuid, uint32 plRank) @@ -136,12 +148,12 @@ bool Guild::AddMember(uint64 plGuid, uint32 plRank) CharacterDatabase.escape_string(dbOFFnote); CharacterDatabase.PExecute("INSERT INTO guild_member (guildid,guid,rank,pnote,offnote) VALUES ('%u', '%u', '%u','%s','%s')", - Id, GUID_LOPART(plGuid), newmember.RankId, dbPnote.c_str(), dbOFFnote.c_str()); + m_Id, GUID_LOPART(plGuid), newmember.RankId, dbPnote.c_str(), dbOFFnote.c_str()); // If player not in game data in data field will be loaded from guild tables, no need to update it!! if(pl) { - pl->SetInGuild(Id); + pl->SetInGuild(m_Id); pl->SetRank(newmember.RankId); pl->SetGuildIdInvited(0); } @@ -154,7 +166,7 @@ void Guild::SetMOTD(std::string motd) // motd now can be used for encoding to DB CharacterDatabase.escape_string(motd); - CharacterDatabase.PExecute("UPDATE guild SET motd='%s' WHERE guildid='%u'", motd.c_str(), Id); + CharacterDatabase.PExecute("UPDATE guild SET motd='%s' WHERE guildid='%u'", motd.c_str(), m_Id); } void Guild::SetGINFO(std::string ginfo) @@ -163,7 +175,7 @@ void Guild::SetGINFO(std::string ginfo) // ginfo now can be used for encoding to DB CharacterDatabase.escape_string(ginfo); - CharacterDatabase.PExecute("UPDATE guild SET info='%s' WHERE guildid='%u'", ginfo.c_str(), Id); + CharacterDatabase.PExecute("UPDATE guild SET info='%s' WHERE guildid='%u'", ginfo.c_str(), m_Id); } bool Guild::LoadGuildFromDB(uint32 GuildId) @@ -178,11 +190,11 @@ bool Guild::LoadGuildFromDB(uint32 GuildId) if(result) { Field *fields = result->Fetch(); - purchased_tabs = fields[0].GetUInt8()+1; // Because TabId begins at 0 + m_PurchasedTabs = fields[0].GetUInt8()+1; // Because TabId begins at 0 delete result; } else - purchased_tabs = 0; + m_PurchasedTabs = 0; LoadBankRightsFromDB(GuildId); // Must be after LoadRanksFromDB because it populates rank struct @@ -196,43 +208,39 @@ bool Guild::LoadGuildFromDB(uint32 GuildId) Field *fields = result->Fetch(); - Id = fields[0].GetUInt32(); - name = fields[1].GetCppString(); - leaderGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER); + m_Id = fields[0].GetUInt32(); + m_Name = fields[1].GetCppString(); + m_LeaderGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER); - EmblemStyle = fields[3].GetUInt32(); - EmblemColor = fields[4].GetUInt32(); - BorderStyle = fields[5].GetUInt32(); - BorderColor = fields[6].GetUInt32(); - BackgroundColor = fields[7].GetUInt32(); + m_EmblemStyle = fields[3].GetUInt32(); + m_EmblemColor = fields[4].GetUInt32(); + m_BorderStyle = fields[5].GetUInt32(); + m_BorderColor = fields[6].GetUInt32(); + m_BackgroundColor = fields[7].GetUInt32(); GINFO = fields[8].GetCppString(); MOTD = fields[9].GetCppString(); uint64 time = fields[10].GetUInt64(); //datetime is uint64 type ... YYYYmmdd:hh:mm:ss - guildbank_money = fields[11].GetUInt64(); + m_GuildBankMoney = fields[11].GetUInt64(); delete result; uint64 dTime = time /1000000; - CreatedDay = dTime%100; - CreatedMonth = (dTime/100)%100; - CreatedYear = (dTime/10000)%10000; + m_CreatedDay = dTime%100; + m_CreatedMonth = (dTime/100)%100; + m_CreatedYear = (dTime/10000)%10000; // If the leader does not exist attempt to promote another member - if(!objmgr.GetPlayerAccountIdByGUID(leaderGuid )) + if(!objmgr.GetPlayerAccountIdByGUID(m_LeaderGuid )) { - DelMember(leaderGuid); + DelMember(m_LeaderGuid); // check no members case (disbanded) if(members.empty()) return false; } - sLog.outDebug("Guild %u Creation time Loaded day: %u, month: %u, year: %u", GuildId, CreatedDay, CreatedMonth, CreatedYear); - m_bankloaded = false; - m_eventlogloaded = false; - m_onlinemembers = 0; - RenumBankLogs(); - RenumGuildEventlog(); + sLog.outDebug("Guild %u Creation time Loaded day: %u, month: %u, year: %u", GuildId, m_CreatedDay, m_CreatedMonth, m_CreatedYear); + return true; } @@ -255,17 +263,17 @@ bool Guild::LoadRanksFromDB(uint32 GuildId) uint32 rankMoney = fields[2].GetUInt32(); uint32 rankRID = fields[3].GetUInt32(); - if(rankRID != m_ranks.size()+1) // guild_rank.rid always store rank+1 + if(rankRID != m_Ranks.size()+1) // guild_rank.rid always store rank+1 broken_ranks = true; - if(m_ranks.size()==GR_GUILDMASTER) // prevent loss leader rights + if(m_Ranks.size() == GR_GUILDMASTER) // prevent loss leader rights rankRights |= GR_RIGHT_ALL; AddRank(rankName,rankRights,rankMoney); }while( result->NextRow() ); delete result; - if(m_ranks.size()==0) // empty rank table? + if(m_Ranks.size()==0) // empty rank table? { AddRank("Guild Master",GR_RIGHT_ALL,0); broken_ranks = true; @@ -277,11 +285,11 @@ bool Guild::LoadRanksFromDB(uint32 GuildId) sLog.outError("Guild %u have broken `guild_rank` data, repairing...",GuildId); CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid='%u'", GuildId); - for(size_t i =0; i < m_ranks.size(); ++i) + for(size_t i =0; i < m_Ranks.size(); ++i) { // guild_rank.rid always store rank+1 - std::string name = m_ranks[i].name; - uint32 rights = m_ranks[i].rights; + std::string name = m_Ranks[i].name; + uint32 rights = m_Ranks[i].rights; CharacterDatabase.escape_string(name); CharacterDatabase.PExecute( "INSERT INTO guild_rank (guildid,rid,rname,rights) VALUES ('%u', '%u', '%s', '%u')", GuildId, uint32(i+1), name.c_str(), rights); } @@ -428,15 +436,15 @@ void Guild::LoadPlayerStatsByGuid(uint64 guid) void Guild::SetLeader(uint64 guid) { - leaderGuid = guid; + m_LeaderGuid = guid; ChangeRank(guid, GR_GUILDMASTER); - CharacterDatabase.PExecute("UPDATE guild SET leaderguid='%u' WHERE guildid='%u'", GUID_LOPART(guid), Id); + CharacterDatabase.PExecute("UPDATE guild SET leaderguid='%u' WHERE guildid='%u'", GUID_LOPART(guid), m_Id); } void Guild::DelMember(uint64 guid, bool isDisbanding) { - if(leaderGuid == guid && !isDisbanding) + if(m_LeaderGuid == guid && !isDisbanding) { MemberSlot* oldLeader = NULL; MemberSlot* best = NULL; @@ -597,76 +605,76 @@ void Guild::BroadcastPacketToRank(WorldPacket *packet, uint32 rankId) void Guild::CreateRank(std::string name_,uint32 rights) { - if(m_ranks.size() >= GUILD_MAX_RANKS) + if(m_Ranks.size() >= GUILD_MAX_RANKS) return; AddRank(name_,rights,0); - for (uint8 i = 0; i < purchased_tabs; ++i) + for (int i = 0; i < m_PurchasedTabs; ++i) { - CreateBankRightForTab(m_ranks.size()-1, uint8(i)); + CreateBankRightForTab(m_Ranks.size()-1, uint8(i)); } // guild_rank.rid always store rank+1 value // name now can be used for encoding to DB CharacterDatabase.escape_string(name_); - CharacterDatabase.PExecute( "INSERT INTO guild_rank (guildid,rid,rname,rights) VALUES ('%u', '%u', '%s', '%u')", Id, (unsigned int)m_ranks.size(), name_.c_str(), rights ); + CharacterDatabase.PExecute( "INSERT INTO guild_rank (guildid,rid,rname,rights) VALUES ('%u', '%u', '%s', '%u')", m_Id, (unsigned int)m_Ranks.size(), name_.c_str(), rights ); } void Guild::AddRank(const std::string& name_,uint32 rights, uint32 money) { - m_ranks.push_back(RankInfo(name_,rights,money)); + m_Ranks.push_back(RankInfo(name_,rights,money)); } void Guild::DelRank() { - if(m_ranks.empty()) + if(m_Ranks.empty()) return; // guild_rank.rid always store rank+1 value - uint32 rank = m_ranks.size()-1; - CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE rid>='%u' AND guildid='%u'", (rank+1), Id); + uint32 rank = m_Ranks.size()-1; + CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE rid>='%u' AND guildid='%u'", (rank+1), m_Id); - m_ranks.pop_back(); + m_Ranks.pop_back(); } std::string Guild::GetRankName(uint32 rankId) { - if(rankId >= m_ranks.size()) + if(rankId >= m_Ranks.size()) return "<unknown>"; - return m_ranks[rankId].name; + return m_Ranks[rankId].name; } uint32 Guild::GetRankRights(uint32 rankId) { - if(rankId >= m_ranks.size()) + if(rankId >= m_Ranks.size()) return 0; - return m_ranks[rankId].rights; + return m_Ranks[rankId].rights; } void Guild::SetRankName(uint32 rankId, std::string name_) { - if(rankId >= m_ranks.size()) + if(rankId >= m_Ranks.size()) return; - m_ranks[rankId].name = name_; + m_Ranks[rankId].name = name_; // name now can be used for encoding to DB CharacterDatabase.escape_string(name_); - CharacterDatabase.PExecute("UPDATE guild_rank SET rname='%s' WHERE rid='%u' AND guildid='%u'", name_.c_str(), (rankId+1), Id); + CharacterDatabase.PExecute("UPDATE guild_rank SET rname='%s' WHERE rid='%u' AND guildid='%u'", name_.c_str(), (rankId+1), m_Id); } void Guild::SetRankRights(uint32 rankId, uint32 rights) { - if(rankId >= m_ranks.size()) + if(rankId >= m_Ranks.size()) return; - m_ranks[rankId].rights = rights; + m_Ranks[rankId].rights = rights; - CharacterDatabase.PExecute("UPDATE guild_rank SET rights='%u' WHERE rid='%u' AND guildid='%u'", rights, (rankId+1), Id); + CharacterDatabase.PExecute("UPDATE guild_rank SET rights='%u' WHERE rid='%u' AND guildid='%u'", rights, (rankId+1), m_Id); } int32 Guild::GetRank(uint32 LowGuid) @@ -691,27 +699,27 @@ void Guild::Disband() } CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("DELETE FROM guild WHERE guildid = '%u'",Id); - CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid = '%u'",Id); - CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid = '%u'",Id); - CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid = '%u'",Id); - CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid = '%u'",Id); - CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid = '%u'",Id); - CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid = '%u'",Id); + CharacterDatabase.PExecute("DELETE FROM guild WHERE guildid = '%u'", m_Id); + CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid = '%u'", m_Id); + CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid = '%u'", m_Id); + CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid = '%u'", m_Id); + CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid = '%u'", m_Id); + CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid = '%u'", m_Id); + CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid = '%u'", m_Id); CharacterDatabase.CommitTransaction(); - objmgr.RemoveGuild(Id); + objmgr.RemoveGuild(m_Id); } void Guild::Roster(WorldSession *session) { // 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)); + 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; - data << (uint32)m_ranks.size(); - for (RankList::const_iterator ritr = m_ranks.begin(); ritr != m_ranks.end(); ++ritr) + 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. @@ -759,22 +767,22 @@ void Guild::Query(WorldSession *session) { WorldPacket data(SMSG_GUILD_QUERY_RESPONSE, (8*32+200));// we can only guess size - data << Id; - data << name; + data << m_Id; + data << m_Name; for (size_t i = 0 ; i < 10; ++i) // show always 10 ranks { - if(i < m_ranks.size()) - data << m_ranks[i].name; + if(i < m_Ranks.size()) + data << m_Ranks[i].name; else data << (uint8)0; // null string } - data << uint32(EmblemStyle); - data << uint32(EmblemColor); - data << uint32(BorderStyle); - data << uint32(BorderColor); - data << uint32(BackgroundColor); + data << uint32(m_EmblemStyle); + data << uint32(m_EmblemColor); + data << uint32(m_BorderStyle); + data << uint32(m_BorderColor); + data << uint32(m_BackgroundColor); data << uint32(0); // something new in WotLK session->SendPacket( &data ); @@ -783,13 +791,13 @@ void Guild::Query(WorldSession *session) void Guild::SetEmblem(uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor, uint32 backgroundColor) { - EmblemStyle = emblemStyle; - EmblemColor = emblemColor; - BorderStyle = borderStyle; - BorderColor = borderColor; - BackgroundColor = backgroundColor; + m_EmblemStyle = emblemStyle; + m_EmblemColor = emblemColor; + m_BorderStyle = borderStyle; + m_BorderColor = borderColor; + m_BackgroundColor = backgroundColor; - CharacterDatabase.PExecute("UPDATE guild SET EmblemStyle=%u, EmblemColor=%u, BorderStyle=%u, BorderColor=%u, BackgroundColor=%u WHERE guildid = %u", EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor, Id); + CharacterDatabase.PExecute("UPDATE guild SET EmblemStyle=%u, EmblemColor=%u, BorderStyle=%u, BorderColor=%u, BackgroundColor=%u WHERE guildid = %u", m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor, m_BackgroundColor, m_Id); } void Guild::UpdateLogoutTime(uint64 guid) @@ -800,12 +808,12 @@ void Guild::UpdateLogoutTime(uint64 guid) itr->second.logout_time = time(NULL); - if (m_onlinemembers > 0) - --m_onlinemembers; + if (m_OnlineMembers > 0) + --m_OnlineMembers; else { UnloadGuildBank(); - UnloadGuildEventlog(); + UnloadGuildEventLog(); } } @@ -813,17 +821,17 @@ void Guild::UpdateLogoutTime(uint64 guid) // Guild Eventlog part // ************************************************* // Display guild eventlog -void Guild::DisplayGuildEventlog(WorldSession *session) +void Guild::DisplayGuildEventLog(WorldSession *session) { // Load guild eventlog, if not already done - if (!m_eventlogloaded) + if (!m_EventLogLoaded) LoadGuildEventLogFromDB(); // Sending result WorldPacket data(MSG_GUILD_EVENT_LOG_QUERY, 0); // count, max count == 100 - data << uint8(m_GuildEventlog.size()); - for (GuildEventlog::const_iterator itr = m_GuildEventlog.begin(); itr != m_GuildEventlog.end(); ++itr) + data << uint8(m_GuildEventLog.size()); + for (GuildEventLog::const_iterator itr = m_GuildEventLog.begin(); itr != m_GuildEventLog.end(); ++itr) { // Event type data << uint8(itr->EventType); @@ -846,82 +854,76 @@ void Guild::DisplayGuildEventlog(WorldSession *session) void Guild::LoadGuildEventLogFromDB() { // Return if already loaded - if (m_eventlogloaded) + if (m_EventLogLoaded) return; - QueryResult *result = CharacterDatabase.PQuery("SELECT LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp FROM guild_eventlog WHERE guildid=%u ORDER BY LogGuid DESC LIMIT %u", Id, GUILD_EVENTLOG_MAX_ENTRIES); + // 0 1 2 3 4 5 + QueryResult *result = CharacterDatabase.PQuery("SELECT LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp FROM guild_eventlog WHERE guildid=%u ORDER BY TimeStamp DESC,LogGuid DESC LIMIT %u", m_Id, GUILD_EVENTLOG_MAX_RECORDS); if(!result) return; + bool isNextLogGuidSet = false; + //uint32 configCount = sWorld.getConfig(CONFIG_GUILD_EVENT_LOG_COUNT); + // First event in list will be the oldest and the latest event is last event in list do { Field *fields = result->Fetch(); - GuildEventlogEntry NewEvent; + if (!isNextLogGuidSet) + { + m_GuildEventLogNextGuid = fields[0].GetUInt32(); + isNextLogGuidSet = true; + } // Fill entry - NewEvent.LogGuid = fields[0].GetUInt32(); + GuildEventLogEntry NewEvent; NewEvent.EventType = fields[1].GetUInt8(); NewEvent.PlayerGuid1 = fields[2].GetUInt32(); NewEvent.PlayerGuid2 = fields[3].GetUInt32(); NewEvent.NewRank = fields[4].GetUInt8(); NewEvent.TimeStamp = fields[5].GetUInt64(); - // Add entry to map - m_GuildEventlog.push_front(NewEvent); + + // There can be a problem if more events have same TimeStamp the ORDER can be broken when fields[0].GetUInt32() == configCount, but + // events with same timestamp can appear when there is lag, and we naivly suppose that mangos isn't laggy + // but if problem appears, player will see set of guild events that have same timestamp in bad order + + // Add entry to list + m_GuildEventLog.push_front(NewEvent); } while( result->NextRow() ); delete result; - // Check lists size in case to many event entries in db - // This cases can happen only if a crash occured somewhere and table has too many log entries - if (!m_GuildEventlog.empty()) - CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid=%u AND LogGuid < %u", Id, m_GuildEventlog.front().LogGuid); - - m_eventlogloaded = true; + m_EventLogLoaded = true; } // Unload guild eventlog -void Guild::UnloadGuildEventlog() +void Guild::UnloadGuildEventLog() { - if (!m_eventlogloaded) + if (!m_EventLogLoaded) return; - m_GuildEventlog.clear(); - m_eventlogloaded = false; -} - -// This will renum guids used at load to prevent always going up until infinit -void Guild::RenumGuildEventlog() -{ - QueryResult *result = CharacterDatabase.PQuery("SELECT Min(LogGuid), Max(LogGuid) FROM guild_eventlog WHERE guildid = %u", Id); - if(!result) - return; - - Field *fields = result->Fetch(); - CharacterDatabase.PExecute("UPDATE guild_eventlog SET LogGuid=LogGuid-%u+1 WHERE guildid=%u ORDER BY LogGuid %s",fields[0].GetUInt32(), Id, fields[0].GetUInt32()?"ASC":"DESC"); - GuildEventlogMaxGuid = fields[1].GetUInt32()+1; - delete result; + m_GuildEventLog.clear(); + m_EventLogLoaded = false; } // Add entry to guild eventlog void Guild::LogGuildEvent(uint8 EventType, uint32 PlayerGuid1, uint32 PlayerGuid2, uint8 NewRank) { - GuildEventlogEntry NewEvent; - // Fill entry - NewEvent.LogGuid = GuildEventlogMaxGuid++; + GuildEventLogEntry NewEvent; + // Create event NewEvent.EventType = EventType; NewEvent.PlayerGuid1 = PlayerGuid1; NewEvent.PlayerGuid2 = PlayerGuid2; NewEvent.NewRank = NewRank; NewEvent.TimeStamp = uint32(time(NULL)); - // Check max entry limit and delete from db if needed - if (m_GuildEventlog.size() > GUILD_EVENTLOG_MAX_ENTRIES) - { - CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid='%u' AND LogGuid='%u'", Id, m_GuildEventlog.front().LogGuid); - m_GuildEventlog.pop_front(); - } - // Add entry to map - m_GuildEventlog.push_back(NewEvent); - // Add new eventlog entry into DB + // Count new LogGuid + m_GuildEventLogNextGuid = (m_GuildEventLogNextGuid + 1) % sWorld.getConfig(CONFIG_GUILD_EVENT_LOG_COUNT); + // Check max records limit + if (m_GuildEventLog.size() >= GUILD_EVENTLOG_MAX_RECORDS) + m_GuildEventLog.pop_front(); + // Add event to list + m_GuildEventLog.push_back(NewEvent); + // Save event to DB + CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid='%u' AND LogGuid='%u'", m_Id, m_GuildEventLogNextGuid); CharacterDatabase.PExecute("INSERT INTO guild_eventlog (guildid, LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','" UI64FMTD "')", - Id, NewEvent.LogGuid, uint32(NewEvent.EventType), NewEvent.PlayerGuid1, NewEvent.PlayerGuid2, uint32(NewEvent.NewRank), NewEvent.TimeStamp); + m_Id, m_GuildEventLogNextGuid, uint32(NewEvent.EventType), NewEvent.PlayerGuid1, NewEvent.PlayerGuid2, uint32(NewEvent.NewRank), NewEvent.TimeStamp); } // ************************************************* @@ -1070,7 +1072,7 @@ Item* Guild::GetItem(uint8 TabId, uint8 SlotId) void Guild::DisplayGuildBankTabsInfo(WorldSession *session) { // Time to load bank if not already done - if (!m_bankloaded) + if (!m_GuildBankLoaded) LoadGuildBankFromDB(); WorldPacket data(SMSG_GUILD_BANK_LIST, 500); @@ -1080,9 +1082,9 @@ void Guild::DisplayGuildBankTabsInfo(WorldSession *session) data << uint32(0xFFFFFFFF); // bit 9 must be set for this packet to work data << uint8(1); // Tell Client this is a TabInfo packet - data << uint8(purchased_tabs); // here is the number of tabs + data << uint8(m_PurchasedTabs); // here is the number of tabs - for(uint8 i = 0; i < purchased_tabs; ++i) + for(int i = 0; i < m_PurchasedTabs; ++i) { data << m_TabListMap[i]->Name.c_str(); data << m_TabListMap[i]->Icon.c_str(); @@ -1095,19 +1097,19 @@ void Guild::DisplayGuildBankTabsInfo(WorldSession *session) void Guild::CreateNewBankTab() { - if (purchased_tabs >= GUILD_BANK_MAX_TABS) + if (m_PurchasedTabs >= GUILD_BANK_MAX_TABS) return; - ++purchased_tabs; + ++m_PurchasedTabs; GuildBankTab* AnotherTab = new GuildBankTab; memset(AnotherTab->Slots, 0, GUILD_BANK_MAX_SLOTS * sizeof(Item*)); - m_TabListMap.resize(purchased_tabs); - m_TabListMap[purchased_tabs-1] = AnotherTab; + m_TabListMap.resize(m_PurchasedTabs); + m_TabListMap[m_PurchasedTabs-1] = AnotherTab; CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid='%u' AND TabId='%u'", Id, uint32(purchased_tabs-1)); - CharacterDatabase.PExecute("INSERT INTO guild_bank_tab (guildid,TabId) VALUES ('%u','%u')", Id, uint32(purchased_tabs-1)); + CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid='%u' AND TabId='%u'", m_Id, uint32(m_PurchasedTabs-1)); + CharacterDatabase.PExecute("INSERT INTO guild_bank_tab (guildid,TabId) VALUES ('%u','%u')", m_Id, uint32(m_PurchasedTabs-1)); CharacterDatabase.CommitTransaction(); } @@ -1129,29 +1131,29 @@ void Guild::SetGuildBankTabInfo(uint8 TabId, std::string Name, std::string Icon) CharacterDatabase.escape_string(Name); CharacterDatabase.escape_string(Icon); - CharacterDatabase.PExecute("UPDATE guild_bank_tab SET TabName='%s',TabIcon='%s' WHERE guildid='%u' AND TabId='%u'", Name.c_str(), Icon.c_str(), Id, uint32(TabId)); + CharacterDatabase.PExecute("UPDATE guild_bank_tab SET TabName='%s',TabIcon='%s' WHERE guildid='%u' AND TabId='%u'", Name.c_str(), Icon.c_str(), m_Id, uint32(TabId)); } void Guild::CreateBankRightForTab(uint32 rankId, uint8 TabId) { sLog.outDebug("CreateBankRightForTab. rank: %u, TabId: %u", rankId, uint32(TabId)); - if (rankId >= m_ranks.size() || TabId >= GUILD_BANK_MAX_TABS) + if (rankId >= m_Ranks.size() || TabId >= GUILD_BANK_MAX_TABS) return; - m_ranks[rankId].TabRight[TabId]=0; - m_ranks[rankId].TabSlotPerDay[TabId]=0; + m_Ranks[rankId].TabRight[TabId]=0; + m_Ranks[rankId].TabSlotPerDay[TabId]=0; CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid = '%u' AND TabId = '%u' AND rid = '%u'", Id, uint32(TabId), rankId); - CharacterDatabase.PExecute("INSERT INTO guild_bank_right (guildid,TabId,rid) VALUES ('%u','%u','%u')", Id, uint32(TabId), rankId); + CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid = '%u' AND TabId = '%u' AND rid = '%u'", m_Id, uint32(TabId), rankId); + CharacterDatabase.PExecute("INSERT INTO guild_bank_right (guildid,TabId,rid) VALUES ('%u','%u','%u')", m_Id, uint32(TabId), rankId); CharacterDatabase.CommitTransaction(); } uint32 Guild::GetBankRights(uint32 rankId, uint8 TabId) const { - if(rankId >= m_ranks.size() || TabId >= GUILD_BANK_MAX_TABS) + if(rankId >= m_Ranks.size() || TabId >= GUILD_BANK_MAX_TABS) return 0; - return m_ranks[rankId].TabRight[TabId]; + return m_Ranks[rankId].TabRight[TabId]; } // ************************************************* @@ -1160,21 +1162,21 @@ uint32 Guild::GetBankRights(uint32 rankId, uint8 TabId) const // This load should be called when the bank is first accessed by a guild member void Guild::LoadGuildBankFromDB() { - if (m_bankloaded) + if (m_GuildBankLoaded) return; - m_bankloaded = true; + m_GuildBankLoaded = true; LoadGuildBankEventLogFromDB(); // 0 1 2 3 - QueryResult *result = CharacterDatabase.PQuery("SELECT TabId, TabName, TabIcon, TabText FROM guild_bank_tab WHERE guildid='%u' ORDER BY TabId", Id); + QueryResult *result = CharacterDatabase.PQuery("SELECT TabId, TabName, TabIcon, TabText FROM guild_bank_tab WHERE guildid='%u' ORDER BY TabId", m_Id); if(!result) { - purchased_tabs = 0; + m_PurchasedTabs = 0; return; } - m_TabListMap.resize(purchased_tabs); + m_TabListMap.resize(m_PurchasedTabs); do { Field *fields = result->Fetch(); @@ -1194,7 +1196,7 @@ void Guild::LoadGuildBankFromDB() // data needs to be at first place for Item::LoadFromDB // 0 1 2 3 4 - result = CharacterDatabase.PQuery("SELECT data, TabId, SlotId, item_guid, item_entry FROM guild_bank_item JOIN item_instance ON item_guid = guid WHERE guildid='%u' ORDER BY TabId", Id); + result = CharacterDatabase.PQuery("SELECT data, TabId, SlotId, item_guid, item_entry FROM guild_bank_item JOIN item_instance ON item_guid = guid WHERE guildid='%u' ORDER BY TabId", m_Id); if(!result) return; @@ -1206,7 +1208,7 @@ void Guild::LoadGuildBankFromDB() uint32 ItemGuid = fields[3].GetUInt32(); uint32 ItemEntry = fields[4].GetUInt32(); - if (TabId >= purchased_tabs || TabId >= GUILD_BANK_MAX_TABS) + if (TabId >= m_PurchasedTabs || TabId >= GUILD_BANK_MAX_TABS) { sLog.outError( "Guild::LoadGuildBankFromDB: Invalid tab for item (GUID: %u id: #%u) in guild bank, skipped.", ItemGuid,ItemEntry); continue; @@ -1229,7 +1231,7 @@ void Guild::LoadGuildBankFromDB() Item *pItem = NewItemOrBag(proto); if(!pItem->LoadFromDB(ItemGuid, 0, result)) { - CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid='%u' AND TabId='%u' AND SlotId='%u'", Id, uint32(TabId), uint32(SlotId)); + CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid='%u' AND TabId='%u' AND SlotId='%u'", m_Id, uint32(TabId), uint32(SlotId)); sLog.outError("Item GUID %u not found in item_instance, deleting from Guild Bank!", ItemGuid); delete pItem; continue; @@ -1245,9 +1247,9 @@ void Guild::LoadGuildBankFromDB() // This unload should be called when the last member of the guild gets offline void Guild::UnloadGuildBank() { - if (!m_bankloaded) + if (!m_GuildBankLoaded) return; - for (uint8 i = 0 ; i < purchased_tabs ; ++i ) + for (uint8 i = 0 ; i < m_PurchasedTabs ; ++i ) { for (uint8 j = 0 ; j < GUILD_BANK_MAX_SLOTS ; ++j) { @@ -1262,7 +1264,7 @@ void Guild::UnloadGuildBank() m_TabListMap.clear(); UnloadGuildBankEventLog(); - m_bankloaded = false; + m_GuildBankLoaded = false; } // ************************************************* @@ -1292,7 +1294,7 @@ bool Guild::MemberMoneyWithdraw(uint32 amount, uint32 LowGuid) return false; itr->second.BankRemMoney -= amount; CharacterDatabase.PExecute("UPDATE guild_member SET BankRemMoney='%u' WHERE guildid='%u' AND guid='%u'", - itr->second.BankRemMoney, Id, LowGuid); + itr->second.BankRemMoney, m_Id, LowGuid); } return true; } @@ -1301,9 +1303,9 @@ void Guild::SetBankMoney(int64 money) { if (money < 0) // I don't know how this happens, it does!! money = 0; - guildbank_money = money; + m_GuildBankMoney = money; - CharacterDatabase.PExecute("UPDATE guild SET BankMoney='" UI64FMTD "' WHERE guildid='%u'", money, Id); + CharacterDatabase.PExecute("UPDATE guild SET BankMoney='" UI64FMTD "' WHERE guildid='%u'", money, m_Id); } // ************************************************* @@ -1323,7 +1325,7 @@ bool Guild::MemberItemWithdraw(uint8 TabId, uint32 LowGuid) return false; --itr->second.BankRemSlotsTab[TabId]; CharacterDatabase.PExecute("UPDATE guild_member SET BankRemSlotsTab%u='%u' WHERE guildid='%u' AND guid='%u'", - uint32(TabId), itr->second.BankRemSlotsTab[TabId], Id, LowGuid); + uint32(TabId), itr->second.BankRemSlotsTab[TabId], m_Id, LowGuid); } return true; } @@ -1358,7 +1360,7 @@ uint32 Guild::GetMemberSlotWithdrawRem(uint32 LowGuid, uint8 TabId) itr->second.BankResetTimeTab[TabId] = curTime; itr->second.BankRemSlotsTab[TabId] = GetBankSlotPerDay(itr->second.RankId, TabId); CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeTab%u='%u',BankRemSlotsTab%u='%u' WHERE guildid='%u' AND guid='%u'", - uint32(TabId), itr->second.BankResetTimeTab[TabId], uint32(TabId), itr->second.BankRemSlotsTab[TabId], Id, LowGuid); + uint32(TabId), itr->second.BankResetTimeTab[TabId], uint32(TabId), itr->second.BankRemSlotsTab[TabId], m_Id, LowGuid); } return itr->second.BankRemSlotsTab[TabId]; } @@ -1379,34 +1381,34 @@ uint32 Guild::GetMemberMoneyWithdrawRem(uint32 LowGuid) itr->second.BankResetTimeMoney = curTime; itr->second.BankRemMoney = GetBankMoneyPerDay(itr->second.RankId); CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeMoney='%u',BankRemMoney='%u' WHERE guildid='%u' AND guid='%u'", - itr->second.BankResetTimeMoney, itr->second.BankRemMoney, Id, LowGuid); + itr->second.BankResetTimeMoney, itr->second.BankRemMoney, m_Id, LowGuid); } return itr->second.BankRemMoney; } void Guild::SetBankMoneyPerDay(uint32 rankId, uint32 money) { - if (rankId >= m_ranks.size()) + if (rankId >= m_Ranks.size()) return; if (rankId == GR_GUILDMASTER) money = WITHDRAW_MONEY_UNLIMITED; - m_ranks[rankId].BankMoneyPerDay = money; + m_Ranks[rankId].BankMoneyPerDay = money; for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) if (itr->second.RankId == rankId) itr->second.BankResetTimeMoney = 0; - CharacterDatabase.PExecute("UPDATE guild_rank SET BankMoneyPerDay='%u' WHERE rid='%u' AND guildid='%u'", money, (rankId+1), Id); - CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeMoney='0' WHERE guildid='%u' AND rank='%u'", Id, rankId); + CharacterDatabase.PExecute("UPDATE guild_rank SET BankMoneyPerDay='%u' WHERE rid='%u' AND guildid='%u'", money, (rankId+1), m_Id); + CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeMoney='0' WHERE guildid='%u' AND rank='%u'", m_Id, rankId); } void Guild::SetBankRightsAndSlots(uint32 rankId, uint8 TabId, uint32 right, uint32 nbSlots, bool db) { - if(rankId >= m_ranks.size() || + if(rankId >= m_Ranks.size() || TabId >= GUILD_BANK_MAX_TABS || - TabId >= purchased_tabs) + TabId >= m_PurchasedTabs) return; if (rankId == GR_GUILDMASTER) @@ -1415,8 +1417,8 @@ void Guild::SetBankRightsAndSlots(uint32 rankId, uint8 TabId, uint32 right, uint right = GUILD_BANK_RIGHT_FULL; } - m_ranks[rankId].TabSlotPerDay[TabId]=nbSlots; - m_ranks[rankId].TabRight[TabId]=right; + m_Ranks[rankId].TabSlotPerDay[TabId]=nbSlots; + m_Ranks[rankId].TabRight[TabId]=right; if (db) { @@ -1425,31 +1427,31 @@ void Guild::SetBankRightsAndSlots(uint32 rankId, uint8 TabId, uint32 right, uint for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; ++i) itr->second.BankResetTimeTab[i] = 0; - CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid='%u' AND TabId='%u' AND rid='%u'", Id, uint32(TabId), rankId); + CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid='%u' AND TabId='%u' AND rid='%u'", m_Id, uint32(TabId), rankId); CharacterDatabase.PExecute("INSERT INTO guild_bank_right (guildid,TabId,rid,gbright,SlotPerDay) VALUES " - "('%u','%u','%u','%u','%u')", Id, uint32(TabId), rankId, m_ranks[rankId].TabRight[TabId], m_ranks[rankId].TabSlotPerDay[TabId]); - CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeTab%u='0' WHERE guildid='%u' AND rank='%u'", uint32(TabId), Id, rankId); + "('%u','%u','%u','%u','%u')", m_Id, uint32(TabId), rankId, m_Ranks[rankId].TabRight[TabId], m_Ranks[rankId].TabSlotPerDay[TabId]); + CharacterDatabase.PExecute("UPDATE guild_member SET BankResetTimeTab%u='0' WHERE guildid='%u' AND rank='%u'", uint32(TabId), m_Id, rankId); } } uint32 Guild::GetBankMoneyPerDay(uint32 rankId) { - if(rankId >= m_ranks.size()) + if(rankId >= m_Ranks.size()) return 0; if (rankId == GR_GUILDMASTER) return WITHDRAW_MONEY_UNLIMITED; - return m_ranks[rankId].BankMoneyPerDay; + return m_Ranks[rankId].BankMoneyPerDay; } uint32 Guild::GetBankSlotPerDay(uint32 rankId, uint8 TabId) { - if(rankId >= m_ranks.size() || TabId >= GUILD_BANK_MAX_TABS) + if(rankId >= m_Ranks.size() || TabId >= GUILD_BANK_MAX_TABS) return 0; if (rankId == GR_GUILDMASTER) return WITHDRAW_SLOT_UNLIMITED; - return m_ranks[rankId].TabSlotPerDay[TabId]; + return m_Ranks[rankId].TabSlotPerDay[TabId]; } // ************************************************* @@ -1484,59 +1486,88 @@ void Guild::LoadBankRightsFromDB(uint32 GuildId) void Guild::LoadGuildBankEventLogFromDB() { - // We can't add a limit as in Guild::LoadGuildEventLogFromDB since we fetch both money and bank log and know nothing about the composition - // 0 1 2 3 4 5 6 7 - QueryResult *result = CharacterDatabase.PQuery("SELECT LogGuid, LogEntry, TabId, PlayerGuid, ItemOrMoney, ItemStackCount, DestTabId, TimeStamp FROM guild_bank_eventlog WHERE guildid='%u' ORDER BY TimeStamp DESC", Id); + // Money log is in TabId = GUILD_BANK_MONEY_LOGS_TAB + + //uint32 configCount = sWorld.getConfig(CONFIG_GUILD_BANK_EVENT_LOG_COUNT); + //cycle through all purchased guild bank item tabs + for (uint32 tabId = 0; tabId < m_PurchasedTabs; tabId++) + { + // 0 1 2 3 4 5 6 + QueryResult *result = CharacterDatabase.PQuery("SELECT LogGuid, EventType, PlayerGuid, ItemOrMoney, ItemStackCount, DestTabId, TimeStamp FROM guild_bank_eventlog WHERE guildid='%u' AND TabId='%u' ORDER BY TimeStamp DESC,LogGuid DESC LIMIT %u", m_Id, tabId, GUILD_BANK_MAX_LOGS); + if(!result) + continue; + + bool isNextLogGuidSet = false; + do + { + Field *fields = result->Fetch(); + + GuildBankEventLogEntry NewEvent; + NewEvent.EventType = fields[1].GetUInt8(); + NewEvent.PlayerGuid = fields[2].GetUInt32(); + NewEvent.ItemOrMoney = fields[3].GetUInt32(); + NewEvent.ItemStackCount = fields[4].GetUInt8(); + NewEvent.DestTabId = fields[5].GetUInt8(); + NewEvent.TimeStamp = fields[6].GetUInt64(); + + //if newEvent is moneyEvent, move it to moneyEventTab in DB and report error + if (NewEvent.isMoneyEvent()) + { + uint32 logGuid = fields[0].GetUInt32(); + CharacterDatabase.PExecute("UPDATE guild_bank_eventlog SET TabId='%u' WHERE guildid='%u' AND TabId='%u' AND LogGuid='%u'", GUILD_BANK_MONEY_LOGS_TAB, m_Id, tabId, logGuid); + sLog.outError("GuildBankEventLog ERROR: MoneyEvent LogGuid %u for Guild %u had incorrectly set its TabId to %u, correcting it to %u TabId", logGuid, m_Id, tabId, GUILD_BANK_MONEY_LOGS_TAB); + continue; + } + else + //add event to list + //events are ordered from oldest (in beginning) to latest (in the end) + m_GuildBankEventLog_Item[tabId].push_front(NewEvent); + + if (!isNextLogGuidSet) + { + m_GuildBankEventLogNextGuid_Item[tabId] = fields[0].GetUInt32(); + //we don't have to do m_GuildBankEventLogNextGuid_Item[tabId] %= configCount; - it will be done when creating new record + isNextLogGuidSet = true; + } + } while( result->NextRow() ); + delete result; + } + + //special handle for guild bank money log + // 0 1 2 3 4 5 6 + QueryResult *result = CharacterDatabase.PQuery("SELECT LogGuid, EventType, PlayerGuid, ItemOrMoney, ItemStackCount, DestTabId, TimeStamp FROM guild_bank_eventlog WHERE guildid='%u' AND TabId='%u' ORDER BY TimeStamp DESC,LogGuid DESC LIMIT %u", m_Id, GUILD_BANK_MONEY_LOGS_TAB, GUILD_BANK_MAX_LOGS); if(!result) return; + bool isNextMoneyLogGuidSet = false; do { Field *fields = result->Fetch(); - GuildBankEvent NewEvent; - - NewEvent.LogGuid = fields[0].GetUInt32(); - NewEvent.LogEntry = fields[1].GetUInt8(); - uint8 TabId = fields[2].GetUInt8(); - NewEvent.PlayerGuid = fields[3].GetUInt32(); - NewEvent.ItemOrMoney = fields[4].GetUInt32(); - NewEvent.ItemStackCount = fields[5].GetUInt8(); - NewEvent.DestTabId = fields[6].GetUInt8(); - NewEvent.TimeStamp = fields[7].GetUInt64(); - - if (TabId >= GUILD_BANK_MAX_TABS) + if (!isNextMoneyLogGuidSet) { - sLog.outError( "Guild::LoadGuildBankEventLogFromDB: Invalid tabid '%u' for guild bank log entry (guild: '%s', LogGuid: %u), skipped.", TabId, GetName().c_str(), NewEvent.LogGuid); - continue; + m_GuildBankEventLogNextGuid_Money = fields[0].GetUInt32(); + //we don't have to do m_GuildBankEventLogNextGuid_Money %= configCount; - it will be done when creating new record + isNextMoneyLogGuidSet = true; } + GuildBankEventLogEntry NewEvent; - if (NewEvent.isMoneyEvent() && m_GuildBankEventLog_Money.size() >= GUILD_BANK_MAX_LOGS || - m_GuildBankEventLog_Item[TabId].size() >= GUILD_BANK_MAX_LOGS) - continue; - - if (NewEvent.isMoneyEvent()) - m_GuildBankEventLog_Money.push_front(NewEvent); + NewEvent.EventType = fields[1].GetUInt8(); + NewEvent.PlayerGuid = fields[2].GetUInt32(); + NewEvent.ItemOrMoney = fields[3].GetUInt32(); + NewEvent.ItemStackCount = fields[4].GetUInt8(); + NewEvent.DestTabId = fields[5].GetUInt8(); + NewEvent.TimeStamp = fields[6].GetUInt64(); + + //if newEvent is not moneyEvent, then report error + if (!NewEvent.isMoneyEvent()) + sLog.outError("GuildBankEventLog ERROR: MoneyEvent LogGuid %u for Guild %u is not MoneyEvent - ignoring...", fields[0].GetUInt32(), m_Id); else - m_GuildBankEventLog_Item[TabId].push_front(NewEvent); + //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() ); + } while( result->NextRow() ); delete result; - - // Check lists size in case to many event entries in db for a tab or for money - // This cases can happen only if a crash occured somewhere and table has too many log entries - if (!m_GuildBankEventLog_Money.empty()) - { - CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid=%u AND LogGuid < %u", - Id, m_GuildBankEventLog_Money.front().LogGuid); - } - for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; ++i) - { - if (!m_GuildBankEventLog_Item[i].empty()) - { - CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid=%u AND LogGuid < %u", - Id, m_GuildBankEventLog_Item[i].front().LogGuid); - } - } } void Guild::UnloadGuildBankEventLog() @@ -1560,13 +1591,13 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId) 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->LogEntry); + data << uint8(itr->EventType); data << uint64(MAKE_NEW_GUID(itr->PlayerGuid,0,HIGHGUID_PLAYER)); - if (itr->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY || - itr->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY || - itr->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY || - itr->LogEntry == GUILD_BANK_LOG_UNK1 || - itr->LogEntry == GUILD_BANK_LOG_UNK2) + 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); } @@ -1574,7 +1605,7 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId) { data << uint32(itr->ItemOrMoney); data << uint32(itr->ItemStackCount); - if (itr->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || itr->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2) + 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); @@ -1590,13 +1621,13 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId) 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->LogEntry); + data << uint8(itr->EventType); data << uint64(MAKE_NEW_GUID(itr->PlayerGuid,0,HIGHGUID_PLAYER)); - if (itr->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY || - itr->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY || - itr->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY || - itr->LogEntry == GUILD_BANK_LOG_UNK1 || - itr->LogEntry == GUILD_BANK_LOG_UNK2) + 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); } @@ -1604,7 +1635,7 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId) { data << uint32(itr->ItemOrMoney); data << uint32(itr->ItemStackCount); - if (itr->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || itr->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2) + 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); @@ -1614,53 +1645,45 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId) sLog.outDebug("WORLD: Sent (MSG_GUILD_BANK_LOG_QUERY)"); } -void Guild::LogBankEvent(uint8 LogEntry, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount, uint8 DestTabId) +void Guild::LogBankEvent(uint8 EventType, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount, uint8 DestTabId) { - GuildBankEvent NewEvent; - - NewEvent.LogGuid = LogMaxGuid++; - NewEvent.LogEntry = LogEntry; + //create Event + GuildBankEventLogEntry NewEvent; + NewEvent.EventType = EventType; NewEvent.PlayerGuid = PlayerGuidLow; NewEvent.ItemOrMoney = ItemOrMoney; NewEvent.ItemStackCount = ItemStackCount; NewEvent.DestTabId = DestTabId; NewEvent.TimeStamp = uint32(time(NULL)); + //add new event to the end of event list + uint32 currentTabId = TabId; + uint32 currentLogGuid = 0; if (NewEvent.isMoneyEvent()) { - if (m_GuildBankEventLog_Money.size() > GUILD_BANK_MAX_LOGS) - { - CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u'", - Id, m_GuildBankEventLog_Money.front().LogGuid); + m_GuildBankEventLogNextGuid_Money = (m_GuildBankEventLogNextGuid_Money + 1) % sWorld.getConfig(CONFIG_GUILD_BANK_EVENT_LOG_COUNT); + currentLogGuid = m_GuildBankEventLogNextGuid_Money; + currentTabId = GUILD_BANK_MONEY_LOGS_TAB; + if (m_GuildBankEventLog_Money.size() >= GUILD_BANK_MAX_LOGS) m_GuildBankEventLog_Money.pop_front(); - } + m_GuildBankEventLog_Money.push_back(NewEvent); } else { - if (m_GuildBankEventLog_Item[TabId].size() > GUILD_BANK_MAX_LOGS) - { - CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u'", - Id, m_GuildBankEventLog_Item[TabId].front().LogGuid); + m_GuildBankEventLogNextGuid_Item[TabId] = ((m_GuildBankEventLogNextGuid_Item[TabId]) + 1) % sWorld.getConfig(CONFIG_GUILD_BANK_EVENT_LOG_COUNT); + currentLogGuid = m_GuildBankEventLogNextGuid_Item[TabId]; + if (m_GuildBankEventLog_Item[TabId].size() >= GUILD_BANK_MAX_LOGS) m_GuildBankEventLog_Item[TabId].pop_front(); - } + m_GuildBankEventLog_Item[TabId].push_back(NewEvent); } - CharacterDatabase.PExecute("INSERT INTO guild_bank_eventlog (guildid,LogGuid,LogEntry,TabId,PlayerGuid,ItemOrMoney,ItemStackCount,DestTabId,TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','%u','%u','" UI64FMTD "')", - Id, NewEvent.LogGuid, uint32(NewEvent.LogEntry), uint32(TabId), NewEvent.PlayerGuid, NewEvent.ItemOrMoney, uint32(NewEvent.ItemStackCount), uint32(NewEvent.DestTabId), NewEvent.TimeStamp); -} -// This will renum guids used at load to prevent always going up until infinit -void Guild::RenumBankLogs() -{ - QueryResult *result = CharacterDatabase.PQuery("SELECT Min(LogGuid), Max(LogGuid) FROM guild_bank_eventlog WHERE guildid = %u", Id); - if(!result) - return; + //save event to database + CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u' AND TabId='%u'", m_Id, currentLogGuid, currentTabId); - Field *fields = result->Fetch(); - CharacterDatabase.PExecute("UPDATE guild_bank_eventlog SET LogGuid=LogGuid-%u+1 WHERE guildid=%u ORDER BY LogGuid %s",fields[0].GetUInt32(), Id, fields[0].GetUInt32()?"ASC":"DESC"); - LogMaxGuid = fields[1].GetUInt32()+1; - delete result; + CharacterDatabase.PExecute("INSERT INTO guild_bank_eventlog (guildid,LogGuid,TabId,EventType,PlayerGuid,ItemOrMoney,ItemStackCount,DestTabId,TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','%u','%u','" UI64FMTD "')", + m_Id, currentLogGuid, currentTabId, uint32(NewEvent.EventType), NewEvent.PlayerGuid, NewEvent.ItemOrMoney, uint32(NewEvent.ItemStackCount), uint32(NewEvent.DestTabId), NewEvent.TimeStamp); } bool Guild::AddGBankItemToDB(uint32 GuildId, uint32 BankTab , uint32 BankTabSlot , uint32 GUIDLow, uint32 Entry ) @@ -1940,7 +1963,7 @@ void Guild::SetGuildBankTabText(uint8 TabId, std::string text) m_TabListMap[TabId]->Text = text; CharacterDatabase.escape_string(text); - CharacterDatabase.PExecute("UPDATE guild_bank_tab SET TabText='%s' WHERE guildid='%u' AND TabId='%u'", text.c_str(), Id, uint32(TabId)); + CharacterDatabase.PExecute("UPDATE guild_bank_tab SET TabText='%s' WHERE guildid='%u' AND TabId='%u'", text.c_str(), m_Id, uint32(TabId)); // announce SendGuildBankTabText(NULL,TabId); |
