2014-04-30 20:16:08 +02:00
/*
2020-01-02 06:44:10 +01:00
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
2014-04-30 20:16:08 +02:00
*
* 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/>.
*/
2016-03-28 17:12:57 +02:00
#include "Session.h"
#include "BattlenetRpcErrorCodes.h"
#include "ByteConverter.h"
2017-05-12 18:49:51 +02:00
#include "DatabaseEnv.h"
#include "Errors.h"
2018-06-22 17:32:39 -06:00
#include "IPLocation.h"
2017-01-13 21:38:03 +01:00
#include "QueryCallback.h"
2016-03-28 17:12:57 +02:00
#include "LoginRESTService.h"
#include "ProtobufJSON.h"
2014-05-06 23:43:29 +02:00
#include "RealmList.h"
2016-03-28 17:12:57 +02:00
#include "ServiceDispatcher.h"
#include "RealmList.pb.h"
#include <zlib.h>
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
void Battlenet :: Session :: AccountInfo :: LoadResult ( PreparedQueryResult result )
2015-04-11 16:25:21 +02:00
{
2017-09-22 18:26:00 +02:00
// ba.id, ba.email, ba.locked, ba.lock_country, ba.last_ip, ba.LoginTicketExpiry, 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 = ?
2016-03-28 17:12:57 +02:00
Field * fields = result -> Fetch ();
2015-04-11 16:25:21 +02:00
Id = fields [ 0 ]. GetUInt32 ();
Login = fields [ 1 ]. GetString ();
IsLockedToIP = fields [ 2 ]. GetBool ();
LockCountry = fields [ 3 ]. GetString ();
LastIP = fields [ 4 ]. GetString ();
2017-09-22 18:26:00 +02:00
LoginTicketExpiry = fields [ 5 ]. GetUInt32 ();
2015-04-11 16:25:21 +02:00
IsBanned = fields [ 6 ]. GetUInt64 () != 0 ;
IsPermanenetlyBanned = fields [ 7 ]. GetUInt64 () != 0 ;
2016-03-28 17:12:57 +02:00
static uint32 const GameAccountFieldsOffset = 8 ;
do
{
GameAccounts [ result -> Fetch ()[ GameAccountFieldsOffset ]. GetUInt32 ()]. LoadResult ( result -> Fetch () + GameAccountFieldsOffset );
} while ( result -> NextRow ());
2015-04-11 16:25:21 +02:00
}
2016-03-28 17:12:57 +02:00
void Battlenet :: Session :: GameAccountInfo :: LoadResult ( Field * fields )
2015-04-11 16:25:21 +02:00
{
2018-04-18 18:27:45 +01:00
// a.id, a.username, ab.unbandate, ab.unbandate = ab.bandate, aa.gmlevel
2015-04-11 16:25:21 +02:00
Id = fields [ 0 ]. GetUInt32 ();
Name = fields [ 1 ]. GetString ();
2018-04-18 18:27:45 +01:00
UnbanDate = fields [ 2 ]. GetUInt32 ();
IsPermanenetlyBanned = fields [ 3 ]. GetUInt32 () != 0 ;
IsBanned = IsPermanenetlyBanned || UnbanDate > time ( nullptr );
2015-04-11 16:25:21 +02:00
SecurityLevel = AccountTypes ( fields [ 4 ]. GetUInt8 ());
std :: size_t hashPos = Name . find ( '#' );
if ( hashPos != std :: string :: npos )
DisplayName = std :: string ( "WoW" ) + Name . substr ( hashPos + 1 );
else
DisplayName = Name ;
}
2016-03-28 17:12:57 +02:00
Battlenet :: Session :: Session ( tcp :: socket && socket ) : BattlenetSocket ( std :: move ( socket )), _accountInfo ( new AccountInfo ()), _gameAccountInfo ( nullptr ), _locale (),
_os (), _build ( 0 ), _ipCountry (), _authed ( false ), _requestToken ( 0 )
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
_headerLengthBuffer . Resize ( 2 );
2014-05-06 23:43:29 +02:00
}
2014-07-19 17:03:32 +02:00
Battlenet :: Session ::~ Session ()
{
}
2016-03-28 17:12:57 +02:00
void Battlenet :: Session :: AsyncHandshake ()
2014-05-06 23:43:29 +02:00
{
2017-05-13 11:49:09 +02:00
underlying_stream (). async_handshake ( boost :: asio :: ssl :: stream_base :: server , std :: bind ( & Session :: HandshakeHandler , shared_from_this (), std :: placeholders :: _1 ));
2016-03-28 17:12:57 +02:00
}
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
void Battlenet :: Session :: Start ()
{
std :: string ip_address = GetRemoteIpAddress (). to_string ();
TC_LOG_TRACE ( "session" , "%s Accepted connection" , GetClientInfo (). c_str ());
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
// Verify that this IP is not in the ip_banned table
LoginDatabase . Execute ( LoginDatabase . GetPreparedStatement ( LOGIN_DEL_EXPIRED_IP_BANS ));
2014-05-06 23:43:29 +02:00
2019-07-27 01:00:37 +02:00
LoginDatabasePreparedStatement * stmt = LoginDatabase . GetPreparedStatement ( LOGIN_SEL_IP_INFO );
2016-03-28 17:12:57 +02:00
stmt -> setString ( 0 , ip_address );
2014-05-06 23:43:29 +02:00
2020-04-14 16:23:44 +02:00
_queryProcessor . AddCallback ( LoginDatabase . AsyncQuery ( stmt ). WithPreparedCallback ( std :: bind ( & Battlenet :: Session :: CheckIpCallback , this , std :: placeholders :: _1 )));
2014-05-06 23:43:29 +02:00
}
2016-03-28 17:12:57 +02:00
void Battlenet :: Session :: CheckIpCallback ( PreparedQueryResult result )
2014-10-05 16:21:27 +02:00
{
2016-03-28 17:12:57 +02:00
if ( result )
{
bool banned = false ;
do
{
Field * fields = result -> Fetch ();
if ( fields [ 0 ]. GetUInt64 () != 0 )
banned = true ;
} while ( result -> NextRow ());
if ( banned )
{
TC_LOG_DEBUG ( "session" , "%s tries to log in using banned IP!" , GetClientInfo (). c_str ());
CloseSocket ();
return ;
}
}
AsyncHandshake ();
2014-10-05 16:21:27 +02:00
}
2016-03-28 17:12:57 +02:00
bool Battlenet :: Session :: Update ()
2014-04-30 20:16:08 +02:00
{
2016-03-28 17:12:57 +02:00
if ( ! BattlenetSocket :: Update ())
return false ;
2014-05-06 23:43:29 +02:00
2020-04-14 16:23:44 +02:00
_queryProcessor . ProcessReadyCallbacks ();
2014-05-02 02:55:10 +02:00
2016-03-28 17:12:57 +02:00
return true ;
}
2014-05-02 02:55:10 +02:00
2016-03-28 17:12:57 +02:00
void Battlenet :: Session :: AsyncWrite ( MessageBuffer * packet )
{
if ( ! IsOpen ())
2014-10-05 16:21:27 +02:00
return ;
2014-05-02 02:55:10 +02:00
2016-03-28 17:12:57 +02:00
QueuePacket ( std :: move ( * packet ));
}
2014-11-09 19:18:54 +01:00
2016-03-28 17:12:57 +02:00
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 ());
2014-04-30 23:02:01 +02:00
2016-03-28 17:12:57 +02:00
uint16 headerSize = header . ByteSize ();
EndianConvertReverse ( headerSize );
2014-05-06 23:43:29 +02:00
2019-07-21 16:32:49 +02:00
MessageBuffer packet ( sizeof ( headerSize ) + header . GetCachedSize () + response -> GetCachedSize ());
2016-03-28 17:12:57 +02:00
packet . Write ( & headerSize , sizeof ( headerSize ));
uint8 * ptr = packet . GetWritePointer ();
2019-07-21 16:32:49 +02:00
packet . WriteCompleted ( header . GetCachedSize ());
header . SerializePartialToArray ( ptr , header . GetCachedSize ());
2016-03-28 17:12:57 +02:00
ptr = packet . GetWritePointer ();
2019-07-21 16:32:49 +02:00
packet . WriteCompleted ( response -> GetCachedSize ());
response -> SerializeToArray ( ptr , response -> GetCachedSize ());
2016-03-28 17:12:57 +02:00
AsyncWrite ( & packet );
}
2014-04-30 23:02:01 +02:00
2016-03-28 17:12:57 +02:00
void Battlenet :: Session :: SendResponse ( uint32 token , uint32 status )
{
Header header ;
header . set_token ( token );
header . set_status ( status );
header . set_service_id ( 0xFE );
2014-04-30 20:16:08 +02:00
2016-03-28 17:12:57 +02:00
uint16 headerSize = header . ByteSize ();
EndianConvertReverse ( headerSize );
2014-05-13 22:02:51 +02:00
2019-07-21 16:32:49 +02:00
MessageBuffer packet ( sizeof ( headerSize ) + header . GetCachedSize ());
2016-03-28 17:12:57 +02:00
packet . Write ( & headerSize , sizeof ( headerSize ));
uint8 * ptr = packet . GetWritePointer ();
2019-07-21 16:32:49 +02:00
packet . WriteCompleted ( header . GetCachedSize ());
header . SerializeToArray ( ptr , header . GetCachedSize ());
2016-03-28 17:12:57 +02:00
AsyncWrite ( & packet );
2015-04-11 18:58:13 +02:00
}
2016-03-28 17:12:57 +02:00
void Battlenet :: Session :: SendRequest ( uint32 serviceHash , uint32 methodId , pb :: Message const * request )
2015-04-11 18:58:13 +02:00
{
2016-03-28 17:12:57 +02:00
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 );
2019-07-21 16:32:49 +02:00
MessageBuffer packet ( sizeof ( headerSize ) + header . GetCachedSize () + request -> GetCachedSize ());
2016-03-28 17:12:57 +02:00
packet . Write ( & headerSize , sizeof ( headerSize ));
uint8 * ptr = packet . GetWritePointer ();
2019-07-21 16:32:49 +02:00
packet . WriteCompleted ( header . GetCachedSize ());
header . SerializeToArray ( ptr , header . GetCachedSize ());
2016-03-28 17:12:57 +02:00
ptr = packet . GetWritePointer ();
2019-07-21 16:32:49 +02:00
packet . WriteCompleted ( request -> GetCachedSize ());
request -> SerializeToArray ( ptr , request -> GetCachedSize ());
2016-03-28 17:12:57 +02:00
AsyncWrite ( & packet );
}
2017-10-03 18:03:57 +02:00
uint32 Battlenet :: Session :: HandleLogon ( authentication :: v1 :: LogonRequest const * logonRequest , std :: function < void ( ServiceBase * , uint32 , :: google :: protobuf :: Message const * ) >& continuation )
2016-03-28 17:12:57 +02:00
{
if ( logonRequest -> program () != "WoW" )
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
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 ;
2014-05-06 23:43:29 +02:00
}
2016-03-28 17:12:57 +02:00
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 ;
}
2015-04-11 18:58:13 +02:00
2016-03-28 17:12:57 +02:00
if ( GetLocaleByName ( logonRequest -> locale ()) == LOCALE_enUS && logonRequest -> locale () != "enUS" )
2015-04-11 18:58:13 +02:00
{
2016-03-28 17:12:57 +02:00
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 ;
}
2015-04-11 18:58:13 +02:00
2016-03-28 17:12:57 +02:00
_locale = logonRequest -> locale ();
_os = logonRequest -> platform ();
2017-09-22 18:26:00 +02:00
_build = logonRequest -> application_version ();
2016-03-28 17:12:57 +02:00
2017-10-03 18:03:57 +02:00
if ( logonRequest -> has_cached_web_credentials ())
return VerifyWebCredentials ( logonRequest -> cached_web_credentials (), continuation );
2017-05-13 11:49:09 +02:00
boost :: asio :: ip :: tcp :: endpoint const & endpoint = sLoginService . GetAddressForClient ( GetRemoteIpAddress ());
2016-03-28 17:12:57 +02:00
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 ;
}
2017-09-22 18:26:00 +02:00
uint32 Battlenet :: Session :: HandleVerifyWebCredentials ( authentication :: v1 :: VerifyWebCredentialsRequest const * verifyWebCredentialsRequest , std :: function < void ( ServiceBase * , uint32 , :: google :: protobuf :: Message const * ) >& continuation )
2016-03-28 17:12:57 +02:00
{
2018-10-22 19:06:26 +02:00
if ( verifyWebCredentialsRequest -> has_web_credentials ())
return VerifyWebCredentials ( verifyWebCredentialsRequest -> web_credentials (), continuation );
return ERROR_DENIED ;
2017-09-22 18:26:00 +02:00
}
2015-04-11 18:58:13 +02:00
2017-09-22 18:26:00 +02:00
uint32 Battlenet :: Session :: VerifyWebCredentials ( std :: string const & webCredentials , std :: function < void ( ServiceBase * , uint32 , :: google :: protobuf :: Message const * ) >& continuation )
{
2018-10-22 19:06:26 +02:00
if ( webCredentials . empty ())
return ERROR_DENIED ;
2019-07-27 01:00:37 +02:00
LoginDatabasePreparedStatement * stmt = LoginDatabase . GetPreparedStatement ( LOGIN_SEL_BNET_ACCOUNT_INFO );
2017-09-22 18:26:00 +02:00
stmt -> setString ( 0 , webCredentials );
2016-03-28 17:12:57 +02:00
2017-09-22 18:26:00 +02:00
std :: function < void ( ServiceBase * , uint32 , :: google :: protobuf :: Message const * ) > asyncContinuation = std :: move ( continuation );
std :: shared_ptr < AccountInfo > accountInfo = std :: make_shared < AccountInfo > ();
2020-04-14 16:23:44 +02:00
_queryProcessor . AddCallback ( LoginDatabase . AsyncQuery ( stmt ). WithChainingPreparedCallback ([ this , accountInfo , asyncContinuation ]( QueryCallback & callback , PreparedQueryResult result )
2014-05-06 23:43:29 +02:00
{
2017-09-22 19:39:04 +02:00
Battlenet :: Services :: Authentication asyncContinuationService ( this );
NoData response ;
2017-09-22 18:26:00 +02:00
if ( ! result )
{
2017-09-22 19:39:04 +02:00
asyncContinuation ( & asyncContinuationService , ERROR_DENIED , & response );
2017-09-22 18:26:00 +02:00
return ;
}
2014-05-06 23:43:29 +02:00
2017-09-22 18:26:00 +02:00
accountInfo -> LoadResult ( result );
if ( accountInfo -> LoginTicketExpiry < time ( nullptr ))
{
2017-09-22 19:39:04 +02:00
asyncContinuation ( & asyncContinuationService , ERROR_TIMED_OUT , & response );
2017-09-22 18:26:00 +02:00
return ;
}
2019-07-27 01:00:37 +02:00
LoginDatabasePreparedStatement * stmt = LoginDatabase . GetPreparedStatement ( LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID );
2017-09-22 18:26:00 +02:00
stmt -> setUInt32 ( 0 , accountInfo -> Id );
callback . SetNextQuery ( LoginDatabase . AsyncQuery ( stmt ));
})
. WithChainingPreparedCallback ([ accountInfo ]( QueryCallback & callback , PreparedQueryResult characterCountsResult )
2014-05-06 23:43:29 +02:00
{
2017-09-22 18:26:00 +02:00
if ( characterCountsResult )
2014-05-06 23:43:29 +02:00
{
2017-09-22 18:26:00 +02:00
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 ();
2016-03-28 17:12:57 +02:00
2017-09-22 18:26:00 +02:00
} while ( characterCountsResult -> NextRow ());
2014-05-06 23:43:29 +02:00
}
2019-07-27 01:00:37 +02:00
LoginDatabasePreparedStatement * stmt = LoginDatabase . GetPreparedStatement ( LOGIN_SEL_BNET_LAST_PLAYER_CHARACTERS );
2017-09-22 18:26:00 +02:00
stmt -> setUInt32 ( 0 , accountInfo -> Id );
callback . SetNextQuery ( LoginDatabase . AsyncQuery ( stmt ));
})
. WithPreparedCallback ([ this , accountInfo , asyncContinuation ]( PreparedQueryResult lastPlayerCharactersResult )
2014-05-06 23:43:29 +02:00
{
2017-09-22 18:26:00 +02:00
if ( lastPlayerCharactersResult )
{
do
{
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 ();
} while ( lastPlayerCharactersResult -> NextRow ());
}
_accountInfo = accountInfo ;
2017-09-22 19:39:04 +02:00
Battlenet :: Services :: Authentication asyncContinuationService ( this );
NoData response ;
2017-09-22 18:26:00 +02:00
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 )
2014-05-06 23:43:29 +02:00
{
2017-09-22 18:26:00 +02:00
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 )
{
2017-09-22 19:39:04 +02:00
asyncContinuation ( & asyncContinuationService , ERROR_RISK_ACCOUNT_LOCKED , & response );
2017-09-22 18:26:00 +02:00
return ;
}
2014-05-06 23:43:29 +02:00
}
else
{
2018-06-23 21:31:09 +02:00
if ( IpLocationRecord const * location = sIPLocation -> GetLocationRecord ( ip_address ))
_ipCountry = location -> CountryCode ;
2018-06-22 17:32:39 -06:00
2017-09-22 18:26:00 +02:00
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" , "[Session::HandleVerifyWebCredentials] Account '%s' is not locked to country" , _accountInfo -> Login . c_str ());
else if ( ! _accountInfo -> LockCountry . empty () && ! _ipCountry . empty ())
{
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 )
{
2017-09-22 19:39:04 +02:00
asyncContinuation ( & asyncContinuationService , ERROR_RISK_ACCOUNT_LOCKED , & response );
2017-09-22 18:26:00 +02:00
return ;
}
}
2014-05-06 23:43:29 +02:00
}
2017-09-22 18:26:00 +02:00
// If the account is banned, reject the logon attempt
if ( _accountInfo -> IsBanned )
2016-03-28 17:12:57 +02:00
{
2017-09-22 18:26:00 +02:00
if ( _accountInfo -> IsPermanenetlyBanned )
{
TC_LOG_DEBUG ( "session" , "%s [Session::HandleVerifyWebCredentials] Banned account %s tried to login!" , GetClientInfo (). c_str (), _accountInfo -> Login . c_str ());
2017-09-22 19:39:04 +02:00
asyncContinuation ( & asyncContinuationService , ERROR_GAME_ACCOUNT_BANNED , & response );
2017-09-22 18:26:00 +02:00
return ;
}
else
{
TC_LOG_DEBUG ( "session" , "%s [Session::HandleVerifyWebCredentials] Temporarily banned account %s tried to login!" , GetClientInfo (). c_str (), _accountInfo -> Login . c_str ());
2017-09-22 19:39:04 +02:00
asyncContinuation ( & asyncContinuationService , ERROR_GAME_ACCOUNT_SUSPENDED , & response );
2017-09-22 18:26:00 +02:00
return ;
}
2016-03-28 17:12:57 +02:00
}
2014-05-06 23:43:29 +02:00
2017-09-22 18:26:00 +02:00
authentication :: v1 :: LogonResult logonResult ;
logonResult . set_error_code ( 0 );
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 )
{
2018-04-18 18:27:45 +01:00
EntityId * gameAccountId = logonResult . add_game_account_id ();
gameAccountId -> set_low ( itr -> second . Id );
gameAccountId -> set_high ( UI64LIT ( 0x200000200576F57 ));
2017-09-22 18:26:00 +02:00
}
if ( ! _ipCountry . empty ())
logonResult . set_geoip_country ( _ipCountry );
BigNumber k ;
k . SetRand ( 8 * 64 );
logonResult . set_session_key ( k . AsByteArray ( 64 ). get (), 64 );
2014-04-30 20:16:08 +02:00
2017-09-22 18:26:00 +02:00
_authed = true ;
2014-06-01 13:56:36 +02:00
2017-09-22 19:39:04 +02:00
asyncContinuation ( & asyncContinuationService , ERROR_OK , & response );
2017-09-22 18:26:00 +02:00
Service < authentication :: v1 :: AuthenticationListener > ( this ). OnLogonComplete ( & logonResult );
}));
2015-04-11 18:58:13 +02:00
2016-03-28 17:12:57 +02:00
return ERROR_OK ;
2015-04-11 18:58:13 +02:00
}
2016-03-28 17:12:57 +02:00
uint32 Battlenet :: Session :: HandleGetAccountState ( account :: v1 :: GetAccountStateRequest const * request , account :: v1 :: GetAccountStateResponse * response )
2015-04-11 18:58:13 +02:00
{
2016-03-28 17:12:57 +02:00
if ( ! _authed )
return ERROR_DENIED ;
2014-06-01 13:56:36 +02:00
2016-03-28 17:12:57 +02:00
if ( request -> options (). field_privacy_info ())
{
response -> mutable_state () -> mutable_privacy_info () -> set_is_using_rid ( false );
2018-11-05 17:41:37 +01:00
response -> mutable_state () -> mutable_privacy_info () -> set_is_visible_for_view_friends ( false );
2016-03-28 17:12:57 +02:00
response -> mutable_state () -> mutable_privacy_info () -> set_is_hidden_from_friend_finder ( true );
2014-06-01 13:56:36 +02:00
2016-03-28 17:12:57 +02:00
response -> mutable_tags () -> set_privacy_info_tag ( 0xD7CA834D );
}
2014-06-01 13:56:36 +02:00
2016-03-28 17:12:57 +02:00
return ERROR_OK ;
2014-06-01 13:56:36 +02:00
}
2016-03-28 17:12:57 +02:00
uint32 Battlenet :: Session :: HandleGetGameAccountState ( account :: v1 :: GetGameAccountStateRequest const * request , account :: v1 :: GetGameAccountStateResponse * response )
2014-04-30 20:16:08 +02:00
{
2016-03-28 17:12:57 +02:00
if ( ! _authed )
return ERROR_DENIED ;
2014-04-30 20:16:08 +02:00
2016-03-28 17:12:57 +02:00
if ( request -> options (). field_game_level_info ())
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
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
}
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
response -> mutable_tags () -> set_game_level_info_tag ( 0x5C46D483 );
2014-05-06 23:43:29 +02:00
}
2016-03-28 17:12:57 +02:00
if ( request -> options (). field_game_status ())
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
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 );
2018-04-18 18:27:45 +01:00
response -> mutable_state () -> mutable_game_status () -> set_suspension_expires ( uint64 ( itr -> second . UnbanDate ) * 1000000 );
2016-03-28 17:12:57 +02:00
}
2014-04-30 20:16:08 +02:00
2016-03-28 17:12:57 +02:00
response -> mutable_state () -> mutable_game_status () -> set_program ( 5730135 ); // WoW
response -> mutable_tags () -> set_game_status_tag ( 0x98B75F99 );
}
2014-04-30 20:16:08 +02:00
2016-03-28 17:12:57 +02:00
return ERROR_OK ;
2014-06-01 13:56:36 +02:00
}
2016-03-28 17:12:57 +02:00
std :: unordered_map < std :: string , Battlenet :: Session :: ClientRequestHandler > const Battlenet :: Session :: ClientRequestHandlers =
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
{ "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 },
};
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
uint32 Battlenet :: Session :: HandleProcessClientRequest ( game_utilities :: v1 :: ClientRequest const * request , game_utilities :: v1 :: ClientResponse * response )
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
if ( ! _authed )
return ERROR_DENIED ;
2015-04-11 18:58:13 +02:00
2016-03-28 17:12:57 +02:00
Attribute const * command = nullptr ;
std :: unordered_map < std :: string , Variant const *> params ;
2015-04-11 18:58:13 +02:00
2016-03-28 17:12:57 +02:00
for ( int32 i = 0 ; i < request -> attribute_size (); ++ i )
2014-05-13 22:02:51 +02:00
{
2016-03-28 17:12:57 +02:00
Attribute const & attr = request -> attribute ( i );
params [ attr . name ()] = & attr . value ();
if ( strstr ( attr . name (). c_str (), "Command_" ) == attr . name (). c_str ())
command = & attr ;
2014-05-13 22:02:51 +02:00
}
2016-03-28 17:12:57 +02:00
if ( ! command )
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
TC_LOG_ERROR ( "session.rpc" , "%s sent ClientRequest with no command." , GetClientInfo (). c_str ());
return ERROR_RPC_MALFORMED_REQUEST ;
2014-05-06 23:43:29 +02:00
}
2016-03-28 17:12:57 +02:00
auto itr = ClientRequestHandlers . find ( command -> name ());
if ( itr == ClientRequestHandlers . end ())
2014-10-13 17:22:24 +02:00
{
2016-03-28 17:12:57 +02:00
TC_LOG_ERROR ( "session.rpc" , "%s sent ClientRequest with unknown command %s." , GetClientInfo (). c_str (), command -> name (). c_str ());
return ERROR_RPC_NOT_IMPLEMENTED ;
2014-10-13 17:22:24 +02:00
}
2016-03-28 17:12:57 +02:00
return ( this ->* itr -> second )( params , response );
2014-10-12 20:58:25 +02:00
}
2016-03-28 17:12:57 +02:00
inline Variant const * GetParam ( std :: unordered_map < std :: string , Variant const *> const & params , char const * paramName )
2014-10-12 20:58:25 +02:00
{
2016-03-28 17:12:57 +02:00
auto itr = params . find ( paramName );
return itr != params . end () ? itr -> second : nullptr ;
2014-04-30 20:16:08 +02:00
}
2016-03-28 17:12:57 +02:00
uint32 Battlenet :: Session :: GetRealmListTicket ( std :: unordered_map < std :: string , Variant const *> const & params , game_utilities :: v1 :: ClientResponse * response )
2014-04-30 20:16:08 +02:00
{
2016-03-28 17:12:57 +02:00
if ( Variant const * identity = GetParam ( params , "Param_Identity" ))
2014-07-27 21:50:01 +02:00
{
2016-03-28 17:12:57 +02:00
:: 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 ))
2014-07-19 17:03:32 +02:00
{
2016-03-28 17:12:57 +02:00
auto itr = _accountInfo -> GameAccounts . find ( data . gameaccountid ());
if ( itr != _accountInfo -> GameAccounts . end ())
_gameAccountInfo = & itr -> second ;
}
}
2014-07-19 17:03:32 +02:00
2016-03-28 17:12:57 +02:00
if ( ! _gameAccountInfo )
return ERROR_UTIL_SERVER_INVALID_IDENTITY_ARGS ;
2014-10-11 22:45:01 +02:00
2018-04-18 18:27:45 +01:00
if ( _gameAccountInfo -> IsPermanenetlyBanned )
return ERROR_GAME_ACCOUNT_BANNED ;
else if ( _gameAccountInfo -> IsBanned )
return ERROR_GAME_ACCOUNT_SUSPENDED ;
2017-09-22 18:26:00 +02:00
bool clientInfoOk = false ;
2016-03-28 17:12:57 +02:00
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 ())
2014-04-30 20:16:08 +02:00
{
2017-09-22 18:26:00 +02:00
clientInfoOk = true ;
2016-03-28 17:12:57 +02:00
memcpy ( _clientSecret . data (), data . info (). secret (). data (), _clientSecret . size ());
2014-04-30 20:16:08 +02:00
}
2014-05-06 23:43:29 +02:00
}
2014-07-27 21:50:01 +02:00
}
2014-04-30 20:16:08 +02:00
2017-09-22 18:26:00 +02:00
if ( ! clientInfoOk )
2016-03-28 17:12:57 +02:00
return ERROR_WOW_SERVICES_DENIED_REALM_LIST_TICKET ;
2014-04-30 20:16:08 +02:00
2019-07-27 01:00:37 +02:00
LoginDatabasePreparedStatement * stmt = LoginDatabase . GetPreparedStatement ( LOGIN_UPD_BNET_LAST_LOGIN_INFO );
2016-03-28 17:12:57 +02:00
stmt -> setString ( 0 , GetRemoteIpAddress (). to_string ());
stmt -> setUInt8 ( 1 , GetLocaleByName ( _locale ));
stmt -> setString ( 2 , _os );
stmt -> setUInt32 ( 3 , _accountInfo -> Id );
2015-04-11 18:58:13 +02:00
2016-03-28 17:12:57 +02:00
LoginDatabase . Execute ( stmt );
2015-04-11 18:58:13 +02:00
2016-03-28 17:12:57 +02:00
Attribute * attribute = response -> add_attribute ();
attribute -> set_name ( "Param_RealmListTicket" );
attribute -> mutable_value () -> set_blob_value ( "AuthRealmListTicket" );
return ERROR_OK ;
2015-04-11 18:58:13 +02:00
}
2016-03-28 17:12:57 +02:00
uint32 Battlenet :: Session :: GetLastCharPlayed ( std :: unordered_map < std :: string , Variant const *> const & params , game_utilities :: v1 :: ClientResponse * response )
2015-04-11 18:58:13 +02:00
{
2016-03-28 17:12:57 +02:00
if ( Variant const * subRegion = GetParam ( params , "Command_LastCharPlayedRequest_v1_b9" ))
2015-04-11 18:58:13 +02:00
{
2016-03-28 17:12:57 +02:00
auto lastPlayerChar = _gameAccountInfo -> LastPlayedCharacters . find ( subRegion -> string_value ());
if ( lastPlayerChar != _gameAccountInfo -> LastPlayedCharacters . end ())
2015-04-11 18:58:13 +02:00
{
2016-03-28 17:12:57 +02:00
std :: vector < uint8 > compressed = sRealmList -> GetRealmEntryJSON ( lastPlayerChar -> second . RealmId , _build );
2015-04-11 18:58:13 +02:00
2016-03-28 17:12:57 +02:00
if ( compressed . empty ())
return ERROR_UTIL_SERVER_FAILED_TO_SERIALIZE_RESPONSE ;
2015-04-11 18:58:13 +02:00
2016-03-28 17:12:57 +02:00
Attribute * attribute = response -> add_attribute ();
attribute -> set_name ( "Param_RealmEntry" );
attribute -> mutable_value () -> set_blob_value ( compressed . data (), compressed . size ());
2015-04-11 18:58:13 +02:00
2016-03-28 17:12:57 +02:00
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 ));
2015-04-11 18:58:13 +02:00
}
2016-03-28 17:12:57 +02:00
return ERROR_OK ;
2015-04-11 18:58:13 +02:00
}
2016-03-28 17:12:57 +02:00
return ERROR_UTIL_SERVER_UNKNOWN_REALM ;
2014-04-30 20:16:08 +02:00
}
2014-04-30 23:02:01 +02:00
2016-03-28 17:12:57 +02:00
uint32 Battlenet :: Session :: GetRealmList ( std :: unordered_map < std :: string , Variant const *> const & params , game_utilities :: v1 :: ClientResponse * response )
2015-04-11 18:58:13 +02:00
{
2016-03-28 17:12:57 +02:00
if ( ! _gameAccountInfo )
return ERROR_USER_SERVER_BAD_WOW_ACCOUNT ;
2016-02-19 19:23:04 +01:00
2016-03-28 17:12:57 +02:00
std :: string subRegionId ;
if ( Variant const * subRegion = GetParam ( params , "Command_RealmListRequest_v1_b9" ))
subRegionId = subRegion -> string_value ();
2016-02-19 19:23:04 +01:00
2016-03-28 17:12:57 +02:00
std :: vector < uint8 > compressed = sRealmList -> GetRealmList ( _build , subRegionId );
2016-02-19 19:23:04 +01:00
2016-03-28 17:12:57 +02:00
if ( compressed . empty ())
return ERROR_UTIL_SERVER_FAILED_TO_SERIALIZE_RESPONSE ;
2016-02-19 19:23:04 +01:00
2016-03-28 17:12:57 +02:00
Attribute * attribute = response -> add_attribute ();
attribute -> set_name ( "Param_RealmList" );
attribute -> mutable_value () -> set_blob_value ( compressed . data (), compressed . size ());
2015-04-11 18:58:13 +02:00
2016-03-28 17:12:57 +02:00
:: JSON :: RealmList :: RealmCharacterCountList realmCharacterCounts ;
for ( auto const & characterCount : _gameAccountInfo -> CharacterCounts )
2015-04-11 18:58:13 +02:00
{
2016-03-28 17:12:57 +02:00
:: JSON :: RealmList :: RealmCharacterCountEntry * countEntry = realmCharacterCounts . add_counts ();
countEntry -> set_wowrealmaddress ( characterCount . first );
countEntry -> set_count ( characterCount . second );
2015-04-11 18:58:13 +02:00
}
2016-03-28 17:12:57 +02:00
std :: string json = "JSONRealmCharacterCountList:" + :: JSON :: Serialize ( realmCharacterCounts );
2014-08-12 00:44:26 +02:00
2016-03-28 17:12:57 +02:00
uLongf compressedLength = compressBound ( json . length ());
compressed . resize ( 4 + compressedLength );
* reinterpret_cast < uint32 *> ( compressed . data ()) = json . length () + 1 ;
2014-07-19 17:03:32 +02:00
2016-03-28 17:12:57 +02:00
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 ;
2014-05-10 12:50:27 +02:00
2016-03-28 17:12:57 +02:00
attribute = response -> add_attribute ();
attribute -> set_name ( "Param_CharacterCountList" );
attribute -> mutable_value () -> set_blob_value ( compressed . data (), compressedLength + 4 );
return ERROR_OK ;
2014-04-30 23:02:01 +02:00
}
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
uint32 Battlenet :: Session :: JoinRealm ( std :: unordered_map < std :: string , Variant const *> const & params , game_utilities :: v1 :: ClientResponse * response )
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
if ( Variant const * realmAddress = GetParam ( params , "Param_RealmAddress" ))
return sRealmList -> JoinRealm ( realmAddress -> uint_value (), _build , GetRemoteIpAddress (), _clientSecret , GetLocaleByName ( _locale ), _os , _gameAccountInfo -> Name , response );
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
return ERROR_WOW_SERVICES_INVALID_JOIN_TICKET ;
2014-05-06 23:43:29 +02:00
}
2016-03-28 17:12:57 +02:00
uint32 Battlenet :: Session :: HandleGetAllValuesForAttribute ( game_utilities :: v1 :: GetAllValuesForAttributeRequest const * request , game_utilities :: v1 :: GetAllValuesForAttributeResponse * response )
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
if ( ! _authed )
return ERROR_DENIED ;
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
if ( request -> attribute_key () == "Command_RealmListRequest_v1_b9" )
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
sRealmList -> WriteSubRegions ( response );
return ERROR_OK ;
2014-05-06 23:43:29 +02:00
}
2016-03-28 17:12:57 +02:00
return ERROR_RPC_NOT_IMPLEMENTED ;
}
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
void Battlenet :: Session :: HandshakeHandler ( boost :: system :: error_code const & error )
{
if ( error )
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
TC_LOG_ERROR ( "session" , "%s SSL Handshake failed %s" , GetClientInfo (). c_str (), error . message (). c_str ());
CloseSocket ();
return ;
2014-05-06 23:43:29 +02:00
}
2016-03-28 17:12:57 +02:00
AsyncRead ();
}
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
template < bool ( Battlenet :: Session ::* processMethod )(), MessageBuffer Battlenet :: Session ::* outputBuffer >
inline bool PartialProcessPacket ( Battlenet :: Session * session , MessageBuffer & inputBuffer )
{
MessageBuffer & buffer = session ->* outputBuffer ;
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
// We have full read header, now check the data payload
if ( buffer . GetRemainingSpace () > 0 )
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
// need more data in the payload
std :: size_t readDataSize = std :: min ( inputBuffer . GetActiveSize (), buffer . GetRemainingSpace ());
buffer . Write ( inputBuffer . GetReadPointer (), readDataSize );
inputBuffer . ReadCompleted ( readDataSize );
2014-05-06 23:43:29 +02:00
}
2016-03-28 17:12:57 +02:00
if ( buffer . GetRemainingSpace () > 0 )
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
// Couldn't receive the whole data this time.
ASSERT ( inputBuffer . GetActiveSize () == 0 );
2014-05-06 23:43:29 +02:00
return false ;
}
2016-03-28 17:12:57 +02:00
// just received fresh new payload
if ( ! ( session ->* processMethod )())
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
session -> CloseSocket ();
2014-05-06 23:43:29 +02:00
return false ;
}
return true ;
}
2016-03-28 17:12:57 +02:00
void Battlenet :: Session :: ReadHandler ()
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
if ( ! IsOpen ())
return ;
2014-06-08 14:54:37 +02:00
2016-03-28 17:12:57 +02:00
MessageBuffer & packet = GetReadBuffer ();
while ( packet . GetActiveSize () > 0 )
2014-08-22 20:09:18 +02:00
{
2016-03-28 17:12:57 +02:00
if ( ! PartialProcessPacket <& Battlenet :: Session :: ReadHeaderLengthHandler , & Battlenet :: Session :: _headerLengthBuffer > ( this , packet ))
2015-04-11 16:25:21 +02:00
break ;
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
if ( ! PartialProcessPacket <& Battlenet :: Session :: ReadHeaderHandler , & Battlenet :: Session :: _headerBuffer > ( this , packet ))
break ;
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
if ( ! PartialProcessPacket <& Battlenet :: Session :: ReadDataHandler , & Battlenet :: Session :: _packetBuffer > ( this , packet ))
break ;
2014-05-06 23:43:29 +02:00
2016-03-28 17:12:57 +02:00
_headerLengthBuffer . Reset ();
_headerBuffer . Reset ();
2014-05-06 23:43:29 +02:00
}
2016-03-28 17:12:57 +02:00
AsyncRead ();
2014-05-06 23:43:29 +02:00
}
2016-03-28 17:12:57 +02:00
bool Battlenet :: Session :: ReadHeaderLengthHandler ()
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
uint16 len = * reinterpret_cast < uint16 *> ( _headerLengthBuffer . GetReadPointer ());
EndianConvertReverse ( len );
_headerBuffer . Resize ( len );
2014-06-01 13:03:30 +02:00
return true ;
2014-05-06 23:43:29 +02:00
}
2016-03-28 17:12:57 +02:00
bool Battlenet :: Session :: ReadHeaderHandler ()
2014-06-01 13:56:36 +02:00
{
2016-03-28 17:12:57 +02:00
Header header ;
if ( ! header . ParseFromArray ( _headerBuffer . GetReadPointer (), _headerBuffer . GetActiveSize ()))
2016-11-26 11:55:28 +01:00
return false ;
2014-06-01 13:56:36 +02:00
2016-03-28 17:12:57 +02:00
_packetBuffer . Resize ( header . size ());
2014-06-01 13:56:36 +02:00
return true ;
}
2016-03-28 17:12:57 +02:00
bool Battlenet :: Session :: ReadDataHandler ()
2014-05-06 23:43:29 +02:00
{
2016-03-28 17:12:57 +02:00
Header header ;
2016-06-06 09:16:59 +02:00
ASSERT ( header . ParseFromArray ( _headerBuffer . GetReadPointer (), _headerBuffer . GetActiveSize ()));
2014-10-11 15:13:30 +02:00
2016-03-28 17:12:57 +02:00
if ( header . service_id () != 0xFE )
2014-10-11 15:13:30 +02:00
{
2016-03-28 17:12:57 +02:00
sServiceDispatcher . Dispatch ( this , header . service_hash (), header . token (), header . method_id (), std :: move ( _packetBuffer ));
2014-10-11 15:13:30 +02:00
}
2016-03-28 17:12:57 +02:00
else
2014-10-11 15:13:30 +02:00
{
2016-03-28 17:12:57 +02:00
auto itr = _responseCallbacks . find ( header . token ());
if ( itr != _responseCallbacks . end ())
{
itr -> second ( std :: move ( _packetBuffer ));
_responseCallbacks . erase ( header . token ());
}
2015-10-06 00:30:47 +02:00
else
2016-03-28 17:12:57 +02:00
_packetBuffer . Reset ();
2014-10-11 15:13:30 +02:00
}
2016-03-28 17:12:57 +02:00
return true ;
2014-10-11 15:13:30 +02:00
}
2014-10-12 15:34:01 +02:00
std :: string Battlenet :: Session :: GetClientInfo () const
{
std :: ostringstream stream ;
stream << '[' << GetRemoteIpAddress () << ':' << GetRemotePort ();
2015-04-11 16:25:21 +02:00
if ( _accountInfo && ! _accountInfo -> Login . empty ())
stream << ", Account: " << _accountInfo -> Login ;
2014-10-12 15:34:01 +02:00
2015-04-11 16:25:21 +02:00
if ( _gameAccountInfo )
stream << ", Game account: " << _gameAccountInfo -> Name ;
2014-10-12 15:34:01 +02:00
stream << ']' ;
return stream . str ();
}