diff options
Diffstat (limited to 'src/server/authserver')
| -rw-r--r-- | src/server/authserver/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/server/authserver/Main.cpp | 4 | ||||
| -rw-r--r-- | src/server/authserver/Realms/RealmList.cpp | 90 | ||||
| -rw-r--r-- | src/server/authserver/Realms/RealmList.h | 58 | ||||
| -rw-r--r-- | src/server/authserver/Server/AuthSession.cpp | 29 |
5 files changed, 82 insertions, 100 deletions
diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt index d87847d6740..34e7ed8a43f 100644 --- a/src/server/authserver/CMakeLists.txt +++ b/src/server/authserver/CMakeLists.txt @@ -57,6 +57,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/database ${CMAKE_SOURCE_DIR}/src/server/database/Database ${CMAKE_SOURCE_DIR}/src/server/database/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Networking ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Service diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index 0618ec437b6..939d15ceca8 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -134,7 +134,7 @@ int main(int argc, char** argv) // Get the list of realms for the server sRealmList->Initialize(*_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 20)); - if (sRealmList->size() == 0) + if (sRealmList->GetRealms().empty()) { TC_LOG_ERROR("server.authserver", "No valid realms specified."); StopDB(); @@ -194,6 +194,8 @@ int main(int argc, char** argv) sAuthSocketMgr.StopNetwork(); + sRealmList->Close(); + // Close the Database Pool and library StopDB(); diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp index 53aeff6133b..f1b25d8554d 100644 --- a/src/server/authserver/Realms/RealmList.cpp +++ b/src/server/authserver/Realms/RealmList.cpp @@ -16,69 +16,62 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <boost/asio/ip/tcp.hpp> #include "Common.h" -#include "RealmList.h" #include "Database/DatabaseEnv.h" +#include "RealmList.h" +#include <boost/asio/ip/tcp.hpp> namespace boost { namespace asio { namespace ip { class address; } } } -RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)), _resolver(nullptr) { } +RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr) { } RealmList::~RealmList() { delete _resolver; + 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); - m_UpdateInterval = updateInterval; // Get the content of the realmlist table in the database - UpdateRealms(true); + UpdateRealms(true, boost::system::error_code()); } -void RealmList::UpdateRealm(uint32 id, 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, uint32 build) +void RealmList::Close() { - // Create new if not exist or update existed - Realm& realm = m_realms[name]; - - realm.m_ID = id; - realm.name = name; - realm.icon = icon; - realm.flag = flag; - realm.timezone = timezone; - realm.allowedSecurityLevel = allowedSecurityLevel; - realm.populationLevel = population; - - // Append port to IP address. + _updateTimer->cancel(); +} +void RealmList::UpdateRealm(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; - realm.gamebuild = build; + realm.Port = port; } -void RealmList::UpdateIfNeed() +void RealmList::UpdateRealms(bool init, boost::system::error_code const& error) { - // maybe disabled or updated recently - if (!m_UpdateInterval || m_NextUpdateTime > time(NULL)) + if (error) return; - m_NextUpdateTime = time(NULL) + m_UpdateInterval; - - // Clears Realm list - m_realms.clear(); - - // Get the content of the realmlist table in the database - UpdateRealms(); -} - -void RealmList::UpdateRealms(bool init) -{ TC_LOG_INFO("server.authserver", "Updating Realm List..."); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); @@ -130,17 +123,23 @@ void RealmList::UpdateRealms(bool init) 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(); - UpdateRealm(realmId, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone, - (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build); + RealmHandle id{ realmId }; + + UpdateRealm(id, build, name, externalAddress, localAddress, localSubmask, port, icon, flag, + timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop); if (init) - TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.to_string().c_str(), port); + TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port); } catch (std::exception& ex) { @@ -150,4 +149,19 @@ void RealmList::UpdateRealms(bool init) } while (result->NextRow()); } + + if (_updateInterval) + { + _updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval)); + _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, false, std::placeholders::_1)); + } +} + +Realm const* RealmList::GetRealm(RealmHandle const& id) const +{ + auto itr = _realms.find(id); + if (itr != _realms.end()) + return &itr->second; + + return NULL; } diff --git a/src/server/authserver/Realms/RealmList.h b/src/server/authserver/Realms/RealmList.h index cc5c88c01f2..e35975b215a 100644 --- a/src/server/authserver/Realms/RealmList.h +++ b/src/server/authserver/Realms/RealmList.h @@ -19,48 +19,20 @@ #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 "Common.h" +#include <boost/asio/deadline_timer.hpp> using namespace boost::asio; -enum RealmFlags -{ - REALM_FLAG_NONE = 0x00, - REALM_FLAG_INVALID = 0x01, - REALM_FLAG_OFFLINE = 0x02, - REALM_FLAG_SPECIFYBUILD = 0x04, - REALM_FLAG_UNK1 = 0x08, - REALM_FLAG_UNK2 = 0x10, - REALM_FLAG_RECOMMENDED = 0x20, - REALM_FLAG_NEW = 0x40, - REALM_FLAG_FULL = 0x80 -}; - -// Storage object for a realm -struct Realm -{ - ip::address ExternalAddress; - ip::address LocalAddress; - ip::address LocalSubnetMask; - uint16 port; - std::string name; - uint8 icon; - RealmFlags flag; - uint8 timezone; - uint32 m_ID; - AccountTypes allowedSecurityLevel; - float populationLevel; - uint32 gamebuild; -}; - /// Storage object for the list of realms on the server class RealmList { public: - typedef std::map<std::string, Realm> RealmMap; + typedef std::map<RealmHandle, Realm> RealmMap; static RealmList* instance() { @@ -71,25 +43,21 @@ public: ~RealmList(); void Initialize(boost::asio::io_service& ioService, uint32 updateInterval); + void Close(); - void UpdateIfNeed(); - - void AddRealm(const Realm& NewRealm) { m_realms[NewRealm.name] = NewRealm; } - - RealmMap::const_iterator begin() const { return m_realms.begin(); } - RealmMap::const_iterator end() const { return m_realms.end(); } - uint32 size() const { return m_realms.size(); } + RealmMap const& GetRealms() const { return _realms; } + Realm const* GetRealm(RealmHandle const& id) const; private: RealmList(); - void UpdateRealms(bool init = false); - void UpdateRealm(uint32 id, 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, uint32 build); + void UpdateRealms(bool init, boost::system::error_code const& error); + void UpdateRealm(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 m_realms; - uint32 m_UpdateInterval; - time_t m_NextUpdateTime; + RealmMap _realms; + uint32 _updateInterval; + boost::asio::deadline_timer* _updateTimer; boost::asio::ip::tcp::resolver* _resolver; }; diff --git a/src/server/authserver/Server/AuthSession.cpp b/src/server/authserver/Server/AuthSession.cpp index 57e5d6682f2..e0b463b74ad 100644 --- a/src/server/authserver/Server/AuthSession.cpp +++ b/src/server/authserver/Server/AuthSession.cpp @@ -844,7 +844,7 @@ tcp::endpoint const GetAddressForClient(Realm const& realm, ip::address const& c realmIp = realm.ExternalAddress; } - tcp::endpoint endpoint(realmIp, realm.port); + tcp::endpoint endpoint(realmIp, realm.Port); // Return external IP return endpoint; @@ -880,22 +880,19 @@ void AuthSession::RealmListCallback(PreparedQueryResult result) } while (result->NextRow()); } - // Update realm list if need - sRealmList->UpdateIfNeed(); - // Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) ByteBuffer pkt; size_t RealmListSize = 0; - for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) + for (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms()) { - const Realm &realm = i->second; + const Realm &realm = i.second; // don't work with realms which not compatible with the client - bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.gamebuild == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.gamebuild)); + bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.Build == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.Build)); // No SQL injection. id of realm is controlled by the database. - uint32 flag = realm.flag; - RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild); + uint32 flag = realm.Flags; + RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.Build); if (!okBuild) { if (!buildInfo) @@ -907,7 +904,7 @@ void AuthSession::RealmListCallback(PreparedQueryResult result) if (!buildInfo) flag &= ~REALM_FLAG_SPECIFYBUILD; - std::string name = i->first; + std::string name = realm.Name; if (_expversion & PRE_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD) { std::ostringstream ss; @@ -915,19 +912,19 @@ void AuthSession::RealmListCallback(PreparedQueryResult result) name = ss.str(); } - uint8 lock = (realm.allowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0; + uint8 lock = (realm.AllowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0; - pkt << uint8(realm.icon); // realm type + pkt << uint8(realm.Type); // realm type if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients pkt << uint8(lock); // if 1, then realm locked pkt << uint8(flag); // RealmFlags pkt << name; pkt << boost::lexical_cast<std::string>(GetAddressForClient(realm, GetRemoteIpAddress())); - pkt << float(realm.populationLevel); - pkt << uint8(characterCounts[realm.m_ID]); - pkt << uint8(realm.timezone); // realm category + pkt << float(realm.PopulationLevel); + pkt << uint8(characterCounts[realm.Id.Realm]); + pkt << uint8(realm.Timezone); // realm category if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients - pkt << uint8(realm.m_ID); + pkt << uint8(realm.Id.Realm); else pkt << uint8(0x0); // 1.12.1 and 1.12.2 clients |
