diff options
author | Spp <spp@jorge.gr> | 2012-11-04 20:17:37 +0100 |
---|---|---|
committer | Spp <spp@jorge.gr> | 2012-11-04 20:17:37 +0100 |
commit | 06eff945065b65cf707837eca6c940ecbf8c7122 (patch) | |
tree | 1f47345347b13ad58cf8bcf5792711df88883758 | |
parent | c6ce7bc9fd7a44acc18b50ec9aa933b96ff8799d (diff) | |
parent | a5a9503bbe80068863bc129afcb41e5ea02cd8b3 (diff) |
Merge branch 'master' into 4.3.4
Note: Will need extra Guild-Related commit to make it work again (Added some extra data beside the merge)
Conflicts:
src/server/game/Battlefield/BattlefieldHandler.cpp
src/server/game/Entities/Player/Player.h
src/server/game/Guilds/Guild.cpp
src/server/game/Guilds/Guild.h
src/server/game/Guilds/GuildMgr.cpp
src/server/game/Guilds/GuildMgr.h
src/server/game/Handlers/AuctionHouseHandler.cpp
src/server/game/Handlers/BattleGroundHandler.cpp
src/server/game/Handlers/CharacterHandler.cpp
src/server/game/Handlers/ChatHandler.cpp
src/server/game/Handlers/GroupHandler.cpp
src/server/game/Handlers/GuildHandler.cpp
src/server/game/Handlers/ItemHandler.cpp
src/server/game/Handlers/LootHandler.cpp
src/server/game/Handlers/MailHandler.cpp
src/server/game/Handlers/MovementHandler.cpp
src/server/game/Handlers/NPCHandler.cpp
src/server/game/Handlers/PetHandler.cpp
src/server/game/Handlers/PetitionsHandler.cpp
src/server/game/Handlers/QueryHandler.cpp
src/server/game/Handlers/QuestHandler.cpp
src/server/game/Handlers/SkillHandler.cpp
src/server/game/Handlers/SpellHandler.cpp
src/server/game/Handlers/TaxiHandler.cpp
src/server/game/Handlers/VehicleHandler.cpp
src/server/game/Server/WorldSession.h
src/server/shared/Database/Implementation/CharacterDatabase.cpp
src/server/shared/Database/Implementation/CharacterDatabase.h
27 files changed, 1203 insertions, 1046 deletions
diff --git a/sql/updates/characters/2012_11_02_00_character_misc.sql b/sql/updates/characters/2012_11_02_00_character_misc.sql new file mode 100644 index 00000000000..a7613944dc4 --- /dev/null +++ b/sql/updates/characters/2012_11_02_00_character_misc.sql @@ -0,0 +1,30 @@ +CREATE TABLE IF NOT EXISTS `guild_member_withdraw` ( + `guid` int(10) unsigned NOT NULL, + `tab0` int(10) unsigned NOT NULL DEFAULT '0', + `tab1` int(10) unsigned NOT NULL DEFAULT '0', + `tab2` int(10) unsigned NOT NULL DEFAULT '0', + `tab3` int(10) unsigned NOT NULL DEFAULT '0', + `tab4` int(10) unsigned NOT NULL DEFAULT '0', + `tab5` int(10) unsigned NOT NULL DEFAULT '0', + `money` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`guid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Guild Member Daily Withdraws'; + +ALTER TABLE `guild_member` DROP COLUMN `BankRemMoney`; +ALTER TABLE `guild_member` DROP COLUMN `BankRemSlotsTab0`; +ALTER TABLE `guild_member` DROP COLUMN `BankRemSlotsTab1`; +ALTER TABLE `guild_member` DROP COLUMN `BankRemSlotsTab2`; +ALTER TABLE `guild_member` DROP COLUMN `BankRemSlotsTab3`; +ALTER TABLE `guild_member` DROP COLUMN `BankRemSlotsTab4`; +ALTER TABLE `guild_member` DROP COLUMN `BankRemSlotsTab5`; +ALTER TABLE `guild_member` DROP COLUMN `BankResetTimeMoney`; +ALTER TABLE `guild_member` DROP COLUMN `BankResetTimeTab0`; +ALTER TABLE `guild_member` DROP COLUMN `BankResetTimeTab1`; +ALTER TABLE `guild_member` DROP COLUMN `BankResetTimeTab2`; +ALTER TABLE `guild_member` DROP COLUMN `BankResetTimeTab3`; +ALTER TABLE `guild_member` DROP COLUMN `BankResetTimeTab4`; +ALTER TABLE `guild_member` DROP COLUMN `BankResetTimeTab5`; + +DELETE FROM `worldstates` WHERE `entry`=20006; +INSERT INTO `worldstates` (`entry`,`value`,`comment`) VALUES (20006,0, 'Guild daily reset'); + diff --git a/sql/updates/world/2012_11_03_00_world_creature_loot_template.sql b/sql/updates/world/2012_11_03_00_world_creature_loot_template.sql new file mode 100644 index 00000000000..0e5c39b796d --- /dev/null +++ b/sql/updates/world/2012_11_03_00_world_creature_loot_template.sql @@ -0,0 +1,6 @@ +-- Readd loot to Stinky +DELETE FROM `creature_loot_template` WHERE `entry` IN(37025,38064); +INSERT INTO `creature_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) +VALUES +(37025,1,100,1,0,-35069,2), +(38064,1,100,1,0,-35069,2); diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 638d9208597..b120cd5e978 100755 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -425,7 +425,7 @@ bool ChatHandler::SetDataForCommandInTable(ChatCommand* table, char const* text, return false; } -int ChatHandler::ParseCommands(char const* text) +bool ChatHandler::ParseCommands(char const* text) { ASSERT(text); ASSERT(*text); @@ -433,23 +433,23 @@ int ChatHandler::ParseCommands(char const* text) std::string fullcmd = text; if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity()) && !sWorld->getBoolConfig(CONFIG_ALLOW_PLAYER_COMMANDS)) - return 0; + return false; /// chat case (.command or !command format) if (m_session) { if (text[0] != '!' && text[0] != '.') - return 0; + return false; } /// ignore single . and ! in line if (strlen(text) < 2) - return 0; + return false; // original `text` can't be used. It content destroyed in command code processing. /// ignore messages staring from many dots. if ((text[0] == '.' && text[1] == '.') || (text[0] == '!' && text[1] == '!')) - return 0; + return false; /// skip first . or ! (in console allowed use command with . and ! and without its) if (text[0] == '!' || text[0] == '.') @@ -458,11 +458,11 @@ int ChatHandler::ParseCommands(char const* text) if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd)) { if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity())) - return 0; + return false; SendSysMessage(LANG_NO_CMD); } - return 1; + return true; } bool ChatHandler::isValidChatMessage(char const* message) diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 473d000d808..b583d749301 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -74,7 +74,7 @@ class ChatHandler void PSendSysMessage(int32 entry, ...); std::string PGetParseString(int32 entry, ...) const; - int ParseCommands(const char* text); + bool ParseCommands(const char* text); static ChatCommand* getCommandTable(); diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp index 8b69b537102..cf600b0645f 100644 --- a/src/server/game/DungeonFinding/LFGQueue.cpp +++ b/src/server/game/DungeonFinding/LFGQueue.cpp @@ -472,8 +472,6 @@ LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check) if (numPlayers != MAXGROUPSIZE) { sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Compatibles but not enough players(%u)", strGuids.c_str(), numPlayers); - LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(check.front()); - LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS); data.roles = proposalRoles; @@ -677,4 +675,4 @@ void LFGQueue::UpdateBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQu else --queueData.dps; } -}
\ No newline at end of file +} diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 459cd030b40..1de1a453d86 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3119,6 +3119,9 @@ void Player::GiveLevel(uint8 level) if (level == oldLevel) return; + if (Guild* guild = GetGuild()) + guild->UpdateMemberData(this, GUILD_MEMBER_DATA_LEVEL, level); + PlayerLevelInfo info; sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), level, &info); @@ -7662,6 +7665,8 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId); sBattlefieldMgr->HandlePlayerEnterZone(this, newZone); SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange... + if (Guild* guild = GetGuild()) + guild->UpdateMemberData(this, GUILD_MEMBER_DATA_ZONEID, newZone); } // group update @@ -23785,11 +23790,15 @@ WorldObject* Player::GetViewpoint() const bool Player::CanUseBattlegroundObject(GameObject* gameobject) { - FactionTemplateEntry const* playerFaction = getFactionTemplateEntry(); - FactionTemplateEntry const* faction = sFactionTemplateStore.LookupEntry(gameobject->GetUInt32Value(GAMEOBJECT_FACTION)); + // It is possible to call this method with a null pointer, only skipping faction check. + if (gameobject) + { + FactionTemplateEntry const* playerFaction = getFactionTemplateEntry(); + FactionTemplateEntry const* faction = sFactionTemplateStore.LookupEntry(gameobject->GetUInt32Value(GAMEOBJECT_FACTION)); - if (playerFaction && faction && !playerFaction->IsFriendlyTo(*faction)) - return false; + if (playerFaction && faction && !playerFaction->IsFriendlyTo(*faction)) + return false; + } // BUG: sometimes when player clicks on flag in AB - client won't send gameobject_use, only gameobject_report_use packet // Note: Mount, stealth and invisibility will be removed when used @@ -23801,9 +23810,8 @@ bool Player::CanUseBattlegroundObject(GameObject* gameobject) bool Player::CanCaptureTowerPoint() { return (!HasStealthAura() && // not stealthed - !HasInvisibilityAura() && // not invisible - isAlive() // live player -); + !HasInvisibilityAura() && // not invisible + isAlive()); // live player } uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin) @@ -26271,3 +26279,9 @@ void Player::SendMovementSetCollisionHeight(float height) SendDirectMessage(&data); } + +Guild* Player::GetGuild() +{ + uint32 guildId = GetGuildId(); + return guildId ? sGuildMgr->GetGuildById(guildId) : NULL; +} diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 406552f78f5..2bc8aeb9c10 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -51,6 +51,7 @@ class Channel; class Creature; class DynamicObject; class Group; +class Guild; class OutdoorPvP; class Pet; class PlayerMenu; @@ -2051,11 +2052,12 @@ class Player : public Unit, public GridObject<Player> void SetInGuild(uint32 guildId); void SetRank(uint8 rankId) { SetUInt32Value(PLAYER_GUILDRANK, rankId); } - uint32 GetRank() { return GetUInt32Value(PLAYER_GUILDRANK); } + uint8 GetRank() const { return uint8(GetUInt32Value(PLAYER_GUILDRANK)); } void SetGuildLevel(uint32 level) { SetUInt32Value(PLAYER_GUILDLEVEL, level); } uint32 GetGuildLevel() { return GetUInt32Value(PLAYER_GUILDLEVEL); } void SetGuildIdInvited(uint32 GuildId) { m_GuildIdInvited = GuildId; } uint32 GetGuildId() const { return GetUInt32Value(OBJECT_FIELD_DATA); /* return only lower part */ } + Guild* GetGuild(); static uint32 GetGuildIdFromDB(uint64 guid); static uint8 GetRankFromDB(uint64 guid); int GetGuildIdInvited() { return m_GuildIdInvited; } diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index ec9e6d7d1e2..0a8267652c6 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -26,6 +26,7 @@ #include "SocialMgr.h" #include "Log.h" #include "AccountMgr.h" +#include "AchievementMgr.h" #define MAX_GUILD_BANK_TAB_TEXT_LEN 500 #define EMBLEM_PRICE 10 * GOLD @@ -44,7 +45,7 @@ inline uint32 _GetGuildBankTabPrice(uint8 tabId) } } -void Guild::SendCommandResult(WorldSession* session, GuildCommandType type, GuildCommandError errCode, const std::string& param) +void Guild::SendCommandResult(WorldSession* session, GuildCommandType type, GuildCommandError errCode, std::string const& param) { WorldPacket data(SMSG_GUILD_COMMAND_RESULT, 8 + param.size() + 1); data << uint32(type); @@ -52,7 +53,8 @@ void Guild::SendCommandResult(WorldSession* session, GuildCommandType type, Guil data << uint32(errCode); session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_COMMAND_RESULT)"); + sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_COMMAND_RESULT [%s]: Type: %u, code: %u, param: %s" + , session->GetPlayerInfo().c_str(), type, errCode, param.c_str()); } void Guild::SendSaveEmblemResult(WorldSession* session, GuildEmblemError errCode) @@ -61,7 +63,7 @@ void Guild::SendSaveEmblemResult(WorldSession* session, GuildEmblemError errCode data << uint32(errCode); session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (MSG_SAVE_GUILD_EMBLEM)"); + sLog->outDebug(LOG_FILTER_GUILD, "MSG_SAVE_GUILD_EMBLEM [%s] Code: %u", session->GetPlayerInfo().c_str(), errCode); } // LogHolder @@ -286,7 +288,33 @@ void Guild::RankInfo::SaveToDB(SQLTransaction& trans) const CharacterDatabase.ExecuteOrAppend(trans, stmt); } -void Guild::RankInfo::SetName(const std::string& name) +bool Guild::RankInfo::CreateMissingTabsIfNeeded(uint8 ranks, SQLTransaction& trans) +{ + bool ret = false; + for (uint8 i = 0; i < ranks; ++i) + { + GuildBankRightsAndSlots& rightsAndSlots = m_bankTabRightsAndSlots[i]; + if (rightsAndSlots.GetTabId() == i) + continue; + + rightsAndSlots.SetTabId(i); + if (m_rankId == GR_GUILDMASTER) + rightsAndSlots.SetGuildMasterValues(); + + ret = true; + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_RIGHT); + stmt->setUInt32(0, m_guildId); + stmt->setUInt8 (1, i); + stmt->setUInt8 (2, m_rankId); + stmt->setUInt32(3, rightsAndSlots.GetRights()); + stmt->setUInt32(4, rightsAndSlots.GetSlots()); + trans->Append(stmt); + } + + return ret; +} + +void Guild::RankInfo::SetName(std::string const& name) { if (m_name == name) return; @@ -327,60 +355,39 @@ void Guild::RankInfo::SetBankMoneyPerDay(uint32 money) m_bankMoneyPerDay = money; - PreparedStatement* stmt = NULL; - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_BANK_MONEY); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_BANK_MONEY); stmt->setUInt32(0, money); stmt->setUInt8 (1, m_rankId); stmt->setUInt32(2, m_guildId); CharacterDatabase.Execute(stmt); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_BANK_RESET_TIME); - stmt->setUInt32(0, m_guildId); - stmt->setUInt8 (1, m_rankId); - CharacterDatabase.Execute(stmt); } -void Guild::RankInfo::SetBankTabSlotsAndRights(uint8 tabId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB) +void Guild::RankInfo::SetBankTabSlotsAndRights(GuildBankRightsAndSlots rightsAndSlots, bool saveToDB) { if (m_rankId == GR_GUILDMASTER) // Prevent loss of leader rights rightsAndSlots.SetGuildMasterValues(); - GuildBankRightsAndSlots& guildBR = m_bankTabRightsAndSlots[tabId]; - if (guildBR.IsEqual(rightsAndSlots)) - return; - + GuildBankRightsAndSlots& guildBR = m_bankTabRightsAndSlots[rightsAndSlots.GetTabId()]; guildBR = rightsAndSlots; if (saveToDB) { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_RIGHT); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_RIGHT); stmt->setUInt32(0, m_guildId); - stmt->setUInt8 (1, tabId); + stmt->setUInt8 (1, guildBR.GetTabId()); stmt->setUInt8 (2, m_rankId); - CharacterDatabase.Execute(stmt); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_RIGHT); - stmt->setUInt32(0, m_guildId); - stmt->setUInt8 (1, tabId); - stmt->setUInt8 (2, m_rankId); - stmt->setUInt8 (3, guildBR.rights); - stmt->setUInt32(4, guildBR.slots); - CharacterDatabase.Execute(stmt); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_BANK_TIME0 + tabId); - stmt->setUInt32(0, m_guildId); - stmt->setUInt8 (1, m_rankId); + stmt->setUInt8 (3, guildBR.GetRights()); + stmt->setUInt32(4, guildBR.GetSlots()); CharacterDatabase.Execute(stmt); } } // BankTab -bool Guild::BankTab::LoadFromDB(Field* fields) +void Guild::BankTab::LoadFromDB(Field* fields) { m_name = fields[2].GetString(); m_icon = fields[3].GetString(); m_text = fields[4].GetString(); - return true; } bool Guild::BankTab::LoadItemFromDB(Field* fields) @@ -435,7 +442,7 @@ void Guild::BankTab::Delete(SQLTransaction& trans, bool removeItemsFromDB) } } -void Guild::BankTab::SetInfo(const std::string& name, const std::string& icon) +void Guild::BankTab::SetInfo(std::string const& name, std::string const& icon) { if (m_name == name && m_icon == icon) return; @@ -451,7 +458,7 @@ void Guild::BankTab::SetInfo(const std::string& name, const std::string& icon) CharacterDatabase.Execute(stmt); } -void Guild::BankTab::SetText(const std::string& text) +void Guild::BankTab::SetText(std::string const& text) { if (m_text == text) return; @@ -506,9 +513,16 @@ void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const data.WriteString(m_text); if (session) + { + sLog->outDebug(LOG_FILTER_GUILD, "MSG_QUERY_GUILD_BANK_TEXT [%s]: Tabid: %u, Text: %s" + , session->GetPlayerInfo().c_str(), m_tabId, m_text.c_str()); session->SendPacket(&data); + } else + { + sLog->outDebug(LOG_FILTER_GUILD, "MSG_QUERY_GUILD_BANK_TEXT [Broadcast]: Tabid: %u, Text: %s", m_tabId, m_text.c_str()); guild->BroadcastPacket(&data); + } } // Member @@ -521,7 +535,7 @@ void Guild::Member::SetStats(Player* player) m_accountId = player->GetSession()->GetAccountId(); } -void Guild::Member::SetStats(const std::string& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId) +void Guild::Member::SetStats(std::string const& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId) { m_name = name; m_level = level; @@ -530,7 +544,7 @@ void Guild::Member::SetStats(const std::string& name, uint8 level, uint8 _class, m_accountId = accountId; } -void Guild::Member::SetPublicNote(const std::string& publicNote) +void Guild::Member::SetPublicNote(std::string const& publicNote) { if (m_publicNote == publicNote) return; @@ -543,7 +557,7 @@ void Guild::Member::SetPublicNote(const std::string& publicNote) CharacterDatabase.Execute(stmt); } -void Guild::Member::SetOfficerNote(const std::string& officerNote) +void Guild::Member::SetOfficerNote(std::string const& officerNote) { if (m_officerNote == officerNote) return; @@ -586,22 +600,18 @@ void Guild::Member::SaveToDB(SQLTransaction& trans) const // In this case member has to be removed from guild. bool Guild::Member::LoadFromDB(Field* fields) { - m_publicNote = fields[3].GetString(); - m_officerNote = fields[4].GetString(); - m_bankRemaining[GUILD_BANK_MAX_TABS].resetTime = fields[5].GetUInt32(); - m_bankRemaining[GUILD_BANK_MAX_TABS].value = fields[6].GetUInt32(); - for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; ++i) - { - m_bankRemaining[i].resetTime = fields[7 + i * 2].GetUInt32(); - m_bankRemaining[i].value = fields[8 + i * 2].GetUInt32(); - } + m_publicNote = fields[3].GetString(); + m_officerNote = fields[4].GetString(); - SetStats(fields[23].GetString(), - fields[24].GetUInt8(), // characters.level - fields[25].GetUInt8(), // characters.class - fields[26].GetUInt16(), // characters.zone - fields[27].GetUInt32()); // characters.account - m_logoutTime = fields[28].GetUInt32(); // characters.logout_time + for (uint8 i = 0; i <= GUILD_BANK_MAX_TABS; ++i) + m_bankWithdraw[i] = fields[5 + i].GetUInt32(); + + SetStats(fields[14].GetString(), + fields[15].GetUInt8(), // characters.level + fields[16].GetUInt8(), // characters.class + fields[17].GetUInt16(), // characters.zone + fields[18].GetUInt32()); // characters.account + m_logoutTime = fields[19].GetUInt32(); // characters.logout_time if (!CheckStats()) return false; @@ -611,6 +621,7 @@ bool Guild::Member::LoadFromDB(Field* fields) sLog->outError(LOG_FILTER_GUILD, "Player (GUID: %u) has broken zone-data", GUID_LOPART(m_guid)); m_zoneId = Player::GetZoneIdFromDB(m_guid); } + ResetFlags(); return true; } @@ -634,66 +645,37 @@ bool Guild::Member::CheckStats() const // Decreases amount of money/slots left for today. // If (tabId == GUILD_BANK_MAX_TABS) decrease money amount. // Otherwise decrease remaining items amount for specified tab. -void Guild::Member::DecreaseBankRemainingValue(SQLTransaction& trans, uint8 tabId, uint32 amount) +void Guild::Member::UpdateBankWithdrawValue(SQLTransaction& trans, uint8 tabId, uint32 amount) { - m_bankRemaining[tabId].value -= amount; + m_bankWithdraw[tabId] += amount; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_MEMBER_WITHDRAW); + stmt->setUInt32(0, GUID_LOPART(m_guid)); + for (uint8 i = 0; i <= GUILD_BANK_MAX_TABS;) + { + uint32 withdraw = m_bankWithdraw[i++]; + stmt->setUInt32(i, withdraw); + } - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement( - tabId == GUILD_BANK_MAX_TABS ? - CHAR_UPD_GUILD_MEMBER_BANK_REM_MONEY : - CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS0 + tabId); - stmt->setUInt32(0, m_bankRemaining[tabId].value); - stmt->setUInt32(1, m_guildId); - stmt->setUInt32(2, GUID_LOPART(m_guid)); CharacterDatabase.ExecuteOrAppend(trans, stmt); } +void Guild::Member::ResetValues(bool /*week*/) +{ + for (uint8 tabId = 0; tabId <= GUILD_BANK_MAX_TABS; ++tabId) + m_bankWithdraw[tabId] = 0; +} + // Get amount of money/slots left for today. // If (tabId == GUILD_BANK_MAX_TABS) return money amount. // Otherwise return remaining items amount for specified tab. -// If reset time was more than 24 hours ago, renew reset time and reset amount to maximum value. -uint32 Guild::Member::GetBankRemainingValue(uint8 tabId, const Guild* guild) const +int32 Guild::Member::GetBankWithdrawValue(uint8 tabId) const { // Guild master has unlimited amount. if (IsRank(GR_GUILDMASTER)) return tabId == GUILD_BANK_MAX_TABS ? GUILD_WITHDRAW_MONEY_UNLIMITED : GUILD_WITHDRAW_SLOT_UNLIMITED; - // Check rights for non-money tab. - if (tabId != GUILD_BANK_MAX_TABS) - if ((guild->_GetRankBankTabRights(m_rankId, tabId) & GUILD_BANK_RIGHT_VIEW_TAB) != GUILD_BANK_RIGHT_VIEW_TAB) - return 0; - - uint32 curTime = uint32(::time(NULL) / MINUTE); // minutes - if (curTime > m_bankRemaining[tabId].resetTime + 24 * HOUR / MINUTE) - { - RemainingValue& rv = const_cast <RemainingValue&> (m_bankRemaining[tabId]); - rv.resetTime = curTime; - rv.value = tabId == GUILD_BANK_MAX_TABS ? - guild->_GetRankBankMoneyPerDay(m_rankId) : - guild->_GetRankBankTabSlotsPerDay(m_rankId, tabId); - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement( - tabId == GUILD_BANK_MAX_TABS ? - CHAR_UPD_GUILD_MEMBER_BANK_TIME_MONEY : - CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS0 + tabId); - stmt->setUInt32(0, m_bankRemaining[tabId].resetTime); - stmt->setUInt32(1, m_bankRemaining[tabId].value); - stmt->setUInt32(2, m_guildId); - stmt->setUInt32(3, GUID_LOPART(m_guid)); - CharacterDatabase.Execute(stmt); - } - return m_bankRemaining[tabId].value; -} - -inline void Guild::Member::ResetTabTimes() -{ - for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId) - m_bankRemaining[tabId].resetTime = 0; -} - -inline void Guild::Member::ResetMoneyTime() -{ - m_bankRemaining[GUILD_BANK_MAX_TABS].resetTime = 0; + return m_bankWithdraw[tabId]; } // EmblemInfo @@ -860,7 +842,12 @@ bool Guild::BankMoveItemData::HasWithdrawRights(MoveItemData* pOther) const // Do not check rights if item is being swapped within the same bank tab if (pOther->IsBank() && pOther->GetContainer() == m_container) return true; - return (m_pGuild->_GetMemberRemainingSlots(m_pPlayer->GetGUID(), m_container) != 0); + + int32 slots = 0; + if (Member const* member = m_pGuild->GetMember(m_pPlayer->GetGUID())) + slots = m_pGuild->_GetMemberRemainingSlots(member, m_container); + + return slots != 0; } void Guild::BankMoveItemData::RemoveItem(SQLTransaction& trans, MoveItemData* pOther, uint32 splitedAmount) @@ -879,7 +866,7 @@ void Guild::BankMoveItemData::RemoveItem(SQLTransaction& trans, MoveItemData* pO } // Decrease amount of player's remaining items (if item is moved to different tab or to player) if (!pOther->IsBank() || pOther->GetContainer() != m_container) - m_pGuild->_DecreaseMemberRemainingSlots(trans, m_pPlayer->GetGUID(), m_container); + m_pGuild->_UpdateMemberWithdrawSlots(trans, m_pPlayer->GetGUID(), m_container); } Item* Guild::BankMoveItemData::StoreItem(SQLTransaction& trans, Item* pItem) @@ -1051,8 +1038,18 @@ InventoryResult Guild::BankMoveItemData::CanStore(Item* pItem, bool swap) } // Guild -Guild::Guild() : m_id(0), m_leaderGuid(0), m_createdDate(0), m_accountsNumber(0), m_bankMoney(0), m_eventLog(NULL), - m_achievementMgr(this), _newsLog(this), _level(1), _experience(0), _todayExperience(0) +Guild::Guild(): + m_id(0), + m_leaderGuid(0), + m_createdDate(0), + m_accountsNumber(0), + m_bankMoney(0), + m_eventLog(NULL), + m_achievementMgr(this), + _newsLog(this), + _level(1), + _experience(0), + _todayExperience(0) { memset(&m_bankEventLog, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(LogHolder*)); } @@ -1063,17 +1060,24 @@ Guild::~Guild() _DeleteBankItems(temp); // Cleanup - if (m_eventLog) - delete m_eventLog; + delete m_eventLog; + m_eventLog = NULL; + for (uint8 tabId = 0; tabId <= GUILD_BANK_MAX_TABS; ++tabId) - if (m_bankEventLog[tabId]) - delete m_bankEventLog[tabId]; + { + delete m_bankEventLog[tabId]; + m_bankEventLog[tabId] = NULL; + } + for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + { delete itr->second; + itr->second = NULL; + } } // Creates new guild with default data and saves it to database. -bool Guild::Create(Player* pLeader, const std::string& name) +bool Guild::Create(Player* pLeader, std::string const& name) { // Check if guild with such name already exists if (sGuildMgr->GetGuildByName(name)) @@ -1096,10 +1100,9 @@ bool Guild::Create(Player* pLeader, const std::string& name) sLog->outDebug(LOG_FILTER_GUILD, "GUILD: creating guild [%s] for leader %s (%u)", name.c_str(), pLeader->GetName().c_str(), GUID_LOPART(m_leaderGuid)); - PreparedStatement* stmt = NULL; SQLTransaction trans = CharacterDatabase.BeginTransaction(); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBERS); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBERS); stmt->setUInt32(0, m_id); trans->Append(stmt); @@ -1120,15 +1123,14 @@ bool Guild::Create(Player* pLeader, const std::string& name) trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); - // Create default ranks - _CreateDefaultGuildRanks(pLeaderSession->GetSessionDbLocaleIndex()); - // Add guildmaster - bool ret = AddMember(m_leaderGuid, GR_GUILDMASTER); + _CreateDefaultGuildRanks(pLeaderSession->GetSessionDbLocaleIndex()); // Create default ranks + bool ret = AddMember(m_leaderGuid, GR_GUILDMASTER); // Add guildmaster + if (ret) - // Call scripts on successful create + { + _BroadcastEvent(GE_FOUNDER, m_leaderGuid); sScriptMgr->OnGuildCreate(this, pLeader, name); - - _BroadcastEvent(GE_FOUNDER, m_leaderGuid); + } return ret; } @@ -1147,9 +1149,9 @@ void Guild::Disband() DeleteMember(itr->second->GetGUID(), true); } - PreparedStatement* stmt = NULL; SQLTransaction trans = CharacterDatabase.BeginTransaction(); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD); stmt->setUInt32(0, m_id); trans->Append(stmt); @@ -1203,6 +1205,36 @@ void Guild::SaveToDB() CharacterDatabase.CommitTransaction(trans); } +void Guild::UpdateMemberData(Player* player, uint8 dataid, uint32 value) +{ + if (Member* member = GetMember(player->GetGUID())) + { + switch (dataid) + { + case GUILD_MEMBER_DATA_ZONEID: + member->SetZoneId(value); + break; + case GUILD_MEMBER_DATA_LEVEL: + member->SetLevel(value); + break; + default: + sLog->outError(LOG_FILTER_GUILD, "Guild::UpdateMemberData: Called with incorrect DATAID %u (value %u)", dataid, value); + return; + } + //HandleRoster(); + } +} + +void Guild::OnPlayerStatusChange(Player* player, uint32 flag, bool state) +{ + if (Member* member = GetMember(player->GetGUID())) + { + if (state) + member->AddFlag(flag); + else member->RemFlag(flag); + } +} + void Guild::HandleRoster(WorldSession* session /*= NULL*/) { ByteBuffer memberData(100); @@ -1214,7 +1246,6 @@ void Guild::HandleRoster(WorldSession* session /*= NULL*/) for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) { Member* member = itr->second; - Player* player = member->FindPlayer(); size_t pubNoteLength = member->GetPublicNote().length(); size_t offNoteLength = member->GetOfficerNote().length(); @@ -1233,16 +1264,6 @@ void Guild::HandleRoster(WorldSession* session /*= NULL*/) data.WriteBit(guid[5]); data.WriteBit(guid[7]); - uint8 flags = GUILDMEMBER_STATUS_NONE; - if (player) - { - flags |= GUILDMEMBER_STATUS_ONLINE; - if (player->isAFK()) - flags |= GUILDMEMBER_STATUS_AFK; - if (player->isDND()) - flags |= GUILDMEMBER_STATUS_DND; - } - memberData << uint8(member->GetClass()); memberData << int32(0); // unk memberData.WriteByteSeq(guid[0]); @@ -1255,8 +1276,8 @@ void Guild::HandleRoster(WorldSession* session /*= NULL*/) memberData << uint32(0) << uint32(0) << uint32(0); memberData.WriteByteSeq(guid[2]); - memberData << uint8(flags); - memberData << uint32(player ? player->GetZoneId() : member->GetZone()); + memberData << uint8(member->GetFlags()); + memberData << uint32(member->GetZoneId()); memberData << uint64(0); // Total activity memberData.WriteByteSeq(guid[7]); memberData << uint32(member->GetRemainingWeeklyReputation());// Remaining guild week Rep @@ -1265,13 +1286,13 @@ void Guild::HandleRoster(WorldSession* session /*= NULL*/) memberData.WriteString(member->GetPublicNote()); memberData.WriteByteSeq(guid[3]); - memberData << uint8(player ? player->getLevel() : member->GetLevel()); + memberData << uint8(member->GetLevel()); memberData << int32(0); // unk memberData.WriteByteSeq(guid[5]); memberData.WriteByteSeq(guid[4]); memberData << uint8(0); // unk memberData.WriteByteSeq(guid[1]); - memberData << float(player ? 0.0f : float(::time(NULL) - member->GetLogoutTime()) / DAY); + memberData << float(member->IsOnline() ? 0.0f : float(::time(NULL) - member->GetLogoutTime()) / DAY); if (offNoteLength) memberData.WriteString(member->GetOfficerNote()); @@ -1296,10 +1317,15 @@ void Guild::HandleRoster(WorldSession* session /*= NULL*/) data << uint32(0); if (session) + { + sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_ROSTER [%s]", session->GetPlayerInfo().c_str()); session->SendPacket(&data); + } else + { + sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_ROSTER [Broadcast]"); BroadcastPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_ROSTER)"); + } } void Guild::HandleQuery(WorldSession* session) @@ -1337,15 +1363,13 @@ void Guild::HandleQuery(WorldSession* session) } m_emblemInfo.WritePacket(data); - data << uint32(_GetRanksSize()); // Number of ranks used session->SendPacket(&data); - - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_QUERY_RESPONSE)"); + sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_QUERY_RESPONSE [%s]", session->GetPlayerInfo().c_str()); } -void Guild::HandleGuildRanks(WorldSession* session) const +void Guild::SendGuildRankInfo(WorldSession* session) const { // perhaps move to guild.cpp..... ByteBuffer rankData(100); @@ -1383,14 +1407,14 @@ void Guild::HandleGuildRanks(WorldSession* session) const session->SendPacket(&data); } -void Guild::HandleSetMOTD(WorldSession* session, const std::string& motd) +void Guild::HandleSetMOTD(WorldSession* session, std::string const& motd) { if (m_motd == motd) return; // Player must have rights to set MOTD if (!_HasRankRight(session->GetPlayer(), GR_RIGHT_SETMOTD)) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_COMMAND_EDIT_MOTD, ERR_GUILD_PERMISSIONS); else { m_motd = motd; @@ -1406,15 +1430,13 @@ void Guild::HandleSetMOTD(WorldSession* session, const std::string& motd) } } -void Guild::HandleSetInfo(WorldSession* session, const std::string& info) +void Guild::HandleSetInfo(WorldSession* session, std::string const& info) { if (m_info == info) return; // Player must have rights to set guild's info - if (!_HasRankRight(session->GetPlayer(), GR_RIGHT_MODIFY_GUILD_INFO)) - SendCommandResult(session, GUILD_CREATE_S, ERR_GUILD_PERMISSIONS); - else + if (_HasRankRight(session->GetPlayer(), GR_RIGHT_MODIFY_GUILD_INFO)) { m_info = info; @@ -1431,11 +1453,9 @@ void Guild::HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo) { Player* player = session->GetPlayer(); if (!_IsLeader(player)) - // "Only guild leaders can create emblems." - SendSaveEmblemResult(session, ERR_GUILDEMBLEM_NOTGUILDMASTER); + SendSaveEmblemResult(session, ERR_GUILDEMBLEM_NOTGUILDMASTER); // "Only guild leaders can create emblems." else if (!player->HasEnoughMoney(uint64(EMBLEM_PRICE))) - // "You can't afford to do that." - SendSaveEmblemResult(session, ERR_GUILDEMBLEM_NOTENOUGHMONEY); + SendSaveEmblemResult(session, ERR_GUILDEMBLEM_NOTENOUGHMONEY); // "You can't afford to do that." else { player->ModifyMoney(-int64(EMBLEM_PRICE)); @@ -1443,100 +1463,118 @@ void Guild::HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo) m_emblemInfo = emblemInfo; m_emblemInfo.SaveToDB(m_id); - // "Guild Emblem saved." - SendSaveEmblemResult(session, ERR_GUILDEMBLEM_SUCCESS); + SendSaveEmblemResult(session, ERR_GUILDEMBLEM_SUCCESS); // "Guild Emblem saved." HandleQuery(session); } } -void Guild::HandleSetLeader(WorldSession* session, const std::string& name) +void Guild::HandleSetLeader(WorldSession* session, std::string const& name) { Player* player = session->GetPlayer(); // Only leader can assign new leader if (!_IsLeader(player)) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_COMMAND_CHANGE_LEADER, ERR_GUILD_PERMISSIONS); // Old leader must be a member of guild else if (Member* pOldLeader = GetMember(player->GetGUID())) { // New leader must be a member of guild - if (Member* pNewLeader = GetMember(session, name)) + if (Member* pNewLeader = GetMember(name)) { _SetLeaderGUID(pNewLeader); pOldLeader->ChangeRank(GR_OFFICER); _BroadcastEvent(GE_LEADER_CHANGED, 0, player->GetName().c_str(), name.c_str()); } } - else - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); } -void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, const std::string& name, const std::string& icon) +void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string const& name, std::string const& icon) { - if (BankTab* pTab = GetBankTab(tabId)) + BankTab* tab = GetBankTab(tabId); + if (!tab) { - pTab->SetInfo(name, icon); - SendBankList(session, tabId, true, true); + sLog->outError(LOG_FILTER_GUILD, "Guild::HandleSetBankTabInfo: Player %s trying to change bank tab info from unexisting tab %d.", + session->GetPlayerInfo().c_str(), tabId); + return; } + + char aux[2]; + sprintf(aux, "%u", tabId); + + tab->SetInfo(name, icon); + _BroadcastEvent(GE_BANK_TAB_UPDATED, 0, aux, name.c_str(), icon.c_str()); } void Guild::HandleSetMemberNote(WorldSession* session, std::string const& note, uint64 guid, bool isPublic) { // Player must have rights to set public/officer note if (!_HasRankRight(session->GetPlayer(), isPublic ? GR_RIGHT_EPNOTE : GR_RIGHT_EOFFNOTE)) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_COMMAND_PUBLIC_NOTE, ERR_GUILD_PERMISSIONS); else if (Member* member = GetMember(guid)) { if (isPublic) member->SetPublicNote(note); else member->SetOfficerNote(note); - HandleRoster(session); + + HandleRoster(session); // FIXME - We should send SMSG_GUILD_SET_NOTE } } -void Guild::HandleSetRankInfo(WorldSession* session, uint32 rankId, const std::string& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec rightsAndSlots) +void Guild::HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec rightsAndSlots) { // Only leader can modify ranks if (!_IsLeader(session->GetPlayer())) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_COMMAND_CHANGE_RANK, ERR_GUILD_PERMISSIONS); else if (RankInfo* rankInfo = GetRankInfo(rankId)) { - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Changed RankName to '%s', rights to 0x%08X", name.c_str(), rights); + sLog->outDebug(LOG_FILTER_GUILD, "Changed RankName to '%s', rights to 0x%08X", name.c_str(), rights); rankInfo->SetName(name); rankInfo->SetRights(rights); _SetRankBankMoneyPerDay(rankId, moneyPerDay); - uint8 tabId = 0; for (GuildBankRightsAndSlotsVec::const_iterator itr = rightsAndSlots.begin(); itr != rightsAndSlots.end(); ++itr) - _SetRankBankTabRightsAndSlots(rankId, tabId++, *itr); + _SetRankBankTabRightsAndSlots(rankId, *itr); - HandleQuery(session); - HandleRoster(); // Broadcast for tab rights update + char aux[2]; + sprintf(aux, "%u", rankId); + _BroadcastEvent(GE_RANK_UPDATED, 0, aux, name.c_str()); } } void Guild::HandleBuyBankTab(WorldSession* session, uint8 tabId) { - if (tabId != _GetPurchasedTabsSize()) + Player* player = session->GetPlayer(); + if (!player) return; - uint32 tabCost = _GetGuildBankTabPrice(tabId) * GOLD; - if (!tabCost) + Member const* member = GetMember(player->GetGUID()); + if (!member) return; - Player* player = session->GetPlayer(); - if (!player->HasEnoughMoney(uint64(tabCost))) // Should not happen, this is checked by client + if (_GetPurchasedTabsSize() >= GUILD_BANK_MAX_TABS) return; - if (!_CreateNewBankTab()) - return; + if (tabId != _GetPurchasedTabsSize()) + return; + + uint32 tabCost = _GetGuildBankTabPrice(tabId) * GOLD; + if (!tabCost) + return; - player->ModifyMoney(-int64(tabCost)); - _SetRankBankMoneyPerDay(player->GetRank(), uint32(GUILD_WITHDRAW_MONEY_UNLIMITED)); - _SetRankBankTabRightsAndSlots(player->GetRank(), tabId, GuildBankRightsAndSlots(GUILD_BANK_RIGHT_FULL, uint32(GUILD_WITHDRAW_SLOT_UNLIMITED))); - HandleRoster(); // Broadcast for tab rights update + + if (!player->HasEnoughMoney(uint64(tabCost))) // Should not happen, this is checked by client + return; + + player->ModifyMoney(-int64(tabCost)); + + uint8 rankId = member->GetRankId(); + _CreateNewBankTab(); + _SetRankBankMoneyPerDay(rankId, uint32(GUILD_WITHDRAW_MONEY_UNLIMITED)); + GuildBankRightsAndSlots rightsAndSlots(tabId); + _SetRankBankTabRightsAndSlots(rankId, rightsAndSlots); + //HandleRoster(); // Broadcast for tab rights update SendBankList(session, tabId, false, true); } @@ -1545,7 +1583,7 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name) Player* pInvitee = sObjectAccessor->FindPlayerByName(name); if (!pInvitee) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PLAYER_NOT_FOUND_S, name); + SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_PLAYER_NOT_FOUND_S, name); return; } @@ -1556,28 +1594,32 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name) if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && pInvitee->GetTeam() != player->GetTeam()) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_NOT_ALLIED, name); + SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_NOT_ALLIED, name); return; } + // Invited player cannot be in another guild /*if (pInvitee->GetGuildId()) { - SendCommandResult(session, GUILD_INVITE, ERR_ALREADY_IN_GUILD_S, name); + SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, name); return; }*/ + // Invited player cannot be invited if (pInvitee->GetGuildIdInvited()) { - SendCommandResult(session, GUILD_INVITE_S, ERR_ALREADY_INVITED_TO_GUILD_S, name); + SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, name); return; } // Inviting player must have rights to invite if (!_HasRankRight(player, GR_RIGHT_INVITE)) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_PERMISSIONS); return; } + SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_COMMAND_SUCCESS, name); + sLog->outDebug(LOG_FILTER_GUILD, "Player %s invited %s to join his Guild", player->GetName().c_str(), name.c_str()); pInvitee->SetGuildIdInvited(m_id); @@ -1643,8 +1685,7 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name) data.WriteByteSeq(newGuildGuid[3]); data.WriteByteSeq(oldGuildGuid[4]); pInvitee->GetSession()->SendPacket(&data); - - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_INVITE)"); + sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_INVITE [%s]", pInvitee->GetName().c_str()); } void Guild::HandleAcceptMember(WorldSession* session) @@ -1654,12 +1695,7 @@ void Guild::HandleAcceptMember(WorldSession* session) player->GetTeam() != sObjectMgr->GetPlayerTeamByGUID(GetLeaderGUID())) return; - if (AddMember(player->GetGUID())) - { - _LogEvent(GUILD_EVENT_LOG_JOIN_GUILD, player->GetGUIDLow()); - _BroadcastEvent(GE_JOINED, player->GetGUID(), player->GetName().c_str()); - sGuildFinderMgr->RemoveMembershipRequest(player->GetGUIDLow(), GUID_LOPART(this->GetGUID())); - } + AddMember(player->GetGUID()); } void Guild::HandleLeaveMember(WorldSession* session) @@ -1670,12 +1706,11 @@ void Guild::HandleLeaveMember(WorldSession* session) { if (m_members.size() > 1) // Leader cannot leave if he is not the last member - SendCommandResult(session, GUILD_QUIT_S, ERR_GUILD_LEADER_LEAVE); + SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_LEADER_LEAVE); else if (GetLevel() >= sWorld->getIntConfig(CONFIG_GUILD_UNDELETABLE_LEVEL)) - SendCommandResult(session, GUILD_QUIT_S, ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL); + SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL); else - // Guild is disbanded if leader leaves. - Disband(); + Disband(); // Guild is disbanded if leader leaves. } else { @@ -1684,82 +1719,84 @@ void Guild::HandleLeaveMember(WorldSession* session) _LogEvent(GUILD_EVENT_LOG_LEAVE_GUILD, player->GetGUIDLow()); _BroadcastEvent(GE_LEFT, player->GetGUID(), player->GetName().c_str()); - SendCommandResult(session, GUILD_QUIT_S, ERR_GUILD_COMMAND_SUCCESS, m_name); + SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_COMMAND_SUCCESS, m_name); } } void Guild::HandleRemoveMember(WorldSession* session, uint64 guid) { Player* player = session->GetPlayer(); - Player* removedPlayer = ObjectAccessor::FindPlayer(guid); - Member* member = GetMember(guid); // Player must have rights to remove members if (!_HasRankRight(player, GR_RIGHT_REMOVE)) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); - // Removed player must be a member of the guild - else if (member && removedPlayer) + SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_PERMISSIONS); + else if (Member* member = GetMember(guid)) { + std::string name = member->GetName(); + // Guild masters cannot be removed if (member->IsRank(GR_GUILDMASTER)) - SendCommandResult(session, GUILD_QUIT_S, ERR_GUILD_LEADER_LEAVE); + SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_LEADER_LEAVE); // Do not allow to remove player with the same rank or higher - else if (member->IsRankNotLower(player->GetRank())) - SendCommandResult(session, GUILD_QUIT_S, ERR_GUILD_RANK_TOO_HIGH_S, removedPlayer->GetName()); else { - // After call to DeleteMember pointer to member becomes invalid - DeleteMember(guid, false, true); - _LogEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, player->GetGUIDLow(), GUID_LOPART(guid)); - _BroadcastEvent(GE_REMOVED, 0, removedPlayer->GetName().c_str(), player->GetName().c_str()); + Member const* memberMe = GetMember(player->GetGUID()); + if (!memberMe || member->IsRankNotLower(memberMe->GetRankId())) + SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_RANK_TOO_HIGH_S, name); + else + { + // After call to DeleteMember pointer to member becomes invalid + DeleteMember(guid, false, true); + _LogEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, player->GetGUIDLow(), GUID_LOPART(guid)); + _BroadcastEvent(GE_REMOVED, 0, name.c_str(), player->GetName().c_str()); + SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_COMMAND_SUCCESS, name); + } } } - else if (removedPlayer) - SendCommandResult(session, GUILD_QUIT_S, ERR_GUILD_COMMAND_SUCCESS, removedPlayer->GetName()); } -void Guild::HandleUpdateMemberRank(WorldSession* session, uint64 targetGuid, bool demote) +void Guild::HandleUpdateMemberRank(WorldSession* session, uint64 guid, bool demote) { Player* player = session->GetPlayer(); - + GuildCommandType type = demote ? GUILD_COMMAND_DEMOTE : GUILD_COMMAND_PROMOTE; + // Player must have rights to promote + if (!_HasRankRight(player, demote ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE)) + SendCommandResult(session, type, ERR_GUILD_PERMISSIONS); // Promoted player must be a member of guild - if (Member* member = GetMember(targetGuid)) + else if (Member* member = GetMember(guid)) { - if (!_HasRankRight(player, demote ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE)) - { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); - return; - } - + std::string name = member->GetName(); // Player cannot promote himself if (member->IsSamePlayer(player->GetGUID())) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_NAME_INVALID); + SendCommandResult(session, type, ERR_GUILD_NAME_INVALID); return; } + Member const* memberMe = GetMember(player->GetGUID()); + uint8 rankId = memberMe->GetRankId(); if (demote) { // Player can demote only lower rank members - if (member->IsRankNotLower(player->GetRank())) + if (member->IsRankNotLower(rankId)) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_RANK_TOO_HIGH_S, member->GetName()); + SendCommandResult(session, type, ERR_GUILD_RANK_TOO_HIGH_S, name); return; } // Lowest rank cannot be demoted if (member->GetRankId() >= _GetLowestRankId()) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_RANK_TOO_LOW_S, member->GetName()); + SendCommandResult(session, type, ERR_GUILD_RANK_TOO_LOW_S, name); return; } } else { // Allow to promote only to lower rank than member's rank - // member->GetRank() + 1 is the highest rank that current player can promote to - if (member->IsRankNotLower(player->GetRank() + 1)) + // member->GetRankId() + 1 is the highest rank that current player can promote to + if (member->IsRankNotLower(rankId + 1)) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_RANK_TOO_HIGH_S, member->GetName()); + SendCommandResult(session, type, ERR_GUILD_RANK_TOO_HIGH_S, name); return; } } @@ -1767,80 +1804,79 @@ void Guild::HandleUpdateMemberRank(WorldSession* session, uint64 targetGuid, boo uint32 newRankId = member->GetRankId() + (demote ? 1 : -1); member->ChangeRank(newRankId); _LogEvent(demote ? GUILD_EVENT_LOG_DEMOTE_PLAYER : GUILD_EVENT_LOG_PROMOTE_PLAYER, player->GetGUIDLow(), GUID_LOPART(member->GetGUID()), newRankId); - _BroadcastEvent(demote ? GE_DEMOTION : GE_PROMOTION, 0, player->GetName().c_str(), member->GetName().c_str(), _GetRankName(newRankId).c_str()); + _BroadcastEvent(demote ? GE_DEMOTION : GE_PROMOTION, 0, player->GetName().c_str(), name.c_str(), _GetRankName(newRankId).c_str()); } } void Guild::HandleSetMemberRank(WorldSession* session, uint64 targetGuid, uint64 setterGuid, uint32 rank) { Player* player = session->GetPlayer(); + Member* member = GetMember(targetGuid); + GuildRankRights rights = GR_RIGHT_PROMOTE; + GuildCommandType type = GUILD_COMMAND_PROMOTE; - // Promoted player must be a member of guild - if (Member* member = GetMember(targetGuid)) + if (rank > member->GetRankId()) { - if (!_HasRankRight(player, rank > member->GetRankId() ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE)) - { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); - return; - } + rights = GR_RIGHT_DEMOTE; + type = GUILD_COMMAND_DEMOTE; + } - // Player cannot promote himself - if (member->IsSamePlayer(player->GetGUID())) - { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_NAME_INVALID); - return; - } + // Promoted player must be a member of guild + if (!_HasRankRight(player, rights)) + { + SendCommandResult(session, type, ERR_GUILD_PERMISSIONS); + return; + } - SendGuildRanksUpdate(setterGuid, targetGuid, rank); + // Player cannot promote himself + if (member->IsSamePlayer(player->GetGUID())) + { + SendCommandResult(session, type, ERR_GUILD_NAME_INVALID); + return; } + + SendGuildRanksUpdate(setterGuid, targetGuid, rank); } -void Guild::HandleAddNewRank(WorldSession* session, std::string const& name) //, uint32 rankId) +void Guild::HandleAddNewRank(WorldSession* session, std::string const& name) { - if (_GetRanksSize() >= GUILD_RANKS_MAX_COUNT) + uint8 size = _GetRanksSize(); + if (size >= GUILD_RANKS_MAX_COUNT) return; // Only leader can add new rank - if (!_IsLeader(session->GetPlayer())) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); - else - { - _CreateRank(name, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); - HandleQuery(session); - HandleRoster(); // Broadcast for tab rights update - } + if (_IsLeader(session->GetPlayer())) + if (_CreateRank(name, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK)) + { + char aux[2]; + sprintf(aux, "%u", size); + _BroadcastEvent(GE_RANK_CREATED, 0, aux, name.c_str()); + } } -void Guild::HandleRemoveRank(WorldSession* session, uint32 rankId) +void Guild::HandleRemoveRank(WorldSession* session, uint8 rankId) { - // Cannot remove rank if total count is minimum allowed by the client - if (_GetRanksSize() <= GUILD_RANKS_MIN_COUNT) + // Cannot remove rank if total count is minimum allowed by the client or is not leader + if (_GetRanksSize() <= GUILD_RANKS_MIN_COUNT || rankId >= _GetRanksSize() || !_IsLeader(session->GetPlayer())) return; - // Only leader can delete ranks - if (!_IsLeader(session->GetPlayer())) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); - else - { - // Delete bank rights for rank - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_RIGHTS_FOR_RANK); - stmt->setUInt32(0, m_id); - stmt->setUInt8(1, rankId); - CharacterDatabase.Execute(stmt); - // Delete rank - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_RANK); - stmt->setUInt32(0, m_id); - stmt->setUInt8(1, rankId); - CharacterDatabase.Execute(stmt); + // Delete bank rights for rank + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_RIGHTS_FOR_RANK); + stmt->setUInt32(0, m_id); + stmt->setUInt8(1, rankId); + CharacterDatabase.Execute(stmt); + // Delete rank + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_RANK); + stmt->setUInt32(0, m_id); + stmt->setUInt8(1, rankId); + CharacterDatabase.Execute(stmt); - m_ranks.erase(m_ranks.begin() + rankId-1); + m_ranks.erase(m_ranks.begin() + rankId-1); - HandleQuery(session); - HandleRoster(); // Broadcast for tab rights update - } + _BroadcastEvent(GE_RANK_DELETED, rankId); } -void Guild::HandleMemberDepositMoney(WorldSession* session, uint32 amount, bool cashFlow /*=false*/) +void Guild::HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool cashFlow /*=false*/) { Player* player = session->GetPlayer(); @@ -1848,66 +1884,61 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint32 amount, bool sScriptMgr->OnGuildMemberDepositMoney(this, player, amount); SQLTransaction trans = CharacterDatabase.BeginTransaction(); - // Add money to bank _ModifyBankMoney(trans, amount, true); - // Remove money from player - player->ModifyMoney(-int64(amount)); - player->SaveGoldToDB(trans); - // Log GM action (TODO: move to scripts) - if (!AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + if (!cashFlow) { - sLog->outCommand(player->GetSession()->GetAccountId(), - "GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)", - player->GetName().c_str(), player->GetSession()->GetAccountId(), amount, m_id); + player->ModifyMoney(-int64(amount)); + player->SaveGoldToDB(trans); } - // Log guild bank event - _LogBankEvent(trans, cashFlow ? GUILD_BANK_LOG_CASH_FLOW_DEPOSIT : GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), player->GetGUIDLow(), amount); + _LogBankEvent(trans, cashFlow ? GUILD_BANK_LOG_CASH_FLOW_DEPOSIT : GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), player->GetGUIDLow(), amount); CharacterDatabase.CommitTransaction(trans); - if (!cashFlow) - SendBankList(session, 0, false, false); + std::string aux = ByteArrayToHexStr(reinterpret_cast<uint8*>(&amount), 8, true); + _BroadcastEvent(GE_BANK_MONEY_CHANGED, 0, aux.c_str()); + + if (!AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) + { + sLog->outCommand(player->GetSession()->GetAccountId(), + "GM %s (Account: %u) deposit money (Amount: " UI64FMTD ") to guild bank (Guild ID %u)", + player->GetName().c_str(), player->GetSession()->GetAccountId(), amount, m_id); + } } -bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool repair) +bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint64 amount, bool repair) { if (m_bankMoney < amount) // Not enough money in bank return false; Player* player = session->GetPlayer(); - if (!_HasRankRight(player, repair ? GR_RIGHT_WITHDRAW_REPAIR : GR_RIGHT_WITHDRAW_GOLD)) - return false; - uint32 remainingMoney = _GetMemberRemainingMoney(player->GetGUID()); - if (!remainingMoney) + Member* member = GetMember(player->GetGUID()); + if (!member) return false; - if (remainingMoney < amount) - return false; + if (uint64(_GetMemberRemainingMoney(member)) < amount) // Check if we have enough slot/money today + return false; // Call script after validation and before money transfer. sScriptMgr->OnGuildMemberWitdrawMoney(this, player, amount, repair); SQLTransaction trans = CharacterDatabase.BeginTransaction(); // Update remaining money amount - if (remainingMoney < uint32(GUILD_WITHDRAW_MONEY_UNLIMITED)) - if (Member* member = GetMember(player->GetGUID())) - member->DecreaseBankRemainingValue(trans, GUILD_BANK_MAX_TABS, amount); + member->UpdateBankWithdrawValue(trans, GUILD_BANK_MAX_TABS, amount); // Remove money from bank _ModifyBankMoney(trans, amount, false); // Add money to player (if required) if (!repair) { - player->ModifyMoney(amount); + player->ModifyMoney((int64)amount); player->SaveGoldToDB(trans); } // Log guild bank event _LogBankEvent(trans, repair ? GUILD_BANK_LOG_REPAIR_MONEY : GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), player->GetGUIDLow(), amount); CharacterDatabase.CommitTransaction(trans); - SendMoneyInfo(session); - if (!repair) - SendBankList(session, 0, false, false); + std::string aux = ByteArrayToHexStr(reinterpret_cast<uint8*>(&amount), 8, true); + _BroadcastEvent(GE_BANK_MONEY_CHANGED, 0, aux.c_str()); return true; } @@ -1918,6 +1949,7 @@ void Guild::HandleMemberLogout(WorldSession* session) { member->SetStats(player); member->UpdateLogoutTime(); + member->ResetFlags(); } _BroadcastEvent(GE_SIGNED_OFF, player->GetGUID(), player->GetName().c_str()); @@ -1927,14 +1959,10 @@ void Guild::HandleMemberLogout(WorldSession* session) void Guild::HandleDisband(WorldSession* session) { // Only leader can disband guild - if (!_IsLeader(session->GetPlayer())) - Guild::SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); - else if (GetLevel() >= sWorld->getIntConfig(CONFIG_GUILD_UNDELETABLE_LEVEL)) - Guild::SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL); - else + if (_IsLeader(session->GetPlayer())) { Disband(); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Guild Successfully Disbanded"); + sLog->outDebug(LOG_FILTER_GUILD, "Guild Successfully Disbanded"); } } @@ -1955,7 +1983,7 @@ void Guild::HandleGuildPartyRequest(WorldSession* session) data << uint32(0); // Needed guild members session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent (SMSG_GUILD_PARTY_STATE_RESPONSE)"); + sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_PARTY_STATE_RESPONSE [%s]", session->GetPlayerInfo().c_str()); } void Guild::SendEventLog(WorldSession* session) const @@ -1963,7 +1991,7 @@ void Guild::SendEventLog(WorldSession* session) const WorldPacket data(SMSG_GUILD_EVENT_LOG_QUERY_RESULT, 1 + m_eventLog->GetSize() * (1 + 8 + 4)); m_eventLog->WritePacket(data); session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_EVENT_LOG_QUERY_RESULT)"); + sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_EVENT_LOG_QUERY_RESULT [%s]", session->GetPlayerInfo().c_str()); } void Guild::SendBankLog(WorldSession* session, uint8 tabId) const @@ -1979,94 +2007,11 @@ void Guild::SendBankLog(WorldSession* session, uint8 tabId) const //if (tabId == GUILD_BANK_MAX_TABS && hasCashFlow) // data << uint64(cashFlowContribution); session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_BANK_LOG_QUERY_RESULT) for tab %u", tabId); + sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_BANK_LOG_QUERY_RESULT [%s] TabId: %u", session->GetPlayerInfo().c_str(), tabId); } } -void Guild::SendBankList(WorldSession* session, uint8 tabId, bool withContent, bool withTabInfo) const -{ - ByteBuffer tabData; - WorldPacket data(SMSG_GUILD_BANK_LIST, 500); - data.WriteBit(0); - uint32 itemCount = 0; - if (withContent && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB)) - if (BankTab const* tab = GetBankTab(tabId)) - for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId) - if (tab->GetItem(slotId)) - ++itemCount; - - data.WriteBits(itemCount, 20); - data.WriteBits(withTabInfo ? _GetPurchasedTabsSize() : 0, 22); - if (withContent && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB)) - { - if (BankTab const* tab = GetBankTab(tabId)) - { - for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId) - { - if (Item* tabItem = tab->GetItem(slotId)) - { - data.WriteBit(0); - - uint32 enchants = 0; - for (uint32 ench = 0; ench < MAX_ENCHANTMENT_SLOT; ++ench) - { - if (uint32 enchantId = tabItem->GetEnchantmentId(EnchantmentSlot(ench))) - { - tabData << uint32(enchantId); - tabData << uint32(ench); - ++enchants; - } - } - - data.WriteBits(enchants, 23); - - tabData << uint32(0); - tabData << uint32(0); - tabData << uint32(0); - tabData << uint32(tabItem->GetCount()); // ITEM_FIELD_STACK_COUNT - tabData << uint32(slotId); - tabData << uint32(0); - tabData << uint32(tabItem->GetEntry()); - tabData << uint32(tabItem->GetItemRandomPropertyId()); - tabData << uint32(abs(tabItem->GetSpellCharges())); // Spell charges - tabData << uint32(tabItem->GetItemSuffixFactor()); // SuffixFactor - } - } - } - } - - if (withTabInfo) - { - for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i) - { - data.WriteBits(m_bankTabs[i]->GetIcon().length(), 9); - data.WriteBits(m_bankTabs[i]->GetName().length(), 7); - } - } - - data.FlushBits(); - - if (withTabInfo) - { - for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i) - { - data.WriteString(m_bankTabs[i]->GetIcon()); - data << uint32(i); - data.WriteString(m_bankTabs[i]->GetName()); - } - } - - data << uint64(m_bankMoney); - if (!tabData.empty()) - data.append(tabData); - - data << uint32(tabId); - data << uint32(_GetMemberRemainingSlots(session->GetPlayer()->GetGUID(), 0)); - session->SendPacket(&data); - - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_BANK_LIST)"); -} void Guild::SendBankTabText(WorldSession* session, uint8 tabId) const { @@ -2076,33 +2021,42 @@ void Guild::SendBankTabText(WorldSession* session, uint8 tabId) const void Guild::SendPermissions(WorldSession* session) const { - uint64 guid = session->GetPlayer()->GetGUID(); - uint32 rankId = session->GetPlayer()->GetRank(); + Member const* member = GetMember(session->GetPlayer()->GetGUID()); + if (!member) + return; + + uint8 rankId = member->GetRankId(); + WorldPacket data(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, 4 * 15 + 1); data << uint32(rankId); data << uint32(_GetPurchasedTabsSize()); data << uint32(_GetRankRights(rankId)); - data << uint32(_GetMemberRemainingMoney(guid)); + data << uint32(_GetMemberRemainingMoney(member)); data.WriteBits(GUILD_BANK_MAX_TABS, 23); for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId) { data << uint32(_GetRankBankTabRights(rankId, tabId)); - data << uint32(_GetMemberRemainingSlots(guid, tabId)); + data << uint32(_GetMemberRemainingSlots(member, tabId)); } session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_PERMISSIONS_QUERY_RESULTS)"); + sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_PERMISSIONS_QUERY_RESULTS [%s] Rank: %u", session->GetPlayerInfo().c_str(), rankId); } void Guild::SendMoneyInfo(WorldSession* session) const { + Member const* member = GetMember(session->GetPlayer()->GetGUID()); + if (!member) + return; + + int32 amount = _GetMemberRemainingMoney(member); WorldPacket data(SMSG_GUILD_BANK_MONEY_WITHDRAWN, 4); - data << uint64(_GetMemberRemainingMoney(session->GetPlayer()->GetGUID())); + data << int64(amount); session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent SMSG_GUILD_BANK_MONEY_WITHDRAWN"); + sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_BANK_MONEY_WITHDRAWN [%s] Money: %u", session->GetPlayerInfo().c_str(), amount); } -void Guild::SendLoginInfo(WorldSession* session) const +void Guild::SendLoginInfo(WorldSession* session) { /* Login sequence: @@ -2120,18 +2074,20 @@ void Guild::SendLoginInfo(WorldSession* session) const data << uint8(1); data << m_motd; session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent guild MOTD (SMSG_GUILD_EVENT)"); - HandleGuildRanks(session); + sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_EVENT [%s] MOTD", session->GetPlayerInfo().c_str()); + + Player* player = session->GetPlayer(); - _BroadcastEvent(GE_SIGNED_ON, session->GetPlayer()->GetGUID(), session->GetPlayer()->GetName().c_str()); + SendGuildRankInfo(session); + _BroadcastEvent(GE_SIGNED_ON, player->GetGUID(), player->GetName().c_str()); // Send to self separately, player is not in world yet and is not found by _BroadcastEvent data.Initialize(SMSG_GUILD_EVENT, 1 + 1 + session->GetPlayer()->GetName().size() + 8); data << uint8(GE_SIGNED_ON); data << uint8(1); - data << session->GetPlayer()->GetName(); - data << uint64(session->GetPlayer()->GetGUID()); + data << player->GetName(); + data << uint64(player->GetGUID()); session->SendPacket(&data); data.Initialize(SMSG_GUILD_MEMBER_DAILY_RESET, 0); // tells the client to request bank withdrawal limit @@ -2147,7 +2103,13 @@ void Guild::SendLoginInfo(WorldSession* session) const SendGuildReputationWeeklyCap(session); - GetAchievementMgr().SendAllAchievementData(session->GetPlayer()); + GetAchievementMgr().SendAllAchievementData(player); + + if (Member* member = GetMember(player->GetGUID())) + { + member->SetStats(player); + member->AddFlag(GUILDMEMBER_STATUS_ONLINE); + } } void Guild::SendGuildReputationWeeklyCap(WorldSession* session) const @@ -2212,10 +2174,10 @@ bool Guild::LoadMemberFromDB(Field* fields) void Guild::LoadBankRightFromDB(Field* fields) { - // rights slots - GuildBankRightsAndSlots rightsAndSlots(fields[3].GetUInt8(), fields[4].GetUInt32()); - // rankId tabId - _SetRankBankTabRightsAndSlots(fields[2].GetUInt8(), fields[1].GetUInt8(), rightsAndSlots, false); + // tabId rights slots + GuildBankRightsAndSlots rightsAndSlots(fields[1].GetUInt8(), fields[3].GetUInt8(), fields[4].GetUInt32()); + // rankId + _SetRankBankTabRightsAndSlots(fields[2].GetUInt8(), rightsAndSlots, false); } bool Guild::LoadEventLogFromDB(Field* fields) @@ -2275,15 +2237,13 @@ bool Guild::LoadBankEventLogFromDB(Field* fields) return true; } -bool Guild::LoadBankTabFromDB(Field* fields) +void Guild::LoadBankTabFromDB(Field* fields) { uint8 tabId = fields[1].GetUInt8(); if (tabId >= _GetPurchasedTabsSize()) - { sLog->outError(LOG_FILTER_GUILD, "Invalid tab (tabId: %u) in guild bank, skipped.", tabId); - return false; - } - return m_bankTabs[tabId]->LoadFromDB(fields); + else + m_bankTabs[tabId]->LoadFromDB(fields); } bool Guild::LoadBankItemFromDB(Field* fields) @@ -2305,16 +2265,17 @@ bool Guild::Validate() // GUILD RANKS represent a sequence starting from 0 = GUILD_MASTER (ALL PRIVILEGES) to max 9 (lowest privileges). // The lower rank id is considered higher rank - so promotion does rank-- and demotion does rank++ // Between ranks in sequence cannot be gaps - so 0, 1, 2, 4 is impossible - // Min ranks count is 5 and max is 10. + // Min ranks count is 2 and max is 10. bool broken_ranks = false; - if (_GetRanksSize() < GUILD_RANKS_MIN_COUNT || _GetRanksSize() > GUILD_RANKS_MAX_COUNT) + uint8 ranks = _GetRanksSize(); + if (ranks < GUILD_RANKS_MIN_COUNT || ranks > GUILD_RANKS_MAX_COUNT) { sLog->outError(LOG_FILTER_GUILD, "Guild %u has invalid number of ranks, creating new...", m_id); broken_ranks = true; } else { - for (uint8 rankId = 0; rankId < _GetRanksSize(); ++rankId) + for (uint8 rankId = 0; rankId < ranks; ++rankId) { RankInfo* rankInfo = GetRankInfo(rankId); if (rankInfo->GetId() != rankId) @@ -2322,6 +2283,15 @@ bool Guild::Validate() sLog->outError(LOG_FILTER_GUILD, "Guild %u has broken rank id %u, creating default set of ranks...", m_id, rankId); broken_ranks = true; } + else + { + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + if (rankInfo->CreateMissingTabsIfNeeded(_GetPurchasedTabsSize(), trans)) + { + sLog->outError(LOG_FILTER_GUILD, "Guild %u has broken Tabs for rank id %u, creating default tab...", m_id, rankId); + CharacterDatabase.CommitTransaction(trans); + } + } } } @@ -2364,7 +2334,7 @@ bool Guild::Validate() } // Broadcasts -void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, const std::string& msg, uint32 language) const +void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::string const& msg, uint32 language) const { if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { @@ -2378,7 +2348,7 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, const std: } } -void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, const std::string& msg, const std::string& prefix) const +void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std::string const& msg, std::string const& prefix) const { if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { @@ -2432,10 +2402,21 @@ bool Guild::AddMember(uint64 guid, uint8 rankId) rankId = _GetLowestRankId(); Member* member = new Member(m_id, guid, rankId); + std::string name; if (player) + { + player->SetInGuild(m_id); + player->SetGuildIdInvited(0); + player->SetRank(rankId); + player->SetGuildLevel(GetLevel()); member->SetStats(player); + SendLoginInfo(player->GetSession()); + name = player->GetName(); + } else { + member->ResetFlags(); + bool ok = false; // Player must exist PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DATA_FOR_GUILD); @@ -2443,8 +2424,9 @@ bool Guild::AddMember(uint64 guid, uint8 rankId) if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) { Field* fields = result->Fetch(); + name = fields[0].GetString(); member->SetStats( - fields[0].GetString(), + name, fields[1].GetUInt8(), fields[2].GetUInt8(), fields[3].GetUInt16(), @@ -2462,24 +2444,11 @@ bool Guild::AddMember(uint64 guid, uint8 rankId) SQLTransaction trans(NULL); member->SaveToDB(trans); - // If player not in game data in will be loaded from guild tables, so no need to update it! - if (player) - { - player->SetInGuild(m_id); - player->SetRank(rankId); - player->SetGuildLevel(GetLevel()); - player->SetGuildIdInvited(0); - - if (sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED)) - { - for (uint32 i = 0; i < sGuildPerkSpellsStore.GetNumRows(); ++i) - if (GuildPerkSpellsEntry const* entry = sGuildPerkSpellsStore.LookupEntry(i)) - if (entry->Level <= GetLevel()) - player->learnSpell(entry->SpellId, true); - } - } _UpdateAccountsNumber(); + _LogEvent(GUILD_EVENT_LOG_JOIN_GUILD, lowguid); + _BroadcastEvent(GE_JOINED, guid, name.c_str()); + sGuildFinderMgr->RemoveMembershipRequest(player->GetGUIDLow(), GUID_LOPART(this->GetGUID())); // Call scripts if member was succesfully added (and stored to database) sScriptMgr->OnGuildAddMember(this, player, rankId); @@ -2595,7 +2564,7 @@ void Guild::SwapItemsWithInventory(Player* player, bool toChar, uint8 tabId, uin } // Bank tabs -void Guild::SetBankTabText(uint8 tabId, const std::string& text) +void Guild::SetBankTabText(uint8 tabId, std::string const& text) { if (BankTab* pTab = GetBankTab(tabId)) { @@ -2612,18 +2581,14 @@ void Guild::_CreateLogHolders() m_bankEventLog[tabId] = new LogHolder(m_id, sWorld->getIntConfig(CONFIG_GUILD_BANK_EVENT_LOG_COUNT)); } -bool Guild::_CreateNewBankTab() +void Guild::_CreateNewBankTab() { - if (_GetPurchasedTabsSize() >= GUILD_BANK_MAX_TABS) - return false; - uint8 tabId = _GetPurchasedTabsSize(); // Next free id m_bankTabs.push_back(new BankTab(m_id, tabId)); - PreparedStatement* stmt = NULL; SQLTransaction trans = CharacterDatabase.BeginTransaction(); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_TAB); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_TAB); stmt->setUInt32(0, m_id); stmt->setUInt8 (1, tabId); trans->Append(stmt); @@ -2634,14 +2599,11 @@ bool Guild::_CreateNewBankTab() trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); - return true; } void Guild::_CreateDefaultGuildRanks(LocaleConstant loc) { - PreparedStatement* stmt = NULL; - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_RANKS); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_RANKS); stmt->setUInt32(0, m_id); CharacterDatabase.Execute(stmt); @@ -2656,28 +2618,22 @@ void Guild::_CreateDefaultGuildRanks(LocaleConstant loc) _CreateRank(sObjectMgr->GetTrinityString(LANG_GUILD_INITIATE, loc), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); } -void Guild::_CreateRank(const std::string& name, uint32 rights) +bool Guild::_CreateRank(std::string const& name, uint32 rights) { - uint32 newRankId = _GetRanksSize(); + uint8 newRankId = _GetRanksSize(); if (newRankId >= GUILD_RANKS_MAX_COUNT) - return; + return false; // Ranks represent sequence 0, 1, 2, ... where 0 means guildmaster RankInfo info(m_id, newRankId, name, rights, 0); m_ranks.push_back(info); SQLTransaction trans = CharacterDatabase.BeginTransaction(); - for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i) - { - // Create bank rights with default values - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_RIGHT_DEFAULT); - stmt->setUInt32(0, m_id); - stmt->setUInt8 (1, i); - stmt->setUInt8 (2, newRankId); - trans->Append(stmt); - } + info.CreateMissingTabsIfNeeded(_GetPurchasedTabsSize(), trans); info.SaveToDB(trans); CharacterDatabase.CommitTransaction(trans); + + return true; } // Updates the number of accounts that are in the guild @@ -2748,55 +2704,43 @@ void Guild::_SetLeaderGUID(Member* pLeader) CharacterDatabase.Execute(stmt); } -void Guild::_SetRankBankMoneyPerDay(uint32 rankId, uint32 moneyPerDay) +void Guild::_SetRankBankMoneyPerDay(uint8 rankId, uint32 moneyPerDay) { if (RankInfo* rankInfo = GetRankInfo(rankId)) - { - for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->second->IsRank(rankId)) - itr->second->ResetMoneyTime(); - rankInfo->SetBankMoneyPerDay(moneyPerDay); - } } -void Guild::_SetRankBankTabRightsAndSlots(uint32 rankId, uint8 tabId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB) +void Guild::_SetRankBankTabRightsAndSlots(uint8 rankId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB) { - if (tabId >= _GetPurchasedTabsSize()) + if (rightsAndSlots.GetTabId() >= _GetPurchasedTabsSize()) return; if (RankInfo* rankInfo = GetRankInfo(rankId)) - { - for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (itr->second->IsRank(rankId)) - itr->second->ResetTabTimes(); - - rankInfo->SetBankTabSlotsAndRights(tabId, rightsAndSlots, saveToDB); - } + rankInfo->SetBankTabSlotsAndRights(rightsAndSlots, saveToDB); } -inline std::string Guild::_GetRankName(uint32 rankId) const +inline std::string Guild::_GetRankName(uint8 rankId) const { if (const RankInfo* rankInfo = GetRankInfo(rankId)) return rankInfo->GetName(); return "<unknown>"; } -inline uint32 Guild::_GetRankRights(uint32 rankId) const +inline uint32 Guild::_GetRankRights(uint8 rankId) const { if (const RankInfo* rankInfo = GetRankInfo(rankId)) return rankInfo->GetRights(); return 0; } -inline uint32 Guild::_GetRankBankMoneyPerDay(uint32 rankId) const +inline int32 Guild::_GetRankBankMoneyPerDay(uint8 rankId) const { if (const RankInfo* rankInfo = GetRankInfo(rankId)) return rankInfo->GetBankMoneyPerDay(); return 0; } -inline uint32 Guild::_GetRankBankTabSlotsPerDay(uint32 rankId, uint8 tabId) const +inline int32 Guild::_GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const { if (tabId < _GetPurchasedTabsSize()) if (const RankInfo* rankInfo = GetRankInfo(rankId)) @@ -2804,35 +2748,57 @@ inline uint32 Guild::_GetRankBankTabSlotsPerDay(uint32 rankId, uint8 tabId) cons return 0; } -inline uint32 Guild::_GetRankBankTabRights(uint32 rankId, uint8 tabId) const +inline int8 Guild::_GetRankBankTabRights(uint8 rankId, uint8 tabId) const { if (const RankInfo* rankInfo = GetRankInfo(rankId)) return rankInfo->GetBankTabRights(tabId); return 0; } -inline uint32 Guild::_GetMemberRemainingSlots(uint64 guid, uint8 tabId) const +inline int32 Guild::_GetMemberRemainingSlots(Member const* member, uint8 tabId) const { - if (const Member* member = GetMember(guid)) - return member->GetBankRemainingValue(tabId, this); + if (member) + { + uint8 rankId = member->GetRankId(); + if (rankId == GR_GUILDMASTER) + return GUILD_WITHDRAW_SLOT_UNLIMITED; + if ((_GetRankBankTabRights(rankId, tabId) & GUILD_BANK_RIGHT_VIEW_TAB) != GR_RIGHT_EMPTY) + { + int32 remaining = _GetRankBankTabSlotsPerDay(rankId, tabId) - member->GetBankWithdrawValue(tabId); + if (remaining > 0) + return remaining; + } + } return 0; } -inline uint32 Guild::_GetMemberRemainingMoney(uint64 guid) const +inline int32 Guild::_GetMemberRemainingMoney(Member const* member) const { - if (const Member* member = GetMember(guid)) - return member->GetBankRemainingValue(GUILD_BANK_MAX_TABS, this); + if (member) + { + uint8 rankId = member->GetRankId(); + if (rankId == GR_GUILDMASTER) + return GUILD_WITHDRAW_MONEY_UNLIMITED; + + if ((_GetRankRights(rankId) & (GR_RIGHT_WITHDRAW_REPAIR | GR_RIGHT_WITHDRAW_GOLD)) != GR_RIGHT_EMPTY) + { + int32 remaining = _GetRankBankMoneyPerDay(rankId) - member->GetBankWithdrawValue(GUILD_BANK_MAX_TABS); + if (remaining > 0) + return remaining; + } + } return 0; } -inline void Guild::_DecreaseMemberRemainingSlots(SQLTransaction& trans, uint64 guid, uint8 tabId) +inline void Guild::_UpdateMemberWithdrawSlots(SQLTransaction& trans, uint64 guid, uint8 tabId) { - // Remaining slots must be more then 0 - if (uint32 remainingSlots = _GetMemberRemainingSlots(guid, tabId)) - // Ignore guild master - if (remainingSlots < uint32(GUILD_WITHDRAW_SLOT_UNLIMITED)) - if (Member* member = GetMember(guid)) - member->DecreaseBankRemainingValue(trans, tabId, 1); + if (Member* member = GetMember(guid)) + { + uint8 rankId = member->GetRankId(); + if (rankId != GR_GUILDMASTER + && member->GetBankWithdrawValue(tabId) < _GetRankBankTabSlotsPerDay(rankId, tabId)) + member->UpdateBankWithdrawValue(trans, tabId, 1); + } } inline bool Guild::_MemberHasTabRights(uint64 guid, uint8 tabId, uint32 rights) const @@ -3087,7 +3053,7 @@ void Guild::_SendBankContentUpdate(uint8 tabId, SlotIds slots) const if (_MemberHasTabRights(itr->second->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB)) if (Player* player = itr->second->FindPlayer()) { - data.put<uint32>(rempos, uint32(_GetMemberRemainingSlots(player->GetGUID(), tabId))); + data.put<uint32>(rempos, uint32(_GetMemberRemainingSlots(itr->second, tabId))); player->GetSession()->SendPacket(&data); } @@ -3117,6 +3083,95 @@ void Guild::_BroadcastEvent(GuildEvents guildEvent, uint64 guid, const char* par sLog->outDebug(LOG_FILTER_GUILD, "SMSG_GUILD_EVENT [Broadcast] Event: %u", guildEvent); } +void Guild::SendBankList(WorldSession* session, uint8 tabId, bool withContent, bool withTabInfo) const +{ + Member const* member = GetMember(session->GetPlayer()->GetGUID()); + if (!member) // Shouldn't happen, just in case + return; + + ByteBuffer tabData; + WorldPacket data(SMSG_GUILD_BANK_LIST, 500); + data.WriteBit(0); + uint32 itemCount = 0; + if (withContent && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB)) + if (BankTab const* tab = GetBankTab(tabId)) + for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId) + if (tab->GetItem(slotId)) + ++itemCount; + + data.WriteBits(itemCount, 20); + data.WriteBits(withTabInfo ? _GetPurchasedTabsSize() : 0, 22); + if (withContent && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB)) + { + if (BankTab const* tab = GetBankTab(tabId)) + { + for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId) + { + if (Item* tabItem = tab->GetItem(slotId)) + { + data.WriteBit(0); + + uint32 enchants = 0; + for (uint32 ench = 0; ench < MAX_ENCHANTMENT_SLOT; ++ench) + { + if (uint32 enchantId = tabItem->GetEnchantmentId(EnchantmentSlot(ench))) + { + tabData << uint32(enchantId); + tabData << uint32(ench); + ++enchants; + } + } + + data.WriteBits(enchants, 23); + + tabData << uint32(0); + tabData << uint32(0); + tabData << uint32(0); + tabData << uint32(tabItem->GetCount()); // ITEM_FIELD_STACK_COUNT + tabData << uint32(slotId); + tabData << uint32(0); + tabData << uint32(tabItem->GetEntry()); + tabData << uint32(tabItem->GetItemRandomPropertyId()); + tabData << uint32(abs(tabItem->GetSpellCharges())); // Spell charges + tabData << uint32(tabItem->GetItemSuffixFactor()); // SuffixFactor + } + } + } + } + + if (withTabInfo) + { + for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i) + { + data.WriteBits(m_bankTabs[i]->GetIcon().length(), 9); + data.WriteBits(m_bankTabs[i]->GetName().length(), 7); + } + } + + data.FlushBits(); + + if (withTabInfo) + { + for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i) + { + data.WriteString(m_bankTabs[i]->GetIcon()); + data << uint32(i); + data.WriteString(m_bankTabs[i]->GetName()); + } + } + + data << uint64(m_bankMoney); + if (!tabData.empty()) + data.append(tabData); + + data << uint32(tabId); + data << uint32(_GetMemberRemainingSlots(member, tabId)); + + session->SendPacket(&data); + + sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_BANK_LIST)"); +} + void Guild::SendGuildRanksUpdate(uint64 setterGuid, uint64 targetGuid, uint32 rank) { ObjectGuid tarGuid = targetGuid; @@ -3237,15 +3292,6 @@ void Guild::SendGuildXP(WorldSession* session) const session->SendPacket(&data); } -void Guild::ResetDailyExperience() -{ - _todayExperience = 0; - - for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (Player* player = itr->second->FindPlayer()) - SendGuildXP(player->GetSession()); -} - void Guild::GuildNewsLog::AddNewEvent(GuildNews eventType, time_t date, uint64 playerGuid, uint32 flags, uint32 data) { uint32 id = _newsLog.size(); @@ -3372,3 +3418,18 @@ void Guild::GuildNewsLog::BuildNewsData(WorldPacket& data) data.AppendPackedTime(it->second.Date); } } + +void Guild::ResetTimes(bool week) +{ + _todayExperience = 0; + for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + { + itr->second->ResetValues(week); + if (Player* player = itr->second->FindPlayer()) + { + //SendGuildXP(player->GetSession()); + WorldPacket data(SMSG_GUILD_MEMBER_DAILY_RESET, 0); // tells the client to request bank withdrawal limit + player->GetSession()->SendPacket(&data); + } + } +} diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index 5ac170a9cb8..9a0b9e682e4 100755 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -39,7 +39,14 @@ enum GuildMisc GUILD_WITHDRAW_MONEY_UNLIMITED = 0xFFFFFFFF, GUILD_WITHDRAW_SLOT_UNLIMITED = 0xFFFFFFFF, GUILD_EVENT_LOG_GUID_UNDEFINED = 0xFFFFFFFF, - GUILD_EXPERIENCE_UNCAPPED_LEVEL = 20 ///> Hardcoded in client, starting from this level, guild daily experience gain is unlimited. + GUILD_EXPERIENCE_UNCAPPED_LEVEL = 20, ///> Hardcoded in client, starting from this level, guild daily experience gain is unlimited. + TAB_UNDEFINED = 0xFF, +}; + +enum GuildMemberData +{ + GUILD_MEMBER_DATA_ZONEID, + GUILD_MEMBER_DATA_LEVEL, }; enum GuildDefaultRanks @@ -56,101 +63,111 @@ enum GuildDefaultRanks enum GuildRankRights { - GR_RIGHT_EMPTY = 0x00000040, - GR_RIGHT_GCHATLISTEN = GR_RIGHT_EMPTY | 0x00000001, - GR_RIGHT_GCHATSPEAK = GR_RIGHT_EMPTY | 0x00000002, - GR_RIGHT_OFFCHATLISTEN = GR_RIGHT_EMPTY | 0x00000004, - GR_RIGHT_OFFCHATSPEAK = GR_RIGHT_EMPTY | 0x00000008, - GR_RIGHT_INVITE = GR_RIGHT_EMPTY | 0x00000010, - GR_RIGHT_REMOVE = GR_RIGHT_EMPTY | 0x00000020, - GR_RIGHT_PROMOTE = GR_RIGHT_EMPTY | 0x00000080, - GR_RIGHT_DEMOTE = GR_RIGHT_EMPTY | 0x00000100, - GR_RIGHT_SETMOTD = GR_RIGHT_EMPTY | 0x00001000, - GR_RIGHT_EPNOTE = GR_RIGHT_EMPTY | 0x00002000, - GR_RIGHT_VIEWOFFNOTE = GR_RIGHT_EMPTY | 0x00004000, - GR_RIGHT_EOFFNOTE = GR_RIGHT_EMPTY | 0x00008000, - GR_RIGHT_MODIFY_GUILD_INFO = GR_RIGHT_EMPTY | 0x00010000, - 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 = 0x00DDFFBF + GR_RIGHT_EMPTY = 0x00000040, + GR_RIGHT_GCHATLISTEN = GR_RIGHT_EMPTY | 0x00000001, + GR_RIGHT_GCHATSPEAK = GR_RIGHT_EMPTY | 0x00000002, + GR_RIGHT_OFFCHATLISTEN = GR_RIGHT_EMPTY | 0x00000004, + GR_RIGHT_OFFCHATSPEAK = GR_RIGHT_EMPTY | 0x00000008, + GR_RIGHT_INVITE = GR_RIGHT_EMPTY | 0x00000010, + GR_RIGHT_REMOVE = GR_RIGHT_EMPTY | 0x00000020, + GR_RIGHT_PROMOTE = GR_RIGHT_EMPTY | 0x00000080, + GR_RIGHT_DEMOTE = GR_RIGHT_EMPTY | 0x00000100, + GR_RIGHT_SETMOTD = GR_RIGHT_EMPTY | 0x00001000, + GR_RIGHT_EPNOTE = GR_RIGHT_EMPTY | 0x00002000, + GR_RIGHT_VIEWOFFNOTE = GR_RIGHT_EMPTY | 0x00004000, + GR_RIGHT_EOFFNOTE = GR_RIGHT_EMPTY | 0x00008000, + GR_RIGHT_MODIFY_GUILD_INFO = GR_RIGHT_EMPTY | 0x00010000, + 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 = 0x00DDFFBF }; enum GuildCommandType { - GUILD_CREATE_S = 0x00, - GUILD_INVITE_S = 0x01, - GUILD_QUIT_S = 0x03, - GUILD_FOUNDER_S = 0x0E, - GUILD_UNK1 = 0x13, - GUILD_UNK2 = 0x14 + GUILD_COMMAND_CREATE = 0, + GUILD_COMMAND_INVITE = 1, + GUILD_COMMAND_QUIT = 3, + GUILD_COMMAND_ROSTER = 5, + GUILD_COMMAND_PROMOTE = 6, + GUILD_COMMAND_DEMOTE = 7, + GUILD_COMMAND_REMOVE = 8, + GUILD_COMMAND_CHANGE_LEADER = 10, + GUILD_COMMAND_EDIT_MOTD = 11, + GUILD_COMMAND_GUILD_CHAT = 13, + GUILD_COMMAND_FOUNDER = 14, + GUILD_COMMAND_CHANGE_RANK = 16, + GUILD_COMMAND_PUBLIC_NOTE = 19, + GUILD_COMMAND_VIEW_TAB = 21, + GUILD_COMMAND_MOVE_ITEM = 22, + GUILD_COMMAND_REPAIR = 25, }; enum GuildCommandError { - ERR_GUILD_COMMAND_SUCCESS = 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, + ERR_GUILD_COMMAND_SUCCESS = 0, + ERR_GUILD_INTERNAL = 1, + ERR_ALREADY_IN_GUILD = 2, + ERR_ALREADY_IN_GUILD_S = 3, + ERR_INVITED_TO_GUILD = 4, + ERR_ALREADY_INVITED_TO_GUILD_S = 5, + ERR_GUILD_NAME_INVALID = 6, + ERR_GUILD_NAME_EXISTS_S = 7, + ERR_GUILD_LEADER_LEAVE = 8, + ERR_GUILD_PERMISSIONS = 8, + ERR_GUILD_PLAYER_NOT_IN_GUILD = 9, + ERR_GUILD_PLAYER_NOT_IN_GUILD_S = 10, + ERR_GUILD_PLAYER_NOT_FOUND_S = 11, + ERR_GUILD_NOT_ALLIED = 12, + ERR_GUILD_RANK_TOO_HIGH_S = 13, + ERR_GUILD_RANK_TOO_LOW_S = 14, + ERR_GUILD_RANKS_LOCKED = 17, + ERR_GUILD_RANK_IN_USE = 18, + ERR_GUILD_IGNORING_YOU_S = 19, + ERR_GUILD_UNK1 = 20, // Forces roster update + ERR_GUILD_WITHDRAW_LIMIT = 25, + ERR_GUILD_NOT_ENOUGH_MONEY = 26, + ERR_GUILD_BANK_FULL = 28, + ERR_GUILD_ITEM_NOT_FOUND = 29, + ERR_GUILD_TOO_MUCH_MONEY = 31, + ERR_GUILD_BANK_WRONG_TAB = 32, + ERR_RANK_REQUIRES_AUTHENTICATOR = 34, + ERR_GUILD_BANK_VOUCHER_FAILED = 35, + ERR_GUILD_TRIAL_ACCOUNT = 36, + ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL = 37, + ERR_GUILD_MOVE_STARTING = 38, + ERR_GUILD_REP_TOO_LOW = 39 }; enum GuildEvents { - GE_PROMOTION = 1, - GE_DEMOTION = 2, - GE_MOTD = 3, - GE_JOINED = 4, - GE_LEFT = 5, - GE_REMOVED = 6, - GE_LEADER_IS = 7, - GE_LEADER_CHANGED = 8, - GE_DISBANDED = 9, - GE_TABARDCHANGE = 10, - GE_RANK_UPDATED = 11, - GE_RANK_CREATED = 12, - GE_RANK_DELETED = 13, - GE_RANK_ORDER_CHANGED = 14, - GE_FOUNDER = 15, - GE_SIGNED_ON = 16, - GE_SIGNED_OFF = 17, - GE_GUILDBANKBAGSLOTS_CHANGED = 18, - GE_BANK_TAB_PURCHASED = 19, - GE_BANK_TAB_UPDATED = 20, - GE_BANK_MONEY_UPDATED = 21, - GE_BANK_MONEY_WITHDRAWN = 22, - GE_BANK_TEXT_CHANGED = 23, + GE_PROMOTION = 1, + GE_DEMOTION = 2, + GE_MOTD = 3, + GE_JOINED = 4, + GE_LEFT = 5, + GE_REMOVED = 6, + GE_LEADER_IS = 7, + GE_LEADER_CHANGED = 8, + GE_DISBANDED = 9, + GE_TABARDCHANGE = 10, + GE_RANK_UPDATED = 11, + GE_RANK_CREATED = 12, + GE_RANK_DELETED = 13, + GE_RANK_ORDER_CHANGED = 14, + GE_FOUNDER = 15, + GE_SIGNED_ON = 16, + GE_SIGNED_OFF = 17, + GE_GUILDBANKBAGSLOTS_CHANGED = 18, + GE_BANK_TAB_PURCHASED = 19, + GE_BANK_TAB_UPDATED = 20, + GE_BANK_MONEY_SET = 21, + GE_BANK_MONEY_CHANGED = 22, + GE_BANK_TEXT_CHANGED = 23, // 24 - error 795 - GE_SIGNED_ON_MOBILE = 25, - GE_SIGNED_Off_MOBILE = 26, + GE_SIGNED_ON_MOBILE = 25, + GE_SIGNED_Off_MOBILE = 26, }; enum PetitionTurns @@ -176,12 +193,12 @@ enum PetitionSigns enum GuildBankRights { - GUILD_BANK_RIGHT_VIEW_TAB = 0x01, - GUILD_BANK_RIGHT_PUT_ITEM = 0x02, - GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04, + GUILD_BANK_RIGHT_VIEW_TAB = 0x01, + GUILD_BANK_RIGHT_PUT_ITEM = 0x02, + GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04, - GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM, - GUILD_BANK_RIGHT_FULL = 0xFF + GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM, + GUILD_BANK_RIGHT_FULL = 0xFF }; enum GuildBankEventLogTypes @@ -200,12 +217,12 @@ enum GuildBankEventLogTypes enum GuildEventLogTypes { - GUILD_EVENT_LOG_INVITE_PLAYER = 1, - GUILD_EVENT_LOG_JOIN_GUILD = 2, - GUILD_EVENT_LOG_PROMOTE_PLAYER = 3, - GUILD_EVENT_LOG_DEMOTE_PLAYER = 4, - GUILD_EVENT_LOG_UNINVITE_PLAYER = 5, - GUILD_EVENT_LOG_LEAVE_GUILD = 6 + GUILD_EVENT_LOG_INVITE_PLAYER = 1, + GUILD_EVENT_LOG_JOIN_GUILD = 2, + GUILD_EVENT_LOG_PROMOTE_PLAYER = 3, + GUILD_EVENT_LOG_DEMOTE_PLAYER = 4, + GUILD_EVENT_LOG_UNINVITE_PLAYER = 5, + GUILD_EVENT_LOG_LEAVE_GUILD = 6 }; enum GuildEmblemError @@ -220,22 +237,22 @@ enum GuildEmblemError enum GuildMemberFlags { - GUILDMEMBER_STATUS_NONE = 0x0000, - GUILDMEMBER_STATUS_ONLINE = 0x0001, - GUILDMEMBER_STATUS_AFK = 0x0002, - GUILDMEMBER_STATUS_DND = 0x0004, - GUILDMEMBER_STATUS_MOBILE = 0x0008, // remote chat from mobile app + GUILDMEMBER_STATUS_NONE = 0x0000, + GUILDMEMBER_STATUS_ONLINE = 0x0001, + GUILDMEMBER_STATUS_AFK = 0x0002, + GUILDMEMBER_STATUS_DND = 0x0004, + GUILDMEMBER_STATUS_MOBILE = 0x0008, // remote chat from mobile app }; enum GuildNews { - GUILD_NEWS_GUILD_ACHIEVEMENT = 0, - GUILD_NEWS_PLAYER_ACHIEVEMENT = 1, - GUILD_NEWS_DUNGEON_ENCOUNTER = 2, // @todo Implement - GUILD_NEWS_ITEM_LOOTED = 3, - GUILD_NEWS_ITEM_CRAFTED = 4, - GUILD_NEWS_ITEM_PURCHASED = 5, - GUILD_NEWS_LEVEL_UP = 6, + GUILD_NEWS_GUILD_ACHIEVEMENT = 0, + GUILD_NEWS_PLAYER_ACHIEVEMENT = 1, + GUILD_NEWS_DUNGEON_ENCOUNTER = 2, // @todo Implement + GUILD_NEWS_ITEM_LOOTED = 3, + GUILD_NEWS_ITEM_CRAFTED = 4, + GUILD_NEWS_ITEM_PURCHASED = 5, + GUILD_NEWS_LEVEL_UP = 6, }; struct GuildNewsEntry @@ -286,21 +303,33 @@ private: }; // Structure for storing guild bank rights and remaining slots together. -struct GuildBankRightsAndSlots +class GuildBankRightsAndSlots { - GuildBankRightsAndSlots() : rights(0), slots(0) { } - GuildBankRightsAndSlots(uint32 _rights, uint32 _slots) : rights(_rights), slots(_slots) { } +public: + GuildBankRightsAndSlots() : tabId(TAB_UNDEFINED), rights(0), slots(0) { } + GuildBankRightsAndSlots(uint8 _tabId) : tabId(_tabId), rights(0), slots(0) { } + GuildBankRightsAndSlots(uint8 _tabId, uint8 _rights, uint32 _slots) : tabId(_tabId), rights(_rights), slots(_slots) { } - inline bool IsEqual(GuildBankRightsAndSlots const& rhs) const { return rights == rhs.rights && slots == rhs.slots; } void SetGuildMasterValues() { rights = GUILD_BANK_RIGHT_FULL; slots = uint32(GUILD_WITHDRAW_SLOT_UNLIMITED); } - uint32 rights; + void SetTabId(uint8 _tabId) { tabId = _tabId; } + void SetSlots(uint32 _slots) { slots = _slots; } + void SetRights(uint8 _rights) { rights = _rights; } + + int8 GetTabId() const { return tabId; } + int32 GetSlots() const { return slots; } + int8 GetRights() const { return rights; } + +private: + uint8 tabId; + uint8 rights; uint32 slots; }; + typedef std::vector <GuildBankRightsAndSlots> GuildBankRightsAndSlotsVec; typedef std::set <uint8> SlotIds; @@ -311,16 +340,19 @@ private: // Class representing guild member class Member { - struct RemainingValue - { - RemainingValue() : value(0), resetTime(0) { } - - uint32 value; - uint32 resetTime; - }; - public: - Member(uint32 guildId, uint64 guid, uint32 rankId) : m_guildId(guildId), m_guid(guid), m_logoutTime(::time(NULL)), m_rankId(rankId) { } + Member(uint32 guildId, uint64 guid, uint8 rankId): + m_guildId(guildId), + m_guid(guid), + m_zoneId(0), + m_level(0), + m_class(0), + m_logoutTime(::time(NULL)), + m_accountId(0), + m_rankId(rankId) + { + memset(m_bankWithdraw, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(int32)); + } void SetStats(Player* player); void SetStats(std::string const& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId); @@ -328,6 +360,12 @@ private: void SetPublicNote(std::string const& publicNote); void SetOfficerNote(std::string const& officerNote); + void SetZoneId(uint32 id) { m_zoneId = id; } + void SetLevel(uint8 var) { m_level = var; } + + void AddFlag(uint8 var) { m_flags |= var; } + void RemFlag(uint8 var) { m_flags &= ~var; } + void ResetFlags() { m_flags = GUILDMEMBER_STATUS_NONE; } std::string GetPublicNote() { return m_publicNote; }; std::string GetOfficerNote() { return m_officerNote; }; @@ -338,11 +376,15 @@ private: uint64 GetGUID() const { return m_guid; } std::string const& GetName() const { return m_name; } uint32 GetAccountId() const { return m_accountId; } - uint32 GetRankId() const { return m_rankId; } + uint8 GetRankId() const { return m_rankId; } + uint64 GetLogoutTime() const { return m_logoutTime; } + std::string GetPublicNote() const { return m_publicNote; } + std::string GetOfficerNote() const { return m_officerNote; } uint8 GetClass() const { return m_class; } uint8 GetLevel() const { return m_level; } - uint8 GetZone() const { return m_zoneId; } - uint64 GetLogoutTime() const { return m_logoutTime; } + uint8 GetFlags() const { return m_flags; } + uint32 GetZoneId() const { return m_zoneId; } + bool IsOnline() { return (m_flags & GUILDMEMBER_STATUS_ONLINE); } void ChangeRank(uint8 newRank); @@ -351,11 +393,9 @@ private: inline bool IsRankNotLower(uint8 rankId) const { return m_rankId <= rankId; } inline bool IsSamePlayer(uint64 guid) const { return m_guid == guid; } - void DecreaseBankRemainingValue(SQLTransaction& trans, uint8 tabId, uint32 amount); - uint32 GetBankRemainingValue(uint8 tabId, const Guild* guild) const; - - void ResetTabTimes(); - void ResetMoneyTime(); + void UpdateBankWithdrawValue(SQLTransaction& trans, uint8 tabId, uint32 amount); + int32 GetBankWithdrawValue(uint8 tabId) const; + void ResetValues(bool week); inline Player* FindPlayer() const { return ObjectAccessor::FindPlayer(m_guid); } @@ -367,16 +407,17 @@ private: uint64 m_guid; std::string m_name; uint32 m_zoneId; - uint8 m_level; - uint8 m_class; + uint8 m_level; + uint8 m_class; + uint8 m_flags; uint64 m_logoutTime; uint32 m_accountId; // Fields from guild_member table - uint32 m_rankId; + uint8 m_rankId; std::string m_publicNote; std::string m_officerNote; - RemainingValue m_bankRemaining[GUILD_BANK_MAX_TABS + 1]; + int32 m_bankWithdraw[GUILD_BANK_MAX_TABS + 1]; }; // News Log class @@ -412,6 +453,7 @@ private: virtual ~LogEntry() { } uint32 GetGUID() const { return m_guid; } + uint64 GetTimestamp() const { return m_timestamp; } virtual void SaveToDB(SQLTransaction& trans) const = 0; virtual void WritePacket(WorldPacket& data, ByteBuffer& content) const = 0; @@ -485,6 +527,8 @@ private: }; // Class encapsulating work with events collection + typedef std::list<LogEntry*> GuildLog; + class LogHolder { public: @@ -503,7 +547,6 @@ private: uint32 GetNextGUID(); private: - typedef std::list<LogEntry*> GuildLog; GuildLog m_log; uint32 m_guildId; uint32 m_maxRecords; @@ -514,6 +557,7 @@ private: class RankInfo { public: + RankInfo(): m_guildId(0), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { } RankInfo(uint32 guildId) : m_guildId(guildId), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { } RankInfo(uint32 guildId, uint32 rankId, std::string const& name, uint32 rights, uint32 money) : m_guildId(guildId), m_rankId(rankId), m_name(name), m_rights(rights), m_bankMoneyPerDay(money) { } @@ -529,20 +573,22 @@ private: uint32 GetRights() const { return m_rights; } void SetRights(uint32 rights); - bool operator < (const RankInfo& rank) const { return m_rights > rank.GetRights(); } - bool operator == (const RankInfo& rank) const { return m_rights == rank.GetRights(); } + int32 GetBankMoneyPerDay() const { return m_bankMoneyPerDay; } - uint32 GetBankMoneyPerDay() const { return m_rankId == GR_GUILDMASTER ? GUILD_WITHDRAW_MONEY_UNLIMITED : m_bankMoneyPerDay; } void SetBankMoneyPerDay(uint32 money); - inline uint32 GetBankTabRights(uint8 tabId) const { return tabId < GUILD_BANK_MAX_TABS ? m_bankTabRightsAndSlots[tabId].rights : 0; } - inline uint32 GetBankTabSlotsPerDay(uint8 tabId) const + inline int8 GetBankTabRights(uint8 tabId) const + { + return tabId < GUILD_BANK_MAX_TABS ? m_bankTabRightsAndSlots[tabId].GetRights() : 0; + } + + inline int32 GetBankTabSlotsPerDay(uint8 tabId) const { - if (tabId < GUILD_BANK_MAX_TABS) - return m_rankId == GR_GUILDMASTER ? GUILD_WITHDRAW_SLOT_UNLIMITED : m_bankTabRightsAndSlots[tabId].slots; - return 0; + return tabId < GUILD_BANK_MAX_TABS ? m_bankTabRightsAndSlots[tabId].GetSlots() : 0; } - void SetBankTabSlotsAndRights(uint8 tabId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB); + + void SetBankTabSlotsAndRights(GuildBankRightsAndSlots rightsAndSlots, bool saveToDB); + bool CreateMissingTabsIfNeeded(uint8 ranks, SQLTransaction& trans); private: uint32 m_guildId; @@ -561,10 +607,18 @@ private: memset(m_items, 0, GUILD_BANK_MAX_SLOTS * sizeof(Item*)); } - bool LoadFromDB(Field* fields); + void LoadFromDB(Field* fields); bool LoadItemFromDB(Field* fields); void Delete(SQLTransaction& trans, bool removeItemsFromDB = false); + void WritePacket(WorldPacket& data) const; + bool WriteSlotPacket(WorldPacket& data, uint8 slotId, bool ignoreEmpty = true) const; + void WriteInfoPacket(WorldPacket& data) const + { + data << m_name; + data << m_icon; + } + void SetInfo(std::string const& name, std::string const& icon); void SetText(std::string const& text); void SendText(Guild const* guild, WorldSession* session) const; @@ -700,14 +754,13 @@ public: // Handle client commands void HandleRoster(WorldSession* session = NULL); // NULL = broadcast void HandleQuery(WorldSession* session); - void HandleGuildRanks(WorldSession* session) const; void HandleSetMOTD(WorldSession* session, std::string const& motd); void HandleSetInfo(WorldSession* session, std::string const& info); void HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo); void HandleSetLeader(WorldSession* session, std::string const& name); void HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string const& name, std::string const& icon); void HandleSetMemberNote(WorldSession* session, std::string const& note, uint64 guid, bool isPublic); - void HandleSetRankInfo(WorldSession* session, uint32 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec rightsAndSlots); + void HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec rightsAndSlots); void HandleBuyBankTab(WorldSession* session, uint8 tabId); void HandleInviteMember(WorldSession* session, std::string const& name); void HandleAcceptMember(WorldSession* session); @@ -716,23 +769,27 @@ public: void HandleUpdateMemberRank(WorldSession* session, uint64 targetGuid, bool demote); void HandleSetMemberRank(WorldSession* session, uint64 targetGuid, uint64 setterGuid, uint32 rank); void HandleAddNewRank(WorldSession* session, std::string const& name); - void HandleRemoveRank(WorldSession* session, uint32 rankId); - void HandleMemberDepositMoney(WorldSession* session, uint32 amount, bool cashFlow = false); - bool HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool repair = false); + void HandleRemoveRank(WorldSession* session, uint8 rankId); + void HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool cashFlow = false); + bool HandleMemberWithdrawMoney(WorldSession* session, uint64 amount, bool repair = false); void HandleMemberLogout(WorldSession* session); void HandleDisband(WorldSession* session); void HandleGuildPartyRequest(WorldSession* session); + void UpdateMemberData(Player* player, uint8 dataid, uint32 value); + void OnPlayerStatusChange(Player* player, uint32 flag, bool state); + // Send info to client + void SendGuildRankInfo(WorldSession* session) const; void SendEventLog(WorldSession* session) const; void SendBankLog(WorldSession* session, uint8 tabId) const; void SendBankList(WorldSession* session, uint8 tabId, bool withContent, bool withTabInfo) const; + void SendGuildReputationWeeklyCap(WorldSession* session) const; + void SendGuildXP(WorldSession* session) const; void SendBankTabText(WorldSession* session, uint8 tabId) const; void SendPermissions(WorldSession* session) const; void SendMoneyInfo(WorldSession* session) const; - void SendLoginInfo(WorldSession* session) const; - void SendGuildReputationWeeklyCap(WorldSession* session) const; - void SendGuildXP(WorldSession* session) const; + void SendLoginInfo(WorldSession* session); // Load from DB bool LoadFromDB(Field* fields); @@ -740,7 +797,7 @@ public: bool LoadMemberFromDB(Field* fields); bool LoadEventLogFromDB(Field* fields); void LoadBankRightFromDB(Field* fields); - bool LoadBankTabFromDB(Field* fields); + void LoadBankTabFromDB(Field* fields); bool LoadBankEventLogFromDB(Field* fields); bool LoadBankItemFromDB(Field* fields); bool Validate(); @@ -787,6 +844,7 @@ public: GuildNewsLog& GetNewsLog() { return _newsLog; } EmblemInfo const& GetEmblemInfo() const { return m_emblemInfo; } + void ResetTimes(bool week); protected: uint32 m_id; @@ -816,11 +874,18 @@ protected: uint64 _todayExperience; private: - inline uint32 _GetRanksSize() const { return uint32(m_ranks.size()); } - inline const RankInfo* GetRankInfo(uint32 rankId) const { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; } - inline RankInfo* GetRankInfo(uint32 rankId) { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; } - inline bool _HasRankRight(Player* player, uint32 right) const { return (_GetRankRights(player->GetRank()) & right) != GR_RIGHT_EMPTY; } - inline uint32 _GetLowestRankId() const { return uint32(m_ranks.size() - 1); } + inline uint8 _GetRanksSize() const { return uint8(m_ranks.size()); } + inline const RankInfo* GetRankInfo(uint8 rankId) const { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; } + inline RankInfo* GetRankInfo(uint8 rankId) { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; } + inline bool _HasRankRight(Player* player, uint32 right) const + { + if (player) + if (Member const* member = GetMember(player->GetGUID())) + return (_GetRankRights(member->GetRankId()) & right) != GR_RIGHT_EMPTY; + return false; + } + + inline uint8 _GetLowestRankId() const { return uint8(m_ranks.size() - 1); } inline uint8 _GetPurchasedTabsSize() const { return uint8(m_bankTabs.size()); } inline BankTab* GetBankTab(uint8 tabId) { return tabId < m_bankTabs.size() ? m_bankTabs[tabId] : NULL; } @@ -831,20 +896,22 @@ private: Members::const_iterator itr = m_members.find(GUID_LOPART(guid)); return itr != m_members.end() ? itr->second : NULL; } + inline Member* GetMember(uint64 guid) { Members::iterator itr = m_members.find(GUID_LOPART(guid)); return itr != m_members.end() ? itr->second : NULL; } - inline Member* GetMember(WorldSession* session, std::string const& name) + + inline Member* GetMember(std::string const& name) { for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (itr->second->GetName() == name) return itr->second; - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PLAYER_NOT_IN_GUILD_S, name); return NULL; } + inline void _DeleteMemberFromDB(uint32 lowguid) const { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBER); @@ -855,11 +922,11 @@ private: // Creates log holders (either when loading or when creating guild) void _CreateLogHolders(); // Tries to create new bank tab - bool _CreateNewBankTab(); + void _CreateNewBankTab(); // Creates default guild ranks with names in given locale void _CreateDefaultGuildRanks(LocaleConstant loc); // Creates new rank - void _CreateRank(std::string const& name, uint32 rights); + bool _CreateRank(std::string const& name, uint32 rights); // Update account number when member added/removed from guild void _UpdateAccountsNumber(); bool _IsLeader(Player* player) const; @@ -867,17 +934,17 @@ private: bool _ModifyBankMoney(SQLTransaction& trans, uint64 amount, bool add); void _SetLeaderGUID(Member* pLeader); - void _SetRankBankMoneyPerDay(uint32 rankId, uint32 moneyPerDay); - void _SetRankBankTabRightsAndSlots(uint32 rankId, uint8 tabId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB = true); - uint32 _GetRankBankTabRights(uint32 rankId, uint8 tabId) const; - uint32 _GetRankRights(uint32 rankId) const; - uint32 _GetRankBankMoneyPerDay(uint32 rankId) const; - uint32 _GetRankBankTabSlotsPerDay(uint32 rankId, uint8 tabId) const; - std::string _GetRankName(uint32 rankId) const; - - uint32 _GetMemberRemainingSlots(uint64 guid, uint8 tabId) const; - uint32 _GetMemberRemainingMoney(uint64 guid) const; - void _DecreaseMemberRemainingSlots(SQLTransaction& trans, uint64 guid, uint8 tabId); + void _SetRankBankMoneyPerDay(uint8 rankId, uint32 moneyPerDay); + void _SetRankBankTabRightsAndSlots(uint8 rankId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB = true); + int8 _GetRankBankTabRights(uint8 rankId, uint8 tabId) const; + uint32 _GetRankRights(uint8 rankId) const; + int32 _GetRankBankMoneyPerDay(uint8 rankId) const; + int32 _GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const; + std::string _GetRankName(uint8 rankId) const; + + int32 _GetMemberRemainingSlots(Member const* member, uint8 tabId) const; + int32 _GetMemberRemainingMoney(Member const* member) const; + void _UpdateMemberWithdrawSlots(SQLTransaction& trans, uint64 guid, uint8 tabId); bool _MemberHasTabRights(uint64 guid, uint8 tabId, uint32 rights) const; void _LogEvent(GuildEventLogTypes eventType, uint32 playerGuid1, uint32 playerGuid2 = 0, uint8 newRank = 0); @@ -890,6 +957,7 @@ private: void _SendBankContentUpdate(MoveItemData* pSrc, MoveItemData* pDest) const; void _SendBankContentUpdate(uint8 tabId, SlotIds slots) const; + void _SendBankList(WorldSession* session = NULL, uint8 tabId = 0, bool sendFullSlots = false, SlotIds *slots = NULL) const; void SendGuildRanksUpdate(uint64 setterGuid, uint64 targetGuid, uint32 rank); diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp index 0f421c7c432..38a5699510e 100644 --- a/src/server/game/Guilds/GuildMgr.cpp +++ b/src/server/game/Guilds/GuildMgr.cpp @@ -18,10 +18,8 @@ #include "Common.h" #include "GuildMgr.h" -GuildMgr::GuildMgr() -{ - NextGuildId = 1; -} +GuildMgr::GuildMgr() : NextGuildId(1) +{ } GuildMgr::~GuildMgr() { @@ -114,19 +112,6 @@ uint32 GuildMgr::GetXPForGuildLevel(uint8 level) const return 0; } -void GuildMgr::ResetExperienceCaps() -{ - CharacterDatabase.Execute(CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE)); - - for (GuildContainer::iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr) - itr->second->ResetDailyExperience(); -} - -void GuildMgr::ResetReputationCaps() -{ - /// @TODO: Implement -} - void GuildMgr::LoadGuilds() { // 1. Load all guilds @@ -158,6 +143,7 @@ void GuildMgr::LoadGuilds() delete guild; continue; } + AddGuild(guild); ++count; @@ -209,23 +195,18 @@ void GuildMgr::LoadGuilds() // Delete orphaned guild member entries before loading the valid ones CharacterDatabase.DirectExecute("DELETE gm FROM guild_member gm LEFT JOIN guild g ON gm.guildId = g.guildId WHERE g.guildId IS NULL"); + CharacterDatabase.DirectExecute("DELETE gm FROM guild_member_withdraw gm LEFT JOIN guild_member g ON gm.guid = g.guid WHERE g.guid IS NULL"); - // 0 1 2 3 4 5 6 - QueryResult result = CharacterDatabase.Query("SELECT gm.guildid, gm.guid, rank, pnote, offnote, BankResetTimeMoney, BankRemMoney, " - // 7 8 9 10 11 12 - "BankResetTimeTab0, BankRemSlotsTab0, BankResetTimeTab1, BankRemSlotsTab1, BankResetTimeTab2, BankRemSlotsTab2, " - // 13 14 15 16 17 18 - "BankResetTimeTab3, BankRemSlotsTab3, BankResetTimeTab4, BankRemSlotsTab4, BankResetTimeTab5, BankRemSlotsTab5, " - // 19 20 21 22 - "BankResetTimeTab6, BankRemSlotsTab6, BankResetTimeTab7, BankRemSlotsTab7, " - // 23 24 25 26 27 28 - "c.name, c.level, c.class, c.zone, c.account, c.logout_time " - "FROM guild_member gm LEFT JOIN characters c ON c.guid = gm.guid ORDER BY guildid ASC"); + // 0 1 2 3 4 5 6 7 8 9 10 + QueryResult result = CharacterDatabase.Query("SELECT guildid, gm.guid, rank, pnote, offnote, w.tab0, w.tab1, w.tab2, w.tab3, w.tab4, w.tab5, " + // 11 12 13 14 15 16 17 18 19 + "w.tab6, w.tab7, w.money, c.name, c.level, c.class, c.zone, c.account, c.logout_time " + "FROM guild_member gm " + "LEFT JOIN guild_member_withdraw w ON gm.guid = w.guid " + "LEFT JOIN characters c ON c.guid = gm.guid ORDER BY guildid ASC"); if (!result) - { sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 guild members. DB table `guild_member` is empty."); - } else { uint32 count = 0; @@ -254,7 +235,7 @@ void GuildMgr::LoadGuilds() // Delete orphaned guild bank right entries before loading the valid ones CharacterDatabase.DirectExecute("DELETE gbr FROM guild_bank_right gbr LEFT JOIN guild g ON gbr.guildId = g.guildId WHERE g.guildId IS NULL"); - // 0 1 2 3 4 + // 0 1 2 3 4 QueryResult result = CharacterDatabase.Query("SELECT guildid, TabId, rid, gbright, SlotPerDay FROM guild_bank_right ORDER BY guildid ASC, TabId ASC"); if (!result) @@ -448,18 +429,20 @@ void GuildMgr::LoadGuilds() sLog->outInfo(LOG_FILTER_GENERAL, "Validating data of loaded guilds..."); { uint32 oldMSTime = getMSTime(); + std::set<Guild*> rm; // temporary storage to avoid modifying GuildStore with RemoveGuild() while iterating for (GuildContainer::iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr) { Guild* guild = itr->second; - if (guild) - { - if (!guild->Validate()) - { - RemoveGuild(guild->GetId()); - delete guild; - } - } + if (guild && !guild->Validate()) + rm.insert(guild); + } + + for (std::set<Guild*>::iterator itr = rm.begin(); itr != rm.end(); ++itr) + { + Guild* guild = *itr; + RemoveGuild(guild->GetId()); + delete guild; } sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Validated data of loaded guilds in %u ms", GetMSTimeDiffToNow(oldMSTime)); @@ -565,3 +548,13 @@ void GuildMgr::LoadGuildRewards() sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u guild reward definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } + +void GuildMgr::ResetTimes(bool week) +{ + CharacterDatabase.Execute(CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE)); + CharacterDatabase.Execute(CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBER_WITHDRAW)); + + for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr) + if (Guild* guild = itr->second) + guild->ResetTimes(week); +} diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h index dea0fee8d8d..672b71143e3 100644 --- a/src/server/game/Guilds/GuildMgr.h +++ b/src/server/game/Guilds/GuildMgr.h @@ -23,13 +23,12 @@ class GuildMgr { friend class ACE_Singleton<GuildMgr, ACE_Null_Mutex>; + private: GuildMgr(); ~GuildMgr(); public: - typedef UNORDERED_MAP<uint32, Guild*> GuildContainer; - Guild* GetGuildByLeader(uint64 guid) const; Guild* GetGuildById(uint32 guildId) const; Guild* GetGuildByGuid(uint64 guid) const; @@ -45,7 +44,6 @@ public: void SaveGuilds(); - void ResetExperienceCaps(); void ResetReputationCaps(); uint32 GenerateGuildId(); @@ -54,7 +52,9 @@ public: uint32 GetXPForGuildLevel(uint8 level) const; std::vector<GuildReward> const& GetGuildRewards() const { return GuildRewards; } + void ResetTimes(bool week); protected: + typedef UNORDERED_MAP<uint32, Guild*> GuildContainer; uint32 NextGuildId; GuildContainer GuildStore; std::vector<uint64> GuildXPperLevel; diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index f9eeb52a09a..e2537d84149 100755 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -266,7 +266,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); } -void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket & /*recvData*/) +void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEGROUND_PLAYER_POSITIONS Message"); diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index c6a46d6d39b..a82496c1335 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -40,28 +40,6 @@ #include "ScriptMgr.h" #include "AccountMgr.h" -bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg, uint32 lang) -{ - if (lang != LANG_ADDON) - { - // strip invisible characters for non-addon messages - if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) - stripLineInvisibleChars(msg); - - if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && AccountMgr::IsPlayerAccount(GetSecurity()) - && !ChatHandler(this).isValidChatMessage(msg.c_str())) - { - sLog->outError(LOG_FILTER_NETWORKIO, "Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(), - GetPlayer()->GetGUIDLow(), msg.c_str()); - if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK)) - KickPlayer(); - return false; - } - } - - return true; -} - void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) { uint32 type = 0; @@ -159,22 +137,39 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } } +<<<<<<< HEAD if (lang == LANG_ADDON) { - if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) + // LANG_ADDON is only valid for the following message types + switch (type) { - std::string msg = ""; - recvData >> msg; + case CHAT_MSG_PARTY: + case CHAT_MSG_RAID: + case CHAT_MSG_GUILD: + case CHAT_MSG_BATTLEGROUND: + case CHAT_MSG_WHISPER: + if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) + { + std::string msg = ""; + recvData >> msg; - if (msg.empty()) - return; + if (msg.empty()) + return; - sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), lang, msg); - } + sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), lang, msg); + } - // Disabled addon channel? - if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL)) - return; + // Disabled addon channel? + if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL)) + return; + break; + default: + sLog->outError(LOG_FILTER_NETWORKIO, "Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination", + GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); + + recvData.rfinish(); + return; + } } // LANG_ADDON should not be changed nor be affected by flood control else @@ -229,8 +224,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER) { - recvData.rfinish(); SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); + recvData.rfinish(); return; } @@ -277,14 +272,26 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) if (msg.empty()) return; - if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) + if (ChatHandler(this).ParseCommands(msg.c_str())) return; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) - return; + if (lang != LANG_ADDON) + { + // Strip invisible characters for non-addon messages + if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); - if (msg.empty()) - return; + if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str())) + { + sLog->outError(LOG_FILTER_NETWORKIO, "Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(), + GetPlayer()->GetGUIDLow(), msg.c_str()); + + if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK)) + KickPlayer(); + + return; + } + } } switch (type) diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index d6f61b45ccf..e27118db6ac 100755 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -28,52 +28,32 @@ #include "GossipDef.h" #include "SocialMgr.h" -// Helper for getting guild object of session's player. -// If guild does not exist, sends error (if necessary). -inline Guild* _GetPlayerGuild(WorldSession* session, bool sendError = false) -{ - if (uint32 guildId = session->GetPlayer()->GetGuildId()) // If guild id = 0, player is not in guild - if (Guild* guild = sGuildMgr->GetGuildById(guildId)) // Find guild by id - return guild; - if (sendError) - Guild::SendCommandResult(session, GUILD_CREATE_S, ERR_GUILD_PLAYER_NOT_IN_GUILD); - return NULL; -} - void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_QUERY"); - uint64 guildGuid, playerGuid; recvPacket >> guildGuid >> playerGuid; - // If guild doesn't exist or player is not part of the guild send error + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_QUERY [%s]: Guild: " UI64FMTD " Target: ", + GetPlayerInfo().c_str(), guildGuid, playerGuid); + if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid)) if (guild->IsMember(playerGuid)) - { guild->HandleQuery(this); - return; - } - - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_PLAYER_NOT_IN_GUILD); } void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_INVITE"); - uint32 nameLength = recvPacket.ReadBits(7); std::string invitedName = recvPacket.ReadString(nameLength); + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_INVITE [%s]: Invited: %s", GetPlayerInfo().c_str(), invitedName.c_str()); if (normalizePlayerName(invitedName)) - if (Guild* guild = _GetPlayerGuild(this, true)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleInviteMember(this, invitedName); } void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_REMOVE"); - ObjectGuid playerGuid; playerGuid[6] = recvPacket.ReadBit(); @@ -94,23 +74,24 @@ void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket) recvPacket.ReadByteSeq(playerGuid[3]); recvPacket.ReadByteSeq(playerGuid[0]); - if (Guild* guild = _GetPlayerGuild(this, true)) + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_REMOVE [%s]: Target: " UI64FMTD, GetPlayerInfo().c_str(), playerGuid); + + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleRemoveMember(this, playerGuid); } void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_ACCEPT"); - // Player cannot be in guild + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_ACCEPT [%s]", GetPlayer()->GetName().c_str()); + if (!GetPlayer()->GetGuildId()) - // Guild where player was invited must exist if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildIdInvited())) guild->HandleAcceptMember(this); } void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_DECLINE"); + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_DECLINE [%s]", GetPlayerInfo().c_str()); GetPlayer()->SetGuildIdInvited(0); GetPlayer()->SetInGuild(0); @@ -118,18 +99,17 @@ void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/) void WorldSession::HandleGuildRosterOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_ROSTER"); - + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_ROSTER [%s]", GetPlayerInfo().c_str()); recvPacket.rfinish(); - if (Guild* guild = _GetPlayerGuild(this, true)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleRoster(this); + else + Guild::SendCommandResult(this, GUILD_COMMAND_ROSTER, ERR_GUILD_PLAYER_NOT_IN_GUILD); } void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_PROMOTE"); - ObjectGuid targetGuid; targetGuid[7] = recvPacket.ReadBit(); @@ -150,14 +130,14 @@ void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket) recvPacket.ReadByteSeq(targetGuid[1]); recvPacket.ReadByteSeq(targetGuid[7]); - if (Guild* guild = _GetPlayerGuild(this, true)) + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_PROMOTE [%s]: Target: " UI64FMTD, GetPlayerInfo().c_str(), targetGuid); + + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleUpdateMemberRank(this, targetGuid, false); } void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_DEMOTE"); - ObjectGuid targetGuid; targetGuid[7] = recvPacket.ReadBit(); @@ -178,14 +158,14 @@ void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket) recvPacket.ReadByteSeq(targetGuid[4]); recvPacket.ReadByteSeq(targetGuid[3]); - if (Guild* guild = _GetPlayerGuild(this, true)) + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_DEMOTE [%s]: Target: " UI64FMTD, GetPlayerInfo().c_str(), targetGuid); + + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleUpdateMemberRank(this, targetGuid, true); } void WorldSession::HandleGuildAssignRankOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_ASSIGN_MEMBER_RANK"); - ObjectGuid targetGuid; ObjectGuid setterGuid; @@ -226,53 +206,53 @@ void WorldSession::HandleGuildAssignRankOpcode(WorldPacket& recvPacket) recvPacket.ReadByteSeq(targetGuid[6]); recvPacket.ReadByteSeq(setterGuid[7]); - if (Guild* guild = _GetPlayerGuild(this, true)) + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_ASSIGN_MEMBER_RANK [%s]: Target: " UI64FMTD " Rank: %u, Issuer " UI64FMTD, + GetPlayerInfo().c_str(), targetGuid, rankId, setterGuid); + + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleSetMemberRank(this, targetGuid, setterGuid, rankId); } void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_LEAVE"); + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_LEAVE [%s]", GetPlayerInfo().c_str()); - if (Guild* guild = _GetPlayerGuild(this, true)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleLeaveMember(this); } void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_DISBAND"); + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_DISBAND [%s]", GetPlayerInfo().c_str()); - if (Guild* guild = _GetPlayerGuild(this, true)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleDisband(this); } void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_LEADER"); - std::string name; recvPacket >> name; + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_LEADER [%s]: Target: %s", GetPlayerInfo().c_str(), name.c_str()); + if (normalizePlayerName(name)) - if (Guild* guild = _GetPlayerGuild(this, true)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleSetLeader(this, name); } void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_MOTD"); - uint32 motdLength = recvPacket.ReadBits(11); std::string motd = recvPacket.ReadString(motdLength); + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_MOTD [%s]: MOTD: %s", GetPlayerInfo().c_str(), motd.c_str()); - if (Guild* guild = _GetPlayerGuild(this, true)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleSetMOTD(this, motd); } void WorldSession::HandleGuildSetNoteOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_SET_NOTE"); - ObjectGuid playerGuid; playerGuid[1] = recvPacket.ReadBit(); @@ -296,14 +276,15 @@ void WorldSession::HandleGuildSetNoteOpcode(WorldPacket& recvPacket) std::string note = recvPacket.ReadString(noteLength); recvPacket.ReadByteSeq(playerGuid[2]); - if (Guild* guild = _GetPlayerGuild(this, true)) + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_SET_NOTE [%s]: Target: " UI64FMTD ", Note: %s, Public: %u", + GetPlayerInfo().c_str(), playerGuid, note.c_str(), type); + + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleSetMemberNote(this, note, playerGuid, type); } void WorldSession::HandleGuildQueryRanksOpcode(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_QUERY_RANKS"); - ObjectGuid guildGuid; guildGuid[2] = recvData.ReadBit(); @@ -324,175 +305,171 @@ void WorldSession::HandleGuildQueryRanksOpcode(WorldPacket& recvData) recvData.ReadByteSeq(guildGuid[6]); recvData.ReadByteSeq(guildGuid[2]); + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_QUERY_RANKS [%s]: Guild: " UI64FMTD, + GetPlayerInfo().c_str(), guildGuid); + if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid)) if (guild->IsMember(_player->GetGUID())) - guild->HandleGuildRanks(this); + guild->SendGuildRankInfo(this); } void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_ADD_RANK"); - uint32 rankId; recvPacket >> rankId; uint32 length = recvPacket.ReadBits(7); std::string rankName = recvPacket.ReadString(length); - if (Guild* guild = _GetPlayerGuild(this, true)) - guild->HandleAddNewRank(this, rankName); //, rankId); + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_ADD_RANK [%s]: Rank: %s", GetPlayerInfo().c_str(), rankName.c_str()); + + if (Guild* guild = GetPlayer()->GetGuild()) + guild->HandleAddNewRank(this, rankName); } void WorldSession::HandleGuildDelRankOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_DEL_RANK"); - uint32 rankId; recvPacket >> rankId; - if (Guild* guild = _GetPlayerGuild(this, true)) + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_DEL_RANK [%s]: Rank: %u", GetPlayerInfo().c_str(), rankId); + + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleRemoveRank(this, rankId); } void WorldSession::HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_INFO_TEXT"); - uint32 length = recvPacket.ReadBits(12); std::string info = recvPacket.ReadString(length); - if (Guild* guild = _GetPlayerGuild(this, true)) + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_INFO_TEXT [%s]: %s", GetPlayerInfo().c_str(), info.c_str()); + + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleSetInfo(this, info); } void WorldSession::HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_SAVE_GUILD_EMBLEM"); - uint64 vendorGuid; recvPacket >> vendorGuid; EmblemInfo emblemInfo; emblemInfo.ReadPacket(recvPacket); + sLog->outDebug(LOG_FILTER_GUILD, "MSG_SAVE_GUILD_EMBLEM [%s]: Guid: [" UI64FMTD + "] Style: %d, Color: %d, BorderStyle: %d, BorderColor: %d, BackgroundColor: %d" + , GetPlayerInfo().c_str(), vendorGuid, emblemInfo.GetStyle() + , emblemInfo.GetColor(), emblemInfo.GetBorderStyle() + , emblemInfo.GetBorderColor(), emblemInfo.GetBackgroundColor()); + if (GetPlayer()->GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_TABARDDESIGNER)) { // Remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - if (Guild* guild = _GetPlayerGuild(this)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleSetEmblem(this, emblemInfo); else - // "You are not part of a guild!"; - Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_NOGUILD); + Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_NOGUILD); // "You are not part of a guild!"; } else - { - // "That's not an emblem vendor!" - Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_INVALIDVENDOR); - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleSaveGuildEmblemOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(vendorGuid)); - } + Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_INVALIDVENDOR); // "That's not an emblem vendor!" } void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_EVENT_LOG_QUERY)"); + sLog->outDebug(LOG_FILTER_GUILD, "MSG_GUILD_EVENT_LOG_QUERY [%s]", GetPlayerInfo().c_str()); - if (Guild* guild = _GetPlayerGuild(this)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->SendEventLog(this); } void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPacket & /* recvData */) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_MONEY_WITHDRAWN_QUERY)"); + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_BANK_MONEY_WITHDRAWN [%s]", GetPlayerInfo().c_str()); - if (Guild* guild = _GetPlayerGuild(this)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->SendMoneyInfo(this); } void WorldSession::HandleGuildPermissions(WorldPacket& /* recvData */) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_PERMISSIONS)"); + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_PERMISSIONS [%s]", GetPlayerInfo().c_str()); - if (Guild* guild = _GetPlayerGuild(this)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->SendPermissions(this); } // Called when clicking on Guild bank gameobject void WorldSession::HandleGuildBankerActivate(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANKER_ACTIVATE)"); + uint64 guid; + bool sendAllSlots; + recvData >> guid >> sendAllSlots; - uint64 GoGuid; - recvData >> GoGuid; + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_BANKER_ACTIVATE [%s]: Go: [" UI64FMTD "] AllSlots: %u" + , GetPlayerInfo().c_str(), guid, sendAllSlots); - uint8 fullSlotList; - recvData >> fullSlotList; // 0 = only slots updated in last operation are shown. 1 = all slots updated - - if (GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) + if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK)) { - if (Guild* guild = _GetPlayerGuild(this)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->SendBankList(this, 0, true, true); else - Guild::SendCommandResult(this, GUILD_UNK1, ERR_GUILD_PLAYER_NOT_IN_GUILD); + Guild::SendCommandResult(this, GUILD_COMMAND_VIEW_TAB, ERR_GUILD_PLAYER_NOT_IN_GUILD); } } // Called when opening guild bank tab only (first one) -void WorldSession::HandleGuildBankQueryTab(WorldPacket & recvData) +void WorldSession::HandleGuildBankQueryTab(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_QUERY_TAB)"); - - uint64 GoGuid; - recvData >> GoGuid; - + uint64 guid; uint8 tabId; - recvData >> tabId; + bool full; - uint8 fullSlotList; - recvData >> fullSlotList; // 0 = only slots updated in last operation are shown. 1 = all slots updated + recvData >> guid >> tabId >> full; - if (GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) - if (Guild* guild = _GetPlayerGuild(this)) + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_BANK_QUERY_TAB [%s]: Go: [" UI64FMTD "], TabId: %u, ShowTabs: %u" + , GetPlayerInfo().c_str(), guid, tabId, full); + + if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->SendBankList(this, tabId, true, false); } -void WorldSession::HandleGuildBankDepositMoney(WorldPacket & recvData) +void WorldSession::HandleGuildBankDepositMoney(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_DEPOSIT_MONEY)"); - - uint64 goGuid; - recvData >> goGuid; - + uint64 guid; uint64 money; - recvData >> money; + recvData >> guid >> money; - if (GetPlayer()->GetGameObjectIfCanInteractWith(goGuid, GAMEOBJECT_TYPE_GUILD_BANK)) + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_BANK_DEPOSIT_MONEY [%s]: Go: [" UI64FMTD "], money: " UI64FMTD, + GetPlayerInfo().c_str(), guid, money); + + if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK)) if (money && GetPlayer()->HasEnoughMoney(money)) - if (Guild* guild = _GetPlayerGuild(this)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleMemberDepositMoney(this, money); } -void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket & recvData) +void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_WITHDRAW_MONEY)"); - - uint64 GoGuid; - recvData >> GoGuid; - + uint64 guid; uint64 money; - recvData >> money; + recvData >> guid >> money; + + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_BANK_WITHDRAW_MONEY [%s]: Go: [" UI64FMTD "], money: " UI64FMTD, + GetPlayerInfo().c_str(), guid, money); - if (money) - if (GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) - if (Guild* guild = _GetPlayerGuild(this)) - guild->HandleMemberWithdrawMoney(this, money); + if (money && GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK)) + if (Guild* guild = GetPlayer()->GetGuild()) + guild->HandleMemberWithdrawMoney(this, money); } -void WorldSession::HandleGuildBankSwapItems(WorldPacket & recvData) +void WorldSession::HandleGuildBankSwapItems(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_SWAP_ITEMS)"); + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_BANK_SWAP_ITEMS [%s]", GetPlayerInfo().c_str()); uint64 GoGuid; recvData >> GoGuid; @@ -503,7 +480,7 @@ void WorldSession::HandleGuildBankSwapItems(WorldPacket & recvData) return; } - Guild* guild = _GetPlayerGuild(this); + Guild* guild = GetPlayer()->GetGuild(); if (!guild) { recvData.rfinish(); // Prevent additional spam at rejected packet @@ -572,76 +549,70 @@ void WorldSession::HandleGuildBankSwapItems(WorldPacket & recvData) } } -void WorldSession::HandleGuildBankBuyTab(WorldPacket & recvData) +void WorldSession::HandleGuildBankBuyTab(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_BUY_TAB)"); - - uint64 GoGuid; - recvData >> GoGuid; + uint64 guid; + recvData >> guid; uint8 tabId; recvData >> tabId; - if (!GoGuid || GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) - if (Guild* guild = _GetPlayerGuild(this)) + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_BANK_BUY_TAB [%s]: Go: [" UI64FMTD "], TabId: %u", GetPlayerInfo().c_str(), guid, tabId); + + if (!guid || GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleBuyBankTab(this, tabId); } -void WorldSession::HandleGuildBankUpdateTab(WorldPacket & recvData) +void WorldSession::HandleGuildBankUpdateTab(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_UPDATE_TAB)"); - - uint64 GoGuid; - recvData >> GoGuid; - + uint64 guid; uint8 tabId; - recvData >> tabId; + std::string name, icon; - std::string name; - recvData >> name; - - std::string icon; - recvData >> icon; + recvData >> guid >> tabId >> name >> icon; + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_GUILD_BANK_UPDATE_TAB [%s]: Go: [" UI64FMTD "], TabId: %u, Name: %s, Icon: %s" + , GetPlayerInfo().c_str(), guid, tabId, name.c_str(), icon.c_str()); if (!name.empty() && !icon.empty()) - if (GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) - if (Guild* guild = _GetPlayerGuild(this)) + if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK)) + if (Guild* guild = GetPlayer()->GetGuild()) guild->HandleSetBankTabInfo(this, tabId, name, icon); } -void WorldSession::HandleGuildBankLogQuery(WorldPacket & recvData) +void WorldSession::HandleGuildBankLogQuery(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (MSG_GUILD_BANK_LOG_QUERY)"); - uint32 tabId; recvData >> tabId; - if (Guild* guild = _GetPlayerGuild(this)) + sLog->outDebug(LOG_FILTER_GUILD, "MSG_GUILD_BANK_LOG_QUERY [%s]: TabId: %u", GetPlayerInfo().c_str(), tabId); + + if (Guild* guild = GetPlayer()->GetGuild()) guild->SendBankLog(this, tabId); } void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_BANK_QUERY_TEXT"); - uint8 tabId; recvData >> tabId; - if (Guild* guild = _GetPlayerGuild(this)) + sLog->outDebug(LOG_FILTER_GUILD, "MSG_QUERY_GUILD_BANK_TEXT [%s]: TabId: %u", GetPlayerInfo().c_str(), tabId); + + if (Guild* guild = GetPlayer()->GetGuild()) guild->SendBankTabText(this, tabId); } void WorldSession::HandleSetGuildBankTabText(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_SET_GUILD_BANK_TEXT"); - uint32 tabId; recvData >> tabId; uint32 textLen = recvData.ReadBits(14); std::string text = recvData.ReadString(textLen); - if (Guild* guild = _GetPlayerGuild(this)) + sLog->outDebug(LOG_FILTER_GUILD, "CMSG_SET_GUILD_BANK_TEXT [%s]: TabId: %u, Text: %s", GetPlayerInfo().c_str(), tabId, text.c_str()); + + if (Guild* guild = GetPlayer()->GetGuild()) guild->SetBankTabText(tabId, text); } @@ -678,7 +649,7 @@ void WorldSession::HandleGuildSetRankPermissionsOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_SET_RANK_PERMISSIONS"); - Guild* guild = _GetPlayerGuild(this, true); + Guild* guild = GetPlayer()->GetGuild(); if (!guild) { recvPacket.rfinish(); @@ -704,7 +675,7 @@ void WorldSession::HandleGuildSetRankPermissionsOpcode(WorldPacket& recvPacket) recvPacket >> bankRights; recvPacket >> slots; - rightsAndSlots[tabId] = GuildBankRightsAndSlots(uint8(bankRights), slots); + rightsAndSlots[tabId] = GuildBankRightsAndSlots(tabId, uint8(bankRights), slots); } recvPacket >> moneyPerDay; diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 995a2e9e42f..83f9f62ee3d 100755 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -267,10 +267,10 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData* SendPacket(&data); } -void WorldSession::HandleLfrJoinOpcode(WorldPacket& recv_data) +void WorldSession::HandleLfrJoinOpcode(WorldPacket& recvData) { uint32 entry; // Raid id to search - recv_data >> entry; + recvData >> entry; sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_LFR_JOIN [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), entry); //SendLfrUpdateListOpcode(entry); } @@ -620,7 +620,7 @@ void WorldSession::SendLfgTeleportError(uint8 err) SendPacket(&data); } -void WorldSession::HandleLfgGetStatus(WorldPacket& /*recv_data*/) +void WorldSession::HandleLfgGetStatus(WorldPacket& /*recvData*/) { uint64 guid = GetPlayer()->GetGUID(); sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_GET_STATUS [" UI64FMTD "]", guid); diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 69100f74d81..09f13401918 100755 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -33,12 +33,6 @@ #define CHARTER_DISPLAY_ID 16161 -/*enum PetitionType // dbc data -{ - PETITION_TYPE_GUILD = 1, - PETITION_TYPE_ARENA_TEAM = 3 -};*/ - // Charters ID in item_template enum CharterItemIDs { @@ -157,12 +151,13 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recvData) { if (sGuildMgr->GetGuildByName(name)) { - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, name); + Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, name); return; } + if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name)) { - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_INVALID, name); + Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_INVALID, name); return; } } @@ -355,8 +350,9 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) data << uint8(0); // some string if (type == GUILD_CHARTER_TYPE) { - data << uint32(4); - data << uint32(4); + uint32 needed = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS); + data << uint32(needed); + data << uint32(needed); data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition } else @@ -379,10 +375,7 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) data << uint32(0); // 14 - if (type == GUILD_CHARTER_TYPE) - data << uint32(0); // 15 0 - guild, 1 - arena team - else - data << uint32(1); + data << uint32(type != GUILD_CHARTER_TYPE); // 15 0 - guild, 1 - arena team SendPacket(&data); } @@ -423,12 +416,12 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recvData) { if (sGuildMgr->GetGuildByName(newName)) { - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, newName); + Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, newName); return; } if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName)) { - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_INVALID, newName); + Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_INVALID, newName); return; } } @@ -498,7 +491,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recvData) if (type != GUILD_CHARTER_TYPE) SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); else - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NOT_ALLIED); + Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED); return; } @@ -530,12 +523,12 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recvData) { if (_player->GetGuildId()) { - Guild::SendCommandResult(this, GUILD_INVITE_S, ERR_ALREADY_IN_GUILD_S, _player->GetName().c_str()); + Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName()); return; } if (_player->GetGuildIdInvited()) { - Guild::SendCommandResult(this, GUILD_INVITE_S, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName().c_str()); + Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName()); return; } } @@ -658,7 +651,7 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recvData) if (type != GUILD_CHARTER_TYPE) SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); else - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NOT_ALLIED); + Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED); return; } @@ -692,13 +685,13 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recvData) { if (player->GetGuildId()) { - Guild::SendCommandResult(this, GUILD_INVITE_S, ERR_ALREADY_IN_GUILD_S, _player->GetName().c_str()); + Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName()); return; } if (player->GetGuildIdInvited()) { - Guild::SendCommandResult(this, GUILD_INVITE_S, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName().c_str()); + Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName()); return; } } @@ -790,7 +783,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recvData) // Check if guild name is already taken if (sGuildMgr->GetGuildByName(name)) { - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, name); + Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, name); return; } } @@ -862,6 +855,8 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recvData) // Register guild and add guild master sGuildMgr->AddGuild(guild); + Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_COMMAND_SUCCESS, name); + // Add members from signatures for (uint8 i = 0; i < signatures; ++i) { @@ -950,7 +945,7 @@ void WorldSession::SendPetitionShowList(uint64 guid) data << uint32(CHARTER_DISPLAY_ID); // charter display id data << uint32(GUILD_CHARTER_COST); // charter cost data << uint32(0); // unknown - data << uint32(4); // required signs? + data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // required signs } else { diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 4df6fe2f9d3..abe55b9c1a7 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -19,6 +19,7 @@ #include "MoveSpline.h" #include <sstream> #include "Log.h" +#include "Unit.h" namespace Movement{ @@ -202,12 +203,12 @@ MoveSpline::MoveSpline() : m_Id(0), time_passed(0), /// ============================================================================================ -bool MoveSplineInitArgs::Validate() const +bool MoveSplineInitArgs::Validate(Unit* unit) const { #define CHECK(exp) \ if (!(exp))\ {\ - sLog->outError(LOG_FILTER_GENERAL, "MoveSplineInitArgs::Validate: expression '%s' failed", #exp);\ + sLog->outError(LOG_FILTER_GENERAL, "MoveSplineInitArgs::Validate: expression '%s' failed for GUID: %u", #exp, unit->GetTypeId() == TYPEID_PLAYER ? unit->GetGUIDLow() : unit->ToCreature()->GetDBTableGUIDLow());\ return false;\ } CHECK(path.size() > 1); diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 1fbb8787efe..fd20d041b4b 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -96,7 +96,7 @@ namespace Movement if (!args.HasVelocity) args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); - if (!args.Validate()) + if (!args.Validate(&unit)) return; if (moveFlags & MOVEMENTFLAG_ROOT) diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h index de02b35d0a0..32045629c9f 100644 --- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h +++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h @@ -22,6 +22,8 @@ #include "MoveSplineFlag.h" #include <G3D/Vector3.h> +class Unit; + namespace Movement { typedef std::vector<Vector3> PointsArray; @@ -61,7 +63,7 @@ namespace Movement bool TransformForTransport; /** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */ - bool Validate() const; + bool Validate(Unit* unit) const; private: bool _checkPathBounds() const; }; diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index e3f550c5f48..6c8d651a5a0 100755 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -1357,12 +1357,12 @@ void ScriptMgr::OnGuildDisband(Guild* guild) FOREACH_SCRIPT(GuildScript)->OnDisband(guild); } -void ScriptMgr::OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint32 &amount, bool isRepair) +void ScriptMgr::OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint64 &amount, bool isRepair) { FOREACH_SCRIPT(GuildScript)->OnMemberWitdrawMoney(guild, player, amount, isRepair); } -void ScriptMgr::OnGuildMemberDepositMoney(Guild* guild, Player* player, uint32 &amount) +void ScriptMgr::OnGuildMemberDepositMoney(Guild* guild, Player* player, uint64 &amount) { FOREACH_SCRIPT(GuildScript)->OnMemberDepositMoney(guild, player, amount); } diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 0dc357c366d..80439b4e556 100755 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -768,10 +768,10 @@ class GuildScript : public ScriptObject virtual void OnDisband(Guild* /*guild*/) { } // Called when a guild member withdraws money from a guild bank. - virtual void OnMemberWitdrawMoney(Guild* /*guild*/, Player* /*player*/, uint32& /*amount*/, bool /*isRepair*/) { } + virtual void OnMemberWitdrawMoney(Guild* /*guild*/, Player* /*player*/, uint64& /*amount*/, bool /*isRepair*/) { } // Called when a guild member deposits money in a guild bank. - virtual void OnMemberDepositMoney(Guild* /*guild*/, Player* /*player*/, uint32& /*amount*/) { } + virtual void OnMemberDepositMoney(Guild* /*guild*/, Player* /*player*/, uint64& /*amount*/) { } // Called when a guild member moves an item in a guild bank. virtual void OnItemMove(Guild* /*guild*/, Player* /*player*/, Item* /*pItem*/, bool /*isSrcBank*/, uint8 /*srcContainer*/, uint8 /*srcSlotId*/, @@ -1019,8 +1019,8 @@ class ScriptMgr void OnGuildInfoChanged(Guild* guild, const std::string& newInfo); void OnGuildCreate(Guild* guild, Player* leader, const std::string& name); void OnGuildDisband(Guild* guild); - void OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint32 &amount, bool isRepair); - void OnGuildMemberDepositMoney(Guild* guild, Player* player, uint32 &amount); + void OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint64 &amount, bool isRepair); + void OnGuildMemberDepositMoney(Guild* guild, Player* player, uint64 &amount); void OnGuildItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId, bool isDestBank, uint8 destContainer, uint8 destSlotId); void OnGuildEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 464b7ee215c..31c78b5662a 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -429,7 +429,6 @@ class WorldSession void HandleReorderCharacters(WorldPacket& recvData); void HandleOpeningCinematic(WorldPacket& recvData); - // played time void HandlePlayedTime(WorldPacket& recvPacket); @@ -728,7 +727,6 @@ class WorldSession void HandlePushQuestToParty(WorldPacket& recvPacket); void HandleQuestPushResult(WorldPacket& recvPacket); - bool processChatmessageFurtherAfterSecurityChecks(std::string&, uint32); void HandleMessagechatOpcode(WorldPacket& recvPacket); void HandleAddonMessagechatOpcode(WorldPacket& recvPacket); void SendPlayerNotFoundNotice(std::string const& name); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 054ca15fd25..75f5dd1c807 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -976,6 +976,13 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_RANDOM_BG_RESET_HOUR] = 6; } + m_int_configs[CONFIG_GUILD_RESET_HOUR] = ConfigMgr::GetIntDefault("Guild.ResetHour", 6); + if (m_int_configs[CONFIG_GUILD_RESET_HOUR] > 23) + { + sLog->outError(LOG_FILTER_GENERAL, "Guild.ResetHour (%i) can't be load. Set to 6.", m_int_configs[CONFIG_GUILD_RESET_HOUR]); + m_int_configs[CONFIG_GUILD_RESET_HOUR] = 6; + } + m_bool_configs[CONFIG_DETECT_POS_COLLISION] = ConfigMgr::GetBoolDefault("DetectPosCollision", true); m_bool_configs[CONFIG_RESTRICTED_LFG_CHANNEL] = ConfigMgr::GetBoolDefault("Channel.RestrictedLfg", true); @@ -1781,6 +1788,9 @@ void World::SetInitialWorldSettings() sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Calculate random battleground reset time..."); InitRandomBGResetTime(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Calculate Guild cap reset time..."); + InitGuildResetTime(); + LoadCharacterNameData(); sLog->outInfo(LOG_FILTER_GENERAL, "Initializing Opcodes..."); @@ -1933,18 +1943,17 @@ void World::Update(uint32 diff) { ResetDailyQuests(); m_NextDailyQuestReset += DAY; - sGuildMgr->ResetExperienceCaps(); } if (m_gameTime > m_NextWeeklyQuestReset) - { ResetWeeklyQuests(); - sGuildMgr->ResetReputationCaps(); - } if (m_gameTime > m_NextRandomBGReset) ResetRandomBG(); + if (m_gameTime > m_NextGuildReset) + ResetGuildCap(); + /// <ul><li> Handle auctions when the timer has passed if (m_timers[WUPDATE_AUCTIONS].Passed()) { @@ -2765,6 +2774,33 @@ void World::InitRandomBGResetTime() sWorld->setWorldState(WS_BG_DAILY_RESET_TIME, uint64(m_NextRandomBGReset)); } +void World::InitGuildResetTime() +{ + time_t gtime = uint64(getWorldState(WS_GUILD_DAILY_RESET_TIME)); + if (!gtime) + m_NextGuildReset = time_t(time(NULL)); // game time not yet init + + // generate time by config + time_t curTime = time(NULL); + tm localTm = *localtime(&curTime); + localTm.tm_hour = getIntConfig(CONFIG_GUILD_RESET_HOUR); + localTm.tm_min = 0; + localTm.tm_sec = 0; + + // current day reset time + time_t nextDayResetTime = mktime(&localTm); + + // next reset time before current moment + if (curTime >= nextDayResetTime) + nextDayResetTime += DAY; + + // normalize reset time + m_NextGuildReset = gtime < curTime ? nextDayResetTime - DAY : nextDayResetTime; + + if (!gtime) + sWorld->setWorldState(WS_GUILD_DAILY_RESET_TIME, uint64(m_NextGuildReset)); +} + void World::ResetDailyQuests() { sLog->outInfo(LOG_FILTER_GENERAL, "Daily quests reset for all characters."); @@ -2841,6 +2877,18 @@ void World::ResetRandomBG() sWorld->setWorldState(WS_BG_DAILY_RESET_TIME, uint64(m_NextRandomBGReset)); } +void World::ResetGuildCap() +{ + m_NextGuildReset = time_t(m_NextGuildReset + DAY); + sWorld->setWorldState(WS_GUILD_DAILY_RESET_TIME, uint64(m_NextGuildReset)); + uint32 week = getWorldState(WS_GUILD_WEEKLY_RESET_TIME); + week = week < 7 ? week + 1 : 1; + + sLog->outInfo(LOG_FILTER_GENERAL, "Guild Daily Cap reset. Week: %u", week == 1); + sWorld->setWorldState(WS_GUILD_WEEKLY_RESET_TIME, week); + sGuildMgr->ResetTimes(week == 1); +} + void World::UpdateMaxSessionCounters() { m_maxActiveSessionCount = std::max(m_maxActiveSessionCount, uint32(m_sessions.size()-m_QueuedPlayer.size())); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index cc97742e25d..1f90c169fa6 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -312,6 +312,7 @@ enum WorldIntConfigs CONFIG_GUILD_BANK_EVENT_LOG_COUNT, CONFIG_MIN_LEVEL_STAT_SAVE, CONFIG_RANDOM_BG_RESET_HOUR, + CONFIG_GUILD_RESET_HOUR, CONFIG_CHARDELETE_KEEP_DAYS, CONFIG_CHARDELETE_METHOD, CONFIG_CHARDELETE_MIN_LEVEL, @@ -483,8 +484,10 @@ enum RealmZone enum WorldStates { - WS_WEEKLY_QUEST_RESET_TIME = 20002, // Next weekly reset time - WS_BG_DAILY_RESET_TIME = 20003 // Next daily BG reset time + WS_WEEKLY_QUEST_RESET_TIME = 20002, // Next weekly reset time + WS_BG_DAILY_RESET_TIME = 20003, // Next daily BG reset time + WS_GUILD_DAILY_RESET_TIME = 20006, // Next guild cap reset time + WS_GUILD_WEEKLY_RESET_TIME = 20007, // Next guild week reset time }; // DB scripting commands @@ -794,9 +797,11 @@ class World void InitDailyQuestResetTime(); void InitWeeklyQuestResetTime(); void InitRandomBGResetTime(); + void InitGuildResetTime(); void ResetDailyQuests(); void ResetWeeklyQuests(); void ResetRandomBG(); + void ResetGuildCap(); private: static ACE_Atomic_Op<ACE_Thread_Mutex, bool> m_stopEvent; static uint8 m_ExitCode; @@ -857,6 +862,7 @@ class World time_t m_NextDailyQuestReset; time_t m_NextWeeklyQuestReset; time_t m_NextRandomBGReset; + time_t m_NextGuildReset; //Player Queue Queue m_QueuedPlayer; diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index c451af2ebd5..96a282d9c85 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -169,10 +169,9 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_INS_GUILD_BANK_ITEM, "INSERT INTO guild_bank_item (guildid, TabId, SlotId, item_guid) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_GUILD_BANK_ITEM, "DELETE FROM guild_bank_item WHERE guildid = ? AND TabId = ? AND SlotId = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8, 2: uint8 PREPARE_STATEMENT(CHAR_DEL_GUILD_BANK_ITEMS, "DELETE FROM guild_bank_item WHERE guildid = ?", CONNECTION_ASYNC) // 0: uint32 - PREPARE_STATEMENT(CHAR_INS_GUILD_BANK_RIGHT_DEFAULT, "INSERT INTO guild_bank_right (guildid, TabId, rid) VALUES (?, ?, ?)", CONNECTION_ASYNC) // 0: uint32, 1: uint8, 2: uint8 // 0: uint32, 1: uint8, 2: uint8, 3: uint8, 4: uint32 - PREPARE_STATEMENT(CHAR_INS_GUILD_BANK_RIGHT, "INSERT INTO guild_bank_right (guildid, TabId, rid, gbright, SlotPerDay) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_DEL_GUILD_BANK_RIGHT, "DELETE FROM guild_bank_right WHERE guildid = ? AND TabId = ? AND rid = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8, 2: uint8 + PREPARE_STATEMENT(CHAR_INS_GUILD_BANK_RIGHT, "INSERT INTO guild_bank_right (guildid, TabId, rid, gbright, SlotPerDay) VALUES (?, ?, ?, ?, ?) " + "ON DUPLICATE KEY UPDATE gbright = VALUES(gbright), SlotPerDay = VALUES(SlotPerDay)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_GUILD_BANK_RIGHTS, "DELETE FROM guild_bank_right WHERE guildid = ?", CONNECTION_ASYNC) // 0: uint32 PREPARE_STATEMENT(CHAR_DEL_GUILD_BANK_RIGHTS_FOR_RANK, "DELETE FROM guild_bank_right WHERE guildid = ? AND rid = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8 // 0-1: uint32, 2-3: uint8, 4-5: uint32, 6: uint16, 7: uint8, 8: uint64 @@ -198,38 +197,15 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_UPD_GUILD_BANK_MONEY, "UPDATE guild SET BankMoney = ? WHERE guildid = ?", CONNECTION_ASYNC) // 0: uint64, 1: uint32 // 0: uint8, 1: uint32, 2: uint8, 3: uint32 PREPARE_STATEMENT(CHAR_UPD_GUILD_BANK_EVENTLOG_TAB, "UPDATE guild_bank_eventlog SET TabId = ? WHERE guildid = ? AND TabId = ? AND LogGuid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_MONEY, "UPDATE guild_member SET BankRemMoney = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint32, 2: uint32 - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_MONEY, "UPDATE guild_member SET BankResetTimeMoney = ?, BankRemMoney = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint32, 2: uint32, 3: uint32 - PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_RESET_TIME, "UPDATE guild_member SET BankResetTimeMoney = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8 PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_MONEY, "UPDATE guild_rank SET BankMoneyPerDay = ? WHERE rid = ? AND guildid = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8, 2: uint32 PREPARE_STATEMENT(CHAR_UPD_GUILD_BANK_TAB_TEXT, "UPDATE guild_bank_tab SET TabText = ? WHERE guildid = ? AND TabId = ?", CONNECTION_ASYNC) // 0: string, 1: uint32, 2: uint8 + + PREPARE_STATEMENT(CHAR_INS_GUILD_MEMBER_WITHDRAW, + "INSERT INTO guild_member_withdraw (guid, tab0, tab1, tab2, tab3, tab4, tab5, tab6, tab7, money) VALUES (?, ?, ?, ?, ?, ?, ?, ?) " + "ON DUPLICATE KEY UPDATE tab0 = VALUES (tab0), tab1 = VALUES (tab1), tab2 = VALUES (tab2), tab3 = VALUES (tab3), tab4 = VALUES (tab4), tab5 = VALUES (tab5), tab6 = VALUES (tab6), tab7 = VALUES (tab7)", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_DEL_GUILD_MEMBER_WITHDRAW, "TRUNCATE guild_member_withdraw", CONNECTION_ASYNC) + // 0: uint32, 1: uint32, 2: uint32 - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS0, "UPDATE guild_member SET BankRemSlotsTab0 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS1, "UPDATE guild_member SET BankRemSlotsTab1 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS2, "UPDATE guild_member SET BankRemSlotsTab2 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS3, "UPDATE guild_member SET BankRemSlotsTab3 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS4, "UPDATE guild_member SET BankRemSlotsTab4 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS5, "UPDATE guild_member SET BankRemSlotsTab5 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS6, "UPDATE guild_member SET BankRemSlotsTab6 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS7, "UPDATE guild_member SET BankRemSlotsTab7 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - // 0: uint32, 1: uint32, 2: uint32, 3: uint32 - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS0, "UPDATE guild_member SET BankResetTimeTab0 = ?, BankRemSlotsTab0 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS1, "UPDATE guild_member SET BankResetTimeTab1 = ?, BankRemSlotsTab1 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS2, "UPDATE guild_member SET BankResetTimeTab2 = ?, BankRemSlotsTab2 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS3, "UPDATE guild_member SET BankResetTimeTab3 = ?, BankRemSlotsTab3 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS4, "UPDATE guild_member SET BankResetTimeTab4 = ?, BankRemSlotsTab4 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS5, "UPDATE guild_member SET BankResetTimeTab5 = ?, BankRemSlotsTab5 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS6, "UPDATE guild_member SET BankResetTimeTab6 = ?, BankRemSlotsTab6 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS7, "UPDATE guild_member SET BankResetTimeTab7 = ?, BankRemSlotsTab7 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) - // 0: uint32, 1: uint8 - PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME0, "UPDATE guild_member SET BankResetTimeTab0 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME1, "UPDATE guild_member SET BankResetTimeTab1 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME2, "UPDATE guild_member SET BankResetTimeTab2 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME3, "UPDATE guild_member SET BankResetTimeTab3 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME4, "UPDATE guild_member SET BankResetTimeTab4 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME5, "UPDATE guild_member SET BankResetTimeTab5 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME6, "UPDATE guild_member SET BankResetTimeTab6 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME7, "UPDATE guild_member SET BankResetTimeTab7 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHAR_DATA_FOR_GUILD, "SELECT name, level, class, zone, account FROM characters WHERE guid = ?", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_DEL_GUILD_ACHIEVEMENT, "DELETE FROM guild_achievement WHERE guildId = ? AND achievement = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_INS_GUILD_ACHIEVEMENT, "INSERT INTO guild_achievement (guildId, achievement, date, guids) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC) diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 38f762a4a48..80c41122e7c 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -173,9 +173,7 @@ enum CharacterDatabaseStatements CHAR_INS_GUILD_BANK_ITEM, CHAR_DEL_GUILD_BANK_ITEM, CHAR_DEL_GUILD_BANK_ITEMS, - CHAR_INS_GUILD_BANK_RIGHT_DEFAULT, CHAR_INS_GUILD_BANK_RIGHT, - CHAR_DEL_GUILD_BANK_RIGHT, CHAR_DEL_GUILD_BANK_RIGHTS, CHAR_DEL_GUILD_BANK_RIGHTS_FOR_RANK, CHAR_INS_GUILD_BANK_EVENTLOG, @@ -196,35 +194,10 @@ enum CharacterDatabaseStatements CHAR_UPD_GUILD_BANK_TAB_INFO, CHAR_UPD_GUILD_BANK_MONEY, CHAR_UPD_GUILD_BANK_EVENTLOG_TAB, - CHAR_UPD_GUILD_MEMBER_BANK_REM_MONEY, - CHAR_UPD_GUILD_MEMBER_BANK_TIME_MONEY, - CHAR_UPD_GUILD_RANK_BANK_RESET_TIME, CHAR_UPD_GUILD_RANK_BANK_MONEY, CHAR_UPD_GUILD_BANK_TAB_TEXT, - CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS0, - CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS1, - CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS2, - CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS3, - CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS4, - CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS5, - CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS6, - CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS7, - CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS0, - CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS1, - CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS2, - CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS3, - CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS4, - CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS5, - CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS6, - CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS7, - CHAR_UPD_GUILD_RANK_BANK_TIME0, - CHAR_UPD_GUILD_RANK_BANK_TIME1, - CHAR_UPD_GUILD_RANK_BANK_TIME2, - CHAR_UPD_GUILD_RANK_BANK_TIME3, - CHAR_UPD_GUILD_RANK_BANK_TIME4, - CHAR_UPD_GUILD_RANK_BANK_TIME5, - CHAR_UPD_GUILD_RANK_BANK_TIME6, - CHAR_UPD_GUILD_RANK_BANK_TIME7, + CHAR_INS_GUILD_MEMBER_WITHDRAW, + CHAR_DEL_GUILD_MEMBER_WITHDRAW, CHAR_SEL_CHAR_DATA_FOR_GUILD, CHAR_DEL_GUILD_ACHIEVEMENT, CHAR_INS_GUILD_ACHIEVEMENT, diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index d8f7932470a..e257198745d 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -967,6 +967,14 @@ Quests.IgnoreAutoComplete = 0 Guild.EventLogRecordsCount = 100 # +# Guild.ResetHour +# Description: Hour of the day when the daily cap resets occur. +# Range: 0-23 +# Default: 6 - (06:00 AM) + +Guild.ResetHour = 6 + +# # Guild.BankEventLogRecordsCount # Description: Number of log entries for guild bank events that are stored per guild. Old # entries will be overwritten if the number of log entries exceed the |