46#include <boost/asio/signal_set.hpp>
47#include <boost/dll/runtime_symbol_info.hpp>
48#include <boost/program_options.hpp>
49#include <boost/filesystem/operations.hpp>
50#include <google/protobuf/stubs/common.h>
56using namespace boost::program_options;
59#ifndef _TRINITY_BNET_CONFIG
60# define _TRINITY_BNET_CONFIG "bnetserver.conf"
62#ifndef _TRINITY_BNET_CONFIG_DIR
63 #define _TRINITY_BNET_CONFIG_DIR "bnetserver.conf.d"
66#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
79void ServiceStatusWatcher(std::weak_ptr<Trinity::Asio::DeadlineTimer> serviceStatusWatchTimerRef, std::weak_ptr<Trinity::Asio::IoContext> ioContextRef, boost::system::error_code
const& error);
84void SignalHandler(std::weak_ptr<Trinity::Asio::IoContext> ioContextRef, boost::system::error_code
const& error,
int signalNumber);
85void KeepDatabaseAliveHandler(std::weak_ptr<Trinity::Asio::DeadlineTimer> dbPingTimerRef,
int32 dbPingInterval, boost::system::error_code
const& error);
86void BanExpiryHandler(std::weak_ptr<Trinity::Asio::DeadlineTimer> banExpiryCheckTimerRef,
int32 banExpiryCheckInterval, boost::system::error_code
const& error);
87variables_map
GetConsoleArguments(
int argc,
char** argv, fs::path& configFile, fs::path& configDir, std::string& winServiceAction);
89int main(
int argc,
char** argv)
99 std::string winServiceAction;
102 if (vm.count(
"help") || vm.count(
"version"))
105 GOOGLE_PROTOBUF_VERIFY_VERSION;
107 std::shared_ptr<void> protobufHandle(
nullptr, [](
void*) { google::protobuf::ShutdownProtobufLibrary(); });
109#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
110 if (winServiceAction ==
"install")
111 return WinServiceInstall() ? 0 : 1;
112 if (winServiceAction ==
"uninstall")
113 return WinServiceUninstall() ? 0 : 1;
114 if (winServiceAction ==
"run")
115 return WinServiceRun() ? 0 : 1;
118 std::string configError;
119 if (!
sConfigMgr->LoadInitial(configFile.generic_string(),
120 std::vector<std::string>(argv, argv + argc),
123 printf(
"Error in config file: %s\n", configError.c_str());
127 std::vector<std::string> loadedConfigFiles;
128 std::vector<std::string> configDirErrors;
129 bool additionalConfigFileLoadSuccess =
sConfigMgr->LoadAdditionalDir(configDir.generic_string(),
true, loadedConfigFiles, configDirErrors);
130 for (std::string
const& loadedConfigFile : loadedConfigFiles)
131 printf(
"Loaded additional config file %s\n", loadedConfigFile.c_str());
133 if (!additionalConfigFileLoadSuccess)
135 for (std::string
const& configDirError : configDirErrors)
136 printf(
"Error in additional config files: %s\n", configDirError.c_str());
141 std::vector<std::string> overriddenKeys =
sConfigMgr->OverrideWithEnvVariablesIfAny();
144 sLog->Initialize(
nullptr);
154 TC_LOG_INFO(
"server.bnetserver",
"Using SSL version: {} (library: {})", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION));
155 TC_LOG_INFO(
"server.bnetserver",
"Using Boost version: {}.{}.{}", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100);
159 for (std::string
const& key : overriddenKeys)
160 TC_LOG_INFO(
"server.authserver",
"Configuration field '{}' was overridden with environment variable.", key);
167 std::string pidFile =
sConfigMgr->GetStringDefault(
"PidFile",
"");
168 if (!pidFile.empty())
171 TC_LOG_INFO(
"server.bnetserver",
"Daemon PID: {}\n", pid);
174 TC_LOG_ERROR(
"server.bnetserver",
"Cannot create PID file {}.\n", pidFile);
181 TC_LOG_ERROR(
"server.bnetserver",
"Failed to initialize SSL context");
189 std::shared_ptr<void> dbHandle(
nullptr, [](
void*) {
StopDB(); });
191 if (vm.count(
"update-databases-only"))
199 std::shared_ptr<Trinity::Asio::IoContext> ioContext = std::make_shared<Trinity::Asio::IoContext>();
203 std::string httpBindIp =
sConfigMgr->GetStringDefault(
"BindIP",
"0.0.0.0");
205 if (httpPort <= 0 || httpPort > 0xFFFF)
207 TC_LOG_ERROR(
"server.bnetserver",
"Specified login service port ({}) out of allowed range (1-65535)", httpPort);
211 if (!
sLoginService.StartNetwork(*ioContext, httpBindIp, httpPort))
213 TC_LOG_ERROR(
"server.bnetserver",
"Failed to initialize login service");
217 std::shared_ptr<void> sLoginServiceHandle(
nullptr, [](
void*) {
sLoginService.StopNetwork(); });
221 if (bnport <= 0 || bnport > 0xFFFF)
223 TC_LOG_ERROR(
"server.bnetserver",
"Specified battle.net port ({}) out of allowed range (1-65535)", bnport);
230 std::shared_ptr<void> sRealmListHandle(
nullptr, [](
void*) {
sRealmList->Close(); });
232 std::string bindIp =
sConfigMgr->GetStringDefault(
"BindIP",
"0.0.0.0");
234 if (!
sSessionMgr.StartNetwork(*ioContext, bindIp, bnport))
236 TC_LOG_ERROR(
"server.bnetserver",
"Failed to initialize network");
240 std::shared_ptr<void> sSessionMgrHandle(
nullptr, [](
void*) {
sSessionMgr.StopNetwork(); });
243 boost::asio::signal_set signals(*ioContext, SIGINT, SIGTERM);
244#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
245 signals.add(SIGBREAK);
247 signals.async_wait([ioContextRef = std::weak_ptr(ioContext)](boost::system::error_code
const& error,
int signalNumber)
mutable
257 std::shared_ptr<Trinity::Asio::DeadlineTimer> dbPingTimer = std::make_shared<Trinity::Asio::DeadlineTimer>(*ioContext);
258 dbPingTimer->expires_from_now(boost::posix_time::minutes(dbPingInterval));
259 dbPingTimer->async_wait([timerRef = std::weak_ptr(dbPingTimer), dbPingInterval](boost::system::error_code
const& error)
mutable
264 int32 banExpiryCheckInterval =
sConfigMgr->GetIntDefault(
"BanExpiryCheckInterval", 60);
265 std::shared_ptr<Trinity::Asio::DeadlineTimer> banExpiryCheckTimer = std::make_shared<Trinity::Asio::DeadlineTimer>(*ioContext);
266 banExpiryCheckTimer->expires_from_now(boost::posix_time::seconds(banExpiryCheckInterval));
267 banExpiryCheckTimer->async_wait([timerRef = std::weak_ptr(banExpiryCheckTimer), banExpiryCheckInterval](boost::system::error_code
const& error)
mutable
272#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
273 std::shared_ptr<Trinity::Asio::DeadlineTimer> serviceStatusWatchTimer;
276 serviceStatusWatchTimer = std::make_shared<Trinity::Asio::DeadlineTimer>(*ioContext);
277 serviceStatusWatchTimer->expires_from_now(boost::posix_time::seconds(1));
278 serviceStatusWatchTimer->async_wait([timerRef = std::weak_ptr(serviceStatusWatchTimer), ioContextRef = std::weak_ptr(ioContext)](boost::system::error_code
const& error)
mutable
288 banExpiryCheckTimer->cancel();
289 dbPingTimer->cancel();
291 TC_LOG_INFO(
"server.bnetserver",
"Halting process...");
311 TC_LOG_INFO(
"server.bnetserver",
"Started auth database connection pool.");
323void SignalHandler(std::weak_ptr<Trinity::Asio::IoContext> ioContextRef, boost::system::error_code
const& error,
int )
326 if (std::shared_ptr<Trinity::Asio::IoContext> ioContext = ioContextRef.lock())
334 if (std::shared_ptr<Trinity::Asio::DeadlineTimer> dbPingTimer = dbPingTimerRef.lock())
336 TC_LOG_INFO(
"server.bnetserver",
"Ping MySQL to keep connection alive");
339 dbPingTimer->expires_from_now(boost::posix_time::minutes(dbPingInterval));
340 dbPingTimer->async_wait([timerRef = std::move(dbPingTimerRef), dbPingInterval](boost::system::error_code
const& error)
mutable
348void BanExpiryHandler(std::weak_ptr<Trinity::Asio::DeadlineTimer> banExpiryCheckTimerRef,
int32 banExpiryCheckInterval, boost::system::error_code
const& error)
352 if (std::shared_ptr<Trinity::Asio::DeadlineTimer> banExpiryCheckTimer = banExpiryCheckTimerRef.lock())
358 banExpiryCheckTimer->expires_from_now(boost::posix_time::seconds(banExpiryCheckInterval));
359 banExpiryCheckTimer->async_wait([timerRef = std::move(banExpiryCheckTimerRef), banExpiryCheckInterval](boost::system::error_code
const& error)
mutable
367#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
368void ServiceStatusWatcher(std::weak_ptr<Trinity::Asio::DeadlineTimer> serviceStatusWatchTimerRef, std::weak_ptr<Trinity::Asio::IoContext> ioContextRef, boost::system::error_code
const& error)
372 if (std::shared_ptr<Trinity::Asio::IoContext> ioContext = ioContextRef.lock())
378 else if (std::shared_ptr<Trinity::Asio::DeadlineTimer> serviceStatusWatchTimer = serviceStatusWatchTimerRef.lock())
380 serviceStatusWatchTimer->expires_from_now(boost::posix_time::seconds(1));
381 serviceStatusWatchTimer->async_wait([timerRef = std::move(serviceStatusWatchTimerRef), ioContextRef = std::move(ioContextRef)](boost::system::error_code
const& error)
mutable
391variables_map
GetConsoleArguments(
int argc,
char** argv, fs::path& configFile, fs::path& configDir, [[maybe_unused]] std::string& winServiceAction)
393 options_description all(
"Allowed options");
395 (
"help,h",
"print usage message")
396 (
"version,v",
"print version build info")
398 "use <arg> as configuration file")
400 "use <arg> as directory with additional config files")
401 (
"update-databases-only,u",
"updates databases only")
403#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
404 options_description win(
"Windows platform specific options");
406 (
"service,s", value<std::string>(&winServiceAction)->default_value(
""),
"Windows service options: [install | uninstall]")
411 variables_map variablesMap;
414 store(command_line_parser(argc, argv).options(all).allow_unregistered().run(), variablesMap);
415 notify(variablesMap);
417 catch (std::exception& e)
419 std::cerr << e.what() <<
"\n";
422 if (variablesMap.count(
"help"))
424 std::cout << all <<
"\n";
426 else if (variablesMap.count(
"version"))
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
#define TC_LOG_ERROR(filterType__,...)
#define TC_LOG_INFO(filterType__,...)
@ LOGIN_DEL_EXPIRED_IP_BANS
@ LOGIN_UPD_EXPIRED_ACCOUNT_BANS
@ LOGIN_DEL_BNET_EXPIRED_ACCOUNT_BANNED
void SetProcessPriority(std::string const &logChannel, uint32 affinity, bool highPriority)
#define CONFIG_HIGH_PRIORITY
#define CONFIG_PROCESSOR_AFFINITY
@ SECRET_OWNER_BNETSERVER
uint32 CreatePIDFile(std::string const &filename)
create PID file
void ServiceStatusWatcher(std::weak_ptr< Trinity::Asio::DeadlineTimer > serviceStatusWatchTimerRef, std::weak_ptr< Trinity::Asio::IoContext > ioContextRef, boost::system::error_code const &error)
char serviceDescription[]
void BanExpiryHandler(std::weak_ptr< Trinity::Asio::DeadlineTimer > banExpiryCheckTimerRef, int32 banExpiryCheckInterval, boost::system::error_code const &error)
void SignalHandler(std::weak_ptr< Trinity::Asio::IoContext > ioContextRef, boost::system::error_code const &error, int signalNumber)
int main(int argc, char **argv)
variables_map GetConsoleArguments(int argc, char **argv, fs::path &configFile, fs::path &configDir, std::string &winServiceAction)
void KeepDatabaseAliveHandler(std::weak_ptr< Trinity::Asio::DeadlineTimer > dbPingTimerRef, int32 dbPingInterval, boost::system::error_code const &error)
#define _TRINITY_BNET_CONFIG_DIR
#define _TRINITY_BNET_CONFIG
bool StartDB()
Initialize connection to the database.
void StopDB()
Close the connection to the database.
DatabaseLoader & AddDatabase(DatabaseWorkerPool< T > &pool, std::string const &name)
TC_COMMON_API char const * GetFullVersion()
TC_DATABASE_API void Library_Init()
TC_DATABASE_API void Library_End()
TC_COMMON_API void threadsSetup(boost::filesystem::path const &providerModulePath)
Needs to be called before threads using openssl are spawned.
TC_COMMON_API void threadsCleanup()
Needs to be called after threads using openssl are despawned.
TC_COMMON_API void Show(char const *applicationName, void(*log)(char const *text), void(*logExtraInfo)())
TC_COMMON_API void Init()
TC_COMMON_API void ScanLocalNetworks()
TC_COMMON_API void VerifyOsVersion()
void AbortHandler(int sigval)