29#include "rpc_types.pb.h"
34 Field* fields = result->Fetch();
44 static constexpr uint32 GameAccountFieldsOffset = 8;
48 GameAccounts[result->Fetch()[GameAccountFieldsOffset].GetUInt32()].LoadResult(result->Fetch() + GameAccountFieldsOffset);
50 }
while (result->NextRow());
60 IsPermanenetlyBanned = fields[4].
GetUInt32() != 0;
61 IsBanned = IsPermanenetlyBanned || UnbanDate > time(
nullptr);
64 std::size_t hashPos =
Name.find(
'#');
65 if (hashPos != std::string::npos)
66 DisplayName = std::string(
"WoW") +
Name.substr(hashPos + 1);
76 _accountInfo(new
AccountInfo()), _gameAccountInfo(nullptr), _locale(),
77 _os(), _build(0), _buildVariant(), _timezoneOffset(0min), _ipCountry(), _clientSecret(), _authed(false), _requestToken(0)
90 TC_LOG_TRACE(
"session",
"{} Accepted connection", GetClientInfo());
93 std::array<std::shared_ptr<Trinity::Net::SocketConnectionInitializer>, 3> initializers =
95 std::make_shared<Trinity::Net::IpBanCheckConnectionInitializer<Session>>(
this),
105 if (!_socket->Update())
108 _queryProcessor.ProcessReadyCallbacks();
123 if (!_socket->IsOpen())
126 _socket->QueuePacket(std::move(*packet));
131 bgs::protocol::Header header;
132 header.set_token(token);
133 header.set_service_id(0xFE);
134 header.set_size(response->ByteSize());
135 header.set_allocated_ciid(&_clientInstanceId);
137 auto ciidGuard = Trinity::make_unique_ptr_with_deleter<&bgs::protocol::Header::release_ciid>(&header);
139 uint16 headerSize = header.ByteSize();
142 MessageBuffer packet(
sizeof(headerSize) + header.GetCachedSize() + response->GetCachedSize());
143 packet.
Write(&headerSize,
sizeof(headerSize));
146 header.SerializePartialToArray(ptr, header.GetCachedSize());
149 response->SerializeToArray(ptr, response->GetCachedSize());
156 bgs::protocol::Header header;
157 header.set_token(token);
158 header.set_status(status);
159 header.set_service_id(0xFE);
160 header.set_allocated_ciid(&_clientInstanceId);
162 auto ciidGuard = Trinity::make_unique_ptr_with_deleter<&bgs::protocol::Header::release_ciid>(&header);
164 uint16 headerSize = header.ByteSize();
167 MessageBuffer packet(
sizeof(headerSize) + header.GetCachedSize());
168 packet.
Write(&headerSize,
sizeof(headerSize));
171 header.SerializeToArray(ptr, header.GetCachedSize());
178 _responseCallbacks[_requestToken] = std::move(callback);
179 SendRequest(serviceHash, methodId, request);
184 bgs::protocol::Header header;
185 header.set_service_id(0);
186 header.set_service_hash(serviceHash);
187 header.set_method_id(methodId);
188 header.set_size(request->ByteSize());
189 header.set_token(_requestToken++);
190 header.set_allocated_ciid(&_clientInstanceId);
192 auto ciidGuard = Trinity::make_unique_ptr_with_deleter<&bgs::protocol::Header::release_ciid>(&header);
194 uint16 headerSize = header.ByteSize();
197 MessageBuffer packet(
sizeof(headerSize) + header.GetCachedSize() + request->GetCachedSize());
198 packet.
Write(&headerSize,
sizeof(headerSize));
201 header.SerializeToArray(ptr, header.GetCachedSize());
204 request->SerializeToArray(ptr, request->GetCachedSize());
211 _queryProcessor.AddCallback(std::move(queryCallback));
218 _build = applicationVersion;
220 _timezoneOffset = timezoneOffset;
225 _accountInfo = std::move(accountInfo);
226 _ipCountry = ipCountry;
232 _gameAccountInfo = GetGameAccountInfo(gameAccountId);
233 _buildVariant = buildVariant;
234 _clientSecret = clientSecret;
239 auto itr = _gameAccountInfo->LastPlayedCharacters.find(subRegion);
240 return itr != _gameAccountInfo->LastPlayedCharacters.end() ? &itr->second :
nullptr;
243template<
bool(Battlenet::Session::*processMethod)()>
263 if (!(session->*processMethod)())
277 switch (_packetReadState)
279 case PacketReadState::HeaderLength:
281 return *partialResult;
283 case PacketReadState::Header:
285 return *partialResult;
287 case PacketReadState::Data:
289 return *partialResult;
299 uint16 len = *
reinterpret_cast<uint16*
>(_packetBuffer.GetReadPointer());
304 _packetReadState = PacketReadState::Header;
305 _packetBuffer.Resize(_packetBuffer.GetBufferSize() + len);
311 bgs::protocol::Header header;
312 if (!header.ParseFromArray(_packetBuffer.GetReadPointer(), _packetBuffer.GetActiveSize()))
315 _packetBuffer.ReadCompleted(_packetBuffer.GetActiveSize());
317 _packetReadState = PacketReadState::Data;
318 _packetBuffer.Resize(_packetBuffer.GetBufferSize() + header.size());
324 bgs::protocol::Header header;
328 if (header.service_id() != 0xFE)
330 sServiceDispatcher.Dispatch(
this, header.service_hash(), header.token(), header.method_id(), std::move(_packetBuffer));
334 if (
auto responseCallback = _responseCallbacks.extract(header.token()))
335 responseCallback.mapped()(std::move(_packetBuffer));
337 _packetBuffer.Reset();
340 _packetReadState = PacketReadState::HeaderLength;
347 std::ostringstream stream;
348 stream <<
'[' << _socket->GetRemoteIpAddress() <<
':' << _socket->GetRemotePort();
349 if (_accountInfo && !_accountInfo->Login.empty())
350 stream <<
", Account: " << _accountInfo->Login;
352 if (_gameAccountInfo)
353 stream <<
", Game account: " << _gameAccountInfo->Name;
357 return std::move(stream).str();
void EndianConvertReverse(T &)
std::shared_ptr< PreparedResultSet > PreparedQueryResult
std::chrono::system_clock::time_point SystemTimePoint
std::chrono::minutes Minutes
Minutes shorthand typedef.
#define TC_LOG_TRACE(filterType__, message__,...)
std::optional< T > Optional
Optional helper class to wrap optional values within.
#define sServiceDispatcher
constexpr std::size_t PacketHeaderLengthSize
static Optional< Trinity::Net::SocketReadCallbackResult > PartialProcessPacket(Battlenet::Session *session, MessageBuffer &inputBuffer, MessageBuffer &buffer)
std::string GetClientInfo() const
void SendResponse(uint32 token, pb::Message const *response)
void OnLogon(std::string_view platform, std::string_view locale, uint32 applicationVersion, Minutes timezoneOffset)
Trinity::Net::SocketReadCallbackResult ReadHandler()
LastPlayedCharacterInfo const * GetLastPlayedCharacter(std::string_view subRegion) const
void SetClientInfo(uint32 gameAccountId, ClientBuild::VariantId buildVariant, std::array< uint8, 32 > const &clientSecret)
static std::shared_ptr< Socket > CreateSocket(Trinity::Net::IoContextTcpSocket &&socket)
Session(Trinity::Net::IoContextTcpSocket &&socket)
bool ReadHeaderLengthHandler()
void AsyncWrite(MessageBuffer *packet)
void QueueQuery(QueryCallback &&queryCallback)
void SendRequest(uint32 serviceHash, uint32 methodId, pb::Message const *request, std::function< void(MessageBuffer)> callback)
void OnLogonSuccess(std::shared_ptr< AccountInfo > accountInfo, std::string_view ipCountry)
GameAccountInfo const * GetGameAccountInfo() const
static boost::asio::ssl::context & instance()
Class used to access individual fields of database query result.
uint64 GetUInt64() const noexcept
bool GetBool() const noexcept
uint32 GetUInt32() const noexcept
std::string GetString() const noexcept
size_type GetRemainingSpace() const
void ReadCompleted(size_type bytes)
void WriteCompleted(size_type bytes)
size_type GetActiveSize() const
uint8 * GetWritePointer()
void Write(void const *data, std::size_t size)
auto MapGetValuePtr(M &map, typename M::key_type const &key)
boost::asio::basic_stream_socket< boost::asio::ip::tcp, Asio::IoContextExecutor > IoContextTcpSocket
void LoadResult(PreparedQueryResult result)
std::unordered_map< uint32, GameAccountInfo > GameAccounts
bool IsPermanenetlyBanned
void LoadResult(Field const *fields)
static std::shared_ptr< SocketConnectionInitializer > & SetupChain(std::span< std::shared_ptr< SocketConnectionInitializer > > initializers)