From dde620c402daf4ea8d132fb72a77eabc22f7a6d0 Mon Sep 17 00:00:00 2001 From: Shauren Date: Mon, 28 Mar 2016 17:12:57 +0200 Subject: Core: Updated to 6.2.4 * Rewrite bnetserver for new authentication protocol --- src/server/game/Services/WorldserverService.cpp | 116 +++++++++++++++++++++ src/server/game/Services/WorldserverService.h | 71 +++++++++++++ .../game/Services/WorldserverServiceDispatcher.cpp | 49 +++++++++ .../game/Services/WorldserverServiceDispatcher.h | 67 ++++++++++++ 4 files changed, 303 insertions(+) create mode 100644 src/server/game/Services/WorldserverService.cpp create mode 100644 src/server/game/Services/WorldserverService.h create mode 100644 src/server/game/Services/WorldserverServiceDispatcher.cpp create mode 100644 src/server/game/Services/WorldserverServiceDispatcher.h (limited to 'src/server/game/Services') diff --git a/src/server/game/Services/WorldserverService.cpp b/src/server/game/Services/WorldserverService.cpp new file mode 100644 index 00000000000..9859d7cfaa4 --- /dev/null +++ b/src/server/game/Services/WorldserverService.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2008-2016 TrinityCore + * + * 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 . + */ + +#include "WorldserverService.h" +#include "Log.h" +#include "RealmList.h" +#include "RealmList.pb.h" +#include "BattlenetRpcErrorCodes.h" +#include "ProtobufJSON.h" +#include + +Battlenet::GameUtilitiesService::GameUtilitiesService(WorldSession* session) : BaseService(session) +{ +} + +uint32 Battlenet::GameUtilitiesService::HandleProcessClientRequest(game_utilities::v1::ClientRequest const* request, game_utilities::v1::ClientResponse* response) +{ + Attribute const* command = nullptr; + std::unordered_map params; + + for (int32 i = 0; i < request->attribute_size(); ++i) + { + Attribute const& attr = request->attribute(i); + params[attr.name()] = &attr.value(); + if (strstr(attr.name().c_str(), "Command_") == attr.name().c_str()) + command = &attr; + } + + if (!command) + { + TC_LOG_ERROR("session.rpc", "%s sent ClientRequest with no command.", GetCallerInfo().c_str()); + return ERROR_RPC_MALFORMED_REQUEST; + } + + if (command->name() == "Command_RealmListRequest_v1_b9") + return HandleRealmListRequest(params, response); + else if (command->name() == "Command_RealmJoinRequest_v1_b9") + return HandleRealmJoinRequest(params, response); + + return ERROR_RPC_NOT_IMPLEMENTED; +} + +uint32 Battlenet::GameUtilitiesService::HandleRealmListRequest(std::unordered_map params, game_utilities::v1::ClientResponse* response) +{ + std::string subRegionId; + auto subRegion = params.find("Command_RealmListRequest_v1_b9"); + if (subRegion != params.end()) + subRegionId = subRegion->second->string_value(); + + std::vector compressed = sRealmList->GetRealmList(realm.Build, subRegionId); + + if (compressed.empty()) + return ERROR_UTIL_SERVER_FAILED_TO_SERIALIZE_RESPONSE; + + Attribute* attribute = response->add_attribute(); + attribute->set_name("Param_RealmList"); + attribute->mutable_value()->set_blob_value(compressed.data(), compressed.size()); + + JSON::RealmList::RealmCharacterCountList realmCharacterCounts; + for (auto const& characterCount : _session->GetRealmCharacterCounts()) + { + ::JSON::RealmList::RealmCharacterCountEntry* countEntry = realmCharacterCounts.add_counts(); + countEntry->set_wowrealmaddress(characterCount.first); + countEntry->set_count(characterCount.second); + } + + std::string json = "JSONRealmCharacterCountList:" + JSON::Serialize(realmCharacterCounts); + + uLongf compressedLength = compressBound(json.length()); + compressed.resize(4 + compressedLength); + *reinterpret_cast(compressed.data()) = json.length() + 1; + + if (compress(compressed.data() + 4, &compressedLength, reinterpret_cast(json.c_str()), json.length() + 1) != Z_OK) + return ERROR_UTIL_SERVER_FAILED_TO_SERIALIZE_RESPONSE; + + attribute = response->add_attribute(); + attribute->set_name("Param_CharacterCountList"); + attribute->mutable_value()->set_blob_value(compressed.data(), compressedLength + 4); + + return ERROR_OK; +} + +uint32 Battlenet::GameUtilitiesService::HandleRealmJoinRequest(std::unordered_map params, game_utilities::v1::ClientResponse* response) +{ + auto realmAddress = params.find("Param_RealmAddress"); + if (realmAddress != params.end()) + return sRealmList->JoinRealm(realmAddress->second->uint_value(), realm.Build, boost::asio::ip::address::from_string(_session->GetRemoteAddress()), _session->GetRealmListSecret(), + _session->GetSessionDbcLocale(), _session->GetOS(), _session->GetAccountName(), response); + + return ERROR_WOW_SERVICES_INVALID_JOIN_TICKET; +} + +uint32 Battlenet::GameUtilitiesService::HandleGetAllValuesForAttribute(game_utilities::v1::GetAllValuesForAttributeRequest const* request, game_utilities::v1::GetAllValuesForAttributeResponse* response) +{ + if (request->attribute_key() == "Command_RealmListRequest_v1_b9") + { + sRealmList->WriteSubRegions(response); + return ERROR_OK; + } + + return ERROR_RPC_NOT_IMPLEMENTED; +} diff --git a/src/server/game/Services/WorldserverService.h b/src/server/game/Services/WorldserverService.h new file mode 100644 index 00000000000..768fb164c13 --- /dev/null +++ b/src/server/game/Services/WorldserverService.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008-2016 TrinityCore + * + * 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 . + */ + +#ifndef WorldserverService_h__ +#define WorldserverService_h__ + +#include "WorldSession.h" +#include "account_service.pb.h" +#include "authentication_service.pb.h" +#include "challenge_service.pb.h" +#include "channel_service.pb.h" +#include "connection_service.pb.h" +#include "friends_service.pb.h" +#include "game_utilities_service.pb.h" +#include "presence_service.pb.h" +#include "report_service.pb.h" +#include "resource_service.pb.h" +#include "user_manager_service.pb.h" + +namespace bgs { namespace protocol { } } +using namespace bgs::protocol; + +namespace Battlenet +{ + template + class WorldserverService : public T + { + public: + WorldserverService(WorldSession* session) : T(false), _session(session) { } + + protected: + void SendRequest(uint32 serviceHash, uint32 methodId, google::protobuf::Message const* request, std::function callback) override { _session->SendBattlenetRequest(serviceHash, methodId, request, std::move(callback)); } + void SendRequest(uint32 serviceHash, uint32 methodId, google::protobuf::Message const* request) override { _session->SendBattlenetRequest(serviceHash, methodId, request); } + void SendResponse(uint32 serviceHash, uint32 methodId, uint32 token, uint32 status) { _session->SendBattlenetResponse(serviceHash, methodId, token, status); } + void SendResponse(uint32 serviceHash, uint32 methodId, uint32 token, google::protobuf::Message const* response) override { _session->SendBattlenetResponse(serviceHash, methodId, token, response); } + std::string GetCallerInfo() const override { return _session->GetPlayerInfo(); } + + WorldSession* _session; + }; + + class GameUtilitiesService : public WorldserverService + { + typedef WorldserverService BaseService; + + public: + GameUtilitiesService(WorldSession* session); + + uint32 HandleProcessClientRequest(game_utilities::v1::ClientRequest const* request, game_utilities::v1::ClientResponse* response) override; + uint32 HandleGetAllValuesForAttribute(game_utilities::v1::GetAllValuesForAttributeRequest const* request, game_utilities::v1::GetAllValuesForAttributeResponse* response) override; + + private: + uint32 HandleRealmListRequest(std::unordered_map params, game_utilities::v1::ClientResponse* response); + uint32 HandleRealmJoinRequest(std::unordered_map params, game_utilities::v1::ClientResponse* response); + }; +} + +#endif // WorldserverService_h__ diff --git a/src/server/game/Services/WorldserverServiceDispatcher.cpp b/src/server/game/Services/WorldserverServiceDispatcher.cpp new file mode 100644 index 00000000000..402a4386786 --- /dev/null +++ b/src/server/game/Services/WorldserverServiceDispatcher.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008-2016 TrinityCore + * + * 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 . + */ + +#include "WorldserverServiceDispatcher.h" +#include "WorldserverService.h" + +Battlenet::WorldserverServiceDispatcher::WorldserverServiceDispatcher() +{ + AddService>(); + AddService>(); + AddService>(); + AddService>(); + AddService>(); + AddService>(); + AddService(); + AddService>(); + AddService>(); + AddService>(); + AddService>(); +} + +void Battlenet::WorldserverServiceDispatcher::Dispatch(WorldSession* session, uint32 serviceHash, uint32 token, uint32 methodId, MessageBuffer buffer) +{ + auto itr = _dispatchers.find(serviceHash); + if (itr != _dispatchers.end()) + itr->second(session, token, methodId, std::forward(buffer)); + else + TC_LOG_DEBUG("session.rpc", "%s tried to call invalid service 0x%X", session->GetPlayerInfo().c_str(), serviceHash); +} + +Battlenet::WorldserverServiceDispatcher& Battlenet::WorldserverServiceDispatcher::Instance() +{ + static WorldserverServiceDispatcher instance; + return instance; +} diff --git a/src/server/game/Services/WorldserverServiceDispatcher.h b/src/server/game/Services/WorldserverServiceDispatcher.h new file mode 100644 index 00000000000..c2e9c9fb131 --- /dev/null +++ b/src/server/game/Services/WorldserverServiceDispatcher.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2008-2016 TrinityCore + * + * 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 . + */ + +#ifndef ServiceRegistry_h__ +#define ServiceRegistry_h__ + +#include "WorldSession.h" +#include "MessageBuffer.h" +#include "Log.h" +#include "Common.h" +#include "account_service.pb.h" +#include "authentication_service.pb.h" +#include "challenge_service.pb.h" +#include "channel_service.pb.h" +#include "connection_service.pb.h" +#include "friends_service.pb.h" +#include "game_utilities_service.pb.h" +#include "presence_service.pb.h" +#include "report_service.pb.h" +#include "resource_service.pb.h" +#include "user_manager_service.pb.h" + +namespace Battlenet +{ + class WorldserverServiceDispatcher + { + public: + void Dispatch(WorldSession* session, uint32 serviceHash, uint32 token, uint32 methodId, MessageBuffer buffer); + + static WorldserverServiceDispatcher& Instance(); + + private: + WorldserverServiceDispatcher(); + + template + void AddService() + { + _dispatchers[Service::NameHash::value] = &WorldserverServiceDispatcher::Dispatch; + } + + template + static void Dispatch(WorldSession* session, uint32 token, uint32 methodId, MessageBuffer buffer) + { + Service(session).CallServerMethod(token, methodId, std::forward(buffer)); + } + + std::unordered_map> _dispatchers; + }; +} + +#define sServiceDispatcher Battlenet::WorldserverServiceDispatcher::Instance() + +#endif // ServiceRegistry_h__ -- cgit v1.2.3