From cfe8a6a58b37280e4ed922e4d70878579dbc8bee Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 26 Mar 2016 13:39:46 +0100 Subject: Core/Misc: Moved RealmList to shared --- src/server/bnetserver/Realms/RealmList.cpp | 208 ----------------------------- src/server/bnetserver/Realms/RealmList.h | 65 --------- src/server/shared/Realm/Realm.h | 2 - src/server/shared/Realm/RealmList.cpp | 193 ++++++++++++++++++++++++++ src/server/shared/Realm/RealmList.h | 65 +++++++++ 5 files changed, 258 insertions(+), 275 deletions(-) delete mode 100644 src/server/bnetserver/Realms/RealmList.cpp delete mode 100644 src/server/bnetserver/Realms/RealmList.h create mode 100644 src/server/shared/Realm/RealmList.cpp create mode 100644 src/server/shared/Realm/RealmList.h (limited to 'src') diff --git a/src/server/bnetserver/Realms/RealmList.cpp b/src/server/bnetserver/Realms/RealmList.cpp deleted file mode 100644 index 056ddef39d4..00000000000 --- a/src/server/bnetserver/Realms/RealmList.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2008-2016 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * 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 . - */ - -#include "Common.h" -#include "Database/DatabaseEnv.h" -#include "SessionManager.h" -#include "Util.h" -#include "RealmList.h" -#include - -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 -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.Keep = true; - - realm.Id = id; - UpdateField(realm.Build, build, realm.Updated); - UpdateField(realm.Name, name, realm.Updated); - UpdateField(realm.Type, icon, realm.Updated); - UpdateField(realm.Flags, flag, realm.Updated); - UpdateField(realm.Timezone, timezone, realm.Updated); - UpdateField(realm.AllowedSecurityLevel, allowedSecurityLevel, realm.Updated); - UpdateField(realm.PopulationLevel, population, realm.Updated); - UpdateField(realm.ExternalAddress, address, realm.Updated); - UpdateField(realm.LocalAddress, localAddr, realm.Updated); - UpdateField(realm.LocalSubnetMask, localSubmask, realm.Updated); - UpdateField(realm.Port, port, realm.Updated); -} - -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); - - // 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(); - 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", fields[2].GetString().c_str()); - 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 address %s", fields[3].GetString().c_str()); - 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 address %s", fields[4].GetString().c_str()); - 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 realmId = fields[0].GetUInt32(); - 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); - - TC_LOG_TRACE("realmlist", "Realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port); - } - catch (std::exception& ex) - { - TC_LOG_ERROR("realmlist", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what()); - ABORT(); - } - } - while (result->NextRow()); - } - - std::vector updatedRealms; - std::vector deletedRealms; - - for (RealmMap::value_type& pair : _realms) - { - if (pair.second.Updated) - updatedRealms.push_back(&pair.second); - else if (!pair.second.Keep) - deletedRealms.push_back(pair.first); - - pair.second.Updated = false; - pair.second.Keep = false; - } - - for (Battlenet::RealmHandle const& deleted : deletedRealms) - _realms.erase(deleted); - - if (!updatedRealms.empty() || !deletedRealms.empty()) - { - sSessionMgr.LockedForEach([&updatedRealms, &deletedRealms](Battlenet::Session* session) - { - if (session->IsSubscribedToRealmListUpdates()) - session->UpdateRealms(updatedRealms, deletedRealms); - }); - } - - 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/bnetserver/Realms/RealmList.h b/src/server/bnetserver/Realms/RealmList.h deleted file mode 100644 index fe3c9185ccf..00000000000 --- a/src/server/bnetserver/Realms/RealmList.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2008-2016 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * 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 . - */ - -#ifndef _REALMLIST_H -#define _REALMLIST_H - -#include "Common.h" -#include "Realm/Realm.h" -#include -#include -#include -#include - -using namespace boost::asio; - -/// Storage object for the list of realms on the server -class RealmList -{ -public: - typedef std::map 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 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 + * Copyright (C) 2005-2009 MaNGOS + * + * 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 . + */ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "Util.h" +#include "RealmList.h" +#include + +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 +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 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 + * Copyright (C) 2005-2009 MaNGOS + * + * 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 . + */ + +#ifndef _REALMLIST_H +#define _REALMLIST_H + +#include "Common.h" +#include "Realm/Realm.h" +#include +#include +#include +#include + +using namespace boost::asio; + +/// Storage object for the list of realms on the server +class TC_SHARED_API RealmList +{ +public: + typedef std::map 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 -- cgit v1.2.3