diff options
-rw-r--r-- | src/server/game/Achievements/AchievementMgr.cpp | 8 | ||||
-rwxr-xr-x | src/server/game/DataStores/DBCStores.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Guilds/Guild.cpp | 129 | ||||
-rwxr-xr-x | src/server/game/Guilds/Guild.h | 59 | ||||
-rw-r--r-- | src/server/game/Guilds/GuildMgr.cpp | 59 | ||||
-rw-r--r-- | src/server/game/Guilds/GuildMgr.h | 2 | ||||
-rwxr-xr-x | src/server/game/Handlers/GuildHandler.cpp | 77 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 10 | ||||
-rwxr-xr-x | src/server/game/Server/WorldSession.h | 3 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 6 | ||||
-rwxr-xr-x | src/server/shared/Database/Implementation/CharacterDatabase.cpp | 2 | ||||
-rwxr-xr-x | src/server/shared/Database/Implementation/CharacterDatabase.h | 2 |
13 files changed, 363 insertions, 10 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index a0400dad77a..a664a6dca06 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -1854,6 +1854,10 @@ void AchievementMgr<T>::CompletedAchievement(AchievementEntry const* achievement if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID)) return; + if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS) + if (Guild* guild = sGuildMgr->GetGuildById(referencePlayer->GetGuildId())) + guild->GetNewsLog().AddNewEvent(GUILD_NEWS_PLAYER_ACHIEVEMENT, time(NULL), referencePlayer->GetGUID(), achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER, achievement->ID); + if (!GetOwner()->GetSession()->PlayerLoading()) SendAchievementEarned(achievement); @@ -1929,6 +1933,10 @@ void AchievementMgr<Guild>::CompletedAchievement(AchievementEntry const* achieve if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID)) return; + if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS) + if (Guild* guild = sGuildMgr->GetGuildById(referencePlayer->GetGuildId())) + guild->GetNewsLog().AddNewEvent(GUILD_NEWS_GUILD_ACHIEVEMENT, time(NULL), 0, achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER, achievement->ID); + SendAchievementEarned(achievement); CompletedAchievementData& ca = m_completedAchievements[achievement->ID]; ca.date = time(NULL); diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 98ae2aa5ff6..9e8dc76d832 100755 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -51,7 +51,8 @@ enum ContentLevels CONTENT_1_60 = 0, CONTENT_61_70 = 1, CONTENT_71_80 = 2, - CONTENT_81_85 = 3 + CONTENT_81_85 = 3, + MAX_CONTENT }; ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ed3f7a144b3..9b80750437c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -21496,7 +21496,13 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 return false; } - return crItem->maxcount != 0; + bool bought = crItem->maxcount != 0; + + if (bought) + if ((pProto->Quality == ITEM_QUALITY_EPIC && pProto->ItemLevel >= MinNewsItemLevel[sWorld->getIntConfig(CONFIG_EXPANSION)]) || pProto->Quality > ITEM_QUALITY_EPIC) + if (Guild* guild = sGuildMgr->GetGuildById(GetGuildId())) + guild->GetNewsLog().AddNewEvent(GUILD_NEWS_ITEM_PURCHASED, time(NULL), GetGUID(), 0, item); + return bought; } uint32 Player::GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot) const @@ -24230,6 +24236,11 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot) --loot->unlootedCount; + if (const ItemTemplate* proto = sObjectMgr->GetItemTemplate(item->itemid)) + if ((proto->Quality == ITEM_QUALITY_EPIC && proto->ItemLevel >= MinNewsItemLevel[sWorld->getIntConfig(CONFIG_EXPANSION)]) || proto->Quality > ITEM_QUALITY_EPIC) + if (Guild* guild = sGuildMgr->GetGuildById(GetGuildId())) + guild->GetNewsLog().AddNewEvent(GUILD_NEWS_ITEM_LOOTED, time(NULL), GetGUID(), 0, item->itemid); + SendNewItem(newitem, uint32(item->count), false, false, true); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count); diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 322e953be4a..09188843d52 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -1061,7 +1061,7 @@ 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), _level(1), _experience(0), _todayExperience(0) + m_achievementMgr(this), _level(1), _experience(0), _todayExperience(0), _newsLog(this) { memset(&m_bankEventLog, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(LogHolder*)); } @@ -3234,6 +3234,7 @@ void Guild::GiveXP(uint32 xp, Player* source) } } + GetNewsLog().AddNewEvent(GUILD_NEWS_LEVEL_UP, time(NULL), 0, 0, _level); GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL, GetLevel(), 0, NULL, source); } @@ -3258,3 +3259,129 @@ void Guild::ResetDailyExperience() 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(); + GuildNewsEntry& log = _newsLog[id]; + log.EventType = eventType; + log.PlayerGuid = playerGuid; + log.Data = data; + log.Flags = flags; + log.Date = date; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SAVE_GUILD_NEWS); + stmt->setUInt32(0, GetGuild()->GetId()); + stmt->setUInt32(1, id); + stmt->setUInt32(2, log.EventType); + stmt->setUInt64(3, log.PlayerGuid); + stmt->setUInt32(4, log.Data); + stmt->setUInt32(5, log.Flags); + stmt->setUInt32(6, uint32(log.Date)); + CharacterDatabase.Execute(stmt); + + WorldPacket pData; + BuildNewsData(id, log, pData); + GetGuild()->BroadcastPacket(&pData); +} + +void Guild::GuildNewsLog::LoadFromDB(PreparedQueryResult result) +{ + if (!result) + return; + do + { + Field* fields = result->Fetch(); + uint32 id = fields[0].GetInt32(); + GuildNewsEntry& log = _newsLog[id]; + log.EventType = GuildNews(fields[1].GetInt32()); + log.PlayerGuid = fields[2].GetInt64(); + log.Data = fields[3].GetInt32(); + log.Flags = fields[4].GetInt32(); + log.Date = time_t(fields[5].GetInt32()); + } + while (result->NextRow()); +} + +void Guild::GuildNewsLog::BuildNewsData(uint32 id, GuildNewsEntry& guildNew, WorldPacket& data) +{ + data.Initialize(SMSG_GUILD_NEWS_UPDATE); + data.WriteBits(1, 21); + + data.WriteBits(0, 26); // Other Guids NYI + ObjectGuid guid = guildNew.PlayerGuid; + + data.WriteBit(guid[7]); + data.WriteBit(guid[0]); + data.WriteBit(guid[6]); + data.WriteBit(guid[5]); + data.WriteBit(guid[4]); + data.WriteBit(guid[3]); + data.WriteBit(guid[1]); + data.WriteBit(guid[2]); + + data.FlushBits(); + + data.WriteByteSeq(guid[5]); + + data << uint32(guildNew.Flags); // 1 sticky + data << uint32(guildNew.Data); + data << uint32(0); + + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[1]); + + data << uint32(id); + data << uint32(guildNew.EventType); + data << uint32(secsToTimeBitFields(guildNew.Date)); +} + +void Guild::GuildNewsLog::BuildNewsData(WorldPacket& data) +{ + data.Initialize(SMSG_GUILD_NEWS_UPDATE); + data.WriteBits(_newsLog.size(), 21); + + for (GuildNewsLogMap::const_iterator it = _newsLog.begin(); it != _newsLog.end(); it++) + { + data.WriteBits(0, 26); // Not yet implemented used for guild achievements + ObjectGuid guid = it->second.PlayerGuid; + + data.WriteBit(guid[7]); + data.WriteBit(guid[0]); + data.WriteBit(guid[6]); + data.WriteBit(guid[5]); + data.WriteBit(guid[4]); + data.WriteBit(guid[3]); + data.WriteBit(guid[1]); + data.WriteBit(guid[2]); + } + + data.FlushBits(); + + for (GuildNewsLogMap::const_iterator it = _newsLog.begin(); it != _newsLog.end(); it++) + { + ObjectGuid guid = it->second.PlayerGuid; + data.WriteByteSeq(guid[5]); + + data << uint32(it->second.Flags); // 1 sticky + data << uint32(it->second.Data); + data << uint32(0); + + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[1]); + + data << uint32(it->first); + data << uint32(it->second.EventType); + data << uint32(secsToTimeBitFields(it->second.Date)); + } +} diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index b7613957a45..d846e814357 100755 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -24,6 +24,7 @@ #include "WorldPacket.h" #include "ObjectMgr.h" #include "Player.h" +#include "DBCStore.h" class Item; @@ -225,6 +226,38 @@ enum GuildMemberFlags 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, +}; + +struct GuildNewsEntry +{ + GuildNews EventType; + time_t Date; + uint64 PlayerGuid; + uint32 Flags; + uint32 Data; +}; + +struct GuildReward +{ + uint32 Entry; + uint8 Standing; + int32 Racemask; + uint64 Price; + uint32 AchievementId; +}; + +uint32 const MinNewsItemLevel[MAX_CONTENT] = { 61, 90, 200, 353 }; + +typedef std::map<uint32, GuildNewsEntry> GuildNewsLogMap; #define GUILD_EXPERIENCE_UNCAPPED_LEVEL 20 ///> Hardcoded in client, starting from this level, guild daily experience gain is unlimited. //////////////////////////////////////////////////////////////////////////////////////////// @@ -347,6 +380,30 @@ private: RemainingValue m_bankRemaining[GUILD_BANK_MAX_TABS + 1]; }; + // News Log class + class GuildNewsLog + { + public: + GuildNewsLog(Guild* guild) : _guild(guild) { } + + void LoadFromDB(PreparedQueryResult result); + void BuildNewsData(WorldPacket& data); + void BuildNewsData(uint32 id, GuildNewsEntry& guildNew, WorldPacket& data); + void AddNewEvent(GuildNews eventType, time_t date, uint64 playerGuid, uint32 flags, uint32 data); + GuildNewsEntry* GetNewById(uint32 id) + { + GuildNewsLogMap::iterator itr = _newsLog.find(id); + if (itr != _newsLog.end()) + return &itr->second; + return NULL; + } + Guild* GetGuild() const {return _guild; } + + private: + Guild* _guild; + GuildNewsLogMap _newsLog; + }; + // Base class for event entries class LogEntry { @@ -727,6 +784,7 @@ public: uint64 GetExperience() const { return _experience; } uint64 GetTodayExperience() const { return _todayExperience; } void ResetDailyExperience(); + GuildNewsLog& GetNewsLog() { return _newsLog; } protected: uint32 m_id; @@ -749,6 +807,7 @@ protected: LogHolder* m_bankEventLog[GUILD_BANK_MAX_TABS + 1]; AchievementMgr<Guild> m_achievementMgr; + GuildNewsLog _newsLog; uint32 _level; uint64 _experience; diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp index 726add2cf44..c611732ab48 100644 --- a/src/server/game/Guilds/GuildMgr.cpp +++ b/src/server/game/Guilds/GuildMgr.cpp @@ -433,8 +433,18 @@ void GuildMgr::LoadGuilds() itr->second->GetAchievementMgr().LoadFromDB(achievementResult, criteriaResult); } } + // 10. Loading Guild news + sLog->outInfo(LOG_FILTER_GENERAL, "Loading Guild News"); + { + for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); itr++) + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_GUILD_NEWS); + stmt->setInt32(0, itr->first); + itr->second->GetNewsLog().LoadFromDB(CharacterDatabase.Query(stmt)); + } + } - // 10. Validate loaded guild data + // 11. Validate loaded guild data sLog->outInfo(LOG_FILTER_GENERAL, "Validating data of loaded guilds..."); { uint32 oldMSTime = getMSTime(); @@ -507,5 +517,50 @@ void GuildMgr::LoadGuildXpForLevel() void GuildMgr::LoadGuildRewards() { - /// @TODO: Implement + uint32 oldMSTime = getMSTime(); + + // 0 1 2 3 4 + QueryResult result = WorldDatabase.Query("SELECT entry, standing, racemask, price, achievement FROM guild_rewards"); + + if (!result) + { + sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 guild reward definitions. DB table `guild_rewards` is empty."); + return; + } + + uint32 count = 0; + + do + { + GuildReward reward; + Field* fields = result->Fetch(); + reward.Entry = fields[0].GetUInt32(); + reward.Standing = fields[1].GetUInt8(); + reward.Racemask = fields[2].GetInt32(); + reward.Price = fields[3].GetUInt64(); + reward.AchievementId = fields[4].GetUInt32(); + + if (!sObjectMgr->GetItemTemplate(reward.Entry)) + { + sLog->outError(LOG_FILTER_SERVER_LOADING, "Guild rewards constains not existing item entry %u", reward.Entry); + continue; + } + + if (reward.AchievementId != 0 && (!sAchievementStore.LookupEntry(reward.AchievementId))) + { + sLog->outError(LOG_FILTER_SERVER_LOADING, "Guild rewards constains not existing achievement entry %u", reward.AchievementId); + continue; + } + + if (reward.Standing >= MAX_REPUTATION_RANK) + { + sLog->outError(LOG_FILTER_SERVER_LOADING, "Guild rewards contains wrong reputation standing %u, max is %u", uint32(reward.Standing), MAX_REPUTATION_RANK - 1); + continue; + } + + GuildRewards.push_back(reward); + ++count; + } while (result->NextRow()); + + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u guild reward definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h index a2bf6d268b5..24c1a4c0d5d 100644 --- a/src/server/game/Guilds/GuildMgr.h +++ b/src/server/game/Guilds/GuildMgr.h @@ -52,11 +52,13 @@ public: void SetNextGuildId(uint32 Id) { NextGuildId = Id; } uint32 GetXPForGuildLevel(uint8 level) const; + std::vector<GuildReward> const& GetGuildRewards() const { return GuildRewards; } protected: uint32 NextGuildId; GuildContainer GuildStore; std::vector<uint64> GuildXPperLevel; + std::vector<GuildReward> GuildRewards; }; #define sGuildMgr ACE_Singleton<GuildMgr, ACE_Null_Mutex>::instance() diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index d45c79d1b84..f5f69b18b62 100755 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -782,3 +782,80 @@ void WorldSession::HandleAutoDeclineGuildInvites(WorldPacket& recvPakcet) GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_AUTO_DECLINE_GUILD, enable); } + +void WorldSession::HandleGuildRewardsQueryOpcode(WorldPacket& recvPacket) +{ + recvPacket.read_skip<uint32>(); // Unk + + if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId())) + { + std::vector<GuildReward> const& rewards = sGuildMgr->GetGuildRewards(); + + WorldPacket data(SMSG_GUILD_REWARDS_LIST, (3 + rewards.size() * (4 + 4 + 4 +8 + 4 +4))); + data.WriteBits(rewards.size(), 21); + data.FlushBits(); + + for (uint32 i = 0; i < rewards.size(); i++) + { + data << uint32(rewards[i].Standing); + data << int32(rewards[i].Racemask); + data << uint32(rewards[i].Entry); + data << uint64(rewards[i].Price); + data << uint32(0); // Unused + data << uint32(rewards[i].AchievementId); + } + data << uint32(time(NULL)); + SendPacket(&data); + } +} + +void WorldSession::HandleGuildQueryNewsOpcode(WorldPacket& recvPacket) +{ + recvPacket.read_skip<uint32>(); + + if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId())) + { + WorldPacket data; + guild->GetNewsLog().BuildNewsData(data); + SendPacket(&data); + } +} + +void WorldSession::HandleGuildNewsUpdateStickyOpcode(WorldPacket& recvPacket) +{ + uint32 newId; + bool unk; + ObjectGuid guid; + + recvPacket >> newId; + + unk = recvPacket.ReadBit(); + guid[2] = recvPacket.ReadBit(); + guid[4] = recvPacket.ReadBit(); + guid[3] = recvPacket.ReadBit(); + guid[0] = recvPacket.ReadBit(); + guid[6] = recvPacket.ReadBit(); + guid[7] = recvPacket.ReadBit(); + guid[1] = recvPacket.ReadBit(); + guid[5] = recvPacket.ReadBit(); + + recvPacket.ReadByteSeq(guid[6]); + recvPacket.ReadByteSeq(guid[2]); + recvPacket.ReadByteSeq(guid[1]); + recvPacket.ReadByteSeq(guid[0]); + recvPacket.ReadByteSeq(guid[5]); + recvPacket.ReadByteSeq(guid[3]); + recvPacket.ReadByteSeq(guid[7]); + recvPacket.ReadByteSeq(guid[4]); + + if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId())) + { + if (GuildNewsEntry* guildNew = guild->GetNewsLog().GetNewById(newId)) + { + guildNew->Flags ^= 1; + WorldPacket data; + guild->GetNewsLog().BuildNewsData(newId, *guildNew, data); + SendPacket(&data); + } + } +} diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 8399c69782d..3ed5c0fe7f8 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -268,11 +268,11 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_GUILD_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildLeaveOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_MEMBER_SEND_SOR_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_MOTD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildMOTDOpcode ); - DEFINE_OPCODE_HANDLER(CMSG_GUILD_NEWS_UPDATE_STICKY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_NEWS_UPDATE_STICKY, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGuildNewsUpdateStickyOpcode); DEFINE_OPCODE_HANDLER(CMSG_GUILD_PERMISSIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPermissions ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_PROMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPromoteOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryOpcode ); - DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGuildQueryNewsOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY_RANKS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryRanksOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_REMOVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRemoveOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_REPLACE_GUILD_MASTER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -419,7 +419,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBERS_FOR_RECIPE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBER_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_REWARDS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_REWARDS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGuildRewardsQueryOpcode ); DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_XP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryXPOpcode ); // STATUS_AUTHED DEFINE_OPCODE_HANDLER(CMSG_QUERY_INSPECT_ACHIEVEMENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryInspectAchievements ); DEFINE_OPCODE_HANDLER(CMSG_QUERY_QUESTS_COMPLETED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryQuestsCompleted ); @@ -874,7 +874,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_GUILD_MOVE_COMPLETE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_MOVE_STARTING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_NEWS_DELETED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_GUILD_NEWS_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_NEWS_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -885,7 +885,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_REACTION_CHANGED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_WEEKLY_CAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_RESET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_ROSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_UPDATE_ROSTER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_XP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index e44514847d6..543f04e305b 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -576,6 +576,7 @@ class WorldSession void HandleGuildDeclineOpcode(WorldPacket& recvPacket); void HandleGuildEventLogQueryOpcode(WorldPacket& recvPacket); void HandleGuildRosterOpcode(WorldPacket& recvPacket); + void HandleGuildRewardsQueryOpcode(WorldPacket& recvPacket); void HandleGuildPromoteOpcode(WorldPacket& recvPacket); void HandleGuildDemoteOpcode(WorldPacket& recvPacket); void HandleGuildAssignRankOpcode(WorldPacket& recvPacket); @@ -583,8 +584,10 @@ class WorldSession void HandleGuildDisbandOpcode(WorldPacket& recvPacket); void HandleGuildLeaderOpcode(WorldPacket& recvPacket); void HandleGuildMOTDOpcode(WorldPacket& recvPacket); + void HandleGuildNewsUpdateStickyOpcode(WorldPacket& recvPacket); void HandleGuildSetNoteOpcode(WorldPacket& recvPacket); void HandleGuildQueryRanksOpcode(WorldPacket& recvPacket); + void HandleGuildQueryNewsOpcode(WorldPacket& recvPacket); void HandleGuildSetRankPermissionsOpcode(WorldPacket& recvPacket); void HandleGuildAddRankOpcode(WorldPacket& recvPacket); void HandleGuildDelRankOpcode(WorldPacket& recvPacket); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 7e32ce9137e..095cceab7bf 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -63,6 +63,8 @@ #include "GameObjectAI.h" #include "AccountMgr.h" #include "InstanceScript.h" +#include "Guild.h" +#include "GuildMgr.h" pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= { @@ -1567,6 +1569,10 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype) // create the new item and store it Item* pItem = player->StoreNewItem(dest, newitemid, true, Item::GenerateItemRandomPropertyId(newitemid)); + if ((pProto->Quality == ITEM_QUALITY_EPIC && pProto->ItemLevel >= MinNewsItemLevel[sWorld->getIntConfig(CONFIG_EXPANSION)]) || pProto->Quality > ITEM_QUALITY_EPIC) + if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) + guild->GetNewsLog().AddNewEvent(GUILD_NEWS_ITEM_CRAFTED, time(NULL), player->GetGUID(), 0, pProto->ItemId); + // was it successful? return error if not if (!pItem) { diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index bb958be8ca7..1b17c35284b 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -241,6 +241,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA, "SELECT criteria, counter, date, completedGuid FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_UPD_GUILD_EXPERIENCE, "UPDATE guild SET level = ?, experience = ?, todayExperience = ? WHERE guildId = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE, "UPDATE guild SET todayExperience = 0", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_LOAD_GUILD_NEWS, "SELECT id, eventType, playerGuid, data, flags, date FROM guild_news_log WHERE guild = ? ORDER BY guild ASC, id ASC", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SAVE_GUILD_NEWS, "INSERT INTO guild_news_log values (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); // Chat channel handling PREPARE_STATEMENT(CHAR_SEL_CHANNEL, "SELECT announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH) diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 9c06c547b39..20454798f98 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -236,6 +236,8 @@ enum CharacterDatabaseStatements CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA, CHAR_UPD_GUILD_EXPERIENCE, CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE, + CHAR_LOAD_GUILD_NEWS, + CHAR_SAVE_GUILD_NEWS, CHAR_SEL_CHANNEL, CHAR_INS_CHANNEL, |