2022-05-26 23:17:01 +00:00
# define _WIN32_WINNT 0x0501
# include <base/logger.h>
# include <base/system.h>
# include <engine/console.h>
# include <engine/engine.h>
# include <engine/map.h>
# include <engine/server.h>
# include <engine/storage.h>
# include <engine/server/antibot.h>
# include <engine/server/databases/connection.h>
# include <engine/server/server.h>
# include <engine/server/server_logger.h>
# include <engine/shared/assertion_logger.h>
# include <engine/shared/config.h>
# include <game/version.h>
# include <vector>
# if defined(CONF_FAMILY_WINDOWS)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# endif
# include <csignal>
volatile sig_atomic_t InterruptSignaled = 0 ;
bool IsInterrupted ( )
{
return InterruptSignaled ;
}
void HandleSigIntTerm ( int Param )
{
InterruptSignaled = 1 ;
// Exit the next time a signal is received
signal ( SIGINT , SIG_DFL ) ;
signal ( SIGTERM , SIG_DFL ) ;
}
int main ( int argc , const char * * argv )
{
CCmdlineFix CmdlineFix ( & argc , & argv ) ;
bool Silent = false ;
for ( int i = 1 ; i < argc ; i + + )
{
if ( str_comp ( " -s " , argv [ i ] ) = = 0 | | str_comp ( " --silent " , argv [ i ] ) = = 0 )
{
Silent = true ;
# if defined(CONF_FAMILY_WINDOWS)
ShowWindow ( GetConsoleWindow ( ) , SW_HIDE ) ;
# endif
break ;
}
}
2022-10-07 20:18:15 +00:00
# if defined(CONF_FAMILY_WINDOWS)
CWindowsComLifecycle WindowsComLifecycle ( false ) ;
# endif
2022-05-26 23:17:01 +00:00
std : : vector < std : : shared_ptr < ILogger > > vpLoggers ;
2022-06-13 19:43:05 +00:00
std : : shared_ptr < ILogger > pStdoutLogger ;
2022-05-26 23:17:01 +00:00
# if defined(CONF_PLATFORM_ANDROID)
2022-06-13 19:43:05 +00:00
pStdoutLogger = std : : shared_ptr < ILogger > ( log_logger_android ( ) ) ;
2022-05-26 23:17:01 +00:00
# else
if ( ! Silent )
{
2022-06-13 19:43:05 +00:00
pStdoutLogger = std : : shared_ptr < ILogger > ( log_logger_stdout ( ) ) ;
2022-05-26 23:17:01 +00:00
}
# endif
2022-06-13 19:43:05 +00:00
if ( pStdoutLogger )
{
vpLoggers . push_back ( pStdoutLogger ) ;
}
2022-05-26 23:17:01 +00:00
std : : shared_ptr < CFutureLogger > pFutureFileLogger = std : : make_shared < CFutureLogger > ( ) ;
vpLoggers . push_back ( pFutureFileLogger ) ;
std : : shared_ptr < CFutureLogger > pFutureConsoleLogger = std : : make_shared < CFutureLogger > ( ) ;
vpLoggers . push_back ( pFutureConsoleLogger ) ;
std : : shared_ptr < CFutureLogger > pFutureAssertionLogger = std : : make_shared < CFutureLogger > ( ) ;
vpLoggers . push_back ( pFutureAssertionLogger ) ;
log_set_global_logger ( log_logger_collection ( std : : move ( vpLoggers ) ) . release ( ) ) ;
if ( secure_random_init ( ) ! = 0 )
{
dbg_msg ( " secure " , " could not initialize secure RNG " ) ;
return - 1 ;
}
if ( MysqlInit ( ) ! = 0 )
{
dbg_msg ( " mysql " , " failed to initialize MySQL library " ) ;
return - 1 ;
}
signal ( SIGINT , HandleSigIntTerm ) ;
signal ( SIGTERM , HandleSigIntTerm ) ;
# if defined(CONF_EXCEPTION_HANDLING)
init_exception_handler ( ) ;
# endif
CServer * pServer = CreateServer ( ) ;
2022-06-13 19:43:05 +00:00
pServer - > SetLoggers ( pFutureFileLogger , std : : move ( pStdoutLogger ) ) ;
2022-05-26 23:17:01 +00:00
IKernel * pKernel = IKernel : : Create ( ) ;
// create the components
2023-10-15 18:56:02 +00:00
IEngine * pEngine = CreateEngine ( GAME_NAME , pFutureConsoleLogger , 2 * std : : thread : : hardware_concurrency ( ) + 2 ) ;
2022-05-26 23:17:01 +00:00
IEngineMap * pEngineMap = CreateEngineMap ( ) ;
IGameServer * pGameServer = CreateGameServer ( ) ;
2022-10-19 21:46:06 +00:00
IConsole * pConsole = CreateConsole ( CFGFLAG_SERVER | CFGFLAG_ECON ) . release ( ) ;
2022-05-26 23:17:01 +00:00
IStorage * pStorage = CreateStorage ( IStorage : : STORAGETYPE_SERVER , argc , argv ) ;
IConfigManager * pConfigManager = CreateConfigManager ( ) ;
IEngineAntibot * pEngineAntibot = CreateEngineAntibot ( ) ;
pFutureAssertionLogger - > Set ( CreateAssertionLogger ( pStorage , GAME_NAME ) ) ;
# if defined(CONF_EXCEPTION_HANDLING)
char aBuf [ IO_MAX_PATH_LENGTH ] ;
char aBufName [ IO_MAX_PATH_LENGTH ] ;
char aDate [ 64 ] ;
str_timestamp ( aDate , sizeof ( aDate ) ) ;
2023-04-28 18:40:28 +00:00
str_format ( aBufName , sizeof ( aBufName ) , " dumps/ " GAME_NAME " -Server_%s_crash_log_%s_%d_%s.RTP " , CONF_PLATFORM_STRING , aDate , pid ( ) , GIT_SHORTREV_HASH ! = nullptr ? GIT_SHORTREV_HASH : " " ) ;
2022-05-26 23:17:01 +00:00
pStorage - > GetCompletePath ( IStorage : : TYPE_SAVE , aBufName , aBuf , sizeof ( aBuf ) ) ;
set_exception_handler_log_file ( aBuf ) ;
# endif
{
bool RegisterFail = false ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pServer ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pEngine ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pEngineMap ) ; // register as both
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( static_cast < IMap * > ( pEngineMap ) , false ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pGameServer ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pConsole ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pStorage ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pConfigManager ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( pEngineAntibot ) ;
RegisterFail = RegisterFail | | ! pKernel - > RegisterInterface ( static_cast < IAntibot * > ( pEngineAntibot ) , false ) ;
if ( RegisterFail )
{
delete pKernel ;
return - 1 ;
}
}
pEngine - > Init ( ) ;
pConfigManager - > Init ( ) ;
pConsole - > Init ( ) ;
// register all console commands
pServer - > RegisterCommands ( ) ;
// execute autoexec file
2023-05-09 21:01:43 +00:00
if ( pStorage - > FileExists ( AUTOEXEC_SERVER_FILE , IStorage : : TYPE_ALL ) )
2022-05-26 23:17:01 +00:00
{
pConsole - > ExecuteFile ( AUTOEXEC_SERVER_FILE ) ;
}
else // fallback
{
pConsole - > ExecuteFile ( AUTOEXEC_FILE ) ;
}
// parse the command line arguments
if ( argc > 1 )
pConsole - > ParseArguments ( argc - 1 , & argv [ 1 ] ) ;
pConsole - > Register ( " sv_test_cmds " , " " , CFGFLAG_SERVER , CServer : : ConTestingCommands , pConsole , " Turns testing commands aka cheats on/off (setting only works in initial config) " ) ;
pConsole - > Register ( " sv_rescue " , " " , CFGFLAG_SERVER , CServer : : ConRescue , pConsole , " Allow /rescue command so players can teleport themselves out of freeze (setting only works in initial config) " ) ;
2023-06-05 07:41:41 +00:00
const int Mode = g_Config . m_Logappend ? IOFLAG_APPEND : IOFLAG_WRITE ;
2022-05-26 23:17:01 +00:00
if ( g_Config . m_Logfile [ 0 ] )
{
2023-06-05 07:41:41 +00:00
IOHANDLE Logfile = pStorage - > OpenFile ( g_Config . m_Logfile , Mode , IStorage : : TYPE_SAVE_OR_ABSOLUTE ) ;
2022-05-26 23:17:01 +00:00
if ( Logfile )
{
pFutureFileLogger - > Set ( log_logger_file ( Logfile ) ) ;
}
else
{
2023-03-02 08:44:27 +00:00
dbg_msg ( " server " , " failed to open '%s' for logging " , g_Config . m_Logfile ) ;
2022-05-26 23:17:01 +00:00
}
}
2023-05-16 23:04:06 +00:00
auto pServerLogger = std : : make_shared < CServerLogger > ( pServer ) ;
pEngine - > SetAdditionalLogger ( pServerLogger ) ;
2022-05-26 23:17:01 +00:00
// run the server
dbg_msg ( " server " , " starting... " ) ;
int Ret = pServer - > Run ( ) ;
2023-05-16 23:04:06 +00:00
pServerLogger - > OnServerDeletion ( ) ;
2022-05-26 23:17:01 +00:00
// free
delete pKernel ;
2023-06-14 09:38:28 +00:00
MysqlUninit ( ) ;
secure_random_uninit ( ) ;
2022-05-26 23:17:01 +00:00
return Ret ;
}