mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-26 20:02:25 +01:00
Merge branch 'battle.net' into 4.3.4
This commit is contained in:
@@ -79,4 +79,9 @@ namespace AuthHelper
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool IsBuildSupportingBattlenet(int build)
|
||||
{
|
||||
return build >= 15595;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,96 @@ enum LoginResult
|
||||
LOGIN_LOCKED_ENFORCED = 0x10
|
||||
};
|
||||
|
||||
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_REFERRAL = 0x00000800,
|
||||
GAMEACCOUNT_FLAG_BLIZZARD = 0x00001000,
|
||||
GAMEACCOUNT_FLAG_RECURRING_BILLING = 0x00002000,
|
||||
GAMEACCOUNT_FLAG_NOELECTUP = 0x00004000,
|
||||
GAMEACCOUNT_FLAG_KR_CERTIFICATE = 0x00008000,
|
||||
GAMEACCOUNT_FLAG_EXPANSION_COLLECTOR = 0x00010000,
|
||||
GAMEACCOUNT_FLAG_DISABLE_VOICE = 0x00020000,
|
||||
GAMEACCOUNT_FLAG_DISABLE_VOICE_SPEAK = 0x00040000,
|
||||
GAMEACCOUNT_FLAG_REFERRAL_RESURRECT = 0x00080000,
|
||||
GAMEACCOUNT_FLAG_EU_FORBID_CC = 0x00100000,
|
||||
GAMEACCOUNT_FLAG_OPENBETA_DELL = 0x00200000,
|
||||
GAMEACCOUNT_FLAG_PROPASS = 0x00400000,
|
||||
GAMEACCOUNT_FLAG_PROPASS_LOCK = 0x00800000,
|
||||
GAMEACCOUNT_FLAG_PENDING_UPGRADE = 0x01000000,
|
||||
GAMEACCOUNT_FLAG_RETAIL_FROM_TRIAL = 0x02000000,
|
||||
GAMEACCOUNT_FLAG_EXPANSION2_COLLECTOR = 0x04000000,
|
||||
GAMEACCOUNT_FLAG_OVERMIND_LINKED = 0x08000000,
|
||||
GAMEACCOUNT_FLAG_DEMOS = 0x10000000,
|
||||
GAMEACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x20000000,
|
||||
};
|
||||
|
||||
namespace Battlenet
|
||||
{
|
||||
enum AuthResult
|
||||
{
|
||||
AUTH_OK = 0,
|
||||
AUTH_INTERNAL_ERROR = 100,
|
||||
AUTH_CORRUPTED_MODULE = 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
|
||||
};
|
||||
}
|
||||
|
||||
enum ExpansionFlags
|
||||
{
|
||||
POST_BC_EXP_FLAG = 0x2,
|
||||
@@ -92,6 +182,7 @@ namespace AuthHelper
|
||||
bool IsAcceptedClientBuild(int build);
|
||||
bool IsPostBCAcceptedClientBuild(int build);
|
||||
bool IsPreBCAcceptedClientBuild(int build);
|
||||
bool IsBuildSupportingBattlenet(int build);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -151,7 +151,8 @@ extern int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
// Launch the listening network socket
|
||||
RealmAcceptor acceptor;
|
||||
RealmAcceptor<AuthSocket> acceptor;
|
||||
RealmAcceptor<Battlenet::Socket> bnetacceptor;
|
||||
|
||||
int32 rmport = sConfigMgr->GetIntDefault("RealmServerPort", 3724);
|
||||
if (rmport < 0 || rmport > 0xFFFF)
|
||||
@@ -170,6 +171,13 @@ extern int main(int argc, char** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
bind_addr.set_port_number(1119);
|
||||
if (bnetacceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1)
|
||||
{
|
||||
TC_LOG_ERROR("server.authserver", "Auth server can not bind to %s:%d", bind_ip.c_str(), 1119);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Initialize the signal handlers
|
||||
AuthServerSignalHandler SignalINT, SignalTERM;
|
||||
|
||||
@@ -246,6 +254,8 @@ extern int main(int argc, char** argv)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
sBattlenetMgr->Load();
|
||||
|
||||
// maximum counter for next ping
|
||||
uint32 numLoops = (sConfigMgr->GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000));
|
||||
uint32 loopCounter = 0;
|
||||
|
||||
@@ -18,9 +18,29 @@
|
||||
|
||||
#include "Common.h"
|
||||
#include "RealmList.h"
|
||||
#include "BattlenetManager.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Util.h"
|
||||
|
||||
RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)) { }
|
||||
ACE_INET_Addr const& Realm::GetAddressForClient(ACE_INET_Addr const& clientAddr) const
|
||||
{
|
||||
// Attempt to send best address for client
|
||||
if (clientAddr.is_loopback())
|
||||
// Assume that user connecting from the machine that authserver is located on
|
||||
// has all realms available in his local network
|
||||
return LocalAddress;
|
||||
|
||||
// Check if connecting client is in the same network
|
||||
if (IsIPAddrInNetwork(LocalAddress, clientAddr, LocalSubnetMask))
|
||||
return LocalAddress;
|
||||
|
||||
// Return external IP
|
||||
return ExternalAddress;
|
||||
}
|
||||
|
||||
RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL))
|
||||
{
|
||||
}
|
||||
|
||||
// Load the realm list from the database
|
||||
void RealmList::Initialize(uint32 updateInterval)
|
||||
@@ -31,7 +51,7 @@ void RealmList::Initialize(uint32 updateInterval)
|
||||
UpdateRealms(true);
|
||||
}
|
||||
|
||||
void RealmList::UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build)
|
||||
void RealmList::UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build, uint8 region, uint8 battlegroup)
|
||||
{
|
||||
// Create new if not exist or update existed
|
||||
Realm& realm = m_realms[name];
|
||||
@@ -49,6 +69,8 @@ void RealmList::UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr co
|
||||
realm.LocalAddress = localAddr;
|
||||
realm.LocalSubnetMask = localSubmask;
|
||||
realm.gamebuild = build;
|
||||
realm.Region = region;
|
||||
realm.Battlegroup = battlegroup;
|
||||
}
|
||||
|
||||
void RealmList::UpdateIfNeed()
|
||||
@@ -91,12 +113,14 @@ void RealmList::UpdateRealms(bool init)
|
||||
uint8 allowedSecurityLevel = fields[9].GetUInt8();
|
||||
float pop = fields[10].GetFloat();
|
||||
uint32 build = fields[11].GetUInt32();
|
||||
uint8 region = fields[12].GetUInt8();
|
||||
uint8 battlegroup = fields[13].GetUInt8();
|
||||
|
||||
ACE_INET_Addr externalAddr(port, externalAddress.c_str(), AF_INET);
|
||||
ACE_INET_Addr localAddr(port, localAddress.c_str(), AF_INET);
|
||||
ACE_INET_Addr submask(0, localSubmask.c_str(), AF_INET);
|
||||
|
||||
UpdateRealm(realmId, name, externalAddr, localAddr, submask, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build);
|
||||
UpdateRealm(realmId, name, externalAddr, localAddr, submask, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build, region, battlegroup);
|
||||
|
||||
if (init)
|
||||
TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.get_host_addr(), port);
|
||||
@@ -104,3 +128,16 @@ void RealmList::UpdateRealms(bool init)
|
||||
while (result->NextRow());
|
||||
}
|
||||
}
|
||||
|
||||
Realm const* RealmList::GetRealm(Battlenet::RealmId const& id) const
|
||||
{
|
||||
auto itr = std::find_if(m_realms.begin(), m_realms.end(), [id](RealmMap::value_type const& pair)
|
||||
{
|
||||
return pair.second.Region == id.Region && pair.second.Battlegroup == id.Battlegroup && pair.second.m_ID == id.Index;
|
||||
});
|
||||
|
||||
if (itr != m_realms.end())
|
||||
return &itr->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -51,8 +51,17 @@ struct Realm
|
||||
AccountTypes allowedSecurityLevel;
|
||||
float populationLevel;
|
||||
uint32 gamebuild;
|
||||
uint8 Region;
|
||||
uint8 Battlegroup;
|
||||
|
||||
ACE_INET_Addr const& GetAddressForClient(ACE_INET_Addr const& clientAddr) const;
|
||||
};
|
||||
|
||||
namespace Battlenet
|
||||
{
|
||||
struct RealmId;
|
||||
}
|
||||
|
||||
/// Storage object for the list of realms on the server
|
||||
class RealmList
|
||||
{
|
||||
@@ -71,10 +80,11 @@ public:
|
||||
RealmMap::const_iterator begin() const { return m_realms.begin(); }
|
||||
RealmMap::const_iterator end() const { return m_realms.end(); }
|
||||
uint32 size() const { return m_realms.size(); }
|
||||
Realm const* GetRealm(Battlenet::RealmId const& id) const;
|
||||
|
||||
private:
|
||||
void UpdateRealms(bool init=false);
|
||||
void UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build);
|
||||
void UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build, uint8 region, uint8 battlegroup);
|
||||
|
||||
RealmMap m_realms;
|
||||
uint32 m_UpdateInterval;
|
||||
|
||||
@@ -293,19 +293,11 @@ void AuthSocket::_SetVSFields(const std::string& rI)
|
||||
x.SetBinary(sha.GetDigest(), sha.GetLength());
|
||||
v = g.ModExp(x, N);
|
||||
|
||||
// No SQL injection (username escaped)
|
||||
char *v_hex, *s_hex;
|
||||
v_hex = v.AsHexStr();
|
||||
s_hex = s.AsHexStr();
|
||||
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_VS);
|
||||
stmt->setString(0, v_hex);
|
||||
stmt->setString(1, s_hex);
|
||||
stmt->setString(0, v.AsHexStr());
|
||||
stmt->setString(1, s.AsHexStr());
|
||||
stmt->setString(2, _login);
|
||||
LoginDatabase.Execute(stmt);
|
||||
|
||||
OPENSSL_free(v_hex);
|
||||
OPENSSL_free(s_hex);
|
||||
}
|
||||
|
||||
// Logon Challenge command handler
|
||||
@@ -488,7 +480,9 @@ bool AuthSocket::_HandleLogonChallenge()
|
||||
unk3.SetRand(16 * 8);
|
||||
|
||||
// Fill the response packet with the result
|
||||
if (AuthHelper::IsAcceptedClientBuild(_build))
|
||||
if (fields[9].GetUInt32() && AuthHelper::IsBuildSupportingBattlenet(_build))
|
||||
pkt << uint8(WOW_FAIL_USE_BATTLENET);
|
||||
else if (AuthHelper::IsAcceptedClientBuild(_build))
|
||||
pkt << uint8(WOW_SUCCESS);
|
||||
else
|
||||
pkt << uint8(WOW_FAIL_VERSION_INVALID);
|
||||
@@ -650,19 +644,14 @@ bool AuthSocket::_HandleLogonProof()
|
||||
TC_LOG_DEBUG("server.authserver", "'%s:%d' User '%s' successfully authenticated", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
|
||||
|
||||
// Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
|
||||
// No SQL injection (escaped user name) and IP address as received by socket
|
||||
const char *K_hex = K.AsHexStr();
|
||||
|
||||
PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF);
|
||||
stmt->setString(0, K_hex);
|
||||
stmt->setString(0, K.AsHexStr());
|
||||
stmt->setString(1, socket().getRemoteAddress().c_str());
|
||||
stmt->setUInt32(2, GetLocaleByName(_localizationName));
|
||||
stmt->setString(3, _os);
|
||||
stmt->setString(4, _login);
|
||||
LoginDatabase.DirectExecute(stmt);
|
||||
|
||||
OPENSSL_free((void*)K_hex);
|
||||
|
||||
// Finish SRP6 and send the final result to the client
|
||||
sha.Initialize();
|
||||
sha.UpdateBigNumbers(&A, &M, &K, NULL);
|
||||
@@ -693,7 +682,7 @@ bool AuthSocket::_HandleLogonProof()
|
||||
memcpy(proof.M2, sha.GetDigest(), 20);
|
||||
proof.cmd = AUTH_LOGON_PROOF;
|
||||
proof.error = 0;
|
||||
proof.unk1 = 0x00800000; // Accountflags. 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament)
|
||||
proof.unk1 = GAMEACCOUNT_FLAG_PROPASS_LOCK;
|
||||
proof.unk2 = 0x00; // SurveyId
|
||||
proof.unk3 = 0x00;
|
||||
socket().send((char *)&proof, sizeof(proof));
|
||||
@@ -879,28 +868,6 @@ bool AuthSocket::_HandleReconnectProof()
|
||||
}
|
||||
}
|
||||
|
||||
ACE_INET_Addr const& AuthSocket::GetAddressForClient(Realm const& realm, ACE_INET_Addr const& clientAddr)
|
||||
{
|
||||
// Attempt to send best address for client
|
||||
if (clientAddr.is_loopback())
|
||||
{
|
||||
// Try guessing if realm is also connected locally
|
||||
if (realm.LocalAddress.is_loopback() || realm.ExternalAddress.is_loopback())
|
||||
return clientAddr;
|
||||
|
||||
// Assume that user connecting from the machine that authserver is located on
|
||||
// has all realms available in his local network
|
||||
return realm.LocalAddress;
|
||||
}
|
||||
|
||||
// Check if connecting client is in the same network
|
||||
if (IsIPAddrInNetwork(realm.LocalAddress, clientAddr, realm.LocalSubnetMask))
|
||||
return realm.LocalAddress;
|
||||
|
||||
// Return external IP
|
||||
return realm.ExternalAddress;
|
||||
}
|
||||
|
||||
// Realm List command handler
|
||||
bool AuthSocket::_HandleRealmList()
|
||||
{
|
||||
@@ -981,12 +948,12 @@ bool AuthSocket::_HandleRealmList()
|
||||
pkt << lock; // if 1, then realm locked
|
||||
pkt << uint8(flag); // RealmFlags
|
||||
pkt << name;
|
||||
pkt << GetAddressString(GetAddressForClient(realm, clientAddr));
|
||||
pkt << GetAddressString(realm.GetAddressForClient(clientAddr));
|
||||
pkt << realm.populationLevel;
|
||||
pkt << AmountOfCharacters;
|
||||
pkt << realm.timezone; // realm category
|
||||
if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients
|
||||
pkt << uint8(0x2C); // unk, may be realm number/id?
|
||||
pkt << uint8(realm.m_ID);
|
||||
else
|
||||
pkt << uint8(0x0); // 1.12.1 and 1.12.2 clients
|
||||
|
||||
|
||||
@@ -39,8 +39,6 @@ public:
|
||||
virtual void OnAccept(void);
|
||||
virtual void OnClose(void);
|
||||
|
||||
static ACE_INET_Addr const& GetAddressForClient(Realm const& realm, ACE_INET_Addr const& clientAddr);
|
||||
|
||||
bool _HandleLogonChallenge();
|
||||
bool _HandleLogonProof();
|
||||
bool _HandleReconnectChallenge();
|
||||
|
||||
220
src/server/authserver/Server/BattlenetBitStream.h
Normal file
220
src/server/authserver/Server/BattlenetBitStream.h
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 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 __BATTLENETBITSTREAM_H__
|
||||
#define __BATTLENETBITSTREAM_H__
|
||||
|
||||
#include "ByteConverter.h"
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include <ace/Auto_Ptr.h>
|
||||
#include <ace/Stack_Trace.h>
|
||||
|
||||
namespace Battlenet
|
||||
{
|
||||
class BitStreamPositionException : public std::exception
|
||||
{
|
||||
public:
|
||||
BitStreamPositionException() : st(1) { }
|
||||
|
||||
char const* what() const
|
||||
{
|
||||
return st.c_str();
|
||||
}
|
||||
|
||||
ACE_Stack_Trace st;
|
||||
};
|
||||
|
||||
class BitStream
|
||||
{
|
||||
public:
|
||||
static uint32 const MaxSize = 0x1000;
|
||||
|
||||
// length : The maximum number of bytes to read
|
||||
BitStream(uint32 length) : _numBits(length * 8), _readPos(0), _writePos(0)
|
||||
{
|
||||
_buffer.resize(length, 0);
|
||||
}
|
||||
|
||||
BitStream() : _numBits(0), _readPos(0), _writePos(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;
|
||||
}
|
||||
|
||||
ACE_Auto_Array_Ptr<uint8> ReadBytes(uint32 count)
|
||||
{
|
||||
AlignToNextByte();
|
||||
if (_readPos + count * 8 > _numBits)
|
||||
throw BitStreamPositionException();
|
||||
|
||||
ACE_Auto_Array_Ptr<uint8> buf(new uint8[count]);
|
||||
memcpy(buf.get(), &_buffer[_readPos >> 3], count);
|
||||
_readPos += count * 8;
|
||||
return buf;
|
||||
}
|
||||
|
||||
float ReadFloat()
|
||||
{
|
||||
uint32 val = Read<uint32>(32);
|
||||
return *reinterpret_cast<float*>(&val);
|
||||
}
|
||||
|
||||
std::string ReadFourCC()
|
||||
{
|
||||
uint32 fcc = Read<uint32>(32);
|
||||
EndianConvertReverse(fcc);
|
||||
size_t len = 4;
|
||||
while (!(fcc & 0xFF))
|
||||
{
|
||||
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");
|
||||
|
||||
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(), str.length());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void WriteBytes(T* data, uint32 count)
|
||||
{
|
||||
AlignToNextByte();
|
||||
if (!count || !data)
|
||||
return;
|
||||
|
||||
if ((_writePos >> 3) + count > MaxSize)
|
||||
throw BitStreamPositionException();
|
||||
|
||||
_buffer.resize(_buffer.size() + count);
|
||||
memcpy(&_buffer[_writePos >> 3], data, count);
|
||||
_writePos += count * 8;
|
||||
}
|
||||
|
||||
void WriteFloat(float value)
|
||||
{
|
||||
uint32 intVal = *reinterpret_cast<uint32*>(&value);
|
||||
Write(intVal, 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();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void SetReadPos(uint32 bits)
|
||||
{
|
||||
if (bits >= _numBits)
|
||||
throw BitStreamPositionException();
|
||||
|
||||
_readPos = bits;
|
||||
}
|
||||
|
||||
bool IsRead() const { return _readPos >= _numBits; }
|
||||
|
||||
uint8* GetBuffer() { return _buffer.data(); }
|
||||
|
||||
size_t GetSize() const { return _buffer.size(); }
|
||||
|
||||
void FinishReading() { _readPos = _numBits; }
|
||||
|
||||
private:
|
||||
std::vector<uint8> _buffer;
|
||||
uint32 _numBits;
|
||||
uint32 _readPos;
|
||||
uint32 _writePos;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __BATTLENETBITSTREAM_H__
|
||||
96
src/server/authserver/Server/BattlenetManager.cpp
Normal file
96
src/server/authserver/Server/BattlenetManager.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 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 "BattlenetManager.h"
|
||||
#include "DatabaseEnv.h"
|
||||
|
||||
BattlenetMgr::~BattlenetMgr()
|
||||
{
|
||||
for (Battlenet::Component* component : _components)
|
||||
delete component;
|
||||
|
||||
for (auto const& m : _modules)
|
||||
delete m.second;
|
||||
}
|
||||
|
||||
void BattlenetMgr::Load()
|
||||
{
|
||||
LoadComponents();
|
||||
LoadModules();
|
||||
}
|
||||
|
||||
void BattlenetMgr::LoadComponents()
|
||||
{
|
||||
QueryResult result = LoginDatabase.Query("SELECT Program, Platform, Build FROM battlenet_components");
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
Battlenet::Component* component = new Battlenet::Component();
|
||||
component->Program = fields[0].GetString();
|
||||
component->Platform = fields[1].GetString();
|
||||
component->Build = fields[2].GetUInt32();
|
||||
|
||||
_components.insert(component);
|
||||
_programs.insert(component->Program);
|
||||
_platforms.insert(component->Platform);
|
||||
|
||||
} while (result->NextRow());
|
||||
}
|
||||
}
|
||||
|
||||
void BattlenetMgr::LoadModules()
|
||||
{
|
||||
QueryResult result = LoginDatabase.Query("SELECT `Hash`, `Name`, `Type`, `System`, `Data` FROM battlenet_modules");
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
Battlenet::ModuleInfo* module = new Battlenet::ModuleInfo();
|
||||
module->Type = fields[2].GetString();
|
||||
HexStrToByteArray(fields[0].GetString(), module->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());
|
||||
}
|
||||
}
|
||||
|
||||
bool BattlenetMgr::HasComponent(Battlenet::Component const* component) const
|
||||
{
|
||||
for (Battlenet::Component const* c : _components)
|
||||
if (component->Program == c->Program && component->Platform == c->Platform && component->Build == c->Build)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Battlenet::ModuleInfo* BattlenetMgr::CreateModule(std::string const& os, std::string const& name) const
|
||||
{
|
||||
Battlenet::ModuleKey key { os, name };
|
||||
ASSERT(_modules.count(key));
|
||||
|
||||
return new Battlenet::ModuleInfo(*_modules.at(key));
|
||||
}
|
||||
111
src/server/authserver/Server/BattlenetManager.h
Normal file
111
src/server/authserver/Server/BattlenetManager.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 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 __BATTLENETMANAGER_H__
|
||||
#define __BATTLENETMANAGER_H__
|
||||
|
||||
#include "Define.h"
|
||||
#include <ace/Singleton.h>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
namespace Battlenet
|
||||
{
|
||||
struct Component
|
||||
{
|
||||
std::string Program;
|
||||
std::string Platform;
|
||||
uint32 Build;
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
ModuleInfo() : Region("EU"), DataSize(0), Data(nullptr) { }
|
||||
ModuleInfo(ModuleInfo const& right) : Type(right.Type), Region(right.Region), DataSize(right.DataSize), Data(nullptr)
|
||||
{
|
||||
memcpy(ModuleId, right.ModuleId, 32);
|
||||
if (DataSize)
|
||||
{
|
||||
Data = new uint8[DataSize];
|
||||
memcpy(Data, right.Data, DataSize);
|
||||
}
|
||||
}
|
||||
~ModuleInfo()
|
||||
{
|
||||
delete Data;
|
||||
}
|
||||
|
||||
std::string Type;
|
||||
std::string Region;
|
||||
uint8 ModuleId[32];
|
||||
uint32 DataSize;
|
||||
uint8* Data;
|
||||
};
|
||||
|
||||
struct RealmId
|
||||
{
|
||||
uint8 Region;
|
||||
uint8 Battlegroup;
|
||||
uint32 Index;
|
||||
uint32 Build;
|
||||
};
|
||||
}
|
||||
|
||||
class BattlenetMgr
|
||||
{
|
||||
friend class ACE_Singleton<BattlenetMgr, ACE_Null_Mutex>;
|
||||
BattlenetMgr() { }
|
||||
~BattlenetMgr();
|
||||
|
||||
public:
|
||||
void Load();
|
||||
bool HasComponent(Battlenet::Component const* component) const;
|
||||
bool HasProgram(std::string const& program) const { return _programs.count(program); }
|
||||
bool HasPlatform(std::string const& platform) const { return _platforms.count(platform); }
|
||||
Battlenet::ModuleInfo* CreateModule(std::string const& os, std::string const& name) const;
|
||||
|
||||
private:
|
||||
void LoadComponents();
|
||||
void LoadModules();
|
||||
|
||||
std::set<Battlenet::Component*> _components;
|
||||
std::set<std::string> _programs;
|
||||
std::set<std::string> _platforms;
|
||||
std::map<Battlenet::ModuleKey, Battlenet::ModuleInfo*> _modules;
|
||||
};
|
||||
|
||||
#define sBattlenetMgr ACE_Singleton<BattlenetMgr, ACE_Null_Mutex>::instance()
|
||||
|
||||
#endif // __BATTLENETMANAGER_H__
|
||||
42
src/server/authserver/Server/BattlenetPacketCrypt.cpp
Normal file
42
src/server/authserver/Server/BattlenetPacketCrypt.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 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;
|
||||
}
|
||||
36
src/server/authserver/Server/BattlenetPacketCrypt.h
Normal file
36
src/server/authserver/Server/BattlenetPacketCrypt.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 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 __BATTLENETPACKETCRYPT_H__
|
||||
#define __BATTLENETPACKETCRYPT_H__
|
||||
|
||||
#include "PacketCrypt.h"
|
||||
|
||||
class BigNumber;
|
||||
|
||||
namespace Battlenet
|
||||
{
|
||||
class PacketCrypt : public ::PacketCrypt
|
||||
{
|
||||
public:
|
||||
PacketCrypt();
|
||||
|
||||
void Init(BigNumber* K) override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __BATTLENETPACKETCRYPT_H__
|
||||
449
src/server/authserver/Server/BattlenetPackets.cpp
Normal file
449
src/server/authserver/Server/BattlenetPackets.cpp
Normal file
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 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"
|
||||
#include "Common.h"
|
||||
#include "Util.h"
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
|
||||
std::string Battlenet::PacketHeader::ToString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Battlenet::PacketHeader opcode: " << Opcode << ", channel: " << Channel;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
Battlenet::ServerPacket::ServerPacket(PacketHeader const& header) : Packet(header, *new BitStream())
|
||||
{
|
||||
_stream.Write(header.Opcode, 6);
|
||||
_stream.Write(1, 1);
|
||||
_stream.Write(header.Channel, 4);
|
||||
}
|
||||
|
||||
Battlenet::ServerPacket::~ServerPacket()
|
||||
{
|
||||
delete &_stream;
|
||||
}
|
||||
|
||||
void Battlenet::AuthChallenge::Read()
|
||||
{
|
||||
Program = _stream.ReadFourCC();
|
||||
Platform = _stream.ReadFourCC();
|
||||
Locale = _stream.ReadFourCC();
|
||||
|
||||
Components.resize(_stream.Read<uint32>(6));
|
||||
for (size_t i = 0; i < Components.size(); ++i)
|
||||
{
|
||||
Component& component = Components[i];
|
||||
component.Program = _stream.ReadFourCC();
|
||||
component.Platform = _stream.ReadFourCC();
|
||||
component.Build = _stream.Read<uint32>(32);
|
||||
}
|
||||
|
||||
if (_stream.Read<uint32>(1))
|
||||
Login = _stream.ReadString(9, 3);
|
||||
}
|
||||
|
||||
std::string Battlenet::AuthChallenge::ToString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Battlenet::AuthChallenge Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale;
|
||||
for (Component const& component : Components)
|
||||
stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build;
|
||||
|
||||
if (!Login.empty())
|
||||
stream << std::endl << "Battlenet::AuthChallenge Login: " << Login;
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
void Battlenet::AuthResumeInfo::Read()
|
||||
{
|
||||
Program = _stream.ReadFourCC();
|
||||
Platform = _stream.ReadFourCC();
|
||||
Locale = _stream.ReadFourCC();
|
||||
|
||||
Components.resize(_stream.Read<uint32>(6));
|
||||
for (size_t i = 0; i < Components.size(); ++i)
|
||||
{
|
||||
Component& component = Components[i];
|
||||
component.Program = _stream.ReadFourCC();
|
||||
component.Platform = _stream.ReadFourCC();
|
||||
component.Build = _stream.Read<uint32>(32);
|
||||
}
|
||||
|
||||
Login = _stream.ReadString(9, 3);
|
||||
Region = _stream.Read<uint8>(8);
|
||||
GameAccountName = _stream.ReadString(5, 1);
|
||||
}
|
||||
|
||||
std::string Battlenet::AuthResumeInfo::ToString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Battlenet::AuthReconnect Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale;
|
||||
for (Component const& component : Components)
|
||||
stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build;
|
||||
|
||||
stream << std::endl << "Battlenet::AuthReconnect Login: " << Login;
|
||||
stream << std::endl << "Battlenet::AuthReconnect Region: " << uint32(Region);
|
||||
stream << std::endl << "Battlenet::AuthReconnect GameAccountName: " << GameAccountName;
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
Battlenet::ProofRequest::~ProofRequest()
|
||||
{
|
||||
for (size_t i = 0; i < Modules.size(); ++i)
|
||||
delete Modules[i];
|
||||
}
|
||||
|
||||
void Battlenet::ProofRequest::Write()
|
||||
{
|
||||
_stream.Write(Modules.size(), 3);
|
||||
for (ModuleInfo const* info : Modules)
|
||||
{
|
||||
_stream.WriteBytes(info->Type.c_str(), 4);
|
||||
_stream.WriteFourCC(info->Region);
|
||||
_stream.WriteBytes(info->ModuleId, 32);
|
||||
_stream.Write(info->DataSize, 10);
|
||||
_stream.WriteBytes(info->Data, info->DataSize);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Battlenet::ProofRequest::ToString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Battlenet::ProofRequest modules " << Modules.size();
|
||||
for (ModuleInfo const* module : Modules)
|
||||
stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize);
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
Battlenet::ProofResponse::~ProofResponse()
|
||||
{
|
||||
for (size_t i = 0; i < Modules.size(); ++i)
|
||||
delete Modules[i];
|
||||
}
|
||||
|
||||
void Battlenet::ProofResponse::Read()
|
||||
{
|
||||
Modules.resize(_stream.Read<uint32>(3));
|
||||
for (size_t i = 0; i < Modules.size(); ++i)
|
||||
{
|
||||
BitStream*& dataStream = Modules[i];
|
||||
dataStream = new BitStream(_stream.Read<uint32>(10));
|
||||
memcpy(dataStream->GetBuffer(), _stream.ReadBytes(dataStream->GetSize()).get(), dataStream->GetSize());
|
||||
}
|
||||
}
|
||||
|
||||
std::string Battlenet::ProofResponse::ToString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Battlenet::ProofResponse Modules " << Modules.size();
|
||||
for (BitStream* module : Modules)
|
||||
{
|
||||
std::string hexStr = ByteArrayToHexStr(module->GetBuffer(), module->GetSize());
|
||||
stream << std::endl << "Battlenet::ProofResponse::ModuleData Size: " << module->GetSize() << ", Data: " << hexStr;
|
||||
}
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
Battlenet::AuthComplete::~AuthComplete()
|
||||
{
|
||||
for (ModuleInfo* m : Modules)
|
||||
delete m;
|
||||
}
|
||||
|
||||
void Battlenet::AuthComplete::Write()
|
||||
{
|
||||
_stream.Write(Result != 0, 1);
|
||||
if (Result == 0)
|
||||
{
|
||||
_stream.Write(Modules.size(), 3);
|
||||
for (size_t i = 0; i < Modules.size(); ++i)
|
||||
{
|
||||
ModuleInfo* info = Modules[i];
|
||||
_stream.WriteBytes(info->Type.c_str(), 4);
|
||||
_stream.WriteFourCC(info->Region);
|
||||
_stream.WriteBytes(info->ModuleId, 32);
|
||||
_stream.Write(info->DataSize, 10);
|
||||
_stream.WriteBytes(info->Data, info->DataSize);
|
||||
}
|
||||
|
||||
_stream.Write(PingTimeout + std::numeric_limits<int32>::min(), 32);
|
||||
_stream.Write(1, 1);
|
||||
// if written == 1
|
||||
{
|
||||
_stream.Write(1, 1);
|
||||
// if written == 1
|
||||
{
|
||||
_stream.Write(Threshold, 32);
|
||||
_stream.Write(Rate, 32);
|
||||
}
|
||||
}
|
||||
|
||||
_stream.WriteString(FirstName, 8); // First name
|
||||
_stream.WriteString(LastName, 8); // Last name - not set for WoW
|
||||
|
||||
_stream.Write(AccountId, 32);
|
||||
_stream.Write(Region, 8);
|
||||
_stream.Write(0, 64);
|
||||
|
||||
_stream.Write(GameAccountRegion, 8);
|
||||
_stream.WriteString(GameAccountName, 5, -1);
|
||||
_stream.Write(GameAccountFlags, 64);
|
||||
|
||||
_stream.Write(0, 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
_stream.Write(!Modules.empty(), 1);
|
||||
if (!Modules.empty())
|
||||
{
|
||||
ModuleInfo* info = Modules[0];
|
||||
_stream.WriteBytes(info->Type.c_str(), 4);
|
||||
_stream.WriteFourCC(info->Region);
|
||||
_stream.WriteBytes(info->ModuleId, 32);
|
||||
}
|
||||
|
||||
_stream.Write(ErrorType, 2);
|
||||
if (ErrorType == 1)
|
||||
{
|
||||
_stream.Write(Result, 16);
|
||||
_stream.Write(0x80000000, 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string Battlenet::AuthComplete::ToString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Battlenet::AuthComplete AuthResult " << Result << " PingTimeout " << PingTimeout << " Threshold " << Threshold << " Rate " << Rate
|
||||
<< " FirstName " << FirstName << " LastName " << LastName << " AccountId " << AccountId << " Region " << uint32(Region) << " GameAccountName " << GameAccountName
|
||||
<< " GameAccountFlags " << GameAccountFlags << " Modules " << Modules.size();
|
||||
|
||||
for (ModuleInfo const* module : Modules)
|
||||
stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize);
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
void Battlenet::AuthComplete::SetAuthResult(AuthResult result)
|
||||
{
|
||||
ErrorType = result != AUTH_OK ? 1 : 0;
|
||||
Result = result;
|
||||
}
|
||||
|
||||
Battlenet::AuthResume::~AuthResume()
|
||||
{
|
||||
for (ModuleInfo* m : Modules)
|
||||
delete m;
|
||||
}
|
||||
|
||||
void Battlenet::AuthResume::Write()
|
||||
{
|
||||
_stream.Write(Result != 0, 1);
|
||||
if (Result == 0)
|
||||
{
|
||||
_stream.Write(Modules.size(), 3);
|
||||
for (size_t i = 0; i < Modules.size(); ++i)
|
||||
{
|
||||
ModuleInfo* info = Modules[i];
|
||||
_stream.WriteBytes(info->Type.c_str(), 4);
|
||||
_stream.WriteFourCC(info->Region);
|
||||
_stream.WriteBytes(info->ModuleId, 32);
|
||||
_stream.Write(info->DataSize, 10);
|
||||
_stream.WriteBytes(info->Data, info->DataSize);
|
||||
}
|
||||
|
||||
_stream.Write(PingTimeout + std::numeric_limits<int32>::min(), 32);
|
||||
_stream.Write(1, 1);
|
||||
// if written == 1
|
||||
{
|
||||
_stream.Write(1, 1);
|
||||
// if written == 1
|
||||
{
|
||||
_stream.Write(Threshold, 32);
|
||||
_stream.Write(Rate, 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_stream.Write(!Modules.empty(), 1);
|
||||
if (!Modules.empty())
|
||||
{
|
||||
ModuleInfo* info = Modules[0];
|
||||
_stream.WriteBytes(info->Type.c_str(), 4);
|
||||
_stream.WriteFourCC(info->Region);
|
||||
_stream.WriteBytes(info->ModuleId, 32);
|
||||
}
|
||||
|
||||
_stream.Write(ErrorType, 2);
|
||||
if (ErrorType == 1)
|
||||
{
|
||||
_stream.Write(Result, 16);
|
||||
_stream.Write(0x80000000, 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string Battlenet::AuthResume::ToString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Battlenet::AuthResume AuthResult " << Result << " PingTimeout " << PingTimeout << " Threshold " << Threshold << " Rate " << Rate << " Modules " << Modules.size();
|
||||
for (ModuleInfo const* module : Modules)
|
||||
stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize);
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
void Battlenet::AuthResume::SetAuthResult(AuthResult result)
|
||||
{
|
||||
ErrorType = result != AUTH_OK ? 1 : 0;
|
||||
Result = result;
|
||||
}
|
||||
|
||||
Battlenet::RealmCharacterCounts::~RealmCharacterCounts()
|
||||
{
|
||||
for (ServerPacket* realmData : RealmData)
|
||||
delete realmData;
|
||||
}
|
||||
|
||||
void Battlenet::RealmCharacterCounts::Write()
|
||||
{
|
||||
_stream.Write(false, 1); // failure
|
||||
_stream.Write(CharacterCounts.size(), 7);
|
||||
for (CharacterCountEntry const& entry : CharacterCounts)
|
||||
{
|
||||
_stream.Write(entry.Realm.Battlegroup, 8);
|
||||
_stream.Write(entry.Realm.Index, 32);
|
||||
_stream.Write(entry.Realm.Region, 8);
|
||||
_stream.Write(entry.CharacterCount, 16);
|
||||
}
|
||||
|
||||
for (ServerPacket* realmData : RealmData)
|
||||
{
|
||||
realmData->Write();
|
||||
_stream.WriteBytes(realmData->GetData(), realmData->GetSize());
|
||||
}
|
||||
}
|
||||
|
||||
std::string Battlenet::RealmCharacterCounts::ToString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Battlenet::RealmCharacterCounts Realms " << CharacterCounts.size();
|
||||
|
||||
for (CharacterCountEntry const& entry : CharacterCounts)
|
||||
stream << std::endl << "Region " << uint32(entry.Realm.Region) << " Battlegroup " << uint32(entry.Realm.Region) << " Index " << entry.Realm.Index << " Characters " << entry.CharacterCount;
|
||||
|
||||
for (ServerPacket* realmData : RealmData)
|
||||
stream << std::endl << realmData->ToString();
|
||||
|
||||
return stream.str().c_str();
|
||||
}
|
||||
|
||||
void Battlenet::RealmUpdate::Write()
|
||||
{
|
||||
_stream.Write(true, 1); // Success
|
||||
_stream.Write(Type + -std::numeric_limits<int32>::min(), 32);
|
||||
_stream.WriteFloat(Population);
|
||||
_stream.Write(Flags, 8);
|
||||
_stream.Write(Lock, 8);
|
||||
_stream.Write(Timezone, 32);
|
||||
_stream.Write(!Version.empty(), 1);
|
||||
if (!Version.empty())
|
||||
{
|
||||
_stream.WriteString(Version, 5);
|
||||
_stream.Write(Build, 32);
|
||||
|
||||
uint32 ip = Address.get_ip_address();
|
||||
uint16 port = Address.get_port_number();
|
||||
|
||||
EndianConvertReverse(ip);
|
||||
EndianConvertReverse(port);
|
||||
|
||||
_stream.WriteBytes(&ip, 4);
|
||||
_stream.WriteBytes(&port, 2);
|
||||
}
|
||||
|
||||
_stream.WriteString(Name, 10);
|
||||
|
||||
_stream.Write(Battlegroup, 8);
|
||||
_stream.Write(Index, 32);
|
||||
_stream.Write(Region, 8);
|
||||
}
|
||||
|
||||
std::string Battlenet::RealmUpdate::ToString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Battlenet::RealmUpdate Timezone " << Timezone << " Population " << Population << " Lock " << uint32(Lock) << " Type " << Type << " Name " << Name
|
||||
<< " Flags " << uint32(Flags) << " Region " << uint32(Region) << " Battlegroup " << uint32(Battlegroup) << " Index " << Index;
|
||||
|
||||
if (!Version.empty())
|
||||
stream << " Version " << Version;
|
||||
|
||||
return stream.str().c_str();
|
||||
}
|
||||
|
||||
void Battlenet::RealmJoinRequest::Read()
|
||||
{
|
||||
Realm.Battlegroup = _stream.Read<uint8>(8);
|
||||
Realm.Index = _stream.Read<uint32>(32);
|
||||
Realm.Region = _stream.Read<uint8>(8);
|
||||
ClientSeed = _stream.Read<uint32>(32);
|
||||
}
|
||||
|
||||
std::string Battlenet::RealmJoinRequest::ToString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Battlenet::RealmJoinRequest ClientSeed " << ClientSeed << " Region " << uint32(Realm.Region) << " Battlegroup " << uint32(Realm.Battlegroup) << " Index " << Realm.Index;
|
||||
return stream.str().c_str();
|
||||
}
|
||||
|
||||
void Battlenet::RealmJoinResult::Write()
|
||||
{
|
||||
_stream.Write(0, 27);
|
||||
_stream.Write(0, 1); // Fail
|
||||
_stream.Write(ServerSeed, 32);
|
||||
_stream.Write(0, 5); // IPv6 addresses
|
||||
_stream.Write(IPv4.size(), 5);
|
||||
for (ACE_INET_Addr const& addr : IPv4)
|
||||
{
|
||||
uint32 ip = addr.get_ip_address();
|
||||
uint16 port = addr.get_port_number();
|
||||
|
||||
EndianConvertReverse(ip);
|
||||
EndianConvertReverse(port);
|
||||
|
||||
_stream.WriteBytes(&ip, 4);
|
||||
_stream.WriteBytes(&port, 2);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Battlenet::RealmJoinResult::ToString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "Battlenet::RealmJoinResult ServerSeed " << ServerSeed << " IPv4 Addresses " << IPv4.size();
|
||||
for (ACE_INET_Addr const& addr : IPv4)
|
||||
stream << std::endl << "Battlenet::RealmJoinResult::Address " << GetAddressString(addr);
|
||||
|
||||
return stream.str().c_str();
|
||||
}
|
||||
360
src/server/authserver/Server/BattlenetPackets.h
Normal file
360
src/server/authserver/Server/BattlenetPackets.h
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 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 "AuthCodes.h"
|
||||
#include "BattlenetBitStream.h"
|
||||
#include "BattlenetManager.h"
|
||||
#include "Define.h"
|
||||
#include "Errors.h"
|
||||
#include <string>
|
||||
|
||||
namespace Battlenet
|
||||
{
|
||||
class BitStream;
|
||||
|
||||
enum Channel
|
||||
{
|
||||
AUTHENTICATION = 0,
|
||||
CREEP = 1,
|
||||
WOW = 2
|
||||
};
|
||||
|
||||
enum AuthOpcode
|
||||
{
|
||||
CMSG_AUTH_CHALLENGE = 0x0,
|
||||
CMSG_AUTH_RECONNECT = 0x1,
|
||||
CMSG_AUTH_PROOF_RESPONSE = 0x2,
|
||||
|
||||
SMSG_AUTH_COMPLETE = 0x0,
|
||||
SMSG_AUTH_RESUME = 0x1,
|
||||
SMSG_AUTH_PROOF_REQUEST = 0x2
|
||||
};
|
||||
|
||||
enum CreepOpcodes
|
||||
{
|
||||
CMSG_PING = 0x0,
|
||||
CMSG_ENABLE_ENCRYPTION = 0x5,
|
||||
CMSG_DISCONNECT = 0x6,
|
||||
CMSG_INVALID_PACKET = 0x9,
|
||||
|
||||
SMSG_PONG = 0x0
|
||||
};
|
||||
|
||||
enum WoWOpcodes
|
||||
{
|
||||
CMSG_REALM_UPDATE_SUBSCRIBE = 0x0,
|
||||
CMSG_REALM_UPDATE_UNSUBSCRIBE = 0x1,
|
||||
CMSG_JOIN_REQUEST = 0x8,
|
||||
|
||||
SMSG_CHARACTER_COUNTS = 0x0,
|
||||
SMSG_REALM_UPDATE = 0x2,
|
||||
SMSG_REALM_UPDATE_END = 0x3,
|
||||
SMSG_JOIN_RESULT = 0x8
|
||||
};
|
||||
|
||||
struct PacketHeader
|
||||
{
|
||||
PacketHeader(uint32 opcode, uint32 channel) : Opcode(opcode), Channel(channel) { }
|
||||
PacketHeader() : Opcode(0), Channel(AUTHENTICATION) { }
|
||||
|
||||
uint32 Opcode;
|
||||
int32 Channel;
|
||||
|
||||
bool operator<(PacketHeader const& right) const
|
||||
{
|
||||
if (Opcode < right.Opcode)
|
||||
return true;
|
||||
if (Opcode > right.Opcode)
|
||||
return false;
|
||||
|
||||
return Channel < right.Channel;
|
||||
}
|
||||
|
||||
bool operator==(PacketHeader const& right) const
|
||||
{
|
||||
return Opcode == right.Opcode && Channel == right.Channel;
|
||||
}
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
class Packet
|
||||
{
|
||||
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;
|
||||
|
||||
virtual std::string ToString() const = 0;
|
||||
|
||||
protected:
|
||||
PacketHeader _header;
|
||||
BitStream& _stream;
|
||||
|
||||
private:
|
||||
Packet(Packet const& right);
|
||||
Packet& operator=(Packet const& right);
|
||||
};
|
||||
|
||||
class ClientPacket : public Packet
|
||||
{
|
||||
public:
|
||||
ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { }
|
||||
|
||||
void Write() override final { ASSERT(!"Write not implemented for this packet."); }
|
||||
};
|
||||
|
||||
class ServerPacket : public Packet
|
||||
{
|
||||
public:
|
||||
ServerPacket(PacketHeader const& header);
|
||||
~ServerPacket();
|
||||
|
||||
void Read() override final { ASSERT(!"Read not implemented for server packets."); }
|
||||
|
||||
uint8 const* GetData() const { return _stream.GetBuffer(); }
|
||||
size_t GetSize() const { return _stream.GetSize(); }
|
||||
};
|
||||
|
||||
class AuthChallenge final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
AuthChallenge(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
|
||||
{
|
||||
ASSERT(header == PacketHeader(CMSG_AUTH_CHALLENGE, AUTHENTICATION) && "Invalid packet header for AuthChallenge");
|
||||
}
|
||||
|
||||
void Read() override;
|
||||
std::string ToString() const override;
|
||||
|
||||
std::string Program;
|
||||
std::string Platform;
|
||||
std::string Locale;
|
||||
std::vector<Component> Components;
|
||||
std::string Login;
|
||||
};
|
||||
|
||||
class AuthResumeInfo final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
AuthResumeInfo(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
|
||||
{
|
||||
ASSERT(header == PacketHeader(CMSG_AUTH_RECONNECT, AUTHENTICATION) && "Invalid packet header for AuthResumeInfo");
|
||||
}
|
||||
|
||||
void Read() override;
|
||||
std::string ToString() const override;
|
||||
|
||||
std::string Program;
|
||||
std::string Platform;
|
||||
std::string Locale;
|
||||
std::vector<Component> Components;
|
||||
std::string Login;
|
||||
uint8 Region;
|
||||
std::string GameAccountName;
|
||||
};
|
||||
|
||||
class ProofRequest final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
ProofRequest() : ServerPacket(PacketHeader(SMSG_AUTH_PROOF_REQUEST, AUTHENTICATION)) { }
|
||||
~ProofRequest();
|
||||
|
||||
void Write() override;
|
||||
std::string ToString() const override;
|
||||
|
||||
std::vector<ModuleInfo*> Modules;
|
||||
};
|
||||
|
||||
class ProofResponse final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
ProofResponse(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
|
||||
{
|
||||
ASSERT(header == PacketHeader(CMSG_AUTH_PROOF_RESPONSE, AUTHENTICATION) && "Invalid packet header for ProofResponse");
|
||||
}
|
||||
|
||||
~ProofResponse();
|
||||
|
||||
void Read() override;
|
||||
std::string ToString() const override;
|
||||
|
||||
std::vector<BitStream*> Modules;
|
||||
};
|
||||
|
||||
class AuthComplete final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
AuthComplete() : ServerPacket(PacketHeader(SMSG_AUTH_COMPLETE, AUTHENTICATION)),
|
||||
Result(AUTH_OK), ErrorType(0), PingTimeout(120000), Threshold(25000000), Rate(1000),
|
||||
FirstName(""), LastName(""), AccountId(0), Region(2), GameAccountRegion(2), GameAccountName("")
|
||||
{
|
||||
}
|
||||
|
||||
~AuthComplete();
|
||||
|
||||
void Write() override;
|
||||
std::string ToString() const override;
|
||||
|
||||
std::vector<ModuleInfo*> Modules;
|
||||
void SetAuthResult(AuthResult result);
|
||||
AuthResult Result;
|
||||
uint32 ErrorType;
|
||||
|
||||
int32 PingTimeout;
|
||||
uint32 Threshold;
|
||||
uint32 Rate;
|
||||
std::string FirstName;
|
||||
std::string LastName;
|
||||
uint32 AccountId;
|
||||
uint8 Region;
|
||||
uint8 GameAccountRegion;
|
||||
std::string GameAccountName;
|
||||
uint64 GameAccountFlags;
|
||||
};
|
||||
|
||||
class AuthResume final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
AuthResume() : ServerPacket(PacketHeader(SMSG_AUTH_RESUME, AUTHENTICATION)),
|
||||
Result(AUTH_OK), ErrorType(0), PingTimeout(120000), Threshold(25000000), Rate(1000)
|
||||
{
|
||||
}
|
||||
|
||||
~AuthResume();
|
||||
|
||||
void Write() override;
|
||||
std::string ToString() const override;
|
||||
|
||||
std::vector<ModuleInfo*> Modules;
|
||||
void SetAuthResult(AuthResult result);
|
||||
AuthResult Result;
|
||||
uint32 ErrorType;
|
||||
|
||||
int32 PingTimeout;
|
||||
uint32 Threshold;
|
||||
uint32 Rate;
|
||||
};
|
||||
|
||||
class Pong final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
Pong() : ServerPacket(PacketHeader(SMSG_PONG, CREEP))
|
||||
{
|
||||
}
|
||||
|
||||
void Write() override { }
|
||||
std::string ToString() const override { return "Battlenet::Pong"; }
|
||||
};
|
||||
|
||||
class RealmCharacterCounts final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
RealmCharacterCounts() : ServerPacket(PacketHeader(SMSG_CHARACTER_COUNTS, WOW))
|
||||
{
|
||||
}
|
||||
~RealmCharacterCounts();
|
||||
|
||||
struct CharacterCountEntry
|
||||
{
|
||||
RealmId Realm;
|
||||
uint32 CharacterCount;
|
||||
};
|
||||
|
||||
void Write() override;
|
||||
std::string ToString() const override;
|
||||
|
||||
std::vector<CharacterCountEntry> CharacterCounts;
|
||||
std::vector<ServerPacket*> RealmData;
|
||||
};
|
||||
|
||||
class RealmUpdate final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
RealmUpdate() : ServerPacket(PacketHeader(SMSG_REALM_UPDATE, WOW)),
|
||||
Timezone(0), Population(0.0f), Lock(0), Type(0), Name(""), Version(""),
|
||||
Address(), Flags(0), Region(0), Battlegroup(0), Index(0), Build(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Write() override;
|
||||
std::string ToString() const override;
|
||||
|
||||
uint32 Timezone;
|
||||
float Population;
|
||||
uint8 Lock;
|
||||
uint32 Type;
|
||||
std::string Name;
|
||||
std::string Version;
|
||||
ACE_INET_Addr Address;
|
||||
uint8 Flags;
|
||||
uint8 Region;
|
||||
uint8 Battlegroup;
|
||||
uint32 Index;
|
||||
uint32 Build;
|
||||
};
|
||||
|
||||
class RealmUpdateComplete final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
RealmUpdateComplete() : ServerPacket(PacketHeader(SMSG_REALM_UPDATE_END, WOW))
|
||||
{
|
||||
}
|
||||
|
||||
void Write() override { }
|
||||
std::string ToString() const override { return "Battlenet::RealmUpdateComplete"; }
|
||||
};
|
||||
|
||||
class RealmJoinRequest final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
RealmJoinRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream)
|
||||
{
|
||||
ASSERT(header == PacketHeader(CMSG_JOIN_REQUEST, WOW) && "Invalid packet header for RealmJoinRequest");
|
||||
}
|
||||
|
||||
void Read() override;
|
||||
std::string ToString() const override;
|
||||
|
||||
uint32 ClientSeed;
|
||||
uint32 Unknown;
|
||||
RealmId Realm;
|
||||
};
|
||||
|
||||
class RealmJoinResult final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
RealmJoinResult() : ServerPacket(PacketHeader(SMSG_JOIN_RESULT, WOW)), ServerSeed(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Write() override;
|
||||
std::string ToString() const override;
|
||||
|
||||
uint32 ServerSeed;
|
||||
std::vector<ACE_INET_Addr> IPv4;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __BATTLENETPACKETS_H__
|
||||
1011
src/server/authserver/Server/BattlenetSocket.cpp
Normal file
1011
src/server/authserver/Server/BattlenetSocket.cpp
Normal file
File diff suppressed because it is too large
Load Diff
120
src/server/authserver/Server/BattlenetSocket.h
Normal file
120
src/server/authserver/Server/BattlenetSocket.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 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 _BATTLENETSOCKET_H
|
||||
#define _BATTLENETSOCKET_H
|
||||
|
||||
#include "RealmSocket.h"
|
||||
#include "BattlenetPackets.h"
|
||||
#include "BattlenetPacketCrypt.h"
|
||||
#include "BigNumber.h"
|
||||
|
||||
class ACE_INET_Addr;
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
class Socket : public RealmSocket::Session
|
||||
{
|
||||
public:
|
||||
static uint32 const SRP6_V_Size;
|
||||
static uint32 const SRP6_S_Size;
|
||||
|
||||
explicit Socket(RealmSocket& socket);
|
||||
|
||||
typedef bool(Socket::*PacketHandler)(PacketHeader& socket, BitStream& packet);
|
||||
|
||||
// Auth
|
||||
bool HandleAuthChallenge(PacketHeader& header, BitStream& packet);
|
||||
bool HandleAuthReconnect(PacketHeader& header, BitStream& packet);
|
||||
bool HandleAuthProofResponse(PacketHeader& header, BitStream& packet);
|
||||
|
||||
// Creep
|
||||
bool HandlePing(PacketHeader& header, BitStream& packet);
|
||||
bool HandleEnableEncryption(PacketHeader& header, BitStream& packet);
|
||||
bool HandleDisconnect(PacketHeader& header, BitStream& packet);
|
||||
|
||||
// WoW
|
||||
bool HandleRealmUpdateSubscribe(PacketHeader& header, BitStream& packet);
|
||||
bool HandleRealmJoinRequest(PacketHeader& header, BitStream& packet);
|
||||
|
||||
void OnRead() override;
|
||||
void OnAccept() override;
|
||||
void OnClose() override;
|
||||
|
||||
void Send(ServerPacket& packet);
|
||||
|
||||
private:
|
||||
void _SetVSFields(std::string const& rI);
|
||||
|
||||
typedef bool(Socket::*ModuleHandler)(BitStream* dataStream, ServerPacket** response);
|
||||
static ModuleHandler const ModuleHandlers[MODULE_COUNT];
|
||||
|
||||
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);
|
||||
|
||||
RealmSocket& _socket;
|
||||
|
||||
uint32 _accountId;
|
||||
std::string _accountName;
|
||||
std::string _locale;
|
||||
std::string _os;
|
||||
uint32 _build;
|
||||
uint32 _gameAccountId;
|
||||
uint8 _gameAccountIndex;
|
||||
AccountTypes _accountSecurityLevel;
|
||||
|
||||
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;
|
||||
|
||||
PacketCrypt _crypt;
|
||||
bool _authed;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _BATTLENETSOCKET_H
|
||||
@@ -24,7 +24,9 @@
|
||||
|
||||
#include "RealmSocket.h"
|
||||
#include "AuthSocket.h"
|
||||
#include "BattlenetSocket.h"
|
||||
|
||||
template<class LoginType>
|
||||
class RealmAcceptor : public ACE_Acceptor<RealmSocket, ACE_SOCK_Acceptor>
|
||||
{
|
||||
public:
|
||||
@@ -42,7 +44,7 @@ protected:
|
||||
ACE_NEW_RETURN(sh, RealmSocket, -1);
|
||||
|
||||
sh->reactor(reactor());
|
||||
sh->set_session(new AuthSocket(*sh));
|
||||
sh->set_session(new LoginType(*sh));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user