diff options
| author | Shauren <shauren.trinity@gmail.com> | 2020-11-04 21:39:21 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2020-12-08 18:16:41 +0100 |
| commit | cab4c87d2d7f6d734ef067d6bf50f4b1d338a7bc (patch) | |
| tree | 2eaf0fd8bc9e937a4c9611e18dd04d5001189036 /src/server/game/Server/Packets | |
| parent | 16b39a448acbe8ace88550a367be8e6bf565b00d (diff) | |
Core/PacketIO: Updated most packet structures to 9.0.1
Diffstat (limited to 'src/server/game/Server/Packets')
61 files changed, 1282 insertions, 900 deletions
diff --git a/src/server/game/Server/Packets/AreaTriggerPackets.cpp b/src/server/game/Server/Packets/AreaTriggerPackets.cpp index eb4b454b028..d293c2beaba 100644 --- a/src/server/game/Server/Packets/AreaTriggerPackets.cpp +++ b/src/server/game/Server/Packets/AreaTriggerPackets.cpp @@ -55,6 +55,14 @@ ByteBuffer& operator<<(ByteBuffer& data, AreaTriggerOrbitInfo const& areaTrigger return data; } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::AreaTrigger::AreaTriggerMovementScriptInfo const& areaTriggerMovementScript) +{ + data << int32(areaTriggerMovementScript.SpellScriptID); + data << areaTriggerMovementScript.Center; + + return data; +} + void WorldPackets::AreaTrigger::AreaTrigger::Read() { _worldPacket >> AreaTriggerID; @@ -77,11 +85,15 @@ WorldPacket const* WorldPackets::AreaTrigger::AreaTriggerRePath::Write() _worldPacket.WriteBit(AreaTriggerSpline.is_initialized()); _worldPacket.WriteBit(AreaTriggerOrbit.is_initialized()); + _worldPacket.WriteBit(AreaTriggerMovementScript.is_initialized()); _worldPacket.FlushBits(); if (AreaTriggerSpline) _worldPacket << *AreaTriggerSpline; + if (AreaTriggerMovementScript) + _worldPacket << *AreaTriggerMovementScript; + if (AreaTriggerOrbit) _worldPacket << *AreaTriggerOrbit; diff --git a/src/server/game/Server/Packets/AreaTriggerPackets.h b/src/server/game/Server/Packets/AreaTriggerPackets.h index 7bb4ec70594..bb7caed140c 100644 --- a/src/server/game/Server/Packets/AreaTriggerPackets.h +++ b/src/server/game/Server/Packets/AreaTriggerPackets.h @@ -34,6 +34,12 @@ namespace WorldPackets std::vector<TaggedPosition<Position::XYZ>> Points; }; + struct AreaTriggerMovementScriptInfo + { + uint32 SpellScriptID = 0; + TaggedPosition<Position::XYZ> Center; + }; + class AreaTrigger final : public ClientPacket { public: @@ -74,6 +80,7 @@ namespace WorldPackets Optional<AreaTriggerSplineInfo> AreaTriggerSpline; Optional<AreaTriggerOrbitInfo> AreaTriggerOrbit; + Optional<AreaTriggerMovementScriptInfo> AreaTriggerMovementScript; ObjectGuid TriggerGUID; }; } diff --git a/src/server/game/Server/Packets/AuctionHousePackets.cpp b/src/server/game/Server/Packets/AuctionHousePackets.cpp index 51b36df9bf4..68154c8572a 100644 --- a/src/server/game/Server/Packets/AuctionHousePackets.cpp +++ b/src/server/game/Server/Packets/AuctionHousePackets.cpp @@ -154,6 +154,7 @@ ByteBuffer& operator<<(ByteBuffer& data, BucketInfo const& bucketInfo) { data << bucketInfo.Key; data << int32(bucketInfo.TotalQuantity); + data << int32(bucketInfo.RequiredLevel); data << uint64(bucketInfo.MinPrice); data << uint32(bucketInfo.ItemModifiedAppearanceIDs.size()); if (!bucketInfo.ItemModifiedAppearanceIDs.empty()) @@ -162,6 +163,7 @@ ByteBuffer& operator<<(ByteBuffer& data, BucketInfo const& bucketInfo) data.WriteBit(bucketInfo.MaxBattlePetQuality.is_initialized()); data.WriteBit(bucketInfo.MaxBattlePetLevel.is_initialized()); data.WriteBit(bucketInfo.BattlePetBreedID.is_initialized()); + data.WriteBit(bucketInfo.Unk901_1.is_initialized()); data.WriteBit(bucketInfo.ContainsOwnerItem); data.WriteBit(bucketInfo.ContainsOnlyCollectedAppearances); data.FlushBits(); @@ -175,6 +177,9 @@ ByteBuffer& operator<<(ByteBuffer& data, BucketInfo const& bucketInfo) if (bucketInfo.BattlePetBreedID) data << uint8(*bucketInfo.BattlePetBreedID); + if (bucketInfo.Unk901_1) + data << uint32(*bucketInfo.Unk901_1); + return data; } @@ -633,6 +638,9 @@ WorldPacket const* AuctionListOwnedItemsResult::Write() for (AuctionItem const& item : Items) _worldPacket << item; + for (AuctionItem const& item : SoldItems) + _worldPacket << item; + return &_worldPacket; } diff --git a/src/server/game/Server/Packets/AuctionHousePackets.h b/src/server/game/Server/Packets/AuctionHousePackets.h index 15016ecd2e8..59dd8dbcff3 100644 --- a/src/server/game/Server/Packets/AuctionHousePackets.h +++ b/src/server/game/Server/Packets/AuctionHousePackets.h @@ -95,11 +95,13 @@ namespace WorldPackets { AuctionBucketKey Key; int32 TotalQuantity = 0; + int32 RequiredLevel = 0; uint64 MinPrice = 0; std::vector<int32> ItemModifiedAppearanceIDs; Optional<uint8> MaxBattlePetQuality; Optional<uint8> MaxBattlePetLevel; Optional<uint8> BattlePetBreedID; + Optional<uint32> Unk901_1; bool ContainsOwnerItem = false; bool ContainsOnlyCollectedAppearances = false; }; diff --git a/src/server/game/Server/Packets/AuthenticationPackets.cpp b/src/server/game/Server/Packets/AuthenticationPackets.cpp index 1215296a877..f7b58ae0659 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.cpp +++ b/src/server/game/Server/Packets/AuthenticationPackets.cpp @@ -150,13 +150,13 @@ WorldPacket const* WorldPackets::Auth::AuthResponse::Write() _worldPacket.FlushBits(); { - _worldPacket << uint32(SuccessInfo->Billing.BillingPlan); - _worldPacket << uint32(SuccessInfo->Billing.TimeRemain); - _worldPacket << uint32(SuccessInfo->Billing.Unknown735); + _worldPacket << uint32(SuccessInfo->GameTimeInfo.BillingPlan); + _worldPacket << uint32(SuccessInfo->GameTimeInfo.TimeRemain); + _worldPacket << uint32(SuccessInfo->GameTimeInfo.Unknown735); // 3x same bit is not a mistake - preserves legacy client behavior of BillingPlanFlags::SESSION_IGR - _worldPacket.WriteBit(SuccessInfo->Billing.InGameRoom); // inGameRoom check in function checking which lua event to fire when remaining time is near end - BILLING_NAG_DIALOG vs IGR_BILLING_NAG_DIALOG - _worldPacket.WriteBit(SuccessInfo->Billing.InGameRoom); // inGameRoom lua return from Script_GetBillingPlan - _worldPacket.WriteBit(SuccessInfo->Billing.InGameRoom); // not used anywhere in the client + _worldPacket.WriteBit(SuccessInfo->GameTimeInfo.InGameRoom); // inGameRoom check in function checking which lua event to fire when remaining time is near end - BILLING_NAG_DIALOG vs IGR_BILLING_NAG_DIALOG + _worldPacket.WriteBit(SuccessInfo->GameTimeInfo.InGameRoom); // inGameRoom lua return from Script_GetBillingPlan + _worldPacket.WriteBit(SuccessInfo->GameTimeInfo.InGameRoom); // not used anywhere in the client _worldPacket.FlushBits(); } diff --git a/src/server/game/Server/Packets/AuthenticationPackets.h b/src/server/game/Server/Packets/AuthenticationPackets.h index 75b61acda5a..dc4eab9e310 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.h +++ b/src/server/game/Server/Packets/AuthenticationPackets.h @@ -118,6 +118,7 @@ namespace WorldPackets struct VirtualRealmInfo { + VirtualRealmInfo() : RealmAddress(0) { } VirtualRealmInfo(uint32 realmAddress, bool isHomeRealm, bool isInternalRealm, std::string const& realmNameActual, std::string const& realmNameNormalized) : RealmAddress(realmAddress), RealmNameInfo(isHomeRealm, isInternalRealm, realmNameActual, realmNameNormalized) { } @@ -130,7 +131,7 @@ namespace WorldPackets public: struct AuthSuccessInfo { - struct BillingInfo + struct GameTime { uint32 BillingPlan = 0; uint32 TimeRemain = 0; @@ -147,7 +148,7 @@ namespace WorldPackets uint32 CurrencyID = 0; ///< this is probably used for the ingame shop. @todo implement int32 Time = 0; - BillingInfo Billing; + GameTime GameTimeInfo; std::vector<VirtualRealmInfo> VirtualRealms; ///< list of realms connected to this one (inclusive) @todo implement std::vector<CharacterTemplate const*> Templates; ///< list of pre-made character templates. @@ -295,6 +296,7 @@ namespace WorldPackets } } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Auth::VirtualRealmInfo const& realmInfo); ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Auth::VirtualRealmNameInfo const& realmInfo); #endif // AuthenticationPacketsWorld_h__ diff --git a/src/server/game/Server/Packets/BattlePetPackets.cpp b/src/server/game/Server/Packets/BattlePetPackets.cpp index d939ee026ba..4568103d7de 100644 --- a/src/server/game/Server/Packets/BattlePetPackets.cpp +++ b/src/server/game/Server/Packets/BattlePetPackets.cpp @@ -84,7 +84,7 @@ WorldPacket const* WorldPackets::BattlePet::BattlePetUpdates::Write() _worldPacket.WriteBit(PetAdded); _worldPacket.FlushBits(); - for (auto const& pet : Pets) + for (BattlePet const& pet : Pets) _worldPacket << pet; return &_worldPacket; diff --git a/src/server/game/Server/Packets/BattlegroundPackets.cpp b/src/server/game/Server/Packets/BattlegroundPackets.cpp index bc925b0ae93..ecf37c02761 100644 --- a/src/server/game/Server/Packets/BattlegroundPackets.cpp +++ b/src/server/game/Server/Packets/BattlegroundPackets.cpp @@ -22,7 +22,10 @@ WorldPacket const* WorldPackets::Battleground::SeasonInfo::Write() _worldPacket << int32(MythicPlusSeasonID); _worldPacket << int32(CurrentSeason); _worldPacket << int32(PreviousSeason); + _worldPacket << int32(ConquestWeeklyProgressCurrencyID); _worldPacket << int32(PvpSeasonID); + _worldPacket.WriteBit(WeeklyRewardChestsEnabled); + _worldPacket.FlushBits(); return &_worldPacket; } diff --git a/src/server/game/Server/Packets/BattlegroundPackets.h b/src/server/game/Server/Packets/BattlegroundPackets.h index dfb19be4108..f5389ae22f1 100644 --- a/src/server/game/Server/Packets/BattlegroundPackets.h +++ b/src/server/game/Server/Packets/BattlegroundPackets.h @@ -33,7 +33,7 @@ namespace WorldPackets class SeasonInfo final : public ServerPacket { public: - SeasonInfo() : ServerPacket(SMSG_SEASON_INFO, 4 + 4 + 4 + 4) { } + SeasonInfo() : ServerPacket(SMSG_SEASON_INFO, 4 + 4 + 4 + 4 + 4 + 1) { } WorldPacket const* Write() override; @@ -41,6 +41,8 @@ namespace WorldPackets int32 PreviousSeason = 0; int32 CurrentSeason = 0; int32 PvpSeasonID = 0; + int32 ConquestWeeklyProgressCurrencyID = 0; + bool WeeklyRewardChestsEnabled = false; }; class AreaSpiritHealerQuery final : public ClientPacket @@ -416,10 +418,10 @@ namespace WorldPackets void Read() override { } }; - class RequestRatedBattlefieldInfo final : public ClientPacket + class RequestRatedPvpInfo final : public ClientPacket { public: - RequestRatedBattlefieldInfo(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_RATED_BATTLEFIELD_INFO, std::move(packet)) { } + RequestRatedPvpInfo(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_RATED_PVP_INFO, std::move(packet)) { } void Read() override { } }; diff --git a/src/server/game/Server/Packets/CalendarPackets.cpp b/src/server/game/Server/Packets/CalendarPackets.cpp index 436a820c020..d12d73831e6 100644 --- a/src/server/game/Server/Packets/CalendarPackets.cpp +++ b/src/server/game/Server/Packets/CalendarPackets.cpp @@ -80,7 +80,7 @@ void WorldPackets::Calendar::CalendarGetEvent::Read() _worldPacket >> EventID; } -void WorldPackets::Calendar::CalendarCommunityFilter::Read() +void WorldPackets::Calendar::CalendarCommunityInviteRequest::Read() { _worldPacket >> ClubID; _worldPacket >> MinLevel; @@ -182,14 +182,14 @@ void WorldPackets::Calendar::CalendarCopyEvent::Read() Date = _worldPacket.ReadPackedTime(); } -void WorldPackets::Calendar::CalendarEventRSVP::Read() +void WorldPackets::Calendar::CalendarRSVP::Read() { _worldPacket >> EventID; _worldPacket >> InviteID; _worldPacket >> Status; } -void WorldPackets::Calendar::CalendarEventInvite::Read() +void WorldPackets::Calendar::CalendarInvite::Read() { _worldPacket >> EventID; _worldPacket >> ModeratorID; @@ -217,7 +217,7 @@ void WorldPackets::Calendar::CalendarRemoveInvite::Read() _worldPacket >> EventID; } -void WorldPackets::Calendar::CalendarEventStatus::Read() +void WorldPackets::Calendar::CalendarStatus::Read() { _worldPacket >> Guid; _worldPacket >> EventID; @@ -233,7 +233,7 @@ void WorldPackets::Calendar::SetSavedInstanceExtend::Read() Extend = _worldPacket.ReadBit(); } -void WorldPackets::Calendar::CalendarEventModeratorStatus::Read() +void WorldPackets::Calendar::CalendarModeratorStatusQuery::Read() { _worldPacket >> Guid; _worldPacket >> EventID; diff --git a/src/server/game/Server/Packets/CalendarPackets.h b/src/server/game/Server/Packets/CalendarPackets.h index 0010dc71c72..1f292ca1468 100644 --- a/src/server/game/Server/Packets/CalendarPackets.h +++ b/src/server/game/Server/Packets/CalendarPackets.h @@ -46,10 +46,10 @@ namespace WorldPackets uint64 EventID = 0; }; - class CalendarCommunityFilter final : public ClientPacket + class CalendarCommunityInviteRequest final : public ClientPacket { public: - CalendarCommunityFilter(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_COMMUNITY_FILTER, std::move(packet)) { } + CalendarCommunityInviteRequest(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_COMMUNITY_INVITE, std::move(packet)) { } void Read() override; @@ -256,10 +256,10 @@ namespace WorldPackets std::string EventName; }; - class CalendarEventInvite final : public ClientPacket + class CalendarInvite final : public ClientPacket { public: - CalendarEventInvite(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_EVENT_INVITE, std::move(packet)) { } + CalendarInvite(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_INVITE, std::move(packet)) { } void Read() override; @@ -271,10 +271,10 @@ namespace WorldPackets std::string Name; }; - class CalendarEventRSVP final : public ClientPacket + class CalendarRSVP final : public ClientPacket { public: - CalendarEventRSVP(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_EVENT_RSVP, std::move(packet)) { } + CalendarRSVP(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_RSVP, std::move(packet)) { } void Read() override; @@ -422,10 +422,10 @@ namespace WorldPackets uint64 InviteID = 0; }; - class CalendarEventStatus final : public ClientPacket + class CalendarStatus final : public ClientPacket { public: - CalendarEventStatus(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_EVENT_STATUS, std::move(packet)) { } + CalendarStatus(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_STATUS, std::move(packet)) { } void Read() override; @@ -448,10 +448,10 @@ namespace WorldPackets uint32 DifficultyID = 0; }; - class CalendarEventModeratorStatus final : public ClientPacket + class CalendarModeratorStatusQuery final : public ClientPacket { public: - CalendarEventModeratorStatus(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_EVENT_MODERATOR_STATUS, std::move(packet)) { } + CalendarModeratorStatusQuery(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_MODERATOR_STATUS, std::move(packet)) { } void Read() override; diff --git a/src/server/game/Server/Packets/ChannelPackets.h b/src/server/game/Server/Packets/ChannelPackets.h index 15a86fed6ca..2e7f834cf27 100644 --- a/src/server/game/Server/Packets/ChannelPackets.h +++ b/src/server/game/Server/Packets/ChannelPackets.h @@ -77,7 +77,7 @@ namespace WorldPackets std::string ChannelWelcomeMsg; int32 ChatChannelID = 0; - int32 InstanceID = 0; + uint64 InstanceID = 0; uint32 _ChannelFlags = 0; ///< @see enum ChannelFlags std::string _Channel; ///< Channel Name ObjectGuid ChannelGUID; diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp index 42d3893ff12..86ebe42cb7f 100644 --- a/src/server/game/Server/Packets/CharacterPackets.cpp +++ b/src/server/game/Server/Packets/CharacterPackets.cpp @@ -22,12 +22,32 @@ #include "Player.h" #include "World.h" -WorldPackets::Character::EnumCharacters::EnumCharacters(WorldPacket&& packet) : ClientPacket(std::move(packet)) +namespace WorldPackets +{ +namespace Character +{ +ByteBuffer& operator<<(ByteBuffer& data, ChrCustomizationChoice const& customizationChoice) +{ + data << uint32(customizationChoice.ChrCustomizationOptionID); + data << uint32(customizationChoice.ChrCustomizationChoiceID); + + return data; +} + +ByteBuffer& operator>>(ByteBuffer& data, ChrCustomizationChoice& customizationChoice) +{ + data >> customizationChoice.ChrCustomizationOptionID; + data >> customizationChoice.ChrCustomizationChoiceID; + + return data; +} + +EnumCharacters::EnumCharacters(WorldPacket&& packet) : ClientPacket(std::move(packet)) { ASSERT(GetOpcode() == CMSG_ENUM_CHARACTERS || GetOpcode() == CMSG_ENUM_CHARACTERS_DELETED_BY_CLIENT); } -WorldPackets::Character::EnumCharactersResult::CharacterInfo::CharacterInfo(Field* fields) +EnumCharactersResult::CharacterInfo::CharacterInfo(Field* fields) { // 0 1 2 3 4 5 6 7 // "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.skin, characters.face, characters.hairStyle, " @@ -123,17 +143,18 @@ WorldPackets::Character::EnumCharactersResult::CharacterInfo::CharacterInfo(Fiel } } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Character::EnumCharactersResult::CharacterInfo::VisualItemInfo const& visualItem) +ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::CharacterInfo::VisualItemInfo const& visualItem) { data << uint32(visualItem.DisplayID); data << uint32(visualItem.DisplayEnchantID); + data << int32(visualItem.ItemModifiedAppearanceID); data << uint8(visualItem.InvType); data << uint8(visualItem.Subclass); return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Character::EnumCharactersResult::CharacterInfo const& charInfo) +ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::CharacterInfo const& charInfo) { data << charInfo.Guid; data << uint64(charInfo.GuildClubMemberID); @@ -141,12 +162,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Character::EnumCharacters data << uint8(charInfo.RaceID); data << uint8(charInfo.ClassID); data << uint8(charInfo.SexID); - data << uint8(charInfo.SkinID); - data << uint8(charInfo.FaceID); - data << uint8(charInfo.HairStyle); - data << uint8(charInfo.HairColor); - data << uint8(charInfo.FacialHair); - data.append(charInfo.CustomDisplay.data(), charInfo.CustomDisplay.size()); + data << uint32(charInfo.Customizations.size()); data << uint8(charInfo.ExperienceLevel); data << int32(charInfo.ZoneID); data << int32(charInfo.MapID); @@ -162,7 +178,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Character::EnumCharacters data << uint32(charInfo.ProfessionIds[0]); data << uint32(charInfo.ProfessionIds[1]); - for (WorldPackets::Character::EnumCharactersResult::CharacterInfo::VisualItemInfo const& visualItem : charInfo.VisualItems) + for (EnumCharactersResult::CharacterInfo::VisualItemInfo const& visualItem : charInfo.VisualItems) data << visualItem; data << uint32(charInfo.LastPlayedTime); @@ -170,18 +186,23 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Character::EnumCharacters data << uint32(charInfo.Unknown703); data << uint32(charInfo.LastLoginVersion); data << uint32(charInfo.Flags4); - data << uint32(charInfo.Unknown830.size()); + data << uint32(charInfo.MailSenders.size()); + data << uint32(charInfo.OverrideSelectScreenFileDataID); + + for (ChrCustomizationChoice customization : charInfo.Customizations) + data << customization; + data.WriteBits(charInfo.Name.length(), 6); data.WriteBit(charInfo.FirstLogin); data.WriteBit(charInfo.BoostInProgress); data.WriteBits(charInfo.unkWod61x, 5); - for (std::string const& str : charInfo.Unknown830) + for (std::string const& str : charInfo.MailSenders) data.WriteBits(str.length() + 1, 6); data.FlushBits(); - for (std::string const& str : charInfo.Unknown830) + for (std::string const& str : charInfo.MailSenders) if (!str.empty()) data << str; @@ -190,7 +211,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Character::EnumCharacters return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Character::EnumCharactersResult::RaceUnlock const& raceUnlock) +ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::RaceUnlock const& raceUnlock) { data << int32(raceUnlock.RaceID); data.WriteBit(raceUnlock.HasExpansion); @@ -201,7 +222,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Character::EnumCharacters return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Character::EnumCharactersResult::UnlockedConditionalAppearance const& unlockedConditionalAppearance) +ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::UnlockedConditionalAppearance const& unlockedConditionalAppearance) { data << int32(unlockedConditionalAppearance.AchievementID); data << int32(unlockedConditionalAppearance.Unused); @@ -209,15 +230,14 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Character::EnumCharacters return data; } -WorldPacket const* WorldPackets::Character::EnumCharactersResult::Write() +WorldPacket const* EnumCharactersResult::Write() { _worldPacket.reserve(9 + Characters.size() * sizeof(CharacterInfo) + RaceUnlockData.size() * sizeof(RaceUnlock)); _worldPacket.WriteBit(Success); _worldPacket.WriteBit(IsDeletedCharacters); - _worldPacket.WriteBit(IsTestDemonHunterCreationAllowed); - _worldPacket.WriteBit(HasDemonHunterOnRealm); - _worldPacket.WriteBit(IsDemonHunterCreationAllowed); + _worldPacket.WriteBit(IsNewPlayerRestrictionSkipped); + _worldPacket.WriteBit(IsNewPlayer); _worldPacket.WriteBit(DisabledClassesMask.is_initialized()); _worldPacket.WriteBit(IsAlliedRacesCreationAllowed); _worldPacket << uint32(Characters.size()); @@ -240,54 +260,66 @@ WorldPacket const* WorldPackets::Character::EnumCharactersResult::Write() return &_worldPacket; } -void WorldPackets::Character::CreateCharacter::Read() +void CheckCharacterNameAvailability::Read() { - CreateInfo.reset(new CharacterCreateInfo()); + _worldPacket >> SequenceIndex; + Name = _worldPacket.ReadString(_worldPacket.ReadBits(6)); +} + +WorldPacket const* CheckCharacterNameAvailabilityResult::Write() +{ + _worldPacket << uint32(SequenceIndex); + _worldPacket << uint32(Result); + + return &_worldPacket; +} + +void CreateCharacter::Read() +{ + CreateInfo = std::make_shared<CharacterCreateInfo>(); uint32 nameLength = _worldPacket.ReadBits(6); bool const hasTemplateSet = _worldPacket.ReadBit(); CreateInfo->IsTrialBoost = _worldPacket.ReadBit(); + CreateInfo->UseNPE = _worldPacket.ReadBit(); _worldPacket >> CreateInfo->Race; _worldPacket >> CreateInfo->Class; _worldPacket >> CreateInfo->Sex; - _worldPacket >> CreateInfo->Skin; - _worldPacket >> CreateInfo->Face; - _worldPacket >> CreateInfo->HairStyle; - _worldPacket >> CreateInfo->HairColor; - _worldPacket >> CreateInfo->FacialHairStyle; - _worldPacket >> CreateInfo->OutfitId; - _worldPacket.read(CreateInfo->CustomDisplay.data(), CreateInfo->CustomDisplay.size()); + CreateInfo->Customizations.resize(_worldPacket.read<uint32>()); CreateInfo->Name = _worldPacket.ReadString(nameLength); if (hasTemplateSet) CreateInfo->TemplateSet = _worldPacket.read<int32>(); + + for (ChrCustomizationChoice& customization : CreateInfo->Customizations) + _worldPacket >> customization; } -WorldPacket const* WorldPackets::Character::CreateChar::Write() +WorldPacket const* CreateChar::Write() { _worldPacket << uint8(Code); _worldPacket << Guid; return &_worldPacket; } -void WorldPackets::Character::CharDelete::Read() +void CharDelete::Read() { _worldPacket >> Guid; } -WorldPacket const* WorldPackets::Character::DeleteChar::Write() +WorldPacket const* DeleteChar::Write() { _worldPacket << uint8(Code); return &_worldPacket; } -void WorldPackets::Character::CharacterRenameRequest::Read() +void CharacterRenameRequest::Read() { - RenameInfo.reset(new CharacterRenameInfo()); + RenameInfo = std::make_shared<CharacterRenameInfo>(); _worldPacket >> RenameInfo->Guid; RenameInfo->NewName = _worldPacket.ReadString(_worldPacket.ReadBits(6)); } -WorldPacket const* WorldPackets::Character::CharacterRenameResult::Write() +WorldPacket const* CharacterRenameResult::Write() { _worldPacket << uint8(Result); _worldPacket.WriteBit(Guid.is_initialized()); @@ -302,23 +334,21 @@ WorldPacket const* WorldPackets::Character::CharacterRenameResult::Write() return &_worldPacket; } -void WorldPackets::Character::CharCustomize::Read() +void CharCustomize::Read() { - CustomizeInfo.reset(new CharCustomizeInfo()); + CustomizeInfo = std::make_shared<CharCustomizeInfo>(); _worldPacket >> CustomizeInfo->CharGUID; _worldPacket >> CustomizeInfo->SexID; - _worldPacket >> CustomizeInfo->SkinID; - _worldPacket >> CustomizeInfo->HairColorID; - _worldPacket >> CustomizeInfo->HairStyleID; - _worldPacket >> CustomizeInfo->FacialHairStyleID; - _worldPacket >> CustomizeInfo->FaceID; - _worldPacket.read(CustomizeInfo->CustomDisplay.data(), CustomizeInfo->CustomDisplay.size()); + CustomizeInfo->Customizations.resize(_worldPacket.read<uint32>()); + for (ChrCustomizationChoice& customization : CustomizeInfo->Customizations) + _worldPacket >> customization; + CustomizeInfo->CharName = _worldPacket.ReadString(_worldPacket.ReadBits(6)); } -void WorldPackets::Character::CharRaceOrFactionChange::Read() +void CharRaceOrFactionChange::Read() { - RaceOrFactionChangeInfo.reset(new CharRaceOrFactionChangeInfo()); + RaceOrFactionChangeInfo = std::make_shared<CharRaceOrFactionChangeInfo>(); RaceOrFactionChangeInfo->FactionChange = _worldPacket.ReadBit(); @@ -327,16 +357,13 @@ void WorldPackets::Character::CharRaceOrFactionChange::Read() _worldPacket >> RaceOrFactionChangeInfo->Guid; _worldPacket >> RaceOrFactionChangeInfo->SexID; _worldPacket >> RaceOrFactionChangeInfo->RaceID; - _worldPacket >> RaceOrFactionChangeInfo->SkinID; - _worldPacket >> RaceOrFactionChangeInfo->HairColorID; - _worldPacket >> RaceOrFactionChangeInfo->HairStyleID; - _worldPacket >> RaceOrFactionChangeInfo->FacialHairStyleID; - _worldPacket >> RaceOrFactionChangeInfo->FaceID; - _worldPacket.read(RaceOrFactionChangeInfo->CustomDisplay.data(), RaceOrFactionChangeInfo->CustomDisplay.size()); + RaceOrFactionChangeInfo->Customizations.resize(_worldPacket.read<uint32>()); RaceOrFactionChangeInfo->Name = _worldPacket.ReadString(nameLength); + for (ChrCustomizationChoice& customization : RaceOrFactionChangeInfo->Customizations) + _worldPacket >> customization; } -WorldPacket const* WorldPackets::Character::CharFactionChangeResult::Write() +WorldPacket const* CharFactionChangeResult::Write() { _worldPacket << uint8(Result); _worldPacket << Guid; @@ -347,26 +374,22 @@ WorldPacket const* WorldPackets::Character::CharFactionChangeResult::Write() { _worldPacket.WriteBits(Display->Name.length(), 6); _worldPacket << uint8(Display->SexID); - _worldPacket << uint8(Display->SkinID); - _worldPacket << uint8(Display->HairColorID); - _worldPacket << uint8(Display->HairStyleID); - _worldPacket << uint8(Display->FacialHairStyleID); - _worldPacket << uint8(Display->FaceID); _worldPacket << uint8(Display->RaceID); - _worldPacket.append(Display->CustomDisplay.data(), Display->CustomDisplay.size()); _worldPacket.WriteString(Display->Name); + for (ChrCustomizationChoice customization : *Display->Customizations) + _worldPacket << customization; } return &_worldPacket; } -void WorldPackets::Character::GenerateRandomCharacterName::Read() +void GenerateRandomCharacterName::Read() { _worldPacket >> Race; _worldPacket >> Sex; } -WorldPacket const* WorldPackets::Character::GenerateRandomCharacterNameResult::Write() +WorldPacket const* GenerateRandomCharacterNameResult::Write() { _worldPacket.WriteBit(Success); _worldPacket.WriteBits(Name.length(), 6); @@ -377,11 +400,11 @@ WorldPacket const* WorldPackets::Character::GenerateRandomCharacterNameResult::W return &_worldPacket; } -WorldPackets::Character::ReorderCharacters::ReorderCharacters(WorldPacket&& packet) : ClientPacket(CMSG_REORDER_CHARACTERS, std::move(packet)) +ReorderCharacters::ReorderCharacters(WorldPacket&& packet) : ClientPacket(CMSG_REORDER_CHARACTERS, std::move(packet)) { } -void WorldPackets::Character::ReorderCharacters::Read() +void ReorderCharacters::Read() { Entries.resize(_worldPacket.ReadBits(9)); for (ReorderInfo& reorderInfo : Entries) @@ -391,14 +414,14 @@ void WorldPackets::Character::ReorderCharacters::Read() } } -void WorldPackets::Character::UndeleteCharacter::Read() +void UndeleteCharacter::Read() { - UndeleteInfo.reset(new CharacterUndeleteInfo()); + UndeleteInfo = std::make_shared<CharacterUndeleteInfo>(); _worldPacket >> UndeleteInfo->ClientToken; _worldPacket >> UndeleteInfo->CharacterGuid; } -WorldPacket const* WorldPackets::Character::UndeleteCharacterResponse::Write() +WorldPacket const* UndeleteCharacterResponse::Write() { ASSERT(UndeleteInfo); _worldPacket << int32(UndeleteInfo->ClientToken); @@ -407,7 +430,7 @@ WorldPacket const* WorldPackets::Character::UndeleteCharacterResponse::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Character::UndeleteCooldownStatusResponse::Write() +WorldPacket const* UndeleteCooldownStatusResponse::Write() { _worldPacket.WriteBit(OnCooldown); _worldPacket << uint32(MaxCooldown); @@ -415,13 +438,13 @@ WorldPacket const* WorldPackets::Character::UndeleteCooldownStatusResponse::Writ return &_worldPacket; } -void WorldPackets::Character::PlayerLogin::Read() +void PlayerLogin::Read() { _worldPacket >> Guid; _worldPacket >> FarClip; } -WorldPacket const* WorldPackets::Character::LoginVerifyWorld::Write() +WorldPacket const* LoginVerifyWorld::Write() { _worldPacket << int32(MapID); _worldPacket << Pos; @@ -429,18 +452,18 @@ WorldPacket const* WorldPackets::Character::LoginVerifyWorld::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Character::CharacterLoginFailed::Write() +WorldPacket const* CharacterLoginFailed::Write() { _worldPacket << uint8(Code); return &_worldPacket; } -void WorldPackets::Character::LogoutRequest::Read() +void LogoutRequest::Read() { IdleLogout = _worldPacket.ReadBit(); } -WorldPacket const* WorldPackets::Character::LogoutResponse::Write() +WorldPacket const* LogoutResponse::Write() { _worldPacket << int32(LogoutResult); _worldPacket.WriteBit(Instant); @@ -448,13 +471,13 @@ WorldPacket const* WorldPackets::Character::LogoutResponse::Write() return &_worldPacket; } -void WorldPackets::Character::LoadingScreenNotify::Read() +void LoadingScreenNotify::Read() { _worldPacket >> MapID; Showing = _worldPacket.ReadBit(); } -WorldPacket const* WorldPackets::Character::InitialSetup::Write() +WorldPacket const* InitialSetup::Write() { _worldPacket << uint8(ServerExpansionLevel); _worldPacket << uint8(ServerExpansionTier); @@ -462,17 +485,17 @@ WorldPacket const* WorldPackets::Character::InitialSetup::Write() return &_worldPacket; } -void WorldPackets::Character::SetActionBarToggles::Read() +void SetActionBarToggles::Read() { _worldPacket >> Mask; } -void WorldPackets::Character::RequestPlayedTime::Read() +void RequestPlayedTime::Read() { TriggerScriptEvent = _worldPacket.ReadBit(); } -WorldPacket const* WorldPackets::Character::PlayedTime::Write() +WorldPacket const* PlayedTime::Write() { _worldPacket << int32(TotalTime); _worldPacket << int32(LevelTime); @@ -482,29 +505,26 @@ WorldPacket const* WorldPackets::Character::PlayedTime::Write() return &_worldPacket; } -void WorldPackets::Character::SetTitle::Read() +void SetTitle::Read() { _worldPacket >> TitleID; } -void WorldPackets::Character::AlterApperance::Read() +void AlterApperance::Read() { - _worldPacket >> NewHairStyle; - _worldPacket >> NewHairColor; - _worldPacket >> NewFacialHair; - _worldPacket >> NewSkinColor; - _worldPacket >> NewFace; - for (std::size_t i = 0; i < NewCustomDisplay.size(); ++i) - _worldPacket >> NewCustomDisplay[i]; + Customizations.resize(_worldPacket.read<uint32>()); + _worldPacket >> NewSex; + for (ChrCustomizationChoice& customization : Customizations) + _worldPacket >> customization; } -WorldPacket const* WorldPackets::Character::BarberShopResult::Write() +WorldPacket const* BarberShopResult::Write() { _worldPacket << int32(Result); return &_worldPacket; } -WorldPacket const* WorldPackets::Character::LogXPGain::Write() +WorldPacket const* LogXPGain::Write() { _worldPacket << Victim; _worldPacket << int32(Original); @@ -516,64 +536,56 @@ WorldPacket const* WorldPackets::Character::LogXPGain::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Character::TitleEarned::Write() +WorldPacket const* TitleEarned::Write() { _worldPacket << uint32(Index); return &_worldPacket; } -void WorldPackets::Character::SetFactionAtWar::Read() +void SetFactionAtWar::Read() { _worldPacket >> FactionIndex; } -void WorldPackets::Character::SetFactionNotAtWar::Read() +void SetFactionNotAtWar::Read() { _worldPacket >> FactionIndex; } -void WorldPackets::Character::SetFactionInactive::Read() +void SetFactionInactive::Read() { _worldPacket >> Index; State = _worldPacket.ReadBit(); } -void WorldPackets::Character::SetWatchedFaction::Read() +void SetWatchedFaction::Read() { _worldPacket >> FactionIndex; } -WorldPacket const* WorldPackets::Character::SetFactionVisible::Write() +WorldPacket const* SetFactionVisible::Write() { _worldPacket << FactionIndex; return &_worldPacket; } -WorldPackets::Character::CharCustomizeSuccess::CharCustomizeSuccess(WorldPackets::Character::CharCustomizeInfo const* info) - : ServerPacket(SMSG_CHAR_CUSTOMIZE_SUCCESS, 16 + 1 + 1 + 1 + 1 + 1 + 1 + 1) +CharCustomizeSuccess::CharCustomizeSuccess(CharCustomizeInfo const* info) + : ServerPacket(SMSG_CHAR_CUSTOMIZE_SUCCESS, 16 + 1 + 1 + 1 + 1 + 1 + 1 + 1), Customizations(info->Customizations) { CharGUID = info->CharGUID; SexID = info->SexID; - SkinID = info->SkinID; - HairColorID = info->HairColorID; - HairStyleID = info->HairStyleID; - FacialHairStyleID = info->FacialHairStyleID; - FaceID = info->FaceID; CharName = info->CharName; - CustomDisplay = info->CustomDisplay; } -WorldPacket const* WorldPackets::Character::CharCustomizeSuccess::Write() +WorldPacket const* CharCustomizeSuccess::Write() { _worldPacket << CharGUID; _worldPacket << uint8(SexID); - _worldPacket << uint8(SkinID); - _worldPacket << uint8(HairColorID); - _worldPacket << uint8(HairStyleID); - _worldPacket << uint8(FacialHairStyleID); - _worldPacket << uint8(FaceID); - _worldPacket.append(CustomDisplay.data(), CustomDisplay.size()); + _worldPacket << uint32(Customizations.size()); + for (ChrCustomizationChoice customization : Customizations) + _worldPacket << customization; + _worldPacket.WriteBits(CharName.length(), 6); _worldPacket.FlushBits(); _worldPacket.WriteString(CharName); @@ -581,7 +593,7 @@ WorldPacket const* WorldPackets::Character::CharCustomizeSuccess::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Character::CharCustomizeFailure::Write() +WorldPacket const* CharCustomizeFailure::Write() { _worldPacket << uint8(Result); _worldPacket << CharGUID; @@ -589,7 +601,7 @@ WorldPacket const* WorldPackets::Character::CharCustomizeFailure::Write() return &_worldPacket; } -void WorldPackets::Character::SetPlayerDeclinedNames::Read() +void SetPlayerDeclinedNames::Read() { _worldPacket >> Player; @@ -602,10 +614,12 @@ void WorldPackets::Character::SetPlayerDeclinedNames::Read() DeclinedNames.name[i] = _worldPacket.ReadString(stringLengths[i]); } -WorldPacket const * WorldPackets::Character::SetPlayerDeclinedNamesResult::Write() +WorldPacket const * SetPlayerDeclinedNamesResult::Write() { _worldPacket << int32(ResultCode); _worldPacket << Player; return &_worldPacket; } +} +} diff --git a/src/server/game/Server/Packets/CharacterPackets.h b/src/server/game/Server/Packets/CharacterPackets.h index 5880cb43119..d34e5d7e301 100644 --- a/src/server/game/Server/Packets/CharacterPackets.h +++ b/src/server/game/Server/Packets/CharacterPackets.h @@ -35,6 +35,15 @@ namespace WorldPackets { namespace Character { + struct ChrCustomizationChoice + { + uint32 ChrCustomizationOptionID = 0; + uint32 ChrCustomizationChoiceID = 0; + }; + + ByteBuffer& operator<<(ByteBuffer& data, ChrCustomizationChoice const& customizationChoice); + ByteBuffer& operator>>(ByteBuffer& data, ChrCustomizationChoice& customizationChoice); + class EnumCharacters final : public ClientPacket { public: @@ -49,15 +58,10 @@ namespace WorldPackets uint8 Race = RACE_NONE; uint8 Class = CLASS_NONE; uint8 Sex = GENDER_NONE; - uint8 Skin = 0; - uint8 Face = 0; - uint8 HairStyle = 0; - uint8 HairColor = 0; - uint8 FacialHairStyle = 0; - std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> CustomDisplay = { }; - uint8 OutfitId = 0; + Array<ChrCustomizationChoice, 50> Customizations; Optional<int32> TemplateSet; bool IsTrialBoost = false; + bool UseNPE = false; std::string Name; /// Server side data @@ -72,30 +76,20 @@ namespace WorldPackets struct CharCustomizeInfo { - uint8 HairStyleID = 0; - uint8 FaceID = 0; ObjectGuid CharGUID; uint8 SexID = GENDER_NONE; std::string CharName; - uint8 HairColorID = 0; - uint8 FacialHairStyleID = 0; - uint8 SkinID = 0; - std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> CustomDisplay = { }; + Array<ChrCustomizationChoice, 50> Customizations; }; struct CharRaceOrFactionChangeInfo { - uint8 HairColorID = 0; uint8 RaceID = RACE_NONE; uint8 SexID = GENDER_NONE; - uint8 SkinID = 0; - uint8 FacialHairStyleID = 0; ObjectGuid Guid; bool FactionChange = false; std::string Name; - uint8 FaceID = 0; - uint8 HairStyleID = 0; - std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> CustomDisplay = { }; + Array<ChrCustomizationChoice, 50> Customizations; }; struct CharacterUndeleteInfo @@ -129,12 +123,7 @@ namespace WorldPackets uint8 RaceID = 0; uint8 ClassID = 0; uint8 SexID = 0; - uint8 SkinID = 0; - uint8 FaceID = 0; - uint8 HairStyle = 0; - uint8 HairColor = 0; - uint8 FacialHair = 0; - std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> CustomDisplay = { }; + std::vector<ChrCustomizationChoice> Customizations; uint8 ExperienceLevel = 0; int32 ZoneID = 0; int32 MapID = 0; @@ -150,6 +139,7 @@ namespace WorldPackets uint16 SpecID = 0; uint32 Unknown703 = 0; uint32 LastLoginVersion = 0; + uint32 OverrideSelectScreenFileDataID = 0; uint32 PetCreatureDisplayID = 0; uint32 PetExperienceLevel = 0; @@ -162,13 +152,13 @@ namespace WorldPackets { uint32 DisplayID = 0; uint32 DisplayEnchantID = 0; + int32 ItemModifiedAppearanceID = 0; // also -1 is some special value uint8 InvType = 0; uint8 Subclass = 0; }; std::array<VisualItemInfo, 23> VisualItems = { }; - std::vector<std::string> Unknown830; // Something with character names, same length limit as name, - // client accepts unlimited number of these in packet but only uses first 3 + std::vector<std::string> MailSenders; }; struct RaceUnlock @@ -191,9 +181,8 @@ namespace WorldPackets bool Success = false; ///< bool IsDeletedCharacters = false; ///< used for character undelete list - bool IsTestDemonHunterCreationAllowed = false; ///< allows client to skip 1 per realm and level 70 requirements - bool HasDemonHunterOnRealm = false; - bool IsDemonHunterCreationAllowed = false; ///< used for demon hunter early access + bool IsNewPlayerRestrictionSkipped = false; ///< allows client to skip new player restrictions + bool IsNewPlayer = false; ///< forbids hero classes and allied races bool IsAlliedRacesCreationAllowed = false; int32 MaxCharacterLevel = 1; @@ -204,6 +193,31 @@ namespace WorldPackets std::vector<UnlockedConditionalAppearance> UnlockedConditionalAppearances; }; + class CheckCharacterNameAvailability final : public ClientPacket + { + public: + CheckCharacterNameAvailability(WorldPacket&& packet) : ClientPacket(CMSG_CHECK_CHARACTER_NAME_AVAILABILITY, std::move(packet)) { } + + void Read() override; + + uint32 SequenceIndex = 0; + std::string Name; + }; + + class CheckCharacterNameAvailabilityResult final : public ServerPacket + { + public: + CheckCharacterNameAvailabilityResult(uint32 sequenceIndex, uint32 result) : ServerPacket(SMSG_CHECK_CHARACTER_NAME_AVAILABILITY_RESULT, 4 + 4), + SequenceIndex(sequenceIndex), Result(result) + { + } + + WorldPacket const* Write() override; + + uint32 SequenceIndex; + uint32 Result; + }; + class CreateCharacter final : public ClientPacket { public: @@ -335,13 +349,8 @@ namespace WorldPackets { std::string Name; uint8 SexID = 0; - uint8 SkinID = 0; - uint8 HairColorID = 0; - uint8 HairStyleID = 0; - uint8 FacialHairStyleID = 0; - uint8 FaceID = 0; uint8 RaceID = RACE_NONE; - std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> CustomDisplay = { }; + Array<ChrCustomizationChoice, 50> const* Customizations = nullptr; }; CharFactionChangeResult() : ServerPacket(SMSG_CHAR_FACTION_CHANGE_RESULT, 20 + sizeof(CharFactionChangeDisplayInfo)) { } @@ -388,7 +397,7 @@ namespace WorldPackets void Read() override; - Array<ReorderInfo, MAX_CHARACTERS_PER_REALM> Entries; + Array<ReorderInfo, 200> Entries; }; class UndeleteCharacter final : public ClientPacket @@ -605,12 +614,8 @@ namespace WorldPackets void Read() override; - uint32 NewHairStyle = 0; - uint32 NewHairColor = 0; - uint32 NewFacialHair = 0; - uint32 NewSkinColor = 0; - uint32 NewFace = 0; - std::array<uint32, PLAYER_CUSTOM_DISPLAY_SIZE> NewCustomDisplay = { }; + uint8 NewSex = 0; + Array<ChrCustomizationChoice, 50> Customizations; }; class BarberShopResult final : public ServerPacket @@ -710,7 +715,6 @@ namespace WorldPackets class CharCustomizeSuccess final : public ServerPacket { public: - CharCustomizeSuccess() : ServerPacket(SMSG_CHAR_CUSTOMIZE_SUCCESS, 16 + 1 + 1 + 1 + 1 + 1 + 1 + 1) { } CharCustomizeSuccess(CharCustomizeInfo const* customizeInfo); WorldPacket const* Write() override; @@ -718,12 +722,7 @@ namespace WorldPackets ObjectGuid CharGUID; std::string CharName; uint8 SexID = 0; - uint8 SkinID = 0; - uint8 HairColorID = 0; - uint8 HairStyleID = 0; - uint8 FacialHairStyleID = 0; - uint8 FaceID = 0; - std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> CustomDisplay = { }; + Array<ChrCustomizationChoice, 50> const& Customizations; }; class CharCustomizeFailure final : public ServerPacket diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp index d52b9045983..9b96753af8b 100644 --- a/src/server/game/Server/Packets/ChatPackets.cpp +++ b/src/server/game/Server/Packets/ChatPackets.cpp @@ -176,7 +176,7 @@ WorldPacket const* WorldPackets::Chat::Chat::Write() _worldPacket.WriteBits(Prefix.length(), 5); _worldPacket.WriteBits(_Channel.length(), 7); _worldPacket.WriteBits(ChatText.length(), 12); - _worldPacket.WriteBits(_ChatFlags, 11); + _worldPacket.WriteBits(_ChatFlags, 14); _worldPacket.WriteBit(HideChatLog); _worldPacket.WriteBit(FakeSenderName); _worldPacket.WriteBit(Unused_801.is_initialized()); diff --git a/src/server/game/Server/Packets/ClientConfigPackets.cpp b/src/server/game/Server/Packets/ClientConfigPackets.cpp index 150c229788c..8ddc8c998ab 100644 --- a/src/server/game/Server/Packets/ClientConfigPackets.cpp +++ b/src/server/game/Server/Packets/ClientConfigPackets.cpp @@ -21,7 +21,7 @@ WorldPacket const* WorldPackets::ClientConfig::AccountDataTimes::Write() { _worldPacket << PlayerGuid; _worldPacket << uint32(ServerTime); - _worldPacket.append(AccountTimes, NUM_ACCOUNT_DATA_TYPES); + _worldPacket.append(AccountTimes.data(), AccountTimes.size()); return &_worldPacket; } diff --git a/src/server/game/Server/Packets/ClientConfigPackets.h b/src/server/game/Server/Packets/ClientConfigPackets.h index 810d2b8dffe..230df93da77 100644 --- a/src/server/game/Server/Packets/ClientConfigPackets.h +++ b/src/server/game/Server/Packets/ClientConfigPackets.h @@ -34,7 +34,7 @@ namespace WorldPackets ObjectGuid PlayerGuid; uint32 ServerTime = 0; - uint32 AccountTimes[NUM_ACCOUNT_DATA_TYPES]; + std::array<uint32, NUM_ACCOUNT_DATA_TYPES> AccountTimes = { }; }; class ClientCacheVersion final : public ServerPacket diff --git a/src/server/game/Server/Packets/CombatLogPackets.cpp b/src/server/game/Server/Packets/CombatLogPackets.cpp index e0253371a2e..cfdb4b39f40 100644 --- a/src/server/game/Server/Packets/CombatLogPackets.cpp +++ b/src/server/game/Server/Packets/CombatLogPackets.cpp @@ -24,7 +24,7 @@ WorldPacket const* WorldPackets::CombatLog::SpellNonMeleeDamageLog::Write() *this << CasterGUID; *this << CastID; *this << int32(SpellID); - *this << int32(SpellXSpellVisualID); + *this << Visual; *this << int32(Damage); *this << int32(OriginalDamage); *this << int32(Overkill); @@ -349,8 +349,8 @@ WorldPacket const* WorldPackets::CombatLog::AttackerStateUpdate::Write() attackRoundInfo << uint8(ContentTuning.TargetMaxScalingLevel); attackRoundInfo << int16(ContentTuning.PlayerLevelDelta); attackRoundInfo << int8(ContentTuning.TargetScalingLevelDelta); - attackRoundInfo << uint16(ContentTuning.PlayerItemLevel); - attackRoundInfo << uint16(ContentTuning.TargetItemLevel); + attackRoundInfo << float(ContentTuning.PlayerItemLevel); + attackRoundInfo << float(ContentTuning.TargetItemLevel); attackRoundInfo << uint16(ContentTuning.ScalingHealthItemLevelCurveID); attackRoundInfo << uint8(ContentTuning.ScalesWithItemLevel ? 1 : 0); diff --git a/src/server/game/Server/Packets/CombatLogPackets.h b/src/server/game/Server/Packets/CombatLogPackets.h index 9227977652e..0d06623746f 100644 --- a/src/server/game/Server/Packets/CombatLogPackets.h +++ b/src/server/game/Server/Packets/CombatLogPackets.h @@ -37,7 +37,7 @@ namespace WorldPackets ObjectGuid CasterGUID; ObjectGuid CastID; int32 SpellID = 0; - int32 SpellXSpellVisualID = 0; + Spells::SpellCastVisual Visual; int32 Damage = 0; int32 OriginalDamage = 0; int32 Overkill = -1; @@ -92,7 +92,7 @@ namespace WorldPackets class SpellHealLog final : public CombatLogServerPacket { public: - SpellHealLog() : CombatLogServerPacket(SMSG_SPELL_HEAL_LOG, 16 + 16 + 4 * 4 + 1) { } + SpellHealLog() : CombatLogServerPacket(SMSG_SPELL_HEAL_LOG, 16 + 16 + 4 * 5 + 1) { } WorldPacket const* Write() override; diff --git a/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp b/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp index 8b6654e79dc..7a48a3ed2da 100644 --- a/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp +++ b/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp @@ -23,7 +23,11 @@ #include "SpellInfo.h" #include "Unit.h" -void WorldPackets::Spells::SpellCastLogData::Initialize(Unit const* unit) +namespace WorldPackets +{ +namespace Spells +{ +void SpellCastLogData::Initialize(Unit const* unit) { Health = unit->GetHealth(); AttackPower = unit->GetTotalAttackPowerValue(unit->getClass() == CLASS_HUNTER ? RANGED_ATTACK : BASE_ATTACK); @@ -32,7 +36,7 @@ void WorldPackets::Spells::SpellCastLogData::Initialize(Unit const* unit) PowerData.emplace_back(int32(unit->GetPowerType()), unit->GetPower(unit->GetPowerType()), int32(0)); } -void WorldPackets::Spells::SpellCastLogData::Initialize(Spell const* spell) +void SpellCastLogData::Initialize(Spell const* spell) { Health = spell->GetCaster()->GetHealth(); AttackPower = spell->GetCaster()->GetTotalAttackPowerValue(spell->GetCaster()->getClass() == CLASS_HUNTER ? RANGED_ATTACK : BASE_ATTACK); @@ -51,110 +55,99 @@ void WorldPackets::Spells::SpellCastLogData::Initialize(Spell const* spell) PowerData.insert(PowerData.begin(), SpellLogPowerData(int32(primaryPowerType), spell->GetCaster()->GetPower(primaryPowerType), 0)); } -namespace WorldPackets +template<class T, class U> +bool ContentTuningParams::GenerateDataForUnits(T* /*attacker*/, U* /*target*/) { - namespace Spells - { - template<class T, class U> - bool ContentTuningParams::GenerateDataForUnits(T* /*attacker*/, U* /*target*/) - { - return false; - } + return false; +} - template<> - bool ContentTuningParams::GenerateDataForUnits<Creature, Player>(Creature* attacker, Player* target) - { - CreatureTemplate const* creatureTemplate = attacker->GetCreatureTemplate(); - CreatureLevelScaling const* creatureScaling = creatureTemplate->GetLevelScaling(attacker->GetMap()->GetDifficultyID()); - - Type = TYPE_CREATURE_TO_PLAYER_DAMAGE; - PlayerLevelDelta = target->m_activePlayerData->ScalingPlayerLevelDelta; - PlayerItemLevel = target->GetAverageItemLevel(); - TargetItemLevel = 0; - ScalingHealthItemLevelCurveID = target->m_unitData->ScalingHealthItemLevelCurveID; - TargetLevel = target->getLevel(); - Expansion = creatureTemplate->HealthScalingExpansion; - TargetMinScalingLevel = uint8(creatureScaling->MinLevel); - TargetMaxScalingLevel = uint8(creatureScaling->MaxLevel); - TargetScalingLevelDelta = int8(attacker->m_unitData->ScalingLevelDelta); - return true; - } +template<> +bool ContentTuningParams::GenerateDataForUnits<Creature, Player>(Creature* attacker, Player* target) +{ + CreatureTemplate const* creatureTemplate = attacker->GetCreatureTemplate(); + CreatureLevelScaling const* creatureScaling = creatureTemplate->GetLevelScaling(attacker->GetMap()->GetDifficultyID()); + + Type = TYPE_CREATURE_TO_PLAYER_DAMAGE; + PlayerLevelDelta = target->m_activePlayerData->ScalingPlayerLevelDelta; + PlayerItemLevel = target->GetAverageItemLevel(); + TargetItemLevel = 0; + ScalingHealthItemLevelCurveID = target->m_unitData->ScalingHealthItemLevelCurveID; + TargetLevel = target->getLevel(); + Expansion = creatureTemplate->HealthScalingExpansion; + TargetMinScalingLevel = uint8(creatureScaling->MinLevel); + TargetMaxScalingLevel = uint8(creatureScaling->MaxLevel); + TargetScalingLevelDelta = int8(attacker->m_unitData->ScalingLevelDelta); + return true; +} - template<> - bool ContentTuningParams::GenerateDataForUnits<Player, Creature>(Player* attacker, Creature* target) +template<> +bool ContentTuningParams::GenerateDataForUnits<Player, Creature>(Player* attacker, Creature* target) +{ + CreatureTemplate const* creatureTemplate = target->GetCreatureTemplate(); + CreatureLevelScaling const* creatureScaling = creatureTemplate->GetLevelScaling(target->GetMap()->GetDifficultyID()); + + Type = TYPE_PLAYER_TO_CREATURE_DAMAGE; + PlayerLevelDelta = attacker->m_activePlayerData->ScalingPlayerLevelDelta; + PlayerItemLevel = attacker->GetAverageItemLevel(); + TargetItemLevel = 0; + ScalingHealthItemLevelCurveID = target->m_unitData->ScalingHealthItemLevelCurveID; + TargetLevel = target->getLevel(); + Expansion = creatureTemplate->HealthScalingExpansion; + TargetMinScalingLevel = uint8(creatureScaling->MinLevel); + TargetMaxScalingLevel = uint8(creatureScaling->MaxLevel); + TargetScalingLevelDelta = int8(target->m_unitData->ScalingLevelDelta); + return true; +} + +template<> +bool ContentTuningParams::GenerateDataForUnits<Creature, Creature>(Creature* attacker, Creature* target) +{ + Creature* accessor = target->HasScalableLevels() ? target : attacker; + CreatureTemplate const* creatureTemplate = accessor->GetCreatureTemplate(); + CreatureLevelScaling const* creatureScaling = creatureTemplate->GetLevelScaling(accessor->GetMap()->GetDifficultyID()); + + Type = TYPE_CREATURE_TO_CREATURE_DAMAGE; + PlayerLevelDelta = 0; + PlayerItemLevel = 0; + TargetLevel = target->getLevel(); + Expansion = creatureTemplate->HealthScalingExpansion; + TargetMinScalingLevel = uint8(creatureScaling->MinLevel); + TargetMaxScalingLevel = uint8(creatureScaling->MaxLevel); + TargetScalingLevelDelta = int8(accessor->m_unitData->ScalingLevelDelta); + return true; +} + +template<> +bool ContentTuningParams::GenerateDataForUnits<Unit, Unit>(Unit* attacker, Unit* target) +{ + if (Player* playerAttacker = attacker->ToPlayer()) + { + if (Player* playerTarget = target->ToPlayer()) + return GenerateDataForUnits(playerAttacker, playerTarget); + else if (Creature* creatureTarget = target->ToCreature()) { - CreatureTemplate const* creatureTemplate = target->GetCreatureTemplate(); - CreatureLevelScaling const* creatureScaling = creatureTemplate->GetLevelScaling(target->GetMap()->GetDifficultyID()); - - Type = TYPE_PLAYER_TO_CREATURE_DAMAGE; - PlayerLevelDelta = attacker->m_activePlayerData->ScalingPlayerLevelDelta; - PlayerItemLevel = attacker->GetAverageItemLevel(); - TargetItemLevel = 0; - ScalingHealthItemLevelCurveID = target->m_unitData->ScalingHealthItemLevelCurveID; - TargetLevel = target->getLevel(); - Expansion = creatureTemplate->HealthScalingExpansion; - TargetMinScalingLevel = uint8(creatureScaling->MinLevel); - TargetMaxScalingLevel = uint8(creatureScaling->MaxLevel); - TargetScalingLevelDelta = int8(target->m_unitData->ScalingLevelDelta); - return true; + if (creatureTarget->HasScalableLevels()) + return GenerateDataForUnits(playerAttacker, creatureTarget); } - - template<> - bool ContentTuningParams::GenerateDataForUnits<Creature, Creature>(Creature* attacker, Creature* target) + } + else if (Creature* creatureAttacker = attacker->ToCreature()) + { + if (Player* playerTarget = target->ToPlayer()) { - Creature* accessor = target->HasScalableLevels() ? target : attacker; - CreatureTemplate const* creatureTemplate = accessor->GetCreatureTemplate(); - CreatureLevelScaling const* creatureScaling = creatureTemplate->GetLevelScaling(accessor->GetMap()->GetDifficultyID()); - - Type = TYPE_CREATURE_TO_CREATURE_DAMAGE; - PlayerLevelDelta = 0; - PlayerItemLevel = 0; - TargetLevel = target->getLevel(); - Expansion = creatureTemplate->HealthScalingExpansion; - TargetMinScalingLevel = uint8(creatureScaling->MinLevel); - TargetMaxScalingLevel = uint8(creatureScaling->MaxLevel); - TargetScalingLevelDelta = int8(accessor->m_unitData->ScalingLevelDelta); - return true; + if (creatureAttacker->HasScalableLevels()) + return GenerateDataForUnits(creatureAttacker, playerTarget); } - - template<> - bool ContentTuningParams::GenerateDataForUnits<Unit, Unit>(Unit* attacker, Unit* target) + else if (Creature* creatureTarget = target->ToCreature()) { - if (Player* playerAttacker = attacker->ToPlayer()) - { - if (Player* playerTarget = target->ToPlayer()) - return GenerateDataForUnits(playerAttacker, playerTarget); - else if (Creature* creatureTarget = target->ToCreature()) - { - if (creatureTarget->HasScalableLevels()) - return GenerateDataForUnits(playerAttacker, creatureTarget); - } - } - else if (Creature* creatureAttacker = attacker->ToCreature()) - { - if (Player* playerTarget = target->ToPlayer()) - { - if (creatureAttacker->HasScalableLevels()) - return GenerateDataForUnits(creatureAttacker, playerTarget); - } - else if (Creature* creatureTarget = target->ToCreature()) - { - if (creatureAttacker->HasScalableLevels() || creatureTarget->HasScalableLevels()) - return GenerateDataForUnits(creatureAttacker, creatureTarget); - } - } - - return false; + if (creatureAttacker->HasScalableLevels() || creatureTarget->HasScalableLevels()) + return GenerateDataForUnits(creatureAttacker, creatureTarget); } } -} -ByteBuffer& WorldPackets::CombatLog::CombatLogServerPacket::WriteLogData() -{ - return _fullLogPacket << LogData; + return false; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastLogData const& spellCastLogData) +ByteBuffer& operator<<(ByteBuffer& data, SpellCastLogData const& spellCastLogData) { data << int64(spellCastLogData.Health); data << int32(spellCastLogData.AttackPower); @@ -173,11 +166,11 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastLogData return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::ContentTuningParams const& contentTuningParams) +ByteBuffer& operator<<(ByteBuffer& data, ContentTuningParams const& contentTuningParams) { + data << float(contentTuningParams.PlayerItemLevel); + data << float(contentTuningParams.TargetItemLevel); data << int16(contentTuningParams.PlayerLevelDelta); - data << uint16(contentTuningParams.PlayerItemLevel); - data << uint16(contentTuningParams.TargetItemLevel); data << uint16(contentTuningParams.ScalingHealthItemLevelCurveID); data << uint8(contentTuningParams.TargetLevel); data << uint8(contentTuningParams.Expansion); @@ -189,3 +182,26 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::ContentTuningPara data.FlushBits(); return data; } + +ByteBuffer& operator>>(ByteBuffer& data, SpellCastVisual& visual) +{ + data >> visual.SpellXSpellVisualID; + data >> visual.ScriptVisualID; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, SpellCastVisual const& visual) +{ + data << int32(visual.SpellXSpellVisualID); + data << int32(visual.ScriptVisualID); + + return data; +} +} +} + +ByteBuffer& WorldPackets::CombatLog::CombatLogServerPacket::WriteLogData() +{ + return _fullLogPacket << LogData; +} diff --git a/src/server/game/Server/Packets/CombatLogPacketsCommon.h b/src/server/game/Server/Packets/CombatLogPacketsCommon.h index 249e8430721..298d478cc94 100644 --- a/src/server/game/Server/Packets/CombatLogPacketsCommon.h +++ b/src/server/game/Server/Packets/CombatLogPacketsCommon.h @@ -61,8 +61,8 @@ namespace WorldPackets uint32 Type = 0; int16 PlayerLevelDelta = 0; - uint16 PlayerItemLevel = 0; - uint16 TargetItemLevel = 0; + float PlayerItemLevel = 0; + float TargetItemLevel = 0; uint16 ScalingHealthItemLevelCurveID = 0; uint8 TargetLevel = 0; uint8 Expansion = 0; @@ -74,6 +74,17 @@ namespace WorldPackets template<class T, class U> bool GenerateDataForUnits(T* attacker, U* target); }; + + struct SpellCastVisual + { + int32 SpellXSpellVisualID = 0; + int32 ScriptVisualID = 0; + }; + + ByteBuffer& operator<<(ByteBuffer& data, SpellCastLogData const& spellCastLogData); + ByteBuffer& operator<<(ByteBuffer& data, ContentTuningParams const& contentTuningParams); + ByteBuffer& operator>>(ByteBuffer& data, SpellCastVisual& visual); + ByteBuffer& operator<<(ByteBuffer& data, SpellCastVisual const& visual); } namespace CombatLog @@ -129,7 +140,4 @@ namespace WorldPackets } } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastLogData const& spellCastLogData); -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::ContentTuningParams const& contentTuningParams); - #endif // CombatLogPacketsCommon_h__ diff --git a/src/server/game/Server/Packets/EquipmentSetPackets.cpp b/src/server/game/Server/Packets/EquipmentSetPackets.cpp index 3ef50d4d525..ff47852e429 100644 --- a/src/server/game/Server/Packets/EquipmentSetPackets.cpp +++ b/src/server/game/Server/Packets/EquipmentSetPackets.cpp @@ -45,6 +45,9 @@ WorldPacket const* WorldPackets::EquipmentSet::LoadEquipmentSet::Write() _worldPacket.append(equipSet->Enchants.data(), equipSet->Enchants.size()); + _worldPacket << int32(equipSet->Unknown901_1); + _worldPacket << int32(equipSet->Unknown901_2); + _worldPacket.WriteBit(equipSet->AssignedSpecIndex != -1); _worldPacket.WriteBits(equipSet->SetName.length(), 8); _worldPacket.WriteBits(equipSet->SetIcon.length(), 9); @@ -62,7 +65,7 @@ WorldPacket const* WorldPackets::EquipmentSet::LoadEquipmentSet::Write() void WorldPackets::EquipmentSet::SaveEquipmentSet::Read() { - Set.Type = EquipmentSetInfo::EquipmentSetType(_worldPacket.read<int32>()); + Set.Type = _worldPacket.read<EquipmentSetInfo::EquipmentSetType, int32>(); _worldPacket >> Set.Guid; _worldPacket >> Set.SetID; _worldPacket >> Set.IgnoreMask; @@ -76,6 +79,9 @@ void WorldPackets::EquipmentSet::SaveEquipmentSet::Read() _worldPacket >> Set.Enchants[0]; _worldPacket >> Set.Enchants[1]; + _worldPacket >> Set.Unknown901_1; + _worldPacket >> Set.Unknown901_2; + bool hasSpecIndex = _worldPacket.ReadBit(); uint32 setNameLength = _worldPacket.ReadBits(8); diff --git a/src/server/game/Server/Packets/GarrisonPackets.cpp b/src/server/game/Server/Packets/GarrisonPackets.cpp index 68678dc7a9f..55f778b39b6 100644 --- a/src/server/game/Server/Packets/GarrisonPackets.cpp +++ b/src/server/game/Server/Packets/GarrisonPackets.cpp @@ -18,7 +18,11 @@ #include "GarrisonPackets.h" #include "DB2Structure.h" -WorldPacket const* WorldPackets::Garrison::GarrisonCreateResult::Write() +namespace WorldPackets +{ +namespace Garrison +{ +WorldPacket const* GarrisonCreateResult::Write() { _worldPacket << uint32(Result); _worldPacket << uint32(GarrSiteLevelID); @@ -26,7 +30,7 @@ WorldPacket const* WorldPackets::Garrison::GarrisonCreateResult::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Garrison::GarrisonDeleteResult::Write() +WorldPacket const* GarrisonDeleteResult::Write() { _worldPacket << uint32(Result); _worldPacket << uint32(GarrSiteID); @@ -34,7 +38,7 @@ WorldPacket const* WorldPackets::Garrison::GarrisonDeleteResult::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonPlotInfo& plotInfo) +ByteBuffer& operator<<(ByteBuffer& data, GarrisonPlotInfo& plotInfo) { data << uint32(plotInfo.GarrPlotInstanceID); data << plotInfo.PlotPos; @@ -43,7 +47,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonPlotInf return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonBuildingInfo const& buildingInfo) +ByteBuffer& operator<<(ByteBuffer& data, GarrisonBuildingInfo const& buildingInfo) { data << uint32(buildingInfo.GarrPlotInstanceID); data << uint32(buildingInfo.GarrBuildingID); @@ -56,7 +60,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonBuildin return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonFollower const& follower) +ByteBuffer& operator<<(ByteBuffer& data, GarrisonFollower const& follower) { data << uint64(follower.DbID); data << uint32(follower.GarrFollowerID); @@ -71,6 +75,9 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonFollowe data << uint32(follower.AbilityID.size()); data << uint32(follower.ZoneSupportSpellID); data << uint32(follower.FollowerStatus); + data << int32(follower.Health); + data << int8(follower.BoardIndex); + data << int32(follower.HealingTimestamp); for (GarrAbilityEntry const* ability : follower.AbilityID) data << uint32(ability->ID); @@ -81,7 +88,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonFollowe return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonMission const& mission) +ByteBuffer& operator<<(ByteBuffer& data, GarrisonMission const& mission) { data << uint64(mission.DbID); data << uint32(mission.MissionRecID); @@ -91,13 +98,14 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonMission data << uint32(mission.TravelDuration); data << uint32(mission.MissionDuration); data << uint32(mission.MissionState); - data << uint32(mission.Unknown1); - data << uint32(mission.Unknown2); + data << uint32(mission.SuccessChance); + data << uint32(mission.Flags); + data << float(mission.MissionScalar); return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonMissionReward const& missionRewardItem) +ByteBuffer& operator<<(ByteBuffer& data, GarrisonMissionReward const& missionRewardItem) { data << int32(missionRewardItem.ItemID); data << uint32(missionRewardItem.Quantity); @@ -110,7 +118,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonMission return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonMissionBonusAbility const& areaBonus) +ByteBuffer& operator<<(ByteBuffer& data, GarrisonMissionBonusAbility const& areaBonus) { data << uint32(areaBonus.GarrMssnBonusAbilityID); data << uint32(areaBonus.StartTime); @@ -118,17 +126,66 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonMission return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonTalent const& talent) +ByteBuffer& operator<<(ByteBuffer& data, GarrisonTalentSocketData const& talentSocketData) +{ + data << int32(talentSocketData.SoulbindConduitID); + data << int32(talentSocketData.SoulbindConduitRank); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, GarrisonTalent const& talent) { data << int32(talent.GarrTalentID); data << int32(talent.Rank); data << int32(talent.ResearchStartTime); data << int32(talent.Flags); + data.WriteBit(talent.Socket.is_initialized()); + data.FlushBits(); + + if (talent.Socket) + data << *talent.Socket; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, GarrisonCollectionEntry const& collectionEntry) +{ + data << int32(collectionEntry.EntryID); + data << int32(collectionEntry.Rank); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, GarrisonCollection const& collection) +{ + data << int32(collection.Type); + data << uint32(collection.Entries.size()); + for (GarrisonCollectionEntry const& collectionEntry : collection.Entries) + data << collectionEntry; return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonInfo const& garrison) +ByteBuffer& operator<<(ByteBuffer& data, GarrisonEventEntry const& event) +{ + data << int32(event.EntryID); + data << int32(event.EventValue); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, GarrisonEventList const& eventList) +{ + data << int32(eventList.Type); + data << uint32(eventList.Events.size()); + for (GarrisonEventEntry const& event : eventList.Events) + data << event; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, GarrisonInfo const& garrison) { ASSERT(garrison.Missions.size() == garrison.MissionRewards.size()); ASSERT(garrison.Missions.size() == garrison.MissionOvermaxRewards.size()); @@ -140,46 +197,52 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonInfo co data << uint32(garrison.Buildings.size()); data << uint32(garrison.Plots.size()); data << uint32(garrison.Followers.size()); + data << uint32(garrison.AutoTroops.size()); data << uint32(garrison.Missions.size()); data << uint32(garrison.MissionRewards.size()); data << uint32(garrison.MissionOvermaxRewards.size()); data << uint32(garrison.MissionAreaBonuses.size()); data << uint32(garrison.Talents.size()); + data << uint32(garrison.Collections.size()); + data << uint32(garrison.EventLists.size()); data << uint32(garrison.CanStartMission.size()); data << uint32(garrison.ArchivedMissions.size()); data << int32(garrison.NumFollowerActivationsRemaining); data << uint32(garrison.NumMissionsStartedToday); - for (WorldPackets::Garrison::GarrisonPlotInfo* plot : garrison.Plots) + for (GarrisonPlotInfo* plot : garrison.Plots) data << *plot; - for (WorldPackets::Garrison::GarrisonMission const* mission : garrison.Missions) + for (GarrisonMission const* mission : garrison.Missions) data << *mission; - for (std::vector<WorldPackets::Garrison::GarrisonMissionReward> const& missionReward : garrison.MissionRewards) + for (std::vector<GarrisonMissionReward> const& missionReward : garrison.MissionRewards) data << uint32(missionReward.size()); - for (std::vector<WorldPackets::Garrison::GarrisonMissionReward> const& missionReward : garrison.MissionRewards) - for (WorldPackets::Garrison::GarrisonMissionReward const& missionRewardItem : missionReward) + for (std::vector<GarrisonMissionReward> const& missionReward : garrison.MissionRewards) + for (GarrisonMissionReward const& missionRewardItem : missionReward) data << missionRewardItem; - for (std::vector<WorldPackets::Garrison::GarrisonMissionReward> const& missionReward : garrison.MissionOvermaxRewards) + for (std::vector<GarrisonMissionReward> const& missionReward : garrison.MissionOvermaxRewards) data << uint32(missionReward.size()); - for (std::vector<WorldPackets::Garrison::GarrisonMissionReward> const& missionReward : garrison.MissionOvermaxRewards) - for (WorldPackets::Garrison::GarrisonMissionReward const& missionRewardItem : missionReward) + for (std::vector<GarrisonMissionReward> const& missionReward : garrison.MissionOvermaxRewards) + for (GarrisonMissionReward const& missionRewardItem : missionReward) data << missionRewardItem; - for (WorldPackets::Garrison::GarrisonMissionBonusAbility const* areaBonus : garrison.MissionAreaBonuses) + for (GarrisonMissionBonusAbility const* areaBonus : garrison.MissionAreaBonuses) data << *areaBonus; - for (WorldPackets::Garrison::GarrisonTalent const& talent : garrison.Talents) - data << talent; + for (GarrisonCollection const& collection : garrison.Collections) + data << collection; + + for (GarrisonEventList const& eventList : garrison.EventLists) + data << eventList; if (!garrison.ArchivedMissions.empty()) data.append(garrison.ArchivedMissions.data(), garrison.ArchivedMissions.size()); - for (WorldPackets::Garrison::GarrisonBuildingInfo const* building : garrison.Buildings) + for (GarrisonBuildingInfo const* building : garrison.Buildings) data << *building; for (bool canStartMission : garrison.CanStartMission) @@ -187,20 +250,26 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonInfo co data.FlushBits(); - for (WorldPackets::Garrison::GarrisonFollower const* follower : garrison.Followers) + for (GarrisonFollower const* follower : garrison.Followers) + data << *follower; + + for (GarrisonFollower const* follower : garrison.AutoTroops) data << *follower; + for (GarrisonTalent const& talent : garrison.Talents) + data << talent; + return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::FollowerSoftCapInfo const& followerSoftCapInfo) +ByteBuffer& operator<<(ByteBuffer& data, FollowerSoftCapInfo const& followerSoftCapInfo) { data << int32(followerSoftCapInfo.GarrFollowerTypeID); data << uint32(followerSoftCapInfo.Count); return data; } -WorldPacket const* WorldPackets::Garrison::GetGarrisonInfoResult::Write() +WorldPacket const* GetGarrisonInfoResult::Write() { _worldPacket << int32(FactionIndex); _worldPacket << uint32(Garrisons.size()); @@ -214,7 +283,7 @@ WorldPacket const* WorldPackets::Garrison::GetGarrisonInfoResult::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonRemoteBuildingInfo const& building) +ByteBuffer& operator<<(ByteBuffer& data, GarrisonRemoteBuildingInfo const& building) { data << uint32(building.GarrPlotInstanceID); data << uint32(building.GarrBuildingID); @@ -222,17 +291,17 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonRemoteB return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonRemoteSiteInfo const& site) +ByteBuffer& operator<<(ByteBuffer& data, GarrisonRemoteSiteInfo const& site) { data << uint32(site.GarrSiteLevelID); data << uint32(site.Buildings.size()); - for (WorldPackets::Garrison::GarrisonRemoteBuildingInfo const& building : site.Buildings) + for (GarrisonRemoteBuildingInfo const& building : site.Buildings) data << building; return data; } -WorldPacket const* WorldPackets::Garrison::GarrisonRemoteInfo::Write() +WorldPacket const* GarrisonRemoteInfo::Write() { _worldPacket << uint32(Sites.size()); for (GarrisonRemoteSiteInfo const& site : Sites) @@ -241,14 +310,14 @@ WorldPacket const* WorldPackets::Garrison::GarrisonRemoteInfo::Write() return &_worldPacket; } -void WorldPackets::Garrison::GarrisonPurchaseBuilding::Read() +void GarrisonPurchaseBuilding::Read() { _worldPacket >> NpcGUID; _worldPacket >> PlotInstanceID; _worldPacket >> BuildingID; } -WorldPacket const* WorldPackets::Garrison::GarrisonPlaceBuildingResult::Write() +WorldPacket const* GarrisonPlaceBuildingResult::Write() { _worldPacket << int32(GarrTypeID); _worldPacket << uint32(Result); @@ -259,13 +328,13 @@ WorldPacket const* WorldPackets::Garrison::GarrisonPlaceBuildingResult::Write() return &_worldPacket; } -void WorldPackets::Garrison::GarrisonCancelConstruction::Read() +void GarrisonCancelConstruction::Read() { _worldPacket >> NpcGUID; _worldPacket >> PlotInstanceID; } -WorldPacket const* WorldPackets::Garrison::GarrisonBuildingRemoved::Write() +WorldPacket const* GarrisonBuildingRemoved::Write() { _worldPacket << int32(GarrTypeID); _worldPacket << uint32(Result); @@ -275,7 +344,7 @@ WorldPacket const* WorldPackets::Garrison::GarrisonBuildingRemoved::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Garrison::GarrisonLearnBlueprintResult::Write() +WorldPacket const* GarrisonLearnBlueprintResult::Write() { _worldPacket << int32(GarrTypeID); _worldPacket << uint32(Result); @@ -284,7 +353,7 @@ WorldPacket const* WorldPackets::Garrison::GarrisonLearnBlueprintResult::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Garrison::GarrisonUnlearnBlueprintResult::Write() +WorldPacket const* GarrisonUnlearnBlueprintResult::Write() { _worldPacket << int32(GarrTypeID); _worldPacket << uint32(Result); @@ -293,7 +362,7 @@ WorldPacket const* WorldPackets::Garrison::GarrisonUnlearnBlueprintResult::Write return &_worldPacket; } -WorldPacket const* WorldPackets::Garrison::GarrisonRequestBlueprintAndSpecializationDataResult::Write() +WorldPacket const* GarrisonRequestBlueprintAndSpecializationDataResult::Write() { _worldPacket << int32(GarrTypeID); _worldPacket << uint32(BlueprintsKnown ? BlueprintsKnown->size() : 0); @@ -309,24 +378,24 @@ WorldPacket const* WorldPackets::Garrison::GarrisonRequestBlueprintAndSpecializa return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonBuildingLandmark& landmark) +ByteBuffer& operator<<(ByteBuffer& data, GarrisonBuildingMapData& building) { - data << uint32(landmark.GarrBuildingPlotInstID); - data << landmark.Pos; + data << uint32(building.GarrBuildingPlotInstID); + data << building.Pos; return data; } -WorldPacket const* WorldPackets::Garrison::GarrisonBuildingLandmarks::Write() +WorldPacket const* GarrisonMapDataResponse::Write() { - _worldPacket << uint32(Landmarks.size()); - for (GarrisonBuildingLandmark& landmark : Landmarks) + _worldPacket << uint32(Buildings.size()); + for (GarrisonBuildingMapData& landmark : Buildings) _worldPacket << landmark; return &_worldPacket; } -WorldPacket const* WorldPackets::Garrison::GarrisonPlotPlaced::Write() +WorldPacket const* GarrisonPlotPlaced::Write() { _worldPacket << int32(GarrTypeID); _worldPacket << *PlotInfo; @@ -334,14 +403,14 @@ WorldPacket const* WorldPackets::Garrison::GarrisonPlotPlaced::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Garrison::GarrisonPlotRemoved::Write() +WorldPacket const* GarrisonPlotRemoved::Write() { _worldPacket << uint32(GarrPlotInstanceID); return &_worldPacket; } -WorldPacket const* WorldPackets::Garrison::GarrisonAddFollowerResult::Write() +WorldPacket const* GarrisonAddFollowerResult::Write() { _worldPacket << int32(GarrTypeID); _worldPacket << uint32(Result); @@ -350,7 +419,7 @@ WorldPacket const* WorldPackets::Garrison::GarrisonAddFollowerResult::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Garrison::GarrisonRemoveFollowerResult::Write() +WorldPacket const* GarrisonRemoveFollowerResult::Write() { _worldPacket << uint64(FollowerDBID); _worldPacket << int32(GarrTypeID); @@ -360,9 +429,11 @@ WorldPacket const* WorldPackets::Garrison::GarrisonRemoveFollowerResult::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Garrison::GarrisonBuildingActivated::Write() +WorldPacket const* GarrisonBuildingActivated::Write() { _worldPacket << uint32(GarrPlotInstanceID); return &_worldPacket; } +} +} diff --git a/src/server/game/Server/Packets/GarrisonPackets.h b/src/server/game/Server/Packets/GarrisonPackets.h index 6e929d08245..cb33d51ff42 100644 --- a/src/server/game/Server/Packets/GarrisonPackets.h +++ b/src/server/game/Server/Packets/GarrisonPackets.h @@ -20,6 +20,7 @@ #include "Packet.h" #include "ObjectGuid.h" +#include "Optional.h" #include "Position.h" #include "PacketUtilities.h" #include <list> @@ -94,6 +95,9 @@ namespace WorldPackets std::list<GarrAbilityEntry const*> AbilityID; uint32 ZoneSupportSpellID = 0; uint32 FollowerStatus = 0; + int32 Health = 0; + int32 HealingTimestamp = 0; + int8 BoardIndex = 0; std::string CustomName; }; @@ -107,8 +111,9 @@ namespace WorldPackets uint32 TravelDuration = 0; uint32 MissionDuration = 0; uint32 MissionState = 0; - uint32 Unknown1 = 0; - uint32 Unknown2 = 0; + uint32 SuccessChance = 0; + uint32 Flags = 0; + float MissionScalar = 1.0f; }; struct GarrisonMissionReward @@ -128,12 +133,43 @@ namespace WorldPackets time_t StartTime = time_t(0); }; + struct GarrisonTalentSocketData + { + int32 SoulbindConduitID = 0; + int32 SoulbindConduitRank = 0; + }; + struct GarrisonTalent { int32 GarrTalentID = 0; int32 Rank = 0; time_t ResearchStartTime = time_t(0); int32 Flags = 0; + Optional<GarrisonTalentSocketData> Socket; + }; + + struct GarrisonCollectionEntry + { + int32 EntryID = 0; + int32 Rank = 0; + }; + + struct GarrisonCollection + { + int32 Type = 0; + std::vector<GarrisonCollectionEntry> Entries; + }; + + struct GarrisonEventEntry + { + int32 EntryID = 0; + int32 EventValue = 0; + }; + + struct GarrisonEventList + { + int32 Type = 0; + std::vector<GarrisonEventEntry> Events; }; struct GarrisonInfo @@ -146,11 +182,14 @@ namespace WorldPackets std::vector<GarrisonPlotInfo*> Plots; std::vector<GarrisonBuildingInfo const*> Buildings; std::vector<GarrisonFollower const*> Followers; + std::vector<GarrisonFollower const*> AutoTroops; std::vector<GarrisonMission const*> Missions; std::vector<std::vector<GarrisonMissionReward>> MissionRewards; std::vector<std::vector<GarrisonMissionReward>> MissionOvermaxRewards; std::vector<GarrisonMissionBonusAbility const*> MissionAreaBonuses; std::vector<GarrisonTalent> Talents; + std::vector<GarrisonCollection> Collections; + std::vector<GarrisonEventList> EventLists; std::vector<bool> CanStartMission; std::vector<int32> ArchivedMissions; }; @@ -291,31 +330,31 @@ namespace WorldPackets std::unordered_set<uint32> const* BlueprintsKnown = nullptr; }; - class GarrisonGetBuildingLandmarks final : public ClientPacket + class GarrisonGetMapData final : public ClientPacket { public: - GarrisonGetBuildingLandmarks(WorldPacket&& packet) : ClientPacket(CMSG_GARRISON_GET_BUILDING_LANDMARKS, std::move(packet)) { } + GarrisonGetMapData(WorldPacket&& packet) : ClientPacket(CMSG_GARRISON_GET_MAP_DATA, std::move(packet)) { } void Read() override { } }; - struct GarrisonBuildingLandmark + struct GarrisonBuildingMapData { - GarrisonBuildingLandmark() : GarrBuildingPlotInstID(0), Pos() { } - GarrisonBuildingLandmark(uint32 buildingPlotInstId, Position const& pos) : GarrBuildingPlotInstID(buildingPlotInstId), Pos(pos) { } + GarrisonBuildingMapData() : GarrBuildingPlotInstID(0), Pos() { } + GarrisonBuildingMapData(uint32 buildingPlotInstId, Position const& pos) : GarrBuildingPlotInstID(buildingPlotInstId), Pos(pos) { } uint32 GarrBuildingPlotInstID; TaggedPosition<Position::XYZ> Pos; }; - class GarrisonBuildingLandmarks final : public ServerPacket + class GarrisonMapDataResponse final : public ServerPacket { public: - GarrisonBuildingLandmarks() : ServerPacket(SMSG_GARRISON_BUILDING_LANDMARKS) { } + GarrisonMapDataResponse() : ServerPacket(SMSG_GARRISON_MAP_DATA_RESPONSE) { } WorldPacket const* Write() override; - std::vector<GarrisonBuildingLandmark> Landmarks; + std::vector<GarrisonBuildingMapData> Buildings; }; class GarrisonPlotPlaced final : public ServerPacket diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp index aae54fca389..d0d91e6ab32 100644 --- a/src/server/game/Server/Packets/GuildPackets.cpp +++ b/src/server/game/Server/Packets/GuildPackets.cpp @@ -188,7 +188,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRosterMemberD return data; } -WorldPacket const* WorldPackets::Guild::GuildEventAwayChange::Write() +WorldPacket const* WorldPackets::Guild::GuildEventStatusChange::Write() { _worldPacket << Guid; _worldPacket.WriteBit(AFK); @@ -272,12 +272,10 @@ WorldPacket const* WorldPackets::Guild::GuildEventPlayerLeft::Write() { _worldPacket.WriteBit(Removed); _worldPacket.WriteBits(LeaverName.length(), 6); - _worldPacket.FlushBits(); if (Removed) { _worldPacket.WriteBits(RemoverName.length(), 6); - _worldPacket.FlushBits(); _worldPacket << RemoverGUID; _worldPacket << uint32(RemoverVirtualRealmAddress); diff --git a/src/server/game/Server/Packets/GuildPackets.h b/src/server/game/Server/Packets/GuildPackets.h index 5762f2b7971..a64595465ac 100644 --- a/src/server/game/Server/Packets/GuildPackets.h +++ b/src/server/game/Server/Packets/GuildPackets.h @@ -227,10 +227,10 @@ namespace WorldPackets std::string OldGuildName; }; - class GuildEventAwayChange final : public ServerPacket + class GuildEventStatusChange final : public ServerPacket { public: - GuildEventAwayChange() : ServerPacket(SMSG_GUILD_EVENT_AWAY_CHANGE, 16 + 1) { } + GuildEventStatusChange() : ServerPacket(SMSG_GUILD_EVENT_STATUS_CHANGE, 16 + 1) { } WorldPacket const* Write() override; diff --git a/src/server/game/Server/Packets/HotfixPackets.cpp b/src/server/game/Server/Packets/HotfixPackets.cpp index 175dee3d600..629627ff852 100644 --- a/src/server/game/Server/Packets/HotfixPackets.cpp +++ b/src/server/game/Server/Packets/HotfixPackets.cpp @@ -54,7 +54,7 @@ WorldPacket const* DBReply::Write() _worldPacket << uint32(TableHash); _worldPacket << uint32(RecordID); _worldPacket << uint32(Timestamp); - _worldPacket.WriteBit(Allow); + _worldPacket.WriteBits(Status, 2); _worldPacket << uint32(Data.size()); _worldPacket.append(Data); @@ -91,12 +91,12 @@ ByteBuffer& operator<<(ByteBuffer& data, HotfixConnect::HotfixData const& hotfix if (hotfixData.Size) { data << uint32(*hotfixData.Size); - data.WriteBit(true); + data.WriteBits(1, 2); } else { data << uint32(0); - data.WriteBit(false); + data.WriteBits(3, 2); } data.FlushBits(); diff --git a/src/server/game/Server/Packets/HotfixPackets.h b/src/server/game/Server/Packets/HotfixPackets.h index e4e0e2b193f..ecd48021203 100644 --- a/src/server/game/Server/Packets/HotfixPackets.h +++ b/src/server/game/Server/Packets/HotfixPackets.h @@ -47,14 +47,14 @@ namespace WorldPackets class DBReply final : public ServerPacket { public: - DBReply() : ServerPacket(SMSG_DB_REPLY, 12) { } + DBReply() : ServerPacket(SMSG_DB_REPLY, 4 + 4 + 4 + 1 + 4) { } WorldPacket const* Write() override; uint32 TableHash = 0; uint32 Timestamp = 0; uint32 RecordID = 0; - bool Allow = false; + uint8 Status = 3; ByteBuffer Data; }; diff --git a/src/server/game/Server/Packets/InspectPackets.cpp b/src/server/game/Server/Packets/InspectPackets.cpp index 7ae472302b3..0abe35115fe 100644 --- a/src/server/game/Server/Packets/InspectPackets.cpp +++ b/src/server/game/Server/Packets/InspectPackets.cpp @@ -78,14 +78,11 @@ void WorldPackets::Inspect::PlayerModelDisplayInfo::Initialize(Player const* pla SpecializationID = player->GetPrimarySpecialization(); Name = player->GetName(); GenderID = player->m_playerData->NativeSex; - Skin = player->m_playerData->SkinID; - HairColor = player->m_playerData->HairColorID; - HairStyle = player->m_playerData->HairStyleID; - FacialHairStyle = player->m_playerData->FacialHairStyleID; - Face = player->m_playerData->FaceID; Race = player->getRace(); ClassID = player->getClass(); - std::copy(player->m_playerData->CustomDisplayOption.begin(), player->m_playerData->CustomDisplayOption.end(), CustomDisplay.begin()); + + for (UF::ChrCustomizationChoice customization : player->m_playerData->Customizations) + Customizations.push_back({ customization.ChrCustomizationOptionID, customization.ChrCustomizationChoiceID }); for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) if (::Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) @@ -99,16 +96,14 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Inspect::PlayerModelDispl data << uint32(displayInfo.Items.size()); data.WriteBits(displayInfo.Name.length(), 6); data << uint8(displayInfo.GenderID); - data << uint8(displayInfo.Skin); - data << uint8(displayInfo.HairColor); - data << uint8(displayInfo.HairStyle); - data << uint8(displayInfo.FacialHairStyle); - data << uint8(displayInfo.Face); data << uint8(displayInfo.Race); data << uint8(displayInfo.ClassID); - data.append(displayInfo.CustomDisplay.data(), displayInfo.CustomDisplay.size()); + data << uint32(displayInfo.Customizations.size()); data.WriteString(displayInfo.Name); + for (WorldPackets::Character::ChrCustomizationChoice const& customization : displayInfo.Customizations) + data << customization; + for (WorldPackets::Inspect::InspectItemData const& item : displayInfo.Items) data << item; diff --git a/src/server/game/Server/Packets/InspectPackets.h b/src/server/game/Server/Packets/InspectPackets.h index eb62955cfb7..91e8e69afc9 100644 --- a/src/server/game/Server/Packets/InspectPackets.h +++ b/src/server/game/Server/Packets/InspectPackets.h @@ -18,6 +18,7 @@ #pragma once #include "Packet.h" +#include "CharacterPackets.h" #include "DBCEnums.h" #include "ItemPacketsCommon.h" #include "ObjectGuid.h" @@ -78,14 +79,9 @@ namespace WorldPackets std::string Name; int32 SpecializationID = 0; uint8 GenderID = GENDER_NONE; - uint8 Skin = 0; - uint8 HairColor = 0; - uint8 HairStyle = 0; - uint8 FacialHairStyle = 0; - uint8 Face = 0; uint8 Race = RACE_NONE; uint8 ClassID = CLASS_NONE; - std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> CustomDisplay; + std::vector<Character::ChrCustomizationChoice> Customizations; void Initialize(Player const* player); }; diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp index 1952ed9242e..12284f1e483 100644 --- a/src/server/game/Server/Packets/ItemPackets.cpp +++ b/src/server/game/Server/Packets/ItemPackets.cpp @@ -32,7 +32,7 @@ void WorldPackets::Item::BuyItem::Read() _worldPacket >> Muid; _worldPacket >> Slot; _worldPacket >> Item; - ItemType = static_cast<ItemVendorType>(_worldPacket.ReadBits(2)); + ItemType = static_cast<ItemVendorType>(_worldPacket.ReadBits(3)); } WorldPacket const* WorldPackets::Item::BuySucceeded::Write() diff --git a/src/server/game/Server/Packets/ItemPacketsCommon.cpp b/src/server/game/Server/Packets/ItemPacketsCommon.cpp index 6e694cf1873..79f7a4a61b0 100644 --- a/src/server/game/Server/Packets/ItemPacketsCommon.cpp +++ b/src/server/game/Server/Packets/ItemPacketsCommon.cpp @@ -19,7 +19,11 @@ #include "Item.h" #include "Player.h" -bool WorldPackets::Item::ItemBonusInstanceData::operator==(ItemBonusInstanceData const& r) const +namespace WorldPackets +{ +namespace Item +{ +bool ItemBonuses::operator==(ItemBonuses const& r) const { if (Context != r.Context) return false; @@ -30,9 +34,22 @@ bool WorldPackets::Item::ItemBonusInstanceData::operator==(ItemBonusInstanceData return std::is_permutation(BonusListIDs.begin(), BonusListIDs.end(), r.BonusListIDs.begin()); } -void WorldPackets::Item::ItemInstance::Initialize(::Item const* item) +bool ItemMod::operator==(ItemMod const& r) const +{ + return Value == r.Value && Type == r.Type; +} + +bool ItemModList::operator==(ItemModList const& r) const +{ + if (Values.size() != r.Values.size()) + return false; + + return std::is_permutation(Values.begin(), Values.end(), r.Values.begin()); +} + +void ItemInstance::Initialize(::Item const* item) { - ItemID = item->GetEntry(); + ItemID = item->GetEntry(); std::vector<int32> const& bonusListIds = item->m_itemData->BonusListIDs; if (!bonusListIds.empty()) { @@ -41,21 +58,15 @@ void WorldPackets::Item::ItemInstance::Initialize(::Item const* item) ItemBonus->Context = item->GetContext(); } - if (uint32 mask = item->m_itemData->ModifiersMask) - { - Modifications = boost::in_place(); - - for (size_t i = 0; mask != 0; mask >>= 1, ++i) - if ((mask & 1) != 0) - Modifications->Insert(i, item->GetModifier(ItemModifier(i))); - } + for (UF::ItemMod mod : item->m_itemData->Modifiers->Values) + Modifications.Values.emplace_back(mod.Value, ItemModifier(mod.Type)); } -void WorldPackets::Item::ItemInstance::Initialize(UF::SocketedGem const* gem) +void ItemInstance::Initialize(UF::SocketedGem const* gem) { ItemID = gem->ItemID; - ItemBonusInstanceData bonus; + ItemBonuses bonus; bonus.Context = ItemContext(*gem->Context); for (uint16 bonusListId : gem->BonusListIDs) if (bonusListId) @@ -65,7 +76,7 @@ void WorldPackets::Item::ItemInstance::Initialize(UF::SocketedGem const* gem) ItemBonus = bonus; } -void WorldPackets::Item::ItemInstance::Initialize(::LootItem const& lootItem) +void ItemInstance::Initialize(::LootItem const& lootItem) { ItemID = lootItem.itemid; @@ -79,18 +90,15 @@ void WorldPackets::Item::ItemInstance::Initialize(::LootItem const& lootItem) } } -void WorldPackets::Item::ItemInstance::Initialize(::VoidStorageItem const* voidItem) +void ItemInstance::Initialize(::VoidStorageItem const* voidItem) { ItemID = voidItem->ItemEntry; - if (voidItem->FixedScalingLevel || voidItem->ArtifactKnowledgeLevel) - { - Modifications = boost::in_place(); - if (voidItem->FixedScalingLevel) - Modifications->Insert(ITEM_MODIFIER_TIMEWALKER_LEVEL, voidItem->FixedScalingLevel); - if (voidItem->ArtifactKnowledgeLevel) - Modifications->Insert(ITEM_MODIFIER_ARTIFACT_KNOWLEDGE_LEVEL, voidItem->ArtifactKnowledgeLevel); - } + if (voidItem->FixedScalingLevel) + Modifications.Values.emplace_back(voidItem->FixedScalingLevel, ITEM_MODIFIER_TIMEWALKER_LEVEL); + + if (voidItem->ArtifactKnowledgeLevel) + Modifications.Values.emplace_back(voidItem->ArtifactKnowledgeLevel, ITEM_MODIFIER_ARTIFACT_KNOWLEDGE_LEVEL); if (!voidItem->BonusListIDs.empty()) { @@ -100,15 +108,15 @@ void WorldPackets::Item::ItemInstance::Initialize(::VoidStorageItem const* voidI } } -bool WorldPackets::Item::ItemInstance::operator==(ItemInstance const& r) const +bool ItemInstance::operator==(ItemInstance const& r) const { if (ItemID != r.ItemID) return false; - if (ItemBonus.is_initialized() != r.ItemBonus.is_initialized() || Modifications.is_initialized() != r.Modifications.is_initialized()) + if (ItemBonus.is_initialized() != r.ItemBonus.is_initialized()) return false; - if (Modifications.is_initialized() && *Modifications != *r.Modifications) + if (Modifications != r.Modifications) return false; if (ItemBonus.is_initialized() && *ItemBonus != *r.ItemBonus) @@ -117,7 +125,7 @@ bool WorldPackets::Item::ItemInstance::operator==(ItemInstance const& r) const return true; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData const& itemBonusInstanceData) +ByteBuffer& operator<<(ByteBuffer& data, ItemBonuses const& itemBonusInstanceData) { data << uint8(itemBonusInstanceData.Context); data << uint32(itemBonusInstanceData.BonusListIDs.size()); @@ -127,7 +135,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceDa return data; } -ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData& itemBonusInstanceData) +ByteBuffer& operator>>(ByteBuffer& data, ItemBonuses& itemBonusInstanceData) { uint32 bonusListIdSize; @@ -144,47 +152,77 @@ ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceDa return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance) +ByteBuffer& operator<<(ByteBuffer& data, ItemMod const& itemMod) +{ + data << int32(itemMod.Value); + data << uint8(itemMod.Type); + + return data; +} + +ByteBuffer& operator>>(ByteBuffer& data, ItemMod& itemMod) +{ + data >> itemMod.Value; + itemMod.Type = data.read<ItemModifier, uint8>(); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, ItemModList const& itemModList) +{ + data.WriteBits(itemModList.Values.size(), 6); + data.FlushBits(); + + for (ItemMod const& itemMod : itemModList.Values) + data << itemMod; + + return data; +} + +ByteBuffer& operator>>(ByteBuffer& data, ItemModList& itemModList) +{ + itemModList.Values.resize(data.ReadBits(6)); + + for (ItemMod& itemMod : itemModList.Values) + data >> itemMod; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, ItemInstance const& itemInstance) { data << int32(itemInstance.ItemID); data.WriteBit(itemInstance.ItemBonus.is_initialized()); - data.WriteBit(itemInstance.Modifications.is_initialized()); data.FlushBits(); + data << itemInstance.Modifications; + if (itemInstance.ItemBonus) data << *itemInstance.ItemBonus; - if (itemInstance.Modifications) - data << *itemInstance.Modifications; - return data; } -ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemInstance& itemInstance) +ByteBuffer& operator>>(ByteBuffer& data, ItemInstance& itemInstance) { data >> itemInstance.ItemID; bool hasItemBonus = data.ReadBit(); - bool hasModifications = data.ReadBit(); data.ResetBitPos(); + data >> itemInstance.Modifications; + if (hasItemBonus) { itemInstance.ItemBonus = boost::in_place(); data >> *itemInstance.ItemBonus; } - if (hasModifications) - { - itemInstance.Modifications = boost::in_place(); - data >> *itemInstance.Modifications; - } - return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemEnchantData const& itemEnchantData) +ByteBuffer& operator<<(ByteBuffer& data, ItemEnchantData const& itemEnchantData) { data << int32(itemEnchantData.ID); data << uint32(itemEnchantData.Expiration); @@ -193,28 +231,30 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemEnchantData con return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemGemData const& itemGemData) +ByteBuffer& operator<<(ByteBuffer& data, ItemGemData const& itemGemData) { data << uint8(itemGemData.Slot); data << itemGemData.Item; return data; } -ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemGemData& itemGemData) +ByteBuffer& operator>>(ByteBuffer& data, ItemGemData& itemGemData) { data >> itemGemData.Slot; data >> itemGemData.Item; return data; } -ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::InvUpdate& invUpdate) +ByteBuffer& operator>>(ByteBuffer& data, InvUpdate& invUpdate) { invUpdate.Items.resize(data.ReadBits(2)); - for (size_t i = 0; i < invUpdate.Items.size(); ++i) + for (InvUpdate::InvItem& item : invUpdate.Items) { - data >> invUpdate.Items[i].ContainerSlot; - data >> invUpdate.Items[i].Slot; + data >> item.ContainerSlot; + data >> item.Slot; } return data; } +} +} diff --git a/src/server/game/Server/Packets/ItemPacketsCommon.h b/src/server/game/Server/Packets/ItemPacketsCommon.h index 147672997b3..2131d8ae7a5 100644 --- a/src/server/game/Server/Packets/ItemPacketsCommon.h +++ b/src/server/game/Server/Packets/ItemPacketsCommon.h @@ -18,7 +18,7 @@ #ifndef ItemPacketsCommon_h__ #define ItemPacketsCommon_h__ -#include "Define.h" +#include "ItemDefines.h" #include "PacketUtilities.h" #include "Optional.h" #include <vector> @@ -38,13 +38,33 @@ namespace WorldPackets { namespace Item { - struct ItemBonusInstanceData + struct ItemBonuses { ItemContext Context = ItemContext(0); std::vector<int32> BonusListIDs; - bool operator==(ItemBonusInstanceData const& r) const; - bool operator!=(ItemBonusInstanceData const& r) const { return !(*this == r); } + bool operator==(ItemBonuses const& r) const; + bool operator!=(ItemBonuses const& r) const { return !(*this == r); } + }; + + struct ItemMod + { + ItemMod() = default; + ItemMod(int32 value, ItemModifier type) : Value(value), Type(type) { } + + int32 Value = 0; + ItemModifier Type = MAX_ITEM_MODIFIERS; + + bool operator==(ItemMod const& r) const; + bool operator!=(ItemMod const& r) const { return !(*this == r); } + }; + + struct ItemModList + { + Array<ItemMod, MAX_ITEM_MODIFIERS> Values; + + bool operator==(ItemModList const& r) const; + bool operator!=(ItemModList const& r) const { return !(*this == r); } }; struct ItemInstance @@ -55,8 +75,8 @@ namespace WorldPackets void Initialize(::VoidStorageItem const* voidItem); uint32 ItemID = 0; - Optional<ItemBonusInstanceData> ItemBonus; - Optional<CompactArray<int32>> Modifications; + Optional<ItemBonuses> ItemBonus; + ItemModList Modifications; bool operator==(ItemInstance const& r) const; bool operator!=(ItemInstance const& r) const { return !(*this == r); } @@ -90,17 +110,20 @@ namespace WorldPackets } } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData const& itemBonusInstanceData); -ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData& itemBonusInstanceData); - -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance); -ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemInstance& itemInstance); +namespace WorldPackets +{ +namespace Item +{ +ByteBuffer& operator<<(ByteBuffer& data, ItemInstance const& itemInstance); +ByteBuffer& operator>>(ByteBuffer& data, ItemInstance& itemInstance); -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemEnchantData const& itemEnchantData); +ByteBuffer& operator<<(ByteBuffer& data, ItemEnchantData const& itemEnchantData); -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemGemData const& itemGemInstanceData); -ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemGemData& itemGemInstanceData); +ByteBuffer& operator<<(ByteBuffer& data, ItemGemData const& itemGemInstanceData); +ByteBuffer& operator>>(ByteBuffer& data, ItemGemData& itemGemInstanceData); -ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::InvUpdate& invUpdate); +ByteBuffer& operator>>(ByteBuffer& data, InvUpdate& invUpdate); +} +} #endif // ItemPacketsCommon_h__ diff --git a/src/server/game/Server/Packets/LFGPackets.cpp b/src/server/game/Server/Packets/LFGPackets.cpp index dee02bba7a2..7452384c7d4 100644 --- a/src/server/game/Server/Packets/LFGPackets.cpp +++ b/src/server/game/Server/Packets/LFGPackets.cpp @@ -69,6 +69,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::LFG::LFGBlackListSlot con data << uint32(lfgBlackListSlot.Reason); data << int32(lfgBlackListSlot.SubReason1); data << int32(lfgBlackListSlot.SubReason2); + data << uint32(lfgBlackListSlot.SoftLock); return data; } @@ -262,27 +263,6 @@ WorldPacket const* WorldPackets::LFG::LFGRoleCheckUpdate::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::LFG::LFGJoinBlackListSlot const& lfgBlackListSlot) -{ - data << int32(lfgBlackListSlot.Slot); - data << int32(lfgBlackListSlot.Reason); - data << int32(lfgBlackListSlot.SubReason1); - data << int32(lfgBlackListSlot.SubReason2); - - return data; -} - -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::LFG::LFGJoinBlackList const& blackList) -{ - data << blackList.Guid; - data << uint32(blackList.Slots.size()); - - for (WorldPackets::LFG::LFGJoinBlackListSlot const& slot : blackList.Slots) - data << slot; - - return data; -} - WorldPacket const* WorldPackets::LFG::LFGJoinResult::Write() { _worldPacket << Ticket; @@ -291,7 +271,7 @@ WorldPacket const* WorldPackets::LFG::LFGJoinResult::Write() _worldPacket << uint32(BlackList.size()); _worldPacket << uint32(BlackListNames.size()); - for (LFGJoinBlackList const& blackList : BlackList) + for (LFGBlackList const& blackList : BlackList) _worldPacket << blackList; for (std::string const* str : BlackListNames) diff --git a/src/server/game/Server/Packets/LFGPackets.h b/src/server/game/Server/Packets/LFGPackets.h index f3580464129..7dd0fbccc2e 100644 --- a/src/server/game/Server/Packets/LFGPackets.h +++ b/src/server/game/Server/Packets/LFGPackets.h @@ -122,14 +122,15 @@ namespace WorldPackets struct LFGBlackListSlot { - LFGBlackListSlot() { } - LFGBlackListSlot(uint32 slot, uint32 reason, int32 subReason1, int32 subReason2) - : Slot(slot), Reason(reason), SubReason1(subReason1), SubReason2(subReason2) { } + LFGBlackListSlot() = default; + LFGBlackListSlot(uint32 slot, uint32 reason, int32 subReason1, int32 subReason2, uint32 softLock) + : Slot(slot), Reason(reason), SubReason1(subReason1), SubReason2(subReason2), SoftLock(softLock) { } uint32 Slot = 0; uint32 Reason = 0; int32 SubReason1 = 0; int32 SubReason2 = 0; + uint32 SoftLock = 0; }; struct LFGBlackList @@ -140,7 +141,7 @@ namespace WorldPackets struct LfgPlayerQuestRewardItem { - LfgPlayerQuestRewardItem() { } + LfgPlayerQuestRewardItem() = default; LfgPlayerQuestRewardItem(int32 itemId, int32 quantity) : ItemID(itemId), Quantity(quantity) { } int32 ItemID = 0; @@ -149,7 +150,7 @@ namespace WorldPackets struct LfgPlayerQuestRewardCurrency { - LfgPlayerQuestRewardCurrency() { } + LfgPlayerQuestRewardCurrency() = default; LfgPlayerQuestRewardCurrency(int32 currencyID, int32 quantity) : CurrencyID(currencyID), Quantity(quantity) { } int32 CurrencyID = 0; @@ -250,7 +251,7 @@ namespace WorldPackets struct LFGRoleCheckUpdateMember { - LFGRoleCheckUpdateMember() { } + LFGRoleCheckUpdateMember() = default; LFGRoleCheckUpdateMember(ObjectGuid guid, uint32 rolesDesired, uint8 level, bool roleCheckComplete) : Guid(guid), RolesDesired(rolesDesired), Level(level), RoleCheckComplete(roleCheckComplete) { } @@ -277,24 +278,6 @@ namespace WorldPackets bool IsRequeue = false; }; - struct LFGJoinBlackListSlot - { - LFGJoinBlackListSlot() { } - LFGJoinBlackListSlot(int32 slot, int32 reason, int32 subReason1, int32 subReason2) - : Slot(slot), Reason(reason), SubReason1(subReason1), SubReason2(subReason2) { } - - int32 Slot = 0; - int32 Reason = 0; - int32 SubReason1 = 0; - int32 SubReason2 = 0; - }; - - struct LFGJoinBlackList - { - ObjectGuid Guid; - std::vector<LFGJoinBlackListSlot> Slots; - }; - class LFGJoinResult final : public ServerPacket { public: @@ -305,7 +288,7 @@ namespace WorldPackets RideTicket Ticket; uint8 Result = 0; uint8 ResultDetail = 0; - std::vector<LFGJoinBlackList> BlackList; + std::vector<LFGBlackList> BlackList; std::vector<std::string const*> BlackListNames; }; @@ -327,7 +310,7 @@ namespace WorldPackets struct LFGPlayerRewards { - LFGPlayerRewards() { } + LFGPlayerRewards() = default; LFGPlayerRewards(int32 id, uint32 quantity, int32 bonusQuantity, bool isCurrency) : Quantity(quantity), BonusQuantity(bonusQuantity) { diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index ba96fcd366f..127a040b032 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -53,6 +53,7 @@ WorldPacket const* WorldPackets::Misc::SetCurrency::Write() _worldPacket.WriteBit(WeeklyQuantity.is_initialized()); _worldPacket.WriteBit(TrackedQuantity.is_initialized()); _worldPacket.WriteBit(MaxQuantity.is_initialized()); + _worldPacket.WriteBit(Unused901.is_initialized()); _worldPacket.WriteBit(SuppressChatLog); _worldPacket.WriteBit(QuantityChange.is_initialized()); _worldPacket.WriteBit(QuantityGainSource.is_initialized()); @@ -68,6 +69,9 @@ WorldPacket const* WorldPackets::Misc::SetCurrency::Write() if (MaxQuantity) _worldPacket << int32(*MaxQuantity); + if (Unused901) + _worldPacket << int32(*Unused901); + if (QuantityChange) _worldPacket << int32(*QuantityChange); @@ -98,6 +102,7 @@ WorldPacket const* WorldPackets::Misc::SetupCurrency::Write() _worldPacket.WriteBit(data.MaxWeeklyQuantity.is_initialized()); _worldPacket.WriteBit(data.TrackedQuantity.is_initialized()); _worldPacket.WriteBit(data.MaxQuantity.is_initialized()); + _worldPacket.WriteBit(data.Unused901.is_initialized()); _worldPacket.WriteBits(data.Flags, 5); _worldPacket.FlushBits(); @@ -109,6 +114,8 @@ WorldPacket const* WorldPackets::Misc::SetupCurrency::Write() _worldPacket << uint32(*data.TrackedQuantity); if (data.MaxQuantity) _worldPacket << int32(*data.MaxQuantity); + if (data.Unused901) + _worldPacket << int32(*data.Unused901); } return &_worldPacket; @@ -181,7 +188,7 @@ WorldPacket const* WorldPackets::Misc::WorldServerInfo::Write() _worldPacket << uint32(*RestrictedAccountMaxLevel); if (RestrictedAccountMaxMoney) - _worldPacket << uint32(*RestrictedAccountMaxMoney); + _worldPacket << uint64(*RestrictedAccountMaxMoney); if (InstanceGroupSize) _worldPacket << uint32(*InstanceGroupSize); @@ -466,6 +473,7 @@ WorldPacket const* WorldPackets::Misc::PlayObjectSound::Write() _worldPacket << SourceObjectGUID; _worldPacket << TargetObjectGUID; _worldPacket << Position; + _worldPacket << int32(BroadcastTextID); return &_worldPacket; } @@ -474,6 +482,7 @@ WorldPacket const* WorldPackets::Misc::PlaySound::Write() { _worldPacket << int32(SoundKitID); _worldPacket << SourceObjectGuid; + _worldPacket << int32(BroadcastTextID); return &_worldPacket; } @@ -491,13 +500,6 @@ void WorldPackets::Misc::FarSight::Read() Enable = _worldPacket.ReadBit(); } -WorldPacket const* WorldPackets::Misc::Dismount::Write() -{ - _worldPacket << Guid; - - return &_worldPacket; -} - void WorldPackets::Misc::SaveCUFProfiles::Read() { CUFProfiles.resize(_worldPacket.read<uint32>()); diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index cc91c0bf49e..78ea4fb997e 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -117,6 +117,7 @@ namespace WorldPackets Optional<int32> WeeklyQuantity; Optional<int32> TrackedQuantity; Optional<int32> MaxQuantity; + Optional<int32> Unused901; Optional<int32> QuantityChange; Optional<int32> QuantityGainSource; Optional<int32> QuantityLostSource; @@ -144,6 +145,7 @@ namespace WorldPackets Optional<int32> MaxWeeklyQuantity; // Weekly Currency cap. Optional<int32> TrackedQuantity; Optional<int32> MaxQuantity; + Optional<int32> Unused901; uint8 Flags = 0; // 0 = none, }; @@ -260,7 +262,7 @@ namespace WorldPackets bool BlockExitingLoadingScreen = false; // when set to true, sending SMSG_UPDATE_OBJECT with CreateObject Self bit = true will not hide loading screen // instead it will be done after this packet is sent again with false in this bit and SMSG_UPDATE_OBJECT Values for player Optional<uint32> RestrictedAccountMaxLevel; - Optional<uint32> RestrictedAccountMaxMoney; + Optional<uint64> RestrictedAccountMaxMoney; Optional<uint32> InstanceGroupSize; }; @@ -631,6 +633,7 @@ namespace WorldPackets ObjectGuid SourceObjectGUID; int32 SoundKitID = 0; TaggedPosition<::Position::XYZ> Position; + int32 BroadcastTextID = 0; }; class TC_GAME_API PlaySound final : public ServerPacket @@ -643,6 +646,7 @@ namespace WorldPackets ObjectGuid SourceObjectGuid; int32 SoundKitID = 0; + int32 BroadcastTextID = 0; }; class TC_GAME_API PlaySpeakerbotSound final : public ServerPacket @@ -692,16 +696,6 @@ namespace WorldPackets bool Enable = false; }; - class Dismount final : public ServerPacket - { - public: - Dismount() : ServerPacket(SMSG_DISMOUNT, 16) { } - - WorldPacket const* Write() override; - - ObjectGuid Guid; - }; - class SaveCUFProfiles final : public ClientPacket { public: diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index f05c3cf1b14..2c44b01bb7c 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -53,8 +53,8 @@ ByteBuffer& operator<<(ByteBuffer& data, MovementInfo const& movementInfo) data.WriteBit(hasFallData); data.WriteBit(hasSpline); - data.WriteBit(0); // HeightChangeFailed - data.WriteBit(0); // RemoteTimeValid + data.WriteBit(false); // HeightChangeFailed + data.WriteBit(false); // RemoteTimeValid data.FlushBits(); @@ -227,24 +227,48 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineJu return data; } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineAnimTierTransition const& animTierTransition) +{ + data << int32(animTierTransition.TierTransitionID); + data << uint32(animTierTransition.StartTime); + data << uint32(animTierTransition.EndTime); + data << uint8(animTierTransition.AnimTier); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineUnknown901 const& unk) +{ + for (WorldPackets::Movement::MonsterSplineUnknown901::Inner const& unkInner : unk.Data) + { + data << int32(unkInner.Unknown_1); + data << int32(unkInner.Unknown_2); + data << int32(unkInner.Unknown_3); + data << uint32(unkInner.Unknown_4); + } + + return data; +} + ByteBuffer& WorldPackets::operator<<(ByteBuffer& data, Movement::MovementSpline const& movementSpline) { data << uint32(movementSpline.Flags); - data << uint8(movementSpline.AnimTier); - data << uint32(movementSpline.TierTransStartTime); data << int32(movementSpline.Elapsed); data << uint32(movementSpline.MoveTime); data << uint32(movementSpline.FadeObjectTime); data << uint8(movementSpline.Mode); - data << uint8(movementSpline.VehicleExitVoluntary); data << movementSpline.TransportGUID; data << int8(movementSpline.VehicleSeat); data.WriteBits(movementSpline.Face, 2); data.WriteBits(movementSpline.Points.size(), 16); + data.WriteBit(movementSpline.VehicleExitVoluntary); + data.WriteBit(movementSpline.Interpolate); data.WriteBits(movementSpline.PackedDeltas.size(), 16); data.WriteBit(movementSpline.SplineFilter.is_initialized()); data.WriteBit(movementSpline.SpellEffectExtraData.is_initialized()); data.WriteBit(movementSpline.JumpExtraData.is_initialized()); + data.WriteBit(movementSpline.AnimTierTransition.is_initialized()); + data.WriteBit(movementSpline.Unknown901.is_initialized()); data.FlushBits(); if (movementSpline.SplineFilter) @@ -266,6 +290,7 @@ ByteBuffer& WorldPackets::operator<<(ByteBuffer& data, Movement::MovementSpline for (TaggedPosition<Position::XYZ> const& pos : movementSpline.Points) data << pos; + for (TaggedPosition<Position::PackedXYZ> const& pos : movementSpline.PackedDeltas) data << pos; @@ -275,6 +300,12 @@ ByteBuffer& WorldPackets::operator<<(ByteBuffer& data, Movement::MovementSpline if (movementSpline.JumpExtraData) data << *movementSpline.JumpExtraData; + if (movementSpline.AnimTierTransition) + data << *movementSpline.AnimTierTransition; + + if (movementSpline.Unknown901) + data << *movementSpline.Unknown901; + return data; } @@ -315,10 +346,11 @@ void WorldPackets::Movement::CommonMovement::WriteCreateObjectSplineDataBlock(:: data.WriteBits(moveSpline.facing.type, 2); // Face bool hasFadeObjectTime = data.WriteBit(moveSpline.splineflags.fadeObject && moveSpline.effect_start_time < moveSpline.Duration()); data.WriteBits(moveSpline.getPath().size(), 16); - data.WriteBits(uint8(moveSpline.spline.mode()), 2); // Mode - data.WriteBit(0); // HasSplineFilter + data.WriteBit(false); // HasSplineFilter data.WriteBit(moveSpline.spell_effect_extra.is_initialized()); // HasSpellEffectExtraData data.WriteBit(moveSpline.splineflags.parabolic); // HasJumpExtraData + data.WriteBit(moveSpline.anim_tier.is_initialized()); // HasAnimationTierTransition + data.WriteBit(false); // HasUnknown901 data.FlushBits(); //if (HasSplineFilterKey) @@ -374,6 +406,25 @@ void WorldPackets::Movement::CommonMovement::WriteCreateObjectSplineDataBlock(:: data << uint32(moveSpline.effect_start_time); data << uint32(0); // Duration (override) } + + if (moveSpline.anim_tier) + { + data << int32(moveSpline.anim_tier->TierTransitionId); + data << uint32(moveSpline.effect_start_time); + data << uint32(0); + data << uint8(moveSpline.anim_tier->AnimTier); + } + + //if (HasUnknown901) + //{ + // for (WorldPackets::Movement::MonsterSplineUnknown901::Inner const& unkInner : unk.Data) size = 16 + // { + // data << int32(unkInner.Unknown_1); + // data << int32(unkInner.Unknown_2); + // data << int32(unkInner.Unknown_3); + // data << uint32(unkInner.Unknown_4); + // } + //} } } @@ -436,15 +487,17 @@ void WorldPackets::Movement::MonsterMove::InitializeSplineData(::Movement::MoveS if (splineFlags.animation) { - movementSpline.AnimTier = splineFlags.getAnimTier(); - movementSpline.TierTransStartTime = moveSpline.effect_start_time; + movementSpline.AnimTierTransition.emplace(); + movementSpline.AnimTierTransition->TierTransitionID = moveSpline.anim_tier->TierTransitionId; + movementSpline.AnimTierTransition->StartTime = moveSpline.effect_start_time; + movementSpline.AnimTierTransition->AnimTier = moveSpline.anim_tier->AnimTier; } movementSpline.MoveTime = moveSpline.Duration(); if (splineFlags.parabolic) { - movementSpline.JumpExtraData = boost::in_place(); + movementSpline.JumpExtraData.emplace(); movementSpline.JumpExtraData->JumpGravity = moveSpline.vertical_acceleration; movementSpline.JumpExtraData->StartTime = moveSpline.effect_start_time; } @@ -454,7 +507,7 @@ void WorldPackets::Movement::MonsterMove::InitializeSplineData(::Movement::MoveS if (moveSpline.spell_effect_extra) { - movementSpline.SpellEffectExtraData = boost::in_place(); + movementSpline.SpellEffectExtraData.emplace(); movementSpline.SpellEffectExtraData->TargetGUID = moveSpline.spell_effect_extra->Target; movementSpline.SpellEffectExtraData->SpellVisualID = moveSpline.spell_effect_extra->SpellVisualId; movementSpline.SpellEffectExtraData->ProgressCurveID = moveSpline.spell_effect_extra->ProgressCurveId; @@ -582,10 +635,19 @@ WorldPacket const* WorldPackets::Movement::TransferAborted::Write() return &_worldPacket; } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::TeleportLocation const& teleportLocation) +{ + data << teleportLocation.Pos; + data << int32(teleportLocation.Unused901_1); + data << int32(teleportLocation.Unused901_2); + + return data; +} + WorldPacket const* WorldPackets::Movement::NewWorld::Write() { _worldPacket << int32(MapID); - _worldPacket << Pos; + _worldPacket << Loc; _worldPacket << uint32(Reason); _worldPacket << MovementOffset; return &_worldPacket; @@ -772,9 +834,9 @@ WorldPacket const* WorldPackets::Movement::MoveSetCollisionHeight::Write() _worldPacket << uint32(SequenceIndex); _worldPacket << float(Height); _worldPacket << float(Scale); + _worldPacket << uint8(Reason); _worldPacket << uint32(MountDisplayID); _worldPacket << int32(ScaleDuration); - _worldPacket.WriteBits(Reason, 2); _worldPacket.FlushBits(); return &_worldPacket; @@ -840,7 +902,7 @@ void WorldPackets::Movement::MoveSetCollisionHeightAck::Read() _worldPacket >> Data; _worldPacket >> Height; _worldPacket >> MountDisplayID; - Reason = UpdateCollisionHeightReason(_worldPacket.ReadBits(2)); + Reason = _worldPacket.read<UpdateCollisionHeightReason, uint8>(); } void WorldPackets::Movement::MoveTimeSkipped::Read() @@ -917,13 +979,8 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MoveSetCompound data.WriteBit(stateChange.MovementForceGUID.is_initialized()); data.FlushBits(); - if (stateChange.CollisionHeight) - { - data << float(stateChange.CollisionHeight->Height); - data << float(stateChange.CollisionHeight->Scale); - data.WriteBits(stateChange.CollisionHeight->Reason, 2); - data.FlushBits(); - } + if (stateChange.MovementForce_) + data << *stateChange.MovementForce_; if (stateChange.Speed) data << float(*stateChange.Speed); @@ -938,12 +995,16 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MoveSetCompound if (stateChange.VehicleRecID) data << int32(*stateChange.VehicleRecID); + if (stateChange.CollisionHeight) + { + data << float(stateChange.CollisionHeight->Height); + data << float(stateChange.CollisionHeight->Scale); + data << uint8(stateChange.CollisionHeight->Reason); + } + if (stateChange.MovementForceGUID) data << *stateChange.MovementForceGUID; - if (stateChange.MovementForce_) - data << *stateChange.MovementForce_; - return data; } diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index e8bb4ac7ae9..ae8c7a07c6c 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -91,24 +91,46 @@ namespace WorldPackets uint32 Duration = 0; }; + struct MonsterSplineAnimTierTransition + { + int32 TierTransitionID = 0; + uint32 StartTime = 0; + uint32 EndTime = 0; + uint8 AnimTier = 0; + }; + + struct MonsterSplineUnknown901 + { + struct Inner + { + int32 Unknown_1 = 0; + int32 Unknown_2 = 0; + int32 Unknown_3 = 0; + uint32 Unknown_4 = 0; + }; + + std::array<Inner, 16> Data; + }; + struct MovementSpline { uint32 Flags = 0; // Spline flags uint8 Face = 0; // Movement direction (see MonsterMoveType enum) - uint8 AnimTier = 0; - uint32 TierTransStartTime = 0; int32 Elapsed = 0; uint32 MoveTime = 0; uint32 FadeObjectTime = 0; std::vector<TaggedPosition<Position::XYZ>> Points; // Spline path uint8 Mode = 0; // Spline mode - actually always 0 in this packet - Catmullrom mode appears only in SMSG_UPDATE_OBJECT. In this packet it is determined by flags - uint8 VehicleExitVoluntary = 0; + bool VehicleExitVoluntary = false; + bool Interpolate = false; ObjectGuid TransportGUID; int8 VehicleSeat = -1; std::vector<TaggedPosition<Position::PackedXYZ>> PackedDeltas; Optional<MonsterSplineFilter> SplineFilter; Optional<MonsterSplineSpellEffectExtraData> SpellEffectExtraData; Optional<MonsterSplineJumpExtraData> JumpExtraData; + Optional<MonsterSplineAnimTierTransition> AnimTierTransition; + Optional<MonsterSplineUnknown901> Unknown901; float FaceDirection = 0.0f; ObjectGuid FaceGUID; TaggedPosition<Position::XYZ> FaceSpot; @@ -233,16 +255,23 @@ namespace WorldPackets uint32 TransfertAbort = 0; }; + struct TeleportLocation + { + TaggedPosition<Position::XYZO> Pos; + int32 Unused901_1 = -1; + int32 Unused901_2 = -1; + }; + class NewWorld final : public ServerPacket { public: - NewWorld() : ServerPacket(SMSG_NEW_WORLD, 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4) { } + NewWorld() : ServerPacket(SMSG_NEW_WORLD, 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4) { } WorldPacket const* Write() override; int32 MapID = 0; uint32 Reason = 0; - TaggedPosition<Position::XYZO> Pos; + TeleportLocation Loc; TaggedPosition<Position::XYZ> MovementOffset; // Adjusts all pending movement events by this offset }; @@ -609,7 +638,7 @@ namespace WorldPackets { float Height = 0.0f; float Scale = 0.0f; - UpdateCollisionHeightReason Reason; + UpdateCollisionHeightReason Reason = UPDATE_COLLISION_HEIGHT_MOUNT; }; struct KnockBackInfo diff --git a/src/server/game/Server/Packets/NPCPackets.cpp b/src/server/game/Server/Packets/NPCPackets.cpp index acaa5f64cbf..770a7bb7ea3 100644 --- a/src/server/game/Server/Packets/NPCPackets.cpp +++ b/src/server/game/Server/Packets/NPCPackets.cpp @@ -16,13 +16,53 @@ */ #include "NPCPackets.h" +#include "Util.h" -void WorldPackets::NPC::Hello::Read() +namespace WorldPackets +{ +namespace NPC +{ +ByteBuffer& operator<<(ByteBuffer& data, ClientGossipText const& gossipText) +{ + data << int32(gossipText.QuestID); + data << int32(gossipText.ContentTuningID); + data << int32(gossipText.QuestType); + data << int32(gossipText.QuestFlags[0]); + data << int32(gossipText.QuestFlags[1]); + + data.WriteBit(gossipText.Repeatable); + data.WriteBits(gossipText.QuestTitle.size(), 9); + data.FlushBits(); + + data.WriteString(gossipText.QuestTitle); + + return data; +} + +void Hello::Read() { _worldPacket >> Unit; } -WorldPacket const* WorldPackets::NPC::GossipMessage::Write() +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; +} + +WorldPacket const* GossipMessage::Write() { _worldPacket << GossipGUID; _worldPacket << int32(GossipID); @@ -39,32 +79,22 @@ WorldPacket const* WorldPackets::NPC::GossipMessage::Write() _worldPacket << int32(options.OptionCost); _worldPacket.WriteBits(options.Text.size(), 12); _worldPacket.WriteBits(options.Confirm.size(), 12); + _worldPacket.WriteBits(AsUnderlyingType(options.Status), 2); _worldPacket.FlushBits(); + _worldPacket << options.Treasure; + _worldPacket.WriteString(options.Text); _worldPacket.WriteString(options.Confirm); } for (ClientGossipText const& text : GossipText) - { - _worldPacket << int32(text.QuestID); - _worldPacket << int32(text.QuestType); - _worldPacket << int32(text.QuestLevel); - _worldPacket << int32(text.QuestMaxScalingLevel); - _worldPacket << int32(text.QuestFlags[0]); - _worldPacket << int32(text.QuestFlags[1]); - - _worldPacket.WriteBit(text.Repeatable); - _worldPacket.WriteBits(text.QuestTitle.size(), 9); - _worldPacket.FlushBits(); - - _worldPacket.WriteString(text.QuestTitle); - } + _worldPacket << text; return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::NPC::VendorItem const &item) +ByteBuffer& operator<<(ByteBuffer& data, VendorItem const& item) { data << uint32(item.MuID); data << int32(item.Type); @@ -75,6 +105,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::NPC::VendorItem const &it data << int32(item.ExtendedCostID); data << int32(item.PlayerConditionFailed); data << item.Item; + data.WriteBit(item.Locked); data.WriteBit(item.DoNotFilterOnVendor); data.WriteBit(item.Refundable); data.FlushBits(); @@ -82,7 +113,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::NPC::VendorItem const &it return data; } -WorldPacket const* WorldPackets::NPC::VendorInventory::Write() +WorldPacket const* VendorInventory::Write() { _worldPacket << Vendor; _worldPacket << uint8(Reason); @@ -93,7 +124,7 @@ WorldPacket const* WorldPackets::NPC::VendorInventory::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::NPC::TrainerList::Write() +WorldPacket const* TrainerList::Write() { _worldPacket << TrainerGUID; _worldPacket << uint32(TrainerType); @@ -118,14 +149,14 @@ WorldPacket const* WorldPackets::NPC::TrainerList::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::NPC::ShowBank::Write() +WorldPacket const* ShowBank::Write() { _worldPacket << Guid; return &_worldPacket; } -void WorldPackets::NPC::GossipSelectOption::Read() +void GossipSelectOption::Read() { _worldPacket >> GossipUnit; _worldPacket >> GossipID; @@ -135,14 +166,14 @@ void WorldPackets::NPC::GossipSelectOption::Read() PromotionCode = _worldPacket.ReadString(length); } -WorldPacket const* WorldPackets::NPC::PlayerTabardVendorActivate::Write() +WorldPacket const* PlayerTabardVendorActivate::Write() { _worldPacket << Vendor; return &_worldPacket; } -WorldPacket const* WorldPackets::NPC::GossipPOI::Write() +WorldPacket const* GossipPOI::Write() { _worldPacket << int32(ID); _worldPacket << Pos; @@ -156,26 +187,26 @@ WorldPacket const* WorldPackets::NPC::GossipPOI::Write() return &_worldPacket; } -void WorldPackets::NPC::SpiritHealerActivate::Read() +void SpiritHealerActivate::Read() { _worldPacket >> Healer; } -WorldPacket const* WorldPackets::NPC::SpiritHealerConfirm::Write() +WorldPacket const* SpiritHealerConfirm::Write() { _worldPacket << Unit; return &_worldPacket; } -void WorldPackets::NPC::TrainerBuySpell::Read() +void TrainerBuySpell::Read() { _worldPacket >> TrainerGUID; _worldPacket >> TrainerID; _worldPacket >> SpellID; } -WorldPacket const* WorldPackets::NPC::TrainerBuyFailed::Write() +WorldPacket const* TrainerBuyFailed::Write() { _worldPacket << TrainerGUID; _worldPacket << SpellID; @@ -184,7 +215,9 @@ WorldPacket const* WorldPackets::NPC::TrainerBuyFailed::Write() return &_worldPacket; } -void WorldPackets::NPC::RequestStabledPets::Read() +void RequestStabledPets::Read() { _worldPacket >> StableMaster; } +} +} diff --git a/src/server/game/Server/Packets/NPCPackets.h b/src/server/game/Server/Packets/NPCPackets.h index 9cc3cad1c7b..c5d57b31efc 100644 --- a/src/server/game/Server/Packets/NPCPackets.h +++ b/src/server/game/Server/Packets/NPCPackets.h @@ -24,6 +24,9 @@ #include "Position.h" #include <array> +enum class GossipOptionStatus : uint8; +enum class GossipOptionRewardType : uint8; + namespace WorldPackets { namespace NPC @@ -45,27 +48,42 @@ namespace WorldPackets ObjectGuid Unit; }; + struct TreasureItem + { + GossipOptionRewardType Type = GossipOptionRewardType(0); + int32 ID = 0; + int32 Quantity = 0; + }; + + struct TreasureLootList + { + std::vector<TreasureItem> Items; + }; + struct ClientGossipOptions { int32 ClientOption = 0; uint8 OptionNPC = 0; uint8 OptionFlags = 0; int32 OptionCost = 0; + GossipOptionStatus Status = GossipOptionStatus(0); std::string Text; std::string Confirm; + TreasureLootList Treasure; }; struct ClientGossipText { int32 QuestID = 0; + int32 ContentTuningID = 0; int32 QuestType = 0; - int32 QuestLevel = 0; - int32 QuestMaxScalingLevel = 0; bool Repeatable = false; std::string QuestTitle; int32 QuestFlags[2] = { }; }; + ByteBuffer& operator<<(ByteBuffer& data, ClientGossipText const& gossipText); + class GossipMessage final : public ServerPacket { public: @@ -113,6 +131,7 @@ namespace WorldPackets int32 StackCount = 0; int32 ExtendedCostID = 0; int32 PlayerConditionFailed = 0; + bool Locked = false; bool DoNotFilterOnVendor = false; bool Refundable = false; }; diff --git a/src/server/game/Server/Packets/PacketUtilities.cpp b/src/server/game/Server/Packets/PacketUtilities.cpp index 510f9bbcbf8..99f3decd0e1 100644 --- a/src/server/game/Server/Packets/PacketUtilities.cpp +++ b/src/server/game/Server/Packets/PacketUtilities.cpp @@ -25,8 +25,3 @@ WorldPackets::PacketArrayMaxCapacityException::PacketArrayMaxCapacityException(s builder << "Attempted to read more array elements from packet " << requestedSize << " than allowed " << sizeLimit; message().assign(builder.str()); } - -void WorldPackets::CheckCompactArrayMaskOverflow(std::size_t index, std::size_t limit) -{ - ASSERT(index < limit, "Attempted to insert " SZFMTD " values into CompactArray but it can only hold " SZFMTD, index, limit); -} diff --git a/src/server/game/Server/Packets/PacketUtilities.h b/src/server/game/Server/Packets/PacketUtilities.h index c40858d0088..327c42923a2 100644 --- a/src/server/game/Server/Packets/PacketUtilities.h +++ b/src/server/game/Server/Packets/PacketUtilities.h @@ -90,101 +90,16 @@ namespace WorldPackets _storage.push_back(std::forward<value_type>(value)); } - private: - storage_type _storage; - }; - - void CheckCompactArrayMaskOverflow(std::size_t index, std::size_t limit); - - template <typename T> - class CompactArray - { - public: - CompactArray() : _mask(0) { } - - CompactArray(CompactArray const& right) - : _mask(right._mask), _contents(right._contents) { } - - CompactArray(CompactArray&& right) - : _mask(right._mask), _contents(std::move(right._contents)) - { - right._mask = 0; - } - - CompactArray& operator=(CompactArray const& right) - { - _mask = right._mask; - _contents = right._contents; - return *this; - } - - CompactArray& operator=(CompactArray&& right) - { - _mask = right._mask; - right._mask = 0; - _contents = std::move(right._contents); - return *this; - } - - uint32 GetMask() const { return _mask; } - T const& operator[](std::size_t index) const { return _contents[index]; } - std::size_t GetSize() const { return _contents.size(); } - - void Insert(std::size_t index, T const& value) - { - CheckCompactArrayMaskOverflow(index, sizeof(_mask) * 8); - - _mask |= 1 << index; - if (_contents.size() <= index) - _contents.resize(index + 1); - _contents[index] = value; - } - - void Clear() + template<typename... Args> + T& emplace_back(Args&&... args) { - _mask = 0; - _contents.clear(); - } - - bool operator==(CompactArray const& r) const - { - if (_mask != r._mask) - return false; - - return _contents == r._contents; + _storage.emplace_back(std::forward<Args>(args)...); + return _storage.back(); } - bool operator!=(CompactArray const& r) const { return !(*this == r); } - private: - uint32 _mask; - std::vector<T> _contents; + storage_type _storage; }; - - template <typename T> - ByteBuffer& operator<<(ByteBuffer& data, CompactArray<T> const& v) - { - uint32 mask = v.GetMask(); - data << uint32(mask); - for (std::size_t i = 0; i < v.GetSize(); ++i) - if (mask & (1 << i)) - data << v[i]; - - return data; - } - - template <typename T> - ByteBuffer& operator>>(ByteBuffer& data, CompactArray<T>& v) - { - uint32 mask; - data >> mask; - - for (std::size_t index = 0; mask != 0; mask >>= 1, ++index) - if ((mask & 1) != 0) - v.Insert(index, data.read<T>()); - - return data; - } } #endif // PacketUtilities_h__ diff --git a/src/server/game/Server/Packets/PartyPackets.cpp b/src/server/game/Server/Packets/PartyPackets.cpp index 1c58bf9edc3..72388d1b98c 100644 --- a/src/server/game/Server/Packets/PartyPackets.cpp +++ b/src/server/game/Server/Packets/PartyPackets.cpp @@ -64,16 +64,10 @@ WorldPacket const* WorldPackets::Party::PartyInvite::Write() _worldPacket.WriteBit(IsXRealm); _worldPacket.WriteBit(MustBeBNetFriend); _worldPacket.WriteBit(AllowMultipleRoles); + _worldPacket.WriteBit(QuestSessionActive); _worldPacket.WriteBits(InviterName.length(), 6); - _worldPacket << InviterVirtualRealmAddress; - _worldPacket.WriteBit(IsLocal); - _worldPacket.WriteBit(Unk2); - _worldPacket.WriteBits(InviterRealmNameActual.size(), 8); - _worldPacket.WriteBits(InviterRealmNameNormalized.size(), 8); - _worldPacket.WriteString(InviterRealmNameActual); - _worldPacket.WriteString(InviterRealmNameNormalized); - + _worldPacket << InviterRealm; _worldPacket << InviterGUID; _worldPacket << InviterBNetAccountId; _worldPacket << uint16(Unk1); @@ -99,9 +93,7 @@ void WorldPackets::Party::PartyInvite::Initialize(Player* const inviter, int32 p ProposedRoles = proposedRoles; - InviterVirtualRealmAddress = realm.Id.GetAddress(); - InviterRealmNameActual = realm.Name; - InviterRealmNameNormalized = realm.NormalizedName; + InviterRealm = Auth::VirtualRealmInfo(realm.Id.GetAddress(), true, false, realm.Name, realm.NormalizedName); } void WorldPackets::Party::PartyInviteResponse::Read() @@ -165,7 +157,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::PartyMemberPhaseSt ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::PartyMemberAuraStates const& aura) { data << int32(aura.SpellID); - data << uint8(aura.Flags); + data << uint16(aura.Flags); data << uint32(aura.ActiveFlags); data << int32(aura.Points.size()); for (float points : aura.Points) @@ -174,6 +166,15 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::PartyMemberAuraSta return data; } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::CTROptions const& ctrOptions) +{ + data << uint32(ctrOptions.ContentTuningConditionMask); + data << int32(ctrOptions.Unused901); + data << uint32(ctrOptions.ExpansionLevelMask); + + return data; +} + ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::PartyMemberPetStats const& petStats) { data << petStats.GUID; @@ -214,6 +215,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::PartyMemberStats c data << int32(memberStats.VehicleSeat); data << uint32(memberStats.Auras.size()); data << memberStats.Phases; + data << memberStats.ChromieTime; for (WorldPackets::Party::PartyMemberAuraStates const& aura : memberStats.Auras) data << aura; diff --git a/src/server/game/Server/Packets/PartyPackets.h b/src/server/game/Server/Packets/PartyPackets.h index 3dde1e61399..769ffae245d 100644 --- a/src/server/game/Server/Packets/PartyPackets.h +++ b/src/server/game/Server/Packets/PartyPackets.h @@ -19,6 +19,7 @@ #define PartyPackets_h__ #include "Packet.h" +#include "AuthenticationPackets.h" #include "ObjectGuid.h" #include "Group.h" #include "Optional.h" @@ -67,22 +68,19 @@ namespace WorldPackets bool MightCRZYou = false; bool MustBeBNetFriend = false; bool AllowMultipleRoles = false; - bool Unk2 = false; + bool QuestSessionActive = false; uint16 Unk1 = 0; bool CanAccept = false; // Inviter + Auth::VirtualRealmInfo InviterRealm; ObjectGuid InviterGUID; ObjectGuid InviterBNetAccountId; std::string InviterName; // Realm bool IsXRealm = false; - bool IsLocal = true; - uint32 InviterVirtualRealmAddress = 0u; - std::string InviterRealmNameActual; - std::string InviterRealmNameNormalized; // Lfg uint32 ProposedRoles = 0; @@ -159,7 +157,7 @@ namespace WorldPackets struct PartyMemberAuraStates { int32 SpellID = 0; - uint8 Flags = 0; + uint16 Flags = 0; uint32 ActiveFlags = 0u; std::vector<float> Points; }; @@ -176,6 +174,13 @@ namespace WorldPackets std::vector<PartyMemberAuraStates> Auras; }; + struct CTROptions + { + uint32 ContentTuningConditionMask = 0; + int32 Unused901 = 0; + uint32 ExpansionLevelMask = 0; + }; + struct PartyMemberStats { uint16 Level = 0; @@ -204,6 +209,8 @@ namespace WorldPackets uint16 WmoGroupID = 0; uint32 WmoDoodadPlacementID = 0; int8 PartyType[2]; + + CTROptions ChromieTime; }; class PartyMemberFullState final : public ServerPacket diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp index c1de4be8960..e6cdb28ee60 100644 --- a/src/server/game/Server/Packets/QueryPackets.cpp +++ b/src/server/game/Server/Packets/QueryPackets.cpp @@ -80,7 +80,6 @@ WorldPacket const* WorldPackets::Query::QueryCreatureResponse::Write() _worldPacket << int32(Stats.RequiredExpansion); _worldPacket << int32(Stats.VignetteID); _worldPacket << int32(Stats.Class); - _worldPacket << float(Stats.FadeRegionRadius); _worldPacket << int32(Stats.WidgetSetID); _worldPacket << int32(Stats.WidgetSetUnitConditionID); @@ -355,9 +354,9 @@ void WorldPackets::Query::QuestPOIQuery::Read() ByteBuffer& operator<<(ByteBuffer& data, QuestPOIData const& questPOIData) { data << int32(questPOIData.QuestID); - data << int32(questPOIData.QuestPOIBlobDataStats.size()); + data << int32(questPOIData.Blobs.size()); - for (QuestPOIBlobData const& questPOIBlobData : questPOIData.QuestPOIBlobDataStats) + for (QuestPOIBlobData const& questPOIBlobData : questPOIData.Blobs) { data << int32(questPOIBlobData.BlobIndex); data << int32(questPOIBlobData.ObjectiveIndex); @@ -369,13 +368,15 @@ ByteBuffer& operator<<(ByteBuffer& data, QuestPOIData const& questPOIData) data << int32(questPOIBlobData.Flags); data << int32(questPOIBlobData.WorldEffectID); data << int32(questPOIBlobData.PlayerConditionID); + data << int32(questPOIBlobData.NavigationPlayerConditionID); data << int32(questPOIBlobData.SpawnTrackingID); - data << int32(questPOIBlobData.QuestPOIBlobPointStats.size()); + data << int32(questPOIBlobData.Points.size()); - for (QuestPOIBlobPoint const& questPOIBlobPoint : questPOIBlobData.QuestPOIBlobPointStats) + for (QuestPOIBlobPoint const& questPOIBlobPoint : questPOIBlobData.Points) { - data << int32(questPOIBlobPoint.X); - data << int32(questPOIBlobPoint.Y); + data << int16(questPOIBlobPoint.X); + data << int16(questPOIBlobPoint.Y); + data << int16(questPOIBlobPoint.Z); } data.WriteBit(questPOIBlobData.AlwaysAllowMergingBlobs); diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h index 6c8d2b6c648..b7279d18964 100644 --- a/src/server/game/Server/Packets/QueryPackets.h +++ b/src/server/game/Server/Packets/QueryPackets.h @@ -83,7 +83,6 @@ namespace WorldPackets uint32 RequiredExpansion = 0; uint32 VignetteID = 0; int32 Class = 0; - float FadeRegionRadius = 0.0f; int32 WidgetSetID = 0; int32 WidgetSetUnitConditionID = 0; std::array<uint32, 2> Flags; diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp index 36bb9c3aa17..3fcd20bb1fe 100644 --- a/src/server/game/Server/Packets/QuestPackets.cpp +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -16,13 +16,26 @@ */ #include "QuestPackets.h" +#include "Util.h" -void WorldPackets::Quest::QuestGiverStatusQuery::Read() +namespace WorldPackets +{ +namespace Quest +{ +ByteBuffer& operator<<(ByteBuffer& data, QuestCompleteDisplaySpell const& questDisplaySpell) +{ + data << int32(questDisplaySpell.SpellID); + data << int32(questDisplaySpell.PlayerConditionID); + + return data; +} + +void QuestGiverStatusQuery::Read() { _worldPacket >> QuestGiverGUID; } -WorldPacket const* WorldPackets::Quest::QuestGiverStatus::Write() +WorldPacket const* QuestGiverStatus::Write() { _worldPacket << QuestGiver.Guid; _worldPacket << uint32(QuestGiver.Status); @@ -30,7 +43,7 @@ WorldPacket const* WorldPackets::Quest::QuestGiverStatus::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Quest::QuestGiverStatusMultiple::Write() +WorldPacket const* QuestGiverStatusMultiple::Write() { _worldPacket << int32(QuestGiver.size()); for (QuestGiverInfo const& questGiver : QuestGiver) @@ -42,18 +55,18 @@ WorldPacket const* WorldPackets::Quest::QuestGiverStatusMultiple::Write() return &_worldPacket; } -void WorldPackets::Quest::QuestGiverHello::Read() +void QuestGiverHello::Read() { _worldPacket >> QuestGiverGUID; } -void WorldPackets::Quest::QueryQuestInfo::Read() +void QueryQuestInfo::Read() { _worldPacket >> QuestID; _worldPacket >> QuestGiver; } -WorldPacket const* WorldPackets::Quest::QueryQuestInfoResponse::Write() +WorldPacket const* QueryQuestInfoResponse::Write() { _worldPacket << uint32(QuestID); @@ -64,11 +77,8 @@ WorldPacket const* WorldPackets::Quest::QueryQuestInfoResponse::Write() { _worldPacket << int32(Info.QuestID); _worldPacket << int32(Info.QuestType); - _worldPacket << int32(Info.QuestLevel); - _worldPacket << int32(Info.QuestScalingFactionGroup); - _worldPacket << int32(Info.QuestMaxScalingLevel); _worldPacket << int32(Info.QuestPackageID); - _worldPacket << int32(Info.QuestMinLevel); + _worldPacket << int32(Info.ContentTuningID); _worldPacket << int32(Info.QuestSortID); _worldPacket << int32(Info.QuestInfoID); _worldPacket << int32(Info.SuggestedGroupNum); @@ -79,7 +89,7 @@ WorldPacket const* WorldPackets::Quest::QueryQuestInfoResponse::Write() _worldPacket << int32(Info.RewardMoneyDifficulty); _worldPacket << float(Info.RewardMoneyMultiplier); _worldPacket << int32(Info.RewardBonusMoney); - _worldPacket.append(Info.RewardDisplaySpell, QUEST_REWARD_DISPLAY_SPELL_COUNT); + _worldPacket << uint32(Info.RewardDisplaySpell.size()); _worldPacket << int32(Info.RewardSpell); _worldPacket << int32(Info.RewardHonor); _worldPacket << float(Info.RewardKillHonor); @@ -149,6 +159,9 @@ WorldPacket const* WorldPackets::Quest::QueryQuestInfoResponse::Write() _worldPacket << int32(Info.ManagedWorldStateID); _worldPacket << int32(Info.QuestSessionBonus); + for (QuestCompleteDisplaySpell const& rewardDisplaySpell : Info.RewardDisplaySpell) + _worldPacket << rewardDisplaySpell; + _worldPacket.WriteBits(Info.LogTitle.size(), 9); _worldPacket.WriteBits(Info.LogDescription.size(), 12); _worldPacket.WriteBits(Info.QuestDescription.size(), 12); @@ -158,6 +171,7 @@ WorldPacket const* WorldPackets::Quest::QueryQuestInfoResponse::Write() _worldPacket.WriteBits(Info.PortraitTurnInText.size(), 10); _worldPacket.WriteBits(Info.PortraitTurnInName.size(), 8); _worldPacket.WriteBits(Info.QuestCompletionLog.size(), 11); + _worldPacket.WriteBit(Info.ReadyForTranslation); _worldPacket.FlushBits(); for (QuestObjective const& questObjective : Info.Objectives) @@ -195,7 +209,7 @@ WorldPacket const* WorldPackets::Quest::QueryQuestInfoResponse::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Quest::QuestUpdateAddCredit::Write() +WorldPacket const* QuestUpdateAddCredit::Write() { _worldPacket << VictimGUID; _worldPacket << int32(QuestID); @@ -207,7 +221,7 @@ WorldPacket const* WorldPackets::Quest::QuestUpdateAddCredit::Write() return &_worldPacket; }; -WorldPacket const* WorldPackets::Quest::QuestUpdateAddCreditSimple::Write() +WorldPacket const* QuestUpdateAddCreditSimple::Write() { _worldPacket << int32(QuestID); _worldPacket << int32(ObjectID); @@ -216,7 +230,7 @@ WorldPacket const* WorldPackets::Quest::QuestUpdateAddCreditSimple::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Quest::QuestUpdateAddPvPCredit::Write() +WorldPacket const* QuestUpdateAddPvPCredit::Write() { _worldPacket << int32(QuestID); _worldPacket << uint16(Count); @@ -224,7 +238,26 @@ WorldPacket const* WorldPackets::Quest::QuestUpdateAddPvPCredit::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::QuestRewards const& questRewards) +ByteBuffer& operator<<(ByteBuffer& data, QuestChoiceItem const& questChoiceItem) +{ + data.WriteBits(AsUnderlyingType(questChoiceItem.LootItemType), 2); + data << questChoiceItem.Item; + data << int32(questChoiceItem.Quantity); + + return data; +} + +ByteBuffer& operator>>(ByteBuffer& data, QuestChoiceItem& questChoiceItem) +{ + data.ResetBitPos(); + questChoiceItem.LootItemType = LootItemType(data.ReadBits(2)); + data >> questChoiceItem.Item; + data >> questChoiceItem.Quantity; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, QuestRewards const& questRewards) { data << int32(questRewards.ChoiceItemCount); data << int32(questRewards.ItemCount); @@ -251,8 +284,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::QuestRewards const data << int32(questRewards.FactionCapIn[i]); } - for (uint32 i = 0; i < QUEST_REWARD_DISPLAY_SPELL_COUNT; ++i) - data << int32(questRewards.SpellCompletionDisplayID[i]); + data.append(questRewards.SpellCompletionDisplayID.data(), questRewards.SpellCompletionDisplayID.size()); data << int32(questRewards.SpellCompletionID); @@ -266,11 +298,8 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::QuestRewards const data << int32(questRewards.NumSkillUps); data << int32(questRewards.TreasurePickerID); - for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) - { - data << questRewards.ChoiceItems[i].Item; - data << int32(questRewards.ChoiceItems[i].Quantity); - } + for (QuestChoiceItem const& choiceItem : questRewards.ChoiceItems) + data << choiceItem; data.WriteBit(questRewards.IsBoostSpell); data.FlushBits(); @@ -278,7 +307,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::QuestRewards const return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::QuestGiverOfferReward const& offer) +ByteBuffer& operator<<(ByteBuffer& data, QuestGiverOfferReward const& offer) { data << offer.QuestGiverGUID; data << int32(offer.QuestGiverCreatureID); @@ -287,23 +316,24 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::QuestGiverOfferRew data << int32(offer.QuestFlags[1]); // FlagsEx data << int32(offer.SuggestedPartyMembers); data << int32(offer.Emotes.size()); - for (WorldPackets::Quest::QuestDescEmote const& emote : offer.Emotes) + for (QuestDescEmote const& emote : offer.Emotes) { data << int32(emote.Type); data << uint32(emote.Delay); } data.WriteBit(offer.AutoLaunched); + data.WriteBit(false); // Unused data.FlushBits(); - data << offer.Rewards; // WorldPackets::Quest::QuestRewards + data << offer.Rewards; // QuestRewards return data; } -WorldPacket const* WorldPackets::Quest::QuestGiverOfferRewardMessage::Write() +WorldPacket const* QuestGiverOfferRewardMessage::Write() { - _worldPacket << QuestData; // WorldPackets::Quest::QuestGiverOfferReward + _worldPacket << QuestData; // QuestGiverOfferReward _worldPacket << int32(QuestPackageID); _worldPacket << int32(PortraitGiver); _worldPacket << int32(PortraitGiverMount); @@ -327,14 +357,14 @@ WorldPacket const* WorldPackets::Quest::QuestGiverOfferRewardMessage::Write() return &_worldPacket; }; -void WorldPackets::Quest::QuestGiverChooseReward::Read() +void QuestGiverChooseReward::Read() { _worldPacket >> QuestGiverGUID; _worldPacket >> QuestID; - _worldPacket >> ItemChoiceID; + _worldPacket >> Choice; } -WorldPacket const* WorldPackets::Quest::QuestGiverQuestComplete::Write() +WorldPacket const* QuestGiverQuestComplete::Write() { _worldPacket << int32(QuestID); _worldPacket << int32(XPReward); @@ -351,14 +381,14 @@ WorldPacket const* WorldPackets::Quest::QuestGiverQuestComplete::Write() return &_worldPacket; } -void WorldPackets::Quest::QuestGiverCompleteQuest::Read() +void QuestGiverCompleteQuest::Read() { _worldPacket >> QuestGiverGUID; _worldPacket >> QuestID; FromScript = _worldPacket.ReadBit(); } -WorldPacket const* WorldPackets::Quest::QuestGiverQuestDetails::Write() +WorldPacket const* QuestGiverQuestDetails::Write() { _worldPacket << QuestGiverGUID; _worldPacket << InformUnit; @@ -379,13 +409,13 @@ WorldPacket const* WorldPackets::Quest::QuestGiverQuestDetails::Write() for (int32 spell : LearnSpells) _worldPacket << int32(spell); - for (WorldPackets::Quest::QuestDescEmote const& emote : DescEmotes) + for (QuestDescEmote const& emote : DescEmotes) { _worldPacket << int32(emote.Type); _worldPacket << uint32(emote.Delay); } - for (WorldPackets::Quest::QuestObjectiveSimple const& obj : Objectives) + for (QuestObjectiveSimple const& obj : Objectives) { _worldPacket << int32(obj.ID); _worldPacket << int32(obj.ObjectID); @@ -406,7 +436,7 @@ WorldPacket const* WorldPackets::Quest::QuestGiverQuestDetails::Write() _worldPacket.WriteBit(DisplayPopup); _worldPacket.FlushBits(); - _worldPacket << Rewards; // WorldPackets::Quest::QuestRewards + _worldPacket << Rewards; // QuestRewards _worldPacket.WriteString(QuestTitle); _worldPacket.WriteString(DescriptionText); _worldPacket.WriteString(LogDescription); @@ -418,7 +448,7 @@ WorldPacket const* WorldPackets::Quest::QuestGiverQuestDetails::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Quest::QuestGiverRequestItems::Write() +WorldPacket const* QuestGiverRequestItems::Write() { _worldPacket << QuestGiverGUID; _worldPacket << int32(QuestGiverCreatureID); @@ -459,32 +489,32 @@ WorldPacket const* WorldPackets::Quest::QuestGiverRequestItems::Write() return &_worldPacket; } -void WorldPackets::Quest::QuestGiverRequestReward::Read() +void QuestGiverRequestReward::Read() { _worldPacket >> QuestGiverGUID; _worldPacket >> QuestID; } -void WorldPackets::Quest::QuestGiverQueryQuest::Read() +void QuestGiverQueryQuest::Read() { _worldPacket >> QuestGiverGUID; _worldPacket >> QuestID; RespondToGiver = _worldPacket.ReadBit(); } -void WorldPackets::Quest::QuestGiverAcceptQuest::Read() +void QuestGiverAcceptQuest::Read() { _worldPacket >> QuestGiverGUID; _worldPacket >> QuestID; StartCheat = _worldPacket.ReadBit(); } -void WorldPackets::Quest::QuestLogRemoveQuest::Read() +void QuestLogRemoveQuest::Read() { _worldPacket >> Entry; } -WorldPacket const* WorldPackets::Quest::QuestGiverQuestListMessage::Write() +WorldPacket const* QuestGiverQuestListMessage::Write() { _worldPacket << QuestGiverGUID; _worldPacket << uint32(GreetEmoteDelay); @@ -493,33 +523,22 @@ WorldPacket const* WorldPackets::Quest::QuestGiverQuestListMessage::Write() _worldPacket.WriteBits(Greeting.size(), 11); _worldPacket.FlushBits(); - for (GossipText const& gossip : QuestDataText) - { - _worldPacket << uint32(gossip.QuestID); - _worldPacket << uint32(gossip.QuestType); - _worldPacket << int32(gossip.QuestLevel); - _worldPacket << int32(gossip.QuestMaxScalingLevel); - _worldPacket << uint32(gossip.QuestFlags); - _worldPacket << uint32(gossip.QuestFlagsEx); - _worldPacket.WriteBit(gossip.Repeatable); - _worldPacket.WriteBits(gossip.QuestTitle.size(), 9); - _worldPacket.FlushBits(); - _worldPacket.WriteString(gossip.QuestTitle); - } + for (NPC::ClientGossipText const& gossip : QuestDataText) + _worldPacket << gossip; _worldPacket.WriteString(Greeting); return &_worldPacket; } -WorldPacket const* WorldPackets::Quest::QuestUpdateComplete::Write() +WorldPacket const* QuestUpdateComplete::Write() { _worldPacket << int32(QuestID); return &_worldPacket; } -WorldPacket const* WorldPackets::Quest::QuestConfirmAcceptResponse::Write() +WorldPacket const* QuestConfirmAcceptResponse::Write() { _worldPacket << uint32(QuestID); _worldPacket << InitiatedBy; @@ -532,12 +551,12 @@ WorldPacket const* WorldPackets::Quest::QuestConfirmAcceptResponse::Write() return &_worldPacket; } -void WorldPackets::Quest::QuestConfirmAccept::Read() +void QuestConfirmAccept::Read() { _worldPacket >> QuestID; } -WorldPacket const* WorldPackets::Quest::QuestPushResultResponse::Write() +WorldPacket const* QuestPushResultResponse::Write() { _worldPacket << SenderGUID; _worldPacket << uint8(Result); @@ -545,14 +564,14 @@ WorldPacket const* WorldPackets::Quest::QuestPushResultResponse::Write() return &_worldPacket; } -void WorldPackets::Quest::QuestPushResult::Read() +void QuestPushResult::Read() { _worldPacket >> SenderGUID; _worldPacket >> QuestID; _worldPacket >> Result; } -WorldPacket const* WorldPackets::Quest::QuestGiverInvalidQuest::Write() +WorldPacket const* QuestGiverInvalidQuest::Write() { _worldPacket << uint32(Reason); _worldPacket << int32(ContributionRewardID); @@ -567,14 +586,14 @@ WorldPacket const* WorldPackets::Quest::QuestGiverInvalidQuest::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::Quest::QuestUpdateFailedTimer::Write() +WorldPacket const* QuestUpdateFailedTimer::Write() { _worldPacket << uint32(QuestID); return &_worldPacket; } -WorldPacket const* WorldPackets::Quest::QuestGiverQuestFailed::Write() +WorldPacket const* QuestGiverQuestFailed::Write() { _worldPacket << uint32(QuestID); _worldPacket << uint32(Reason); @@ -582,19 +601,19 @@ WorldPacket const* WorldPackets::Quest::QuestGiverQuestFailed::Write() return &_worldPacket; } -void WorldPackets::Quest::PushQuestToParty::Read() +void PushQuestToParty::Read() { _worldPacket >> QuestID; } -WorldPacket const* WorldPackets::Quest::DailyQuestsReset::Write() +WorldPacket const* DailyQuestsReset::Write() { _worldPacket << int32(Count); return &_worldPacket; } -WorldPacket const* WorldPackets::Quest::WorldQuestUpdateResponse::Write() +WorldPacket const* WorldQuestUpdateResponse::Write() { _worldPacket << uint32(WorldQuestUpdates.size()); @@ -610,14 +629,14 @@ WorldPacket const* WorldPackets::Quest::WorldQuestUpdateResponse::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::PlayerChoiceResponseRewardEntry const& playerChoiceResponseRewardEntry) +ByteBuffer& operator<<(ByteBuffer& data, PlayerChoiceResponseRewardEntry const& playerChoiceResponseRewardEntry) { data << playerChoiceResponseRewardEntry.Item; data << int32(playerChoiceResponseRewardEntry.Quantity); return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::PlayerChoiceResponseReward const& playerChoiceResponseReward) +ByteBuffer& operator<<(ByteBuffer& data, PlayerChoiceResponseReward const& playerChoiceResponseReward) { data << int32(playerChoiceResponseReward.TitleID); data << int32(playerChoiceResponseReward.PackageID); @@ -632,30 +651,45 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::PlayerChoiceRespon data << uint32(playerChoiceResponseReward.Factions.size()); data << uint32(playerChoiceResponseReward.ItemChoices.size()); - for (WorldPackets::Quest::PlayerChoiceResponseRewardEntry const& item : playerChoiceResponseReward.Items) + for (PlayerChoiceResponseRewardEntry const& item : playerChoiceResponseReward.Items) data << item; - for (WorldPackets::Quest::PlayerChoiceResponseRewardEntry const& currency : playerChoiceResponseReward.Currencies) + for (PlayerChoiceResponseRewardEntry const& currency : playerChoiceResponseReward.Currencies) data << currency; - for (WorldPackets::Quest::PlayerChoiceResponseRewardEntry const& faction : playerChoiceResponseReward.Factions) + for (PlayerChoiceResponseRewardEntry const& faction : playerChoiceResponseReward.Factions) data << faction; - for (WorldPackets::Quest::PlayerChoiceResponseRewardEntry const& itemChoice : playerChoiceResponseReward.ItemChoices) + for (PlayerChoiceResponseRewardEntry const& itemChoice : playerChoiceResponseReward.ItemChoices) data << itemChoice; return data; } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::PlayerChoiceResponse const& playerChoiceResponse) +ByteBuffer& operator<<(ByteBuffer& data, PlayerChoiceResponseMawPower const& playerChoiceResponseMawPower) +{ + data << int32(playerChoiceResponseMawPower.Unused901_1); + data << int32(playerChoiceResponseMawPower.TypeArtFileID); + data << int32(playerChoiceResponseMawPower.Rarity); + data << uint32(playerChoiceResponseMawPower.RarityColor); + data << int32(playerChoiceResponseMawPower.Unused901_2); + data << int32(playerChoiceResponseMawPower.SpellID); + data << int32(playerChoiceResponseMawPower.MaxStacks); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, PlayerChoiceResponse const& playerChoiceResponse) { data << int32(playerChoiceResponse.ResponseID); + data << uint16(playerChoiceResponse.ResponseIdentifier); data << int32(playerChoiceResponse.ChoiceArtFileID); data << int32(playerChoiceResponse.Flags); data << uint32(playerChoiceResponse.WidgetSetID); data << uint32(playerChoiceResponse.UiTextureAtlasElementID); data << uint32(playerChoiceResponse.SoundKitID); data << uint8(playerChoiceResponse.GroupID); + data << int32(playerChoiceResponse.UiTextureKitID); data.WriteBits(playerChoiceResponse.Answer.length(), 9); data.WriteBits(playerChoiceResponse.Header.length(), 9); @@ -665,6 +699,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::PlayerChoiceRespon data.WriteBits(playerChoiceResponse.Confirmation.length(), 7); data.WriteBit(playerChoiceResponse.RewardQuestID.is_initialized()); data.WriteBit(playerChoiceResponse.Reward.is_initialized()); + data.WriteBit(playerChoiceResponse.MawPower.is_initialized()); data.FlushBits(); if (playerChoiceResponse.Reward) @@ -680,10 +715,13 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::PlayerChoiceRespon if (playerChoiceResponse.RewardQuestID) data << uint32(*playerChoiceResponse.RewardQuestID); + if (playerChoiceResponse.MawPower) + data << *playerChoiceResponse.MawPower; + return data; } -WorldPacket const* WorldPackets::Quest::DisplayPlayerChoice::Write() +WorldPacket const* DisplayPlayerChoice::Write() { _worldPacket << int32(ChoiceID); _worldPacket << uint32(Responses.size()); @@ -703,8 +741,10 @@ WorldPacket const* WorldPackets::Quest::DisplayPlayerChoice::Write() return &_worldPacket; } -void WorldPackets::Quest::ChoiceResponse::Read() +void ChoiceResponse::Read() { _worldPacket >> ChoiceID; _worldPacket >> ResponseID; } +} +} diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h index 096c77c28cc..8c738fdcebe 100644 --- a/src/server/game/Server/Packets/QuestPackets.h +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -20,8 +20,12 @@ #include "Packet.h" #include "ItemPacketsCommon.h" +#include "NPCPackets.h" #include "ObjectGuid.h" #include "QuestDef.h" +#include <array> + +enum class LootItemType : uint8; namespace WorldPackets { @@ -104,15 +108,18 @@ namespace WorldPackets int32 DisplayID = 0; }; + struct QuestCompleteDisplaySpell + { + int32 SpellID = 0; + int32 PlayerConditionID = 0; + }; + struct QuestInfo { int32 QuestID = 0; int32 QuestType = 0; // Accepted values: 0, 1 or 2. 0 == IsAutoComplete() (skip objectives/details) - int32 QuestLevel = 0; // may be -1, static data, in other cases must be used dynamic level: Player::GetQuestLevel (0 is not known, but assuming this is no longer valid for quest intended for client) - int32 QuestScalingFactionGroup = 0; - int32 QuestMaxScalingLevel = 255; + int32 ContentTuningID = 0; int32 QuestPackageID = 0; - int32 QuestMinLevel = 0; int32 QuestSortID = 0; // zone or sort to display in quest log int32 QuestInfoID = 0; int32 SuggestedGroupNum = 0; @@ -123,7 +130,7 @@ namespace WorldPackets int32 RewardMoneyDifficulty = 0; float RewardMoneyMultiplier = 1.0f; int32 RewardBonusMoney = 0; - int32 RewardDisplaySpell[QUEST_REWARD_DISPLAY_SPELL_COUNT] = { }; // reward spell, this spell will be displayed (icon) + std::vector<QuestCompleteDisplaySpell> RewardDisplaySpell; // reward spell, this spell will be displayed (icon) int32 RewardSpell = 0; int32 RewardHonor = 0; float RewardKillHonor = 0.0f; @@ -176,6 +183,7 @@ namespace WorldPackets int32 RewardFactionCapIn[QUEST_REWARD_REPUTATIONS_COUNT] = { }; int32 RewardCurrencyID[QUEST_REWARD_CURRENCY_COUNT] = { }; int32 RewardCurrencyQty[QUEST_REWARD_CURRENCY_COUNT] = { }; + bool ReadyForTranslation = false; }; class QueryQuestInfoResponse final : public ServerPacket @@ -230,6 +238,7 @@ namespace WorldPackets struct QuestChoiceItem { + ::LootItemType LootItemType = ::LootItemType(0); Item::ItemInstance Item; int32 Quantity = 0; }; @@ -245,20 +254,20 @@ namespace WorldPackets int32 Honor = 0; int32 Title = 0; int32 FactionFlags = 0; - int32 SpellCompletionDisplayID[QUEST_REWARD_DISPLAY_SPELL_COUNT] = { }; + std::array<int32, QUEST_REWARD_DISPLAY_SPELL_COUNT> SpellCompletionDisplayID = { }; int32 SpellCompletionID = 0; int32 SkillLineID = 0; int32 NumSkillUps = 0; int32 TreasurePickerID = 0; - QuestChoiceItem ChoiceItems[QUEST_REWARD_CHOICES_COUNT]; - int32 ItemID[QUEST_REWARD_ITEM_COUNT] = { }; - int32 ItemQty[QUEST_REWARD_ITEM_COUNT] = { }; - int32 FactionID[QUEST_REWARD_REPUTATIONS_COUNT] = { }; - int32 FactionValue[QUEST_REWARD_REPUTATIONS_COUNT] = { }; - int32 FactionOverride[QUEST_REWARD_REPUTATIONS_COUNT] = { }; - int32 FactionCapIn[QUEST_REWARD_REPUTATIONS_COUNT] = { }; - int32 CurrencyID[QUEST_REWARD_CURRENCY_COUNT] = { }; - int32 CurrencyQty[QUEST_REWARD_CURRENCY_COUNT] = { }; + std::array<QuestChoiceItem, QUEST_REWARD_CHOICES_COUNT> ChoiceItems; + std::array<int32, QUEST_REWARD_ITEM_COUNT> ItemID = { }; + std::array<int32, QUEST_REWARD_ITEM_COUNT> ItemQty = { }; + std::array<int32, QUEST_REWARD_REPUTATIONS_COUNT> FactionID = { }; + std::array<int32, QUEST_REWARD_REPUTATIONS_COUNT> FactionValue = { }; + std::array<int32, QUEST_REWARD_REPUTATIONS_COUNT> FactionOverride = { }; + std::array<int32, QUEST_REWARD_REPUTATIONS_COUNT> FactionCapIn = { }; + std::array<int32, QUEST_REWARD_CURRENCY_COUNT> CurrencyID = { }; + std::array<int32, QUEST_REWARD_CURRENCY_COUNT> CurrencyQty = { }; bool IsBoostSpell = false; }; @@ -310,7 +319,7 @@ namespace WorldPackets ObjectGuid QuestGiverGUID; int32 QuestID = 0; - int32 ItemChoiceID = 0; + QuestChoiceItem Choice; }; class QuestGiverQuestComplete final : public ServerPacket @@ -469,21 +478,6 @@ namespace WorldPackets uint8 Entry = 0; }; - struct GossipText - { - GossipText(uint32 questID, uint32 questType, int32 questLevel, int32 questMaxScalingLevel, uint32 questFlags, uint32 questFlagsEx, bool repeatable, std::string questTitle) : - QuestID(questID), QuestType(questType), QuestLevel(questLevel), QuestMaxScalingLevel(questMaxScalingLevel), QuestFlags(questFlags), - QuestFlagsEx(questFlagsEx), Repeatable(repeatable), QuestTitle(std::move(questTitle)) { } - uint32 QuestID; - uint32 QuestType; - int32 QuestLevel; - int32 QuestMaxScalingLevel; - uint32 QuestFlags; - uint32 QuestFlagsEx; - bool Repeatable; - std::string QuestTitle; - }; - class QuestGiverQuestListMessage final : public ServerPacket { public: @@ -494,7 +488,7 @@ namespace WorldPackets ObjectGuid QuestGiverGUID; uint32 GreetEmoteDelay = 0; uint32 GreetEmoteType = 0; - std::vector<GossipText> QuestDataText; + std::vector<NPC::ClientGossipText> QuestDataText; std::string Greeting; }; @@ -667,15 +661,28 @@ namespace WorldPackets std::vector<PlayerChoiceResponseRewardEntry> ItemChoices; }; + struct PlayerChoiceResponseMawPower + { + int32 Unused901_1 = 0; + int32 TypeArtFileID = 0; + int32 Rarity = 0; + uint32 RarityColor = 0; + int32 Unused901_2 = 0; + int32 SpellID = 0; + int32 MaxStacks = 0; + }; + struct PlayerChoiceResponse { int32 ResponseID = 0; + uint16 ResponseIdentifier = 0; int32 ChoiceArtFileID = 0; int32 Flags = 0; uint32 WidgetSetID = 0; uint32 UiTextureAtlasElementID = 0; uint32 SoundKitID = 0; uint8 GroupID = 0; + int32 UiTextureKitID = 0; std::string Answer; std::string Header; std::string SubHeader; @@ -684,6 +691,7 @@ namespace WorldPackets std::string Confirmation; Optional<PlayerChoiceResponseReward> Reward; Optional<uint32> RewardQuestID; + Optional<PlayerChoiceResponseMawPower> MawPower; }; class DisplayPlayerChoice final : public ServerPacket @@ -717,7 +725,4 @@ namespace WorldPackets } } -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::QuestRewards const& questRewards); -ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Quest::QuestGiverOfferReward const& offer); - #endif // QuestPackets_h__ diff --git a/src/server/game/Server/Packets/ReputationPackets.h b/src/server/game/Server/Packets/ReputationPackets.h index b6406fe95cb..b3eecced951 100644 --- a/src/server/game/Server/Packets/ReputationPackets.h +++ b/src/server/game/Server/Packets/ReputationPackets.h @@ -25,7 +25,7 @@ namespace WorldPackets { namespace Reputation { - static uint16 const FactionCount = 350; + static uint16 const FactionCount = 400; class InitializeFactions final : public ServerPacket { diff --git a/src/server/game/Server/Packets/ScenarioPackets.cpp b/src/server/game/Server/Packets/ScenarioPackets.cpp index cc40dca1135..c833e6a2104 100644 --- a/src/server/game/Server/Packets/ScenarioPackets.cpp +++ b/src/server/game/Server/Packets/ScenarioPackets.cpp @@ -114,12 +114,14 @@ WorldPacket const* WorldPackets::Scenario::ScenarioPOIs::Write() _worldPacket << int32(scenarioPOI.Flags); _worldPacket << int32(scenarioPOI.WorldEffectID); _worldPacket << int32(scenarioPOI.PlayerConditionID); + _worldPacket << int32(scenarioPOI.NavigationPlayerConditionID); _worldPacket << uint32(scenarioPOI.Points.size()); for (ScenarioPOIPoint const& scenarioPOIBlobPoint : scenarioPOI.Points) { _worldPacket << int32(scenarioPOIBlobPoint.X); _worldPacket << int32(scenarioPOIBlobPoint.Y); + _worldPacket << int32(scenarioPOIBlobPoint.Z); } } } diff --git a/src/server/game/Server/Packets/SocialPackets.cpp b/src/server/game/Server/Packets/SocialPackets.cpp index 0ab58ca7bb7..a86a8f4c706 100644 --- a/src/server/game/Server/Packets/SocialPackets.cpp +++ b/src/server/game/Server/Packets/SocialPackets.cpp @@ -64,8 +64,8 @@ WorldPacket const* WorldPackets::Social::ContactList::Write() _worldPacket.WriteBits(Contacts.size(), 8); _worldPacket.FlushBits(); - for (size_t i = 0; i < Contacts.size(); ++i) - _worldPacket << Contacts[i]; + for (ContactInfo const& contact : Contacts) + _worldPacket << contact; return &_worldPacket; } diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp index 9efe37d956d..d31647bb122 100644 --- a/src/server/game/Server/Packets/SpellPackets.cpp +++ b/src/server/game/Server/Packets/SpellPackets.cpp @@ -95,8 +95,8 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::AuraDataInfo cons { data << auraData.CastID; data << int32(auraData.SpellID); - data << int32(auraData.SpellXSpellVisualID); - data << uint8(auraData.Flags); + data << auraData.Visual; + data << uint16(auraData.Flags); data << uint32(auraData.ActiveFlags); data << uint16(auraData.CastLevel); data << uint8(auraData.Applications); @@ -205,15 +205,39 @@ ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::MissileTrajecto return buffer; } +ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Spells::SpellOptionalReagent& optionalReagent) +{ + data >> optionalReagent.ItemID; + data >> optionalReagent.Slot; + data >> optionalReagent.Count; + return data; +} + +ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Spells::SpellExtraCurrencyCost& extraCurrencyCost) +{ + data >> extraCurrencyCost.CurrencyID; + data >> extraCurrencyCost.Count; + return data; +} + ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::SpellCastRequest& request) { buffer >> request.CastID; buffer >> request.Misc[0]; buffer >> request.Misc[1]; buffer >> request.SpellID; - buffer >> request.SpellXSpellVisualID; + buffer >> request.Visual; buffer >> request.MissileTrajectory; buffer >> request.CraftingNPC; + request.OptionalReagents.resize(buffer.read<uint32>()); + request.OptionalCurrencies.resize(buffer.read<uint32>()); + + for (WorldPackets::Spells::SpellOptionalReagent& optionalReagent : request.OptionalReagents) + buffer >> optionalReagent; + + for (WorldPackets::Spells::SpellExtraCurrencyCost& optionalCurrency : request.OptionalCurrencies) + buffer >> optionalCurrency; + request.SendCastFlags = buffer.ReadBits(5); bool hasMoveUpdate = buffer.ReadBit(); request.Weight.resize(buffer.ReadBits(2)); @@ -372,7 +396,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastData con data << spellCastData.CastID; data << spellCastData.OriginalCastID; data << int32(spellCastData.SpellID); - data << uint32(spellCastData.SpellXSpellVisualID); + data << spellCastData.Visual; data << uint32(spellCastData.CastFlags); data << uint32(spellCastData.CastFlagsEx); data << uint32(spellCastData.CastTime); @@ -439,6 +463,7 @@ WorldPacket const* WorldPackets::Spells::LearnedSpells::Write() { _worldPacket << uint32(SpellID.size()); _worldPacket << uint32(FavoriteSpellID.size()); + _worldPacket << uint32(SpecializationID); for (int32 spell : SpellID) _worldPacket << spell; @@ -474,7 +499,7 @@ WorldPacket const* WorldPackets::Spells::SpellFailure::Write() _worldPacket << CasterUnit; _worldPacket << CastID; _worldPacket << int32(SpellID); - _worldPacket << uint32(SpellXSpellVisualID); + _worldPacket << Visual; _worldPacket << uint16(Reason); return &_worldPacket; @@ -485,7 +510,7 @@ WorldPacket const* WorldPackets::Spells::SpellFailedOther::Write() _worldPacket << CasterUnit; _worldPacket << CastID; _worldPacket << uint32(SpellID); - _worldPacket << uint32(SpellXSpellVisualID); + _worldPacket << Visual; _worldPacket << uint8(Reason); return &_worldPacket; @@ -495,7 +520,7 @@ WorldPacket const* WorldPackets::Spells::CastFailed::Write() { _worldPacket << CastID; _worldPacket << int32(SpellID); - _worldPacket << int32(SpellXSpellVisualID); + _worldPacket << Visual; _worldPacket << int32(Reason); _worldPacket << int32(FailedArg1); _worldPacket << int32(FailedArg2); @@ -715,6 +740,8 @@ WorldPacket const* WorldPackets::Spells::CancelSpellVisualKit::Write() { _worldPacket << Source; _worldPacket << int32(SpellVisualKitID); + _worldPacket.WriteBit(MountedVisual); + _worldPacket.FlushBits(); return &_worldPacket; } @@ -760,6 +787,8 @@ WorldPacket const* WorldPackets::Spells::PlaySpellVisualKit::Write() _worldPacket << int32(KitRecID); _worldPacket << int32(KitType); _worldPacket << uint32(Duration); + _worldPacket.WriteBit(MountedVisual); + _worldPacket.FlushBits(); return &_worldPacket; } @@ -794,7 +823,7 @@ WorldPacket const* WorldPackets::Spells::SpellChannelStart::Write() { _worldPacket << CasterGUID; _worldPacket << int32(SpellID); - _worldPacket << int32(SpellXSpellVisualID); + _worldPacket << Visual; _worldPacket << uint32(ChannelDuration); _worldPacket.WriteBit(InterruptImmunities.is_initialized()); _worldPacket.WriteBit(HealPrediction.is_initialized()); @@ -852,18 +881,17 @@ WorldPacket const* WorldPackets::Spells::MirrorImageComponentedData::Write() { _worldPacket << UnitGUID; _worldPacket << int32(DisplayID); + _worldPacket << int32(SpellVisualKitID); _worldPacket << uint8(RaceID); _worldPacket << uint8(Gender); _worldPacket << uint8(ClassID); - _worldPacket << uint8(SkinColor); - _worldPacket << uint8(FaceVariation); - _worldPacket << uint8(HairVariation); - _worldPacket << uint8(HairColor); - _worldPacket << uint8(BeardVariation); - _worldPacket.append(CustomDisplay.data(), CustomDisplay.size()); + _worldPacket << uint32(Customizations.size()); _worldPacket << GuildGUID; _worldPacket << uint32(ItemDisplayID.size()); + for (Character::ChrCustomizationChoice const& customization : Customizations) + _worldPacket << customization; + for (int32 itemDisplayId : ItemDisplayID) _worldPacket << int32(itemDisplayId); @@ -874,6 +902,7 @@ WorldPacket const* WorldPackets::Spells::MirrorImageCreatureData::Write() { _worldPacket << UnitGUID; _worldPacket << int32(DisplayID); + _worldPacket << int32(SpellVisualKitID); return &_worldPacket; } diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index 65f1484322d..fa043ec305f 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -18,10 +18,12 @@ #ifndef SpellPackets_h__ #define SpellPackets_h__ +#include "CharacterPackets.h" #include "CombatLogPacketsCommon.h" #include "MovementInfo.h" #include "ObjectGuid.h" #include "Optional.h" +#include "PacketUtilities.h" #include "Position.h" #include "SharedDefines.h" #include <array> @@ -174,8 +176,8 @@ namespace WorldPackets { ObjectGuid CastID; int32 SpellID = 0; - int32 SpellXSpellVisualID = 0; - uint8 Flags = 0; + SpellCastVisual Visual; + uint16 Flags = 0; uint32 ActiveFlags = 0; uint16 CastLevel = 1; uint8 Applications = 1; @@ -238,16 +240,31 @@ namespace WorldPackets uint32 Quantity = 0; }; + struct SpellOptionalReagent + { + int32 ItemID = 0; + int32 Slot = 0; + int32 Count = 0; + }; + + struct SpellExtraCurrencyCost + { + int32 CurrencyID = 0; + int32 Count = 0; + }; + struct SpellCastRequest { ObjectGuid CastID; int32 SpellID = 0; - uint32 SpellXSpellVisualID = 0; + SpellCastVisual Visual; uint8 SendCastFlags = 0; SpellTargetData Target; MissileTrajectoryRequest MissileTrajectory; Optional<MovementInfo> MoveUpdate; std::vector<SpellWeight> Weight; + Array<SpellOptionalReagent, 3> OptionalReagents; + Array<SpellExtraCurrencyCost, 5 /*MAX_ITEM_EXT_COST_CURRENCIES*/> OptionalCurrencies; ObjectGuid CraftingNPC; int32 Misc[2] = { }; }; @@ -359,7 +376,7 @@ namespace WorldPackets ObjectGuid CastID; ObjectGuid OriginalCastID; int32 SpellID = 0; - uint32 SpellXSpellVisualID = 0; + SpellCastVisual Visual; uint32 CastFlags = 0; uint32 CastFlagsEx = 0; uint32 CastTime = 0; @@ -407,6 +424,7 @@ namespace WorldPackets std::vector<int32> SpellID; std::vector<int32> FavoriteSpellID; + uint32 SpecializationID = 0; bool SuppressMessaging = false; }; @@ -425,13 +443,13 @@ namespace WorldPackets class SpellFailure final : public ServerPacket { public: - SpellFailure() : ServerPacket(SMSG_SPELL_FAILURE, 16+4+2+1) { } + SpellFailure() : ServerPacket(SMSG_SPELL_FAILURE, 16 + 4 + 8 + 2 + 16) { } WorldPacket const* Write() override; ObjectGuid CasterUnit; uint32 SpellID = 0; - uint32 SpellXSpellVisualID = 0; + SpellCastVisual Visual; uint16 Reason = 0; ObjectGuid CastID; }; @@ -439,13 +457,13 @@ namespace WorldPackets class SpellFailedOther final : public ServerPacket { public: - SpellFailedOther() : ServerPacket(SMSG_SPELL_FAILED_OTHER, 16+4+1+1) { } + SpellFailedOther() : ServerPacket(SMSG_SPELL_FAILED_OTHER, 16 + 4 + 8 + 1 + 16) { } WorldPacket const* Write() override; ObjectGuid CasterUnit; uint32 SpellID = 0; - uint32 SpellXSpellVisualID = 0; + SpellCastVisual Visual; uint8 Reason = 0; ObjectGuid CastID; }; @@ -459,7 +477,7 @@ namespace WorldPackets ObjectGuid CastID; int32 SpellID = 0; - int32 SpellXSpellVisualID = 0; + SpellCastVisual Visual; int32 Reason = 0; int32 FailedArg1 = -1; int32 FailedArg2 = -1; @@ -697,6 +715,7 @@ namespace WorldPackets ObjectGuid Source; int32 SpellVisualKitID = 0; + bool MountedVisual = false; }; class PlayOrphanSpellVisual final : public ServerPacket @@ -749,6 +768,7 @@ namespace WorldPackets int32 KitRecID = 0; int32 KitType = 0; uint32 Duration = 0; + bool MountedVisual = false; }; class CancelCast final : public ClientPacket @@ -793,7 +813,7 @@ namespace WorldPackets WorldPacket const* Write() override; int32 SpellID = 0; - int32 SpellXSpellVisualID = 0; + SpellCastVisual Visual; Optional<SpellChannelStartInterruptImmunities> InterruptImmunities; ObjectGuid CasterGUID; Optional<SpellTargetedHealPrediction> HealPrediction; @@ -867,15 +887,11 @@ namespace WorldPackets ObjectGuid UnitGUID; int32 DisplayID = 0; + int32 SpellVisualKitID = 0; uint8 RaceID = 0; uint8 Gender = 0; uint8 ClassID = 0; - uint8 SkinColor = 0; - uint8 FaceVariation = 0; - uint8 HairVariation = 0; - uint8 HairColor = 0; - uint8 BeardVariation = 0; - std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> CustomDisplay; + std::vector<Character::ChrCustomizationChoice> Customizations; ObjectGuid GuildGUID; std::vector<int32> ItemDisplayID; @@ -890,6 +906,7 @@ namespace WorldPackets ObjectGuid UnitGUID; int32 DisplayID = 0; + int32 SpellVisualKitID = 0; }; class SpellClick final : public ClientPacket diff --git a/src/server/game/Server/Packets/SystemPackets.cpp b/src/server/game/Server/Packets/SystemPackets.cpp index cd7501cd52a..ca8be7045e7 100644 --- a/src/server/game/Server/Packets/SystemPackets.cpp +++ b/src/server/game/Server/Packets/SystemPackets.cpp @@ -18,7 +18,32 @@ #include "SystemPackets.h" #include "Errors.h" -WorldPacket const* WorldPackets::System::FeatureSystemStatus::Write() +namespace WorldPackets +{ +namespace System +{ +ByteBuffer& operator<<(ByteBuffer& data, SavedThrottleObjectState const& throttleState) +{ + data << uint32(throttleState.MaxTries); + data << uint32(throttleState.PerMilliseconds); + data << uint32(throttleState.TryCount); + data << uint32(throttleState.LastResetTimeBeforeNow); + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, EuropaTicketConfig const& europaTicketSystemStatus) +{ + data.WriteBit(europaTicketSystemStatus.TicketsEnabled); + data.WriteBit(europaTicketSystemStatus.BugsEnabled); + data.WriteBit(europaTicketSystemStatus.ComplaintsEnabled); + data.WriteBit(europaTicketSystemStatus.SuggestionsEnabled); + + data << europaTicketSystemStatus.ThrottleState; + + return data; +} + +WorldPacket const* FeatureSystemStatus::Write() { _worldPacket << uint8(ComplaintStatus); @@ -37,6 +62,7 @@ WorldPacket const* WorldPackets::System::FeatureSystemStatus::Write() _worldPacket << uint32(TwitterPostThrottleCooldown); _worldPacket << uint32(TokenPollTimeSeconds); + _worldPacket << uint32(KioskSessionMinutes); _worldPacket << int64(TokenBalanceAmount); _worldPacket << uint32(BpayStoreProductDeliveryDelay); @@ -59,7 +85,6 @@ WorldPacket const* WorldPackets::System::FeatureSystemStatus::Write() _worldPacket.WriteBit(RestrictedAccount); _worldPacket.WriteBit(CommerceSystemEnabled); _worldPacket.WriteBit(TutorialsEnabled); - _worldPacket.WriteBit(NPETutorialsEnabled); _worldPacket.WriteBit(TwitterEnabled); _worldPacket.WriteBit(Unk67); _worldPacket.WriteBit(WillKickFromWorld); @@ -76,6 +101,7 @@ WorldPacket const* WorldPackets::System::FeatureSystemStatus::Write() _worldPacket.WriteBit(QuestSessionEnabled); _worldPacket.WriteBit(IsMuted); _worldPacket.WriteBit(ClubFinderEnabled); + _worldPacket.WriteBit(Unknown901CheckoutRelated); _worldPacket.FlushBits(); @@ -113,28 +139,18 @@ WorldPacket const* WorldPackets::System::FeatureSystemStatus::Write() } { - _worldPacket.WriteBit(VoiceChatManagerSettings.IsSquelched); - _worldPacket << VoiceChatManagerSettings.BnetAccountGuid; - _worldPacket << VoiceChatManagerSettings.GuildGuid; + _worldPacket.WriteBit(Squelch.IsSquelched); + _worldPacket << Squelch.BnetAccountGuid; + _worldPacket << Squelch.GuildGuid; } if (EuropaTicketSystemStatus) - { - _worldPacket.WriteBit(EuropaTicketSystemStatus->TicketsEnabled); - _worldPacket.WriteBit(EuropaTicketSystemStatus->BugsEnabled); - _worldPacket.WriteBit(EuropaTicketSystemStatus->ComplaintsEnabled); - _worldPacket.WriteBit(EuropaTicketSystemStatus->SuggestionsEnabled); - - _worldPacket << uint32(EuropaTicketSystemStatus->ThrottleState.MaxTries); - _worldPacket << uint32(EuropaTicketSystemStatus->ThrottleState.PerMilliseconds); - _worldPacket << uint32(EuropaTicketSystemStatus->ThrottleState.TryCount); - _worldPacket << uint32(EuropaTicketSystemStatus->ThrottleState.LastResetTimeBeforeNow); - } + _worldPacket << *EuropaTicketSystemStatus; return &_worldPacket; } -WorldPacket const* WorldPackets::System::FeatureSystemStatusGlueScreen::Write() +WorldPacket const* FeatureSystemStatusGlueScreen::Write() { _worldPacket.WriteBit(BpayStoreEnabled); _worldPacket.WriteBit(BpayStoreAvailable); @@ -151,21 +167,32 @@ WorldPacket const* WorldPackets::System::FeatureSystemStatusGlueScreen::Write() _worldPacket.WriteBit(LiveRegionCharacterListEnabled); _worldPacket.WriteBit(LiveRegionCharacterCopyEnabled); _worldPacket.WriteBit(LiveRegionAccountCopyEnabled); + _worldPacket.WriteBit(LiveRegionKeyBindingsCopyEnabled); + _worldPacket.WriteBit(Unknown901CheckoutRelated); + _worldPacket.WriteBit(EuropaTicketSystemStatus.is_initialized()); _worldPacket.FlushBits(); + if (EuropaTicketSystemStatus) + _worldPacket << *EuropaTicketSystemStatus; + _worldPacket << uint32(TokenPollTimeSeconds); + _worldPacket << uint32(KioskSessionMinutes); _worldPacket << int64(TokenBalanceAmount); _worldPacket << int32(MaxCharactersPerRealm); + _worldPacket << uint32(LiveRegionCharacterCopySourceRegions.size()); _worldPacket << uint32(BpayStoreProductDeliveryDelay); _worldPacket << int32(ActiveCharacterUpgradeBoostType); _worldPacket << int32(ActiveClassTrialBoostType); _worldPacket << int32(MinimumExpansionLevel); _worldPacket << int32(MaximumExpansionLevel); + if (!LiveRegionCharacterCopySourceRegions.empty()) + _worldPacket.append(LiveRegionCharacterCopySourceRegions.data(), LiveRegionCharacterCopySourceRegions.size()); + return &_worldPacket; } -WorldPacket const* WorldPackets::System::MOTD::Write() +WorldPacket const* MOTD::Write() { ASSERT(Text); _worldPacket.WriteBits(Text->size(), 4); @@ -181,7 +208,7 @@ WorldPacket const* WorldPackets::System::MOTD::Write() return &_worldPacket; } -WorldPacket const* WorldPackets::System::SetTimeZoneInformation::Write() +WorldPacket const* SetTimeZoneInformation::Write() { _worldPacket.WriteBits(ServerTimeTZ.length(), 7); _worldPacket.WriteBits(GameTimeTZ.length(), 7); @@ -192,3 +219,5 @@ WorldPacket const* WorldPackets::System::SetTimeZoneInformation::Write() return &_worldPacket; } +} +} diff --git a/src/server/game/Server/Packets/SystemPackets.h b/src/server/game/Server/Packets/SystemPackets.h index 4f87ab34edc..34d9aabfda0 100644 --- a/src/server/game/Server/Packets/SystemPackets.h +++ b/src/server/game/Server/Packets/SystemPackets.h @@ -26,27 +26,27 @@ namespace WorldPackets { namespace System { - class FeatureSystemStatus final : public ServerPacket + struct SavedThrottleObjectState { - public: - struct SavedThrottleObjectState - { - uint32 MaxTries = 0; - uint32 PerMilliseconds = 0; - uint32 TryCount = 0; - uint32 LastResetTimeBeforeNow = 0; - }; + uint32 MaxTries = 0; + uint32 PerMilliseconds = 0; + uint32 TryCount = 0; + uint32 LastResetTimeBeforeNow = 0; + }; - struct EuropaTicketConfig - { - bool TicketsEnabled = false; - bool BugsEnabled = false; - bool ComplaintsEnabled = false; - bool SuggestionsEnabled = false; + struct EuropaTicketConfig + { + bool TicketsEnabled = false; + bool BugsEnabled = false; + bool ComplaintsEnabled = false; + bool SuggestionsEnabled = false; - SavedThrottleObjectState ThrottleState; - }; + SavedThrottleObjectState ThrottleState; + }; + class FeatureSystemStatus final : public ServerPacket + { + public: struct SessionAlertConfig { int32 Delay = 0; @@ -81,7 +81,7 @@ namespace WorldPackets float ThrottleDfBestPriority = 0.0f; }; - struct VoiceChatProxySettings + struct SquelchInfo { bool IsSquelched = false; ObjectGuid BnetAccountGuid; @@ -121,6 +121,7 @@ namespace WorldPackets uint32 BpayStoreProductDeliveryDelay = 0; uint32 ClubsPresenceUpdateTimer = 0; uint32 HiddenUIClubsPresenceUpdateTimer = 0; ///< Timer for updating club presence when communities ui frame is hidden + uint32 KioskSessionMinutes = 0; bool ItemRestorationButtonEnabled = false; bool CharUndeleteEnabled = false; ///< Implemented bool BpayStoreDisabledByParentalControls = false; @@ -144,9 +145,10 @@ namespace WorldPackets bool QuestSessionEnabled = false; bool IsMuted = false; bool ClubFinderEnabled = false; + bool Unknown901CheckoutRelated = false; SocialQueueConfig QuickJoinConfig; - VoiceChatProxySettings VoiceChatManagerSettings; + SquelchInfo Squelch; RafSystemFeatureInfo RAFSystem; }; @@ -172,6 +174,10 @@ namespace WorldPackets bool LiveRegionCharacterListEnabled = false; // NYI bool LiveRegionCharacterCopyEnabled = false; // NYI bool LiveRegionAccountCopyEnabled = false; // NYI + bool LiveRegionKeyBindingsCopyEnabled = false; + bool Unknown901CheckoutRelated = false; // NYI + Optional<EuropaTicketConfig> EuropaTicketSystemStatus; + std::vector<int32> LiveRegionCharacterCopySourceRegions; uint32 TokenPollTimeSeconds = 0; // NYI int64 TokenBalanceAmount = 0; // NYI int32 MaxCharactersPerRealm = 0; @@ -180,6 +186,7 @@ namespace WorldPackets int32 ActiveClassTrialBoostType = 0; // NYI int32 MinimumExpansionLevel = 0; int32 MaximumExpansionLevel = 0; + uint32 KioskSessionMinutes = 0; }; class MOTD final : public ServerPacket diff --git a/src/server/game/Server/Packets/TicketPackets.cpp b/src/server/game/Server/Packets/TicketPackets.cpp index 0b38d9e2df7..30c2f8a06a9 100644 --- a/src/server/game/Server/Packets/TicketPackets.cpp +++ b/src/server/game/Server/Packets/TicketPackets.cpp @@ -64,16 +64,16 @@ void WorldPackets::Ticket::GMTicketAcknowledgeSurvey::Read() _worldPacket >> CaseID; } -void WorldPackets::Ticket::SupportTicketSubmitBug::Read() +void WorldPackets::Ticket::SubmitUserFeedback::Read() { _worldPacket >> Header; - Note = _worldPacket.ReadString(_worldPacket.ReadBits(10)); -} - -void WorldPackets::Ticket::SupportTicketSubmitSuggestion::Read() -{ - _worldPacket >> Header; - Note = _worldPacket.ReadString(_worldPacket.ReadBits(10)); + uint32 noteLength = _worldPacket.ReadBits(24); + IsSuggestion = _worldPacket.ReadBit(); + if (noteLength) + { + Note = _worldPacket.ReadString(noteLength - 1); + _worldPacket.read_skip<char>(); // null terminator + } } WorldPackets::Ticket::SupportTicketSubmitComplaint::SupportTicketChatLine::SupportTicketChatLine(uint32 timestamp, std::string const& text) : diff --git a/src/server/game/Server/Packets/TicketPackets.h b/src/server/game/Server/Packets/TicketPackets.h index 344deabd972..4e7026c6c6e 100644 --- a/src/server/game/Server/Packets/TicketPackets.h +++ b/src/server/game/Server/Packets/TicketPackets.h @@ -92,26 +92,16 @@ namespace WorldPackets int32 CaseID; }; - class SupportTicketSubmitBug final : public ClientPacket + class SubmitUserFeedback final : public ClientPacket { public: - SupportTicketSubmitBug(WorldPacket&& packet) : ClientPacket(CMSG_SUPPORT_TICKET_SUBMIT_BUG, std::move(packet)) { } - - void Read() override; - - SupportTicketHeader Header; - std::string Note; - }; - - class SupportTicketSubmitSuggestion final : public ClientPacket - { - public: - SupportTicketSubmitSuggestion(WorldPacket&& packet) : ClientPacket(CMSG_SUPPORT_TICKET_SUBMIT_SUGGESTION, std::move(packet)) { } + SubmitUserFeedback(WorldPacket&& packet) : ClientPacket(CMSG_SUBMIT_USER_FEEDBACK, std::move(packet)) { } void Read() override; SupportTicketHeader Header; std::string Note; + bool IsSuggestion = false; }; class SupportTicketSubmitComplaint final : public ClientPacket diff --git a/src/server/game/Server/Packets/TransmogrificationPackets.cpp b/src/server/game/Server/Packets/TransmogrificationPackets.cpp index a36dac184a6..3ea86ae6106 100644 --- a/src/server/game/Server/Packets/TransmogrificationPackets.cpp +++ b/src/server/game/Server/Packets/TransmogrificationPackets.cpp @@ -22,6 +22,7 @@ ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Transmogrification::Trans data >> transmogItem.ItemModifiedAppearanceID; data >> transmogItem.Slot; data >> transmogItem.SpellItemEnchantmentID; + data >> transmogItem.SecondaryItemModifiedAppearanceID; return data; } diff --git a/src/server/game/Server/Packets/TransmogrificationPackets.h b/src/server/game/Server/Packets/TransmogrificationPackets.h index 09926a52e4f..2f1e22063fa 100644 --- a/src/server/game/Server/Packets/TransmogrificationPackets.h +++ b/src/server/game/Server/Packets/TransmogrificationPackets.h @@ -31,6 +31,7 @@ namespace WorldPackets int32 ItemModifiedAppearanceID = 0; uint32 Slot = 0; int32 SpellItemEnchantmentID = 0; + int32 SecondaryItemModifiedAppearanceID = 0; }; class TransmogrifyItems final : public ClientPacket diff --git a/src/server/game/Server/Packets/WardenPackets.h b/src/server/game/Server/Packets/WardenPackets.h index a8a13bea65e..d3160e33ab4 100644 --- a/src/server/game/Server/Packets/WardenPackets.h +++ b/src/server/game/Server/Packets/WardenPackets.h @@ -27,7 +27,7 @@ namespace WorldPackets class WardenData final : public ClientPacket { public: - WardenData(WorldPacket&& packet) : ClientPacket(CMSG_WARDEN_DATA, std::move(packet)) { } + WardenData(WorldPacket&& packet) : ClientPacket(CMSG_WARDEN3_DATA, std::move(packet)) { } void Read() override; |
