Core/Misc: Moved RealmList to shared

This commit is contained in:
Shauren
2016-03-26 13:39:46 +01:00
parent 499a159932
commit cfe8a6a58b
3 changed files with 30 additions and 47 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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