aboutsummaryrefslogtreecommitdiff
path: root/src/server/bnetserver
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/bnetserver
parent619669c6209441fc2fb5b483d553badee8c30ad5 (diff)
Core: Updated to 6.2.4
* Rewrite bnetserver for new authentication protocol
Diffstat (limited to 'src/server/bnetserver')
-rw-r--r--src/server/bnetserver/Authentication/AuthCodes.cpp59
-rw-r--r--src/server/bnetserver/Authentication/AuthCodes.h162
-rw-r--r--src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp42
-rw-r--r--src/server/bnetserver/CMakeLists.txt24
-rw-r--r--src/server/bnetserver/Main.cpp43
-rw-r--r--src/server/bnetserver/Packets/AuthenticationPackets.cpp428
-rw-r--r--src/server/bnetserver/Packets/AuthenticationPackets.h267
-rw-r--r--src/server/bnetserver/Packets/BitStream.h258
-rw-r--r--src/server/bnetserver/Packets/CachePackets.cpp111
-rw-r--r--src/server/bnetserver/Packets/CachePackets.h110
-rw-r--r--src/server/bnetserver/Packets/ChatPackets.h71
-rw-r--r--src/server/bnetserver/Packets/ConnectionPackets.cpp123
-rw-r--r--src/server/bnetserver/Packets/ConnectionPackets.h157
-rw-r--r--src/server/bnetserver/Packets/FriendsPackets.cpp71
-rw-r--r--src/server/bnetserver/Packets/FriendsPackets.h90
-rw-r--r--src/server/bnetserver/Packets/PacketManager.cpp263
-rw-r--r--src/server/bnetserver/Packets/PacketManager.h105
-rw-r--r--src/server/bnetserver/Packets/Packets.h32
-rw-r--r--src/server/bnetserver/Packets/PacketsBase.h119
-rw-r--r--src/server/bnetserver/Packets/PacketsCommon.cpp111
-rw-r--r--src/server/bnetserver/Packets/PacketsCommon.h182
-rw-r--r--src/server/bnetserver/Packets/ProfilePackets.h44
-rw-r--r--src/server/bnetserver/Packets/WoWRealmPackets.cpp260
-rw-r--r--src/server/bnetserver/Packets/WoWRealmPackets.h238
-rw-r--r--src/server/bnetserver/PrecompiledHeaders/bnetPCH.h13
-rw-r--r--src/server/bnetserver/REST/LoginRESTService.cpp433
-rw-r--r--src/server/bnetserver/REST/LoginRESTService.h108
-rw-r--r--src/server/bnetserver/Server/ComponentManager.cpp55
-rw-r--r--src/server/bnetserver/Server/ComponentManager.h55
-rw-r--r--src/server/bnetserver/Server/ModuleManager.cpp66
-rw-r--r--src/server/bnetserver/Server/ModuleManager.h91
-rw-r--r--src/server/bnetserver/Server/Session.cpp1309
-rw-r--r--src/server/bnetserver/Server/Session.h241
-rw-r--r--src/server/bnetserver/Server/SessionManager.cpp39
-rw-r--r--src/server/bnetserver/Server/SessionManager.h47
-rw-r--r--src/server/bnetserver/Server/SslContext.cpp45
-rw-r--r--src/server/bnetserver/Server/SslContext.h (renamed from src/server/bnetserver/Packets/BitStream.cpp)22
-rw-r--r--src/server/bnetserver/Services/AccountService.cpp (renamed from src/server/bnetserver/Packets/SupportPackets.h)24
-rw-r--r--src/server/bnetserver/Services/AccountService.h (renamed from src/server/bnetserver/Packets/AchievementPackets.h)30
-rw-r--r--src/server/bnetserver/Services/AuthenticationService.cpp (renamed from src/server/bnetserver/Packets/PresencePackets.h)28
-rw-r--r--src/server/bnetserver/Services/AuthenticationService.h (renamed from src/server/bnetserver/Authentication/BattlenetPacketCrypt.h)28
-rw-r--r--src/server/bnetserver/Services/ConnectionService.cpp57
-rw-r--r--src/server/bnetserver/Services/ConnectionService.h46
-rw-r--r--src/server/bnetserver/Services/GameUtilitiesService.cpp (renamed from src/server/bnetserver/Packets/PacketsBase.cpp)25
-rw-r--r--src/server/bnetserver/Services/GameUtilitiesService.h44
-rw-r--r--src/server/bnetserver/Services/Service.h45
-rw-r--r--src/server/bnetserver/Services/ServiceDispatcher.cpp48
-rw-r--r--src/server/bnetserver/Services/ServiceDispatcher.h68
-rw-r--r--src/server/bnetserver/bnetserver.cert.pem100
-rw-r--r--src/server/bnetserver/bnetserver.conf.dist16
-rw-r--r--src/server/bnetserver/bnetserver.key.pem27
51 files changed, 1695 insertions, 4785 deletions
diff --git a/src/server/bnetserver/Authentication/AuthCodes.cpp b/src/server/bnetserver/Authentication/AuthCodes.cpp
deleted file mode 100644
index 41e2aad35ef..00000000000
--- a/src/server/bnetserver/Authentication/AuthCodes.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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 "AuthCodes.h"
-#include "Define.h"
-#include <vector>
-
-namespace AuthHelper
-{
- // List of client builds for verbose version info in realmlist packet
- static std::vector<RealmBuildInfo> const ClientBuilds =
- {
- { 20726, 6, 2, 3, ' ' },
- { 20574, 6, 2, 2, 'a' },
- { 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 (std::size_t i = 0; i < ClientBuilds.size(); ++i)
- if (ClientBuilds[i].Build == build)
- return &ClientBuilds[i];
-
- return nullptr;
- }
-
- bool IsBuildSupportingBattlenet(int build)
- {
- return build >= 15595;
- }
-}
diff --git a/src/server/bnetserver/Authentication/AuthCodes.h b/src/server/bnetserver/Authentication/AuthCodes.h
deleted file mode 100644
index dc545445e68..00000000000
--- a/src/server/bnetserver/Authentication/AuthCodes.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * 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 _AUTHCODES_H
-#define _AUTHCODES_H
-
-enum GameAccountFlags
-{
- GAMEACCOUNT_FLAG_GM = 0x00000001,
- GAMEACCOUNT_FLAG_NOKICK = 0x00000002,
- GAMEACCOUNT_FLAG_COLLECTOR = 0x00000004,
- GAMEACCOUNT_FLAG_WOW_TRIAL = 0x00000008,
- GAMEACCOUNT_FLAG_CANCELLED = 0x00000010,
- GAMEACCOUNT_FLAG_IGR = 0x00000020,
- GAMEACCOUNT_FLAG_WHOLESALER = 0x00000040,
- GAMEACCOUNT_FLAG_PRIVILEGED = 0x00000080,
- GAMEACCOUNT_FLAG_EU_FORBID_ELV = 0x00000100,
- GAMEACCOUNT_FLAG_EU_FORBID_BILLING = 0x00000200,
- GAMEACCOUNT_FLAG_WOW_RESTRICTED = 0x00000400,
- GAMEACCOUNT_FLAG_PARENTAL_CONTROL = 0x00000800,
- GAMEACCOUNT_FLAG_REFERRAL = 0x00001000,
- GAMEACCOUNT_FLAG_BLIZZARD = 0x00002000,
- GAMEACCOUNT_FLAG_RECURRING_BILLING = 0x00004000,
- GAMEACCOUNT_FLAG_NOELECTUP = 0x00008000,
- GAMEACCOUNT_FLAG_KR_CERTIFICATE = 0x00010000,
- GAMEACCOUNT_FLAG_EXPANSION_COLLECTOR = 0x00020000,
- GAMEACCOUNT_FLAG_DISABLE_VOICE = 0x00040000,
- GAMEACCOUNT_FLAG_DISABLE_VOICE_SPEAK = 0x00080000,
- GAMEACCOUNT_FLAG_REFERRAL_RESURRECT = 0x00100000,
- GAMEACCOUNT_FLAG_EU_FORBID_CC = 0x00200000,
- GAMEACCOUNT_FLAG_OPENBETA_DELL = 0x00400000,
- GAMEACCOUNT_FLAG_PROPASS = 0x00800000,
- GAMEACCOUNT_FLAG_PROPASS_LOCK = 0x01000000,
- GAMEACCOUNT_FLAG_PENDING_UPGRADE = 0x02000000,
- GAMEACCOUNT_FLAG_RETAIL_FROM_TRIAL = 0x04000000,
- GAMEACCOUNT_FLAG_EXPANSION2_COLLECTOR = 0x08000000,
- GAMEACCOUNT_FLAG_OVERMIND_LINKED = 0x10000000,
- GAMEACCOUNT_FLAG_DEMOS = 0x20000000,
- GAMEACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x40000000,
-};
-
-namespace Battlenet
-{
- enum AuthResult
- {
- AUTH_OK = 0,
- AUTH_INTERNAL_ERROR = 100,
- AUTH_CORRUPTED_MODULE = 101,
- AUTH_NO_BATTLETAGS = 102,
- AUTH_BAD_SERVER_PROOF = 103,
- AUTH_UNKNOWN_ACCOUNT = 104,
- AUTH_CLOSED = 105,
- AUTH_LOGIN_TIMEOUT = 106,
- AUTH_NO_GAME_ACCOUNTS = 107,
- AUTH_INVALID_TOKEN = 108,
- AUTH_INVALID_PROGRAM = 109,
- AUTH_INVALID_OS = 110,
- AUTH_UNSUPPORTED_LANGUAGE = 111,
- AUTH_REGION_BAD_VERSION = 112,
- AUTH_TEMP_OUTAGE = 113,
- AUTH_CANT_DOWNLOAD_MODULE = 114,
- AUTH_DUPLICATE_LOGON = 115,
- AUTH_BAD_CREDENTIALS_2 = 116,
- AUTH_VERSION_CHECK_SUCCEEDED = 117,
- AUTH_BAD_VERSION_HASH = 118,
- AUTH_CANT_RETRIEVE_PORTAL_LIST = 119,
- AUTH_DARK_PORTAL_DOES_NOT_EXIST = 120,
- AUTH_DARK_PORTAL_FILE_CORRUPTED = 121,
- AUTH_BATTLENET_MAINTENANCE = 122,
- AUTH_LOGON_TOO_FAST = 123,
- AUTH_USE_GRUNT_LOGON = 124,
- AUTH_NO_GAME_ACCOUNTS_IN_REGION = 140,
- AUTH_ACCOUNT_LOCKED = 141,
-
- LOGIN_SERVER_BUSY = 200,
- LOGIN_NO_GAME_ACCOUNT = 201,
- LOGIN_BANNED = 202,
- LOGIN_SUSPENDED = 203,
- LOGIN_GAME_ACCOUNT_LOCKED = 204,
- LOGIN_ALREADY_ONLINE = 205,
- LOGIN_NOTIME = 206,
- LOGIN_EXPIRED = 207,
- LOGIN_EXPIRED_2 = 208,
- LOGIN_PARENTALCONTROL = 209,
- LOGIN_TRIAL_EXPIRED = 210,
- LOGIN_ANTI_INDULGENCE = 211,
- LOGIN_INCORRECT_REGION = 212,
- LOGIN_LOCKED_ENFORCED = 213,
- LOGIN_CHARGEBACK = 214,
- LOGIN_IGR_WITHOUT_BNET = 215,
- LOGIN_UNLOCKABLE_LOCK = 216,
- LOGIN_IGR_REQUIRED = 217,
- LOGIN_PAYMENT_CHANGED = 218,
- 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
-{
- int Build;
- int MajorVersion;
- int MinorVersion;
- int BugfixVersion;
- int HotfixVersion;
-};
-
-namespace AuthHelper
-{
- RealmBuildInfo const* GetBuildInfo(int build);
- bool IsBuildSupportingBattlenet(int build);
-}
-
-#endif
diff --git a/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp
deleted file mode 100644
index c23a7931c67..00000000000
--- a/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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 "BattlenetPacketCrypt.h"
-#include "Cryptography/HmacHash.h"
-#include "Cryptography/BigNumber.h"
-
-Battlenet::PacketCrypt::PacketCrypt() : ::PacketCrypt(SHA256_DIGEST_LENGTH)
-{
-}
-
-void Battlenet::PacketCrypt::Init(BigNumber* K)
-{
- uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0x68, 0xE0, 0xC7, 0x2E, 0xDD, 0xD6, 0xD2, 0xF3, 0x1E, 0x5A, 0xB1, 0x55, 0xB1, 0x8B, 0x63, 0x1E };
- uint8 ClientDecryptionKey[SEED_KEY_SIZE] = { 0xDE, 0xA9, 0x65, 0xAE, 0x54, 0x3A, 0x1E, 0x93, 0x9E, 0x69, 0x0C, 0xAA, 0x68, 0xDE, 0x78, 0x39 };
-
- HmacSha256 serverEncryptHmac(K->GetNumBytes(), K->AsByteArray().get());
- serverEncryptHmac.UpdateData(ServerEncryptionKey, SEED_KEY_SIZE);
- serverEncryptHmac.Finalize();
-
- HmacSha256 clientDecryptHmac(K->GetNumBytes(), K->AsByteArray().get());
- clientDecryptHmac.UpdateData(ClientDecryptionKey, SEED_KEY_SIZE);
- clientDecryptHmac.Finalize();
-
- _clientDecrypt.Init(clientDecryptHmac.GetDigest());
- _serverEncrypt.Init(serverEncryptHmac.GetDigest());
- _initialized = true;
-}
diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt
index 7aa861499d9..c6e8808b69a 100644
--- a/src/server/bnetserver/CMakeLists.txt
+++ b/src/server/bnetserver/CMakeLists.txt
@@ -16,9 +16,9 @@ CollectSourceFiles(
# Exclude
${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders)
-if( WIN32 )
+if (WIN32)
list(APPEND PRIVATE_SOURCES ${sources_windows})
- if ( MSVC )
+ if (MSVC)
list(APPEND PRIVATE_SOURCES bnetserver.rc)
endif()
endif()
@@ -35,7 +35,7 @@ add_executable(bnetserver
${PRIVATE_PCH_SOURCE}
)
-if( NOT WIN32 )
+if (NOT WIN32)
set_target_properties(bnetserver PROPERTIES
COMPILE_DEFINITIONS _TRINITY_BNET_CONFIG="${CONF_DIR}/bnetserver.conf"
)
@@ -62,26 +62,32 @@ set_target_properties(bnetserver
FOLDER
"server")
-if( WIN32 )
- if ( MSVC )
+if (WIN32)
+ if (MSVC)
add_custom_command(TARGET bnetserver
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.conf.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.cert.pem ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.key.pem ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
)
- elseif ( MINGW )
+ elseif (MINGW)
add_custom_command(TARGET bnetserver
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.conf.dist ${CMAKE_BINARY_DIR}/bin/
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.cert.pem ${CMAKE_BINARY_DIR}/bin/
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.key.pem ${CMAKE_BINARY_DIR}/bin/
)
endif()
endif()
-if( UNIX )
+if (UNIX)
install(TARGETS bnetserver DESTINATION bin)
- install(FILES bnetserver.conf.dist DESTINATION ${CONF_DIR})
-elseif( WIN32 )
+ install(FILES bnetserver.conf.dist DESTINATION ${CONF_DIR})
+ install(FILES bnetserver.cert.pem bnetserver.key.pem DESTINATION bin)
+elseif (WIN32)
install(TARGETS bnetserver DESTINATION "${CMAKE_INSTALL_PREFIX}")
install(FILES bnetserver.conf.dist DESTINATION "${CMAKE_INSTALL_PREFIX}")
+ install(FILES bnetserver.cert.pem bnetserver.key.pem DESTINATION "${CMAKE_INSTALL_PREFIX}")
endif()
# Generate precompiled header
diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp
index 65b8d6e772b..f95c7b90d07 100644
--- a/src/server/bnetserver/Main.cpp
+++ b/src/server/bnetserver/Main.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* 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
@@ -24,25 +23,17 @@
* authentication server
*/
-#include "ComponentManager.h"
-#include "ModuleManager.h"
#include "SessionManager.h"
-#include "Common.h"
-#include "Config.h"
-#include "DatabaseEnv.h"
-#include "Log.h"
#include "AppenderDB.h"
#include "ProcessPriority.h"
#include "RealmList.h"
#include "GitRevision.h"
-#include "Util.h"
+#include "SslContext.h"
#include "DatabaseLoader.h"
-#include <cstdlib>
+#include "LoginRESTService.h"
#include <iostream>
-#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/program_options.hpp>
-#include <openssl/opensslv.h>
-#include <openssl/crypto.h>
+#include <google/protobuf/stubs/common.h>
using boost::asio::ip::tcp;
using namespace boost::program_options;
@@ -92,6 +83,8 @@ int main(int argc, char** argv)
if (vm.count("help") || vm.count("version"))
return 0;
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
#if PLATFORM == PLATFORM_WINDOWS
if (configService.compare("install") == 0)
return WinServiceInstall() ? 0 : 1;
@@ -135,15 +128,18 @@ int main(int argc, char** argv)
}
}
+ if (!Battlenet::SslContext::Initialize())
+ {
+ TC_LOG_ERROR("server.bnetserver", "Failed to initialize SSL context");
+ return 1;
+ }
+
// Initialize the database connection
if (!StartDB())
return 1;
_ioService = new boost::asio::io_service();
- // Get the list of realms for the server
- sRealmList->Initialize(*_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 10));
-
// Start the listening port (acceptor) for auth connections
int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119);
if (bnport < 0 || bnport > 0xFFFF)
@@ -154,6 +150,17 @@ int main(int argc, char** argv)
return 1;
}
+ if (!sLoginService.Start(*_ioService))
+ {
+ StopDB();
+ delete _ioService;
+ TC_LOG_ERROR("server.bnetserver", "Failed to initialize login service");
+ return 1;
+ }
+
+ // Get the list of realms for the server
+ sRealmList->Initialize(*_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 10));
+
std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
sSessionMgr.StartNetwork(*_ioService, bindIp, bnport);
@@ -179,9 +186,6 @@ int main(int argc, char** argv)
_banExpiryCheckTimer->expires_from_now(boost::posix_time::seconds(_banExpiryCheckInterval));
_banExpiryCheckTimer->async_wait(BanExpiryHandler);
- sComponentMgr->Load();
- sModuleMgr->Load();
-
#if PLATFORM == PLATFORM_WINDOWS
if (m_ServiceStatus != -1)
{
@@ -197,6 +201,8 @@ int main(int argc, char** argv)
_banExpiryCheckTimer->cancel();
_dbPingTimer->cancel();
+ sLoginService.Stop();
+
sSessionMgr.StopNetwork();
sRealmList->Close();
@@ -211,6 +217,7 @@ int main(int argc, char** argv)
delete _banExpiryCheckTimer;
delete _dbPingTimer;
delete _ioService;
+ google::protobuf::ShutdownProtobufLibrary();
return 0;
}
diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.cpp b/src/server/bnetserver/Packets/AuthenticationPackets.cpp
deleted file mode 100644
index d9dd3ad6bd7..00000000000
--- a/src/server/bnetserver/Packets/AuthenticationPackets.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * 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 "AuthenticationPackets.h"
-#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()
-{
- Common.Program = _stream.ReadFourCC();
- Common.Platform = _stream.ReadFourCC();
- Common.Locale = _stream.ReadFourCC();
-
- Common.Versions.resize(_stream.Read<uint32>(6));
- for (size_t i = 0; i < Common.Versions.size(); ++i)
- {
- Version::Record& component = Common.Versions[i];
- component.ProgramId = _stream.ReadFourCC();
- component.Component = _stream.ReadFourCC();
- component.Version = _stream.Read<uint32>(32);
- }
-
- Account = _stream.ReadString(9, 3);
- GameAccountRegion = _stream.Read<uint8>(8);
- GameAccountName = _stream.ReadString(5, 1);
-}
-
-std::string Battlenet::Authentication::ResumeRequest::ToString() const
-{
- std::ostringstream stream;
- 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();
-}
-
-void Battlenet::Authentication::ResumeRequest::CallHandler(Session* session)
-{
- session->HandleResumeRequest(*this);
-}
-
-Battlenet::Authentication::ProofResponse::~ProofResponse()
-{
- for (size_t i = 0; i < Response.size(); ++i)
- delete Response[i];
-}
-
-void Battlenet::Authentication::ProofResponse::Read()
-{
- Response.resize(_stream.Read<uint32>(3));
- for (size_t i = 0; i < Response.size(); ++i)
- {
- BitStream*& dataStream = Response[i];
- dataStream = new BitStream(_stream.Read<uint32>(10));
- memcpy(dataStream->GetBuffer(), _stream.ReadBytes(dataStream->GetSize()).get(), dataStream->GetSize());
- }
-}
-
-std::string Battlenet::Authentication::ProofResponse::ToString() const
-{
- std::ostringstream stream;
- stream << "Battlenet::Authentication::ProofRequest" << std::endl;
- APPEND_FIELD(stream, Response.size());
- return stream.str();
-}
-
-void Battlenet::Authentication::ProofResponse::CallHandler(Session* session)
-{
- session->HandleProofResponse(*this);
-}
-
-void Battlenet::Authentication::LogonRequest3::Read()
-{
- Common.Program = _stream.ReadFourCC();
- Common.Platform = _stream.ReadFourCC();
- Common.Locale = _stream.ReadFourCC();
-
- Common.Versions.resize(_stream.Read<uint32>(6));
- for (size_t i = 0; i < Common.Versions.size(); ++i)
- {
- 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))
- Account = _stream.ReadString(9, 3);
-
- Compatibility = _stream.Read<uint64>(64);
-}
-
-std::string Battlenet::Authentication::LogonRequest3::ToString() const
-{
- std::ostringstream stream;
- stream << "Battlenet::Authentication::LogonRequest3" << std::endl;
- APPEND_FIELD(stream, Common);
- APPEND_FIELD(stream, Account);
- APPEND_FIELD(stream, Compatibility);
- return stream.str();
-}
-
-void Battlenet::Authentication::LogonRequest3::CallHandler(Session* session)
-{
- session->HandleLogonRequest(*this);
-}
-
-Battlenet::Authentication::LogonResponse::~LogonResponse()
-{
- for (ModuleInfo* m : Result.Success.FinalRequest)
- delete m;
-}
-
-void Battlenet::Authentication::LogonResponse::Write()
-{
- _stream.Write(Result.Type, 1);
- if (Result.Type == ResultType::SUCCESS)
- {
- _stream.Write(Result.Success.FinalRequest.size(), 3);
- for (size_t i = 0; i < Result.Success.FinalRequest.size(); ++i)
- {
- 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(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(Result.Success.RegulatorRules->Type == Regulator::LEAKY_BUCKET, 1);
- if (Result.Success.RegulatorRules->Type == Regulator::LEAKY_BUCKET)
- {
- _stream.Write(Result.Success.RegulatorRules->LeakyBucket.Threshold, 32);
- _stream.Write(Result.Success.RegulatorRules->LeakyBucket.Rate, 32);
- }
- }
-
- _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(Result.Failure.Strings.is_initialized(), 1);
- if (Result.Failure.Strings.is_initialized())
- {
- _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.Failure.Result.Type, 2);
- if (Result.Failure.Result.Type == FailureType::FAILURE)
- {
- _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" << std::endl;
- APPEND_FIELD(stream, Result);
- APPEND_FIELD(stream, Raf);
- return stream.str();
-}
-
-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.Type = result != AUTH_OK ? ResultType::FAILURE : ResultType::SUCCESS;
- Result.Failure.Result.Failure.Error = result;
-}
-
-Battlenet::Authentication::ResumeResponse::~ResumeResponse()
-{
- for (ModuleInfo* m : Result.Success.FinalRequest)
- delete m;
-}
-
-void Battlenet::Authentication::ResumeResponse::Write()
-{
- _stream.Write(Result.Type, 1);
- if (Result.Type == ResultType::SUCCESS)
- {
- _stream.Write(Result.Success.FinalRequest.size(), 3);
- for (size_t i = 0; i < Result.Success.FinalRequest.size(); ++i)
- {
- 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(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(Result.Success.RegulatorRules->Type == Regulator::LEAKY_BUCKET, 1);
- if (Result.Success.RegulatorRules->Type == Regulator::LEAKY_BUCKET)
- {
- _stream.Write(Result.Success.RegulatorRules->LeakyBucket.Threshold, 32);
- _stream.Write(Result.Success.RegulatorRules->LeakyBucket.Rate, 32);
- }
- }
- }
- else
- {
- _stream.Write(Result.Failure.Strings.is_initialized(), 1);
- if (Result.Failure.Strings.is_initialized())
- {
- _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.Failure.Result.Type, 2);
- if (Result.Failure.Result.Type == FailureType::FAILURE)
- {
- _stream.Write(Result.Failure.Result.Failure.Error, 16);
- _stream.Write(Result.Failure.Result.Failure.Wait + std::numeric_limits<int32>::min(), 32);
- }
- }
-}
-
-std::string Battlenet::Authentication::ResumeResponse::ToString() const
-{
- std::ostringstream stream;
- stream << "Battlenet::Authentication::ResumeResponse" << std::endl;
- return stream.str();
-}
-
-void Battlenet::Authentication::ResumeResponse::SetAuthResult(AuthResult 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
deleted file mode 100644
index 9082585085d..00000000000
--- a/src/server/bnetserver/Packets/AuthenticationPackets.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * 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 AuthenticationPackets_h__
-#define AuthenticationPackets_h__
-
-#include "PacketsBase.h"
-#include "ComponentManager.h"
-#include "ModuleManager.h"
-
-namespace Battlenet
-{
- namespace Authentication
- {
- enum Opcode
- {
- CMSG_LOGON_REQUEST = 0x0, // Deprecated
- CMSG_RESUME_REQUEST = 0x1,
- CMSG_PROOF_RESPONSE = 0x2,
- CMSG_GENERATE_SINGLE_SIGN_ON_TOKEN_REQUEST_2 = 0x8, // Not implemented
- CMSG_LOGON_REQUEST_3 = 0x9,
- CMSG_SINGLE_SIGN_ON_REQUEST_3 = 0xA, // Not implemented
-
- SMSG_LOGON_RESPONSE = 0x0,
- SMSG_RESUME_RESPONSE = 0x1,
- SMSG_PROOF_REQUEST = 0x2,
- SMSG_PATCH = 0x3, // Not implemented
- SMSG_AUTHORIZED_LICENSES = 0x4, // Not implemented
- SMSG_GENERATE_SINGLE_SIGN_ON_TOKEN_RESPONSE_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:
- ResumeRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_RESUME_REQUEST, AUTHENTICATION) && "Invalid packet header for ResumeRequest");
- }
-
- void Read() override;
- std::string ToString() const override;
- void CallHandler(Session* session) override;
-
- RequestCommon Common;
- std::string Account;
- uint8 GameAccountRegion = 0;
- std::string GameAccountName;
- };
-
- class ProofResponse final : public ClientPacket
- {
- public:
- ProofResponse(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_PROOF_RESPONSE, AUTHENTICATION) && "Invalid packet header for ProofResponse");
- }
-
- ~ProofResponse();
-
- void Read() override;
- std::string ToString() const override;
- void CallHandler(Session* session) override;
-
- std::vector<BitStream*> Response;
- };
-
- class LogonRequest3 final : public ClientPacket
- {
- public:
- LogonRequest3(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_LOGON_REQUEST_3, AUTHENTICATION) && "Invalid packet header for LogonRequest3");
- }
-
- void Read() override;
- std::string ToString() const override;
- void CallHandler(Session* session) override;
-
- RequestCommon Common;
- std::string Account;
- uint64 Compatibility = 0;
- };
-
- struct FailureType : public PrintableComponent
- {
- Optional<Cache::Handle> Strings;
-
- enum
- {
- UPDATE = 0,
- FAILURE = 1,
- VERSION_CHECK_DISCONNECT = 2
- };
-
- struct ResultType : public PrintableComponent
- {
- int32 Type = FAILURE;
-
- struct UpdateType : public PrintableComponent
- {
- std::string ToString() const override;
- } Update;
-
- 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;
- };
-
- struct Regulator : public PrintableComponent
- {
- enum
- {
- NONE = 0,
- LEAKY_BUCKET = 1
- };
-
- int32 Type = LEAKY_BUCKET;
- struct NoneType : public PrintableComponent
- {
- std::string ToString() const override;
- } None;
-
- struct LeakyBucketType : public PrintableComponent
- {
- uint32 Threshold = 25000000;
- uint32 Rate = 1000;
-
- std::string ToString() const override;
- } LeakyBucket;
-
- std::string ToString() const override;
- };
-
- class LogonResponse final : public ServerPacket
- {
- public:
- LogonResponse() : ServerPacket(PacketHeader(SMSG_LOGON_RESPONSE, AUTHENTICATION))
- {
- }
-
- ~LogonResponse();
-
- void Write() override;
- std::string ToString() const override;
- void SetAuthResult(AuthResult result);
-
- 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))
- {
- }
-
- ~ResumeResponse();
-
- void Write() override;
- std::string ToString() const override;
-
- void SetAuthResult(AuthResult result);
-
- 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
- {
- public:
- ProofRequest() : ServerPacket(PacketHeader(SMSG_PROOF_REQUEST, AUTHENTICATION)) { }
- ~ProofRequest();
-
- void Write() override;
- std::string ToString() const override;
-
- std::vector<ModuleInfo*> Modules;
- };
- }
-}
-
-#endif // AuthenticationPackets_h__
diff --git a/src/server/bnetserver/Packets/BitStream.h b/src/server/bnetserver/Packets/BitStream.h
deleted file mode 100644
index 0e91c930514..00000000000
--- a/src/server/bnetserver/Packets/BitStream.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * 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 BitStream_h__
-#define BitStream_h__
-
-#include "Common.h"
-#include "ByteConverter.h"
-#include "MessageBuffer.h"
-#include <exception>
-#include <vector>
-#include <type_traits>
-#include <memory>
-
-namespace Battlenet
-{
- union FloatToInt
- {
- float AsFloat;
- uint32 AsInt;
- };
-
- class BitStreamPositionException : public std::exception
- {
- static uint32 const MessageSize = 128;
-
- public:
- BitStreamPositionException(bool read, uint32 operationSize, uint32 position, uint32 streamSize)
- {
- memset(_message, 0, MessageSize);
- snprintf(_message, MessageSize, "Attempted to %s more bits (%u) %s stream than %s (%u)\n",
- (read ? "read" : "write"),
- operationSize + position,
- (read ? "from" : "to"),
- (read ? "exist" : "allowed"),
- streamSize);
- }
-
- char const* what() const throw()
- {
- return _message;
- }
-
- private:
- char _message[MessageSize];
- };
-
- class BitStream
- {
- public:
- static uint32 const MaxSize = 0x4000;
-
- // length : The maximum number of bytes to read
- BitStream(uint32 length) : _writePos(length * 8), _readPos(0)
- {
- _buffer.resize(length, 0);
- }
-
- BitStream(MessageBuffer&& buffer) : _writePos(uint32(buffer.GetActiveSize()) << 3), _readPos(0), _buffer(buffer.Move())
- {
- }
-
- BitStream() : _writePos(0), _readPos(0)
- {
- _buffer.reserve(0x1000);
- }
-
- void AlignToNextByte()
- {
- _readPos = (_readPos + 7) & ~7;
- _writePos = (_writePos + 7) & ~7;
- }
-
- std::string ReadString(uint32 bitCount, int32 baseLength = 0)
- {
- uint32 len = Read<uint32>(bitCount) + baseLength;
- AlignToNextByte();
- std::string str(reinterpret_cast<char*>(&_buffer[_readPos >> 3]), len);
- _readPos += len * 8;
- return str;
- }
-
- std::unique_ptr<uint8[]> ReadBytes(uint32 count)
- {
- AlignToNextByte();
- if (_readPos + count * 8 > _writePos)
- throw BitStreamPositionException(true, count * 8, _readPos, _writePos);
-
- std::unique_ptr<uint8[]> buf(new uint8[count]);
- memcpy(buf.get(), &_buffer[_readPos >> 3], count);
- _readPos += count * 8;
- return buf;
- }
-
- float ReadFloat()
- {
- union
- {
- float AsFloat;
- uint32 AsInt;
- } convert;
-
- convert.AsInt = Read<uint32>(32);
- return convert.AsFloat;
- }
-
- std::string ReadFourCC()
- {
- uint32 fcc = Read<uint32>(32);
- EndianConvertReverse(fcc);
- size_t len = 4;
- while (!(fcc & 0xFF) && len)
- {
- fcc >>= 8;
- --len;
- }
-
- return std::string(reinterpret_cast<char*>(&fcc), len);
- }
-
- template<typename T>
- T Read(uint32 bitCount)
- {
- static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "T must be an integer type");
-
- if (_readPos + bitCount > _writePos)
- throw BitStreamPositionException(true, bitCount, _readPos, _writePos);
-
- uint64 ret = 0;
- while (bitCount != 0)
- {
- uint32 bitPos = (_readPos & 7);
- uint32 bitsLeftInByte = 8 - bitPos;
- if (bitsLeftInByte >= bitCount)
- bitsLeftInByte = bitCount;
-
- bitCount -= bitsLeftInByte;
- ret |= (uint64)(_buffer[_readPos >> 3] >> bitPos & (uint32)((uint8)(1 << bitsLeftInByte) - 1)) << bitCount;
- _readPos += bitsLeftInByte;
- }
-
- return static_cast<T>(ret);
- }
-
- void WriteString(std::string const& str, uint32 bitCount, int32 baseLength = 0)
- {
- Write(str.length() + baseLength, bitCount);
- WriteBytes(str.c_str(), uint32(str.length()));
- }
-
- template<typename T>
- void WriteBytes(T* data, uint32 count)
- {
- AlignToNextByte();
- if (!count || !data)
- return;
-
- if ((_writePos >> 3) + count > MaxSize)
- throw BitStreamPositionException(false, count * 8, _writePos, MaxSize * 8);
-
- _buffer.resize(_buffer.size() + count);
- memcpy(&_buffer[_writePos >> 3], data, count);
- _writePos += count * 8;
- }
-
- void WriteFloat(float value)
- {
- union
- {
- float AsFloat;
- uint32 AsInt;
- } convert;
-
- convert.AsFloat = value;
- Write(convert.AsInt, 32);
- }
-
- void WriteFourCC(std::string const& fcc)
- {
- uint32 intVal = *(uint32*)fcc.c_str();
- size_t len = fcc.length();
- EndianConvertReverse(intVal);
- // Add padding
- while (len++ < 4)
- intVal >>= 8;
-
- Write(intVal, 32);
- }
-
- template<typename T>
- void Write(T value, uint32 bitCount)
- {
- static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "T must be an integer type");
-
- if (_writePos + bitCount > 8 * MaxSize)
- throw BitStreamPositionException(false, bitCount, _writePos, MaxSize * 8);
-
- while (bitCount != 0)
- {
- uint32 bitPos = (_writePos & 7);
- uint32 bitsLeftInByte = 8 - bitPos;
- if (bitsLeftInByte >= bitCount)
- bitsLeftInByte = bitCount;
-
- bitCount -= bitsLeftInByte;
-
- uint8 firstHalf = (uint8)(~(((uint8)(1 << bitsLeftInByte) - 1) << bitPos));
- uint8 secondHalf = (uint8)((((uint8)(1 << bitsLeftInByte) - 1) & (uint8)(value >> bitCount)) << bitPos);
-
- if (_buffer.size() > (_writePos >> 3))
- _buffer[_writePos >> 3] = (uint8)((_buffer[_writePos >> 3] & firstHalf) | secondHalf);
- else
- _buffer.push_back(secondHalf);
-
- _writePos += bitsLeftInByte;
- }
- }
-
- bool IsRead() const { return _readPos >= _writePos; }
-
- uint8* GetBuffer() { return _buffer.data(); }
- uint8 const* GetBuffer() const { return _buffer.data(); }
-
- uint32 GetReadPos() const { return _readPos; }
- size_t GetSize() const { return ((_writePos + 7) & ~7) / 8; }
-
- // These methods are meant to only be used when their corresponding actions in the client ignore the value completely
- void ReadSkip(uint32 bitCount) { _readPos += bitCount; }
- void WriteSkip(uint32 bitCount) { Write(0, bitCount); }
-
- private:
- uint32 _writePos;
- uint32 _readPos;
- std::vector<uint8> _buffer;
- };
-
- template<>
- bool BitStream::Read<bool>(uint32 bitCount);
-
- template<>
- void BitStream::Write<bool>(bool value, uint32 bitCount);
-}
-
-#endif // BitStream_h__
diff --git a/src/server/bnetserver/Packets/CachePackets.cpp b/src/server/bnetserver/Packets/CachePackets.cpp
deleted file mode 100644
index ece7a9db08b..00000000000
--- a/src/server/bnetserver/Packets/CachePackets.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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 "Session.h"
-#include "Util.h"
-#include "CachePackets.h"
-
-void Battlenet::Cache::GetStreamItemsRequest::Read()
-{
- _stream.ReadSkip(31);
- Token = _stream.Read<uint32>(32);
- ReferenceTime = _stream.Read<int32>(32) - std::numeric_limits<int32>::min();
- Direction = _stream.Read<uint8>(1);
- MaxItems = _stream.Read<uint8>(6);
- Locale = _stream.ReadFourCC();
- Stream.Type = _stream.Read<uint8>(1);
- if (Stream.Type == StreamId::DESCRIPTION)
- {
- Stream.Description.ItemName = _stream.ReadFourCC();
- Stream.Description.Channel = _stream.ReadFourCC();
- }
- else
- 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" << 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();
-}
-
-void Battlenet::Cache::GetStreamItemsRequest::CallHandler(Session* session)
-{
- session->HandleGetStreamItemsRequest(*this);
-}
-
-Battlenet::Cache::GetStreamItemsResponse::~GetStreamItemsResponse()
-{
- for (size_t i = 0; i < Items.size(); ++i)
- delete Items[i];
-}
-
-void Battlenet::Cache::GetStreamItemsResponse::Write()
-{
- _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->Handle.Type.c_str(), 4);
- _stream.WriteFourCC(info->Handle.Region);
- _stream.WriteBytes(info->Handle.ModuleId, 32);
- _stream.WriteSkip(27);
- _stream.WriteBytes(info->Data, 4);
- }
-}
-
-std::string Battlenet::Cache::GetStreamItemsResponse::ToString() const
-{
- std::ostringstream stream;
- 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
deleted file mode 100644
index 5cdd0905289..00000000000
--- a/src/server/bnetserver/Packets/CachePackets.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 CachePackets_h__
-#define CachePackets_h__
-
-#include "ModuleManager.h"
-#include "PacketsBase.h"
-
-namespace Battlenet
-{
- namespace Cache
- {
- enum Opcode
- {
- CMSG_GATEWAY_LOOKUP_REQUEST = 0x2, // Not implemented
- CMSG_CONNECT_REQUEST = 0x4, // Not implemented
- CMSG_DATA_CHUNK = 0x7, // Not implemented
- CMSG_GET_STREAM_ITEMS_REQUEST = 0x9,
-
- SMSG_GATEWAY_LOOKUP_RESPONSE = 0x3, // Not implemented
- SMSG_CONNECT_RESPONSE = 0x4, // Not implemented
- SMSG_PUBLISH_LIST_RESPONSE = 0x7, // Not implemented
- SMSG_RESULT = 0x8, // Not implemented
- SMSG_GET_STREAM_ITEMS_RESPONSE = 0x9
- };
-
- class GetStreamItemsRequest final : public ClientPacket
- {
- public:
- GetStreamItemsRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_GET_STREAM_ITEMS_REQUEST, CACHE) && "Invalid packet header for GetStreamItemsRequest");
- }
-
- void Read() override;
- std::string ToString() const override;
- void CallHandler(Session* session) override;
-
- 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
- {
- public:
- GetStreamItemsResponse() : ServerPacket(PacketHeader(SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE))
- {
- }
-
- ~GetStreamItemsResponse();
-
- void Write() override;
- std::string ToString() const override;
-
- std::vector<ModuleInfo*> Items;
- uint16 Offset = 0;
- uint16 TotalNumItems = 1;
- uint32 Token = 0;
- };
- }
-}
-
-#endif // CachePackets_h__
diff --git a/src/server/bnetserver/Packets/ChatPackets.h b/src/server/bnetserver/Packets/ChatPackets.h
deleted file mode 100644
index 3b1c5c155e0..00000000000
--- a/src/server/bnetserver/Packets/ChatPackets.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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 ChatPackets_h__
-#define ChatPackets_h__
-
-#include "PacketsBase.h"
-
-namespace Battlenet
-{
- namespace Chat
- {
- enum Opcode
- {
- CMSG_JOIN_REQUEST_2 = 0x00, // Not implemented
- CMSG_LEAVE_REQUEST = 0x02, // Not implemented
- CMSG_INVITE_REQUEST = 0x03, // Not implemented
- CMSG_CREATE_AND_INVITE_REQUEST = 0x0A, // Not implemented
- CMSG_MESSAGE_SEND = 0x0B, // Not implemented
- CMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented
- CMSG_REPORT_SPAM_REQUEST = 0x0E, // Not implemented
- CMSG_WHISPER_SEND = 0x13, // Not implemented
- CMSG_ENUM_CATEGORY_DESCRIPTIONS = 0x15, // Not implemented
- CMSG_ENUM_CONFERENCE_DESCRIPTIONS = 0x17, // Not implemented
- CMSG_ENUM_CONFERENCE_MEMBER_COUNTS = 0x19, // Not implemented
- CMSG_MODIFY_CHANNEL_LIST_REQUEST = 0x1B, // Deprecated in client
- 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
- SMSG_INVITE_CANCELED = 0x07, // Not implemented
- SMSG_MESSAGE_RECV = 0x0B, // Not implemented
- SMSG_MESSAGE_UNDELIVERABLE = 0x0C, // Not implemented
- SMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented
- SMSG_INVITE_FAILURE = 0x0F, // Not implemented
- SMSG_SYSTEM_MESSAGE = 0x10, // Not implemented
- SMSG_MESSAGE_BLOCKED = 0x12, // Not implemented
- SMSG_WHISPER_RECV = 0x13, // Not implemented
- SMSG_WHISPER_UNDELIVERABLE = 0x14, // Not implemented
- SMSG_CATEGORY_DESCRIPTIONS = 0x16, // Not implemented
- SMSG_CONFERENCE_DESCRIPTIONS = 0x18, // Not implemented
- SMSG_CONFERENCE_MEMBER_COUNTS = 0x1A, // Not implemented
- SMSG_JOIN_NOTIFY_2 = 0x1B, // Not implemented
- SMSG_MODIFY_CHANNEL_LIST_RESPONSE = 0x1C, // Deprecated in client
- SMSG_CONFIG_CHANGED = 0x1D, // Not implemented
- SMSG_WHISPER_ECHO_RECV = 0x1E, // Not implemented
- SMSG_GET_MEMBER_COUNT_RESPONSE = 0x1F, // Not implemented
- SMSG_MODIFY_CHANNEL_LIST_RESPONSE_2 = 0x21, // Not implemented
- SMSG_GAME_DATA_SEND_RESPONSE = 0x23, // Not implemented
- SMSG_GAME_DATA_RECV = 0x24 // Not implemented
- };
- }
-}
-
-#endif // ChatPackets_h__
diff --git a/src/server/bnetserver/Packets/ConnectionPackets.cpp b/src/server/bnetserver/Packets/ConnectionPackets.cpp
deleted file mode 100644
index cdb438085f1..00000000000
--- a/src/server/bnetserver/Packets/ConnectionPackets.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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 "Session.h"
-#include "ConnectionPackets.h"
-
-std::string Battlenet::Connection::Ping::ToString() const
-{
- return "Battlenet::Connection::Ping";
-}
-
-void Battlenet::Connection::Ping::CallHandler(Session* session)
-{
- session->HandlePing(*this);
-}
-
-std::string Battlenet::Connection::EnableEncryption::ToString() const
-{
- return "Battlenet::Connection::EnableEncryption";
-}
-
-void Battlenet::Connection::EnableEncryption::CallHandler(Session* session)
-{
- session->HandleEnableEncryption(*this);
-}
-
-std::string Battlenet::Connection::LogoutRequest::ToString() const
-{
- return "Battlenet::Connection::LogoutRequest";
-}
-
-void Battlenet::Connection::LogoutRequest::CallHandler(Session* session)
-{
- session->HandleLogoutRequest(*this);
-}
-
-void Battlenet::Connection::DisconnectRequest::Read()
-{
- Error = _stream.Read<uint16>(16);
- Timeout = _stream.Read<uint32>(32);
-}
-
-std::string Battlenet::Connection::DisconnectRequest::ToString() const
-{
- std::ostringstream str;
- str << "Battlenet::Connection::DisconnectRequest" << std::endl;
- APPEND_FIELD(str, Error);
- APPEND_FIELD(str, Timeout);
- return str.str();
-}
-
-void Battlenet::Connection::ConnectionClosing::Read()
-{
- Packets.resize(_stream.Read<uint8>(6));
- for (size_t i = 0; i < Packets.size(); ++i)
- {
- PacketInfo& info = Packets[i];
- info.Command = _stream.ReadFourCC();
- info.Time = _stream.Read<uint32>(32);
- info.Size = _stream.Read<uint32>(16);
- info.Layer = _stream.ReadFourCC();
- info.Offset = _stream.Read<uint32>(16);
- }
-
- Reason = _stream.Read<ClosingReason>(4);
- _stream.ReadBytes(_stream.Read<uint8>(8)); // BadData
-
- if (_stream.Read<bool>(1)) // HasHeader
- {
- Header.Command = _stream.Read<uint32>(6);
- if (_stream.Read<bool>(1))
- Header.Channel = _stream.Read<int32>(4);
- }
-
- Now = _stream.Read<time_t>(32);
-}
-
-std::string Battlenet::Connection::ConnectionClosing::PacketInfo::ToString() const
-{
- std::ostringstream stream;
- 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();
-}
-
-void Battlenet::Connection::ConnectionClosing::CallHandler(Session* session)
-{
- session->HandleConnectionClosing(*this);
-}
-
-std::string Battlenet::Connection::Pong::ToString() const
-{
- return "Battlenet::Connection::Pong";
-}
diff --git a/src/server/bnetserver/Packets/ConnectionPackets.h b/src/server/bnetserver/Packets/ConnectionPackets.h
deleted file mode 100644
index 9987c65d770..00000000000
--- a/src/server/bnetserver/Packets/ConnectionPackets.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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 ConnectionPackets_h__
-#define ConnectionPackets_h__
-
-#include "PacketsBase.h"
-
-namespace Battlenet
-{
- namespace Connection
- {
- enum Opcode
- {
- CMSG_PING = 0x0,
- CMSG_ENABLE_ENCRYPTION = 0x5,
- CMSG_LOGOUT_REQUEST = 0x6,
- CMSG_DISCONNECT_REQUEST = 0x7, // Not handled
- CMSG_CONNECTION_CLOSING = 0x9,
-
- SMSG_PONG = 0x0,
- SMSG_BOOM = 0x1, // Not implemented
- SMSG_REGULATOR_UPDATE = 0x2, // Not implemented
- SMSG_SERVER_VERSION = 0x3, // Not implemented
- SMSG_STUN_SERVERS = 0x4 // Not implemented
- };
-
- class Ping final : public ClientPacket
- {
- public:
- Ping(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_PING, CONNECTION) && "Invalid packet header for Ping");
- }
-
- void Read() override { }
- std::string ToString() const override;
- void CallHandler(Session* session) override;
- };
-
- class EnableEncryption final : public ClientPacket
- {
- public:
- EnableEncryption(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_ENABLE_ENCRYPTION, CONNECTION) && "Invalid packet header for EnableEncryption");
- }
-
- void Read() override { }
- std::string ToString() const override;
- void CallHandler(Session* session) override;
- uint8* GetRemainingData() { return _stream.GetBuffer() + (((_stream.GetReadPos() + 7) & ~7) / 8); }
- size_t GetRemainingSize() const { return _stream.GetSize() - (((_stream.GetReadPos() + 7) & ~7) / 8); }
- };
-
- class LogoutRequest final : public ClientPacket
- {
- public:
- LogoutRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_LOGOUT_REQUEST, CONNECTION) && "Invalid packet header for LogoutRequest");
- }
-
- void Read() override { }
- std::string ToString() const override;
- void CallHandler(Session* session) override;
- };
-
- class DisconnectRequest final : public ClientPacket
- {
- public:
- DisconnectRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_DISCONNECT_REQUEST, CONNECTION) && "Invalid packet header for DisconnectRequest");
- }
-
- void Read() override;
- std::string ToString() const override;
-
- uint16 Error = 0;
- uint32 Timeout = 0;
- };
-
- class ConnectionClosing final : public ClientPacket
- {
- public:
- enum ClosingReason
- {
- PACKET_TOO_LARGE = 1,
- PACKET_CORRUPT = 2,
- PACKET_INVALID = 3,
- PACKET_INCORRECT = 4,
- HEADER_CORRUPT = 5,
- HEADER_IGNORED = 6,
- HEADER_INCORRECT = 7,
- PACKET_REJECTED = 8,
- CHANNEL_UNHANDLED = 9,
- COMMAND_UNHANDLED = 10,
- COMMAND_BAD_PERMISSIONS = 11,
- DIRECT_CALL = 12,
- TIMEOUT = 13,
- };
-
- struct PacketInfo : public PrintableComponent
- {
- 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)
- {
- ASSERT(header == PacketHeader(CMSG_CONNECTION_CLOSING, CONNECTION) && "Invalid packet header for ConnectionClosing");
- }
-
- void Read() override;
- std::string ToString() const override;
- void CallHandler(Session* session) override;
-
- PacketHeader Header;
- ClosingReason Reason = PACKET_CORRUPT;
- std::vector<PacketInfo> Packets;
- time_t Now = 0;
- };
-
- class Pong final : public ServerPacket
- {
- public:
- Pong() : ServerPacket(PacketHeader(SMSG_PONG, CONNECTION))
- {
- }
-
- void Write() override { }
- std::string ToString() const override;
- };
- }
-}
-
-#endif // ConnectionPackets_h__
diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp
deleted file mode 100644
index 90a124fb915..00000000000
--- a/src/server/bnetserver/Packets/FriendsPackets.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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 "FriendsPackets.h"
-
-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
-{
- 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::SendInvitationRequest::CallHandler(Session* /*session*/)
-{
-}
diff --git a/src/server/bnetserver/Packets/FriendsPackets.h b/src/server/bnetserver/Packets/FriendsPackets.h
deleted file mode 100644
index 8f1f513f521..00000000000
--- a/src/server/bnetserver/Packets/FriendsPackets.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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 FriendsPackets_h__
-#define FriendsPackets_h__
-
-#include "PacketsBase.h"
-
-namespace Battlenet
-{
- namespace Friends
- {
- enum Opcode
- {
- CMSG_FRIEND_INVITE = 0x01, // Not implemented
- CMSG_FRIEND_INVITE_RESPONSE = 0x02, // Not implemented
- CMSG_FRIEND_REMOVE = 0x04, // Not implemented
- CMSG_FRIEND_NOTE = 0x05, // Not implemented
- CMSG_TOONS_OF_FRIEND_REQUEST = 0x06, // Not implemented
- 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, // 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
- SMSG_TOONS_OF_FRIEND_NOTIFY = 0x06, // Not implemented
- SMSG_BLOCK_INVITE_NOTIFY = 0x07, // Deprecated in client
- SMSG_BLOCK_ADD_FAILURE = 0x09, // Not implemented
- SMSG_FRIENDS_OF_FRIEND = 0x0C, // Deprecated in client
- 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, // Deprecated in client
- SMSG_SEND_INVITATION_RESULT = 0x1B, // Not implemented
- SMSG_FRIEND_INVITATION_ADDED_NOTIFY = 0x1C, // Not implemented
- SMSG_FRIEND_INVITATION_REMOVED_NOTIFY = 0x1D, // Not implemented
- SMSG_FRIENDS_LIST_NOTIFY_5 = 0x1E, // Not implemented
- SMSG_ACCOUNT_BLOCK_ADDED_NOTIFY = 0x1F, // Not implemented
- SMSG_ACCOUNT_BLOCK_REMOVED_NOTIFY = 0x20, // Not implemented
- SMSG_TOON_BLOCK_NOTIFY = 0x21, // Not implemented
- SMSG_FRIENDS_OF_FRIEND_RESULT = 0x22 // Not implemented
- };
-
- class SendInvitationRequest final : public ClientPacket
- {
- public:
- SendInvitationRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) { }
-
- void Read() override;
- std::string ToString() const override;
- void CallHandler(Session* session) override;
-
- uint32 Token = 0;
-
- Optional<uint32> PresenceId;
- Optional<GameAccount::Handle> GameAccount;
- Optional<uint32> AccountId;
- Optional<std::string> AccountMail;
- Optional<std::string> Nickname;
-
- Optional<std::string> InvitationMsg;
- std::string Source;
- uint32 Role = 0;
- };
- }
-}
-
-#endif // FriendsPackets_h__
diff --git a/src/server/bnetserver/Packets/PacketManager.cpp b/src/server/bnetserver/Packets/PacketManager.cpp
deleted file mode 100644
index 588ca1a0a86..00000000000
--- a/src/server/bnetserver/Packets/PacketManager.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * 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 "PacketManager.h"
-
-Battlenet::ClientPacket* Battlenet::PacketManager::CreateClientPacket(PacketHeader const& header, BitStream& stream)
-{
- auto packetInfo = _clientPacketTable.find(header);
- if (packetInfo == _clientPacketTable.end())
- return nullptr;
-
- if (!packetInfo->second.Constructor)
- return nullptr;
-
- ClientPacket* packet = packetInfo->second.Constructor(header, stream);
- packet->Read();
- return packet;
-}
-
-char const* Battlenet::PacketManager::GetClientPacketName(PacketHeader const& header)
-{
- auto packetInfo = _clientPacketTable.find(header);
- if (packetInfo == _clientPacketTable.end())
- return nullptr;
-
- return packetInfo->second.Name;
-}
-
-char const* Battlenet::PacketManager::GetServerPacketName(PacketHeader const& header)
-{
- auto packetInfo = _serverPacketTable.find(header);
- if (packetInfo == _serverPacketTable.end())
- return nullptr;
-
- return packetInfo->second.Name;
-}
-
-bool Battlenet::PacketManager::IsHandled(PacketHeader const& header)
-{
- auto packetInfo = _clientPacketTable.find(header);
- if (packetInfo == _clientPacketTable.end())
- return false;
-
- return packetInfo->second.HasHandler;
-}
-
-Battlenet::PacketManager::PacketManager()
-{
- RegisterAuthenticationPackets();
- RegisterConnectionPackets();
- RegisterWoWRealmPackets();
- RegisterFriendsPackets();
- RegisterPresencePackets();
- RegisterChatPackets();
- RegisterSupportPackets();
- RegisterCachePackets();
- RegisterAchievementPackets();
- RegisterProfilePackets();
-}
-
-#define REGISTER_CLIENT_PACKET(header, packetClass) RegisterClientPacket<packetClass>(header, #packetClass)
-#define REGISTER_SERVER_PACKET(header, packetClass) RegisterPacketName(_serverPacketTable, header, #packetClass)
-#define REGISTER_CLIENT_PACKET_NAME(header, name) RegisterPacketName(_clientPacketTable, header, name)
-#define REGISTER_SERVER_PACKET_NAME(header, name) RegisterPacketName(_serverPacketTable, header, name)
-
-void Battlenet::PacketManager::RegisterAuthenticationPackets()
-{
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Authentication::CMSG_LOGON_REQUEST, AUTHENTICATION), "Authentication::LogonRequest");
- REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_RESUME_REQUEST, AUTHENTICATION), Authentication::ResumeRequest);
- REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_PROOF_RESPONSE, AUTHENTICATION), Authentication::ProofResponse);
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Authentication::CMSG_GENERATE_SINGLE_SIGN_ON_TOKEN_REQUEST_2, AUTHENTICATION), "Authentication::GenerateSingleSignOnTokenRequest2");
- REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_LOGON_REQUEST_3, AUTHENTICATION), Authentication::LogonRequest3);
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Authentication::CMSG_SINGLE_SIGN_ON_REQUEST_3, AUTHENTICATION), "Authentication::SingleSignOnRequest3");
-
- REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_LOGON_RESPONSE, AUTHENTICATION), Authentication::LogonResponse);
- REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_RESUME_RESPONSE, AUTHENTICATION), Authentication::ResumeResponse);
- REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_PROOF_REQUEST, AUTHENTICATION), Authentication::ProofRequest);
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Authentication::SMSG_PATCH, AUTHENTICATION), "Authentication::Patch");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Authentication::SMSG_AUTHORIZED_LICENSES, AUTHENTICATION), "Authentication::AuthorizedLicenses");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Authentication::SMSG_GENERATE_SINGLE_SIGN_ON_TOKEN_RESPONSE_2, AUTHENTICATION), "Authentication::GenerateSingleSignOnTokenResponse2");
-}
-
-void Battlenet::PacketManager::RegisterConnectionPackets()
-{
- REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_PING, CONNECTION), Connection::Ping);
- REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_ENABLE_ENCRYPTION, CONNECTION), Connection::EnableEncryption);
- REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_LOGOUT_REQUEST, CONNECTION), Connection::LogoutRequest);
- REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_DISCONNECT_REQUEST, CONNECTION), Connection::DisconnectRequest);
- REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_CONNECTION_CLOSING, CONNECTION), Connection::ConnectionClosing);
-
- REGISTER_SERVER_PACKET(PacketHeader(Connection::SMSG_PONG, CONNECTION), Connection::Pong);
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_BOOM, CONNECTION), "Connection::Boom");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_REGULATOR_UPDATE, CONNECTION), "Connection::RegulatorUpdate");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_SERVER_VERSION, CONNECTION), "Connection::ServerVersion");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_STUN_SERVERS, CONNECTION), "Connection::STUNServers");
-}
-
-void Battlenet::PacketManager::RegisterWoWRealmPackets()
-{
- REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM), WoWRealm::ListSubscribeRequest);
- REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_LIST_UNSUBSCRIBE, WOWREALM), WoWRealm::ListUnsubscribe);
- REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_JOIN_REQUEST_V2, WOWREALM), WoWRealm::JoinRequestV2);
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(WoWRealm::CMSG_MULTI_LOGON_REQUEST_V2, WOWREALM), "WoWRealm::MultiLogonRequestV2");
-
- REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM), WoWRealm::ListSubscribeResponse);
- REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_UPDATE, WOWREALM), WoWRealm::ListUpdate);
- REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_COMPLETE, WOWREALM), WoWRealm::ListComplete);
- REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_TOON_READY, WOWREALM), WoWRealm::ToonReady);
- REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_TOON_LOGGED_OUT, WOWREALM), WoWRealm::ToonLoggedOut);
- REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_JOIN_RESPONSE_V2, WOWREALM), WoWRealm::JoinResponseV2);
-}
-
-void Battlenet::PacketManager::RegisterFriendsPackets()
-{
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_INVITE, FRIENDS), "Friends::FriendInvite");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_INVITE_RESPONSE, FRIENDS), "Friends::FriendInviteResponse");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_REMOVE, FRIENDS), "Friends::FriendRemove");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_NOTE, FRIENDS), "Friends::FriendNote");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_TOONS_OF_FRIEND_REQUEST, FRIENDS), "Friends::ToonsOfFriendRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_BLOCK_ADD, FRIENDS), "Friends::BlockAdd");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_BLOCK_REMOVE, FRIENDS), "Friends::BlockRemove");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS), "Friends::GetFriendsOfFriend");
- 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_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS), "Friends::SocialNetworkCheckConnected");
- 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_NAME(PacketHeader(Friends::SMSG_FRIEND_INVITE_RESULT, FRIENDS), "Friends::FriendInviteResult");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_TOONS_OF_FRIEND_NOTIFY, FRIENDS), "Friends::ToonsOfFriendNotify");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_BLOCK_INVITE_NOTIFY, FRIENDS), "Friends::BlockInviteNotify");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_BLOCK_ADD_FAILURE, FRIENDS), "Friends::BlockAddFailure");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_OF_FRIEND, FRIENDS), "Friends::FriendsOfFriend");
- 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_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");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SEND_INVITATION_RESULT, FRIENDS), "SendInvitationResult");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIEND_INVITATION_ADDED_NOTIFY, FRIENDS), "Friends::FriendInvitationAddedNotify");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIEND_INVITATION_REMOVED_NOTIFY, FRIENDS), "Friends::FriendInvitationRemovedNotify");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_LIST_NOTIFY_5, FRIENDS), "Friends::FriendsListNotify5");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_ACCOUNT_BLOCK_ADDED_NOTIFY, FRIENDS), "Friends::AccountBlockAddedNotify");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_ACCOUNT_BLOCK_REMOVED_NOTIFY, FRIENDS), "Friends::AccountBlockRemovedNotify");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_TOON_BLOCK_NOTIFY, FRIENDS), "Friends::ToonBlockNotify");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_OF_FRIEND_RESULT, FRIENDS), "Friends::FriendsOfFriendResult");
-}
-
-void Battlenet::PacketManager::RegisterPresencePackets()
-{
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Presence::CMSG_UPDATE_REQUEST, PRESENCE), "Presence::UpdateRequest");
- REGISTER_CLIENT_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");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_STATISTICS_UPDATE, PRESENCE), "Presence::StatisticsUpdate");
-}
-
-void Battlenet::PacketManager::RegisterChatPackets()
-{
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_JOIN_REQUEST_2, CHAT), "Chat::JoinRequest2");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_LEAVE_REQUEST, CHAT), "Chat::LeaveRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_INVITE_REQUEST, CHAT), "Chat::InviteRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_CREATE_AND_INVITE_REQUEST, CHAT), "Chat::CreateAndInviteRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_MESSAGE_SEND, CHAT), "Chat::MessageSend");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_DATAGRAM_CONNECTION_UPDATE, CHAT), "Chat::DatagramConnectionUpdate");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_REPORT_SPAM_REQUEST, CHAT), "Chat::ReportSpamRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_WHISPER_SEND, CHAT), "Chat::WhisperSend");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CATEGORY_DESCRIPTIONS, CHAT), "Chat::EnumCategoryDescriptions");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CONFERENCE_DESCRIPTIONS, CHAT), "Chat::EnumConferenceDescriptions");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CONFERENCE_MEMBER_COUNTS, CHAT), "Chat::EnumConferenceMemberCounts");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_MODIFY_CHANNEL_LIST_REQUEST, CHAT), "Chat::ModifyChannelListRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_GET_MEMBER_COUNT_REQUEST, CHAT), "Chat::GetMemberCountRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_MODIFY_CHANNEL_LIST_REQUEST_2, CHAT), "Chat::ModifyChannelListRequest2");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_GAME_DATA_SEND_REQUEST, CHAT), "Chat::GameDataSendRequest");
-
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MEMBERSHIP_CHANGE_NOTIFY, CHAT), "Chat::MembershipChangeNotify");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_NOTIFY, CHAT), "Chat::InviteNotify");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_CANCELED, CHAT), "Chat::InviteCanceled");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_RECV, CHAT), "Chat::MessageRecv");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_UNDELIVERABLE, CHAT), "Chat::MessageUndeliverable");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_DATAGRAM_CONNECTION_UPDATE, CHAT), "Chat::DatagramConnectionUpdate");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_FAILURE, CHAT), "Chat::InviteFailed");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_SYSTEM_MESSAGE, CHAT), "Chat::SystemMessage");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_BLOCKED, CHAT), "Chat::MessageBlocked");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_WHISPER_RECV, CHAT), "Chat::WhisperRecv");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_WHISPER_UNDELIVERABLE, CHAT), "Chat::WhisperUndeliverable");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CATEGORY_DESCRIPTIONS, CHAT), "Chat::CategoryDescriptions");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFERENCE_DESCRIPTIONS, CHAT), "Chat::ConferenceDescriptions");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFERENCE_MEMBER_COUNTS, CHAT), "Chat::ConferenceMemberCounts");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_JOIN_NOTIFY_2, CHAT), "Chat::JoinNotify2");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MODIFY_CHANNEL_LIST_RESPONSE, CHAT), "Chat::ModifyChannelListResponse");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFIG_CHANGED, CHAT), "Chat::ConfigChanged");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_WHISPER_ECHO_RECV, CHAT), "Chat::WhisperEchoRecv");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_GET_MEMBER_COUNT_RESPONSE, CHAT), "Chat::GetMemberCountResponse");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MODIFY_CHANNEL_LIST_RESPONSE_2, CHAT), "Chat::ModifyChannelListResponse2");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_GAME_DATA_SEND_RESPONSE, CHAT), "Chat::GameDataSendResponse");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_GAME_DATA_RECV, CHAT), "Chat::GameDataRecv");
-}
-
-void Battlenet::PacketManager::RegisterSupportPackets()
-{
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Support::CMSG_COMPLAINT_REQUEST, SUPPORT), "Support::ComplaintRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Support::CMSG_COMPLAINT_REQUEST_2, SUPPORT), "Support::ComplaintRequest2");
-}
-
-void Battlenet::PacketManager::RegisterAchievementPackets()
-{
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_LISTEN_REQUEST, ACHIEVEMENT), "Achievement::ListenRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_CRITERIA_FLUSH_REQUEST, ACHIEVEMENT), "Achievement::CriteriaFlushRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_CHANGE_TROPHY_CASE_REQUEST, ACHIEVEMENT), "Achievement::ChangeTrophyCaseRequest");
-
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_DATA, ACHIEVEMENT), "Achievement::Data");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_CRITERIA_FLUSH_RESPONSE, ACHIEVEMENT), "Achievement::CriteriaFlushResponse");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_ACHIEVEMENT_HANDLE_UPDATE, ACHIEVEMENT), "Achievement::AchievementHandleUpdate");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_CHANGE_TROPHY_CASE_RESULT, ACHIEVEMENT), "Achievement::ChangeTrophyCaseResult");
-}
-
-void Battlenet::PacketManager::RegisterCachePackets()
-{
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_GATEWAY_LOOKUP_REQUEST, CACHE), "Cache::GatewayLookupRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_CONNECT_REQUEST, CACHE), "Cache::ConnectRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_DATA_CHUNK, CACHE), "Cache::DataChunk");
- REGISTER_CLIENT_PACKET(PacketHeader(Cache::CMSG_GET_STREAM_ITEMS_REQUEST, CACHE), Cache::GetStreamItemsRequest);
-
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_GATEWAY_LOOKUP_RESPONSE, CACHE), "Cache::GatewayLookupResponse");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_CONNECT_RESPONSE, CACHE), "Cache::ConnectResponse");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_PUBLISH_LIST_RESPONSE, CACHE), "Cache::PublishListResponse");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_RESULT, CACHE), "Cache::Result");
- REGISTER_SERVER_PACKET(PacketHeader(Cache::SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE), Cache::GetStreamItemsResponse);
-}
-
-void Battlenet::PacketManager::RegisterProfilePackets()
-{
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_READ_REQUEST, PROFILE), "Profile::ReadRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_ADDRESS_QUERY_REQUEST, PROFILE), "Profile::AddressQueryRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST, PROFILE), "Profile::ResolveHandleToToonNameRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST, PROFILE), "Profile::ResolveToonNameToHandleRequest");
- REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_CHANGE_SETTINGS, PROFILE), "Profile::ChangeSettings");
-
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_READ_RESPONSE, PROFILE), "Profile::ReadResponse");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_ADDRESS_QUERY_RESPONSE, PROFILE), "Profile::AddressQueryResponse");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE, PROFILE), "Profile::ResolveHandleToToonNameResponse");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE, PROFILE), "Profile::ResolveToonNameToHandleResponse");
- REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_SETTINGS_AVAILABLE, PROFILE), "Profile::SettingsAvailable");
-}
diff --git a/src/server/bnetserver/Packets/PacketManager.h b/src/server/bnetserver/Packets/PacketManager.h
deleted file mode 100644
index 50fcaaa0d05..00000000000
--- a/src/server/bnetserver/Packets/PacketManager.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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 PacketManager_h__
-#define PacketManager_h__
-
-#include "Packets.h"
-#include <map>
-#include <type_traits>
-
-template<typename T>
-struct has_call_handler
-{
- template<typename U, void(U::*)(Battlenet::Session*)> struct test_has_call_handler { };
- template<typename U> static char Test(test_has_call_handler<U, &U::CallHandler>*);
- template<typename U> static int Test(...);
- static const bool value = sizeof(Test<T>(nullptr)) == sizeof(char);
-};
-
-namespace Battlenet
-{
- class PacketManager
- {
- typedef ClientPacket*(*PacketCreateFn)(PacketHeader const& header, BitStream& stream);
-
- struct PacketInfo
- {
- PacketCreateFn Constructor;
- char const* Name;
- bool HasHandler;
- };
-
- PacketManager();
-
- void RegisterAuthenticationPackets();
- void RegisterConnectionPackets();
- void RegisterWoWRealmPackets();
- void RegisterFriendsPackets();
- void RegisterPresencePackets();
- void RegisterChatPackets();
- void RegisterSupportPackets();
- void RegisterAchievementPackets();
- void RegisterCachePackets();
- void RegisterProfilePackets();
-
- template<class PacketType>
- static ClientPacket* New(PacketHeader const& header, BitStream& stream)
- {
- return new PacketType(header, stream);
- }
-
- void RegisterPacketName(std::map<PacketHeader, PacketInfo>& packetTable, PacketHeader const& header, char const* name)
- {
- PacketInfo& info = packetTable[header];
- info.Constructor = nullptr;
- info.Name = name;
- info.HasHandler = false;
- }
-
- template<class PacketType>
- void RegisterClientPacket(PacketHeader const& header, char const* name)
- {
- PacketInfo& info = _clientPacketTable[header];
- info.Constructor = &New<PacketType>;
- info.Name = name;
- info.HasHandler = has_call_handler<PacketType>::value;
- }
-
- public:
- ClientPacket* CreateClientPacket(PacketHeader const& header, BitStream& stream);
-
- char const* GetClientPacketName(PacketHeader const& header);
- char const* GetServerPacketName(PacketHeader const& header);
-
- bool IsHandled(PacketHeader const& header);
-
- static PacketManager& Instance()
- {
- static PacketManager instance;
- return instance;
- }
-
- private:
- std::map<PacketHeader, PacketInfo> _clientPacketTable;
- std::map<PacketHeader, PacketInfo> _serverPacketTable;
- };
-}
-
-#define sPacketManager Battlenet::PacketManager::Instance()
-
-#endif // PacketManager_h__
diff --git a/src/server/bnetserver/Packets/Packets.h b/src/server/bnetserver/Packets/Packets.h
deleted file mode 100644
index 834bb735a16..00000000000
--- a/src/server/bnetserver/Packets/Packets.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 Packets_h__
-#define Packets_h__
-
-#include "AuthenticationPackets.h"
-#include "ConnectionPackets.h"
-#include "WoWRealmPackets.h"
-#include "FriendsPackets.h"
-#include "PresencePackets.h"
-#include "ChatPackets.h"
-#include "SupportPackets.h"
-#include "AchievementPackets.h"
-#include "CachePackets.h"
-#include "ProfilePackets.h"
-
-#endif // Packets_h__
diff --git a/src/server/bnetserver/Packets/PacketsBase.h b/src/server/bnetserver/Packets/PacketsBase.h
deleted file mode 100644
index 856fbe258c3..00000000000
--- a/src/server/bnetserver/Packets/PacketsBase.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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 PacketsBase_h__
-#define PacketsBase_h__
-
-#include "AuthCodes.h"
-#include "BitStream.h"
-#include "Common.h"
-#include "Errors.h"
-#include "PacketsCommon.h"
-#include <string>
-#include <boost/asio/ip/tcp.hpp>
-
-using boost::asio::ip::tcp;
-
-namespace Battlenet
-{
- class BitStream;
- class Session;
-
- enum Channel
- {
- AUTHENTICATION = 0,
- CONNECTION = 1,
- WOWREALM = 2,
- FRIENDS = 3,
- PRESENCE = 4,
- CHAT = 5,
- SUPPORT = 7,
- ACHIEVEMENT = 8,
- CACHE = 11,
- PROFILE = 14
- };
-
- struct PacketHeader : public PrintableComponent
- {
- PacketHeader(uint32 opcode, uint32 channel) : Command(opcode), Channel(channel) { }
- PacketHeader() : Command(0), Channel(AUTHENTICATION) { }
-
- uint32 Command;
- int32 Channel;
-
- bool operator<(PacketHeader const& right) const
- {
- if (Command < right.Command)
- return true;
- if (Command > right.Command)
- return false;
-
- return Channel < right.Channel;
- }
-
- bool operator==(PacketHeader const& right) const
- {
- return Command == right.Command && Channel == right.Channel;
- }
-
- std::string ToString() const override;
- };
-
- class Packet : public PrintableComponent
- {
- public:
- Packet(PacketHeader const& header, BitStream& stream) : _header(header), _stream(stream) { }
- virtual ~Packet() { }
-
- PacketHeader const& GetHeader() const { return _header; }
-
- virtual void Write() = 0;
- virtual void Read() = 0;
-
- protected:
- PacketHeader _header;
- BitStream& _stream;
-
- private:
- Packet(Packet const& right) = delete;
- Packet& operator=(Packet const& right) = delete;
- };
-
- class ClientPacket : public Packet
- {
- public:
- ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { }
-
- void Write() override final { ASSERT(!"Write not implemented for client packets."); }
- virtual void CallHandler(Session* session);
- };
-
- class ServerPacket : public Packet
- {
- public:
- ServerPacket(PacketHeader const& header);
- ~ServerPacket();
-
- void Read() override final { ASSERT(!"Read not implemented for server packets."); }
-
- uint8* GetData() { return _stream.GetBuffer(); }
- uint8 const* GetData() const { return _stream.GetBuffer(); }
- size_t GetSize() const { return _stream.GetSize(); }
- };
-}
-
-#endif // PacketsBase_h__
diff --git a/src/server/bnetserver/Packets/PacketsCommon.cpp b/src/server/bnetserver/Packets/PacketsCommon.cpp
deleted file mode 100644
index 59ab8540faf..00000000000
--- a/src/server/bnetserver/Packets/PacketsCommon.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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 "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
deleted file mode 100644
index c2a264c3eae..00000000000
--- a/src/server/bnetserver/Packets/PacketsCommon.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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 PacketsCommon_h__
-#define PacketsCommon_h__
-
-#include "Common.h"
-#include "Realm/Realm.h"
-#include <typeinfo>
-
-namespace Battlenet
-{
- struct PrintableComponent
- {
- virtual ~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/ProfilePackets.h b/src/server/bnetserver/Packets/ProfilePackets.h
deleted file mode 100644
index afa2f076c58..00000000000
--- a/src/server/bnetserver/Packets/ProfilePackets.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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 ProfilePackets_h__
-#define ProfilePackets_h__
-
-#include "PacketsBase.h"
-
-namespace Battlenet
-{
- namespace Profile
- {
- enum Opcode
- {
- CMSG_READ_REQUEST = 0x0, // Not implemented
- CMSG_ADDRESS_QUERY_REQUEST = 0x1, // Not implemented
- CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST = 0x2, // Not implemented
- CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST = 0x3, // Not implemented
- CMSG_CHANGE_SETTINGS = 0x5, // Not implemented
-
- SMSG_READ_RESPONSE = 0x0, // Not implemented
- SMSG_ADDRESS_QUERY_RESPONSE = 0x1, // Not implemented
- SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE = 0x2, // Not implemented
- SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE = 0x3, // Not implemented
- SMSG_SETTINGS_AVAILABLE = 0x4 // Not implemented
- };
- }
-}
-
-#endif // ProfilePackets_h__
diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.cpp b/src/server/bnetserver/Packets/WoWRealmPackets.cpp
deleted file mode 100644
index ca066b9064c..00000000000
--- a/src/server/bnetserver/Packets/WoWRealmPackets.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * 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 "WoWRealmPackets.h"
-#include "Session.h"
-#include <boost/lexical_cast.hpp>
-#include <boost/asio/ip/address.hpp>
-
-void Battlenet::WoWRealm::ListSubscribeRequest::CallHandler(Session* session)
-{
- session->HandleListSubscribeRequest(*this);
-}
-
-void Battlenet::WoWRealm::ListUnsubscribe::CallHandler(Session* session)
-{
- session->HandleListUnsubscribe(*this);
-}
-
-void Battlenet::WoWRealm::JoinRequestV2::Read()
-{
- 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" << std::endl;
- APPEND_FIELD(stream, Id);
- APPEND_FIELD(stream, ClientSalt);
- return stream.str();
-}
-
-void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session)
-{
- session->HandleJoinRequestV2(*this);
-}
-
-void Battlenet::WoWRealm::ListSubscribeResponse::Write()
-{
- _stream.Write(Type, 1);
- if (Type == SUCCESS)
- {
- _stream.Write(ToonCounts.size(), 7);
- for (ToonCountEntry const& entry : ToonCounts)
- {
- _stream.Write(entry.Realm.Region, 8);
- _stream.WriteSkip(12);
- _stream.Write(entry.Realm.Site, 8);
- _stream.Write(entry.Realm.Realm, 32);
- _stream.Write(entry.Count, 16);
- }
- }
- else
- _stream.Write(Failure, 8);
-}
-
-std::string Battlenet::WoWRealm::ListSubscribeResponse::ToonCountEntry::ToString() const
-{
- std::ostringstream stream;
- stream << "Battlenet::WoWRealm::ListSubscribeResponse::ToonCountEntry" << std::endl;
- APPEND_FIELD(stream, Realm);
- APPEND_FIELD(stream, Count);
- return stream.str();
-}
-
-std::string Battlenet::WoWRealm::ListSubscribeResponse::ToString() const
-{
- std::ostringstream stream;
- stream << "Battlenet::WoWRealm::ListSubscribeResponse" << std::endl;
-
- if (Type == SUCCESS)
- APPEND_FIELD(stream, ToonCounts);
- else
- APPEND_FIELD(stream, Failure);
-
- return stream.str();
-}
-
-void Battlenet::WoWRealm::ListUpdate::Write()
-{
- _stream.Write(State.Type, 1);
- if (State.Type == StateType::UPDATE)
- {
- _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(State.Update.PrivilegedData->Version, 5);
- _stream.Write(State.Update.PrivilegedData->ConfigId, 32);
-
- 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);
-
- _stream.WriteBytes(ip.data(), 4);
- _stream.WriteBytes(&port, 2);
- }
-
- _stream.Write(State.Update.InfoFlags, 8);
- }
-
- _stream.Write(Id.Region, 8);
- _stream.WriteSkip(12);
- _stream.Write(Id.Site, 8);
- _stream.Write(Id.Realm, 32);
-}
-
-std::string Battlenet::WoWRealm::ListUpdate::PrivilegedDataType::ToString() const
-{
- std::ostringstream stream;
- stream << "Battlenet::WoWRealm::RealmInfo::PrivilegedData" << std::endl;
- APPEND_FIELD(stream, Version);
- APPEND_FIELD(stream, ConfigId);
- APPEND_FIELD(stream, Address);
- return stream.str();
-}
-
-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
- APPEND_FIELD(stream, Delete);
-
- 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(Name.Region, 8);
- _stream.WriteFourCC(Name.ProgramId);
- _stream.Write(Name.Realm, 32);
- _stream.WriteString(Name.Name, 7, -2);
- _stream.WriteSkip(21);
- _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" << std::endl;
- APPEND_FIELD(stream, Name);
- APPEND_FIELD(stream, Handle);
- APPEND_FIELD(stream, ProfileAddress);
- return stream.str();
-}
-
-void Battlenet::WoWRealm::JoinResponseV2::Write()
-{
- _stream.Write(Type, 1);
- if (Type == SUCCESS)
- {
- _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();
-
- EndianConvertReverse(port);
-
- _stream.WriteBytes(ip.data(), 4);
- _stream.WriteBytes(&port, 2);
- }
-
- _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();
-
- EndianConvertReverse(port);
-
- _stream.WriteBytes(ip.data(), 16);
- _stream.WriteBytes(&port, 2);
- }
- }
- else
- _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" << std::endl;
-
- if (Type == SUCCESS)
- APPEND_FIELD(stream, Success);
- else
- APPEND_FIELD(stream, Failure);
-
- return stream.str();
-}
diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h
deleted file mode 100644
index 320270abb61..00000000000
--- a/src/server/bnetserver/Packets/WoWRealmPackets.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * 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 WoWRealmPackets_h__
-#define WoWRealmPackets_h__
-
-#include "PacketsBase.h"
-#include "RealmList.h"
-
-namespace Battlenet
-{
- namespace WoWRealm
- {
- enum Opcode
- {
- CMSG_LIST_SUBSCRIBE_REQUEST = 0x0,
- CMSG_LIST_UNSUBSCRIBE = 0x1,
- CMSG_JOIN_REQUEST_V2 = 0x8,
- CMSG_MULTI_LOGON_REQUEST_V2 = 0x9, // Not implemented
-
- SMSG_LIST_SUBSCRIBE_RESPONSE = 0x0,
- SMSG_LIST_UPDATE = 0x2,
- SMSG_LIST_COMPLETE = 0x3,
- SMSG_TOON_READY = 0x6, // Not implemented
- SMSG_TOON_LOGGED_OUT = 0x7, // Not implemented
- SMSG_JOIN_RESPONSE_V2 = 0x8
- };
-
- class ListSubscribeRequest final : public ClientPacket
- {
- public:
- ListSubscribeRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM) && "Invalid packet header for ListSubscribeRequest");
- }
-
- void Read() override { }
- std::string ToString() const override { return "Battlenet::WoWRealm::ListSubscribeRequest"; }
-
- void CallHandler(Session* session) override;
- };
-
- class ListUnsubscribe final : public ClientPacket
- {
- public:
- ListUnsubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_LIST_UNSUBSCRIBE, WOWREALM) && "Invalid packet header for ListUnsubscribe");
- }
-
- void Read() override { }
- std::string ToString() const override { return "Battlenet::WoWRealm::ListUnsubscribe"; }
- void CallHandler(Session* session) override;
- };
-
- class JoinRequestV2 final : public ClientPacket
- {
- public:
- JoinRequestV2(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
- {
- ASSERT(header == PacketHeader(CMSG_JOIN_REQUEST_V2, WOWREALM) && "Invalid packet header for RealmJoinRequest");
- }
-
- void Read() override;
- std::string ToString() const override;
- void CallHandler(Session* session) override;
-
- uint32 ClientSalt = 0;
- PrintableRealmHandle Id;
- };
-
- class ListSubscribeResponse final : public ServerPacket
- {
- public:
- ListSubscribeResponse() : ServerPacket(PacketHeader(SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM))
- {
- }
-
- struct ToonCountEntry : public PrintableComponent
- {
- ToonCountEntry(PrintableRealmHandle const& realm, uint16 count) : Realm(realm), Count(count) { }
-
- PrintableRealmHandle Realm;
- uint16 Count;
-
- std::string ToString() const override;
- };
-
- void Write() override;
- std::string ToString() const override;
-
- enum
- {
- SUCCESS = 0,
- FAILURE = 1
- };
-
- int32 Type = SUCCESS;
-
- std::vector<ToonCountEntry> ToonCounts;
- Wow::AuthResult Failure = Wow::WOW_SUCCESS;
- };
-
- class ListUpdate final : public ServerPacket
- {
- public:
- ListUpdate() : ServerPacket(PacketHeader(SMSG_LIST_UPDATE, WOWREALM))
- {
- }
-
- void Write() override;
- std::string ToString() const override;
-
- 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
- {
- public:
- ListComplete() : ServerPacket(PacketHeader(SMSG_LIST_COMPLETE, WOWREALM))
- {
- }
-
- void Write() override { }
- std::string ToString() const override { return "Battlenet::WoWRealm::ListComplete"; }
- };
-
- class ToonReady final : public ServerPacket
- {
- public:
- ToonReady() : ServerPacket(PacketHeader(SMSG_TOON_READY, WOWREALM))
- {
- }
-
- void Write() override;
- std::string ToString() const override;
-
- Toon::FullName Name;
- Toon::Handle Handle;
- Profile::RecordAddress ProfileAddress;
- };
-
- class ToonLoggedOut final : public ServerPacket
- {
- public:
- ToonLoggedOut() : ServerPacket(PacketHeader(SMSG_TOON_LOGGED_OUT, WOWREALM))
- {
- }
-
- void Write() override { }
- std::string ToString() const override { return "Battlenet::WoWRealm::ToonLoggedOut"; }
- };
-
- class JoinResponseV2 final : public ServerPacket
- {
- public:
- JoinResponseV2() : ServerPacket(PacketHeader(SMSG_JOIN_RESPONSE_V2, WOWREALM))
- {
- }
-
- void Write() override;
- std::string ToString() const override;
-
- enum
- {
- SUCCESS = 0,
- FAILURE = 1
- };
-
- int32 Type = SUCCESS;
- struct SuccessType : public PrintableComponent
- {
- uint32 ServerSalt;
- std::vector<tcp::endpoint> IPv4;
- std::vector<tcp::endpoint> IPv6;
-
- std::string ToString() const override;
- } Success;
-
- Wow::AuthResult Failure = Wow::WOW_SUCCESS;
- };
- }
-}
-
-#endif // WoWRealmPackets_h__
diff --git a/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h
index 82cd5393489..0be88a714d5 100644
--- a/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h
+++ b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h
@@ -1,10 +1,5 @@
-#include "Common.h"
#include "Configuration/Config.h"
-#include "Database/DatabaseEnv.h"
-#include "Log.h"
-#include "ComponentManager.h"
-#include "ModuleManager.h"
-#include "RealmList.h"
-#include "ByteBuffer.h"
-#include "Packets.h"
-#include "Session.h"
+#include "LoginRESTService.h"
+#include "SessionManager.h"
+#include "SslContext.h"
+#include "ServiceDispatcher.h"
diff --git a/src/server/bnetserver/REST/LoginRESTService.cpp b/src/server/bnetserver/REST/LoginRESTService.cpp
new file mode 100644
index 00000000000..9ce21be9459
--- /dev/null
+++ b/src/server/bnetserver/REST/LoginRESTService.cpp
@@ -0,0 +1,433 @@
+/*
+ * 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 "LoginRESTService.h"
+#include "Configuration/Config.h"
+#include "DatabaseEnv.h"
+#include "ProtobufJSON.h"
+#include "Realm.h"
+#include "SessionManager.h"
+#include "SHA1.h"
+#include "SHA256.h"
+#include "SslContext.h"
+#include "Util.h"
+#include "httpget.h"
+#include "httppost.h"
+#include "soapH.h"
+
+int ns1__executeCommand(soap*, char*, char**) { return SOAP_OK; }
+
+int32 handle_get_plugin(soap* soapClient)
+{
+ return sLoginService.HandleGet(soapClient);
+}
+
+int32 handle_post_plugin(soap* soapClient)
+{
+ return sLoginService.HandlePost(soapClient);
+}
+
+bool LoginRESTService::Start(boost::asio::io_service& ioService)
+{
+ _bindIP = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
+ _port = sConfigMgr->GetIntDefault("LoginREST.Port", 8081);
+ if (_port < 0 || _port > 0xFFFF)
+ {
+ TC_LOG_ERROR("server.rest", "Specified login service port (%d) out of allowed range (1-65535), defaulting to 8081", _port);
+ _port = 8081;
+ }
+
+ boost::system::error_code ec;
+ boost::asio::ip::tcp::resolver resolver(ioService);
+ boost::asio::ip::tcp::resolver::iterator end;
+
+ std::string configuredAddress = sConfigMgr->GetStringDefault("LoginREST.ExternalAddress", "127.0.0.1");
+ boost::asio::ip::tcp::resolver::query externalAddressQuery(boost::asio::ip::tcp::v4(), configuredAddress, std::to_string(_port));
+ boost::asio::ip::tcp::resolver::iterator endPoint = resolver.resolve(externalAddressQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("server.rest", "Could not resolve LoginREST.ExternalAddress %s", configuredAddress.c_str());
+ return false;
+ }
+
+ _externalAddress = endPoint->endpoint();
+
+ configuredAddress = sConfigMgr->GetStringDefault("LoginREST.LocalAddress", "127.0.0.1");
+ boost::asio::ip::tcp::resolver::query localAddressQuery(boost::asio::ip::tcp::v4(), configuredAddress, std::to_string(_port));
+ endPoint = resolver.resolve(localAddressQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("server.rest", "Could not resolve LoginREST.ExternalAddress %s", configuredAddress.c_str());
+ return false;
+ }
+
+ _localAddress = endPoint->endpoint();
+
+ // set up form inputs
+ Battlenet::JSON::Login::FormInput* input;
+ _formInputs.set_type(Battlenet::JSON::Login::LOGIN_FORM);
+ input = _formInputs.add_inputs();
+ input->set_input_id("account_name");
+ input->set_type("text");
+ input->set_label("E-mail");
+ input->set_max_length(320);
+
+ input = _formInputs.add_inputs();
+ input->set_input_id("password");
+ input->set_type("password");
+ input->set_label("Password");
+ input->set_max_length(16);
+
+ input = _formInputs.add_inputs();
+ input->set_input_id("log_in_submit");
+ input->set_type("submit");
+ input->set_label("Log In");
+
+ _loginTicketCleanupTimer = new boost::asio::deadline_timer(ioService);
+ _loginTicketCleanupTimer->expires_from_now(boost::posix_time::seconds(10));
+ _loginTicketCleanupTimer->async_wait(std::bind(&LoginRESTService::CleanupLoginTickets, this, std::placeholders::_1));
+
+ _thread = std::thread(std::bind(&LoginRESTService::Run, this));
+ return true;
+}
+
+void LoginRESTService::Stop()
+{
+ _stopped = true;
+ _loginTicketCleanupTimer->cancel();
+ _thread.join();
+}
+
+boost::asio::ip::tcp::endpoint const& LoginRESTService::GetAddressForClient(boost::asio::ip::address const& address) const
+{
+ if (address.is_loopback())
+ return _localAddress;
+
+ if (boost::asio::ip::address_v4::netmask(_localAddress.address().to_v4()).to_ulong() & address.to_v4().to_ulong())
+ return _localAddress;
+
+ return _externalAddress;
+}
+
+void LoginRESTService::Run()
+{
+ soap soapServer(SOAP_C_UTFSTRING, SOAP_C_UTFSTRING);
+
+ // check every 3 seconds if world ended
+ soapServer.accept_timeout = 3;
+ soapServer.recv_timeout = 5;
+ soapServer.send_timeout = 5;
+ if (!soap_valid_socket(soap_bind(&soapServer, _bindIP.c_str(), _port, 100)))
+ {
+ TC_LOG_ERROR("server.rest", "Couldn't bind to %s:%d", _bindIP.c_str(), _port);
+ return;
+ }
+
+ TC_LOG_INFO("server.rest", "Login service bound to http://%s:%d", _bindIP.c_str(), _port);
+
+ http_post_handlers handlers[] =
+ {
+ { "application/json;charset=utf-8", handle_post_plugin },
+ { "application/json", handle_post_plugin },
+ { NULL }
+ };
+
+ soap_register_plugin_arg(&soapServer, &http_get, handle_get_plugin);
+ soap_register_plugin_arg(&soapServer, &http_post, handlers);
+ soap_register_plugin_arg(&soapServer, &ContentTypePlugin::Init, "application/json;charset=utf-8");
+
+ // Use our already ready ssl context
+ soapServer.ctx = Battlenet::SslContext::instance().native_handle();
+ soapServer.ssl_flags = SOAP_SSL_RSA;
+
+ while (!_stopped)
+ {
+ if (!soap_valid_socket(soap_accept(&soapServer)))
+ continue; // ran into an accept timeout
+
+ std::unique_ptr<soap> soapClient = Trinity::make_unique<soap>(soapServer);
+ boost::asio::ip::address_v4 address(soapClient->ip);
+ if (soap_ssl_accept(soapClient.get()) != SOAP_OK)
+ {
+ TC_LOG_DEBUG("server.rest", "Failed SSL handshake from IP=%s", address.to_string().c_str());
+ continue;
+ }
+
+ TC_LOG_DEBUG("server.rest", "Accepted connection from IP=%s", address.to_string().c_str());
+
+ std::thread([soapClient{ std::move(soapClient) }]
+ {
+ soap_serve(soapClient.get());
+ }).detach();
+ }
+
+ // and release the context handle here - soap does not own it so it should not free it on exit
+ soapServer.ctx = nullptr;
+
+ TC_LOG_INFO("server.rest", "Login service exiting...");
+}
+
+int32 LoginRESTService::HandleGet(soap* soapClient)
+{
+ boost::asio::ip::address_v4 address(soapClient->ip);
+ std::string ip_address = address.to_string();
+
+ TC_LOG_DEBUG("server.rest", "[%s:%d] Handling GET request path=\"%s\"", ip_address.c_str(), soapClient->port, soapClient->path);
+
+ static std::string const expectedPath = "/bnetserver/login/";
+ if (strstr(soapClient->path, expectedPath.c_str()) != &soapClient->path[0])
+ return 404;
+
+ return SendResponse(soapClient, _formInputs);
+}
+
+int32 LoginRESTService::HandlePost(soap* soapClient)
+{
+ boost::asio::ip::address_v4 address(soapClient->ip);
+ std::string ip_address = address.to_string();
+
+ TC_LOG_DEBUG("server.rest", "[%s:%d] Handling POST request path=\"%s\"", ip_address.c_str(), soapClient->port, soapClient->path);
+
+ static std::string const expectedPath = "/bnetserver/login/";
+ if (strstr(soapClient->path, expectedPath.c_str()) != &soapClient->path[0])
+ return 404;
+
+ char *buf;
+ size_t len;
+ soap_http_body(soapClient, &buf, &len);
+
+ Battlenet::JSON::Login::LoginForm loginForm;
+ Battlenet::JSON::Login::LoginResult loginResult;
+ if (!JSON::Deserialize(buf, &loginForm))
+ {
+ if (soap_register_plugin_arg(soapClient, &ResponseCodePlugin::Init, nullptr) != SOAP_OK)
+ return 500;
+
+ ResponseCodePlugin* responseCode = reinterpret_cast<ResponseCodePlugin*>(soap_lookup_plugin(soapClient, ResponseCodePlugin::PluginId));
+ ASSERT(responseCode);
+
+ responseCode->ErrorCode = 400;
+
+ loginResult.set_authentication_state(Battlenet::JSON::Login::LOGIN);
+ loginResult.set_error_code("UNABLE_TO_DECODE");
+ loginResult.set_error_message("There was an internal error while connecting to Battle.net. Please try again later.");
+ return SendResponse(soapClient, loginResult);
+ }
+
+ std::string login;
+ std::string password;
+
+ for (int32 i = 0; i < loginForm.inputs_size(); ++i)
+ {
+ if (loginForm.inputs(i).input_id() == "account_name")
+ login = loginForm.inputs(i).value();
+ else if (loginForm.inputs(i).input_id() == "password")
+ password = loginForm.inputs(i).value();
+ }
+
+ Utf8ToUpperOnlyLatin(login);
+ Utf8ToUpperOnlyLatin(password);
+
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO);
+ stmt->setString(0, login);
+ stmt->setString(1, CalculateShaPassHash(login, std::move(password)));
+ if (PreparedQueryResult result = LoginDatabase.Query(stmt))
+ {
+ std::unique_ptr<Battlenet::Session::AccountInfo> accountInfo = Trinity::make_unique<Battlenet::Session::AccountInfo>();
+ accountInfo->LoadResult(result);
+
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID);
+ stmt->setUInt32(0, accountInfo->Id);
+ if (PreparedQueryResult characterCountsResult = LoginDatabase.Query(stmt))
+ {
+ do
+ {
+ Field* fields = characterCountsResult->Fetch();
+ accountInfo->GameAccounts[fields[0].GetUInt32()]
+ .CharacterCounts[Battlenet::RealmHandle{ fields[3].GetUInt8(), fields[4].GetUInt8(), fields[2].GetUInt32() }.GetAddress()] = fields[1].GetUInt8();
+
+ } while (characterCountsResult->NextRow());
+ }
+
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_LAST_PLAYER_CHARACTERS);
+ stmt->setUInt32(0, accountInfo->Id);
+ if (PreparedQueryResult lastPlayerCharactersResult = LoginDatabase.Query(stmt))
+ {
+ Field* fields = lastPlayerCharactersResult->Fetch();
+ Battlenet::RealmHandle realmId{ fields[1].GetUInt8(), fields[2].GetUInt8(), fields[3].GetUInt32() };
+ Battlenet::Session::LastPlayedCharacterInfo& lastPlayedCharacter = accountInfo->GameAccounts[fields[0].GetUInt32()]
+ .LastPlayedCharacters[realmId.GetSubRegionAddress()];
+
+ lastPlayedCharacter.RealmId = realmId;
+ lastPlayedCharacter.CharacterName = fields[4].GetString();
+ lastPlayedCharacter.CharacterGUID = fields[5].GetUInt64();
+ lastPlayedCharacter.LastPlayedTime = fields[6].GetUInt32();
+ }
+
+ BigNumber ticket;
+ ticket.SetRand(20 * 8);
+
+ loginResult.set_login_ticket("TC-" + ByteArrayToHexStr(ticket.AsByteArray(20).get(), 20));
+
+ AddLoginTicket(loginResult.login_ticket(), std::move(accountInfo));
+ }
+
+ loginResult.set_authentication_state(Battlenet::JSON::Login::DONE);
+ return SendResponse(soapClient, loginResult);
+}
+
+int32 LoginRESTService::SendResponse(soap* soapClient, google::protobuf::Message const& response)
+{
+ std::string jsonResponse = JSON::Serialize(response);
+
+ soap_response(soapClient, SOAP_FILE);
+ soap_send_raw(soapClient, jsonResponse.c_str(), jsonResponse.length());
+ return soap_end_send(soapClient);
+}
+
+std::string LoginRESTService::CalculateShaPassHash(std::string const& name, std::string const& password)
+{
+ SHA256Hash email;
+ email.UpdateData(name);
+ email.Finalize();
+
+ SHA256Hash sha;
+ sha.UpdateData(ByteArrayToHexStr(email.GetDigest(), email.GetLength()));
+ sha.UpdateData(":");
+ sha.UpdateData(password);
+ sha.Finalize();
+
+ return ByteArrayToHexStr(sha.GetDigest(), sha.GetLength(), true);
+}
+
+std::unique_ptr<Battlenet::Session::AccountInfo> LoginRESTService::VerifyLoginTicket(std::string const& id)
+{
+ std::unique_lock<std::mutex> lock(_loginTicketMutex);
+
+ auto itr = _validLoginTickets.find(id);
+ if (itr != _validLoginTickets.end())
+ {
+ if (itr->second.ExpiryTime > time(nullptr))
+ {
+ std::unique_ptr<Battlenet::Session::AccountInfo> accountInfo = std::move(itr->second.Account);
+ _validLoginTickets.erase(itr);
+ return accountInfo;
+ }
+ }
+
+ return std::unique_ptr<Battlenet::Session::AccountInfo>();
+}
+
+void LoginRESTService::AddLoginTicket(std::string const& id, std::unique_ptr<Battlenet::Session::AccountInfo> accountInfo)
+{
+ std::unique_lock<std::mutex> lock(_loginTicketMutex);
+
+ _validLoginTickets[id] = { id, std::move(accountInfo), time(nullptr) + 10 };
+}
+
+void LoginRESTService::CleanupLoginTickets(boost::system::error_code const& error)
+{
+ if (error)
+ return;
+
+ time_t now = time(nullptr);
+
+ {
+ std::unique_lock<std::mutex> lock(_loginTicketMutex);
+ for (auto itr = _validLoginTickets.begin(); itr != _validLoginTickets.end();)
+ {
+ if (itr->second.ExpiryTime < now)
+ itr = _validLoginTickets.erase(itr);
+ else
+ ++itr;
+ }
+ }
+
+ _loginTicketCleanupTimer->expires_from_now(boost::posix_time::seconds(10));
+ _loginTicketCleanupTimer->async_wait(std::bind(&LoginRESTService::CleanupLoginTickets, this, std::placeholders::_1));
+}
+
+Namespace namespaces[] =
+{
+ { NULL, NULL, NULL, NULL }
+};
+
+LoginRESTService& LoginRESTService::Instance()
+{
+ static LoginRESTService instance;
+ return instance;
+}
+
+char const* const LoginRESTService::ResponseCodePlugin::PluginId = "bnet-error-code";
+
+int32 LoginRESTService::ResponseCodePlugin::Init(soap* s, soap_plugin* p, void* /*arg*/)
+{
+ ResponseCodePlugin* data = new ResponseCodePlugin();
+ data->fresponse = s->fresponse;
+
+ p->id = PluginId;
+ p->fdelete = &Destroy;
+ p->data = data;
+
+ s->fresponse = &ChangeResponse;
+ return SOAP_OK;
+}
+
+void LoginRESTService::ResponseCodePlugin::Destroy(soap* s, soap_plugin* p)
+{
+ ResponseCodePlugin* data = reinterpret_cast<ResponseCodePlugin*>(p->data);
+ s->fresponse = data->fresponse;
+ delete data;
+}
+
+int32 LoginRESTService::ResponseCodePlugin::ChangeResponse(soap* s, int32 originalResponse, size_t contentLength)
+{
+ ResponseCodePlugin* self = reinterpret_cast<ResponseCodePlugin*>(soap_lookup_plugin(s, PluginId));
+ return self->fresponse(s, self->ErrorCode && originalResponse == SOAP_FILE ? self->ErrorCode : originalResponse, contentLength);
+}
+
+char const* const LoginRESTService::ContentTypePlugin::PluginId = "bnet-content-type";
+
+int32 LoginRESTService::ContentTypePlugin::Init(soap* s, soap_plugin* p, void* arg)
+{
+ ContentTypePlugin* data = new ContentTypePlugin();
+ data->fposthdr = s->fposthdr;
+ data->ContentType = reinterpret_cast<char const*>(arg);
+
+ p->id = PluginId;
+ p->fdelete = &Destroy;
+ p->data = data;
+
+ s->fposthdr = &OnSetHeader;
+ return SOAP_OK;
+}
+
+void LoginRESTService::ContentTypePlugin::Destroy(soap* s, soap_plugin* p)
+{
+ ContentTypePlugin* data = reinterpret_cast<ContentTypePlugin*>(p->data);
+ s->fposthdr = data->fposthdr;
+ delete data;
+}
+
+int32 LoginRESTService::ContentTypePlugin::OnSetHeader(soap* s, char const* key, char const* value)
+{
+ ContentTypePlugin* self = reinterpret_cast<ContentTypePlugin*>(soap_lookup_plugin(s, PluginId));
+ if (key && !strcmp("Content-Type", key))
+ value = self->ContentType;
+
+ return self->fposthdr(s, key, value);
+}
diff --git a/src/server/bnetserver/REST/LoginRESTService.h b/src/server/bnetserver/REST/LoginRESTService.h
new file mode 100644
index 00000000000..01c08577688
--- /dev/null
+++ b/src/server/bnetserver/REST/LoginRESTService.h
@@ -0,0 +1,108 @@
+/*
+ * 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 LoginRESTService_h__
+#define LoginRESTService_h__
+
+#include "Session.h"
+#include "Define.h"
+#include "Login.pb.h"
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/deadline_timer.hpp>
+#include <atomic>
+#include <mutex>
+#include <thread>
+
+struct soap;
+struct soap_plugin;
+
+class LoginRESTService
+{
+public:
+ LoginRESTService() : _stopped(false), _port(0) { }
+
+ static LoginRESTService& Instance();
+
+ bool Start(boost::asio::io_service& ioService);
+ void Stop();
+
+ boost::asio::ip::tcp::endpoint const& GetAddressForClient(boost::asio::ip::address const& address) const;
+
+ std::unique_ptr<Battlenet::Session::AccountInfo> VerifyLoginTicket(std::string const& id);
+
+private:
+ void Run();
+
+ friend int32 handle_get_plugin(soap* soapClient);
+ int32 HandleGet(soap* soapClient);
+
+ friend int32 handle_post_plugin(soap* soapClient);
+ int32 HandlePost(soap* soapClient);
+
+ int32 SendResponse(soap* soapClient, google::protobuf::Message const& response);
+
+ std::string CalculateShaPassHash(std::string const& name, std::string const& password);
+
+ void AddLoginTicket(std::string const& id, std::unique_ptr<Battlenet::Session::AccountInfo> accountInfo);
+ void CleanupLoginTickets(boost::system::error_code const& error);
+
+ struct LoginTicket
+ {
+ std::string Id;
+ std::unique_ptr<Battlenet::Session::AccountInfo> Account;
+ std::time_t ExpiryTime;
+ };
+
+ struct ResponseCodePlugin
+ {
+ static char const* const PluginId;
+ static int32 Init(soap* s, soap_plugin*, void*);
+ static void Destroy(soap* s, soap_plugin* p);
+ static int32 ChangeResponse(soap* s, int32 originalResponse, size_t contentLength);
+
+ int32(*fresponse)(soap* s, int32 status, size_t length);
+ int32 ErrorCode;
+ };
+
+ struct ContentTypePlugin
+ {
+ static char const* const PluginId;
+ static int32 Init(soap* s, soap_plugin* p, void*);
+ static void Destroy(soap* s, soap_plugin* p);
+ static int32 OnSetHeader(soap* s, char const* key, char const* value);
+
+ int32(*fposthdr)(soap* s, char const* key, char const* value);
+ char const* ContentType;
+ };
+
+ std::thread _thread;
+ std::atomic<bool> _stopped;
+ Battlenet::JSON::Login::FormInputs _formInputs;
+ std::string _bindIP;
+ int32 _port;
+ boost::asio::ip::tcp::endpoint _externalAddress;
+ boost::asio::ip::tcp::endpoint _localAddress;
+ std::mutex _loginTicketMutex;
+ std::unordered_map<std::string, LoginTicket> _validLoginTickets;
+ boost::asio::deadline_timer* _loginTicketCleanupTimer;
+};
+
+#define sLoginService LoginRESTService::Instance()
+
+#endif // LoginRESTService_h__
diff --git a/src/server/bnetserver/Server/ComponentManager.cpp b/src/server/bnetserver/Server/ComponentManager.cpp
deleted file mode 100644
index 216c0603985..00000000000
--- a/src/server/bnetserver/Server/ComponentManager.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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 "ComponentManager.h"
-#include "DatabaseEnv.h"
-
-Battlenet::ComponentMgr::~ComponentMgr()
-{
- for (Version::Record* component : _components)
- delete component;
-}
-
-void Battlenet::ComponentMgr::Load()
-{
- QueryResult result = LoginDatabase.Query("SELECT Program, Platform, Build FROM battlenet_components");
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- 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->ProgramId);
- _platforms.insert(component->Component);
-
- } while (result->NextRow());
- }
-}
-
-bool Battlenet::ComponentMgr::HasComponent(Battlenet::Version::Record const* component) const
-{
- 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
deleted file mode 100644
index 464ddbfcd89..00000000000
--- a/src/server/bnetserver/Server/ComponentManager.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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 ComponentManager_h__
-#define ComponentManager_h__
-
-#include "Define.h"
-#include "PacketsCommon.h"
-#include <cstring>
-#include <string>
-#include <set>
-
-namespace Battlenet
-{
- class ComponentMgr
- {
- ComponentMgr() { }
- ~ComponentMgr();
-
- public:
- void Load();
- 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; }
-
- static ComponentMgr* instance()
- {
- static ComponentMgr instance;
- return &instance;
- }
-
- private:
- std::set<Version::Record*> _components;
- std::set<std::string> _programs;
- std::set<std::string> _platforms;
- };
-}
-
-#define sComponentMgr Battlenet::ComponentMgr::instance()
-
-#endif // ComponentManager_h__
diff --git a/src/server/bnetserver/Server/ModuleManager.cpp b/src/server/bnetserver/Server/ModuleManager.cpp
deleted file mode 100644
index 2919dacf2ad..00000000000
--- a/src/server/bnetserver/Server/ModuleManager.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 "ModuleManager.h"
-#include "DatabaseEnv.h"
-
-Battlenet::ModuleManager::~ModuleManager()
-{
- for (auto const& m : _modules)
- delete m.second;
-}
-
-void Battlenet::ModuleManager::Load()
-{
- QueryResult result = LoginDatabase.Query("SELECT `Hash`, `Name`, `Type`, `System`, `Data` FROM battlenet_modules");
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- ModuleInfo* module = new ModuleInfo();
- 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)
- {
- module->Data = new uint8[data.length() / 2];
- HexStrToByteArray(data, module->Data);
- }
-
- _modules[{ fields[3].GetString(), fields[1].GetString() }] = module;
- } while (result->NextRow());
- }
-}
-
-Battlenet::ModuleInfo* Battlenet::ModuleManager::CreateModule(std::string const& os, std::string const& name) const
-{
- ModuleKey key { os, name };
- if (!_modules.count(key))
- return nullptr;
-
- 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
deleted file mode 100644
index 457bae4573b..00000000000
--- a/src/server/bnetserver/Server/ModuleManager.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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 ModuleManager_h__
-#define ModuleManager_h__
-
-#include "PacketsCommon.h"
-
-namespace Battlenet
-{
- struct ModuleKey
- {
- std::string Platform;
- std::string Name;
-
- bool operator<(ModuleKey const& right) const
- {
- int32 res = Platform.compare(right.Platform);
- if (res < 0)
- return true;
- else if (res > 0)
- return false;
-
- return Name < right.Name;
- }
- };
-
- struct ModuleInfo : public PrintableComponent
- {
- ModuleInfo() : DataSize(0), Data(nullptr) { Handle.Region = "EU"; }
- ModuleInfo(ModuleInfo const& right) : DataSize(right.DataSize), Data(nullptr)
- {
- Handle.Type = right.Handle.Type;
- Handle.Region = right.Handle.Region;
- memcpy(Handle.ModuleId, right.Handle.ModuleId, 32);
- if (DataSize)
- {
- Data = new uint8[DataSize];
- memcpy(Data, right.Data, DataSize);
- }
- }
-
- virtual ~ModuleInfo()
- {
- delete[] Data;
- }
-
- Cache::Handle Handle;
- uint32 DataSize;
- uint8* Data;
-
- std::string ToString() const override;
- };
-
- class ModuleManager
- {
- ModuleManager() { }
- ~ModuleManager();
-
- public:
- void Load();
- ModuleInfo* CreateModule(std::string const& os, std::string const& name) const;
-
- static ModuleManager* instance()
- {
- static ModuleManager instance;
- return &instance;
- }
-
- private:
- std::map<ModuleKey, ModuleInfo*> _modules;
- };
-}
-
-#define sModuleMgr Battlenet::ModuleManager::instance()
-
-#endif // ModuleManager_h__
diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp
index 4d54562501f..66d55480796 100644
--- a/src/server/bnetserver/Server/Session.cpp
+++ b/src/server/bnetserver/Server/Session.cpp
@@ -15,30 +15,21 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "AuthCodes.h"
-#include "BitStream.h"
-#include "PacketManager.h"
-#include "SessionManager.h"
+#include "Session.h"
+#include "BattlenetRpcErrorCodes.h"
+#include "ByteConverter.h"
#include "Database/DatabaseEnv.h"
-#include "HmacHash.h"
-#include "Log.h"
+#include "LoginRESTService.h"
+#include "ProtobufJSON.h"
#include "RealmList.h"
-#include "SHA256.h"
-#include <map>
+#include "ServiceDispatcher.h"
+#include "RealmList.pb.h"
+#include <zlib.h>
-Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODULE_COUNT] =
-{
- &Battlenet::Session::HandlePasswordModule,
- &Battlenet::Session::UnhandledModule,
- &Battlenet::Session::UnhandledModule,
- &Battlenet::Session::HandleSelectGameAccountModule,
- &Battlenet::Session::HandleRiskFingerprintModule,
- &Battlenet::Session::HandleResumeModule,
-};
-
-void Battlenet::AccountInfo::LoadResult(Field* fields)
+void Battlenet::Session::AccountInfo::LoadResult(PreparedQueryResult result)
{
// ba.id, ba.email, ba.locked, ba.lock_country, ba.last_ip, ba.failed_logins, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab WHERE email = ?
+ Field* fields = result->Fetch();
Id = fields[0].GetUInt32();
Login = fields[1].GetString();
IsLockedToIP = fields[2].GetBool();
@@ -47,9 +38,17 @@ void Battlenet::AccountInfo::LoadResult(Field* fields)
FailedLogins = fields[5].GetUInt32();
IsBanned = fields[6].GetUInt64() != 0;
IsPermanenetlyBanned = fields[7].GetUInt64() != 0;
+
+ static uint32 const GameAccountFieldsOffset = 8;
+
+ do
+ {
+ GameAccounts[result->Fetch()[GameAccountFieldsOffset].GetUInt32()].LoadResult(result->Fetch() + GameAccountFieldsOffset);
+
+ } while (result->NextRow());
}
-void Battlenet::GameAccountInfo::LoadResult(Field* fields)
+void Battlenet::Session::GameAccountInfo::LoadResult(Field* fields)
{
// a.id, a.username, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, ab.unbandate = ab.bandate, aa.gmlevel
Id = fields[0].GetUInt32();
@@ -65,204 +64,215 @@ void Battlenet::GameAccountInfo::LoadResult(Field* fields)
DisplayName = Name;
}
-Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _accountInfo(new AccountInfo()), _gameAccountInfo(nullptr), _locale(),
- _os(), _build(0), _ipCountry(), I(), s(), v(), b(), B(), K(),
- _reconnectProof(), _crypt(), _authed(false), _subscribedToRealmListUpdates(false), _toonOnline(false)
+Battlenet::Session::Session(tcp::socket&& socket) : BattlenetSocket(std::move(socket)), _accountInfo(new AccountInfo()), _gameAccountInfo(nullptr), _locale(),
+ _os(), _build(0), _ipCountry(), _authed(false), _requestToken(0)
{
- static uint8 const N_Bytes[] =
- {
- 0xAB, 0x24, 0x43, 0x63, 0xA9, 0xC2, 0xA6, 0xC3, 0x3B, 0x37, 0xE4, 0x61, 0x84, 0x25, 0x9F, 0x8B,
- 0x3F, 0xCB, 0x8A, 0x85, 0x27, 0xFC, 0x3D, 0x87, 0xBE, 0xA0, 0x54, 0xD2, 0x38, 0x5D, 0x12, 0xB7,
- 0x61, 0x44, 0x2E, 0x83, 0xFA, 0xC2, 0x21, 0xD9, 0x10, 0x9F, 0xC1, 0x9F, 0xEA, 0x50, 0xE3, 0x09,
- 0xA6, 0xE5, 0x5E, 0x23, 0xA7, 0x77, 0xEB, 0x00, 0xC7, 0xBA, 0xBF, 0xF8, 0x55, 0x8A, 0x0E, 0x80,
- 0x2B, 0x14, 0x1A, 0xA2, 0xD4, 0x43, 0xA9, 0xD4, 0xAF, 0xAD, 0xB5, 0xE1, 0xF5, 0xAC, 0xA6, 0x13,
- 0x1C, 0x69, 0x78, 0x64, 0x0B, 0x7B, 0xAF, 0x9C, 0xC5, 0x50, 0x31, 0x8A, 0x23, 0x08, 0x01, 0xA1,
- 0xF5, 0xFE, 0x31, 0x32, 0x7F, 0xE2, 0x05, 0x82, 0xD6, 0x0B, 0xED, 0x4D, 0x55, 0x32, 0x41, 0x94,
- 0x29, 0x6F, 0x55, 0x7D, 0xE3, 0x0F, 0x77, 0x19, 0xE5, 0x6C, 0x30, 0xEB, 0xDE, 0xF6, 0xA7, 0x86
- };
-
- N.SetBinary(N_Bytes, sizeof(N_Bytes));
- g.SetDword(2);
-
- SHA256Hash sha;
- sha.UpdateBigNumbers(&N, &g, NULL);
- sha.Finalize();
- k.SetBinary(sha.GetDigest(), sha.GetLength());
+ _headerLengthBuffer.Resize(2);
}
Battlenet::Session::~Session()
{
- if (_authed)
- sSessionMgr.RemoveSession(this);
-
- delete _accountInfo;
}
-void Battlenet::Session::_SetVSFields(std::string const& pstr)
+void Battlenet::Session::AsyncHandshake()
{
- s.SetRand(uint32(BufferSizes::SRP_6_S) * 8);
+ underlying_stream().async_handshake(ssl::stream_base::server, std::bind(&Session::HandshakeHandler, shared_from_this(), std::placeholders::_1));
+}
- BigNumber p;
- p.SetHexStr(pstr.c_str());
+void Battlenet::Session::Start()
+{
+ std::string ip_address = GetRemoteIpAddress().to_string();
+ TC_LOG_TRACE("session", "%s Accepted connection", GetClientInfo().c_str());
- SHA256Hash sha;
- sha.UpdateBigNumbers(&s, &p, NULL);
- sha.Finalize();
- BigNumber x;
- x.SetBinary(sha.GetDigest(), sha.GetLength());
- v = g.ModExp(x, N);
+ // Verify that this IP is not in the ip_banned table
+ LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_VS_FIELDS);
- stmt->setString(0, v.AsHexStr());
- stmt->setString(1, s.AsHexStr());
- stmt->setString(2, _accountInfo->Login);
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_INFO);
+ stmt->setString(0, ip_address);
+ stmt->setUInt32(1, inet_addr(ip_address.c_str()));
- LoginDatabase.Execute(stmt);
+ _queryCallback = std::bind(&Battlenet::Session::CheckIpCallback, this, std::placeholders::_1);
+ _queryFuture = LoginDatabase.AsyncQuery(stmt);
}
-void Battlenet::Session::LogUnhandledPacket(PacketHeader const& header)
+void Battlenet::Session::CheckIpCallback(PreparedQueryResult result)
{
- TC_LOG_DEBUG("session.packets", "%s Received unhandled packet %s", GetClientInfo().c_str(), sPacketManager.GetClientPacketName(header));
+ if (result)
+ {
+ bool banned = false;
+ do
+ {
+ Field* fields = result->Fetch();
+ if (fields[0].GetUInt64() != 0)
+ banned = true;
+
+ if (!fields[1].GetString().empty())
+ _ipCountry = fields[1].GetString();
+
+ } while (result->NextRow());
+
+ if (banned)
+ {
+ TC_LOG_DEBUG("session", "%s tries to log in using banned IP!", GetClientInfo().c_str());
+ CloseSocket();
+ return;
+ }
+ }
+
+ AsyncHandshake();
}
-void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& logonRequest)
+bool Battlenet::Session::Update()
{
- if (_queryCallback)
- {
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(AUTH_LOGON_TOO_FAST);
- AsyncWrite(logonResponse);
- TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log too quick after previous attempt!", GetClientInfo().c_str());
- return;
- }
+ if (!BattlenetSocket::Update())
+ return false;
- if (logonRequest.Common.Program != "WoW")
+ if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
- 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.Common.Program.c_str());
- return;
+ auto callback = std::move(_queryCallback);
+ _queryCallback = nullptr;
+ callback(_queryFuture.get());
}
- 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.Common.Platform.c_str());
- return;
- }
+ return true;
+}
- 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.Common.Locale.c_str());
+void Battlenet::Session::AsyncWrite(MessageBuffer* packet)
+{
+ if (!IsOpen())
return;
- }
- for (Version::Record const& component : logonRequest.Common.Versions)
- {
- if (!sComponentMgr->HasComponent(&component))
- {
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- 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.ProgramId.c_str());
- }
- 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.Component.c_str());
- }
- else
- {
- if (component.ProgramId != "WoW" || AuthHelper::IsBuildSupportingBattlenet(component.Version))
- logonResponse->SetAuthResult(AUTH_REGION_BAD_VERSION);
- else
- logonResponse->SetAuthResult(AUTH_USE_GRUNT_LOGON);
+ QueuePacket(std::move(*packet));
+}
- TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component version %u!", GetClientInfo().c_str(), component.Version);
- }
+void Battlenet::Session::SendResponse(uint32 token, pb::Message const* response)
+{
+ Header header;
+ header.set_token(token);
+ header.set_service_id(0xFE);
+ header.set_size(response->ByteSize());
- AsyncWrite(logonResponse);
- return;
- }
+ uint16 headerSize = header.ByteSize();
+ EndianConvertReverse(headerSize);
- if (component.Component == "base")
- _build = component.Version;
- }
+ MessageBuffer packet;
+ packet.Write(&headerSize, sizeof(headerSize));
+ uint8* ptr = packet.GetWritePointer();
+ packet.WriteCompleted(header.ByteSize());
+ header.SerializeToArray(ptr, header.ByteSize());
+ ptr = packet.GetWritePointer();
+ packet.WriteCompleted(response->ByteSize());
+ response->SerializeToArray(ptr, response->ByteSize());
+
+ AsyncWrite(&packet);
+}
- std::string login = logonRequest.Account;
- _locale = logonRequest.Common.Locale;
- _os = logonRequest.Common.Platform;
+void Battlenet::Session::SendResponse(uint32 token, uint32 status)
+{
+ Header header;
+ header.set_token(token);
+ header.set_status(status);
+ header.set_service_id(0xFE);
- Utf8ToUpperOnlyLatin(login);
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO);
- stmt->setString(0, login);
+ uint16 headerSize = header.ByteSize();
+ EndianConvertReverse(headerSize);
- _queryCallback = std::bind(&Battlenet::Session::HandleLogonRequestCallback, this, std::placeholders::_1);
- _queryFuture = LoginDatabase.AsyncQuery(stmt);
+ MessageBuffer packet;
+ packet.Write(&headerSize, sizeof(headerSize));
+ uint8* ptr = packet.GetWritePointer();
+ packet.WriteCompleted(header.ByteSize());
+ header.SerializeToArray(ptr, header.ByteSize());
+
+ AsyncWrite(&packet);
}
-void Battlenet::Session::HandleLogonRequestCallback(PreparedQueryResult result)
+void Battlenet::Session::SendRequest(uint32 serviceHash, uint32 methodId, pb::Message const* request)
{
- if (!result)
+ Header header;
+ header.set_service_id(0);
+ header.set_service_hash(serviceHash);
+ header.set_method_id(methodId);
+ header.set_size(request->ByteSize());
+ header.set_token(_requestToken++);
+
+ uint16 headerSize = header.ByteSize();
+ EndianConvertReverse(headerSize);
+
+ MessageBuffer packet;
+ packet.Write(&headerSize, sizeof(headerSize));
+ uint8* ptr = packet.GetWritePointer();
+ packet.WriteCompleted(header.ByteSize());
+ header.SerializeToArray(ptr, header.ByteSize());
+ ptr = packet.GetWritePointer();
+ packet.WriteCompleted(request->ByteSize());
+ request->SerializeToArray(ptr, request->ByteSize());
+
+ AsyncWrite(&packet);
+}
+
+uint32 Battlenet::Session::HandleLogon(authentication::v1::LogonRequest const* logonRequest)
+{
+ if (logonRequest->program() != "WoW")
{
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- AsyncWrite(logonResponse);
- TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is trying to log in from unknown account!", GetClientInfo().c_str());
- return;
+ 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());
+ return ERROR_BAD_PROGRAM;
}
- Field* fields = result->Fetch();
- _accountInfo->LoadResult(fields);
-
- std::string pStr = fields[8].GetString();
- std::string databaseV = fields[9].GetString();
- std::string databaseS = fields[10].GetString();
+ if (logonRequest->platform() != "Win" && logonRequest->platform() != "Wn64" && logonRequest->platform() != "Mc64")
+ {
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in from an unsupported platform (using %s)!", GetClientInfo().c_str(), logonRequest->platform().c_str());
+ return ERROR_BAD_PLATFORM;
+ }
- _gameAccounts.resize(result->GetRowCount());
- uint32 i = 0;
- do
+ if (GetLocaleByName(logonRequest->locale()) == LOCALE_enUS && logonRequest->locale() != "enUS")
{
- _gameAccounts[i++].LoadResult(result->Fetch() + 11);
+ TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in with unsupported locale (using %s)!", GetClientInfo().c_str(), logonRequest->locale().c_str());
+ return ERROR_BAD_LOCALE;
+ }
- } while (result->NextRow());
+ _locale = logonRequest->locale();
+ _os = logonRequest->platform();
+
+ ip::tcp::endpoint const& endpoint = sLoginService.GetAddressForClient(GetRemoteIpAddress());
+
+ challenge::v1::ChallengeExternalRequest externalChallenge;
+ externalChallenge.set_payload_type("web_auth_url");
+ externalChallenge.set_payload(Trinity::StringFormat("https://%s:%u/bnetserver/login/", endpoint.address().to_string().c_str(), endpoint.port()));
+ Service<challenge::v1::ChallengeListener>(this).OnExternalChallenge(&externalChallenge);
+ return ERROR_OK;
+}
+
+uint32 Battlenet::Session::HandleVerifyWebCredentials(authentication::v1::VerifyWebCredentialsRequest const* verifyWebCredentialsRequest)
+{
+ authentication::v1::LogonResult logonResult;
+ logonResult.set_error_code(0);
+ _accountInfo = sLoginService.VerifyLoginTicket(verifyWebCredentialsRequest->web_credentials());
+ if (!_accountInfo)
+ return ERROR_DENIED;
std::string ip_address = GetRemoteIpAddress().to_string();
+
// If the IP is 'locked', check that the player comes indeed from the correct IP address
if (_accountInfo->IsLockedToIP)
{
- TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountInfo->Login.c_str(), _accountInfo->LastIP.c_str(), ip_address.c_str());
+ TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is locked to IP - '%s' is logging in from '%s'",
+ _accountInfo->Login.c_str(), _accountInfo->LastIP.c_str(), ip_address.c_str());
if (_accountInfo->LastIP != ip_address)
- {
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED);
- AsyncWrite(logonResponse);
- return;
- }
+ return ERROR_RISK_ACCOUNT_LOCKED;
}
else
{
- TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to ip", _accountInfo->Login.c_str());
+ TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is not locked to ip", _accountInfo->Login.c_str());
if (_accountInfo->LockCountry.empty() || _accountInfo->LockCountry == "00")
- TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to country", _accountInfo->Login.c_str());
+ TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is not locked to country", _accountInfo->Login.c_str());
else if (!_accountInfo->LockCountry.empty() && !_ipCountry.empty())
{
- TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to country: '%s' Player country is '%s'", _accountInfo->Login.c_str(), _accountInfo->LockCountry.c_str(), _ipCountry.c_str());
+ TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is locked to country: '%s' Player country is '%s'",
+ _accountInfo->Login.c_str(), _accountInfo->LockCountry.c_str(), _ipCountry.c_str());
+
if (_ipCountry != _accountInfo->LockCountry)
- {
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED);
- AsyncWrite(logonResponse);
- return;
- }
+ return ERROR_RISK_ACCOUNT_LOCKED;
}
}
@@ -271,886 +281,391 @@ void Battlenet::Session::HandleLogonRequestCallback(PreparedQueryResult result)
{
if (_accountInfo->IsPermanenetlyBanned)
{
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(LOGIN_BANNED);
- AsyncWrite(logonResponse);
- TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountInfo->Login.c_str());
- return;
+ TC_LOG_DEBUG("session", "%s [Session::HandleVerifyWebCredentials] Banned account %s tried to login!", GetClientInfo().c_str(), _accountInfo->Login.c_str());
+ return ERROR_GAME_ACCOUNT_BANNED;
}
else
{
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(LOGIN_SUSPENDED);
- AsyncWrite(logonResponse);
- TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountInfo->Login.c_str());
- return;
+ TC_LOG_DEBUG("session", "%s [Session::HandleVerifyWebCredentials] Temporarily banned account %s tried to login!", GetClientInfo().c_str(), _accountInfo->Login.c_str());
+ return ERROR_GAME_ACCOUNT_SUSPENDED;
}
}
- SHA256Hash sha;
- sha.UpdateData(_accountInfo->Login);
- sha.Finalize();
-
- I.SetBinary(sha.GetDigest(), sha.GetLength());
-
- ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password");
- ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint");
-
- if (databaseV.size() != size_t(BufferSizes::SRP_6_V) * 2 || databaseS.size() != size_t(BufferSizes::SRP_6_S) * 2)
- _SetVSFields(pStr);
- else
+ logonResult.mutable_account_id()->set_low(_accountInfo->Id);
+ logonResult.mutable_account_id()->set_high(UI64LIT(0x100000000000000));
+ for (auto itr = _accountInfo->GameAccounts.begin(); itr != _accountInfo->GameAccounts.end(); ++itr)
{
- s.SetHexStr(databaseS.c_str());
- v.SetHexStr(databaseV.c_str());
+ if (!itr->second.IsBanned)
+ {
+ EntityId* gameAccountId = logonResult.add_game_account_id();
+ gameAccountId->set_low(itr->second.Id);
+ gameAccountId->set_high(UI64LIT(0x200000200576F57));
+ }
}
- b.SetRand(128 * 8);
- B = ((v * k) + g.ModExp(b, N)) % N;
- BigNumber unk;
- unk.SetRand(128 * 8);
-
- BitStream passwordData;
- uint8 state = 0;
- passwordData.WriteBytes(&state, 1);
- passwordData.WriteBytes(I.AsByteArray(32).get(), 32);
- passwordData.WriteBytes(s.AsByteArray(32).get(), 32);
- passwordData.WriteBytes(B.AsByteArray(128).get(), 128);
- passwordData.WriteBytes(unk.AsByteArray(128).get(), 128);
-
- password->DataSize = passwordData.GetSize();
- password->Data = new uint8[password->DataSize];
- memcpy(password->Data, passwordData.GetBuffer(), password->DataSize);
-
- _modulesWaitingForData.push(MODULE_PASSWORD);
-
- Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
- proofRequest->Modules.push_back(password);
- // if has authenticator, send Token module
- proofRequest->Modules.push_back(thumbprint);
- AsyncWrite(proofRequest);
-}
+ if (!_ipCountry.empty())
+ logonResult.set_geoip_country(_ipCountry);
-void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest)
-{
- if (_queryCallback)
- {
- Authentication::ResumeResponse* logonResponse = new Authentication::ResumeResponse();
- logonResponse->SetAuthResult(AUTH_LOGON_TOO_FAST);
- AsyncWrite(logonResponse);
- TC_LOG_DEBUG("session", "[Battlenet::ResumeRequest] %s attempted to log too quick after previous attempt!", GetClientInfo().c_str());
- return;
- }
-
- 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;
+ BigNumber k;
+ k.SetRand(8 * 64);
+ logonResult.set_session_key(k.AsByteArray(64).get(), 64);
- Utf8ToUpperOnlyLatin(login);
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO);
- stmt->setString(0, login);
- stmt->setString(1, resumeRequest.GameAccountName);
+ _authed = true;
- _queryCallback = std::bind(&Battlenet::Session::HandleResumeRequestCallback, this, std::placeholders::_1);
- _queryFuture = LoginDatabase.AsyncQuery(stmt);
+ Service<authentication::v1::AuthenticationListener>(this).OnLogonComplete(&logonResult);
+ return ERROR_OK;
}
-void Battlenet::Session::HandleResumeRequestCallback(PreparedQueryResult result)
+uint32 Battlenet::Session::HandleGetAccountState(account::v1::GetAccountStateRequest const* request, account::v1::GetAccountStateResponse* response)
{
- if (!result)
- {
- Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
- resumeResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- AsyncWrite(resumeResponse);
- return;
- }
-
- Field* fields = result->Fetch();
- _accountInfo->LoadResult(fields);
- K.SetHexStr(fields[8].GetString().c_str());
-
- _gameAccounts.resize(1);
- _gameAccountInfo = &_gameAccounts[0];
- _gameAccountInfo->LoadResult(fields + 9);
-
- ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint");
- ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume");
- BitStream resumeData;
- uint8 state = 0;
- _reconnectProof.SetRand(16 * 8);
+ if (!_authed)
+ return ERROR_DENIED;
- resumeData.WriteBytes(&state, 1);
- resumeData.WriteBytes(_reconnectProof.AsByteArray().get(), 16);
-
- resume->DataSize = resumeData.GetSize();
- resume->Data = new uint8[resume->DataSize];
- memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize);
+ if (request->options().field_privacy_info())
+ {
+ response->mutable_state()->mutable_privacy_info()->set_is_using_rid(false);
+ response->mutable_state()->mutable_privacy_info()->set_is_real_id_visible_for_view_friends(false);
+ response->mutable_state()->mutable_privacy_info()->set_is_hidden_from_friend_finder(true);
- _modulesWaitingForData.push(MODULE_RESUME);
+ response->mutable_tags()->set_privacy_info_tag(0xD7CA834D);
+ }
- Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
- proofRequest->Modules.push_back(thumbprint);
- proofRequest->Modules.push_back(resume);
- AsyncWrite(proofRequest);
+ return ERROR_OK;
}
-void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const& proofResponse)
+uint32 Battlenet::Session::HandleGetGameAccountState(account::v1::GetGameAccountStateRequest const* request, account::v1::GetGameAccountStateResponse* response)
{
- if (_modulesWaitingForData.size() < proofResponse.Response.size())
- {
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(AUTH_CORRUPTED_MODULE);
- AsyncWrite(complete);
- return;
- }
+ if (!_authed)
+ return ERROR_DENIED;
- ServerPacket* response = nullptr;
- for (size_t i = 0; i < proofResponse.Response.size(); ++i)
+ if (request->options().field_game_level_info())
{
- if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proofResponse.Response[i], &response))
- break;
+ auto itr = _accountInfo->GameAccounts.find(request->game_account_id().low());
+ if (itr != _accountInfo->GameAccounts.end())
+ {
+ response->mutable_state()->mutable_game_level_info()->set_name(itr->second.DisplayName);
+ response->mutable_state()->mutable_game_level_info()->set_program(5730135); // WoW
+ }
- _modulesWaitingForData.pop();
+ response->mutable_tags()->set_game_level_info_tag(0x5C46D483);
}
- if (!response)
+ if (request->options().field_game_status())
{
- response = new Authentication::LogonResponse();
- static_cast<Authentication::LogonResponse*>(response)->SetAuthResult(AUTH_INTERNAL_ERROR);
- }
-
- AsyncWrite(response);
-}
-
-void Battlenet::Session::HandlePing(Connection::Ping const& /*ping*/)
-{
- AsyncWrite(new Connection::Pong());
-}
+ auto itr = _accountInfo->GameAccounts.find(request->game_account_id().low());
+ if (itr != _accountInfo->GameAccounts.end())
+ {
+ response->mutable_state()->mutable_game_status()->set_is_suspended(itr->second.IsBanned);
+ response->mutable_state()->mutable_game_status()->set_is_banned(itr->second.IsPermanenetlyBanned);
+ }
-void Battlenet::Session::HandleEnableEncryption(Connection::EnableEncryption& enableEncryption)
-{
- _crypt.Init(&K);
- _crypt.DecryptRecv(enableEncryption.GetRemainingData(), enableEncryption.GetRemainingSize());
-}
+ response->mutable_state()->mutable_game_status()->set_program(5730135); // WoW
+ response->mutable_tags()->set_game_status_tag(0x98B75F99);
+ }
-void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /*logoutRequest*/)
-{
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY);
- stmt->setString(0, "");
- stmt->setBool(1, false);
- stmt->setUInt32(2, _accountInfo->Id);
- LoginDatabase.Execute(stmt);
+ return ERROR_OK;
}
-void Battlenet::Session::HandleConnectionClosing(Connection::ConnectionClosing const& /*connectionClosing*/)
+std::unordered_map<std::string, Battlenet::Session::ClientRequestHandler> const Battlenet::Session::ClientRequestHandlers =
{
-}
+ { "Command_RealmListTicketRequest_v1_b9", &Battlenet::Session::GetRealmListTicket },
+ { "Command_LastCharPlayedRequest_v1_b9", &Battlenet::Session::GetLastCharPlayed },
+ { "Command_RealmListRequest_v1_b9", &Battlenet::Session::GetRealmList },
+ { "Command_RealmJoinRequest_v1_b9", &Battlenet::Session::JoinRealm },
+};
-void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& /*listSubscribeRequest*/)
+uint32 Battlenet::Session::HandleProcessClientRequest(game_utilities::v1::ClientRequest const* request, game_utilities::v1::ClientResponse* response)
{
- if (_subscribedToRealmListUpdates || _queryCallback)
- return;
-
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS);
- stmt->setUInt32(0, _gameAccountInfo->Id);
-
- _queryCallback = std::bind(&Battlenet::Session::HandleListSubscribeRequestCallback, this, std::placeholders::_1);
- _queryFuture = LoginDatabase.AsyncQuery(stmt);
-}
+ if (!_authed)
+ return ERROR_DENIED;
-void Battlenet::Session::HandleListSubscribeRequestCallback(PreparedQueryResult result)
-{
- WoWRealm::ListSubscribeResponse* listSubscribeResponse = new WoWRealm::ListSubscribeResponse();
+ Attribute const* command = nullptr;
+ std::unordered_map<std::string, Variant const*> params;
- if (result)
+ for (int32 i = 0; i < request->attribute_size(); ++i)
{
- do
- {
- Field* fields = result->Fetch();
- listSubscribeResponse->ToonCounts.emplace_back(PrintableRealmHandle(fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32()), uint16(fields[0].GetUInt8()));
- } while (result->NextRow());
+ Attribute const& attr = request->attribute(i);
+ params[attr.name()] = &attr.value();
+ if (strstr(attr.name().c_str(), "Command_") == attr.name().c_str())
+ command = &attr;
}
- AsyncWrite(listSubscribeResponse);
-
- for (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms())
- AsyncWrite(BuildListUpdate(&i.second));
-
- AsyncWrite(new WoWRealm::ListComplete());
-
- _subscribedToRealmListUpdates = true;
-}
-
-void Battlenet::Session::HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& /*listUnsubscribe*/)
-{
- _subscribedToRealmListUpdates = false;
-}
-
-void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest)
-{
- WoWRealm::JoinResponseV2* joinResponse = new WoWRealm::JoinResponseV2();
- Realm const* realm = sRealmList->GetRealm(joinRequest.Id);
- if (!realm || realm->Flags & (REALM_FLAG_VERSION_MISMATCH | REALM_FLAG_OFFLINE) || realm->Build != _build)
+ if (!command)
{
- joinResponse->Type = WoWRealm::JoinResponseV2::FAILURE;
- AsyncWrite(joinResponse);
- return;
+ TC_LOG_ERROR("session.rpc", "%s sent ClientRequest with no command.", GetClientInfo().c_str());
+ return ERROR_RPC_MALFORMED_REQUEST;
}
- joinResponse->Success.ServerSalt = rand32();
-
- uint8 sessionKey[40];
- HmacSha1 hmac(K.GetNumBytes(), K.AsByteArray().get());
- hmac.UpdateData((uint8*)"WoW\0", 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->Success.ServerSalt, 4);
- hmac2.UpdateData((uint8*)&joinRequest.ClientSalt, 4);
- hmac2.Finalize();
-
- memcpy(sessionKey + hmac.GetLength(), hmac2.GetDigest(), hmac2.GetLength());
-
- 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->Success.IPv4.push_back(realm->GetAddressForClient(GetRemoteIpAddress()));
-
- AsyncWrite(joinResponse);
-}
-
-void Battlenet::Session::HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest)
-{
- if (getStreamItemsRequest.Stream.Type != Cache::GetStreamItemsRequest::StreamId::DESCRIPTION)
- return;
-
- if (ModuleInfo* module = sModuleMgr->CreateModule(getStreamItemsRequest.Locale, getStreamItemsRequest.Stream.Description.ItemName))
+ auto itr = ClientRequestHandlers.find(command->name());
+ if (itr == ClientRequestHandlers.end())
{
- Cache::GetStreamItemsResponse* getStreamItemsResponse = new Cache::GetStreamItemsResponse();
- getStreamItemsResponse->Token = getStreamItemsRequest.Token;
- getStreamItemsResponse->Items.push_back(module);
- AsyncWrite(getStreamItemsResponse);
+ TC_LOG_ERROR("session.rpc", "%s sent ClientRequest with unknown command %s.", GetClientInfo().c_str(), command->name().c_str());
+ return ERROR_RPC_NOT_IMPLEMENTED;
}
-}
-inline std::string PacketToStringHelper(Battlenet::ClientPacket const* packet)
-{
- if (sLog->ShouldLog("session.packets", LOG_LEVEL_TRACE))
- return packet->ToString();
-
- return sPacketManager.GetClientPacketName(packet->GetHeader());
+ return (this->*itr->second)(params, response);
}
-inline std::string PacketToStringHelper(Battlenet::ServerPacket const* packet)
+inline Variant const* GetParam(std::unordered_map<std::string, Variant const*> const& params, char const* paramName)
{
- if (sLog->ShouldLog("session.packets", LOG_LEVEL_TRACE))
- return packet->ToString();
-
- return sPacketManager.GetServerPacketName(packet->GetHeader());
+ auto itr = params.find(paramName);
+ return itr != params.end() ? itr->second : nullptr;
}
-void Battlenet::Session::ReadHandler()
+uint32 Battlenet::Session::GetRealmListTicket(std::unordered_map<std::string, Variant const*> const& params, game_utilities::v1::ClientResponse* response)
{
- BitStream stream(std::move(GetReadBuffer()));
- _crypt.DecryptRecv(stream.GetBuffer(), stream.GetSize());
-
- while (!stream.IsRead())
+ if (Variant const* identity = GetParam(params, "Param_Identity"))
{
- try
+ ::JSON::RealmList::RealmListTicketIdentity data;
+ std::size_t jsonStart = identity->blob_value().find(':');
+ if (jsonStart != std::string::npos && ::JSON::Deserialize(identity->blob_value().substr(jsonStart + 1), &data))
{
- PacketHeader header;
- 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.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();
- return;
- }
+ auto itr = _accountInfo->GameAccounts.find(data.gameaccountid());
+ if (itr != _accountInfo->GameAccounts.end())
+ _gameAccountInfo = &itr->second;
+ }
+ }
- if (ClientPacket* packet = sPacketManager.CreateClientPacket(header, stream))
- {
- if (sPacketManager.IsHandled(header))
- TC_LOG_DEBUG("session.packets", "%s Received %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str());
+ if (!_gameAccountInfo)
+ return ERROR_UTIL_SERVER_INVALID_IDENTITY_ARGS;
- packet->CallHandler(this);
- delete packet;
- }
- else if (sPacketManager.GetClientPacketName(header))
- {
- LogUnhandledPacket(header);
- break;
- }
- else
+ if (Variant const* clientInfo = GetParam(params, "Param_ClientInfo"))
+ {
+ ::JSON::RealmList::RealmListTicketClientInformation data;
+ std::size_t jsonStart = clientInfo->blob_value().find(':');
+ if (jsonStart != std::string::npos && ::JSON::Deserialize(clientInfo->blob_value().substr(jsonStart + 1), &data))
+ {
+ if (_clientSecret.size() == data.info().secret().size())
{
- TC_LOG_DEBUG("session.packets", "%s Received unknown %s", GetClientInfo().c_str(), header.ToString().c_str());
- break;
+ _build = data.info().version().versionbuild();
+ memcpy(_clientSecret.data(), data.info().secret().data(), _clientSecret.size());
}
-
- stream.AlignToNextByte();
- }
- catch (BitStreamPositionException const& e)
- {
- TC_LOG_ERROR("session.packets", "%s Exception thrown during packet processing %s", GetClientInfo().c_str(), e.what());
- CloseSocket();
- return;
}
}
- GetReadBuffer().Resize(size_t(BufferSizes::Read));
- AsyncRead();
-}
+ if (!_build)
+ return ERROR_WOW_SERVICES_DENIED_REALM_LIST_TICKET;
-void Battlenet::Session::Start()
-{
- std::string ip_address = GetRemoteIpAddress().to_string();
- TC_LOG_TRACE("session", "Accepted connection from %s", ip_address.c_str());
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO);
+ stmt->setString(0, GetRemoteIpAddress().to_string());
+ stmt->setUInt8(1, GetLocaleByName(_locale));
+ stmt->setString(2, _os);
+ stmt->setUInt32(3, _accountInfo->Id);
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_INFO);
- stmt->setString(0, ip_address);
- stmt->setUInt32(1, inet_addr(ip_address.c_str()));
+ LoginDatabase.Execute(stmt);
- _queryCallback = std::bind(&Battlenet::Session::CheckIpCallback, this, std::placeholders::_1);
- _queryFuture = LoginDatabase.AsyncQuery(stmt);
+ Attribute* attribute = response->add_attribute();
+ attribute->set_name("Param_RealmListTicket");
+ attribute->mutable_value()->set_blob_value("AuthRealmListTicket");
+
+ return ERROR_OK;
}
-void Battlenet::Session::CheckIpCallback(PreparedQueryResult result)
+uint32 Battlenet::Session::GetLastCharPlayed(std::unordered_map<std::string, Variant const*> const& params, game_utilities::v1::ClientResponse* response)
{
- if (result)
+ if (Variant const* subRegion = GetParam(params, "Command_LastCharPlayedRequest_v1_b9"))
{
- bool banned = false;
- do
+ auto lastPlayerChar = _gameAccountInfo->LastPlayedCharacters.find(subRegion->string_value());
+ if (lastPlayerChar != _gameAccountInfo->LastPlayedCharacters.end())
{
- Field* fields = result->Fetch();
- if (fields[0].GetUInt64() != 0)
- banned = true;
+ std::vector<uint8> compressed = sRealmList->GetRealmEntryJSON(lastPlayerChar->second.RealmId, _build);
- if (!fields[1].GetString().empty())
- _ipCountry = fields[1].GetString();
+ if (compressed.empty())
+ return ERROR_UTIL_SERVER_FAILED_TO_SERIALIZE_RESPONSE;
- } while (result->NextRow());
+ Attribute* attribute = response->add_attribute();
+ attribute->set_name("Param_RealmEntry");
+ attribute->mutable_value()->set_blob_value(compressed.data(), compressed.size());
- if (banned)
- {
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(AUTH_INTERNAL_ERROR);
- AsyncWrite(logonResponse);
- TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort());
- return;
+ attribute = response->add_attribute();
+ attribute->set_name("Param_CharacterName");
+ attribute->mutable_value()->set_string_value(lastPlayerChar->second.CharacterName);
+
+ attribute = response->add_attribute();
+ attribute->set_name("Param_CharacterGUID");
+ attribute->mutable_value()->set_blob_value(&lastPlayerChar->second.CharacterGUID, sizeof(lastPlayerChar->second.CharacterGUID));
+
+ attribute = response->add_attribute();
+ attribute->set_name("Param_LastPlayedTime");
+ attribute->mutable_value()->set_int_value(int32(lastPlayerChar->second.LastPlayedTime));
}
+
+ return ERROR_OK;
}
- AsyncRead();
+ return ERROR_UTIL_SERVER_UNKNOWN_REALM;
}
-bool Battlenet::Session::Update()
+uint32 Battlenet::Session::GetRealmList(std::unordered_map<std::string, Variant const*> const& params, game_utilities::v1::ClientResponse* response)
{
- EncryptableBuffer* queued;
- MessageBuffer buffer((std::size_t(BufferSizes::Read)));
- while (_bufferQueue.Dequeue(queued))
- {
- std::size_t packetSize = queued->Buffer.GetActiveSize();
- if (queued->Encrypt)
- _crypt.EncryptSend(queued->Buffer.GetReadPointer(), packetSize);
-
- if (buffer.GetRemainingSpace() < packetSize)
- {
- QueuePacket(std::move(buffer));
- buffer.Resize(std::size_t(BufferSizes::Read));
- }
+ if (!_gameAccountInfo)
+ return ERROR_USER_SERVER_BAD_WOW_ACCOUNT;
- if (buffer.GetRemainingSpace() >= packetSize)
- buffer.Write(queued->Buffer.GetReadPointer(), packetSize);
- else // single packet larger than 16384 bytes - client will reject.
- QueuePacket(std::move(queued->Buffer));
+ std::string subRegionId;
+ if (Variant const* subRegion = GetParam(params, "Command_RealmListRequest_v1_b9"))
+ subRegionId = subRegion->string_value();
- delete queued;
- }
+ std::vector<uint8> compressed = sRealmList->GetRealmList(_build, subRegionId);
- if (buffer.GetActiveSize() > 0)
- QueuePacket(std::move(buffer));
+ if (compressed.empty())
+ return ERROR_UTIL_SERVER_FAILED_TO_SERIALIZE_RESPONSE;
- if (!BattlenetSocket::Update())
- return false;
+ Attribute* attribute = response->add_attribute();
+ attribute->set_name("Param_RealmList");
+ attribute->mutable_value()->set_blob_value(compressed.data(), compressed.size());
- if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
+ ::JSON::RealmList::RealmCharacterCountList realmCharacterCounts;
+ for (auto const& characterCount : _gameAccountInfo->CharacterCounts)
{
- auto callback = _queryCallback;
- _queryCallback = nullptr;
- callback(_queryFuture.get());
+ ::JSON::RealmList::RealmCharacterCountEntry* countEntry = realmCharacterCounts.add_counts();
+ countEntry->set_wowrealmaddress(characterCount.first);
+ countEntry->set_count(characterCount.second);
}
- return true;
-}
-
-void Battlenet::Session::AsyncWrite(ServerPacket* packet)
-{
- if (!IsOpen())
- {
- delete packet;
- return;
- }
+ std::string json = "JSONRealmCharacterCountList:" + ::JSON::Serialize(realmCharacterCounts);
- TC_LOG_DEBUG("session.packets", "%s Sending %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str());
+ uLongf compressedLength = compressBound(json.length());
+ compressed.resize(4 + compressedLength);
+ *reinterpret_cast<uint32*>(compressed.data()) = json.length() + 1;
- packet->Write();
+ 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;
- EncryptableBuffer* buffer = new EncryptableBuffer();
- buffer->Buffer.Write(packet->GetData(), packet->GetSize());
- buffer->Encrypt = _crypt.IsInitialized();
- delete packet;
-
- _bufferQueue.Enqueue(buffer);
+ attribute = response->add_attribute();
+ attribute->set_name("Param_CharacterCountList");
+ attribute->mutable_value()->set_blob_value(compressed.data(), compressedLength + 4);
+ return ERROR_OK;
}
-inline void ReplaceResponse(Battlenet::ServerPacket** oldResponse, Battlenet::ServerPacket* newResponse)
+uint32 Battlenet::Session::JoinRealm(std::unordered_map<std::string, Variant const*> const& params, game_utilities::v1::ClientResponse* response)
{
- if (*oldResponse)
- delete *oldResponse;
+ if (Variant const* realmAddress = GetParam(params, "Param_RealmAddress"))
+ return sRealmList->JoinRealm(realmAddress->uint_value(), _build, GetRemoteIpAddress(), _clientSecret, GetLocaleByName(_locale), _os, _gameAccountInfo->Name, response);
- *oldResponse = newResponse;
+ return ERROR_WOW_SERVICES_INVALID_JOIN_TICKET;
}
-bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacket** response)
+uint32 Battlenet::Session::HandleGetAllValuesForAttribute(game_utilities::v1::GetAllValuesForAttributeRequest const* request, game_utilities::v1::GetAllValuesForAttributeResponse* response)
{
- if (dataStream->GetSize() != 1 + 128 + 32 + 128)
- {
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, logonResponse);
- return false;
- }
+ if (!_authed)
+ return ERROR_DENIED;
- if (dataStream->Read<uint8>(8) != 2) // State
+ if (request->attribute_key() == "Command_RealmListRequest_v1_b9")
{
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, logonResponse);
- return false;
+ sRealmList->WriteSubRegions(response);
+ return ERROR_OK;
}
- BigNumber A, clientM1, clientChallenge;
- A.SetBinary(dataStream->ReadBytes(128).get(), 128);
- clientM1.SetBinary(dataStream->ReadBytes(32).get(), 32);
- clientChallenge.SetBinary(dataStream->ReadBytes(128).get(), 128);
+ return ERROR_RPC_NOT_IMPLEMENTED;
+}
- if (A.IsZero())
+void Battlenet::Session::HandshakeHandler(boost::system::error_code const& error)
+{
+ if (error)
{
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, logonResponse);
- return false;
+ TC_LOG_ERROR("session", "%s SSL Handshake failed %s", GetClientInfo().c_str(), error.message().c_str());
+ CloseSocket();
+ return;
}
- SHA256Hash sha;
- sha.UpdateBigNumbers(&A, &B, NULL);
- sha.Finalize();
-
- BigNumber u;
- u.SetBinary(sha.GetDigest(), sha.GetLength());
-
- BigNumber S = ((A * v.ModExp(u, N)) % N).ModExp(b, N);
-
- uint8 S_bytes[128];
- memcpy(S_bytes, S.AsByteArray(128).get(), 128);
+ AsyncRead();
+}
- uint8 part1[64];
- uint8 part2[64];
+template<bool(Battlenet::Session::*processMethod)(), MessageBuffer Battlenet::Session::*outputBuffer>
+inline bool PartialProcessPacket(Battlenet::Session* session, MessageBuffer& inputBuffer)
+{
+ MessageBuffer& buffer = session->*outputBuffer;
- for (int i = 0; i < 64; ++i)
+ // We have full read header, now check the data payload
+ if (buffer.GetRemainingSpace() > 0)
{
- part1[i] = S_bytes[i * 2];
- part2[i] = S_bytes[i * 2 + 1];
+ // need more data in the payload
+ std::size_t readDataSize = std::min(inputBuffer.GetActiveSize(), buffer.GetRemainingSpace());
+ buffer.Write(inputBuffer.GetReadPointer(), readDataSize);
+ inputBuffer.ReadCompleted(readDataSize);
}
- SHA256Hash part1sha, part2sha;
- part1sha.UpdateData(part1, 64);
- part1sha.Finalize();
- part2sha.UpdateData(part2, 64);
- part2sha.Finalize();
-
- uint8 sessionKey[SHA256_DIGEST_LENGTH * 2];
- for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i)
+ if (buffer.GetRemainingSpace() > 0)
{
- sessionKey[i * 2] = part1sha.GetDigest()[i];
- sessionKey[i * 2 + 1] = part2sha.GetDigest()[i];
- }
-
- K.SetBinary(sessionKey, SHA256_DIGEST_LENGTH * 2);
-
- BigNumber M1;
-
- uint8 hash[SHA256_DIGEST_LENGTH];
- sha.Initialize();
- sha.UpdateBigNumbers(&N, NULL);
- sha.Finalize();
- memcpy(hash, sha.GetDigest(), sha.GetLength());
-
- sha.Initialize();
- sha.UpdateBigNumbers(&g, NULL);
- sha.Finalize();
-
- for (int i = 0; i < sha.GetLength(); ++i)
- hash[i] ^= sha.GetDigest()[i];
-
- SHA256Hash shaI;
- shaI.UpdateData(ByteArrayToHexStr(I.AsByteArray().get(), 32));
- shaI.Finalize();
-
- // Concat all variables for M1 hash
- sha.Initialize();
- sha.UpdateData(hash, SHA256_DIGEST_LENGTH);
- sha.UpdateData(shaI.GetDigest(), shaI.GetLength());
- sha.UpdateBigNumbers(&s, &A, &B, &K, NULL);
- sha.Finalize();
-
- M1.SetBinary(sha.GetDigest(), sha.GetLength());
-
- if (memcmp(M1.AsByteArray().get(), clientM1.AsByteArray().get(), 32))
- {
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS);
- stmt->setString(0, _accountInfo->Login);
- LoginDatabase.Execute(stmt);
-
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- ReplaceResponse(response, logonResponse);
- TC_LOG_DEBUG("session", "[Battlenet::Password] %s attempted to log in with invalid password!", GetClientInfo().c_str());
+ // Couldn't receive the whole data this time.
+ ASSERT(inputBuffer.GetActiveSize() == 0);
return false;
}
- if (_gameAccounts.empty())
+ // just received fresh new payload
+ if (!(session->*processMethod)())
{
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
- ReplaceResponse(response, logonResponse);
- TC_LOG_DEBUG("session", "[Battlenet::Password] %s does not have any linked game accounts!", GetClientInfo().c_str());
+ session->CloseSocket();
return false;
}
- BigNumber M;
- sha.Initialize();
- sha.UpdateBigNumbers(&A, &M1, &K, NULL);
- sha.Finalize();
- M.SetBinary(sha.GetDigest(), sha.GetLength());
-
- BigNumber serverProof;
- serverProof.SetRand(128 * 8); // just send garbage, server signature check is patched out in client
-
- BitStream stream;
- ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password");
- uint8 state = 3;
-
- stream.WriteBytes(&state, 1);
- stream.WriteBytes(M.AsByteArray(32).get(), 32);
- stream.WriteBytes(serverProof.AsByteArray(128).get(), 128);
-
- password->DataSize = stream.GetSize();
- password->Data = new uint8[password->DataSize];
- memcpy(password->Data, stream.GetBuffer(), password->DataSize);
-
- Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
- proofRequest->Modules.push_back(password);
- if (_gameAccounts.size() > 1)
- {
- BitStream accounts;
- state = 0;
- accounts.WriteBytes(&state, 1);
- accounts.Write(_gameAccounts.size(), 8);
- for (GameAccountInfo const& gameAccount : _gameAccounts)
- {
- accounts.Write(2, 8);
- accounts.WriteString(gameAccount.DisplayName, 8);
- }
-
- ModuleInfo* selectGameAccount = sModuleMgr->CreateModule(_os, "SelectGameAccount");
- selectGameAccount->DataSize = accounts.GetSize();
- selectGameAccount->Data = new uint8[selectGameAccount->DataSize];
- memcpy(selectGameAccount->Data, accounts.GetBuffer(), selectGameAccount->DataSize);
- proofRequest->Modules.push_back(selectGameAccount);
- _modulesWaitingForData.push(MODULE_SELECT_GAME_ACCOUNT);
- }
- else
- {
- _gameAccountInfo = &_gameAccounts[0];
-
- if (_gameAccountInfo->IsBanned)
- {
- delete proofRequest;
-
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- if (_gameAccountInfo->IsPermanenetlyBanned)
- {
- logonResponse->SetAuthResult(LOGIN_BANNED);
- TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str());
- }
- else
- {
- logonResponse->SetAuthResult(LOGIN_SUSPENDED);
- TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str());
- }
-
- ReplaceResponse(response, logonResponse);
- return false;
- }
-
- proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint"));
- _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT);
- }
-
- ReplaceResponse(response, proofRequest);
return true;
}
-bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response)
+void Battlenet::Session::ReadHandler()
{
- if (dataStream->Read<uint8>(8) != 1)
- {
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, logonResponse);
- return false;
- }
-
- dataStream->Read<uint8>(8);
- std::string account = dataStream->ReadString(8);
- if (account.empty())
- {
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
- ReplaceResponse(response, logonResponse);
- return false;
- }
+ if (!IsOpen())
+ return;
- for (std::size_t i = 0; i < _gameAccounts.size(); ++i)
+ MessageBuffer& packet = GetReadBuffer();
+ while (packet.GetActiveSize() > 0)
{
- if (_gameAccounts[i].DisplayName == account)
- {
- _gameAccountInfo = &_gameAccounts[i];
+ if (!PartialProcessPacket<&Battlenet::Session::ReadHeaderLengthHandler, &Battlenet::Session::_headerLengthBuffer>(this, packet))
break;
- }
- }
- if (!_gameAccountInfo)
- {
- Authentication::LogonResponse* complete = new Authentication::LogonResponse();
- complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
- ReplaceResponse(response, complete);
- TC_LOG_DEBUG("session", "[Battlenet::SelectGameAccount] %s attempted to log in with invalid game account name %s!", GetClientInfo().c_str(), account.c_str());
- return false;
- }
+ if (!PartialProcessPacket<&Battlenet::Session::ReadHeaderHandler, &Battlenet::Session::_headerBuffer>(this, packet))
+ break;
- if (_gameAccountInfo->IsBanned)
- {
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- if (_gameAccountInfo->IsPermanenetlyBanned)
- {
- logonResponse->SetAuthResult(LOGIN_BANNED);
- TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str());
- }
- else
- {
- logonResponse->SetAuthResult(LOGIN_SUSPENDED);
- TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str());
- }
+ if (!PartialProcessPacket<&Battlenet::Session::ReadDataHandler, &Battlenet::Session::_packetBuffer>(this, packet))
+ break;
- ReplaceResponse(response, logonResponse);
- return false;
+ _headerLengthBuffer.Reset();
+ _headerBuffer.Reset();
}
- Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
- proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint"));
- ReplaceResponse(response, proofRequest);
-
- _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT);
- return true;
+ AsyncRead();
}
-bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response)
+bool Battlenet::Session::ReadHeaderLengthHandler()
{
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- if (dataStream->Read<uint8>(8) == 1 && _accountInfo && _gameAccountInfo)
- {
- 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();
-
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO);
- stmt->setString(0, GetRemoteIpAddress().to_string());
- stmt->setUInt8(1, GetLocaleByName(_locale));
- stmt->setString(2, _os);
- stmt->setUInt32(3, _accountInfo->Id);
- trans->Append(stmt);
-
- stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY);
- stmt->setString(0, K.AsHexStr());
- stmt->setBool(1, true);
- stmt->setUInt32(2, _accountInfo->Id);
- trans->Append(stmt);
-
- LoginDatabase.CommitTransaction(trans);
-
- _authed = true;
- sSessionMgr.AddSession(this);
- }
- else
- logonResponse->SetAuthResult(AUTH_BAD_VERSION_HASH);
-
- ReplaceResponse(response, logonResponse);
+ uint16 len = *reinterpret_cast<uint16*>(_headerLengthBuffer.GetReadPointer());
+ EndianConvertReverse(len);
+ _headerBuffer.Resize(len);
return true;
}
-bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket** response)
+bool Battlenet::Session::ReadHeaderHandler()
{
- if (dataStream->Read<uint8>(8) != 1)
- {
- Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
- resumeResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, resumeResponse);
- return false;
- }
-
- static uint8 const ResumeClient = 0;
- static uint8 const ResumeServer = 1;
-
- std::unique_ptr<uint8[]> clientChallenge = dataStream->ReadBytes(16);
- std::unique_ptr<uint8[]> clientProof = dataStream->ReadBytes(32);
- std::unique_ptr<uint8[]> serverChallenge = _reconnectProof.AsByteArray(16);
- std::unique_ptr<uint8[]> sessionKey = K.AsByteArray(64);
-
- HmacSha256 clientPart(64, sessionKey.get());
- clientPart.UpdateData(&ResumeClient, 1);
- clientPart.UpdateData(clientChallenge.get(), 16);
- clientPart.UpdateData(serverChallenge.get(), 16);
- clientPart.Finalize();
-
- HmacSha256 serverPart(64, sessionKey.get());
- serverPart.UpdateData(&ResumeServer, 1);
- serverPart.UpdateData(serverChallenge.get(), 16);
- serverPart.UpdateData(clientChallenge.get(), 16);
- serverPart.Finalize();
-
- uint8 newSessionKey[64];
- memcpy(&newSessionKey[0], clientPart.GetDigest(), clientPart.GetLength());
- memcpy(&newSessionKey[32], serverPart.GetDigest(), serverPart.GetLength());
-
- K.SetBinary(newSessionKey, 64);
+ Header header;
+ if (!header.ParseFromArray(_headerBuffer.GetReadPointer(), _headerBuffer.GetActiveSize()))
+ return true;
- HmacSha256 proof(64, newSessionKey);
- proof.UpdateData(&ResumeClient, 1);
- proof.UpdateData(clientChallenge.get(), 16);
- proof.UpdateData(serverChallenge.get(), 16);
- proof.Finalize();
-
- if (memcmp(proof.GetDigest(), clientProof.get(), serverPart.GetLength()))
- {
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS);
- stmt->setString(0, _accountInfo->Login);
- LoginDatabase.Execute(stmt);
-
- TC_LOG_DEBUG("session", "[Battlenet::Resume] %s attempted to reconnect with invalid password!", GetClientInfo().c_str());
- Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
- resumeResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
- ReplaceResponse(response, resumeResponse);
- return false;
- }
-
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY);
- stmt->setString(0, K.AsHexStr());
- stmt->setBool(1, true);
- stmt->setUInt32(2, _accountInfo->Id);
- LoginDatabase.Execute(stmt);
-
- HmacSha256 serverProof(64, newSessionKey);
- serverProof.UpdateData(&ResumeServer, 1);
- serverProof.UpdateData(serverChallenge.get(), 16);
- serverProof.UpdateData(clientChallenge.get(), 16);
- serverProof.Finalize();
-
- ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume");
-
- BitStream resumeData;
- uint8 state = 2;
- resumeData.WriteBytes(&state, 1);
- resumeData.WriteBytes(serverProof.GetDigest(), serverProof.GetLength());
-
- resume->DataSize = resumeData.GetSize();
- resume->Data = new uint8[resume->DataSize];
- memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize);
-
- Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse();
- resumeResponse->Result.Success.FinalRequest.push_back(resume);
- ReplaceResponse(response, resumeResponse);
- _authed = true;
- sSessionMgr.AddSession(this);
+ _packetBuffer.Resize(header.size());
return true;
}
-bool Battlenet::Session::UnhandledModule(BitStream* /*dataStream*/, ServerPacket** response)
+bool Battlenet::Session::ReadDataHandler()
{
- TC_LOG_ERROR("session.packets", "Unhandled module.");
- Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
- logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
- ReplaceResponse(response, logonResponse);
- return false;
-}
-
-void Battlenet::Session::UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmHandle>& deletedRealms)
-{
- for (Realm const* realm : realms)
- AsyncWrite(BuildListUpdate(realm));
+ Header header;
+ header.ParseFromArray(_headerBuffer.GetReadPointer(), _headerBuffer.GetActiveSize());
- for (RealmHandle& deleted : deletedRealms)
+ if (header.service_id() != 0xFE)
{
- WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate();
- listUpdate->State.Type = WoWRealm::ListUpdate::StateType::DELETED;
- listUpdate->Id = deleted;
- AsyncWrite(listUpdate);
+ sServiceDispatcher.Dispatch(this, header.service_hash(), header.token(), header.method_id(), std::move(_packetBuffer));
}
-}
-
-Battlenet::WoWRealm::ListUpdate* Battlenet::Session::BuildListUpdate(Realm const* realm) const
-{
- uint32 flag = realm->Flags;
- if (realm->Build != _build)
- flag |= REALM_FLAG_VERSION_MISMATCH;
-
- WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate();
- 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 (_gameAccountInfo->SecurityLevel > SEC_PLAYER)
+ else
{
- listUpdate->State.Update.PrivilegedData = boost::in_place();
- std::ostringstream version;
- if (RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm->Build))
- version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build;
+ auto itr = _responseCallbacks.find(header.token());
+ if (itr != _responseCallbacks.end())
+ {
+ itr->second(std::move(_packetBuffer));
+ _responseCallbacks.erase(header.token());
+ }
else
- version << "x.x.x." << realm->Build;
-
- listUpdate->State.Update.PrivilegedData->Version = version.str();
- listUpdate->State.Update.PrivilegedData->ConfigId = realm->GetConfigId();
- listUpdate->State.Update.PrivilegedData->Address = realm->GetAddressForClient(GetRemoteIpAddress());
+ _packetBuffer.Reset();
}
- listUpdate->State.Update.InfoFlags = flag;
- listUpdate->Id = realm->Id;
- return listUpdate;
+ return true;
}
std::string Battlenet::Session::GetClientInfo() const
diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h
index 2443d694a80..4170cbc7826 100644
--- a/src/server/bnetserver/Server/Session.h
+++ b/src/server/bnetserver/Server/Session.h
@@ -18,140 +18,165 @@
#ifndef Session_h__
#define Session_h__
-#include "Packets.h"
-#include "BattlenetPacketCrypt.h"
+#include "Realm.h"
+#include "SslContext.h"
+#include "SslSocket.h"
#include "Socket.h"
#include "BigNumber.h"
#include "Callback.h"
-#include "MPSCQueue.h"
-#include <memory>
#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ssl.hpp>
+#include <google/protobuf/message.h>
+#include <memory>
-struct Realm;
using boost::asio::ip::tcp;
-namespace Battlenet
-{
- struct PacketHeader;
- class BitStream;
-
- enum ModuleType
- {
- MODULE_PASSWORD,
- MODULE_TOKEN,
- MODULE_THUMBPRINT,
- MODULE_SELECT_GAME_ACCOUNT,
- MODULE_RISK_FINGERPRINT,
- MODULE_RESUME,
-
- MODULE_COUNT
- };
+namespace pb = google::protobuf;
- enum class BufferSizes : uint32
+namespace bgs
+{
+ namespace protocol
{
- SRP_6_V = 0x80,
- SRP_6_S = 0x20,
- Read = 0x4000
- };
+ class Variant;
- struct AccountInfo
- {
- void LoadResult(Field* fields);
-
- uint32 Id;
- std::string Login;
- bool IsLockedToIP;
- std::string LockCountry;
- std::string LastIP;
- uint32 FailedLogins;
- bool IsBanned;
- bool IsPermanenetlyBanned;
- };
+ namespace account
+ {
+ namespace v1
+ {
+ class GetAccountStateRequest;
+ class GetAccountStateResponse;
+ class GetGameAccountStateRequest;
+ class GetGameAccountStateResponse;
+ }
+ }
+
+ namespace authentication
+ {
+ namespace v1
+ {
+ class LogonRequest;
+ class VerifyWebCredentialsRequest;
+ }
+ }
+
+ namespace game_utilities
+ {
+ namespace v1
+ {
+ class ClientRequest;
+ class ClientResponse;
+ class GetAllValuesForAttributeRequest;
+ class GetAllValuesForAttributeResponse;
+ }
+ }
+ }
+}
- struct GameAccountInfo
- {
- void LoadResult(Field* fields);
-
- uint32 Id;
- std::string Name;
- std::string DisplayName;
- bool IsBanned;
- bool IsPermanenetlyBanned;
- AccountTypes SecurityLevel;
- };
+using namespace bgs::protocol;
- class Session : public Socket<Session>
+namespace Battlenet
+{
+ class Session : public Socket<Session, SslSocket<SslContext>>
{
- typedef Socket<Session> BattlenetSocket;
+ typedef Socket<Session, SslSocket<SslContext>> BattlenetSocket;
public:
- explicit Session(tcp::socket&& socket);
- ~Session();
-
- void LogUnhandledPacket(PacketHeader const& header);
+ struct LastPlayedCharacterInfo
+ {
+ Battlenet::RealmHandle RealmId;
+ std::string CharacterName;
+ uint64 CharacterGUID;
+ uint32 LastPlayedTime;
+ };
- // Authentication
- void HandleLogonRequest(Authentication::LogonRequest3 const& logonRequest);
- void HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest);
- void HandleProofResponse(Authentication::ProofResponse const& proofResponse);
+ struct GameAccountInfo
+ {
+ void LoadResult(Field* fields);
- // Connection
- void HandlePing(Connection::Ping const& ping);
- void HandleEnableEncryption(Connection::EnableEncryption& enableEncryption);
- void HandleLogoutRequest(Connection::LogoutRequest const& logoutRequest);
- void HandleConnectionClosing(Connection::ConnectionClosing const& connectionClosing);
+ uint32 Id;
+ std::string Name;
+ std::string DisplayName;
+ bool IsBanned;
+ bool IsPermanenetlyBanned;
+ AccountTypes SecurityLevel;
- // WoWRealm
- void HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& listSubscribeRequest);
- void HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& listUnsubscribe);
- void HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest);
+ std::unordered_map<uint32 /*realmAddress*/, uint8> CharacterCounts;
+ std::unordered_map<std::string /*subRegion*/, LastPlayedCharacterInfo> LastPlayedCharacters;
+ };
- // Friends
+ struct AccountInfo
+ {
+ void LoadResult(PreparedQueryResult result);
+
+ uint32 Id;
+ std::string Login;
+ bool IsLockedToIP;
+ std::string LockCountry;
+ std::string LastIP;
+ uint32 FailedLogins;
+ bool IsBanned;
+ bool IsPermanenetlyBanned;
+
+ std::unordered_map<uint32, GameAccountInfo> GameAccounts;
+ };
- // Cache
- void HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest);
+ explicit Session(tcp::socket&& socket);
+ ~Session();
void Start() override;
bool Update() override;
- void UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmHandle>& deletedRealms);
-
uint32 GetAccountId() const { return _accountInfo->Id; }
uint32 GetGameAccountId() const { return _gameAccountInfo->Id; }
- bool IsToonOnline() const { return _toonOnline; }
- void SetToonOnline(bool online) { _toonOnline = online; }
+ void SendResponse(uint32 token, pb::Message const* response);
+ void SendResponse(uint32 token, uint32 status);
+
+ void SendRequest(uint32 serviceHash, uint32 methodId, pb::Message const* request, std::function<void(MessageBuffer)> callback)
+ {
+ _responseCallbacks[_requestToken] = std::move(callback);
+ SendRequest(serviceHash, methodId, request);
+ }
+
+ void SendRequest(uint32 serviceHash, uint32 methodId, pb::Message const* request);
- bool IsSubscribedToRealmListUpdates() const { return _subscribedToRealmListUpdates; }
+ uint32 HandleLogon(authentication::v1::LogonRequest const* logonRequest);
+ uint32 HandleVerifyWebCredentials(authentication::v1::VerifyWebCredentialsRequest const* verifyWebCredentialsRequest);
+ uint32 HandleGetAccountState(account::v1::GetAccountStateRequest const* request, account::v1::GetAccountStateResponse* response);
+ uint32 HandleGetGameAccountState(account::v1::GetGameAccountStateRequest const* request, account::v1::GetGameAccountStateResponse* response);
+ uint32 HandleProcessClientRequest(game_utilities::v1::ClientRequest const* request, game_utilities::v1::ClientResponse* response);
+ uint32 HandleGetAllValuesForAttribute(game_utilities::v1::GetAllValuesForAttributeRequest const* request, game_utilities::v1::GetAllValuesForAttributeResponse* response);
- void AsyncWrite(ServerPacket* packet);
+ std::string GetClientInfo() const;
protected:
+ void HandshakeHandler(boost::system::error_code const& error);
void ReadHandler() override;
+ bool ReadHeaderLengthHandler();
+ bool ReadHeaderHandler();
+ bool ReadDataHandler();
private:
- void _SetVSFields(std::string const& rI);
+ void AsyncWrite(MessageBuffer* packet);
- typedef bool(Session::*ModuleHandler)(BitStream* dataStream, ServerPacket** response);
- static ModuleHandler const ModuleHandlers[MODULE_COUNT];
+ void AsyncHandshake();
void CheckIpCallback(PreparedQueryResult result);
- void HandleLogonRequestCallback(PreparedQueryResult result);
- void HandleResumeRequestCallback(PreparedQueryResult result);
- void HandleListSubscribeRequestCallback(PreparedQueryResult result);
- bool HandlePasswordModule(BitStream* dataStream, ServerPacket** response);
- bool HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response);
- bool HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response);
- bool HandleResumeModule(BitStream* dataStream, ServerPacket** response);
- bool UnhandledModule(BitStream* dataStream, ServerPacket** response);
+ typedef uint32(Session::*ClientRequestHandler)(std::unordered_map<std::string, Variant const*> const&, game_utilities::v1::ClientResponse*);
+ static std::unordered_map<std::string, ClientRequestHandler> const ClientRequestHandlers;
- WoWRealm::ListUpdate* BuildListUpdate(Realm const* realm) const;
- std::string GetClientInfo() const;
+ uint32 GetRealmListTicket(std::unordered_map<std::string, Variant const*> const& params, game_utilities::v1::ClientResponse* response);
+ uint32 GetLastCharPlayed(std::unordered_map<std::string, Variant const*> const& params, game_utilities::v1::ClientResponse* response);
+ uint32 GetRealmList(std::unordered_map<std::string, Variant const*> const& params, game_utilities::v1::ClientResponse* response);
+ uint32 JoinRealm(std::unordered_map<std::string, Variant const*> const& params, game_utilities::v1::ClientResponse* response);
+
+ MessageBuffer _headerLengthBuffer;
+ MessageBuffer _headerBuffer;
+ MessageBuffer _packetBuffer;
- AccountInfo* _accountInfo;
+ std::unique_ptr<AccountInfo> _accountInfo;
GameAccountInfo* _gameAccountInfo; // Points at selected game account (inside _gameAccounts)
- std::vector<GameAccountInfo> _gameAccounts;
std::string _locale;
std::string _os;
@@ -159,38 +184,16 @@ namespace Battlenet
std::string _ipCountry;
- BigNumber N;
- BigNumber g;
- BigNumber k;
-
- BigNumber I;
- BigNumber s;
- BigNumber v;
-
- BigNumber b;
- BigNumber B;
- BigNumber K; // session key
-
- BigNumber _reconnectProof;
-
- std::queue<ModuleType> _modulesWaitingForData;
+ std::array<uint8, 32> _clientSecret;
- struct EncryptableBuffer
- {
- MessageBuffer Buffer;
- bool Encrypt;
- };
-
- MPSCQueue<EncryptableBuffer> _bufferQueue;
- PacketCrypt _crypt;
bool _authed;
- bool _subscribedToRealmListUpdates;
- bool _toonOnline;
PreparedQueryResultFuture _queryFuture;
std::function<void(PreparedQueryResult)> _queryCallback;
- };
+ std::unordered_map<uint32, std::function<void(MessageBuffer)>> _responseCallbacks;
+ uint32 _requestToken;
+ };
}
#endif // Session_h__
diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp
index ed36a3630e1..1920496ffff 100644
--- a/src/server/bnetserver/Server/SessionManager.cpp
+++ b/src/server/bnetserver/Server/SessionManager.cpp
@@ -37,41 +37,8 @@ void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock, uint32 thread
sSessionMgr.OnSocketOpen(std::forward<tcp::socket>(sock), threadIndex);
}
-void Battlenet::SessionManager::AddSession(Session* session)
+Battlenet::SessionManager& Battlenet::SessionManager::Instance()
{
- std::unique_lock<boost::shared_mutex> lock(_sessionMutex);
- _sessions[{ session->GetAccountId(), session->GetGameAccountId() }] = session;
- _sessionsByAccountId[session->GetAccountId()].push_back(session);
-}
-
-void Battlenet::SessionManager::RemoveSession(Session* session)
-{
- std::unique_lock<boost::shared_mutex> lock(_sessionMutex);
- auto itr = _sessions.find({ session->GetAccountId(), session->GetGameAccountId() });
- // Remove old session only if it was not overwritten by reconnecting
- if (itr != _sessions.end() && itr->second == session)
- _sessions.erase(itr);
-
- _sessionsByAccountId[session->GetAccountId()].remove(session);
-}
-
-Battlenet::Session* Battlenet::SessionManager::GetSession(uint32 accountId, uint32 gameAccountId) const
-{
- boost::shared_lock<boost::shared_mutex> lock(_sessionMutex);
- auto itr = _sessions.find({ accountId, gameAccountId });
- if (itr != _sessions.end())
- return itr->second;
-
- return nullptr;
-}
-
-std::list<Battlenet::Session*> Battlenet::SessionManager::GetSessions(uint32 accountId) const
-{
- boost::shared_lock<boost::shared_mutex> lock(_sessionMutex);
- std::list<Session*> sessions;
- auto itr = _sessionsByAccountId.find(accountId);
- if (itr != _sessionsByAccountId.end())
- sessions = itr->second;
-
- return sessions;
+ static SessionManager instance;
+ return instance;
}
diff --git a/src/server/bnetserver/Server/SessionManager.h b/src/server/bnetserver/Server/SessionManager.h
index 701802056da..c1aa955812c 100644
--- a/src/server/bnetserver/Server/SessionManager.h
+++ b/src/server/bnetserver/Server/SessionManager.h
@@ -18,68 +18,25 @@
#ifndef SessionManager_h__
#define SessionManager_h__
-#include "Session.h"
#include "SocketMgr.h"
-#include <boost/thread/locks.hpp>
-#include <boost/thread/shared_mutex.hpp>
+#include "Session.h"
namespace Battlenet
{
-#pragma pack(push, 1)
-
- struct SessionInfo
- {
- uint32 AccountId;
- uint32 GameAccountId;
-
- bool operator<(SessionInfo const& right) const
- {
- return memcmp(this, &right, sizeof(SessionInfo)) < 0;
- }
- };
-
-#pragma pack(pop)
-
class SessionManager : public SocketMgr<Session>
{
typedef SocketMgr<Session> BaseSocketMgr;
- typedef std::map<SessionInfo, Session*> SessionMap;
- typedef std::map<uint32, std::list<Session*>> SessionByAccountMap;
public:
- static SessionManager& Instance()
- {
- static SessionManager instance;
- return instance;
- }
+ static SessionManager& Instance();
bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port, int threadCount = 1) override;
- // noop for now, will be needed later to broadcast realmlist updates for example
- void AddSession(Session* /*session*/);
-
- void RemoveSession(Session* /*session*/);
-
- Session* GetSession(uint32 accountId, uint32 gameAccountId) const;
- std::list<Session*> GetSessions(uint32 accountId) const;
-
- template<typename Iterator>
- void LockedForEach(Iterator iterator) const
- {
- boost::shared_lock<boost::shared_mutex> lock(_sessionMutex);
- for (SessionMap::value_type const& pair : _sessions)
- iterator(pair.second);
- }
-
protected:
NetworkThread<Session>* CreateThreads() const override;
private:
static void OnSocketAccept(tcp::socket&& sock, uint32 threadIndex);
-
- SessionMap _sessions;
- SessionByAccountMap _sessionsByAccountId;
- mutable boost::shared_mutex _sessionMutex;
};
}
diff --git a/src/server/bnetserver/Server/SslContext.cpp b/src/server/bnetserver/Server/SslContext.cpp
new file mode 100644
index 00000000000..f1b2a185563
--- /dev/null
+++ b/src/server/bnetserver/Server/SslContext.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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 "SslContext.h"
+#include "Log.h"
+
+bool Battlenet::SslContext::Initialize()
+{
+ boost::system::error_code err;
+
+#define LOAD_CHECK(fn) do { fn; \
+ if (err) \
+ { \
+ TC_LOG_ERROR("server.ssl", #fn ## "failed: %s", err.message().c_str()); \
+ return false; \
+ } } while (0)
+
+ LOAD_CHECK(instance().set_options(boost::asio::ssl::context::no_sslv3, err));
+ LOAD_CHECK(instance().use_certificate_chain_file("bnetserver.cert.pem", err));
+ LOAD_CHECK(instance().use_private_key_file("bnetserver.key.pem", boost::asio::ssl::context::pem, err));
+
+#undef LOAD_CHECK
+
+ return true;
+}
+
+boost::asio::ssl::context& Battlenet::SslContext::instance()
+{
+ static boost::asio::ssl::context context(boost::asio::ssl::context::sslv23);
+ return context;
+}
diff --git a/src/server/bnetserver/Packets/BitStream.cpp b/src/server/bnetserver/Server/SslContext.h
index 1aeac731d28..5425ab46231 100644
--- a/src/server/bnetserver/Packets/BitStream.cpp
+++ b/src/server/bnetserver/Server/SslContext.h
@@ -15,16 +15,20 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "BitStream.h"
+#ifndef SslContext_h__
+#define SslContext_h__
-template<>
-bool Battlenet::BitStream::Read<bool>(uint32 /*bitCount*/)
-{
- return Read<uint8>(1) != 0;
-}
+#include <boost/asio/ssl/context.hpp>
-template<>
-void Battlenet::BitStream::Write<bool>(bool value, uint32 /*bitCount*/)
+namespace Battlenet
{
- Write<uint8>(value ? 1 : 0, 1);
+ class SslContext
+ {
+ public:
+ static bool Initialize();
+
+ static boost::asio::ssl::context& instance();
+ };
}
+
+#endif // SslContext_h__
diff --git a/src/server/bnetserver/Packets/SupportPackets.h b/src/server/bnetserver/Services/AccountService.cpp
index c84c96607f0..c4b6da289b8 100644
--- a/src/server/bnetserver/Packets/SupportPackets.h
+++ b/src/server/bnetserver/Services/AccountService.cpp
@@ -15,21 +15,19 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SupportPackets_h__
-#define SupportPackets_h__
+#include "AccountService.h"
+#include "Session.h"
-#include "PacketsBase.h"
+Battlenet::Services::Account::Account(Session* session) : AccountService(session)
+{
+}
-namespace Battlenet
+uint32 Battlenet::Services::Account::HandleGetAccountState(account::v1::GetAccountStateRequest const* request, account::v1::GetAccountStateResponse* response)
{
- namespace Support
- {
- enum Opcode
- {
- CMSG_COMPLAINT_REQUEST = 0x0, // Deprecated in client
- CMSG_COMPLAINT_REQUEST_2 = 0x1 // Not implemented
- };
- }
+ return _session->HandleGetAccountState(request, response);
}
-#endif // SupportPackets_h__
+uint32 Battlenet::Services::Account::HandleGetGameAccountState(account::v1::GetGameAccountStateRequest const* request, account::v1::GetGameAccountStateResponse* response)
+{
+ return _session->HandleGetGameAccountState(request, response);
+}
diff --git a/src/server/bnetserver/Packets/AchievementPackets.h b/src/server/bnetserver/Services/AccountService.h
index 3773e8475b7..8f950961a90 100644
--- a/src/server/bnetserver/Packets/AchievementPackets.h
+++ b/src/server/bnetserver/Services/AccountService.h
@@ -15,28 +15,30 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef AchievementPackets_h__
-#define AchievementPackets_h__
+#ifndef AccountService_h__
+#define AccountService_h__
-#include "PacketsBase.h"
+#include "Common.h"
+#include "Service.h"
+#include "account_service.pb.h"
namespace Battlenet
{
- namespace Achievement
+ class Session;
+
+ namespace Services
{
- enum Opcode
+ class Account : public Service<account::v1::AccountService>
{
- CMSG_LISTEN_REQUEST = 0x0, // Not implemented
- CMSG_CRITERIA_FLUSH_REQUEST = 0x3, // Not implemented
- CMSG_CHANGE_TROPHY_CASE_REQUEST = 0x5, // Not implemented
+ typedef Service<account::v1::AccountService> AccountService;
+
+ public:
+ Account(Session* session);
- SMSG_DATA = 0x2, // Not implemented
- SMSG_CRITERIA_FLUSH_RESPONSE = 0x3, // Not implemented
- SMSG_ACHIEVEMENT_HANDLE_UPDATE = 0x4, // Not implemented
- SMSG_CHANGE_TROPHY_CASE_RESULT = 0x6 // Not implemented
+ uint32 HandleGetAccountState(account::v1::GetAccountStateRequest const* request, account::v1::GetAccountStateResponse* response) override;
+ uint32 HandleGetGameAccountState(account::v1::GetGameAccountStateRequest const* request, account::v1::GetGameAccountStateResponse* response) override;
};
}
}
-#endif // AchievementPackets_h__
-
+#endif // AccountService_h__
diff --git a/src/server/bnetserver/Packets/PresencePackets.h b/src/server/bnetserver/Services/AuthenticationService.cpp
index e098d6e9053..fd703ad22ac 100644
--- a/src/server/bnetserver/Packets/PresencePackets.h
+++ b/src/server/bnetserver/Services/AuthenticationService.cpp
@@ -15,25 +15,19 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PresencePackets_h__
-#define PresencePackets_h__
+#include "AuthenticationService.h"
+#include "Session.h"
-#include "PacketsBase.h"
-
-namespace Battlenet
+Battlenet::Services::Authentication::Authentication(Session* session) : AuthenticationService(session)
{
- namespace Presence
- {
- enum Opcode
- {
- CMSG_UPDATE_REQUEST = 0x0, // Not implemented
- CMSG_STATISTIC_SUBSCRIBE = 0x2, // Not implemented
+}
- SMSG_UPDATE_NOTIFY = 0x0, // Not implemented
- SMSG_FIELD_SPEC_ANNOUNCE = 0x1, // Not implemented
- SMSG_STATISTICS_UPDATE = 0x3 // Not implemented
- };
- }
+uint32 Battlenet::Services::Authentication::HandleLogon(authentication::v1::LogonRequest const* request, NoData* /*respons*/)
+{
+ return _session->HandleLogon(request);
}
-#endif // PresencePackets_h__
+uint32 Battlenet::Services::Authentication::HandleVerifyWebCredentials(authentication::v1::VerifyWebCredentialsRequest const* request, NoData* /*respons*/)
+{
+ return _session->HandleVerifyWebCredentials(request);
+}
diff --git a/src/server/bnetserver/Authentication/BattlenetPacketCrypt.h b/src/server/bnetserver/Services/AuthenticationService.h
index 8344391d523..e5a2726b110 100644
--- a/src/server/bnetserver/Authentication/BattlenetPacketCrypt.h
+++ b/src/server/bnetserver/Services/AuthenticationService.h
@@ -15,22 +15,30 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef BattlenetPacketCrypt_h__
-#define BattlenetPacketCrypt_h__
+#ifndef AuthenticationService_h__
+#define AuthenticationService_h__
-#include "PacketCrypt.h"
-
-class BigNumber;
+#include "Common.h"
+#include "Service.h"
+#include "authentication_service.pb.h"
namespace Battlenet
{
- class PacketCrypt : public ::PacketCrypt
+ class Session;
+
+ namespace Services
{
+ class Authentication : public Service<authentication::v1::AuthenticationService>
+ {
+ typedef Service<authentication::v1::AuthenticationService> AuthenticationService;
+
public:
- PacketCrypt();
+ Authentication(Session* session);
- void Init(BigNumber* K) override;
- };
+ uint32 HandleLogon(authentication::v1::LogonRequest const* request, NoData* respons) override;
+ uint32 HandleVerifyWebCredentials(authentication::v1::VerifyWebCredentialsRequest const* request, NoData* respons) override;
+ };
+ }
}
-#endif // BattlenetPacketCrypt_h__
+#endif // AuthenticationService_h__
diff --git a/src/server/bnetserver/Services/ConnectionService.cpp b/src/server/bnetserver/Services/ConnectionService.cpp
new file mode 100644
index 00000000000..78ead03b7e6
--- /dev/null
+++ b/src/server/bnetserver/Services/ConnectionService.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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 "ConnectionService.h"
+#include "Duration.h"
+#include "Log.h"
+#include "Session.h"
+#include "Util.h"
+#include "BattlenetRpcErrorCodes.h"
+
+Battlenet::Services::Connection::Connection(Session* session) : ConnectionService(session)
+{
+}
+
+uint32 Battlenet::Services::Connection::HandleConnect(connection::v1::ConnectRequest const* request, connection::v1::ConnectResponse* response)
+{
+ if (request->has_client_id())
+ response->mutable_client_id()->CopyFrom(request->client_id());
+
+ std::chrono::system_clock::duration now = std::chrono::system_clock::now().time_since_epoch();
+
+ response->mutable_server_id()->set_label(GetPID());
+ response->mutable_server_id()->set_epoch(std::chrono::duration_cast<Seconds>(now).count());
+ response->set_server_time(std::chrono::duration_cast<Milliseconds>(now).count());
+
+ response->set_use_bindless_rpc(request->use_bindless_rpc());
+ return ERROR_OK;
+}
+
+uint32 Battlenet::Services::Connection::HandleKeepAlive(NoData const* /*request*/)
+{
+ return ERROR_OK;
+}
+
+uint32 Battlenet::Services::Connection::HandleRequestDisconnect(connection::v1::DisconnectRequest const* request)
+{
+ connection::v1::DisconnectNotification disconnectNotification;
+ disconnectNotification.set_error_code(request->error_code());
+ ForceDisconnect(&disconnectNotification);
+
+ _session->DelayedCloseSocket();
+ return ERROR_OK;
+}
diff --git a/src/server/bnetserver/Services/ConnectionService.h b/src/server/bnetserver/Services/ConnectionService.h
new file mode 100644
index 00000000000..48b726eb2ba
--- /dev/null
+++ b/src/server/bnetserver/Services/ConnectionService.h
@@ -0,0 +1,46 @@
+/*
+ * 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 ConnectionService_h__
+#define ConnectionService_h__
+
+#include "Common.h"
+#include "Service.h"
+#include "connection_service.pb.h"
+
+namespace Battlenet
+{
+ class Session;
+
+ namespace Services
+ {
+ class Connection : public Service<connection::v1::ConnectionService>
+ {
+ typedef Service<connection::v1::ConnectionService> ConnectionService;
+
+ public:
+ Connection(Session* session);
+
+ uint32 HandleConnect(connection::v1::ConnectRequest const* request, connection::v1::ConnectResponse* respons) override;
+ uint32 HandleKeepAlive(NoData const* request) override;
+ uint32 HandleRequestDisconnect(connection::v1::DisconnectRequest const* request) override;
+
+ };
+ }
+}
+
+#endif // ConnectionService_h__
diff --git a/src/server/bnetserver/Packets/PacketsBase.cpp b/src/server/bnetserver/Services/GameUtilitiesService.cpp
index 61301307954..e9e7b36724d 100644
--- a/src/server/bnetserver/Packets/PacketsBase.cpp
+++ b/src/server/bnetserver/Services/GameUtilitiesService.cpp
@@ -15,32 +15,19 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "Packets.h"
+#include "GameUtilitiesService.h"
#include "Session.h"
-#include <sstream>
-std::string Battlenet::PacketHeader::ToString() const
+Battlenet::Services::GameUtilities::GameUtilities(Session* session) : GameUtilitiesService(session)
{
- std::ostringstream stream;
- 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())
+uint32 Battlenet::Services::GameUtilities::HandleProcessClientRequest(game_utilities::v1::ClientRequest const* request, game_utilities::v1::ClientResponse* response)
{
- _stream.Write(header.Command, 6);
- _stream.Write(1, 1);
- _stream.Write(header.Channel, 4);
+ return _session->HandleProcessClientRequest(request, response);
}
-Battlenet::ServerPacket::~ServerPacket()
+uint32 Battlenet::Services::GameUtilities::HandleGetAllValuesForAttribute(game_utilities::v1::GetAllValuesForAttributeRequest const* request, game_utilities::v1::GetAllValuesForAttributeResponse* response)
{
- delete &_stream;
-}
-
-void Battlenet::ClientPacket::CallHandler(Session* session)
-{
- session->LogUnhandledPacket(GetHeader());
+ return _session->HandleGetAllValuesForAttribute(request, response);
}
diff --git a/src/server/bnetserver/Services/GameUtilitiesService.h b/src/server/bnetserver/Services/GameUtilitiesService.h
new file mode 100644
index 00000000000..37f56e03566
--- /dev/null
+++ b/src/server/bnetserver/Services/GameUtilitiesService.h
@@ -0,0 +1,44 @@
+/*
+ * 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 GameUtilitiesServiceService_h__
+#define GameUtilitiesServiceService_h__
+
+#include "Common.h"
+#include "Service.h"
+#include "game_utilities_service.pb.h"
+
+namespace Battlenet
+{
+ class Session;
+
+ namespace Services
+ {
+ class GameUtilities : public Service<game_utilities::v1::GameUtilitiesService>
+ {
+ typedef Service<game_utilities::v1::GameUtilitiesService> GameUtilitiesService;
+
+ public:
+ GameUtilities(Session* 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;
+ };
+ }
+}
+
+#endif // GameUtilitiesServiceService_h__
diff --git a/src/server/bnetserver/Services/Service.h b/src/server/bnetserver/Services/Service.h
new file mode 100644
index 00000000000..f2f4ee76c3f
--- /dev/null
+++ b/src/server/bnetserver/Services/Service.h
@@ -0,0 +1,45 @@
+/*
+ * 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 Service_h__
+#define Service_h__
+
+#include "Session.h"
+
+namespace bgs { namespace protocol { } }
+using namespace bgs::protocol;
+
+namespace Battlenet
+{
+ template<class T>
+ class Service : public T
+ {
+ public:
+ Service(Session* session) : T(true), _session(session) { }
+
+ protected:
+ void SendRequest(uint32 serviceHash, uint32 methodId, google::protobuf::Message const* request, std::function<void(MessageBuffer)> callback) override { _session->SendRequest(serviceHash, methodId, request, std::move(callback)); }
+ void SendRequest(uint32 serviceHash, uint32 methodId, google::protobuf::Message const* request) override { _session->SendRequest(serviceHash, methodId, request); }
+ void SendResponse(uint32 /*serviceHash*/, uint32 /*methodId*/, uint32 token, uint32 status) override { _session->SendResponse(token, status); }
+ void SendResponse(uint32 /*serviceHash*/, uint32 /*methodId*/, uint32 token, google::protobuf::Message const* response) override { _session->SendResponse(token, response); }
+ std::string GetCallerInfo() const override { return _session->GetClientInfo(); }
+
+ Session* _session;
+ };
+}
+
+#endif // Service_h__
diff --git a/src/server/bnetserver/Services/ServiceDispatcher.cpp b/src/server/bnetserver/Services/ServiceDispatcher.cpp
new file mode 100644
index 00000000000..ded1c2d3765
--- /dev/null
+++ b/src/server/bnetserver/Services/ServiceDispatcher.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 "ServiceDispatcher.h"
+
+Battlenet::ServiceDispatcher::ServiceDispatcher()
+{
+ AddService<Services::Account>();
+ AddService<Services::Authentication>();
+ AddService<Service<challenge::v1::ChallengeService>>();
+ AddService<Service<channel::v1::ChannelService>>();
+ AddService<Services::Connection>();
+ AddService<Service<friends::v1::FriendsService>>();
+ AddService<Services::GameUtilities>();
+ AddService<Service<presence::v1::PresenceService>>();
+ AddService<Service<report::v1::ReportService>>();
+ AddService<Service<resources::v1::ResourcesService>>();
+ AddService<Service<user_manager::v1::UserManagerService>>();
+}
+
+void Battlenet::ServiceDispatcher::Dispatch(Session* 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->GetClientInfo().c_str(), serviceHash);
+}
+
+Battlenet::ServiceDispatcher& Battlenet::ServiceDispatcher::Instance()
+{
+ static ServiceDispatcher instance;
+ return instance;
+}
diff --git a/src/server/bnetserver/Services/ServiceDispatcher.h b/src/server/bnetserver/Services/ServiceDispatcher.h
new file mode 100644
index 00000000000..03f67070ef5
--- /dev/null
+++ b/src/server/bnetserver/Services/ServiceDispatcher.h
@@ -0,0 +1,68 @@
+/*
+ * 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 "MessageBuffer.h"
+#include "Log.h"
+#include "Common.h"
+#include "AccountService.h"
+#include "AuthenticationService.h"
+#include "challenge_service.pb.h"
+#include "channel_service.pb.h"
+#include "ConnectionService.h"
+#include "friends_service.pb.h"
+#include "GameUtilitiesService.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 Session;
+
+ class ServiceDispatcher
+ {
+ public:
+ void Dispatch(Session* session, uint32 serviceHash, uint32 token, uint32 methodId, MessageBuffer buffer);
+
+ static ServiceDispatcher& Instance();
+
+ private:
+ ServiceDispatcher();
+
+ template<class Service>
+ void AddService()
+ {
+ _dispatchers[Service::OriginalHash::value] = &ServiceDispatcher::Dispatch<Service>;
+ }
+
+ template<class Service>
+ static void Dispatch(Session* session, uint32 token, uint32 methodId, MessageBuffer buffer)
+ {
+ Service(session).CallServerMethod(token, methodId, std::forward<MessageBuffer>(buffer));
+ }
+
+ std::unordered_map<uint32, std::function<void(Session*, uint32, uint32, MessageBuffer)>> _dispatchers;
+ };
+}
+
+#define sServiceDispatcher ServiceDispatcher::Instance()
+
+#endif // ServiceRegistry_h__
diff --git a/src/server/bnetserver/bnetserver.cert.pem b/src/server/bnetserver/bnetserver.cert.pem
new file mode 100644
index 00000000000..f556bcf80b8
--- /dev/null
+++ b/src/server/bnetserver/bnetserver.cert.pem
@@ -0,0 +1,100 @@
+-----BEGIN CERTIFICATE-----
+MIIFhjCCA26gAwIBAgIBATANBgkqhkiG9w0BAQsFADB6MQswCQYDVQQGEwJVUzEU
+MBIGA1UECgwLVHJpbml0eUNvcmUxKjAoBgNVBAsMIVRyaW5pdHlDb3JlIENlcnRp
+ZmljYXRlIEF1dGhvcml0eTEpMCcGA1UEAwwgVHJpbml0eUNvcmUgQmF0dGxlLm5l
+dCBBdXJvcmEgQ0EwHhcNMTYwMjI4MTMxMTI4WhcNMzYwMjIzMTMxMTI4WjBGMQsw
+CQYDVQQGEwJVUzEUMBIGA1UECgwLVHJpbml0eUNvcmUxEzARBgNVBAsMCkRldmVs
+b3BlcnMxDDAKBgNVBAMMAyouKjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAMDdxGJioQxmsBq4etsAII4d8K+AnFepaetRL9/Y805IHrVwwRdklgvbP6c0
+v4ddB0MC/T9HGJam2R4/3WqzqYXKqZStOVrCQvO+pVAEknlVlT4h7Jn6Us48eual
+dj35nDRNUlBIszjn6WqMby31aoecuDJLksV8Tlwl0vQp0AcEKPH/+LlenMx2YIoI
+uwkiA++VSt1Yar5U2i2BaBIjqY1jQEO8f9fLL/laElbl/mpWHs9jw8FPoZdAqcxC
+KrWmr57XHvbEN7hHd3l2BgCael/mzlSLUZlIW91l6CF5hzGi3uaEnHCDWte2S+x9
+iEjqq/9T36vOApP1UrW8xHyXU2cCAwEAAaOCAUkwggFFMAkGA1UdEwQCMAAwEQYJ
+YIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRl
+ZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFL5TLPbXOTB9xRBJ8pUFw7+2
+6nlqMIGrBgNVHSMEgaMwgaCAFI7XCpyCprztwOvx8+S7g+SXQuFZoYGEpIGBMH8x
+CzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtUcmluaXR5Q29yZTEqMCgGA1UECwwhVHJp
+bml0eUNvcmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MS4wLAYDVQQDDCVUcmluaXR5
+Q29yZSBCYXR0bGUubmV0IEF1cm9yYSBSb290IENBggEBMA4GA1UdDwEB/wQEAwIF
+oDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEACt0tfSaR
+8wu4GPpqDD69Ch7o2tN6K4Wr8S2xkdmVMKTp6DXvpeWVlIiK30q8yxQdrzupyaTJ
+CVmWmA+IAHlaHYy5EsWI3CW2q47y6HugZoGEYL7oVZEcgCy3F1c2q100T/fdYXoO
+Se6PM87hC9iE9kvmL8WxN8o98zRYcrSgzen/xJjESSR1gdyVBiFiT0RE4qr+tFkq
+JW6PUZiYoFXXerqR5QrsUkIkIYBp9f2BCOR9ZMlrlKe/ojUaRaW/3fFwyV22g+jQ
+MRkzkxeg6ynfTcsMiiIHSpX3ajy+m03mfbp1fIaHr/F6YbxqpzylfUOu0VOp3cUo
+5/so4JESWMpDaArmlNdfrfvLAjn0jKQZwNg/rI5SNGF55r2Dc8KXc6rZ7wJo0bvl
+ZQIQMWES1ZLxBa/r5yF8kPnxUrNLIQ8HdPxonPeU5L2CpEv8k3Fii//8N6h0Orpv
+I+FUGpYOcdBLITb/jVn5WkXW0q3Qjlb5MQjLyRweBVfP6WOUbyI3rV+BvbrgkJSI
+DqN2duvVLJgJa6ebmYRs1NfkTaX/TY3MB4B+Eo0nM6f9qSbptDo2oXAt6mhJDyRQ
+m9T7wdl98+cv5QlCZUBPbOEGv8ZM2I/hUZeW+svcWhd1ONyLVByCAFLsGWpAylML
+DgH8o+NLrjzNhQxllkENFN0mVnfc42Yo+T8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2jCCA8KgAwIBAgIBATANBgkqhkiG9w0BAQsFADB/MQswCQYDVQQGEwJVUzEU
+MBIGA1UECgwLVHJpbml0eUNvcmUxKjAoBgNVBAsMIVRyaW5pdHlDb3JlIENlcnRp
+ZmljYXRlIEF1dGhvcml0eTEuMCwGA1UEAwwlVHJpbml0eUNvcmUgQmF0dGxlLm5l
+dCBBdXJvcmEgUm9vdCBDQTAeFw0xNjAyMjgxMzAxMjJaFw0zNjAyMjMxMzAxMjJa
+MHoxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtUcmluaXR5Q29yZTEqMCgGA1UECwwh
+VHJpbml0eUNvcmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSkwJwYDVQQDDCBUcmlu
+aXR5Q29yZSBCYXR0bGUubmV0IEF1cm9yYSBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD
+ggIPADCCAgoCggIBAMOim0oMJ8hed2ZO0n4FSWCK+AqTKqOKEwkZzmv+f0jd5dH9
+F9DmlkqGJXb1FWsd+5rp6GbDHorMsJDIKBfWuNxoVHvgSQUnBXosY/TTXn6DbLCN
+hZWnfxARzAp8T/FXL/rlwhR1cYkN+WugAq58/Aa+khaG2JNvSb/e1y5KiJ7wKN2N
+bFLZ/dIslBE5gJzgO5hU19WM0vSXRl2Pw0gWBNvvZUa4FH4tW95zdARtAxJPgg1d
+21qtXnfbE8xTCLKE5GAIlOK+r9+3elt6y+EZiZ8cq/b/Jfp+1GNBAlVLlpPzS7LQ
+f+DtVKJ4FTtADWmRWEEy4vaUhblDfo2nokNdmcnTy93bmOHwJlKkRZVT/vwhKlMS
+INtBEXJfZS+UM+CvhIAhSwRwSa97Nz8WEpNvWJwl/eUT3D+JOF+bklTvR7Vwwwtu
+PgJks8+aLCjEC/T5n7KotxTV1tW5OD3Dy3urJ01INe0SEHMMPVPj2ejqHg2ndGRF
+dC0QlmIxNpaSGqs5H12rxbmwyOpv2P0+ESwlWCJn87WUJhbs9ez3lr8OyXByMpvU
+5wqJxzrTMkJ2xHQp8XVIJclKHt/irExru/v7wS05usvr5fC4uCICAqQO5Ed6OvP+
+/krW3YNR/5UgzUpFz+2md4AIXur8uU6qVEc31fKufiTWnVS2h3v1tccGsKg/AgMB
+AAGjZjBkMB0GA1UdDgQWBBSO1wqcgqa87cDr8fPku4Pkl0LhWTAfBgNVHSMEGDAW
+gBQS3qDGF+YcRzusE6ockR82TMa/czASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1Ud
+DwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAvxnyXNtRosLnrG4BCgr3zwHx
+H0T4h2yllCsqcM9DE3dBzyjtIooHLIEtuK5JtZKQawh95Hg9Y/e+aiXPgiIZtsob
+mJn8GovjB6JpUsiA5I7NqNfOfcsZu39/PZC2F0C8t7M1FHmQpSEnL5m9pGnJ4Kzi
+y/Zz4woAeT+tipJISDPJnWjvItQOS8Wv/mScbHa/8Z7o21ZITZMGRG8LIo8Fpc+p
+8VT9ysJ1WvP/Cc1g703ojperADspKpA/yAWSI0WBrlNUUP3zN/RNKJq+pwKSad+3
+o30tYGDkfTUMDFfsJ68UwalZHPuwCuG5g4ZIhMQwqzeOhX8nW40Pcsc9dQPIF2Jz
+FHfSRtAUj0JCb5dS08AH7z2wQRELkzeR5x/5GB6b9fg96xjcHWTsfbH7K63e6Lv4
++ZEggfBip5VCL9xAyNK22p1TvXLY73V2zyqJ9dH/8lGWfm+OvQ1hzQbwPJ7J8BPI
+u+fJJaOze557QKTmeHYPvoj/q3X2xLyMXW236fu5EBXK1RhDgrRXxf4aHB0Bzn7n
+quyUU8spdLG97OljvGEiESLj9oWYbXKLnWqz6TWOnAmTtRLaK2iau3iP+7lwkaoe
+Q6DZHDkgLtiTx7VwsSJZTU5o+TPj4wfjS9Jl3j8PMVPpfG5IFF3ErOEsz/KPu9Nz
+j7x/l+OtqHw4Pithuig=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF5DCCA8ygAwIBAgIJAIgLslwk40XzMA0GCSqGSIb3DQEBCwUAMH8xCzAJBgNV
+BAYTAlVTMRQwEgYDVQQKDAtUcmluaXR5Q29yZTEqMCgGA1UECwwhVHJpbml0eUNv
+cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MS4wLAYDVQQDDCVUcmluaXR5Q29yZSBC
+YXR0bGUubmV0IEF1cm9yYSBSb290IENBMB4XDTE2MDIyODEyNDkwOFoXDTM2MDIy
+MzEyNDkwOFowfzELMAkGA1UEBhMCVVMxFDASBgNVBAoMC1RyaW5pdHlDb3JlMSow
+KAYDVQQLDCFUcmluaXR5Q29yZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxLjAsBgNV
+BAMMJVRyaW5pdHlDb3JlIEJhdHRsZS5uZXQgQXVyb3JhIFJvb3QgQ0EwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGrYWvS0mVParJd96E4z/qjCvW6eR0
+buQ++VNEqVgeG14k4V41wkEzakB4nr2oGH10z9J/aqLlWnxaOl+yJ7BaomUAAOgJ
+aCyqAJ8HaEU+7BbDO4MZXmtw1A3YcHsBkVx5wGm3tcH5IEXfVhvNZDqwAmYIcm7g
+KFgnds6RFJmRxF4WznWiRr2MQkSOr/kc2eQ2VUg5afTlTxZva/mXEVpShinvbhaM
+SgFBW+QahCwBJVQaLhEn+Wc6YNuHFmZ/i716xGb3cuYu89TF46iKQ/9Bm8yEFGg8
+QA28IZQ1sXgVpzJI9eowFtqAwhl65ipjGw4xH33of+WcwJQNjF7HXymRqk0WAa2j
+tXOEiShI3XDloblX7vKbAe9RFpfVIqT8UfKSOJGQDVzvl4wSihINshO7YgIqp97M
+GnWtnlWCDb2mcSj8JjnzRjG2kZZCNR/2lgfCG/1VF+QLh/3vD2+N5YkJZqBK1JTF
+Fx+p66lVQWfdh2MXPlGjat343HZGm0YR7nRjngO2j3YtTojdJxRfLgztQv94jMtW
+PHE38ysUK7mS6KKqYXqyB19IOHL2QB8fjmON1hCd0wDW42ZB23ywNkASw6uJDR02
+xXN2wiynIIb3cz6zouXd60wC7utMTveq8+rhFFgmFDdI2o9gwWQPA/43OYIlAdKV
+g2NRhXb/6bzFkwIDAQABo2MwYTAdBgNVHQ4EFgQUEt6gxhfmHEc7rBOqHJEfNkzG
+v3MwHwYDVR0jBBgwFoAUEt6gxhfmHEc7rBOqHJEfNkzGv3MwDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAFzCJkcDCPVM
+al+Thlip26LPkszZ4zWTsNsbUYmSe7h0kmMWt4x3mmZITfwb/eysYCnHThBVTjXj
+9VWBGfbECZ/xdyXC2ur+qp0Mm7xH2Wuswf7yfPC+USNO6+/tFS282FO/nM0quaKV
+knOC8ioCoASsBICB9lwRoYRKNBwRn3pkJplHepGahaJez4eedujO3dzxDdD32zy2
+/AfdeFXTxhWY8PTjMBKC2zpUQD7Kdvl+D8SfIsq73b8a9XmhdNX7qTc6MjecCD7W
+HAP2rrK7epjTaVJp4+PYlw7qfix/NT1fNkq2Mb2E77h2eToUG1mjs/mvG/4WfVCf
+MaBHOKaw6fyZULf366Jbx02r8K05P5ouvS1Z0De1mZJuUEUYhTRSs2POIdrmVrn9
+R83Y4l7TKNPJelq2uyEc4r+/fRrerIlT4HVlLPTC3SdW8ytYSUZXx+1NfJfQimie
+veIyIaTOV3SfC4EfeXtPtUpcVJvmFXqVbnXOO7bQU63bfFuuVSeU6OXWjoFRVkdH
+NYTGUGb5xg4hgWqlLWvWg0WPgLLabMbetrP6c5/Qhml/l07nJHeLoVxlFuwsL8HG
+eu0JWqnmwamp4/mmblRC9UfyrIQeDS8gsx8q/t2zdzT4bBph0nqYkZSyiIoQzlMr
+YdrWxeJm3sReR0G3FluL+03TGJypGfhr
+-----END CERTIFICATE-----
diff --git a/src/server/bnetserver/bnetserver.conf.dist b/src/server/bnetserver/bnetserver.conf.dist
index 252a29440b5..211e63cfdb9 100644
--- a/src/server/bnetserver/bnetserver.conf.dist
+++ b/src/server/bnetserver/bnetserver.conf.dist
@@ -55,6 +55,22 @@ MaxPingTime = 30
BattlenetPort = 1119
#
+# LoginREST.Port
+# Description: TCP port to reach the REST login method.
+# Default: 8081
+#
+# LoginREST.ExternalAddress
+# Description: IP address sent to clients connecting from outside the network where bnetserver runs
+#
+# LoginREST.LocalAddress
+# Description: IP address sent to clients connecting from inside the network where bnetserver runs
+#
+
+LoginREST.Port = 8081
+LoginREST.ExternalAddress=127.0.0.1
+LoginREST.LocalAddress=127.0.0.1
+
+#
#
# BindIP
# Description: Bind auth server to IP/hostname
diff --git a/src/server/bnetserver/bnetserver.key.pem b/src/server/bnetserver/bnetserver.key.pem
new file mode 100644
index 00000000000..bec4bcd1e4b
--- /dev/null
+++ b/src/server/bnetserver/bnetserver.key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAwN3EYmKhDGawGrh62wAgjh3wr4CcV6lp61Ev39jzTkgetXDB
+F2SWC9s/pzS/h10HQwL9P0cYlqbZHj/darOphcqplK05WsJC876lUASSeVWVPiHs
+mfpSzjx65qV2PfmcNE1SUEizOOfpaoxvLfVqh5y4MkuSxXxOXCXS9CnQBwQo8f/4
+uV6czHZgigi7CSID75VK3VhqvlTaLYFoEiOpjWNAQ7x/18sv+VoSVuX+alYez2PD
+wU+hl0CpzEIqtaavntce9sQ3uEd3eXYGAJp6X+bOVItRmUhb3WXoIXmHMaLe5oSc
+cINa17ZL7H2ISOqr/1Pfq84Ck/VStbzEfJdTZwIDAQABAoIBAHcu1DQERQd30a3B
+gNIi4vtPzzN1I6gcXgL3+cC3vasLcEapdflxxDNxeoVmWFFbEKi9iSf4VF6MnrFN
+wBM3ETRHh8IDxeSrFVqw3lFzcdyfIYnyxtZkVZVy1HQBne8wd/HuMkbAllg9IAYi
+4HWjKgDBvSX/g6Sca4QQL6uIxy/9s3Z4K2vU8KbvUpwo+ON4HMt61fgrIrbEUVCl
+TMCVEf8UphwHctmQJb/Pr0+BCTdiv04ga1dkt+ZyR2o0VN6T/zKDqk4m1sSl0GZz
+8sn63GbuTlwHcm9GgkaxoeeZJK1/sdOSIZN8W3PpnyHrAZJlNOY7G684F1mBaWV1
+PGCcVtkCgYEA8jCDTGub7ZyMk48x+8L3Devja3TQz7YNIGkVEbQBpNw4gDV8j1m6
+EgqFdzowkY+gbA76ylNfm6Aa66RDR/LbTbXlsNd8YkXcbU3xDQ96F6cS51VBkled
+hq+iAuGJB9VYN5yP1P/Oswg/AFMjOnsfBL/1zFo26364z9x8zazw0wsCgYEAy907
+mpkk59AQ4YIDSR9wK2YpXv6HoBPFld6m7PAnBWFO0uNtQ0YppbYbrhmDqrxUoFud
+ZiEHIa0gLlp9lHr+UdUAMPDlJ6gbMnJW3U5qiVuuZA13tiZFlv11qUeU1tQUzTUv
+ZoIISN15Im0PQzUFbTxSFbS+vTYjsedv1C9UOpUCgYEAkTaTUzvmV3cZNtSSFLFW
+ros0Zda56QDwJ/G5x06V+cJtQjpPwCf9kBms4ssKGgzzFDd7GdsZpVc/LPDlwnsU
+ESkyWnEpzEa1HvivwrP38bykcf5Ffbh45CvkyTNvlTnPVjDScNUcm24jUE+I/OSb
+uZ5bg7bH3TWzHDbIwg2iq/cCgYB+DPqvqoVhOAtYBBWX/vJSQ0bNT7/4QIFpG1RH
+KG5YK0SbrLeAYz+ZELKowWniBbSluj/mSAGq1usQ/i6rwijB3FvT5v8puA2o8X24
+NKY27BM2FgWxAJUCuREpa/Mhqdx6zanTTg9lTlt558kKGxyR4Dw445sUTwdfFuTU
+Y7dGyQKBgAG0vyOdfku9TlPX2a3LasM5jkbxljeTlCJUlahW7LSoQEmLoEhOM4Ja
+6CA5PADhA16pOUweKjOtSkNEcVEorFNjlH34PpnsysF+NsDBP5HEy0eYyHSYwg1Y
+7BGwQxUOoBaUKMu7jVQcffrKiWOGEXzBDSEZ3A30t7+JIS7qy1d1
+-----END RSA PRIVATE KEY-----