├── .gitignore ├── Crypto ├── ARC4.cpp ├── ARC4.hpp ├── BigNumber.cpp ├── BigNumber.hpp ├── SHA1.cpp ├── SHA1.hpp ├── SRP6.cpp ├── SRP6.hpp ├── WardenKeyGenerator.cpp ├── WardenKeyGenerator.hpp ├── WoWCrypt.cpp └── WoWCrypt.hpp ├── LICENSE ├── Logon ├── LogonEnums.hpp ├── LogonManager.cpp ├── LogonManager.hpp ├── LogonOpcodes.hpp └── LogonPackets.hpp ├── Network ├── ByteBuffer.cpp ├── ByteBuffer.hpp ├── ByteBuffer.inl ├── TCPClient.cpp └── TCPClient.hpp ├── Utils ├── UtilsEndian.hpp ├── UtilsString.cpp └── UtilsString.hpp └── World ├── Entities ├── WorldEObject.cpp ├── WorldEObject.hpp ├── WorldEUnit.cpp ├── WorldEUnit.hpp └── WorldEUpdateFields.hpp ├── Enums └── WorldEnums.hpp ├── Handlers ├── WorldHAuth.cpp ├── WorldHAuth.hpp ├── WorldHCharacters.cpp ├── WorldHCharacters.hpp ├── WorldHChat.cpp ├── WorldHChat.hpp ├── WorldHRPC.cpp ├── WorldHRPC.hpp ├── WorldHWarden.cpp └── WorldHWarden.hpp ├── Network ├── WorldHeaders.hpp ├── WorldOpcodes.cpp ├── WorldOpcodes.hpp ├── WorldPacket.cpp ├── WorldPacket.hpp ├── WorldSocket.cpp └── WorldSocket.hpp ├── Warden ├── WorldWardenStructs.hpp ├── WorldWardenUtils.cpp └── WorldWardenUtils.hpp ├── WorldManager.cpp └── WorldManager.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | *.smod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | -------------------------------------------------------------------------------- /Crypto/ARC4.cpp: -------------------------------------------------------------------------------- 1 | #include "ARC4.hpp" 2 | #include 3 | 4 | namespace RCN { namespace Crypto { 5 | 6 | /// Constructor 7 | /// @p_Key : Panama cypher key 8 | ARC4::ARC4(BigNumber p_Key) 9 | { 10 | m_Context = new EVP_CIPHER_CTX(); 11 | 12 | EVP_CIPHER_CTX_init(reinterpret_cast(m_Context)); 13 | EVP_EncryptInit_ex(reinterpret_cast(m_Context), EVP_rc4(), NULL, NULL, NULL); 14 | EVP_CIPHER_CTX_set_key_length(reinterpret_cast(m_Context), p_Key.GetNumBytes()); 15 | EVP_EncryptInit_ex(reinterpret_cast(m_Context), NULL, NULL, p_Key.AsByteArray(), NULL); 16 | } 17 | /// Destructor 18 | ARC4::~ARC4() 19 | { 20 | EVP_CIPHER_CTX_cleanup(reinterpret_cast(m_Context)); 21 | 22 | delete m_Context; 23 | } 24 | 25 | ////////////////////////////////////////////////////////////////////////// 26 | ////////////////////////////////////////////////////////////////////////// 27 | 28 | /// Update 29 | /// @p_Data : input data 30 | /// @p_Size : input data len 31 | void ARC4::UpdateData(uint8_t* p_Data, int p_Size) 32 | { 33 | int l_OutLen = 0; 34 | EVP_EncryptUpdate(reinterpret_cast(m_Context), p_Data, &l_OutLen, p_Data, p_Size); 35 | EVP_EncryptFinal_ex(reinterpret_cast(m_Context), p_Data, &l_OutLen); 36 | } 37 | 38 | } ///< namespace Crypto 39 | } ///< namespace RCN -------------------------------------------------------------------------------- /Crypto/ARC4.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "BigNumber.hpp" 4 | #include 5 | #include 6 | 7 | namespace RCN { namespace Crypto { 8 | 9 | class ARC4 10 | { 11 | public: 12 | /// Constructor 13 | /// @p_Key : Panama cypher key 14 | ARC4(BigNumber p_Key); 15 | /// Destructor 16 | ~ARC4(); 17 | 18 | /// Update 19 | /// @p_Data : input data 20 | /// @p_Size : input data len 21 | void UpdateData(uint8_t* p_Data, int p_Size); 22 | 23 | private: 24 | void * m_Context; ///< ARC4 context 25 | 26 | }; 27 | 28 | } ///< namespace Crypto 29 | } ///< namespace RCN -------------------------------------------------------------------------------- /Crypto/BigNumber.cpp: -------------------------------------------------------------------------------- 1 | #include "BigNumber.hpp" 2 | #include 3 | #include 4 | 5 | namespace RCN { namespace Crypto { 6 | 7 | /// Constructor 8 | BigNumber::BigNumber() 9 | { 10 | m_BN = BN_new(); 11 | m_Array = NULL; 12 | } 13 | /// Constructor 14 | /// @p_BN : Copy 15 | BigNumber::BigNumber(const BigNumber& p_BN) 16 | { 17 | m_BN = BN_dup(p_BN.m_BN); 18 | m_Array = NULL; 19 | } 20 | /// Constructor 21 | /// @p_Value : Copy 22 | BigNumber::BigNumber(uint32_t p_Value) 23 | { 24 | m_BN = BN_new(); 25 | BN_set_word(m_BN, p_Value); 26 | m_Array = NULL; 27 | } 28 | /// Destructor 29 | BigNumber::~BigNumber() 30 | { 31 | BN_free(m_BN); 32 | 33 | if (m_Array) 34 | delete[] m_Array; 35 | } 36 | 37 | ////////////////////////////////////////////////////////////////////////// 38 | ////////////////////////////////////////////////////////////////////////// 39 | 40 | /// Set value 41 | /// @p_Value : New value 42 | void BigNumber::SetDword(uint32_t p_Value) 43 | { 44 | BN_set_word(m_BN, p_Value); 45 | } 46 | /// Set value 47 | /// @p_Value : New value 48 | void BigNumber::SetQword(uint64_t p_Value) 49 | { 50 | BN_add_word(m_BN, (uint32_t)(p_Value >> 32)); 51 | BN_lshift(m_BN, m_BN, 32); 52 | BN_add_word(m_BN, (uint32_t)(p_Value & 0xFFFFFFFF)); 53 | } 54 | /// Set value 55 | /// @p_Value : New value 56 | /// @p_Size : New value size 57 | void BigNumber::SetBinary(const uint8_t* p_Value, size_t p_Size) 58 | { 59 | uint8_t l_Buffer[1000]; 60 | for (int l_I = 0; l_I < p_Size; ++l_I) 61 | l_Buffer[l_I] = p_Value[p_Size - 1 - l_I]; 62 | 63 | BN_bin2bn(l_Buffer, p_Size, m_BN); 64 | } 65 | /// Set value 66 | /// @p_Value : New value 67 | void BigNumber::SetHexStr(const char* p_Value) 68 | { 69 | BN_hex2bn(&m_BN, p_Value); 70 | } 71 | 72 | ////////////////////////////////////////////////////////////////////////// 73 | ////////////////////////////////////////////////////////////////////////// 74 | 75 | /// Set rand value 76 | /// @p_NumBits : Num bits 77 | void BigNumber::SetRand(int p_NumBits) 78 | { 79 | BN_rand(m_BN, p_NumBits, 0, 1); 80 | } 81 | 82 | ////////////////////////////////////////////////////////////////////////// 83 | ////////////////////////////////////////////////////////////////////////// 84 | 85 | /// Operator 86 | /// @p_Other : Operand right value 87 | BigNumber BigNumber::operator=(const BigNumber& p_Other) 88 | { 89 | BN_copy(m_BN, p_Other.m_BN); 90 | return *this; 91 | } 92 | /// Operator 93 | /// @p_Other : Operand right value 94 | BigNumber BigNumber::operator+=(const BigNumber& p_Other) 95 | { 96 | BN_add(m_BN, m_BN, p_Other.m_BN); 97 | return *this; 98 | } 99 | /// Operator 100 | /// @p_Other : Operand right value 101 | BigNumber BigNumber::operator+(const BigNumber& p_Other) 102 | { 103 | BigNumber l_Temp(*this); 104 | return l_Temp += p_Other; 105 | } 106 | /// Operator 107 | /// @p_Other : Operand right value 108 | BigNumber BigNumber::operator-=(const BigNumber& p_Other) 109 | { 110 | BN_sub(m_BN, m_BN, p_Other.m_BN); 111 | return *this; 112 | } 113 | /// Operator 114 | /// @p_Other : Operand right value 115 | BigNumber BigNumber::operator-(const BigNumber& p_Other) 116 | { 117 | BigNumber l_Temp(*this); 118 | return l_Temp -= p_Other; 119 | } 120 | /// Operator 121 | /// @p_Other : Operand right value 122 | BigNumber BigNumber::operator*=(const BigNumber& p_Other) 123 | { 124 | BN_CTX* l_Context; 125 | 126 | l_Context = BN_CTX_new(); 127 | BN_mul(m_BN, m_BN, p_Other.m_BN, l_Context); 128 | BN_CTX_free(l_Context); 129 | 130 | return *this; 131 | } 132 | /// Operator 133 | /// @p_Other : Operand right value 134 | BigNumber BigNumber::operator*(const BigNumber& p_Other) 135 | { 136 | BigNumber l_Temp(*this); 137 | return l_Temp *= p_Other; 138 | } 139 | /// Operator 140 | /// @p_Other : Operand right value 141 | BigNumber BigNumber::operator/=(const BigNumber& p_Other) 142 | { 143 | BN_CTX* l_Context; 144 | 145 | l_Context = BN_CTX_new(); 146 | BN_div(m_BN, NULL, m_BN, p_Other.m_BN, l_Context); 147 | BN_CTX_free(l_Context); 148 | 149 | return *this; 150 | } 151 | /// Operator 152 | /// @p_Other : Operand right value 153 | BigNumber BigNumber::operator/(const BigNumber& p_Other) 154 | { 155 | BigNumber l_Temp(*this); 156 | return l_Temp /= p_Other; 157 | } 158 | /// Operator 159 | /// @p_Other : Operand right value 160 | BigNumber BigNumber::operator%=(const BigNumber& p_Other) 161 | { 162 | BN_CTX* l_Context; 163 | 164 | l_Context = BN_CTX_new(); 165 | BN_mod(m_BN, m_BN, p_Other.m_BN, l_Context); 166 | BN_CTX_free(l_Context); 167 | 168 | return *this; 169 | } 170 | /// Operator 171 | /// @p_Other : Operand right value 172 | BigNumber BigNumber::operator%(const BigNumber& p_Other) 173 | { 174 | BigNumber l_Temp(*this); 175 | return l_Temp %= p_Other; 176 | } 177 | 178 | ////////////////////////////////////////////////////////////////////////// 179 | ////////////////////////////////////////////////////////////////////////// 180 | 181 | /// Is zero 182 | bool BigNumber::IsZero() const 183 | { 184 | return BN_is_zero(m_BN) != 0; 185 | } 186 | 187 | ////////////////////////////////////////////////////////////////////////// 188 | ////////////////////////////////////////////////////////////////////////// 189 | 190 | /// Mod exp 191 | /// @p_OtherA : A 192 | /// @p_OtherB : B 193 | BigNumber BigNumber::ModExp(const BigNumber& p_OtherA, const BigNumber& p_OtherB) 194 | { 195 | BigNumber l_Result; 196 | BN_CTX* l_Context; 197 | 198 | l_Context = BN_CTX_new(); 199 | BN_mod_exp(l_Result.m_BN, m_BN, p_OtherA.m_BN, p_OtherB.m_BN, l_Context); 200 | BN_CTX_free(l_Context); 201 | 202 | return l_Result; 203 | } 204 | /// Exp 205 | /// @p_Other : Other 206 | BigNumber BigNumber::Exp(const BigNumber& p_Other) 207 | { 208 | BigNumber l_Result; 209 | BN_CTX* l_Context; 210 | 211 | l_Context = BN_CTX_new(); 212 | BN_exp(l_Result.m_BN, m_BN, p_Other.m_BN, l_Context); 213 | BN_CTX_free(l_Context); 214 | 215 | return l_Result; 216 | } 217 | 218 | ////////////////////////////////////////////////////////////////////////// 219 | ////////////////////////////////////////////////////////////////////////// 220 | 221 | /// Get num bytes 222 | int BigNumber::GetNumBytes() 223 | { 224 | return BN_num_bytes(m_BN); 225 | } 226 | 227 | ////////////////////////////////////////////////////////////////////////// 228 | ////////////////////////////////////////////////////////////////////////// 229 | 230 | /// Get as uint32 231 | uint32_t BigNumber::AsDword() 232 | { 233 | return (uint32_t)BN_get_word(m_BN); 234 | } 235 | 236 | ////////////////////////////////////////////////////////////////////////// 237 | ////////////////////////////////////////////////////////////////////////// 238 | 239 | /// As byte array 240 | /// @p_MinSize : Min size 241 | uint8_t* BigNumber::AsByteArray(int p_MinSize) 242 | { 243 | int l_Size = (p_MinSize >= GetNumBytes()) ? p_MinSize : GetNumBytes(); 244 | 245 | delete[] m_Array; 246 | m_Array = new uint8_t[l_Size]; 247 | 248 | /// If we need more bytes than length of BigNumber set the rest to 0 249 | if (l_Size > GetNumBytes()) 250 | memset((void*)m_Array, 0, l_Size); 251 | 252 | BN_bn2bin(m_BN, (unsigned char*)m_Array); 253 | 254 | std::reverse(m_Array, m_Array + l_Size); 255 | 256 | return m_Array; 257 | } 258 | /// As byte array 259 | /// @p_MinSize : Min size 260 | /// @p_Reverse : Reverse array 261 | uint8_t* BigNumber::AsByteArray(int p_MinSize, bool p_Reverse) 262 | { 263 | int l_Size = (p_MinSize >= GetNumBytes()) ? p_MinSize : GetNumBytes(); 264 | 265 | if (m_Array) 266 | { 267 | delete[] m_Array; 268 | m_Array = NULL; 269 | } 270 | m_Array = new uint8_t[l_Size]; 271 | 272 | /// If we need more bytes than length of BigNumber set the rest to 0 273 | if (l_Size > GetNumBytes()) 274 | memset((void*)m_Array, 0, l_Size); 275 | 276 | BN_bn2bin(m_BN, (unsigned char *)m_Array); 277 | 278 | if (p_Reverse) 279 | std::reverse(m_Array, m_Array + l_Size); 280 | 281 | return m_Array; 282 | } 283 | /// As hex str 284 | const char* BigNumber::AsHexStr() 285 | { 286 | return BN_bn2hex(m_BN); 287 | } 288 | /// As dec str 289 | const char* BigNumber::AsDecStr() 290 | { 291 | return BN_bn2dec(m_BN); 292 | } 293 | 294 | } ///< namespace Crypto 295 | } ///< namespace RCN -------------------------------------------------------------------------------- /Crypto/BigNumber.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct bignum_st; 6 | 7 | namespace RCN { namespace Crypto { 8 | 9 | class BigNumber 10 | { 11 | public: 12 | /// Constructor 13 | BigNumber(); 14 | /// Constructor 15 | /// @p_BN : Copy 16 | BigNumber(const BigNumber& p_BN); 17 | /// Constructor 18 | /// @p_Value : Copy 19 | BigNumber(uint32_t p_Value); 20 | /// Destructor 21 | ~BigNumber(); 22 | 23 | /// Set value 24 | /// @p_Value : New value 25 | void SetDword(uint32_t p_Value); 26 | /// Set value 27 | /// @p_Value : New value 28 | void SetQword(uint64_t p_Value); 29 | /// Set value 30 | /// @p_Value : New value 31 | /// @p_Size : New value size 32 | void SetBinary(const uint8_t* p_Value, size_t p_Size); 33 | /// Set value 34 | /// @p_Value : New value 35 | void SetHexStr(const char* p_Value); 36 | 37 | /// Set rand value 38 | /// @p_NumBits : Num bits 39 | void SetRand(int p_NumBits); 40 | 41 | /// Operator 42 | /// @p_Other : Operand right value 43 | BigNumber operator=(const BigNumber& p_Other); 44 | /// Operator 45 | /// @p_Other : Operand right value 46 | BigNumber operator+=(const BigNumber& p_Other); 47 | /// Operator 48 | /// @p_Other : Operand right value 49 | BigNumber operator+(const BigNumber& p_Other); 50 | /// Operator 51 | /// @p_Other : Operand right value 52 | BigNumber operator-=(const BigNumber& p_Other); 53 | /// Operator 54 | /// @p_Other : Operand right value 55 | BigNumber operator-(const BigNumber& p_Other); 56 | /// Operator 57 | /// @p_Other : Operand right value 58 | BigNumber operator*=(const BigNumber& p_Other); 59 | /// Operator 60 | /// @p_Other : Operand right value 61 | BigNumber operator*(const BigNumber& p_Other); 62 | /// Operator 63 | /// @p_Other : Operand right value 64 | BigNumber operator/=(const BigNumber& p_Other); 65 | /// Operator 66 | /// @p_Other : Operand right value 67 | BigNumber operator/(const BigNumber& p_Other); 68 | /// Operator 69 | /// @p_Other : Operand right value 70 | BigNumber operator%=(const BigNumber& p_Other); 71 | /// Operator 72 | /// @p_Other : Operand right value 73 | BigNumber operator%(const BigNumber& p_Other); 74 | 75 | /// Is zero 76 | bool IsZero() const; 77 | 78 | /// Mod exp 79 | /// @p_OtherA : A 80 | /// @p_OtherB : B 81 | BigNumber ModExp(const BigNumber& p_OtherA, const BigNumber& p_OtherB); 82 | /// Exp 83 | /// @p_Other : Other 84 | BigNumber Exp(const BigNumber& p_Other); 85 | 86 | /// Get num bytes 87 | int GetNumBytes(); 88 | 89 | /// Get as uint32 90 | uint32_t AsDword(); 91 | 92 | /// As byte array 93 | /// @p_MinSize : Min size 94 | uint8_t* AsByteArray(int p_MinSize = 0); 95 | /// As byte array 96 | /// @p_MinSize : Min size 97 | /// @p_Reverse : Reverse array 98 | uint8_t* AsByteArray(int p_MinSize, bool p_Reverse); 99 | /// As hex str 100 | const char* AsHexStr(); 101 | /// As dec str 102 | const char* AsDecStr(); 103 | 104 | private: 105 | struct bignum_st* m_BN; ///< The number 106 | uint8_t* m_Array; ///< Output temp 107 | 108 | }; 109 | 110 | } ///< namespace Crypto 111 | } ///< namespace RCN -------------------------------------------------------------------------------- /Crypto/SHA1.cpp: -------------------------------------------------------------------------------- 1 | #include "SHA1.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace RCN { namespace Crypto { 8 | 9 | /// Constructor 10 | SHA1::SHA1() 11 | { 12 | m_Context = new SHA_CTX(); 13 | SHA1_Init(reinterpret_cast(m_Context)); 14 | } 15 | /// Destructor 16 | SHA1::~SHA1() 17 | { 18 | SHA1_Init(reinterpret_cast(m_Context)); 19 | delete m_Context; 20 | } 21 | 22 | ////////////////////////////////////////////////////////////////////////// 23 | ////////////////////////////////////////////////////////////////////////// 24 | 25 | /// Update 26 | /// @p_BN1 : First big number 27 | /// ... 28 | void SHA1::UpdateBigNumbers(BigNumber* p_BN1, ...) 29 | { 30 | va_list l_VAList; 31 | BigNumber* l_BigNumber; 32 | 33 | va_start(l_VAList, p_BN1); 34 | l_BigNumber = p_BN1; 35 | 36 | while (l_BigNumber) 37 | { 38 | UpdateData(l_BigNumber->AsByteArray(), l_BigNumber->GetNumBytes()); 39 | l_BigNumber = va_arg(l_VAList, BigNumber*); 40 | } 41 | 42 | va_end(l_VAList); 43 | } 44 | /// Update 45 | /// @p_Data : input data 46 | /// @p_Size : input data len 47 | void SHA1::UpdateData(const uint8_t* p_Data, int p_Size) 48 | { 49 | SHA1_Update(reinterpret_cast(m_Context), p_Data, p_Size); 50 | } 51 | /// Update 52 | /// @p_Str : input data 53 | void SHA1::UpdateData(const std::string& p_Str) 54 | { 55 | UpdateData((uint8_t const*)p_Str.c_str(), p_Str.length()); 56 | } 57 | 58 | ////////////////////////////////////////////////////////////////////////// 59 | ////////////////////////////////////////////////////////////////////////// 60 | 61 | /// Init 62 | void SHA1::Initialize() 63 | { 64 | SHA1_Init(reinterpret_cast(m_Context)); 65 | } 66 | /// Finish 67 | void SHA1::Finalize() 68 | { 69 | SHA1_Final(m_Digest, reinterpret_cast(m_Context)); 70 | } 71 | 72 | ////////////////////////////////////////////////////////////////////////// 73 | ////////////////////////////////////////////////////////////////////////// 74 | 75 | /// Get digest 76 | uint8_t* SHA1::GetDigest() 77 | { 78 | return m_Digest; 79 | }; 80 | /// Get digest length 81 | int SHA1::GetLength() 82 | { 83 | return SHA_DIGEST_LENGTH; 84 | }; 85 | 86 | } ///< namespace Crypto 87 | } ///< namespace RCN -------------------------------------------------------------------------------- /Crypto/SHA1.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "BigNumber.hpp" 4 | #include 5 | #include 6 | 7 | #define SHA_DIGEST_LENGTH 20 8 | 9 | namespace RCN { namespace Crypto { 10 | 11 | class SHA1 12 | { 13 | public: 14 | /// Constructor 15 | SHA1(); 16 | /// Destructor 17 | ~SHA1(); 18 | 19 | /// Update 20 | /// @p_BN1 : First big number 21 | /// ... 22 | void UpdateBigNumbers(BigNumber* p_BN1, ...); 23 | /// Update 24 | /// @p_Data : input data 25 | /// @p_Size : input data len 26 | void UpdateData(const uint8_t* p_Data, int p_Size); 27 | /// Update 28 | /// @p_Str : input data 29 | void UpdateData(const std::string& p_Str); 30 | 31 | /// Init 32 | void Initialize(); 33 | /// Finish 34 | void Finalize(); 35 | 36 | /// Get digest 37 | uint8_t* GetDigest(); 38 | /// Get digest length 39 | int GetLength(); 40 | 41 | private: 42 | void * m_Context; ///< SHA1 context 43 | uint8_t m_Digest[SHA_DIGEST_LENGTH]; ///< Output digest 44 | 45 | }; 46 | 47 | } ///< namespace Crypto 48 | } ///< namespace RCN -------------------------------------------------------------------------------- /Crypto/SRP6.cpp: -------------------------------------------------------------------------------- 1 | #include "SRP6.hpp" 2 | #include "SHA1.hpp" 3 | #include 4 | 5 | namespace RCN { namespace Crypto { 6 | 7 | /// Constructor 8 | /// p_N : N number 9 | /// p_G : G number 10 | SRP6::SRP6(BigNumber p_N, BigNumber p_G) 11 | : m_N(p_N), m_G(p_G), m_K(3) 12 | { 13 | 14 | } 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | ////////////////////////////////////////////////////////////////////////// 18 | 19 | /// Get A number 20 | /// @p_A : a input 21 | BigNumber SRP6::GetA(BigNumber p_a) 22 | { 23 | return m_G.ModExp(p_a, m_N); 24 | } 25 | /// Get x number 26 | /// @p_Salt : Salt 27 | /// @p_LogonHash : Logon hash 28 | BigNumber SRP6::Getx(BigNumber p_Salt, BigNumber p_LogonHash) 29 | { 30 | SHA1 l_SHA1; 31 | l_SHA1.Initialize(); 32 | l_SHA1.UpdateBigNumbers(&p_Salt, &p_LogonHash, nullptr); 33 | l_SHA1.Finalize(); 34 | 35 | BigNumber l_Result; 36 | l_Result.SetBinary(l_SHA1.GetDigest(), SHA_DIGEST_LENGTH); 37 | 38 | return l_Result; 39 | } 40 | /// Get u number 41 | /// @p_A : A number 42 | /// @p_B : B number 43 | BigNumber SRP6::Getu(BigNumber p_A, BigNumber p_B) 44 | { 45 | SHA1 l_SHA1; 46 | l_SHA1.Initialize(); 47 | l_SHA1.UpdateBigNumbers(&p_A, &p_B, nullptr); 48 | l_SHA1.Finalize(); 49 | 50 | BigNumber l_Result; 51 | l_Result.SetBinary(l_SHA1.GetDigest(), SHA_DIGEST_LENGTH); 52 | 53 | return l_Result; 54 | } 55 | 56 | ////////////////////////////////////////////////////////////////////////// 57 | ////////////////////////////////////////////////////////////////////////// 58 | 59 | /// Get client session key 60 | /// @p_a : a input 61 | /// @p_B : B number 62 | /// @p_x : x number 63 | /// @p_u : u number 64 | BigNumber SRP6::GetClientS(BigNumber p_a, BigNumber p_B, BigNumber p_x, BigNumber p_u) 65 | { 66 | BigNumber l_S; 67 | l_S = (p_B - (m_K * m_G.ModExp(p_x, m_N))).ModExp(p_a + (p_u * p_x), m_N); 68 | 69 | return l_S; 70 | } 71 | 72 | ////////////////////////////////////////////////////////////////////////// 73 | /////////////////////////////////////////////////////////////// 5 | 6 | namespace RCN { namespace Crypto { 7 | 8 | class SRP6 9 | { 10 | public: 11 | /// Constructor 12 | /// p_N : N number 13 | /// p_G : G number 14 | SRP6(BigNumber p_N, BigNumber p_G); 15 | 16 | /// Get A number 17 | /// @p_a : a input 18 | BigNumber GetA(BigNumber p_a); 19 | /// Get x number 20 | /// @p_Salt : Salt 21 | /// @p_LogonHash : Logon hash 22 | BigNumber Getx(BigNumber p_Salt, BigNumber p_LogonHash); 23 | /// Get u number 24 | /// @p_A : A number 25 | /// @p_B : B number 26 | BigNumber Getu(BigNumber p_A, BigNumber p_B); 27 | 28 | /// Get client session key 29 | /// @p_a : a input 30 | /// @p_B : B number 31 | /// @p_x : x number 32 | /// @p_u : u number 33 | BigNumber GetClientS(BigNumber p_a, BigNumber p_B, BigNumber p_x, BigNumber p_u); 34 | 35 | /// Get logon hash 36 | /// @p_Username : Account name 37 | /// @p_Password : Account password 38 | BigNumber GetLogonHash(std::string p_Username, std::string p_Password); 39 | 40 | /// @p_Username : Account name 41 | /// @p_s : s number 42 | /// @p_A : A number 43 | /// @p_B : B number 44 | /// @p_K : K number 45 | BigNumber GetM(std::string p_Username, BigNumber p_s, BigNumber p_A, BigNumber p_B, BigNumber p_K); 46 | 47 | /// SHAInterleave 48 | /// @p_S : S number 49 | BigNumber SHAInterleave(BigNumber p_S); 50 | 51 | private: 52 | BigNumber m_N; ///< N number 53 | BigNumber m_G; ///< G number 54 | BigNumber m_K; ///< K number 55 | 56 | }; 57 | 58 | } ///< namespace Crypto 59 | } ///< namespace RCN -------------------------------------------------------------------------------- /Crypto/WardenKeyGenerator.cpp: -------------------------------------------------------------------------------- 1 | #include "WardenKeyGenerator.hpp" 2 | #include "SHA1.hpp" 3 | #include 4 | 5 | namespace RCN { namespace Crypto { 6 | 7 | /// Constructor 8 | /// @p_SessionKey : World crypto key 9 | WardenKeyGenerator::WardenKeyGenerator(BigNumber p_SessionKey) 10 | : m_SizeTaked(0) 11 | { 12 | m_PairA = new uint8_t[SHA_DIGEST_LENGTH]; 13 | m_PairB = new uint8_t[SHA_DIGEST_LENGTH]; 14 | m_PairC = new uint8_t[SHA_DIGEST_LENGTH]; 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | 18 | memset(m_PairA, 0, SHA_DIGEST_LENGTH); 19 | 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | uint8_t * l_SubSessionKeyA = new uint8_t[SHA_DIGEST_LENGTH]; 23 | memcpy(l_SubSessionKeyA, p_SessionKey.AsByteArray(), 20); 24 | 25 | SHA1 l_Sha1A; 26 | l_Sha1A.Initialize(); 27 | l_Sha1A.UpdateData(l_SubSessionKeyA, SHA_DIGEST_LENGTH); 28 | l_Sha1A.Finalize(); 29 | 30 | memcpy(m_PairB, l_Sha1A.GetDigest(), SHA_DIGEST_LENGTH); 31 | 32 | ////////////////////////////////////////////////////////////////////////// 33 | 34 | uint8_t * l_SubSessionKeyB = new uint8_t[SHA_DIGEST_LENGTH]; 35 | memcpy(l_SubSessionKeyB, p_SessionKey.AsByteArray() + 20, 20); 36 | 37 | SHA1 l_Sha1B; 38 | l_Sha1B.Initialize(); 39 | l_Sha1B.UpdateData(l_SubSessionKeyB, SHA_DIGEST_LENGTH); 40 | l_Sha1B.Finalize(); 41 | 42 | memcpy(m_PairC, l_Sha1B.GetDigest(), SHA_DIGEST_LENGTH); 43 | 44 | ////////////////////////////////////////////////////////////////////////// 45 | 46 | delete[] l_SubSessionKeyA; 47 | delete[] l_SubSessionKeyB; 48 | 49 | FillUp(); 50 | } 51 | /// Destructor 52 | WardenKeyGenerator::~WardenKeyGenerator() 53 | { 54 | delete m_PairA; 55 | delete m_PairB; 56 | delete m_PairC; 57 | } 58 | 59 | ////////////////////////////////////////////////////////////////////////// 60 | ////////////////////////////////////////////////////////////////////////// 61 | 62 | /// Generate a new key 63 | BigNumber WardenKeyGenerator::GenerateKey() 64 | { 65 | uint8_t * l_NewKey = new uint8_t[16]; 66 | 67 | for (size_t l_I = 0; l_I < 16; ++l_I) 68 | { 69 | if (m_SizeTaked == SHA_DIGEST_LENGTH) 70 | FillUp(); 71 | 72 | l_NewKey[l_I] = m_PairA[m_SizeTaked]; 73 | m_SizeTaked++; 74 | } 75 | 76 | BigNumber l_Result; 77 | l_Result.SetBinary(l_NewKey, 16); 78 | 79 | return l_Result; 80 | } 81 | 82 | ////////////////////////////////////////////////////////////////////////// 83 | ////////////////////////////////////////////////////////////////////////// 84 | 85 | /// Fill up pair A 86 | void WardenKeyGenerator::FillUp() 87 | { 88 | SHA1 l_Sha1; 89 | l_Sha1.UpdateData(m_PairB, SHA_DIGEST_LENGTH); 90 | l_Sha1.UpdateData(m_PairA, SHA_DIGEST_LENGTH); 91 | l_Sha1.UpdateData(m_PairC, SHA_DIGEST_LENGTH); 92 | l_Sha1.Finalize(); 93 | 94 | memcpy(m_PairA, l_Sha1.GetDigest(), SHA_DIGEST_LENGTH); 95 | 96 | m_SizeTaked = 0; 97 | } 98 | 99 | 100 | } ///< namespace Crypto 101 | } ///< namespace RCN -------------------------------------------------------------------------------- /Crypto/WardenKeyGenerator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "BigNumber.hpp" 4 | #include 5 | 6 | namespace RCN { namespace Crypto { 7 | 8 | class WardenKeyGenerator 9 | { 10 | public: 11 | /// Constructor 12 | /// @p_SessionKey : World crypto key 13 | WardenKeyGenerator(BigNumber p_SessionKey); 14 | /// Destructor 15 | ~WardenKeyGenerator(); 16 | 17 | /// Generate a new key 18 | BigNumber GenerateKey(); 19 | 20 | private: 21 | /// Fill up pair A 22 | void FillUp(); 23 | 24 | private: 25 | uint8_t* m_PairA; 26 | uint8_t* m_PairB; 27 | uint8_t* m_PairC; 28 | 29 | size_t m_SizeTaked; 30 | 31 | }; 32 | 33 | } ///< namespace Crypto 34 | } ///< namespace RCN -------------------------------------------------------------------------------- /Crypto/WoWCrypt.cpp: -------------------------------------------------------------------------------- 1 | #include "WoWCrypt.hpp" 2 | 3 | const static size_t CRYPTED_SEND_LEN = 6; 4 | const static size_t CRYPTED_RECV_LEN = 4; 5 | 6 | namespace RCN { namespace Crypto { 7 | 8 | /// Constructor 9 | WoWCrypt::WoWCrypt() 10 | { 11 | m_Initialized = false; 12 | } 13 | /// Destructor 14 | WoWCrypt::~WoWCrypt() 15 | { 16 | 17 | } 18 | 19 | ////////////////////////////////////////////////////////////////////////// 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | /// Init WoWCrypt 23 | void WoWCrypt::Init() 24 | { 25 | m_SendA = 0; 26 | m_SendB = 0; 27 | m_RecvA = 0; 28 | m_RecvB = 0; 29 | m_Initialized = true; 30 | } 31 | /// Set encrypt key 32 | /// @p_Key : Key 33 | /// @p_KeySize : Size of the key 34 | void WoWCrypt::SetKey(uint8_t* p_Key, size_t p_KeySize) 35 | { 36 | m_Key.resize(p_KeySize); 37 | std::copy(p_Key, p_Key + p_KeySize, m_Key.begin()); 38 | } 39 | /// Is the WoWCrypt initialized 40 | bool WoWCrypt::IsInitialized() 41 | { 42 | return m_Initialized; 43 | } 44 | 45 | ////////////////////////////////////////////////////////////////////////// 46 | ////////////////////////////////////////////////////////////////////////// 47 | 48 | /// Decrypt data 49 | /// @p_Data : Data to decrypt 50 | /// @p_Size : Size of data 51 | void WoWCrypt::Decrypt(uint8_t* p_Data, size_t p_Size) 52 | { 53 | if (!m_Initialized) 54 | return; 55 | 56 | if (p_Size < CRYPTED_RECV_LEN) 57 | return; 58 | 59 | for (size_t l_I = 0; l_I < CRYPTED_RECV_LEN; l_I++) 60 | { 61 | m_RecvA %= m_Key.size(); 62 | 63 | uint8_t l_Byte = (p_Data[l_I] - m_RecvB) ^ m_Key[m_RecvA]; 64 | 65 | ++m_RecvA; 66 | 67 | m_RecvB = p_Data[l_I]; 68 | p_Data[l_I] = l_Byte; 69 | } 70 | } 71 | /// Encrypt data 72 | /// @p_Data : Data to encrypt 73 | /// @p_Size : Size of data 74 | void WoWCrypt::Encrypt(uint8_t* p_Data, size_t p_Size) 75 | { 76 | if (!m_Initialized) 77 | return; 78 | 79 | if (p_Size < CRYPTED_SEND_LEN) 80 | return; 81 | 82 | for (size_t l_I = 0; l_I < CRYPTED_SEND_LEN; l_I++) 83 | { 84 | m_SendA %= m_Key.size(); 85 | 86 | uint8_t l_Byte = (p_Data[l_I] ^ m_Key[m_SendA]) + m_SendB; 87 | 88 | ++m_SendA; 89 | 90 | p_Data[l_I] = m_SendB = l_Byte; 91 | } 92 | } 93 | 94 | } ///< namespace Crypto 95 | } ///< namespace RCN -------------------------------------------------------------------------------- /Crypto/WoWCrypt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace RCN { namespace Crypto { 7 | 8 | class WoWCrypt 9 | { 10 | public: 11 | /// Constructor 12 | WoWCrypt(); 13 | /// Destructor 14 | ~WoWCrypt(); 15 | 16 | /// Init WoWCrypt 17 | void Init(); 18 | /// Set encrypt key 19 | /// @p_Key : Key 20 | /// @p_KeySize : Size of the key 21 | void SetKey(uint8_t* p_Key, size_t p_KeySize); 22 | /// Is the WoWCrypt initialized 23 | bool IsInitialized(); 24 | 25 | /// Decrypt data 26 | /// @p_Data : Data to decrypt 27 | /// @p_Size : Size of data 28 | void Decrypt(uint8_t* p_Data, size_t p_Size); 29 | /// Encrypt data 30 | /// @p_Data : Data to encrypt 31 | /// @p_Size : Size of data 32 | void Encrypt(uint8_t* p_Data, size_t p_Size); 33 | 34 | private: 35 | std::vector m_Key; ///< Encrypt/Decrypt key 36 | uint8_t m_SendA; ///< Encrypt state A 37 | uint8_t m_SendB; ///< Encrypt state B 38 | uint8_t m_RecvA; ///< Decrypt state A 39 | uint8_t m_RecvB; ///< Decrypt state B 40 | bool m_Initialized; ///< Is the system initialized 41 | 42 | }; 43 | 44 | } ///< namespace Crypto 45 | } ///< namespace RCN -------------------------------------------------------------------------------- /Logon/LogonEnums.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace RCN { namespace Logon { 4 | 5 | namespace AuthResult 6 | { 7 | enum 8 | { 9 | WOW_SUCCESS = 0x00, 10 | WOW_FAIL_UNKNOWN0 = 0x01, ///< ? Unable to connect 11 | WOW_FAIL_UNKNOWN1 = 0x02, ///< ? Unable to connect 12 | WOW_FAIL_BANNED = 0x03, ///< This account has been closed and is no longer available for use. Please go to /banned.html for further information. 13 | WOW_FAIL_UNKNOWN_ACCOUNT = 0x04, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see for more information 14 | WOW_FAIL_INCORRECT_PASSWORD = 0x05, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see for more information 15 | WOW_FAIL_ALREADY_ONLINE = 0x06, ///< This account is already logged into . Please check the spelling and try again. 16 | WOW_FAIL_NO_TIME = 0x07, ///< You have used up your prepaid time for this account. Please purchase more to continue playing 17 | WOW_FAIL_DB_BUSY = 0x08, ///< Could not log in to at this time. Please try again later. 18 | WOW_FAIL_VERSION_INVALID = 0x09, ///< Unable to validate game version. This may be caused by file corruption or interference of another program. Please visit for more information and possible solutions to this issue. 19 | WOW_FAIL_VERSION_UPDATE = 0x0A, ///< Downloading 20 | WOW_FAIL_INVALID_SERVER = 0x0B, ///< Unable to connect 21 | WOW_FAIL_SUSPENDED = 0x0C, ///< This account has been temporarily suspended. Please go to /banned.html for further information 22 | WOW_FAIL_FAIL_NOACCESS = 0x0D, ///< Unable to connect 23 | WOW_SUCCESS_SURVEY = 0x0E, ///< Connected. 24 | WOW_FAIL_PARENTCONTROL = 0x0F, ///< Access to this account has been blocked by parental controls. Your settings may be changed in your account preferences at 25 | WOW_FAIL_LOCKED_ENFORCED = 0x10, ///< You have applied a lock to your account. You can change your locked status by calling your account lock phone number. 26 | WOW_FAIL_TRIAL_ENDED = 0x11, ///< Your trial subscription has expired. Please visit to upgrade your account. 27 | WOW_FAIL_USE_BATTLENET = 0x12 ///< WOW_FAIL_OTHER This account is now attached to a Battle.net account. Please login with your Battle.net account email address and password. 28 | }; 29 | } 30 | 31 | static const char* AuthResultStr[] = 32 | { 33 | "WOW_SUCCESS", 34 | "WOW_FAIL_UNKNOWN0", 35 | "WOW_FAIL_UNKNOWN1", 36 | "WOW_FAIL_BANNED", 37 | "WOW_FAIL_UNKNOWN_ACCOUNT", 38 | "WOW_FAIL_INCORRECT_PASSWORD", 39 | "WOW_FAIL_ALREADY_ONLINE", 40 | "WOW_FAIL_NO_TIME", 41 | "WOW_FAIL_DB_BUSY", 42 | "WOW_FAIL_VERSION_INVALID", 43 | "WOW_FAIL_VERSION_UPDATE", 44 | "WOW_FAIL_INVALID_SERVER", 45 | "WOW_FAIL_SUSPENDED", 46 | "WOW_FAIL_FAIL_NOACCESS", 47 | "WOW_SUCCESS_SURVEY", 48 | "WOW_FAIL_PARENTCONTROL", 49 | "WOW_FAIL_LOCKED_ENFORCED", 50 | "WOW_FAIL_TRIAL_ENDED", 51 | "WOW_FAIL_USE_BATTLENET", 52 | }; 53 | 54 | } ///< namespace Logon 55 | } ///< namespace RCN -------------------------------------------------------------------------------- /Logon/LogonManager.cpp: -------------------------------------------------------------------------------- 1 | #include "LogonManager.hpp" 2 | #include "LogonEnums.hpp" 3 | #include "LogonOpcodes.hpp" 4 | #include "LogonPackets.hpp" 5 | #include "../Crypto/BigNumber.hpp" 6 | #include "../Crypto/SRP6.hpp" 7 | #include "../Network/ByteBuffer.hpp" 8 | 9 | namespace RCN { namespace Logon { 10 | 11 | /// Constructor 12 | /// @p_Server : Server address 13 | /// @p_Port : Auth server port 14 | /// @p_User : Username 15 | /// @p_Password : Password 16 | LogonManager::LogonManager(std::string p_Server, uint16_t p_Port, std::string p_User, std::string p_Password) 17 | : m_Server(p_Server), m_Port(p_Port), m_User(p_User), m_Password(p_Password), m_Connecting(false) 18 | { 19 | 20 | } 21 | 22 | ////////////////////////////////////////////////////////////////////////// 23 | ////////////////////////////////////////////////////////////////////////// 24 | 25 | /// Do the connection 26 | bool LogonManager::Connect() 27 | { 28 | if (!m_Client.Connect(m_Server, m_Port)) 29 | { 30 | printf("[AUTH] failed to connect to %s\n", m_Server.c_str()); 31 | return false; 32 | } 33 | 34 | SendAuthLogonChallenge(); 35 | 36 | m_Connecting = true; 37 | m_IsAuthed = false; 38 | 39 | while (m_Connecting) 40 | { 41 | uint8_t l_Command = 0; 42 | m_Client.Receive(&l_Command, sizeof(uint8_t)); 43 | 44 | switch (static_cast(l_Command)) 45 | { 46 | case Opcodes::CMD_AUTH_LOGON_CHALLENGE: 47 | printf("[AUTH] Received Opcodes::CMD_AUTH_LOGON_CHALLENGE\n"); 48 | HandleAuthLogonChallenge(); 49 | break; 50 | case Opcodes::CMD_AUTH_LOGON_PROOF: 51 | printf("[AUTH] Received Opcodes::CMD_AUTH_LOGON_PROOF\n"); 52 | HandleAuthLogonProof(); 53 | break; 54 | case Opcodes::CMD_AUTH_RECONNECT_CHALLENGE: 55 | printf("[AUTH] Received UNHANDLED Opcodes::CMD_AUTH_RECONNECT_CHALLENGE\n"); 56 | break; 57 | case Opcodes::CMD_AUTH_RECONNECT_PROOF: 58 | printf("[AUTH] Received UNHANDLED Opcodes::CMD_AUTH_RECONNECT_PROOF\n"); 59 | break; 60 | case Opcodes::CMD_REALM_LIST: 61 | printf("[AUTH] Received Opcodes::CMD_REALM_LIST\n"); 62 | HandleRealmList(); 63 | break; 64 | case Opcodes::CMD_XFER_INITIATE: 65 | printf("[AUTH] Received UNHANDLED Opcodes::CMD_XFER_INITIATE\n"); 66 | break; 67 | case Opcodes::CMD_XFER_DATA: 68 | printf("[AUTH] Received UNHANDLED Opcodes::CMD_XFER_DATA\n"); 69 | break; 70 | case Opcodes::CMD_XFER_ACCEPT: 71 | printf("[AUTH] Received UNHANDLED Opcodes::CMD_XFER_ACCEPT\n"); 72 | break; 73 | case Opcodes::CMD_XFER_RESUME: 74 | printf("[AUTH] Received UNHANDLED Opcodes::CMD_XFER_RESUME\n"); 75 | break; 76 | case Opcodes::CMD_XFER_CANCEL: 77 | printf("[AUTH] Received UNHANDLED Opcodes::CMD_XFER_CANCEL\n"); 78 | break; 79 | default: 80 | printf("[AUTH] Received UNK %u\n", l_Command); 81 | break; 82 | } 83 | } 84 | 85 | m_Client.Disconnect(); 86 | 87 | return m_IsAuthed; 88 | } 89 | 90 | ////////////////////////////////////////////////////////////////////////// 91 | ////////////////////////////////////////////////////////////////////////// 92 | 93 | /// Send Opcodes::CMD_AUTH_LOGON_CHALLENGE 94 | void LogonManager::SendAuthLogonChallenge() 95 | { 96 | uint8_t l_GameName[] = "WoW\0"; 97 | uint8_t l_PlatformName[] = "68x\0"; 98 | uint8_t l_OSName[] = "niW\0"; 99 | uint8_t l_CountryName[] = "BGne"; 100 | 101 | union IPAddress 102 | { 103 | uint32_t Packed; 104 | uint8_t Bytes[4]; 105 | } l_IPAddress; 106 | 107 | l_IPAddress.Bytes[0] = 127; 108 | l_IPAddress.Bytes[1] = 0; 109 | l_IPAddress.Bytes[2] = 0; 110 | l_IPAddress.Bytes[3] = 1; 111 | 112 | Client_AuthLogonChallenge l_AuthLogonChallengePacket; 113 | l_AuthLogonChallengePacket._Header.Opcode = Opcodes::CMD_AUTH_LOGON_CHALLENGE; 114 | l_AuthLogonChallengePacket.Error = 3; 115 | l_AuthLogonChallengePacket.Size = 30 + m_User.length(); 116 | memcpy(l_AuthLogonChallengePacket.GameName, l_GameName, 4); 117 | l_AuthLogonChallengePacket.Version1 = 1; 118 | l_AuthLogonChallengePacket.Version2 = 12; 119 | l_AuthLogonChallengePacket.Version3 = 1; 120 | l_AuthLogonChallengePacket.Build = 5875; 121 | memcpy(l_AuthLogonChallengePacket.Platform, l_PlatformName, 4); 122 | memcpy(l_AuthLogonChallengePacket.OS, l_OSName, 4); 123 | memcpy(l_AuthLogonChallengePacket.Country, l_CountryName, 4); 124 | l_AuthLogonChallengePacket.TimezoneBias = 1; 125 | l_AuthLogonChallengePacket.IP = l_IPAddress.Packed; 126 | l_AuthLogonChallengePacket.UsernameLen = m_User.length(); 127 | memcpy(l_AuthLogonChallengePacket.Username, m_User.c_str(), min((size_t)15, (size_t)m_User.c_str())); 128 | 129 | m_Client.Send(reinterpret_cast(&l_AuthLogonChallengePacket), 4 + 30 + m_User.length()); 130 | 131 | printf("[AUTH] Sent Opcodes::CMD_AUTH_LOGON_CHALLENGE\n"); 132 | } 133 | 134 | ////////////////////////////////////////////////////////////////////////// 135 | ////////////////////////////////////////////////////////////////////////// 136 | 137 | /// Handle Opcodes::CMD_AUTH_LOGON_CHALLENGE 138 | void LogonManager::HandleAuthLogonChallenge() 139 | { 140 | Server_GruntAuthChallenge l_Result; 141 | m_Client.Receive(reinterpret_cast(&l_Result), sizeof(Server_GruntAuthChallenge)); 142 | 143 | if (l_Result.Result != AuthResult::WOW_SUCCESS) 144 | { 145 | m_Connecting = false; 146 | printf("[AUTH] Auth failed : %s(%u)\n", AuthResultStr[l_Result.Result], l_Result.Result); 147 | return; 148 | } 149 | 150 | Server_GruntAuthChallenge_OnSuccess l_CryptoContext; 151 | m_Client.Receive(reinterpret_cast(&l_CryptoContext), sizeof(Server_GruntAuthChallenge_OnSuccess)); 152 | 153 | Crypto::BigNumber l_B; 154 | Crypto::BigNumber l_G; 155 | Crypto::BigNumber l_N; 156 | Crypto::BigNumber l_Salt; 157 | 158 | l_B.SetBinary(l_CryptoContext.B, 32); 159 | l_G.SetBinary(l_CryptoContext.G, l_CryptoContext.GLen); 160 | l_N.SetBinary(l_CryptoContext.N, l_CryptoContext.NLen); 161 | l_Salt.SetBinary(l_CryptoContext.Salt, 32); 162 | 163 | Crypto::SRP6 l_SRP6(l_N, l_G); 164 | Crypto::BigNumber l_AuthHash = l_SRP6.GetLogonHash(m_User, m_Password); 165 | 166 | Crypto::BigNumber l_A; 167 | Crypto::BigNumber l_S; 168 | do 169 | { 170 | Crypto::BigNumber l_a; 171 | l_a.SetRand(19 * 8); 172 | 173 | l_A = l_SRP6.GetA(l_a); 174 | 175 | Crypto::BigNumber l_x = l_SRP6.Getx(l_Salt, l_AuthHash); 176 | Crypto::BigNumber l_u = l_SRP6.Getu(l_A, l_B); 177 | l_S = l_SRP6.GetClientS(l_a, l_B, l_x, l_u); 178 | } while (l_S.AsDword() < 0); 179 | 180 | SessionKey = l_SRP6.SHAInterleave(l_S); 181 | Crypto::BigNumber l_M = l_SRP6.GetM(m_User, l_Salt, l_A, l_B, SessionKey); 182 | 183 | Client_AuthLogonProof l_Response; 184 | l_Response._Header.Opcode = Opcodes::CMD_AUTH_LOGON_PROOF; 185 | memcpy(l_Response.A, l_A.AsByteArray(32), 32); 186 | memcpy(l_Response.M1, l_M.AsByteArray(20), 20); 187 | memset(l_Response.CRCHash, 0, 20); 188 | l_Response.SurveyID = 0; 189 | l_Response.SecurityFlags = l_CryptoContext.SecurityFlag; 190 | 191 | m_Client.Send(reinterpret_cast(&l_Response), sizeof(Client_AuthLogonProof)); 192 | 193 | printf("[AUTH] SessionKey : %s\n", SessionKey.AsHexStr()); 194 | printf("[AUTH] Sent Opcodes::CMD_AUTH_LOGON_PROOF\n"); 195 | } 196 | /// Handle Opcodes::CMD_AUTH_LOGON_PROOF 197 | void LogonManager::HandleAuthLogonProof() 198 | { 199 | Server_GruntAuthProof l_Result; 200 | m_Client.Receive(reinterpret_cast(&l_Result), sizeof(Server_GruntAuthProof)); 201 | 202 | if (l_Result.Result != AuthResult::WOW_SUCCESS) 203 | { 204 | m_Connecting = false; 205 | printf("[AUTH] Auth failed : %s(%u)\n", AuthResultStr[l_Result.Result], l_Result.Result); 206 | return; 207 | } 208 | 209 | Server_GruntAuthProof_OnSuccess l_CryptoResult; 210 | m_Client.Receive(reinterpret_cast(&l_CryptoResult), sizeof(Server_GruntAuthProof_OnSuccess)); 211 | 212 | Client_AuthRealmList l_Query; 213 | l_Query._Header.Opcode = Opcodes::CMD_REALM_LIST; 214 | l_Query.Unk = 0x00; 215 | 216 | m_Client.Send(reinterpret_cast(&l_Query), sizeof(Client_AuthRealmList)); 217 | 218 | printf("[AUTH] Sent Opcodes::CMD_REALM_LIST\n"); 219 | } 220 | /// Handle Opcodes::CMD_REALM_LIST 221 | void LogonManager::HandleRealmList() 222 | { 223 | Server_AuthRealmList l_Result; 224 | m_Client.Receive(reinterpret_cast(&l_Result), sizeof(Server_AuthRealmList)); 225 | 226 | uint8_t* l_Buffer = new uint8_t[l_Result.Size]; 227 | m_Client.Receive(l_Buffer, l_Result.Size); 228 | 229 | Network::ByteBuffer l_Packet; 230 | l_Packet.Append(l_Buffer, l_Result.Size); 231 | l_Packet.ReadPosition(0); 232 | delete[] l_Buffer; 233 | 234 | uint32_t l_UnusedValue = l_Packet.Read(); 235 | uint8_t l_RealmCount = l_Packet.Read(); 236 | 237 | for (size_t l_I = 0; l_I < l_RealmCount; ++l_I) 238 | { 239 | RealmInfo l_Info; 240 | l_Packet >> l_Info.Icon; 241 | l_Packet >> l_Info.Flags; 242 | l_Packet >> l_Info.Name; 243 | l_Packet >> l_Info.Address; 244 | l_Packet >> l_Info.PopulationLevel; 245 | l_Packet >> l_Info.AmountOfCharacters; 246 | l_Packet >> l_Info.TimeZone; 247 | l_Packet >> l_Info.UnkRealmID; 248 | 249 | Realms.push_back(l_Info); 250 | } 251 | 252 | uint16_t l_UnusedValue2 = l_Packet.Read(); 253 | 254 | m_Connecting = false; 255 | m_IsAuthed = true; 256 | } 257 | 258 | } ///< namespace Logon 259 | } ///< namespace RCN -------------------------------------------------------------------------------- /Logon/LogonManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Network/TCPClient.hpp" 4 | #include "../Crypto/BigNumber.hpp" 5 | #include 6 | #include 7 | #include 8 | 9 | namespace RCN { namespace Logon { 10 | 11 | struct RealmInfo 12 | { 13 | uint32_t Icon; 14 | uint8_t Flags; 15 | std::string Name; 16 | std::string Address; 17 | float PopulationLevel; 18 | uint8_t AmountOfCharacters; 19 | uint8_t TimeZone; 20 | uint8_t UnkRealmID; 21 | }; 22 | 23 | class LogonManager 24 | { 25 | public: 26 | /// Constructor 27 | /// @p_Server : Server address 28 | /// @p_Port : Auth server port 29 | /// @p_User : Username 30 | /// @p_Password : Password 31 | LogonManager(std::string p_Server, uint16_t p_Port, std::string p_User, std::string p_Password); 32 | 33 | /// Do the connection 34 | bool Connect(); 35 | 36 | public: 37 | Crypto::BigNumber SessionKey; ///< Account session key 38 | std::vector Realms; ///< Realms 39 | 40 | private: 41 | /// Send ClientMessage::CMD_AUTH_LOGON_CHALLENGE 42 | void SendAuthLogonChallenge(); 43 | 44 | /// Handle Opcodes::CMD_AUTH_LOGON_CHALLENGE 45 | void HandleAuthLogonChallenge(); 46 | /// Handle Opcodes::CMD_AUTH_LOGON_PROOF 47 | void HandleAuthLogonProof(); 48 | /// Handle Opcodes::CMD_REALM_LIST 49 | void HandleRealmList(); 50 | 51 | private: 52 | std::string m_Server; ///< Logon server address 53 | uint16_t m_Port; ///< Logon server port 54 | std::string m_User; ///< Account name 55 | std::string m_Password; ///< Account password 56 | 57 | Network::TCPClient m_Client; ///< TCP Client 58 | 59 | bool m_Connecting; ///< Is currently connecting 60 | bool m_IsAuthed; ///< Is correctly authed 61 | }; 62 | 63 | } ///< namespace Logon 64 | } ///< namespace RCN 65 | -------------------------------------------------------------------------------- /Logon/LogonOpcodes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace RCN { namespace Logon { 6 | 7 | /// Client packet list 8 | namespace Opcodes 9 | { 10 | enum Type : uint8_t 11 | { 12 | CMD_AUTH_LOGON_CHALLENGE = 0x00, 13 | CMD_AUTH_LOGON_PROOF = 0x01, 14 | CMD_AUTH_RECONNECT_CHALLENGE = 0x02, 15 | CMD_AUTH_RECONNECT_PROOF = 0x03, 16 | CMD_REALM_LIST = 0x10, 17 | CMD_XFER_INITIATE = 0x30, 18 | CMD_XFER_DATA = 0x31, 19 | CMD_XFER_ACCEPT = 0x32, 20 | CMD_XFER_RESUME = 0x33, 21 | CMD_XFER_CANCEL = 0x34 22 | }; 23 | } 24 | 25 | } ///< namespace Logon 26 | } ///< namespace RCN 27 | -------------------------------------------------------------------------------- /Logon/LogonPackets.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace RCN { namespace Logon { 6 | 7 | #if defined( __GNUC__ ) 8 | #pragma pack(1) 9 | #else 10 | #pragma pack(push,1) 11 | #endif 12 | 13 | struct Header 14 | { 15 | uint8_t Opcode; 16 | }; 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | struct Client_AuthLogonChallenge 22 | { 23 | Header _Header; 24 | uint8_t Error; 25 | uint16_t Size; 26 | uint8_t GameName[4]; 27 | uint8_t Version1; 28 | uint8_t Version2; 29 | uint8_t Version3; 30 | uint16_t Build; 31 | uint8_t Platform[4]; 32 | uint8_t OS[4]; 33 | uint8_t Country[4]; 34 | uint32_t TimezoneBias; 35 | uint32_t IP; 36 | uint8_t UsernameLen; 37 | uint8_t Username[15]; 38 | }; 39 | 40 | ////////////////////////////////////////////////////////////////////////// 41 | ////////////////////////////////////////////////////////////////////////// 42 | 43 | struct Server_GruntAuthChallenge 44 | { 45 | uint8_t Error; 46 | uint8_t Result; 47 | }; 48 | 49 | struct Server_GruntAuthChallenge_OnSuccess 50 | { 51 | uint8_t B[32]; 52 | uint8_t GLen; 53 | uint8_t G[1]; 54 | uint8_t NLen; 55 | uint8_t N[32]; 56 | uint8_t Salt[32]; 57 | uint8_t CRCSalt[16]; 58 | uint8_t SecurityFlag; 59 | }; 60 | 61 | ////////////////////////////////////////////////////////////////////////// 62 | ////////////////////////////////////////////////////////////////////////// 63 | 64 | struct Client_AuthLogonProof 65 | { 66 | Header _Header; 67 | uint8_t A[32]; 68 | uint8_t M1[20]; 69 | uint8_t CRCHash[20]; 70 | uint8_t SurveyID; 71 | uint8_t SecurityFlags; 72 | }; 73 | 74 | ////////////////////////////////////////////////////////////////////////// 75 | ////////////////////////////////////////////////////////////////////////// 76 | 77 | struct Server_GruntAuthProof 78 | { 79 | uint8_t Result; 80 | }; 81 | 82 | struct Server_GruntAuthProof_OnSuccess 83 | { 84 | uint8_t M2[20]; 85 | uint32_t Unk2; 86 | }; 87 | 88 | ////////////////////////////////////////////////////////////////////////// 89 | ////////////////////////////////////////////////////////////////////////// 90 | 91 | struct Client_AuthRealmList 92 | { 93 | Header _Header; 94 | uint32_t Unk; 95 | }; 96 | 97 | ////////////////////////////////////////////////////////////////////////// 98 | ////////////////////////////////////////////////////////////////////////// 99 | 100 | struct Server_AuthRealmList 101 | { 102 | uint16_t Size; 103 | }; 104 | 105 | #if defined( __GNUC__ ) 106 | #pragma pack() 107 | #else 108 | #pragma pack(pop) 109 | #endif 110 | 111 | } ///< namespace Logon 112 | } ///< namespace RCN 113 | -------------------------------------------------------------------------------- /Network/ByteBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "ByteBuffer.hpp" 2 | 3 | namespace RCN { namespace Network { 4 | 5 | /// Constructor 6 | ByteBuffer::ByteBuffer() 7 | : m_ReadPos(0), m_WritePos(0) 8 | { 9 | m_Storage.reserve(DEFAULT_SIZE); 10 | } 11 | /// Constructor 12 | ByteBuffer::ByteBuffer(size_t pRes) 13 | : m_ReadPos(0), m_WritePos(0) 14 | { 15 | m_Storage.reserve(pRes); 16 | } 17 | /// Constructor 18 | ByteBuffer::ByteBuffer(const ByteBuffer &pBuf) 19 | : m_ReadPos(pBuf.m_ReadPos), m_WritePos(pBuf.m_WritePos), m_Storage(pBuf.m_Storage) 20 | { 21 | 22 | } 23 | 24 | ////////////////////////////////////////////////////////////////////////// 25 | ////////////////////////////////////////////////////////////////////////// 26 | 27 | /// Clear 28 | void ByteBuffer::Clear() 29 | { 30 | m_Storage.clear(); 31 | m_ReadPos = m_WritePos = 0; 32 | } 33 | 34 | ////////////////////////////////////////////////////////////////////////// 35 | ////////////////////////////////////////////////////////////////////////// 36 | 37 | /// Write 38 | ByteBuffer &ByteBuffer::operator<<(uint8_t pValue) 39 | { 40 | Append(pValue); 41 | return *this; 42 | } 43 | /// Write 44 | ByteBuffer &ByteBuffer::operator<<(uint16_t pValue) 45 | { 46 | Append(pValue); 47 | return *this; 48 | } 49 | /// Write 50 | ByteBuffer &ByteBuffer::operator<<(uint32_t pValue) 51 | { 52 | Append(pValue); 53 | return *this; 54 | } 55 | /// Write 56 | ByteBuffer &ByteBuffer::operator<<(uint64_t pValue) 57 | { 58 | Append(pValue); 59 | return *this; 60 | } 61 | 62 | ////////////////////////////////////////////////////////////////////////// 63 | ////////////////////////////////////////////////////////////////////////// 64 | 65 | /// Write 66 | ByteBuffer &ByteBuffer::operator<<(int8_t pValue) 67 | { 68 | Append(pValue); 69 | return *this; 70 | } 71 | /// Write 72 | ByteBuffer &ByteBuffer::operator<<(int16_t pValue) 73 | { 74 | Append(pValue); 75 | return *this; 76 | } 77 | /// Write 78 | ByteBuffer &ByteBuffer::operator<<(int32_t pValue) 79 | { 80 | Append(pValue); 81 | return *this; 82 | } 83 | /// Write 84 | ByteBuffer &ByteBuffer::operator<<(int64_t pValue) 85 | { 86 | Append(pValue); 87 | return *this; 88 | } 89 | 90 | ////////////////////////////////////////////////////////////////////////// 91 | ////////////////////////////////////////////////////////////////////////// 92 | 93 | /// Write 94 | ByteBuffer &ByteBuffer::operator<<(float pValue) 95 | { 96 | Append(pValue); 97 | return *this; 98 | } 99 | 100 | ////////////////////////////////////////////////////////////////////////// 101 | ////////////////////////////////////////////////////////////////////////// 102 | 103 | /// Write 104 | ByteBuffer &ByteBuffer::operator<<(const std::string &pValue) 105 | { 106 | Append((uint8_t const *)pValue.c_str(), pValue.length()); 107 | Append((uint8_t)0); 108 | return *this; 109 | } 110 | /// Write 111 | ByteBuffer &ByteBuffer::operator<<(const char *pStr) 112 | { 113 | Append((uint8_t const *)pStr, pStr ? strlen(pStr) : 0); 114 | Append((uint8_t)0); 115 | return *this; 116 | } 117 | 118 | ////////////////////////////////////////////////////////////////////////// 119 | ////////////////////////////////////////////////////////////////////////// 120 | 121 | /// Read 122 | ByteBuffer &ByteBuffer::operator>>(bool &pValue) 123 | { 124 | pValue = Read() > 0 ? true : false; 125 | return *this; 126 | } 127 | 128 | ////////////////////////////////////////////////////////////////////////// 129 | ////////////////////////////////////////////////////////////////////////// 130 | 131 | /// Read 132 | ByteBuffer &ByteBuffer::operator>>(uint8_t &pValue) 133 | { 134 | pValue = Read(); 135 | return *this; 136 | } 137 | /// Read 138 | ByteBuffer &ByteBuffer::operator>>(uint16_t &pValue) 139 | { 140 | pValue = Read(); 141 | return *this; 142 | } 143 | /// Read 144 | ByteBuffer &ByteBuffer::operator>>(uint32_t &pValue) 145 | { 146 | pValue = Read(); 147 | return *this; 148 | } 149 | /// Read 150 | ByteBuffer &ByteBuffer::operator>>(uint64_t &pValue) 151 | { 152 | pValue = Read(); 153 | return *this; 154 | } 155 | 156 | ////////////////////////////////////////////////////////////////////////// 157 | ////////////////////////////////////////////////////////////////////////// 158 | 159 | /// Read 160 | ByteBuffer &ByteBuffer::operator>>(int8_t &pValue) 161 | { 162 | pValue = Read(); 163 | return *this; 164 | } 165 | /// Read 166 | ByteBuffer &ByteBuffer::operator>>(int16_t &pValue) 167 | { 168 | pValue = Read(); 169 | return *this; 170 | } 171 | /// Read 172 | ByteBuffer &ByteBuffer::operator>>(int32_t &pValue) 173 | { 174 | pValue = Read(); 175 | return *this; 176 | } 177 | /// Read 178 | ByteBuffer &ByteBuffer::operator>>(int64_t &pValue) 179 | { 180 | pValue = Read(); 181 | return *this; 182 | } 183 | 184 | ////////////////////////////////////////////////////////////////////////// 185 | ////////////////////////////////////////////////////////////////////////// 186 | 187 | /// Read 188 | ByteBuffer &ByteBuffer::operator>>(float &pValue) 189 | { 190 | pValue = Read(); 191 | return *this; 192 | } 193 | 194 | ////////////////////////////////////////////////////////////////////////// 195 | ////////////////////////////////////////////////////////////////////////// 196 | 197 | /// Read 198 | ByteBuffer &ByteBuffer::operator>>(std::string& pValue) 199 | { 200 | pValue.clear(); 201 | while (ReadPosition() < GetSize()) 202 | { 203 | char lC = Read(); 204 | if (lC == 0) 205 | break; 206 | pValue += lC; 207 | } 208 | return *this; 209 | } 210 | /// Read 211 | uint8_t ByteBuffer::operator[](size_t pos) const 212 | { 213 | return Read(pos); 214 | } 215 | 216 | ////////////////////////////////////////////////////////////////////////// 217 | ////////////////////////////////////////////////////////////////////////// 218 | 219 | /// Get read pos 220 | size_t ByteBuffer::ReadPosition() const 221 | { 222 | return m_ReadPos; 223 | } 224 | /// Set read pos 225 | size_t ByteBuffer::ReadPosition(size_t pValue) 226 | { 227 | m_ReadPos = pValue; 228 | return m_ReadPos; 229 | } 230 | 231 | ////////////////////////////////////////////////////////////////////////// 232 | ////////////////////////////////////////////////////////////////////////// 233 | 234 | /// Read finis ? 235 | void ByteBuffer::ReadFinish() 236 | { 237 | m_ReadPos = WritePos(); 238 | } 239 | 240 | ////////////////////////////////////////////////////////////////////////// 241 | ////////////////////////////////////////////////////////////////////////// 242 | 243 | /// Get write pos 244 | size_t ByteBuffer::WritePos() const 245 | { 246 | return m_WritePos; 247 | } 248 | /// Set write pos 249 | size_t ByteBuffer::WritePos(size_t pValue) 250 | { 251 | m_WritePos = pValue; 252 | return m_WritePos; 253 | } 254 | 255 | ////////////////////////////////////////////////////////////////////////// 256 | ////////////////////////////////////////////////////////////////////////// 257 | 258 | /// Skip read of an element 259 | void ByteBuffer::ReadSkip(size_t pSkip) 260 | { 261 | //if (m_ReadPos + pSkip > GetSize()) 262 | // throw Core::Exception::Core(__FILE__, __LINE__, "Read skip overflow"); 263 | 264 | m_ReadPos += pSkip; 265 | } 266 | 267 | ////////////////////////////////////////////////////////////////////////// 268 | ////////////////////////////////////////////////////////////////////////// 269 | 270 | /// Read 271 | void ByteBuffer::Read(uint8_t *pDest, size_t pLen) 272 | { 273 | //if (m_ReadPos + pLen > GetSize()) 274 | // throw Core::Exception::Core(__FILE__, __LINE__, "Read overflow"); 275 | 276 | memcpy(pDest, &m_Storage[m_ReadPos], pLen); 277 | m_ReadPos += pLen; 278 | } 279 | 280 | ////////////////////////////////////////////////////////////////////////// 281 | ////////////////////////////////////////////////////////////////////////// 282 | 283 | /// Read a fixed length ASCII string 284 | /// @p_Size : String size 285 | std::string ByteBuffer::ReadFixedString(std::size_t p_Size) 286 | { 287 | //if (m_ReadPos + p_Size > GetSize()) 288 | // throw Core::Exception::Core(__FILE__, __LINE__, "Read overflow"); 289 | 290 | std::string l_String(&m_Storage[m_ReadPos], &m_Storage[m_ReadPos + p_Size]); 291 | m_ReadPos += p_Size; 292 | 293 | return l_String; 294 | } 295 | /// Write a fixed length ASCII string 296 | /// @p_Str : The string 297 | /// @p_Size : Full size 298 | void ByteBuffer::WriteFixedString(std::string p_Str, std::size_t p_Size) 299 | { 300 | std::size_t l_StringLen = p_Str.length() > p_Size ? p_Size : p_Str.length(); 301 | Append((char*)&p_Str[0], l_StringLen); 302 | 303 | std::size_t l_PaddingSize = p_Size - l_StringLen; 304 | 305 | for (std::size_t l_I = 0; l_I < l_PaddingSize; ++l_I) 306 | (*this) << uint8_t(0); 307 | } 308 | 309 | ////////////////////////////////////////////////////////////////////////// 310 | ////////////////////////////////////////////////////////////////////////// 311 | 312 | /// Get contents 313 | const uint8_t * ByteBuffer::GetData() const 314 | { 315 | return &m_Storage[0]; 316 | } 317 | 318 | ////////////////////////////////////////////////////////////////////////// 319 | ////////////////////////////////////////////////////////////////////////// 320 | 321 | /// Get Size 322 | size_t ByteBuffer::GetSize() const 323 | { 324 | return m_Storage.size(); 325 | } 326 | /// Get is empty 327 | bool ByteBuffer::IsEmpty() const 328 | { 329 | return m_Storage.empty(); 330 | } 331 | 332 | ////////////////////////////////////////////////////////////////////////// 333 | ////////////////////////////////////////////////////////////////////////// 334 | 335 | /// Resize 336 | void ByteBuffer::Resise(size_t pNewSize) 337 | { 338 | m_Storage.resize(pNewSize); 339 | m_ReadPos = 0; 340 | m_WritePos = GetSize(); 341 | } 342 | /// Reserve 343 | void ByteBuffer::Reserve(size_t pResize) 344 | { 345 | if (pResize > GetSize()) 346 | m_Storage.reserve(pResize); 347 | } 348 | 349 | ////////////////////////////////////////////////////////////////////////// 350 | ////////////////////////////////////////////////////////////////////////// 351 | 352 | /// Append string 353 | void ByteBuffer::Append(const std::string& pStr) 354 | { 355 | Append((uint8_t const*)pStr.c_str(), pStr.size() + 1); 356 | } 357 | /// Append string 358 | void ByteBuffer::Append(const char *pSrc, size_t pCnt) 359 | { 360 | return Append((const uint8_t *)pSrc, pCnt); 361 | } 362 | /// Append 363 | void ByteBuffer::Append(const uint8_t *pSrc, size_t pCnt) 364 | { 365 | if (!pCnt) 366 | return; 367 | 368 | //assert(GetSize() < 10000000); 369 | 370 | if (m_Storage.size() < m_WritePos + pCnt) 371 | m_Storage.resize(m_WritePos + pCnt); 372 | 373 | memcpy(&m_Storage[m_WritePos], pSrc, pCnt); 374 | 375 | m_WritePos += pCnt; 376 | } 377 | /// Append 378 | void ByteBuffer::Append(const ByteBuffer& pBuffer) 379 | { 380 | if (pBuffer.WritePos()) 381 | Append(pBuffer.GetData(), pBuffer.WritePos()); 382 | } 383 | 384 | ////////////////////////////////////////////////////////////////////////// 385 | ////////////////////////////////////////////////////////////////////////// 386 | 387 | /// Put 388 | void ByteBuffer::Put(size_t pPos, const uint8_t *pSrc, size_t pCount) 389 | { 390 | //if (pPos + pCount > GetSize()) 391 | // throw Core::Exception::Core(__FILE__, __LINE__, "Put overflow"); 392 | 393 | memcpy(&m_Storage[pPos], pSrc, pCount); 394 | } 395 | 396 | ////////////////////////////////////////////////////////////////////////// 397 | ////////////////////////////////////////////////////////////////////////// 398 | 399 | /// Read a pack GUID 400 | uint64_t ByteBuffer::ReadPackGUID() 401 | { 402 | uint64_t l_GUID = 0; 403 | uint8_t l_GUIDMark = 0; 404 | (*this) >> l_GUIDMark; 405 | 406 | for (int l_I = 0; l_I < 8; ++l_I) 407 | { 408 | if (l_GUIDMark & (uint8_t(1) << l_I)) 409 | { 410 | uint8_t l_Bit; 411 | (*this) >> l_Bit; 412 | l_GUID |= (uint64_t(l_Bit) << (l_I * 8)); 413 | } 414 | } 415 | 416 | return l_GUID; 417 | } 418 | 419 | } ///< namespace Network 420 | } ///< namespace RCN -------------------------------------------------------------------------------- /Network/ByteBuffer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace RCN { namespace Network { 8 | 9 | /// Byte buffer class 10 | class ByteBuffer 11 | { 12 | public: 13 | const static size_t DEFAULT_SIZE = 0x1000; 14 | 15 | /// Constructor 16 | ByteBuffer(); 17 | /// Constructor 18 | ByteBuffer(size_t res); 19 | /// Constructor 20 | ByteBuffer(const ByteBuffer &buf); 21 | 22 | /// Clear 23 | void Clear(); 24 | 25 | /// Append 26 | template void Append(T pValue); 27 | /// Put 28 | template void Put(size_t pPos, T pValue); 29 | 30 | ////////////////////////////////////////////////////////////////////////// 31 | ////////////////////////////////////////////////////////////////////////// 32 | 33 | /// Write 34 | ByteBuffer &operator<<(uint8_t pValue); 35 | /// Write 36 | ByteBuffer &operator<<(uint16_t pValue); 37 | /// Write 38 | ByteBuffer &operator<<(uint32_t pValue); 39 | /// Write 40 | ByteBuffer &operator<<(uint64_t pValue); 41 | 42 | /// Write 43 | ByteBuffer &operator<<(int8_t pValue); 44 | /// Write 45 | ByteBuffer &operator<<(int16_t pValue); 46 | /// Write 47 | ByteBuffer &operator<<(int32_t pValue); 48 | /// Write 49 | ByteBuffer &operator<<(int64_t pValue); 50 | 51 | /// Write 52 | ByteBuffer &operator<<(float pValue); 53 | /// Write 54 | ByteBuffer &operator<<(double pValue); 55 | 56 | /// Write 57 | ByteBuffer &operator<<(const std::string &pValue); 58 | /// Write 59 | ByteBuffer &operator<<(const char *pStr); 60 | 61 | ////////////////////////////////////////////////////////////////////////// 62 | ////////////////////////////////////////////////////////////////////////// 63 | 64 | /// Read 65 | ByteBuffer &operator>>(bool &pValue); 66 | 67 | /// Read 68 | ByteBuffer &operator>>(uint8_t &pValue); 69 | /// Read 70 | ByteBuffer &operator>>(uint16_t &pValue); 71 | /// Read 72 | ByteBuffer &operator>>(uint32_t &pValue); 73 | /// Read 74 | ByteBuffer &operator>>(uint64_t &pValue); 75 | 76 | /// Read 77 | ByteBuffer &operator>>(int8_t &pValue); 78 | /// Read 79 | ByteBuffer &operator>>(int16_t &pValue); 80 | /// Read 81 | ByteBuffer &operator>>(int32_t &pValue); 82 | /// Read 83 | ByteBuffer &operator>>(int64_t &pValue); 84 | 85 | /// Read 86 | ByteBuffer &operator>>(float &pValue); 87 | 88 | /// Read 89 | ByteBuffer &operator>>(std::string& pValue); 90 | /// Read 91 | uint8_t operator[](size_t pos) const; 92 | 93 | ////////////////////////////////////////////////////////////////////////// 94 | ////////////////////////////////////////////////////////////////////////// 95 | 96 | /// Get read pos 97 | size_t ReadPosition() const; 98 | /// Set read pos 99 | size_t ReadPosition(size_t pValue); 100 | 101 | /// Read finis ? 102 | void ReadFinish(); 103 | 104 | /// Get write pos 105 | size_t WritePos() const; 106 | /// Set write pos 107 | size_t WritePos(size_t pValue); 108 | 109 | /// Skip read of an element 110 | template void ReadSkip(); 111 | 112 | /// Skip read of an element 113 | void ReadSkip(size_t pSkip); 114 | 115 | /// Read 116 | template T Read(); 117 | /// Read 118 | template T Read(size_t pPos) const; 119 | 120 | /// Read 121 | void Read(uint8_t *pDest, size_t pLen); 122 | 123 | /// Read a fixed length ASCII string 124 | /// @p_Size : String size 125 | std::string ReadFixedString(std::size_t p_Size); 126 | /// Write a fixed length ASCII string 127 | /// @p_Str : The string 128 | /// @p_Size : Full size 129 | void WriteFixedString(std::string p_Str, std::size_t p_Size); 130 | 131 | /// Get contents 132 | const uint8_t * GetData() const; 133 | 134 | /// Get Size 135 | size_t GetSize() const; 136 | /// Get is empty 137 | bool IsEmpty() const; 138 | 139 | /// Resize 140 | void Resise(size_t pNewSize); 141 | /// Reserve 142 | void Reserve(size_t pRessize); 143 | 144 | /// Append string 145 | void Append(const std::string& pStr); 146 | /// Append string 147 | void Append(const char *pSrc, size_t pCnt); 148 | 149 | /// Append 150 | template void Append(const T *pSrc, size_t pCnt); 151 | 152 | /// Append 153 | void Append(const uint8_t *pSrc, size_t pCnt); 154 | /// Append 155 | void Append(const ByteBuffer& pBuffer); 156 | 157 | /// Put 158 | void Put(size_t pPos, const uint8_t *pSrc, size_t pCount); 159 | 160 | /// Read a pack GUID 161 | uint64_t ReadPackGUID(); 162 | 163 | protected: 164 | size_t m_ReadPos; /// Read position 165 | size_t m_WritePos; /// Write position 166 | 167 | std::vector m_Storage; /// Data 168 | 169 | }; 170 | 171 | #include "ByteBuffer.inl" 172 | 173 | } ///< namespace Network 174 | } ///< namespace RCN -------------------------------------------------------------------------------- /Network/ByteBuffer.inl: -------------------------------------------------------------------------------- 1 | /// Append 2 | template void ByteBuffer::Append(T p_Value) 3 | { 4 | Append((uint8_t *)&p_Value, sizeof(p_Value)); 5 | } 6 | /// Put 7 | template void ByteBuffer::Put(size_t p_Pos, T p_Value) 8 | { 9 | Put(p_Pos, (uint8_t *)&p_Value, sizeof(p_Value)); 10 | } 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | ////////////////////////////////////////////////////////////////////////// 14 | 15 | /// Skip read of an element 16 | template void ByteBuffer::ReadSkip() 17 | { 18 | ReadSkip(sizeof(T)); 19 | } 20 | 21 | ////////////////////////////////////////////////////////////////////////// 22 | ////////////////////////////////////////////////////////////////////////// 23 | 24 | /// Read 25 | template T ByteBuffer::Read() 26 | { 27 | T l_Res = Read(m_ReadPos); 28 | m_ReadPos += sizeof(T); 29 | return l_Res; 30 | } 31 | /// Read 32 | template T ByteBuffer::Read(size_t p_Pos) const 33 | { 34 | //if (p_Pos + sizeof(T) > GetSize()) 35 | // throw Core::Exception::Core(__FILE__, __LINE__, "Read overflow"); 36 | 37 | T l_Val = *((T const*)&m_Storage[p_Pos]); 38 | return l_Val; 39 | } 40 | 41 | ////////////////////////////////////////////////////////////////////////// 42 | ////////////////////////////////////////////////////////////////////////// 43 | 44 | /// Append 45 | template void Append(const T *p_Src, size_t p_Cnt) 46 | { 47 | return Append((const uint8_t *)p_Src, p_Cnt * sizeof(T)); 48 | } 49 | -------------------------------------------------------------------------------- /Network/TCPClient.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPClient.hpp" 2 | 3 | namespace RCN { namespace Network { 4 | 5 | /// Constructor 6 | TCPClient::TCPClient() 7 | { 8 | m_Socket = socket(AF_INET, SOCK_STREAM, 0); 9 | } 10 | /// Destructor 11 | TCPClient::~TCPClient() 12 | { 13 | closesocket(m_Socket); 14 | } 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | ////////////////////////////////////////////////////////////////////////// 18 | 19 | /// Connect to a server 20 | /// @p_Address : Server address 21 | /// @p_Port : Server port 22 | bool TCPClient::Connect(std::string p_Address, uint16_t p_Port) 23 | { 24 | std::lock_guard l_Lock(m_Mutex); 25 | 26 | struct sockaddr_in l_Sin; 27 | 28 | /// DNS based address 29 | if (inet_addr(p_Address.c_str()) == -1) 30 | { 31 | struct hostent *l_Hostent; 32 | struct in_addr **l_AddrList; 33 | 34 | /// Query the DNS local service 35 | if ((l_Hostent = gethostbyname(p_Address.c_str())) == NULL) 36 | return false; 37 | 38 | /// Get address list 39 | l_AddrList = (struct in_addr **)l_Hostent->h_addr_list; 40 | 41 | /// Pick first valid IP address 42 | for (int l_I = 0; l_AddrList[l_I] != NULL; l_I++) 43 | { 44 | l_Sin.sin_addr = *l_AddrList[l_I]; 45 | break; 46 | } 47 | } 48 | else 49 | { 50 | /// Single IP address 51 | l_Sin.sin_addr.s_addr = inet_addr(p_Address.c_str()); 52 | } 53 | 54 | l_Sin.sin_family = AF_INET; ///< IPV4 mode 55 | l_Sin.sin_port = htons(p_Port); ///< Reverse port into big endian 56 | 57 | if (connect(m_Socket, (struct sockaddr*)&l_Sin, sizeof(l_Sin)) < 0) 58 | return false; 59 | 60 | return true; 61 | } 62 | /// Disconnect 63 | void TCPClient::Disconnect() 64 | { 65 | std::lock_guard l_Lock(m_Mutex); 66 | closesocket(m_Socket); 67 | 68 | m_Socket = INVALID_SOCKET; 69 | } 70 | 71 | ////////////////////////////////////////////////////////////////////////// 72 | ////////////////////////////////////////////////////////////////////////// 73 | 74 | /// Send data 75 | /// @p_Data : Buffer 76 | /// @p_Size : Buffer size 77 | bool TCPClient::Send(const uint8_t* p_Data, uint32_t p_Size) 78 | { 79 | std::lock_guard l_Lock(m_Mutex); 80 | 81 | size_t l_Remaining = p_Size; 82 | char *l_BufPtr = (char*)p_Data; 83 | 84 | while (l_Remaining > 0) 85 | { 86 | size_t l_SentLen = send(m_Socket, l_BufPtr, l_Remaining, 0); 87 | if (l_SentLen <= 0) 88 | return false; 89 | 90 | l_Remaining -= l_SentLen; 91 | l_BufPtr += l_SentLen; 92 | } 93 | 94 | return true; 95 | } 96 | /// Receive data 97 | /// @p_Dest : Destination buffer 98 | /// @p_Size : Waiting size 99 | bool TCPClient::Receive(uint8_t* p_Dest, uint32_t p_Size) 100 | { 101 | //std::lock_guard l_Lock(m_Mutex); 102 | 103 | size_t l_Remaining = p_Size; 104 | char *l_BufPtr = (char*)p_Dest; 105 | 106 | while (l_Remaining > 0) 107 | { 108 | size_t l_ReceivedLen = recv(m_Socket, l_BufPtr, l_Remaining, 0); 109 | if (l_ReceivedLen <= 0) 110 | return false; 111 | 112 | l_Remaining -= l_ReceivedLen; 113 | l_BufPtr += l_ReceivedLen; 114 | } 115 | 116 | return true; 117 | } 118 | 119 | } ///< namespace Network 120 | } ///< namespace RCN -------------------------------------------------------------------------------- /Network/TCPClient.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define _WINSOCK_DEPRECATED_NO_WARNINGS 1 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #pragma comment(lib, "ws2_32.lib") 11 | 12 | namespace RCN { namespace Network { 13 | 14 | class TCPClient 15 | { 16 | public: 17 | /// Constructor 18 | TCPClient(); 19 | /// Destructor 20 | ~TCPClient(); 21 | 22 | /// Connect to a server 23 | /// @p_Address : Server address 24 | /// @p_Port : Server port 25 | bool Connect(std::string p_Address, uint16_t p_Port); 26 | /// Disconnect 27 | void Disconnect(); 28 | 29 | /// Send data 30 | /// @p_Data : Buffer 31 | /// @p_Size : Buffer size 32 | bool Send(const uint8_t* p_Data, uint32_t p_Size); 33 | /// Receive data 34 | /// @p_Dest : Destination buffer 35 | /// @p_Size : Waiting size 36 | bool Receive(uint8_t* p_Dest, uint32_t p_Size); 37 | 38 | private: 39 | std::mutex m_Mutex; ///< Mutex 40 | SOCKET m_Socket; ///< Socket ID 41 | }; 42 | 43 | } ///< namespace Network 44 | } ///< namespace RCN -------------------------------------------------------------------------------- /Utils/UtilsEndian.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace RCN { namespace Utils { 6 | 7 | namespace ByteConverter 8 | { 9 | /// Convert data 10 | /// @p_Data : Data to convert 11 | template inline void Convert(char* p_Data) 12 | { 13 | std::swap(*p_Data, *(p_Data + T - 1)); 14 | Convert(p_Data + 1); 15 | } 16 | 17 | /// Ignore null size data 18 | /// @p_Data : Data to convert 19 | template<> inline void Convert<0>(char* p_Data) 20 | { 21 | } 22 | /// Ignore central byte 23 | /// @p_Data : Data to convert 24 | template<> inline void Convert<1>(char* p_Data) 25 | { 26 | } 27 | 28 | /// Endian convert 29 | /// @p_Data : Data to convert 30 | template inline void Apply(T* p_Data) 31 | { 32 | Convert((char*)(p_Data)); 33 | } 34 | } 35 | 36 | } ///< namespace Utils 37 | } ///< namespace RCN -------------------------------------------------------------------------------- /Utils/UtilsString.cpp: -------------------------------------------------------------------------------- 1 | #include "UtilsString.hpp" 2 | #include 3 | 4 | namespace RCN { namespace Utils { 5 | 6 | /// Split string 7 | /// @p_Src ; Source 8 | /// @p_Delimeter : Token 9 | /// @p_KeepEmpty : Keep empty parts 10 | std::vector Split(const std::string& p_Str, const std::string& p_Delimiter, const bool p_KeepEmpty) 11 | { 12 | std::vector l_Result; 13 | if (p_Delimiter.empty()) 14 | { 15 | l_Result.push_back(p_Str); 16 | return l_Result; 17 | } 18 | 19 | std::string::const_iterator l_SubStart = p_Str.begin(), l_SubEnd; 20 | while (true) 21 | { 22 | l_SubEnd = std::search(l_SubStart, p_Str.end(), p_Delimiter.begin(), p_Delimiter.end()); 23 | 24 | std::string l_Temp(l_SubStart, l_SubEnd); 25 | 26 | if (p_KeepEmpty || !l_Temp.empty()) 27 | l_Result.push_back(l_Temp); 28 | 29 | if (l_SubEnd == p_Str.end()) 30 | break; 31 | 32 | l_SubStart = l_SubEnd + p_Delimiter.size(); 33 | } 34 | 35 | return l_Result; 36 | } 37 | 38 | } ///< namespace Utils 39 | } ///< namespace RCN -------------------------------------------------------------------------------- /Utils/UtilsString.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace RCN { namespace Utils { 7 | 8 | /// Split string 9 | /// @p_Src ; Source 10 | /// @p_Delimeter : Token 11 | /// @p_KeepEmpty : Keep empty parts 12 | std::vector Split(const std::string& p_Str, const std::string& p_Delimiter, const bool p_KeepEmpty = true); 13 | 14 | } ///< namespace Utils 15 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Entities/WorldEObject.cpp: -------------------------------------------------------------------------------- 1 | #include "WorldEObject.hpp" 2 | 3 | namespace RCN { namespace World { namespace Entities { 4 | 5 | /// Constructor 6 | Object::Object() 7 | { 8 | 9 | } 10 | /// Destructor 11 | Object::~Object() 12 | { 13 | 14 | } 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | ////////////////////////////////////////////////////////////////////////// 18 | 19 | 20 | 21 | } ///< namespace Entities 22 | } ///< namespace World 23 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Entities/WorldEObject.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Enums/WorldEnums.hpp" 4 | #include "WorldEUpdateFields.hpp" 5 | 6 | namespace RCN { namespace World { namespace Entities { 7 | 8 | struct Position 9 | { 10 | /// Constructor 11 | Position() 12 | : X(0.0f), Y(0.0f), Z(0.0f), O(0.0f) 13 | { 14 | 15 | } 16 | 17 | float X, Y, Z, O; 18 | }; 19 | 20 | ////////////////////////////////////////////////////////////////////////// 21 | ////////////////////////////////////////////////////////////////////////// 22 | 23 | class Object 24 | { 25 | public: 26 | /// Constructor 27 | Object(); 28 | /// Destructor 29 | virtual ~Object(); 30 | 31 | }; 32 | 33 | } ///< namespace Entities 34 | } ///< namespace World 35 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Entities/WorldEUnit.cpp: -------------------------------------------------------------------------------- 1 | #include "WorldEUnit.hpp" 2 | 3 | namespace RCN { namespace World { namespace Entities { 4 | 5 | /// Constructor 6 | MovementInfo::MovementInfo() 7 | { 8 | MovementFlags = 0; 9 | Time = 0; 10 | Pos.X = 0.0f; 11 | Pos.Y = 0.0f; 12 | Pos.Z = 0.0f; 13 | Pos.O = 0.0f; 14 | Pitch = 0.0f; 15 | SplineElevation = 0.0f; 16 | FallTime = 0; 17 | 18 | ClearTransportData(); 19 | ClearJumpInfoData(); 20 | } 21 | 22 | ////////////////////////////////////////////////////////////////////////// 23 | ////////////////////////////////////////////////////////////////////////// 24 | 25 | /// Add movement flag 26 | /// @p_Flags : New flags 27 | void MovementInfo::AddMovementFlag(Enums::MovementFlags::Type p_Flag) 28 | { 29 | this->MovementFlags |= p_Flag; 30 | } 31 | /// Remove movement flag 32 | /// @p_Flags : Old flags 33 | void MovementInfo::RemoveMovementFlag(Enums::MovementFlags::Type p_Flag) 34 | { 35 | this->MovementFlags &= ~p_Flag; 36 | } 37 | /// Set movement flag 38 | /// @p_Flags : New flags 39 | bool MovementInfo::HasMovementFlag(Enums::MovementFlags::Type p_Flag) const 40 | { 41 | return (this->MovementFlags & p_Flag) != 0; 42 | } 43 | /// Set movement flag 44 | /// @p_Flags : New flags 45 | void MovementInfo::SetMovementFlags(Enums::MovementFlags::Type p_Flags) 46 | { 47 | this->MovementFlags = p_Flags; 48 | } 49 | 50 | ////////////////////////////////////////////////////////////////////////// 51 | ////////////////////////////////////////////////////////////////////////// 52 | 53 | /// Set transport data 54 | /// @p_GUID : Transport GUID 55 | /// @p_X : Transport X offset 56 | /// @p_Y : Transport Y offset 57 | /// @p_Z : Transport Z offset 58 | /// @p_O : Transport O offset 59 | /// @p_Time : Transport time 60 | void MovementInfo::SetTransportData(uint64_t p_GUID, float p_X, float p_Y, float p_Z, float p_O, uint32_t p_Time) 61 | { 62 | this->Transport.GUID = p_GUID; 63 | this->Transport.Pos.X = p_X; 64 | this->Transport.Pos.Y = p_Y; 65 | this->Transport.Pos.Z = p_Z; 66 | this->Transport.Pos.O = p_O; 67 | this->Transport.Time = p_Time; 68 | } 69 | /// Set jump info data 70 | /// @p_Velocity : Jump weight 71 | /// @p_SinAngle : Jump X axis coord 72 | /// @p_CosAngle : Jump Y axis coord 73 | /// @p_XYZSpeed : Jump axis speed 74 | void MovementInfo::SetJumpInfoData(float p_Velocity, float p_SinAngle, float p_CosAngle, float p_XYZSpeed) 75 | { 76 | this->JumpInfo.Velocity = p_Velocity; 77 | this->JumpInfo.SinAngle = p_SinAngle; 78 | this->JumpInfo.CosAngle = p_CosAngle; 79 | this->JumpInfo.XYZSpeed = p_XYZSpeed; 80 | } 81 | 82 | /// Reset transport data 83 | void MovementInfo::ClearTransportData() 84 | { 85 | this->Transport.GUID = 0; 86 | this->Transport.Pos.X = 0.0f; 87 | this->Transport.Pos.Y = 0.0f; 88 | this->Transport.Pos.Z = 0.0f; 89 | this->Transport.Pos.O = 0.0f; 90 | this->Transport.Time = 0; 91 | } 92 | /// Reset jump info data 93 | void MovementInfo::ClearJumpInfoData() 94 | { 95 | this->JumpInfo.Velocity = 0.0f; 96 | this->JumpInfo.SinAngle = 0.0f; 97 | this->JumpInfo.CosAngle = 0.0f; 98 | this->JumpInfo.XYZSpeed = 0.0f; 99 | } 100 | 101 | ////////////////////////////////////////////////////////////////////////// 102 | ////////////////////////////////////////////////////////////////////////// 103 | ////////////////////////////////////////////////////////////////////////// 104 | ////////////////////////////////////////////////////////////////////////// 105 | 106 | 107 | 108 | } ///< namespace Entities 109 | } ///< namespace World 110 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Entities/WorldEUnit.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "WorldEObject.hpp" 4 | 5 | namespace RCN { namespace World { namespace Entities { 6 | 7 | class MovementInfo 8 | { 9 | public: 10 | /// Constructor 11 | MovementInfo(); 12 | 13 | // void Read(ByteBuffer& data); 14 | // void Write(ByteBuffer& data) const; 15 | 16 | /// Add movement flag 17 | /// @p_Flags : New flags 18 | void AddMovementFlag(Enums::MovementFlags::Type p_Flag); 19 | /// Remove movement flag 20 | /// @p_Flags : Old flags 21 | void RemoveMovementFlag(Enums::MovementFlags::Type p_Flag); 22 | /// Set movement flag 23 | /// @p_Flags : New flags 24 | bool HasMovementFlag(Enums::MovementFlags::Type p_Flag) const; 25 | /// Set movement flag 26 | /// @p_Flags : New flags 27 | void SetMovementFlags(Enums::MovementFlags::Type p_Flags); 28 | 29 | /// Set transport data 30 | /// @p_GUID : Transport GUID 31 | /// @p_X : Transport X offset 32 | /// @p_Y : Transport Y offset 33 | /// @p_Z : Transport Z offset 34 | /// @p_O : Transport O offset 35 | /// @p_Time : Transport time 36 | void SetTransportData(uint64_t p_GUID, float p_X, float p_Y, float p_Z, float p_O, uint32_t p_Time); 37 | /// Set jump info data 38 | /// @p_Velocity : Jump weight 39 | /// @p_SinAngle : Jump X axis coord 40 | /// @p_CosAngle : Jump Y axis coord 41 | /// @p_XYZSpeed : Jump axis speed 42 | void SetJumpInfoData(float p_Velocity, float p_SinAngle, float p_CosAngle, float p_XYZSpeed); 43 | 44 | /// Reset transport data 45 | void ClearTransportData(); 46 | /// Reset jump info data 47 | void ClearJumpInfoData(); 48 | 49 | public: 50 | uint32_t MovementFlags; 51 | uint32_t Time; 52 | Position Pos; 53 | float Pitch; 54 | float SplineElevation; 55 | uint32_t FallTime; 56 | 57 | struct 58 | { 59 | uint64_t GUID; ///< Transport GUID 60 | Position Pos; ///< Transport position offset 61 | uint32_t Time; ///< Transport time 62 | } Transport; 63 | 64 | struct 65 | { 66 | float Velocity; ///< Jump weight 67 | float SinAngle; ///< Jump X axis coord 68 | float CosAngle; ///< Jump Y axis coord 69 | float XYZSpeed; ///< Jump axis speed 70 | } JumpInfo; 71 | 72 | }; 73 | 74 | ////////////////////////////////////////////////////////////////////////// 75 | ////////////////////////////////////////////////////////////////////////// 76 | 77 | class Unit : public Object 78 | { 79 | public: 80 | /// Constructor 81 | Unit(); 82 | /// Destructor 83 | virtual ~Unit(); 84 | 85 | }; 86 | 87 | } ///< namespace Entities 88 | } ///< namespace World 89 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Entities/WorldEUpdateFields.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace RCN { namespace World { namespace Entities { 6 | 7 | /// Object fields 8 | namespace ObjectFields 9 | { 10 | enum Type 11 | { 12 | OBJECT_FIELD_GUID = 0x00, // Size:2 13 | OBJECT_FIELD_TYPE = 0x02, // Size:1 14 | OBJECT_FIELD_ENTRY = 0x03, // Size:1 15 | OBJECT_FIELD_SCALE_X = 0x04, // Size:1 16 | OBJECT_FIELD_PADDING = 0x05, // Size:1 17 | OBJECT_END = 0x06, 18 | }; 19 | } 20 | 21 | /// Item fields 22 | namespace ItemFields 23 | { 24 | enum Type 25 | { 26 | ITEM_FIELD_OWNER = ObjectFields::OBJECT_END + 0x00, // Size:2 27 | ITEM_FIELD_CONTAINED = ObjectFields::OBJECT_END + 0x02, // Size:2 28 | ITEM_FIELD_CREATOR = ObjectFields::OBJECT_END + 0x04, // Size:2 29 | ITEM_FIELD_GIFTCREATOR = ObjectFields::OBJECT_END + 0x06, // Size:2 30 | ITEM_FIELD_STACK_COUNT = ObjectFields::OBJECT_END + 0x08, // Size:1 31 | ITEM_FIELD_DURATION = ObjectFields::OBJECT_END + 0x09, // Size:1 32 | ITEM_FIELD_SPELL_CHARGES = ObjectFields::OBJECT_END + 0x0A, // Size:5 33 | ITEM_FIELD_SPELL_CHARGES_01 = ObjectFields::OBJECT_END + 0x0B, 34 | ITEM_FIELD_SPELL_CHARGES_02 = ObjectFields::OBJECT_END + 0x0C, 35 | ITEM_FIELD_SPELL_CHARGES_03 = ObjectFields::OBJECT_END + 0x0D, 36 | ITEM_FIELD_SPELL_CHARGES_04 = ObjectFields::OBJECT_END + 0x0E, 37 | ITEM_FIELD_FLAGS = ObjectFields::OBJECT_END + 0x0F, // Size:1 38 | ITEM_FIELD_ENCHANTMENT = ObjectFields::OBJECT_END + 0x10, // count=21 39 | ITEM_FIELD_PROPERTY_SEED = ObjectFields::OBJECT_END + 0x25, // Size:1 40 | ITEM_FIELD_RANDOM_PROPERTIES_ID = ObjectFields::OBJECT_END + 0x26, // Size:1 41 | ITEM_FIELD_ITEM_TEXT_ID = ObjectFields::OBJECT_END + 0x27, // Size:1 42 | ITEM_FIELD_DURABILITY = ObjectFields::OBJECT_END + 0x28, // Size:1 43 | ITEM_FIELD_MAXDURABILITY = ObjectFields::OBJECT_END + 0x29, // Size:1 44 | ITEM_END = ObjectFields::OBJECT_END + 0x2A, 45 | }; 46 | } 47 | 48 | /// Container fields 49 | namespace ContainerFields 50 | { 51 | enum Type 52 | { 53 | CONTAINER_FIELD_NUM_SLOTS = ItemFields::ITEM_END + 0x00, // Size:1 54 | CONTAINER_ALIGN_PAD = ItemFields::ITEM_END + 0x01, // Size:1 55 | CONTAINER_FIELD_SLOT_1 = ItemFields::ITEM_END + 0x02, // count=56 56 | CONTAINER_FIELD_SLOT_LAST = ItemFields::ITEM_END + 0x38, 57 | CONTAINER_END = ItemFields::ITEM_END + 0x3A, 58 | }; 59 | } 60 | 61 | /// Unit fields 62 | namespace UnitFields 63 | { 64 | enum Type 65 | { 66 | UNIT_FIELD_CHARM = 0x00 + ObjectFields::OBJECT_END, // Size:2 67 | UNIT_FIELD_SUMMON = 0x02 + ObjectFields::OBJECT_END, // Size:2 68 | UNIT_FIELD_CHARMEDBY = 0x04 + ObjectFields::OBJECT_END, // Size:2 69 | UNIT_FIELD_SUMMONEDBY = 0x06 + ObjectFields::OBJECT_END, // Size:2 70 | UNIT_FIELD_CREATEDBY = 0x08 + ObjectFields::OBJECT_END, // Size:2 71 | UNIT_FIELD_TARGET = 0x0A + ObjectFields::OBJECT_END, // Size:2 72 | UNIT_FIELD_PERSUADED = 0x0C + ObjectFields::OBJECT_END, // Size:2 73 | UNIT_FIELD_CHANNEL_OBJECT = 0x0E + ObjectFields::OBJECT_END, // Size:2 74 | UNIT_FIELD_HEALTH = 0x10 + ObjectFields::OBJECT_END, // Size:1 75 | UNIT_FIELD_POWER1 = 0x11 + ObjectFields::OBJECT_END, // Size:1 76 | UNIT_FIELD_POWER2 = 0x12 + ObjectFields::OBJECT_END, // Size:1 77 | UNIT_FIELD_POWER3 = 0x13 + ObjectFields::OBJECT_END, // Size:1 78 | UNIT_FIELD_POWER4 = 0x14 + ObjectFields::OBJECT_END, // Size:1 79 | UNIT_FIELD_POWER5 = 0x15 + ObjectFields::OBJECT_END, // Size:1 80 | UNIT_FIELD_MAXHEALTH = 0x16 + ObjectFields::OBJECT_END, // Size:1 81 | UNIT_FIELD_MAXPOWER1 = 0x17 + ObjectFields::OBJECT_END, // Size:1 82 | UNIT_FIELD_MAXPOWER2 = 0x18 + ObjectFields::OBJECT_END, // Size:1 83 | UNIT_FIELD_MAXPOWER3 = 0x19 + ObjectFields::OBJECT_END, // Size:1 84 | UNIT_FIELD_MAXPOWER4 = 0x1A + ObjectFields::OBJECT_END, // Size:1 85 | UNIT_FIELD_MAXPOWER5 = 0x1B + ObjectFields::OBJECT_END, // Size:1 86 | UNIT_FIELD_LEVEL = 0x1C + ObjectFields::OBJECT_END, // Size:1 87 | UNIT_FIELD_FACTIONTEMPLATE = 0x1D + ObjectFields::OBJECT_END, // Size:1 88 | UNIT_FIELD_BYTES_0 = 0x1E + ObjectFields::OBJECT_END, // Size:1 89 | UNIT_VIRTUAL_ITEM_SLOT_DISPLAY = 0x1F + ObjectFields::OBJECT_END, // Size:3 90 | UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01 = 0x20 + ObjectFields::OBJECT_END, 91 | UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02 = 0x21 + ObjectFields::OBJECT_END, 92 | UNIT_VIRTUAL_ITEM_INFO = 0x22 + ObjectFields::OBJECT_END, // Size:6 93 | UNIT_VIRTUAL_ITEM_INFO_01 = 0x23 + ObjectFields::OBJECT_END, 94 | UNIT_VIRTUAL_ITEM_INFO_02 = 0x24 + ObjectFields::OBJECT_END, 95 | UNIT_VIRTUAL_ITEM_INFO_03 = 0x25 + ObjectFields::OBJECT_END, 96 | UNIT_VIRTUAL_ITEM_INFO_04 = 0x26 + ObjectFields::OBJECT_END, 97 | UNIT_VIRTUAL_ITEM_INFO_05 = 0x27 + ObjectFields::OBJECT_END, 98 | UNIT_FIELD_FLAGS = 0x28 + ObjectFields::OBJECT_END, // Size:1 99 | UNIT_FIELD_AURA = 0x29 + ObjectFields::OBJECT_END, // Size:48 100 | UNIT_FIELD_AURA_LAST = 0x58 + ObjectFields::OBJECT_END, 101 | UNIT_FIELD_AURAFLAGS = 0x59 + ObjectFields::OBJECT_END, // Size:6 102 | UNIT_FIELD_AURAFLAGS_01 = 0x5a + ObjectFields::OBJECT_END, 103 | UNIT_FIELD_AURAFLAGS_02 = 0x5b + ObjectFields::OBJECT_END, 104 | UNIT_FIELD_AURAFLAGS_03 = 0x5c + ObjectFields::OBJECT_END, 105 | UNIT_FIELD_AURAFLAGS_04 = 0x5d + ObjectFields::OBJECT_END, 106 | UNIT_FIELD_AURAFLAGS_05 = 0x5e + ObjectFields::OBJECT_END, 107 | UNIT_FIELD_AURALEVELS = 0x5f + ObjectFields::OBJECT_END, // Size:12 108 | UNIT_FIELD_AURALEVELS_LAST = 0x6a + ObjectFields::OBJECT_END, 109 | UNIT_FIELD_AURAAPPLICATIONS = 0x6b + ObjectFields::OBJECT_END, // Size:12 110 | UNIT_FIELD_AURAAPPLICATIONS_LAST = 0x76 + ObjectFields::OBJECT_END, 111 | UNIT_FIELD_AURASTATE = 0x77 + ObjectFields::OBJECT_END, // Size:1 112 | UNIT_FIELD_BASEATTACKTIME = 0x78 + ObjectFields::OBJECT_END, // Size:2 113 | UNIT_FIELD_OFFHANDATTACKTIME = 0x79 + ObjectFields::OBJECT_END, // Size:2 114 | UNIT_FIELD_RANGEDATTACKTIME = 0x7a + ObjectFields::OBJECT_END, // Size:1 115 | UNIT_FIELD_BOUNDINGRADIUS = 0x7b + ObjectFields::OBJECT_END, // Size:1 116 | UNIT_FIELD_COMBATREACH = 0x7c + ObjectFields::OBJECT_END, // Size:1 117 | UNIT_FIELD_DISPLAYID = 0x7d + ObjectFields::OBJECT_END, // Size:1 118 | UNIT_FIELD_NATIVEDISPLAYID = 0x7e + ObjectFields::OBJECT_END, // Size:1 119 | UNIT_FIELD_MOUNTDISPLAYID = 0x7f + ObjectFields::OBJECT_END, // Size:1 120 | UNIT_FIELD_MINDAMAGE = 0x80 + ObjectFields::OBJECT_END, // Size:1 121 | UNIT_FIELD_MAXDAMAGE = 0x81 + ObjectFields::OBJECT_END, // Size:1 122 | UNIT_FIELD_MINOFFHANDDAMAGE = 0x82 + ObjectFields::OBJECT_END, // Size:1 123 | UNIT_FIELD_MAXOFFHANDDAMAGE = 0x83 + ObjectFields::OBJECT_END, // Size:1 124 | UNIT_FIELD_BYTES_1 = 0x84 + ObjectFields::OBJECT_END, // Size:1 125 | UNIT_FIELD_PETNUMBER = 0x85 + ObjectFields::OBJECT_END, // Size:1 126 | UNIT_FIELD_PET_NAME_TIMESTAMP = 0x86 + ObjectFields::OBJECT_END, // Size:1 127 | UNIT_FIELD_PETEXPERIENCE = 0x87 + ObjectFields::OBJECT_END, // Size:1 128 | UNIT_FIELD_PETNEXTLEVELEXP = 0x88 + ObjectFields::OBJECT_END, // Size:1 129 | UNIT_DYNAMIC_FLAGS = 0x89 + ObjectFields::OBJECT_END, // Size:1 130 | UNIT_CHANNEL_SPELL = 0x8a + ObjectFields::OBJECT_END, // Size:1 131 | UNIT_MOD_CAST_SPEED = 0x8b + ObjectFields::OBJECT_END, // Size:1 132 | UNIT_CREATED_BY_SPELL = 0x8c + ObjectFields::OBJECT_END, // Size:1 133 | UNIT_NPC_FLAGS = 0x8d + ObjectFields::OBJECT_END, // Size:1 134 | UNIT_NPC_EMOTESTATE = 0x8e + ObjectFields::OBJECT_END, // Size:1 135 | UNIT_TRAINING_POINTS = 0x8f + ObjectFields::OBJECT_END, // Size:1 136 | UNIT_FIELD_STAT0 = 0x90 + ObjectFields::OBJECT_END, // Size:1 137 | UNIT_FIELD_STAT1 = 0x91 + ObjectFields::OBJECT_END, // Size:1 138 | UNIT_FIELD_STAT2 = 0x92 + ObjectFields::OBJECT_END, // Size:1 139 | UNIT_FIELD_STAT3 = 0x93 + ObjectFields::OBJECT_END, // Size:1 140 | UNIT_FIELD_STAT4 = 0x94 + ObjectFields::OBJECT_END, // Size:1 141 | UNIT_FIELD_RESISTANCES = 0x95 + ObjectFields::OBJECT_END, // Size:7 142 | UNIT_FIELD_RESISTANCES_01 = 0x96 + ObjectFields::OBJECT_END, 143 | UNIT_FIELD_RESISTANCES_02 = 0x97 + ObjectFields::OBJECT_END, 144 | UNIT_FIELD_RESISTANCES_03 = 0x98 + ObjectFields::OBJECT_END, 145 | UNIT_FIELD_RESISTANCES_04 = 0x99 + ObjectFields::OBJECT_END, 146 | UNIT_FIELD_RESISTANCES_05 = 0x9a + ObjectFields::OBJECT_END, 147 | UNIT_FIELD_RESISTANCES_06 = 0x9b + ObjectFields::OBJECT_END, 148 | UNIT_FIELD_BASE_MANA = 0x9c + ObjectFields::OBJECT_END, // Size:1 149 | UNIT_FIELD_BASE_HEALTH = 0x9d + ObjectFields::OBJECT_END, // Size:1 150 | UNIT_FIELD_BYTES_2 = 0x9e + ObjectFields::OBJECT_END, // Size:1 151 | UNIT_FIELD_ATTACK_POWER = 0x9f + ObjectFields::OBJECT_END, // Size:1 152 | UNIT_FIELD_ATTACK_POWER_MODS = 0xa0 + ObjectFields::OBJECT_END, // Size:1 153 | UNIT_FIELD_ATTACK_POWER_MULTIPLIER = 0xa1 + ObjectFields::OBJECT_END, // Size:1 154 | UNIT_FIELD_RANGED_ATTACK_POWER = 0xa2 + ObjectFields::OBJECT_END, // Size:1 155 | UNIT_FIELD_RANGED_ATTACK_POWER_MODS = 0xa3 + ObjectFields::OBJECT_END, // Size:1 156 | UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = 0xa4 + ObjectFields::OBJECT_END, // Size:1 157 | UNIT_FIELD_MINRANGEDDAMAGE = 0xa5 + ObjectFields::OBJECT_END, // Size:1 158 | UNIT_FIELD_MAXRANGEDDAMAGE = 0xa6 + ObjectFields::OBJECT_END, // Size:1 159 | UNIT_FIELD_POWER_COST_MODIFIER = 0xa7 + ObjectFields::OBJECT_END, // Size:7 160 | UNIT_FIELD_POWER_COST_MODIFIER_01 = 0xa8 + ObjectFields::OBJECT_END, 161 | UNIT_FIELD_POWER_COST_MODIFIER_02 = 0xa9 + ObjectFields::OBJECT_END, 162 | UNIT_FIELD_POWER_COST_MODIFIER_03 = 0xaa + ObjectFields::OBJECT_END, 163 | UNIT_FIELD_POWER_COST_MODIFIER_04 = 0xab + ObjectFields::OBJECT_END, 164 | UNIT_FIELD_POWER_COST_MODIFIER_05 = 0xac + ObjectFields::OBJECT_END, 165 | UNIT_FIELD_POWER_COST_MODIFIER_06 = 0xad + ObjectFields::OBJECT_END, 166 | UNIT_FIELD_POWER_COST_MULTIPLIER = 0xae + ObjectFields::OBJECT_END, // Size:7 167 | UNIT_FIELD_POWER_COST_MULTIPLIER_01 = 0xaf + ObjectFields::OBJECT_END, 168 | UNIT_FIELD_POWER_COST_MULTIPLIER_02 = 0xb0 + ObjectFields::OBJECT_END, 169 | UNIT_FIELD_POWER_COST_MULTIPLIER_03 = 0xb1 + ObjectFields::OBJECT_END, 170 | UNIT_FIELD_POWER_COST_MULTIPLIER_04 = 0xb2 + ObjectFields::OBJECT_END, 171 | UNIT_FIELD_POWER_COST_MULTIPLIER_05 = 0xb3 + ObjectFields::OBJECT_END, 172 | UNIT_FIELD_POWER_COST_MULTIPLIER_06 = 0xb4 + ObjectFields::OBJECT_END, 173 | UNIT_FIELD_PADDING = 0xb5 + ObjectFields::OBJECT_END, 174 | UNIT_END = 0xb6 + ObjectFields::OBJECT_END, 175 | }; 176 | } 177 | 178 | /// Player fields 179 | namespace PlayerFields 180 | { 181 | enum Type 182 | { 183 | PLAYER_DUEL_ARBITER = 0x000 + UnitFields::UNIT_END, // Size:2 184 | PLAYER_FLAGS = 0x002 + UnitFields::UNIT_END, // Size:1 185 | PLAYER_GUILDID = 0x003 + UnitFields::UNIT_END, // Size:1 186 | PLAYER_GUILDRANK = 0x004 + UnitFields::UNIT_END, // Size:1 187 | PLAYER_BYTES = 0x005 + UnitFields::UNIT_END, // Size:1 188 | PLAYER_BYTES_2 = 0x006 + UnitFields::UNIT_END, // Size:1 189 | PLAYER_BYTES_3 = 0x007 + UnitFields::UNIT_END, // Size:1 190 | PLAYER_DUEL_TEAM = 0x008 + UnitFields::UNIT_END, // Size:1 191 | PLAYER_GUILD_TIMESTAMP = 0x009 + UnitFields::UNIT_END, // Size:1 192 | PLAYER_QUEST_LOG_1_1 = 0x00A + UnitFields::UNIT_END, // count = 20 193 | PLAYER_QUEST_LOG_1_2 = 0x00B + UnitFields::UNIT_END, 194 | PLAYER_QUEST_LOG_1_3 = 0x00C + UnitFields::UNIT_END, 195 | PLAYER_QUEST_LOG_LAST_1 = 0x043 + UnitFields::UNIT_END, 196 | PLAYER_QUEST_LOG_LAST_2 = 0x044 + UnitFields::UNIT_END, 197 | PLAYER_QUEST_LOG_LAST_3 = 0x045 + UnitFields::UNIT_END, 198 | PLAYER_VISIBLE_ITEM_1_CREATOR = 0x046 + UnitFields::UNIT_END, // Size:2, count = 19 199 | PLAYER_VISIBLE_ITEM_1_0 = 0x048 + UnitFields::UNIT_END, // Size:8 200 | PLAYER_VISIBLE_ITEM_1_PROPERTIES = 0x050 + UnitFields::UNIT_END, // Size:1 201 | PLAYER_VISIBLE_ITEM_1_PAD = 0x051 + UnitFields::UNIT_END, // Size:1 202 | PLAYER_VISIBLE_ITEM_LAST_CREATOR = 0x11E + UnitFields::UNIT_END, 203 | PLAYER_VISIBLE_ITEM_LAST_0 = 0x120 + UnitFields::UNIT_END, 204 | PLAYER_VISIBLE_ITEM_LAST_PROPERTIES = 0x128 + UnitFields::UNIT_END, 205 | PLAYER_VISIBLE_ITEM_LAST_PAD = 0x129 + UnitFields::UNIT_END, 206 | PLAYER_FIELD_INV_SLOT_HEAD = 0x12A + UnitFields::UNIT_END, // Size:46 207 | PLAYER_FIELD_PACK_SLOT_1 = 0x158 + UnitFields::UNIT_END, // Size:32 208 | PLAYER_FIELD_PACK_SLOT_LAST = 0x176 + UnitFields::UNIT_END, 209 | PLAYER_FIELD_BANK_SLOT_1 = 0x178 + UnitFields::UNIT_END, // Size:48 210 | PLAYER_FIELD_BANK_SLOT_LAST = 0x1A6 + UnitFields::UNIT_END, 211 | PLAYER_FIELD_BANKBAG_SLOT_1 = 0x1A8 + UnitFields::UNIT_END, // Size:12 212 | PLAYER_FIELD_BANKBAG_SLOT_LAST = 0xAB2 + UnitFields::UNIT_END, 213 | PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = 0x1B4 + UnitFields::UNIT_END, // Size:24 214 | PLAYER_FIELD_VENDORBUYBACK_SLOT_LAST = 0x1CA + UnitFields::UNIT_END, 215 | PLAYER_FIELD_KEYRING_SLOT_1 = 0x1CC + UnitFields::UNIT_END, // Size:64 216 | PLAYER_FIELD_KEYRING_SLOT_LAST = 0x20A + UnitFields::UNIT_END, 217 | PLAYER_FARSIGHT = 0x20C + UnitFields::UNIT_END, // Size:2 218 | PLAYER_FIELD_COMBO_TARGET = 0x20E + UnitFields::UNIT_END, // Size:2 219 | PLAYER_XP = 0x210 + UnitFields::UNIT_END, // Size:1 220 | PLAYER_NEXT_LEVEL_XP = 0x211 + UnitFields::UNIT_END, // Size:1 221 | PLAYER_SKILL_INFO_1_1 = 0x212 + UnitFields::UNIT_END, // Size:384 222 | PLAYER_CHARACTER_POINTS1 = 0x392 + UnitFields::UNIT_END, // Size:1 223 | PLAYER_CHARACTER_POINTS2 = 0x393 + UnitFields::UNIT_END, // Size:1 224 | PLAYER_TRACK_CREATURES = 0x394 + UnitFields::UNIT_END, // Size:1 225 | PLAYER_TRACK_RESOURCES = 0x395 + UnitFields::UNIT_END, // Size:1 226 | PLAYER_BLOCK_PERCENTAGE = 0x396 + UnitFields::UNIT_END, // Size:1 227 | PLAYER_DODGE_PERCENTAGE = 0x397 + UnitFields::UNIT_END, // Size:1 228 | PLAYER_PARRY_PERCENTAGE = 0x398 + UnitFields::UNIT_END, // Size:1 229 | PLAYER_CRIT_PERCENTAGE = 0x399 + UnitFields::UNIT_END, // Size:1 230 | PLAYER_RANGED_CRIT_PERCENTAGE = 0x39A + UnitFields::UNIT_END, // Size:1 231 | PLAYER_EXPLORED_ZONES_1 = 0x39B + UnitFields::UNIT_END, // Size:64 232 | PLAYER_REST_STATE_EXPERIENCE = 0x3DB + UnitFields::UNIT_END, // Size:1 233 | PLAYER_FIELD_COINAGE = 0x3DC + UnitFields::UNIT_END, // Size:1 234 | PLAYER_FIELD_POSSTAT0 = 0x3DD + UnitFields::UNIT_END, // Size:1 235 | PLAYER_FIELD_POSSTAT1 = 0x3DE + UnitFields::UNIT_END, // Size:1 236 | PLAYER_FIELD_POSSTAT2 = 0x3DF + UnitFields::UNIT_END, // Size:1 237 | PLAYER_FIELD_POSSTAT3 = 0x3E0 + UnitFields::UNIT_END, // Size:1 238 | PLAYER_FIELD_POSSTAT4 = 0x3E1 + UnitFields::UNIT_END, // Size:1 239 | PLAYER_FIELD_NEGSTAT0 = 0x3E2 + UnitFields::UNIT_END, // Size:1 240 | PLAYER_FIELD_NEGSTAT1 = 0x3E3 + UnitFields::UNIT_END, // Size:1 241 | PLAYER_FIELD_NEGSTAT2 = 0x3E4 + UnitFields::UNIT_END, // Size:1 242 | PLAYER_FIELD_NEGSTAT3 = 0x3E5 + UnitFields::UNIT_END, // Size:1, 243 | PLAYER_FIELD_NEGSTAT4 = 0x3E6 + UnitFields::UNIT_END, // Size:1 244 | PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE = 0x3E7 + UnitFields::UNIT_END, // Size:7 245 | PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE = 0x3EE + UnitFields::UNIT_END, // Size:7 246 | PLAYER_FIELD_MOD_DAMAGE_DONE_POS = 0x3F5 + UnitFields::UNIT_END, // Size:7 247 | PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = 0x3FC + UnitFields::UNIT_END, // Size:7 248 | PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = 0x403 + UnitFields::UNIT_END, // Size:7 249 | PLAYER_FIELD_BYTES = 0x40A + UnitFields::UNIT_END, // Size:1 250 | PLAYER_AMMO_ID = 0x40B + UnitFields::UNIT_END, // Size:1 251 | PLAYER_SELF_RES_SPELL = 0x40C + UnitFields::UNIT_END, // Size:1 252 | PLAYER_FIELD_PVP_MEDALS = 0x40D + UnitFields::UNIT_END, // Size:1 253 | PLAYER_FIELD_BUYBACK_PRICE_1 = 0x40E + UnitFields::UNIT_END, // count=12 254 | PLAYER_FIELD_BUYBACK_PRICE_LAST = 0x419 + UnitFields::UNIT_END, 255 | PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = 0x41A + UnitFields::UNIT_END, // count=12 256 | PLAYER_FIELD_BUYBACK_TIMESTAMP_LAST = 0x425 + UnitFields::UNIT_END, 257 | PLAYER_FIELD_SESSION_KILLS = 0x426 + UnitFields::UNIT_END, // Size:1 258 | PLAYER_FIELD_YESTERDAY_KILLS = 0x427 + UnitFields::UNIT_END, // Size:1 259 | PLAYER_FIELD_LAST_WEEK_KILLS = 0x428 + UnitFields::UNIT_END, // Size:1 260 | PLAYER_FIELD_THIS_WEEK_KILLS = 0x429 + UnitFields::UNIT_END, // Size:1 261 | PLAYER_FIELD_THIS_WEEK_CONTRIBUTION = 0x42A + UnitFields::UNIT_END, // Size:1 262 | PLAYER_FIELD_LIFETIME_HONORABLE_KILLS = 0x42B + UnitFields::UNIT_END, // Size:1 263 | PLAYER_FIELD_LIFETIME_DISHONORABLE_KILLS = 0x42c + UnitFields::UNIT_END, // Size:1 264 | PLAYER_FIELD_YESTERDAY_CONTRIBUTION = 0x42D + UnitFields::UNIT_END, // Size:1 265 | PLAYER_FIELD_LAST_WEEK_CONTRIBUTION = 0x42E + UnitFields::UNIT_END, // Size:1 266 | PLAYER_FIELD_LAST_WEEK_RANK = 0x42F + UnitFields::UNIT_END, // Size:1 267 | PLAYER_FIELD_BYTES2 = 0x430 + UnitFields::UNIT_END, // Size:1 268 | PLAYER_FIELD_WATCHED_FACTION_INDEX = 0x431 + UnitFields::UNIT_END, // Size:1 269 | PLAYER_FIELD_COMBAT_RATING_1 = 0x432 + UnitFields::UNIT_END, // Size:20 270 | PLAYER_END = 0x446 + UnitFields::UNIT_END 271 | }; 272 | } 273 | 274 | /// GameObject fields 275 | namespace GameObjectFields 276 | { 277 | enum Type 278 | { 279 | GAMEOBJECT_CREATED_BY = ObjectFields::OBJECT_END + 0x00, 280 | GAMEOBJECT_DISPLAYID = ObjectFields::OBJECT_END + 0x02, 281 | GAMEOBJECT_FLAGS = ObjectFields::OBJECT_END + 0x03, 282 | GAMEOBJECT_ROTATION = ObjectFields::OBJECT_END + 0x04, 283 | GAMEOBJECT_STATE = ObjectFields::OBJECT_END + 0x08, 284 | GAMEOBJECT_POS_X = ObjectFields::OBJECT_END + 0x09, 285 | GAMEOBJECT_POS_Y = ObjectFields::OBJECT_END + 0x0A, 286 | GAMEOBJECT_POS_Z = ObjectFields::OBJECT_END + 0x0B, 287 | GAMEOBJECT_FACING = ObjectFields::OBJECT_END + 0x0C, 288 | GAMEOBJECT_DYN_FLAGS = ObjectFields::OBJECT_END + 0x0D, 289 | GAMEOBJECT_FACTION = ObjectFields::OBJECT_END + 0x0E, 290 | GAMEOBJECT_TYPE_ID = ObjectFields::OBJECT_END + 0x0F, 291 | GAMEOBJECT_LEVEL = ObjectFields::OBJECT_END + 0x10, 292 | GAMEOBJECT_ARTKIT = ObjectFields::OBJECT_END + 0x11, 293 | GAMEOBJECT_ANIMPROGRESS = ObjectFields::OBJECT_END + 0x12, 294 | GAMEOBJECT_PADDING = ObjectFields::OBJECT_END + 0x13, 295 | GAMEOBJECT_END = ObjectFields::OBJECT_END + 0x14, 296 | }; 297 | } 298 | 299 | /// DynamicObject fields 300 | namespace DynamicObjectFields 301 | { 302 | enum Type 303 | { 304 | DYNAMICOBJECT_CASTER = ObjectFields::OBJECT_END + 0x00, 305 | DYNAMICOBJECT_BYTES = ObjectFields::OBJECT_END + 0x02, 306 | DYNAMICOBJECT_SPELLID = ObjectFields::OBJECT_END + 0x03, 307 | DYNAMICOBJECT_RADIUS = ObjectFields::OBJECT_END + 0x04, 308 | DYNAMICOBJECT_POS_X = ObjectFields::OBJECT_END + 0x05, 309 | DYNAMICOBJECT_POS_Y = ObjectFields::OBJECT_END + 0x06, 310 | DYNAMICOBJECT_POS_Z = ObjectFields::OBJECT_END + 0x07, 311 | DYNAMICOBJECT_FACING = ObjectFields::OBJECT_END + 0x08, 312 | DYNAMICOBJECT_PAD = ObjectFields::OBJECT_END + 0x09, 313 | DYNAMICOBJECT_END = ObjectFields::OBJECT_END + 0x0A, 314 | }; 315 | } 316 | 317 | /// Corpse fields 318 | namespace CorpseFields 319 | { 320 | enum Type 321 | { 322 | CORPSE_FIELD_OWNER = ObjectFields::OBJECT_END + 0x00, 323 | CORPSE_FIELD_FACING = ObjectFields::OBJECT_END + 0x02, 324 | CORPSE_FIELD_POS_X = ObjectFields::OBJECT_END + 0x03, 325 | CORPSE_FIELD_POS_Y = ObjectFields::OBJECT_END + 0x04, 326 | CORPSE_FIELD_POS_Z = ObjectFields::OBJECT_END + 0x05, 327 | CORPSE_FIELD_DISPLAY_ID = ObjectFields::OBJECT_END + 0x06, 328 | CORPSE_FIELD_ITEM = ObjectFields::OBJECT_END + 0x07, // 19 329 | CORPSE_FIELD_BYTES_1 = ObjectFields::OBJECT_END + 0x1A, 330 | CORPSE_FIELD_BYTES_2 = ObjectFields::OBJECT_END + 0x1B, 331 | CORPSE_FIELD_GUILD = ObjectFields::OBJECT_END + 0x1C, 332 | CORPSE_FIELD_FLAGS = ObjectFields::OBJECT_END + 0x1D, 333 | CORPSE_FIELD_DYNAMIC_FLAGS = ObjectFields::OBJECT_END + 0x1E, 334 | CORPSE_FIELD_PAD = ObjectFields::OBJECT_END + 0x1F, 335 | CORPSE_END = ObjectFields::OBJECT_END + 0x20, 336 | }; 337 | } 338 | 339 | } ///< namespace Entities 340 | } ///< namespace World 341 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Enums/WorldEnums.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace RCN { namespace World { namespace Enums { 6 | 7 | namespace ResponseCodes 8 | { 9 | enum Type : uint8_t 10 | { 11 | RESPONSE_SUCCESS = 0x00, 12 | RESPONSE_FAILURE = 0x01, 13 | RESPONSE_CANCELLED = 0x02, 14 | RESPONSE_DISCONNECTED = 0x03, 15 | RESPONSE_FAILED_TO_CONNECT = 0x04, 16 | RESPONSE_CONNECTED = 0x05, 17 | RESPONSE_VERSION_MISMATCH = 0x06, 18 | 19 | CSTATUS_CONNECTING = 0x07, 20 | CSTATUS_NEGOTIATING_SECURITY = 0x08, 21 | CSTATUS_NEGOTIATION_COMPLETE = 0x09, 22 | CSTATUS_NEGOTIATION_FAILED = 0x0A, 23 | CSTATUS_AUTHENTICATING = 0x0B, 24 | 25 | AUTH_OK = 0x0C, 26 | AUTH_FAILED = 0x0D, 27 | AUTH_REJECT = 0x0E, 28 | AUTH_BAD_SERVER_PROOF = 0x0F, 29 | AUTH_UNAVAILABLE = 0x10, 30 | AUTH_SYSTEM_ERROR = 0x11, 31 | AUTH_BILLING_ERROR = 0x12, 32 | AUTH_BILLING_EXPIRED = 0x13, 33 | AUTH_VERSION_MISMATCH = 0x14, 34 | AUTH_UNKNOWN_ACCOUNT = 0x15, 35 | AUTH_INCORRECT_PASSWORD = 0x16, 36 | AUTH_SESSION_EXPIRED = 0x17, 37 | AUTH_SERVER_SHUTTING_DOWN = 0x18, 38 | AUTH_ALREADY_LOGGING_IN = 0x19, 39 | AUTH_LOGIN_SERVER_NOT_FOUND = 0x1A, 40 | AUTH_WAIT_QUEUE = 0x1B, 41 | AUTH_BANNED = 0x1C, 42 | AUTH_ALREADY_ONLINE = 0x1D, 43 | AUTH_NO_TIME = 0x1E, 44 | AUTH_DB_BUSY = 0x1F, 45 | AUTH_SUSPENDED = 0x20, 46 | AUTH_PARENTAL_CONTROL = 0x21, 47 | AUTH_LOCKED_ENFORCED = 0x02, /// Unsure 48 | 49 | REALM_LIST_IN_PROGRESS = 0x22, 50 | REALM_LIST_SUCCESS = 0x23, 51 | REALM_LIST_FAILED = 0x24, 52 | REALM_LIST_INVALID = 0x25, 53 | REALM_LIST_REALM_NOT_FOUND = 0x26, 54 | 55 | ACCOUNT_CREATE_IN_PROGRESS = 0x27, 56 | ACCOUNT_CREATE_SUCCESS = 0x28, 57 | ACCOUNT_CREATE_FAILED = 0x29, 58 | 59 | CHAR_LIST_RETRIEVING = 0x2A, 60 | CHAR_LIST_RETRIEVED = 0x2B, 61 | CHAR_LIST_FAILED = 0x2C, 62 | 63 | CHAR_CREATE_IN_PROGRESS = 0x2D, 64 | CHAR_CREATE_SUCCESS = 0x2E, 65 | CHAR_CREATE_ERROR = 0x2F, 66 | CHAR_CREATE_FAILED = 0x30, 67 | CHAR_CREATE_NAME_IN_USE = 0x31, 68 | CHAR_CREATE_DISABLED = 0x3A, 69 | CHAR_CREATE_PVP_TEAMS_VIOLATION = 0x33, 70 | CHAR_CREATE_SERVER_LIMIT = 0x34, 71 | CHAR_CREATE_ACCOUNT_LIMIT = 0x35, 72 | CHAR_CREATE_SERVER_QUEUE = 0x30,/// UNSURE 73 | CHAR_CREATE_ONLY_EXISTING = 0x30,/// UNSURE 74 | 75 | CHAR_DELETE_IN_PROGRESS = 0x38, 76 | CHAR_DELETE_SUCCESS = 0x39, 77 | CHAR_DELETE_FAILED = 0x3A, 78 | CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x3A,/// UNSURE 79 | CHAR_DELETE_FAILED_GUILD_LEADER = 0x3A,/// UNSURE 80 | 81 | CHAR_LOGIN_IN_PROGRESS = 0x3B, 82 | CHAR_LOGIN_SUCCESS = 0x3C, 83 | CHAR_LOGIN_NO_WORLD = 0x3D, 84 | CHAR_LOGIN_DUPLICATE_CHARACTER = 0x3E, 85 | CHAR_LOGIN_NO_INSTANCES = 0x3F, 86 | CHAR_LOGIN_FAILED = 0x40, 87 | CHAR_LOGIN_DISABLED = 0x41, 88 | CHAR_LOGIN_NO_CHARACTER = 0x42, 89 | CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x40, /// UNSURE 90 | CHAR_LOGIN_LOCKED_BY_BILLING = 0x40, /// UNSURE 91 | 92 | CHAR_NAME_SUCCESS = 0x50, 93 | CHAR_NAME_FAILURE = 0x4F, 94 | CHAR_NAME_NO_NAME = 0x43, 95 | CHAR_NAME_TOO_SHORT = 0x44, 96 | CHAR_NAME_TOO_LONG = 0x45, 97 | CHAR_NAME_INVALID_CHARACTER = 0x46, 98 | CHAR_NAME_MIXED_LANGUAGES = 0x47, 99 | CHAR_NAME_PROFANE = 0x48, 100 | CHAR_NAME_RESERVED = 0x49, 101 | CHAR_NAME_INVALID_APOSTROPHE = 0x4A, 102 | CHAR_NAME_MULTIPLE_APOSTROPHES = 0x4B, 103 | CHAR_NAME_THREE_CONSECUTIVE = 0x4C, 104 | CHAR_NAME_INVALID_SPACE = 0x4D, 105 | CHAR_NAME_CONSECUTIVE_SPACES = 0x4E, 106 | CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x4E,/// UNSURE 107 | CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x4E,/// UNSURE 108 | CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x4E,/// UNSURE 109 | }; 110 | } 111 | 112 | namespace ObjectUpdateType 113 | { 114 | enum Type 115 | { 116 | UPDATETYPE_VALUES = 0, 117 | UPDATETYPE_MOVEMENT = 1, 118 | UPDATETYPE_CREATE_OBJECT = 2, 119 | UPDATETYPE_CREATE_OBJECT2 = 3, 120 | UPDATETYPE_OUT_OF_RANGE_OBJECTS = 4, 121 | UPDATETYPE_NEAR_OBJECTS = 5 122 | }; 123 | } 124 | 125 | namespace ObjectUpdateFlags 126 | { 127 | enum Type 128 | { 129 | UPDATEFLAG_NONE = 0x0000, 130 | UPDATEFLAG_SELF = 0x0001, 131 | UPDATEFLAG_TRANSPORT = 0x0002, 132 | UPDATEFLAG_FULLGUID = 0x0004, 133 | UPDATEFLAG_HIGHGUID = 0x0008, 134 | UPDATEFLAG_ALL = 0x0010, 135 | UPDATEFLAG_LIVING = 0x0020, 136 | UPDATEFLAG_HAS_POSITION = 0x0040 137 | }; 138 | } 139 | 140 | namespace UnitMoveType 141 | { 142 | enum Type 143 | { 144 | MOVE_WALK = 0, 145 | MOVE_RUN = 1, 146 | MOVE_RUN_BACK = 2, 147 | MOVE_SWIM = 3, 148 | MOVE_SWIM_BACK = 4, 149 | MOVE_TURN_RATE = 5, 150 | MAX 151 | }; 152 | } 153 | 154 | namespace MovementFlags 155 | { 156 | enum Type : uint32_t 157 | { 158 | MOVEFLAG_NONE = 0x00000000, 159 | MOVEFLAG_FORWARD = 0x00000001, 160 | MOVEFLAG_BACKWARD = 0x00000002, 161 | MOVEFLAG_STRAFE_LEFT = 0x00000004, 162 | MOVEFLAG_STRAFE_RIGHT = 0x00000008, 163 | MOVEFLAG_TURN_LEFT = 0x00000010, 164 | MOVEFLAG_TURN_RIGHT = 0x00000020, 165 | MOVEFLAG_PITCH_UP = 0x00000040, 166 | MOVEFLAG_PITCH_DOWN = 0x00000080, 167 | MOVEFLAG_WALK_MODE = 0x00000100, ///< Walking 168 | 169 | MOVEFLAG_LEVITATING = 0x00000400, 170 | MOVEFLAG_FLYING = 0x00000800, ///< [-ZERO] is it really need and correct value 171 | MOVEFLAG_FALLING = 0x00002000, 172 | MOVEFLAG_FALLINGFAR = 0x00004000, 173 | MOVEFLAG_SWIMMING = 0x00200000, ///< appears with fly flag also 174 | MOVEFLAG_SPLINE_ENABLED = 0x00400000, 175 | MOVEFLAG_CAN_FLY = 0x00800000, ///< [-ZERO] is it really need and correct value 176 | MOVEFLAG_FLYING_OLD = 0x01000000, ///< [-ZERO] is it really need and correct value 177 | 178 | MOVEFLAG_ONTRANSPORT = 0x02000000, ///< Used for flying on some creatures 179 | MOVEFLAG_SPLINE_ELEVATION = 0x04000000, ///< used for flight paths 180 | MOVEFLAG_ROOT = 0x08000000, ///< used for flight paths 181 | MOVEFLAG_WATERWALKING = 0x10000000, ///< prevent unit from falling through water 182 | MOVEFLAG_SAFE_FALL = 0x20000000, ///< active rogue safe fall spell (passive) 183 | MOVEFLAG_HOVER = 0x40000000 184 | }; 185 | } 186 | 187 | namespace EquipmentSlots 188 | { 189 | enum Type : uint16_t 190 | { 191 | EQUIPMENT_SLOT_START = 0, 192 | EQUIPMENT_SLOT_HEAD = 0, 193 | EQUIPMENT_SLOT_NECK = 1, 194 | EQUIPMENT_SLOT_SHOULDERS = 2, 195 | EQUIPMENT_SLOT_BODY = 3, 196 | EQUIPMENT_SLOT_CHEST = 4, 197 | EQUIPMENT_SLOT_WAIST = 5, 198 | EQUIPMENT_SLOT_LEGS = 6, 199 | EQUIPMENT_SLOT_FEET = 7, 200 | EQUIPMENT_SLOT_WRISTS = 8, 201 | EQUIPMENT_SLOT_HANDS = 9, 202 | EQUIPMENT_SLOT_FINGER1 = 10, 203 | EQUIPMENT_SLOT_FINGER2 = 11, 204 | EQUIPMENT_SLOT_TRINKET1 = 12, 205 | EQUIPMENT_SLOT_TRINKET2 = 13, 206 | EQUIPMENT_SLOT_BACK = 14, 207 | EQUIPMENT_SLOT_MAINHAND = 15, 208 | EQUIPMENT_SLOT_OFFHAND = 16, 209 | EQUIPMENT_SLOT_RANGED = 17, 210 | EQUIPMENT_SLOT_TABARD = 18, 211 | EQUIPMENT_SLOT_END = 19 212 | }; 213 | } 214 | 215 | namespace ChatMessageType 216 | { 217 | enum Type 218 | { 219 | CHAT_MSG_ADDON = 0xFFFFFFFF, 220 | CHAT_MSG_SAY = 0x00, 221 | CHAT_MSG_PARTY = 0x01, 222 | CHAT_MSG_RAID = 0x02, 223 | CHAT_MSG_GUILD = 0x03, 224 | CHAT_MSG_OFFICER = 0x04, 225 | CHAT_MSG_YELL = 0x05, 226 | CHAT_MSG_WHISPER = 0x06, 227 | CHAT_MSG_WHISPER_INFORM = 0x07, 228 | CHAT_MSG_EMOTE = 0x08, 229 | CHAT_MSG_TEXT_EMOTE = 0x09, 230 | CHAT_MSG_SYSTEM = 0x0A, 231 | CHAT_MSG_MONSTER_SAY = 0x0B, 232 | CHAT_MSG_MONSTER_YELL = 0x0C, 233 | CHAT_MSG_MONSTER_EMOTE = 0x0D, 234 | CHAT_MSG_CHANNEL = 0x0E, 235 | CHAT_MSG_CHANNEL_JOIN = 0x0F, 236 | CHAT_MSG_CHANNEL_LEAVE = 0x10, 237 | CHAT_MSG_CHANNEL_LIST = 0x11, 238 | CHAT_MSG_CHANNEL_NOTICE = 0x12, 239 | CHAT_MSG_CHANNEL_NOTICE_USER = 0x13, 240 | CHAT_MSG_AFK = 0x14, 241 | CHAT_MSG_DND = 0x15, 242 | CHAT_MSG_IGNORED = 0x16, 243 | CHAT_MSG_SKILL = 0x17, 244 | CHAT_MSG_LOOT = 0x18, 245 | CHAT_MSG_MONSTER_WHISPER = 0x1A, 246 | CHAT_MSG_BG_SYSTEM_NEUTRAL = 0x52, 247 | CHAT_MSG_BG_SYSTEM_ALLIANCE = 0x53, 248 | CHAT_MSG_BG_SYSTEM_HORDE = 0x54, 249 | CHAT_MSG_RAID_LEADER = 0x57, 250 | CHAT_MSG_RAID_WARNING = 0x58, 251 | CHAT_MSG_RAID_BOSS_WHISPER = 0x59, 252 | CHAT_MSG_RAID_BOSS_EMOTE = 0x5A, 253 | CHAT_MSG_BATTLEGROUND = 0x5C, 254 | CHAT_MSG_BATTLEGROUND_LEADER = 0x5D 255 | }; 256 | } 257 | 258 | } ///< namespace Enums 259 | } ///< namespace World 260 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Handlers/WorldHAuth.cpp: -------------------------------------------------------------------------------- 1 | #include "WorldHAuth.hpp" 2 | #include "../Enums/WorldEnums.hpp" 3 | #include "../Network/WorldOpcodes.hpp" 4 | #include "../../Crypto/SHA1.hpp" 5 | 6 | namespace RCN { namespace World { namespace Handlers { 7 | 8 | /// Handle SMSG_AUTH_CHALLENGE 9 | /// @p_Packet : Packet 10 | /// @p_Manager : World manager 11 | void Handle_AuthChallenge(Network::WorldPacket& p_Packet, WorldManager* p_Manager) 12 | { 13 | uint32_t l_ServerSeed = 0; 14 | p_Packet >> l_ServerSeed; 15 | 16 | uint32_t l_DigestUnk = 0; 17 | time_t l_ClientSeed = time(nullptr); 18 | 19 | Crypto::SHA1 l_SHA1; 20 | l_SHA1.UpdateData(p_Manager->GetAccountName()); 21 | l_SHA1.UpdateData(reinterpret_cast(&l_DigestUnk), sizeof(uint32_t)); 22 | l_SHA1.UpdateData(reinterpret_cast(&l_ClientSeed), sizeof(uint32_t)); 23 | l_SHA1.UpdateData(reinterpret_cast(&l_ServerSeed), sizeof(uint32_t)); 24 | l_SHA1.UpdateBigNumbers(&p_Manager->GetWorldSocket()->GetSessionKey(), nullptr); 25 | l_SHA1.Finalize(); 26 | 27 | static const uint8_t s_AddonData[] = 28 | { 29 | 0x56, 0x01, 0x00, 0x00, 0x78, 0x9C, 0x75, 0xCC, 0xBD, 0x0E, 0xC2, 0x30, 0x0C, 0x04, 0xE0, 0xF2, 30 | 0x1E, 0xBC, 0x0C, 0x61, 0x40, 0x95, 0xC8, 0x42, 0xC3, 0x8C, 0x4C, 0xE2, 0x22, 0x0B, 0xC7, 0xA9, 31 | 0x8C, 0xCB, 0x4F, 0x9F, 0x1E, 0x16, 0x24, 0x06, 0x73, 0xEB, 0x77, 0x77, 0x81, 0x69, 0x59, 0x40, 32 | 0xCB, 0x69, 0x33, 0x67, 0xA3, 0x26, 0xC7, 0xBE, 0x5B, 0xD5, 0xC7, 0x7A, 0xDF, 0x7D, 0x12, 0xBE, 33 | 0x16, 0xC0, 0x8C, 0x71, 0x24, 0xE4, 0x12, 0x49, 0xA8, 0xC2, 0xE4, 0x95, 0x48, 0x0A, 0xC9, 0xC5, 34 | 0x3D, 0xD8, 0xB6, 0x7A, 0x06, 0x4B, 0xF8, 0x34, 0x0F, 0x15, 0x46, 0x73, 0x67, 0xBB, 0x38, 0xCC, 35 | 0x7A, 0xC7, 0x97, 0x8B, 0xBD, 0xDC, 0x26, 0xCC, 0xFE, 0x30, 0x42, 0xD6, 0xE6, 0xCA, 0x01, 0xA8, 36 | 0xB8, 0x90, 0x80, 0x51, 0xFC, 0xB7, 0xA4, 0x50, 0x70, 0xB8, 0x12, 0xF3, 0x3F, 0x26, 0x41, 0xFD, 37 | 0xB5, 0x37, 0x90, 0x19, 0x66, 0x8F 38 | }; 39 | 40 | Network::WorldPacket l_Packet(Network::Opcodes::CMSG_AUTH_SESSION); 41 | l_Packet << uint32_t(5875); ///< Build 42 | l_Packet << uint32_t(0); ///< Unk 2 43 | l_Packet << p_Manager->GetAccountName(); ///< Account name 44 | l_Packet << uint32_t(l_ClientSeed); ///< ClientSeed 45 | l_Packet.Append(l_SHA1.GetDigest(), SHA_DIGEST_LENGTH); ///< Logon digest 46 | l_Packet.Append(&s_AddonData[0], sizeof(s_AddonData)); ///< Addon infos 47 | 48 | p_Manager->GetWorldSocket()->SendPacket(l_Packet); 49 | p_Manager->GetWorldSocket()->InitWoWCrypt(); 50 | } 51 | /// Handle SMSG_AUTH_RESULT 52 | /// @p_Packet : Packet 53 | /// @p_Manager : World manager 54 | void Handle_AuthResult(Network::WorldPacket& p_Packet, WorldManager* p_Manager) 55 | { 56 | uint8_t l_Result; 57 | p_Packet >> l_Result; 58 | 59 | if (l_Result == Enums::ResponseCodes::AUTH_OK) 60 | { 61 | printf("[WORLD] Auth success!!\n"); 62 | 63 | uint32_t l_BillingTimeRemaining = 0; 64 | uint32_t l_BillingPlanFlags = 0; 65 | uint32_t l_BillingTimeRested = 0; 66 | 67 | p_Packet >> l_BillingTimeRemaining; 68 | p_Packet >> l_BillingPlanFlags; 69 | p_Packet >> l_BillingTimeRested; 70 | 71 | Network::WorldPacket l_Packet(Network::Opcodes::CMSG_CHAR_ENUM); 72 | p_Manager->GetWorldSocket()->SendPacket(l_Packet); 73 | } 74 | else 75 | printf("[WORLD] Auth failed : %u\n", l_Result); 76 | } 77 | 78 | } ///< namespace Handlers 79 | } ///< namespace World 80 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Handlers/WorldHAuth.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Network/WorldPacket.hpp" 4 | #include "../WorldManager.hpp" 5 | 6 | namespace RCN { namespace World { namespace Handlers { 7 | 8 | /// Handle SMSG_AUTH_CHALLENGE 9 | /// @p_Packet : Packet 10 | /// @p_Manager : World manager 11 | void Handle_AuthChallenge(Network::WorldPacket& p_Packet, WorldManager* p_Manager); 12 | /// Handle SMSG_AUTH_RESULT 13 | /// @p_Packet : Packet 14 | /// @p_Manager : World manager 15 | void Handle_AuthResult(Network::WorldPacket& p_Packet, WorldManager* p_Manager); 16 | 17 | } ///< namespace Handlers 18 | } ///< namespace World 19 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Handlers/WorldHCharacters.cpp: -------------------------------------------------------------------------------- 1 | #include "WorldHCharacters.hpp" 2 | #include "../Enums/WorldEnums.hpp" 3 | #include "../Network/WorldOpcodes.hpp" 4 | 5 | namespace RCN { namespace World { namespace Handlers { 6 | 7 | /// Handle SMSG_AUTH_CHALLENGE 8 | /// @p_Packet : Packet 9 | /// @p_Manager : World manager 10 | void Handle_CharEnum(Network::WorldPacket& p_Packet, WorldManager* p_Manager) 11 | { 12 | uint8_t l_Num; 13 | p_Packet >> l_Num; 14 | 15 | for (uint8_t l_I = 0; l_I < l_Num; ++l_I) 16 | { 17 | std::string l_Name = ""; 18 | uint64_t l_GUID = 0; 19 | uint8_t l_Level = 0; 20 | float l_X = 0.0f; 21 | float l_Y = 0.0f; 22 | float l_Z = 0.0f; 23 | 24 | p_Packet >> l_GUID; 25 | p_Packet >> l_Name; 26 | p_Packet.ReadSkip(); ///< Race 27 | p_Packet.ReadSkip(); ///< Class 28 | p_Packet.ReadSkip(); ///< Gender 29 | 30 | p_Packet.ReadSkip(); ///< Skin 31 | p_Packet.ReadSkip(); ///< Face 32 | p_Packet.ReadSkip(); ///< HairStyle 33 | p_Packet.ReadSkip(); ///< HairColor 34 | p_Packet.ReadSkip(); ///< FacialHair 35 | 36 | p_Packet >> l_Level; 37 | p_Packet.ReadSkip(); ///< Zone 38 | p_Packet.ReadSkip(); ///< Map 39 | 40 | p_Packet >> l_X; 41 | p_Packet >> l_Y; 42 | p_Packet >> l_Z; 43 | 44 | p_Packet.ReadSkip(); ///< GuildID 45 | p_Packet.ReadSkip(); ///< CharFlags 46 | 47 | p_Packet.ReadSkip(); ///< PetDisplayID 48 | p_Packet.ReadSkip(); ///< PetLevel 49 | p_Packet.ReadSkip(); ///< PetFamily 50 | 51 | for (size_t l_Slot = Enums::EquipmentSlots::EQUIPMENT_SLOT_START; 52 | l_Slot < Enums::EquipmentSlots::EQUIPMENT_SLOT_END; 53 | ++l_Slot) 54 | { 55 | 56 | p_Packet.ReadSkip(); ///< DisplayID 57 | p_Packet.ReadSkip(); ///< InventoryType 58 | } 59 | 60 | p_Packet.ReadSkip(); ///< First bag display ID 61 | p_Packet.ReadSkip(); ///< Fist bag inventory type 62 | 63 | printf("[WORLD] Character %s(%llu) Level %u X %f Y %f Z %f\n", l_Name.c_str(), l_GUID, l_Level, l_X, l_Y, l_Z); 64 | 65 | Network::WorldPacket l_Test(Network::Opcodes::CMSG_PLAYER_LOGIN); 66 | l_Test << l_GUID; 67 | 68 | p_Manager->GetWorldSocket()->SendPacket(l_Test); 69 | return; 70 | } 71 | } 72 | 73 | } ///< namespace Handlers 74 | } ///< namespace World 75 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Handlers/WorldHCharacters.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Network/WorldPacket.hpp" 4 | #include "../WorldManager.hpp" 5 | 6 | namespace RCN { namespace World { namespace Handlers { 7 | 8 | /// Handle SMSG_AUTH_CHALLENGE 9 | /// @p_Packet : Packet 10 | /// @p_Manager : World manager 11 | void Handle_CharEnum(Network::WorldPacket& p_Packet, WorldManager* p_Manager); 12 | 13 | } ///< namespace Handlers 14 | } ///< namespace World 15 | } ///< namespace RCN#pragma once 16 | -------------------------------------------------------------------------------- /World/Handlers/WorldHChat.cpp: -------------------------------------------------------------------------------- 1 | #include "WorldHChat.hpp" 2 | #include "../Enums/WorldEnums.hpp" 3 | #include "../Network/WorldOpcodes.hpp" 4 | 5 | namespace RCN { namespace World { namespace Handlers { 6 | 7 | struct ChatMessage 8 | { 9 | uint8_t MessageType; 10 | uint32_t Language; 11 | std::string Message; 12 | uint8_t ChatTag; 13 | 14 | struct 15 | { 16 | uint64_t GUID; 17 | std::string Name; 18 | uint32_t ChannelRank; 19 | } Sender, Target; 20 | 21 | struct 22 | { 23 | std::string Name; 24 | } Channel; 25 | }; 26 | 27 | /// Handle SMSG_MESSAGECHAT 28 | /// @p_Packet : Packet 29 | /// @p_Manager : World manager 30 | void Handle_MessageChat(Network::WorldPacket& p_Packet, WorldManager* p_Manager) 31 | { 32 | ChatMessage l_Message; 33 | 34 | p_Packet >> l_Message.MessageType; 35 | p_Packet >> l_Message.Language; 36 | 37 | switch (static_cast(l_Message.MessageType)) 38 | { 39 | case Enums::ChatMessageType::CHAT_MSG_MONSTER_WHISPER: 40 | case Enums::ChatMessageType::CHAT_MSG_RAID_BOSS_WHISPER: 41 | case Enums::ChatMessageType::CHAT_MSG_RAID_BOSS_EMOTE: 42 | case Enums::ChatMessageType::CHAT_MSG_MONSTER_EMOTE: 43 | p_Packet.ReadSkip(); 44 | p_Packet >> l_Message.Sender.Name; 45 | p_Packet >> l_Message.Target.GUID; 46 | break; 47 | 48 | case Enums::ChatMessageType::CHAT_MSG_SAY: 49 | case Enums::ChatMessageType::CHAT_MSG_PARTY: 50 | case Enums::ChatMessageType::CHAT_MSG_YELL: 51 | p_Packet >> l_Message.Sender.GUID; 52 | p_Packet >> l_Message.Sender.GUID; 53 | break; 54 | 55 | case Enums::ChatMessageType::CHAT_MSG_MONSTER_SAY: 56 | case Enums::ChatMessageType::CHAT_MSG_MONSTER_YELL: 57 | p_Packet >> l_Message.Sender.GUID; 58 | p_Packet.ReadSkip(); 59 | p_Packet >> l_Message.Sender.Name; 60 | p_Packet >> l_Message.Target.GUID; 61 | break; 62 | 63 | case Enums::ChatMessageType::CHAT_MSG_CHANNEL: 64 | p_Packet >> l_Message.Channel.Name; 65 | p_Packet >> l_Message.Sender.ChannelRank; 66 | p_Packet >> l_Message.Sender.GUID; 67 | break; 68 | 69 | default: 70 | p_Packet >> l_Message.Sender.GUID; 71 | break; 72 | } 73 | 74 | p_Packet.ReadSkip(); 75 | p_Packet >> l_Message.Message; 76 | p_Packet >> l_Message.ChatTag; 77 | 78 | ////////////////////////////////////////////////////////////////////////// 79 | ////////////////////////////////////////////////////////////////////////// 80 | 81 | printf("[CHAT]"); 82 | switch (static_cast(l_Message.MessageType)) 83 | { 84 | 85 | case Enums::ChatMessageType::CHAT_MSG_SAY: 86 | printf("[SAY]"); 87 | break; 88 | case Enums::ChatMessageType::CHAT_MSG_PARTY: 89 | printf("[PARTY]"); 90 | break; 91 | case Enums::ChatMessageType::CHAT_MSG_YELL: 92 | printf("[YELL]"); 93 | break; 94 | 95 | case Enums::ChatMessageType::CHAT_MSG_MONSTER_SAY: 96 | printf("[MONTER_SAY]"); 97 | break; 98 | 99 | case Enums::ChatMessageType::CHAT_MSG_MONSTER_YELL: 100 | printf("[MONTER_YELL]"); 101 | break; 102 | 103 | case Enums::ChatMessageType::CHAT_MSG_CHANNEL: 104 | printf("[%s]", l_Message.Channel.Name.c_str()); 105 | break; 106 | } 107 | printf(" : %s\n", l_Message.Message.c_str()); 108 | } 109 | 110 | } ///< namespace Handlers 111 | } ///< namespace World 112 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Handlers/WorldHChat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Network/WorldPacket.hpp" 4 | #include "../WorldManager.hpp" 5 | 6 | namespace RCN { namespace World { namespace Handlers { 7 | 8 | /// Handle SMSG_MESSAGECHAT 9 | /// @p_Packet : Packet 10 | /// @p_Manager : World manager 11 | void Handle_MessageChat(Network::WorldPacket& p_Packet, WorldManager* p_Manager); 12 | 13 | } ///< namespace Handlers 14 | } ///< namespace World 15 | } ///< namespace RCN#pragma once 16 | -------------------------------------------------------------------------------- /World/Handlers/WorldHRPC.cpp: -------------------------------------------------------------------------------- 1 | #include "WorldHChat.hpp" 2 | #include "../Enums/WorldEnums.hpp" 3 | #include "../Network/WorldOpcodes.hpp" 4 | #include "../Entities/WorldEUnit.hpp" 5 | #include 6 | 7 | namespace RCN { namespace World { namespace Handlers { 8 | 9 | /// Handle SMSG_UPDATE_OBJECT 10 | /// @p_Packet : Packet 11 | /// @p_Manager : World manager 12 | void Handle_UpdateObject(Network::WorldPacket& p_Packet, WorldManager* p_Manager) 13 | { 14 | uint32_t l_BlockCount = p_Packet.Read(); 15 | uint8_t l_HasTransport = p_Packet.Read(); 16 | 17 | for (uint32_t l_I = 0; l_I < l_BlockCount; ++l_I) 18 | { 19 | Enums::ObjectUpdateType::Type l_BlockType = static_cast(p_Packet.Read()); 20 | 21 | if (l_BlockType == Enums::ObjectUpdateType::UPDATETYPE_VALUES) 22 | { 23 | uint64_t l_GUID = p_Packet.ReadPackGUID(); 24 | 25 | } 26 | else if (l_BlockType == Enums::ObjectUpdateType::UPDATETYPE_MOVEMENT) 27 | { 28 | /// Nothing to do here 29 | } 30 | else if (l_BlockType == Enums::ObjectUpdateType::UPDATETYPE_CREATE_OBJECT 31 | || l_BlockType == Enums::ObjectUpdateType::UPDATETYPE_CREATE_OBJECT2) 32 | { 33 | uint64_t l_GUID = p_Packet.ReadPackGUID(); 34 | uint8_t l_ObjectTypeID = p_Packet.Read(); 35 | 36 | uint8_t l_UpdateFlags = p_Packet.Read(); 37 | 38 | Entities::MovementInfo l_MovementInfo; 39 | float l_Speeds[Enums::UnitMoveType::MAX]; 40 | 41 | if ((l_UpdateFlags & Enums::ObjectUpdateFlags::UPDATEFLAG_LIVING) != 0) 42 | { 43 | // l_MovementInfo.Read(p_Packet); 44 | 45 | p_Packet >> l_Speeds[Enums::UnitMoveType::MOVE_WALK]; 46 | p_Packet >> l_Speeds[Enums::UnitMoveType::MOVE_RUN]; 47 | p_Packet >> l_Speeds[Enums::UnitMoveType::MOVE_RUN_BACK]; 48 | p_Packet >> l_Speeds[Enums::UnitMoveType::MOVE_SWIM]; 49 | p_Packet >> l_Speeds[Enums::UnitMoveType::MOVE_SWIM_BACK]; 50 | p_Packet >> l_Speeds[Enums::UnitMoveType::MOVE_TURN_RATE]; 51 | 52 | 53 | 54 | } 55 | 56 | if ((l_UpdateFlags & Enums::ObjectUpdateFlags::UPDATEFLAG_HAS_POSITION) != 0) 57 | { 58 | 59 | } 60 | 61 | if ((l_UpdateFlags & Enums::ObjectUpdateFlags::UPDATEFLAG_HIGHGUID) != 0) 62 | p_Packet.ReadSkip(); 63 | 64 | if ((l_UpdateFlags & Enums::ObjectUpdateFlags::UPDATEFLAG_ALL) != 0) 65 | p_Packet.ReadSkip(); 66 | 67 | if ((l_UpdateFlags & Enums::ObjectUpdateFlags::UPDATEFLAG_FULLGUID) != 0) 68 | p_Packet.ReadPackGUID(); 69 | 70 | if ((l_UpdateFlags & Enums::ObjectUpdateFlags::UPDATEFLAG_TRANSPORT) != 0) 71 | p_Packet.ReadSkip(); 72 | 73 | } 74 | else if (l_BlockType == Enums::ObjectUpdateType::UPDATETYPE_OUT_OF_RANGE_OBJECTS) 75 | { 76 | uint32_t l_ObjectCount = p_Packet.Read(); 77 | 78 | for (uint32_t l_Y = 0; l_Y < l_ObjectCount; ++l_Y) 79 | { 80 | uint64_t l_GUID = p_Packet.ReadPackGUID(); 81 | 82 | 83 | } 84 | } 85 | else if (l_BlockType == Enums::ObjectUpdateType::UPDATETYPE_NEAR_OBJECTS) 86 | { 87 | /// Nothing to do here 88 | } 89 | } 90 | } 91 | /// Handle SMSG_COMPRESSED_UPDATE_OBJECT 92 | /// @p_Packet : Packet 93 | /// @p_Manager : World manager 94 | void Handle_CompressedUpdateObject(Network::WorldPacket& p_Packet, WorldManager* p_Manager) 95 | { 96 | uint32_t l_DecompressedSizeUI32 = p_Packet.Read(); 97 | uLongf l_DecompressedSize = l_DecompressedSizeUI32; 98 | uint32_t l_CompressedSize = p_Packet.GetSize() - p_Packet.ReadPosition(); 99 | uint8_t * l_CompressedData = new uint8_t[l_CompressedSize]; 100 | 101 | p_Packet.Read(l_CompressedData, l_CompressedSize); 102 | 103 | uint8_t * l_UncompressedData = new uint8_t[l_DecompressedSizeUI32]; 104 | 105 | if (uncompress(l_UncompressedData, &l_DecompressedSize, l_CompressedData, l_CompressedSize) == Z_OK) 106 | { 107 | Network::WorldPacket l_Packet(l_DecompressedSize); 108 | l_Packet.Append(l_UncompressedData, l_DecompressedSize); 109 | 110 | Handle_UpdateObject(l_Packet, p_Manager); 111 | } 112 | else 113 | printf("[WORLD] Decompression of SMSG_COMPRESSED_UPDATE_OBJECT failed !\n"); 114 | 115 | delete[] l_UncompressedData; 116 | delete[] l_CompressedData; 117 | } 118 | /// Handle SMSG_DESTROY_OBJECT 119 | /// @p_Packet : Packet 120 | /// @p_Manager : World manager 121 | void Handle_DestroyObject(Network::WorldPacket& p_Packet, WorldManager* p_Manager) 122 | { 123 | uint64_t l_GUID = p_Packet.Read(); 124 | 125 | /// @TODO 126 | } 127 | 128 | } ///< namespace Handlers 129 | } ///< namespace World 130 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Handlers/WorldHRPC.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Network/WorldPacket.hpp" 4 | #include "../WorldManager.hpp" 5 | 6 | namespace RCN { namespace World { namespace Handlers { 7 | 8 | /// Handle SMSG_UPDATE_OBJECT 9 | /// @p_Packet : Packet 10 | /// @p_Manager : World manager 11 | void Handle_UpdateObject(Network::WorldPacket& p_Packet, WorldManager* p_Manager); 12 | /// Handle SMSG_COMPRESSED_UPDATE_OBJECT 13 | /// @p_Packet : Packet 14 | /// @p_Manager : World manager 15 | void Handle_CompressedUpdateObject(Network::WorldPacket& p_Packet, WorldManager* p_Manager); 16 | /// Handle SMSG_DESTROY_OBJECT 17 | /// @p_Packet : Packet 18 | /// @p_Manager : World manager 19 | void Handle_DestroyObject(Network::WorldPacket& p_Packet, WorldManager* p_Manager); 20 | 21 | } ///< namespace Handlers 22 | } ///< namespace World 23 | } ///< namespace RCN#pragma once 24 | -------------------------------------------------------------------------------- /World/Handlers/WorldHWarden.cpp: -------------------------------------------------------------------------------- 1 | #include "WorldHWarden.hpp" 2 | #include "../Enums/WorldEnums.hpp" 3 | #include "../Network/WorldOpcodes.hpp" 4 | #include "../Warden/WorldWardenUtils.hpp" 5 | #include "../../Crypto/WardenKeyGenerator.hpp" 6 | #include "../../Crypto/ARC4.hpp" 7 | #include "../../Crypto/SHA1.hpp" 8 | #include 9 | 10 | namespace RCN { namespace World { namespace Handlers { 11 | 12 | struct WardenContext 13 | { 14 | WardenContext() 15 | { 16 | IsWardenCryptOK = false; 17 | } 18 | 19 | bool IsWardenCryptOK; 20 | Crypto::BigNumber EncryptKey; 21 | Crypto::BigNumber DecryptKey; 22 | Crypto::ARC4 * Encrypter; 23 | Crypto::ARC4 * Decrypter; 24 | uint8_t EncryptFirstByte; 25 | 26 | Crypto::BigNumber ModuleID; 27 | Crypto::BigNumber ModuleKey; 28 | uint32_t ModuleSize; 29 | 30 | RCN::Network::ByteBuffer WardenModule; 31 | RCN::Network::ByteBuffer WowModule; 32 | }; 33 | 34 | /// Handle WardenOpcodes::WARDEN_SMSG_MODULE_USE 35 | /// @p_Packet : Packet 36 | /// @p_Manager : World manager 37 | /// @p_Context : Warden context 38 | void HandleWardenModuleUse(Network::WorldPacket& p_Packet, WorldManager* p_Manager, WardenContext* p_Context); 39 | /// Handle WardenOpcodes::WARDEN_SMSG_MODULE_CACHE 40 | /// @p_Packet : Packet 41 | /// @p_Manager : World manager 42 | /// @p_Context : Warden context 43 | void HandleWardenModuleCache(Network::WorldPacket& p_Packet, WorldManager* p_Manager, WardenContext* p_Context); 44 | /// Handle WardenOpcodes::WARDEN_SMSG_HASH_REQUEST 45 | /// @p_Packet : Packet 46 | /// @p_Manager : World manager 47 | /// @p_Context : Warden context 48 | void HandleWardenHashRequest(Network::WorldPacket& p_Packet, WorldManager* p_Manager, WardenContext* p_Context); 49 | /// Handle WardenOpcodes::WARDEN_SMSG_CHEAT_CHECKS_REQUEST 50 | /// @p_Packet : Packet 51 | /// @p_Manager : World manager 52 | /// @p_Context : Warden context 53 | void HandleWardenCheatChecksRequest(Network::WorldPacket& p_Packet, WorldManager* p_Manager, WardenContext* p_Context); 54 | /// Handle WardenOpcodes::WARDEN_SMSG_MODULE_INITIALIZE 55 | /// @p_Packet : Packet 56 | /// @p_Manager : World manager 57 | /// @p_Context : Warden context 58 | void HandleWardenModuleInitialize(Network::WorldPacket& p_Packet, WorldManager* p_Manager, WardenContext* p_Context); 59 | 60 | ////////////////////////////////////////////////////////////////////////// 61 | ////////////////////////////////////////////////////////////////////////// 62 | 63 | /// Handle SMSG_WARDEN_DATA 64 | /// @p_Packet : Packet 65 | /// @p_Manager : World manager 66 | void Handle_WardenData(Network::WorldPacket& p_Packet, WorldManager* p_Manager) 67 | { 68 | /// Private code 69 | } 70 | 71 | } ///< namespace Handlers 72 | } ///< namespace World 73 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Handlers/WorldHWarden.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Network/WorldPacket.hpp" 4 | #include "../WorldManager.hpp" 5 | 6 | namespace RCN { namespace World { namespace Handlers { 7 | 8 | namespace WardenOpcodes 9 | { 10 | enum Type 11 | { 12 | /// Client->Server 13 | WARDEN_CMSG_MODULE_MISSING = 0, 14 | WARDEN_CMSG_MODULE_OK = 1, 15 | WARDEN_CMSG_CHEAT_CHECKS_RESULT = 2, 16 | WARDEN_CMSG_MEM_CHECKS_RESULT = 3, 17 | WARDEN_CMSG_HASH_RESULT = 4, 18 | WARDEN_CMSG_MODULE_FAILED = 5, 19 | 20 | /// Server->Client 21 | WARDEN_SMSG_MODULE_USE = 0, 22 | WARDEN_SMSG_MODULE_CACHE = 1, 23 | WARDEN_SMSG_CHEAT_CHECKS_REQUEST = 2, 24 | WARDEN_SMSG_MODULE_INITIALIZE = 3, 25 | WARDEN_SMSG_MEM_CHECKS_REQUEST = 4, 26 | WARDEN_SMSG_HASH_REQUEST = 5 27 | }; 28 | } 29 | 30 | namespace WardenCheckType 31 | { 32 | enum Type 33 | { 34 | Timing = 0x57, ///< 87: empty (check to ensure GetTickCount() isn't detoured) 35 | Driver = 0x71, ///< 113: uint Seed + byte[20] SHA1 + byte driverNameIndex (check to ensure driver isn't loaded) 36 | Proc = 0x7E, ///< 126: uint Seed + byte[20] SHA1 + byte moluleNameIndex + byte procNameIndex + uint Offset + byte Len (check to ensure proc isn't detoured) 37 | LuaStr = 0x8B, ///< 139: byte luaNameIndex (check to ensure LUA string isn't used) 38 | Mpq = 0x98, ///< 152: byte fileNameIndex (check to ensure MPQ file isn't modified) 39 | PageCheckA = 0xB2, ///< 178: uint Seed + byte[20] SHA1 + uint Addr + byte Len (scans all pages for specified hash) 40 | PageCheckB = 0xBF, ///< 191: uint Seed + byte[20] SHA1 + uint Addr + byte Len (scans only pages starts with MZ+PE headers for specified hash) 41 | Module = 0xD9, ///< 217: uint Seed + byte[20] SHA1 (check to ensure module isn't injected) 42 | Memory = 0xF3, ///< 243: byte moduleNameIndex + uint Offset + byte Len (check to ensure memory isn't modified) 43 | }; 44 | } 45 | 46 | ////////////////////////////////////////////////////////////////////////// 47 | ////////////////////////////////////////////////////////////////////////// 48 | 49 | /// Handle SMSG_WARDEN_DATA 50 | /// @p_Packet : Packet 51 | /// @p_Manager : World manager 52 | void Handle_WardenData(Network::WorldPacket& p_Packet, WorldManager* p_Manager); 53 | 54 | } ///< namespace Handlers 55 | } ///< namespace World 56 | } ///< namespace RCN#pragma once 57 | -------------------------------------------------------------------------------- /World/Network/WorldHeaders.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Network/TCPClient.hpp" 4 | 5 | namespace RCN { namespace World { namespace Network { 6 | 7 | #if defined( __GNUC__ ) 8 | #pragma pack(1) 9 | #else 10 | #pragma pack(push,1) 11 | #endif 12 | 13 | struct ServerPktHeader 14 | { 15 | uint16_t size; 16 | uint16_t cmd; 17 | }; 18 | 19 | struct ClientPktHeader 20 | { 21 | uint16_t size; 22 | uint32_t cmd; 23 | }; 24 | 25 | #if defined( __GNUC__ ) 26 | #pragma pack() 27 | #else 28 | #pragma pack(pop) 29 | #endif 30 | 31 | } ///< namespace Network 32 | } ///< namespace World 33 | } ///< namespace RCN 34 | -------------------------------------------------------------------------------- /World/Network/WorldPacket.cpp: -------------------------------------------------------------------------------- 1 | #include "WorldPacket.hpp" 2 | #include "WorldOpcodes.hpp" 3 | 4 | namespace RCN { namespace World { namespace Network { 5 | 6 | /// Constructor 7 | /// @p_Opcode : New opcode 8 | /// @p_Reserve : Packet reserve 9 | WorldPacket::WorldPacket() 10 | : ByteBuffer(0), m_Opcode(Opcodes::MSG_NULL_ACTION) 11 | { 12 | } 13 | /// Constructor 14 | WorldPacket::WorldPacket(uint16_t p_Opcode, size_t p_Reserve) 15 | : ByteBuffer(p_Reserve), m_Opcode(p_Opcode) 16 | { 17 | } 18 | /// Copy constructor 19 | /// @p_Packet : Packet to copy 20 | WorldPacket::WorldPacket(const WorldPacket& p_Packet) 21 | : ByteBuffer(p_Packet), m_Opcode(p_Packet.m_Opcode) 22 | { 23 | } 24 | 25 | ////////////////////////////////////////////////////////////////////////// 26 | ////////////////////////////////////////////////////////////////////////// 27 | 28 | /// Initialize 29 | /// @p_Opcode : New opcode 30 | /// @p_Reserve : Packet reserve 31 | void WorldPacket::Initialize(uint16_t p_Opcode, size_t p_Reserve) 32 | { 33 | Clear(); 34 | m_Storage.reserve(p_Reserve); 35 | m_Opcode = p_Opcode; 36 | } 37 | 38 | ////////////////////////////////////////////////////////////////////////// 39 | ////////////////////////////////////////////////////////////////////////// 40 | 41 | /// Get packet opcode 42 | uint16_t WorldPacket::GetOpcode() const 43 | { 44 | return m_Opcode; 45 | } 46 | /// Set the packet opcode 47 | /// @p_Opcode : New opcode 48 | void WorldPacket::SetOpcode(uint16_t p_Opcode) 49 | { 50 | m_Opcode = p_Opcode; 51 | } 52 | 53 | } ///< namespace Network 54 | } ///< namespace World 55 | } ///< namespace RCN 56 | -------------------------------------------------------------------------------- /World/Network/WorldPacket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Network/TCPClient.hpp" 4 | #include "../../Network/ByteBuffer.hpp" 5 | 6 | namespace RCN { namespace World { namespace Network { 7 | 8 | class WorldPacket : public RCN::Network::ByteBuffer 9 | { 10 | public: 11 | /// Constructor 12 | /// @p_Opcode : New opcode 13 | /// @p_Reserve : Packet reserve 14 | WorldPacket(); 15 | /// Constructor 16 | explicit WorldPacket(uint16_t p_Opcode, size_t p_Reserve = 200); 17 | /// Copy constructor 18 | /// @p_Packet : Packet to copy 19 | WorldPacket(const WorldPacket& p_Packet); 20 | 21 | /// Initialize 22 | /// @p_Opcode : New opcode 23 | /// @p_Reserve : Packet reserve 24 | void Initialize(uint16_t p_Opcode, size_t p_Reserve = 200); 25 | 26 | /// Get packet opcode 27 | uint16_t GetOpcode() const; 28 | /// Set the packet opcode 29 | /// @p_Opcode : New opcode 30 | void SetOpcode(uint16_t p_Opcode); 31 | 32 | private: 33 | uint16_t m_Opcode; ///< Opcode value 34 | 35 | }; 36 | 37 | } ///< namespace Network 38 | } ///< namespace World 39 | } ///< namespace RCN 40 | -------------------------------------------------------------------------------- /World/Network/WorldSocket.cpp: -------------------------------------------------------------------------------- 1 | #include "WorldSocket.hpp" 2 | #include "WorldOpcodes.hpp" 3 | #include "../WorldManager.hpp" 4 | #include "../../Utils/UtilsString.hpp" 5 | #include "../../Utils/UtilsEndian.hpp" 6 | 7 | namespace RCN { namespace World { namespace Network { 8 | 9 | /// Constructor 10 | /// @p_Manager : Manager 11 | WorldSocket::WorldSocket(WorldManager* p_Manager) 12 | : m_Manager(p_Manager), m_ReceiveThread(nullptr), m_ReceiveThreadCond(false) 13 | { 14 | 15 | } 16 | /// Destructor 17 | WorldSocket::~WorldSocket() 18 | { 19 | if (m_ReceiveThread) 20 | { 21 | m_ReceiveThreadCond = false; 22 | m_ReceiveThread->join(); 23 | delete m_ReceiveThread; 24 | } 25 | } 26 | 27 | ////////////////////////////////////////////////////////////////////////// 28 | ////////////////////////////////////////////////////////////////////////// 29 | 30 | /// Do the connection 31 | /// @p_Realm : Realm 32 | /// @p_Key : Session key 33 | bool WorldSocket::Connect(Logon::RealmInfo p_Realm, Crypto::BigNumber p_SessionKey) 34 | { 35 | auto l_Parts = Utils::Split(p_Realm.Address, ":", false); 36 | 37 | std::string l_Host = l_Parts[0]; 38 | uint16_t l_Port = atoi(l_Parts[1].c_str()); 39 | 40 | printf("[WORLD] Connecting to world server %s:%u\n", l_Host.c_str(), l_Port); 41 | 42 | if (!m_Socket.Connect(l_Host, l_Port)) 43 | return false; 44 | 45 | printf("[WORLD] Connected !\n"); 46 | 47 | m_SessionKey = p_SessionKey; 48 | m_IsConnected = true; 49 | 50 | m_ReceiveThreadCond = true; 51 | m_ReceiveThread = new std::thread(&WorldSocket::ReceiveThread, this); 52 | 53 | return true; 54 | } 55 | 56 | ////////////////////////////////////////////////////////////////////////// 57 | ////////////////////////////////////////////////////////////////////////// 58 | 59 | /// Send a packet 60 | /// @p_Packet : Packet to send 61 | void WorldSocket::SendPacket(WorldPacket& p_Packet) 62 | { 63 | ClientPktHeader l_Header; 64 | l_Header.cmd = p_Packet.GetOpcode(); 65 | l_Header.size = static_cast(p_Packet.GetSize() + 4); 66 | 67 | Utils::ByteConverter::Apply(&l_Header.size); ///< Endian reverse 68 | 69 | m_Crypto.Encrypt(reinterpret_cast(&l_Header), sizeof(l_Header)); 70 | 71 | WorldPacket l_Copy; 72 | l_Copy.Append(reinterpret_cast(&l_Header), sizeof(l_Header)); 73 | 74 | if (p_Packet.GetSize()) 75 | l_Copy.Append(p_Packet.GetData(), p_Packet.GetSize()); 76 | 77 | if (!m_Socket.Send(l_Copy.GetData(), l_Copy.GetSize())) 78 | { 79 | printf("[WORLD] Socket error\n"); 80 | m_ReceiveThreadCond = false; 81 | m_IsConnected = false; 82 | } 83 | else 84 | printf("[WORLD] Send packet %s(%u) size %u\n", OpcodesName[p_Packet.GetOpcode()], p_Packet.GetOpcode(), p_Packet.GetSize()); 85 | } 86 | 87 | ////////////////////////////////////////////////////////////////////////// 88 | ////////////////////////////////////////////////////////////////////////// 89 | 90 | /// Init WoWCrypt 91 | void WorldSocket::InitWoWCrypt() 92 | { 93 | m_Crypto.Init(); 94 | m_Crypto.SetKey(m_SessionKey.AsByteArray(), m_SessionKey.GetNumBytes()); 95 | } 96 | 97 | ////////////////////////////////////////////////////////////////////////// 98 | ////////////////////////////////////////////////////////////////////////// 99 | 100 | /// Is connected 101 | bool WorldSocket::IsConnected() const 102 | { 103 | return m_IsConnected; 104 | } 105 | /// Get session key 106 | Crypto::BigNumber WorldSocket::GetSessionKey() 107 | { 108 | return m_SessionKey; 109 | } 110 | 111 | ////////////////////////////////////////////////////////////////////////// 112 | ////////////////////////////////////////////////////////////////////////// 113 | 114 | /// Receive thread 115 | void WorldSocket::ReceiveThread() 116 | { 117 | while (m_ReceiveThreadCond) 118 | { 119 | ServerPktHeader l_Header; 120 | 121 | if (!m_Socket.Receive(reinterpret_cast(&l_Header), sizeof(ServerPktHeader))) 122 | { 123 | printf("[WORLD] Socket error\n"); 124 | m_ReceiveThreadCond = false; 125 | m_IsConnected = false; 126 | } 127 | 128 | m_Crypto.Decrypt(reinterpret_cast(&l_Header), sizeof(ServerPktHeader)); 129 | 130 | Utils::ByteConverter::Apply(&l_Header.size); ///< Endian reverse 131 | l_Header.size -= 2; ///< Don't count Size in size 132 | 133 | uint8_t* l_Data = new uint8_t[l_Header.size]; 134 | m_Socket.Receive(l_Data, l_Header.size); 135 | 136 | WorldPacket l_Packet; 137 | l_Packet.Append(l_Data, l_Header.size); 138 | l_Packet.ReadPosition(0); 139 | l_Packet.SetOpcode(l_Header.cmd); 140 | 141 | delete[] l_Data; 142 | 143 | if (l_Header.cmd >= Opcodes::MAX) 144 | { 145 | printf("[WORLD] Socket error\n"); 146 | m_ReceiveThreadCond = false; 147 | m_IsConnected = false; 148 | break; 149 | } 150 | 151 | m_Manager->EnqueuePacket(std::move(l_Packet)); 152 | 153 | Sleep(5); 154 | } 155 | } 156 | 157 | } ///< namespace Network 158 | } ///< namespace World 159 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Network/WorldSocket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Network/TCPClient.hpp" 4 | #include "../../Logon/LogonManager.hpp" 5 | #include "../../Crypto/WoWCrypt.hpp" 6 | #include "WorldHeaders.hpp" 7 | #include "WorldPacket.hpp" 8 | #include 9 | 10 | namespace RCN { namespace World { 11 | 12 | class WorldManager; 13 | 14 | namespace Network { 15 | 16 | class WorldSocket 17 | { 18 | public: 19 | /// Constructor 20 | /// @p_Manager : Manager 21 | WorldSocket(WorldManager* p_Manager); 22 | /// Destructor 23 | ~WorldSocket(); 24 | 25 | /// Do the connection 26 | /// @p_Realm : Realm 27 | /// @p_Key : Session key 28 | bool Connect(Logon::RealmInfo p_Realm, Crypto::BigNumber p_SessionKey); 29 | 30 | /// Send a packet 31 | /// @p_Packet : Packet to send 32 | void SendPacket(WorldPacket& p_Packet); 33 | 34 | /// Init WoWCrypt 35 | void InitWoWCrypt(); 36 | 37 | /// Is connected 38 | bool IsConnected() const; 39 | /// Get session key 40 | Crypto::BigNumber GetSessionKey(); 41 | 42 | private: 43 | /// Receive thread 44 | void ReceiveThread(); 45 | 46 | private: 47 | WorldManager * m_Manager; ///< World manager 48 | RCN::Network::TCPClient m_Socket; ///< Socket 49 | Crypto::BigNumber m_SessionKey; ///< Session key 50 | Crypto::WoWCrypt m_Crypto; ///< Packet crypto 51 | std::thread * m_ReceiveThread; ///< Receive thread 52 | bool m_ReceiveThreadCond; ///< Receive thread condition 53 | bool m_IsConnected; ///< Is the socket connected 54 | }; 55 | 56 | } ///< namespace Network 57 | } ///< namespace World 58 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/Warden/WorldWardenStructs.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace RCN { namespace World { namespace Warden { 6 | 7 | struct ModuleHeader 8 | { 9 | uint32_t MapedSize; 10 | uint32_t Unknown1; 11 | uint32_t RefTable; 12 | uint32_t RefCount; 13 | uint32_t InitAddr; 14 | uint32_t Unknown3; 15 | uint32_t Unknown4; 16 | uint32_t LibTable; 17 | uint32_t LibCount; 18 | uint32_t Unknown5; 19 | }; 20 | 21 | struct LibraryReferance 22 | { 23 | uint32_t NameAddress; 24 | uint32_t FunctionTable; 25 | }; 26 | 27 | } ///< namespace Warden 28 | } ///< namespace World 29 | } ///< namespace RCN 30 | -------------------------------------------------------------------------------- /World/Warden/WorldWardenUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "WorldWardenUtils.hpp" 2 | #include 3 | #include 4 | 5 | namespace RCN { namespace World { namespace Warden { 6 | 7 | /// Get module mapped size 8 | /// @p_Input : Input decompressed warden module 9 | size_t GetModuleMapedSize(RCN::Network::ByteBuffer& p_Input) 10 | { 11 | ModuleHeader* l_Header = reinterpret_cast(const_cast(p_Input.GetData())); 12 | return l_Header->MapedSize; 13 | } 14 | /// Remap warden module 15 | /// @p_Input : Input decompressed warden module 16 | uint32_t RemapModule(RCN::Network::ByteBuffer& p_Input) 17 | { 18 | #define module_get_int32(a, b) (*(uint32_t*)(a + (uint32_t)b)) 19 | #define module_get_aint32(a, b) (*(uint32_t*)(&a[b])) 20 | #define module_get_int16(a, b) (*(uint16_t*)&a[(uint32_t)b]) 21 | #define module_swap_int16(a) (((a & 0xFF00) >> 8) | ((a & 0xFF) << 8)) 22 | #define module_set_int32(a, b, c) (*(uint32_t*)(a + b) = c) 23 | 24 | auto AllocExecMemory = [](uint32_t size) -> uint32_t 25 | { 26 | LPVOID l_Result = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 27 | VirtualLock(l_Result, size); 28 | return (uint32_t)l_Result; 29 | }; 30 | 31 | ModuleHeader *l_Header = reinterpret_cast(const_cast(p_Input.GetData())); 32 | 33 | uint32_t l_MapedSize = GetModuleMapedSize(p_Input); 34 | uint32_t l_FinalModule = AllocExecMemory(l_MapedSize); 35 | 36 | uint8_t* l_Source = const_cast(p_Input.GetData()); 37 | 38 | memset((uint8_t*)l_FinalModule, 0, l_MapedSize); ///< Init destination 39 | memcpy((uint8_t*)l_FinalModule, l_Source, sizeof(ModuleHeader)); ///< Copy module header 40 | 41 | printf("[WARDEN:RemapModule] Source size %u final size %u\n", p_Input.GetSize(), l_MapedSize); 42 | 43 | ////////////////////////////////////////////////////////////////////////// 44 | /// Code blocks 45 | ////////////////////////////////////////////////////////////////////////// 46 | 47 | uint32_t l_SourceLocation = sizeof(ModuleHeader) + (l_Header->Unknown5 * 12); 48 | uint32_t l_DestLocation = module_get_aint32(l_Source, 40); 49 | 50 | uint8_t l_BlockSkip = 0; 51 | while (l_DestLocation < l_MapedSize) 52 | { 53 | uint16_t l_Length = module_get_int16(l_Source, l_SourceLocation); 54 | l_SourceLocation += 2; 55 | 56 | if (!l_BlockSkip) 57 | { 58 | memcpy((uint8_t*)(l_FinalModule + l_DestLocation), l_Source + l_SourceLocation, l_Length); 59 | l_SourceLocation += l_Length; 60 | } 61 | l_BlockSkip = !l_BlockSkip; 62 | l_DestLocation += l_Length; 63 | } 64 | 65 | ////////////////////////////////////////////////////////////////////////// 66 | /// Global vars 67 | ////////////////////////////////////////////////////////////////////////// 68 | 69 | uint16_t * l_RefTables = (uint16_t*)(l_FinalModule + l_Header->RefTable); 70 | l_DestLocation = 0; 71 | 72 | printf("[WARDEN:RemapModule] Adjusting %d references to global variables\n", static_cast(l_Header->RefCount)); 73 | 74 | for (uint32_t l_X = 0; l_X < l_Header->RefCount; l_X++) 75 | { 76 | l_DestLocation += module_swap_int16(l_RefTables[l_X]); 77 | module_set_int32(l_FinalModule, l_DestLocation, (module_get_int32(l_FinalModule, l_DestLocation) % l_MapedSize) + l_FinalModule); 78 | } 79 | 80 | ////////////////////////////////////////////////////////////////////////// 81 | /// Imports 82 | ////////////////////////////////////////////////////////////////////////// 83 | 84 | printf("[WARDEN:RemapModule] Updating API library references\n"); 85 | 86 | LibraryReferance* l_LibTables = reinterpret_cast(l_FinalModule + l_Header->LibTable); 87 | for (uint32_t l_X = 0; l_X < l_Header->LibCount; l_X++) 88 | { 89 | char* l_LibName = reinterpret_cast(l_FinalModule + l_LibTables[l_X].NameAddress); 90 | HMODULE l_LibHandle = LoadLibrary(l_LibName); 91 | 92 | uint32_t l_LibFunction = l_LibTables[l_X].FunctionTable; 93 | while (module_get_int32(l_FinalModule, l_LibFunction) != 0) 94 | { 95 | uint32_t l_FuncBaseAddr = module_get_int32(l_FinalModule, l_LibFunction); 96 | 97 | if ((l_FuncBaseAddr & 0x7FFFFFFF) > l_MapedSize) 98 | { 99 | printf("[WARDEN:RemapModule] Attempted to read API from offset pass end of module: 0x%08X\n", static_cast(l_FuncBaseAddr)); 100 | break; 101 | } 102 | 103 | uint32_t l_FinalAddress = 0; 104 | if (l_FuncBaseAddr & 0x80000000) 105 | l_FinalAddress = (uint32_t)GetProcAddress(l_LibHandle, reinterpret_cast(l_FuncBaseAddr & 0x7FFFFFFF)); 106 | else 107 | l_FinalAddress = (uint32_t)GetProcAddress(l_LibHandle, reinterpret_cast(l_FinalModule + l_FuncBaseAddr)); 108 | 109 | module_set_int32(l_FinalModule, l_LibFunction, l_FinalAddress); 110 | l_LibFunction += 4; 111 | } 112 | } 113 | 114 | return l_FinalModule; 115 | 116 | #undef module_get_int32 117 | #undef module_get_aint32 118 | #undef module_get_int16 119 | #undef module_swap_int16 120 | #undef module_set_int32 121 | } 122 | 123 | ////////////////////////////////////////////////////////////////////////// 124 | ////////////////////////////////////////////////////////////////////////// 125 | template T __ROL__(T value, int count) 126 | { 127 | const uint nbits = sizeof(T) * 8; 128 | 129 | if (count > 0) 130 | { 131 | count %= nbits; 132 | T high = value >> (nbits - count); 133 | if (T(-1) < 0) // signed value 134 | high &= ~((T(-1) << count)); 135 | value <<= count; 136 | value |= high; 137 | } 138 | else 139 | { 140 | count = -count % nbits; 141 | T low = value << (nbits - count); 142 | value >>= count; 143 | value |= low; 144 | } 145 | return value; 146 | } 147 | inline uint8_t __ROL1__(uint8_t value, int count) { return __ROL__((uint8_t)value, count); } 148 | inline uint8_t __ROR1__(uint8_t value, int count) { return __ROL__((uint8_t)value, -count); } 149 | inline uint16_t __ROL2__(uint16_t value, int count) { return __ROL__((uint16_t)value, count); } 150 | inline uint32_t __ROL4__(uint32_t value, int count) { return __ROL__((uint32_t)value, count); } 151 | inline uint64_t __ROL8__(uint64_t value, int count) { return __ROL__((uint64_t)value, count); } 152 | inline uint16_t __ROR2__(uint16_t value, int count) { return __ROL__((uint16_t)value, -count); } 153 | inline uint32_t __ROR4__(uint32_t value, int count) { return __ROL__((uint32_t)value, -count); } 154 | inline uint64_t __ROR8__(uint64_t value, int count) { return __ROL__((uint64_t)value, -count); } 155 | #define __PAIR__(high, low) (((uint64_t)(high)<Key[0] + 0x7D7D7BBE, 31) - 865160792; 196 | int32_t v3 = __ROL4__(p_This->Key[1] + 0x67B6EA46 + v2, 27) + 0x4B13D756; 197 | 198 | l_ResultPartA = v2; 199 | l_ResultPartB = v3; 200 | l_ResultPartD = 0xB4EC28AA; 201 | 202 | int32_t v4 = __ROL4__((v2 ^ v3 & (v2 ^ 0xB4EC28AA)) + p_This->Key[2] - 1606725526, 5); 203 | int32_t v5 = v4 + v3 + 1; 204 | v219 = v5; 205 | 206 | l_ResultPartD = v5; 207 | l_ResultPartA = 0xB4EC28AA; 208 | 209 | int32_t v8 = __ROL4__( 210 | p_This->Key[3] 211 | + (l_ResultPartA & l_ResultPartB ^ v219 & (l_ResultPartA ^ l_ResultPartB)) 212 | + l_ResultPartD 213 | - 0x5CF436A3, 214 | 23); 215 | int32_t v9 = -l_ResultPartA ^ v8; 216 | l_ResultPartD = v9; 217 | int32_t v11 = __ROL4__(p_This->Key[0] + (v219 ^ l_ResultPartB & (v219 ^ v9)) + l_ResultPartA - 0xD4D9021, 25); 218 | int32_t v12 = v11 - _byteswap_ulong(l_ResultPartB); 219 | int32_t v13 = __ROL4__(l_ResultPartB + v219 + p_This->Key[1] - v9 + v12 - 0x4FBC7F55, 25); 220 | int32_t v14 = v12 ^ v13; 221 | int32_t v15 = __ROL4__(p_This->Key[2] + (v12 ^ (v9 | ~v14)) + v219 - 0x718FA137, 24); 222 | int32_t v16 = v9 + v15; 223 | l_ResultPartB = v14; 224 | int32_t v17 = ScrambleKey_UnkXorShifting(v16, v12, v14); 225 | int32_t v18 = __ROL4__(v17 + l_ResultPartD + p_This->Key[3] - 0x51F43506, 29); 226 | l_ResultPartD = v18 - v16; 227 | int32_t v20 = __ROL4__(p_This->Key[2] + (l_ResultPartB & v16 ^ l_ResultPartD & (l_ResultPartB ^ v16)) + v12 + 0x6B843618, 4); 228 | int32_t v21 = v20 + v16 + 1; 229 | l_ResultPartA = v21; 230 | int32_t v22 = __ROL4__(p_This->Key[0] + (v21 & v16 ^ l_ResultPartD & (v21 ^ v16)) + l_ResultPartB + 0x3F8FC37B, 7); 231 | l_ResultPartB = -v21 ^ v22; 232 | int32_t v24 = __ROL4__(v16 + l_ResultPartD + p_This->Key[0] - v21 + l_ResultPartB - 0x272B066D, 15); 233 | int32_t v25 = v24 - l_ResultPartD; 234 | v219 = v25; 235 | 236 | 237 | 238 | signed __int32 v25; // eax@1 239 | signed __int32 v28; // edx@1 240 | int v29; // eax@1 241 | signed __int32 v30; // eax@1 242 | int v33; // edi@1 243 | int v34; // edi@1 244 | int v35; // ebx@1 245 | int v36; // ebx@1 246 | int v37; // eax@1 247 | int v38; // eax@1 248 | int v39; // eax@1 249 | int v40; // ecx@1 250 | int v41; // ecx@1 251 | int v42; // edi@1 252 | int v43; // edi@1 253 | signed __int32 v44; // edx@1 254 | int v45; // ebx@1 255 | int v46; // eax@1 256 | signed __int32 v47; // eax@1 257 | int v50; // ecx@1 258 | unsigned int v51; // ebx@1 259 | int v52; // ecx@1 260 | int v53; // edi@1 261 | int v54; // edi@1 262 | int v55; // ecx@1 263 | int v56; // ecx@1 264 | int v57; // edx@1 265 | int v58; // edx@1 266 | int v59; // eax@1 267 | int v60; // ecx@1 268 | unsigned __int32 v61; // ebx@1 269 | int v62; // edi@1 270 | int v63; // eax@1 271 | int v64; // eax@1 272 | int v65; // edx@1 273 | int v66; // eax@1 274 | int v67; // edi@1 275 | int v68; // eax@1 276 | signed __int32 v69; // eax@1 277 | int v72; // ebx@1 278 | int v73; // eax@1 279 | int v74; // eax@1 280 | int v75; // edi@1 281 | int v76; // edi@1 282 | int v77; // eax@1 283 | int v78; // edx@1 284 | int v79; // eax@1 285 | int v80; // eax@1 286 | int v81; // edx@1 287 | int v82; // ebx@1 288 | int v83; // ebx@1 289 | int v84; // eax@1 290 | signed __int32 v85; // edx@1 291 | int v86; // eax@1 292 | int v87; // eax@1 293 | signed __int32 v88; // eax@1 294 | int v91; // ebx@1 295 | int v92; // eax@1 296 | int v93; // eax@1 297 | int v94; // edi@1 298 | int v95; // edi@1 299 | int v96; // eax@1 300 | int v97; // eax@1 301 | signed __int32 v98; // eax@1 302 | signed __int32 v100; // edx@1 303 | int v102; // ebx@1 304 | int v103; // eax@1 305 | int v104; // edi@1 306 | int v105; // edi@1 307 | int v106; // eax@1 308 | int v107; // eax@1 309 | unsigned __int32 v108; // eax@1 310 | int v109; // ecx@1 311 | int v110; // ecx@1 312 | int v111; // edi@1 313 | int v112; // edi@1 314 | signed __int32 v113; // edx@1 315 | int v114; // eax@1 316 | signed __int32 v115; // eax@1 317 | int v118; // ecx@1 318 | int v119; // ecx@1 319 | signed __int32 v120; // edx@1 320 | int v121; // eax@1 321 | int v122; // eax@1 322 | signed __int32 v123; // eax@1 323 | int v126; // eax@1 324 | int v127; // ebx@1 325 | int v128; // ebx@1 326 | int v129; // eax@1 327 | int v130; // eax@1 328 | int v131; // edi@1 329 | int v132; // edi@1 330 | int v133; // eax@1 331 | int v134; // eax@1 332 | int v135; // eax@1 333 | int v136; // edi@1 334 | int v137; // eax@1 335 | signed __int32 v138; // eax@1 336 | signed __int32 v140; // edx@1 337 | int v142; // edx@1 338 | int v143; // edx@1 339 | int v144; // eax@1 340 | int v145; // eax@1 341 | int v146; // edi@1 342 | int v147; // edi@1 343 | int v148; // ecx@1 344 | int v149; // ecx@1 345 | int v150; // edx@1 346 | int v151; // edx@1 347 | int v152; // edi@1 348 | int v153; // edi@1 349 | int v154; // eax@1 350 | int v155; // eax@1 351 | int v156; // ebx@1 352 | int v157; // ecx@1 353 | int v158; // ST04_4@1 354 | int v159; // edx@1 355 | int v160; // eax@1 356 | signed __int32 v161; // eax@1 357 | signed __int32 v163; // edx@1 358 | int v165; // edi@1 359 | int v166; // ebx@1 360 | int v167; // ebx@1 361 | int v168; // eax@1 362 | int v169; // ecx@1 363 | int v170; // ecx@1 364 | int v171; // edi@1 365 | int v172; // edi@1 366 | int v173; // eax@1 367 | int v174; // eax@1 368 | int v175; // ebx@1 369 | int v176; // ebx@1 370 | int v177; // eax@1 371 | int v178; // eax@1 372 | unsigned __int32 v179; // eax@1 373 | int v180; // edi@1 374 | signed __int32 v181; // edx@1 375 | signed __int32 v182; // eax@1 376 | int v183; // ecx@1 377 | int v186; // ebx@1 378 | int v187; // edi@1 379 | int v188; // edi@1 380 | int v189; // eax@1 381 | int v190; // eax@1 382 | int v191; // eax@1 383 | signed __int32 v193; // edx@1 384 | int v195; // eax@1 385 | int v196; // eax@1 386 | int v197; // edx@1 387 | int v198; // edx@1 388 | signed __int32 v199; // edx@1 389 | int v200; // ecx@1 390 | int v201; // eax@1 391 | int v202; // eax@1 392 | int v203; // eax@1 393 | int v204; // ecx@1 394 | int v205; // ecx@1 395 | int v206; // eax@1 396 | signed __int32 v209; // edx@1 397 | int v210; // eax@1 398 | int v211; // eax@1 399 | 400 | 401 | l_ResultPartB = v25; 402 | l_ResultPartA = -v21; 403 | 404 | v29 = __ROL4__( 405 | p_This->Key[3] + (l_ResultPartA ^ l_ResultPartB & (l_ResultPartA ^ v219)) + l_ResultPartD + 1935600934, 406 | 20); 407 | v30 = v29 - l_ResultPartB; 408 | l_ResultPartD = v30; 409 | 410 | v219 = v30; 411 | l_ResultPartA = v28; 412 | 413 | v33 = __ROL4__(p_This->Key[3] + (v219 ^ (l_ResultPartD | ~l_ResultPartB)) + l_ResultPartA - 44424322, 16); 414 | v34 = v33 - _byteswap_ulong(~l_ResultPartD); 415 | v35 = __ROL4__(p_This->Key[1] + (v219 ^ (v34 | ~l_ResultPartD)) + l_ResultPartB - 1072881336, 24); 416 | v36 = v34 + v35; 417 | v37 = ScrambleKey_UnkXorShifting(v36, v34, l_ResultPartD); 418 | v38 = __ROL4__(p_This->Key[1] + v37 + v219 + 0x16CB7F43, 2); 419 | v39 = ~v36 + v38; 420 | v40 = __ROL4__(p_This->Key[1] + (v34 & v36 ^ v39 & (v34 ^ v36)) + l_ResultPartD - 57792775, 10); 421 | v41 = v40 - v34; 422 | v42 = v39 + v41 + p_This->Key[0] - v36 + v34 - 1140507570; 423 | l_ResultPartB = ~v39; 424 | v42 = __ROL4__(v42, 3); 425 | v43 = ~v39 + v42; 426 | l_ResultPartD = v41; 427 | v44 = p_This->Key[1] + (v43 & v39 ^ v41 & (v43 ^ v39)); 428 | l_ResultPartA = v43; 429 | v45 = __ROL4__(v44 + v36 - 926107165, 14); 430 | l_ResultPartB = ~v39 ^ v45; 431 | v46 = __ROL4__(p_This->Key[3] + (v43 & l_ResultPartB ^ v41 & (v43 ^ l_ResultPartB)) + v39 - 1784804023, 18); 432 | v47 = v46 - v43; 433 | v219 = v47; 434 | 435 | l_ResultPartB = v47; 436 | l_ResultPartD = v44; 437 | 438 | v50 = __ROL4__(p_This->Key[1] + (l_ResultPartA ^ (v219 | ~l_ResultPartB)) + l_ResultPartD + 1931948882, 21); 439 | v51 = v50 + v219 + 1; 440 | v52 = p_This->Key[3]; 441 | v53 = __ROL4__(v52 + (v219 ^ (v51 | ~l_ResultPartB)) + l_ResultPartA - 858370070, 22); 442 | v54 = _byteswap_ulong(v51) ^ v53; 443 | v55 = __ROL4__(l_ResultPartB + v51 + v52 - v219 + v54 - 1272824402, 17); 444 | v56 = v55 + v51 + 1; 445 | v57 = p_This->Key[0] + (v54 ^ v56 ^ v51); 446 | l_ResultPartB = v56; 447 | v58 = __ROL4__(v57 + v219 - 465401009, 18); 448 | v219 = v58 - v51; 449 | v59 = __ROL4__(ScrambleKey_UnkXorShifting(v54, v58 - v51, v56) + v51 + p_This->Key[3] - 1169475669, 24); 450 | l_ResultPartD = v59 - _byteswap_ulong(~v54); 451 | v60 = __ROL4__(p_This->Key[1] + (l_ResultPartB ^ v219 & (l_ResultPartB ^ l_ResultPartD)) + v54 + 1669942078, 2); 452 | l_ResultPartA = v60 - v219; 453 | ScrambleKey_UnkMultSum((int)&l_ResultPartA, (int)&v219, l_ResultPartD, l_ResultPartB); 454 | v61 = l_ResultPartA; 455 | v62 = l_ResultPartD; 456 | v63 = ScrambleKey_UnkXorShifting(v219, l_ResultPartD, l_ResultPartA); 457 | v64 = __ROL4__(p_This->Key[3] + v63 + l_ResultPartB + 341668086, 5); 458 | v65 = ~v219; 459 | v66 = ~v219 + v64; 460 | v67 = p_This->Key[1] + (v66 ^ (v61 | ~v62)); 461 | l_ResultPartB = v66; 462 | v68 = __ROL4__(v67 + v219 + 1517207598, 5); 463 | v69 = ~v61 + v68; 464 | v219 = v69; 465 | 466 | l_ResultPartD = v69; 467 | l_ResultPartB = v65; 468 | 469 | v72 = p_This->Key[0]; 470 | v73 = __ROL4__(p_This->Key[3] + (l_ResultPartA ^ l_ResultPartB ^ v219) + l_ResultPartD + 817002477, 20); 471 | v74 = _byteswap_ulong(~l_ResultPartA) ^ v73; 472 | v75 = __ROL4__(v219 + v74 + p_This->Key[0] - l_ResultPartB + l_ResultPartA - 576727961, 27); 473 | v76 = v75 - v219; 474 | l_ResultPartD = v74; 475 | v77 = ScrambleKey_UnkXorShifting(v219, v76, v74); 476 | v78 = __ROL4__(v77 + l_ResultPartB + p_This->Key[3] - 2061401035, 19); 477 | l_ResultPartB = v219 ^ v78; 478 | v79 = ScrambleKey_UnkXorShifting(v76, v219 ^ v78, l_ResultPartD); 479 | v80 = __ROL4__(v79 + v72 + v219 - 498018272, 24); 480 | v81 = v80 + v76 + 1; 481 | v82 = __ROL4__(l_ResultPartB + l_ResultPartD + v72 - v81 + v76 + 590866247, 30); 482 | v83 = _byteswap_ulong(~v76) + v82; 483 | v219 = v80 + v76 + 1; 484 | l_ResultPartD = v83; 485 | v84 = __ROL4__(ScrambleKey_UnkXorShifting(l_ResultPartB, v81, v83) + v76 + p_This->Key[2] - 463880395, 9); 486 | v85 = _byteswap_ulong(-l_ResultPartB); 487 | v86 = v84 - v85; 488 | l_ResultPartA = v86; 489 | v87 = __ROL4__(p_This->Key[3] + (v219 ^ (v83 | ~v86)) + l_ResultPartB - 1591766676, 24); 490 | v88 = _byteswap_ulong(-v83) + v87; 491 | l_ResultPartB = v88; 492 | 493 | l_ResultPartA = v88; 494 | v219 = v85; 495 | 496 | v91 = p_This->Key[3]; 497 | v92 = __ROL4__(v91 + (l_ResultPartD ^ l_ResultPartB & (l_ResultPartA ^ l_ResultPartD)) + v219 + 749824959, 23); 498 | v93 = ~l_ResultPartB + v92; 499 | v94 = __ROL4__(v91 + (l_ResultPartA ^ l_ResultPartB ^ v93) + l_ResultPartD - 136550937, 21); 500 | v95 = -l_ResultPartB ^ v94; 501 | v219 = v93; 502 | l_ResultPartD = v95; 503 | v96 = ScrambleKey_UnkXorShifting(v95, l_ResultPartB, v93); 504 | v97 = __ROL4__(v96 + l_ResultPartA + v91 - 49354047, 30); 505 | v98 = ~v95 + v97; 506 | l_ResultPartA = v98; 507 | 508 | l_ResultPartB = v98; 509 | v219 = v100; 510 | 511 | v102 = l_ResultPartA; 512 | v103 = ScrambleKey_UnkXorShifting(l_ResultPartA, v219, l_ResultPartD); 513 | v104 = __ROL4__(p_This->Key[1] + v103 + l_ResultPartB + 1684704892, 21); 514 | v105 = v104 - v102; 515 | v219 = v219 + v105 + p_This->Key[0] + 2 * l_ResultPartD - v102 - 141223932; 516 | v106 = ScrambleKey_UnkXorShifting(v102, v219, v105); 517 | v107 = __ROL4__(v106 + l_ResultPartD + p_This->Key[0] - 1722647589, 10); 518 | v108 = _byteswap_ulong(~v102) ^ v107; 519 | v109 = p_This->Key[3] + (v105 ^ v219 ^ v108); 520 | l_ResultPartD = v108; 521 | v110 = __ROL4__(v109 + v102 + 0x70251807, 16); 522 | l_ResultPartA = _byteswap_ulong(v219) + v110; 523 | v111 = __ROL4__(p_This->Key[0] + (v219 ^ (l_ResultPartA | ~v108)) + v105 - 1019739042, 25); 524 | v112 = -l_ResultPartA ^ v111; 525 | v113 = v219; 526 | v114 = __ROL4__(p_This->Key[2] + (l_ResultPartA ^ v112 ^ v108) + v219 - 1888176249, 24); 527 | v115 = ~l_ResultPartA + v114; 528 | l_ResultPartB = v112; 529 | v219 = v115; 530 | 531 | l_ResultPartB = v115; 532 | l_ResultPartD = v113; 533 | 534 | v118 = __ROL4__(p_This->Key[3] + (v219 ^ (l_ResultPartB | ~l_ResultPartA)) + l_ResultPartD + 721969381, 5); 535 | v119 = ~l_ResultPartB + v118; 536 | v120 = _byteswap_ulong(~l_ResultPartB); 537 | v121 = p_This->Key[2] + (v119 ^ (l_ResultPartB | ~v219)); 538 | l_ResultPartD = v119; 539 | v122 = __ROL4__(v121 + l_ResultPartA - 294827682, 2); 540 | v123 = v122 - v120; 541 | l_ResultPartA = v123; 542 | 543 | v219 = v123; 544 | l_ResultPartD = v120; 545 | 546 | v126 = p_This->Key[1]; 547 | v127 = __ROL4__(v126 + (l_ResultPartA ^ v219 ^ l_ResultPartD) + l_ResultPartB - 1121068160, 1); 548 | v128 = v127 - _byteswap_ulong(l_ResultPartA); 549 | v129 = __ROL4__(v128 + v219 + v126 - l_ResultPartD + l_ResultPartA + 852905038, 17); 550 | v130 = v129 - v128; 551 | v131 = __ROL4__(p_This->Key[3] + (l_ResultPartA ^ v128 ^ v130) + l_ResultPartD - 1918557888, 28); 552 | v132 = l_ResultPartA ^ v131; 553 | v219 = v130; 554 | l_ResultPartD = v132; 555 | v133 = ScrambleKey_UnkXorShifting(v132, v128, v130); 556 | v134 = __ROL4__(v133 + l_ResultPartA + p_This->Key[0] - 586597598, 15); 557 | v135 = v134 - v132; 558 | v136 = p_This->Key[1] + (v135 ^ v219 & (v135 ^ v132)); 559 | l_ResultPartA = v135; 560 | v137 = __ROL4__(v136 + v128 - 1256288990, 28); 561 | v138 = v137 + v219 + 1; 562 | 563 | l_ResultPartA = v140; 564 | l_ResultPartB = v138; 565 | l_ResultPartD = v138; 566 | 567 | v142 = __ROL4__(l_ResultPartB + v219 + p_This->Key[2] - l_ResultPartD + l_ResultPartA - 2139378914, 26); 568 | v143 = ~l_ResultPartA ^ v142; 569 | v144 = __ROL4__(p_This->Key[0] + (l_ResultPartA ^ l_ResultPartB ^ v143) + l_ResultPartD - 1138839693, 19); 570 | v145 = v144 - v143; 571 | v146 = __ROL4__(p_This->Key[3] + (l_ResultPartB ^ v143 ^ v145) + l_ResultPartA - 1344109271, 29); 572 | v147 = v146 - v145; 573 | v148 = v143 + v145 + p_This->Key[1] - v147 + l_ResultPartB + 1432226185; 574 | l_ResultPartA = v147; 575 | v148 = __ROL4__(v148, 30); 576 | v149 = v145 ^ v148; 577 | v150 = __ROL4__(p_This->Key[2] + (v149 ^ (v145 | ~v147)) + v143 - 1744504997, 4); 578 | v151 = v145 + v150; 579 | v152 = __ROL4__(p_This->Key[0] + (v151 ^ (v147 | ~v149)) + v145 - 1992707294, 4); 580 | v153 = v152 - l_ResultPartA; 581 | v154 = __ROL4__(p_This->Key[3] + (v149 & v151 ^ v153 & (v149 ^ v151)) + l_ResultPartA + 981988726, 9); 582 | v155 = v154 - _byteswap_ulong(-v149); 583 | v156 = p_This->Key[0] + (v155 ^ v151 ^ v153); 584 | l_ResultPartA = v155; 585 | v157 = __ROL4__(v156 + v149 - 930831509, 13); 586 | l_ResultPartB = v151 + v157; 587 | v158 = v151 + v157; 588 | v159 = __ROL4__(p_This->Key[2] + (v155 ^ (v153 | ~(v151 + v157))) + v151 + 354549815, 28); 589 | v219 = v153 + v159; 590 | v160 = __ROL4__(ScrambleKey_UnkXorShifting(v155, v153 + v159, v158) + v153 + p_This->Key[3] - 980228899, 23); 591 | v161 = l_ResultPartA + v160; 592 | l_ResultPartD = v161; 593 | 594 | v219 = v161; 595 | l_ResultPartB = v163; 596 | 597 | v165 = p_This->Key[3]; 598 | v166 = __ROL4__(v165 + (l_ResultPartB ^ v219 & (l_ResultPartB ^ l_ResultPartD)) + l_ResultPartA + 1602925481, 24); 599 | v167 = _byteswap_ulong(~v219) ^ v166; 600 | v168 = ScrambleKey_UnkXorShifting(l_ResultPartD, v167, v219); 601 | v169 = __ROL4__(v168 + v165 + l_ResultPartB - 1900654549, 31); 602 | v170 = l_ResultPartD + v169; 603 | v171 = __ROL4__(v165 + (v167 ^ (v170 | ~l_ResultPartD)) + v219 - 1925935449, 11); 604 | v172 = ~v170 ^ v171; 605 | l_ResultPartB = v170; 606 | v173 = ScrambleKey_UnkXorShifting(v170, v172, v167); 607 | v174 = __ROL4__(p_This->Key[1] + v173 + l_ResultPartD + 1445381881, 7); 608 | l_ResultPartD = l_ResultPartB + v174; 609 | v175 = __ROL4__(p_This->Key[0] + ScrambleKey_UnkXorShifting(v172, l_ResultPartB, l_ResultPartB + v174) + v167 + 109428117, 29); 610 | v176 = ~v172 ^ v175; 611 | l_ResultPartA = v176; 612 | v177 = ScrambleKey_UnkXorShifting(v176, l_ResultPartD, v172); 613 | v178 = __ROL4__(v177 + l_ResultPartB + p_This->Key[2] - 1217426128, 22); 614 | v179 = _byteswap_ulong(~v176) ^ v178; 615 | l_ResultPartB = v179; 616 | v180 = __ROL4__(p_This->Key[3] + (l_ResultPartA & v179 ^ l_ResultPartD & (v176 ^ v179)) + v172 - 1216826231, 17); 617 | v219 = ~v179 ^ v180; 618 | v181 = p_This->Key[0] + (v219 ^ v179 & (l_ResultPartA ^ v219)); 619 | v182 = -v179; 620 | v183 = __ROL4__(v181 + l_ResultPartD + 1130335055, 20); 621 | l_ResultPartD = v182 ^ v183; 622 | 623 | l_ResultPartA = v182; 624 | v219 = v181; 625 | 626 | v186 = p_This->Key[2]; 627 | v187 = __ROL4__(v186 + (v219 ^ l_ResultPartB & (v219 ^ l_ResultPartD)) + l_ResultPartA - 1067365145, 29); 628 | v188 = -l_ResultPartB ^ v187; 629 | l_ResultPartA = v188; 630 | v189 = ScrambleKey_UnkXorShifting(v188, l_ResultPartD, v219); 631 | v190 = __ROL4__(v189 + l_ResultPartB + v186 - 943834555, 21); 632 | v191 = v188 ^ v190; 633 | l_ResultPartB = v191; 634 | 635 | l_ResultPartD = v191; 636 | v219 = v193; 637 | v195 = __ROL4__( 638 | p_This->Key[2] 639 | + (l_ResultPartA & l_ResultPartB ^ l_ResultPartD & (l_ResultPartA ^ l_ResultPartB)) 640 | + v219 641 | - 408343377, 642 | 13); 643 | v196 = l_ResultPartD ^ v195; 644 | v197 = p_This->Key[0] + (v196 ^ l_ResultPartB & (l_ResultPartA ^ v196)); 645 | v219 = v196; 646 | v198 = __ROL4__(v197 + l_ResultPartD + 1076531487, 10); 647 | v199 = v198 - l_ResultPartB; 648 | v200 = v196 ^ v199; 649 | v201 = p_This->Key[1] + (l_ResultPartB ^ v196 ^ v199); 650 | l_ResultPartD = v199; 651 | v202 = __ROL4__(v201 + l_ResultPartA - 496270228, 4); 652 | v203 = v199 + v202; 653 | v204 = p_This->Key[2] + (v203 ^ v200); 654 | l_ResultPartA = v203; 655 | v205 = __ROL4__(v204 + l_ResultPartB - 30260576, 24); 656 | v206 = ~v203; 657 | 658 | l_ResultPartB = v206 + v205; 659 | l_ResultPartD = v206; 660 | 661 | v219 = v199; 662 | 663 | v210 = __ROL4__(p_This->Key[3] + (l_ResultPartB ^ (l_ResultPartD | ~l_ResultPartA)) + v219 + 0x74B03359, 2); 664 | v211 = l_ResultPartD ^ v210; 665 | v219 = v211; 666 | 667 | l_ResultPartA = v211; 668 | l_ResultPartA += 0x31307474; 669 | l_ResultPartB = v209; 670 | l_ResultPartB -= 875575088; 671 | l_ResultPartC = v219 ^ 0x38; 672 | 673 | p_This->Key[0] += l_ResultPartA; 674 | p_This->Key[1] += l_ResultPartB; 675 | p_This->Key[2] += l_ResultPartC; 676 | p_This->Key[3] += l_ResultPartD 677 | 678 | _m_femms(); 679 | 680 | return l_ResultPartD; 681 | } 682 | } ///< namespace Warden 683 | } ///< namespace World 684 | } ///< namespace RCN 685 | -------------------------------------------------------------------------------- /World/Warden/WorldWardenUtils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Network/ByteBuffer.hpp" 4 | #include "WorldWardenStructs.hpp" 5 | 6 | namespace RCN { namespace World { namespace Warden { 7 | 8 | /// Get module mapped size 9 | /// @p_Input : Input decompressed warden module 10 | size_t GetModuleMapedSize(RCN::Network::ByteBuffer& p_Input); 11 | /// Remap warden module 12 | /// @p_Input : Input decompressed warden module 13 | uint32_t RemapModule(RCN::Network::ByteBuffer& p_Input); 14 | 15 | void ScrambleKey(); 16 | 17 | } ///< namespace Warden 18 | } ///< namespace World 19 | } ///< namespace RCN 20 | -------------------------------------------------------------------------------- /World/WorldManager.cpp: -------------------------------------------------------------------------------- 1 | #include "WorldManager.hpp" 2 | #include "Network/WorldOpcodes.hpp" 3 | #include 4 | 5 | namespace RCN { namespace World { 6 | 7 | /// Constructor 8 | WorldManager::WorldManager() 9 | { 10 | Network::InitWorldNetworkOpcodes(); 11 | 12 | m_Socket = new Network::WorldSocket(this); 13 | } 14 | /// Destructor 15 | WorldManager::~WorldManager() 16 | { 17 | delete m_Socket; 18 | } 19 | 20 | ////////////////////////////////////////////////////////////////////////// 21 | ////////////////////////////////////////////////////////////////////////// 22 | 23 | /// Do the connection 24 | /// @p_Realm : Realm 25 | /// @p_Key : Session key 26 | /// @p_Account : Account name 27 | bool WorldManager::Connect(Logon::RealmInfo p_Realm, Crypto::BigNumber p_SessionKey, std::string p_Account) 28 | { 29 | m_Account = p_Account; 30 | 31 | std::transform(m_Account.begin(), m_Account.end(), m_Account.begin(), ::toupper); 32 | 33 | if (!m_Socket->Connect(p_Realm, p_SessionKey)) 34 | return false; 35 | 36 | return true; 37 | } 38 | 39 | ////////////////////////////////////////////////////////////////////////// 40 | ////////////////////////////////////////////////////////////////////////// 41 | 42 | /// Run 43 | void WorldManager::Run() 44 | { 45 | while (m_Socket->IsConnected()) 46 | { 47 | /// Copy all packets in queue with 20 as max limit 48 | std::vector l_Packets; 49 | { 50 | std::lock_guard l_Lock(m_PacketQueueMutex); 51 | 52 | for (size_t l_I = 0; l_I < 20; ++l_I) 53 | { 54 | if (m_PacketQueue.empty()) 55 | break; 56 | 57 | l_Packets.push_back(std::move(m_PacketQueue.front())); 58 | m_PacketQueue.pop(); 59 | } 60 | } 61 | 62 | /// Handle packets 63 | for (auto& l_Packet : l_Packets) 64 | { 65 | printf("[WORLD] Receive packet %s(%u) size %u\n", Network::OpcodesName[l_Packet.GetOpcode()], l_Packet.GetOpcode(), l_Packet.GetSize()); 66 | 67 | if (Network::OpcodesHandlers[l_Packet.GetOpcode()]) 68 | Network::OpcodesHandlers[l_Packet.GetOpcode()](l_Packet, this); 69 | } 70 | 71 | Sleep(5); 72 | } 73 | } 74 | 75 | ////////////////////////////////////////////////////////////////////////// 76 | ////////////////////////////////////////////////////////////////////////// 77 | 78 | /// Enqueue a packet 79 | /// @p_Packet : World packet to enqueue 80 | void WorldManager::EnqueuePacket(Network::WorldPacket&& p_Packet) 81 | { 82 | std::lock_guard l_Lock(m_PacketQueueMutex); 83 | m_PacketQueue.push(std::move(p_Packet)); 84 | } 85 | 86 | ////////////////////////////////////////////////////////////////////////// 87 | ////////////////////////////////////////////////////////////////////////// 88 | 89 | /// Get world socket 90 | Network::WorldSocket * WorldManager::GetWorldSocket() 91 | { 92 | return m_Socket; 93 | } 94 | /// Get account name 95 | std::string WorldManager::GetAccountName() 96 | { 97 | return m_Account; 98 | } 99 | 100 | } ///< namespace World 101 | } ///< namespace RCN -------------------------------------------------------------------------------- /World/WorldManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Network/WorldSocket.hpp" 4 | #include 5 | #include 6 | 7 | namespace RCN { namespace World { 8 | 9 | class WorldManager 10 | { 11 | public: 12 | /// Constructor 13 | WorldManager(); 14 | /// Destructor 15 | ~WorldManager(); 16 | 17 | /// Do the connection 18 | /// @p_Realm : Realm 19 | /// @p_Key : Session key 20 | /// @p_Account : Account name 21 | bool Connect(Logon::RealmInfo p_Realm, Crypto::BigNumber p_SessionKey, std::string p_Account); 22 | 23 | /// Run 24 | void Run(); 25 | 26 | /// Enqueue a packet 27 | /// @p_Packet : World packet to enqueue 28 | void EnqueuePacket(Network::WorldPacket&& p_Packet); 29 | 30 | public: 31 | /// Get world socket 32 | Network::WorldSocket * GetWorldSocket(); 33 | /// Get account name 34 | std::string GetAccountName(); 35 | 36 | private: 37 | Network::WorldSocket * m_Socket; ///< World socket 38 | std::string m_Account; ///< Account name 39 | 40 | std::queue m_PacketQueue; 41 | std::mutex m_PacketQueueMutex; 42 | }; 43 | 44 | } ///< namespace World 45 | } ///< namespace RCN --------------------------------------------------------------------------------