mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2025-11-29 17:38:24 +08:00
feat(Core/Config): rework config and delete ACE inherited (#4608)
This commit is contained in:
@@ -97,6 +97,7 @@ include(ConfigureBaseTargets)
|
|||||||
include(CheckPlatform)
|
include(CheckPlatform)
|
||||||
include(GroupSources)
|
include(GroupSources)
|
||||||
include(AutoCollect)
|
include(AutoCollect)
|
||||||
|
include(ConfigInstall)
|
||||||
|
|
||||||
CU_RUN_HOOK("AFTER_LOAD_CMAKE_MODULES")
|
CU_RUN_HOOK("AFTER_LOAD_CMAKE_MODULES")
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,30 @@ target_compile_definitions(acore-compile-option-interface
|
|||||||
INTERFACE
|
INTERFACE
|
||||||
-D_BUILD_DIRECTIVE="${CMAKE_BUILD_TYPE}")
|
-D_BUILD_DIRECTIVE="${CMAKE_BUILD_TYPE}")
|
||||||
|
|
||||||
|
# This tests for a bug in clang-7 that causes linkage to fail for 64-bit from_chars (in some configurations)
|
||||||
|
# If the clang requirement is bumped to >= clang-8, you can remove this check, as well as
|
||||||
|
# the associated ifdef block in src/common/Utilities/StringConvert.h
|
||||||
|
include(CheckCXXSourceCompiles)
|
||||||
|
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
#include <charconv>
|
||||||
|
#include <cstdint>
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
uint64_t n;
|
||||||
|
char const c[] = \"0\";
|
||||||
|
std::from_chars(c, c+1, n);
|
||||||
|
return static_cast<int>(n);
|
||||||
|
}
|
||||||
|
" CLANG_HAVE_PROPER_CHARCONV)
|
||||||
|
|
||||||
|
if (NOT CLANG_HAVE_PROPER_CHARCONV)
|
||||||
|
message(STATUS "Clang: Detected from_chars bug for 64-bit integers, workaround enabled")
|
||||||
|
target_compile_definitions(acore-compile-option-interface
|
||||||
|
INTERFACE
|
||||||
|
-DACORE_NEED_CHARCONV_WORKAROUND)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_WARNINGS)
|
if(WITH_WARNINGS)
|
||||||
target_compile_options(acore-warning-interface
|
target_compile_options(acore-warning-interface
|
||||||
INTERFACE
|
INTERFACE
|
||||||
|
|||||||
90
src/cmake/macros/ConfigInstall.cmake
Normal file
90
src/cmake/macros/ConfigInstall.cmake
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||||
|
# Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Use it like:
|
||||||
|
# CopyDefaultConfig(worldserver)
|
||||||
|
#
|
||||||
|
|
||||||
|
function(CopyDefaultConfig servertype)
|
||||||
|
if(WIN32)
|
||||||
|
if("${CMAKE_MAKE_PROGRAM}" MATCHES "MSBuild")
|
||||||
|
add_custom_command(TARGET ${servertype}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/configs")
|
||||||
|
add_custom_command(TARGET ${servertype}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${servertype}.conf.dist" "${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/configs")
|
||||||
|
elseif(MINGW)
|
||||||
|
add_custom_command(TARGET ${servertype}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bin/configs")
|
||||||
|
add_custom_command(TARGET ${servertype}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${servertype}.conf.dist ${CMAKE_BINARY_DIR}/bin/configs")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(UNIX)
|
||||||
|
install(FILES "${servertype}.conf.dist" DESTINATION "${CONF_DIR}")
|
||||||
|
elseif(WIN32)
|
||||||
|
install(FILES "${servertype}.conf.dist" DESTINATION "${CMAKE_INSTALL_PREFIX}/configs")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
#
|
||||||
|
# Use it like:
|
||||||
|
# CopyModuleConfig("warhead.conf.dist")
|
||||||
|
#
|
||||||
|
|
||||||
|
function(CopyModuleConfig configDir)
|
||||||
|
set(postPath "configs/modules")
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
if("${CMAKE_MAKE_PROGRAM}" MATCHES "MSBuild")
|
||||||
|
add_custom_command(TARGET worldserver
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/${postPath}")
|
||||||
|
add_custom_command(TARGET worldserver
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${configDir}" "${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/${postPath}")
|
||||||
|
elseif(MINGW)
|
||||||
|
add_custom_command(TARGET worldserver
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bin/${postPath}")
|
||||||
|
add_custom_command(TARGET worldserver
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${configDir} ${CMAKE_BINARY_DIR}/bin/${postPath}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(UNIX)
|
||||||
|
install(FILES "${configDir}" DESTINATION "${CONF_DIR}/modules")
|
||||||
|
elseif(WIN32)
|
||||||
|
install(FILES "${configDir}" DESTINATION "${CMAKE_INSTALL_PREFIX}/${postPath}")
|
||||||
|
endif()
|
||||||
|
unset(postPath)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
#
|
||||||
|
# Use it like:
|
||||||
|
# CollectModulesConfig()
|
||||||
|
#
|
||||||
|
|
||||||
|
function(CollectModulesConfig)
|
||||||
|
message(STATUS "* Modules config list:")
|
||||||
|
|
||||||
|
CU_GET_GLOBAL("MODULE_CONFIG_FILE_LIST")
|
||||||
|
|
||||||
|
foreach(configFile ${MODULE_CONFIG_FILE_LIST})
|
||||||
|
CopyModuleConfig(${configFile})
|
||||||
|
get_filename_component(file_name ${configFile} NAME)
|
||||||
|
set(CONFIG_LIST ${CONFIG_LIST}${file_name},)
|
||||||
|
message(STATUS " |- ${file_name}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
message("")
|
||||||
|
add_definitions(-DCONFIG_FILE_LIST=$<1:"${CONFIG_LIST}">)
|
||||||
|
endfunction()
|
||||||
@@ -1,284 +1,295 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-GPL2
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-GPL2
|
||||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Errors.h"
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "StringConvert.h"
|
||||||
|
#include "StringFormat.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include <ace/Configuration_Import_Export.h>
|
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <fstream>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
std::unique_ptr<ACE_Configuration_Heap> _config;
|
std::string _filename;
|
||||||
std::vector<std::string> _modulesConfigFiles;
|
std::vector<std::string> _additonalFiles;
|
||||||
std::string _initConfigFile;
|
std::vector<std::string> _args;
|
||||||
|
std::unordered_map<std::string /*name*/, std::string /*value*/> _configOptions;
|
||||||
std::mutex _configLock;
|
std::mutex _configLock;
|
||||||
|
|
||||||
// Defined here as it must not be exposed to end-users.
|
void AddKey(std::string const& optionName, std::string const& optionKey, bool replace = true)
|
||||||
bool GetValueHelper(const char* name, ACE_TString& result)
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(_configLock);
|
auto const& itr = _configOptions.find(optionName);
|
||||||
|
if (itr != _configOptions.end())
|
||||||
if (!_config.get())
|
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
_config->open_section(root_key, section_name.c_str(), 0, section_key);
|
if (!replace)
|
||||||
|
{
|
||||||
|
sLog->outError("> Config: Option '%s' is exist! Option key - '%s'", optionName.c_str(), itr->second.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_config->get_string_value(section_key, name, result))
|
_configOptions.erase(optionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
_configOptions.emplace(optionName, optionKey);
|
||||||
|
|
||||||
|
//sLog->outError("> Config: Add '%s' - '%s'\n", optionName.c_str(), optionKey.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseFile(std::string const& file)
|
||||||
|
{
|
||||||
|
std::ifstream in(file);
|
||||||
|
|
||||||
|
if (in.fail())
|
||||||
|
throw ConfigException(acore::StringFormat("Config::LoadFile: Failed open file '%s'", file.c_str()));
|
||||||
|
|
||||||
|
uint32 count = 0;
|
||||||
|
|
||||||
|
while (in.good())
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::getline(in, line);
|
||||||
|
|
||||||
|
if (line.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
line = acore::String::Reduce(line);
|
||||||
|
|
||||||
|
// comments
|
||||||
|
if (line[0] == '#' || line[0] == '[')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto const equal_pos = line.find('=');
|
||||||
|
|
||||||
|
if (equal_pos == std::string::npos || equal_pos == line.length())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto entry = acore::String::Reduce(line.substr(0, equal_pos));
|
||||||
|
auto value = acore::String::Reduce(line.substr(equal_pos + 1));
|
||||||
|
|
||||||
|
value.erase(std::remove(value.begin(), value.end(), '"'), value.end());
|
||||||
|
|
||||||
|
AddKey(entry, value);
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
throw ConfigException(acore::StringFormat("Config::LoadFile: Empty file '%s'", file.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadFile(std::string const& file)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ParseFile(file);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
++i;
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
sLog->outError("> Config: %s", e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConfigMgr::LoadInitial(std::string const& file)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_configLock);
|
||||||
|
_configOptions.clear();
|
||||||
|
return LoadFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigMgr::LoadAdditionalFile(std::string file)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_configLock);
|
||||||
|
return LoadFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
ConfigMgr* ConfigMgr::instance()
|
ConfigMgr* ConfigMgr::instance()
|
||||||
{
|
{
|
||||||
static ConfigMgr instance;
|
static ConfigMgr instance;
|
||||||
return &instance;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigMgr::LoadInitial(std::string const& file)
|
|
||||||
{
|
|
||||||
ASSERT(file.c_str());
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> guard(_configLock);
|
|
||||||
|
|
||||||
_config.reset(new ACE_Configuration_Heap());
|
|
||||||
if (!_config->open())
|
|
||||||
if (LoadData(file))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
_config.reset();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigMgr::LoadMore(std::string const& file)
|
|
||||||
{
|
|
||||||
ASSERT(file.c_str());
|
|
||||||
ASSERT(_config);
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> guard(_configLock);
|
|
||||||
|
|
||||||
return LoadData(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigMgr::Reload()
|
bool ConfigMgr::Reload()
|
||||||
{
|
{
|
||||||
if (!LoadAppConfigs())
|
if (!LoadAppConfigs())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LoadModulesConfigs();
|
return LoadModulesConfigs();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigMgr::LoadData(std::string const& file)
|
template<class T>
|
||||||
|
T ConfigMgr::GetValueDefault(std::string const& name, T const& def, bool showLogs /*= true*/) const
|
||||||
{
|
{
|
||||||
ACE_Ini_ImpExp config_importer(*_config.get());
|
auto const& itr = _configOptions.find(name);
|
||||||
if (!config_importer.import_config(file.c_str()))
|
if (itr == _configOptions.end())
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ConfigMgr::GetStringDefault(std::string const& name, const std::string& def, bool logUnused /*= true*/)
|
|
||||||
{
|
|
||||||
ACE_TString val;
|
|
||||||
|
|
||||||
if (GetValueHelper(name.c_str(), val))
|
|
||||||
{
|
{
|
||||||
std::string value = val.c_str();
|
if (showLogs)
|
||||||
value.erase(std::remove(value.begin(), value.end(), '"'), value.end());
|
{
|
||||||
return value;
|
sLog->outError("> Config: Missing name %s in config, add \"%s = %s\"",
|
||||||
|
name.c_str(), name.c_str(), acore::ToString(def).c_str());
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (logUnused)
|
|
||||||
sLog->outError("-> Not found option '%s'. The default value is used (%s)", name.c_str(), def.c_str());
|
|
||||||
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigMgr::GetBoolDefault(std::string const& name, bool def, bool logUnused /*= true*/)
|
|
||||||
{
|
|
||||||
ACE_TString val;
|
|
||||||
|
|
||||||
if (!GetValueHelper(name.c_str(), val))
|
|
||||||
{
|
|
||||||
if (logUnused)
|
|
||||||
def ? sLog->outError("-> Not found option '%s'. The default value is used (Yes)", name.c_str()) : sLog->outError("-> Not found option '%s'. The default value is used (No)", name.c_str());
|
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
return StringToBool(val.c_str());
|
auto value = acore::StringTo<T>(itr->second);
|
||||||
}
|
if (!value)
|
||||||
|
|
||||||
int ConfigMgr::GetIntDefault(std::string const& name, int def, bool logUnused /*= true*/)
|
|
||||||
{
|
|
||||||
ACE_TString val;
|
|
||||||
|
|
||||||
if (GetValueHelper(name.c_str(), val))
|
|
||||||
return std::stoi(val.c_str());
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (logUnused)
|
if (showLogs)
|
||||||
sLog->outError("-> Not found option '%s'. The default value is used (%i)", name.c_str(), def);
|
{
|
||||||
|
sLog->outError("> Config: Bad value defined for name '%s', going to use '%s' instead",
|
||||||
|
name.c_str(), acore::ToString(def).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return *value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float ConfigMgr::GetFloatDefault(std::string const& name, float def, bool logUnused /*= true*/)
|
template<>
|
||||||
|
std::string ConfigMgr::GetValueDefault<std::string>(std::string const& name, std::string const& def, bool showLogs /*= true*/) const
|
||||||
{
|
{
|
||||||
ACE_TString val;
|
auto const& itr = _configOptions.find(name);
|
||||||
|
if (itr == _configOptions.end())
|
||||||
if (GetValueHelper(name.c_str(), val))
|
|
||||||
return std::stof(val.c_str());
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (logUnused)
|
if (showLogs)
|
||||||
sLog->outError("-> Not found option '%s'. The default value is used (%f)", name.c_str(), def);
|
{
|
||||||
|
sLog->outError("> Config: Missing name %s in config, add \"%s = %s\"",
|
||||||
|
name.c_str(), name.c_str(), def.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return itr->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<std::string> ConfigMgr::GetKeysByString(std::string const& name)
|
template<class T>
|
||||||
|
T ConfigMgr::GetOption(std::string const& name, T const& def, bool showLogs /*= true*/) const
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(_configLock);
|
return GetValueDefault<T>(name, def, showLogs);
|
||||||
|
}
|
||||||
|
|
||||||
std::list<std::string> keys;
|
template<>
|
||||||
if (!_config.get())
|
bool ConfigMgr::GetOption<bool>(std::string const& name, bool const& def, bool showLogs /*= true*/) const
|
||||||
return keys;
|
{
|
||||||
|
std::string val = GetValueDefault(name, std::string(def ? "1" : "0"), showLogs);
|
||||||
|
|
||||||
ACE_TString section_name;
|
auto boolVal = acore::StringTo<bool>(val);
|
||||||
ACE_Configuration_Section_Key section_key;
|
if (!boolVal)
|
||||||
const ACE_Configuration_Section_Key& root_key = _config->root_section();
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while (!_config->enumerate_sections(root_key, i++, section_name))
|
|
||||||
{
|
{
|
||||||
_config->open_section(root_key, section_name.c_str(), 0, section_key);
|
if (showLogs)
|
||||||
|
|
||||||
ACE_TString key_name;
|
|
||||||
ACE_Configuration::VALUETYPE type;
|
|
||||||
|
|
||||||
int j = 0;
|
|
||||||
|
|
||||||
while (!_config->enumerate_values(section_key, j++, key_name, type))
|
|
||||||
{
|
{
|
||||||
std::string temp = key_name.c_str();
|
sLog->outError("> Config: Bad value defined for name '%s', going to use '%s' instead",
|
||||||
|
name.c_str(), def ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
if (temp.find(name) != std::string::npos)
|
return def;
|
||||||
keys.push_back(temp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return *boolVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> ConfigMgr::GetKeysByString(std::string const& name)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_configLock);
|
||||||
|
|
||||||
|
std::vector<std::string> keys;
|
||||||
|
|
||||||
|
for (auto const& [optionName, key] : _configOptions)
|
||||||
|
if (!optionName.compare(0, name.length(), name))
|
||||||
|
keys.emplace_back(optionName);
|
||||||
|
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigMgr::SetConfigList(std::string const& fileName, std::string const& modulesConfigList /*= ""*/)
|
std::string const& ConfigMgr::GetFilename()
|
||||||
{
|
{
|
||||||
_initConfigFile = fileName;
|
std::lock_guard<std::mutex> lock(_configLock);
|
||||||
|
return _filename;
|
||||||
|
}
|
||||||
|
|
||||||
if (modulesConfigList.empty())
|
std::vector<std::string> const& ConfigMgr::GetArguments() const
|
||||||
return;
|
{
|
||||||
|
return _args;
|
||||||
|
}
|
||||||
|
|
||||||
// Clean config list before load
|
std::string const ConfigMgr::GetConfigPath()
|
||||||
_modulesConfigFiles.clear();
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_configLock);
|
||||||
|
|
||||||
|
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
|
||||||
|
return "configs/";
|
||||||
|
#else
|
||||||
|
return std::string(_CONF_DIR) + "/";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigMgr::Configure(std::string const& initFileName, std::vector<std::string> args, std::string const& modulesConfigList /*= ""*/)
|
||||||
|
{
|
||||||
|
_filename = initFileName;
|
||||||
|
_args = std::move(args);
|
||||||
|
|
||||||
|
// Add modules config if exist
|
||||||
|
if (!modulesConfigList.empty())
|
||||||
|
{
|
||||||
Tokenizer configFileList(modulesConfigList, ',');
|
Tokenizer configFileList(modulesConfigList, ',');
|
||||||
for (auto const& itr : configFileList)
|
for (auto const& itr : configFileList)
|
||||||
_modulesConfigFiles.push_back(itr);
|
_additonalFiles.emplace_back(std::string(itr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigMgr::LoadAppConfigs(std::string const& applicationName /*= "worldserver"*/)
|
bool ConfigMgr::LoadAppConfigs()
|
||||||
{
|
{
|
||||||
// #1 - Load init config file .conf.dist
|
// #1 - Load init config file .conf.dist
|
||||||
if (!sConfigMgr->LoadInitial(_initConfigFile + ".dist"))
|
if (!LoadInitial(_filename + ".dist"))
|
||||||
{
|
|
||||||
printf("Load config error. Invalid or missing dist configuration file: %s", std::string(_initConfigFile + ".dist").c_str());
|
|
||||||
printf("Verify that the file exists and has \'[%s]' written in the top of the file!", applicationName.c_str());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// #2 - Load .conf file
|
// #2 - Load .conf file
|
||||||
if (!sConfigMgr->LoadMore(_initConfigFile))
|
if (!LoadAdditionalFile(_filename))
|
||||||
{
|
|
||||||
sLog->outString();
|
|
||||||
sLog->outString("Load config error. Invalid or missing configuration file: %s", _initConfigFile.c_str());
|
|
||||||
sLog->outString("Verify that the file exists and has \'[%s]' written in the top of the file!", applicationName.c_str());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigMgr::LoadModulesConfigs()
|
bool ConfigMgr::LoadModulesConfigs()
|
||||||
{
|
{
|
||||||
// If not modules config - load failed
|
if (_additonalFiles.empty())
|
||||||
if (_modulesConfigFiles.empty())
|
return true;
|
||||||
return false;
|
|
||||||
|
|
||||||
// Start loading module configs
|
// Start loading module configs
|
||||||
std::unordered_map<std::string /*module name*/, std::string /*config variant*/> moduleConfigFiles;
|
std::vector<std::string /*config variant*/> moduleConfigFiles;
|
||||||
|
std::string const& moduleConfigPath = GetConfigPath() + "modules/";
|
||||||
|
bool isExistDefaultConfig = true;
|
||||||
|
bool isExistDistConfig = true;
|
||||||
|
|
||||||
moduleConfigFiles.clear();
|
for (auto const& distFileName : _additonalFiles)
|
||||||
|
|
||||||
std::string configPath = _CONF_DIR;
|
|
||||||
|
|
||||||
for (auto const& itr : _modulesConfigFiles)
|
|
||||||
{
|
{
|
||||||
bool IsExistDefaultConfig = true;
|
std::string defaultFileName = distFileName;
|
||||||
bool IsExistDistConfig = true;
|
|
||||||
|
|
||||||
std::string moduleName = itr;
|
if (!defaultFileName.empty())
|
||||||
std::string configFile = std::string(itr) + std::string(".conf");
|
defaultFileName.erase(defaultFileName.end() - 5, defaultFileName.end());
|
||||||
std::string defaultConfig = configPath + "/" + configFile;
|
|
||||||
|
|
||||||
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
|
|
||||||
defaultConfig = configFile;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::string ConfigFileDist = defaultConfig + std::string(".dist");
|
|
||||||
|
|
||||||
// Load .conf.dist config
|
// Load .conf.dist config
|
||||||
if (!sConfigMgr->LoadMore(ConfigFileDist.c_str()))
|
if (!LoadAdditionalFile(moduleConfigPath + distFileName))
|
||||||
{
|
isExistDistConfig = false;
|
||||||
sLog->outError("> Invalid or missing dist configuration file: %s", ConfigFileDist.c_str());
|
|
||||||
IsExistDistConfig = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load .conf config
|
// Load .conf config
|
||||||
if (!sConfigMgr->LoadMore(defaultConfig.c_str()))
|
if (!LoadAdditionalFile(moduleConfigPath + defaultFileName))
|
||||||
IsExistDefaultConfig = false;
|
isExistDefaultConfig = false;
|
||||||
|
|
||||||
// #1 - Not exist .conf and exist .conf.dist
|
if (isExistDefaultConfig && isExistDistConfig)
|
||||||
if (!IsExistDefaultConfig && IsExistDistConfig)
|
moduleConfigFiles.emplace_back(defaultFileName);
|
||||||
moduleConfigFiles.insert(std::make_pair(moduleName, ConfigFileDist));
|
else if (!isExistDefaultConfig && isExistDistConfig)
|
||||||
else if (!IsExistDefaultConfig && !IsExistDistConfig) // #2 - Not exist .conf and not exist .conf.dist
|
moduleConfigFiles.emplace_back(distFileName);
|
||||||
moduleConfigFiles.insert(std::make_pair(moduleName, "default hardcoded settings"));
|
|
||||||
else if (IsExistDefaultConfig && IsExistDistConfig)
|
|
||||||
moduleConfigFiles.insert(std::make_pair(moduleName, defaultConfig));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If module configs not exist - no load
|
// If module configs not exist - no load
|
||||||
@@ -287,12 +298,60 @@ bool ConfigMgr::LoadModulesConfigs()
|
|||||||
|
|
||||||
// Print modules configurations
|
// Print modules configurations
|
||||||
sLog->outString();
|
sLog->outString();
|
||||||
sLog->outString("Using configuration for modules:");
|
sLog->outString("Using modules configuration:");
|
||||||
|
|
||||||
for (auto const& itr : moduleConfigFiles)
|
for (auto const& itr : moduleConfigFiles)
|
||||||
sLog->outString("> Module (%s) using (%s)", itr.first.c_str(), itr.second.c_str());
|
sLog->outString("> %s", itr.c_str());
|
||||||
|
|
||||||
sLog->outString();
|
sLog->outString("");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deprecated geters. This geters will be deleted
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @deprecated DO NOT USE - use GetOption<std::string> instead.
|
||||||
|
std::string ConfigMgr::GetStringDefault(std::string const& name, const std::string& def, bool showLogs /*= true*/)
|
||||||
|
{
|
||||||
|
return GetOption<std::string>(name, def, showLogs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @deprecated DO NOT USE - use GetOption<bool> instead.
|
||||||
|
bool ConfigMgr::GetBoolDefault(std::string const& name, bool def, bool showLogs /*= true*/)
|
||||||
|
{
|
||||||
|
return GetOption<bool>(name, def, showLogs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @deprecated DO NOT USE - use GetOption<int32> instead.
|
||||||
|
int ConfigMgr::GetIntDefault(std::string const& name, int def, bool showLogs /*= true*/)
|
||||||
|
{
|
||||||
|
return GetOption<int32>(name, def, showLogs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @deprecated DO NOT USE - use GetOption<float> instead.
|
||||||
|
float ConfigMgr::GetFloatDefault(std::string const& name, float def, bool showLogs /*= true*/)
|
||||||
|
{
|
||||||
|
return GetOption<float>(name, def, showLogs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* End deprecated geters
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TEMPLATE_CONFIG_OPTION(__typename) \
|
||||||
|
template __typename ConfigMgr::GetOption<__typename>(std::string const& name, __typename const& def, bool showLogs /*= true*/) const;
|
||||||
|
|
||||||
|
TEMPLATE_CONFIG_OPTION(std::string)
|
||||||
|
TEMPLATE_CONFIG_OPTION(uint8)
|
||||||
|
TEMPLATE_CONFIG_OPTION(int8)
|
||||||
|
TEMPLATE_CONFIG_OPTION(uint16)
|
||||||
|
TEMPLATE_CONFIG_OPTION(int16)
|
||||||
|
TEMPLATE_CONFIG_OPTION(uint32)
|
||||||
|
TEMPLATE_CONFIG_OPTION(int32)
|
||||||
|
TEMPLATE_CONFIG_OPTION(uint64)
|
||||||
|
TEMPLATE_CONFIG_OPTION(int64)
|
||||||
|
TEMPLATE_CONFIG_OPTION(float)
|
||||||
|
|
||||||
|
#undef TEMPLATE_CONFIG_OPTION
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-GPL2
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-GPL2
|
||||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_H
|
#ifndef CONFIG_H
|
||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Define.h"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
class ConfigMgr
|
class ConfigMgr
|
||||||
{
|
{
|
||||||
@@ -17,40 +19,60 @@ class ConfigMgr
|
|||||||
~ConfigMgr() = default;
|
~ConfigMgr() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool LoadAppConfigs();
|
||||||
|
bool LoadModulesConfigs();
|
||||||
|
void Configure(std::string const& initFileName, std::vector<std::string> args, std::string const& modulesConfigList = "");
|
||||||
|
|
||||||
static ConfigMgr* instance();
|
static ConfigMgr* instance();
|
||||||
|
|
||||||
/// Method used only for loading main configuration files (authserver.conf and worldserver.conf)
|
|
||||||
bool LoadInitial(std::string const& file);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method loads additional configuration files
|
|
||||||
* It is recommended to use this method in WorldScript::OnConfigLoad hooks
|
|
||||||
*
|
|
||||||
* @return true if loading was successful
|
|
||||||
*/
|
|
||||||
bool LoadMore(std::string const& file);
|
|
||||||
|
|
||||||
bool Reload();
|
bool Reload();
|
||||||
|
|
||||||
bool LoadAppConfigs(std::string const& applicationName = "worldserver");
|
std::string const& GetFilename();
|
||||||
bool LoadModulesConfigs();
|
std::string const GetConfigPath();
|
||||||
|
std::vector<std::string> const& GetArguments() const;
|
||||||
|
std::vector<std::string> GetKeysByString(std::string const& name);
|
||||||
|
|
||||||
std::string GetStringDefault(std::string const& name, const std::string& def, bool logUnused = true);
|
template<class T>
|
||||||
bool GetBoolDefault(std::string const& name, bool def, bool logUnused = true);
|
T GetOption(std::string const& name, T const& def, bool showLogs = true) const;
|
||||||
int GetIntDefault(std::string const& name, int def, bool logUnused = true);
|
|
||||||
float GetFloatDefault(std::string const& name, float def, bool logUnused = true);
|
|
||||||
|
|
||||||
std::list<std::string> GetKeysByString(std::string const& name);
|
/*
|
||||||
|
* Deprecated geters. This geters will be deleted
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @deprecated DO NOT USE - use GetOption<std::string> instead.
|
||||||
|
std::string GetStringDefault(std::string const& name, const std::string& def, bool showLogs = true);
|
||||||
|
|
||||||
|
// @deprecated DO NOT USE - use GetOption<bool> instead.
|
||||||
|
bool GetBoolDefault(std::string const& name, bool def, bool showLogs = true);
|
||||||
|
|
||||||
|
// @deprecated DO NOT USE - use GetOption<int32> instead.
|
||||||
|
int GetIntDefault(std::string const& name, int def, bool showLogs = true);
|
||||||
|
|
||||||
|
// @deprecated DO NOT USE - use GetOption<float> instead.
|
||||||
|
float GetFloatDefault(std::string const& name, float def, bool showLogs = true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* End deprecated geters
|
||||||
|
*/
|
||||||
|
|
||||||
bool isDryRun() { return dryRun; }
|
bool isDryRun() { return dryRun; }
|
||||||
void setDryRun(bool mode) { dryRun = mode; }
|
void setDryRun(bool mode) { dryRun = mode; }
|
||||||
|
|
||||||
void SetConfigList(std::string const& fileName, std::string const& modulesConfigList = "");
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool dryRun = false;
|
/// Method used only for loading main configuration files (authserver.conf and worldserver.conf)
|
||||||
|
bool LoadInitial(std::string const& file);
|
||||||
|
bool LoadAdditionalFile(std::string file);
|
||||||
|
|
||||||
bool LoadData(std::string const& file);
|
template<class T>
|
||||||
|
T GetValueDefault(std::string const& name, T const& def, bool showLogs = true) const;
|
||||||
|
|
||||||
|
bool dryRun = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConfigException : public std::length_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ConfigException(std::string const& message) : std::length_error(message) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define sConfigMgr ConfigMgr::instance()
|
#define sConfigMgr ConfigMgr::instance()
|
||||||
|
|||||||
@@ -93,16 +93,16 @@ void Log::SetLogFileLevel(char* Level)
|
|||||||
void Log::Initialize()
|
void Log::Initialize()
|
||||||
{
|
{
|
||||||
/// Check whether we'll log GM commands/RA events/character outputs/chat stuffs
|
/// Check whether we'll log GM commands/RA events/character outputs/chat stuffs
|
||||||
m_dbChar = sConfigMgr->GetBoolDefault("LogDB.Char", false, false);
|
m_dbChar = sConfigMgr->GetOption<bool>("LogDB.Char", false, false);
|
||||||
m_dbRA = sConfigMgr->GetBoolDefault("LogDB.RA", false, false);
|
m_dbRA = sConfigMgr->GetOption<bool>("LogDB.RA", false, false);
|
||||||
m_dbGM = sConfigMgr->GetBoolDefault("LogDB.GM", false, false);
|
m_dbGM = sConfigMgr->GetOption<bool>("LogDB.GM", false, false);
|
||||||
m_dbChat = sConfigMgr->GetBoolDefault("LogDB.Chat", false, false);
|
m_dbChat = sConfigMgr->GetOption<bool>("LogDB.Chat", false, false);
|
||||||
|
|
||||||
/// Realm must be 0 by default
|
/// Realm must be 0 by default
|
||||||
SetRealmID(0);
|
SetRealmID(0);
|
||||||
|
|
||||||
/// Common log files data
|
/// Common log files data
|
||||||
m_logsDir = sConfigMgr->GetStringDefault("LogsDir", "", false);
|
m_logsDir = sConfigMgr->GetOption<std::string>("LogsDir", "", false);
|
||||||
if (!m_logsDir.empty())
|
if (!m_logsDir.empty())
|
||||||
if ((m_logsDir.at(m_logsDir.length() - 1) != '/') && (m_logsDir.at(m_logsDir.length() - 1) != '\\'))
|
if ((m_logsDir.at(m_logsDir.length() - 1) != '/') && (m_logsDir.at(m_logsDir.length() - 1) != '\\'))
|
||||||
m_logsDir.push_back('/');
|
m_logsDir.push_back('/');
|
||||||
@@ -111,18 +111,18 @@ void Log::Initialize()
|
|||||||
|
|
||||||
/// Open specific log files
|
/// Open specific log files
|
||||||
logfile = openLogFile("LogFile", "LogTimestamp", "w");
|
logfile = openLogFile("LogFile", "LogTimestamp", "w");
|
||||||
InitColors(sConfigMgr->GetStringDefault("LogColors", "", false));
|
InitColors(sConfigMgr->GetOption<std::string>("LogColors", "", false));
|
||||||
|
|
||||||
m_gmlog_per_account = sConfigMgr->GetBoolDefault("GmLogPerAccount", false, false);
|
m_gmlog_per_account = sConfigMgr->GetOption<bool>("GmLogPerAccount", false, false);
|
||||||
if (!m_gmlog_per_account)
|
if (!m_gmlog_per_account)
|
||||||
gmLogfile = openLogFile("GMLogFile", "GmLogTimestamp", "a");
|
gmLogfile = openLogFile("GMLogFile", "GmLogTimestamp", "a");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// GM log settings for per account case
|
// GM log settings for per account case
|
||||||
m_gmlog_filename_format = sConfigMgr->GetStringDefault("GMLogFile", "", false);
|
m_gmlog_filename_format = sConfigMgr->GetOption<std::string>("GMLogFile", "", false);
|
||||||
if (!m_gmlog_filename_format.empty())
|
if (!m_gmlog_filename_format.empty())
|
||||||
{
|
{
|
||||||
bool m_gmlog_timestamp = sConfigMgr->GetBoolDefault("GmLogTimestamp", false, false);
|
bool m_gmlog_timestamp = sConfigMgr->GetOption<bool>("GmLogTimestamp", false, false);
|
||||||
|
|
||||||
size_t dot_pos = m_gmlog_filename_format.find_last_of('.');
|
size_t dot_pos = m_gmlog_filename_format.find_last_of('.');
|
||||||
if (dot_pos != m_gmlog_filename_format.npos)
|
if (dot_pos != m_gmlog_filename_format.npos)
|
||||||
@@ -153,19 +153,19 @@ void Log::Initialize()
|
|||||||
miscLogFile = fopen((m_logsDir + "Misc.log").c_str(), "a");
|
miscLogFile = fopen((m_logsDir + "Misc.log").c_str(), "a");
|
||||||
|
|
||||||
// Main log file settings
|
// Main log file settings
|
||||||
m_logLevel = sConfigMgr->GetIntDefault("LogLevel", LOGL_NORMAL, false);
|
m_logLevel = sConfigMgr->GetOption<int32>("LogLevel", LOGL_NORMAL, false);
|
||||||
m_logFileLevel = sConfigMgr->GetIntDefault("LogFileLevel", LOGL_NORMAL, false);
|
m_logFileLevel = sConfigMgr->GetOption<int32>("LogFileLevel", LOGL_NORMAL, false);
|
||||||
m_dbLogLevel = sConfigMgr->GetIntDefault("DBLogLevel", LOGL_NORMAL, false);
|
m_dbLogLevel = sConfigMgr->GetOption<int32>("DBLogLevel", LOGL_NORMAL, false);
|
||||||
m_sqlDriverQueryLogging = sConfigMgr->GetBoolDefault("SQLDriverQueryLogging", false, false);
|
m_sqlDriverQueryLogging = sConfigMgr->GetOption<bool>("SQLDriverQueryLogging", false, false);
|
||||||
|
|
||||||
m_DebugLogMask = DebugLogFilters(sConfigMgr->GetIntDefault("DebugLogMask", LOG_FILTER_NONE, false));
|
m_DebugLogMask = DebugLogFilters(sConfigMgr->GetOption<int32>("DebugLogMask", LOG_FILTER_NONE, false));
|
||||||
|
|
||||||
// Char log settings
|
// Char log settings
|
||||||
m_charLog_Dump = sConfigMgr->GetBoolDefault("CharLogDump", false, false);
|
m_charLog_Dump = sConfigMgr->GetOption<bool>("CharLogDump", false, false);
|
||||||
m_charLog_Dump_Separate = sConfigMgr->GetBoolDefault("CharLogDump.Separate", false, false);
|
m_charLog_Dump_Separate = sConfigMgr->GetOption<bool>("CharLogDump.Separate", false, false);
|
||||||
if (m_charLog_Dump_Separate)
|
if (m_charLog_Dump_Separate)
|
||||||
{
|
{
|
||||||
m_dumpsDir = sConfigMgr->GetStringDefault("CharLogDump.SeparateDir", "", false);
|
m_dumpsDir = sConfigMgr->GetOption<std::string>("CharLogDump.SeparateDir", "", false);
|
||||||
if (!m_dumpsDir.empty())
|
if (!m_dumpsDir.empty())
|
||||||
if ((m_dumpsDir.at(m_dumpsDir.length() - 1) != '/') && (m_dumpsDir.at(m_dumpsDir.length() - 1) != '\\'))
|
if ((m_dumpsDir.at(m_dumpsDir.length() - 1) != '/') && (m_dumpsDir.at(m_dumpsDir.length() - 1) != '\\'))
|
||||||
m_dumpsDir.push_back('/');
|
m_dumpsDir.push_back('/');
|
||||||
@@ -174,20 +174,20 @@ void Log::Initialize()
|
|||||||
|
|
||||||
void Log::ReloadConfig()
|
void Log::ReloadConfig()
|
||||||
{
|
{
|
||||||
m_logLevel = sConfigMgr->GetIntDefault("LogLevel", LOGL_NORMAL);
|
m_logLevel = sConfigMgr->GetOption<int32>("LogLevel", LOGL_NORMAL);
|
||||||
m_logFileLevel = sConfigMgr->GetIntDefault("LogFileLevel", LOGL_NORMAL);
|
m_logFileLevel = sConfigMgr->GetOption<int32>("LogFileLevel", LOGL_NORMAL);
|
||||||
m_dbLogLevel = sConfigMgr->GetIntDefault("DBLogLevel", LOGL_NORMAL);
|
m_dbLogLevel = sConfigMgr->GetOption<int32>("DBLogLevel", LOGL_NORMAL);
|
||||||
|
|
||||||
m_DebugLogMask = DebugLogFilters(sConfigMgr->GetIntDefault("DebugLogMask", LOG_FILTER_NONE));
|
m_DebugLogMask = DebugLogFilters(sConfigMgr->GetOption<int32>("DebugLogMask", LOG_FILTER_NONE));
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* Log::openLogFile(char const* configFileName, char const* configTimeStampFlag, char const* mode)
|
FILE* Log::openLogFile(char const* configFileName, char const* configTimeStampFlag, char const* mode)
|
||||||
{
|
{
|
||||||
std::string logfn = sConfigMgr->GetStringDefault(configFileName, "", false);
|
std::string logfn = sConfigMgr->GetOption<std::string>(configFileName, "", false);
|
||||||
if (logfn.empty())
|
if (logfn.empty())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (configTimeStampFlag && sConfigMgr->GetBoolDefault(configTimeStampFlag, false, false))
|
if (configTimeStampFlag && sConfigMgr->GetOption<bool>(configTimeStampFlag, false, false))
|
||||||
{
|
{
|
||||||
size_t dot_pos = logfn.find_last_of(".");
|
size_t dot_pos = logfn.find_last_of(".");
|
||||||
if (dot_pos != logfn.npos)
|
if (dot_pos != logfn.npos)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include "DetourCommon.h"
|
#include "DetourCommon.h"
|
||||||
#include "Geometry.h"
|
#include "Geometry.h"
|
||||||
|
|
||||||
|
|
||||||
float dtQueryFilterExt::getCost(const float* pa, const float* pb,
|
float dtQueryFilterExt::getCost(const float* pa, const float* pb,
|
||||||
const dtPolyRef /*prevRef*/, const dtMeshTile* /*prevTile*/, const dtPoly* /*prevPoly*/,
|
const dtPolyRef /*prevRef*/, const dtMeshTile* /*prevTile*/, const dtPoly* /*prevPoly*/,
|
||||||
const dtPolyRef /*curRef*/, const dtMeshTile* /*curTile*/, const dtPoly* curPoly,
|
const dtPolyRef /*curRef*/, const dtMeshTile* /*curTile*/, const dtPoly* curPoly,
|
||||||
|
|||||||
259
src/common/Utilities/StringConvert.h
Normal file
259
src/common/Utilities/StringConvert.h
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||||
|
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ACORE_STRINGCONVERT_H_
|
||||||
|
#define _ACORE_STRINGCONVERT_H_
|
||||||
|
|
||||||
|
#include "Define.h"
|
||||||
|
#include "Errors.h"
|
||||||
|
#include "Optional.h"
|
||||||
|
#include "Types.h"
|
||||||
|
#include "Util.h"
|
||||||
|
#include <charconv>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace acore::Impl::StringConvertImpl
|
||||||
|
{
|
||||||
|
template <typename T, typename = void> struct For
|
||||||
|
{
|
||||||
|
static_assert(acore::dependant_false_v<T>, "Unsupported type used for ToString or StringTo");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct For<T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, bool>>>
|
||||||
|
{
|
||||||
|
static Optional<T> FromString(std::string_view str, int base = 10)
|
||||||
|
{
|
||||||
|
if (base == 0)
|
||||||
|
{
|
||||||
|
if (StringEqualI(str.substr(0, 2), "0x"))
|
||||||
|
{
|
||||||
|
base = 16;
|
||||||
|
str.remove_prefix(2);
|
||||||
|
}
|
||||||
|
else if (StringEqualI(str.substr(0, 2), "0b"))
|
||||||
|
{
|
||||||
|
base = 2;
|
||||||
|
str.remove_prefix(2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
base = 10;
|
||||||
|
|
||||||
|
if (str.empty())
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* const start = str.data();
|
||||||
|
char const* const end = (start + str.length());
|
||||||
|
|
||||||
|
T val;
|
||||||
|
std::from_chars_result const res = std::from_chars(start, end, val, base);
|
||||||
|
if ((res.ptr == end) && (res.ec == std::errc()))
|
||||||
|
return val;
|
||||||
|
else
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ToString(T val)
|
||||||
|
{
|
||||||
|
std::string buf(20,'\0'); /* 2^64 is 20 decimal characters, -(2^63) is 20 including the sign */
|
||||||
|
char* const start = buf.data();
|
||||||
|
char* const end = (start + buf.length());
|
||||||
|
std::to_chars_result const res = std::to_chars(start, end, val);
|
||||||
|
ASSERT(res.ec == std::errc());
|
||||||
|
buf.resize(res.ptr - start);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef ACORE_NEED_CHARCONV_WORKAROUND
|
||||||
|
/*
|
||||||
|
If this is defined, std::from_chars will cause linkage errors for 64-bit types.
|
||||||
|
(This is a bug in clang-7.)
|
||||||
|
|
||||||
|
If the clang requirement is bumped to >= clang-8, remove this ifdef block and its
|
||||||
|
associated check in cmake/compiler/clang/settings.cmake
|
||||||
|
*/
|
||||||
|
template <>
|
||||||
|
struct For<uint64, void>
|
||||||
|
{
|
||||||
|
static Optional<uint64> FromString(std::string_view str, int base = 10)
|
||||||
|
{
|
||||||
|
if (str.empty())
|
||||||
|
return std::nullopt;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
size_t n;
|
||||||
|
uint64 val = std::stoull(std::string(str), &n, base);
|
||||||
|
if (n != str.length())
|
||||||
|
return std::nullopt;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
catch (...) { return std::nullopt; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ToString(uint64 val)
|
||||||
|
{
|
||||||
|
return std::to_string(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct For<int64, void>
|
||||||
|
{
|
||||||
|
static Optional<int64> FromString(std::string_view str, int base = 10)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (str.empty())
|
||||||
|
return std::nullopt;
|
||||||
|
size_t n;
|
||||||
|
int64 val = std::stoll(std::string(str), &n, base);
|
||||||
|
if (n != str.length())
|
||||||
|
return std::nullopt;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
catch (...) { return std::nullopt; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ToString(int64 val)
|
||||||
|
{
|
||||||
|
return std::to_string(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct For<bool, void>
|
||||||
|
{
|
||||||
|
static Optional<bool> FromString(std::string_view str, int strict = 0) /* this is int to match the signature for "proper" integral types */
|
||||||
|
{
|
||||||
|
if (strict)
|
||||||
|
{
|
||||||
|
if (str == "1")
|
||||||
|
return true;
|
||||||
|
if (str == "0")
|
||||||
|
return false;
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((str == "1") || StringEqualI(str, "y") || StringEqualI(str, "on") || StringEqualI(str, "yes") || StringEqualI(str, "true"))
|
||||||
|
return true;
|
||||||
|
if ((str == "0") || StringEqualI(str, "n") || StringEqualI(str, "off") || StringEqualI(str, "no") || StringEqualI(str, "false"))
|
||||||
|
return false;
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ToString(bool val)
|
||||||
|
{
|
||||||
|
return (val ? "1" : "0");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if AC_COMPILER == AC_COMPILER_MICROSOFT
|
||||||
|
template <typename T>
|
||||||
|
struct For<T, std::enable_if_t<std::is_floating_point_v<T>>>
|
||||||
|
{
|
||||||
|
static Optional<T> FromString(std::string_view str, std::chars_format fmt = std::chars_format())
|
||||||
|
{
|
||||||
|
if (str.empty())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
if (fmt == std::chars_format())
|
||||||
|
{
|
||||||
|
if (StringEqualI(str.substr(0, 2), "0x"))
|
||||||
|
{
|
||||||
|
fmt = std::chars_format::hex;
|
||||||
|
str.remove_prefix(2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fmt = std::chars_format::general;
|
||||||
|
|
||||||
|
if (str.empty())
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* const start = str.data();
|
||||||
|
char const* const end = (start + str.length());
|
||||||
|
|
||||||
|
T val;
|
||||||
|
std::from_chars_result const res = std::from_chars(start, end, val, fmt);
|
||||||
|
if ((res.ptr == end) && (res.ec == std::errc()))
|
||||||
|
return val;
|
||||||
|
else
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this allows generic converters for all numeric types (easier templating!)
|
||||||
|
static Optional<T> FromString(std::string_view str, int base)
|
||||||
|
{
|
||||||
|
if (base == 16)
|
||||||
|
return FromString(str, std::chars_format::hex);
|
||||||
|
else if (base == 10)
|
||||||
|
return FromString(str, std::chars_format::general);
|
||||||
|
else
|
||||||
|
return FromString(str, std::chars_format());
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ToString(T val)
|
||||||
|
{
|
||||||
|
return std::to_string(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
// @todo replace this once libc++ supports double args to from_chars
|
||||||
|
template <typename T>
|
||||||
|
struct For<T, std::enable_if_t<std::is_floating_point_v<T>>>
|
||||||
|
{
|
||||||
|
static Optional<T> FromString(std::string_view str, int base = 0)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (str.empty())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
if ((base == 10) && StringEqualI(str.substr(0, 2), "0x"))
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
std::string tmp;
|
||||||
|
if (base == 16)
|
||||||
|
tmp.append("0x");
|
||||||
|
tmp.append(str);
|
||||||
|
|
||||||
|
size_t n;
|
||||||
|
T val = static_cast<T>(std::stold(tmp, &n));
|
||||||
|
if (n != tmp.length())
|
||||||
|
return std::nullopt;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
catch (...) { return std::nullopt; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ToString(T val)
|
||||||
|
{
|
||||||
|
return std::to_string(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace acore
|
||||||
|
{
|
||||||
|
template <typename Result, typename... Params>
|
||||||
|
Optional<Result> StringTo(std::string_view str, Params&&... params)
|
||||||
|
{
|
||||||
|
return acore::Impl::StringConvertImpl::For<Result>::FromString(str, std::forward<Params>(params)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type, typename... Params>
|
||||||
|
std::string ToString(Type&& val, Params&&... params)
|
||||||
|
{
|
||||||
|
return acore::Impl::StringConvertImpl::For<std::decay_t<Type>>::ToString(std::forward<Type>(val), std::forward<Params>(params)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _ACORE_STRINGCONVERT_H_
|
||||||
40
src/common/Utilities/StringFormat.cpp
Normal file
40
src/common/Utilities/StringFormat.cpp
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||||
|
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StringFormat.h"
|
||||||
|
|
||||||
|
// Taken from https://stackoverflow.com/a/1798170
|
||||||
|
std::string acore::String::Trim(std::string const& str, std::string_view whitespace /*= " \t"*/)
|
||||||
|
{
|
||||||
|
const auto strBegin = str.find_first_not_of(whitespace);
|
||||||
|
if (strBegin == std::string::npos)
|
||||||
|
return ""; // no content
|
||||||
|
|
||||||
|
auto const strEnd = str.find_last_not_of(whitespace);
|
||||||
|
auto const strRange = strEnd - strBegin + 1;
|
||||||
|
|
||||||
|
return str.substr(strBegin, strRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string acore::String::Reduce(std::string const& str, std::string_view fill /*= " "*/, std::string_view whitespace /*= " \t"*/)
|
||||||
|
{
|
||||||
|
// trim first
|
||||||
|
auto result = Trim(str, whitespace);
|
||||||
|
|
||||||
|
// replace sub ranges
|
||||||
|
auto beginSpace = result.find_first_of(whitespace);
|
||||||
|
while (beginSpace != std::string::npos)
|
||||||
|
{
|
||||||
|
const auto endSpace = result.find_first_not_of(whitespace, beginSpace);
|
||||||
|
const auto range = endSpace - beginSpace;
|
||||||
|
|
||||||
|
result.replace(beginSpace, range, fill);
|
||||||
|
|
||||||
|
const auto newStart = beginSpace + fill.length();
|
||||||
|
beginSpace = result.find_first_of(whitespace, newStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||||
|
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __STRING_FORMAT_H__
|
#ifndef _STRING_FORMAT_H_
|
||||||
#define __STRING_FORMAT_H__
|
#define _STRING_FORMAT_H_
|
||||||
|
|
||||||
#include "fmt/printf.h"
|
#include <fmt/printf.h>
|
||||||
|
|
||||||
namespace acore
|
namespace acore
|
||||||
{
|
{
|
||||||
@@ -39,4 +40,10 @@ namespace acore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace acore::String
|
||||||
|
{
|
||||||
|
std::string Trim(std::string const& str, std::string_view whitespace = " \t");
|
||||||
|
std::string Reduce(std::string const& str, std::string_view fill = " ", std::string_view whitespace = " \t");
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
63
src/common/Utilities/Types.h
Normal file
63
src/common/Utilities/Types.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||||
|
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TYPES_H_
|
||||||
|
#define _TYPES_H_
|
||||||
|
|
||||||
|
#include "advstd.h"
|
||||||
|
|
||||||
|
namespace acore
|
||||||
|
{
|
||||||
|
// end "iterator" tag for find_type_if
|
||||||
|
struct find_type_end;
|
||||||
|
|
||||||
|
template<template<typename...> typename Check, typename... Ts>
|
||||||
|
struct find_type_if;
|
||||||
|
|
||||||
|
template<template<typename...> typename Check>
|
||||||
|
struct find_type_if<Check>
|
||||||
|
{
|
||||||
|
using type = find_type_end;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<typename...> typename Check, typename T1, typename... Ts>
|
||||||
|
struct find_type_if<Check, T1, Ts...> : std::conditional_t<Check<T1>::value, advstd::type_identity<T1>, find_type_if<Check, Ts...>>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Utility to find a type matching predicate (Check) in a given type list (Ts)
|
||||||
|
Evaluates to first type matching predicate or find_type_end
|
||||||
|
Check must be a type that contains static bool ::value, _v aliases don't work
|
||||||
|
|
||||||
|
template<typename... Ts>
|
||||||
|
struct Example
|
||||||
|
{
|
||||||
|
using TupleArg = acore::find_type_if_t<acore::is_tuple, Ts...>;
|
||||||
|
|
||||||
|
bool HasTuple()
|
||||||
|
{
|
||||||
|
return !std::is_same_v<TupleArg, acore::find_type_end>;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Example<int, std::string, std::tuple<int, int, int>, char> example;
|
||||||
|
example.HasTuple() == true; // TupleArg is std::tuple<int, int, int>
|
||||||
|
|
||||||
|
Example<int, std::string, char> example2;
|
||||||
|
example2.HasTuple() == false; // TupleArg is acore::find_type_end
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<template<typename...> typename Check, typename... Ts>
|
||||||
|
using find_type_if_t = typename find_type_if<Check, Ts...>::type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct dependant_false { static constexpr bool value = false; };
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr bool dependant_false_v = dependant_false<T>::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _TYPES_H_
|
||||||
@@ -682,15 +682,13 @@ void HexStrToByteArray(std::string const& str, uint8* out, bool reverse /*= fals
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StringToBool(std::string const& str)
|
|
||||||
{
|
|
||||||
std::string lowerStr = str;
|
|
||||||
std::transform(str.begin(), str.end(), lowerStr.begin(), ::tolower);
|
|
||||||
return lowerStr == "1" || lowerStr == "true" || lowerStr == "yes";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StringContainsStringI(std::string const& haystack, std::string const& needle)
|
bool StringContainsStringI(std::string const& haystack, std::string const& needle)
|
||||||
{
|
{
|
||||||
return haystack.end() !=
|
return haystack.end() !=
|
||||||
std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), [](char c1, char c2) { return std::toupper(c1) == std::toupper(c2); });
|
std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), [](char c1, char c2) { return std::toupper(c1) == std::toupper(c2); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StringEqualI(std::string_view a, std::string_view b)
|
||||||
|
{
|
||||||
|
return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](char c1, char c2) { return std::tolower(c1) == std::tolower(c2); });
|
||||||
|
}
|
||||||
|
|||||||
@@ -343,9 +343,10 @@ std::string GetAddressString(ACE_INET_Addr const& addr);
|
|||||||
uint32 CreatePIDFile(const std::string& filename);
|
uint32 CreatePIDFile(const std::string& filename);
|
||||||
uint32 GetPID();
|
uint32 GetPID();
|
||||||
|
|
||||||
|
bool StringEqualI(std::string_view str1, std::string_view str2);
|
||||||
|
|
||||||
std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
|
std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
|
||||||
void HexStrToByteArray(std::string const& str, uint8* out, bool reverse = false);
|
void HexStrToByteArray(std::string const& str, uint8* out, bool reverse = false);
|
||||||
bool StringToBool(std::string const& str);
|
|
||||||
|
|
||||||
bool StringContainsStringI(std::string const& haystack, std::string const& needle);
|
bool StringContainsStringI(std::string const& haystack, std::string const& needle);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
31
src/common/Utilities/advstd.h
Normal file
31
src/common/Utilities/advstd.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||||
|
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ACORE_ADV_STD_H_
|
||||||
|
#define _ACORE_ADV_STD_H_
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
// this namespace holds implementations of upcoming stdlib features that our c++ version doesn't have yet
|
||||||
|
namespace advstd
|
||||||
|
{
|
||||||
|
// C++20 advstd::remove_cvref_t
|
||||||
|
template <class T>
|
||||||
|
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||||
|
|
||||||
|
// C++20 std::type_identity
|
||||||
|
template <typename T>
|
||||||
|
struct type_identity
|
||||||
|
{
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
// C++20 std::type_identity_t
|
||||||
|
template <typename T>
|
||||||
|
using type_identity_t = typename type_identity<T>::type;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _ADV_STD_H_
|
||||||
@@ -36,11 +36,6 @@ add_executable(authserver
|
|||||||
|
|
||||||
add_dependencies(authserver revision.h)
|
add_dependencies(authserver revision.h)
|
||||||
|
|
||||||
if(NOT WIN32)
|
|
||||||
set_target_properties(authserver PROPERTIES
|
|
||||||
COMPILE_DEFINITIONS _ACORE_REALM_CONFIG="${CONF_DIR}/authserver.conf")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_link_libraries(authserver
|
target_link_libraries(authserver
|
||||||
PUBLIC
|
PUBLIC
|
||||||
shared)
|
shared)
|
||||||
@@ -62,28 +57,15 @@ set_target_properties(authserver
|
|||||||
FOLDER
|
FOLDER
|
||||||
"server")
|
"server")
|
||||||
|
|
||||||
if( WIN32 )
|
# Install config
|
||||||
if ( MSVC )
|
CopyDefaultConfig(authserver)
|
||||||
add_custom_command(TARGET authserver
|
|
||||||
POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/authserver.conf.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
|
|
||||||
)
|
|
||||||
elseif ( MINGW )
|
|
||||||
add_custom_command(TARGET authserver
|
|
||||||
POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/authserver.conf.dist ${CMAKE_BINARY_DIR}/bin/
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if( UNIX )
|
if ( UNIX )
|
||||||
install(TARGETS authserver DESTINATION bin)
|
install(TARGETS authserver DESTINATION bin)
|
||||||
elseif( WIN32 )
|
elseif ( WIN32 )
|
||||||
install(TARGETS authserver DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
install(TARGETS authserver DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
install(FILES authserver.conf.dist DESTINATION ${CONF_DIR})
|
|
||||||
|
|
||||||
# Generate precompiled header
|
# Generate precompiled header
|
||||||
if (USE_COREPCH)
|
if (USE_COREPCH)
|
||||||
add_cxx_pch(authserver ${PRIVATE_PCH_HEADER})
|
add_cxx_pch(authserver ${PRIVATE_PCH_HEADER})
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ void usage(const char* prog)
|
|||||||
extern int main(int argc, char** argv)
|
extern int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
// Command line parsing to get the configuration file name
|
// Command line parsing to get the configuration file name
|
||||||
char const* configFile = _ACORE_REALM_CONFIG;
|
std::string configFile = sConfigMgr->GetConfigPath() + std::string(_ACORE_REALM_CONFIG);
|
||||||
int count = 1;
|
int count = 1;
|
||||||
while (count < argc)
|
while (count < argc)
|
||||||
{
|
{
|
||||||
@@ -92,9 +92,10 @@ extern int main(int argc, char** argv)
|
|||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
sConfigMgr->SetConfigList(std::string(configFile));
|
// Add file and args in config
|
||||||
|
sConfigMgr->Configure(configFile, std::vector<std::string>(argv, argv + argc));
|
||||||
|
|
||||||
if (!sConfigMgr->LoadAppConfigs("authserver"))
|
if (!sConfigMgr->LoadAppConfigs())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
sLog->outString("%s (authserver)", GitRevision::GetFullVersion());
|
sLog->outString("%s (authserver)", GitRevision::GetFullVersion());
|
||||||
@@ -115,7 +116,7 @@ extern int main(int argc, char** argv)
|
|||||||
|
|
||||||
sLog->outString(" AzerothCore 3.3.5a - www.azerothcore.org\n");
|
sLog->outString(" AzerothCore 3.3.5a - www.azerothcore.org\n");
|
||||||
|
|
||||||
sLog->outString("Using configuration file %s.", configFile);
|
sLog->outString("Using configuration file %s.", configFile.c_str());
|
||||||
|
|
||||||
sLog->outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
|
sLog->outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
|
||||||
|
|
||||||
@@ -128,7 +129,7 @@ extern int main(int argc, char** argv)
|
|||||||
sLog->outBasic("Max allowed open files is %d", ACE::max_handles());
|
sLog->outBasic("Max allowed open files is %d", ACE::max_handles());
|
||||||
|
|
||||||
// authserver PID file creation
|
// authserver PID file creation
|
||||||
std::string pidFile = sConfigMgr->GetStringDefault("PidFile", "");
|
std::string pidFile = sConfigMgr->GetOption<std::string>("PidFile", "");
|
||||||
if (!pidFile.empty())
|
if (!pidFile.empty())
|
||||||
{
|
{
|
||||||
if (uint32 pid = CreatePIDFile(pidFile))
|
if (uint32 pid = CreatePIDFile(pidFile))
|
||||||
@@ -149,7 +150,7 @@ extern int main(int argc, char** argv)
|
|||||||
sLog->SetRealmID(0); // ensure we've set realm to 0 (authserver realmid)
|
sLog->SetRealmID(0); // ensure we've set realm to 0 (authserver realmid)
|
||||||
|
|
||||||
// Get the list of realms for the server
|
// Get the list of realms for the server
|
||||||
sRealmList->Initialize(sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 20));
|
sRealmList->Initialize(sConfigMgr->GetOption<int32>("RealmsStateUpdateDelay", 20));
|
||||||
if (sRealmList->size() == 0)
|
if (sRealmList->size() == 0)
|
||||||
{
|
{
|
||||||
sLog->outError("No valid realms specified.");
|
sLog->outError("No valid realms specified.");
|
||||||
@@ -159,14 +160,14 @@ extern int main(int argc, char** argv)
|
|||||||
// Launch the listening network socket
|
// Launch the listening network socket
|
||||||
RealmAcceptor acceptor;
|
RealmAcceptor acceptor;
|
||||||
|
|
||||||
int32 rmport = sConfigMgr->GetIntDefault("RealmServerPort", 3724);
|
int32 rmport = sConfigMgr->GetOption<int32>("RealmServerPort", 3724);
|
||||||
if (rmport < 0 || rmport > 0xFFFF)
|
if (rmport < 0 || rmport > 0xFFFF)
|
||||||
{
|
{
|
||||||
sLog->outError("The specified RealmServerPort (%d) is out of the allowed range (1-65535)", rmport);
|
sLog->outError("The specified RealmServerPort (%d) is out of the allowed range (1-65535)", rmport);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string bind_ip = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
|
std::string bind_ip = sConfigMgr->GetOption<std::string>("BindIP", "0.0.0.0");
|
||||||
|
|
||||||
ACE_INET_Addr bind_addr(uint16(rmport), bind_ip.c_str());
|
ACE_INET_Addr bind_addr(uint16(rmport), bind_ip.c_str());
|
||||||
|
|
||||||
@@ -189,8 +190,8 @@ extern int main(int argc, char** argv)
|
|||||||
#if defined(_WIN32) || defined(__linux__)
|
#if defined(_WIN32) || defined(__linux__)
|
||||||
|
|
||||||
///- Handle affinity for multiple processors and process priority
|
///- Handle affinity for multiple processors and process priority
|
||||||
uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0);
|
uint32 affinity = sConfigMgr->GetOption<int32>("UseProcessors", 0);
|
||||||
bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false);
|
bool highPriority = sConfigMgr->GetOption<bool>("ProcessPriority", false);
|
||||||
|
|
||||||
#ifdef _WIN32 // Windows
|
#ifdef _WIN32 // Windows
|
||||||
|
|
||||||
@@ -255,11 +256,11 @@ extern int main(int argc, char** argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// maximum counter for next ping
|
// maximum counter for next ping
|
||||||
uint32 numLoops = (sConfigMgr->GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000));
|
uint32 numLoops = (sConfigMgr->GetOption<int32>("MaxPingTime", 30) * (MINUTE * 1000000 / 100000));
|
||||||
uint32 loopCounter = 0;
|
uint32 loopCounter = 0;
|
||||||
|
|
||||||
// possibly enable db logging; avoid massive startup spam by doing it here.
|
// possibly enable db logging; avoid massive startup spam by doing it here.
|
||||||
if (sConfigMgr->GetBoolDefault("EnableLogDB", false))
|
if (sConfigMgr->GetOption<bool>("EnableLogDB", false))
|
||||||
{
|
{
|
||||||
sLog->outString("Enabling database logging...");
|
sLog->outString("Enabling database logging...");
|
||||||
sLog->SetLogDB(true);
|
sLog->SetLogDB(true);
|
||||||
@@ -294,21 +295,21 @@ bool StartDB()
|
|||||||
{
|
{
|
||||||
MySQL::Library_Init();
|
MySQL::Library_Init();
|
||||||
|
|
||||||
std::string dbstring = sConfigMgr->GetStringDefault("LoginDatabaseInfo", "");
|
std::string dbstring = sConfigMgr->GetOption<std::string>("LoginDatabaseInfo", "");
|
||||||
if (dbstring.empty())
|
if (dbstring.empty())
|
||||||
{
|
{
|
||||||
sLog->outError("Database not specified");
|
sLog->outError("Database not specified");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 worker_threads = sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1);
|
int32 worker_threads = sConfigMgr->GetOption<int32>("LoginDatabase.WorkerThreads", 1);
|
||||||
if (worker_threads < 1 || worker_threads > 32)
|
if (worker_threads < 1 || worker_threads > 32)
|
||||||
{
|
{
|
||||||
sLog->outError("Improper value specified for LoginDatabase.WorkerThreads, defaulting to 1.");
|
sLog->outError("Improper value specified for LoginDatabase.WorkerThreads, defaulting to 1.");
|
||||||
worker_threads = 1;
|
worker_threads = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 synch_threads = sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1);
|
int32 synch_threads = sConfigMgr->GetOption<int32>("LoginDatabase.SynchThreads", 1);
|
||||||
if (synch_threads < 1 || synch_threads > 32)
|
if (synch_threads < 1 || synch_threads > 32)
|
||||||
{
|
{
|
||||||
sLog->outError("Improper value specified for LoginDatabase.SynchThreads, defaulting to 1.");
|
sLog->outError("Improper value specified for LoginDatabase.SynchThreads, defaulting to 1.");
|
||||||
|
|||||||
@@ -776,10 +776,10 @@ bool AuthSocket::_HandleLogonProof()
|
|||||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "'%s:%d' [AuthChallenge] account %s tried to login with invalid password!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
|
sLog->outDebug(LOG_FILTER_NETWORKIO, "'%s:%d' [AuthChallenge] account %s tried to login with invalid password!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32 MaxWrongPassCount = sConfigMgr->GetIntDefault("WrongPass.MaxCount", 0);
|
uint32 MaxWrongPassCount = sConfigMgr->GetOption<int32>("WrongPass.MaxCount", 0);
|
||||||
|
|
||||||
// We can not include the failed account login hook. However, this is a workaround to still log this.
|
// We can not include the failed account login hook. However, this is a workaround to still log this.
|
||||||
if (sConfigMgr->GetBoolDefault("WrongPass.Logging", false))
|
if (sConfigMgr->GetOption<bool>("WrongPass.Logging", false))
|
||||||
{
|
{
|
||||||
PreparedStatement* logstmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_FALP_IP_LOGGING);
|
PreparedStatement* logstmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_FALP_IP_LOGGING);
|
||||||
logstmt->setString(0, _login);
|
logstmt->setString(0, _login);
|
||||||
@@ -805,8 +805,8 @@ bool AuthSocket::_HandleLogonProof()
|
|||||||
|
|
||||||
if (failed_logins >= MaxWrongPassCount)
|
if (failed_logins >= MaxWrongPassCount)
|
||||||
{
|
{
|
||||||
uint32 WrongPassBanTime = sConfigMgr->GetIntDefault("WrongPass.BanTime", 600);
|
uint32 WrongPassBanTime = sConfigMgr->GetOption<int32>("WrongPass.BanTime", 600);
|
||||||
bool WrongPassBanType = sConfigMgr->GetBoolDefault("WrongPass.BanType", false);
|
bool WrongPassBanType = sConfigMgr->GetOption<bool>("WrongPass.BanType", false);
|
||||||
|
|
||||||
if (WrongPassBanType)
|
if (WrongPassBanType)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -336,7 +336,6 @@ void PetAI::UpdateAI(uint32 diff)
|
|||||||
delete itr->second;
|
delete itr->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update speed as needed to prevent dropping too far behind and despawning
|
// Update speed as needed to prevent dropping too far behind and despawning
|
||||||
me->UpdateSpeed(MOVE_RUN, true);
|
me->UpdateSpeed(MOVE_RUN, true);
|
||||||
me->UpdateSpeed(MOVE_WALK, true);
|
me->UpdateSpeed(MOVE_WALK, true);
|
||||||
|
|||||||
@@ -1839,7 +1839,6 @@ void Creature::LoadSpellTemplateImmunity()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo)
|
bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo)
|
||||||
{
|
{
|
||||||
if (!spellInfo)
|
if (!spellInfo)
|
||||||
|
|||||||
@@ -897,7 +897,6 @@ bool Object::PrintIndexError(uint32 index, bool set) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Position::operator==(Position const& a)
|
bool Position::operator==(Position const& a)
|
||||||
{
|
{
|
||||||
return (G3D::fuzzyEq(a.m_positionX, m_positionX) &&
|
return (G3D::fuzzyEq(a.m_positionX, m_positionX) &&
|
||||||
|
|||||||
@@ -2140,7 +2140,7 @@ bool Guild::Validate()
|
|||||||
_SetLeaderGUID(pLeader);
|
_SetLeaderGUID(pLeader);
|
||||||
|
|
||||||
// Check config if multiple guildmasters are allowed
|
// Check config if multiple guildmasters are allowed
|
||||||
if (!sConfigMgr->GetBoolDefault("Guild.AllowMultipleGuildMaster", 0))
|
if (!sConfigMgr->GetOption<bool>("Guild.AllowMultipleGuildMaster", 0))
|
||||||
for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||||
if (itr->second->GetRankId() == GR_GUILDMASTER && !itr->second->IsSamePlayer(m_leaderGuid))
|
if (itr->second->GetRankId() == GR_GUILDMASTER && !itr->second->IsSamePlayer(m_leaderGuid))
|
||||||
itr->second->ChangeRank(GR_OFFICER);
|
itr->second->ChangeRank(GR_OFFICER);
|
||||||
|
|||||||
@@ -2303,7 +2303,6 @@ bool Map::HasEnoughWater(WorldObject const* searcher, LiquidData liquidData) con
|
|||||||
return liquidData.level > INVALID_HEIGHT && liquidData.level > liquidData.depth_level && liquidData.level - liquidData.depth_level >= minHeightInWater;
|
return liquidData.level > INVALID_HEIGHT && liquidData.level > liquidData.depth_level && liquidData.level - liquidData.depth_level >= minHeightInWater;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char const* Map::GetMapName() const
|
char const* Map::GetMapName() const
|
||||||
{
|
{
|
||||||
return i_mapEntry ? i_mapEntry->name[sWorld->GetDefaultDbcLocale()] : "UNNAMEDMAP\x0";
|
return i_mapEntry ? i_mapEntry->name[sWorld->GetDefaultDbcLocale()] : "UNNAMEDMAP\x0";
|
||||||
|
|||||||
@@ -1131,7 +1131,6 @@ bool PathGenerator::IsSwimmableSegment(float const* v1, float const* v2, bool ch
|
|||||||
return IsSwimmableSegment(v1[2], v1[0], v1[1], v2[2], v2[0], v2[1], checkSwim);
|
return IsSwimmableSegment(v1[2], v1[0], v1[1], v2[2], v2[0], v2[1], checkSwim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief predict if a certain segment is underwater and the unit can swim
|
* @brief predict if a certain segment is underwater and the unit can swim
|
||||||
* Must only be used for very short segments since this check doesn't work on
|
* Must only be used for very short segments since this check doesn't work on
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ bool ChaseMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
|
|||||||
(owner->CanFly())
|
(owner->CanFly())
|
||||||
; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to
|
; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to
|
||||||
|
|
||||||
|
|
||||||
Unit* target = i_target.getTarget();
|
Unit* target = i_target.getTarget();
|
||||||
|
|
||||||
bool const mutualChase = IsMutualChase(owner, target);
|
bool const mutualChase = IsMutualChase(owner, target);
|
||||||
@@ -272,7 +271,6 @@ bool FollowMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
|
|||||||
(i_target->GetTypeId() == TYPEID_PLAYER && i_target->ToPlayer()->IsGameMaster()) // for .npc follow
|
(i_target->GetTypeId() == TYPEID_PLAYER && i_target->ToPlayer()->IsGameMaster()) // for .npc follow
|
||||||
; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to
|
; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to
|
||||||
|
|
||||||
|
|
||||||
i_recheckDistance.Update(time_diff);
|
i_recheckDistance.Update(time_diff);
|
||||||
if (i_recheckDistance.Passed())
|
if (i_recheckDistance.Passed())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ protected:
|
|||||||
FollowerReference i_target;
|
FollowerReference i_target;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class ChaseMovementGenerator : public MovementGeneratorMedium<T, ChaseMovementGenerator<T>>, public TargetedMovementGeneratorBase
|
class ChaseMovementGenerator : public MovementGeneratorMedium<T, ChaseMovementGenerator<T>>, public TargetedMovementGeneratorBase
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ PacketLog* PacketLog::instance()
|
|||||||
|
|
||||||
void PacketLog::Initialize()
|
void PacketLog::Initialize()
|
||||||
{
|
{
|
||||||
std::string logsDir = sConfigMgr->GetStringDefault("LogsDir", "");
|
std::string logsDir = sConfigMgr->GetOption<std::string>("LogsDir", "");
|
||||||
|
|
||||||
if (!logsDir.empty())
|
if (!logsDir.empty())
|
||||||
if ((logsDir.at(logsDir.length() - 1) != '/') && (logsDir.at(logsDir.length() - 1) != '\\'))
|
if ((logsDir.at(logsDir.length() - 1) != '/') && (logsDir.at(logsDir.length() - 1) != '\\'))
|
||||||
logsDir.push_back('/');
|
logsDir.push_back('/');
|
||||||
|
|
||||||
std::string logname = sConfigMgr->GetStringDefault("PacketLogFile", "");
|
std::string logname = sConfigMgr->GetOption<std::string>("PacketLogFile", "");
|
||||||
if (!logname.empty())
|
if (!logname.empty())
|
||||||
_file = fopen((logsDir + logname).c_str(), "wb");
|
_file = fopen((logsDir + logname).c_str(), "wb");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,9 +222,9 @@ WorldSocketMgr* WorldSocketMgr::instance()
|
|||||||
int
|
int
|
||||||
WorldSocketMgr::StartReactiveIO (uint16 port, const char* address)
|
WorldSocketMgr::StartReactiveIO (uint16 port, const char* address)
|
||||||
{
|
{
|
||||||
m_UseNoDelay = sConfigMgr->GetBoolDefault ("Network.TcpNodelay", true);
|
m_UseNoDelay = sConfigMgr->GetOption<bool> ("Network.TcpNodelay", true);
|
||||||
|
|
||||||
int num_threads = sConfigMgr->GetIntDefault ("Network.Threads", 1);
|
int num_threads = sConfigMgr->GetOption<int32> ("Network.Threads", 1);
|
||||||
|
|
||||||
if (num_threads <= 0)
|
if (num_threads <= 0)
|
||||||
{
|
{
|
||||||
@@ -239,9 +239,9 @@ WorldSocketMgr::StartReactiveIO (uint16 port, const char* address)
|
|||||||
sLog->outBasic ("Max allowed socket connections %d", ACE::max_handles());
|
sLog->outBasic ("Max allowed socket connections %d", ACE::max_handles());
|
||||||
|
|
||||||
// -1 means use default
|
// -1 means use default
|
||||||
m_SockOutKBuff = sConfigMgr->GetIntDefault ("Network.OutKBuff", -1);
|
m_SockOutKBuff = sConfigMgr->GetOption<int32> ("Network.OutKBuff", -1);
|
||||||
|
|
||||||
m_SockOutUBuff = sConfigMgr->GetIntDefault ("Network.OutUBuff", 65536);
|
m_SockOutUBuff = sConfigMgr->GetOption<int32> ("Network.OutUBuff", 65536);
|
||||||
|
|
||||||
if (m_SockOutUBuff <= 0)
|
if (m_SockOutUBuff <= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -238,4 +238,3 @@ WardenCheckResult const* WardenCheckMgr::GetWardenResultById(uint16 Id)
|
|||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -32,11 +32,6 @@ GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
|
|||||||
add_executable(worldserver
|
add_executable(worldserver
|
||||||
${PRIVATE_SOURCES})
|
${PRIVATE_SOURCES})
|
||||||
|
|
||||||
if(NOT WIN32)
|
|
||||||
set_target_properties(worldserver PROPERTIES
|
|
||||||
COMPILE_DEFINITIONS _ACORE_CORE_CONFIG="${CONF_DIR}/worldserver.conf")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_dependencies(worldserver revision.h)
|
add_dependencies(worldserver revision.h)
|
||||||
|
|
||||||
if(UNIX AND NOT NOJEM)
|
if(UNIX AND NOT NOJEM)
|
||||||
@@ -73,19 +68,9 @@ set_target_properties(worldserver
|
|||||||
FOLDER
|
FOLDER
|
||||||
"server")
|
"server")
|
||||||
|
|
||||||
if( WIN32 )
|
# Install config
|
||||||
if ( MSVC )
|
CopyDefaultConfig(worldserver)
|
||||||
add_custom_command(TARGET worldserver
|
CollectModulesConfig()
|
||||||
POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/worldserver.conf.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
|
|
||||||
)
|
|
||||||
elseif ( MINGW )
|
|
||||||
add_custom_command(TARGET worldserver
|
|
||||||
POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/worldserver.conf.dist ${CMAKE_BINARY_DIR}/bin/
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if( UNIX )
|
if( UNIX )
|
||||||
install(TARGETS worldserver DESTINATION bin)
|
install(TARGETS worldserver DESTINATION bin)
|
||||||
@@ -93,38 +78,9 @@ elseif( WIN32 )
|
|||||||
install(TARGETS worldserver DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
install(TARGETS worldserver DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
install(FILES worldserver.conf.dist DESTINATION ${CONF_DIR})
|
|
||||||
|
|
||||||
# Generate precompiled header
|
# Generate precompiled header
|
||||||
if( USE_COREPCH )
|
if( USE_COREPCH )
|
||||||
add_cxx_pch(worldserver ${PRIVATE_PCH_HEADER})
|
add_cxx_pch(worldserver ${PRIVATE_PCH_HEADER})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# handle config file
|
|
||||||
CU_GET_GLOBAL("MODULE_CONFIG_FILE_LIST")
|
|
||||||
FOREACH(configFile ${MODULE_CONFIG_FILE_LIST})
|
|
||||||
if( WIN32 )
|
|
||||||
if ( MSVC )
|
|
||||||
add_custom_command(TARGET worldserver
|
|
||||||
POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${configFile}" ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
|
|
||||||
)
|
|
||||||
elseif ( MINGW )
|
|
||||||
add_custom_command(TARGET worldserver
|
|
||||||
POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${configFile}" ${CMAKE_BINARY_DIR}/bin/
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
install(FILES "${configFile}" DESTINATION ${CONF_DIR})
|
|
||||||
ENDFOREACH()
|
|
||||||
|
|
||||||
CU_GET_GLOBAL("MODULE_CONFIG_FILE_LIST")
|
|
||||||
FOREACH(configFile ${MODULE_CONFIG_FILE_LIST})
|
|
||||||
get_filename_component(file_name ${configFile} NAME_WE)
|
|
||||||
set(CONFIG_LIST ${CONFIG_LIST}${file_name},)
|
|
||||||
ENDFOREACH()
|
|
||||||
add_definitions(-DCONFIG_FILE_LIST=$<1:"${CONFIG_LIST}">)
|
|
||||||
# end handle config file
|
|
||||||
|
|
||||||
CU_RUN_HOOK("AFTER_WORLDSERVER_CMAKE")
|
CU_RUN_HOOK("AFTER_WORLDSERVER_CMAKE")
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ void CliRunnable::run()
|
|||||||
rl_event_hook = cli_hook_func;
|
rl_event_hook = cli_hook_func;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sConfigMgr->GetBoolDefault("BeepAtStart", true))
|
if (sConfigMgr->GetOption<bool>("BeepAtStart", true))
|
||||||
printf("\a"); // \a = Alert
|
printf("\a"); // \a = Alert
|
||||||
|
|
||||||
// print this here the first time
|
// print this here the first time
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void usage(const char* prog)
|
|||||||
extern int main(int argc, char** argv)
|
extern int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
///- Command line parsing to get the configuration file name
|
///- Command line parsing to get the configuration file name
|
||||||
char const* configFile = _ACORE_CORE_CONFIG;
|
std::string configFile = sConfigMgr->GetConfigPath() + std::string(_ACORE_CORE_CONFIG);
|
||||||
int c = 1;
|
int c = 1;
|
||||||
while (c < argc)
|
while (c < argc)
|
||||||
{
|
{
|
||||||
@@ -116,12 +116,13 @@ extern int main(int argc, char** argv)
|
|||||||
++c;
|
++c;
|
||||||
}
|
}
|
||||||
|
|
||||||
sConfigMgr->SetConfigList(std::string(configFile), std::string(CONFIG_FILE_LIST));
|
// Add file and args in config
|
||||||
|
sConfigMgr->Configure(configFile, std::vector<std::string>(argv, argv + argc), CONFIG_FILE_LIST);
|
||||||
|
|
||||||
if (!sConfigMgr->LoadAppConfigs())
|
if (!sConfigMgr->LoadAppConfigs())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
sLog->outString("Using configuration file %s.", configFile);
|
sLog->outString("Using configuration file %s.", configFile.c_str());
|
||||||
sLog->outString("Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
|
sLog->outString("Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
|
||||||
sLog->outString("Using ACE version: %s", ACE_VERSION);
|
sLog->outString("Using ACE version: %s", ACE_VERSION);
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ int Master::Run()
|
|||||||
sLog->outString(" AzerothCore 3.3.5a - www.azerothcore.org\n");
|
sLog->outString(" AzerothCore 3.3.5a - www.azerothcore.org\n");
|
||||||
|
|
||||||
/// worldserver PID file creation
|
/// worldserver PID file creation
|
||||||
std::string pidFile = sConfigMgr->GetStringDefault("PidFile", "");
|
std::string pidFile = sConfigMgr->GetOption<std::string>("PidFile", "");
|
||||||
if (!pidFile.empty())
|
if (!pidFile.empty())
|
||||||
{
|
{
|
||||||
if (uint32 pid = CreatePIDFile(pidFile))
|
if (uint32 pid = CreatePIDFile(pidFile))
|
||||||
@@ -185,9 +185,9 @@ int Master::Run()
|
|||||||
acore::Thread* cliThread = nullptr;
|
acore::Thread* cliThread = nullptr;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (sConfigMgr->GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/)
|
if (sConfigMgr->GetOption<bool>("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/)
|
||||||
#else
|
#else
|
||||||
if (sConfigMgr->GetBoolDefault("Console.Enable", true))
|
if (sConfigMgr->GetOption<bool>("Console.Enable", true))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
///- Launch CliRunnable thread
|
///- Launch CliRunnable thread
|
||||||
@@ -203,8 +203,8 @@ int Master::Run()
|
|||||||
#if defined(_WIN32) || defined(__linux__)
|
#if defined(_WIN32) || defined(__linux__)
|
||||||
|
|
||||||
///- Handle affinity for multiple processors and process priority
|
///- Handle affinity for multiple processors and process priority
|
||||||
uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0);
|
uint32 affinity = sConfigMgr->GetOption<int32>("UseProcessors", 0);
|
||||||
bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false);
|
bool highPriority = sConfigMgr->GetOption<bool>("ProcessPriority", false);
|
||||||
|
|
||||||
#ifdef _WIN32 // Windows
|
#ifdef _WIN32 // Windows
|
||||||
|
|
||||||
@@ -270,16 +270,16 @@ int Master::Run()
|
|||||||
|
|
||||||
// Start soap serving thread
|
// Start soap serving thread
|
||||||
acore::Thread* soapThread = nullptr;
|
acore::Thread* soapThread = nullptr;
|
||||||
if (sConfigMgr->GetBoolDefault("SOAP.Enabled", false))
|
if (sConfigMgr->GetOption<bool>("SOAP.Enabled", false))
|
||||||
{
|
{
|
||||||
ACSoapRunnable* runnable = new ACSoapRunnable();
|
ACSoapRunnable* runnable = new ACSoapRunnable();
|
||||||
runnable->SetListenArguments(sConfigMgr->GetStringDefault("SOAP.IP", "127.0.0.1"), uint16(sConfigMgr->GetIntDefault("SOAP.Port", 7878)));
|
runnable->SetListenArguments(sConfigMgr->GetOption<std::string>("SOAP.IP", "127.0.0.1"), uint16(sConfigMgr->GetOption<int32>("SOAP.Port", 7878)));
|
||||||
soapThread = new acore::Thread(runnable);
|
soapThread = new acore::Thread(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start up freeze catcher thread
|
// Start up freeze catcher thread
|
||||||
acore::Thread* freezeThread = nullptr;
|
acore::Thread* freezeThread = nullptr;
|
||||||
if (uint32 freezeDelay = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0))
|
if (uint32 freezeDelay = sConfigMgr->GetOption<int32>("MaxCoreStuckTime", 0))
|
||||||
{
|
{
|
||||||
FreezeDetectorRunnable* runnable = new FreezeDetectorRunnable(freezeDelay * 1000);
|
FreezeDetectorRunnable* runnable = new FreezeDetectorRunnable(freezeDelay * 1000);
|
||||||
freezeThread = new acore::Thread(runnable);
|
freezeThread = new acore::Thread(runnable);
|
||||||
@@ -288,7 +288,7 @@ int Master::Run()
|
|||||||
|
|
||||||
///- Launch the world listener socket
|
///- Launch the world listener socket
|
||||||
uint16 worldPort = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD));
|
uint16 worldPort = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD));
|
||||||
std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
|
std::string bindIp = sConfigMgr->GetOption<std::string>("BindIP", "0.0.0.0");
|
||||||
if (sWorldSocketMgr->StartNetwork(worldPort, bindIp.c_str()) == -1)
|
if (sWorldSocketMgr->StartNetwork(worldPort, bindIp.c_str()) == -1)
|
||||||
{
|
{
|
||||||
sLog->outError("Failed to start network");
|
sLog->outError("Failed to start network");
|
||||||
@@ -398,14 +398,14 @@ bool Master::_StartDB()
|
|||||||
std::string dbstring;
|
std::string dbstring;
|
||||||
uint8 async_threads, synch_threads;
|
uint8 async_threads, synch_threads;
|
||||||
|
|
||||||
dbstring = sConfigMgr->GetStringDefault("WorldDatabaseInfo", "");
|
dbstring = sConfigMgr->GetOption<std::string>("WorldDatabaseInfo", "");
|
||||||
if (dbstring.empty())
|
if (dbstring.empty())
|
||||||
{
|
{
|
||||||
sLog->outError("World database not specified in configuration file");
|
sLog->outError("World database not specified in configuration file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async_threads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.WorkerThreads", 1));
|
async_threads = uint8(sConfigMgr->GetOption<int32>("WorldDatabase.WorkerThreads", 1));
|
||||||
if (async_threads < 1 || async_threads > 32)
|
if (async_threads < 1 || async_threads > 32)
|
||||||
{
|
{
|
||||||
sLog->outError("World database: invalid number of worker threads specified. "
|
sLog->outError("World database: invalid number of worker threads specified. "
|
||||||
@@ -413,7 +413,7 @@ bool Master::_StartDB()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
synch_threads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.SynchThreads", 1));
|
synch_threads = uint8(sConfigMgr->GetOption<int32>("WorldDatabase.SynchThreads", 1));
|
||||||
///- Initialise the world database
|
///- Initialise the world database
|
||||||
if (!WorldDatabase.Open(dbstring, async_threads, synch_threads))
|
if (!WorldDatabase.Open(dbstring, async_threads, synch_threads))
|
||||||
{
|
{
|
||||||
@@ -422,14 +422,14 @@ bool Master::_StartDB()
|
|||||||
}
|
}
|
||||||
|
|
||||||
///- Get character database info from configuration file
|
///- Get character database info from configuration file
|
||||||
dbstring = sConfigMgr->GetStringDefault("CharacterDatabaseInfo", "");
|
dbstring = sConfigMgr->GetOption<std::string>("CharacterDatabaseInfo", "");
|
||||||
if (dbstring.empty())
|
if (dbstring.empty())
|
||||||
{
|
{
|
||||||
sLog->outError("Character database not specified in configuration file");
|
sLog->outError("Character database not specified in configuration file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async_threads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.WorkerThreads", 1));
|
async_threads = uint8(sConfigMgr->GetOption<int32>("CharacterDatabase.WorkerThreads", 1));
|
||||||
if (async_threads < 1 || async_threads > 32)
|
if (async_threads < 1 || async_threads > 32)
|
||||||
{
|
{
|
||||||
sLog->outError("Character database: invalid number of worker threads specified. "
|
sLog->outError("Character database: invalid number of worker threads specified. "
|
||||||
@@ -437,7 +437,7 @@ bool Master::_StartDB()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
synch_threads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.SynchThreads", 2));
|
synch_threads = uint8(sConfigMgr->GetOption<int32>("CharacterDatabase.SynchThreads", 2));
|
||||||
|
|
||||||
///- Initialise the Character database
|
///- Initialise the Character database
|
||||||
if (!CharacterDatabase.Open(dbstring, async_threads, synch_threads))
|
if (!CharacterDatabase.Open(dbstring, async_threads, synch_threads))
|
||||||
@@ -447,14 +447,14 @@ bool Master::_StartDB()
|
|||||||
}
|
}
|
||||||
|
|
||||||
///- Get login database info from configuration file
|
///- Get login database info from configuration file
|
||||||
dbstring = sConfigMgr->GetStringDefault("LoginDatabaseInfo", "");
|
dbstring = sConfigMgr->GetOption<std::string>("LoginDatabaseInfo", "");
|
||||||
if (dbstring.empty())
|
if (dbstring.empty())
|
||||||
{
|
{
|
||||||
sLog->outError("Login database not specified in configuration file");
|
sLog->outError("Login database not specified in configuration file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async_threads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1));
|
async_threads = uint8(sConfigMgr->GetOption<int32>("LoginDatabase.WorkerThreads", 1));
|
||||||
if (async_threads < 1 || async_threads > 32)
|
if (async_threads < 1 || async_threads > 32)
|
||||||
{
|
{
|
||||||
sLog->outError("Login database: invalid number of worker threads specified. "
|
sLog->outError("Login database: invalid number of worker threads specified. "
|
||||||
@@ -462,7 +462,7 @@ bool Master::_StartDB()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
synch_threads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1));
|
synch_threads = uint8(sConfigMgr->GetOption<int32>("LoginDatabase.SynchThreads", 1));
|
||||||
///- Initialise the login database
|
///- Initialise the login database
|
||||||
if (!LoginDatabase.Open(dbstring, async_threads, synch_threads))
|
if (!LoginDatabase.Open(dbstring, async_threads, synch_threads))
|
||||||
{
|
{
|
||||||
@@ -471,7 +471,7 @@ bool Master::_StartDB()
|
|||||||
}
|
}
|
||||||
|
|
||||||
///- Get the realm Id from the configuration file
|
///- Get the realm Id from the configuration file
|
||||||
realmID = sConfigMgr->GetIntDefault("RealmID", 0);
|
realmID = sConfigMgr->GetOption<int32>("RealmID", 0);
|
||||||
if (!realmID)
|
if (!realmID)
|
||||||
{
|
{
|
||||||
sLog->outError("Realm ID not defined in configuration file");
|
sLog->outError("Realm ID not defined in configuration file");
|
||||||
|
|||||||
@@ -43,13 +43,13 @@ RARunnable::~RARunnable()
|
|||||||
|
|
||||||
void RARunnable::run()
|
void RARunnable::run()
|
||||||
{
|
{
|
||||||
if (!sConfigMgr->GetBoolDefault("Ra.Enable", false))
|
if (!sConfigMgr->GetOption<bool>("Ra.Enable", false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ACE_Acceptor<RASocket, ACE_SOCK_ACCEPTOR> acceptor;
|
ACE_Acceptor<RASocket, ACE_SOCK_ACCEPTOR> acceptor;
|
||||||
|
|
||||||
uint16 raPort = uint16(sConfigMgr->GetIntDefault("Ra.Port", 3443));
|
uint16 raPort = uint16(sConfigMgr->GetOption<int32>("Ra.Port", 3443));
|
||||||
std::string stringIp = sConfigMgr->GetStringDefault("Ra.IP", "0.0.0.0");
|
std::string stringIp = sConfigMgr->GetOption<std::string>("Ra.IP", "0.0.0.0");
|
||||||
ACE_INET_Addr listenAddress(raPort, stringIp.c_str());
|
ACE_INET_Addr listenAddress(raPort, stringIp.c_str());
|
||||||
|
|
||||||
if (acceptor.open(listenAddress, m_Reactor) == -1)
|
if (acceptor.open(listenAddress, m_Reactor) == -1)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
RASocket::RASocket()
|
RASocket::RASocket()
|
||||||
{
|
{
|
||||||
_minLevel = uint8(sConfigMgr->GetIntDefault("RA.MinLevel", 3));
|
_minLevel = uint8(sConfigMgr->GetOption<int32>("RA.MinLevel", 3));
|
||||||
_commandExecuting = false;
|
_commandExecuting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1967,7 +1967,6 @@ NpcEvadeIfTargetIsUnreachable = 5
|
|||||||
|
|
||||||
NpcRegenHPIfTargetIsUnreachable = 1
|
NpcRegenHPIfTargetIsUnreachable = 1
|
||||||
|
|
||||||
|
|
||||||
# NpcRegenHPTimeIfTargetIsUnreachable
|
# NpcRegenHPTimeIfTargetIsUnreachable
|
||||||
# Description: Specifies the time (in seconds) that a creature whom target
|
# Description: Specifies the time (in seconds) that a creature whom target
|
||||||
# is unreachable in raid to end up regenerate health.
|
# is unreachable in raid to end up regenerate health.
|
||||||
@@ -2768,16 +2767,16 @@ Battleground.QueueAnnouncer.PlayerOnly = 0
|
|||||||
# Default: 300000 - (Enabled, 5 minutes)
|
# Default: 300000 - (Enabled, 5 minutes)
|
||||||
# 0 - (Disabled, Not recommended)
|
# 0 - (Disabled, Not recommended)
|
||||||
|
|
||||||
BattleGround.PrematureFinishTimer = 300000
|
Battleground.PrematureFinishTimer = 300000
|
||||||
|
|
||||||
#
|
#
|
||||||
# BattleGround.PremadeGroupWaitForMatch
|
# Battleground.PremadeGroupWaitForMatch
|
||||||
# Description: Time (in milliseconds) a pre-made group has to wait for matching group of the
|
# Description: Time (in milliseconds) a pre-made group has to wait for matching group of the
|
||||||
# other faction.
|
# other faction.
|
||||||
# Default: 1800000 - (Enabled, 30 minutes)
|
# Default: 1800000 - (Enabled, 30 minutes)
|
||||||
# 0 - (Disabled, Not recommended)
|
# 0 - (Disabled, Not recommended)
|
||||||
|
|
||||||
BattleGround.PremadeGroupWaitForMatch = 1800000
|
Battleground.PremadeGroupWaitForMatch = 1800000
|
||||||
|
|
||||||
#
|
#
|
||||||
# Battleground.GiveXPForKills
|
# Battleground.GiveXPForKills
|
||||||
|
|||||||
Reference in New Issue
Block a user