2021-12-25 22:36:38 +01:00
# include "core/stdafx.h"
2022-05-23 19:14:12 +02:00
# include "basepanel.h"
2022-05-24 02:23:37 +02:00
# include "sdklauncher_const.h"
# include "sdklauncher.h"
2022-05-23 19:14:12 +02:00
# include <objidl.h>
# include "gdiplus.h"
# include "shellapi.h"
using namespace Gdiplus ;
# pragma comment (lib,"Shell32.lib")
# pragma comment (lib,"Gdi32.lib")
# pragma comment (lib,"Gdiplus.lib")
# pragma comment (lib,"Advapi32.lib")
2021-08-01 02:25:29 -07:00
2022-05-24 02:23:37 +02:00
# pragma comment(linker," / manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
2021-10-21 15:56:45 -07:00
//-----------------------------------------------------------------------------
2022-01-19 23:14:50 +01:00
// Purpose switch case:
2021-08-01 02:25:29 -07:00
// * Launch the game in user specified mode and state.
// * Load specified command line arguments from a file on the disk.
// * Format the file paths for the game exe and specified hook dll.
//-----------------------------------------------------------------------------
2022-05-23 19:14:12 +02:00
bool CLauncher : : Setup ( eLaunchMode lMode , eLaunchState lState )
2021-04-13 04:45:22 -07:00
{
2021-06-17 17:07:26 -07:00
///////////////////////////////////////////////////////////////////////////
2022-04-16 00:30:46 +02:00
std : : string svCmdLineArgs = std : : string ( ) ;
2021-04-13 04:45:22 -07:00
2021-08-30 16:39:56 +02:00
///////////////////////////////////////////////////////////////////////////
2021-08-01 02:25:29 -07:00
switch ( lMode )
2021-04-13 05:05:29 -07:00
{
2022-05-24 02:23:37 +02:00
case eLaunchMode : : LM_HOST_DEBUG :
2022-05-23 19:14:12 +02:00
{
fs : : path cfgPath = fs : : current_path ( ) / = " platform \\ cfg \\ startup_debug.cfg " ;
std : : ifstream cfgFile ( cfgPath ) ;
if ( cfgFile . good ( ) & & cfgFile )
2021-04-25 14:36:55 -07:00
{
2022-05-23 19:14:12 +02:00
std : : stringstream ss ;
ss < < cfgFile . rdbuf ( ) ;
svCmdLineArgs = ss . str ( ) + " -launcher " ;
2021-08-01 02:25:29 -07:00
}
2022-05-23 19:14:12 +02:00
else
2021-08-01 02:25:29 -07:00
{
2022-05-23 19:14:12 +02:00
spdlog : : error ( " File 'platform \\ cfg \\ startup_debug.cfg' does not exist! \n " ) ;
cfgFile . close ( ) ;
return false ;
}
cfgFile . close ( ) ; // Close cfg file.
2021-08-01 02:25:29 -07:00
2022-05-23 19:14:12 +02:00
m_svWorkerDll = m_svCurrentDir + " \\ gamesdk.dll " ;
m_svGameExe = m_svCurrentDir + " \\ r5apex.exe " ;
m_svCmdLine = m_svCurrentDir + " \\ r5apex.exe " + svCmdLineArgs ;
2021-08-30 16:39:56 +02:00
2022-05-23 19:14:12 +02:00
spdlog : : info ( " *** LAUNCHING GAME [DEBUG] *** \n " ) ;
break ;
}
2022-05-24 02:23:37 +02:00
case eLaunchMode : : LM_HOST :
2022-05-23 19:14:12 +02:00
{
fs : : path cfgPath = fs : : current_path ( ) / = " platform \\ cfg \\ startup_retail.cfg " ;
std : : ifstream cfgFile ( cfgPath ) ;
if ( cfgFile . good ( ) & & cfgFile )
{
std : : stringstream ss ;
ss < < cfgFile . rdbuf ( ) ;
svCmdLineArgs = ss . str ( ) + " -launcher " ;
2021-08-01 02:25:29 -07:00
}
2022-05-23 19:14:12 +02:00
else
2021-08-01 02:25:29 -07:00
{
2022-05-23 19:14:12 +02:00
spdlog : : error ( " File 'platform \\ cfg \\ startup_retail.cfg' does not exist! \n " ) ;
cfgFile . close ( ) ;
return false ;
}
cfgFile . close ( ) ; // Close cfg file.
2021-08-01 02:25:29 -07:00
2022-05-23 19:14:12 +02:00
m_svWorkerDll = m_svCurrentDir + " \\ gamesdk.dll " ;
m_svGameExe = m_svCurrentDir + " \\ r5apex.exe " ;
m_svCmdLine = m_svCurrentDir + " \\ r5apex.exe " + svCmdLineArgs ;
2021-08-30 16:39:56 +02:00
2022-05-23 19:14:12 +02:00
spdlog : : info ( " *** LAUNCHING GAME [RELEASE] *** \n " ) ;
break ;
}
2022-05-24 02:23:37 +02:00
case eLaunchMode : : LM_SERVER_DEBUG :
2022-05-23 19:14:12 +02:00
{
fs : : path cfgPath = fs : : current_path ( ) / = " platform \\ cfg \\ startup_dedi_debug.cfg " ;
std : : ifstream cfgFile ( cfgPath ) ;
if ( cfgFile . good ( ) & & cfgFile )
{
std : : stringstream ss ;
ss < < cfgFile . rdbuf ( ) ;
svCmdLineArgs = ss . str ( ) + " -launcher " ;
2022-01-16 12:48:56 +01:00
}
2022-05-23 19:14:12 +02:00
else
2022-01-16 12:48:56 +01:00
{
2022-05-23 19:14:12 +02:00
spdlog : : error ( " File 'platform \\ cfg \\ startup_dedi_debug.cfg' does not exist! \n " ) ;
cfgFile . close ( ) ;
return false ;
}
cfgFile . close ( ) ; // Close cfg file.
2022-01-16 12:48:56 +01:00
2022-05-23 19:14:12 +02:00
m_svWorkerDll = m_svCurrentDir + " \\ dedicated.dll " ;
m_svGameExe = m_svCurrentDir + " \\ r5apex_ds.exe " ;
m_svCmdLine = m_svCurrentDir + " \\ r5apex_ds.exe " + svCmdLineArgs ;
2022-01-16 12:48:56 +01:00
2022-05-23 19:14:12 +02:00
spdlog : : info ( " *** LAUNCHING DEDICATED [DEBUG] *** \n " ) ;
break ;
}
2022-05-24 02:23:37 +02:00
case eLaunchMode : : LM_SERVER :
2022-05-23 19:14:12 +02:00
{
fs : : path cfgPath = fs : : current_path ( ) / = " platform \\ cfg \\ startup_dedi_retail.cfg " ;
std : : ifstream cfgFile ( cfgPath ) ;
if ( cfgFile . good ( ) & & cfgFile )
{
std : : stringstream ss ;
ss < < cfgFile . rdbuf ( ) ;
svCmdLineArgs = ss . str ( ) ; + " -launcher " ;
2021-08-01 02:25:29 -07:00
}
2022-05-23 19:14:12 +02:00
else
2021-08-01 02:25:29 -07:00
{
2022-05-23 19:14:12 +02:00
spdlog : : error ( " File 'platform \\ cfg \\ startup_dedi_retail.cfg' does not exist! \n " ) ;
cfgFile . close ( ) ;
2021-08-01 02:25:29 -07:00
return false ;
2021-04-25 14:36:55 -07:00
}
2022-05-23 19:14:12 +02:00
cfgFile . close ( ) ; // Close cfg file.
m_svWorkerDll = m_svCurrentDir + " \\ dedicated.dll " ;
m_svGameExe = m_svCurrentDir + " \\ r5apex_ds.exe " ;
m_svCmdLine = m_svCurrentDir + " \\ r5apex_ds.exe " + svCmdLineArgs ;
spdlog : : info ( " *** LAUNCHING DEDICATED [RELEASE] *** \n " ) ;
break ;
}
default :
{
spdlog : : error ( " *** NO LAUNCH MODE SPECIFIED *** \n " ) ;
return false ;
}
2021-04-13 05:05:29 -07:00
}
2021-06-17 17:07:26 -07:00
///////////////////////////////////////////////////////////////////////////
2022-05-23 19:14:12 +02:00
// Print the file paths and arguments.
2022-01-16 12:48:56 +01:00
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
2022-05-23 19:14:12 +02:00
spdlog : : debug ( " - CWD: {} \n " , m_svCurrentDir ) ;
spdlog : : debug ( " - EXE: {} \n " , m_svGameExe ) ;
spdlog : : debug ( " - DLL: {} \n " , m_svWorkerDll ) ;
2022-04-16 00:30:46 +02:00
spdlog : : debug ( " - CLI: {} \n " , svCmdLineArgs ) ;
2022-01-16 12:48:56 +01:00
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
2021-04-13 04:45:22 -07:00
2022-05-23 19:14:12 +02:00
return true ;
}
2022-05-24 02:23:37 +02:00
bool CLauncher : : Setup ( eLaunchMode lMode , const string & svCommandLine )
{
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
switch ( lMode )
{
case eLaunchMode : : LM_HOST_DEBUG :
{
m_svWorkerDll = m_svCurrentDir + " \\ gamesdk.dll " ;
m_svGameExe = m_svCurrentDir + " \\ r5apex.exe " ;
m_svCmdLine = m_svCurrentDir + " \\ r5apex.exe " + svCommandLine ;
spdlog : : info ( " *** LAUNCHER SETUP FOR HOST [DEBUG] *** \n " ) ;
break ;
}
case eLaunchMode : : LM_HOST :
{
m_svWorkerDll = m_svCurrentDir + " \\ gamesdk.dll " ;
m_svGameExe = m_svCurrentDir + " \\ r5apex.exe " ;
m_svCmdLine = m_svCurrentDir + " \\ r5apex.exe " + svCommandLine ;
spdlog : : info ( " *** LAUNCHER SETUP FOR HOST [RELEASE] *** \n " ) ;
break ;
}
case eLaunchMode : : LM_SERVER_DEBUG :
{
m_svWorkerDll = m_svCurrentDir + " \\ dedicated.dll " ;
m_svGameExe = m_svCurrentDir + " \\ r5apex_ds.exe " ;
m_svCmdLine = m_svCurrentDir + " \\ r5apex_ds.exe " + svCommandLine ;
spdlog : : info ( " *** LAUNCHER SETUP FOR DEDICATED [DEBUG] *** \n " ) ;
break ;
}
case eLaunchMode : : LM_SERVER :
{
m_svWorkerDll = m_svCurrentDir + " \\ dedicated.dll " ;
m_svGameExe = m_svCurrentDir + " \\ r5apex_ds.exe " ;
m_svCmdLine = m_svCurrentDir + " \\ r5apex_ds.exe " + svCommandLine ;
spdlog : : info ( " *** LAUNCHER SETUP FOR DEDICATED [RELEASE] *** \n " ) ;
break ;
}
default :
{
spdlog : : error ( " *** INVALID LAUNCH MODE SPECIFIED *** \n " ) ;
return false ;
}
}
///////////////////////////////////////////////////////////////////////////
// Print the file paths and arguments.
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
spdlog : : debug ( " - CWD: {} \n " , m_svCurrentDir ) ;
spdlog : : debug ( " - EXE: {} \n " , m_svGameExe ) ;
spdlog : : debug ( " - DLL: {} \n " , m_svWorkerDll ) ;
spdlog : : debug ( " - CLI: {} \n " , svCommandLine ) ;
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
return true ;
}
2022-05-23 19:14:12 +02:00
bool CLauncher : : Launch ( )
{
2021-06-17 17:07:26 -07:00
///////////////////////////////////////////////////////////////////////////
2021-04-13 04:45:22 -07:00
// Build our list of dlls to inject.
LPCSTR DllsToInject [ 1 ] =
{
2022-05-23 19:14:12 +02:00
m_svWorkerDll . c_str ( )
2021-04-13 04:45:22 -07:00
} ;
2022-03-04 16:06:36 +01:00
STARTUPINFOA StartupInfo = { 0 } ;
2021-08-30 16:39:56 +02:00
PROCESS_INFORMATION ProcInfo = { 0 } ;
// Initialize startup info struct.
2022-03-04 16:06:36 +01:00
StartupInfo . cb = sizeof ( STARTUPINFOA ) ;
2021-08-30 16:39:56 +02:00
2021-06-17 17:07:26 -07:00
///////////////////////////////////////////////////////////////////////////
2021-04-13 04:45:22 -07:00
// Create the game process in a suspended state with our dll.
2021-08-30 16:39:56 +02:00
BOOL result = DetourCreateProcessWithDllsA
(
2022-05-23 19:14:12 +02:00
m_svGameExe . c_str ( ) , // lpApplicationName
( LPSTR ) m_svCmdLine . c_str ( ) , // lpCommandLine
2021-08-30 16:39:56 +02:00
NULL , // lpProcessAttributes
NULL , // lpThreadAttributes
FALSE , // bInheritHandles
CREATE_SUSPENDED , // dwCreationFlags
NULL , // lpEnvironment
2022-05-23 19:14:12 +02:00
m_svCurrentDir . c_str ( ) , // lpCurrentDirectory
2021-08-30 16:39:56 +02:00
& StartupInfo , // lpStartupInfo
& ProcInfo , // lpProcessInformation
sizeof ( DllsToInject ) / sizeof ( LPCSTR ) , // nDlls
DllsToInject , // rlpDlls
NULL // pfCreateProcessA
2021-04-13 04:45:22 -07:00
) ;
2021-06-17 17:07:26 -07:00
///////////////////////////////////////////////////////////////////////////
// Failed to create the process.
2021-04-13 04:45:22 -07:00
if ( ! result )
{
PrintLastError ( ) ;
return false ;
}
2021-06-17 17:07:26 -07:00
///////////////////////////////////////////////////////////////////////////
2021-04-13 04:45:22 -07:00
// Resume the process.
ResumeThread ( ProcInfo . hThread ) ;
2021-06-17 17:07:26 -07:00
///////////////////////////////////////////////////////////////////////////
2021-04-13 04:45:22 -07:00
// Close the process and thread handles.
CloseHandle ( ProcInfo . hProcess ) ;
CloseHandle ( ProcInfo . hThread ) ;
return true ;
}
2021-06-17 17:07:26 -07:00
///////////////////////////////////////////////////////////////////////////////
2021-06-28 15:51:32 -07:00
// Entrypoint.
2021-07-12 08:47:54 -07:00
///////////////////////////////////////////////////////////////////////////////
2021-04-13 04:45:22 -07:00
int main ( int argc , char * argv [ ] , char * envp [ ] )
{
2021-09-12 07:15:42 -07:00
spdlog : : set_pattern ( " [%^%l%$] %v " ) ;
spdlog : : set_level ( spdlog : : level : : trace ) ;
2022-05-23 19:14:12 +02:00
if ( argc < 2 )
2021-08-01 02:25:29 -07:00
{
2022-05-23 19:14:12 +02:00
Forms : : Application : : EnableVisualStyles ( ) ;
UIX : : UIXTheme : : InitializeRenderer ( new Themes : : KoreTheme ( ) ) ;
2021-08-19 15:26:44 +02:00
2022-05-26 01:44:46 +02:00
g_pLauncher - > m_pSurface = new CUIBaseSurface ( ) ;
Forms : : Application : : Run ( g_pLauncher - > m_pSurface ) ;
2022-05-23 19:14:12 +02:00
UIX : : UIXTheme : : ShutdownRenderer ( ) ;
}
else
2021-08-19 15:26:44 +02:00
{
2022-05-23 19:14:12 +02:00
for ( int i = 1 ; i < argc ; + + i )
2021-08-19 15:26:44 +02:00
{
2022-05-23 19:14:12 +02:00
std : : string arg = argv [ i ] ;
if ( ( arg = = " -debug " ) | | ( arg = = " -dbg " ) )
2022-01-16 12:48:56 +01:00
{
2022-05-24 02:23:37 +02:00
if ( g_pLauncher - > Setup ( eLaunchMode : : LM_HOST_DEBUG , eLaunchState : : LS_CHEATS ) )
2022-05-23 19:14:12 +02:00
{
if ( g_pLauncher - > Launch ( ) )
{
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
}
2022-01-16 12:48:56 +01:00
Sleep ( 2000 ) ;
2022-05-23 19:14:12 +02:00
return EXIT_FAILURE ;
2022-01-16 12:48:56 +01:00
}
2022-05-23 19:14:12 +02:00
if ( ( arg = = " -release " ) | | ( arg = = " -rel " ) )
2021-08-19 15:26:44 +02:00
{
2022-05-24 02:23:37 +02:00
if ( g_pLauncher - > Setup ( eLaunchMode : : LM_HOST , eLaunchState : : LS_CHEATS ) )
2022-05-23 19:14:12 +02:00
{
if ( g_pLauncher - > Launch ( ) )
{
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
}
2021-08-19 15:26:44 +02:00
Sleep ( 2000 ) ;
2022-05-23 19:14:12 +02:00
return EXIT_FAILURE ;
2021-08-19 15:26:44 +02:00
}
2022-05-23 19:14:12 +02:00
if ( ( arg = = " -dedicated_dev " ) | | ( arg = = " -dedid " ) )
2021-08-19 15:26:44 +02:00
{
2022-05-24 02:23:37 +02:00
if ( g_pLauncher - > Setup ( eLaunchMode : : LM_SERVER_DEBUG , eLaunchState : : LS_CHEATS ) )
2022-05-23 19:14:12 +02:00
{
if ( g_pLauncher - > Launch ( ) )
{
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
}
2021-08-19 15:26:44 +02:00
Sleep ( 2000 ) ;
2022-05-23 19:14:12 +02:00
return EXIT_FAILURE ;
2021-08-19 15:26:44 +02:00
}
2022-05-23 19:14:12 +02:00
if ( ( arg = = " -dedicated " ) | | ( arg = = " -dedi " ) )
2021-08-19 15:26:44 +02:00
{
2022-05-24 02:23:37 +02:00
if ( g_pLauncher - > Setup ( eLaunchMode : : LM_SERVER , eLaunchState : : LS_CHEATS ) )
2022-05-23 19:14:12 +02:00
{
if ( g_pLauncher - > Launch ( ) )
{
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
}
2021-08-19 15:26:44 +02:00
Sleep ( 2000 ) ;
2022-05-23 19:14:12 +02:00
return EXIT_FAILURE ;
2021-08-19 15:26:44 +02:00
}
2022-05-23 19:14:12 +02:00
}
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
spdlog : : warn ( " If a DEBUG option has been choosen as launch parameter, do not broadcast servers to the Server Browser! \n " ) ;
spdlog : : warn ( " All FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ConVar's/ConCommand's will be enabled. \n " ) ;
spdlog : : warn ( " Connected clients will be able to set and execute anything flagged FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY. \n " ) ;
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
2022-05-24 02:23:37 +02:00
spdlog : : warn ( " Use DEBUG HOST [1] for research and development purposes. \n " ) ;
spdlog : : warn ( " Use RELEASE HOST [2] for playing the game and creating servers. \n " ) ;
spdlog : : warn ( " Use DEBUG SERVER [3] for research and development purposes. \n " ) ;
spdlog : : warn ( " Use RELEASE SERVER [4] for running and hosting dedicated servers. \n " ) ;
spdlog : : warn ( " Use DEBUG CLIENT [5] for research and development purposes. \n " ) ;
spdlog : : warn ( " Use RELEASE CLIENT [6] for running client only builds against remote servers. \n " ) ;
2022-05-23 19:14:12 +02:00
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
2022-05-24 02:23:37 +02:00
spdlog : : info ( " Enter '1' for 'DEBUG HOST'. \n " ) ;
spdlog : : info ( " Enter '2' for 'RELEASE HOST'. \n " ) ;
spdlog : : info ( " Enter '3' for 'DEBUG SERVER'. \n " ) ;
spdlog : : info ( " Enter '4' for 'RELEASE SERVER'. \n " ) ;
spdlog : : info ( " Enter '5' for 'DEBUG CLIENT'. \n " ) ;
spdlog : : info ( " Enter '6' for 'RELEASE CLIENT'. \n " ) ;
2022-05-23 19:14:12 +02:00
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
std : : cout < < " User input: " ;
std : : string input = std : : string ( ) ;
if ( std : : cin > > input )
{
try
2021-08-19 15:26:44 +02:00
{
2022-05-23 19:14:12 +02:00
eLaunchMode mode = ( eLaunchMode ) std : : stoi ( input ) ;
switch ( mode )
{
2022-05-24 02:23:37 +02:00
case eLaunchMode : : LM_HOST_DEBUG :
2022-05-23 19:14:12 +02:00
{
2022-05-24 02:23:37 +02:00
if ( g_pLauncher - > Setup ( eLaunchMode : : LM_HOST_DEBUG , eLaunchState : : LS_CHEATS ) )
2022-05-23 19:14:12 +02:00
{
if ( g_pLauncher - > Launch ( ) )
{
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
}
Sleep ( 2000 ) ;
return EXIT_FAILURE ;
}
2022-05-24 02:23:37 +02:00
case eLaunchMode : : LM_HOST :
2022-05-23 19:14:12 +02:00
{
2022-05-24 02:23:37 +02:00
if ( g_pLauncher - > Setup ( eLaunchMode : : LM_HOST , eLaunchState : : LS_CHEATS ) )
2022-05-23 19:14:12 +02:00
{
if ( g_pLauncher - > Launch ( ) )
{
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
}
Sleep ( 2000 ) ;
return EXIT_FAILURE ;
}
2022-05-24 02:23:37 +02:00
case eLaunchMode : : LM_SERVER_DEBUG :
2022-05-23 19:14:12 +02:00
{
2022-05-24 02:23:37 +02:00
if ( g_pLauncher - > Setup ( eLaunchMode : : LM_SERVER_DEBUG , eLaunchState : : LS_CHEATS ) )
2022-05-23 19:14:12 +02:00
{
if ( g_pLauncher - > Launch ( ) )
{
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
}
Sleep ( 2000 ) ;
return EXIT_FAILURE ;
}
2022-05-24 02:23:37 +02:00
case eLaunchMode : : LM_SERVER :
2022-05-23 19:14:12 +02:00
{
2022-05-24 02:23:37 +02:00
if ( g_pLauncher - > Setup ( eLaunchMode : : LM_SERVER , eLaunchState : : LS_CHEATS ) )
2022-05-23 19:14:12 +02:00
{
if ( g_pLauncher - > Launch ( ) )
{
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
}
Sleep ( 2000 ) ;
return EXIT_FAILURE ;
}
default :
{
spdlog : : error ( " R5Reloaded requires '1' for DEBUG GAME mode, '2' for RELEASE GAME mode, '3' for DEBUG DEDICATED mode, '4' for RELEASE DEDICATED mode. \n " ) ;
Sleep ( 5000 ) ;
return EXIT_FAILURE ;
}
}
}
catch ( std : : exception & e )
{
spdlog : : error ( " R5Reloaded only takes numerical input to launch. Error: {}. \n " , e . what ( ) ) ;
2021-09-12 07:15:42 -07:00
Sleep ( 5000 ) ;
2021-08-19 15:26:44 +02:00
return EXIT_FAILURE ;
}
}
2022-05-23 19:14:12 +02:00
spdlog : : error ( " R5Reloaded requires numerical input to launch. \n " ) ;
2021-08-19 15:26:44 +02:00
2022-05-23 19:14:12 +02:00
Sleep ( 5000 ) ;
return EXIT_FAILURE ;
}
return EXIT_SUCCESS ;
2021-12-25 22:36:38 +01:00
}