From ca3327dbed76d7d13b9e2754990b717267700be9 Mon Sep 17 00:00:00 2001 From: leak Date: Sun, 22 Jun 2014 15:45:54 +0200 Subject: Replaced ACE_Configuration_Heap based config file handling with boost::property_tree::ini_parser --- src/server/shared/Configuration/Config.cpp | 120 ++++++++++------------------- 1 file changed, 42 insertions(+), 78 deletions(-) (limited to 'src/server/shared/Configuration/Config.cpp') diff --git a/src/server/shared/Configuration/Config.cpp b/src/server/shared/Configuration/Config.cpp index 3f8997e6d55..95336457428 100644 --- a/src/server/shared/Configuration/Config.cpp +++ b/src/server/shared/Configuration/Config.cpp @@ -16,57 +16,41 @@ * with this program. If not, see . */ +#include +#include +#include +#include #include "Config.h" #include "Errors.h" -// Defined here as it must not be exposed to end-users. -bool ConfigMgr::GetValueHelper(const char* name, ACE_TString &result) -{ - GuardType guard(_configLock); - - if (_config.get() == 0) - return false; - - ACE_TString section_name; - ACE_Configuration_Section_Key section_key; - const ACE_Configuration_Section_Key &root_key = _config->root_section(); - - int i = 0; - while (_config->enumerate_sections(root_key, i, section_name) == 0) - { - _config->open_section(root_key, section_name.c_str(), 0, section_key); - if (_config->get_string_value(section_key, name, result) == 0) - return true; - ++i; - } - - return false; -} +using namespace boost::property_tree; bool ConfigMgr::LoadInitial(char const* file) { ASSERT(file); - GuardType guard(_configLock); + std::lock_guard lock(_configLock); _filename = file; - _config.reset(new ACE_Configuration_Heap()); - if (_config->open() == 0) - if (LoadData(_filename.c_str())) - return true; - _config.reset(); - return false; -} + try + { + ptree temp; + boost::property_tree::ini_parser::read_ini(file, temp); -bool ConfigMgr::LoadMore(char const* file) -{ - ASSERT(file); - ASSERT(_config); - GuardType guard(_configLock); + for (auto bla : temp) + { + _config = bla.second; + break; + } + } + catch (std::exception const& /*ex*/) + { + return false; + } - return LoadData(file); + return true; } bool ConfigMgr::Reload() @@ -74,78 +58,58 @@ bool ConfigMgr::Reload() return LoadInitial(_filename.c_str()); } -bool ConfigMgr::LoadData(char const* file) +std::string ConfigMgr::GetStringDefault(const char* name, const std::string &def) { - ACE_Ini_ImpExp config_importer(*_config.get()); - if (config_importer.import_config(file) == 0) - return true; + std::string value = _config.get(ptree::path_type(name,'/'), def); - return false; -} + value.erase(std::remove(value.begin(), value.end(), '"'), value.end()); -std::string ConfigMgr::GetStringDefault(const char* name, const std::string &def) -{ - ACE_TString val; - return GetValueHelper(name, val) ? val.c_str() : def; + return value; } bool ConfigMgr::GetBoolDefault(const char* name, bool def) { - ACE_TString val; - - if (!GetValueHelper(name, val)) + try + { + std::string val = _config.get(name); + val.erase(std::remove(val.begin(), val.end(), '"'), val.end()); + return (val == "true" || val == "TRUE" || val == "yes" || val == "YES" || val == "1"); + } + catch (std::exception const& /*ex*/) + { return def; - - return (val == "true" || val == "TRUE" || val == "yes" || val == "YES" || - val == "1"); + } } int ConfigMgr::GetIntDefault(const char* name, int def) { - ACE_TString val; - return GetValueHelper(name, val) ? atoi(val.c_str()) : def; + return _config.get(name, def); } float ConfigMgr::GetFloatDefault(const char* name, float def) { - ACE_TString val; - return GetValueHelper(name, val) ? (float)atof(val.c_str()) : def; + return _config.get(name, def); } std::string const& ConfigMgr::GetFilename() { - GuardType guard(_configLock); + std::lock_guard lock(_configLock); return _filename; } std::list ConfigMgr::GetKeysByString(std::string const& name) { - GuardType guard(_configLock); + std::lock_guard lock(_configLock); std::list keys; - if (_config.get() == 0) - return keys; - ACE_TString section_name; - ACE_Configuration_Section_Key section_key; - const ACE_Configuration_Section_Key &root_key = _config->root_section(); - - int i = 0; - while (_config->enumerate_sections(root_key, i++, section_name) == 0) + for (const ptree::value_type& child : _config) { - _config->open_section(root_key, section_name.c_str(), 0, section_key); - - ACE_TString key_name; - ACE_Configuration::VALUETYPE type; - int j = 0; - while (_config->enumerate_values(section_key, j++, key_name, type) == 0) + if (child.first.compare(0, name.length(), name) == 0) { - std::string temp = key_name.c_str(); - - if (!temp.find(name)) - keys.push_back(temp); + keys.push_back(child.first); } } - + return keys; } -- cgit v1.2.3 From bfcbde1c97971211d2ecdf5c5f8033eb138658d1 Mon Sep 17 00:00:00 2001 From: leak Date: Sun, 22 Jun 2014 16:29:49 +0200 Subject: Various cleanups and fixes due to feedback --- src/server/shared/Configuration/Config.cpp | 10 +++++----- src/server/shared/Cryptography/BigNumber.cpp | 4 ++-- src/server/shared/Cryptography/BigNumber.h | 2 +- src/server/shared/Utilities/Util.cpp | 7 ++----- src/server/worldserver/Master.cpp | 2 +- 5 files changed, 11 insertions(+), 14 deletions(-) (limited to 'src/server/shared/Configuration/Config.cpp') diff --git a/src/server/shared/Configuration/Config.cpp b/src/server/shared/Configuration/Config.cpp index 95336457428..9e0e57eb198 100644 --- a/src/server/shared/Configuration/Config.cpp +++ b/src/server/shared/Configuration/Config.cpp @@ -35,13 +35,13 @@ bool ConfigMgr::LoadInitial(char const* file) try { - ptree temp; - boost::property_tree::ini_parser::read_ini(file, temp); + ptree fullTree; + boost::property_tree::ini_parser::read_ini(file, fullTree); - - for (auto bla : temp) + // Since we're using only one section per config file, we skip the section and have direct property access + for (auto section : fullTree) { - _config = bla.second; + _config = section.second; break; } } diff --git a/src/server/shared/Cryptography/BigNumber.cpp b/src/server/shared/Cryptography/BigNumber.cpp index ed355b5f63c..c5e0635c5ec 100644 --- a/src/server/shared/Cryptography/BigNumber.cpp +++ b/src/server/shared/Cryptography/BigNumber.cpp @@ -168,7 +168,7 @@ bool BigNumber::isZero() const return BN_is_zero(_bn); } -std::unique_ptr BigNumber::AsByteArray(int32 minSize, bool littleEndian) +std::unique_ptr BigNumber::AsByteArray(int32 minSize, bool littleEndian) { int length = (minSize >= GetNumBytes()) ? minSize : GetNumBytes(); @@ -184,7 +184,7 @@ std::unique_ptr BigNumber::AsByteArray(int32 minSize, bool littleEndian) if (littleEndian) std::reverse(array, array + length); - std::unique_ptr ret(array); + std::unique_ptr ret(array); return ret; } diff --git a/src/server/shared/Cryptography/BigNumber.h b/src/server/shared/Cryptography/BigNumber.h index d0a09dca6c4..848b3da3e2d 100644 --- a/src/server/shared/Cryptography/BigNumber.h +++ b/src/server/shared/Cryptography/BigNumber.h @@ -88,7 +88,7 @@ class BigNumber uint32 AsDword(); - std::unique_ptr AsByteArray(int32 minSize = 0, bool littleEndian = true); + std::unique_ptr AsByteArray(int32 minSize = 0, bool littleEndian = true); char * AsHexStr() const; char * AsDecStr() const; diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp index f80730af05d..1290a7dbae4 100644 --- a/src/server/shared/Utilities/Util.cpp +++ b/src/server/shared/Utilities/Util.cpp @@ -139,16 +139,13 @@ void stripLineInvisibleChars(std::string &str) } +#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) struct tm* localtime_r(const time_t* time, struct tm *result) { -#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) localtime_s(result, time); return result; -#else - return localtime_r(&time, &result); // POSIX -#endif } - +#endif std::string secsToTimeString(uint64 timeInSecs, bool shortText, bool hoursOnly) { diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index 32ca89f3c45..765ab0f09a6 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -171,7 +171,7 @@ int Master::Run() std::thread worldThread(WorldThread); - std::thread* cliThread = NULL; + std::thread* cliThread = nullptr; #ifdef _WIN32 if (sConfigMgr->GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) -- cgit v1.2.3 From eb36acd1522a2e5b8a7d2b4b4a67fc34fc777f03 Mon Sep 17 00:00:00 2001 From: leak Date: Mon, 30 Jun 2014 14:44:52 +0200 Subject: Replaced ACE_Task_Base based LogWorker with ProducerConsumerQueue --- src/server/authserver/Main.cpp | 1 - src/server/shared/Configuration/Config.cpp | 6 +- src/server/shared/Logging/Log.cpp | 2 +- src/server/shared/Logging/Log.h | 1 + src/server/shared/Logging/LogWorker.cpp | 34 ++++--- src/server/shared/Logging/LogWorker.h | 27 +++--- .../shared/Threading/ProducerConsumerQueue.h | 102 +++++++++++++++++++++ 7 files changed, 140 insertions(+), 33 deletions(-) create mode 100644 src/server/shared/Threading/ProducerConsumerQueue.h (limited to 'src/server/shared/Configuration/Config.cpp') diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index 2427c47a438..3901480c70d 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -67,7 +67,6 @@ using boost::asio::ip::tcp; void SignalHandler(const boost::system::error_code& error, int signalNumber) { - TC_LOG_ERROR("server.authserver", "SIGNAL HANDLER WORKING"); if (!error) { switch (signalNumber) diff --git a/src/server/shared/Configuration/Config.cpp b/src/server/shared/Configuration/Config.cpp index 9e0e57eb198..b6690d02155 100644 --- a/src/server/shared/Configuration/Config.cpp +++ b/src/server/shared/Configuration/Config.cpp @@ -71,7 +71,7 @@ bool ConfigMgr::GetBoolDefault(const char* name, bool def) { try { - std::string val = _config.get(name); + std::string val = _config.get(ptree::path_type(name, '/')); val.erase(std::remove(val.begin(), val.end(), '"'), val.end()); return (val == "true" || val == "TRUE" || val == "yes" || val == "YES" || val == "1"); } @@ -83,12 +83,12 @@ bool ConfigMgr::GetBoolDefault(const char* name, bool def) int ConfigMgr::GetIntDefault(const char* name, int def) { - return _config.get(name, def); + return _config.get(ptree::path_type(name, '/'), def); } float ConfigMgr::GetFloatDefault(const char* name, float def) { - return _config.get(name, def); + return _config.get(ptree::path_type(name, '/'), def); } std::string const& ConfigMgr::GetFilename() diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index fd7aa84c0e9..57d8797e61e 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -273,7 +273,7 @@ void Log::write(LogMessage* msg) const msg->text.append("\n"); if (worker) - worker->enqueue(new LogOperation(logger, msg)); + worker->Enqueue(new LogOperation(logger, msg)); else { logger->write(*msg); diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index c3a47d14e9e..8d2fd33d886 100644 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -23,6 +23,7 @@ #include "Appender.h" #include "Logger.h" #include "LogWorker.h" +#include #include #include diff --git a/src/server/shared/Logging/LogWorker.cpp b/src/server/shared/Logging/LogWorker.cpp index b0c82b614f4..ab0f41bf105 100644 --- a/src/server/shared/Logging/LogWorker.cpp +++ b/src/server/shared/Logging/LogWorker.cpp @@ -16,35 +16,41 @@ */ #include "LogWorker.h" +#include LogWorker::LogWorker() - : m_queue(HIGH_WATERMARK, LOW_WATERMARK) { - ACE_Task_Base::activate(THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, 1); + _cancelationToken = false; + _workerThread = std::thread(&LogWorker::WorkerThread, this); } LogWorker::~LogWorker() { - m_queue.deactivate(); - wait(); + _cancelationToken = true; + + _queue.Cancel(); + + _workerThread.join(); } -int LogWorker::enqueue(LogOperation* op) +void LogWorker::Enqueue(LogOperation* op) { - return m_queue.enqueue(op); + return _queue.Push(op); } -int LogWorker::svc() +void LogWorker::WorkerThread() { while (1) { - LogOperation* request; - if (m_queue.dequeue(request) == -1) - break; + LogOperation* operation = nullptr; + + _queue.WaitAndPop(operation); - request->call(); - delete request; - } + if (_cancelationToken) + return; - return 0; + operation->call(); + + delete operation; + } } diff --git a/src/server/shared/Logging/LogWorker.h b/src/server/shared/Logging/LogWorker.h index 25a57842e08..b2680b12c34 100644 --- a/src/server/shared/Logging/LogWorker.h +++ b/src/server/shared/Logging/LogWorker.h @@ -18,30 +18,29 @@ #ifndef LOGWORKER_H #define LOGWORKER_H -#include "LogOperation.h" +#include +#include -#include -#include +#include "LogOperation.h" +#include "ProducerConsumerQueue.h" -class LogWorker: protected ACE_Task_Base +class LogWorker { public: LogWorker(); ~LogWorker(); - typedef ACE_Message_Queue_Ex LogMessageQueueType; + void Enqueue(LogOperation *op); - enum - { - HIGH_WATERMARK = 8 * 1024 * 1024, - LOW_WATERMARK = 8 * 1024 * 1024 - }; + private: + ProducerConsumerQueue _queue; - int enqueue(LogOperation *op); + void WorkerThread(); + std::thread _workerThread; - private: - virtual int svc(); - LogMessageQueueType m_queue; + std::atomic_bool _cancelationToken; }; + + #endif diff --git a/src/server/shared/Threading/ProducerConsumerQueue.h b/src/server/shared/Threading/ProducerConsumerQueue.h new file mode 100644 index 00000000000..961cb9f9c82 --- /dev/null +++ b/src/server/shared/Threading/ProducerConsumerQueue.h @@ -0,0 +1,102 @@ +/* +* Copyright (C) 2008-2014 TrinityCore +* +* 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 _PCQ_H +#define _PCQ_H + +#include +#include +#include + +template +class ProducerConsumerQueue +{ +private: + std::mutex _queueLock; + std::queue _queue; + std::condition_variable _condition; + +public: + + void Push(const T& value) + { + _queueLock.lock(); + + _queue.push(std::move(value)); + + _queueLock.unlock(); + + _condition.notify_one(); + } + + bool Empty() const + { + std::lock_guard lock(_queueLock); + + return _queue.empty(); + } + + bool Pop(T& value) + { + std::lock_guard lock(_queueLock); + + if (_queue.empty()) + return false; + + value = _queue.front(); + + _queue.pop(); + + return true; + } + + void WaitAndPop(T& value) + { + std::unique_lock lock(_queueLock); + + _condition.wait(lock, [this](){ return !_queue.empty(); }); + + if (_queue.empty()) + return; + + value = _queue.front(); + + _queue.pop(); + } + + void Cancel() + { + _queueLock.lock(); + + while (!_queue.empty()) + { + T& value = _queue.front(); + + delete &value; + + _queue.pop(); + } + + _queueLock.unlock(); + + _condition.notify_all(); + } +}; + +#endif + + -- cgit v1.2.3 From 0a07fd5fc38f5b3beac187de88dcd26cb60d9f76 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 3 Jul 2014 15:08:10 -0500 Subject: Some changes here and there in shared --- src/server/shared/Configuration/Config.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'src/server/shared/Configuration/Config.cpp') diff --git a/src/server/shared/Configuration/Config.cpp b/src/server/shared/Configuration/Config.cpp index b6690d02155..aea9d4c1366 100644 --- a/src/server/shared/Configuration/Config.cpp +++ b/src/server/shared/Configuration/Config.cpp @@ -38,12 +38,11 @@ bool ConfigMgr::LoadInitial(char const* file) ptree fullTree; boost::property_tree::ini_parser::read_ini(file, fullTree); + if (fullTree.empty()) + return false; + // Since we're using only one section per config file, we skip the section and have direct property access - for (auto section : fullTree) - { - _config = section.second; - break; - } + _config = fullTree.begin().second; } catch (std::exception const& /*ex*/) { @@ -58,9 +57,9 @@ bool ConfigMgr::Reload() return LoadInitial(_filename.c_str()); } -std::string ConfigMgr::GetStringDefault(const char* name, const std::string &def) +std::string ConfigMgr::GetStringDefault(const char* name, const std::string& def) { - std::string value = _config.get(ptree::path_type(name,'/'), def); + std::string value = _config.get(ptree::path_type(name, '/'), def); value.erase(std::remove(value.begin(), value.end(), '"'), value.end()); @@ -104,12 +103,8 @@ std::list ConfigMgr::GetKeysByString(std::string const& name) std::list keys; for (const ptree::value_type& child : _config) - { if (child.first.compare(0, name.length(), name) == 0) - { keys.push_back(child.first); - } - } return keys; } -- cgit v1.2.3 From 4f2f9e08f80f46149dbbe8e5ca469267f39ae438 Mon Sep 17 00:00:00 2001 From: leak Date: Fri, 4 Jul 2014 15:20:23 +0200 Subject: Fixed compilation and some copy paste error --- src/server/authserver/Server/AuthSession.cpp | 2 +- src/server/game/World/World.cpp | 2 -- src/server/shared/Configuration/Config.cpp | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src/server/shared/Configuration/Config.cpp') diff --git a/src/server/authserver/Server/AuthSession.cpp b/src/server/authserver/Server/AuthSession.cpp index 6646f1203b5..f518dc7593b 100644 --- a/src/server/authserver/Server/AuthSession.cpp +++ b/src/server/authserver/Server/AuthSession.cpp @@ -595,7 +595,7 @@ bool AuthSession::_HandleLogonProof() uint32 MaxWrongPassCount = sConfigMgr->GetIntDefault("WrongPass.MaxCount", 0); // We can not include the failed account login hook. However, this is a workaround to still log this. - if (sConfigMgr->GetBoolDefault("Additional.IP.Based.Login.Logging", false)) + if (sConfigMgr->GetBoolDefault("Wrong.Password.Login.Logging", false)) { PreparedStatement* logstmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_FALP_IP_LOGGING); logstmt->setString(0, _login); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 48dd6565f95..ad23e016e32 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1259,8 +1259,6 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_IP_BASED_ACTION_LOGGING] = sConfigMgr->GetBoolDefault("Allow.IP.Based.Action.Logging", false); - m_bool_configs[CONFIG_IP_BASED_LOGIN_LOGGING] = sConfigMgr->GetBoolDefault("Wrong.Password.Login.Logging", false); - // call ScriptMgr if we're reloading the configuration if (reload) sScriptMgr->OnConfigLoad(reload); diff --git a/src/server/shared/Configuration/Config.cpp b/src/server/shared/Configuration/Config.cpp index aea9d4c1366..fe61cde5594 100644 --- a/src/server/shared/Configuration/Config.cpp +++ b/src/server/shared/Configuration/Config.cpp @@ -42,7 +42,7 @@ bool ConfigMgr::LoadInitial(char const* file) return false; // Since we're using only one section per config file, we skip the section and have direct property access - _config = fullTree.begin().second; + _config = fullTree.begin()->second; } catch (std::exception const& /*ex*/) { -- cgit v1.2.3 From 68398a559e2264b85d8765949989f44e39ce364d Mon Sep 17 00:00:00 2001 From: Chaplain Date: Tue, 15 Jul 2014 17:46:09 +0200 Subject: [Auth\Worldserver] Use boost to load console arguments. (Added a few style changes and cmake fix) Conflicts: src/server/worldserver/Main.cpp --- cmake/macros/ConfigureBoost.cmake | 2 +- src/server/authserver/Main.cpp | 60 ++++++++------ src/server/shared/Configuration/Config.cpp | 12 ++- src/server/shared/Configuration/Config.h | 10 +-- src/server/shared/Utilities/ServiceWin32.cpp | 6 +- src/server/worldserver/Main.cpp | 118 ++++++++++++--------------- 6 files changed, 101 insertions(+), 107 deletions(-) (limited to 'src/server/shared/Configuration/Config.cpp') diff --git a/cmake/macros/ConfigureBoost.cmake b/cmake/macros/ConfigureBoost.cmake index a06b1949964..aa64414afb7 100644 --- a/cmake/macros/ConfigureBoost.cmake +++ b/cmake/macros/ConfigureBoost.cmake @@ -27,7 +27,7 @@ if(WIN32) add_definitions(-D_WIN32_WINNT=${ver}) endif() -find_package(Boost 1.49 REQUIRED system thread) +find_package(Boost 1.49 REQUIRED system thread program_options) add_definitions(-DBOOST_DATE_TIME_NO_LIB) add_definitions(-DBOOST_REGEX_NO_LIB) add_definitions(-DBOOST_CHRONO_NO_LIB) diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index 1286e261a47..701f65c0c14 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -42,6 +43,7 @@ #include "Util.h" using boost::asio::ip::tcp; +using namespace boost::program_options; #ifndef _TRINITY_REALM_CONFIG # define _TRINITY_REALM_CONFIG "authserver.conf" @@ -51,7 +53,7 @@ bool StartDB(); void StopDB(); void SignalHandler(const boost::system::error_code& error, int signalNumber); void KeepDatabaseAliveHandler(const boost::system::error_code& error); -void usage(const char* prog); +variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile); boost::asio::io_service _ioService; boost::asio::deadline_timer _dbPingTimer(_ioService); @@ -60,36 +62,24 @@ LoginDatabaseWorkerPool LoginDatabase; int main(int argc, char** argv) { - // Command line parsing to get the configuration file name - char const* configFile = _TRINITY_REALM_CONFIG; - int count = 1; - while (count < argc) - { - if (strcmp(argv[count], "-c") == 0) - { - if (++count >= argc) - { - printf("Runtime-Error: -c option requires an input argument\n"); - usage(argv[0]); - return 1; - } - else - configFile = argv[count]; - } - ++count; - } + std::string configFile = _TRINITY_REALM_CONFIG; + auto vm = GetConsoleArguments(argc, argv, configFile); + // exit if help is enabled + if (vm.count("help")) + return 0; if (!sConfigMgr->LoadInitial(configFile)) { - printf("Invalid or missing configuration file : %s\n", configFile); + printf("Invalid or missing configuration file : %s\n", configFile.c_str()); printf("Verify that the file exists and has \'[authserver]\' written in the top of the file!\n"); return 1; } TC_LOG_INFO("server.authserver", "%s (authserver)", _FULLVERSION); TC_LOG_INFO("server.authserver", " to stop.\n"); - TC_LOG_INFO("server.authserver", "Using configuration file %s.", configFile); - TC_LOG_INFO("server.authserver", "%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + TC_LOG_INFO("server.authserver", "Using configuration file %s.", configFile.c_str()); + TC_LOG_INFO("server.worldserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + TC_LOG_INFO("server.worldserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); // authserver PID file creation std::string pidFile = sConfigMgr->GetStringDefault("PidFile", ""); @@ -222,10 +212,26 @@ void KeepDatabaseAliveHandler(const boost::system::error_code& error) } } -/// Print out the usage string for this program on the console. -void usage(const char* prog) +variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile) { - TC_LOG_INFO("server.authserver", "Usage: \n %s []\n" - " -c config_file use config_file as configuration file\n\r", - prog); + options_description all("Allowed options"); + all.add_options() + ("help,h", "print usage message") + ("config,c", value(&configFile)->default_value(_TRINITY_REALM_CONFIG), "use as configuration file") + ; + variables_map variablesMap; + try + { + store(command_line_parser(argc, argv).options(all).allow_unregistered().run(), variablesMap); + notify(variablesMap); + } + catch (std::exception& e) { + std::cerr << e.what() << "\n"; + } + + if (variablesMap.count("help")) { + std::cout << all << "\n"; + } + + return variablesMap; } diff --git a/src/server/shared/Configuration/Config.cpp b/src/server/shared/Configuration/Config.cpp index fe61cde5594..5cd7ef52f82 100644 --- a/src/server/shared/Configuration/Config.cpp +++ b/src/server/shared/Configuration/Config.cpp @@ -25,10 +25,8 @@ using namespace boost::property_tree; -bool ConfigMgr::LoadInitial(char const* file) +bool ConfigMgr::LoadInitial(std::string const& file) { - ASSERT(file); - std::lock_guard lock(_configLock); _filename = file; @@ -57,7 +55,7 @@ bool ConfigMgr::Reload() return LoadInitial(_filename.c_str()); } -std::string ConfigMgr::GetStringDefault(const char* name, const std::string& def) +std::string ConfigMgr::GetStringDefault(std::string const& name, const std::string& def) { std::string value = _config.get(ptree::path_type(name, '/'), def); @@ -66,7 +64,7 @@ std::string ConfigMgr::GetStringDefault(const char* name, const std::string& def return value; } -bool ConfigMgr::GetBoolDefault(const char* name, bool def) +bool ConfigMgr::GetBoolDefault(std::string const& name, bool def) { try { @@ -80,12 +78,12 @@ bool ConfigMgr::GetBoolDefault(const char* name, bool def) } } -int ConfigMgr::GetIntDefault(const char* name, int def) +int ConfigMgr::GetIntDefault(std::string const& name, int def) { return _config.get(ptree::path_type(name, '/'), def); } -float ConfigMgr::GetFloatDefault(const char* name, float def) +float ConfigMgr::GetFloatDefault(std::string const& name, float def) { return _config.get(ptree::path_type(name, '/'), def); } diff --git a/src/server/shared/Configuration/Config.h b/src/server/shared/Configuration/Config.h index d05a083d166..68daca5440f 100644 --- a/src/server/shared/Configuration/Config.h +++ b/src/server/shared/Configuration/Config.h @@ -31,7 +31,7 @@ class ConfigMgr public: /// Method used only for loading main configuration files (authserver.conf and worldserver.conf) - bool LoadInitial(char const* file); + bool LoadInitial(std::string const& file); static ConfigMgr* instance() { @@ -41,10 +41,10 @@ public: bool Reload(); - std::string GetStringDefault(const char* name, const std::string& def); - bool GetBoolDefault(const char* name, bool def); - int GetIntDefault(const char* name, int def); - float GetFloatDefault(const char* name, float def); + std::string GetStringDefault(std::string const& name, const std::string& def); + bool GetBoolDefault(std::string const& name, bool def); + int GetIntDefault(std::string const& name, int def); + float GetFloatDefault(std::string const& name, float def); std::string const& GetFilename(); std::list GetKeysByString(std::string const& name); diff --git a/src/server/shared/Utilities/ServiceWin32.cpp b/src/server/shared/Utilities/ServiceWin32.cpp index ec472b33f40..f4a0339d9e6 100644 --- a/src/server/shared/Utilities/ServiceWin32.cpp +++ b/src/server/shared/Utilities/ServiceWin32.cpp @@ -60,7 +60,7 @@ bool WinServiceInstall() if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0) { SC_HANDLE service; - std::strcat(path, " --service"); + std::strcat(path, " --service run"); service = CreateService(serviceControlManager, serviceName, // name of service serviceLongName, // service name to display @@ -119,6 +119,8 @@ bool WinServiceInstall() } CloseServiceHandle(serviceControlManager); } + + printf("Service installed\n"); return true; } @@ -143,6 +145,8 @@ bool WinServiceUninstall() CloseServiceHandle(serviceControlManager); } + + printf("Service uninstalled\n"); return true; } diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 967a31579fa..c28adbc7c21 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "Common.h" #include "DatabaseEnv.h" @@ -45,6 +46,8 @@ #include "SystemConfig.h" #include "WorldSocket.h" +using namespace boost::program_options; + #ifndef _TRINITY_CORE_CONFIG #define _TRINITY_CORE_CONFIG "worldserver.conf" #endif @@ -76,7 +79,6 @@ CharacterDatabaseWorkerPool CharacterDatabase; ///< Accessor to the LoginDatabaseWorkerPool LoginDatabase; ///< Accessor to the realm/login database uint32 realmID; ///< Id of the realm -void usage(const char* prog); void SignalHandler(const boost::system::error_code& error, int signalNumber); void FreezeDetectorHandler(const boost::system::error_code& error); AsyncAcceptor* StartRaSocketAcceptor(boost::asio::io_service& ioService); @@ -84,66 +86,32 @@ bool StartDB(); void StopDB(); void WorldUpdateLoop(); void ClearOnlineAccounts(); +variables_map GetConsoleArguments(int argc, char** argv, std::string& cfg_file, std::string& cfg_service); /// Launch the Trinity server extern int main(int argc, char** argv) { - ///- Command line parsing to get the configuration file name - char const* cfg_file = _TRINITY_CORE_CONFIG; - int c = 1; - while (c < argc) - { - if (!strcmp(argv[c], "-c")) - { - if (++c >= argc) - { - printf("Runtime-Error: -c option requires an input argument"); - usage(argv[0]); - return 1; - } - else - cfg_file = argv[c]; - } + std::string configFile = _TRINITY_CORE_CONFIG; + std::string configService; -#ifdef _WIN32 - if (strcmp(argv[c], "-s") == 0) // Services - { - if (++c >= argc) - { - printf("Runtime-Error: -s option requires an input argument"); - usage(argv[0]); - return 1; - } - - if (strcmp(argv[c], "install") == 0) - { - if (WinServiceInstall()) - printf("Installing service\n"); - return 1; - } - else if (strcmp(argv[c], "uninstall") == 0) - { - if (WinServiceUninstall()) - printf("Uninstalling service\n"); - return 1; - } - else - { - printf("Runtime-Error: unsupported option %s", argv[c]); - usage(argv[0]); - return 1; - } - } + auto vm = GetConsoleArguments(argc, argv, configFile, configService); + // exit if help is enabled + if (vm.count("help")) + return 0; - if (strcmp(argv[c], "--service") == 0) + if (!configService.empty()) + { + if (configService.compare("install") == 0) + return WinServiceInstall() == true ? 0 : 1; + else if (configService.compare("uninstall") == 0) + return WinServiceUninstall() == true ? 0 : 1; + else if (configService.compare("run") == 0) WinServiceRun(); -#endif - ++c; } - if (!sConfigMgr->LoadInitial(cfg_file)) + if (!sConfigMgr->LoadInitial(configFile)) { - printf("Invalid or missing configuration file : %s\n", cfg_file); + printf("Invalid or missing configuration file : %s\n", configFile.c_str()); printf("Verify that the file exists and has \'[worldserver]' written in the top of the file!\n"); return 1; } @@ -165,7 +133,7 @@ extern int main(int argc, char** argv) TC_LOG_INFO("server.worldserver", " \\/_/\\/_/ \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\"); TC_LOG_INFO("server.worldserver", " C O R E /\\___/"); TC_LOG_INFO("server.worldserver", "http://TrinityCore.org \\/__/\n"); - TC_LOG_INFO("server.worldserver", "Using configuration file %s.", cfg_file); + TC_LOG_INFO("server.worldserver", "Using configuration file %s.", configFile.c_str()); TC_LOG_INFO("server.worldserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); TC_LOG_INFO("server.worldserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); @@ -403,20 +371,6 @@ void WorldUpdateLoop() } } -/// Print out the usage string for this program on the console. -void usage(const char* prog) -{ - printf("Usage:\n"); - printf(" %s []\n", prog); - printf(" -c config_file use config_file as configuration file\n"); -#ifdef _WIN32 - printf(" Running as service functions:\n"); - printf(" --service run as service\n"); - printf(" -s install install service\n"); - printf(" -s uninstall uninstall service\n"); -#endif -} - void SignalHandler(const boost::system::error_code& error, int signalNumber) { if (!error) @@ -587,3 +541,35 @@ void ClearOnlineAccounts() } /// @} + +variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile, std::string& configService) +{ + options_description all("Allowed options"); + all.add_options() + ("help,h", "print usage message") + ("config,c", value(&configFile)->default_value(_TRINITY_CORE_CONFIG), "use as configuration file") + ; +#ifdef _WIN32 + options_description win("Windows platform specific options"); + win.add_options() + ("service,s", value(&configService)->default_value(""), "Windows service options: [install | uninstall]") + ; + + all.add(win); +#endif + variables_map vm; + try + { + store(command_line_parser(argc, argv).options(all).allow_unregistered().run(), vm); + notify(vm); + } + catch (std::exception& e) { + std::cerr << e.what() << "\n"; + } + + if (vm.count("help")) { + std::cout << all << "\n"; + } + + return vm; +} -- cgit v1.2.3