diff options
| author | Shauren <shauren.trinity@gmail.com> | 2022-12-04 15:13:20 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2022-12-04 15:13:20 +0100 |
| commit | e98e1283ea0034baf6be9aa2ffb386eb5582801b (patch) | |
| tree | b1dd854d88e6e049d26b208bb259cdc7d31f29f8 /src/server/game/Server/Packets | |
| parent | de7c03c8385780f05530c2b3cf952a712d5f8f00 (diff) | |
Core: Updated to 10.0.2
Diffstat (limited to 'src/server/game/Server/Packets')
49 files changed, 937 insertions, 515 deletions
diff --git a/src/server/game/Server/Packets/AuctionHousePackets.cpp b/src/server/game/Server/Packets/AuctionHousePackets.cpp index 08478565728..e3eec9efc7e 100644 --- a/src/server/game/Server/Packets/AuctionHousePackets.cpp +++ b/src/server/game/Server/Packets/AuctionHousePackets.cpp @@ -80,8 +80,8 @@ ByteBuffer& operator<<(ByteBuffer& data, AuctionBucketKey const& itemKey) ByteBuffer& operator>>(ByteBuffer& data, AuctionListFilterSubClass& filterSubClass) { - data >> filterSubClass.ItemSubclass; data >> filterSubClass.InvTypeMask; + data >> filterSubClass.ItemSubclass; return data; } @@ -595,7 +595,7 @@ WorldPacket const* AuctionHelloResponse::Write() WorldPacket const* AuctionListBiddedItemsResult::Write() { - _worldPacket << int32(Items.size()); + _worldPacket << uint32(Items.size()); _worldPacket << uint32(DesiredDelay); _worldPacket.WriteBit(HasMoreResults); _worldPacket.FlushBits(); diff --git a/src/server/game/Server/Packets/AuctionHousePackets.h b/src/server/game/Server/Packets/AuctionHousePackets.h index 795565c6fa0..da5a2a6570f 100644 --- a/src/server/game/Server/Packets/AuctionHousePackets.h +++ b/src/server/game/Server/Packets/AuctionHousePackets.h @@ -51,7 +51,7 @@ namespace WorldPackets struct AuctionListFilterSubClass { int32 ItemSubclass = 0; - uint32 InvTypeMask = 0; + uint64 InvTypeMask = 0; }; struct AuctionListFilterClass diff --git a/src/server/game/Server/Packets/AuthenticationPackets.cpp b/src/server/game/Server/Packets/AuthenticationPackets.cpp index f05643e807e..3809c421c86 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.cpp +++ b/src/server/game/Server/Packets/AuthenticationPackets.cpp @@ -138,6 +138,7 @@ WorldPacket const* WorldPackets::Auth::AuthResponse::Write() _worldPacket << uint8(classAvailability.ClassID); _worldPacket << uint8(classAvailability.ActiveExpansionLevel); _worldPacket << uint8(classAvailability.AccountExpansionLevel); + _worldPacket << uint8(classAvailability.MinActiveExpansionLevel); } } @@ -166,7 +167,7 @@ WorldPacket const* WorldPackets::Auth::AuthResponse::Write() _worldPacket << uint16(*SuccessInfo->NumPlayersAlliance); if (SuccessInfo->ExpansionTrialExpiration) - _worldPacket << int32(*SuccessInfo->ExpansionTrialExpiration); + _worldPacket << *SuccessInfo->ExpansionTrialExpiration; for (VirtualRealmInfo const& virtualRealm : SuccessInfo->VirtualRealms) _worldPacket << virtualRealm; diff --git a/src/server/game/Server/Packets/AuthenticationPackets.h b/src/server/game/Server/Packets/AuthenticationPackets.h index 0e6b2b65331..7999186ed3d 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.h +++ b/src/server/game/Server/Packets/AuthenticationPackets.h @@ -162,7 +162,7 @@ namespace WorldPackets bool ForceCharacterTemplate = false; ///< forces the client to always use a character template when creating a new character. @see Templates. @todo implement Optional<uint16> NumPlayersHorde; ///< number of horde players in this realm. @todo implement Optional<uint16> NumPlayersAlliance; ///< number of alliance players in this realm. @todo implement - Optional<int32> ExpansionTrialExpiration; ///< expansion trial expiration unix timestamp + Optional<Timestamp<>> ExpansionTrialExpiration; ///< expansion trial expiration unix timestamp }; AuthResponse() : ServerPacket(SMSG_AUTH_RESPONSE, 132) { } diff --git a/src/server/game/Server/Packets/AzeritePackets.cpp b/src/server/game/Server/Packets/AzeritePackets.cpp index 13222e3175e..87406b757dc 100644 --- a/src/server/game/Server/Packets/AzeritePackets.cpp +++ b/src/server/game/Server/Packets/AzeritePackets.cpp @@ -26,13 +26,6 @@ WorldPacket const* WorldPackets::Azerite::PlayerAzeriteItemGains::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Azerite::OpenHeartForge::Write() -{ - _worldPacket << ForgeGUID; - - return &_worldPacket; -} - void WorldPackets::Azerite::AzeriteEssenceUnlockMilestone::Read() { _worldPacket >> AzeriteItemMilestonePowerID; @@ -76,10 +69,3 @@ WorldPacket const* WorldPackets::Azerite::PlayerAzeriteItemEquippedStatusChanged return &_worldPacket; } - -WorldPacket const* WorldPackets::Azerite::AzeriteRespecNPC::Write() -{ - _worldPacket << NpcGUID; - - return &_worldPacket; -} diff --git a/src/server/game/Server/Packets/AzeritePackets.h b/src/server/game/Server/Packets/AzeritePackets.h index 487c5d2bced..0a0204c61e7 100644 --- a/src/server/game/Server/Packets/AzeritePackets.h +++ b/src/server/game/Server/Packets/AzeritePackets.h @@ -38,24 +38,6 @@ namespace WorldPackets uint64 XP = 0; }; - class OpenHeartForge final : public ServerPacket - { - public: - OpenHeartForge() : ServerPacket(SMSG_OPEN_HEART_FORGE, 16) { } - - WorldPacket const* Write() override; - - ObjectGuid ForgeGUID; - }; - - class CloseHeartForge final : public ServerPacket - { - public: - CloseHeartForge() : ServerPacket(SMSG_CLOSE_HEART_FORGE, 0) { } - - WorldPacket const* Write() override { return &_worldPacket; } - }; - class AzeriteEssenceUnlockMilestone final : public ClientPacket { public: @@ -122,16 +104,6 @@ namespace WorldPackets bool IsHeartEquipped = false; }; - - class AzeriteRespecNPC final : public ServerPacket - { - public: - AzeriteRespecNPC(ObjectGuid npcGuid) : ServerPacket(SMSG_AZERITE_RESPEC_NPC, 16), NpcGUID(npcGuid) { } - - WorldPacket const* Write() override; - - ObjectGuid NpcGUID; - }; } } diff --git a/src/server/game/Server/Packets/BattlegroundPackets.cpp b/src/server/game/Server/Packets/BattlegroundPackets.cpp index 1c8abe81261..2fa88ef4901 100644 --- a/src/server/game/Server/Packets/BattlegroundPackets.cpp +++ b/src/server/game/Server/Packets/BattlegroundPackets.cpp @@ -323,12 +323,15 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::RatedPvpInf data << int32(bracketInfo.Unused2); data << int32(bracketInfo.WeeklyPlayed); data << int32(bracketInfo.WeeklyWon); + data << int32(bracketInfo.RoundsSeasonPlayed); + data << int32(bracketInfo.RoundsSeasonWon); + data << int32(bracketInfo.RoundsWeeklyPlayed); + data << int32(bracketInfo.RoundsWeeklyWon); data << int32(bracketInfo.BestWeeklyRating); data << int32(bracketInfo.LastWeeksBestRating); data << int32(bracketInfo.BestSeasonRating); data << int32(bracketInfo.PvpTierID); data << int32(bracketInfo.Unused3); - data << int32(bracketInfo.WeeklyBestWinPvpTierID); data << int32(bracketInfo.Unused4); data << int32(bracketInfo.Rank); data.WriteBit(bracketInfo.Disqualified); diff --git a/src/server/game/Server/Packets/BattlegroundPackets.h b/src/server/game/Server/Packets/BattlegroundPackets.h index fcc98786fa6..587efc4e224 100644 --- a/src/server/game/Server/Packets/BattlegroundPackets.h +++ b/src/server/game/Server/Packets/BattlegroundPackets.h @@ -450,12 +450,15 @@ namespace WorldPackets int32 Unused2 = 0; int32 WeeklyPlayed = 0; int32 WeeklyWon = 0; + int32 RoundsSeasonPlayed = 0; + int32 RoundsSeasonWon = 0; + int32 RoundsWeeklyPlayed = 0; + int32 RoundsWeeklyWon = 0; int32 BestWeeklyRating = 0; int32 LastWeeksBestRating = 0; int32 BestSeasonRating = 0; int32 PvpTierID = 0; int32 Unused3 = 0; - int32 WeeklyBestWinPvpTierID = 0; int32 Unused4 = 0; int32 Rank = 0; bool Disqualified = false; diff --git a/src/server/game/Server/Packets/BlackMarketPackets.cpp b/src/server/game/Server/Packets/BlackMarketPackets.cpp index aac7626632a..d24019ec693 100644 --- a/src/server/game/Server/Packets/BlackMarketPackets.cpp +++ b/src/server/game/Server/Packets/BlackMarketPackets.cpp @@ -22,15 +22,6 @@ void WorldPackets::BlackMarket::BlackMarketOpen::Read() _worldPacket >> Guid; } -WorldPacket const* WorldPackets::BlackMarket::BlackMarketOpenResult::Write() -{ - _worldPacket << Guid; - _worldPacket.WriteBit(Enable); - _worldPacket.FlushBits(); - - return &_worldPacket; -} - void WorldPackets::BlackMarket::BlackMarketRequestItems::Read() { _worldPacket >> Guid; diff --git a/src/server/game/Server/Packets/BlackMarketPackets.h b/src/server/game/Server/Packets/BlackMarketPackets.h index 5c51cb5f095..aa400617008 100644 --- a/src/server/game/Server/Packets/BlackMarketPackets.h +++ b/src/server/game/Server/Packets/BlackMarketPackets.h @@ -50,17 +50,6 @@ namespace WorldPackets ObjectGuid Guid; }; - class BlackMarketOpenResult final : public ServerPacket - { - public: - BlackMarketOpenResult() : ServerPacket(SMSG_BLACK_MARKET_OPEN_RESULT, 15) { } - - WorldPacket const* Write() override; - - ObjectGuid Guid; - bool Enable = true; - }; - class BlackMarketRequestItems final : public ClientPacket { public: diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp index 92de494024c..9eae2466da9 100644 --- a/src/server/game/Server/Packets/CharacterPackets.cpp +++ b/src/server/game/Server/Packets/CharacterPackets.cpp @@ -141,7 +141,7 @@ EnumCharactersResult::CharacterInfo::CharacterInfo(Field* fields) LastLoginVersion = fields[22].GetUInt32(); - for (uint8 slot = 0; slot < INVENTORY_SLOT_BAG_END; ++slot) + for (uint8 slot = 0; slot < REAGENT_BAG_SLOT_END; ++slot) { uint32 visualBase = slot * 5; VisualItems[slot].InvType = Trinity::StringTo<uint8>(equipment[visualBase + 0]).value_or(0); @@ -193,9 +193,9 @@ ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::CharacterInfo con data << visualItem; data << charInfo.LastPlayedTime; - data << uint16(charInfo.SpecID); - data << uint32(charInfo.Unknown703); - data << uint32(charInfo.LastLoginVersion); + data << int16(charInfo.SpecID); + data << int32(charInfo.Unknown703); + data << int32(charInfo.LastLoginVersion); data << uint32(charInfo.Flags4); data << uint32(charInfo.MailSenders.size()); data << uint32(charInfo.MailSenderTypes.size()); @@ -245,6 +245,14 @@ ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::UnlockedCondition return data; } +ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::RaceLimitDisableInfo const& raceLimitDisableInfo) +{ + data << int32(raceLimitDisableInfo.RaceID); + data << int32(raceLimitDisableInfo.BlockReason); + + return data; +} + WorldPacket const* EnumCharactersResult::Write() { _worldPacket.reserve(9 + Characters.size() * sizeof(CharacterInfo) + RaceUnlockData.size() * sizeof(RaceUnlock)); @@ -254,12 +262,14 @@ WorldPacket const* EnumCharactersResult::Write() _worldPacket.WriteBit(IsNewPlayerRestrictionSkipped); _worldPacket.WriteBit(IsNewPlayerRestricted); _worldPacket.WriteBit(IsNewPlayer); + _worldPacket.WriteBit(IsTrialAccountRestricted); _worldPacket.WriteBit(DisabledClassesMask.has_value()); _worldPacket.WriteBit(IsAlliedRacesCreationAllowed); _worldPacket << uint32(Characters.size()); _worldPacket << int32(MaxCharacterLevel); _worldPacket << uint32(RaceUnlockData.size()); _worldPacket << uint32(UnlockedConditionalAppearances.size()); + _worldPacket << uint32(RaceLimitDisables.size()); if (DisabledClassesMask) _worldPacket << uint32(*DisabledClassesMask); @@ -267,6 +277,9 @@ WorldPacket const* EnumCharactersResult::Write() for (UnlockedConditionalAppearance const& unlockedConditionalAppearance : UnlockedConditionalAppearances) _worldPacket << unlockedConditionalAppearance; + for (RaceLimitDisableInfo const& raceLimitDisableInfo : RaceLimitDisables) + _worldPacket << raceLimitDisableInfo; + for (CharacterInfo const& charInfo : Characters) _worldPacket << charInfo; @@ -377,6 +390,7 @@ void CharRaceOrFactionChange::Read() _worldPacket >> RaceOrFactionChangeInfo->Guid; _worldPacket >> RaceOrFactionChangeInfo->SexID; _worldPacket >> RaceOrFactionChangeInfo->RaceID; + _worldPacket >> RaceOrFactionChangeInfo->InitialRaceID; RaceOrFactionChangeInfo->Customizations.resize(_worldPacket.read<uint32>()); RaceOrFactionChangeInfo->Name = _worldPacket.ReadString(nameLength); for (ChrCustomizationChoice& customization : RaceOrFactionChangeInfo->Customizations) @@ -537,6 +551,7 @@ void AlterApperance::Read() { Customizations.resize(_worldPacket.read<uint32>()); _worldPacket >> NewSex; + _worldPacket >> CustomizedRace; for (ChrCustomizationChoice& customization : Customizations) _worldPacket >> customization; @@ -556,7 +571,6 @@ WorldPacket const* LogXPGain::Write() _worldPacket << uint8(Reason); _worldPacket << int32(Amount); _worldPacket << float(GroupBonus); - _worldPacket << uint8(ReferAFriendBonusType); return &_worldPacket; } diff --git a/src/server/game/Server/Packets/CharacterPackets.h b/src/server/game/Server/Packets/CharacterPackets.h index d4eff75626a..cf7b14a81ff 100644 --- a/src/server/game/Server/Packets/CharacterPackets.h +++ b/src/server/game/Server/Packets/CharacterPackets.h @@ -87,6 +87,7 @@ namespace WorldPackets struct CharRaceOrFactionChangeInfo { uint8 RaceID = RACE_NONE; + uint8 InitialRaceID = RACE_NONE; uint8 SexID = GENDER_NONE; ObjectGuid Guid; bool FactionChange = false; @@ -159,7 +160,7 @@ namespace WorldPackets uint8 Subclass = 0; }; - std::array<VisualItemInfo, 23> VisualItems = { }; + std::array<VisualItemInfo, 35> VisualItems = { }; std::vector<std::string> MailSenders; std::vector<uint32> MailSenderTypes; }; @@ -178,6 +179,18 @@ namespace WorldPackets int32 Unused = 0; }; + struct RaceLimitDisableInfo + { + enum + { + Server, + Level + }; + + int32 RaceID = 0; + int32 BlockReason = 0; + }; + EnumCharactersResult() : ServerPacket(SMSG_ENUM_CHARACTERS_RESULT) { } WorldPacket const* Write() override; @@ -187,6 +200,7 @@ namespace WorldPackets bool IsNewPlayerRestrictionSkipped = false; ///< allows client to skip new player restrictions bool IsNewPlayerRestricted = false; ///< forbids using level boost and class trials bool IsNewPlayer = false; ///< forbids hero classes and allied races + bool IsTrialAccountRestricted = false; bool IsAlliedRacesCreationAllowed = false; int32 MaxCharacterLevel = 1; @@ -195,6 +209,7 @@ namespace WorldPackets std::vector<CharacterInfo> Characters; ///< all characters on the list std::vector<RaceUnlock> RaceUnlockData; ///< std::vector<UnlockedConditionalAppearance> UnlockedConditionalAppearances; + std::vector<RaceLimitDisableInfo> RaceLimitDisables; }; class CheckCharacterNameAvailability final : public ClientPacket @@ -623,6 +638,7 @@ namespace WorldPackets uint8 NewSex = 0; Array<ChrCustomizationChoice, 50> Customizations; + int32 CustomizedRace = 0; }; class BarberShopResult final : public ServerPacket @@ -646,7 +662,7 @@ namespace WorldPackets class LogXPGain final : public ServerPacket { public: - LogXPGain() : ServerPacket(SMSG_LOG_XP_GAIN, 30) { } + LogXPGain() : ServerPacket(SMSG_LOG_XP_GAIN, 16 + 4 + 1 + 4 + 4) { } WorldPacket const* Write() override; @@ -654,8 +670,7 @@ namespace WorldPackets int32 Original = 0; uint8 Reason = 0; int32 Amount = 0; - float GroupBonus = 0; - uint8 ReferAFriendBonusType = 0; // 1 - 300% of normal XP; 2 - 150% of normal XP + float GroupBonus = 0.0f; }; class TitleEarned final : public ServerPacket diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp index 2cf1eec9701..c99a5f1b577 100644 --- a/src/server/game/Server/Packets/ChatPackets.cpp +++ b/src/server/game/Server/Packets/ChatPackets.cpp @@ -25,7 +25,7 @@ void WorldPackets::Chat::ChatMessage::Read() { _worldPacket >> Language; - uint32 len = _worldPacket.ReadBits(9); + uint32 len = _worldPacket.ReadBits(11); Text = _worldPacket.ReadString(len); } @@ -33,7 +33,7 @@ void WorldPackets::Chat::ChatMessageWhisper::Read() { _worldPacket >> Language; uint32 targetLen = _worldPacket.ReadBits(9); - uint32 textLen = _worldPacket.ReadBits(9); + uint32 textLen = _worldPacket.ReadBits(11); Target = _worldPacket.ReadString(targetLen); Text = _worldPacket.ReadString(textLen); } @@ -43,7 +43,7 @@ void WorldPackets::Chat::ChatMessageChannel::Read() _worldPacket >> Language; _worldPacket >> ChannelGUID; uint32 targetLen = _worldPacket.ReadBits(9); - uint32 textLen = _worldPacket.ReadBits(9); + uint32 textLen = _worldPacket.ReadBits(11); Target = _worldPacket.ReadString(targetLen); Text = _worldPacket.ReadString(textLen); } @@ -77,19 +77,19 @@ void WorldPackets::Chat::ChatAddonMessageTargeted::Read() void WorldPackets::Chat::ChatMessageDND::Read() { - uint32 len = _worldPacket.ReadBits(9); + uint32 len = _worldPacket.ReadBits(11); Text = _worldPacket.ReadString(len); } void WorldPackets::Chat::ChatMessageAFK::Read() { - uint32 len = _worldPacket.ReadBits(9); + uint32 len = _worldPacket.ReadBits(11); Text = _worldPacket.ReadString(len); } void WorldPackets::Chat::ChatMessageEmote::Read() { - uint32 len = _worldPacket.ReadBits(9); + uint32 len = _worldPacket.ReadBits(11); Text = _worldPacket.ReadString(len); } diff --git a/src/server/game/Server/Packets/CraftingPacketsCommon.cpp b/src/server/game/Server/Packets/CraftingPacketsCommon.cpp new file mode 100644 index 00000000000..d06b0e21e7d --- /dev/null +++ b/src/server/game/Server/Packets/CraftingPacketsCommon.cpp @@ -0,0 +1,61 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "CraftingPacketsCommon.h" + +namespace WorldPackets::Crafting +{ +ByteBuffer& operator<<(ByteBuffer& data, SpellReducedReagent const& spellReducedReagent) +{ + data << int32(spellReducedReagent.ItemID); + data << int32(spellReducedReagent.Quantity); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, CraftingData const& craftingData) +{ + data << int32(craftingData.CraftingQualityID); + data << int32(craftingData.field_4); + data << int32(craftingData.field_8); + data << int32(craftingData.Multicraft); + data << int32(craftingData.field_10); + data << int32(craftingData.field_14); + data << int32(craftingData.CritBonusSkill); + data << float(craftingData.field_1C); + data << uint64(craftingData.field_20); + data << uint32(craftingData.ResourcesReturned.size()); + data << uint32(craftingData.OperationID); + data << craftingData.ItemGUID; + data << int32(craftingData.Quantity); + data << int32(craftingData.EnchantID); + + for (SpellReducedReagent const& spellReducedReagent : craftingData.ResourcesReturned) + data << spellReducedReagent; + + data.WriteBit(craftingData.IsCrit); + data.WriteBit(craftingData.field_29); + data.WriteBit(craftingData.field_2A); + data.WriteBit(craftingData.BonusCraft); + data.FlushBits(); + + data << craftingData.OldItem; + data << craftingData.NewItem; + + return data; +} +} diff --git a/src/server/game/Server/Packets/CraftingPacketsCommon.h b/src/server/game/Server/Packets/CraftingPacketsCommon.h new file mode 100644 index 00000000000..b74d77cda29 --- /dev/null +++ b/src/server/game/Server/Packets/CraftingPacketsCommon.h @@ -0,0 +1,59 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITYCORE_CRAFTING_PACKETS_COMMON_H +#define TRINITYCORE_CRAFTING_PACKETS_COMMON_H + +#include "ItemPacketsCommon.h" +#include "ObjectGuid.h" + +namespace WorldPackets::Crafting +{ +struct SpellReducedReagent +{ + int32 ItemID = 0; + int32 Quantity = 0; +}; + +struct CraftingData +{ + int32 CraftingQualityID = 0; + int32 field_4 = 0; + int32 field_8 = 0; + int32 Multicraft = 0; + int32 field_10 = 0; + int32 field_14 = 0; + int32 CritBonusSkill = 0; + float field_1C = 0.0f; + uint64 field_20 = 0; + bool IsCrit = false; + bool field_29 = false; + bool field_2A = false; + bool BonusCraft = false; + std::vector<SpellReducedReagent> ResourcesReturned; + uint32 OperationID = 0; + ObjectGuid ItemGUID; + int32 Quantity = 0; + Item::ItemInstance OldItem; + Item::ItemInstance NewItem; + int32 EnchantID = 0; +}; + +ByteBuffer& operator<<(ByteBuffer& data, SpellReducedReagent const& spellReducedReagent); +ByteBuffer& operator<<(ByteBuffer& data, CraftingData const& craftingData); +} +#endif // TRINITYCORE_CRAFTING_PACKETS_COMMON_H diff --git a/src/server/game/Server/Packets/GameObjectPackets.cpp b/src/server/game/Server/Packets/GameObjectPackets.cpp index fd15e7264cf..987a0e4edac 100644 --- a/src/server/game/Server/Packets/GameObjectPackets.cpp +++ b/src/server/game/Server/Packets/GameObjectPackets.cpp @@ -20,11 +20,13 @@ void WorldPackets::GameObject::GameObjUse::Read() { _worldPacket >> Guid; + IsSoftInteract = _worldPacket.ReadBit(); } void WorldPackets::GameObject::GameObjReportUse::Read() { _worldPacket >> Guid; + IsSoftInteract = _worldPacket.ReadBit(); } WorldPacket const* WorldPackets::GameObject::GameObjectDespawn::Write() @@ -70,28 +72,34 @@ WorldPacket const* WorldPackets::GameObject::GameObjectCustomAnim::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::GameObject::GameObjectUILink::Write() +WorldPacket const* WorldPackets::GameObject::GameObjectPlaySpellVisual::Write() { _worldPacket << ObjectGUID; - _worldPacket << int32(UILink); - _worldPacket << int32(UIItemInteractionID); + _worldPacket << ActivatorGUID; + _worldPacket << int32(SpellVisualID); return &_worldPacket; } -WorldPacket const* WorldPackets::GameObject::GameObjectPlaySpellVisual::Write() +WorldPacket const* WorldPackets::GameObject::GameObjectSetStateLocal::Write() { _worldPacket << ObjectGUID; - _worldPacket << ActivatorGUID; - _worldPacket << int32(SpellVisualID); + _worldPacket << uint8(State); return &_worldPacket; } -WorldPacket const* WorldPackets::GameObject::GameObjectSetStateLocal::Write() +WorldPacket const* WorldPackets::GameObject::GameObjectInteraction::Write() { _worldPacket << ObjectGUID; - _worldPacket << uint8(State); + _worldPacket << int32(InteractionType); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::GameObject::GameObjectCloseInteraction::Write() +{ + _worldPacket << int32(InteractionType); return &_worldPacket; } diff --git a/src/server/game/Server/Packets/GameObjectPackets.h b/src/server/game/Server/Packets/GameObjectPackets.h index 3bd71aba0ab..d7ce351bdab 100644 --- a/src/server/game/Server/Packets/GameObjectPackets.h +++ b/src/server/game/Server/Packets/GameObjectPackets.h @@ -21,6 +21,8 @@ #include "Packet.h" #include "GameObject.h" +enum class PlayerInteractionType : int32; + namespace WorldPackets { namespace GameObject @@ -33,6 +35,7 @@ namespace WorldPackets void Read() override; ObjectGuid Guid; + bool IsSoftInteract = false; }; class GameObjReportUse final : public ClientPacket @@ -43,6 +46,7 @@ namespace WorldPackets void Read() override; ObjectGuid Guid; + bool IsSoftInteract = false; }; class GameObjectDespawn final : public ServerPacket @@ -119,39 +123,48 @@ namespace WorldPackets bool PlayAsDespawn = false; }; - class GameObjectUILink final : public ServerPacket + class GameObjectPlaySpellVisual final : public ServerPacket { public: - GameObjectUILink() : ServerPacket(SMSG_GAME_OBJECT_UI_LINK, 16 + 4) { } + GameObjectPlaySpellVisual() : ServerPacket(SMSG_GAME_OBJECT_PLAY_SPELL_VISUAL, 16 + 16 + 4) { } WorldPacket const* Write() override; ObjectGuid ObjectGUID; - int32 UILink = 0; - int32 UIItemInteractionID = 0; + ObjectGuid ActivatorGUID; + int32 SpellVisualID = 0; }; - class GameObjectPlaySpellVisual final : public ServerPacket + class GameObjectSetStateLocal final : public ServerPacket { public: - GameObjectPlaySpellVisual() : ServerPacket(SMSG_GAME_OBJECT_PLAY_SPELL_VISUAL, 16 + 16 + 4) { } + GameObjectSetStateLocal() : ServerPacket(SMSG_GAME_OBJECT_SET_STATE_LOCAL, 16 + 1) { } WorldPacket const* Write() override; ObjectGuid ObjectGUID; - ObjectGuid ActivatorGUID; - int32 SpellVisualID = 0; + uint8 State = 0; }; - class GameObjectSetStateLocal final : public ServerPacket + class GameObjectInteraction final : public ServerPacket { public: - GameObjectSetStateLocal() : ServerPacket(SMSG_GAME_OBJECT_SET_STATE_LOCAL, 16 + 1) { } + GameObjectInteraction() : ServerPacket(SMSG_GAME_OBJECT_INTERACTION, 16 + 4) { } WorldPacket const* Write() override; ObjectGuid ObjectGUID; - uint8 State = 0; + PlayerInteractionType InteractionType = {}; + }; + + class GameObjectCloseInteraction final : public ServerPacket + { + public: + GameObjectCloseInteraction() : ServerPacket(SMSG_GAME_OBJECT_CLOSE_INTERACTION, 4) { } + + WorldPacket const* Write() override; + + PlayerInteractionType InteractionType = {}; }; } } diff --git a/src/server/game/Server/Packets/GarrisonPackets.cpp b/src/server/game/Server/Packets/GarrisonPackets.cpp index 234ce345462..0796748d877 100644 --- a/src/server/game/Server/Packets/GarrisonPackets.cpp +++ b/src/server/game/Server/Packets/GarrisonPackets.cpp @@ -481,13 +481,4 @@ WorldPacket const* GarrisonBuildingActivated::Write() return &_worldPacket; } - -WorldPacket const* GarrisonOpenTalentNpc::Write() -{ - _worldPacket << NpcGUID; - _worldPacket << int32(GarrTalentTreeID); - _worldPacket << int32(FriendshipFactionID); - - return &_worldPacket; -} } diff --git a/src/server/game/Server/Packets/GarrisonPackets.h b/src/server/game/Server/Packets/GarrisonPackets.h index 9b1367a5819..983982842f8 100644 --- a/src/server/game/Server/Packets/GarrisonPackets.h +++ b/src/server/game/Server/Packets/GarrisonPackets.h @@ -437,18 +437,6 @@ namespace WorldPackets uint32 GarrPlotInstanceID = 0; }; - - class GarrisonOpenTalentNpc final : public ServerPacket - { - public: - GarrisonOpenTalentNpc() : ServerPacket(SMSG_GARRISON_OPEN_TALENT_NPC, 16 + 4 + 4) { } - - WorldPacket const* Write() override; - - ObjectGuid NpcGUID; - int32 GarrTalentTreeID = 0; - int32 FriendshipFactionID = 0; // Always 0 except on The Deaths of Chromie Scenario - }; } } diff --git a/src/server/game/Server/Packets/InspectPackets.cpp b/src/server/game/Server/Packets/InspectPackets.cpp index 9cd83f4ac62..71cd2daf6d9 100644 --- a/src/server/game/Server/Packets/InspectPackets.cpp +++ b/src/server/game/Server/Packets/InspectPackets.cpp @@ -20,12 +20,14 @@ #include "Item.h" #include "Player.h" -void WorldPackets::Inspect::Inspect::Read() +namespace WorldPackets::Inspect +{ +void Inspect::Read() { _worldPacket >> Target; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::InspectEnchantData const& enchantData) +ByteBuffer& operator<<(ByteBuffer& data, InspectEnchantData const& enchantData) { data << uint32(enchantData.Id); data << uint8(enchantData.Index); @@ -33,7 +35,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::InspectEnchantDa return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::AzeriteEssenceData const& azeriteEssenceData) +ByteBuffer& operator<<(ByteBuffer& data, AzeriteEssenceData const& azeriteEssenceData) { data << uint32(azeriteEssenceData.Index); data << uint32(azeriteEssenceData.AzeriteEssenceID); @@ -44,7 +46,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::AzeriteEssenceDa return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::InspectItemData const& itemData) +ByteBuffer& operator<<(ByteBuffer& data, InspectItemData const& itemData) { data << itemData.CreatorGUID; data << uint8(itemData.Index); @@ -60,19 +62,19 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::InspectItemData data.WriteBits(itemData.Gems.size(), 2); data.FlushBits(); - for (WorldPackets::Inspect::AzeriteEssenceData const& azeriteEssenceData : itemData.AzeriteEssences) + for (AzeriteEssenceData const& azeriteEssenceData : itemData.AzeriteEssences) data << azeriteEssenceData; - for (WorldPackets::Inspect::InspectEnchantData const& enchantData : itemData.Enchants) + for (InspectEnchantData const& enchantData : itemData.Enchants) data << enchantData; - for (WorldPackets::Item::ItemGemData const& gem : itemData.Gems) + for (Item::ItemGemData const& gem : itemData.Gems) data << gem; return data; } -void WorldPackets::Inspect::PlayerModelDisplayInfo::Initialize(Player const* player) +void PlayerModelDisplayInfo::Initialize(Player const* player) { GUID = player->GetGUID(); SpecializationID = player->GetPrimarySpecialization(); @@ -89,7 +91,7 @@ void WorldPackets::Inspect::PlayerModelDisplayInfo::Initialize(Player const* pla Items.emplace_back(item, i); } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::PlayerModelDisplayInfo const& displayInfo) +ByteBuffer& operator<<(ByteBuffer& data, PlayerModelDisplayInfo const& displayInfo) { data << displayInfo.GUID; data << int32(displayInfo.SpecializationID); @@ -101,16 +103,16 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::PlayerModelDispl data << uint32(displayInfo.Customizations.size()); data.WriteString(displayInfo.Name); - for (WorldPackets::Character::ChrCustomizationChoice const& customization : displayInfo.Customizations) + for (Character::ChrCustomizationChoice const& customization : displayInfo.Customizations) data << customization; - for (WorldPackets::Inspect::InspectItemData const& item : displayInfo.Items) + for (InspectItemData const& item : displayInfo.Items) data << item; return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::InspectGuildData const& guildData) +ByteBuffer& operator<<(ByteBuffer& data, InspectGuildData const& guildData) { data << guildData.GuildGUID; data << int32(guildData.NumGuildMembers); @@ -119,9 +121,10 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::InspectGuildData return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::PVPBracketData const& bracket) +ByteBuffer& operator<<(ByteBuffer& data, PVPBracketData const& bracket) { data << uint8(bracket.Bracket); + data << int32(bracket.Unused3); data << int32(bracket.Rating); data << int32(bracket.Rank); data << int32(bracket.WeeklyPlayed); @@ -134,13 +137,26 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::PVPBracketData c data << int32(bracket.WeeklyBestWinPvpTierID); data << int32(bracket.Unused1); data << int32(bracket.Unused2); + data << int32(bracket.RoundsSeasonPlayed); + data << int32(bracket.RoundsSeasonWon); + data << int32(bracket.RoundsWeeklyPlayed); + data << int32(bracket.RoundsWeeklyWon); data.WriteBit(bracket.Disqualified); data.FlushBits(); return data; } -WorldPackets::Inspect::InspectItemData::InspectItemData(::Item const* item, uint8 index) +ByteBuffer& operator<<(ByteBuffer& data, TraitInspectInfo const& traits) +{ + data << int32(traits.Level); + data << int32(traits.ChrSpecializationID); + data << traits.Config; + + return data; +} + +InspectItemData::InspectItemData(::Item const* item, uint8 index) { CreatorGUID = item->GetCreator(); @@ -159,7 +175,7 @@ WorldPackets::Inspect::InspectItemData::InspectItemData(::Item const* item, uint { Gems.emplace_back(); - WorldPackets::Item::ItemGemData& gem = Gems.back(); + Item::ItemGemData& gem = Gems.back(); gem.Slot = i; gem.Item.Initialize(&gemData); } @@ -174,7 +190,7 @@ WorldPackets::Inspect::InspectItemData::InspectItemData(::Item const* item, uint { AzeriteEssences.emplace_back(); - WorldPackets::Inspect::AzeriteEssenceData& essence = AzeriteEssences.back(); + AzeriteEssenceData& essence = AzeriteEssences.back(); essence.Index = slot; essence.AzeriteEssenceID = essences->AzeriteEssenceID[slot]; if (essence.AzeriteEssenceID) @@ -189,7 +205,7 @@ WorldPackets::Inspect::InspectItemData::InspectItemData(::Item const* item, uint } } -WorldPacket const* WorldPackets::Inspect::InspectResult::Write() +WorldPacket const* InspectResult::Write() { _worldPacket << DisplayInfo; _worldPacket << uint32(Glyphs.size()); @@ -221,10 +237,13 @@ WorldPacket const* WorldPackets::Inspect::InspectResult::Write() if (AzeriteLevel) _worldPacket << int32(*AzeriteLevel); + _worldPacket << TalentTraits; + return &_worldPacket; } -void WorldPackets::Inspect::QueryInspectAchievements::Read() +void QueryInspectAchievements::Read() { _worldPacket >> Guid; } +} diff --git a/src/server/game/Server/Packets/InspectPackets.h b/src/server/game/Server/Packets/InspectPackets.h index 94411ef5e07..ac65e1a0785 100644 --- a/src/server/game/Server/Packets/InspectPackets.h +++ b/src/server/game/Server/Packets/InspectPackets.h @@ -24,6 +24,7 @@ #include "ObjectGuid.h" #include "RaceMask.h" #include "SharedDefines.h" +#include "TraitPacketsCommon.h" class Item; class Player; @@ -46,7 +47,7 @@ namespace WorldPackets { InspectEnchantData(uint32 id, uint8 index) : Id(id), Index(index) { } - uint32 Id = 0; + uint32 Id = 0; uint8 Index = 0; }; @@ -95,20 +96,32 @@ namespace WorldPackets struct PVPBracketData { - int32 Rating = 0; - int32 Rank = 0; - int32 WeeklyPlayed = 0; - int32 WeeklyWon = 0; - int32 SeasonPlayed = 0; - int32 SeasonWon = 0; + int32 Rating = 0; + int32 Rank = 0; + int32 WeeklyPlayed = 0; + int32 WeeklyWon = 0; + int32 SeasonPlayed = 0; + int32 SeasonWon = 0; int32 WeeklyBestRating = 0; int32 SeasonBestRating = 0; - int32 PvpTierID = 0; + int32 PvpTierID = 0; int32 WeeklyBestWinPvpTierID = 0; - int32 Unused1 = 0; - int32 Unused2 = 0; - uint8 Bracket = 0; - bool Disqualified = false; + int32 Unused1 = 0; + int32 Unused2 = 0; + int32 Unused3 = 0; + int32 RoundsSeasonPlayed = 0; + int32 RoundsSeasonWon = 0; + int32 RoundsWeeklyPlayed = 0; + int32 RoundsWeeklyWon = 0; + uint8 Bracket = 0; + bool Disqualified = false; + }; + + struct TraitInspectInfo + { + int32 Level = 0; + int32 ChrSpecializationID = 0; + Traits::TraitConfig Config; }; class InspectResult final : public ServerPacket @@ -126,7 +139,7 @@ namespace WorldPackets std::vector<uint16> Talents; std::array<uint16, MAX_PVP_TALENT_SLOTS> PvpTalents; Optional<InspectGuildData> GuildData; - std::array<PVPBracketData, 6> Bracket; + std::array<PVPBracketData, 7> Bracket; Optional<int32> AzeriteLevel; int32 ItemLevel = 0; uint32 LifetimeHK = 0; @@ -134,6 +147,7 @@ namespace WorldPackets uint16 TodayHK = 0; uint16 YesterdayHK = 0; uint8 LifetimeMaxRank = 0; + TraitInspectInfo TalentTraits; }; class QueryInspectAchievements final : public ClientPacket diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp index 1c6c2117e76..c747b94a643 100644 --- a/src/server/game/Server/Packets/ItemPackets.cpp +++ b/src/server/game/Server/Packets/ItemPackets.cpp @@ -258,14 +258,27 @@ WorldPacket const* WorldPackets::Item::ItemPushResult::Write() _worldPacket << uint32(BattlePetBreedQuality); _worldPacket << int32(BattlePetLevel); _worldPacket << ItemGUID; + _worldPacket << uint32(Toasts.size()); + for (UiEventToast const& uiEventToast : Toasts) + _worldPacket << uiEventToast; + _worldPacket.WriteBit(Pushed); _worldPacket.WriteBit(Created); _worldPacket.WriteBits(DisplayText, 3); _worldPacket.WriteBit(IsBonusRoll); _worldPacket.WriteBit(IsEncounterLoot); + _worldPacket.WriteBit(CraftingData.has_value()); + _worldPacket.WriteBit(FirstCraftOperationID.has_value()); _worldPacket.FlushBits(); + _worldPacket << Item; + if (FirstCraftOperationID) + _worldPacket << uint32(*FirstCraftOperationID); + + if (CraftingData) + _worldPacket << *CraftingData; + return &_worldPacket; } diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h index caa18789635..702ed6c8adf 100644 --- a/src/server/game/Server/Packets/ItemPackets.h +++ b/src/server/game/Server/Packets/ItemPackets.h @@ -19,6 +19,7 @@ #define ItemPackets_h__ #include "Packet.h" +#include "CraftingPacketsCommon.h" #include "DBCEnums.h" #include "ItemDefines.h" #include "ItemPacketsCommon.h" @@ -345,12 +346,15 @@ namespace WorldPackets // only set if different than real ID (similar to CreatureTemplate.KillCredit) int32 Quantity = 0; int32 QuantityInInventory = 0; - int32 DungeonEncounterID = 0; + int32 DungeonEncounterID = 0; int32 BattlePetSpeciesID = 0; int32 BattlePetBreedID = 0; uint32 BattlePetBreedQuality = 0; int32 BattlePetLevel = 0; ObjectGuid ItemGUID; + std::vector<UiEventToast> Toasts; + Optional<Crafting::CraftingData> CraftingData; + Optional<uint32> FirstCraftOperationID; bool Pushed = false; DisplayType DisplayText = DISPLAY_TYPE_HIDDEN; bool Created = false; diff --git a/src/server/game/Server/Packets/ItemPacketsCommon.cpp b/src/server/game/Server/Packets/ItemPacketsCommon.cpp index a022a0b3783..70da5777d07 100644 --- a/src/server/game/Server/Packets/ItemPacketsCommon.cpp +++ b/src/server/game/Server/Packets/ItemPacketsCommon.cpp @@ -20,9 +20,7 @@ #include "Loot.h" #include "Player.h" -namespace WorldPackets -{ -namespace Item +namespace WorldPackets::Item { bool ItemBonuses::operator==(ItemBonuses const& r) const { @@ -51,7 +49,7 @@ bool ItemModList::operator==(ItemModList const& r) const void ItemInstance::Initialize(::Item const* item) { ItemID = item->GetEntry(); - std::vector<int32> const& bonusListIds = item->m_itemData->BonusListIDs; + std::vector<int32> const& bonusListIds = item->GetBonusListIDs(); if (!bonusListIds.empty()) { ItemBonus.emplace(); @@ -126,6 +124,20 @@ bool ItemInstance::operator==(ItemInstance const& r) const return true; } +bool ItemBonusKey::operator==(ItemBonusKey const& right) const +{ + if (ItemID != right.ItemID) + return false; + + if (BonusListIDs != right.BonusListIDs) + return false; + + if (Modifications != right.Modifications) + return false; + + return true; +} + ByteBuffer& operator<<(ByteBuffer& data, ItemBonuses const& itemBonusInstanceData) { data << uint8(itemBonusInstanceData.Context); @@ -224,6 +236,21 @@ ByteBuffer& operator>>(ByteBuffer& data, ItemInstance& itemInstance) return data; } +ByteBuffer& operator<<(ByteBuffer& data, ItemBonusKey const& itemBonusKey) +{ + data << int32(itemBonusKey.ItemID); + data << uint32(itemBonusKey.BonusListIDs.size()); + data << uint32(itemBonusKey.Modifications.size()); + + if (!itemBonusKey.BonusListIDs.empty()) + data.append(itemBonusKey.BonusListIDs.data(), itemBonusKey.BonusListIDs.size()); + + for (ItemMod const& modification : itemBonusKey.Modifications) + data << modification; + + return data; +} + ByteBuffer& operator<<(ByteBuffer& data, ItemEnchantData const& itemEnchantData) { data << int32(itemEnchantData.ID); @@ -259,5 +286,12 @@ ByteBuffer& operator>>(ByteBuffer& data, InvUpdate& invUpdate) return data; } + +ByteBuffer& operator<<(ByteBuffer& data, UiEventToast const& uiEventToast) +{ + data << int32(uiEventToast.UiEventToastID); + data << int32(uiEventToast.Asset); + + return data; } } diff --git a/src/server/game/Server/Packets/ItemPacketsCommon.h b/src/server/game/Server/Packets/ItemPacketsCommon.h index 2131d8ae7a5..b70cb8b1491 100644 --- a/src/server/game/Server/Packets/ItemPacketsCommon.h +++ b/src/server/game/Server/Packets/ItemPacketsCommon.h @@ -82,6 +82,16 @@ namespace WorldPackets bool operator!=(ItemInstance const& r) const { return !(*this == r); } }; + struct ItemBonusKey + { + int32 ItemID = 0; + std::vector<int32> BonusListIDs; + std::vector<ItemMod> Modifications; + + bool operator==(ItemBonusKey const& right) const; + bool operator!=(ItemBonusKey const& r) const { return !(*this == r); } + }; + struct ItemEnchantData { ItemEnchantData(int32 id, uint32 expiration, int32 charges, uint8 slot) : ID(id), Expiration(expiration), Charges(charges), Slot(slot) { } @@ -107,23 +117,27 @@ namespace WorldPackets std::vector<InvItem> Items; }; - } -} -namespace WorldPackets -{ -namespace Item -{ -ByteBuffer& operator<<(ByteBuffer& data, ItemInstance const& itemInstance); -ByteBuffer& operator>>(ByteBuffer& data, ItemInstance& itemInstance); + struct UiEventToast + { + int32 UiEventToastID = 0; + int32 Asset = 0; + }; -ByteBuffer& operator<<(ByteBuffer& data, ItemEnchantData const& itemEnchantData); + ByteBuffer& operator<<(ByteBuffer& data, ItemEnchantData const& itemEnchantData); -ByteBuffer& operator<<(ByteBuffer& data, ItemGemData const& itemGemInstanceData); -ByteBuffer& operator>>(ByteBuffer& data, ItemGemData& itemGemInstanceData); + ByteBuffer& operator<<(ByteBuffer& data, ItemGemData const& itemGemInstanceData); + ByteBuffer& operator>>(ByteBuffer& data, ItemGemData& itemGemInstanceData); -ByteBuffer& operator>>(ByteBuffer& data, InvUpdate& invUpdate); -} + ByteBuffer& operator<<(ByteBuffer& data, ItemInstance const& itemInstance); + ByteBuffer& operator>>(ByteBuffer& data, ItemInstance& itemInstance); + + ByteBuffer& operator<<(ByteBuffer& data, ItemBonusKey const& itemBonusKey); + + ByteBuffer& operator>>(ByteBuffer& data, InvUpdate& invUpdate); + + ByteBuffer& operator<<(ByteBuffer& data, UiEventToast const& uiEventToast); + } } #endif // ItemPacketsCommon_h__ diff --git a/src/server/game/Server/Packets/LootPackets.cpp b/src/server/game/Server/Packets/LootPackets.cpp index 5c06b7bd41f..ee205ab1908 100644 --- a/src/server/game/Server/Packets/LootPackets.cpp +++ b/src/server/game/Server/Packets/LootPackets.cpp @@ -33,6 +33,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Loot::LootItemData const& void WorldPackets::Loot::LootUnit::Read() { _worldPacket >> Unit; + IsSoftInteract = _worldPacket.ReadBit(); } WorldPacket const* WorldPackets::Loot::LootResponse::Write() @@ -168,6 +169,7 @@ WorldPacket const* WorldPackets::Loot::StartLootRoll::Write() _worldPacket << int32(MapID); _worldPacket << RollTime; _worldPacket << uint8(ValidRolls); + _worldPacket.append(LootRollIneligibleReason.data(), LootRollIneligibleReason.size()); _worldPacket << uint8(Method); _worldPacket << Item; diff --git a/src/server/game/Server/Packets/LootPackets.h b/src/server/game/Server/Packets/LootPackets.h index 794e5ca3212..a69b36586c9 100644 --- a/src/server/game/Server/Packets/LootPackets.h +++ b/src/server/game/Server/Packets/LootPackets.h @@ -22,6 +22,8 @@ #include "ObjectGuid.h" #include "ItemPacketsCommon.h" +enum class LootRollIneligibilityReason : uint32; + namespace WorldPackets { namespace Loot @@ -34,6 +36,7 @@ namespace WorldPackets void Read() override; ObjectGuid Unit; + bool IsSoftInteract = false; }; struct LootItemData @@ -221,6 +224,7 @@ namespace WorldPackets Duration<Milliseconds, uint32> RollTime; uint8 Method = 0; uint8 ValidRolls = 0; + std::array<LootRollIneligibilityReason, 4> LootRollIneligibleReason = { }; LootItemData Item; }; diff --git a/src/server/game/Server/Packets/MailPackets.cpp b/src/server/game/Server/Packets/MailPackets.cpp index e916410f78b..712f174bd39 100644 --- a/src/server/game/Server/Packets/MailPackets.cpp +++ b/src/server/game/Server/Packets/MailPackets.cpp @@ -277,10 +277,3 @@ WorldPacket const* WorldPackets::Mail::NotifyReceivedMail::Write() return &_worldPacket; } - -WorldPacket const* WorldPackets::Mail::ShowMailbox::Write() -{ - _worldPacket << PostmasterGUID; - - return &_worldPacket; -} diff --git a/src/server/game/Server/Packets/MailPackets.h b/src/server/game/Server/Packets/MailPackets.h index c7cb29bf4c0..5c65dce692e 100644 --- a/src/server/game/Server/Packets/MailPackets.h +++ b/src/server/game/Server/Packets/MailPackets.h @@ -235,16 +235,6 @@ namespace WorldPackets float Delay = 0.0f; }; - - class ShowMailbox final : public ServerPacket - { - public: - ShowMailbox() : ServerPacket(SMSG_SHOW_MAILBOX, 16) { } - - WorldPacket const* Write() override; - - ObjectGuid PostmasterGUID; - }; } } diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index bfbe9f748a4..dc07825fdf5 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -53,11 +53,13 @@ WorldPacket const* WorldPackets::Misc::SetCurrency::Write() _worldPacket.WriteBit(WeeklyQuantity.has_value()); _worldPacket.WriteBit(TrackedQuantity.has_value()); _worldPacket.WriteBit(MaxQuantity.has_value()); - _worldPacket.WriteBit(Unused901.has_value()); + _worldPacket.WriteBit(TotalEarned.has_value()); _worldPacket.WriteBit(SuppressChatLog); _worldPacket.WriteBit(QuantityChange.has_value()); - _worldPacket.WriteBit(QuantityGainSource.has_value()); _worldPacket.WriteBit(QuantityLostSource.has_value()); + _worldPacket.WriteBit(QuantityGainSource.has_value()); + _worldPacket.WriteBit(FirstCraftOperationID.has_value()); + _worldPacket.WriteBit(LastSpendTime.has_value()); _worldPacket.FlushBits(); if (WeeklyQuantity) @@ -69,17 +71,23 @@ WorldPacket const* WorldPackets::Misc::SetCurrency::Write() if (MaxQuantity) _worldPacket << int32(*MaxQuantity); - if (Unused901) - _worldPacket << int32(*Unused901); + if (TotalEarned) + _worldPacket << int32(*TotalEarned); if (QuantityChange) _worldPacket << int32(*QuantityChange); + if (QuantityLostSource) + _worldPacket << int32(*QuantityLostSource); + if (QuantityGainSource) _worldPacket << int32(*QuantityGainSource); - if (QuantityLostSource) - _worldPacket << int32(*QuantityLostSource); + if (FirstCraftOperationID) + _worldPacket << uint32(*FirstCraftOperationID); + + if (LastSpendTime) + _worldPacket << *LastSpendTime; return &_worldPacket; } @@ -102,7 +110,8 @@ WorldPacket const* WorldPackets::Misc::SetupCurrency::Write() _worldPacket.WriteBit(data.MaxWeeklyQuantity.has_value()); _worldPacket.WriteBit(data.TrackedQuantity.has_value()); _worldPacket.WriteBit(data.MaxQuantity.has_value()); - _worldPacket.WriteBit(data.Unused901.has_value()); + _worldPacket.WriteBit(data.TotalEarned.has_value()); + _worldPacket.WriteBit(data.LastSpendTime.has_value()); _worldPacket.WriteBits(data.Flags, 5); _worldPacket.FlushBits(); @@ -114,8 +123,10 @@ WorldPacket const* WorldPackets::Misc::SetupCurrency::Write() _worldPacket << uint32(*data.TrackedQuantity); if (data.MaxQuantity) _worldPacket << int32(*data.MaxQuantity); - if (data.Unused901) - _worldPacket << int32(*data.Unused901); + if (data.TotalEarned) + _worldPacket << int32(*data.TotalEarned); + if (data.LastSpendTime) + _worldPacket << *data.LastSpendTime; } return &_worldPacket; @@ -321,13 +332,6 @@ WorldPacket const* WorldPackets::Misc::PlayerBound::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Misc::BinderConfirm::Write() -{ - _worldPacket << Unit; - - return &_worldPacket; -} - WorldPacket const* WorldPackets::Misc::StartMirrorTimer::Write() { _worldPacket << int32(Timer); diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index ead73143901..f4b089371b7 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -63,17 +63,6 @@ namespace WorldPackets uint32 AreaID = 0; }; - class BinderConfirm final : public ServerPacket - { - public: - BinderConfirm() : ServerPacket(SMSG_BINDER_CONFIRM, 16) { } - BinderConfirm(ObjectGuid unit) : ServerPacket(SMSG_BINDER_CONFIRM, 16), Unit(unit) { } - - WorldPacket const* Write() override; - - ObjectGuid Unit; - }; - class InvalidatePlayer final : public ServerPacket { public: @@ -116,13 +105,16 @@ namespace WorldPackets int32 Type = 0; int32 Quantity = 0; uint32 Flags = 0; + std::vector<Item::UiEventToast> Toasts; Optional<int32> WeeklyQuantity; Optional<int32> TrackedQuantity; Optional<int32> MaxQuantity; - Optional<int32> Unused901; + Optional<int32> TotalEarned; Optional<int32> QuantityChange; Optional<int32> QuantityGainSource; Optional<int32> QuantityLostSource; + Optional<uint32> FirstCraftOperationID; + Optional<Timestamp<>> LastSpendTime; bool SuppressChatLog = false; }; @@ -147,7 +139,8 @@ namespace WorldPackets Optional<int32> MaxWeeklyQuantity; // Weekly Currency cap. Optional<int32> TrackedQuantity; Optional<int32> MaxQuantity; - Optional<int32> Unused901; + Optional<int32> TotalEarned; + Optional<Timestamp<>> LastSpendTime; uint8 Flags = 0; // 0 = none, }; diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index c631249f01a..391be953ee7 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -29,6 +29,7 @@ ByteBuffer& operator<<(ByteBuffer& data, MovementInfo const& movementInfo) bool hasFallData = hasFallDirection || movementInfo.jump.fallTime != 0; bool hasSpline = false; // todo 6.x send this infos bool hasInertia = movementInfo.inertia.has_value(); + bool hasAdvFlying = movementInfo.advFlying.has_value(); data << movementInfo.guid; data << uint32(movementInfo.flags); @@ -57,6 +58,7 @@ ByteBuffer& operator<<(ByteBuffer& data, MovementInfo const& movementInfo) data.WriteBit(false); // HeightChangeFailed data.WriteBit(false); // RemoteTimeValid data.WriteBit(hasInertia); + data.WriteBit(hasAdvFlying); data.FlushBits(); @@ -65,11 +67,17 @@ ByteBuffer& operator<<(ByteBuffer& data, MovementInfo const& movementInfo) if (hasInertia) { - data << movementInfo.inertia->guid; + data << uint32(movementInfo.inertia->id); data << movementInfo.inertia->force.PositionXYZStream(); data << uint32(movementInfo.inertia->lifetime); } + if (hasAdvFlying) + { + data << float(movementInfo.advFlying->forwardVelocity); + data << float(movementInfo.advFlying->upVelocity); + } + if (hasFallData) { data << uint32(movementInfo.jump.fallTime); @@ -120,6 +128,7 @@ ByteBuffer& operator>>(ByteBuffer& data, MovementInfo& movementInfo) data.ReadBit(); // HeightChangeFailed data.ReadBit(); // RemoteTimeValid bool hasInertia = data.ReadBit(); + bool hasAdvFlying = data.ReadBit(); if (hasTransport) data >> movementInfo.transport; @@ -128,11 +137,19 @@ ByteBuffer& operator>>(ByteBuffer& data, MovementInfo& movementInfo) { movementInfo.inertia.emplace(); - data >> movementInfo.inertia->guid; + data >> movementInfo.inertia->id; data >> movementInfo.inertia->force.PositionXYZStream(); data >> movementInfo.inertia->lifetime; } + if (hasAdvFlying) + { + movementInfo.advFlying.emplace(); + + data >> movementInfo.advFlying->forwardVelocity; + data >> movementInfo.advFlying->upVelocity; + } + if (hasFall) { data >> movementInfo.jump.fallTime; @@ -1008,12 +1025,13 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MoveSetCompound data << uint16(stateChange.MessageID); data << uint32(stateChange.SequenceIndex); data.WriteBit(stateChange.Speed.has_value()); + data.WriteBit(stateChange.SpeedRange.has_value()); data.WriteBit(stateChange.KnockBack.has_value()); data.WriteBit(stateChange.VehicleRecID.has_value()); data.WriteBit(stateChange.CollisionHeight.has_value()); data.WriteBit(stateChange.MovementForce_.has_value()); data.WriteBit(stateChange.MovementForceGUID.has_value()); - data.WriteBit(stateChange.MovementInertiaGUID.has_value()); + data.WriteBit(stateChange.MovementInertiaID.has_value()); data.WriteBit(stateChange.MovementInertiaLifetimeMs.has_value()); data.FlushBits(); @@ -1023,6 +1041,12 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MoveSetCompound if (stateChange.Speed) data << float(*stateChange.Speed); + if (stateChange.SpeedRange) + { + data << float(stateChange.SpeedRange->Min); + data << float(stateChange.SpeedRange->Max); + } + if (stateChange.KnockBack) { data << float(stateChange.KnockBack->HorzSpeed); @@ -1043,8 +1067,8 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MoveSetCompound if (stateChange.MovementForceGUID) data << *stateChange.MovementForceGUID; - if (stateChange.MovementInertiaGUID) - data << *stateChange.MovementInertiaGUID; + if (stateChange.MovementInertiaID) + data << int32(*stateChange.MovementInertiaID); if (stateChange.MovementInertiaLifetimeMs) data << uint32(*stateChange.MovementInertiaLifetimeMs); diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index 8b114cb0e1f..e9421952c33 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -670,6 +670,12 @@ namespace WorldPackets float InitVertSpeed = 0.0f; }; + struct SpeedRange + { + float Min = 0.0f; + float Max = 0.0f; + }; + struct MoveStateChange { MoveStateChange(OpcodeServer messageId, uint32 sequenceIndex) : MessageID(messageId), SequenceIndex(sequenceIndex) { } @@ -677,12 +683,13 @@ namespace WorldPackets uint16 MessageID = 0; uint32 SequenceIndex = 0; Optional<float> Speed; + Optional<SpeedRange> SpeedRange; Optional<KnockBackInfo> KnockBack; Optional<int32> VehicleRecID; Optional<CollisionHeightInfo> CollisionHeight; Optional<MovementForce> MovementForce_; Optional<ObjectGuid> MovementForceGUID; - Optional<ObjectGuid> MovementInertiaGUID; + Optional<int32> MovementInertiaID; Optional<uint32> MovementInertiaLifetimeMs; }; diff --git a/src/server/game/Server/Packets/MythicPlusPacketsCommon.h b/src/server/game/Server/Packets/MythicPlusPacketsCommon.h index eaf56d5344d..c9f921a21ec 100644 --- a/src/server/game/Server/Packets/MythicPlusPacketsCommon.h +++ b/src/server/game/Server/Packets/MythicPlusPacketsCommon.h @@ -82,7 +82,6 @@ namespace WorldPackets int32 MapChallengeModeID = 0; std::vector<DungeonScoreBestRunForAffix> BestRuns; float OverAllScore = 0.0f; - }; struct DungeonScoreSeasonData diff --git a/src/server/game/Server/Packets/NPCPackets.cpp b/src/server/game/Server/Packets/NPCPackets.cpp index 74551b6380b..7a6d003e4a3 100644 --- a/src/server/game/Server/Packets/NPCPackets.cpp +++ b/src/server/game/Server/Packets/NPCPackets.cpp @@ -18,10 +18,56 @@ #include "NPCPackets.h" #include "Util.h" -namespace WorldPackets +namespace WorldPackets::NPC { -namespace NPC +ByteBuffer& operator<<(ByteBuffer& data, TreasureItem const& treasureItem) +{ + data.WriteBits(AsUnderlyingType(treasureItem.Type), 1); + data << int32(treasureItem.ID); + data << int32(treasureItem.Quantity); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, TreasureLootList const& treasureLootList) { + data << uint32(treasureLootList.Items.size()); + for (TreasureItem const& treasureItem : treasureLootList.Items) + data << treasureItem; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, ClientGossipOptions const& gossipOption) +{ + data << int32(gossipOption.GossipOptionID); + data << uint8(gossipOption.OptionNPC); + data << int8(gossipOption.OptionFlags); + data << int32(gossipOption.OptionCost); + data << uint32(gossipOption.OptionLanguage); + data << int32(gossipOption.Flags); + data << int32(gossipOption.OrderIndex); + data.WriteBits(gossipOption.Text.size(), 12); + data.WriteBits(gossipOption.Confirm.size(), 12); + data.WriteBits(AsUnderlyingType(gossipOption.Status), 2); + data.WriteBit(gossipOption.SpellID.has_value()); + data.WriteBit(gossipOption.OverrideIconID.has_value()); + data.FlushBits(); + + data << gossipOption.Treasure; + + data.WriteString(gossipOption.Text); + data.WriteString(gossipOption.Confirm); + + if (gossipOption.SpellID) + data << int32(*gossipOption.SpellID); + + if (*gossipOption.OverrideIconID) + data << int32(*gossipOption.OverrideIconID); + + return data; +} + ByteBuffer& operator<<(ByteBuffer& data, ClientGossipText const& gossipText) { data << int32(gossipText.QuestID); @@ -44,22 +90,14 @@ void Hello::Read() _worldPacket >> Unit; } -ByteBuffer& operator<<(ByteBuffer& data, TreasureItem const& treasureItem) -{ - data.WriteBits(AsUnderlyingType(treasureItem.Type), 1); - data << int32(treasureItem.ID); - data << int32(treasureItem.Quantity); - - return data; -} - -ByteBuffer& operator<<(ByteBuffer& data, TreasureLootList const& treasureLootList) +WorldPacket const* NPCInteractionOpenResult::Write() { - data << uint32(treasureLootList.Items.size()); - for (TreasureItem const& treasureItem : treasureLootList.Items) - data << treasureItem; + _worldPacket << Npc; + _worldPacket << int32(InteractionType); + _worldPacket.WriteBit(Success); + _worldPacket.FlushBits(); - return data; + return &_worldPacket; } WorldPacket const* GossipMessage::Write() @@ -67,31 +105,20 @@ WorldPacket const* GossipMessage::Write() _worldPacket << GossipGUID; _worldPacket << int32(GossipID); _worldPacket << int32(FriendshipFactionID); - _worldPacket << int32(TextID); _worldPacket << uint32(GossipOptions.size()); _worldPacket << uint32(GossipText.size()); + _worldPacket.WriteBit(TextID.has_value()); + _worldPacket.WriteBit(TextID2.has_value()); + _worldPacket.FlushBits(); for (ClientGossipOptions const& options : GossipOptions) - { - _worldPacket << int32(options.ClientOption); - _worldPacket << uint8(options.OptionNPC); - _worldPacket << int8(options.OptionFlags); - _worldPacket << int32(options.OptionCost); - _worldPacket << uint32(options.OptionLanguage); - _worldPacket.WriteBits(options.Text.size(), 12); - _worldPacket.WriteBits(options.Confirm.size(), 12); - _worldPacket.WriteBits(AsUnderlyingType(options.Status), 2); - _worldPacket.WriteBit(options.SpellID.has_value()); - _worldPacket.FlushBits(); - - _worldPacket << options.Treasure; - - _worldPacket.WriteString(options.Text); - _worldPacket.WriteString(options.Confirm); - - if (options.SpellID) - _worldPacket << int32(*options.SpellID); - } + _worldPacket << options; + + if (TextID) + _worldPacket << int32(*TextID); + + if (TextID2) + _worldPacket << int32(*TextID2); for (ClientGossipText const& text : GossipText) _worldPacket << text; @@ -101,20 +128,21 @@ WorldPacket const* GossipMessage::Write() ByteBuffer& operator<<(ByteBuffer& data, VendorItem const& item) { - data << uint32(item.MuID); - data << int32(item.Type); - data << int32(item.Quantity); data << uint64(item.Price); + data << uint32(item.MuID); data << int32(item.Durability); data << int32(item.StackCount); + data << int32(item.Quantity); data << int32(item.ExtendedCostID); data << int32(item.PlayerConditionFailed); - data << item.Item; + data.WriteBits(item.Type, 3); data.WriteBit(item.Locked); data.WriteBit(item.DoNotFilterOnVendor); data.WriteBit(item.Refundable); data.FlushBits(); + data << item.Item; + return data; } @@ -154,34 +182,33 @@ WorldPacket const* TrainerList::Write() return &_worldPacket; } -WorldPacket const* ShowBank::Write() -{ - _worldPacket << Guid; - - return &_worldPacket; -} - void GossipSelectOption::Read() { _worldPacket >> GossipUnit; _worldPacket >> GossipID; - _worldPacket >> GossipIndex; + _worldPacket >> GossipOptionID; uint32 length = _worldPacket.ReadBits(8); PromotionCode = _worldPacket.ReadString(length); } -WorldPacket const* GossipComplete::Write() +WorldPacket const* GossipOptionNPCInteraction::Write() { - _worldPacket.WriteBit(SuppressSound); + _worldPacket << GossipGUID; + _worldPacket << int32(GossipNpcOptionID); + _worldPacket.WriteBit(FriendshipFactionID.has_value()); _worldPacket.FlushBits(); + if (FriendshipFactionID) + _worldPacket << int32(*FriendshipFactionID); + return &_worldPacket; } -WorldPacket const* PlayerTabardVendorActivate::Write() +WorldPacket const* GossipComplete::Write() { - _worldPacket << Vendor; + _worldPacket.WriteBit(SuppressSound); + _worldPacket.FlushBits(); return &_worldPacket; } @@ -206,13 +233,6 @@ void SpiritHealerActivate::Read() _worldPacket >> Healer; } -WorldPacket const* SpiritHealerConfirm::Write() -{ - _worldPacket << Unit; - - return &_worldPacket; -} - void TrainerBuySpell::Read() { _worldPacket >> TrainerGUID; @@ -241,4 +261,3 @@ void SetPetSlot::Read() _worldPacket >> StableMaster; } } -} diff --git a/src/server/game/Server/Packets/NPCPackets.h b/src/server/game/Server/Packets/NPCPackets.h index ab6f04fd4af..cb6666cfa71 100644 --- a/src/server/game/Server/Packets/NPCPackets.h +++ b/src/server/game/Server/Packets/NPCPackets.h @@ -24,9 +24,11 @@ #include "Position.h" #include <array> +enum class GossipOptionFlags : int32; enum class GossipOptionNpc : uint8; enum class GossipOptionStatus : uint8; enum class GossipOptionRewardType : uint8; +enum class PlayerInteractionType : int32; namespace WorldPackets { @@ -49,6 +51,18 @@ namespace WorldPackets ObjectGuid Unit; }; + class TC_GAME_API NPCInteractionOpenResult final : public ServerPacket + { + public: + NPCInteractionOpenResult() : ServerPacket(SMSG_NPC_INTERACTION_OPEN_RESULT, 16 + 4 + 1) { } + + WorldPacket const* Write() override; + + ObjectGuid Npc; + PlayerInteractionType InteractionType = {}; + bool Success = true; + }; + struct TreasureItem { GossipOptionRewardType Type = GossipOptionRewardType(0); @@ -63,16 +77,19 @@ namespace WorldPackets struct ClientGossipOptions { - int32 ClientOption = 0; - GossipOptionNpc OptionNPC = GossipOptionNpc(0); + int32 GossipOptionID = 0; + GossipOptionNpc OptionNPC = {}; uint8 OptionFlags = 0; int32 OptionCost = 0; uint32 OptionLanguage = 0; - GossipOptionStatus Status = GossipOptionStatus(0); - std::string Text; - std::string Confirm; + GossipOptionFlags Flags = {}; + int32 OrderIndex = 0; + GossipOptionStatus Status = {}; + std::string_view Text; + std::string_view Confirm; TreasureLootList Treasure; Optional<int32> SpellID; + Optional<int32> OverrideIconID; }; struct ClientGossipText @@ -98,7 +115,8 @@ namespace WorldPackets int32 FriendshipFactionID = 0; ObjectGuid GossipGUID; std::vector<ClientGossipText> GossipText; - int32 TextID = 0; + Optional<int32> TextID; + Optional<int32> TextID2; int32 GossipID = 0; }; @@ -110,11 +128,23 @@ namespace WorldPackets void Read() override; ObjectGuid GossipUnit; - int32 GossipIndex = 0; + int32 GossipOptionID = 0; int32 GossipID = 0; std::string PromotionCode; }; + class GossipOptionNPCInteraction final : public ServerPacket + { + public: + GossipOptionNPCInteraction() : ServerPacket(SMSG_GOSSIP_OPTION_NPC_INTERACTION, 16 + 4 + 4 + 4) { } + + WorldPacket const* Write() override; + + ObjectGuid GossipGUID; + int32 GossipNpcOptionID = 0; + Optional<int32> FriendshipFactionID; + }; + class GossipComplete final : public ServerPacket { public: @@ -178,26 +208,6 @@ namespace WorldPackets std::string Greeting; }; - class ShowBank final : public ServerPacket - { - public: - ShowBank() : ServerPacket(SMSG_SHOW_BANK, 16) { } - - WorldPacket const* Write() override; - - ObjectGuid Guid; - }; - - class PlayerTabardVendorActivate final : public ServerPacket - { - public: - PlayerTabardVendorActivate() : ServerPacket(SMSG_PLAYER_TABARD_VENDOR_ACTIVATE, 16) { } - - WorldPacket const* Write() override; - - ObjectGuid Vendor; - }; - class GossipPOI final : public ServerPacket { public: @@ -224,16 +234,6 @@ namespace WorldPackets ObjectGuid Healer; }; - class TC_GAME_API SpiritHealerConfirm final : public ServerPacket - { - public: - SpiritHealerConfirm() : ServerPacket(SMSG_SPIRIT_HEALER_CONFIRM, 16) { } - - WorldPacket const* Write() override; - - ObjectGuid Unit; - }; - class TrainerBuySpell final : public ClientPacket { public: diff --git a/src/server/game/Server/Packets/PacketUtilities.h b/src/server/game/Server/Packets/PacketUtilities.h index a4ecc96c08c..f445169784c 100644 --- a/src/server/game/Server/Packets/PacketUtilities.h +++ b/src/server/game/Server/Packets/PacketUtilities.h @@ -78,6 +78,7 @@ namespace WorldPackets public: bool empty() const { return _storage.empty(); } + std::size_t length() const { return _storage.length(); } char const* c_str() const { return _storage.c_str(); } operator std::string_view() const { return _storage; } @@ -132,11 +133,11 @@ namespace WorldPackets /** * Utility class for automated prevention of loop counter spoofing in client packets */ - template<typename T, std::size_t N> + template<typename T, std::size_t N, typename Container = boost::container::static_vector<T, N>> class Array { public: - typedef boost::container::static_vector<T, N> storage_type; + typedef Container storage_type; typedef std::integral_constant<std::size_t, N> max_capacity; diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp index 76d803dbf17..43fd278239f 100644 --- a/src/server/game/Server/Packets/QuestPackets.cpp +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -18,9 +18,7 @@ #include "QuestPackets.h" #include "Util.h" -namespace WorldPackets -{ -namespace Quest +namespace WorldPackets::Quest { ByteBuffer& operator<<(ByteBuffer& data, QuestCompleteDisplaySpell const& questDisplaySpell) { @@ -30,6 +28,18 @@ ByteBuffer& operator<<(ByteBuffer& data, QuestCompleteDisplaySpell const& questD return data; } +ByteBuffer& operator<<(ByteBuffer& data, ConditionalQuestText const& conditionalQuestText) +{ + data << int32(conditionalQuestText.PlayerConditionID); + data << int32(conditionalQuestText.QuestGiverCreatureID); + data.WriteBits(conditionalQuestText.Text.length(), 12); + data.FlushBits(); + + data.WriteString(conditionalQuestText.Text); + + return data; +} + void QuestGiverStatusQuery::Read() { _worldPacket >> QuestGiverGUID; @@ -159,6 +169,10 @@ WorldPacket const* QueryQuestInfoResponse::Write() _worldPacket << int32(Info.Expansion); _worldPacket << int32(Info.ManagedWorldStateID); _worldPacket << int32(Info.QuestSessionBonus); + _worldPacket << int32(Info.QuestGiverCreatureID); + + _worldPacket << uint32(Info.ConditionalQuestDescription.size()); + _worldPacket << uint32(Info.ConditionalQuestCompletionLog.size()); for (QuestCompleteDisplaySpell const& rewardDisplaySpell : Info.RewardDisplaySpell) _worldPacket << rewardDisplaySpell; @@ -205,6 +219,12 @@ WorldPacket const* QueryQuestInfoResponse::Write() _worldPacket.WriteString(Info.PortraitTurnInText); _worldPacket.WriteString(Info.PortraitTurnInName); _worldPacket.WriteString(Info.QuestCompletionLog); + + for (ConditionalQuestText const& conditionalQuestText : Info.ConditionalQuestDescription) + _worldPacket << conditionalQuestText; + + for (ConditionalQuestText const& conditionalQuestText : Info.ConditionalQuestCompletionLog) + _worldPacket << conditionalQuestText; } return &_worldPacket; @@ -315,6 +335,7 @@ ByteBuffer& operator<<(ByteBuffer& data, QuestGiverOfferReward const& offer) data << int32(offer.QuestID); data << int32(offer.QuestFlags[0]); // Flags data << int32(offer.QuestFlags[1]); // FlagsEx + data << int32(offer.QuestFlags[2]); // FlagsEx2 data << int32(offer.SuggestedPartyMembers); data << int32(offer.Emotes.size()); for (QuestDescEmote const& emote : offer.Emotes) @@ -340,6 +361,8 @@ WorldPacket const* QuestGiverOfferRewardMessage::Write() _worldPacket << int32(PortraitGiverMount); _worldPacket << int32(PortraitGiverModelSceneID); _worldPacket << int32(PortraitTurnIn); + _worldPacket << int32(QuestGiverCreatureID); + _worldPacket << uint32(ConditionalRewardText.size()); _worldPacket.WriteBits(QuestTitle.size(), 9); _worldPacket.WriteBits(RewardText.size(), 12); @@ -349,6 +372,9 @@ WorldPacket const* QuestGiverOfferRewardMessage::Write() _worldPacket.WriteBits(PortraitTurnInName.size(), 8); _worldPacket.FlushBits(); + for (ConditionalQuestText const& conditionalQuestText : ConditionalRewardText) + _worldPacket << conditionalQuestText; + _worldPacket.WriteString(QuestTitle); _worldPacket.WriteString(RewardText); _worldPacket.WriteString(PortraitGiverText); @@ -407,12 +433,15 @@ WorldPacket const* QuestGiverQuestDetails::Write() _worldPacket << int32(PortraitTurnIn); _worldPacket << uint32(QuestFlags[0]); // Flags _worldPacket << uint32(QuestFlags[1]); // FlagsEx + _worldPacket << uint32(QuestFlags[2]); // FlagsEx _worldPacket << int32(SuggestedPartyMembers); _worldPacket << uint32(LearnSpells.size()); _worldPacket << uint32(DescEmotes.size()); _worldPacket << uint32(Objectives.size()); _worldPacket << int32(QuestStartItemID); _worldPacket << int32(QuestSessionBonus); + _worldPacket << int32(QuestGiverCreatureID); + _worldPacket << uint32(ConditionalDescriptionText.size()); for (int32 spell : LearnSpells) _worldPacket << int32(spell); @@ -453,6 +482,9 @@ WorldPacket const* QuestGiverQuestDetails::Write() _worldPacket.WriteString(PortraitTurnInText); _worldPacket.WriteString(PortraitTurnInName); + for (ConditionalQuestText const& conditionalQuestText : ConditionalDescriptionText) + _worldPacket << conditionalQuestText; + return &_worldPacket; } @@ -465,6 +497,7 @@ WorldPacket const* QuestGiverRequestItems::Write() _worldPacket << int32(CompEmoteType); _worldPacket << uint32(QuestFlags[0]); _worldPacket << uint32(QuestFlags[1]); + _worldPacket << uint32(QuestFlags[2]); _worldPacket << int32(SuggestPartyMembers); _worldPacket << int32(MoneyToGet); _worldPacket << int32(Collect.size()); @@ -487,10 +520,16 @@ WorldPacket const* QuestGiverRequestItems::Write() _worldPacket.WriteBit(AutoLaunched); _worldPacket.FlushBits(); + _worldPacket << int32(QuestGiverCreatureID); + _worldPacket << uint32(ConditionalCompletionText.size()); + _worldPacket.WriteBits(QuestTitle.size(), 9); _worldPacket.WriteBits(CompletionText.size(), 12); _worldPacket.FlushBits(); + for (ConditionalQuestText const& conditionalQuestText : ConditionalCompletionText) + _worldPacket << conditionalQuestText; + _worldPacket.WriteString(QuestTitle); _worldPacket.WriteString(CompletionText); @@ -773,4 +812,3 @@ void ChoiceResponse::Read() IsReroll = _worldPacket.ReadBit(); } } -} diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h index 630cb3880cc..14c9f25e981 100644 --- a/src/server/game/Server/Packets/QuestPackets.h +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -113,6 +113,13 @@ namespace WorldPackets int32 PlayerConditionID = 0; }; + struct ConditionalQuestText + { + int32 PlayerConditionID = 0; + int32 QuestGiverCreatureID = 0; + std::string_view Text; + }; + struct QuestInfo { int32 QuestID = 0; @@ -171,7 +178,10 @@ namespace WorldPackets int32 Expansion = 0; int32 ManagedWorldStateID = 0; int32 QuestSessionBonus = 0; + int32 QuestGiverCreatureID = 0; // used to select ConditionalQuestText std::vector<QuestObjective> Objectives; + std::vector<ConditionalQuestText> ConditionalQuestDescription; + std::vector<ConditionalQuestText> ConditionalQuestCompletionLog; int32 RewardItems[QUEST_REWARD_ITEM_COUNT] = { }; int32 RewardAmount[QUEST_REWARD_ITEM_COUNT] = { }; int32 ItemDrop[QUEST_ITEM_DROP_COUNT] = { }; @@ -287,7 +297,7 @@ namespace WorldPackets int32 SuggestedPartyMembers = 0; QuestRewards Rewards; std::vector<QuestDescEmote> Emotes; - int32 QuestFlags[2] = { }; // Flags and FlagsEx + int32 QuestFlags[3] = { }; // Flags and FlagsEx }; class QuestGiverOfferRewardMessage final : public ServerPacket @@ -301,12 +311,14 @@ namespace WorldPackets int32 PortraitGiver = 0; int32 PortraitGiverMount = 0; int32 PortraitGiverModelSceneID = 0; + int32 QuestGiverCreatureID = 0; std::string QuestTitle; std::string RewardText; std::string PortraitGiverText; std::string PortraitGiverName; std::string PortraitTurnInText; std::string PortraitTurnInName; + std::vector<ConditionalQuestText> ConditionalRewardText; QuestGiverOfferReward QuestData; int32 QuestPackageID = 0; }; @@ -383,7 +395,7 @@ namespace WorldPackets ObjectGuid InformUnit; int32 QuestID = 0; int32 QuestPackageID = 0; - uint32 QuestFlags[2] = { }; + uint32 QuestFlags[3] = { }; int32 SuggestedPartyMembers = 0; QuestRewards Rewards; std::vector<QuestObjectiveSimple> Objectives; @@ -395,6 +407,7 @@ namespace WorldPackets int32 PortraitGiverModelSceneID = 0; int32 QuestStartItemID = 0; int32 QuestSessionBonus = 0; + int32 QuestGiverCreatureID = 0; std::string PortraitGiverText; std::string PortraitGiverName; std::string PortraitTurnInText; @@ -402,6 +415,7 @@ namespace WorldPackets std::string QuestTitle; std::string LogDescription; std::string DescriptionText; + std::vector<ConditionalQuestText> ConditionalDescriptionText; bool DisplayPopup = false; bool StartCheat = false; bool AutoLaunched = false; @@ -440,9 +454,10 @@ namespace WorldPackets std::vector<QuestObjectiveCollect> Collect; std::vector<QuestCurrency> Currency; int32 StatusFlags = 0; - uint32 QuestFlags[2] = { }; + uint32 QuestFlags[3] = { }; std::string QuestTitle; std::string CompletionText; + std::vector<ConditionalQuestText> ConditionalCompletionText; }; class QuestGiverRequestReward final : public ClientPacket diff --git a/src/server/game/Server/Packets/ReputationPackets.cpp b/src/server/game/Server/Packets/ReputationPackets.cpp index 5029e785cc6..8896c2071c0 100644 --- a/src/server/game/Server/Packets/ReputationPackets.cpp +++ b/src/server/game/Server/Packets/ReputationPackets.cpp @@ -21,7 +21,7 @@ WorldPacket const* WorldPackets::Reputation::InitializeFactions::Write() { for (uint16 i = 0; i < FactionCount; ++i) { - _worldPacket << uint8(FactionFlags[i]); + _worldPacket << uint16(FactionFlags[i]); _worldPacket << int32(FactionStandings[i]); } @@ -58,7 +58,6 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Reputation::FactionStandi WorldPacket const* WorldPackets::Reputation::SetFactionStanding::Write() { - _worldPacket << float(ReferAFriendBonus); _worldPacket << float(BonusFromAchievementSystem); _worldPacket << uint32(Faction.size()); for (FactionStandingData const& factionStanding : Faction) diff --git a/src/server/game/Server/Packets/ReputationPackets.h b/src/server/game/Server/Packets/ReputationPackets.h index b3eecced951..84fe8f001e8 100644 --- a/src/server/game/Server/Packets/ReputationPackets.h +++ b/src/server/game/Server/Packets/ReputationPackets.h @@ -25,23 +25,18 @@ namespace WorldPackets { namespace Reputation { - static uint16 const FactionCount = 400; + static constexpr uint16 FactionCount = 443; class InitializeFactions final : public ServerPacket { public: - InitializeFactions() : ServerPacket(SMSG_INITIALIZE_FACTIONS, FactionCount * (4 + 1) + FactionCount / 8) - { - FactionStandings.fill(0); - FactionHasBonus.fill(false); - FactionFlags.fill(0); - } + InitializeFactions() : ServerPacket(SMSG_INITIALIZE_FACTIONS, FactionCount * (4 + 2) + FactionCount / 8) { } WorldPacket const* Write() override; - std::array<int32, FactionCount> FactionStandings; - std::array<bool, FactionCount> FactionHasBonus; ///< @todo: implement faction bonus - std::array<uint8, FactionCount> FactionFlags; ///< @see enum FactionFlags + std::array<int32, FactionCount> FactionStandings = { }; + std::array<bool, FactionCount> FactionHasBonus = { }; ///< @todo: implement faction bonus + std::array<uint16, FactionCount> FactionFlags = { }; ///< @see enum FactionFlags }; class RequestForcedReactions final : public ClientPacket @@ -84,7 +79,6 @@ namespace WorldPackets WorldPacket const* Write() override; - float ReferAFriendBonus = 0.0f; float BonusFromAchievementSystem = 0.0f; std::vector<FactionStandingData> Faction; bool ShowVisual = false; diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp index ebf38bba3ad..84b5066863f 100644 --- a/src/server/game/Server/Packets/SpellPackets.cpp +++ b/src/server/game/Server/Packets/SpellPackets.cpp @@ -19,30 +19,32 @@ #include "CharacterPackets.h" #include "SpellPackets.h" -void WorldPackets::Spells::CancelAura::Read() +namespace WorldPackets::Spells +{ +void CancelAura::Read() { _worldPacket >> SpellID; _worldPacket >> CasterGUID; } -void WorldPackets::Spells::CancelChannelling::Read() +void CancelChannelling::Read() { _worldPacket >> ChannelSpell; _worldPacket >> Reason; } -void WorldPackets::Spells::CancelModSpeedNoControlAuras::Read() +void CancelModSpeedNoControlAuras::Read() { _worldPacket >> TargetGUID; } -void WorldPackets::Spells::PetCancelAura::Read() +void PetCancelAura::Read() { _worldPacket >> PetGUID; _worldPacket >> SpellID; } -WorldPacket const* WorldPackets::Spells::CategoryCooldown::Write() +WorldPacket const* CategoryCooldown::Write() { _worldPacket.reserve(4 + 8 * CategoryCooldowns.size()); @@ -57,7 +59,7 @@ WorldPacket const* WorldPackets::Spells::CategoryCooldown::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::SendKnownSpells::Write() +WorldPacket const* SendKnownSpells::Write() { _worldPacket.reserve(1 + 4 * KnownSpells.size() + 4 * FavoriteSpells.size()); @@ -74,7 +76,7 @@ WorldPacket const* WorldPackets::Spells::SendKnownSpells::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::UpdateActionButtons::Write() +WorldPacket const* UpdateActionButtons::Write() { _worldPacket.append(ActionButtons.data(), ActionButtons.size()); _worldPacket << Reason; @@ -82,13 +84,13 @@ WorldPacket const* WorldPackets::Spells::UpdateActionButtons::Write() return &_worldPacket; } -void WorldPackets::Spells::SetActionButton::Read() +void SetActionButton::Read() { _worldPacket >> Action; _worldPacket >> Index; } -WorldPacket const* WorldPackets::Spells::SendUnlearnSpells::Write() +WorldPacket const* SendUnlearnSpells::Write() { _worldPacket << uint32(Spells.size()); for (uint32 spellId : Spells) @@ -97,7 +99,7 @@ WorldPacket const* WorldPackets::Spells::SendUnlearnSpells::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::AuraDataInfo const& auraData) +ByteBuffer& operator<<(ByteBuffer& data, AuraDataInfo const& auraData) { data << auraData.CastID; data << int32(auraData.SpellID); @@ -139,7 +141,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::AuraDataInfo cons return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::AuraInfo const& aura) +ByteBuffer& operator<<(ByteBuffer& data, AuraInfo const& aura) { data << aura.Slot; data.WriteBit(aura.AuraData.has_value()); @@ -151,7 +153,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::AuraInfo const& a return data; } -WorldPacket const* WorldPackets::Spells::AuraUpdate::Write() +WorldPacket const* AuraUpdate::Write() { _worldPacket.WriteBit(UpdateAll); _worldPacket.WriteBits(Auras.size(), 9); @@ -163,7 +165,7 @@ WorldPacket const* WorldPackets::Spells::AuraUpdate::Write() return &_worldPacket; } -ByteBuffer& operator>>(ByteBuffer& buffer, Optional<WorldPackets::Spells::TargetLocation>& location) +ByteBuffer& operator>>(ByteBuffer& buffer, Optional<TargetLocation>& location) { location.emplace(); buffer >> location->Transport; @@ -173,11 +175,11 @@ ByteBuffer& operator>>(ByteBuffer& buffer, Optional<WorldPackets::Spells::Target return buffer; } -ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::SpellTargetData& targetData) +ByteBuffer& operator>>(ByteBuffer& buffer, SpellTargetData& targetData) { buffer.ResetBitPos(); - targetData.Flags = buffer.ReadBits(26); + targetData.Flags = buffer.ReadBits(28); bool hasSrcLocation = buffer.ReadBit(); bool hasDstLocation = buffer.ReadBit(); bool hasOrientation = buffer.ReadBit(); @@ -204,28 +206,32 @@ ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::SpellTargetData return buffer; } -ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::MissileTrajectoryRequest& trajectory) +ByteBuffer& operator>>(ByteBuffer& buffer, MissileTrajectoryRequest& trajectory) { buffer >> trajectory.Pitch; buffer >> trajectory.Speed; return buffer; } -ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Spells::SpellOptionalReagent& optionalReagent) +ByteBuffer& operator>>(ByteBuffer& data, SpellCraftingReagent& optionalReagent) { data >> optionalReagent.ItemID; - data >> optionalReagent.Slot; + data >> optionalReagent.DataSlotIndex; + data >> optionalReagent.Quantity; + if (data.ReadBit()) + optionalReagent.Unknown_1000 = data.read<uint8>(); + return data; } -ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Spells::SpellExtraCurrencyCost& extraCurrencyCost) +ByteBuffer& operator>>(ByteBuffer& data, SpellExtraCurrencyCost& extraCurrencyCost) { data >> extraCurrencyCost.CurrencyID; data >> extraCurrencyCost.Count; return data; } -ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::SpellCastRequest& request) +ByteBuffer& operator>>(ByteBuffer& buffer, SpellCastRequest& request) { buffer >> request.CastID; buffer >> request.Misc[0]; @@ -234,27 +240,31 @@ ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::SpellCastReques buffer >> request.Visual; buffer >> request.MissileTrajectory; buffer >> request.CraftingNPC; - request.OptionalReagents.resize(buffer.read<uint32>()); request.OptionalCurrencies.resize(buffer.read<uint32>()); + request.OptionalReagents.resize(buffer.read<uint32>()); - for (WorldPackets::Spells::SpellOptionalReagent& optionalReagent : request.OptionalReagents) - buffer >> optionalReagent; - - for (WorldPackets::Spells::SpellExtraCurrencyCost& optionalCurrency : request.OptionalCurrencies) + for (SpellExtraCurrencyCost& optionalCurrency : request.OptionalCurrencies) buffer >> optionalCurrency; request.SendCastFlags = buffer.ReadBits(5); bool hasMoveUpdate = buffer.ReadBit(); request.Weight.resize(buffer.ReadBits(2)); + bool hasCraftingOrderID = buffer.ReadBit(); buffer >> request.Target; + if (hasCraftingOrderID) + request.CraftingOrderID = buffer.read<uint64>(); + + for (SpellCraftingReagent& optionalReagent : request.OptionalReagents) + buffer >> optionalReagent; + if (hasMoveUpdate) { request.MoveUpdate.emplace(); buffer >> *request.MoveUpdate; } - for (WorldPackets::Spells::SpellWeight& weight : request.Weight) + for (SpellWeight& weight : request.Weight) { buffer.ResetBitPos(); weight.Type = buffer.ReadBits(2); @@ -265,18 +275,18 @@ ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::SpellCastReques return buffer; } -void WorldPackets::Spells::CastSpell::Read() +void CastSpell::Read() { _worldPacket >> Cast; } -void WorldPackets::Spells::PetCastSpell::Read() +void PetCastSpell::Read() { _worldPacket >> PetGUID; _worldPacket >> Cast; } -void WorldPackets::Spells::UseItem::Read() +void UseItem::Read() { _worldPacket >> PackSlot; _worldPacket >> Slot; @@ -284,7 +294,7 @@ void WorldPackets::Spells::UseItem::Read() _worldPacket >> Cast; } -WorldPacket const* WorldPackets::Spells::SpellPrepare::Write() +WorldPacket const* SpellPrepare::Write() { _worldPacket << ClientCastID; _worldPacket << ServerCastID; @@ -292,7 +302,7 @@ WorldPacket const* WorldPackets::Spells::SpellPrepare::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::TargetLocation const& targetLocation) +ByteBuffer& operator<<(ByteBuffer& data, TargetLocation const& targetLocation) { data << targetLocation.Transport; data << float(targetLocation.Location.m_positionX); @@ -301,9 +311,9 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::TargetLocation co return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellTargetData const& spellTargetData) +ByteBuffer& operator<<(ByteBuffer& data, SpellTargetData const& spellTargetData) { - data.WriteBits(spellTargetData.Flags, 26); + data.WriteBits(spellTargetData.Flags, 28); data.WriteBit(spellTargetData.SrcLocation.has_value()); data.WriteBit(spellTargetData.DstLocation.has_value()); data.WriteBit(spellTargetData.Orientation.has_value()); @@ -331,7 +341,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellTargetData c return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellMissStatus const& spellMissStatus) +ByteBuffer& operator<<(ByteBuffer& data, SpellMissStatus const& spellMissStatus) { data.WriteBits(spellMissStatus.Reason, 4); if (spellMissStatus.Reason == SPELL_MISS_REFLECT) @@ -341,20 +351,20 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellMissStatus c return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellHitStatus const& spellHitStatus) +ByteBuffer& operator<<(ByteBuffer& data, SpellHitStatus const& spellHitStatus) { data << uint8(spellHitStatus.Reason); return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellPowerData const& spellPowerData) +ByteBuffer& operator<<(ByteBuffer& data, SpellPowerData const& spellPowerData) { data << int32(spellPowerData.Cost); data << int8(spellPowerData.Type); return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::RuneData const& runeData) +ByteBuffer& operator<<(ByteBuffer& data, RuneData const& runeData) { data << uint8(runeData.Start); data << uint8(runeData.Count); @@ -365,28 +375,28 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::RuneData const& r return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::MissileTrajectoryResult const& missileTrajectory) +ByteBuffer& operator<<(ByteBuffer& data, MissileTrajectoryResult const& missileTrajectory) { data << uint32(missileTrajectory.TravelTime); data << float(missileTrajectory.Pitch); return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellAmmo const& spellAmmo) +ByteBuffer& operator<<(ByteBuffer& data, SpellAmmo const& spellAmmo) { data << int32(spellAmmo.DisplayID); data << int8(spellAmmo.InventoryType); return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::CreatureImmunities const& immunities) +ByteBuffer& operator<<(ByteBuffer& data, CreatureImmunities const& immunities) { data << int32(immunities.School); data << int32(immunities.Value); return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellHealPrediction const& spellPred) +ByteBuffer& operator<<(ByteBuffer& data, SpellHealPrediction const& spellPred) { data << int32(spellPred.Points); data << uint8(spellPred.Type); @@ -394,7 +404,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellHealPredicti return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastData const& spellCastData) +ByteBuffer& operator<<(ByteBuffer& data, SpellCastData const& spellCastData) { data << spellCastData.CasterGUID; data << spellCastData.CasterUnit; @@ -419,7 +429,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastData con data.WriteBits(spellCastData.TargetPoints.size(), 16); data.FlushBits(); - for (WorldPackets::Spells::SpellMissStatus const& missStatus : spellCastData.MissStatus) + for (SpellMissStatus const& missStatus : spellCastData.MissStatus) data << missStatus; data << spellCastData.Target; @@ -430,29 +440,29 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastData con for (ObjectGuid const& missTarget : spellCastData.MissTargets) data << missTarget; - for (WorldPackets::Spells::SpellHitStatus const& hitStatus : spellCastData.HitStatus) + for (SpellHitStatus const& hitStatus : spellCastData.HitStatus) data << hitStatus; - for (WorldPackets::Spells::SpellPowerData const& power : spellCastData.RemainingPower) + for (SpellPowerData const& power : spellCastData.RemainingPower) data << power; if (spellCastData.RemainingRunes) data << *spellCastData.RemainingRunes; - for (WorldPackets::Spells::TargetLocation const& targetLoc : spellCastData.TargetPoints) + for (TargetLocation const& targetLoc : spellCastData.TargetPoints) data << targetLoc; return data; } -WorldPacket const* WorldPackets::Spells::SpellStart::Write() +WorldPacket const* SpellStart::Write() { _worldPacket << Cast; return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::SpellGo::Write() +WorldPacket const* SpellGo::Write() { *this << Cast; @@ -464,42 +474,51 @@ WorldPacket const* WorldPackets::Spells::SpellGo::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::LearnedSpells::Write() +ByteBuffer& operator<<(ByteBuffer& data, LearnedSpellInfo const& learnedSpellInfo) { - _worldPacket << uint32(SpellID.size()); - _worldPacket << uint32(FavoriteSpellID.size()); - _worldPacket << uint32(SpecializationID); - for (int32 spell : SpellID) - _worldPacket << spell; + data << int32(learnedSpellInfo.SpellID); + data.WriteBit(learnedSpellInfo.IsFavorite); + data.WriteBit(learnedSpellInfo.field_8.has_value()); + data.WriteBit(learnedSpellInfo.Superceded.has_value()); + data.WriteBit(learnedSpellInfo.TraitDefinitionID.has_value()); + data.FlushBits(); - for (int32 spell : FavoriteSpellID) - _worldPacket << spell; + if (learnedSpellInfo.field_8) + data << int32(*learnedSpellInfo.field_8); + + if (learnedSpellInfo.Superceded) + data << int32(*learnedSpellInfo.Superceded); + if (learnedSpellInfo.TraitDefinitionID) + data << int32(*learnedSpellInfo.TraitDefinitionID); + + return data; +} + +WorldPacket const* LearnedSpells::Write() +{ + _worldPacket << uint32(ClientLearnedSpellData.size()); + _worldPacket << uint32(SpecializationID); _worldPacket.WriteBit(SuppressMessaging); _worldPacket.FlushBits(); + for (LearnedSpellInfo const& spell : ClientLearnedSpellData) + _worldPacket << spell; + return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::SupercededSpells::Write() +WorldPacket const* SupercededSpells::Write() { - _worldPacket << uint32(SpellID.size()); - _worldPacket << uint32(Superceded.size()); - _worldPacket << uint32(FavoriteSpellID.size()); - - if (!SpellID.empty()) - _worldPacket.append(SpellID.data(), SpellID.size()); + _worldPacket << uint32(ClientLearnedSpellData.size()); - if (!Superceded.empty()) - _worldPacket.append(Superceded.data(), Superceded.size()); - - if (!FavoriteSpellID.empty()) - _worldPacket.append(FavoriteSpellID.data(), FavoriteSpellID.size()); + for (LearnedSpellInfo const& spell : ClientLearnedSpellData) + _worldPacket << spell; return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::SpellFailure::Write() +WorldPacket const* SpellFailure::Write() { _worldPacket << CasterUnit; _worldPacket << CastID; @@ -510,7 +529,7 @@ WorldPacket const* WorldPackets::Spells::SpellFailure::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::SpellFailedOther::Write() +WorldPacket const* SpellFailedOther::Write() { _worldPacket << CasterUnit; _worldPacket << CastID; @@ -521,7 +540,7 @@ WorldPacket const* WorldPackets::Spells::SpellFailedOther::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::CastFailed::Write() +WorldPacket const* CastFailed::Write() { _worldPacket << CastID; _worldPacket << int32(SpellID); @@ -533,7 +552,7 @@ WorldPacket const* WorldPackets::Spells::CastFailed::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::PetCastFailed::Write() +WorldPacket const* PetCastFailed::Write() { _worldPacket << CastID; _worldPacket << int32(SpellID); @@ -544,7 +563,7 @@ WorldPacket const* WorldPackets::Spells::PetCastFailed::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellModifierData const& spellModifierData) +ByteBuffer& operator<<(ByteBuffer& data, SpellModifierData const& spellModifierData) { data << float(spellModifierData.ModifierValue); data << uint8(spellModifierData.ClassIndex); @@ -552,26 +571,26 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellModifierData return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellModifier const& spellModifier) +ByteBuffer& operator<<(ByteBuffer& data, SpellModifier const& spellModifier) { data << uint8(spellModifier.ModIndex); data << uint32(spellModifier.ModifierData.size()); - for (WorldPackets::Spells::SpellModifierData const& modData : spellModifier.ModifierData) + for (SpellModifierData const& modData : spellModifier.ModifierData) data << modData; return data; } -WorldPacket const* WorldPackets::Spells::SetSpellModifier::Write() +WorldPacket const* SetSpellModifier::Write() { _worldPacket << uint32(Modifiers.size()); - for (WorldPackets::Spells::SpellModifier const& spellMod : Modifiers) + for (SpellModifier const& spellMod : Modifiers) _worldPacket << spellMod; return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::UnlearnedSpells::Write() +WorldPacket const* UnlearnedSpells::Write() { _worldPacket << uint32(SpellID.size()); for (uint32 spellId : SpellID) @@ -583,7 +602,7 @@ WorldPacket const* WorldPackets::Spells::UnlearnedSpells::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::CooldownEvent::Write() +WorldPacket const* CooldownEvent::Write() { _worldPacket << int32(SpellID); _worldPacket.WriteBit(IsPet); @@ -592,7 +611,7 @@ WorldPacket const* WorldPackets::Spells::CooldownEvent::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::ClearCooldowns::Write() +WorldPacket const* ClearCooldowns::Write() { _worldPacket << uint32(SpellID.size()); if (!SpellID.empty()) @@ -604,7 +623,7 @@ WorldPacket const* WorldPackets::Spells::ClearCooldowns::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::ClearCooldown::Write() +WorldPacket const* ClearCooldown::Write() { _worldPacket << uint32(SpellID); _worldPacket.WriteBit(ClearOnHold); @@ -614,7 +633,7 @@ WorldPacket const* WorldPackets::Spells::ClearCooldown::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::ModifyCooldown::Write() +WorldPacket const* ModifyCooldown::Write() { _worldPacket << int32(SpellID); _worldPacket << int32(DeltaTime); @@ -625,7 +644,7 @@ WorldPacket const* WorldPackets::Spells::ModifyCooldown::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCooldownStruct const& cooldown) +ByteBuffer& operator<<(ByteBuffer& data, SpellCooldownStruct const& cooldown) { data << uint32(cooldown.SrecID); data << uint32(cooldown.ForcedCooldown); @@ -633,7 +652,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCooldownStru return data; } -WorldPacket const* WorldPackets::Spells::SpellCooldown::Write() +WorldPacket const* SpellCooldown::Write() { _worldPacket << Caster; _worldPacket << uint8(Flags); @@ -644,7 +663,7 @@ WorldPacket const* WorldPackets::Spells::SpellCooldown::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellHistoryEntry const& historyEntry) +ByteBuffer& operator<<(ByteBuffer& data, SpellHistoryEntry const& historyEntry) { data << uint32(historyEntry.SpellID); data << uint32(historyEntry.ItemID); @@ -664,7 +683,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellHistoryEntry return data; } -WorldPacket const* WorldPackets::Spells::SendSpellHistory::Write() +WorldPacket const* SendSpellHistory::Write() { _worldPacket << uint32(Entries.size()); for (SpellHistoryEntry const& historyEntry : Entries) @@ -673,7 +692,7 @@ WorldPacket const* WorldPackets::Spells::SendSpellHistory::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::ClearAllSpellCharges::Write() +WorldPacket const* ClearAllSpellCharges::Write() { _worldPacket.WriteBit(IsPet); _worldPacket.FlushBits(); @@ -681,7 +700,7 @@ WorldPacket const* WorldPackets::Spells::ClearAllSpellCharges::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::ClearSpellCharges::Write() +WorldPacket const* ClearSpellCharges::Write() { _worldPacket << int32(Category); _worldPacket.WriteBit(IsPet); @@ -690,7 +709,7 @@ WorldPacket const* WorldPackets::Spells::ClearSpellCharges::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::SetSpellCharges::Write() +WorldPacket const* SetSpellCharges::Write() { _worldPacket << int32(Category); _worldPacket << uint32(NextRecoveryTime); @@ -702,7 +721,7 @@ WorldPacket const* WorldPackets::Spells::SetSpellCharges::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellChargeEntry const& chargeEntry) +ByteBuffer& operator<<(ByteBuffer& data, SpellChargeEntry const& chargeEntry) { data << uint32(chargeEntry.Category); data << uint32(chargeEntry.NextRecoveryTime); @@ -711,7 +730,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellChargeEntry return data; } -WorldPacket const* WorldPackets::Spells::SendSpellCharges::Write() +WorldPacket const* SendSpellCharges::Write() { _worldPacket << uint32(Entries.size()); for (SpellChargeEntry const& chargeEntry : Entries) @@ -720,21 +739,21 @@ WorldPacket const* WorldPackets::Spells::SendSpellCharges::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::ClearTarget::Write() +WorldPacket const* ClearTarget::Write() { _worldPacket << Guid; return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::CancelOrphanSpellVisual::Write() +WorldPacket const* CancelOrphanSpellVisual::Write() { _worldPacket << int32(SpellVisualID); return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::CancelSpellVisual::Write() +WorldPacket const* CancelSpellVisual::Write() { _worldPacket << Source; _worldPacket << int32(SpellVisualID); @@ -742,7 +761,7 @@ WorldPacket const* WorldPackets::Spells::CancelSpellVisual::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::CancelSpellVisualKit::Write() +WorldPacket const* CancelSpellVisualKit::Write() { _worldPacket << Source; _worldPacket << int32(SpellVisualKitID); @@ -752,7 +771,7 @@ WorldPacket const* WorldPackets::Spells::CancelSpellVisualKit::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::PlayOrphanSpellVisual::Write() +WorldPacket const* PlayOrphanSpellVisual::Write() { _worldPacket << SourceLocation; _worldPacket << SourceRotation; @@ -768,7 +787,7 @@ WorldPacket const* WorldPackets::Spells::PlayOrphanSpellVisual::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::PlaySpellVisual::Write() +WorldPacket const* PlaySpellVisual::Write() { _worldPacket << Source; _worldPacket << Target; @@ -787,7 +806,7 @@ WorldPacket const* WorldPackets::Spells::PlaySpellVisual::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::PlaySpellVisualKit::Write() +WorldPacket const* PlaySpellVisualKit::Write() { _worldPacket << Unit; _worldPacket << int32(KitRecID); @@ -799,7 +818,7 @@ WorldPacket const* WorldPackets::Spells::PlaySpellVisualKit::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::SpellVisualLoadScreen::Write() +WorldPacket const* SpellVisualLoadScreen::Write() { _worldPacket << int32(SpellVisualKitID); _worldPacket << int32(Delay); @@ -807,33 +826,33 @@ WorldPacket const* WorldPackets::Spells::SpellVisualLoadScreen::Write() return &_worldPacket; } -void WorldPackets::Spells::CancelCast::Read() +void CancelCast::Read() { _worldPacket >> CastID; _worldPacket >> SpellID; } -void WorldPackets::Spells::OpenItem::Read() +void OpenItem::Read() { _worldPacket >> Slot >> PackSlot; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellChannelStartInterruptImmunities const& interruptImmunities) +ByteBuffer& operator<<(ByteBuffer& data, SpellChannelStartInterruptImmunities const& interruptImmunities) { data << int32(interruptImmunities.SchoolImmunities); data << int32(interruptImmunities.Immunities); return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellTargetedHealPrediction const& targetedHealPrediction) +ByteBuffer& operator<<(ByteBuffer& data, SpellTargetedHealPrediction const& targetedHealPrediction) { data << targetedHealPrediction.TargetGUID; data << targetedHealPrediction.Predict; return data; } -WorldPacket const* WorldPackets::Spells::SpellChannelStart::Write() +WorldPacket const* SpellChannelStart::Write() { _worldPacket << CasterGUID; _worldPacket << int32(SpellID); @@ -852,14 +871,14 @@ WorldPacket const* WorldPackets::Spells::SpellChannelStart::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::SpellChannelUpdate::Write() +WorldPacket const* SpellChannelUpdate::Write() { _worldPacket << CasterGUID; _worldPacket << int32(TimeRemaining); return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::ResurrectRequest::Write() +WorldPacket const* ResurrectRequest::Write() { _worldPacket << ResurrectOffererGUID; _worldPacket << uint32(ResurrectOffererVirtualRealmAddress); @@ -875,30 +894,30 @@ WorldPacket const* WorldPackets::Spells::ResurrectRequest::Write() return &_worldPacket; } -void WorldPackets::Spells::UnlearnSkill::Read() +void UnlearnSkill::Read() { _worldPacket >> SkillLine; } -void WorldPackets::Spells::SelfRes::Read() +void SelfRes::Read() { _worldPacket >> SpellID; } -void WorldPackets::Spells::GetMirrorImageData::Read() +void GetMirrorImageData::Read() { _worldPacket >> UnitGUID; _worldPacket >> DisplayID; } -WorldPackets::Spells::MirrorImageComponentedData::MirrorImageComponentedData() +MirrorImageComponentedData::MirrorImageComponentedData() : ServerPacket(SMSG_MIRROR_IMAGE_COMPONENTED_DATA, 8 + 4 + 8 * 1 + 8 + 11 * 4) { } -WorldPackets::Spells::MirrorImageComponentedData::~MirrorImageComponentedData() = default; +MirrorImageComponentedData::~MirrorImageComponentedData() = default; -WorldPacket const* WorldPackets::Spells::MirrorImageComponentedData::Write() +WorldPacket const* MirrorImageComponentedData::Write() { _worldPacket << UnitGUID; _worldPacket << int32(DisplayID); @@ -919,7 +938,7 @@ WorldPacket const* WorldPackets::Spells::MirrorImageComponentedData::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::MirrorImageCreatureData::Write() +WorldPacket const* MirrorImageCreatureData::Write() { _worldPacket << UnitGUID; _worldPacket << int32(DisplayID); @@ -928,27 +947,28 @@ WorldPacket const* WorldPackets::Spells::MirrorImageCreatureData::Write() return &_worldPacket; } -void WorldPackets::Spells::SpellClick::Read() +void SpellClick::Read() { _worldPacket >> SpellClickUnitGuid; TryAutoDismount = _worldPacket.ReadBit(); + IsSoftInteract = _worldPacket.ReadBit(); } -WorldPacket const* WorldPackets::Spells::ResyncRunes::Write() +WorldPacket const* ResyncRunes::Write() { _worldPacket << Runes; return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::AddRunePower::Write() +WorldPacket const* AddRunePower::Write() { _worldPacket << uint32(AddedRunesMask); return &_worldPacket; } -void WorldPackets::Spells::MissileTrajectoryCollision::Read() +void MissileTrajectoryCollision::Read() { _worldPacket >> Target; _worldPacket >> SpellID; @@ -956,7 +976,7 @@ void WorldPackets::Spells::MissileTrajectoryCollision::Read() _worldPacket >> CollisionPos; } -WorldPacket const* WorldPackets::Spells::NotifyMissileTrajectoryCollision::Write() +WorldPacket const* NotifyMissileTrajectoryCollision::Write() { _worldPacket << Caster; _worldPacket << CastID; @@ -965,7 +985,7 @@ WorldPacket const* WorldPackets::Spells::NotifyMissileTrajectoryCollision::Write return &_worldPacket; } -void WorldPackets::Spells::UpdateMissileTrajectory::Read() +void UpdateMissileTrajectory::Read() { _worldPacket >> Guid; _worldPacket >> CastID; @@ -985,7 +1005,7 @@ void WorldPackets::Spells::UpdateMissileTrajectory::Read() } } -WorldPacket const* WorldPackets::Spells::SpellDelayed::Write() +WorldPacket const* SpellDelayed::Write() { _worldPacket << Caster; _worldPacket << uint32(ActualDelay); @@ -993,7 +1013,7 @@ WorldPacket const* WorldPackets::Spells::SpellDelayed::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::DispelFailed::Write() +WorldPacket const* DispelFailed::Write() { _worldPacket << CasterGUID; _worldPacket << VictimGUID; @@ -1005,21 +1025,21 @@ WorldPacket const* WorldPackets::Spells::DispelFailed::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::CustomLoadScreen::Write() +WorldPacket const* CustomLoadScreen::Write() { _worldPacket << uint32(TeleportSpellID); _worldPacket << uint32(LoadingScreenID); return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::MountResult::Write() +WorldPacket const* MountResult::Write() { _worldPacket << int32(Result); return &_worldPacket; } -WorldPacket const* WorldPackets::Spells::MissileCancel::Write() +WorldPacket const* MissileCancel::Write() { _worldPacket << OwnerGUID; _worldPacket << int32(SpellID); @@ -1028,3 +1048,4 @@ WorldPacket const* WorldPackets::Spells::MissileCancel::Write() return &_worldPacket; } +} diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index b5c1bc3edbd..4d2380a964f 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -62,8 +62,8 @@ namespace WorldPackets void Read() override; int32 ChannelSpell = 0; - int32 Reason = 0; // 40 = /run SpellStopCasting(), 16 = movement/SpellAuraInterruptFlags::Moving, 41 = turning/SpellAuraInterruptFlags::Turning - // does not match SpellCastResult enum + int32 Reason = 0; // 40 = /run SpellStopCasting(), 16 = movement/SpellAuraInterruptFlags::Moving, 41 = turning/SpellAuraInterruptFlags::Turning + // does not match SpellCastResult enum }; class CancelGrowthAura final : public ClientPacket @@ -139,22 +139,19 @@ namespace WorldPackets bool InitialLogin = false; std::vector<uint32> KnownSpells; - std::vector<uint32> FavoriteSpells; // tradeskill recipes + std::vector<uint32> FavoriteSpells; // tradeskill recipes }; class UpdateActionButtons final : public ServerPacket { public: - static std::size_t constexpr NumActionButtons = 132; + static std::size_t constexpr NumActionButtons = 180; - UpdateActionButtons() : ServerPacket(SMSG_UPDATE_ACTION_BUTTONS, NumActionButtons * 8 + 1) - { - ActionButtons.fill(0); - } + UpdateActionButtons() : ServerPacket(SMSG_UPDATE_ACTION_BUTTONS, NumActionButtons * 8 + 1) { } WorldPacket const* Write() override; - std::array<uint64, NumActionButtons> ActionButtons; + std::array<uint64, NumActionButtons> ActionButtons = { }; uint8 Reason = 0; /* Reason can be 0, 1, 2 @@ -253,10 +250,12 @@ namespace WorldPackets uint32 Quantity = 0; }; - struct SpellOptionalReagent + struct SpellCraftingReagent { int32 ItemID = 0; - int32 Slot = 0; + int32 DataSlotIndex = 0; + int32 Quantity = 0; + Optional<uint8> Unknown_1000; }; struct SpellExtraCurrencyCost @@ -275,8 +274,9 @@ namespace WorldPackets MissileTrajectoryRequest MissileTrajectory; Optional<MovementInfo> MoveUpdate; std::vector<SpellWeight> Weight; - Array<SpellOptionalReagent, 3> OptionalReagents; + Array<SpellCraftingReagent, 3> OptionalReagents; Array<SpellExtraCurrencyCost, 5 /*MAX_ITEM_EXT_COST_CURRENCIES*/> OptionalCurrencies; + Optional<uint64> CraftingOrderID; ObjectGuid CraftingNPC; int32 Misc[2] = { }; }; @@ -331,7 +331,7 @@ namespace WorldPackets SpellHitStatus() { } SpellHitStatus(uint8 reason) : Reason(reason) { } - uint8 Reason; + uint8 Reason = 0; }; struct SpellMissStatus @@ -427,6 +427,15 @@ namespace WorldPackets SpellCastData Cast; }; + struct LearnedSpellInfo + { + int32 SpellID = 0; + bool IsFavorite = false; + Optional<int32> field_8; + Optional<int32> Superceded; + Optional<int32> TraitDefinitionID; + }; + class LearnedSpells final : public ServerPacket { public: @@ -434,8 +443,7 @@ namespace WorldPackets WorldPacket const* Write() override; - std::vector<int32> SpellID; - std::vector<int32> FavoriteSpellID; + std::vector<LearnedSpellInfo> ClientLearnedSpellData; uint32 SpecializationID = 0; bool SuppressMessaging = false; }; @@ -447,9 +455,7 @@ namespace WorldPackets WorldPacket const* Write() override; - std::vector<int32> SpellID; - std::vector<int32> Superceded; - std::vector<int32> FavoriteSpellID; + std::vector<LearnedSpellInfo> ClientLearnedSpellData; }; class SpellFailure final : public ServerPacket @@ -551,7 +557,7 @@ namespace WorldPackets WorldPacket const* Write() override; bool IsPet = false; - int32 SpellID; + int32 SpellID = 0; }; class ClearCooldowns final : public ServerPacket @@ -621,8 +627,8 @@ namespace WorldPackets int32 CategoryRecoveryTime = 0; float ModRate = 1.0f; bool OnHold = false; - Optional<uint32> unused622_1; ///< This field is not used for anything in the client in 6.2.2.20444 - Optional<uint32> unused622_2; ///< This field is not used for anything in the client in 6.2.2.20444 + Optional<uint32> unused622_1; ///< This field is not used for anything in the client in 6.2.2.20444 + Optional<uint32> unused622_2; ///< This field is not used for anything in the client in 6.2.2.20444 }; class SendSpellHistory final : public ServerPacket @@ -758,7 +764,7 @@ namespace WorldPackets ObjectGuid Source; ObjectGuid Target; - ObjectGuid Transport; // Used when Target = Empty && (SpellVisual::Flags & 0x400) == 0 + ObjectGuid Transport; // Used when Target = Empty && (SpellVisual::Flags & 0x400) == 0 TaggedPosition<Position::XYZ> TargetPosition; // Overrides missile destination for SpellVisual::SpellVisualMissileSetID uint32 SpellVisualID = 0; float TravelSpeed = 0.0f; @@ -944,6 +950,7 @@ namespace WorldPackets ObjectGuid SpellClickUnitGuid; bool TryAutoDismount = false; + bool IsSoftInteract = false; }; class ResyncRunes final : public ServerPacket @@ -1065,9 +1072,9 @@ namespace WorldPackets bool Reverse = false; int32 SpellID = 0; }; + + ByteBuffer& operator>>(ByteBuffer& buffer, SpellCastRequest& request); } } -ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::SpellCastRequest& request); - #endif // SpellPackets_h__ diff --git a/src/server/game/Server/Packets/SystemPackets.cpp b/src/server/game/Server/Packets/SystemPackets.cpp index 5f6304d4bee..18ad36f7cbb 100644 --- a/src/server/game/Server/Packets/SystemPackets.cpp +++ b/src/server/game/Server/Packets/SystemPackets.cpp @@ -18,9 +18,7 @@ #include "SystemPackets.h" #include "Errors.h" -namespace WorldPackets -{ -namespace System +namespace WorldPackets::System { ByteBuffer& operator<<(ByteBuffer& data, SavedThrottleObjectState const& throttleState) { @@ -82,6 +80,7 @@ WorldPacket const* FeatureSystemStatus::Write() _worldPacket << int16(MaxPlayerNameQueriesPerPacket); _worldPacket << int16(PlayerNameQueryTelemetryInterval); + _worldPacket << PlayerNameQueryInterval; for (GameRuleValuePair const& gameRuleValue : GameRuleValues) _worldPacket << gameRuleValue; @@ -94,6 +93,7 @@ WorldPacket const* FeatureSystemStatus::Write() _worldPacket.WriteBit(BpayStoreDisabledByParentalControls); _worldPacket.WriteBit(ItemRestorationButtonEnabled); _worldPacket.WriteBit(BrowserEnabled); + _worldPacket.WriteBit(SessionAlert.has_value()); _worldPacket.WriteBit(RAFSystem.Enabled); _worldPacket.WriteBit(RAFSystem.RecruitingEnabled); @@ -102,6 +102,7 @@ WorldPacket const* FeatureSystemStatus::Write() _worldPacket.WriteBit(CommerceSystemEnabled); _worldPacket.WriteBit(TutorialsEnabled); _worldPacket.WriteBit(TwitterEnabled); + _worldPacket.WriteBit(Unk67); _worldPacket.WriteBit(WillKickFromWorld); _worldPacket.WriteBit(KioskModeEnabled); @@ -110,6 +111,7 @@ WorldPacket const* FeatureSystemStatus::Write() _worldPacket.WriteBit(WarModeFeatureEnabled); _worldPacket.WriteBit(ClubsEnabled); _worldPacket.WriteBit(ClubsBattleNetClubTypeAllowed); + _worldPacket.WriteBit(ClubsCharacterClubTypeAllowed); _worldPacket.WriteBit(ClubsPresenceUpdateEnabled); _worldPacket.WriteBit(VoiceChatDisabledByParentalControl); @@ -118,10 +120,13 @@ WorldPacket const* FeatureSystemStatus::Write() _worldPacket.WriteBit(IsMuted); _worldPacket.WriteBit(ClubFinderEnabled); _worldPacket.WriteBit(Unknown901CheckoutRelated); + _worldPacket.WriteBit(TextToSpeechFeatureEnabled); _worldPacket.WriteBit(ChatDisabledByDefault); _worldPacket.WriteBit(ChatDisabledByPlayer); _worldPacket.WriteBit(LFGListCustomRequiresAuthenticator); + _worldPacket.WriteBit(AddonsDisabled); + _worldPacket.WriteBit(Unused1000); _worldPacket.FlushBits(); @@ -180,6 +185,7 @@ WorldPacket const* FeatureSystemStatusGlueScreen::Write() _worldPacket.WriteBit(Unk14); _worldPacket.WriteBit(WillKickFromWorld); _worldPacket.WriteBit(IsExpansionPreorderInStore); + _worldPacket.WriteBit(KioskModeEnabled); _worldPacket.WriteBit(CompetitiveModeEnabled); _worldPacket.WriteBit(TrialBoostEnabled); @@ -188,9 +194,12 @@ WorldPacket const* FeatureSystemStatusGlueScreen::Write() _worldPacket.WriteBit(LiveRegionCharacterCopyEnabled); _worldPacket.WriteBit(LiveRegionAccountCopyEnabled); _worldPacket.WriteBit(LiveRegionKeyBindingsCopyEnabled); + _worldPacket.WriteBit(Unknown901CheckoutRelated); _worldPacket.WriteBit(EuropaTicketSystemStatus.has_value()); _worldPacket.WriteBit(LaunchETA.has_value()); + _worldPacket.WriteBit(AddonsDisabled); + _worldPacket.WriteBit(Unused1000); _worldPacket.FlushBits(); if (EuropaTicketSystemStatus) @@ -210,6 +219,7 @@ WorldPacket const* FeatureSystemStatusGlueScreen::Write() _worldPacket << uint32(GameRuleValues.size()); _worldPacket << int16(MaxPlayerNameQueriesPerPacket); _worldPacket << int16(PlayerNameQueryTelemetryInterval); + _worldPacket << PlayerNameQueryInterval; if (LaunchETA) _worldPacket << int32(*LaunchETA); @@ -243,12 +253,13 @@ WorldPacket const* SetTimeZoneInformation::Write() { _worldPacket.WriteBits(ServerTimeTZ.length(), 7); _worldPacket.WriteBits(GameTimeTZ.length(), 7); + _worldPacket.WriteBits(ServerRegionalTZ.length(), 7); _worldPacket.FlushBits(); _worldPacket.WriteString(ServerTimeTZ); _worldPacket.WriteString(GameTimeTZ); + _worldPacket.WriteString(ServerRegionalTZ); return &_worldPacket; } } -} diff --git a/src/server/game/Server/Packets/SystemPackets.h b/src/server/game/Server/Packets/SystemPackets.h index f6a3d37c133..2091940632f 100644 --- a/src/server/game/Server/Packets/SystemPackets.h +++ b/src/server/game/Server/Packets/SystemPackets.h @@ -21,6 +21,7 @@ #include "Packet.h" #include "ObjectGuid.h" #include "Optional.h" +#include "PacketUtilities.h" namespace WorldPackets { @@ -131,6 +132,7 @@ namespace WorldPackets int32 ActiveSeason = 0; ///< Currently active Classic season int16 MaxPlayerNameQueriesPerPacket = 50; int16 PlayerNameQueryTelemetryInterval = 600; + Duration<Seconds, uint32> PlayerNameQueryInterval = 10s; bool ItemRestorationButtonEnabled = false; bool CharUndeleteEnabled = false; ///< Implemented bool BpayStoreDisabledByParentalControls = false; @@ -159,6 +161,8 @@ namespace WorldPackets bool ChatDisabledByDefault = false; bool ChatDisabledByPlayer = false; bool LFGListCustomRequiresAuthenticator = false; + bool AddonsDisabled = false; + bool Unused1000 = false; SocialQueueConfig QuickJoinConfig; SquelchInfo Squelch; @@ -190,6 +194,8 @@ namespace WorldPackets bool LiveRegionAccountCopyEnabled = false; // NYI bool LiveRegionKeyBindingsCopyEnabled = false; bool Unknown901CheckoutRelated = false; // NYI + bool AddonsDisabled = false; + bool Unused1000 = false; Optional<EuropaTicketConfig> EuropaTicketSystemStatus; std::vector<int32> LiveRegionCharacterCopySourceRegions; uint32 TokenPollTimeSeconds = 0; // NYI @@ -205,6 +211,7 @@ namespace WorldPackets std::vector<GameRuleValuePair> GameRuleValues; int16 MaxPlayerNameQueriesPerPacket = 50; int16 PlayerNameQueryTelemetryInterval = 600; + Duration<Seconds, uint32> PlayerNameQueryInterval = 10s; Optional<int32> LaunchETA; }; @@ -227,6 +234,7 @@ namespace WorldPackets std::string ServerTimeTZ; std::string GameTimeTZ; + std::string ServerRegionalTZ; }; } } diff --git a/src/server/game/Server/Packets/TraitPacketsCommon.cpp b/src/server/game/Server/Packets/TraitPacketsCommon.cpp new file mode 100644 index 00000000000..482f3b5e91d --- /dev/null +++ b/src/server/game/Server/Packets/TraitPacketsCommon.cpp @@ -0,0 +1,65 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "TraitPacketsCommon.h" +#include "DBCEnums.h" + +namespace WorldPackets::Traits +{ +ByteBuffer& operator<<(ByteBuffer& data, TraitEntry const& traitEntry) +{ + data << int32(traitEntry.TraitNodeID); + data << int32(traitEntry.TraitNodeEntryID); + data << int32(traitEntry.Rank); + data << int32(traitEntry.GrantedRanks); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, TraitConfig const& traitConfig) +{ + data << int32(traitConfig.ID); + data << int32(traitConfig.Type); + data << uint32(traitConfig.Entries.size()); + switch (traitConfig.Type) + { + case TraitConfigType::Combat: + data << int32(traitConfig.ChrSpecializationID); + data << int32(traitConfig.CombatConfigFlags); + data << int32(traitConfig.LocalIdentifier); + break; + case TraitConfigType::Profession: + data << int32(traitConfig.SkillLineID); + break; + case TraitConfigType::Generic: + data << int32(traitConfig.TraitSystemID); + break; + default: + break; + } + + for (TraitEntry const& traitEntry : traitConfig.Entries) + data << traitEntry; + + data.WriteBits(traitConfig.Name.length(), 9); + data.FlushBits(); + + data.WriteString(static_cast<std::string const&>(traitConfig.Name)); + + return data; +} +} diff --git a/src/server/game/Server/Packets/TraitPacketsCommon.h b/src/server/game/Server/Packets/TraitPacketsCommon.h new file mode 100644 index 00000000000..d61e16ed49b --- /dev/null +++ b/src/server/game/Server/Packets/TraitPacketsCommon.h @@ -0,0 +1,53 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITYCORE_TRAIT_PACKETS_COMMON_H +#define TRINITYCORE_TRAIT_PACKETS_COMMON_H + +#include "PacketUtilities.h" + +enum class TraitCombatConfigFlags : int32; +enum class TraitConfigType : int32; + +namespace WorldPackets::Traits +{ +struct TraitEntry +{ + int32 TraitNodeID = 0; + int32 TraitNodeEntryID = 0; + int32 Rank = 0; + int32 GrantedRanks = 0; +}; + +struct TraitConfig +{ + int32 ID = 0; + TraitConfigType Type = {}; + int32 ChrSpecializationID = 0; + TraitCombatConfigFlags CombatConfigFlags = {}; + int32 LocalIdentifier = 0; // Local to specialization + int32 SkillLineID = 0; + int32 TraitSystemID = 0; + Array<TraitEntry, 100, std::vector<TraitEntry>> Entries; + String<259> Name; +}; + +ByteBuffer& operator<<(ByteBuffer& data, TraitEntry const& traitEntry); +ByteBuffer& operator<<(ByteBuffer& data, TraitConfig const& traitConfig); +} + +#endif // TRINITYCORE_TRAIT_PACKETS_COMMON_H diff --git a/src/server/game/Server/Packets/TransmogrificationPackets.cpp b/src/server/game/Server/Packets/TransmogrificationPackets.cpp index 3ea86ae6106..5a856fc4805 100644 --- a/src/server/game/Server/Packets/TransmogrificationPackets.cpp +++ b/src/server/game/Server/Packets/TransmogrificationPackets.cpp @@ -51,10 +51,3 @@ WorldPacket const* WorldPackets::Transmogrification::AccountTransmogUpdate::Writ return &_worldPacket; } - -WorldPacket const* WorldPackets::Transmogrification::TransmogrifyNPC::Write() -{ - _worldPacket << Guid; - - return &_worldPacket; -} diff --git a/src/server/game/Server/Packets/TransmogrificationPackets.h b/src/server/game/Server/Packets/TransmogrificationPackets.h index 2f1e22063fa..4ad6b3adbff 100644 --- a/src/server/game/Server/Packets/TransmogrificationPackets.h +++ b/src/server/game/Server/Packets/TransmogrificationPackets.h @@ -63,16 +63,6 @@ namespace WorldPackets std::vector<uint32> FavoriteAppearances; std::vector<uint32> NewAppearances; }; - - class TransmogrifyNPC final : public ServerPacket - { - public: - TransmogrifyNPC(ObjectGuid const& guid) : ServerPacket(SMSG_TRANSMOGRIFY_NPC, 16), Guid(guid) { } - - WorldPacket const* Write() override; - - ObjectGuid Guid; - }; } } |
