diff options
| author | Shauren <shauren.trinity@gmail.com> | 2016-03-28 17:12:57 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2016-03-28 17:12:57 +0200 |
| commit | dde620c402daf4ea8d132fb72a77eabc22f7a6d0 (patch) | |
| tree | 7c12161d7a22915736b0c9a106de896eeb283399 /src/server/game/Services | |
| parent | 619669c6209441fc2fb5b483d553badee8c30ad5 (diff) | |
Core: Updated to 6.2.4
* Rewrite bnetserver for new authentication protocol
Diffstat (limited to 'src/server/game/Services')
| -rw-r--r-- | src/server/game/Services/WorldserverService.cpp | 116 | ||||
| -rw-r--r-- | src/server/game/Services/WorldserverService.h | 71 | ||||
| -rw-r--r-- | src/server/game/Services/WorldserverServiceDispatcher.cpp | 49 | ||||
| -rw-r--r-- | src/server/game/Services/WorldserverServiceDispatcher.h | 67 |
4 files changed, 303 insertions, 0 deletions
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 <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 "WorldserverService.h" +#include "Log.h" +#include "RealmList.h" +#include "RealmList.pb.h" +#include "BattlenetRpcErrorCodes.h" +#include "ProtobufJSON.h" +#include <zlib.h> + +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<std::string, Variant const*> 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<std::string, Variant const*> 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<uint8> 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<uint32*>(compressed.data()) = json.length() + 1; + + if (compress(compressed.data() + 4, &compressedLength, reinterpret_cast<uint8 const*>(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<std::string, Variant const*> 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 <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 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 T> + 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<void(MessageBuffer)> 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<game_utilities::v1::GameUtilitiesService> + { + typedef WorldserverService<game_utilities::v1::GameUtilitiesService> 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<std::string, Variant const*> params, game_utilities::v1::ClientResponse* response); + uint32 HandleRealmJoinRequest(std::unordered_map<std::string, Variant const*> 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 <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 "WorldserverServiceDispatcher.h" +#include "WorldserverService.h" + +Battlenet::WorldserverServiceDispatcher::WorldserverServiceDispatcher() +{ + AddService<WorldserverService<account::v1::AccountService>>(); + AddService<WorldserverService<authentication::v1::AuthenticationService>>(); + AddService<WorldserverService<challenge::v1::ChallengeService>>(); + AddService<WorldserverService<channel::v1::ChannelService>>(); + AddService<WorldserverService<connection::v1::ConnectionService>>(); + AddService<WorldserverService<friends::v1::FriendsService>>(); + AddService<GameUtilitiesService>(); + AddService<WorldserverService<presence::v1::PresenceService>>(); + AddService<WorldserverService<report::v1::ReportService>>(); + AddService<WorldserverService<resources::v1::ResourcesService>>(); + AddService<WorldserverService<user_manager::v1::UserManagerService>>(); +} + +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<MessageBuffer>(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 <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 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<class Service> + void AddService() + { + _dispatchers[Service::NameHash::value] = &WorldserverServiceDispatcher::Dispatch<Service>; + } + + template<class Service> + static void Dispatch(WorldSession* session, uint32 token, uint32 methodId, MessageBuffer buffer) + { + Service(session).CallServerMethod(token, methodId, std::forward<MessageBuffer>(buffer)); + } + + std::unordered_map<uint32, std::function<void(WorldSession*, uint32, uint32, MessageBuffer)>> _dispatchers; + }; +} + +#define sServiceDispatcher Battlenet::WorldserverServiceDispatcher::Instance() + +#endif // ServiceRegistry_h__ |
