diff options
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/Packets/AuthenticationPackets.cpp | 177 | ||||
-rw-r--r-- | src/server/game/Server/Packets/AuthenticationPackets.h | 94 | ||||
-rw-r--r-- | src/server/game/Server/Packets/CombatLogPackets.cpp | 66 | ||||
-rw-r--r-- | src/server/game/Server/Packets/CombatLogPackets.h | 44 | ||||
-rw-r--r-- | src/server/game/Server/Packets/CombatLogPacketsCommon.h | 9 | ||||
-rw-r--r-- | src/server/game/Server/Packets/InspectPackets.h | 7 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MiscPackets.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MovementPackets.cpp | 45 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MovementPackets.h | 72 | ||||
-rw-r--r-- | src/server/game/Server/Packets/PacketUtilities.h | 126 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SystemPackets.cpp | 85 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SystemPackets.h | 82 | ||||
-rw-r--r-- | src/server/shared/Packets/ByteBuffer.cpp | 1 | ||||
-rw-r--r-- | src/server/shared/Packets/ByteBuffer.h | 70 |
15 files changed, 482 insertions, 402 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 80ea5a2d1fe..2d640a0fd24 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -5542,7 +5542,7 @@ void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* info) data.SpellID = aura->GetId(); data.LogData.Initialize(this); - WorldPackets::CombatLog::SpellPeriodicAuraLog::SpellLogEffect spellLogEffect; + WorldPackets::CombatLog::PeriodicAuraLogEffect& spellLogEffect = data.Effects.emplace_back(); spellLogEffect.Effect = aura->GetAuraType(); spellLogEffect.Amount = info->damage; spellLogEffect.OriginalDamage = info->originalDamage; @@ -5558,8 +5558,6 @@ void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* info) if (contentTuningParams.GenerateDataForUnits(caster, this)) spellLogEffect.ContentTuning = contentTuningParams; - data.Effects.push_back(spellLogEffect); - SendCombatLogMessage(&data); } diff --git a/src/server/game/Server/Packets/AuthenticationPackets.cpp b/src/server/game/Server/Packets/AuthenticationPackets.cpp index 0dda7373312..1fee24274a1 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.cpp +++ b/src/server/game/Server/Packets/AuthenticationPackets.cpp @@ -86,110 +86,125 @@ void AuthSession::Read() } } -ByteBuffer& operator<<(ByteBuffer& data, AuthWaitInfo const& waitInfo) +ByteBuffer& operator<<(ByteBuffer& data, GameTime const& gameTime) { - data << uint32(waitInfo.WaitCount); - data << uint32(waitInfo.WaitTime); - data << uint8(waitInfo.AllowedFactionGroupForCharacterCreate); - data << WorldPackets::Bits<1>(waitInfo.HasFCM); - data << WorldPackets::Bits<1>(waitInfo.CanCreateOnlyIfExisting); + data << uint32(gameTime.BillingType); + data << uint32(gameTime.MinutesRemaining); + data << uint32(gameTime.RealBillingType); + data << Bits<1>(gameTime.IsInIGR); + data << Bits<1>(gameTime.IsPaidForByIGR); + data << Bits<1>(gameTime.IsCAISEnabled); data.FlushBits(); return data; } -WorldPacket const* AuthResponse::Write() +ByteBuffer& operator<<(ByteBuffer& data, BaseBuildKey const& buildKey) { - _worldPacket << uint32(Result); - _worldPacket << OptionalInit(SuccessInfo); - _worldPacket << OptionalInit(WaitInfo); - _worldPacket.FlushBits(); + for (std::size_t i = 0; i < 16; ++i) + { + data << buildKey.BuildKey[i]; + data << buildKey.ConfigKey[i]; + } - if (SuccessInfo) + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, AuthSuccessInfo const& successInfo) +{ + data << uint32(successInfo.VirtualRealmAddress); + data << Size<uint32>(successInfo.VirtualRealms); + data << uint32(successInfo.TimeRested); + data << uint8(successInfo.ActiveExpansionLevel); + data << uint8(successInfo.AccountExpansionLevel); + data << uint32(successInfo.TimeSecondsUntilPCKick); + data << Size<uint32>(*successInfo.AvailableClasses); + data << Size<uint32>(successInfo.Templates); + data << uint32(successInfo.CurrencyID); + data << successInfo.Time; + + for (RaceClassAvailability const& raceClassAvailability : *successInfo.AvailableClasses) { - _worldPacket << uint32(SuccessInfo->VirtualRealmAddress); - _worldPacket << Size<uint32>(SuccessInfo->VirtualRealms); - _worldPacket << uint32(SuccessInfo->TimeRested); - _worldPacket << uint8(SuccessInfo->ActiveExpansionLevel); - _worldPacket << uint8(SuccessInfo->AccountExpansionLevel); - _worldPacket << uint32(SuccessInfo->TimeSecondsUntilPCKick); - _worldPacket << Size<uint32>(*SuccessInfo->AvailableClasses); - _worldPacket << Size<uint32>(SuccessInfo->Templates); - _worldPacket << uint32(SuccessInfo->CurrencyID); - _worldPacket << SuccessInfo->Time; - - for (RaceClassAvailability const& raceClassAvailability : *SuccessInfo->AvailableClasses) + data << uint8(raceClassAvailability.RaceID); + data << Size<uint32>(raceClassAvailability.Classes); + + for (ClassAvailability const& classAvailability : raceClassAvailability.Classes) { - _worldPacket << uint8(raceClassAvailability.RaceID); - _worldPacket << Size<uint32>(raceClassAvailability.Classes); - - for (ClassAvailability const& classAvailability : raceClassAvailability.Classes) - { - _worldPacket << uint8(classAvailability.ClassID); - _worldPacket << uint8(classAvailability.ActiveExpansionLevel); - _worldPacket << uint8(classAvailability.AccountExpansionLevel); - _worldPacket << uint8(classAvailability.MinActiveExpansionLevel); - } + data << uint8(classAvailability.ClassID); + data << uint8(classAvailability.ActiveExpansionLevel); + data << uint8(classAvailability.AccountExpansionLevel); + data << uint8(classAvailability.MinActiveExpansionLevel); } + } - _worldPacket << Bits<1>(SuccessInfo->IsExpansionTrial); - _worldPacket << Bits<1>(SuccessInfo->ForceCharacterTemplate); - _worldPacket << OptionalInit(SuccessInfo->NumPlayersHorde); - _worldPacket << OptionalInit(SuccessInfo->NumPlayersAlliance); - _worldPacket << OptionalInit(SuccessInfo->ExpansionTrialExpiration); - _worldPacket << OptionalInit(SuccessInfo->NewBuildKeys); - _worldPacket.FlushBits(); + data << Bits<1>(successInfo.IsExpansionTrial); + data << Bits<1>(successInfo.ForceCharacterTemplate); + data << OptionalInit(successInfo.NumPlayersHorde); + data << OptionalInit(successInfo.NumPlayersAlliance); + data << OptionalInit(successInfo.ExpansionTrialExpiration); + data << OptionalInit(successInfo.CurrentBuild); + data.FlushBits(); - { - _worldPacket << uint32(SuccessInfo->GameTimeInfo.BillingType); - _worldPacket << uint32(SuccessInfo->GameTimeInfo.MinutesRemaining); - _worldPacket << uint32(SuccessInfo->GameTimeInfo.RealBillingType); - _worldPacket << Bits<1>(SuccessInfo->GameTimeInfo.IsInIGR); // 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 << Bits<1>(SuccessInfo->GameTimeInfo.IsPaidForByIGR); // inGameRoom lua return from Script_GetBillingPlan - _worldPacket << Bits<1>(SuccessInfo->GameTimeInfo.IsCAISEnabled); // not used anywhere in the client - _worldPacket.FlushBits(); - } + data << successInfo.GameTimeInfo; - if (SuccessInfo->NumPlayersHorde) - _worldPacket << uint16(*SuccessInfo->NumPlayersHorde); + if (successInfo.NumPlayersHorde) + data << uint16(*successInfo.NumPlayersHorde); - if (SuccessInfo->NumPlayersAlliance) - _worldPacket << uint16(*SuccessInfo->NumPlayersAlliance); + if (successInfo.NumPlayersAlliance) + data << uint16(*successInfo.NumPlayersAlliance); - if (SuccessInfo->ExpansionTrialExpiration) - _worldPacket << *SuccessInfo->ExpansionTrialExpiration; + if (successInfo.ExpansionTrialExpiration) + data << *successInfo.ExpansionTrialExpiration; - if (SuccessInfo->NewBuildKeys) - { - for (std::size_t i = 0; i < 16; ++i) - { - _worldPacket << SuccessInfo->NewBuildKeys->NewBuildKey[i]; - _worldPacket << SuccessInfo->NewBuildKeys->SomeKey[i]; - } - } + if (successInfo.CurrentBuild) + data << *successInfo.CurrentBuild; - for (VirtualRealmInfo const& virtualRealm : SuccessInfo->VirtualRealms) - _worldPacket << virtualRealm; + for (VirtualRealmInfo const& virtualRealm : successInfo.VirtualRealms) + data << virtualRealm; - for (CharacterTemplate const* characterTemplate : SuccessInfo->Templates) + for (CharacterTemplate const* characterTemplate : successInfo.Templates) + { + data << uint32(characterTemplate->TemplateSetId); + data << Size<uint32>(characterTemplate->Classes); + for (CharacterTemplateClass const& templateClass : characterTemplate->Classes) { - _worldPacket << uint32(characterTemplate->TemplateSetId); - _worldPacket << Size<uint32>(characterTemplate->Classes); - for (CharacterTemplateClass const& templateClass : characterTemplate->Classes) - { - _worldPacket << uint8(templateClass.ClassID); - _worldPacket << uint8(templateClass.FactionGroup); - } - - _worldPacket << SizedString::BitsSize<7>(characterTemplate->Name); - _worldPacket << SizedString::BitsSize<10>(characterTemplate->Description); - _worldPacket.FlushBits(); - - _worldPacket << SizedString::Data(characterTemplate->Name); - _worldPacket << SizedString::Data(characterTemplate->Description); + data << uint8(templateClass.ClassID); + data << uint8(templateClass.FactionGroup); } + + data << SizedString::BitsSize<7>(characterTemplate->Name); + data << SizedString::BitsSize<10>(characterTemplate->Description); + data.FlushBits(); + + data << SizedString::Data(characterTemplate->Name); + data << SizedString::Data(characterTemplate->Description); } + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, AuthWaitInfo const& waitInfo) +{ + data << uint32(waitInfo.WaitCount); + data << uint32(waitInfo.WaitTime); + data << uint8(waitInfo.AllowedFactionGroupForCharacterCreate); + data << WorldPackets::Bits<1>(waitInfo.HasFCM); + data << WorldPackets::Bits<1>(waitInfo.CanCreateOnlyIfExisting); + data.FlushBits(); + + return data; +} + +WorldPacket const* AuthResponse::Write() +{ + _worldPacket << uint32(Result); + _worldPacket << OptionalInit(SuccessInfo); + _worldPacket << OptionalInit(WaitInfo); + _worldPacket.FlushBits(); + + if (SuccessInfo) + _worldPacket << *SuccessInfo; + if (WaitInfo) _worldPacket << *WaitInfo; diff --git a/src/server/game/Server/Packets/AuthenticationPackets.h b/src/server/game/Server/Packets/AuthenticationPackets.h index 1f2f76091c3..e6a7a96f8ae 100644 --- a/src/server/game/Server/Packets/AuthenticationPackets.h +++ b/src/server/game/Server/Packets/AuthenticationPackets.h @@ -91,17 +91,13 @@ namespace WorldPackets public: static constexpr uint32 DigestLength = 24; - explicit AuthSession(WorldPacket&& packet) : EarlyProcessClientPacket(CMSG_AUTH_SESSION, std::move(packet)) - { - LocalChallenge.fill(0); - Digest.fill(0); - } + explicit AuthSession(WorldPacket&& packet) : EarlyProcessClientPacket(CMSG_AUTH_SESSION, std::move(packet)) { } uint32 RegionID = 0; uint32 BattlegroupID = 0; uint32 RealmID = 0; - std::array<uint8, 32> LocalChallenge; - std::array<uint8, DigestLength> Digest; + std::array<uint8, 32> LocalChallenge = { }; + std::array<uint8, DigestLength> Digest = { }; uint64 DosResponse = 0; std::string RealmJoinTicket; bool UseIPv6 = false; @@ -142,53 +138,51 @@ namespace WorldPackets VirtualRealmNameInfo RealmNameInfo; }; - class AuthResponse final : public ServerPacket + struct GameTime { - public: - struct AuthSuccessInfo - { - struct GameTime - { - uint32 BillingType = 0; - uint32 MinutesRemaining = 0; - uint32 RealBillingType = 0; - bool IsInIGR = false; - bool IsPaidForByIGR = false; - bool IsCAISEnabled = false; - }; - - struct NewBuild - { - std::array<uint8, 16> NewBuildKey = { }; - std::array<uint8, 16> SomeKey = { }; - }; + uint32 BillingType = 0; + uint32 MinutesRemaining = 0; + uint32 RealBillingType = 0; + bool IsInIGR = false; + bool IsPaidForByIGR = false; + bool IsCAISEnabled = false; + }; - AuthSuccessInfo() { } // work around clang bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101227 + struct BaseBuildKey + { + std::array<uint8, 16> BuildKey = { }; + std::array<uint8, 16> ConfigKey = { }; + }; - uint8 ActiveExpansionLevel = 0; ///< the current server expansion, the possible values are in @ref Expansions - uint8 AccountExpansionLevel = 0; ///< the current expansion of this account, the possible values are in @ref Expansions - uint32 TimeRested = 0; ///< affects the return value of the GetBillingTimeRested() client API call, it is the number of seconds you have left until the experience points and loot you receive from creatures and quests is reduced. It is only used in the Asia region in retail, it's not implemented in TC and will probably never be. + struct AuthSuccessInfo + { + uint8 ActiveExpansionLevel = 0; ///< the current server expansion, the possible values are in @ref Expansions + uint8 AccountExpansionLevel = 0; ///< the current expansion of this account, the possible values are in @ref Expansions + uint32 TimeRested = 0; ///< affects the return value of the GetBillingTimeRested() client API call, it is the number of seconds you have left until the experience points and loot you receive from creatures and quests is reduced. It is only used in the Asia region in retail, it's not implemented in TC and will probably never be. - uint32 VirtualRealmAddress = 0; ///< a special identifier made from the Index, BattleGroup and Region. - uint32 TimeSecondsUntilPCKick = 0; ///< @todo research - uint32 CurrencyID = 0; ///< this is probably used for the ingame shop. @todo implement - Timestamp<> Time; + uint32 VirtualRealmAddress = 0; ///< a special identifier made from the Index, BattleGroup and Region. + uint32 TimeSecondsUntilPCKick = 0; ///< @todo research + uint32 CurrencyID = 0; ///< this is probably used for the ingame shop. @todo implement + Timestamp<> Time; - GameTime GameTimeInfo; + 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. + 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. - std::vector<RaceClassAvailability> const* AvailableClasses = nullptr; ///< the minimum AccountExpansion required to select race/class combinations + std::vector<RaceClassAvailability> const* AvailableClasses = nullptr; ///< the minimum AccountExpansion required to select race/class combinations - bool IsExpansionTrial = false; - bool ForceCharacterTemplate = false; ///< forces the client to always use a character template when creating a new character. @see Templates. @todo implement - Optional<uint16> NumPlayersHorde; ///< number of horde players in this realm. @todo implement - Optional<uint16> NumPlayersAlliance; ///< number of alliance players in this realm. @todo implement - Optional<Timestamp<>> ExpansionTrialExpiration; ///< expansion trial expiration unix timestamp - Optional<NewBuild> NewBuildKeys; - }; + bool IsExpansionTrial = false; + bool ForceCharacterTemplate = false; ///< forces the client to always use a character template when creating a new character. @see Templates. @todo implement + Optional<uint16> NumPlayersHorde; ///< number of horde players in this realm. @todo implement + Optional<uint16> NumPlayersAlliance; ///< number of alliance players in this realm. @todo implement + Optional<Timestamp<>> ExpansionTrialExpiration; ///< expansion trial expiration unix timestamp + Optional<BaseBuildKey> CurrentBuild; + }; + class AuthResponse final : public ServerPacket + { + public: explicit AuthResponse() : ServerPacket(SMSG_AUTH_RESPONSE, 132) { } WorldPacket const* Write() override; @@ -274,16 +268,12 @@ namespace WorldPackets public: static constexpr uint32 DigestLength = 24; - explicit AuthContinuedSession(WorldPacket&& packet) : EarlyProcessClientPacket(CMSG_AUTH_CONTINUED_SESSION, std::move(packet)) - { - LocalChallenge.fill(0); - Digest.fill(0); - } + explicit AuthContinuedSession(WorldPacket&& packet) : EarlyProcessClientPacket(CMSG_AUTH_CONTINUED_SESSION, std::move(packet)) { } uint64 DosResponse = 0; uint64 Key = 0; - std::array<uint8, 32> LocalChallenge; - std::array<uint8, DigestLength> Digest; + std::array<uint8, 32> LocalChallenge = { }; + std::array<uint8, DigestLength> Digest = { }; private: friend EarlyProcessClientPacket; diff --git a/src/server/game/Server/Packets/CombatLogPackets.cpp b/src/server/game/Server/Packets/CombatLogPackets.cpp index 408d8029311..4baec163035 100644 --- a/src/server/game/Server/Packets/CombatLogPackets.cpp +++ b/src/server/game/Server/Packets/CombatLogPackets.cpp @@ -191,6 +191,42 @@ WorldPacket const* SpellHealLog::Write() return &_worldPacket; } +ByteBuffer& operator<<(ByteBuffer& data, PeriodicalAuraLogEffectDebugInfo const& debugInfo) +{ + data << float(debugInfo.CritRollMade); + data << float(debugInfo.CritRollNeeded); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, PeriodicAuraLogEffect const& effect) +{ + data << int32(effect.Effect); + data << int32(effect.Amount); + data << int32(effect.OriginalDamage); + data << int32(effect.OverHealOrKill); + data << int32(effect.SchoolMaskOrPower); + data << int32(effect.AbsorbedOrAmplitude); + data << int32(effect.Resisted); + data << Size<uint32>(effect.Supporters); + + for (Spells::SpellSupportInfo const& supportInfo : effect.Supporters) + data << supportInfo; + + data << Bits<1>(effect.Crit); + data << OptionalInit(effect.DebugInfo); + data << OptionalInit(effect.ContentTuning); + data.FlushBits(); + + if (effect.ContentTuning) + data << *effect.ContentTuning; + + if (effect.DebugInfo) + data << *effect.DebugInfo; + + return data; +} + WorldPacket const* SpellPeriodicAuraLog::Write() { *this << TargetGUID; @@ -200,34 +236,8 @@ WorldPacket const* SpellPeriodicAuraLog::Write() WriteLogDataBit(); FlushBits(); - for (SpellLogEffect const& effect : Effects) - { - *this << int32(effect.Effect); - *this << int32(effect.Amount); - *this << int32(effect.OriginalDamage); - *this << int32(effect.OverHealOrKill); - *this << int32(effect.SchoolMaskOrPower); - *this << int32(effect.AbsorbedOrAmplitude); - *this << int32(effect.Resisted); - *this << Size<uint32>(effect.Supporters); - - for (Spells::SpellSupportInfo const& supportInfo : effect.Supporters) - *this << supportInfo; - - *this << Bits<1>(effect.Crit); - *this << OptionalInit(effect.DebugInfo); - *this << OptionalInit(effect.ContentTuning); - FlushBits(); - - if (effect.ContentTuning) - *this << *effect.ContentTuning; - - if (effect.DebugInfo) - { - *this << float(effect.DebugInfo->CritRollMade); - *this << float(effect.DebugInfo->CritRollNeeded); - } - } + for (PeriodicAuraLogEffect const& effect : Effects) + *this << effect; WriteLogData(); diff --git a/src/server/game/Server/Packets/CombatLogPackets.h b/src/server/game/Server/Packets/CombatLogPackets.h index 303cd14ae00..7b94d4a9223 100644 --- a/src/server/game/Server/Packets/CombatLogPackets.h +++ b/src/server/game/Server/Packets/CombatLogPackets.h @@ -108,30 +108,30 @@ namespace WorldPackets std::vector<Spells::SpellSupportInfo> Supporters; }; + struct PeriodicalAuraLogEffectDebugInfo + { + float CritRollMade = 0.0f; + float CritRollNeeded = 0.0f; + }; + + struct PeriodicAuraLogEffect + { + int32 Effect = 0; + int32 Amount = 0; + int32 OriginalDamage = 0; + int32 OverHealOrKill = 0; + int32 SchoolMaskOrPower = 0; + int32 AbsorbedOrAmplitude = 0; + int32 Resisted = 0; + bool Crit = false; + Optional<PeriodicalAuraLogEffectDebugInfo> DebugInfo; + Optional<Spells::ContentTuningParams> ContentTuning; + std::vector<Spells::SpellSupportInfo> Supporters; + }; + class SpellPeriodicAuraLog final : public CombatLogServerPacket { public: - struct PeriodicalAuraLogEffectDebugInfo - { - float CritRollMade = 0.0f; - float CritRollNeeded = 0.0f; - }; - - struct SpellLogEffect - { - int32 Effect = 0; - int32 Amount = 0; - int32 OriginalDamage = 0; - int32 OverHealOrKill = 0; - int32 SchoolMaskOrPower = 0; - int32 AbsorbedOrAmplitude = 0; - int32 Resisted = 0; - bool Crit = false; - Optional<PeriodicalAuraLogEffectDebugInfo> DebugInfo; - Optional<Spells::ContentTuningParams> ContentTuning; - std::vector<Spells::SpellSupportInfo> Supporters; - }; - explicit SpellPeriodicAuraLog() : CombatLogServerPacket(SMSG_SPELL_PERIODIC_AURA_LOG, 16 + 16 + 4 + 4 + 1) { } WorldPacket const* Write() override; @@ -139,7 +139,7 @@ namespace WorldPackets ObjectGuid TargetGUID; ObjectGuid CasterGUID; int32 SpellID = 0; - std::vector<SpellLogEffect> Effects; + std::vector<PeriodicAuraLogEffect> Effects; }; class SpellInterruptLog final : public ServerPacket diff --git a/src/server/game/Server/Packets/CombatLogPacketsCommon.h b/src/server/game/Server/Packets/CombatLogPacketsCommon.h index 69b0c031470..cc9294dfe4f 100644 --- a/src/server/game/Server/Packets/CombatLogPacketsCommon.h +++ b/src/server/game/Server/Packets/CombatLogPacketsCommon.h @@ -120,7 +120,14 @@ namespace WorldPackets Spells::SpellCastLogData LogData; protected: - template <typename T> + template <ByteBufferNumeric T> + void operator<<(T val) + { + _worldPacket << val; + _fullLogPacket << val; + } + + template <typename T> requires (!ByteBufferNumeric<T>) void operator<<(T const& val) { _worldPacket << val; diff --git a/src/server/game/Server/Packets/InspectPackets.h b/src/server/game/Server/Packets/InspectPackets.h index a57d0c5c612..bd8c0703129 100644 --- a/src/server/game/Server/Packets/InspectPackets.h +++ b/src/server/game/Server/Packets/InspectPackets.h @@ -128,17 +128,14 @@ namespace WorldPackets class InspectResult final : public ServerPacket { public: - explicit InspectResult() : ServerPacket(SMSG_INSPECT_RESULT, 4096) - { - PvpTalents.fill(0); - } + explicit InspectResult() : ServerPacket(SMSG_INSPECT_RESULT, 4096) { } WorldPacket const* Write() override; PlayerModelDisplayInfo DisplayInfo; std::vector<uint16> Glyphs; std::vector<uint16> Talents; - std::array<uint16, MAX_PVP_TALENT_SLOTS> PvpTalents; + std::array<uint16, MAX_PVP_TALENT_SLOTS> PvpTalents = { }; Optional<InspectGuildData> GuildData; std::array<PVPBracketData, 9> Bracket; Optional<int32> AzeriteLevel; diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index 29a1a7ed5ae..c641abdb94f 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -575,7 +575,7 @@ WorldPacket const* LoadCUFProfiles::Write() // Bool Options for (uint8 option = 0; option < CUF_BOOL_OPTIONS_COUNT; option++) - _worldPacket << Bits<1>(cufProfile->BoolOptions[option]); + _worldPacket.WriteBit(cufProfile->BoolOptions[option]); // Other Options _worldPacket << uint16(cufProfile->FrameHeight); diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index 443c458339e..d706d273667 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -1095,7 +1095,33 @@ WorldPacket const* ResumeToken::Write() return &_worldPacket; } -ByteBuffer& operator<<(ByteBuffer& data, MoveSetCompoundState::MoveStateChange const& stateChange) +ByteBuffer& operator<<(ByteBuffer& data, CollisionHeightInfo const& collisionHeightInfo) +{ + data << float(collisionHeightInfo.Height); + data << float(collisionHeightInfo.Scale); + data << uint8(collisionHeightInfo.Reason); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, StateChangeRangeInfo const& stateChangeRangeInfo) +{ + data << float(stateChangeRangeInfo.Min); + data << float(stateChangeRangeInfo.Max); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, KnockBackInfo const& knockBackInfo) +{ + data << float(knockBackInfo.HorzSpeed); + data << knockBackInfo.Direction; + data << float(knockBackInfo.InitVertSpeed); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, MoveStateChange const& stateChange) { data << uint32(stateChange.MessageID); data << uint32(stateChange.SequenceIndex); @@ -1118,27 +1144,16 @@ ByteBuffer& operator<<(ByteBuffer& data, MoveSetCompoundState::MoveStateChange c data << float(*stateChange.Speed); if (stateChange.Range) - { - data << float(stateChange.Range->Min); - data << float(stateChange.Range->Max); - } + data << *stateChange.Range; if (stateChange.KnockBack) - { - data << float(stateChange.KnockBack->HorzSpeed); - data << stateChange.KnockBack->Direction; - data << float(stateChange.KnockBack->InitVertSpeed); - } + data << *stateChange.KnockBack; 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); - } + data << *stateChange.CollisionHeight; if (stateChange.MovementForceGUID) data << *stateChange.MovementForceGUID; diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index cbfba392381..71a51a5b9b4 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -691,47 +691,47 @@ namespace WorldPackets uint32 Reason = 1; }; - class MoveSetCompoundState final : public ServerPacket + struct CollisionHeightInfo { - public: - struct CollisionHeightInfo - { - float Height = 0.0f; - float Scale = 0.0f; - UpdateCollisionHeightReason Reason = UpdateCollisionHeightReason::Scale; - }; + float Height = 0.0f; + float Scale = 0.0f; + UpdateCollisionHeightReason Reason = UpdateCollisionHeightReason::Scale; + }; - struct KnockBackInfo - { - float HorzSpeed = 0.0f; - TaggedPosition<Position::XY> Direction; - float InitVertSpeed = 0.0f; - }; + struct StateChangeRangeInfo + { + float Min = 0.0f; + float Max = 0.0f; + }; - struct StateChangeRangeInfo - { - float Min = 0.0f; - float Max = 0.0f; - }; + struct KnockBackInfo + { + float HorzSpeed = 0.0f; + TaggedPosition<Position::XY> Direction; + float InitVertSpeed = 0.0f; + }; - struct MoveStateChange - { - MoveStateChange(OpcodeServer messageId, uint32 sequenceIndex) : MessageID(messageId), SequenceIndex(sequenceIndex) { } - - uint32 MessageID = 0; - uint32 SequenceIndex = 0; - Optional<float> Speed; - Optional<StateChangeRangeInfo> Range; - Optional<KnockBackInfo> KnockBack; - Optional<int32> VehicleRecID; - Optional<CollisionHeightInfo> CollisionHeight; - Optional<MovementForce> MovementForce_; - Optional<ObjectGuid> MovementForceGUID; - Optional<int32> MovementInertiaID; - Optional<uint32> MovementInertiaLifetimeMs; - Optional<int32> DriveCapabilityRecID; - }; + struct MoveStateChange + { + MoveStateChange(OpcodeServer messageId, uint32 sequenceIndex) : MessageID(messageId), SequenceIndex(sequenceIndex) { } + uint32 MessageID = 0; + uint32 SequenceIndex = 0; + Optional<float> Speed; + Optional<StateChangeRangeInfo> Range; + Optional<KnockBackInfo> KnockBack; + Optional<int32> VehicleRecID; + Optional<CollisionHeightInfo> CollisionHeight; + Optional<MovementForce> MovementForce_; + Optional<ObjectGuid> MovementForceGUID; + Optional<int32> MovementInertiaID; + Optional<uint32> MovementInertiaLifetimeMs; + Optional<int32> DriveCapabilityRecID; + }; + + class MoveSetCompoundState final : public ServerPacket + { + public: explicit MoveSetCompoundState() : ServerPacket(SMSG_MOVE_SET_COMPOUND_STATE, 4 + 1) { } WorldPacket const* Write() override; diff --git a/src/server/game/Server/Packets/PacketUtilities.h b/src/server/game/Server/Packets/PacketUtilities.h index 2917d2d8d25..c7b859ecd65 100644 --- a/src/server/game/Server/Packets/PacketUtilities.h +++ b/src/server/game/Server/Packets/PacketUtilities.h @@ -345,19 +345,26 @@ namespace WorldPackets ChronoDuration _value = ChronoDuration::zero(); }; - template<typename Underlying, typename T> + template<typename T> + concept AsWritable = std::is_default_constructible_v<T> && HasByteBufferShiftOperators<T>; + + template<typename T, typename Underlying> + concept AsWritableFor = requires { static_cast<Underlying>(std::declval<T>()); } + && requires { static_cast<T>(Underlying()); }; + + template<AsWritable Underlying, AsWritableFor<Underlying> T> struct AsWriter { T const& Value; friend inline ByteBuffer& operator<<(ByteBuffer& data, AsWriter const& opt) { - data << Underlying(opt.Value); + data << static_cast<Underlying>(opt.Value); return data; } }; - template<typename Underlying, typename T> + template<AsWritable Underlying, AsWritableFor<Underlying> T> struct AsReaderWriter : AsWriter<Underlying, T> { friend inline ByteBuffer& operator>>(ByteBuffer& data, AsReaderWriter const& opt) @@ -369,13 +376,16 @@ namespace WorldPackets } }; - template<typename Underlying, typename T> + template<AsWritable Underlying, AsWritableFor<Underlying> T> inline AsWriter<Underlying, T> As(T const& value) { return { value }; } - template<typename Underlying, typename T> + template<AsWritable Underlying, AsWritableFor<Underlying> T> inline AsReaderWriter<Underlying, T> As(T& value) { return { value }; } template<typename T> + concept OptionalWritable = std::is_default_constructible_v<T>; + + template<OptionalWritable T> struct OptionalInitWriter { Optional<T> const& Opt; @@ -387,7 +397,7 @@ namespace WorldPackets } }; - template<typename T> + template<OptionalWritable T> struct OptionalInitReaderWriter : OptionalInitWriter<T> { friend inline ByteBuffer& operator>>(ByteBuffer& data, OptionalInitReaderWriter const& opt) @@ -398,13 +408,13 @@ namespace WorldPackets } }; - template<typename T> + template<OptionalWritable T> inline OptionalInitWriter<T> OptionalInit(Optional<T> const& value) { return { value }; } - template<typename T> + template<OptionalWritable T> inline OptionalInitReaderWriter<T> OptionalInit(Optional<T>& value) { return { value }; } - template<typename T> + template<OptionalWritable T> struct PtrInitWriter { std::unique_ptr<T> const& Ptr; @@ -416,7 +426,7 @@ namespace WorldPackets } }; - template<typename T> + template<OptionalWritable T> struct PtrInitReaderWriter : PtrInitWriter<T> { friend inline ByteBuffer& operator>>(ByteBuffer& data, PtrInitReaderWriter const& opt) @@ -427,41 +437,62 @@ namespace WorldPackets } }; - template<typename T> + template<OptionalWritable T> inline PtrInitWriter<T> OptionalInit(std::unique_ptr<T> const& value) { return { value }; } - template<typename T> + template<OptionalWritable T> inline PtrInitReaderWriter<T> OptionalInit(std::unique_ptr<T>& value) { return { value }; } - template<uint32 BitCount, typename T> + template<typename T> + concept BitsWritable = AsWritableFor<T, uint32>; + + template<uint32 BitCount, BitsWritable T> struct BitsWriter { T const& Value; friend inline ByteBuffer& operator<<(ByteBuffer& data, BitsWriter const& bits) { - data.WriteBits(static_cast<uint32>(bits.Value), BitCount); + if constexpr (BitCount != 1) + data.WriteBits(static_cast<uint32>(bits.Value), BitCount); + else + data.WriteBit(static_cast<uint32>(bits.Value) != 0); + return data; } }; - template<uint32 BitCount, typename T> + template<uint32 BitCount, BitsWritable T> struct BitsReaderWriter : BitsWriter<BitCount, T> { friend inline ByteBuffer& operator>>(ByteBuffer& data, BitsReaderWriter const& bits) { - const_cast<T&>(bits.Value) = static_cast<T>(data.ReadBits(BitCount)); + if constexpr (BitCount != 1) + const_cast<T&>(bits.Value) = static_cast<T>(data.ReadBits(BitCount)); + else + const_cast<T&>(bits.Value) = static_cast<T>(data.ReadBit() ? 1 : 0); + return data; } }; - template<uint32 BitCount, typename T> + template<uint32 BitCount, BitsWritable T> inline BitsWriter<BitCount, T> Bits(T const& value) { return { value }; } - template<uint32 BitCount, typename T> + template<uint32 BitCount, BitsWritable T> inline BitsReaderWriter<BitCount, T> Bits(T& value) { return { value }; } - template<typename Underlying, typename Container> + template<typename T, typename SizeType> + concept ContainerWritable = requires(T const& container) { { container.size() } -> AsWritableFor<SizeType>; } + && !std::same_as<T, std::string_view> + && !std::same_as<T, std::string>; + + template<typename T, typename SizeType> + concept ContainerReadable = ContainerWritable<T, SizeType> + && !std::is_const_v<T> + && requires(T & container) { container.resize(SizeType{}); }; + + template<AsWritable Underlying, ContainerWritable<Underlying> Container> struct SizeWriter { Container const& Value; @@ -473,7 +504,7 @@ namespace WorldPackets } }; - template<typename Underlying, typename Container> + template<AsWritable Underlying, ContainerReadable<Underlying> Container> struct SizeReaderWriter : SizeWriter<Underlying, Container> { friend inline ByteBuffer& operator>>(ByteBuffer& data, SizeReaderWriter const& size) @@ -485,13 +516,13 @@ namespace WorldPackets } }; - template<typename Underlying, typename Container> + template<AsWritable Underlying, ContainerWritable<Underlying> Container> inline SizeWriter<Underlying, Container> Size(Container const& value) { return { value }; } - template<typename Underlying, typename Container> + template<AsWritable Underlying, ContainerReadable<Underlying> Container> inline SizeReaderWriter<Underlying, Container> Size(Container& value) { return { value }; } - template<uint32 BitCount, typename Container> + template<uint32 BitCount, ContainerWritable<uint32> Container> struct BitsSizeWriter { Container const& Value; @@ -503,7 +534,7 @@ namespace WorldPackets } }; - template<uint32 BitCount, typename Container> + template<uint32 BitCount, ContainerReadable<uint32> Container> struct BitsSizeReaderWriter : BitsSizeWriter<BitCount, Container> { friend inline ByteBuffer& operator>>(ByteBuffer& data, BitsSizeReaderWriter const& bits) @@ -513,15 +544,26 @@ namespace WorldPackets } }; - template<uint32 BitCount, typename Container> + template<uint32 BitCount, ContainerWritable<uint32> Container> inline BitsSizeWriter<BitCount, Container> BitsSize(Container const& value) { return { value }; } - template<uint32 BitCount, typename Container> + template<uint32 BitCount, ContainerReadable<uint32> Container> inline BitsSizeReaderWriter<BitCount, Container> BitsSize(Container& value) { return { value }; } + template<typename T> + concept StringWritable = requires(T const& container) { { container.length() } -> AsWritableFor<uint32>; } + && requires(ByteBuffer& data, T const& string) { data.WriteString(static_cast<std::string_view>(string)); /*TODO: Kill String class and remove the cast*/ }; + + template<typename T> + concept StringReadable = StringWritable<T> + && !std::is_const_v<T> + && !std::same_as<T, std::string_view> + && requires(T& container) { container.resize(uint32()); } + && requires(ByteBuffer& data, T& string) { string = data.ReadString(uint32(), bool()); }; + namespace SizedString { - template<uint32 BitCount, typename Container> + template<uint32 BitCount, StringWritable Container> struct SizeWriter { Container const& Value; @@ -533,7 +575,7 @@ namespace WorldPackets } }; - template<uint32 BitCount, typename Container> + template<uint32 BitCount, StringReadable Container> struct SizeReaderWriter : SizeWriter<BitCount, Container> { friend inline ByteBuffer& operator>>(ByteBuffer& data, SizeReaderWriter const& bits) @@ -543,13 +585,13 @@ namespace WorldPackets } }; - template<uint32 BitCount, typename Container> + template<uint32 BitCount, StringWritable Container> inline SizeWriter<BitCount, Container> BitsSize(Container const& value) { return { value }; } - template<uint32 BitCount, typename Container> + template<uint32 BitCount, StringReadable Container> inline SizeReaderWriter<BitCount, Container> BitsSize(Container& value) { return { value }; } - template<typename Container> + template<StringWritable Container> struct DataWriter { Container const& Value; @@ -561,7 +603,7 @@ namespace WorldPackets } }; - template<typename Container, Strings::Utf8Mode Mode> + template<StringReadable Container, Strings::Utf8Mode Mode> struct DataReaderWriter : DataWriter<Container> { static constexpr bool IsUtf8() { return Mode == Strings::ValidUtf8; } @@ -573,17 +615,17 @@ namespace WorldPackets } }; - template<Strings::Utf8Mode = Strings::ValidUtf8, typename Container> + template<Strings::Utf8Mode = Strings::ValidUtf8, StringWritable Container> inline DataWriter<Container> Data(Container const& value) { return { value }; } - template<Strings::Utf8Mode Mode = Strings::ValidUtf8, typename Container> + template<Strings::Utf8Mode Mode = Strings::ValidUtf8, StringReadable Container> inline DataReaderWriter<Container, Mode> Data(Container& value) { return { value }; } } // SizedCString (sends size + string + null terminator but only if not empty) namespace SizedCString { - template<uint32 BitCount, typename Container> + template<uint32 BitCount, StringWritable Container> struct SizeWriter { Container const& Value; @@ -595,7 +637,7 @@ namespace WorldPackets } }; - template<uint32 BitCount, typename Container> + template<uint32 BitCount, StringReadable Container> struct SizeReaderWriter : SizeWriter<BitCount, Container> { friend inline ByteBuffer& operator>>(ByteBuffer& data, SizeReaderWriter const& bits) @@ -606,13 +648,13 @@ namespace WorldPackets } }; - template<uint32 BitCount, typename Container> + template<uint32 BitCount, StringWritable Container> inline SizeWriter<BitCount, Container> BitsSize(Container const& value) { return { value }; } - template<uint32 BitCount, typename Container> + template<uint32 BitCount, StringReadable Container> inline SizeReaderWriter<BitCount, Container> BitsSize(Container& value) { return { value }; } - template<typename Container> + template<StringWritable Container> struct DataWriter { Container const& Value; @@ -628,7 +670,7 @@ namespace WorldPackets } }; - template<typename Container, Strings::Utf8Mode Mode> + template<StringReadable Container, Strings::Utf8Mode Mode> struct DataReaderWriter : DataWriter<Container> { static constexpr bool IsUtf8() { return Mode == Strings::ValidUtf8; } @@ -644,10 +686,10 @@ namespace WorldPackets } }; - template<Strings::Utf8Mode = Strings::ValidUtf8, typename Container> + template<Strings::Utf8Mode = Strings::ValidUtf8, StringWritable Container> inline DataWriter<Container> Data(Container const& value) { return { value }; } - template<Strings::Utf8Mode Mode = Strings::ValidUtf8, typename Container> + template<Strings::Utf8Mode Mode = Strings::ValidUtf8, StringReadable Container> inline DataReaderWriter<Container, Mode> Data(Container& value) { return { value }; } } } diff --git a/src/server/game/Server/Packets/SystemPackets.cpp b/src/server/game/Server/Packets/SystemPackets.cpp index 0afe471b740..651ce1ae4cd 100644 --- a/src/server/game/Server/Packets/SystemPackets.cpp +++ b/src/server/game/Server/Packets/SystemPackets.cpp @@ -19,6 +19,44 @@ namespace WorldPackets::System { +ByteBuffer& operator<<(ByteBuffer& data, SocialQueueConfig const& socialQueueConfig) +{ + data << Bits<1>(socialQueueConfig.ToastsDisabled); + data << float(socialQueueConfig.ToastDuration); + data << float(socialQueueConfig.DelayDuration); + data << float(socialQueueConfig.QueueMultiplier); + data << float(socialQueueConfig.PlayerMultiplier); + data << float(socialQueueConfig.PlayerFriendValue); + data << float(socialQueueConfig.PlayerGuildValue); + data << float(socialQueueConfig.ThrottleInitialThreshold); + data << float(socialQueueConfig.ThrottleDecayTime); + data << float(socialQueueConfig.ThrottlePrioritySpike); + data << float(socialQueueConfig.ThrottleMinThreshold); + data << float(socialQueueConfig.ThrottlePvPPriorityNormal); + data << float(socialQueueConfig.ThrottlePvPPriorityLow); + data << float(socialQueueConfig.ThrottlePvPHonorThreshold); + data << float(socialQueueConfig.ThrottleLfgListPriorityDefault); + data << float(socialQueueConfig.ThrottleLfgListPriorityAbove); + data << float(socialQueueConfig.ThrottleLfgListPriorityBelow); + data << float(socialQueueConfig.ThrottleLfgListIlvlScalingAbove); + data << float(socialQueueConfig.ThrottleLfgListIlvlScalingBelow); + data << float(socialQueueConfig.ThrottleRfPriorityAbove); + data << float(socialQueueConfig.ThrottleRfIlvlScalingAbove); + data << float(socialQueueConfig.ThrottleDfMaxItemLevel); + data << float(socialQueueConfig.ThrottleDfBestPriority); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, SessionAlertConfig const& sessionAlert) +{ + data << int32(sessionAlert.Delay); + data << int32(sessionAlert.Period); + data << int32(sessionAlert.DisplayTime); + + return data; +} + ByteBuffer& operator<<(ByteBuffer& data, SavedThrottleObjectState const& throttleState) { data << uint32(throttleState.MaxTries); @@ -41,6 +79,15 @@ ByteBuffer& operator<<(ByteBuffer& data, EuropaTicketConfig const& europaTicketS return data; } +ByteBuffer& operator<<(ByteBuffer& data, SquelchInfo const& squelch) +{ + data << Bits<1>(squelch.IsSquelched); + data << squelch.BnetAccountGuid; + data << squelch.GuildGuid; + + return data; +} + ByteBuffer& operator<<(ByteBuffer& data, GameRuleValuePair const& gameRuleValue) { data << int32(gameRuleValue.Rule); @@ -167,46 +214,14 @@ WorldPacket const* FeatureSystemStatus::Write() _worldPacket.FlushBits(); - { - _worldPacket << Bits<1>(QuickJoinConfig.ToastsDisabled); - _worldPacket << float(QuickJoinConfig.ToastDuration); - _worldPacket << float(QuickJoinConfig.DelayDuration); - _worldPacket << float(QuickJoinConfig.QueueMultiplier); - _worldPacket << float(QuickJoinConfig.PlayerMultiplier); - _worldPacket << float(QuickJoinConfig.PlayerFriendValue); - _worldPacket << float(QuickJoinConfig.PlayerGuildValue); - _worldPacket << float(QuickJoinConfig.ThrottleInitialThreshold); - _worldPacket << float(QuickJoinConfig.ThrottleDecayTime); - _worldPacket << float(QuickJoinConfig.ThrottlePrioritySpike); - _worldPacket << float(QuickJoinConfig.ThrottleMinThreshold); - _worldPacket << float(QuickJoinConfig.ThrottlePvPPriorityNormal); - _worldPacket << float(QuickJoinConfig.ThrottlePvPPriorityLow); - _worldPacket << float(QuickJoinConfig.ThrottlePvPHonorThreshold); - _worldPacket << float(QuickJoinConfig.ThrottleLfgListPriorityDefault); - _worldPacket << float(QuickJoinConfig.ThrottleLfgListPriorityAbove); - _worldPacket << float(QuickJoinConfig.ThrottleLfgListPriorityBelow); - _worldPacket << float(QuickJoinConfig.ThrottleLfgListIlvlScalingAbove); - _worldPacket << float(QuickJoinConfig.ThrottleLfgListIlvlScalingBelow); - _worldPacket << float(QuickJoinConfig.ThrottleRfPriorityAbove); - _worldPacket << float(QuickJoinConfig.ThrottleRfIlvlScalingAbove); - _worldPacket << float(QuickJoinConfig.ThrottleDfMaxItemLevel); - _worldPacket << float(QuickJoinConfig.ThrottleDfBestPriority); - } + _worldPacket << QuickJoinConfig; if (SessionAlert) - { - _worldPacket << int32(SessionAlert->Delay); - _worldPacket << int32(SessionAlert->Period); - _worldPacket << int32(SessionAlert->DisplayTime); - } + _worldPacket << *SessionAlert; _worldPacket << SizedString::Data(Unknown1027); - { - _worldPacket << Bits<1>(Squelch.IsSquelched); - _worldPacket << Squelch.BnetAccountGuid; - _worldPacket << Squelch.GuildGuid; - } + _worldPacket << Squelch; if (EuropaTicketSystemStatus) _worldPacket << *EuropaTicketSystemStatus; diff --git a/src/server/game/Server/Packets/SystemPackets.h b/src/server/game/Server/Packets/SystemPackets.h index 1d17c83ab6d..42d40c4cf60 100644 --- a/src/server/game/Server/Packets/SystemPackets.h +++ b/src/server/game/Server/Packets/SystemPackets.h @@ -27,6 +27,40 @@ namespace WorldPackets { namespace System { + struct SocialQueueConfig + { + bool ToastsDisabled = false; + float ToastDuration = 0.0f; + float DelayDuration = 0.0f; + float QueueMultiplier = 0.0f; + float PlayerMultiplier = 0.0f; + float PlayerFriendValue = 0.0f; + float PlayerGuildValue = 0.0f; + float ThrottleInitialThreshold = 0.0f; + float ThrottleDecayTime = 0.0f; + float ThrottlePrioritySpike = 0.0f; + float ThrottleMinThreshold = 0.0f; + float ThrottlePvPPriorityNormal = 0.0f; + float ThrottlePvPPriorityLow = 0.0f; + float ThrottlePvPHonorThreshold = 0.0f; + float ThrottleLfgListPriorityDefault = 0.0f; + float ThrottleLfgListPriorityAbove = 0.0f; + float ThrottleLfgListPriorityBelow = 0.0f; + float ThrottleLfgListIlvlScalingAbove = 0.0f; + float ThrottleLfgListIlvlScalingBelow = 0.0f; + float ThrottleRfPriorityAbove = 0.0f; + float ThrottleRfIlvlScalingAbove = 0.0f; + float ThrottleDfMaxItemLevel = 0.0f; + float ThrottleDfBestPriority = 0.0f; + }; + + struct SessionAlertConfig + { + int32 Delay = 0; + int32 Period = 0; + int32 DisplayTime = 0; + }; + struct SavedThrottleObjectState { uint32 MaxTries = 0; @@ -45,6 +79,13 @@ namespace WorldPackets SavedThrottleObjectState ThrottleState; }; + struct SquelchInfo + { + bool IsSquelched = false; + ObjectGuid BnetAccountGuid; + ObjectGuid GuildGuid; + }; + struct GameRuleValuePair { int32 Rule = 0; @@ -55,47 +96,6 @@ namespace WorldPackets class FeatureSystemStatus final : public ServerPacket { public: - struct SessionAlertConfig - { - int32 Delay = 0; - int32 Period = 0; - int32 DisplayTime = 0; - }; - - struct SocialQueueConfig - { - bool ToastsDisabled = false; - float ToastDuration = 0.0f; - float DelayDuration = 0.0f; - float QueueMultiplier = 0.0f; - float PlayerMultiplier = 0.0f; - float PlayerFriendValue = 0.0f; - float PlayerGuildValue = 0.0f; - float ThrottleInitialThreshold = 0.0f; - float ThrottleDecayTime = 0.0f; - float ThrottlePrioritySpike = 0.0f; - float ThrottleMinThreshold = 0.0f; - float ThrottlePvPPriorityNormal = 0.0f; - float ThrottlePvPPriorityLow = 0.0f; - float ThrottlePvPHonorThreshold = 0.0f; - float ThrottleLfgListPriorityDefault = 0.0f; - float ThrottleLfgListPriorityAbove = 0.0f; - float ThrottleLfgListPriorityBelow = 0.0f; - float ThrottleLfgListIlvlScalingAbove = 0.0f; - float ThrottleLfgListIlvlScalingBelow = 0.0f; - float ThrottleRfPriorityAbove = 0.0f; - float ThrottleRfIlvlScalingAbove = 0.0f; - float ThrottleDfMaxItemLevel = 0.0f; - float ThrottleDfBestPriority = 0.0f; - }; - - struct SquelchInfo - { - bool IsSquelched = false; - ObjectGuid BnetAccountGuid; - ObjectGuid GuildGuid; - }; - struct RafSystemFeatureInfo { bool Enabled = false; diff --git a/src/server/shared/Packets/ByteBuffer.cpp b/src/server/shared/Packets/ByteBuffer.cpp index c8980a93fe4..f5d6a5ab4b5 100644 --- a/src/server/shared/Packets/ByteBuffer.cpp +++ b/src/server/shared/Packets/ByteBuffer.cpp @@ -198,6 +198,7 @@ void ByteBuffer::OnInvalidPosition(size_t pos, size_t valueSize) const throw ByteBufferPositionException(pos, _storage.size(), valueSize); } +template TC_SHARED_API char ByteBuffer::read<char>(); template TC_SHARED_API uint8 ByteBuffer::read<uint8>(); template TC_SHARED_API uint16 ByteBuffer::read<uint16>(); template TC_SHARED_API uint32 ByteBuffer::read<uint32>(); diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 94c22206aa0..df6fc935a58 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -18,8 +18,9 @@ #ifndef TRINITYCORE_BYTE_BUFFER_H #define TRINITYCORE_BYTE_BUFFER_H -#include "Define.h" #include "ByteConverter.h" +#include "Concepts.h" +#include "Define.h" #include <array> #include <string> #include <vector> @@ -50,6 +51,14 @@ public: ByteBufferInvalidValueException(char const* type, std::string_view value); }; +template <typename T> +concept ByteBufferNumeric = std::same_as<T, int8> || std::same_as<T, uint8> + || std::same_as<T, int16> || std::same_as<T, uint16> + || std::same_as<T, int32> || std::same_as<T, uint32> + || std::same_as<T, int64> || std::same_as<T, uint64> + || std::same_as<T, float> || std::same_as<T, double> + || std::same_as<T, char> || std::is_enum_v<T>; + class TC_SHARED_API ByteBuffer { public: @@ -117,10 +126,9 @@ class TC_SHARED_API ByteBuffer _storage.clear(); } - template <typename T> + template <ByteBufferNumeric T> void append(T value) { - static_assert(std::is_trivially_copyable_v<T>, "append(T) must be used with trivially copyable types"); EndianConvert(value); append(reinterpret_cast<uint8 const*>(&value), sizeof(value)); } @@ -248,10 +256,9 @@ class TC_SHARED_API ByteBuffer return value; } - template <typename T> + template <ByteBufferNumeric T> void put(std::size_t pos, T value) { - static_assert(std::is_trivially_copyable_v<T>, "put(size_t, T) must be used with trivially copyable types"); EndianConvert(value); put(pos, reinterpret_cast<uint8 const*>(&value), sizeof(value)); } @@ -469,7 +476,7 @@ class TC_SHARED_API ByteBuffer return _wpos * 8 + 8 - _bitpos; } - template <typename T> + template <ByteBufferNumeric T> void read_skip() { read_skip(sizeof(T)); } void read_skip(size_t skip) @@ -481,7 +488,7 @@ class TC_SHARED_API ByteBuffer _rpos += skip; } - template <typename T> + template <ByteBufferNumeric T> T read() { ResetBitPos(); @@ -490,7 +497,7 @@ class TC_SHARED_API ByteBuffer return r; } - template <typename T> + template <ByteBufferNumeric T> T read(size_t pos) const { if (pos + sizeof(T) > _storage.size()) @@ -502,7 +509,7 @@ class TC_SHARED_API ByteBuffer return val; } - template <typename T> + template <ByteBufferNumeric T> void read(T* dest, size_t count) { static_assert(std::is_trivially_copyable_v<T>, "read(T*, size_t) must be used with trivially copyable types"); @@ -523,8 +530,8 @@ class TC_SHARED_API ByteBuffer _rpos += len; } - template <size_t Size> - void read(std::array<uint8, Size>& arr) + template <ByteBufferNumeric T, size_t Size> + void read(std::array<T, Size>& arr) { read(arr.data(), Size); } @@ -549,6 +556,8 @@ class TC_SHARED_API ByteBuffer append(str, len); } + void ReadSkipCString(bool requireValidUtf8 = true) { (void)ReadCString(requireValidUtf8); } + std::string_view ReadCString(bool requireValidUtf8 = true); std::string_view ReadString(uint32 length, bool requireValidUtf8 = true); @@ -563,12 +572,12 @@ class TC_SHARED_API ByteBuffer { _storage.resize(newsize, 0); _rpos = 0; - _wpos = size(); + _wpos = _storage.size(); } void reserve(size_t ressize) { - if (ressize > size()) + if (ressize > _storage.size()) _storage.reserve(ressize); } @@ -577,7 +586,7 @@ class TC_SHARED_API ByteBuffer _storage.shrink_to_fit(); } - template <typename T> + template <ByteBufferNumeric T> void append(T const* src, size_t cnt) { #if TRINITY_ENDIAN == TRINITY_LITTLEENDIAN @@ -596,8 +605,8 @@ class TC_SHARED_API ByteBuffer append(buffer.data(), buffer.size()); } - template <size_t Size> - void append(std::array<uint8, Size> const& arr) + template <ByteBufferNumeric T, std::size_t Size> + void append(std::array<T, Size> const& arr) { append(arr.data(), Size); } @@ -619,30 +628,7 @@ class TC_SHARED_API ByteBuffer std::vector<uint8> _storage; }; -template <> -inline std::string ByteBuffer::read<std::string>() -{ - return std::string(ReadCString()); -} - -template <> -inline void ByteBuffer::read_skip<char*>() -{ - (void)ReadCString(); -} - -template <> -inline void ByteBuffer::read_skip<char const*>() -{ - read_skip<char*>(); -} - -template <> -inline void ByteBuffer::read_skip<std::string>() -{ - read_skip<char*>(); -} - +extern template char ByteBuffer::read<char>(); extern template uint8 ByteBuffer::read<uint8>(); extern template uint16 ByteBuffer::read<uint16>(); extern template uint32 ByteBuffer::read<uint32>(); @@ -654,4 +640,8 @@ extern template int64 ByteBuffer::read<int64>(); extern template float ByteBuffer::read<float>(); extern template double ByteBuffer::read<double>(); +template <typename T> +concept HasByteBufferShiftOperators = requires(ByteBuffer& data, T const& value) { { data << value } -> std::convertible_to<ByteBuffer&>; } + && requires(ByteBuffer& data, T& value) { { data >> value } -> std::convertible_to<ByteBuffer&>; }; + #endif |