Core: cherry picked several packet changes from 11.0.7 which are also needed for 4.4.2

This commit is contained in:
Ovahlord
2025-04-05 12:12:58 +02:00
parent 1f7643db03
commit 8903b7d751
23 changed files with 176 additions and 68 deletions

View File

@@ -19,11 +19,11 @@
#include <array>
#include <cstring>
WorldPacketCrypt::WorldPacketCrypt() : _clientDecrypt(false), _serverEncrypt(true), _clientCounter(0), _serverCounter(0), _initialized(false)
WorldPacketCrypt::WorldPacketCrypt() : _clientDecrypt(false, 256), _serverEncrypt(true, 256), _clientCounter(0), _serverCounter(0), _initialized(false)
{
}
void WorldPacketCrypt::Init(Trinity::Crypto::AES::Key const& key)
void WorldPacketCrypt::Init(Key const& key)
{
_clientDecrypt.Init(key);
_serverEncrypt.Init(key);

View File

@@ -23,9 +23,11 @@
class TC_COMMON_API WorldPacketCrypt
{
public:
using Key = std::array<uint8, 32>;
WorldPacketCrypt();
void Init(Trinity::Crypto::AES::Key const& key);
void Init(Key const& key);
bool PeekDecryptRecv(uint8* data, size_t length);
bool DecryptRecv(uint8* data, size_t length, Trinity::Crypto::AES::Tag& tag);
bool EncryptSend(uint8* data, size_t length, Trinity::Crypto::AES::Tag& tag);

View File

@@ -15645,14 +15645,27 @@ void Player::SetQuestCompletedBit(uint32 questId, bool completed)
return;
uint32 fieldOffset = (questBit - 1) / QUESTS_COMPLETED_BITS_PER_BLOCK;
if (fieldOffset >= QUESTS_COMPLETED_BITS_SIZE)
return;
uint64 flag = UI64LIT(1) << ((questBit - 1) % QUESTS_COMPLETED_BITS_PER_BLOCK);
if (fieldOffset < QUESTS_COMPLETED_BITS_SIZE)
{
if (completed)
SetUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::QuestCompleted, fieldOffset), flag);
else
RemoveUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::QuestCompleted, fieldOffset), flag);
}
if (completed)
SetUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::QuestCompleted, fieldOffset), flag);
SetUpdateFieldFlagValue(m_values
.ModifyValue(&Player::m_activePlayerData)
.ModifyValue(&UF::ActivePlayerData::BitVectors)
.ModifyValue(&UF::BitVectors::Values, PLAYER_DATA_FLAG_CHARACTER_QUEST_COMPLETED_INDEX)
.ModifyValue(&UF::BitVector::Values, fieldOffset), flag);
else
RemoveUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::QuestCompleted, fieldOffset), flag);
RemoveUpdateFieldFlagValue(m_values
.ModifyValue(&Player::m_activePlayerData)
.ModifyValue(&UF::ActivePlayerData::BitVectors)
.ModifyValue(&UF::BitVectors::Values, PLAYER_DATA_FLAG_CHARACTER_QUEST_COMPLETED_INDEX)
.ModifyValue(&UF::BitVector::Values, fieldOffset), flag);
}
void Player::AreaExploredOrEventHappens(uint32 questId)

View File

@@ -143,6 +143,7 @@ enum PlayerDataFlagConstants
PLAYER_DATA_FLAG_ACCOUNT_COMBINED_QUESTS_INDEX = 6,
PLAYER_DATA_FLAG_ACCOUNT_COMBINED_QUEST_REWARDS_INDEX = 7,
PLAYER_DATA_FLAG_CHARACTER_CONTENTPUSH_INDEX = 8,
PLAYER_DATA_FLAG_CHARACTER_QUEST_COMPLETED_INDEX = 9,
};
enum SpellModType : uint8

View File

@@ -17,7 +17,7 @@
#include "Vignette.h"
#include "CellImpl.h"
#include "DB2Stores.h"
#include "DB2Structure.h"
#include "GridNotifiersImpl.h"
#include "VignettePackets.h"
@@ -35,6 +35,11 @@ void UpdatePosition(VignetteData& vignette, WorldObject const* owner)
}
}
void UpdateHealth(VignetteData& vignette, Unit const* owner)
{
vignette.HealthPercent = float(owner->GetHealth()) / float(owner->GetMaxHealth()); // converted to percentage in lua
}
template<WorldPackets::Vignette::VignetteDataSet WorldPackets::Vignette::VignetteUpdate::* Field>
void SendVignetteUpdate(VignetteData const& vignette, WorldObject const* owner)
{
@@ -70,6 +75,7 @@ void VignetteData::FillPacket(WorldPackets::Vignette::VignetteDataSet& dataSet)
data.ZoneID = ZoneID;
data.WMOGroupID = WMOGroupID;
data.WMODoodadPlacementID = WMODoodadPlacementID;
data.HealthPercent = HealthPercent;
}
std::unique_ptr<VignetteData> Create(VignetteEntry const* vignetteData, WorldObject const* owner)
@@ -81,6 +87,8 @@ std::unique_ptr<VignetteData> Create(VignetteEntry const* vignetteData, WorldObj
vignette->Data = vignetteData;
vignette->ZoneID = owner->GetZoneId(); // not updateable
UpdatePosition(*vignette, owner);
if (Unit const* unitOwner = owner->ToUnit())
UpdateHealth(*vignette, unitOwner);
if (vignetteData->IsInfiniteAOI())
owner->GetMap()->AddInfiniteAOIVignette(vignette.get());
@@ -93,6 +101,8 @@ std::unique_ptr<VignetteData> Create(VignetteEntry const* vignetteData, WorldObj
void Update(VignetteData& vignette, WorldObject const* owner)
{
UpdatePosition(vignette, owner);
if (Unit const* unitOwner = owner->ToUnit())
UpdateHealth(vignette, unitOwner);
if (vignette.Data->IsInfiniteAOI())
vignette.NeedUpdate = true;

View File

@@ -42,6 +42,7 @@ struct VignetteData
uint32 ZoneID = 0;
uint32 WMOGroupID = 0;
uint32 WMODoodadPlacementID = 0;
float HealthPercent = 1.0f;
bool NeedUpdate = false;
void FillPacket(WorldPackets::Vignette::VignetteDataSet& dataSet) const;

View File

@@ -346,12 +346,13 @@ void WorldPackets::Auth::EnterEncryptedMode::ShutdownEncryption()
EnterEncryptedModeSigner.reset();
}
std::array<uint8, 16> constexpr EnableEncryptionSeed = { 0x90, 0x9C, 0xD0, 0x50, 0x5A, 0x2C, 0x14, 0xDD, 0x5C, 0x2C, 0xC0, 0x64, 0x14, 0xF3, 0xFE, 0xC9 };
std::array<uint8, 32> constexpr EnableEncryptionSeed = { 0x66, 0xBE, 0x29, 0x79, 0xEF, 0xF2, 0xD5, 0xB5, 0x61, 0x53, 0xF6, 0x5F, 0x45, 0xAE, 0x81, 0xCB,
0x32, 0xEC, 0x94, 0xEC, 0x75, 0xB3, 0x5F, 0x44, 0x6A, 0x63, 0x43, 0x67, 0x17, 0x20, 0x44, 0x34 };
std::array<uint8, 16> constexpr EnableEncryptionContext = { 0xA7, 0x1F, 0xB6, 0x9B, 0xC9, 0x7C, 0xDD, 0x96, 0xE9, 0xBB, 0xB8, 0x21, 0x39, 0x8D, 0x5A, 0xD4 };
WorldPacket const* WorldPackets::Auth::EnterEncryptedMode::Write()
{
std::array<uint8, 32> toSign = Trinity::Crypto::HMAC_SHA256::GetDigestOf(EncryptionKey,
std::array<uint8, 64> toSign = Trinity::Crypto::HMAC_SHA512::GetDigestOf(EncryptionKey,
std::array<uint8, 1>{uint8(Enabled ? 1 : 0)},
EnableEncryptionSeed);

View File

@@ -69,7 +69,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
std::array<uint8, 16> Challenge = { };
std::array<uint8, 32> Challenge = { };
std::array<uint32, 8> DosChallenge = { };
uint8 DosZeroBits = 0;
};
@@ -88,7 +88,7 @@ namespace WorldPackets
uint32 RegionID = 0;
uint32 BattlegroupID = 0;
uint32 RealmID = 0;
std::array<uint8, 16> LocalChallenge;
std::array<uint8, 32> LocalChallenge;
std::array<uint8, DigestLength> Digest;
uint64 DosResponse = 0;
std::string RealmJoinTicket;
@@ -267,7 +267,7 @@ namespace WorldPackets
uint64 DosResponse = 0;
uint64 Key = 0;
std::array<uint8, 16> LocalChallenge;
std::array<uint8, 32> LocalChallenge;
std::array<uint8, DigestLength> Digest;
private:
@@ -300,14 +300,14 @@ namespace WorldPackets
static bool InitializeEncryption();
static void ShutdownEncryption();
EnterEncryptedMode(std::array<uint8, 16> const& encryptionKey, bool enabled) : ServerPacket(SMSG_ENTER_ENCRYPTED_MODE, 256 + 1),
EnterEncryptedMode(std::array<uint8, 32> const& encryptionKey, bool enabled) : ServerPacket(SMSG_ENTER_ENCRYPTED_MODE, 256 + 1),
EncryptionKey(encryptionKey), Enabled(enabled)
{
}
WorldPacket const* Write() override;
std::array<uint8, 16> const& EncryptionKey;
std::array<uint8, 32> const& EncryptionKey;
bool Enabled = false;
};
}

View File

@@ -67,6 +67,7 @@ WorldPacket const* WorldPackets::Channel::ChannelNotifyJoined::Write()
_worldPacket.WriteBits(_Channel.length(), 7);
_worldPacket.WriteBits(ChannelWelcomeMsg.length(), 11);
_worldPacket << uint32(_ChannelFlags);
_worldPacket << uint8(Unknown1107);
_worldPacket << int32(ChatChannelID);
_worldPacket << uint64(InstanceID);
_worldPacket << ChannelGUID;

View File

@@ -81,6 +81,7 @@ namespace WorldPackets
uint32 _ChannelFlags = 0; ///< @see enum ChannelFlags
std::string _Channel; ///< Channel Name
ObjectGuid ChannelGUID;
uint8 Unknown1107 = 0;
};
class ChannelNotifyLeft final : public ServerPacket

View File

@@ -612,6 +612,47 @@ WorldPacket const* LogoutResponse::Write()
return &_worldPacket;
}
ByteBuffer& operator<<(ByteBuffer& data, GameModeData const& gameModeData)
{
data << int32(gameModeData.Unknown_1107_0);
data << gameModeData.Guid;
data << uint8(gameModeData.GameMode);
data << int32(gameModeData.MapID);
data << uint8(gameModeData.Unknown_1107_1);
data << uint8(gameModeData.Unknown_1107_2);
data << uint8(gameModeData.Unknown_1107_3);
data << uint32(gameModeData.Customizations.size());
data << uint32(gameModeData.Unknown_1107_4.size());
for (ChrCustomizationChoice const& customization : gameModeData.Customizations)
data << customization;
for (ChrCustomizationChoice const& customization : gameModeData.Unknown_1107_4)
data << customization;
return data;
}
ByteBuffer& operator<<(ByteBuffer& data, SwitchGameModeData const& switchGameModeData)
{
data << Bits<1>(switchGameModeData.IsFastLogin);
data << switchGameModeData.Current;
data << switchGameModeData.New;
return data;
}
WorldPacket const* LogoutComplete::Write()
{
_worldPacket << OptionalInit(SwitchGameMode);
_worldPacket.FlushBits();
if (SwitchGameMode)
_worldPacket << *SwitchGameMode;
return &_worldPacket;
}
void LoadingScreenNotify::Read()
{
_worldPacket >> MapID;

View File

@@ -592,12 +592,34 @@ namespace WorldPackets
bool Instant = false;
};
struct GameModeData
{
int32 Unknown_1107_0 = 0;
ObjectGuid Guid;
uint8 GameMode = 0;
int32 MapID = 0;
uint8 Unknown_1107_1 = 0;
uint8 Unknown_1107_2 = 0;
uint8 Unknown_1107_3 = 0;
Array<ChrCustomizationChoice, 250> Customizations;
Array<ChrCustomizationChoice, 250> Unknown_1107_4;
};
struct SwitchGameModeData
{
bool IsFastLogin = false;
GameModeData Current;
GameModeData New;
};
class LogoutComplete final : public ServerPacket
{
public:
LogoutComplete() : ServerPacket(SMSG_LOGOUT_COMPLETE, 0) { }
LogoutComplete() : ServerPacket(SMSG_LOGOUT_COMPLETE, 1) { }
WorldPacket const* Write() override { return &_worldPacket; }
WorldPacket const* Write() override;
std::unique_ptr<SwitchGameModeData> SwitchGameMode;
};
class LogoutCancel final : public ClientPacket

View File

@@ -288,7 +288,7 @@ ByteBuffer& operator<<(ByteBuffer& data, LfgBootInfo const& lfgBootInfo)
data << Bits<1>(lfgBootInfo.VotePassed);
data << Bits<1>(lfgBootInfo.MyVoteCompleted);
data << Bits<1>(lfgBootInfo.MyVote);
data << SizedString::BitsSize<8>(lfgBootInfo.Reason);
data << SizedString::BitsSize<9>(lfgBootInfo.Reason);
data << lfgBootInfo.Target;
data << uint32(lfgBootInfo.TotalVotes);
data << uint32(lfgBootInfo.BootVotes);

View File

@@ -315,16 +315,13 @@ WorldPacket const* WorldPackets::Misc::Weather::Write()
void WorldPackets::Misc::StandStateChange::Read()
{
uint32 state;
_worldPacket >> state;
StandState = UnitStandStateType(state);
_worldPacket >> As<uint8>(StandState);
}
WorldPacket const* WorldPackets::Misc::StandStateUpdate::Write()
{
_worldPacket << uint32(AnimKitID);
_worldPacket << uint8(State);
_worldPacket << uint32(AnimKitID);
return &_worldPacket;
}
@@ -348,7 +345,7 @@ WorldPacket const* WorldPackets::Misc::PlayerBound::Write()
WorldPacket const* WorldPackets::Misc::StartMirrorTimer::Write()
{
_worldPacket << int32(Timer);
_worldPacket << uint8(Timer);
_worldPacket << int32(Value);
_worldPacket << int32(MaxValue);
_worldPacket << int32(Scale);
@@ -361,7 +358,7 @@ WorldPacket const* WorldPackets::Misc::StartMirrorTimer::Write()
WorldPacket const* WorldPackets::Misc::PauseMirrorTimer::Write()
{
_worldPacket << int32(Timer);
_worldPacket << uint8(Timer);
_worldPacket.WriteBit(Paused);
_worldPacket.FlushBits();
@@ -370,7 +367,7 @@ WorldPacket const* WorldPackets::Misc::PauseMirrorTimer::Write()
WorldPacket const* WorldPackets::Misc::StopMirrorTimer::Write()
{
_worldPacket << int32(Timer);
_worldPacket << uint8(Timer);
return &_worldPacket;
}

View File

@@ -445,15 +445,15 @@ namespace WorldPackets
class StartMirrorTimer final : public ServerPacket
{
public:
StartMirrorTimer() : ServerPacket(SMSG_START_MIRROR_TIMER, 21) { }
StartMirrorTimer(int32 timer, int32 value, int32 maxValue, int32 scale, int32 spellID, bool paused) :
ServerPacket(SMSG_START_MIRROR_TIMER, 21), Scale(scale), MaxValue(maxValue), Timer(timer), SpellID(spellID), Value(value), Paused(paused) { }
StartMirrorTimer() : ServerPacket(SMSG_START_MIRROR_TIMER, 1 + 4 + 4 + 4 + 4 + 1) { }
StartMirrorTimer(uint8 timer, int32 value, int32 maxValue, int32 scale, int32 spellID, bool paused) :
ServerPacket(SMSG_START_MIRROR_TIMER, 1 + 4 + 4 + 4 + 4 + 1), Timer(timer), Scale(scale), MaxValue(maxValue), SpellID(spellID), Value(value), Paused(paused) { }
WorldPacket const* Write() override;
uint8 Timer = 0;
int32 Scale = 0;
int32 MaxValue = 0;
int32 Timer = 0;
int32 SpellID = 0;
int32 Value = 0;
bool Paused = false;
@@ -462,24 +462,24 @@ namespace WorldPackets
class PauseMirrorTimer final : public ServerPacket
{
public:
PauseMirrorTimer() : ServerPacket(SMSG_PAUSE_MIRROR_TIMER, 5) { }
PauseMirrorTimer(int32 timer, bool paused) : ServerPacket(SMSG_PAUSE_MIRROR_TIMER, 5), Paused(paused), Timer(timer) { }
PauseMirrorTimer() : ServerPacket(SMSG_PAUSE_MIRROR_TIMER, 1 + 1) { }
PauseMirrorTimer(uint8 timer, bool paused) : ServerPacket(SMSG_PAUSE_MIRROR_TIMER, 1 + 1), Timer(timer), Paused(paused) { }
WorldPacket const* Write() override;
uint8 Timer = 0;
bool Paused = true;
int32 Timer = 0;
};
class StopMirrorTimer final : public ServerPacket
{
public:
StopMirrorTimer() : ServerPacket(SMSG_STOP_MIRROR_TIMER, 4) { }
StopMirrorTimer(int32 timer) : ServerPacket(SMSG_STOP_MIRROR_TIMER, 4), Timer(timer) { }
StopMirrorTimer() : ServerPacket(SMSG_STOP_MIRROR_TIMER, 1) { }
StopMirrorTimer(uint8 timer) : ServerPacket(SMSG_STOP_MIRROR_TIMER, 1), Timer(timer) { }
WorldPacket const* Write() override;
int32 Timer = 0;
uint8 Timer = 0;
};
class ExplorationExperience final : public ServerPacket

View File

@@ -23,7 +23,8 @@ WorldPacket const* WorldPackets::Pet::PetSpells::Write()
_worldPacket << uint16(_CreatureFamily);
_worldPacket << uint16(Specialization);
_worldPacket << uint32(TimeLimit);
_worldPacket << uint16(CommandState | (Flag << 16));
_worldPacket << uint8(CommandState);
_worldPacket << uint8(Flag);
_worldPacket << uint8(ReactState);
_worldPacket.append(ActionButtons.data(), ActionButtons.size());
_worldPacket << uint32(Actions.size());
@@ -205,7 +206,8 @@ WorldPacket const* WorldPackets::Pet::PetTameFailure::Write()
WorldPacket const* WorldPackets::Pet::PetMode::Write()
{
_worldPacket << PetGUID;
_worldPacket << uint16(CommandState | Flag << 8);
_worldPacket << uint8(CommandState);
_worldPacket << uint8(Flag);
_worldPacket << uint8(ReactState);
return &_worldPacket;

View File

@@ -44,11 +44,11 @@ ByteBuffer& operator<<(ByteBuffer& data, PetitionInfo const& petitionInfo)
data << int32(petitionInfo.StaticType);
data << uint32(petitionInfo.Muid);
data << SizedString::BitsSize<7>(petitionInfo.Title);
data << SizedString::BitsSize<8>(petitionInfo.Title);
data << SizedString::BitsSize<12>(petitionInfo.BodyText);
for (std::string const& choiceText : petitionInfo.Choicetext)
data << SizedString::BitsSize<6>(choiceText);
data << SizedString::BitsSize<7>(choiceText);
data.FlushBits();

View File

@@ -51,10 +51,14 @@ WorldPacket const* WorldPackets::Ticket::GMTicketCaseStatus::Write()
_worldPacket << SizedString::BitsSize<11>(c.Url);
_worldPacket << SizedString::BitsSize<10>(c.WaitTimeOverrideMessage);
_worldPacket << SizedCString::BitsSize<24>(c.Title);
_worldPacket << SizedCString::BitsSize<24>(c.Description);
_worldPacket.FlushBits();
_worldPacket << SizedString::Data(c.Url);
_worldPacket << SizedString::Data(c.WaitTimeOverrideMessage);
_worldPacket << SizedCString::Data(c.Title);
_worldPacket << SizedCString::Data(c.Description);
}
return &_worldPacket;

View File

@@ -74,6 +74,8 @@ namespace WorldPackets
int32 WaitTimeOverrideMinutes = 0;
std::string Url;
std::string WaitTimeOverrideMessage;
std::string Title;
std::string Description;
};
GMTicketCaseStatus() : ServerPacket(SMSG_GM_TICKET_CASE_STATUS, 12) { }

View File

@@ -27,6 +27,9 @@ ByteBuffer& operator<<(ByteBuffer& data, VignetteData const& vignetteData)
data << uint32(vignetteData.ZoneID);
data << uint32(vignetteData.WMOGroupID);
data << uint32(vignetteData.WMODoodadPlacementID);
data << float(vignetteData.HealthPercent);
data << uint16(vignetteData.RecommendedGroupSizeMin);
data << uint16(vignetteData.RecommendedGroupSizeMax);
return data;
}

View File

@@ -32,6 +32,9 @@ struct VignetteData
uint32 ZoneID = 0;
uint32 WMOGroupID = 0;
uint32 WMODoodadPlacementID = 0;
float HealthPercent = 1.0f;
uint16 RecommendedGroupSizeMin = 0;
uint16 RecommendedGroupSizeMax = 0;
};
struct VignetteDataSet

View File

@@ -53,10 +53,14 @@ std::string const WorldSocket::ServerConnectionInitialize("WORLD OF WARCRAFT CON
std::string const WorldSocket::ClientConnectionInitialize("WORLD OF WARCRAFT CONNECTION - CLIENT TO SERVER - V2");
uint32 const WorldSocket::MinSizeForCompression = 0x400;
uint8 const WorldSocket::AuthCheckSeed[16] = { 0xC5, 0xC6, 0x98, 0x95, 0x76, 0x3F, 0x1D, 0xCD, 0xB6, 0xA1, 0x37, 0x28, 0xB3, 0x12, 0xFF, 0x8A };
uint8 const WorldSocket::SessionKeySeed[16] = { 0x58, 0xCB, 0xCF, 0x40, 0xFE, 0x2E, 0xCE, 0xA6, 0x5A, 0x90, 0xB8, 0x01, 0x68, 0x6C, 0x28, 0x0B };
uint8 const WorldSocket::ContinuedSessionSeed[16] = { 0x16, 0xAD, 0x0C, 0xD4, 0x46, 0xF9, 0x4F, 0xB2, 0xEF, 0x7D, 0xEA, 0x2A, 0x17, 0x66, 0x4D, 0x2F };
uint8 const WorldSocket::EncryptionKeySeed[16] = { 0xE9, 0x75, 0x3C, 0x50, 0x90, 0x93, 0x61, 0xDA, 0x3B, 0x07, 0xEE, 0xFA, 0xFF, 0x9D, 0x41, 0xB8 };
std::array<uint8, 32> const WorldSocket::AuthCheckSeed = { 0xDE, 0x3A, 0x2A, 0x8E, 0x6B, 0x89, 0x52, 0x66, 0x88, 0x9D, 0x7E, 0x7A, 0x77, 0x1D, 0x5D, 0x1F,
0x4E, 0xD9, 0x0C, 0x23, 0x9B, 0xCD, 0x0E, 0xDC, 0xD2, 0xE8, 0x04, 0x3A, 0x68, 0x64, 0xC7, 0xB0 };
std::array<uint8, 32> const WorldSocket::SessionKeySeed = { 0xE8, 0x1E, 0x8B, 0x59, 0x27, 0x62, 0x1E, 0xAA, 0x86, 0x15, 0x18, 0xEA, 0xC0, 0xBF, 0x66, 0x8C,
0x6D, 0xBF, 0x83, 0x93, 0xBC, 0xAA, 0x80, 0x52, 0x5B, 0x1E, 0xDC, 0x23, 0xA0, 0x12, 0xB7, 0x50 };
std::array<uint8, 32> const WorldSocket::ContinuedSessionSeed = { 0x56, 0x5C, 0x61, 0x9C, 0x48, 0x3A, 0x52, 0x1F, 0x61, 0x5D, 0x05, 0x49, 0xB2, 0x9A, 0x39, 0xBF,
0x4B, 0x97, 0xB0, 0x1B, 0xF9, 0x6C, 0xDE, 0xD6, 0x80, 0x1D, 0xAB, 0x26, 0x02, 0xA9, 0x9B, 0x9D };
std::array<uint8, 32> const WorldSocket::EncryptionKeySeed = { 0x71, 0xC9, 0xED, 0x5A, 0xA7, 0x0E, 0x4D, 0xFF, 0x4C, 0x36, 0xA6, 0x5A, 0x3E, 0x46, 0x8A, 0x4A,
0x5D, 0xA1, 0x48, 0xC8, 0x30, 0x47, 0x4A, 0xDE, 0xF6, 0x0D, 0x6C, 0xBE, 0x6F, 0xE4, 0x55, 0x73 };
WorldSocket::WorldSocket(boost::asio::ip::tcp::socket&& socket) : Socket(std::move(socket)),
_type(CONNECTION_TYPE_REALM), _key(0), _serverChallenge(), _sessionKey(), _encryptKey(), _OverSpeedPings(0),
@@ -728,15 +732,15 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth::
// For hook purposes, we get Remoteaddress at this point.
std::string address = GetRemoteIpAddress().to_string();
Trinity::Crypto::SHA256 digestKeyHash;
Trinity::Crypto::SHA512 digestKeyHash;
digestKeyHash.UpdateData(account.Game.KeyData.data(), account.Game.KeyData.size());
digestKeyHash.UpdateData(clientBuildAuthKey->Key.data(), clientBuildAuthKey->Key.size());
digestKeyHash.Finalize();
Trinity::Crypto::HMAC_SHA256 hmac(digestKeyHash.GetDigest());
Trinity::Crypto::HMAC_SHA512 hmac(digestKeyHash.GetDigest());
hmac.UpdateData(authSession->LocalChallenge);
hmac.UpdateData(_serverChallenge);
hmac.UpdateData(AuthCheckSeed, 16);
hmac.UpdateData(AuthCheckSeed);
hmac.Finalize();
// Check that Key and account name are the same on client and server
@@ -748,27 +752,27 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth::
return;
}
Trinity::Crypto::SHA256 keyData;
Trinity::Crypto::SHA512 keyData;
keyData.UpdateData(account.Game.KeyData.data(), account.Game.KeyData.size());
keyData.Finalize();
Trinity::Crypto::HMAC_SHA256 sessionKeyHmac(keyData.GetDigest());
Trinity::Crypto::HMAC_SHA512 sessionKeyHmac(keyData.GetDigest());
sessionKeyHmac.UpdateData(_serverChallenge);
sessionKeyHmac.UpdateData(authSession->LocalChallenge);
sessionKeyHmac.UpdateData(SessionKeySeed, 16);
sessionKeyHmac.UpdateData(SessionKeySeed);
sessionKeyHmac.Finalize();
SessionKeyGenerator<Trinity::Crypto::SHA256> sessionKeyGenerator(sessionKeyHmac.GetDigest());
SessionKeyGenerator<Trinity::Crypto::SHA512> sessionKeyGenerator(sessionKeyHmac.GetDigest());
sessionKeyGenerator.Generate(_sessionKey.data(), 40);
Trinity::Crypto::HMAC_SHA256 encryptKeyGen(_sessionKey);
Trinity::Crypto::HMAC_SHA512 encryptKeyGen(_sessionKey);
encryptKeyGen.UpdateData(authSession->LocalChallenge);
encryptKeyGen.UpdateData(_serverChallenge);
encryptKeyGen.UpdateData(EncryptionKeySeed, 16);
encryptKeyGen.UpdateData(EncryptionKeySeed);
encryptKeyGen.Finalize();
// only first 16 bytes of the hmac are used
memcpy(_encryptKey.data(), encryptKeyGen.GetDigest().data(), 16);
// only first 32 bytes of the hmac are used
memcpy(_encryptKey.data(), encryptKeyGen.GetDigest().data(), 32);
LoginDatabasePreparedStatement* stmt = nullptr;
@@ -957,11 +961,11 @@ void WorldSocket::HandleAuthContinuedSessionCallback(std::shared_ptr<WorldPacket
std::string login = fields[0].GetString();
_sessionKey = fields[1].GetBinary<SESSION_KEY_LENGTH>();
Trinity::Crypto::HMAC_SHA256 hmac(_sessionKey);
Trinity::Crypto::HMAC_SHA512 hmac(_sessionKey);
hmac.UpdateData(reinterpret_cast<uint8 const*>(&authSession->Key), sizeof(authSession->Key));
hmac.UpdateData(authSession->LocalChallenge);
hmac.UpdateData(_serverChallenge);
hmac.UpdateData(ContinuedSessionSeed, 16);
hmac.UpdateData(ContinuedSessionSeed);
hmac.Finalize();
if (memcmp(hmac.GetDigest().data(), authSession->Digest.data(), authSession->Digest.size()))
@@ -971,14 +975,14 @@ void WorldSocket::HandleAuthContinuedSessionCallback(std::shared_ptr<WorldPacket
return;
}
Trinity::Crypto::HMAC_SHA256 encryptKeyGen(_sessionKey);
Trinity::Crypto::HMAC_SHA512 encryptKeyGen(_sessionKey);
encryptKeyGen.UpdateData(authSession->LocalChallenge);
encryptKeyGen.UpdateData(_serverChallenge);
encryptKeyGen.UpdateData(EncryptionKeySeed, 16);
encryptKeyGen.UpdateData(EncryptionKeySeed);
encryptKeyGen.Finalize();
// only first 16 bytes of the hmac are used
memcpy(_encryptKey.data(), encryptKeyGen.GetDigest().data(), 16);
// only first 32 bytes of the hmac are used
memcpy(_encryptKey.data(), encryptKeyGen.GetDigest().data(), 32);
SendPacketAndLogOpcode(*WorldPackets::Auth::EnterEncryptedMode(_encryptKey, true).Write());
AsyncRead();

View File

@@ -93,10 +93,10 @@ class TC_GAME_API WorldSocket : public Socket<WorldSocket>
static std::string const ClientConnectionInitialize;
static uint32 const MinSizeForCompression;
static uint8 const AuthCheckSeed[16];
static uint8 const SessionKeySeed[16];
static uint8 const ContinuedSessionSeed[16];
static uint8 const EncryptionKeySeed[16];
static std::array<uint8, 32> const AuthCheckSeed;
static std::array<uint8, 32> const SessionKeySeed;
static std::array<uint8, 32> const ContinuedSessionSeed;
static std::array<uint8, 32> const EncryptionKeySeed;
typedef Socket<WorldSocket> BaseSocket;
@@ -157,10 +157,10 @@ private:
ConnectionType _type;
uint64 _key;
std::array<uint8, 16> _serverChallenge;
std::array<uint8, 32> _serverChallenge;
WorldPacketCrypt _authCrypt;
SessionKey _sessionKey;
std::array<uint8, 16> _encryptKey;
std::array<uint8, 32> _encryptKey;
TimePoint _LastPingTime;
uint32 _OverSpeedPings;