2021-09-12 07:15:42 -07:00
|
|
|
#include "pch.h"
|
2021-08-01 02:25:29 -07:00
|
|
|
#include "main.h"
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
2021-09-12 07:15:42 -07:00
|
|
|
// Print the error message to the console if any.
|
2021-08-01 02:25:29 -07:00
|
|
|
//----------------------------------------------------------------------------
|
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-09-12 07:15:42 -07:00
|
|
|
spdlog::error("{}", 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.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool LaunchR5Apex(LAUNCHMODE lMode, LAUNCHSTATE 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
|
|
|
{
|
2021-09-12 07:15:42 -07:00
|
|
|
case LAUNCHMODE::LM_DEBUG:
|
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
|
|
|
|
{
|
2021-09-12 07:15:42 -07: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.
|
|
|
|
|
2021-09-12 07:15:42 -07:00
|
|
|
WorkerDll = currentDirectory + "\\r5dev.dll"; // Get path to worker dll.
|
|
|
|
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;
|
|
|
|
}
|
2021-09-12 07:15:42 -07:00
|
|
|
case LAUNCHMODE::LM_RELEASE:
|
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
|
|
|
{
|
2021-09-12 07:15:42 -07: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-09-12 07:15:42 -07:00
|
|
|
WorkerDll = currentDirectory + "\\r5detours.dll"; // Get path to worker dll.
|
|
|
|
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;
|
|
|
|
}
|
2021-09-12 07:15:42 -07:00
|
|
|
case LAUNCHMODE::LM_DEDI:
|
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_dedi.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-09-12 07:15:42 -07:00
|
|
|
ss << cfgFile.rdbuf(); // Read ifstream buffer into stringstream.
|
2021-08-30 16:39:56 +02:00
|
|
|
CommandLineArguments = ss.str(); // Get all the contents of the cfg file.
|
|
|
|
}
|
|
|
|
else
|
2021-08-01 02:25:29 -07:00
|
|
|
{
|
2021-09-12 07:15:42 -07:00
|
|
|
spdlog::error("File 'platform\\cfg\\startup_dedi.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-09-12 07:15:42 -07:00
|
|
|
WorkerDll = currentDirectory + "\\dedicated.dll"; // Get path to worker dll.
|
2021-08-30 16:39:56 +02:00
|
|
|
GameDirectory = currentDirectory + "\\r5apex.exe"; // Get path to game executeable.
|
|
|
|
StartupCommandLine = currentDirectory + "\\r5apex.exe " + CommandLineArguments; // Setup startup command line string.
|
|
|
|
|
2021-09-12 07:15:42 -07:00
|
|
|
spdlog::info("*** LAUNCHING GAME [DEDICATED] ***\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.
|
|
|
|
std::cout << "--------------------------------------------------------------------------------------------------------" << std::endl;
|
|
|
|
spdlog::debug("- CWD: {}\n", currentDirectory);
|
|
|
|
spdlog::debug("- EXE: {}\n", GameDirectory);
|
|
|
|
spdlog::debug("- DLL: {}\n", WorkerDll);
|
|
|
|
spdlog::debug("- CLI: {}\n", CommandLineArguments);
|
|
|
|
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
|
|
|
{
|
2021-09-12 07:15:42 -07:00
|
|
|
LaunchR5Apex(LAUNCHMODE::LM_DEBUG, LAUNCHSTATE::LS_CHEATS);
|
2021-08-01 02:25:29 -07:00
|
|
|
Sleep(2000);
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
2021-08-19 15:26:44 +02:00
|
|
|
|
2021-09-12 07:15:42 -07:00
|
|
|
if ((arg == "-release") || (arg == "-rel"))
|
2021-08-01 02:25:29 -07:00
|
|
|
{
|
2021-09-12 07:15:42 -07:00
|
|
|
LaunchR5Apex(LAUNCHMODE::LM_RELEASE, LAUNCHSTATE::LS_CHEATS);
|
2021-08-01 02:25:29 -07:00
|
|
|
Sleep(2000);
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
2021-08-19 15:26:44 +02:00
|
|
|
|
2021-09-12 07:15:42 -07:00
|
|
|
if ((arg == "-dedicated") || (arg == "-dedi"))
|
2021-08-19 15:26:44 +02:00
|
|
|
{
|
2021-09-12 07:15:42 -07:00
|
|
|
LaunchR5Apex(LAUNCHMODE::LM_DEDI, LAUNCHSTATE::LS_CHEATS);
|
2021-08-19 15:26:44 +02:00
|
|
|
Sleep(2000);
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-12 07:15:42 -07:00
|
|
|
std::cout << "--------------------------------------------------------------------------------------------------------" << std::endl;
|
|
|
|
spdlog::warn("If DEBUG 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;
|
|
|
|
spdlog::warn("Use DEBUG [1] for development and debugging perposes.\n");
|
|
|
|
spdlog::warn("Use RELEASE [2] for normal playing and server hosting.\n");
|
|
|
|
spdlog::warn("Use DEDICATED [3] for running the server only without the client/ui components.\n");
|
|
|
|
std::cout << "--------------------------------------------------------------------------------------------------------" << std::endl;
|
|
|
|
spdlog::info("Enter 1 for DEBUG. Enter 2 for RELEASE. Enter 3 for DEDICATED: ");
|
2021-08-19 15:26:44 +02:00
|
|
|
|
|
|
|
std::string input = std::string();
|
|
|
|
if (std::cin >> input)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
LAUNCHMODE iinput = (LAUNCHMODE)std::stoi(input);
|
|
|
|
switch (iinput)
|
|
|
|
{
|
|
|
|
case LAUNCHMODE::LM_DEBUG:
|
|
|
|
{
|
|
|
|
LaunchR5Apex(LAUNCHMODE::LM_DEBUG, LAUNCHSTATE::LS_CHEATS);
|
|
|
|
Sleep(2000);
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
2021-09-12 07:15:42 -07:00
|
|
|
case LAUNCHMODE::LM_RELEASE:
|
2021-08-19 15:26:44 +02:00
|
|
|
{
|
2021-09-12 07:15:42 -07:00
|
|
|
LaunchR5Apex(LAUNCHMODE::LM_RELEASE, LAUNCHSTATE::LS_CHEATS);
|
2021-08-19 15:26:44 +02:00
|
|
|
Sleep(2000);
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
case LAUNCHMODE::LM_DEDI:
|
|
|
|
{
|
|
|
|
LaunchR5Apex(LAUNCHMODE::LM_DEDI, LAUNCHSTATE::LS_CHEATS);
|
|
|
|
Sleep(2000);
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
2021-09-12 07:15:42 -07:00
|
|
|
spdlog::error("R5Reloaded requires '1' for DEBUG mode, '2' for RELEASE mode, '3' for DEDICATED mode.\n");
|
|
|
|
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-08-19 15:26:44 +02: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-08-01 02:25:29 -07:00
|
|
|
}
|