2021-12-25 22:36:38 +01:00
# include "core/stdafx.h"
# include "sdklauncher.h"
2021-08-01 02:25:29 -07:00
2021-10-21 15:56:45 -07:00
//-----------------------------------------------------------------------------
// Print the error message to the console if any.
//-----------------------------------------------------------------------------
2021-04-13 04:45:22 -07:00
void PrintLastError ( )
{
DWORD errorMessageID = : : GetLastError ( ) ;
2021-08-30 16:39:56 +02:00
if ( errorMessageID ! = NULL )
2021-04-25 14:36:55 -07:00
{
2021-08-30 16:39:56 +02:00
LPSTR messageBuffer = nullptr ;
size_t size = FormatMessageA ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS ,
NULL , errorMessageID , MAKELANGID ( LANG_NEUTRAL , SUBLANG_DEFAULT ) , ( LPSTR ) & messageBuffer , 0 , NULL ) ;
2021-04-13 04:45:22 -07:00
2021-12-25 22:36:38 +01:00
spdlog : : error ( " {} \n " , messageBuffer ) ;
2021-08-30 16:39:56 +02:00
LocalFree ( messageBuffer ) ;
}
2021-04-13 04:45:22 -07:00
}
2021-08-01 02:25:29 -07:00
//-----------------------------------------------------------------------------
// Purpose case switch:
// * 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-01-16 12:48:56 +01:00
bool LaunchR5Apex ( eLaunchMode lMode , eLaunchState lState )
2021-04-13 04:45:22 -07:00
{
2021-06-17 17:07:26 -07:00
///////////////////////////////////////////////////////////////////////////
2021-08-30 16:39:56 +02:00
// Initialize strings.
std : : string WorkerDll = std : : string ( ) ;
std : : string GameDirectory = std : : string ( ) ;
std : : string CommandLineArguments = std : : string ( ) ;
std : : string StartupCommandLine = std : : string ( ) ;
std : : string currentDirectory = std : : filesystem : : current_path ( ) . u8string ( ) ;
2021-04-13 04:45:22 -07:00
2021-08-30 16:39:56 +02:00
///////////////////////////////////////////////////////////////////////////
// Determine launch mode.
2021-08-01 02:25:29 -07:00
switch ( lMode )
2021-04-13 05:05:29 -07:00
{
2022-01-16 12:48:56 +01:00
case eLaunchMode : : LM_DEBUG_GAME :
2021-04-25 14:36:55 -07:00
{
2021-09-12 07:15:42 -07:00
std : : filesystem : : path cfgPath = std : : filesystem : : current_path ( ) / = " platform \\ cfg \\ startup_debug.cfg " ; // Get cfg path for debug startup.
2021-08-30 16:39:56 +02:00
std : : ifstream cfgFile ( cfgPath ) ; // Read the cfg file.
2021-09-12 07:15:42 -07:00
if ( cfgFile . good ( ) & & cfgFile ) // Does the cfg file exist?
2021-08-01 02:25:29 -07:00
{
2021-08-30 16:39:56 +02:00
std : : stringstream ss ;
2021-09-12 07:15:42 -07:00
ss < < cfgFile . rdbuf ( ) ; // Read ifstream buffer into stringstream.
CommandLineArguments = ss . str ( ) ; // Get all the contents of the cfg file.
2021-08-01 02:25:29 -07:00
}
2021-08-30 16:39:56 +02:00
else
{
2022-01-16 12:48:56 +01:00
spdlog : : error ( " File 'platform \\ cfg \\ startup_debug.cfg' does not exist! \n " ) ;
2021-08-30 16:39:56 +02:00
cfgFile . close ( ) ;
return false ;
}
cfgFile . close ( ) ; // Close cfg file.
2022-01-09 16:29:36 +01:00
WorkerDll = currentDirectory + " \\ r5apexsdkd64.dll " ; // Get path to worker dll.
2021-09-12 07:15:42 -07:00
GameDirectory = currentDirectory + " \\ r5apex.exe " ; // Get path to game executeable.
StartupCommandLine = currentDirectory + " \\ r5apex.exe " + CommandLineArguments ; // Setup startup command line string.
2021-08-01 02:25:29 -07:00
2021-09-12 07:15:42 -07:00
spdlog : : info ( " *** LAUNCHING GAME [DEBUG] *** \n " ) ;
2021-08-01 02:25:29 -07:00
break ;
}
2022-01-16 12:48:56 +01:00
case eLaunchMode : : LM_RELEASE_GAME :
2021-08-01 02:25:29 -07:00
{
2021-09-12 07:15:42 -07:00
std : : filesystem : : path cfgPath = std : : filesystem : : current_path ( ) / = " platform \\ cfg \\ startup_retail.cfg " ; // Get cfg path for release startup.
2021-08-30 16:39:56 +02:00
std : : ifstream cfgFile ( cfgPath ) ; // Read the cfg file.
2021-09-12 07:15:42 -07:00
if ( cfgFile . good ( ) & & cfgFile ) // Does the cfg file exist?
2021-08-30 16:39:56 +02:00
{
std : : stringstream ss ;
2021-09-12 07:15:42 -07:00
ss < < cfgFile . rdbuf ( ) ; // Read ifstream buffer into stringstream.
CommandLineArguments = ss . str ( ) ; // Get all the contents of the cfg file.
2021-08-30 16:39:56 +02:00
}
else
2021-08-01 02:25:29 -07:00
{
2022-01-16 12:48:56 +01:00
spdlog : : error ( " File 'platform \\ cfg \\ startup_retail.cfg' does not exist! \n " ) ;
2021-08-30 16:39:56 +02:00
cfgFile . close ( ) ;
return false ;
2021-08-01 02:25:29 -07:00
}
2021-08-30 16:39:56 +02:00
cfgFile . close ( ) ; // Close cfg file.
2021-08-01 02:25:29 -07:00
2021-12-25 22:36:38 +01:00
WorkerDll = currentDirectory + " \\ r5apexsdkd64.dll " ; // Get path to worker dll.
2021-09-12 07:15:42 -07:00
GameDirectory = currentDirectory + " \\ r5apex.exe " ; // Get path to game executeable.
StartupCommandLine = currentDirectory + " \\ r5apex.exe " + CommandLineArguments ; // Setup startup command line string.
2021-08-30 16:39:56 +02:00
2021-09-12 07:15:42 -07:00
spdlog : : info ( " *** LAUNCHING GAME [RELEASE] *** \n " ) ;
2021-08-01 02:25:29 -07:00
break ;
}
2022-01-16 12:48:56 +01:00
case eLaunchMode : : LM_DEBUG_DEDI :
2021-08-01 02:25:29 -07:00
{
2022-01-16 12:48:56 +01:00
std : : filesystem : : path cfgPath = std : : filesystem : : current_path ( ) / = " platform \\ cfg \\ startup_dedi_debug.cfg " ; // Get cfg path for dedicated startup.
2021-08-30 16:39:56 +02:00
std : : ifstream cfgFile ( cfgPath ) ; // Read the cfg file.
2021-09-12 07:15:42 -07:00
if ( cfgFile . good ( ) & & cfgFile ) // Does the cfg file exist?
2021-08-30 16:39:56 +02:00
{
std : : stringstream ss ;
2021-12-25 22:36:38 +01:00
ss < < cfgFile . rdbuf ( ) ; // Read ifstream buffer into stringstream.
CommandLineArguments = ss . str ( ) ; // Get all the contents of the cfg file.
2021-08-30 16:39:56 +02:00
}
else
2021-08-01 02:25:29 -07:00
{
2022-01-16 12:48:56 +01:00
spdlog : : error ( " File 'platform \\ cfg \\ startup_dedi_debug.cfg' does not exist! \n " ) ;
2021-08-30 16:39:56 +02:00
cfgFile . close ( ) ;
return false ;
2021-08-01 02:25:29 -07:00
}
2021-08-30 16:39:56 +02:00
cfgFile . close ( ) ; // Close cfg file.
2021-08-01 02:25:29 -07:00
2022-01-09 16:29:36 +01:00
WorkerDll = currentDirectory + " \\ dedicated.dll " ; // Get path to worker dll.
2021-12-29 02:16:21 +01:00
GameDirectory = currentDirectory + " \\ r5apex_ds.exe " ; // Get path to game executeable.
StartupCommandLine = currentDirectory + " \\ r5apex_ds.exe " + CommandLineArguments ; // Setup startup command line string.
2021-08-30 16:39:56 +02:00
2022-01-16 12:48:56 +01:00
spdlog : : info ( " *** LAUNCHING DEDICATED [DEBUG] *** \n " ) ;
break ;
}
case eLaunchMode : : LM_RELEASE_DEDI :
{
std : : filesystem : : path cfgPath = std : : filesystem : : current_path ( ) / = " platform \\ cfg \\ startup_dedi_retail.cfg " ; // Get cfg path for dedicated startup.
std : : ifstream cfgFile ( cfgPath ) ; // Read the cfg file.
if ( cfgFile . good ( ) & & cfgFile ) // Does the cfg file exist?
{
std : : stringstream ss ;
ss < < cfgFile . rdbuf ( ) ; // Read ifstream buffer into stringstream.
CommandLineArguments = ss . str ( ) ; // Get all the contents of the cfg file.
}
else
{
spdlog : : error ( " File 'platform \\ cfg \\ startup_dedi_retail.cfg' does not exist! \n " ) ;
cfgFile . close ( ) ;
return false ;
}
cfgFile . close ( ) ; // Close cfg file.
WorkerDll = currentDirectory + " \\ dedicated.dll " ; // Get path to worker dll.
GameDirectory = currentDirectory + " \\ r5apex_ds.exe " ; // Get path to game executeable.
StartupCommandLine = currentDirectory + " \\ r5apex_ds.exe " + CommandLineArguments ; // Setup startup command line string.
spdlog : : info ( " *** LAUNCHING DEDICATED [RELEASE] *** \n " ) ;
2021-08-01 02:25:29 -07:00
break ;
}
default :
{
2021-09-12 07:15:42 -07:00
spdlog : : error ( " *** NO LAUNCH MODE SPECIFIED *** \n " ) ;
2021-08-01 02:25:29 -07:00
return false ;
2021-04-25 14:36:55 -07:00
}
2021-04-13 05:05:29 -07:00
}
2021-06-17 17:07:26 -07:00
///////////////////////////////////////////////////////////////////////////
2021-09-12 07:15:42 -07:00
// Print the file paths and arguments.
2022-01-16 12:48:56 +01:00
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
2021-09-12 07:15:42 -07:00
spdlog : : debug ( " - CWD: {} \n " , currentDirectory ) ;
spdlog : : debug ( " - EXE: {} \n " , GameDirectory ) ;
spdlog : : debug ( " - DLL: {} \n " , WorkerDll ) ;
spdlog : : debug ( " - CLI: {} \n " , CommandLineArguments ) ;
2022-01-16 12:48:56 +01:00
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
2021-04-13 04:45:22 -07:00
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 ] =
{
2021-08-30 16:39:56 +02:00
WorkerDll . c_str ( )
2021-04-13 04:45:22 -07:00
} ;
2021-08-30 16:39:56 +02:00
STARTUPINFO StartupInfo = { 0 } ;
PROCESS_INFORMATION ProcInfo = { 0 } ;
// Initialize startup info struct.
StartupInfo . cb = sizeof ( STARTUPINFO ) ;
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
(
GameDirectory . c_str ( ) , // lpApplicationName
( LPSTR ) StartupCommandLine . c_str ( ) , // lpCommandLine
NULL , // lpProcessAttributes
NULL , // lpThreadAttributes
FALSE , // bInheritHandles
CREATE_SUSPENDED , // dwCreationFlags
NULL , // lpEnvironment
currentDirectory . c_str ( ) , // lpCurrentDirectory
& 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 ) ;
2021-08-01 02:25:29 -07:00
for ( int i = 1 ; i < argc ; + + i )
{
std : : string arg = argv [ i ] ;
2021-09-12 07:15:42 -07:00
if ( ( arg = = " -debug " ) | | ( arg = = " -dbg " ) )
2021-08-01 02:25:29 -07:00
{
2022-01-16 12:48:56 +01:00
LaunchR5Apex ( eLaunchMode : : LM_DEBUG_GAME , eLaunchState : : LS_CHEATS ) ;
2021-08-01 02:25:29 -07:00
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
2021-09-12 07:15:42 -07:00
if ( ( arg = = " -release " ) | | ( arg = = " -rel " ) )
2021-08-01 02:25:29 -07:00
{
2022-01-16 12:48:56 +01:00
LaunchR5Apex ( eLaunchMode : : LM_RELEASE_GAME , eLaunchState : : LS_CHEATS ) ;
2021-08-01 02:25:29 -07:00
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
2021-09-12 07:15:42 -07:00
if ( ( arg = = " -dedicated " ) | | ( arg = = " -dedi " ) )
2021-08-19 15:26:44 +02:00
{
2022-01-16 12:48:56 +01:00
LaunchR5Apex ( eLaunchMode : : LM_DEBUG_DEDI , eLaunchState : : LS_CHEATS ) ;
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
if ( ( arg = = " -dedicated_dev " ) | | ( arg = = " -dedid " ) )
{
LaunchR5Apex ( eLaunchMode : : LM_DEBUG_DEDI , eLaunchState : : LS_CHEATS ) ;
2021-08-19 15:26:44 +02:00
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
}
2022-01-16 12:48:56 +01: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 " ) ;
2021-09-12 07:15:42 -07:00
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 " ) ;
2022-01-16 12:48:56 +01:00
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
spdlog : : warn ( " Use DEBUG GAME [1] for research and development purposes. \n " ) ;
spdlog : : warn ( " Use RELEASE GAME [2] for playing the game and creating servers. \n " ) ;
spdlog : : warn ( " Use DEBUG DEDICATED [3] for research and development purposes. \n " ) ;
2022-01-19 19:03:59 +01:00
spdlog : : warn ( " Use RELEASE DEDICATED [4] for running and hosting dedicated servers. \n " ) ;
2022-01-16 12:48:56 +01:00
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
spdlog : : info ( " Enter '1' for 'DEBUG GAME'. \n " ) ;
spdlog : : info ( " Enter '2' for 'RELEASE GAME'. \n " ) ;
spdlog : : info ( " Enter '3' for 'DEBUG DEDICATED'. \n " ) ;
spdlog : : info ( " Enter '4' for 'RELEASE DEDICATED'. \n " ) ;
std : : cout < < " ---------------------------------------------------------------------------------------------------------------------- " < < std : : endl ;
std : : cout < < " User input: " ;
2021-08-19 15:26:44 +02:00
std : : string input = std : : string ( ) ;
if ( std : : cin > > input )
{
try
{
2022-01-16 12:48:56 +01:00
eLaunchMode iinput = ( eLaunchMode ) std : : stoi ( input ) ;
2021-08-19 15:26:44 +02:00
switch ( iinput )
{
2022-01-16 12:48:56 +01:00
case eLaunchMode : : LM_DEBUG_GAME :
{
LaunchR5Apex ( eLaunchMode : : LM_DEBUG_GAME , eLaunchState : : LS_CHEATS ) ;
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
case eLaunchMode : : LM_RELEASE_GAME :
2021-08-19 15:26:44 +02:00
{
2022-01-16 12:48:56 +01:00
LaunchR5Apex ( eLaunchMode : : LM_RELEASE_GAME , eLaunchState : : LS_CHEATS ) ;
2021-08-19 15:26:44 +02:00
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
2022-01-16 12:48:56 +01:00
case eLaunchMode : : LM_DEBUG_DEDI :
2021-08-19 15:26:44 +02:00
{
2022-01-16 12:48:56 +01:00
LaunchR5Apex ( eLaunchMode : : LM_DEBUG_DEDI , eLaunchState : : LS_CHEATS ) ;
2021-08-19 15:26:44 +02:00
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
2022-01-16 12:48:56 +01:00
case eLaunchMode : : LM_RELEASE_DEDI :
2021-08-19 15:26:44 +02:00
{
2022-01-16 12:48:56 +01:00
LaunchR5Apex ( eLaunchMode : : LM_DEBUG_DEDI , eLaunchState : : LS_CHEATS ) ;
2021-08-19 15:26:44 +02:00
Sleep ( 2000 ) ;
return EXIT_SUCCESS ;
}
default :
{
2022-01-16 12:48:56 +01:00
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 " ) ;
2021-09-12 07:15:42 -07:00
Sleep ( 5000 ) ;
2021-08-19 15:26:44 +02:00
return EXIT_FAILURE ;
}
}
}
catch ( std : : exception & e )
{
2021-09-12 07:15:42 -07:00
spdlog : : error ( " R5Reloaded only takes numerical input to launch. Error: {}. \n " , e . what ( ) ) ;
2021-08-19 15:26:44 +02:00
Sleep ( 5000 ) ;
return EXIT_FAILURE ;
}
2021-08-01 02:25:29 -07:00
}
2021-09-12 07:15:42 -07:00
spdlog : : error ( " R5Reloaded requires numerical input to launch. \n " ) ;
2021-08-19 15:26:44 +02:00
Sleep ( 5000 ) ;
return EXIT_FAILURE ;
2021-12-25 22:36:38 +01:00
}