diff options
55 files changed, 1446 insertions, 964 deletions
diff --git a/src/server/bnetserver/Authentication/AuthCodes.cpp b/src/server/bnetserver/Authentication/AuthCodes.cpp index 97723816ce3..a717263786e 100644 --- a/src/server/bnetserver/Authentication/AuthCodes.cpp +++ b/src/server/bnetserver/Authentication/AuthCodes.cpp @@ -16,34 +16,36 @@ */ #include "AuthCodes.h" -#include <cstddef> +#include "Define.h" +#include <vector> namespace AuthHelper { - static RealmBuildInfo const PostBcAcceptedClientBuilds[] = + // List of client builds for verbose version info in realmlist packet + static std::vector<RealmBuildInfo> const ClientBuilds = { - {15595, 4, 3, 4, ' '}, - {14545, 4, 2, 2, ' '}, - {13623, 4, 0, 6, 'a'}, - {13930, 3, 3, 5, 'a'}, // 3.3.5a China Mainland build - {12340, 3, 3, 5, 'a'}, - {11723, 3, 3, 3, 'a'}, - {11403, 3, 3, 2, ' '}, - {11159, 3, 3, 0, 'a'}, - {10505, 3, 2, 2, 'a'}, - {9947, 3, 1, 3, ' '}, - {8606, 2, 4, 3, ' '}, - {6141, 1, 12, 3, ' '}, - {6005, 1, 12, 2, ' '}, - {5875, 1, 12, 1, ' '}, - {0, 0, 0, 0, ' '} // terminator + { 20490, 6, 2, 2, 'a' }, + { 15595, 4, 3, 4, ' ' }, + { 14545, 4, 2, 2, ' ' }, + { 13623, 4, 0, 6, 'a' }, + { 13930, 3, 3, 5, 'a' }, // 3.3.5a China Mainland build + { 12340, 3, 3, 5, 'a' }, + { 11723, 3, 3, 3, 'a' }, + { 11403, 3, 3, 2, ' ' }, + { 11159, 3, 3, 0, 'a' }, + { 10505, 3, 2, 2, 'a' }, + { 9947, 3, 1, 3, ' ' }, + { 8606, 2, 4, 3, ' ' }, + { 6141, 1, 12, 3, ' ' }, + { 6005, 1, 12, 2, ' ' }, + { 5875, 1, 12, 1, ' ' }, }; RealmBuildInfo const* GetBuildInfo(int build) { - for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i) - if (PostBcAcceptedClientBuilds[i].Build == build) - return &PostBcAcceptedClientBuilds[i]; + for (int32 i = 0; ClientBuilds.size(); ++i) + if (ClientBuilds[i].Build == build) + return &ClientBuilds[i]; return nullptr; } diff --git a/src/server/bnetserver/Authentication/AuthCodes.h b/src/server/bnetserver/Authentication/AuthCodes.h index e7b1582a6af..a217238fe59 100644 --- a/src/server/bnetserver/Authentication/AuthCodes.h +++ b/src/server/bnetserver/Authentication/AuthCodes.h @@ -109,6 +109,39 @@ namespace Battlenet LOGIN_INVALID_PAYMENT = 219, LOGIN_INVALID_ACCOUNT_STATE = 220 }; + + namespace Wow + { + enum AuthResult + { + WOW_SUCCESS = 0, + WOW_FAIL_BANNED = 3, + WOW_FAIL_UNKNOWN_ACCOUNT = 4, + WOW_FAIL_INCORRECT_PASSWORD = 5, + WOW_FAIL_ALREADY_ONLINE = 6, + WOW_FAIL_NO_TIME = 7, + WOW_FAIL_DB_BUSY = 8, + WOW_FAIL_VERSION_INVALID = 9, + WOW_FAIL_VERSION_UPDATE = 10, + WOW_FAIL_INVALID_SERVER = 11, + WOW_FAIL_SUSPENDED = 12, + WOW_FAIL_FAIL_NOACCESS = 13, + WOW_SUCCESS_SURVEY = 14, + WOW_FAIL_PARENTCONTROL = 15, + WOW_FAIL_LOCKED_ENFORCED = 16, + WOW_FAIL_TRIAL_ENDED = 17, + WOW_FAIL_OVERMIND_CONVERTED = 18, + WOW_FAIL_ANTI_INDULGENCE = 19, + WOW_FAIL_EXPIRED = 20, + WOW_FAIL_NO_GAME_ACCOUNT = 21, + WOW_FAIL_BILLING_LOCK = 22, + WOW_FAIL_IGR_WITHOUT_BNET = 23, + WOW_FAIL_AA_LOCK = 24, + WOW_FAIL_UNLOCKABLE_LOCK = 25, + WOW_FAIL_MUST_USE_BNET = 26, + WOW_FAIL_OTHER = 255, + }; + } } struct RealmBuildInfo diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt index f3089202889..cc7f59743ac 100644 --- a/src/server/bnetserver/CMakeLists.txt +++ b/src/server/bnetserver/CMakeLists.txt @@ -63,9 +63,9 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/database/Database ${CMAKE_SOURCE_DIR}/src/server/database/Logging ${CMAKE_SOURCE_DIR}/src/server/ipc + ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Networking ${CMAKE_SOURCE_DIR}/src/server/shared/Packets - ${CMAKE_SOURCE_DIR}/src/server/shared/Realm ${CMAKE_SOURCE_DIR}/src/server/shared/Service ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.cpp b/src/server/bnetserver/Packets/AuthenticationPackets.cpp index 4c49bdcc5f1..10c0bfe2499 100644 --- a/src/server/bnetserver/Packets/AuthenticationPackets.cpp +++ b/src/server/bnetserver/Packets/AuthenticationPackets.cpp @@ -19,22 +19,33 @@ #include "Session.h" #include "Util.h" +std::string Battlenet::Authentication::RequestCommon::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::RequestCommon" << std::endl; + APPEND_FIELD(stream, Program); + APPEND_FIELD(stream, Platform); + APPEND_FIELD(stream, Locale); + APPEND_FIELD(stream, Versions); + return stream.str(); +} + void Battlenet::Authentication::ResumeRequest::Read() { - Program = _stream.ReadFourCC(); - Platform = _stream.ReadFourCC(); - Locale = _stream.ReadFourCC(); + Common.Program = _stream.ReadFourCC(); + Common.Platform = _stream.ReadFourCC(); + Common.Locale = _stream.ReadFourCC(); - Components.resize(_stream.Read<uint32>(6)); - for (size_t i = 0; i < Components.size(); ++i) + Common.Versions.resize(_stream.Read<uint32>(6)); + for (size_t i = 0; i < Common.Versions.size(); ++i) { - Component& component = Components[i]; - component.Program = _stream.ReadFourCC(); - component.Platform = _stream.ReadFourCC(); - component.Build = _stream.Read<uint32>(32); + Version::Record& component = Common.Versions[i]; + component.ProgramId = _stream.ReadFourCC(); + component.Component = _stream.ReadFourCC(); + component.Version = _stream.Read<uint32>(32); } - Login = _stream.ReadString(9, 3); + Account = _stream.ReadString(9, 3); GameAccountRegion = _stream.Read<uint8>(8); GameAccountName = _stream.ReadString(5, 1); } @@ -42,14 +53,11 @@ void Battlenet::Authentication::ResumeRequest::Read() std::string Battlenet::Authentication::ResumeRequest::ToString() const { std::ostringstream stream; - stream << "Battlenet::Authentication::ResumeRequest Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale; - for (Component const& component : Components) - stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build; - - stream << std::endl << "Login: " << Login; - stream << std::endl << "GameAccountRegion: " << uint32(GameAccountRegion); - stream << std::endl << "GameAccountName: " << GameAccountName; - + stream << "Battlenet::Authentication::ResumeRequest" << std::endl; + APPEND_FIELD(stream, Common); + APPEND_FIELD(stream, Account); + APPEND_FIELD(stream, GameAccountRegion); + APPEND_FIELD(stream, GameAccountName); return stream.str(); } @@ -58,47 +66,18 @@ void Battlenet::Authentication::ResumeRequest::CallHandler(Session* session) session->HandleResumeRequest(*this); } -Battlenet::Authentication::ProofRequest::~ProofRequest() -{ - for (size_t i = 0; i < Modules.size(); ++i) - delete Modules[i]; -} - -void Battlenet::Authentication::ProofRequest::Write() -{ - _stream.Write(Modules.size(), 3); - for (ModuleInfo const* info : Modules) - { - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - _stream.Write(info->DataSize, 10); - _stream.WriteBytes(info->Data, info->DataSize); - } -} - -std::string Battlenet::Authentication::ProofRequest::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::ProofRequest modules " << Modules.size(); - for (ModuleInfo const* module : Modules) - stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); - - return stream.str(); -} - Battlenet::Authentication::ProofResponse::~ProofResponse() { - for (size_t i = 0; i < Modules.size(); ++i) - delete Modules[i]; + for (size_t i = 0; i < Response.size(); ++i) + delete Response[i]; } void Battlenet::Authentication::ProofResponse::Read() { - Modules.resize(_stream.Read<uint32>(3)); - for (size_t i = 0; i < Modules.size(); ++i) + Response.resize(_stream.Read<uint32>(3)); + for (size_t i = 0; i < Response.size(); ++i) { - BitStream*& dataStream = Modules[i]; + BitStream*& dataStream = Response[i]; dataStream = new BitStream(_stream.Read<uint32>(10)); memcpy(dataStream->GetBuffer(), _stream.ReadBytes(dataStream->GetSize()).get(), dataStream->GetSize()); } @@ -107,13 +86,8 @@ void Battlenet::Authentication::ProofResponse::Read() std::string Battlenet::Authentication::ProofResponse::ToString() const { std::ostringstream stream; - stream << "Battlenet::Authentication::ProofResponse Modules " << Modules.size(); - for (BitStream* module : Modules) - { - std::string hexStr = ByteArrayToHexStr(module->GetBuffer(), module->GetSize()); - stream << std::endl << "Battlenet::Authentication::ProofResponse::ModuleData Size: " << module->GetSize() << ", Data: " << hexStr; - } - + stream << "Battlenet::Authentication::ProofRequest" << std::endl; + APPEND_FIELD(stream, Response.size()); return stream.str(); } @@ -124,21 +98,21 @@ void Battlenet::Authentication::ProofResponse::CallHandler(Session* session) void Battlenet::Authentication::LogonRequest3::Read() { - Program = _stream.ReadFourCC(); - Platform = _stream.ReadFourCC(); - Locale = _stream.ReadFourCC(); + Common.Program = _stream.ReadFourCC(); + Common.Platform = _stream.ReadFourCC(); + Common.Locale = _stream.ReadFourCC(); - Components.resize(_stream.Read<uint32>(6)); - for (size_t i = 0; i < Components.size(); ++i) + Common.Versions.resize(_stream.Read<uint32>(6)); + for (size_t i = 0; i < Common.Versions.size(); ++i) { - Component& component = Components[i]; - component.Program = _stream.ReadFourCC(); - component.Platform = _stream.ReadFourCC(); - component.Build = _stream.Read<uint32>(32); + Version::Record& component = Common.Versions[i]; + component.ProgramId = _stream.ReadFourCC(); + component.Component = _stream.ReadFourCC(); + component.Version = _stream.Read<uint32>(32); } if (_stream.Read<uint32>(1)) - Login = _stream.ReadString(9, 3); + Account = _stream.ReadString(9, 3); Compatibility = _stream.Read<uint64>(64); } @@ -146,15 +120,10 @@ void Battlenet::Authentication::LogonRequest3::Read() std::string Battlenet::Authentication::LogonRequest3::ToString() const { std::ostringstream stream; - stream << "Battlenet::Authentication::LogonRequest3 Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale; - for (Component const& component : Components) - stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build; - - if (!Login.empty()) - stream << std::endl << " Login: " << Login; - - stream << " Compatibility: " << Compatibility; - + stream << "Battlenet::Authentication::LogonRequest3" << std::endl; + APPEND_FIELD(stream, Common); + APPEND_FIELD(stream, Account); + APPEND_FIELD(stream, Compatibility); return stream.str(); } @@ -165,142 +134,255 @@ void Battlenet::Authentication::LogonRequest3::CallHandler(Session* session) Battlenet::Authentication::LogonResponse::~LogonResponse() { - for (ModuleInfo* m : Modules) + for (ModuleInfo* m : Result.Success.FinalRequest) delete m; } void Battlenet::Authentication::LogonResponse::Write() { - _stream.Write(Result.ResultValue != ResponseFailure::UPDATE, 1); - if (Result.ResultValue == ResponseFailure::UPDATE) + _stream.Write(Result.Type, 1); + if (Result.Type == ResultType::SUCCESS) { - _stream.Write(Modules.size(), 3); - for (size_t i = 0; i < Modules.size(); ++i) + _stream.Write(Result.Success.FinalRequest.size(), 3); + for (size_t i = 0; i < Result.Success.FinalRequest.size(); ++i) { - ModuleInfo* info = Modules[i]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); + ModuleInfo* info = Result.Success.FinalRequest[i]; + _stream.WriteBytes(info->Handle.Type.c_str(), 4); + _stream.WriteFourCC(info->Handle.Region); + _stream.WriteBytes(info->Handle.ModuleId, 32); _stream.Write(info->DataSize, 10); _stream.WriteBytes(info->Data, info->DataSize); } - _stream.Write(PingTimeout + std::numeric_limits<int32>::min(), 32); - _stream.Write(1, 1); // RegulatorRules != NULL (not a pointer for us, always write) - // if written == 1 + _stream.Write(Result.Success.PingTimeout + std::numeric_limits<int32>::min(), 32); + _stream.Write(Result.Success.RegulatorRules.is_initialized(), 1); + if (Result.Success.RegulatorRules.is_initialized()) { - _stream.Write(RegulatorRules.Type == Regulator::LEAKY_BUCKET, 1); - if (RegulatorRules.Type == Regulator::LEAKY_BUCKET) + _stream.Write(Result.Success.RegulatorRules->Type == Regulator::LEAKY_BUCKET, 1); + if (Result.Success.RegulatorRules->Type == Regulator::LEAKY_BUCKET) { - _stream.Write(RegulatorRules.Threshold, 32); - _stream.Write(RegulatorRules.Rate, 32); + _stream.Write(Result.Success.RegulatorRules->LeakyBucket.Threshold, 32); + _stream.Write(Result.Success.RegulatorRules->LeakyBucket.Rate, 32); } } - _stream.WriteString(FirstName, 8); // First name - _stream.WriteString(LastName, 8); // Last name - not set for WoW - - _stream.Write(AccountId, 32); - _stream.Write(Region, 8); - _stream.Write(Flags, 64); - - _stream.Write(GameAccountRegion, 8); - _stream.WriteString(GameAccountName, 5, -1); - _stream.Write(GameAccountFlags, 64); - - _stream.Write(FailedLogins, 32); - _stream.Write(false, 1); // RaF + _stream.WriteString(Result.Success.FullName.GivenName, 8); + _stream.WriteString(Result.Success.FullName.Surname, 8); + _stream.Write(Result.Success.AccountId, 32); + _stream.Write(Result.Success.Region, 8); + _stream.Write(Result.Success.Flags, 64); + _stream.Write(Result.Success.GameAccountRegion, 8); + _stream.WriteString(Result.Success.GameAccountName, 5, -1); + _stream.Write(Result.Success.GameAccountFlags, 64); + _stream.Write(Result.Success.LogonFailures, 32); } else { - _stream.Write(!Modules.empty(), 1); - if (!Modules.empty()) + _stream.Write(Result.Failure.Strings.is_initialized(), 1); + if (Result.Failure.Strings.is_initialized()) { - ModuleInfo* info = Modules[0]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); + _stream.WriteBytes(Result.Failure.Strings->Type.c_str(), 4); + _stream.WriteFourCC(Result.Failure.Strings->Region); + _stream.WriteBytes(Result.Failure.Strings->ModuleId, 32); } - _stream.Write(Result.ResultValue, 2); - if (Result.ResultValue == ResponseFailure::FAILURE) + _stream.Write(Result.Failure.Result.Type, 2); + if (Result.Failure.Result.Type == FailureType::FAILURE) { - _stream.Write(Result.Error, 16); - _stream.Write(Result.Wait + std::numeric_limits<int32>::min(), 32); + _stream.Write(Result.Failure.Result.Failure.Error, 16); + _stream.Write(Result.Failure.Result.Failure.Wait + std::numeric_limits<int32>::min(), 32); } } + + _stream.Write(Raf.is_initialized(), 1); + if (Raf.is_initialized()) + { + _stream.Write(Raf->size(), 10); + _stream.WriteBytes(Raf->data(), Raf->size()); + } } std::string Battlenet::Authentication::LogonResponse::ToString() const { std::ostringstream stream; - stream << "Battlenet::Authentication::LogonResponse AuthResult " << Result.Error << " PingTimeout " << PingTimeout - << " RegulatorRules.Threshold " << RegulatorRules.Threshold << " RegulatorRules.Rate " << RegulatorRules.Rate - << " FirstName " << FirstName << " LastName " << LastName << " AccountId " << AccountId << " Region " << uint32(Region) << " GameAccountName " << GameAccountName - << " GameAccountFlags " << GameAccountFlags << " FailedLogins " << FailedLogins << " Modules " << Modules.size(); + stream << "Battlenet::Authentication::LogonResponse" << std::endl; + APPEND_FIELD(stream, Result); + APPEND_FIELD(stream, Raf); + return stream.str(); +} - for (ModuleInfo const* module : Modules) - stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); +std::string Battlenet::Authentication::FailureType::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::FailureType" << std::endl; + APPEND_FIELD(stream, Strings); + APPEND_FIELD(stream, Result); + return stream.str(); +} +std::string Battlenet::Authentication::FailureType::ResultType::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::ResponseFailure::Result" << std::endl; + switch (Type) + { + case UPDATE: + APPEND_FIELD(stream, Update); + break; + case FAILURE: + APPEND_FIELD(stream, Failure); + break; + case VERSION_CHECK_DISCONNECT: + APPEND_FIELD(stream, VersionCheckDisconnect); + break; + default: + break; + } + return stream.str(); +} + +std::string Battlenet::Authentication::FailureType::ResultType::UpdateType::ToString() const +{ + return "Battlenet::Authentication::ResponseFailure::Result::Update"; +} + +std::string Battlenet::Authentication::FailureType::ResultType::FailureType::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::ResponseFailure::Result::Failure" << std::endl; + APPEND_FIELD(stream, Error); + APPEND_FIELD(stream, Wait); + return stream.str(); +} + +std::string Battlenet::Authentication::FailureType::ResultType::VersionCheckDisconnectType::ToString() const +{ + return "Battlenet::Authentication::ResponseFailure::Result::VersionCheckDisconnect"; +} + +std::string Battlenet::Authentication::Regulator::NoneType::ToString() const +{ + return "Battlenet::Regulator::None"; +} + +std::string Battlenet::Authentication::Regulator::LeakyBucketType::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Regulator::LeakyBucket" << std::endl; + APPEND_FIELD(stream, Threshold); + APPEND_FIELD(stream, Rate); + return stream.str(); +} + +std::string Battlenet::Authentication::Regulator::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Regulator" << std::endl; + switch (Type) + { + case NONE: + APPEND_FIELD(stream, None); + break; + case LEAKY_BUCKET: + APPEND_FIELD(stream, LeakyBucket); + break; + default: + break; + } + return stream.str(); +} + +std::string Battlenet::Authentication::LogonResponse::ResultType::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::LogonResponse::Result" << std::endl; + switch (Type) + { + case SUCCESS: + APPEND_FIELD(stream, Success); + break; + case FAILURE: + APPEND_FIELD(stream, Failure); + break; + default: + break; + } + return stream.str(); +} + +std::string Battlenet::Authentication::LogonResponse::ResultType::SuccessType::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::LogonResponse::Result::Success" << std::endl; + APPEND_FIELD(stream, FinalRequest); + APPEND_FIELD(stream, PingTimeout); + APPEND_FIELD(stream, RegulatorRules); + APPEND_FIELD(stream, FullName); + APPEND_FIELD(stream, AccountId); + APPEND_FIELD(stream, Region); + APPEND_FIELD(stream, Flags); + APPEND_FIELD(stream, GameAccountRegion); + APPEND_FIELD(stream, GameAccountName); + APPEND_FIELD(stream, GameAccountFlags); + APPEND_FIELD(stream, LogonFailures); return stream.str(); } void Battlenet::Authentication::LogonResponse::SetAuthResult(AuthResult result) { - Result.ResultValue = result != AUTH_OK ? ResponseFailure::FAILURE : ResponseFailure::UPDATE; - Result.Error = result; + Result.Type = result != AUTH_OK ? ResultType::FAILURE : ResultType::SUCCESS; + Result.Failure.Result.Failure.Error = result; } Battlenet::Authentication::ResumeResponse::~ResumeResponse() { - for (ModuleInfo* m : Modules) + for (ModuleInfo* m : Result.Success.FinalRequest) delete m; } void Battlenet::Authentication::ResumeResponse::Write() { - _stream.Write(Result.ResultValue != ResponseFailure::UPDATE, 1); - if (Result.ResultValue == ResponseFailure::UPDATE) + _stream.Write(Result.Type, 1); + if (Result.Type == ResultType::SUCCESS) { - _stream.Write(Modules.size(), 3); - for (size_t i = 0; i < Modules.size(); ++i) + _stream.Write(Result.Success.FinalRequest.size(), 3); + for (size_t i = 0; i < Result.Success.FinalRequest.size(); ++i) { - ModuleInfo* info = Modules[i]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); + ModuleInfo* info = Result.Success.FinalRequest[i]; + _stream.WriteBytes(info->Handle.Type.c_str(), 4); + _stream.WriteFourCC(info->Handle.Region); + _stream.WriteBytes(info->Handle.ModuleId, 32); _stream.Write(info->DataSize, 10); _stream.WriteBytes(info->Data, info->DataSize); } - _stream.Write(PingTimeout + std::numeric_limits<int32>::min(), 32); - _stream.Write(1, 1); // RegulatorRules != NULL (not a pointer for us, always write) - // if written == 1 + _stream.Write(Result.Success.PingTimeout + std::numeric_limits<int32>::min(), 32); + _stream.Write(Result.Success.RegulatorRules.is_initialized(), 1); + if (Result.Success.RegulatorRules.is_initialized()) { - _stream.Write(RegulatorRules.Type == Regulator::LEAKY_BUCKET, 1); - if (RegulatorRules.Type == Regulator::LEAKY_BUCKET) + _stream.Write(Result.Success.RegulatorRules->Type == Regulator::LEAKY_BUCKET, 1); + if (Result.Success.RegulatorRules->Type == Regulator::LEAKY_BUCKET) { - _stream.Write(RegulatorRules.Threshold, 32); - _stream.Write(RegulatorRules.Rate, 32); + _stream.Write(Result.Success.RegulatorRules->LeakyBucket.Threshold, 32); + _stream.Write(Result.Success.RegulatorRules->LeakyBucket.Rate, 32); } } } else { - _stream.Write(!Modules.empty(), 1); - if (!Modules.empty()) + _stream.Write(Result.Failure.Strings.is_initialized(), 1); + if (Result.Failure.Strings.is_initialized()) { - ModuleInfo* info = Modules[0]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); + _stream.WriteBytes(Result.Failure.Strings->Type.c_str(), 4); + _stream.WriteFourCC(Result.Failure.Strings->Region); + _stream.WriteBytes(Result.Failure.Strings->ModuleId, 32); } - _stream.Write(Result.ResultValue, 2); - if (Result.ResultValue == ResponseFailure::FAILURE) + _stream.Write(Result.Failure.Result.Type, 2); + if (Result.Failure.Result.Type == FailureType::FAILURE) { - _stream.Write(Result.Error, 16); - _stream.Write(Result.Wait + std::numeric_limits<int32>::min(), 32); + _stream.Write(Result.Failure.Result.Failure.Error, 16); + _stream.Write(Result.Failure.Result.Failure.Wait + std::numeric_limits<int32>::min(), 32); } } } @@ -308,18 +390,39 @@ void Battlenet::Authentication::ResumeResponse::Write() std::string Battlenet::Authentication::ResumeResponse::ToString() const { std::ostringstream stream; - stream << "Battlenet::Authentication::ResumeResponse AuthResult " << Result.Error << " PingTimeout " << PingTimeout - << " RegulatorRules.Threshold " << RegulatorRules.Threshold << " RegulatorRules.Rate " << RegulatorRules.Rate - << " Modules " << Modules.size(); - - for (ModuleInfo const* module : Modules) - stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); - + stream << "Battlenet::Authentication::ResumeResponse" << std::endl; return stream.str(); } void Battlenet::Authentication::ResumeResponse::SetAuthResult(AuthResult result) { - Result.ResultValue = result != AUTH_OK ? ResponseFailure::FAILURE : ResponseFailure::UPDATE; - Result.Error = result; + Result.Type = result != AUTH_OK ? ResultType::FAILURE : ResultType::SUCCESS; + Result.Failure.Result.Failure.Error = result; +} + +Battlenet::Authentication::ProofRequest::~ProofRequest() +{ + for (size_t i = 0; i < Modules.size(); ++i) + delete Modules[i]; +} + +void Battlenet::Authentication::ProofRequest::Write() +{ + _stream.Write(Modules.size(), 3); + for (ModuleInfo const* info : Modules) + { + _stream.WriteBytes(info->Handle.Type.c_str(), 4); + _stream.WriteFourCC(info->Handle.Region); + _stream.WriteBytes(info->Handle.ModuleId, 32); + _stream.Write(info->DataSize, 10); + _stream.WriteBytes(info->Data, info->DataSize); + } +} + +std::string Battlenet::Authentication::ProofRequest::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::ProofRequest" << std::endl; + APPEND_FIELD(stream, Modules); + return stream.str(); } diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.h b/src/server/bnetserver/Packets/AuthenticationPackets.h index 5f7b653157d..e80567b76e9 100644 --- a/src/server/bnetserver/Packets/AuthenticationPackets.h +++ b/src/server/bnetserver/Packets/AuthenticationPackets.h @@ -43,6 +43,16 @@ namespace Battlenet SMSG_GENERATE_SINGLE_SIGN_ON_TOKEN_REQUEST_2 = 0x8 // Not implemented }; + struct RequestCommon : public PrintableComponent + { + std::string Program; + std::string Platform; + std::string Locale; + std::vector<Version::Record> Versions; + + std::string ToString() const override; + }; + class ResumeRequest final : public ClientPacket { public: @@ -55,11 +65,8 @@ namespace Battlenet std::string ToString() const override; void CallHandler(Session* session) override; - std::string Program; - std::string Platform; - std::string Locale; - std::vector<Component> Components; - std::string Login; + RequestCommon Common; + std::string Account; uint8 GameAccountRegion = 0; std::string GameAccountName; }; @@ -78,7 +85,7 @@ namespace Battlenet std::string ToString() const override; void CallHandler(Session* session) override; - std::vector<BitStream*> Modules; + std::vector<BitStream*> Response; }; class LogonRequest3 final : public ClientPacket @@ -93,53 +100,79 @@ namespace Battlenet std::string ToString() const override; void CallHandler(Session* session) override; - std::string Program; - std::string Platform; - std::string Locale; - std::vector<Component> Components; - std::string Login; + RequestCommon Common; + std::string Account; uint64 Compatibility = 0; }; - class ResponseFailure + struct FailureType : public PrintableComponent { - public: - enum Result + Optional<Cache::Handle> Strings; + + enum { UPDATE = 0, FAILURE = 1, VERSION_CHECK_DISCONNECT = 2 }; - ResponseFailure() : ResultValue(UPDATE), Error(AUTH_OK), Wait(0) { } + struct ResultType : public PrintableComponent + { + int32 Type = FAILURE; + + struct UpdateType : public PrintableComponent + { + std::string ToString() const override; + } Update; - Result ResultValue; - AuthResult Error; - int32 Wait; + struct FailureType : public PrintableComponent + { + AuthResult Error = AUTH_OK; + int32 Wait = 0; + + std::string ToString() const override; + } Failure; + + struct VersionCheckDisconnectType : public PrintableComponent + { + std::string ToString() const override; + } VersionCheckDisconnect; + + std::string ToString() const override; + } Result; + + std::string ToString() const override; }; - class Regulator + struct Regulator : public PrintableComponent { - public: - enum Info + enum { NONE = 0, LEAKY_BUCKET = 1 }; - Regulator() : Type(LEAKY_BUCKET), Threshold(25000000), Rate(1000) { } + int32 Type = LEAKY_BUCKET; + struct NoneType : public PrintableComponent + { + std::string ToString() const override; + } None; + + struct LeakyBucketType : public PrintableComponent + { + uint32 Threshold = 25000000; + uint32 Rate = 1000; - Info Type; - uint32 Threshold; - uint32 Rate; + std::string ToString() const override; + } LeakyBucket; + + std::string ToString() const override; }; class LogonResponse final : public ServerPacket { public: - LogonResponse() : ServerPacket(PacketHeader(SMSG_LOGON_RESPONSE, AUTHENTICATION)), - PingTimeout(120000), AccountId(0), Region(2), Flags(0), - GameAccountRegion(2), GameAccountFlags(0), FailedLogins(0) + LogonResponse() : ServerPacket(PacketHeader(SMSG_LOGON_RESPONSE, AUTHENTICATION)) { } @@ -147,29 +180,46 @@ namespace Battlenet void Write() override; std::string ToString() const override; - - std::vector<ModuleInfo*> Modules; void SetAuthResult(AuthResult result); - ResponseFailure Result; - - int32 PingTimeout; - Regulator RegulatorRules; - std::string FirstName; - std::string LastName; - uint32 AccountId; - uint8 Region; - uint64 Flags; - uint8 GameAccountRegion; - std::string GameAccountName; - uint64 GameAccountFlags; - uint32 FailedLogins; + struct ResultType : public PrintableComponent + { + enum + { + SUCCESS = 0, + FAILURE = 1 + }; + + int32 Type = SUCCESS; + struct SuccessType : public PrintableComponent + { + std::vector<ModuleInfo*> FinalRequest; + int32 PingTimeout = 120000; + Optional<Regulator> RegulatorRules; + Battlenet::Account::FullName FullName; + uint32 AccountId = 0; + uint8 Region = 2; + uint64 Flags = 0; + uint8 GameAccountRegion = 2; + std::string GameAccountName; + uint64 GameAccountFlags = 0; + uint32 LogonFailures = 0; + + std::string ToString() const override; + } Success; + + FailureType Failure; + + std::string ToString() const override; + } Result; + + Optional<std::vector<uint8>> Raf; }; class ResumeResponse final : public ServerPacket { public: - ResumeResponse() : ServerPacket(PacketHeader(SMSG_RESUME_RESPONSE, AUTHENTICATION)), PingTimeout(120000) + ResumeResponse() : ServerPacket(PacketHeader(SMSG_RESUME_RESPONSE, AUTHENTICATION)) { } @@ -178,12 +228,26 @@ namespace Battlenet void Write() override; std::string ToString() const override; - std::vector<ModuleInfo*> Modules; void SetAuthResult(AuthResult result); - ResponseFailure Result; - int32 PingTimeout; - Regulator RegulatorRules; + struct ResultType + { + enum + { + SUCCESS = 0, + FAILURE = 1 + }; + + int32 Type = SUCCESS; + struct SuccessType + { + std::vector<ModuleInfo*> FinalRequest; + int32 PingTimeout = 120000; + Optional<Regulator> RegulatorRules; + } Success; + + FailureType Failure; + } Result; }; class ProofRequest final : public ServerPacket diff --git a/src/server/bnetserver/Packets/CachePackets.cpp b/src/server/bnetserver/Packets/CachePackets.cpp index 98a03077f35..a4fa7e74ff4 100644 --- a/src/server/bnetserver/Packets/CachePackets.cpp +++ b/src/server/bnetserver/Packets/CachePackets.cpp @@ -22,25 +22,53 @@ void Battlenet::Cache::GetStreamItemsRequest::Read() { _stream.ReadSkip(31); - Index = _stream.Read<uint32>(32); + Token = _stream.Read<uint32>(32); ReferenceTime = _stream.Read<int32>(32) - std::numeric_limits<int32>::min(); - _stream.Read<bool>(1); // StreamDirection - _stream.Read<uint8>(6); // Module count, always 0 + Direction = _stream.Read<uint8>(1); + MaxItems = _stream.Read<uint8>(6); Locale = _stream.ReadFourCC(); - if (_stream.Read<bool>(1)) + Stream.Type = _stream.Read<uint8>(1); + if (Stream.Type == StreamId::DESCRIPTION) { - ItemName = _stream.ReadFourCC(); - Channel = _stream.ReadFourCC(); + Stream.Description.ItemName = _stream.ReadFourCC(); + Stream.Description.Channel = _stream.ReadFourCC(); } else - _stream.Read<uint16>(16); + Stream.Index = _stream.Read<uint16>(16); +} + +std::string Battlenet::Cache::GetStreamItemsRequest::StreamId::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Cache::GetStreamItemsRequest::StreamId" << std::endl; + + if (Type == INDEX) + APPEND_FIELD(stream, Index); + else + APPEND_FIELD(stream, Description); + + return stream.str(); +} + +std::string Battlenet::Cache::GetStreamItemsRequest::StreamId::DescriptionType::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Cache::GetStreamItemsRequest::StreamId::Description" << std::endl; + APPEND_FIELD(stream, Channel); + APPEND_FIELD(stream, ItemName); + return stream.str(); } std::string Battlenet::Cache::GetStreamItemsRequest::ToString() const { std::ostringstream stream; - stream << "Battlenet::Cache::GetStreamItemsRequest Channel: " << Channel << ", ItemName: " << ItemName - << ", Locale: " << Locale << ", Index: " << Index; + stream << "Battlenet::Cache::GetStreamItemsRequest" << std::endl; + APPEND_FIELD(stream, Token); + APPEND_FIELD(stream, MaxItems); + APPEND_FIELD(stream, ReferenceTime); + APPEND_FIELD(stream, Direction); + APPEND_FIELD(stream, Stream); + APPEND_FIELD(stream, Locale); return stream.str(); } @@ -51,21 +79,21 @@ void Battlenet::Cache::GetStreamItemsRequest::CallHandler(Session* session) Battlenet::Cache::GetStreamItemsResponse::~GetStreamItemsResponse() { - for (size_t i = 0; i < Modules.size(); ++i) - delete Modules[i]; + for (size_t i = 0; i < Items.size(); ++i) + delete Items[i]; } void Battlenet::Cache::GetStreamItemsResponse::Write() { - _stream.Write(0, 16); - _stream.Write(1, 16); - _stream.Write(Index, 32); - _stream.Write(Modules.size(), 6); - for (ModuleInfo const* info : Modules) + _stream.Write(Offset, 16); + _stream.Write(TotalNumItems, 16); + _stream.Write(Token, 32); + _stream.Write(Items.size(), 6); + for (ModuleInfo const* info : Items) { - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); + _stream.WriteBytes(info->Handle.Type.c_str(), 4); + _stream.WriteFourCC(info->Handle.Region); + _stream.WriteBytes(info->Handle.ModuleId, 32); _stream.WriteSkip(27); _stream.WriteBytes(info->Data, 4); } @@ -74,9 +102,10 @@ void Battlenet::Cache::GetStreamItemsResponse::Write() std::string Battlenet::Cache::GetStreamItemsResponse::ToString() const { std::ostringstream stream; - stream << "Battlenet::Cache::GetStreamItemsResponse modules " << Modules.size(); - for (ModuleInfo const* module : Modules) - stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); - + stream << "Battlenet::Cache::GetStreamItemsResponse" << std::endl; + APPEND_FIELD(stream, Items); + APPEND_FIELD(stream, Offset); + APPEND_FIELD(stream, TotalNumItems); + APPEND_FIELD(stream, Token); return stream.str(); } diff --git a/src/server/bnetserver/Packets/CachePackets.h b/src/server/bnetserver/Packets/CachePackets.h index 67488101320..aaa9594610f 100644 --- a/src/server/bnetserver/Packets/CachePackets.h +++ b/src/server/bnetserver/Packets/CachePackets.h @@ -51,11 +51,40 @@ namespace Battlenet std::string ToString() const override; void CallHandler(Session* session) override; - std::string Channel; - std::string ItemName; - std::string Locale; - uint32 Index = 0; + enum + { + BEFORE = 0, + AFTER = 1 + }; + + uint32 Token = 0; + uint8 MaxItems = 0; int32 ReferenceTime = 0; + uint8 Direction = BEFORE; + + struct StreamId : public PrintableComponent + { + enum + { + INDEX = 0, + DESCRIPTION = 1 + }; + + int32 Type; + + uint16 Index; + struct DescriptionType : public PrintableComponent + { + std::string Channel; + std::string ItemName; + + std::string ToString() const override; + } Description; + + std::string ToString() const override; + } Stream; + + std::string Locale; }; class GetStreamItemsResponse final : public ServerPacket @@ -70,8 +99,10 @@ namespace Battlenet void Write() override; std::string ToString() const override; - uint32 Index = 0; - std::vector<ModuleInfo*> Modules; + std::vector<ModuleInfo*> Items; + uint16 Offset = 0; + uint16 TotalNumItems = 1; + uint32 Token = 0; }; } } diff --git a/src/server/bnetserver/Packets/ChatPackets.h b/src/server/bnetserver/Packets/ChatPackets.h index 23d8ea84d21..333a07245ed 100644 --- a/src/server/bnetserver/Packets/ChatPackets.h +++ b/src/server/bnetserver/Packets/ChatPackets.h @@ -38,6 +38,9 @@ namespace Battlenet CMSG_ENUM_CONFERENCE_DESCRIPTIONS = 0x17, // Not implemented CMSG_ENUM_CONFERENCE_MEMBER_COUNTS = 0x19, // Not implemented CMSG_MODIFY_CHANNEL_LIST_REQUEST = 0x1B, // Not implemented + CMSG_GET_MEMBER_COUNT_REQUEST = 0x1F, // Not implemented + CMSG_MODIFY_CHANNEL_LIST_REQUEST_2 = 0x20, // Not implemented + CMSG_GAME_DATA_SEND_REQUEST = 0x22, // Not implemented SMSG_MEMBERSHIP_CHANGE_NOTIFY = 0x01, // Not implemented SMSG_INVITE_NOTIFY = 0x04, // Not implemented diff --git a/src/server/bnetserver/Packets/ConnectionPackets.cpp b/src/server/bnetserver/Packets/ConnectionPackets.cpp index 2c23dd2fe9f..51e3954a69d 100644 --- a/src/server/bnetserver/Packets/ConnectionPackets.cpp +++ b/src/server/bnetserver/Packets/ConnectionPackets.cpp @@ -50,14 +50,16 @@ void Battlenet::Connection::LogoutRequest::CallHandler(Session* session) void Battlenet::Connection::DisconnectRequest::Read() { - Timeout = _stream.Read<uint16>(16); - Tick = _stream.Read<uint32>(32); + Error = _stream.Read<uint16>(16); + Timeout = _stream.Read<uint32>(32); } std::string Battlenet::Connection::DisconnectRequest::ToString() const { std::ostringstream str; - str << "Battlenet::Connection::DisconnectRequest Timeout: " << Timeout << ", Tick: " << Tick; + str << "Battlenet::Connection::DisconnectRequest" << std::endl; + APPEND_FIELD(str, Error); + APPEND_FIELD(str, Timeout); return str.str(); } @@ -67,11 +69,11 @@ void Battlenet::Connection::ConnectionClosing::Read() for (size_t i = 0; i < Packets.size(); ++i) { PacketInfo& info = Packets[i]; - info.CommandName = _stream.ReadFourCC(); - info.Timestamp = _stream.Read<uint32>(32); + info.Command = _stream.ReadFourCC(); + info.Time = _stream.Read<uint32>(32); info.Size = _stream.Read<uint32>(16); - info.Channel = _stream.ReadFourCC(); - info.LayerId = _stream.Read<uint32>(16); + info.Layer = _stream.ReadFourCC(); + info.Offset = _stream.Read<uint32>(16); } Reason = _stream.Read<ClosingReason>(4); @@ -79,7 +81,7 @@ void Battlenet::Connection::ConnectionClosing::Read() if (_stream.Read<bool>(1)) // HasHeader { - Header.Opcode = _stream.Read<uint32>(6); + Header.Command = _stream.Read<uint32>(6); if (_stream.Read<bool>(1)) Header.Channel = _stream.Read<int32>(4); } @@ -87,14 +89,26 @@ void Battlenet::Connection::ConnectionClosing::Read() Now = _stream.Read<time_t>(32); } -std::string Battlenet::Connection::ConnectionClosing::ToString() const +std::string Battlenet::Connection::ConnectionClosing::PacketInfo::ToString() const { std::ostringstream stream; - stream << "Battlenet::Connection::ConnectionClosing Reason: " << Reason << ", Now: " << Now << ", Packet history size: " << Packets.size(); - for (PacketInfo const& packet : Packets) - stream << std::endl << "Battlenet::Connection::ConnectionClosing::PacketInfo LayerId: " << packet.LayerId - << ", Channel: " << packet.Channel << ", CommandName: " << packet.CommandName << ", Size: " << packet.Size << ", Timestamp: " << packet.Timestamp; + stream << "Battlenet::Connection::ConnectionClosing::PacketInfo" << std::endl; + APPEND_FIELD(stream, Layer); + APPEND_FIELD(stream, Command); + APPEND_FIELD(stream, Offset); + APPEND_FIELD(stream, Size); + APPEND_FIELD(stream, Time); + return stream.str(); +} +std::string Battlenet::Connection::ConnectionClosing::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Connection::ConnectionClosing" << std::endl; + APPEND_FIELD(stream, Header); + APPEND_FIELD(stream, Reason); + APPEND_FIELD(stream, Packets); + APPEND_FIELD(stream, Now); return stream.str(); } diff --git a/src/server/bnetserver/Packets/ConnectionPackets.h b/src/server/bnetserver/Packets/ConnectionPackets.h index 6cd11e5fcaa..fc441c2f2e1 100644 --- a/src/server/bnetserver/Packets/ConnectionPackets.h +++ b/src/server/bnetserver/Packets/ConnectionPackets.h @@ -91,8 +91,8 @@ namespace Battlenet void Read() override; std::string ToString() const override; - uint16 Timeout = 0; - uint32 Tick = 0; + uint16 Error = 0; + uint32 Timeout = 0; }; class ConnectionClosing final : public ClientPacket @@ -115,13 +115,15 @@ namespace Battlenet TIMEOUT = 13, }; - struct PacketInfo + struct PacketInfo : public PrintableComponent { - uint16 LayerId; - std::string Channel; - uint32 Timestamp; - std::string CommandName; + std::string Layer; + std::string Command; + uint16 Offset; uint16 Size; + uint32 Time; + + std::string ToString() const override; }; ConnectionClosing(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp index a9d85877f93..0f39241ebbf 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.cpp +++ b/src/server/bnetserver/Packets/FriendsPackets.cpp @@ -18,82 +18,6 @@ #include "Session.h" #include "FriendsPackets.h" -void Battlenet::Friends::GetFriendsOfFriend::Read() -{ - _stream.Read<uint8>(2); - _stream.Read<uint32>(32); -} - -std::string Battlenet::Friends::GetFriendsOfFriend::ToString() const -{ - return "Battlenet::Friends::GetFriendsOfFriend"; -} - -void Battlenet::Friends::SocialNetworkCheckConnected::Read() -{ - SocialNetworkId = _stream.Read<uint32>(32); -} - -std::string Battlenet::Friends::SocialNetworkCheckConnected::ToString() const -{ - return "Battlenet::Friends::SocialNetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId); -} - -void Battlenet::Friends::SocialNetworkCheckConnected::CallHandler(Session* session) -{ - session->HandleSocialNetworkCheckConnected(*this); -} - -void Battlenet::Friends::RealIdFriendInvite::Read() -{ - _stream.Read<uint32>(32); - uint8 type = _stream.Read<uint8>(3); - - switch (type) - { - case 0: - { - _stream.Read<uint32>(32); // Presence Id? - break; - } - case 1: // GameAccount? - { - _stream.Read<uint8>(8); - _stream.Read<uint32>(32); - _stream.Read<uint32>(32); - uint8 size = _stream.Read<uint8>(7); // Only if *(a1 + 16) <= 0x64 - _stream.ReadBytes(size); - break; - } - case 2: - Email = _stream.ReadString(9, 3); - break; - case 3: - { - _stream.Read<uint32>(32); - break; - } - case 4: - { - _stream.Read<uint64>(64); - _stream.Read<uint32>(32); - break; - } - } - - _stream.Read<uint8>(1); - - if (_stream.Read<uint8>(1)) - Message = _stream.ReadString(9); - - _stream.Read<uint32>(32); -} - -std::string Battlenet::Friends::RealIdFriendInvite::ToString() const -{ - return "Battlenet::Friends::RealIdFriendInvite Mail: " + Email + " Message: " + Message; -} - std::string Battlenet::Friends::FriendInviteResult::ToString() const { return "Battlenet::Friends::RealIdFriendInviteResult"; @@ -125,14 +49,55 @@ void Battlenet::Friends::FriendInviteResult::Write() } } -std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() const +void Battlenet::Friends::SendInvitationRequest::Read() +{ + Token = _stream.Read<uint32>(32); + + if (_stream.Read<bool>(1)) + PresenceId = _stream.Read<uint32>(32); + + if (_stream.Read<bool>(1)) + AccountMail = _stream.ReadString(9, 3); + + if (_stream.Read<bool>(1)) + AccountId = _stream.Read<uint32>(32); + + if (_stream.Read<bool>(1)) + { + GameAccount = boost::in_place(); + GameAccount->Region = _stream.Read<uint8>(8); + GameAccount->ProgramId = _stream.ReadFourCC(); + GameAccount->Id = _stream.Read<uint32>(32); + } + + _stream.ReadSkip(7); + + if (_stream.Read<bool>(1)) + Nickname = _stream.ReadString(7); + + Source = _stream.ReadFourCC(); + Role = _stream.Read<uint32>(32); + + if (_stream.Read<bool>(1)) + InvitationMsg = _stream.ReadString(9); +} + +std::string Battlenet::Friends::SendInvitationRequest::ToString() const { - return "Battlenet::Friends::SocialNetworkCheckConnectedResult"; + std::ostringstream stream; + stream << "Battlenet::Friends::SendInvitationRequest" << std::endl; + APPEND_FIELD(stream, Token); + APPEND_FIELD(stream, PresenceId); + APPEND_FIELD(stream, GameAccount); + APPEND_FIELD(stream, AccountId); + APPEND_FIELD(stream, AccountMail); + APPEND_FIELD(stream, Nickname); + APPEND_FIELD(stream, InvitationMsg); + APPEND_FIELD(stream, Source); + APPEND_FIELD(stream, Role); + return stream.str(); } -void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write() +void Battlenet::Friends::SendInvitationRequest::CallHandler(Session* /*session*/) { - _stream.WriteSkip(23); - _stream.Write(Result, 16); - _stream.Write(SocialNetworkId, 32); } diff --git a/src/server/bnetserver/Packets/FriendsPackets.h b/src/server/bnetserver/Packets/FriendsPackets.h index 909dc7d52b3..463863d3063 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.h +++ b/src/server/bnetserver/Packets/FriendsPackets.h @@ -34,11 +34,12 @@ namespace Battlenet CMSG_BLOCK_ADD = 0x08, // Not implemented CMSG_BLOCK_REMOVE = 0x0A, // Not implemented CMSG_GET_FRIENDS_OF_FRIEND = 0x0B, // Not implemented - CMSG_GET_SOCIAL_NETWORK_FRIENDS = 0x0D, // Won't support - CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Won't support - CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Won't support - CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13, - CMSG_REALID_FRIEND_INVITE = 0x16, // Not implemented + CMSG_GET_SOCIAL_NETWORK_FRIENDS = 0x0D, // Deprecated in client + CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Deprecated in client + CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Deprecated in client + CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13, // Deprecated in client + CMSG_REALID_FRIEND_INVITE = 0x16, // Deprecated in client + CMSG_SEND_INVITATION_REQUEST = 0x1A, // Not implemented SMSG_FRIEND_INVITE_NOTIFY = 0x01, // Not implemented SMSG_FRIEND_INVITE_RESULT = 0x03, // Not implemented @@ -46,54 +47,34 @@ namespace Battlenet SMSG_BLOCK_INVITE_NOTIFY = 0x07, // Not implemented SMSG_BLOCK_ADD_FAILURE = 0x09, // Not implemented SMSG_FRIENDS_OF_FRIEND = 0x0C, // Not implemented - SMSG_SOCIAL_NETWORK_FRIENDS = 0x0E, // Won't support - SMSG_SOCIAL_NETWORK_CONNECT_RESULT = 0x10, // Won't support - SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT = 0x12, // Won't support - SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT = 0x14, + SMSG_SOCIAL_NETWORK_FRIENDS = 0x0E, // Deprecated in client + SMSG_SOCIAL_NETWORK_CONNECT_RESULT = 0x10, // Deprecated in client + SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT = 0x12, // Deprecated in client + SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT = 0x14, // Deprecated in client SMSG_MAX_FRIENDS_NOTIFY = 0x15, // Not implemented SMSG_FRIENDS_LIST_NOTIFY_3 = 0x18 // Not implemented }; - class GetFriendsOfFriend final : public ClientPacket + class SendInvitationRequest final : public ClientPacket { public: - GetFriendsOfFriend(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS) && "Invalid packet header for GetFriendsOfFriend"); - } - - void Read() override; - std::string ToString() const override; - }; - - class SocialNetworkCheckConnected final : public ClientPacket - { - public: - SocialNetworkCheckConnected(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS) && "Invalid packet header for SocialNetworkCheckConnected"); - } + SendInvitationRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) { } void Read() override; std::string ToString() const override; void CallHandler(Session* session) override; - uint32 SocialNetworkId = 0; - }; + uint32 Token = 0; - class RealIdFriendInvite final : public ClientPacket - { - public: - RealIdFriendInvite(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_REALID_FRIEND_INVITE, FRIENDS) && "Invalid packet header for RealIdFriendInvite"); - } - - void Read() override; - std::string ToString() const override; + Optional<uint32> PresenceId; + Optional<GameAccount::Handle> GameAccount; + Optional<uint32> AccountId; + Optional<std::string> AccountMail; + Optional<std::string> Nickname; - std::string Email; - std::string Message; + Optional<std::string> InvitationMsg; + std::string Source; + uint32 Role; }; class FriendInviteResult final : public ServerPacket @@ -106,32 +87,6 @@ namespace Battlenet void Write() override; std::string ToString() const override; }; - - class FriendsOfFriend final : public ServerPacket - { - public: - FriendsOfFriend() : ServerPacket(PacketHeader(SMSG_FRIENDS_OF_FRIEND, FRIENDS)) - { - } - - void Write() override; - std::string ToString() const override; - }; - - class SocialNetworkCheckConnectedResult final : public ServerPacket - { - public: - SocialNetworkCheckConnectedResult() : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS)), - Result(4601), SocialNetworkId(0) // 4601 = The Facebook add friend service is unavailable right now. Please try again later. - { - } - - void Write() override; - std::string ToString() const override; - - uint16 Result; - uint32 SocialNetworkId; - }; } } diff --git a/src/server/bnetserver/Packets/PacketManager.cpp b/src/server/bnetserver/Packets/PacketManager.cpp index 46ffc42d9f4..48216a39ab8 100644 --- a/src/server/bnetserver/Packets/PacketManager.cpp +++ b/src/server/bnetserver/Packets/PacketManager.cpp @@ -134,9 +134,10 @@ void Battlenet::PacketManager::RegisterFriendsPackets() REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_GET_SOCIAL_NETWORK_FRIENDS, FRIENDS), "Friends::GetSocialNetworkFriends"); REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS), "Friends::SocialNetworkConnect"); REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_DISCONNECT, FRIENDS), "Friends::SocialNetworkDisconnect"); - REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS), Friends::SocialNetworkCheckConnected); - REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS), Friends::GetFriendsOfFriend); - REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_REALID_FRIEND_INVITE, FRIENDS), Friends::RealIdFriendInvite); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS), "Friends::SocialNetworkCheckConnected"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS), "Friends::GetFriendsOfFriend"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_REALID_FRIEND_INVITE, FRIENDS), "Friends::RealIdFriendInvite"); + REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_SEND_INVITATION_REQUEST, FRIENDS), Friends::SendInvitationRequest); REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIEND_INVITE_NOTIFY, FRIENDS), "Friends::FriendInviteNotify"); REGISTER_SERVER_PACKET(PacketHeader(Friends::SMSG_FRIEND_INVITE_RESULT, FRIENDS), Friends::FriendInviteResult); @@ -147,15 +148,15 @@ void Battlenet::PacketManager::RegisterFriendsPackets() REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_FRIENDS, FRIENDS), "Friends::SocialNetworkFriends"); REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_CONNECT_RESULT, FRIENDS), "Friends::SocialNetworkConnectResult"); REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT, FRIENDS), "Friends::SocialNetworkDisconnectResult"); - REGISTER_SERVER_PACKET(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS), Friends::SocialNetworkCheckConnectedResult); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS), "Friends::SocialNetworkCheckConnectedResult"); REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_MAX_FRIENDS_NOTIFY, FRIENDS), "Friends::MaxFriendsNotify"); REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_LIST_NOTIFY_3, FRIENDS), "Friends::FriendsListNotify3"); } void Battlenet::PacketManager::RegisterPresencePackets() { - REGISTER_CLIENT_PACKET(PacketHeader(Presence::CMSG_UPDATE_REQUEST, PRESENCE), Presence::UpdateRequest); - REGISTER_CLIENT_PACKET(PacketHeader(Presence::CMSG_STATISTIC_SUBSCRIBE, PRESENCE), Presence::StatisticSubscribe); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::CMSG_UPDATE_REQUEST, PRESENCE), "Presence::UpdateRequest"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::CMSG_STATISTIC_SUBSCRIBE, PRESENCE), "Presence::StatisticSubscribe"); REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_UPDATE_NOTIFY, PRESENCE), "Presence::UpdateNotify"); REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_FIELD_SPEC_ANNOUNCE, PRESENCE), "Presence::FieldSpecAnnounce"); diff --git a/src/server/bnetserver/Packets/PacketsBase.cpp b/src/server/bnetserver/Packets/PacketsBase.cpp index da76865ff8d..87e24c96e3e 100644 --- a/src/server/bnetserver/Packets/PacketsBase.cpp +++ b/src/server/bnetserver/Packets/PacketsBase.cpp @@ -22,13 +22,15 @@ std::string Battlenet::PacketHeader::ToString() const { std::ostringstream stream; - stream << "Battlenet::PacketHeader opcode: " << Opcode << ", channel: " << Channel; + stream << "Battlenet::PacketHeader" << std::endl; + APPEND_FIELD(stream, Command); + APPEND_FIELD(stream, Channel); return stream.str(); } Battlenet::ServerPacket::ServerPacket(PacketHeader const& header) : Packet(header, *new BitStream()) { - _stream.Write(header.Opcode, 6); + _stream.Write(header.Command, 6); _stream.Write(1, 1); _stream.Write(header.Channel, 4); } diff --git a/src/server/bnetserver/Packets/PacketsBase.h b/src/server/bnetserver/Packets/PacketsBase.h index d66205a33b8..e542c409e63 100644 --- a/src/server/bnetserver/Packets/PacketsBase.h +++ b/src/server/bnetserver/Packets/PacketsBase.h @@ -20,8 +20,9 @@ #include "AuthCodes.h" #include "BitStream.h" -#include "Define.h" +#include "Common.h" #include "Errors.h" +#include "PacketsCommon.h" #include <string> #include <boost/asio/ip/tcp.hpp> @@ -46,19 +47,19 @@ namespace Battlenet PROFILE = 14 }; - struct PacketHeader + struct PacketHeader : public PrintableComponent { - PacketHeader(uint32 opcode, uint32 channel) : Opcode(opcode), Channel(channel) { } - PacketHeader() : Opcode(0), Channel(AUTHENTICATION) { } + PacketHeader(uint32 opcode, uint32 channel) : Command(opcode), Channel(channel) { } + PacketHeader() : Command(0), Channel(AUTHENTICATION) { } - uint32 Opcode; + uint32 Command; int32 Channel; bool operator<(PacketHeader const& right) const { - if (Opcode < right.Opcode) + if (Command < right.Command) return true; - if (Opcode > right.Opcode) + if (Command > right.Command) return false; return Channel < right.Channel; @@ -66,10 +67,10 @@ namespace Battlenet bool operator==(PacketHeader const& right) const { - return Opcode == right.Opcode && Channel == right.Channel; + return Command == right.Command && Channel == right.Channel; } - std::string ToString() const; + std::string ToString() const override; }; class Packet @@ -90,8 +91,8 @@ namespace Battlenet BitStream& _stream; private: - Packet(Packet const& right); - Packet& operator=(Packet const& right); + Packet(Packet const& right) = delete; + Packet& operator=(Packet const& right) = delete; }; class ClientPacket : public Packet diff --git a/src/server/bnetserver/Packets/PacketsCommon.cpp b/src/server/bnetserver/Packets/PacketsCommon.cpp new file mode 100644 index 00000000000..f0febcc8d90 --- /dev/null +++ b/src/server/bnetserver/Packets/PacketsCommon.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "PacketsCommon.h" +#include "Util.h" + +std::string Battlenet::Version::Record::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Version::Record" << std::endl; + APPEND_FIELD(stream, ProgramId); + APPEND_FIELD(stream, Component); + APPEND_FIELD(stream, Version); + return stream.str(); +} + +std::string Battlenet::Cache::Handle::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Cache::Handle" << std::endl; + APPEND_FIELD(stream, Type); + APPEND_FIELD(stream, Region); + stream << "ModuleId: " << ByteArrayToHexStr(ModuleId, 32) << std::endl; + return stream.str(); +} + +std::string Battlenet::Account::FullName::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Account::FullName" << std::endl; + APPEND_FIELD(stream, GivenName); + APPEND_FIELD(stream, Surname); + return stream.str(); +} + +std::string Battlenet::GameAccount::Handle::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::GameAccount::Handle" << std::endl; + APPEND_FIELD(stream, Region); + APPEND_FIELD(stream, ProgramId); + APPEND_FIELD(stream, Id); + return stream.str(); +} + +std::string Battlenet::PrintableRealmHandle::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::RealmHandle" << std::endl; + APPEND_FIELD(stream, Region); + APPEND_FIELD(stream, Site); + APPEND_FIELD(stream, Realm); + return stream.str(); +} + +std::string Battlenet::Toon::FullName::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Toon::FullName" << std::endl; + APPEND_FIELD(stream, Region); + APPEND_FIELD(stream, ProgramId); + APPEND_FIELD(stream, Realm); + APPEND_FIELD(stream, Name); + return stream.str(); +} + +std::string Battlenet::Toon::Handle::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Toon::Handle" << std::endl; + APPEND_FIELD(stream, Region); + APPEND_FIELD(stream, ProgramId); + APPEND_FIELD(stream, Realm); + APPEND_FIELD(stream, Id); + return stream.str(); +} + +std::string Battlenet::Profile::RecordAddress::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Profile::RecordAddress" << std::endl; + APPEND_FIELD(stream, Label); + APPEND_FIELD(stream, Id); + return stream.str(); +} + +std::ostream& Battlenet::Format::FieldToString(std::ostream& stream, char const* fieldName, PrintableComponent const& u, std::true_type) +{ + if (fieldName[0]) + stream << fieldName << ": "; + return stream << u.ToString(); +} + +std::ostream& Battlenet::Format::FieldToString(std::ostream& stream, char const* fieldName, uint8 const& u, std::false_type) +{ + return FieldToString(stream, fieldName, uint32(u), std::false_type()); +} diff --git a/src/server/bnetserver/Packets/PacketsCommon.h b/src/server/bnetserver/Packets/PacketsCommon.h new file mode 100644 index 00000000000..a8eddd87463 --- /dev/null +++ b/src/server/bnetserver/Packets/PacketsCommon.h @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef PacketsCommon_h__ +#define PacketsCommon_h__ + +#include "Common.h" +#include "Realm/Realm.h" +#include <typeinfo> + +namespace Battlenet +{ + struct PrintableComponent + { + virtual std::string ToString() const = 0; + }; + + namespace Format + { + template<typename T> + struct is_printable : std::is_base_of<PrintableComponent, typename std::remove_pointer<T>::type>::type + { + }; + + template<typename T> + typename std::enable_if<!std::is_pointer<T>::value, T>::type const& Dereference(T const& t) { return t; }; + + template<typename T> + typename std::enable_if<std::is_pointer<T>::value, typename std::remove_pointer<T>::type>::type const& Dereference(T const& t) { return *t; }; + + template<typename T> + std::ostream& FieldToString(std::ostream& stream, char const* fieldName, T const& u, std::false_type) + { + if (fieldName[0]) + stream << fieldName << ": "; + return stream << u << std::endl; + } + + std::ostream& FieldToString(std::ostream& stream, char const* fieldName, PrintableComponent const& u, std::true_type); + std::ostream& FieldToString(std::ostream& stream, char const* fieldName, uint8 const& u, std::false_type); + + template<typename T> + std::ostream& FieldToString(std::ostream& stream, char const* fieldName, std::vector<T> const& u, std::false_type) + { + stream << fieldName << ":" << std::endl; + for (T const& t : u) + FieldToString(stream, "", Dereference(t), is_printable<T>()); + return stream; + } + + template<typename T> + std::ostream& FieldToString(std::ostream& stream, char const* fieldName, Optional<T> const& u) + { + if (u) + FieldToString(stream, fieldName, Dereference(*u), is_printable<T>()); + return stream; + } + + template<typename T> + std::ostream& FieldToString(std::ostream& stream, char const* fieldName, T const& u) + { + return FieldToString(stream, fieldName, Dereference(u), is_printable<T>()); + } + } + +#define APPEND_FIELD(stream, field) Format::FieldToString(stream, #field, field) + + namespace Version + { + struct Record : public PrintableComponent + { + std::string ProgramId; + std::string Component; + uint32 Version; + + std::string ToString() const override; + }; + } + + namespace Cache + { + struct Handle : public PrintableComponent + { + std::string Type; + std::string Region; + uint8 ModuleId[32] = { }; + + std::string ToString() const override; + }; + } + + namespace Account + { + struct FullName : public PrintableComponent + { + std::string GivenName; + std::string Surname; + + std::string ToString() const override; + }; + } + + namespace GameAccount + { + struct Handle : public PrintableComponent + { + uint8 Region = 0; + std::string ProgramId; + uint32 Id = 0; + + std::string ToString() const override; + }; + } + + // For use in packets + struct PrintableRealmHandle : public RealmHandle, public PrintableComponent + { + PrintableRealmHandle() : RealmHandle() { } + PrintableRealmHandle(uint8 region, uint8 battlegroup, uint32 index) + : RealmHandle(region, battlegroup, index) { } + + PrintableRealmHandle& operator=(RealmHandle const& r) + { + RealmHandle::operator=(r); + return *this; + } + + std::string ToString() const override; + }; + + namespace Toon + { + struct FullName : public PrintableComponent + { + uint8 Region = 0; + std::string ProgramId; + uint32 Realm = 0; + std::string Name; + + std::string ToString() const override; + }; + + struct Handle : public PrintableComponent + { + uint8 Region = 0; + std::string ProgramId; + uint32 Realm = 0; + uint64 Id = 0; + + std::string ToString() const override; + }; + } + + namespace Profile + { + struct RecordAddress : public PrintableComponent + { + uint32 Label = 0; + uint64 Id = 0; + + std::string ToString() const override; + }; + } +} + +#endif // PacketsCommon_h__ diff --git a/src/server/bnetserver/Packets/PresencePackets.cpp b/src/server/bnetserver/Packets/PresencePackets.cpp deleted file mode 100644 index ac6af093fc8..00000000000 --- a/src/server/bnetserver/Packets/PresencePackets.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "Session.h" -#include "PresencePackets.h" - -void Battlenet::Presence::UpdateRequest::Read() -{ - -} - -std::string Battlenet::Presence::UpdateRequest::ToString() const -{ - return "Battlenet::Presence::UpdateRequest"; -} - -void Battlenet::Presence::StatisticSubscribe::Read() -{ -} - -std::string Battlenet::Presence::StatisticSubscribe::ToString() const -{ - return "Battlenet::Presence::StatisticSubscribe"; -} diff --git a/src/server/bnetserver/Packets/PresencePackets.h b/src/server/bnetserver/Packets/PresencePackets.h index 9c4464ccab3..4494e3d1f17 100644 --- a/src/server/bnetserver/Packets/PresencePackets.h +++ b/src/server/bnetserver/Packets/PresencePackets.h @@ -33,30 +33,6 @@ namespace Battlenet SMSG_FIELD_SPEC_ANNOUNCE = 0x1, // Not implemented SMSG_STATISTICS_UPDATE = 0x3 // Not implemented }; - - class UpdateRequest final : public ClientPacket - { - public: - UpdateRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_UPDATE_REQUEST, PRESENCE) && "Invalid packet header for UpdateRequest"); - } - - void Read() override; - std::string ToString() const override; - }; - - class StatisticSubscribe final : public ClientPacket - { - public: - StatisticSubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_STATISTIC_SUBSCRIBE, PRESENCE) && "Invalid packet header for StatisticSubscribe"); - } - - void Read() override; - std::string ToString() const override; - }; } } diff --git a/src/server/bnetserver/Packets/SupportPackets.h b/src/server/bnetserver/Packets/SupportPackets.h index 3475fd687d2..03bd53e4bf6 100644 --- a/src/server/bnetserver/Packets/SupportPackets.h +++ b/src/server/bnetserver/Packets/SupportPackets.h @@ -26,7 +26,8 @@ namespace Battlenet { enum Opcode { - CMSG_COMPLAINT_REQUEST = 0x0 // Not implemented + CMSG_COMPLAINT_REQUEST = 0x0, // Deprecated in client + CMSG_COMPLAINT_REQUEST2 = 0x1 // Not implemented }; } } diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.cpp b/src/server/bnetserver/Packets/WoWRealmPackets.cpp index 0a86d671afc..4a86d97d817 100644 --- a/src/server/bnetserver/Packets/WoWRealmPackets.cpp +++ b/src/server/bnetserver/Packets/WoWRealmPackets.cpp @@ -20,21 +20,11 @@ #include <boost/lexical_cast.hpp> #include <boost/asio/ip/address.hpp> -std::string Battlenet::WoWRealm::ListSubscribeRequest::ToString() const -{ - return "Battlenet::WoWRealm::ListSubscribeRequest"; -} - void Battlenet::WoWRealm::ListSubscribeRequest::CallHandler(Session* session) { session->HandleListSubscribeRequest(*this); } -std::string Battlenet::WoWRealm::ListUnsubscribe::ToString() const -{ - return "Battlenet::WoWRealm::ListUnsubscribe"; -} - void Battlenet::WoWRealm::ListUnsubscribe::CallHandler(Session* session) { session->HandleListUnsubscribe(*this); @@ -42,19 +32,21 @@ void Battlenet::WoWRealm::ListUnsubscribe::CallHandler(Session* session) void Battlenet::WoWRealm::JoinRequestV2::Read() { - ClientSeed = _stream.Read<uint32>(32); - _stream.Read<uint32>(20); - Realm.Region = _stream.Read<uint8>(8); - _stream.Read<uint16>(12); - Realm.Battlegroup = _stream.Read<uint8>(8); - Realm.Index = _stream.Read<uint32>(32); + ClientSalt = _stream.Read<uint32>(32); + _stream.ReadSkip(20); + Id.Region = _stream.Read<uint8>(8); + _stream.ReadSkip(12); + Id.Site = _stream.Read<uint8>(8); + Id.Realm = _stream.Read<uint32>(32); } std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const { std::ostringstream stream; - stream << "Battlenet::WoWRealm::JoinRequestV2 ClientSeed " << ClientSeed << " Region " << uint32(Realm.Region) << " Battlegroup " << uint32(Realm.Battlegroup) << " Index " << Realm.Index; - return stream.str().c_str(); + stream << "Battlenet::WoWRealm::JoinRequestV2" << std::endl; + APPEND_FIELD(stream, Id); + APPEND_FIELD(stream, ClientSalt); + return stream.str(); } void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session) @@ -62,77 +54,66 @@ void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session) session->HandleJoinRequestV2(*this); } -Battlenet::WoWRealm::ListSubscribeResponse::~ListSubscribeResponse() -{ - for (ServerPacket* realmData : RealmData) - delete realmData; -} - void Battlenet::WoWRealm::ListSubscribeResponse::Write() { - _stream.Write(Response, 1); - if (Response == SUCCESS) + _stream.Write(Type, 1); + if (Type == SUCCESS) { - _stream.Write(CharacterCounts.size(), 7); - for (CharacterCountEntry const& entry : CharacterCounts) + _stream.Write(ToonCounts.size(), 7); + for (ToonCountEntry const& entry : ToonCounts) { _stream.Write(entry.Realm.Region, 8); - _stream.Write(0, 12); - _stream.Write(entry.Realm.Battlegroup, 8); - _stream.Write(entry.Realm.Index, 32); - _stream.Write(entry.CharacterCount, 16); - } - - for (ServerPacket* realmData : RealmData) - { - realmData->Write(); - _stream.WriteBytes(realmData->GetData(), realmData->GetSize()); + _stream.WriteSkip(12); + _stream.Write(entry.Realm.Site, 8); + _stream.Write(entry.Realm.Realm, 32); + _stream.Write(entry.Count, 16); } } else - _stream.Write(ResponseCode, 8); + _stream.Write(Failure, 8); } -std::string Battlenet::WoWRealm::ListSubscribeResponse::ToString() const +std::string Battlenet::WoWRealm::ListSubscribeResponse::ToonCountEntry::ToString() const { std::ostringstream stream; - stream << "Battlenet::WoWRealm::ListSubscribeResponse"; - - if (Response == SUCCESS) - { - stream << " Realms " << CharacterCounts.size(); + stream << "Battlenet::WoWRealm::ListSubscribeResponse::ToonCountEntry" << std::endl; + APPEND_FIELD(stream, Realm); + APPEND_FIELD(stream, Count); + return stream.str(); +} - for (CharacterCountEntry const& entry : CharacterCounts) - stream << std::endl << "Region " << uint32(entry.Realm.Region) << " Battlegroup " << uint32(entry.Realm.Region) << " Index " << entry.Realm.Index << " Characters " << entry.CharacterCount; +std::string Battlenet::WoWRealm::ListSubscribeResponse::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::WoWRealm::ListSubscribeResponse" << std::endl; - for (ServerPacket* realmData : RealmData) - stream << std::endl << realmData->ToString(); - } + if (Type == SUCCESS) + APPEND_FIELD(stream, ToonCounts); else - stream << " Failure"; + APPEND_FIELD(stream, Failure); - return stream.str().c_str(); + return stream.str(); } void Battlenet::WoWRealm::ListUpdate::Write() { - _stream.Write(UpdateState, 1); - if (UpdateState == UPDATE) + _stream.Write(State.Type, 1); + if (State.Type == StateType::UPDATE) { - _stream.Write(Timezone, 32); - _stream.WriteFloat(Population); - _stream.Write(Lock, 8); - _stream.Write(0, 19); - _stream.Write(Type + -std::numeric_limits<int32>::min(), 32); - _stream.WriteString(Name, 10); - _stream.Write(!Version.empty(), 1); - if (!Version.empty()) + _stream.Write(State.Update.Category, 32); + _stream.WriteFloat(State.Update.Population); + _stream.Write(State.Update.StateFlags, 8); + _stream.WriteSkip(19); + _stream.Write(State.Update.Type + -std::numeric_limits<int32>::min(), 32); + _stream.WriteString(State.Update.Name, 10); + _stream.Write(State.Update.PrivilegedData.is_initialized(), 1); + if (State.Update.PrivilegedData.is_initialized()) { - _stream.WriteString(Version, 5); - _stream.Write(Id.Build, 32); + _stream.WriteString(State.Update.PrivilegedData->Version, 5); + _stream.Write(State.Update.PrivilegedData->ConfigId, 32); - boost::asio::ip::address_v4::bytes_type ip = Address.address().to_v4().to_bytes(); - uint16 port = Address.port(); + boost::asio::ip::address_v4::bytes_type ip = State.Update.PrivilegedData->Address.address().to_v4().to_bytes(); + uint16 port = State.Update.PrivilegedData->Address.port(); EndianConvertReverse(ip); EndianConvertReverse(port); @@ -141,67 +122,94 @@ void Battlenet::WoWRealm::ListUpdate::Write() _stream.WriteBytes(&port, 2); } - _stream.Write(Flags, 8); + _stream.Write(State.Update.InfoFlags, 8); } _stream.Write(Id.Region, 8); - _stream.Write(0, 12); - _stream.Write(Id.Battlegroup, 8); - _stream.Write(Id.Index, 32); + _stream.WriteSkip(12); + _stream.Write(Id.Site, 8); + _stream.Write(Id.Realm, 32); } -std::string Battlenet::WoWRealm::ListUpdate::ToString() const +std::string Battlenet::WoWRealm::ListUpdate::PrivilegedDataType::ToString() const { std::ostringstream stream; - stream << "Battlenet::WoWRealm::ListUpdate"; - if (UpdateState == UPDATE) - { - stream << " Timezone: " << Timezone << " Population: " << Population << " Lock: " << uint32(Lock) << " Type: " << Type << " Name: " << Name - << " Flags: " << uint32(Flags) << " Region: " << uint32(Id.Region) << " Battlegroup: " << uint32(Id.Battlegroup) << " Index: " << Id.Index; + stream << "Battlenet::WoWRealm::RealmInfo::PrivilegedData" << std::endl; + APPEND_FIELD(stream, Version); + APPEND_FIELD(stream, ConfigId); + APPEND_FIELD(stream, Address); + return stream.str(); +} - if (!Version.empty()) - stream << " Version: " << Version; - } +std::string Battlenet::WoWRealm::ListUpdate::StateType::UpdateType::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::WoWRealm::ListUpdate::State::Update" << std::endl; + APPEND_FIELD(stream, InfoFlags); + APPEND_FIELD(stream, Name); + APPEND_FIELD(stream, Type); + APPEND_FIELD(stream, Category); + APPEND_FIELD(stream, StateFlags); + APPEND_FIELD(stream, Population); + APPEND_FIELD(stream, PrivilegedData); + return stream.str(); +} + +std::string Battlenet::WoWRealm::ListUpdate::StateType::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::WoWRealm::ListUpdate::State" << std::endl; + + if (Type == UPDATE) + APPEND_FIELD(stream, Update); else - stream << " Delete realm [Region: " << uint32(Id.Region) << " Battlegroup : " << uint32(Id.Battlegroup) << " Index : " << Id.Index << "]"; + APPEND_FIELD(stream, Delete); - return stream.str().c_str(); + return stream.str(); +} + +std::string Battlenet::WoWRealm::ListUpdate::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::WoWRealm::ListUpdate" << std::endl; + APPEND_FIELD(stream, Id); + APPEND_FIELD(stream, State); + return stream.str(); } void Battlenet::WoWRealm::ToonReady::Write() { - _stream.Write(Realm.Region, 8); - _stream.WriteFourCC(Game); - uint32 realmAddress = ((Realm.Battlegroup << 16) & 0xFF0000) | uint16(Realm.Index); - _stream.Write(realmAddress, 32); - _stream.WriteString(Name, 7, -2); + _stream.Write(Name.Region, 8); + _stream.WriteFourCC(Name.ProgramId); + _stream.Write(Name.Realm, 32); + _stream.WriteString(Name.Name, 7, -2); _stream.WriteSkip(21); - _stream.Write(0, 64); // Unknown - _stream.Write(0, 32); // Unknown - _stream.Write(Guid, 64); - _stream.Write(realmAddress, 32); - _stream.Write(Realm.Region, 8); - _stream.WriteFourCC(Game); + _stream.Write(ProfileAddress.Id, 64); + _stream.Write(ProfileAddress.Label, 32); + _stream.Write(Handle.Id, 64); + _stream.Write(Handle.Realm, 32); + _stream.Write(Handle.Region, 8); + _stream.WriteFourCC(Handle.ProgramId); } std::string Battlenet::WoWRealm::ToonReady::ToString() const { std::ostringstream stream; - stream << "Battlenet::WoWRealm::ToonReady" << " Game: " << Game - << ", Region: " << uint32(Realm.Region) << ", Battlegroup: " << uint32(Realm.Battlegroup) << ", Index: " << Realm.Index - << ", Guid: " << Guid << ", Name: " << Name; - - return stream.str().c_str(); + stream << "Battlenet::WoWRealm::ToonReady" << std::endl; + APPEND_FIELD(stream, Name); + APPEND_FIELD(stream, Handle); + APPEND_FIELD(stream, ProfileAddress); + return stream.str(); } void Battlenet::WoWRealm::JoinResponseV2::Write() { - _stream.Write(Response, 1); - if (Response == SUCCESS) + _stream.Write(Type, 1); + if (Type == SUCCESS) { - _stream.Write(ServerSeed, 32); - _stream.Write(IPv4.size(), 5); - for (tcp::endpoint const& addr : IPv4) + _stream.Write(Success.ServerSalt, 32); + _stream.Write(Success.IPv4.size(), 5); + for (tcp::endpoint const& addr : Success.IPv4) { boost::asio::ip::address_v4::bytes_type ip = addr.address().to_v4().to_bytes(); uint16 port = addr.port(); @@ -212,8 +220,8 @@ void Battlenet::WoWRealm::JoinResponseV2::Write() _stream.WriteBytes(&port, 2); } - _stream.Write(IPv6.size(), 5); - for (tcp::endpoint const& addr : IPv6) + _stream.Write(Success.IPv6.size(), 5); + for (tcp::endpoint const& addr : Success.IPv6) { boost::asio::ip::address_v6::bytes_type ip = addr.address().to_v6().to_bytes(); uint16 port = addr.port(); @@ -225,24 +233,28 @@ void Battlenet::WoWRealm::JoinResponseV2::Write() } } else - _stream.Write(ResponseCode, 8); + _stream.Write(Failure, 8); +} + +std::string Battlenet::WoWRealm::JoinResponseV2::SuccessType::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::WoWRealm::JoinResponseV2::Success" << std::endl; + APPEND_FIELD(stream, ServerSalt); + APPEND_FIELD(stream, IPv4); + APPEND_FIELD(stream, IPv6); + return stream.str(); } std::string Battlenet::WoWRealm::JoinResponseV2::ToString() const { std::ostringstream stream; - stream << "Battlenet::WoWRealm::JoinResponseV2"; - if (Response == SUCCESS) - { - stream << " ServerSeed " << ServerSeed << " IPv4 Addresses " << IPv4.size() << " IPv6 Addresses " << IPv6.size(); - for (tcp::endpoint const& addr : IPv4) - stream << std::endl << "Battlenet::WoWRealm::JoinResponseV2::Address " << boost::lexical_cast<std::string>(addr); + stream << "Battlenet::WoWRealm::JoinResponseV2" << std::endl; - for (tcp::endpoint const& addr : IPv6) - stream << std::endl << "Battlenet::WoWRealm::JoinResponseV2::Address " << boost::lexical_cast<std::string>(addr); - } + if (Type == SUCCESS) + APPEND_FIELD(stream, Success); else - stream << " Failure"; + APPEND_FIELD(stream, Failure); - return stream.str().c_str(); + return stream.str(); } diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h index 6c0eb431dde..9daadc6a075 100644 --- a/src/server/bnetserver/Packets/WoWRealmPackets.h +++ b/src/server/bnetserver/Packets/WoWRealmPackets.h @@ -49,7 +49,8 @@ namespace Battlenet } void Read() override { } - std::string ToString() const override; + std::string ToString() const override { return "Battlenet::WoWRealm::ListSubscribeRequest"; } + void CallHandler(Session* session) override; }; @@ -62,7 +63,7 @@ namespace Battlenet } void Read() override { } - std::string ToString() const override; + std::string ToString() const override { return "Battlenet::WoWRealm::ListUnsubscribe"; } void CallHandler(Session* session) override; }; @@ -78,68 +79,92 @@ namespace Battlenet std::string ToString() const override; void CallHandler(Session* session) override; - uint32 ClientSeed = 0; - RealmId Realm; + uint32 ClientSalt = 0; + PrintableRealmHandle Id; }; class ListSubscribeResponse final : public ServerPacket { public: - enum Result + ListSubscribeResponse() : ServerPacket(PacketHeader(SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM)) { - SUCCESS = 0, - FAILURE = 1 - }; + } - ListSubscribeResponse() : ServerPacket(PacketHeader(SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM)), - Response(SUCCESS), ResponseCode(26) + struct ToonCountEntry : public PrintableComponent { - } + ToonCountEntry(PrintableRealmHandle const& realm, uint16 count) : Realm(realm), Count(count) { } - ~ListSubscribeResponse(); + PrintableRealmHandle Realm; + uint16 Count; - struct CharacterCountEntry - { - RealmId Realm; - uint32 CharacterCount; + std::string ToString() const override; }; void Write() override; std::string ToString() const override; - Result Response; - uint8 ResponseCode; - std::vector<CharacterCountEntry> CharacterCounts; - std::vector<ServerPacket*> RealmData; + enum + { + SUCCESS = 0, + FAILURE = 1 + }; + + int32 Type = SUCCESS; + + std::vector<ToonCountEntry> ToonCounts; + Wow::AuthResult Failure; }; class ListUpdate final : public ServerPacket { public: - enum State - { - DELETED = 0, - UPDATE = 1 - }; - - ListUpdate() : ServerPacket(PacketHeader(SMSG_LIST_UPDATE, WOWREALM)), UpdateState(UPDATE), - Timezone(0), Population(0.0f), Lock(0), Type(0), Name(""), Version(""), Flags(0) + ListUpdate() : ServerPacket(PacketHeader(SMSG_LIST_UPDATE, WOWREALM)) { } void Write() override; std::string ToString() const override; - int UpdateState; - uint32 Timezone; - float Population; - uint8 Lock; - uint32 Type; - std::string Name; - std::string Version; - tcp::endpoint Address; - uint8 Flags; - RealmId Id; + PrintableRealmHandle Id; + + struct PrivilegedDataType : public PrintableComponent + { + std::string Version; + uint32 ConfigId = 0; + tcp::endpoint Address; + + std::string ToString() const override; + }; + + struct StateType : public PrintableComponent + { + enum + { + DELETED = 0, + UPDATE = 1 + }; + + int32 Type = UPDATE; + struct DeleteType : public PrintableComponent + { + std::string ToString() const override { return "Battlenet::WoWRealm::ListUpdate::State::Delete"; } + } Delete; + + struct UpdateType : public PrintableComponent + { + uint8 InfoFlags = 0; + std::string Name; + int32 Type = 0; + uint32 Category = 0; + uint8 StateFlags = 0; + float Population = 0.0f; + Optional<PrivilegedDataType> PrivilegedData; + + std::string ToString() const override; + } Update; + + std::string ToString() const override; + } State; }; class ListComplete final : public ServerPacket @@ -156,17 +181,16 @@ namespace Battlenet class ToonReady final : public ServerPacket { public: - ToonReady() : ServerPacket(PacketHeader(SMSG_TOON_READY, WOWREALM)), Game("WoW"), Guid(0) + ToonReady() : ServerPacket(PacketHeader(SMSG_TOON_READY, WOWREALM)) { } void Write() override; std::string ToString() const override; - std::string Game; - RealmId Realm; - uint64 Guid; - std::string Name; + Toon::FullName Name; + Toon::Handle Handle; + Profile::RecordAddress ProfileAddress; }; class ToonLoggedOut final : public ServerPacket @@ -183,25 +207,30 @@ namespace Battlenet class JoinResponseV2 final : public ServerPacket { public: - enum Result + JoinResponseV2() : ServerPacket(PacketHeader(SMSG_JOIN_RESPONSE_V2, WOWREALM)) + { + } + + void Write() override; + std::string ToString() const override; + + enum { SUCCESS = 0, FAILURE = 1 }; - JoinResponseV2() : ServerPacket(PacketHeader(SMSG_JOIN_RESPONSE_V2, WOWREALM)), - Response(SUCCESS), ResponseCode(26), ServerSeed(0) + int32 Type = SUCCESS; + struct SuccessType : public PrintableComponent { - } + uint32 ServerSalt; + std::vector<tcp::endpoint> IPv4; + std::vector<tcp::endpoint> IPv6; - void Write() override; - std::string ToString() const override; + std::string ToString() const override; + } Success; - Result Response; - uint8 ResponseCode; - uint32 ServerSeed; - std::vector<tcp::endpoint> IPv4; - std::vector<tcp::endpoint> IPv6; + Wow::AuthResult Failure; }; } } diff --git a/src/server/bnetserver/Realms/RealmList.cpp b/src/server/bnetserver/Realms/RealmList.cpp index ff7e2779a6e..089ca37a54a 100644 --- a/src/server/bnetserver/Realms/RealmList.cpp +++ b/src/server/bnetserver/Realms/RealmList.cpp @@ -65,7 +65,7 @@ inline void UpdateField(FieldType& out, FieldType const& in, bool& changed) } } -void RealmList::UpdateRealm(Battlenet::RealmId const& id, const std::string& name, ip::address const& address, ip::address const& localAddr, +void RealmList::UpdateRealm(Battlenet::RealmHandle const& id, uint32 build, const std::string& name, ip::address const& address, ip::address const& localAddr, ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population) { @@ -75,6 +75,7 @@ void RealmList::UpdateRealm(Battlenet::RealmId const& id, const std::string& nam realm.Keep = true; realm.Id = id; + UpdateField(realm.Build, build, realm.Updated); UpdateField(realm.Name, name, realm.Updated); UpdateField(realm.Type, icon, realm.Updated); UpdateField(realm.Flags, flag, realm.Updated); @@ -142,6 +143,10 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) uint16 port = fields[5].GetUInt16(); uint8 icon = fields[6].GetUInt8(); + if (icon == REALM_TYPE_FFA_PVP) + icon = REALM_TYPE_PVP; + if (icon >= MAX_CLIENT_REALM_TYPE) + icon = REALM_TYPE_NORMAL; RealmFlags flag = RealmFlags(fields[7].GetUInt8()); uint8 timezone = fields[8].GetUInt8(); uint8 allowedSecurityLevel = fields[9].GetUInt8(); @@ -151,10 +156,10 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) uint8 region = fields[12].GetUInt8(); uint8 battlegroup = fields[13].GetUInt8(); - Battlenet::RealmId id{ region, battlegroup, realmId, build }; + Battlenet::RealmHandle id{ region, battlegroup, realmId }; - UpdateRealm(id, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone, - (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop); + UpdateRealm(id, build, name, externalAddress, localAddress, localSubmask, port, icon, flag, + timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop); TC_LOG_TRACE("realmlist", "Realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port); } @@ -168,7 +173,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) } std::vector<Realm const*> updatedRealms; - std::vector<Battlenet::RealmId> deletedRealms; + std::vector<Battlenet::RealmHandle> deletedRealms; for (RealmMap::value_type& pair : _realms) { @@ -181,7 +186,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) pair.second.Keep = false; } - for (Battlenet::RealmId const& deleted : deletedRealms) + for (Battlenet::RealmHandle const& deleted : deletedRealms) _realms.erase(deleted); if (!updatedRealms.empty() || !deletedRealms.empty()) @@ -200,7 +205,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) } } -Realm const* RealmList::GetRealm(Battlenet::RealmId const& id) const +Realm const* RealmList::GetRealm(Battlenet::RealmHandle const& id) const { auto itr = _realms.find(id); if (itr != _realms.end()) diff --git a/src/server/bnetserver/Realms/RealmList.h b/src/server/bnetserver/Realms/RealmList.h index 5e0a73017cc..670c51a7c36 100644 --- a/src/server/bnetserver/Realms/RealmList.h +++ b/src/server/bnetserver/Realms/RealmList.h @@ -20,7 +20,7 @@ #define _REALMLIST_H #include "Common.h" -#include "Realm.h" +#include "Realm/Realm.h" #include "WorldListener.h" #include <boost/asio/ip/address.hpp> #include <boost/asio/ip/tcp.hpp> @@ -33,7 +33,7 @@ using namespace boost::asio; class RealmList { public: - typedef std::map<Battlenet::RealmId, Realm> RealmMap; + typedef std::map<Battlenet::RealmHandle, Realm> RealmMap; static RealmList* instance() { @@ -47,13 +47,13 @@ public: void Close(); RealmMap const& GetRealms() const { return _realms; } - Realm const* GetRealm(Battlenet::RealmId const& id) const; + Realm const* GetRealm(Battlenet::RealmHandle const& id) const; private: RealmList(); void UpdateRealms(boost::system::error_code const& error); - void UpdateRealm(Battlenet::RealmId const& id, const std::string& name, ip::address const& address, ip::address const& localAddr, + void UpdateRealm(Battlenet::RealmHandle const& id, uint32 build, const std::string& name, ip::address const& address, ip::address const& localAddr, ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population); RealmMap _realms; diff --git a/src/server/bnetserver/Realms/WorldListener.cpp b/src/server/bnetserver/Realms/WorldListener.cpp index d6a12453644..3bf7e4ecf03 100644 --- a/src/server/bnetserver/Realms/WorldListener.cpp +++ b/src/server/bnetserver/Realms/WorldListener.cpp @@ -85,7 +85,7 @@ void WorldListener::HandleClose() void WorldListener::Dispatch(zmqpp::message& msg) const { - Battlenet::Header ipcHeader; + IPC::BattlenetComm::Header ipcHeader; msg >> ipcHeader; if (ipcHeader.Ipc.Channel != IPC_CHANNEL_BNET) @@ -97,7 +97,7 @@ void WorldListener::Dispatch(zmqpp::message& msg) const void WorldListener::HandleToonOnlineStatusChange(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const { - Battlenet::ToonHandle toonHandle; + IPC::BattlenetComm::ToonHandle toonHandle; bool online; msg >> toonHandle; msg >> online; @@ -109,11 +109,16 @@ void WorldListener::HandleToonOnlineStatusChange(Battlenet::RealmHandle const& r if (!session->IsToonOnline()) { Battlenet::WoWRealm::ToonReady* toonReady = new Battlenet::WoWRealm::ToonReady(); - toonReady->Realm.Battlegroup = realm.Battlegroup; - toonReady->Realm.Index = realm.Index; - toonReady->Realm.Region = realm.Region; - toonReady->Guid = toonHandle.Guid; - toonReady->Name = toonHandle.Name; + toonReady->Name.Region = realm.Region; + toonReady->Name.ProgramId = "WoW"; + toonReady->Name.Realm = realm.GetAddress(); + toonReady->Name.Name = toonHandle.Name; + + toonReady->Handle.Region = realm.Region; + toonReady->Handle.ProgramId = "WoW"; + toonReady->Handle.Realm = realm.GetAddress(); + toonReady->Handle.Id = toonHandle.Guid; + session->SetToonOnline(true); session->AsyncWrite(toonReady); } diff --git a/src/server/bnetserver/Server/ComponentManager.cpp b/src/server/bnetserver/Server/ComponentManager.cpp index 52f93fd52ad..468b03bf13b 100644 --- a/src/server/bnetserver/Server/ComponentManager.cpp +++ b/src/server/bnetserver/Server/ComponentManager.cpp @@ -20,7 +20,7 @@ Battlenet::ComponentMgr::~ComponentMgr() { - for (Component* component : _components) + for (Version::Record* component : _components) delete component; } @@ -32,23 +32,23 @@ void Battlenet::ComponentMgr::Load() do { Field* fields = result->Fetch(); - Component* component = new Component(); - component->Program = fields[0].GetString(); - component->Platform = fields[1].GetString(); - component->Build = fields[2].GetUInt32(); + Version::Record* component = new Version::Record(); + component->ProgramId = fields[0].GetString(); + component->Component = fields[1].GetString(); + component->Version = fields[2].GetUInt32(); _components.insert(component); - _programs.insert(component->Program); - _platforms.insert(component->Platform); + _programs.insert(component->ProgramId); + _platforms.insert(component->Component); } while (result->NextRow()); } } -bool Battlenet::ComponentMgr::HasComponent(Battlenet::Component const* component) const +bool Battlenet::ComponentMgr::HasComponent(Battlenet::Version::Record const* component) const { - for (Component const* c : _components) - if (component->Program == c->Program && component->Platform == c->Platform && component->Build == c->Build) + for (Version::Record const* c : _components) + if (component->ProgramId == c->ProgramId && component->Component == c->Component && component->Version == c->Version) return true; return false; diff --git a/src/server/bnetserver/Server/ComponentManager.h b/src/server/bnetserver/Server/ComponentManager.h index 7aae45d94c5..0b403d2f309 100644 --- a/src/server/bnetserver/Server/ComponentManager.h +++ b/src/server/bnetserver/Server/ComponentManager.h @@ -19,19 +19,13 @@ #define ComponentManager_h__ #include "Define.h" +#include "PacketsCommon.h" #include <cstring> #include <string> #include <set> namespace Battlenet { - struct Component - { - std::string Program; - std::string Platform; - uint32 Build; - }; - class ComponentMgr { ComponentMgr() { } @@ -39,7 +33,7 @@ namespace Battlenet public: void Load(); - bool HasComponent(Component const* component) const; + bool HasComponent(Version::Record const* component) const; bool HasProgram(std::string const& program) const { return _programs.count(program) != 0; } bool HasPlatform(std::string const& platform) const { return _platforms.count(platform) != 0; } @@ -50,7 +44,7 @@ namespace Battlenet } private: - std::set<Component*> _components; + std::set<Version::Record*> _components; std::set<std::string> _programs; std::set<std::string> _platforms; }; diff --git a/src/server/bnetserver/Server/ModuleManager.cpp b/src/server/bnetserver/Server/ModuleManager.cpp index 3b525eae094..04d21c191a2 100644 --- a/src/server/bnetserver/Server/ModuleManager.cpp +++ b/src/server/bnetserver/Server/ModuleManager.cpp @@ -33,8 +33,8 @@ void Battlenet::ModuleManager::Load() { Field* fields = result->Fetch(); ModuleInfo* module = new ModuleInfo(); - module->Type = fields[2].GetString(); - HexStrToByteArray(fields[0].GetString(), module->ModuleId); + module->Handle.Type = fields[2].GetString(); + HexStrToByteArray(fields[0].GetString(), module->Handle.ModuleId); std::string data = fields[4].GetString(); module->DataSize = data.length() / 2; if (module->DataSize) @@ -56,3 +56,11 @@ Battlenet::ModuleInfo* Battlenet::ModuleManager::CreateModule(std::string const& return new ModuleInfo(*_modules.at(key)); } + +std::string Battlenet::ModuleInfo::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::ModuleInput" << std::endl; + APPEND_FIELD(stream, Handle); + return stream.str(); +} diff --git a/src/server/bnetserver/Server/ModuleManager.h b/src/server/bnetserver/Server/ModuleManager.h index 68d5b2a1e78..ecd24a07363 100644 --- a/src/server/bnetserver/Server/ModuleManager.h +++ b/src/server/bnetserver/Server/ModuleManager.h @@ -18,10 +18,7 @@ #ifndef ModuleManager_h__ #define ModuleManager_h__ -#include "Define.h" -#include <cstring> -#include <string> -#include <map> +#include "PacketsCommon.h" namespace Battlenet { @@ -42,12 +39,14 @@ namespace Battlenet } }; - struct ModuleInfo + struct ModuleInfo : public PrintableComponent { - ModuleInfo() : Region("EU"), DataSize(0), Data(nullptr) { } - ModuleInfo(ModuleInfo const& right) : Type(right.Type), Region(right.Region), DataSize(right.DataSize), Data(nullptr) + ModuleInfo() : DataSize(0), Data(nullptr) { Handle.Region = "EU"; } + ModuleInfo(ModuleInfo const& right) : DataSize(right.DataSize), Data(nullptr) { - memcpy(ModuleId, right.ModuleId, 32); + Handle.Type = right.Handle.Type; + Handle.Region = right.Handle.Region; + memcpy(Handle.ModuleId, right.Handle.ModuleId, 32); if (DataSize) { Data = new uint8[DataSize]; @@ -60,11 +59,11 @@ namespace Battlenet delete[] Data; } - std::string Type; - std::string Region; - uint8 ModuleId[32]; + Cache::Handle Handle; uint32 DataSize; uint8* Data; + + std::string ToString() const override; }; class ModuleManager @@ -83,9 +82,6 @@ namespace Battlenet } private: - void LoadComponents(); - void LoadModules(); - std::map<ModuleKey, ModuleInfo*> _modules; }; } diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index 25c50ba867b..36137b20b41 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -136,69 +136,69 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& return; } - if (logonRequest.Program != "WoW") + if (logonRequest.Common.Program != "WoW") { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM); AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in with game other than WoW (using %s)!", GetClientInfo().c_str(), logonRequest.Program.c_str()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in with game other than WoW (using %s)!", GetClientInfo().c_str(), logonRequest.Common.Program.c_str()); return; } - if (!sComponentMgr->HasPlatform(logonRequest.Platform)) + if (!sComponentMgr->HasPlatform(logonRequest.Common.Platform)) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(AUTH_INVALID_OS); AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in from an unsupported platform (using %s)!", GetClientInfo().c_str(), logonRequest.Platform.c_str()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in from an unsupported platform (using %s)!", GetClientInfo().c_str(), logonRequest.Common.Platform.c_str()); return; } - if (!sComponentMgr->HasPlatform(logonRequest.Locale)) + if (!sComponentMgr->HasPlatform(logonRequest.Common.Locale)) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE); AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in with unsupported locale (using %s)!", GetClientInfo().c_str(), logonRequest.Locale.c_str()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in with unsupported locale (using %s)!", GetClientInfo().c_str(), logonRequest.Common.Locale.c_str()); return; } - for (Component const& component : logonRequest.Components) + for (Version::Record const& component : logonRequest.Common.Versions) { if (!sComponentMgr->HasComponent(&component)) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - if (!sComponentMgr->HasProgram(component.Program)) + if (!sComponentMgr->HasProgram(component.ProgramId)) { logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component program %s!", GetClientInfo().c_str(), component.Program.c_str()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component program %s!", GetClientInfo().c_str(), component.ProgramId.c_str()); } - else if (!sComponentMgr->HasPlatform(component.Platform)) + else if (!sComponentMgr->HasPlatform(component.Component)) { logonResponse->SetAuthResult(AUTH_INVALID_OS); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component platform %s!", GetClientInfo().c_str(), component.Platform.c_str()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component platform %s!", GetClientInfo().c_str(), component.Component.c_str()); } else { - if (component.Program != "WoW" || AuthHelper::IsBuildSupportingBattlenet(component.Build)) + if (component.ProgramId != "WoW" || AuthHelper::IsBuildSupportingBattlenet(component.Version)) logonResponse->SetAuthResult(AUTH_REGION_BAD_VERSION); else logonResponse->SetAuthResult(AUTH_USE_GRUNT_LOGON); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component version %u!", GetClientInfo().c_str(), component.Build); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component version %u!", GetClientInfo().c_str(), component.Version); } AsyncWrite(logonResponse); return; } - if (component.Platform == "base") - _build = component.Build; + if (component.Component == "base") + _build = component.Version; } - std::string login = logonRequest.Login; - _locale = logonRequest.Locale; - _os = logonRequest.Platform; + std::string login = logonRequest.Account; + _locale = logonRequest.Common.Locale; + _os = logonRequest.Common.Platform; Utf8ToUpperOnlyLatin(login); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO); @@ -341,12 +341,12 @@ void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const return; } - std::string login = resumeRequest.Login; - _locale = resumeRequest.Locale; - _os = resumeRequest.Platform; - auto baseComponent = std::find_if(resumeRequest.Components.begin(), resumeRequest.Components.end(), [](Component const& c) { return c.Program == "base"; }); - if (baseComponent != resumeRequest.Components.end()) - _build = baseComponent->Build; + std::string login = resumeRequest.Account; + _locale = resumeRequest.Common.Locale; + _os = resumeRequest.Common.Platform; + auto baseComponent = std::find_if(resumeRequest.Common.Versions.begin(), resumeRequest.Common.Versions.end(), [](Version::Record const& c) { return c.ProgramId == "base"; }); + if (baseComponent != resumeRequest.Common.Versions.end()) + _build = baseComponent->Version; Utf8ToUpperOnlyLatin(login); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO); @@ -398,7 +398,7 @@ void Battlenet::Session::HandleResumeRequestCallback(PreparedQueryResult result) void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const& proofResponse) { - if (_modulesWaitingForData.size() < proofResponse.Modules.size()) + if (_modulesWaitingForData.size() < proofResponse.Response.size()) { Authentication::LogonResponse* complete = new Authentication::LogonResponse(); complete->SetAuthResult(AUTH_CORRUPTED_MODULE); @@ -407,9 +407,9 @@ void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const } ServerPacket* response = nullptr; - for (size_t i = 0; i < proofResponse.Modules.size(); ++i) + for (size_t i = 0; i < proofResponse.Response.size(); ++i) { - if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proofResponse.Modules[i], &response)) + if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proofResponse.Response[i], &response)) break; _modulesWaitingForData.pop(); @@ -469,17 +469,17 @@ void Battlenet::Session::HandleListSubscribeRequestCallback(PreparedQueryResult do { Field* fields = result->Fetch(); - uint32 build = fields[4].GetUInt32(); - listSubscribeResponse->CharacterCounts.push_back({ RealmId(fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0)), fields[0].GetUInt8() }); + listSubscribeResponse->ToonCounts.emplace_back(PrintableRealmHandle(fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32()), uint16(fields[0].GetUInt8())); } while (result->NextRow()); } + AsyncWrite(listSubscribeResponse); + for (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms()) - listSubscribeResponse->RealmData.push_back(BuildListUpdate(&i.second)); + AsyncWrite(BuildListUpdate(&i.second)); - listSubscribeResponse->RealmData.push_back(new WoWRealm::ListComplete()); + AsyncWrite(new WoWRealm::ListComplete()); - AsyncWrite(listSubscribeResponse); _subscribedToRealmListUpdates = true; } @@ -491,29 +491,29 @@ void Battlenet::Session::HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest) { WoWRealm::JoinResponseV2* joinResponse = new WoWRealm::JoinResponseV2(); - Realm const* realm = sRealmList->GetRealm(joinRequest.Realm); - if (!realm || realm->Flags & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE) || realm->Id.Build != _build) + Realm const* realm = sRealmList->GetRealm(joinRequest.Id); + if (!realm || realm->Flags & (REALM_FLAG_VERSION_MISMATCH | REALM_FLAG_OFFLINE) || realm->Build != _build) { - joinResponse->Response = WoWRealm::JoinResponseV2::FAILURE; + joinResponse->Type = WoWRealm::JoinResponseV2::FAILURE; AsyncWrite(joinResponse); return; } - joinResponse->ServerSeed = rand32(); + joinResponse->Success.ServerSalt = rand32(); uint8 sessionKey[40]; HmacSha1 hmac(K.GetNumBytes(), K.AsByteArray().get()); hmac.UpdateData((uint8*)"WoW\0", 4); - hmac.UpdateData((uint8*)&joinRequest.ClientSeed, 4); - hmac.UpdateData((uint8*)&joinResponse->ServerSeed, 4); + hmac.UpdateData((uint8*)&joinRequest.ClientSalt, 4); + hmac.UpdateData((uint8*)&joinResponse->Success.ServerSalt, 4); hmac.Finalize(); memcpy(sessionKey, hmac.GetDigest(), hmac.GetLength()); HmacSha1 hmac2(K.GetNumBytes(), K.AsByteArray().get()); hmac2.UpdateData((uint8*)"WoW\0", 4); - hmac2.UpdateData((uint8*)&joinResponse->ServerSeed, 4); - hmac2.UpdateData((uint8*)&joinRequest.ClientSeed, 4); + hmac2.UpdateData((uint8*)&joinResponse->Success.ServerSalt, 4); + hmac2.UpdateData((uint8*)&joinRequest.ClientSalt, 4); hmac2.Finalize(); memcpy(sessionKey + hmac.GetLength(), hmac2.GetDigest(), hmac2.GetLength()); @@ -521,25 +521,21 @@ void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& join LoginDatabase.DirectPExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = %u, failed_logins = 0, os = '%s' WHERE id = %u", ByteArrayToHexStr(sessionKey, 40, true).c_str(), GetRemoteIpAddress().to_string().c_str(), GetLocaleByName(_locale), _os.c_str(), _gameAccountInfo->Id); - joinResponse->IPv4.push_back(realm->GetAddressForClient(GetRemoteIpAddress())); + joinResponse->Success.IPv4.push_back(realm->GetAddressForClient(GetRemoteIpAddress())); AsyncWrite(joinResponse); } -void Battlenet::Session::HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected) -{ - Friends::SocialNetworkCheckConnectedResult* socialNetworkCheckConnectedResult = new Friends::SocialNetworkCheckConnectedResult(); - socialNetworkCheckConnectedResult->SocialNetworkId = socialNetworkCheckConnected.SocialNetworkId; - AsyncWrite(socialNetworkCheckConnectedResult); -} - void Battlenet::Session::HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest) { - if (ModuleInfo* module = sModuleMgr->CreateModule(getStreamItemsRequest.Locale, getStreamItemsRequest.ItemName)) + if (getStreamItemsRequest.Stream.Type != Cache::GetStreamItemsRequest::StreamId::DESCRIPTION) + return; + + if (ModuleInfo* module = sModuleMgr->CreateModule(getStreamItemsRequest.Locale, getStreamItemsRequest.Stream.Description.ItemName)) { Cache::GetStreamItemsResponse* getStreamItemsResponse = new Cache::GetStreamItemsResponse(); - getStreamItemsResponse->Index = getStreamItemsRequest.Index; - getStreamItemsResponse->Modules.push_back(module); + getStreamItemsResponse->Token = getStreamItemsRequest.Token; + getStreamItemsResponse->Items.push_back(module); AsyncWrite(getStreamItemsResponse); } } @@ -570,11 +566,11 @@ void Battlenet::Session::ReadHandler() try { PacketHeader header; - header.Opcode = stream.Read<uint32>(6); + header.Command = stream.Read<uint32>(6); if (stream.Read<bool>(1)) header.Channel = stream.Read<int32>(4); - if (header.Channel != AUTHENTICATION && (header.Channel != CONNECTION || header.Opcode != Connection::CMSG_PING) && !_authed) + if (header.Channel != AUTHENTICATION && (header.Channel != CONNECTION || header.Command != Connection::CMSG_PING) && !_authed) { TC_LOG_DEBUG("session.packets", "%s Received not allowed %s. Client has not authed yet.", GetClientInfo().c_str(), header.ToString().c_str()); CloseSocket(); @@ -976,10 +972,10 @@ bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, Serv Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); if (dataStream->Read<uint8>(8) == 1 && _accountInfo && _gameAccountInfo) { - logonResponse->AccountId = _accountInfo->Id; - logonResponse->GameAccountName = _gameAccountInfo->Name; - logonResponse->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS; - logonResponse->FailedLogins = _accountInfo->FailedLogins; + logonResponse->Result.Success.AccountId = _accountInfo->Id; + logonResponse->Result.Success.GameAccountName = _gameAccountInfo->Name; + logonResponse->Result.Success.GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS; + logonResponse->Result.Success.LogonFailures = _accountInfo->FailedLogins; SQLTransaction trans = LoginDatabase.BeginTransaction(); @@ -1087,7 +1083,7 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket* memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize); Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse(); - resumeResponse->Modules.push_back(resume); + resumeResponse->Result.Success.FinalRequest.push_back(resume); ReplaceResponse(response, resumeResponse); _authed = true; sSessionMgr.AddSession(this); @@ -1103,15 +1099,15 @@ bool Battlenet::Session::UnhandledModule(BitStream* /*dataStream*/, ServerPacket return false; } -void Battlenet::Session::UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmId>& deletedRealms) +void Battlenet::Session::UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmHandle>& deletedRealms) { for (Realm const* realm : realms) AsyncWrite(BuildListUpdate(realm)); - for (RealmId& deleted : deletedRealms) + for (RealmHandle& deleted : deletedRealms) { WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate(); - listUpdate->UpdateState = WoWRealm::ListUpdate::DELETED; + listUpdate->State.Type = WoWRealm::ListUpdate::StateType::DELETED; listUpdate->Id = deleted; AsyncWrite(listUpdate); } @@ -1119,32 +1115,32 @@ void Battlenet::Session::UpdateRealms(std::vector<Realm const*>& realms, std::ve Battlenet::WoWRealm::ListUpdate* Battlenet::Session::BuildListUpdate(Realm const* realm) const { - uint32 flag = realm->Flags & ~REALM_FLAG_SPECIFYBUILD; - RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm->Id.Build); - if (realm->Id.Build != _build) - { - flag |= REALM_FLAG_INVALID; - if (buildInfo) - flag |= REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for - } + uint32 flag = realm->Flags; + if (realm->Build != _build) + flag |= REALM_FLAG_VERSION_MISMATCH; WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate(); - listUpdate->Timezone = realm->Timezone; - listUpdate->Population = realm->PopulationLevel; - listUpdate->Lock = (realm->AllowedSecurityLevel > _gameAccountInfo->SecurityLevel) ? 1 : 0; - listUpdate->Type = realm->Type; - listUpdate->Name = realm->Name; + listUpdate->State.Update.Category = realm->Timezone; + listUpdate->State.Update.Population = realm->PopulationLevel; + listUpdate->State.Update.StateFlags = (realm->AllowedSecurityLevel > _gameAccountInfo->SecurityLevel) ? 1 : 0; + listUpdate->State.Update.Type = realm->Type; + listUpdate->State.Update.Name = realm->Name; - if (flag & REALM_FLAG_SPECIFYBUILD) + if (_gameAccountInfo->SecurityLevel > SEC_PLAYER) { + listUpdate->State.Update.PrivilegedData = boost::in_place(); std::ostringstream version; - version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build; + if (RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm->Build)) + version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build; + else + version << "x.x.x." << realm->Build; - listUpdate->Version = version.str(); - listUpdate->Address = realm->GetAddressForClient(GetRemoteIpAddress()); + listUpdate->State.Update.PrivilegedData->Version = version.str(); + listUpdate->State.Update.PrivilegedData->ConfigId = realm->GetConfigId(); + listUpdate->State.Update.PrivilegedData->Address = realm->GetAddressForClient(GetRemoteIpAddress()); } - listUpdate->Flags = flag; + listUpdate->State.Update.InfoFlags = flag; listUpdate->Id = realm->Id; return listUpdate; } diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index 91890f9becb..6d5b97e85c9 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -106,7 +106,6 @@ namespace Battlenet void HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest); // Friends - void HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected); // Cache void HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest); @@ -114,7 +113,7 @@ namespace Battlenet void Start() override; bool Update() override; - void UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmId>& deletedRealms); + void UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmHandle>& deletedRealms); uint32 GetAccountId() const { return _accountInfo->Id; } uint32 GetGameAccountId() const { return _gameAccountInfo->Id; } diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 9897a747ab0..c284a4acdfe 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -456,7 +456,7 @@ void AccountMgr::LoadRBAC() while (result->NextRow()); TC_LOG_DEBUG("rbac", "AccountMgr::LoadRBAC: Loading default permissions"); - result = LoginDatabase.PQuery("SELECT secId, permissionId FROM rbac_default_permissions WHERE (realmId = %u OR realmId = -1) ORDER BY secId ASC", realmHandle.Index); + result = LoginDatabase.PQuery("SELECT secId, permissionId FROM rbac_default_permissions WHERE (realmId = %u OR realmId = -1) ORDER BY secId ASC", realm.Id.Realm); if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty."); diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index dfff09f0694..787009901f5 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -107,7 +107,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& else { bidderAccId = ObjectMgr::GetPlayerAccountIdByGUID(bidderGuid); - logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realmHandle.Index); + logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realm.Id.Realm); if (logGmTrade && !ObjectMgr::GetPlayerNameByGUID(bidderGuid, bidderName)) bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index be63eb87888..ff8192e459a 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -147,7 +147,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac if (target) target_sec = target->GetSecurity(); else if (target_account) - target_sec = AccountMgr::GetSecurity(target_account, realmHandle.Index); + target_sec = AccountMgr::GetSecurity(target_account, realm.Id.Realm); else return true; // caller must report error for (target == NULL && target_account == 0) diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp index 05ef5d7dc32..063756035b9 100644 --- a/src/server/game/Entities/Object/ObjectGuid.cpp +++ b/src/server/game/Entities/Object/ObjectGuid.cpp @@ -97,12 +97,12 @@ ObjectGuid ObjectGuid::Global(HighGuid type, LowType counter) ObjectGuid ObjectGuid::RealmSpecific(HighGuid type, LowType counter) { - return ObjectGuid(uint64(uint64(type) << 58 | uint64(realmHandle.Index) << 42), counter); + return ObjectGuid(uint64(uint64(type) << 58 | uint64(realm.Id.Realm) << 42), counter); } ObjectGuid ObjectGuid::MapSpecific(HighGuid type, uint8 subType, uint16 mapId, uint32 serverId, uint32 entry, LowType counter) { - return ObjectGuid(uint64((uint64(type) << 58) | (uint64(realmHandle.Index & 0x1FFF) << 42) | (uint64(mapId & 0x1FFF) << 29) | (uint64(entry & 0x7FFFFF) << 6) | (uint64(subType) & 0x3F)), + return ObjectGuid(uint64((uint64(type) << 58) | (uint64(realm.Id.Realm & 0x1FFF) << 42) | (uint64(mapId & 0x1FFF) << 29) | (uint64(entry & 0x7FFFFF) << 6) | (uint64(subType) & 0x3F)), uint64((uint64(serverId & 0xFFFFFF) << 40) | (counter & UI64LIT(0xFFFFFFFFFF)))); } diff --git a/src/server/game/Handlers/AuthHandler.cpp b/src/server/game/Handlers/AuthHandler.cpp index 66a31ce0bf2..e0c09d41969 100644 --- a/src/server/game/Handlers/AuthHandler.cpp +++ b/src/server/game/Handlers/AuthHandler.cpp @@ -40,7 +40,7 @@ void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos) response.SuccessInfo->ActiveExpansionLevel = GetExpansion(); response.SuccessInfo->VirtualRealmAddress = GetVirtualRealmAddress(); - std::string realmName = sObjectMgr->GetRealmName(realmHandle.Index); + std::string realmName = sObjectMgr->GetRealmName(realm.Id.Realm); // Send current home realm. Also there is no need to send it later in realm queries. response.SuccessInfo->VirtualRealms.emplace_back(GetVirtualRealmAddress(), true, false, realmName, realmName); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index cb5493dba0e..dbf6076efdc 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -715,13 +715,13 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM); stmt->setUInt32(0, GetAccountId()); - stmt->setUInt32(1, realmHandle.Index); + stmt->setUInt32(1, realm.Id.Realm); trans->Append(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS); stmt->setUInt32(0, createInfo->CharCount); stmt->setUInt32(1, GetAccountId()); - stmt->setUInt32(2, realmHandle.Index); + stmt->setUInt32(2, realm.Id.Realm); trans->Append(stmt); LoginDatabase.CommitTransaction(trans); diff --git a/src/server/game/Handlers/SocialHandler.cpp b/src/server/game/Handlers/SocialHandler.cpp index e8533ff917c..9091701660c 100644 --- a/src/server/game/Handlers/SocialHandler.cpp +++ b/src/server/game/Handlers/SocialHandler.cpp @@ -61,7 +61,7 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std uint32 team = Player::TeamForRace(fields[1].GetUInt8()); uint32 friendAccountId = fields[2].GetUInt32(); - if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmHandle.Index))) + if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realm.Id.Realm))) { if (friendGuid == GetPlayer()->GetGUID()) friendResult = FRIEND_SELF; diff --git a/src/server/game/Server/BattlenetServerManager.cpp b/src/server/game/Server/BattlenetServerManager.cpp index 18d74d14cd6..9990ada0ead 100644 --- a/src/server/game/Server/BattlenetServerManager.cpp +++ b/src/server/game/Server/BattlenetServerManager.cpp @@ -20,7 +20,7 @@ #include "ZmqContext.h" #include "BattlenetServerManager.h" -void Battlenet::ServerManager::InitializeConnection() +void IPC::BattlenetComm::ServerManager::InitializeConnection() { std::string bnetserverAddress = sConfigMgr->GetStringDefault("BnetServer.Address", "127.0.0.1"); int32 bnetserverPort = sConfigMgr->GetIntDefault("BnetServer.Port", 1118); @@ -28,23 +28,23 @@ void Battlenet::ServerManager::InitializeConnection() _socket->Start(); } -void Battlenet::ServerManager::CloseConnection() +void IPC::BattlenetComm::ServerManager::CloseConnection() { _socket->End(); delete _socket; _socket = nullptr; } -Battlenet::Header Battlenet::ServerManager::CreateHeader(BnetCommands command) +IPC::BattlenetComm::Header IPC::BattlenetComm::ServerManager::CreateHeader(BnetCommands command) { Header header; header.Ipc.Channel = IPC_CHANNEL_BNET; header.Ipc.Command = command; - header.Realm = realmHandle; + header.Realm = realm.Id; return header; } -void Battlenet::ServerManager::SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online) +void IPC::BattlenetComm::ServerManager::SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online) { // Do nothing for Grunt login if (!battlenetAccountId) @@ -65,7 +65,7 @@ void Battlenet::ServerManager::SendChangeToonOnlineState(uint32 battlenetAccount Send(&msg); } -void Battlenet::ServerManager::Send(zmqpp::message* msg) +void IPC::BattlenetComm::ServerManager::Send(zmqpp::message* msg) { if (!_socket) return; diff --git a/src/server/game/Server/BattlenetServerManager.h b/src/server/game/Server/BattlenetServerManager.h index 424d3131336..e4d7eae156e 100644 --- a/src/server/game/Server/BattlenetServerManager.h +++ b/src/server/game/Server/BattlenetServerManager.h @@ -27,32 +27,35 @@ namespace zmqpp class message; } -namespace Battlenet +namespace IPC { - class ServerManager + namespace BattlenetComm { - ServerManager() : _socket(nullptr) { } + class ServerManager + { + ServerManager() : _socket(nullptr) { } - public: - void InitializeConnection(); - void CloseConnection(); + public: + void InitializeConnection(); + void CloseConnection(); - static ServerManager& Instance() - { - static ServerManager instance; - return instance; - } + static ServerManager& Instance() + { + static ServerManager instance; + return instance; + } - void SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online); + void SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online); - private: - void Send(zmqpp::message* msg); + private: + void Send(zmqpp::message* msg); - static Header CreateHeader(BnetCommands command); - ZmqMux* _socket; - }; + static Header CreateHeader(BnetCommands command); + ZmqMux* _socket; + }; + } } -#define sBattlenetServer Battlenet::ServerManager::Instance() +#define sBattlenetServer IPC::BattlenetComm::ServerManager::Instance() #endif // BattlenetMgr_h__ diff --git a/src/server/game/Server/Packets/PartyPackets.cpp b/src/server/game/Server/Packets/PartyPackets.cpp index 332aa959a1e..def6669968d 100644 --- a/src/server/game/Server/Packets/PartyPackets.cpp +++ b/src/server/game/Server/Packets/PartyPackets.cpp @@ -103,7 +103,7 @@ void WorldPackets::Party::PartyInvite::Initialize(Player* const inviter, int32 p ProposedRoles = proposedRoles; - std::string realmName = sObjectMgr->GetRealmName(realmHandle.Index); + std::string realmName = sObjectMgr->GetRealmName(realm.Id.Realm); InviterVirtualRealmAddress = GetVirtualRealmAddress(); InviterRealmNameActual = realmName; diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 550dfa69d5e..1874403eb19 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -1105,9 +1105,9 @@ void WorldSession::LoadPermissions() uint8 secLevel = GetSecurity(); TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d, secLevel: %u]", - id, _accountName.c_str(), realmHandle.Index, secLevel); + id, _accountName.c_str(), realm.Id.Realm, secLevel); - _RBACData = new rbac::RBACData(id, _accountName, realmHandle.Index, secLevel); + _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel); _RBACData->LoadFromDB(); } @@ -1117,9 +1117,9 @@ PreparedQueryResultFuture WorldSession::LoadPermissionsAsync() uint8 secLevel = GetSecurity(); TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d, secLevel: %u]", - id, _accountName.c_str(), realmHandle.Index, secLevel); + id, _accountName.c_str(), realm.Id.Realm, secLevel); - _RBACData = new rbac::RBACData(id, _accountName, realmHandle.Index, secLevel); + _RBACData = new rbac::RBACData(id, _accountName, realm.Id.Realm, secLevel); return _RBACData->LoadFromDBAsync(); } @@ -1248,7 +1248,7 @@ bool WorldSession::HasPermission(uint32 permission) bool hasPermission = _RBACData->HasPermission(permission); TC_LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: %u, Name: %s, realmId: %d]", - _RBACData->GetId(), _RBACData->GetName().c_str(), realmHandle.Index); + _RBACData->GetId(), _RBACData->GetName().c_str(), realm.Id.Realm); return hasPermission; } @@ -1256,7 +1256,7 @@ bool WorldSession::HasPermission(uint32 permission) void WorldSession::InvalidateRBACData() { TC_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: %u, Name: %s, realmId: %d]", - _RBACData->GetId(), _RBACData->GetName().c_str(), realmHandle.Index); + _RBACData->GetId(), _RBACData->GetName().c_str(), realm.Id.Realm); delete _RBACData; _RBACData = NULL; } diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 6407b29924a..7f9b398e50d 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -593,7 +593,7 @@ void WorldSocket::HandleAuthSession(std::shared_ptr<WorldPackets::Auth::AuthSess // Get the account information from the auth database PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME); - stmt->setInt32(0, int32(realmHandle.Index)); + stmt->setInt32(0, int32(realm.Id.Realm)); stmt->setString(1, authSession->Account); { @@ -639,7 +639,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth:: return; } - if (authSession->RealmID != realmHandle.Index) + if (authSession->RealmID != realm.Id.Realm) { SendAuthResponseError(REALM_LIST_REALM_NOT_FOUND); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (bad realm)."); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 6e4a3b39e18..fefd49f1d92 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1457,7 +1457,7 @@ void World::SetInitialWorldSettings() uint32 server_type = IsFFAPvPRealm() ? uint32(REALM_TYPE_PVP) : getIntConfig(CONFIG_GAME_TYPE); uint32 realm_zone = getIntConfig(CONFIG_REALM_ZONE); - LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmHandle.Index); // One-time query + LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realm.Id.Realm); // One-time query TC_LOG_INFO("server.loading", "Initialize data stores..."); ///- Load DBCs @@ -1918,7 +1918,7 @@ void World::SetInitialWorldSettings() m_startTime = m_gameTime; LoginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, uptime, revision) VALUES(%u, %u, 0, '%s')", - realmHandle.Index, uint32(m_startTime), GitRevision::GetFullVersion()); // One-time query + realm.Id.Realm, uint32(m_startTime), GitRevision::GetFullVersion()); // One-time query m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILLISECONDS); m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILLISECONDS); @@ -2202,7 +2202,7 @@ void World::Update(uint32 diff) stmt->setUInt32(0, tmpDiff); stmt->setUInt16(1, uint16(maxOnlinePlayers)); - stmt->setUInt32(2, realmHandle.Index); + stmt->setUInt32(2, realm.Id.Realm); stmt->setUInt32(3, uint32(m_startTime)); LoginDatabase.Execute(stmt); @@ -2922,13 +2922,13 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount) PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM); stmt->setUInt32(0, accountId); - stmt->setUInt32(1, realmHandle.Index); + stmt->setUInt32(1, realm.Id.Realm); LoginDatabase.Execute(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS); stmt->setUInt8(0, charCount); stmt->setUInt32(1, accountId); - stmt->setUInt32(2, realmHandle.Index); + stmt->setUInt32(2, realm.Id.Realm); LoginDatabase.Execute(stmt); } } @@ -3102,7 +3102,7 @@ void World::ResetCurrencyWeekCap() void World::LoadDBAllowedSecurityLevel() { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL); - stmt->setInt32(0, int32(realmHandle.Index)); + stmt->setInt32(0, int32(realm.Id.Realm)); PreparedQueryResult result = LoginDatabase.Query(stmt); if (result) @@ -3451,5 +3451,5 @@ void World::RemoveOldCorpses() uint32 GetVirtualRealmAddress() { - return uint32(realmHandle.Region) << 24 | uint32(realmHandle.Battlegroup) << 16 | realmHandle.Index; + return uint32(realm.Id.Region) << 24 | uint32(realm.Id.Site) << 16 | realm.Id.Realm; } diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 7f32e1a4fd4..97e498169d3 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -24,7 +24,7 @@ #define __WORLD_H #include "Common.h" -#include "Commands.h" +#include "Realm/Realm.h" #include "ObjectGuid.h" #include "Timer.h" #include "SharedDefines.h" @@ -455,18 +455,6 @@ enum BillingPlanFlags SESSION_ENABLE_CAIS = 0x80 }; -/// Type of server, this is values from second column of Cfg_Configs.dbc -enum RealmType -{ - REALM_TYPE_NORMAL = 0, - REALM_TYPE_PVP = 1, - REALM_TYPE_NORMAL2 = 4, - REALM_TYPE_RP = 6, - REALM_TYPE_RPPVP = 8, - REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries - // replaced by REALM_PVP in realm list -}; - enum RealmZone { REALM_ZONE_UNKNOWN = 0, // any language @@ -903,7 +891,6 @@ class World std::deque<PreparedQueryResultFuture> m_realmCharCallbacks; }; -extern Battlenet::RealmHandle realmHandle; extern Realm realm; uint32 GetVirtualRealmAddress(); diff --git a/src/server/ipc/CMakeLists.txt b/src/server/ipc/CMakeLists.txt index e9f38f20c17..7f4541ab91b 100644 --- a/src/server/ipc/CMakeLists.txt +++ b/src/server/ipc/CMakeLists.txt @@ -19,7 +19,8 @@ set(ipc_SRCS include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/zmqpp - ${CMAKE_SOURCE_DIR}/src/common/ + ${CMAKE_SOURCE_DIR}/src/common + ${CMAKE_SOURCE_DIR}/src/server/shared ${ZMQ_INCLUDE_DIR} ) diff --git a/src/server/ipc/Commands.cpp b/src/server/ipc/Commands.cpp index e08943030f7..777bf3932ae 100644 --- a/src/server/ipc/Commands.cpp +++ b/src/server/ipc/Commands.cpp @@ -18,7 +18,7 @@ #include "Commands.h" #include <zmqpp/message.hpp> -zmqpp::message& operator>>(zmqpp::message& msg, IPCHeader& header) +zmqpp::message& operator>>(zmqpp::message& msg, IPC::Header& header) { msg >> header.Channel; msg >> header.Command; @@ -28,19 +28,19 @@ zmqpp::message& operator>>(zmqpp::message& msg, IPCHeader& header) zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::RealmHandle& realm) { msg >> realm.Region; - msg >> realm.Battlegroup; - msg >> realm.Index; + msg >> realm.Site; + msg >> realm.Realm; return msg; } -zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::Header& header) +zmqpp::message& operator>>(zmqpp::message& msg, IPC::BattlenetComm::Header& header) { msg >> header.Ipc; msg >> header.Realm; return msg; } -zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle) +zmqpp::message& operator>>(zmqpp::message& msg, IPC::BattlenetComm::ToonHandle& toonHandle) { msg >> toonHandle.AccountId; msg >> toonHandle.GameAccountId; @@ -49,7 +49,7 @@ zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::ToonHandle& toonHandl return msg; } -zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader const& header) +zmqpp::message& operator<<(zmqpp::message& msg, IPC::Header const& header) { msg << header.Channel; msg << header.Command; @@ -59,19 +59,19 @@ zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader const& header) zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle const& realm) { msg << realm.Region; - msg << realm.Battlegroup; - msg << realm.Index; + msg << realm.Site; + msg << realm.Realm; return msg; } -zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header const& header) +zmqpp::message& operator<<(zmqpp::message& msg, IPC::BattlenetComm::Header const& header) { msg << header.Ipc; msg << header.Realm; return msg; } -zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle const& toonHandle) +zmqpp::message& operator<<(zmqpp::message& msg, IPC::BattlenetComm::ToonHandle const& toonHandle) { msg << toonHandle.AccountId; msg << toonHandle.GameAccountId; diff --git a/src/server/ipc/Commands.h b/src/server/ipc/Commands.h index b594090b0f8..174b5b10795 100644 --- a/src/server/ipc/Commands.h +++ b/src/server/ipc/Commands.h @@ -19,6 +19,7 @@ #define _COMMANDS_H #include "Define.h" +#include "Realm/Realm.h" #include <string> enum Channels @@ -35,34 +36,30 @@ enum BnetCommands IPC_BNET_MAX_COMMAND }; -struct IPCHeader +namespace IPC { - uint8 Channel; - uint8 Command; -}; - -namespace Battlenet -{ - struct RealmHandle - { - uint8 Region; - uint8 Battlegroup; - uint32 Index; - }; - struct Header { - IPCHeader Ipc; - RealmHandle Realm; + uint8 Channel; + uint8 Command; }; - struct ToonHandle + namespace BattlenetComm { - uint32 AccountId; - uint32 GameAccountId; - uint64 Guid; - std::string Name; - }; + struct Header + { + IPC::Header Ipc; + Battlenet::RealmHandle Realm; + }; + + struct ToonHandle + { + uint32 AccountId; + uint32 GameAccountId; + uint64 Guid; + std::string Name; + }; + } } namespace zmqpp @@ -70,14 +67,14 @@ namespace zmqpp class message; } -zmqpp::message& operator>>(zmqpp::message& msg, IPCHeader& header); +zmqpp::message& operator>>(zmqpp::message& msg, IPC::Header& header); zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::RealmHandle& realm); -zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::Header& header); -zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle); +zmqpp::message& operator>>(zmqpp::message& msg, IPC::BattlenetComm::Header& header); +zmqpp::message& operator>>(zmqpp::message& msg, IPC::BattlenetComm::ToonHandle& toonHandle); -zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader const& header); +zmqpp::message& operator<<(zmqpp::message& msg, IPC::Header const& header); zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle const& realm); -zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header const& header); -zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle const& toonHandle); +zmqpp::message& operator<<(zmqpp::message& msg, IPC::BattlenetComm::Header const& header); +zmqpp::message& operator<<(zmqpp::message& msg, IPC::BattlenetComm::ToonHandle const& toonHandle); #endif // _COMMANDS_H diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index 8bf4eebd62e..14be108f878 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -163,7 +163,7 @@ public: ///- Get the accounts with GM Level >0 PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_GM_ACCOUNTS); stmt->setUInt8(0, uint8(SEC_MODERATOR)); - stmt->setInt32(1, int32(realmHandle.Index)); + stmt->setInt32(1, int32(realm.Id.Realm)); PreparedQueryResult result = LoginDatabase.Query(stmt); if (result) diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 73fab358f38..7871b0e9ff0 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1602,7 +1602,7 @@ public: // Query the prepared statement for login data stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); - stmt->setInt32(0, int32(realmHandle.Index)); + stmt->setInt32(0, int32(realm.Id.Realm)); stmt->setUInt32(1, accId); PreparedQueryResult result = LoginDatabase.Query(stmt); diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp index 93593870975..9a7848ce171 100644 --- a/src/server/scripts/Commands/cs_rbac.cpp +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -160,7 +160,7 @@ public: if (!rdata) { - data->rbac = new rbac::RBACData(accountId, accountName, realmHandle.Index, AccountMgr::GetSecurity(accountId, realmHandle.Index)); + data->rbac = new rbac::RBACData(accountId, accountName, realm.Id.Realm, AccountMgr::GetSecurity(accountId, realm.Id.Realm)); data->rbac->LoadFromDB(); data->needDelete = true; } diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp index 7591cbf1712..db24295bb21 100644 --- a/src/server/scripts/Commands/cs_ticket.cpp +++ b/src/server/scripts/Commands/cs_ticket.cpp @@ -125,7 +125,7 @@ bool ticket_commandscript::HandleTicketAssignToCommand(ChatHandler* handler, cha ObjectGuid targetGuid = ObjectMgr::GetPlayerGUIDByName(target); uint32 accountId = ObjectMgr::GetPlayerAccountIdByGUID(targetGuid); // Target must exist and have administrative rights - if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmHandle.Index)) + if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realm.Id.Realm)) { handler->SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A); return true; @@ -324,7 +324,7 @@ bool ticket_commandscript::HandleTicketUnAssignCommand(ChatHandler* handler, cha { ObjectGuid guid = ticket->GetAssignedToGUID(); uint32 accountId = ObjectMgr::GetPlayerAccountIdByGUID(guid); - security = AccountMgr::GetSecurity(accountId, realmHandle.Index); + security = AccountMgr::GetSecurity(accountId, realm.Id.Realm); } // Check security diff --git a/src/server/shared/Realm/Realm.cpp b/src/server/shared/Realm/Realm.cpp index 156a0739d02..fbf2c274e23 100644 --- a/src/server/shared/Realm/Realm.cpp +++ b/src/server/shared/Realm/Realm.cpp @@ -51,3 +51,13 @@ ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) cons // Return external IP return endpoint; } + +uint32 Realm::GetConfigId() const +{ + return ConfigIdByType[Type]; +} + +uint32 const Realm::ConfigIdByType[MAX_CLIENT_REALM_TYPE] = +{ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 +}; diff --git a/src/server/shared/Realm/Realm.h b/src/server/shared/Realm/Realm.h index 8e3b3c41576..f8d7321d3df 100644 --- a/src/server/shared/Realm/Realm.h +++ b/src/server/shared/Realm/Realm.h @@ -26,47 +26,62 @@ using namespace boost::asio; enum RealmFlags { - REALM_FLAG_NONE = 0x00, - REALM_FLAG_INVALID = 0x01, - REALM_FLAG_OFFLINE = 0x02, - REALM_FLAG_SPECIFYBUILD = 0x04, - REALM_FLAG_UNK1 = 0x08, - REALM_FLAG_UNK2 = 0x10, - REALM_FLAG_RECOMMENDED = 0x20, - REALM_FLAG_NEW = 0x40, - REALM_FLAG_FULL = 0x80 + REALM_FLAG_NONE = 0x00, + REALM_FLAG_VERSION_MISMATCH = 0x01, + REALM_FLAG_OFFLINE = 0x02, + REALM_FLAG_SPECIFYBUILD = 0x04, + REALM_FLAG_UNK1 = 0x08, + REALM_FLAG_UNK2 = 0x10, + REALM_FLAG_RECOMMENDED = 0x20, + REALM_FLAG_NEW = 0x40, + REALM_FLAG_FULL = 0x80 }; #pragma pack(push, 1) namespace Battlenet { - struct RealmHandle; - - struct RealmId + struct RealmHandle { - RealmId() : Region(0), Battlegroup(0), Index(0), Build(0) { } - RealmId(uint8 region, uint8 battlegroup, uint32 index, uint32 build) - : Region(region), Battlegroup(battlegroup), Index(index), Build(build) { } + RealmHandle() : Region(0), Site(0), Realm(0) { } + RealmHandle(uint8 region, uint8 battlegroup, uint32 index) + : Region(region), Site(battlegroup), Realm(index) { } uint8 Region; - uint8 Battlegroup; - uint32 Index; - uint32 Build; + uint8 Site; + uint32 Realm; // primary key in `realmlist` table - bool operator<(RealmId const& r) const + bool operator<(RealmHandle const& r) const { - return memcmp(this, &r, sizeof(RealmId) - sizeof(Build)) < 0; + return Realm < r.Realm; } + + uint32 GetAddress() const { return ((Site << 16) & 0xFF0000) | uint16(Realm); } }; } #pragma pack(pop) +/// Type of server, this is values from second column of Cfg_Configs.dbc +enum RealmType +{ + REALM_TYPE_NORMAL = 0, + REALM_TYPE_PVP = 1, + REALM_TYPE_NORMAL2 = 4, + REALM_TYPE_RP = 6, + REALM_TYPE_RPPVP = 8, + + MAX_CLIENT_REALM_TYPE = 14, + + REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries + // replaced by REALM_PVP in realm list +}; + // Storage object for a realm struct Realm { - Battlenet::RealmId Id; + Battlenet::RealmHandle Id; + uint32 Build; ip::address ExternalAddress; ip::address LocalAddress; ip::address LocalSubnetMask; @@ -81,6 +96,9 @@ struct Realm bool Keep; ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const; + uint32 GetConfigId() const; + + static uint32 const ConfigIdByType[MAX_CLIENT_REALM_TYPE]; }; #endif // Realm_h__ diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 9c3c984b9b3..db4e2696bd7 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -84,7 +84,6 @@ WorldDatabaseWorkerPool WorldDatabase; ///< Accessor to the CharacterDatabaseWorkerPool CharacterDatabase; ///< Accessor to the character database HotfixDatabaseWorkerPool HotfixDatabase; ///< Accessor to the hotfix database LoginDatabaseWorkerPool LoginDatabase; ///< Accessor to the realm/login database -Battlenet::RealmHandle realmHandle; ///< Id of the realm Realm realm; void SignalHandler(const boost::system::error_code& error, int signalNumber); @@ -193,7 +192,7 @@ extern int main(int argc, char** argv) } // Set server offline (not connectable) - LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmHandle.Index); + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realm.Id.Realm); LoadRealmInfo(); @@ -230,9 +229,9 @@ extern int main(int argc, char** argv) sWorldSocketMgr.StartNetwork(_ioService, worldListener, worldPort); // Set server online (allow connecting now) - LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmHandle.Index); + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_OFFLINE, realm.Id.Realm); realm.PopulationLevel = 0.0f; - realm.Flags = RealmFlags(realm.Flags & ~uint32(REALM_FLAG_INVALID)); + realm.Flags = RealmFlags(realm.Flags & ~uint32(REALM_FLAG_OFFLINE)); // Start the freeze check callback cycle in 5 seconds (cycle itself is 1 sec) if (int coreStuckTime = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0)) @@ -276,7 +275,7 @@ extern int main(int argc, char** argv) sScriptMgr->Unload(); // set server offline - LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmHandle.Index); + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realm.Id.Realm); // Clean up threads if any if (soapThread != nullptr) @@ -463,7 +462,7 @@ bool LoadRealmInfo() boost::asio::ip::tcp::resolver resolver(_ioService); boost::asio::ip::tcp::resolver::iterator end; - QueryResult result = LoginDatabase.PQuery("SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE id = %u", realmHandle.Index); + QueryResult result = LoginDatabase.PQuery("SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE id = %u", realm.Id.Realm); if (!result) return false; @@ -507,10 +506,9 @@ bool LoadRealmInfo() realm.Timezone = fields[8].GetUInt8(); realm.AllowedSecurityLevel = AccountTypes(fields[9].GetUInt8()); realm.PopulationLevel = fields[10].GetFloat(); - realm.Id.Index = fields[0].GetUInt32(); - realm.Id.Build = fields[11].GetUInt32(); realm.Id.Region = fields[12].GetUInt8(); - realm.Id.Battlegroup = fields[13].GetUInt8(); + realm.Id.Site = fields[13].GetUInt8(); + realm.Build = fields[11].GetUInt32(); return true; } @@ -531,25 +529,14 @@ bool StartDB() return false; ///- Get the realm Id from the configuration file - realmHandle.Index = sConfigMgr->GetIntDefault("RealmID", 0); - if (!realmHandle.Index) + realm.Id.Realm = sConfigMgr->GetIntDefault("RealmID", 0); + if (!realm.Id.Realm) { TC_LOG_ERROR("server.worldserver", "Realm ID not defined in configuration file"); return false; } - // Realm Handles - QueryResult realmIdQuery = LoginDatabase.PQuery("SELECT `Region`,`Battlegroup` FROM `realmlist` WHERE `id`=%u", realmHandle.Index); - if (!realmIdQuery) - { - TC_LOG_ERROR("server.worldserver", "Realm id %u not defined in realmlist table", realmHandle.Index); - return false; - } - - realmHandle.Region = (*realmIdQuery)[0].GetUInt8(); - realmHandle.Battlegroup = (*realmIdQuery)[1].GetUInt8(); - - TC_LOG_INFO("server.worldserver", "Realm running as realm ID %u region %u battlegroup %u", realmHandle.Index, uint32(realmHandle.Region), uint32(realmHandle.Battlegroup)); + TC_LOG_INFO("server.worldserver", "Realm running as realm ID %u", realm.Id.Realm); ///- Clean the database before starting ClearOnlineAccounts(); @@ -576,7 +563,7 @@ void StopDB() void ClearOnlineAccounts() { // Reset online status for all accounts with characters on the current realm - LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmHandle.Index); + LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realm.Id.Realm); // Reset online status for all characters CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0"); |