TrinityCore
RealmList.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "RealmList.h"
20#include "CryptoRandom.h"
21#include "DatabaseEnv.h"
22#include "DeadlineTimer.h"
23#include "Errors.h"
24#include "IoContext.h"
25#include "Log.h"
26#include "MapUtils.h"
27#include "ProtobufJSON.h"
28#include "Resolver.h"
29#include "Util.h"
31#include "RealmList.pb.h"
32#include <boost/asio/ip/tcp.hpp>
33#include <zlib.h>
34
35RealmList::RealmList() : _updateInterval(0)
36{
37}
38
39RealmList::~RealmList() = default;
40
42{
43 static RealmList instance;
44 return &instance;
45}
46
47// Load the realm list from the database
49{
50 _updateInterval = updateInterval;
51 _updateTimer = std::make_unique<Trinity::Asio::DeadlineTimer>(ioContext);
52 _resolver = std::make_unique<Trinity::Asio::Resolver>(ioContext);
53
55 // Get the content of the realmlist table in the database
57}
58
60{
61 _updateTimer->cancel();
62}
63
65{
66 // 0 1 2 3 4 5 6
67 if (QueryResult result = LoginDatabase.Query("SELECT majorVersion, minorVersion, bugfixVersion, hotfixVersion, build, win64AuthSeed, mac64AuthSeed FROM build_info ORDER BY build ASC"))
68 {
69 do
70 {
71 Field* fields = result->Fetch();
72 _builds.emplace_back();
73 RealmBuildInfo& build = _builds.back();
74 build.MajorVersion = fields[0].GetUInt32();
75 build.MinorVersion = fields[1].GetUInt32();
76 build.BugfixVersion = fields[2].GetUInt32();
77 std::string hotfixVersion = fields[3].GetString();
78 if (hotfixVersion.length() < build.HotfixVersion.size())
79 std::copy(hotfixVersion.begin(), hotfixVersion.end(), build.HotfixVersion.begin());
80 else
81 std::fill(hotfixVersion.begin(), hotfixVersion.end(), '\0');
82
83 build.Build = fields[4].GetUInt32();
84 std::string win64AuthSeedHexStr = fields[5].GetString();
85 if (win64AuthSeedHexStr.length() == build.Win64AuthSeed.size() * 2)
86 HexStrToByteArray(win64AuthSeedHexStr, build.Win64AuthSeed);
87
88 std::string mac64AuthSeedHexStr = fields[6].GetString();
89 if (mac64AuthSeedHexStr.length() == build.Mac64AuthSeed.size() * 2)
90 HexStrToByteArray(mac64AuthSeedHexStr, build.Mac64AuthSeed);
91
92 } while (result->NextRow());
93 }
94}
95
96void RealmList::UpdateRealm(Realm& realm, Battlenet::RealmHandle const& id, uint32 build, std::string const& name,
97 boost::asio::ip::address&& address, boost::asio::ip::address&& localAddr,
98 uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel,
99 float population)
100{
101 realm.Id = id;
102 realm.Build = build;
103 if (realm.Name != name)
104 realm.SetName(name);
105 realm.Type = icon;
106 realm.Flags = flag;
107 realm.Timezone = timezone;
108 realm.AllowedSecurityLevel = allowedSecurityLevel;
109 realm.PopulationLevel = population;
110 realm.Addresses.resize(2);
111 realm.Addresses[0] = std::move(address);
112 realm.Addresses[1] = std::move(localAddr);
113 realm.Port = port;
114}
115
117{
118 TC_LOG_DEBUG("realmlist", "Updating Realm List...");
119
121 PreparedQueryResult result = LoginDatabase.Query(stmt);
122
123 std::map<Battlenet::RealmHandle, std::string> existingRealms;
124 for (auto const& p : _realms)
125 existingRealms[p.first] = p.second.Name;
126
127 std::unordered_set<std::string> newSubRegions;
128 RealmMap newRealms;
129
130 // Circle through results and add them to the realm map
131 if (result)
132 {
133 do
134 {
135 try
136 {
137 Field* fields = result->Fetch();
138 uint32 realmId = fields[0].GetUInt32();
139 std::string name = fields[1].GetString();
140 std::string externalAddressString = fields[2].GetString();
141 std::string localAddressString = fields[3].GetString();
142
143 Optional<boost::asio::ip::tcp::endpoint> externalAddress = _resolver->Resolve(boost::asio::ip::tcp::v4(), externalAddressString, "");
144 if (!externalAddress)
145 {
146 TC_LOG_ERROR("realmlist", "Could not resolve address {} for realm \"{}\" id {}", externalAddressString, name, realmId);
147 continue;
148 }
149
150 Optional<boost::asio::ip::tcp::endpoint> localAddress = _resolver->Resolve(boost::asio::ip::tcp::v4(), localAddressString, "");
151 if (!localAddress)
152 {
153 TC_LOG_ERROR("realmlist", "Could not resolve localAddress {} for realm \"{}\" id {}", localAddressString, name, realmId);
154 continue;
155 }
156
157 uint16 port = fields[4].GetUInt16();
158 uint8 icon = fields[5].GetUInt8();
159 if (icon == REALM_TYPE_FFA_PVP)
160 icon = REALM_TYPE_PVP;
161 if (icon >= MAX_CLIENT_REALM_TYPE)
162 icon = REALM_TYPE_NORMAL;
163 RealmFlags flag = RealmFlags(fields[6].GetUInt8());
164 uint8 timezone = fields[7].GetUInt8();
165 uint8 allowedSecurityLevel = fields[8].GetUInt8();
166 float pop = fields[9].GetFloat();
167 uint32 build = fields[10].GetUInt32();
168 uint8 region = fields[11].GetUInt8();
169 uint8 battlegroup = fields[12].GetUInt8();
170
171 Battlenet::RealmHandle id{ region, battlegroup, realmId };
172
173 UpdateRealm(newRealms[id], id, build, name, externalAddress->address(), localAddress->address(), port, icon,
174 flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop);
175
176 newSubRegions.insert(Battlenet::RealmHandle{ region, battlegroup, 0 }.GetAddressString());
177
178 if (!existingRealms.count(id))
179 TC_LOG_INFO("realmlist", "Added realm \"{}\" at {}:{}.", name, externalAddressString, port);
180 else
181 TC_LOG_DEBUG("realmlist", "Updating realm \"{}\" at {}:{}.", name, externalAddressString, port);
182
183 existingRealms.erase(id);
184 }
185 catch (std::exception& ex)
186 {
187 TC_LOG_ERROR("realmlist", "Realmlist::UpdateRealms has thrown an exception: {}", ex.what());
188 ABORT();
189 }
190 }
191 while (result->NextRow());
192 }
193
194 for (auto itr = existingRealms.begin(); itr != existingRealms.end(); ++itr)
195 TC_LOG_INFO("realmlist", "Removed realm \"{}\".", itr->second);
196
197 {
198 std::unique_lock<std::shared_mutex> lock(_realmsMutex);
199
200 _subRegions.swap(newSubRegions);
201 _realms.swap(newRealms);
202 }
203
204 if (_updateInterval)
205 {
206 _updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval));
207 _updateTimer->async_wait([this](boost::system::error_code const& error)
208 {
209 if (error)
210 return;
211
212 UpdateRealms();
213 });
214 }
215}
216
218{
219 std::shared_lock<std::shared_mutex> lock(_realmsMutex);
221}
222
223bool RealmList::GetRealmNames(Battlenet::RealmHandle const& id, std::string* name, std::string* normalizedName) const
224{
225 std::shared_lock<std::shared_mutex> lock(_realmsMutex);
227 if (!realm)
228 return false;
229
230 *name = realm->Name;
231 *normalizedName = realm->NormalizedName;
232 return true;
233}
234
236{
237 for (RealmBuildInfo const& clientBuild : _builds)
238 if (clientBuild.Build == build)
239 return &clientBuild;
240
241 return nullptr;
242}
243
245{
246 auto buildInfo = std::lower_bound(_builds.begin(), _builds.end(), build, [](RealmBuildInfo const& buildInfo, uint32 value)
247 {
248 return buildInfo.Build < value;
249 });
250 return buildInfo != _builds.end() ? (buildInfo->MajorVersion * 10000 + buildInfo->MinorVersion * 100 + buildInfo->BugfixVersion) : 0;
251}
252
254{
255 std::shared_lock<std::shared_mutex> lock(_realmsMutex);
256 for (std::string const& subRegion : _subRegions)
257 response->add_attribute_value()->set_string_value(subRegion);
258}
259
260std::vector<uint8> RealmList::GetRealmEntryJSON(Battlenet::RealmHandle const& id, uint32 build) const
261{
262 std::vector<uint8> compressed;
263 std::shared_lock<std::shared_mutex> lock(_realmsMutex);
264 if (Realm const* realm = GetRealm(id))
265 {
266 if (!(realm->Flags & REALM_FLAG_OFFLINE) && realm->Build == build)
267 {
269 realmEntry.set_wowrealmaddress(realm->Id.GetAddress());
270 realmEntry.set_cfgtimezonesid(1);
271 realmEntry.set_populationstate(std::max(uint32(realm->PopulationLevel), 1u));
273
274 JSON::RealmList::ClientVersion* version = realmEntry.mutable_version();
275 if (RealmBuildInfo const* buildInfo = GetBuildInfo(realm->Build))
276 {
277 version->set_versionmajor(buildInfo->MajorVersion);
278 version->set_versionminor(buildInfo->MinorVersion);
279 version->set_versionrevision(buildInfo->BugfixVersion);
280 version->set_versionbuild(buildInfo->Build);
281 }
282 else
283 {
284 version->set_versionmajor(6);
285 version->set_versionminor(2);
286 version->set_versionrevision(4);
287 version->set_versionbuild(realm->Build);
288 }
289
290 realmEntry.set_cfgrealmsid(realm->Id.Realm);
291 realmEntry.set_flags(realm->Flags);
292 realmEntry.set_name(realm->Name);
293 realmEntry.set_cfgconfigsid(realm->GetConfigId());
294 realmEntry.set_cfglanguagesid(1);
295
296 lock.unlock();
297
298 std::string json = "JamJSONRealmEntry:" + JSON::Serialize(realmEntry);
299
300 uLong compressedLength = compressBound(uLong(json.length()));
301 compressed.resize(compressedLength + 4);
302 *reinterpret_cast<uint32*>(compressed.data()) = uint32(json.length() + 1);
303
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);
306 else
307 compressed.clear();
308 }
309 }
310
311 return compressed;
312}
313
314std::vector<uint8> RealmList::GetRealmList(uint32 build, std::string const& subRegion) const
315{
317 {
318 std::shared_lock<std::shared_mutex> lock(_realmsMutex);
319 for (auto const& realm : _realms)
320 {
321 if (realm.second.Id.GetSubRegionAddress() != subRegion)
322 continue;
323
324 uint32 flag = realm.second.Flags;
325 if (realm.second.Build != build)
327
328 JSON::RealmList::RealmState* state = realmList.add_updates();
331 state->mutable_update()->set_populationstate((realm.second.Flags & REALM_FLAG_OFFLINE) ? 0u : std::max(uint32(realm.second.PopulationLevel), 1u));
333
335 if (RealmBuildInfo const* buildInfo = GetBuildInfo(realm.second.Build))
336 {
337 version->set_versionmajor(buildInfo->MajorVersion);
338 version->set_versionminor(buildInfo->MinorVersion);
339 version->set_versionrevision(buildInfo->BugfixVersion);
340 version->set_versionbuild(buildInfo->Build);
341 }
342 else
343 {
344 version->set_versionmajor(6);
345 version->set_versionminor(2);
346 version->set_versionrevision(4);
347 version->set_versionbuild(realm.second.Build);
348 }
349
350 state->mutable_update()->set_cfgrealmsid(realm.second.Id.Realm);
351 state->mutable_update()->set_flags(flag);
352 state->mutable_update()->set_name(realm.second.Name);
355
356 state->set_deleting(false);
357 }
358 }
359
360 std::string json = "JSONRealmListUpdates:" + JSON::Serialize(realmList);
361
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);
366
367 compress(compressed.data() + 4, &compressedLength, reinterpret_cast<uint8 const*>(json.c_str()), uLong(json.length() + 1));
368
369 compressed.resize(compressedLength + 4);
370
371 return compressed;
372}
373
374uint32 RealmList::JoinRealm(uint32 realmAddress, uint32 build, boost::asio::ip::address const& clientAddress, std::array<uint8, 32> const& clientSecret,
375 LocaleConstant locale, std::string const& os, Minutes timezoneOffset, std::string const& accountName, bgs::protocol::game_utilities::v1::ClientResponse* response) const
376{
377 std::shared_lock<std::shared_mutex> lock(_realmsMutex);
378 if (Realm const* realm = GetRealm(Battlenet::RealmHandle(realmAddress)))
379 {
380 if (realm->Flags & REALM_FLAG_OFFLINE || realm->Build != build)
382
384 JSON::RealmList::RealmIPAddressFamily* addressFamily = serverAddresses.add_families();
385 addressFamily->set_family(1);
386
387 JSON::RealmList::IPAddress* address = addressFamily->add_addresses();
388 address->set_ip(realm->GetAddressForClient(clientAddress).to_string());
389 address->set_port(realm->Port);
390
391 lock.unlock();
392
393 std::string json = "JSONRealmListServerIPAddresses:" + JSON::Serialize(serverAddresses);
394
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);
399
400 if (compress(compressed.data() + 4, &compressedLength, reinterpret_cast<uint8 const*>(json.c_str()), uLong(json.length() + 1)) != Z_OK)
402
403 std::array<uint8, 32> serverSecret = Trinity::Crypto::GetRandomBytes<32>();
404
405 std::array<uint8, 64> keyData;
406 auto keyDestItr = keyData.begin();
407 keyDestItr = std::copy(clientSecret.begin(), clientSecret.end(), keyDestItr);
408 keyDestItr = std::copy(serverSecret.begin(), serverSecret.end(), keyDestItr);
409
411 stmt->setBinary(0, keyData);
412 stmt->setString(1, clientAddress.to_string());
413 stmt->setUInt8(2, locale);
414 stmt->setString(3, os);
415 stmt->setInt16(4, timezoneOffset.count());
416 stmt->setString(5, accountName);
417 LoginDatabase.DirectExecute(stmt);
418
419 bgs::protocol::Attribute* attribute = response->add_attribute();
420 attribute->set_name("Param_RealmJoinTicket");
421 attribute->mutable_value()->set_blob_value(accountName);
422
423 attribute = response->add_attribute();
424 attribute->set_name("Param_ServerAddresses");
425 attribute->mutable_value()->set_blob_value(compressed.data(), compressedLength + 4);
426
427 attribute = response->add_attribute();
428 attribute->set_name("Param_JoinSecret");
429 attribute->mutable_value()->set_blob_value(serverSecret.data(), 32);
430 return ERROR_OK;
431 }
432
434}
@ ERROR_UTIL_SERVER_FAILED_TO_SERIALIZE_RESPONSE
@ ERROR_USER_SERVER_NOT_PERMITTED_ON_REALM
@ ERROR_UTIL_SERVER_UNKNOWN_REALM
LocaleConstant
Definition: Common.h:48
AccountTypes
Definition: Common.h:39
@ SEC_ADMINISTRATOR
Definition: Common.h:43
std::shared_ptr< ResultSet > QueryResult
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
Definition: DatabaseEnv.cpp:22
uint8_t uint8
Definition: Define.h:144
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
std::chrono::minutes Minutes
Minutes shorthand typedef.
Definition: Duration.h:35
#define ABORT
Definition: Errors.h:74
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:159
@ LOGIN_SEL_REALMLIST
Definition: LoginDatabase.h:31
@ LOGIN_UPD_BNET_GAME_ACCOUNT_LOGIN_INFO
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
RealmFlags
Definition: Realm.h:27
@ REALM_FLAG_OFFLINE
Definition: Realm.h:30
@ REALM_FLAG_VERSION_MISMATCH
Definition: Realm.h:29
@ REALM_TYPE_FFA_PVP
Definition: Realm.h:73
@ MAX_CLIENT_REALM_TYPE
Definition: Realm.h:71
@ REALM_TYPE_PVP
Definition: Realm.h:66
@ REALM_TYPE_NORMAL
Definition: Realm.h:65
Class used to access individual fields of database query result.
Definition: Field.h:90
uint8 GetUInt8() const
Definition: Field.cpp:30
std::string GetString() const
Definition: Field.cpp:118
uint16 GetUInt16() const
Definition: Field.cpp:46
float GetFloat() const
Definition: Field.cpp:94
uint32 GetUInt32() const
Definition: Field.cpp:62
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.
Definition: RealmList.h:55
std::unique_ptr< Trinity::Asio::Resolver > _resolver
Definition: RealmList.h:93
std::vector< uint8 > GetRealmList(uint32 build, std::string const &subRegion) const
Definition: RealmList.cpp:314
RealmBuildInfo const * GetBuildInfo(uint32 build) const
Definition: RealmList.cpp:235
void Close()
Definition: RealmList.cpp:59
void LoadBuildInfo()
Definition: RealmList.cpp:64
void UpdateRealms()
Definition: RealmList.cpp:116
std::vector< uint8 > GetRealmEntryJSON(Battlenet::RealmHandle const &id, uint32 build) const
Definition: RealmList.cpp:260
std::map< Battlenet::RealmHandle, Realm > RealmMap
Definition: RealmList.h:57
RealmMap _realms
Definition: RealmList.h:89
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
Definition: RealmList.cpp:374
bool GetRealmNames(Battlenet::RealmHandle const &id, std::string *name, std::string *normalizedName) const
Definition: RealmList.cpp:223
uint32 GetMinorMajorBugfixVersionForBuild(uint32 build) const
Definition: RealmList.cpp:244
std::vector< RealmBuildInfo > _builds
Definition: RealmList.h:87
Realm const * GetRealm(Battlenet::RealmHandle const &id) const
Definition: RealmList.cpp:217
std::unordered_set< std::string > _subRegions
Definition: RealmList.h:90
uint32 _updateInterval
Definition: RealmList.h:91
void Initialize(Trinity::Asio::IoContext &ioContext, uint32 updateInterval)
Definition: RealmList.cpp:48
std::shared_mutex _realmsMutex
Definition: RealmList.h:88
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)
Definition: RealmList.cpp:96
std::unique_ptr< Trinity::Asio::DeadlineTimer > _updateTimer
Definition: RealmList.h:92
static RealmList * Instance()
Definition: RealmList.cpp:41
void WriteSubRegions(bgs::protocol::game_utilities::v1::GetAllValuesForAttributeResponse *response) const
Definition: RealmList.cpp:253
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)
Realm realm
Definition: World.cpp:3966
TC_SHARED_API std::string Serialize(google::protobuf::Message const &message)
auto MapGetValuePtr(M &map, typename M::key_type const &key)
Definition: MapUtils.h:29
TC_COMMON_API void HexStrToByteArray(std::string_view str, uint8 *out, size_t outlen, bool reverse=false)
Definition: Util.cpp:871
std::string GetAddressString() const
Definition: Realm.cpp:53
uint32 GetAddress() const
Definition: Realm.h:56
std::string GetSubRegionAddress() const
Definition: Realm.cpp:58
std::array< char, 4 > HotfixVersion
Definition: RealmList.h:37
uint32 MajorVersion
Definition: RealmList.h:34
uint32 BugfixVersion
Definition: RealmList.h:36
uint32 Build
Definition: RealmList.h:33
uint32 MinorVersion
Definition: RealmList.h:35
std::array< uint8, 16 > Mac64AuthSeed
Definition: RealmList.h:39
std::array< uint8, 16 > Win64AuthSeed
Definition: RealmList.h:38
Definition: Realm.h:81
uint16 Port
Definition: Realm.h:85
RealmFlags Flags
Definition: Realm.h:89
AccountTypes AllowedSecurityLevel
Definition: Realm.h:91
uint32 GetConfigId() const
Definition: Realm.cpp:43
boost::asio::ip::address GetAddressForClient(boost::asio::ip::address const &clientAddr) const
Definition: Realm.cpp:32
uint8 Timezone
Definition: Realm.h:90
float PopulationLevel
Definition: Realm.h:92
uint32 Build
Definition: Realm.h:83
std::string NormalizedName
Definition: Realm.h:87
std::string Name
Definition: Realm.h:86
void SetName(std::string name)
Definition: Realm.cpp:25
Battlenet::RealmHandle Id
Definition: Realm.h:82
std::vector< boost::asio::ip::address > Addresses
Definition: Realm.h:84
uint8 Type
Definition: Realm.h:88