aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Services
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2016-03-28 17:12:57 +0200
committerShauren <shauren.trinity@gmail.com>2016-03-28 17:12:57 +0200
commitdde620c402daf4ea8d132fb72a77eabc22f7a6d0 (patch)
tree7c12161d7a22915736b0c9a106de896eeb283399 /src/server/game/Services
parent619669c6209441fc2fb5b483d553badee8c30ad5 (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.cpp116
-rw-r--r--src/server/game/Services/WorldserverService.h71
-rw-r--r--src/server/game/Services/WorldserverServiceDispatcher.cpp49
-rw-r--r--src/server/game/Services/WorldserverServiceDispatcher.h67
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__