32#include <boost/asio/ip/tcp.hpp>
51 _updateTimer = std::make_unique<Trinity::Asio::DeadlineTimer>(ioContext);
52 _resolver = std::make_unique<Trinity::Asio::Resolver>(ioContext);
67 if (
QueryResult result =
LoginDatabase.Query(
"SELECT majorVersion, minorVersion, bugfixVersion, hotfixVersion, build, win64AuthSeed, mac64AuthSeed FROM build_info ORDER BY build ASC"))
71 Field* fields = result->Fetch();
77 std::string hotfixVersion = fields[3].
GetString();
79 std::copy(hotfixVersion.begin(), hotfixVersion.end(), build.
HotfixVersion.begin());
81 std::fill(hotfixVersion.begin(), hotfixVersion.end(),
'\0');
84 std::string win64AuthSeedHexStr = fields[5].
GetString();
85 if (win64AuthSeedHexStr.length() == build.
Win64AuthSeed.size() * 2)
88 std::string mac64AuthSeedHexStr = fields[6].
GetString();
89 if (mac64AuthSeedHexStr.length() == build.
Mac64AuthSeed.size() * 2)
92 }
while (result->NextRow());
97 boost::asio::ip::address&& address, boost::asio::ip::address&& localAddr,
123 std::map<Battlenet::RealmHandle, std::string> existingRealms;
125 existingRealms[p.first] = p.second.Name;
127 std::unordered_set<std::string> newSubRegions;
137 Field* fields = result->Fetch();
139 std::string name = fields[1].
GetString();
140 std::string externalAddressString = fields[2].
GetString();
141 std::string localAddressString = fields[3].
GetString();
144 if (!externalAddress)
146 TC_LOG_ERROR(
"realmlist",
"Could not resolve address {} for realm \"{}\" id {}", externalAddressString, name, realmId);
153 TC_LOG_ERROR(
"realmlist",
"Could not resolve localAddress {} for realm \"{}\" id {}", localAddressString, name, realmId);
173 UpdateRealm(newRealms[
id],
id, build, name, externalAddress->address(), localAddress->address(), port, icon,
178 if (!existingRealms.count(
id))
179 TC_LOG_INFO(
"realmlist",
"Added realm \"{}\" at {}:{}.", name, externalAddressString, port);
181 TC_LOG_DEBUG(
"realmlist",
"Updating realm \"{}\" at {}:{}.", name, externalAddressString, port);
183 existingRealms.erase(
id);
185 catch (std::exception& ex)
187 TC_LOG_ERROR(
"realmlist",
"Realmlist::UpdateRealms has thrown an exception: {}", ex.what());
191 while (result->NextRow());
194 for (
auto itr = existingRealms.begin(); itr != existingRealms.end(); ++itr)
195 TC_LOG_INFO(
"realmlist",
"Removed realm \"{}\".", itr->second);
207 _updateTimer->async_wait([
this](boost::system::error_code
const& error)
238 if (clientBuild.Build == build)
248 return buildInfo.Build < value;
262 std::vector<uint8> compressed;
300 uLong compressedLength = compressBound(uLong(json.length()));
301 compressed.resize(compressedLength + 4);
302 *
reinterpret_cast<uint32*
>(compressed.data()) =
uint32(json.length() + 1);
304 if (compress(compressed.data() + 4, &compressedLength,
reinterpret_cast<uint8 const*
>(json.c_str()), uLong(json.length() + 1)) == Z_OK)
305 compressed.resize(compressedLength + 4);
360 std::string json =
"JSONRealmListUpdates:" +
JSON::Serialize(realmList);
362 uLong compressedLength = compressBound(uLong(json.length()));
363 std::vector<uint8> compressed;
364 compressed.resize(4 + compressedLength);
365 *
reinterpret_cast<uint32*
>(compressed.data()) =
uint32(json.length() + 1);
367 compress(compressed.data() + 4, &compressedLength,
reinterpret_cast<uint8 const*
>(json.c_str()), uLong(json.length() + 1));
369 compressed.resize(compressedLength + 4);
393 std::string json =
"JSONRealmListServerIPAddresses:" +
JSON::Serialize(serverAddresses);
395 uLong compressedLength = compressBound(uLong(json.length()));
396 std::vector<uint8> compressed;
397 compressed.resize(4 + compressedLength);
398 *
reinterpret_cast<uint32*
>(compressed.data()) =
uint32(json.length() + 1);
400 if (compress(compressed.data() + 4, &compressedLength,
reinterpret_cast<uint8 const*
>(json.c_str()), uLong(json.length() + 1)) != Z_OK)
403 std::array<uint8, 32> serverSecret = Trinity::Crypto::GetRandomBytes<32>();
406 auto keyDestItr =
keyData.begin();
407 keyDestItr = std::copy(clientSecret.begin(), clientSecret.end(), keyDestItr);
408 keyDestItr = std::copy(serverSecret.begin(), serverSecret.end(), keyDestItr);
412 stmt->
setString(1, clientAddress.to_string());
415 stmt->
setInt16(4, timezoneOffset.count());
420 attribute->
set_name(
"Param_RealmJoinTicket");
424 attribute->
set_name(
"Param_ServerAddresses");
428 attribute->
set_name(
"Param_JoinSecret");
@ ERROR_UTIL_SERVER_FAILED_TO_SERIALIZE_RESPONSE
@ ERROR_USER_SERVER_NOT_PERMITTED_ON_REALM
@ ERROR_UTIL_SERVER_UNKNOWN_REALM
std::shared_ptr< ResultSet > QueryResult
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
std::chrono::minutes Minutes
Minutes shorthand typedef.
#define TC_LOG_DEBUG(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
#define TC_LOG_INFO(filterType__,...)
@ LOGIN_UPD_BNET_GAME_ACCOUNT_LOGIN_INFO
std::optional< T > Optional
Optional helper class to wrap optional values within.
@ REALM_FLAG_VERSION_MISMATCH
Class used to access individual fields of database query result.
std::string GetString() const
void set_versionminor(::google::protobuf::uint32 value)
void set_versionmajor(::google::protobuf::uint32 value)
void set_versionrevision(::google::protobuf::uint32 value)
void set_versionbuild(::google::protobuf::uint32 value)
void set_port(::google::protobuf::uint32 value)
void set_ip(const ::std::string &value)
inline ::JSON::RealmList::ClientVersion * mutable_version()
void set_populationstate(::google::protobuf::uint32 value)
void set_wowrealmaddress(::google::protobuf::uint32 value)
void set_cfgrealmsid(::google::protobuf::uint32 value)
void set_name(const ::std::string &value)
void set_flags(::google::protobuf::uint32 value)
void set_cfgcategoriesid(::google::protobuf::uint32 value)
void set_cfgtimezonesid(::google::protobuf::uint32 value)
void set_cfgconfigsid(::google::protobuf::uint32 value)
void set_cfglanguagesid(::google::protobuf::uint32 value)
void set_family(::google::protobuf::uint32 value)
inline ::JSON::RealmList::IPAddress * add_addresses()
inline ::JSON::RealmList::RealmIPAddressFamily * add_families()
inline ::JSON::RealmList::RealmState * add_updates()
inline ::JSON::RealmList::RealmEntry * mutable_update()
void set_deleting(bool value)
void setInt16(const uint8 index, const int16 value)
void setUInt8(const uint8 index, const uint8 value)
void setBinary(const uint8 index, const std::vector< uint8 > &value)
void setString(const uint8 index, const std::string &value)
Storage object for the list of realms on the server.
std::unique_ptr< Trinity::Asio::Resolver > _resolver
std::vector< uint8 > GetRealmList(uint32 build, std::string const &subRegion) const
RealmBuildInfo const * GetBuildInfo(uint32 build) const
std::vector< uint8 > GetRealmEntryJSON(Battlenet::RealmHandle const &id, uint32 build) const
std::map< Battlenet::RealmHandle, Realm > RealmMap
uint32 JoinRealm(uint32 realmAddress, uint32 build, boost::asio::ip::address const &clientAddress, std::array< uint8, 32 > const &clientSecret, LocaleConstant locale, std::string const &os, Minutes timezoneOffset, std::string const &accountName, bgs::protocol::game_utilities::v1::ClientResponse *response) const
bool GetRealmNames(Battlenet::RealmHandle const &id, std::string *name, std::string *normalizedName) const
uint32 GetMinorMajorBugfixVersionForBuild(uint32 build) const
std::vector< RealmBuildInfo > _builds
Realm const * GetRealm(Battlenet::RealmHandle const &id) const
std::unordered_set< std::string > _subRegions
void Initialize(Trinity::Asio::IoContext &ioContext, uint32 updateInterval)
std::shared_mutex _realmsMutex
void UpdateRealm(Realm &realm, Battlenet::RealmHandle const &id, uint32 build, std::string const &name, boost::asio::ip::address &&address, boost::asio::ip::address &&localAddr, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population)
std::unique_ptr< Trinity::Asio::DeadlineTimer > _updateTimer
static RealmList * Instance()
void WriteSubRegions(bgs::protocol::game_utilities::v1::GetAllValuesForAttributeResponse *response) const
inline ::bgs::protocol::Variant * mutable_value()
void set_name(const ::std::string &value)
void set_blob_value(const ::std::string &value)
void set_string_value(const ::std::string &value)
inline ::bgs::protocol::Attribute * add_attribute()
inline ::bgs::protocol::Variant * add_attribute_value()
TC_SHARED_API std::string Serialize(google::protobuf::Message const &message)
auto MapGetValuePtr(M &map, typename M::key_type const &key)
TC_COMMON_API void HexStrToByteArray(std::string_view str, uint8 *out, size_t outlen, bool reverse=false)
std::string GetAddressString() const
uint32 GetAddress() const
std::string GetSubRegionAddress() const
std::array< char, 4 > HotfixVersion
std::array< uint8, 16 > Mac64AuthSeed
std::array< uint8, 16 > Win64AuthSeed
AccountTypes AllowedSecurityLevel
uint32 GetConfigId() const
boost::asio::ip::address GetAddressForClient(boost::asio::ip::address const &clientAddr) const
std::string NormalizedName
void SetName(std::string name)
Battlenet::RealmHandle Id
std::vector< boost::asio::ip::address > Addresses