aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Server
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2016-03-28 17:12:57 +0200
committerShauren <shauren.trinity@gmail.com>2016-03-28 17:12:57 +0200
commitdde620c402daf4ea8d132fb72a77eabc22f7a6d0 (patch)
tree7c12161d7a22915736b0c9a106de896eeb283399 /src/server/game/Server
parent619669c6209441fc2fb5b483d553badee8c30ad5 (diff)
Core: Updated to 6.2.4
* Rewrite bnetserver for new authentication protocol
Diffstat (limited to 'src/server/game/Server')
-rw-r--r--src/server/game/Server/Packets/AllPackets.h1
-rw-r--r--src/server/game/Server/Packets/BattlenetPackets.cpp89
-rw-r--r--src/server/game/Server/Packets/BattlenetPackets.h108
-rw-r--r--src/server/game/Server/Packets/QueryPackets.cpp2
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp12
-rw-r--r--src/server/game/Server/WorldSession.cpp23
-rw-r--r--src/server/game/Server/WorldSession.h36
7 files changed, 262 insertions, 9 deletions
diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h
index 60dd2493b12..0d6d28446bc 100644
--- a/src/server/game/Server/Packets/AllPackets.h
+++ b/src/server/game/Server/Packets/AllPackets.h
@@ -24,6 +24,7 @@
#include "BankPackets.h"
#include "BattlefieldPackets.h"
#include "BattlegroundPackets.h"
+#include "BattlenetPackets.h"
#include "BattlePetPackets.h"
#include "BlackMarketPackets.h"
#include "CalendarPackets.h"
diff --git a/src/server/game/Server/Packets/BattlenetPackets.cpp b/src/server/game/Server/Packets/BattlenetPackets.cpp
new file mode 100644
index 00000000000..de3d6ab3010
--- /dev/null
+++ b/src/server/game/Server/Packets/BattlenetPackets.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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 "BattlenetPackets.h"
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battlenet::MethodCall const& method)
+{
+ data << uint64(method.Type);
+ data << uint64(method.ObjectId);
+ data << uint32(method.Token);
+ return data;
+}
+
+ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Battlenet::MethodCall& method)
+{
+ data >> method.Type;
+ data >> method.ObjectId;
+ data >> method.Token;
+ return data;
+}
+
+WorldPacket const* WorldPackets::Battlenet::Notification::Write()
+{
+ _worldPacket << Method;
+ _worldPacket << uint32(Data.size());
+ _worldPacket.append(Data);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battlenet::Response::Write()
+{
+ _worldPacket << uint32(BnetStatus);
+ _worldPacket << Method;
+ _worldPacket << uint32(Data.size());
+ _worldPacket.append(Data);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battlenet::SetSessionState::Write()
+{
+ _worldPacket.WriteBits(State, 2);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battlenet::RealmListTicket::Write()
+{
+ _worldPacket << uint32(Token);
+ _worldPacket.WriteBit(Allow);
+ _worldPacket << uint32(Ticket.size());
+ _worldPacket.append(Ticket);
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Battlenet::Request::Read()
+{
+ uint32 protoSize;
+
+ _worldPacket >> Method;
+ _worldPacket >> protoSize;
+
+ Data.Resize(protoSize);
+ _worldPacket.read(Data.GetWritePointer(), Data.GetRemainingSpace());
+ Data.WriteCompleted(protoSize);
+}
+
+void WorldPackets::Battlenet::RequestRealmListTicket::Read()
+{
+ _worldPacket >> Token;
+ _worldPacket.read(Secret.data(), Secret.size());
+}
diff --git a/src/server/game/Server/Packets/BattlenetPackets.h b/src/server/game/Server/Packets/BattlenetPackets.h
new file mode 100644
index 00000000000..f059b39b75f
--- /dev/null
+++ b/src/server/game/Server/Packets/BattlenetPackets.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 BattlenetPackets_h__
+#define BattlenetPackets_h__
+
+#include "Packet.h"
+#include "MessageBuffer.h"
+#include "BattlenetRpcErrorCodes.h"
+
+namespace WorldPackets
+{
+ namespace Battlenet
+ {
+ struct MethodCall
+ {
+ uint64 Type = 0;
+ uint64 ObjectId = 0;
+ uint32 Token = 0;
+
+ uint32 GetServiceHash() const { return uint32(Type >> 32); }
+ uint32 GetMethodId() const { return uint32(Type & 0xFFFFFFFF); }
+ };
+
+ class Notification final : public ServerPacket
+ {
+ public:
+ Notification() : ServerPacket(SMSG_BATTLENET_NOTIFICATION, 8 + 8 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ MethodCall Method;
+ ByteBuffer Data;
+ };
+
+ class Response final : public ServerPacket
+ {
+ public:
+ Response() : ServerPacket(SMSG_BATTLENET_RESPONSE, 4 + 8 + 8 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ BattlenetRpcErrorCode BnetStatus = ERROR_OK;
+ MethodCall Method;
+ ByteBuffer Data;
+ };
+
+ class SetSessionState final : public ServerPacket
+ {
+ public:
+ SetSessionState() : ServerPacket(SMSG_BATTLENET_SET_SESSION_STATE, 1) { }
+
+ WorldPacket const* Write() override;
+
+ uint8 State = 0;
+ };
+
+ class RealmListTicket final : public ServerPacket
+ {
+ public:
+ RealmListTicket() : ServerPacket(SMSG_BATTLENET_REALM_LIST_TICKET) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 Token;
+ bool Allow;
+ ByteBuffer Ticket;
+ };
+
+ class Request final : public ClientPacket
+ {
+ public:
+ Request(WorldPacket&& packet) : ClientPacket(CMSG_BATTLENET_REQUEST, std::move(packet)) { }
+
+ void Read() override;
+
+ MethodCall Method;
+ MessageBuffer Data;
+ };
+
+ class RequestRealmListTicket final : public ClientPacket
+ {
+ public:
+ RequestRealmListTicket(WorldPacket&& packet) : ClientPacket(CMSG_BATTLENET_REQUEST_REALM_LIST_TICKET, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 Token = 0;
+ std::array<uint8, 32> Secret;
+ };
+ }
+}
+
+#endif // BattlenetPackets_h__
diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp
index ca37b04f484..aeaf43e6e8a 100644
--- a/src/server/game/Server/Packets/QueryPackets.cpp
+++ b/src/server/game/Server/Packets/QueryPackets.cpp
@@ -137,7 +137,7 @@ bool WorldPackets::Query::PlayerGuidLookupData::Initialize(ObjectGuid const& gui
else
{
uint32 accountId = ObjectMgr::GetPlayerAccountIdByGUID(guid);
- uint32 bnetAccountId = Battlenet::AccountMgr::GetIdByGameAccount(accountId);
+ uint32 bnetAccountId = ::Battlenet::AccountMgr::GetIdByGameAccount(accountId);
AccountID = ObjectGuid::Create<HighGuid::WowAccount>(accountId);
BnetAccountID = ObjectGuid::Create<HighGuid::BNetAccount>(bnetAccountId);
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 19aff2468a9..931b74dd234 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -159,8 +159,8 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_BATTLEMASTER_JOIN_ARENA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battleground::BattlemasterJoinArena, &WorldSession::HandleBattlemasterJoinArena);
DEFINE_HANDLER(CMSG_BATTLEMASTER_JOIN_SKIRMISH, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_BATTLENET_CHALLENGE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
- DEFINE_HANDLER(CMSG_BATTLENET_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Null, &WorldSession::Handle_NULL);
- DEFINE_HANDLER(CMSG_BATTLENET_REQUEST_REALM_LIST_TICKET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Null, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_BATTLENET_REQUEST, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Battlenet::Request, &WorldSession::HandleBattlenetRequest);
+ DEFINE_HANDLER(CMSG_BATTLENET_REQUEST_REALM_LIST_TICKET, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Battlenet::RequestRealmListTicket, &WorldSession::HandleBattlenetRequestRealmListTicket);
DEFINE_HANDLER(CMSG_BATTLE_PAY_ACK_FAILED_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_BATTLE_PAY_CONFIRM_PURCHASE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_BATTLE_PAY_DISTRIBUTION_ASSIGN_TO_TARGET, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
@@ -867,10 +867,10 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_POINTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLENET_CHALLENGE_ABORT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLENET_CHALLENGE_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLENET_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLENET_REALM_LIST_TICKET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLENET_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLENET_SET_SESSION_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLENET_NOTIFICATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLENET_REALM_LIST_TICKET, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLENET_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLENET_SET_SESSION_STATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_ACK_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_CONFIRM_PURCHASE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_DELIVERY_ENDED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 44bfa90589c..aa2b2c28ede 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -43,7 +43,7 @@
#include "ScriptMgr.h"
#include "WardenWin.h"
#include "AuthenticationPackets.h"
-#include "BattlenetRpcErrorCodes.h"
+#include "BattlenetPackets.h"
#include "CharacterPackets.h"
#include "ClientConfigPackets.h"
#include "MiscPackets.h"
@@ -1151,13 +1151,14 @@ public:
BATTLE_PETS,
BATTLE_PET_SLOTS,
GLOBAL_ACCOUNT_HEIRLOOMS,
+ GLOBAL_REALM_CHARACTER_COUNTS,
MAX_QUERIES
};
AccountInfoQueryHolder() { SetSize(MAX_QUERIES); }
- bool Initialize(uint32 /*accountId*/, uint32 battlenetAccountId)
+ bool Initialize(uint32 accountId, uint32 battlenetAccountId)
{
bool ok = true;
@@ -1177,6 +1178,10 @@ public:
stmt->setUInt32(0, battlenetAccountId);
ok = SetPreparedQuery(GLOBAL_ACCOUNT_HEIRLOOMS, stmt) && ok;
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_ACCOUNT_ID);
+ stmt->setUInt32(0, accountId);
+ ok = SetPreparedQuery(GLOBAL_REALM_CHARACTER_COUNTS, stmt) && ok;
+
return ok;
}
};
@@ -1225,6 +1230,20 @@ void WorldSession::InitializeSessionCallback(SQLQueryHolder* realmHolder, SQLQue
SendClientCacheVersion(sWorld->getIntConfig(CONFIG_CLIENTCACHE_VERSION));
SendTutorialsData();
+ if (PreparedQueryResult characterCountsResult = holder->GetPreparedResult(AccountInfoQueryHolder::GLOBAL_REALM_CHARACTER_COUNTS))
+ {
+ do
+ {
+ Field* fields = characterCountsResult->Fetch();
+ _realmCharacterCounts[Battlenet::RealmHandle{ fields[3].GetUInt8(), fields[4].GetUInt8(), fields[2].GetUInt32() }.GetAddress()] = fields[1].GetUInt8();
+
+ } while (characterCountsResult->NextRow());
+ }
+
+ WorldPackets::Battlenet::SetSessionState bnetConnected;
+ bnetConnected.State = 1;
+ SendPacket(bnetConnected.Write());
+
_battlePetMgr->LoadFromDB(holder->GetPreparedResult(AccountInfoQueryHolder::BATTLE_PETS),
holder->GetPreparedResult(AccountInfoQueryHolder::BATTLE_PET_SLOTS));
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 0b23e0ac71b..35ce9c7026f 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -129,6 +129,12 @@ namespace WorldPackets
class RequestRatedBattlefieldInfo;
}
+ namespace Battlenet
+ {
+ class Request;
+ class RequestRealmListTicket;
+ }
+
namespace BattlePet
{
class BattlePetRequestJournal;
@@ -704,6 +710,16 @@ namespace WorldPackets
};
}
+namespace google
+{
+ namespace protobuf
+ {
+ class Message;
+ }
+}
+
+namespace pb = google::protobuf;
+
enum AccountDataType
{
GLOBAL_CONFIG_CACHE = 0, // 0x01 g
@@ -916,6 +932,7 @@ class TC_GAME_API WorldSession
std::string const& GetRemoteAddress() const { return m_Address; }
void SetPlayer(Player* player);
uint8 GetExpansion() const { return m_expansion; }
+ std::string const& GetOS() const { return _os; }
void InitWarden(BigNumber* k);
@@ -1678,6 +1695,20 @@ class TC_GAME_API WorldSession
// Warden
void HandleWardenData(WorldPackets::Warden::WardenData& packet);
+ // Battlenet
+ void HandleBattlenetRequest(WorldPackets::Battlenet::Request& request);
+ void HandleBattlenetRequestRealmListTicket(WorldPackets::Battlenet::RequestRealmListTicket& requestRealmListTicket);
+
+ void SendBattlenetResponse(uint32 serviceHash, uint32 methodId, uint32 token, pb::Message const* response);
+ void SendBattlenetResponse(uint32 serviceHash, uint32 methodId, uint32 token, uint32 status);
+ void SendBattlenetRequest(uint32 serviceHash, uint32 methodId, pb::Message const* request, std::function<void(MessageBuffer)> callback);
+ void SendBattlenetRequest(uint32 serviceHash, uint32 methodId, pb::Message const* request);
+
+ std::array<uint8, 32> const& GetRealmListSecret() const { return _realmListSecret; }
+ void SetRealmListSecret(std::array<uint8, 32> const& secret) { memcpy(_realmListSecret.data(), secret.data(), secret.size()); }
+
+ std::unordered_map<uint32, uint8> const& GetRealmCharacterCounts() const { return _realmCharacterCounts; }
+
union ConnectToKey
{
struct
@@ -1775,6 +1806,11 @@ class TC_GAME_API WorldSession
uint8 m_expansion;
std::string _os;
+ std::array<uint8, 32> _realmListSecret;
+ std::unordered_map<uint32 /*realmAddress*/, uint8> _realmCharacterCounts;
+ std::unordered_map<uint32, std::function<void(MessageBuffer)>> _battlenetResponseCallbacks;
+ uint32 _battlenetRequestToken;
+
typedef std::list<AddonInfo> AddonsList;
// Warden