TrinityCore
Loading...
Searching...
No Matches
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"
19#include "ClientBuildInfo.h"
20#include "DatabaseEnv.h"
21#include "DeadlineTimer.h"
22#include "IoContext.h"
23#include "Log.h"
24#include "Resolver.h"
25#include "Util.h"
26#include <boost/asio/ip/tcp.hpp>
27
28RealmList::RealmList() : _updateInterval(0)
29{
30}
31
32RealmList::~RealmList() = default;
33
35{
36 static RealmList instance;
37 return &instance;
38}
39
40// Load the realm list from the database
42{
43 _updateInterval = updateInterval;
44 _updateTimer = std::make_unique<Trinity::Asio::DeadlineTimer>(ioContext);
45 _resolver = std::make_unique<Trinity::Asio::Resolver>(ioContext);
46
48 // Get the content of the realmlist table in the database
49 UpdateRealms(boost::system::error_code());
50}
51
53{
54 _updateTimer->cancel();
55}
56
57void RealmList::UpdateRealm(RealmHandle const& id, uint32 build, std::string const& name,
58 boost::asio::ip::address&& address, boost::asio::ip::address&& localAddr, boost::asio::ip::address&& localSubmask,
59 uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population)
60{
61 // Create new if not exist or update existed
62 Realm& realm = _realms[id];
63
64 realm.Id = id;
65 realm.Build = build;
66 realm.Name = name;
67 realm.Type = icon;
68 realm.Flags = flag;
69 realm.Timezone = timezone;
70 realm.AllowedSecurityLevel = allowedSecurityLevel;
71 realm.PopulationLevel = population;
72 if (!realm.ExternalAddress || *realm.ExternalAddress != address)
73 realm.ExternalAddress = std::make_unique<boost::asio::ip::address>(std::move(address));
74 if (!realm.LocalAddress || *realm.LocalAddress != localAddr)
75 realm.LocalAddress = std::make_unique<boost::asio::ip::address>(std::move(localAddr));
76 if (!realm.LocalSubnetMask || *realm.LocalSubnetMask != localSubmask)
77 realm.LocalSubnetMask = std::make_unique<boost::asio::ip::address>(std::move(localSubmask));
78 realm.Port = port;
79}
80
81void RealmList::UpdateRealms(boost::system::error_code const& error)
82{
83 if (error)
84 return;
85
86 TC_LOG_DEBUG("server.authserver", "Updating Realm List...");
87
89 PreparedQueryResult result = LoginDatabase.Query(stmt);
90
91 std::map<RealmHandle, std::string> existingRealms;
92 for (auto const& p : _realms)
93 existingRealms[p.first] = p.second.Name;
94
95 _realms.clear();
96
97 // Circle through results and add them to the realm map
98 if (result)
99 {
100 do
101 {
102 try
103 {
104 Field* fields = result->Fetch();
105 uint32 realmId = fields[0].GetUInt32();
106 std::string name = fields[1].GetString();
107 std::string externalAddressString = fields[2].GetString();
108 std::string localAddressString = fields[3].GetString();
109 std::string localSubmaskString = fields[4].GetString();
110
111 Optional<boost::asio::ip::tcp::endpoint> externalAddress = _resolver->Resolve(boost::asio::ip::tcp::v4(), externalAddressString, "");
112 if (!externalAddress)
113 {
114 TC_LOG_ERROR("server.authserver", "Could not resolve address {} for realm \"{}\" id {}", externalAddressString, name, realmId);
115 continue;
116 }
117
118 Optional<boost::asio::ip::tcp::endpoint> localAddress = _resolver->Resolve(boost::asio::ip::tcp::v4(), localAddressString, "");
119 if (!localAddress)
120 {
121 TC_LOG_ERROR("server.authserver", "Could not resolve localAddress {} for realm \"{}\" id {}", localAddressString, name, realmId);
122 continue;
123 }
124
125 Optional<boost::asio::ip::tcp::endpoint> localSubmask = _resolver->Resolve(boost::asio::ip::tcp::v4(), localSubmaskString, "");
126 if (!localSubmask)
127 {
128 TC_LOG_ERROR("server.authserver", "Could not resolve localSubnetMask {} for realm \"{}\" id {}", localSubmaskString, name, realmId);
129 continue;
130 }
131
132 uint16 port = fields[5].GetUInt16();
133 uint8 icon = fields[6].GetUInt8();
134 if (icon == REALM_TYPE_FFA_PVP)
135 icon = REALM_TYPE_PVP;
136 if (icon >= MAX_CLIENT_REALM_TYPE)
137 icon = REALM_TYPE_NORMAL;
138 RealmFlags flag = RealmFlags(fields[7].GetUInt8());
139 uint8 timezone = fields[8].GetUInt8();
140 uint8 allowedSecurityLevel = fields[9].GetUInt8();
141 float pop = fields[10].GetFloat();
142 uint32 build = fields[11].GetUInt32();
143
144 RealmHandle id{ realmId };
145
146 UpdateRealm(id, build, name, externalAddress->address(), localAddress->address(), localSubmask->address(), port, icon, flag,
147 timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop);
148
149 if (!existingRealms.count(id))
150 TC_LOG_INFO("server.authserver", "Added realm \"{}\" at {}:{}.", name, externalAddressString, port);
151 else
152 TC_LOG_DEBUG("server.authserver", "Updating realm \"{}\" at {}:{}.", name, externalAddressString, port);
153
154 existingRealms.erase(id);
155 }
156 catch (std::exception& ex)
157 {
158 TC_LOG_ERROR("server.authserver", "Realmlist::UpdateRealms has thrown an exception: {}", ex.what());
159 ABORT();
160 }
161 }
162 while (result->NextRow());
163 }
164
165 for (auto itr = existingRealms.begin(); itr != existingRealms.end(); ++itr)
166 TC_LOG_INFO("server.authserver", "Removed realm \"{}\".", itr->second);
167
168 if (_updateInterval)
169 {
170 _updateTimer->expires_after(std::chrono::seconds(_updateInterval));
171 _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, std::placeholders::_1));
172 }
173}
174
175Realm const* RealmList::GetRealm(RealmHandle const& id) const
176{
177 auto itr = _realms.find(id);
178 if (itr != _realms.end())
179 return &itr->second;
180
181 return nullptr;
182}
AccountTypes
Definition Common.h:39
@ SEC_ADMINISTRATOR
Definition Common.h:43
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
uint8_t uint8
Definition Define.h:135
uint16_t uint16
Definition Define.h:134
uint32_t uint32
Definition Define.h:133
#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
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
RealmFlags
Definition Realm.h:27
@ REALM_TYPE_FFA_PVP
Definition Realm.h:60
@ MAX_CLIENT_REALM_TYPE
Definition Realm.h:58
@ REALM_TYPE_PVP
Definition Realm.h:53
@ REALM_TYPE_NORMAL
Definition Realm.h:52
Class used to access individual fields of database query result.
Definition Field.h:92
uint8 GetUInt8() const
Definition Field.cpp:29
std::string GetString() const
Definition Field.cpp:125
uint16 GetUInt16() const
Definition Field.cpp:45
float GetFloat() const
Definition Field.cpp:93
uint32 GetUInt32() const
Definition Field.cpp:61
Storage object for the list of realms on the server.
Definition RealmList.h:35
std::unique_ptr< Trinity::Asio::Resolver > _resolver
Definition RealmList.h:60
void UpdateRealms(boost::system::error_code const &error)
Definition RealmList.cpp:81
void Close()
Definition RealmList.cpp:52
void UpdateRealm(RealmHandle const &id, uint32 build, std::string const &name, boost::asio::ip::address &&address, boost::asio::ip::address &&localAddr, boost::asio::ip::address &&localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population)
Definition RealmList.cpp:57
Realm const * GetRealm(RealmHandle const &id) const
RealmMap _realms
Definition RealmList.h:57
uint32 _updateInterval
Definition RealmList.h:58
void Initialize(Trinity::Asio::IoContext &ioContext, uint32 updateInterval)
Definition RealmList.cpp:41
std::unique_ptr< Trinity::Asio::DeadlineTimer > _updateTimer
Definition RealmList.h:59
static RealmList * Instance()
Definition RealmList.cpp:34
Realm realm
Definition World.cpp:3605
Definition Realm.h:66
uint16 Port
Definition Realm.h:72
RealmFlags Flags
Definition Realm.h:75
AccountTypes AllowedSecurityLevel
Definition Realm.h:77
uint8 Timezone
Definition Realm.h:76
std::unique_ptr< boost::asio::ip::address > LocalSubnetMask
Definition Realm.h:71
std::unique_ptr< boost::asio::ip::address > LocalAddress
Definition Realm.h:70
float PopulationLevel
Definition Realm.h:78
uint32 Build
Definition Realm.h:68
std::unique_ptr< boost::asio::ip::address > ExternalAddress
Definition Realm.h:69
std::string Name
Definition Realm.h:73
RealmHandle Id
Definition Realm.h:67
uint8 Type
Definition Realm.h:74