aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared/Realm
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/shared/Realm')
-rw-r--r--src/server/shared/Realm/Realm.h2
-rw-r--r--src/server/shared/Realm/RealmList.cpp193
-rw-r--r--src/server/shared/Realm/RealmList.h65
3 files changed, 258 insertions, 2 deletions
diff --git a/src/server/shared/Realm/Realm.h b/src/server/shared/Realm/Realm.h
index 87d333a4bf6..9dc672403f7 100644
--- a/src/server/shared/Realm/Realm.h
+++ b/src/server/shared/Realm/Realm.h
@@ -92,8 +92,6 @@ struct TC_SHARED_API Realm
uint8 Timezone;
AccountTypes AllowedSecurityLevel;
float PopulationLevel;
- bool Updated;
- bool Keep;
ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const;
uint32 GetConfigId() const;
diff --git a/src/server/shared/Realm/RealmList.cpp b/src/server/shared/Realm/RealmList.cpp
new file mode 100644
index 00000000000..8d16b610991
--- /dev/null
+++ b/src/server/shared/Realm/RealmList.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * 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/>.
+ */
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "Util.h"
+#include "RealmList.h"
+#include <boost/asio/ip/tcp.hpp>
+
+RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr)
+{
+}
+
+RealmList::~RealmList()
+{
+ delete _updateTimer;
+}
+
+// Load the realm list from the database
+void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval)
+{
+ _updateInterval = updateInterval;
+ _updateTimer = new boost::asio::deadline_timer(ioService);
+ _resolver = new boost::asio::ip::tcp::resolver(ioService);
+
+ // Get the content of the realmlist table in the database
+ UpdateRealms(boost::system::error_code());
+}
+
+void RealmList::Close()
+{
+ _updateTimer->cancel();
+}
+
+template<typename FieldType>
+inline void UpdateField(FieldType& out, FieldType const& in, bool& changed)
+{
+ if (out != in)
+ {
+ out = in;
+ changed = true;
+ }
+}
+
+void RealmList::UpdateRealm(Battlenet::RealmHandle const& id, uint32 build, const std::string& name, ip::address const& address, ip::address const& localAddr,
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel,
+ float population)
+{
+ // Create new if not exist or update existed
+ Realm& realm = _realms[id];
+
+ realm.Id = id;
+ realm.Build = build;
+ realm.Name = name;
+ realm.Type = icon;
+ realm.Flags = flag;
+ realm.Timezone = timezone;
+ realm.AllowedSecurityLevel = allowedSecurityLevel;
+ realm.PopulationLevel = population;
+ realm.ExternalAddress = address;
+ realm.LocalAddress = localAddr;
+ realm.LocalSubnetMask = localSubmask;
+ realm.Port = port;
+}
+
+void RealmList::UpdateRealms(boost::system::error_code const& error)
+{
+ if (error)
+ return;
+
+ TC_LOG_DEBUG("realmlist", "Updating Realm List...");
+
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST);
+ PreparedQueryResult result = LoginDatabase.Query(stmt);
+
+ std::map<Battlenet::RealmHandle, std::string> existingRealms;
+ for (auto const& p : _realms)
+ existingRealms[p.first] = p.second.Name;
+
+ _realms.clear();
+
+ // Circle through results and add them to the realm map
+ if (result)
+ {
+ do
+ {
+ try
+ {
+ boost::asio::ip::tcp::resolver::iterator end;
+
+ Field* fields = result->Fetch();
+ uint32 realmId = fields[0].GetUInt32();
+ std::string name = fields[1].GetString();
+ boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), "");
+
+ boost::system::error_code ec;
+ boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("realmlist", "Could not resolve address %s for realm \"%s\" id %u", fields[2].GetString().c_str(), name.c_str(), realmId);
+ continue;
+ }
+
+ ip::address externalAddress = (*endPoint).endpoint().address();
+
+ boost::asio::ip::tcp::resolver::query localAddressQuery(ip::tcp::v4(), fields[3].GetString(), "");
+ endPoint = _resolver->resolve(localAddressQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("realmlist", "Could not resolve localAddress %s for realm \"%s\" id %u", fields[3].GetString().c_str(), name.c_str(), realmId);
+ continue;
+ }
+
+ ip::address localAddress = (*endPoint).endpoint().address();
+
+ boost::asio::ip::tcp::resolver::query localSubmaskQuery(ip::tcp::v4(), fields[4].GetString(), "");
+ endPoint = _resolver->resolve(localSubmaskQuery, ec);
+ if (endPoint == end || ec)
+ {
+ TC_LOG_ERROR("realmlist", "Could not resolve localSubnetMask %s for realm \"%s\" id %u", fields[4].GetString().c_str(), name.c_str(), realmId);
+ continue;
+ }
+
+ ip::address localSubmask = (*endPoint).endpoint().address();
+
+ uint16 port = fields[5].GetUInt16();
+ uint8 icon = fields[6].GetUInt8();
+ if (icon == REALM_TYPE_FFA_PVP)
+ icon = REALM_TYPE_PVP;
+ if (icon >= MAX_CLIENT_REALM_TYPE)
+ icon = REALM_TYPE_NORMAL;
+ RealmFlags flag = RealmFlags(fields[7].GetUInt8());
+ uint8 timezone = fields[8].GetUInt8();
+ uint8 allowedSecurityLevel = fields[9].GetUInt8();
+ float pop = fields[10].GetFloat();
+ uint32 build = fields[11].GetUInt32();
+ uint8 region = fields[12].GetUInt8();
+ uint8 battlegroup = fields[13].GetUInt8();
+
+ Battlenet::RealmHandle id{ region, battlegroup, realmId };
+
+ UpdateRealm(id, build, name, externalAddress, localAddress, localSubmask, port, icon, flag,
+ timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop);
+
+ if (!existingRealms.count(id))
+ TC_LOG_INFO("realmlist", "Added realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port);
+ else
+ TC_LOG_DEBUG("realmlist", "Updating realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port);
+
+ existingRealms.erase(id);
+ }
+ catch (std::exception& ex)
+ {
+ TC_LOG_ERROR("realmlist", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what());
+ ABORT();
+ }
+ }
+ while (result->NextRow());
+ }
+
+ for (auto itr = existingRealms.begin(); itr != existingRealms.end(); ++itr)
+ TC_LOG_INFO("realmlist", "Removed realm \"%s\".", itr->second.c_str());
+
+ if (_updateInterval)
+ {
+ _updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval));
+ _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, std::placeholders::_1));
+ }
+}
+
+Realm const* RealmList::GetRealm(Battlenet::RealmHandle const& id) const
+{
+ auto itr = _realms.find(id);
+ if (itr != _realms.end())
+ return &itr->second;
+
+ return NULL;
+}
diff --git a/src/server/shared/Realm/RealmList.h b/src/server/shared/Realm/RealmList.h
new file mode 100644
index 00000000000..0e1350e0a84
--- /dev/null
+++ b/src/server/shared/Realm/RealmList.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * 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/>.
+ */
+
+#ifndef _REALMLIST_H
+#define _REALMLIST_H
+
+#include "Common.h"
+#include "Realm/Realm.h"
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/deadline_timer.hpp>
+
+using namespace boost::asio;
+
+/// Storage object for the list of realms on the server
+class TC_SHARED_API RealmList
+{
+public:
+ typedef std::map<Battlenet::RealmHandle, Realm> RealmMap;
+
+ static RealmList* instance()
+ {
+ static RealmList instance;
+ return &instance;
+ }
+
+ ~RealmList();
+
+ void Initialize(boost::asio::io_service& ioService, uint32 updateInterval);
+ void Close();
+
+ RealmMap const& GetRealms() const { return _realms; }
+ Realm const* GetRealm(Battlenet::RealmHandle const& id) const;
+
+private:
+ RealmList();
+
+ void UpdateRealms(boost::system::error_code const& error);
+ void UpdateRealm(Battlenet::RealmHandle const& id, uint32 build, const std::string& name, ip::address const& address, ip::address const& localAddr,
+ ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population);
+
+ RealmMap _realms;
+ uint32 _updateInterval;
+ boost::asio::deadline_timer* _updateTimer;
+ boost::asio::ip::tcp::resolver* _resolver;
+};
+
+#define sRealmList RealmList::instance()
+#endif