2022-04-16 00:30:46 +02:00
|
|
|
|
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
|
|
|
|
//
|
|
|
|
|
// Purpose: Defines the entry point for the application.
|
|
|
|
|
//
|
|
|
|
|
// $NoKeywords: $
|
|
|
|
|
//===========================================================================//
|
|
|
|
|
#include "core/stdafx.h"
|
2023-03-18 21:42:30 +01:00
|
|
|
|
#include "core/logdef.h"
|
2023-01-31 22:13:40 +01:00
|
|
|
|
#include "tier0/crashhandler.h"
|
2022-04-16 00:30:46 +02:00
|
|
|
|
#include "tier0/commandline.h"
|
2022-08-20 03:15:51 +02:00
|
|
|
|
#include "tier1/strtools.h"
|
2022-04-16 00:30:46 +02:00
|
|
|
|
#include "launcher/launcher.h"
|
2023-05-13 18:07:05 +02:00
|
|
|
|
#include <eiface.h>
|
2022-04-16 00:30:46 +02:00
|
|
|
|
|
|
|
|
|
int HWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
|
|
|
|
{
|
|
|
|
|
// !TODO [AMOS]: 'RemoveSpuriousGameParameters()' is inline with 'LauncherMain()' in S0 and S1,
|
|
|
|
|
// and its the only function where we could append our own command line parameters early enough
|
|
|
|
|
// programatically (has to be after 'CommandLine()->CreateCmdLine()', but before 'SetPriorityClass()')
|
|
|
|
|
// For S0 and S1 we should modify the command line buffer passed to the entry point instead (here).
|
|
|
|
|
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
2023-06-01 23:44:55 +02:00
|
|
|
|
return v_WinMain(hInstance, hPrevInstance, const_cast<LPSTR>(g_svCmdLine.c_str()), nShowCmd);
|
2022-04-16 00:30:46 +02:00
|
|
|
|
#else
|
|
|
|
|
return v_WinMain(hInstance, hPrevInstance, lpCmdLine, nShowCmd);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int LauncherMain(HINSTANCE hInstance)
|
|
|
|
|
{
|
2023-03-18 21:42:30 +01:00
|
|
|
|
SpdLog_PostInit();
|
|
|
|
|
|
2022-04-16 00:30:46 +02:00
|
|
|
|
int results = v_LauncherMain(hInstance);
|
2023-03-20 00:21:41 +01:00
|
|
|
|
spdlog::info("{:s} returned: {:s}\n", __FUNCTION__, ExitCodeToString(results));
|
2022-04-16 00:30:46 +02:00
|
|
|
|
return results;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !defined (GAMEDLL_S0) || !defined (GAMEDLL_S1)
|
|
|
|
|
// Remove all but the last -game parameter.
|
|
|
|
|
// This is for mods based off something other than Half-Life 2 (like HL2MP mods).
|
|
|
|
|
// The Steam UI does 'steam -applaunch 320 -game c:\steam\steamapps\sourcemods\modname', but applaunch inserts
|
2022-09-09 19:47:31 +02:00
|
|
|
|
// its own -game parameter, which would supersede the one we really want if we didn't intercede here.
|
2022-04-16 00:30:46 +02:00
|
|
|
|
void RemoveSpuriousGameParameters()
|
|
|
|
|
{
|
|
|
|
|
AppendSDKParametersPreInit();
|
|
|
|
|
|
|
|
|
|
// Find the last -game parameter.
|
|
|
|
|
int nGameArgs = 0;
|
|
|
|
|
char lastGameArg[MAX_PATH];
|
|
|
|
|
for (int i = 0; i < CommandLine()->ParmCount() - 1; i++)
|
|
|
|
|
{
|
2022-08-20 03:15:51 +02:00
|
|
|
|
if (Q_stricmp(CommandLine()->GetParm(i), "-game") == 0)
|
2022-04-16 00:30:46 +02:00
|
|
|
|
{
|
2022-08-20 03:15:51 +02:00
|
|
|
|
Q_snprintf(lastGameArg, sizeof(lastGameArg), "\"%s\"", CommandLine()->GetParm(i + 1));
|
2022-04-16 00:30:46 +02:00
|
|
|
|
++nGameArgs;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We only care if > 1 was specified.
|
|
|
|
|
if (nGameArgs > 1)
|
|
|
|
|
{
|
|
|
|
|
CommandLine()->RemoveParm("-game");
|
|
|
|
|
CommandLine()->AppendParm("-game", lastGameArg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Append required command line parameters.
|
|
|
|
|
// This avoids having all these in the startup configuration files
|
|
|
|
|
// as all there are required to run the game with the game sdk.
|
|
|
|
|
void AppendSDKParametersPreInit()
|
|
|
|
|
{
|
2023-06-01 23:44:55 +02:00
|
|
|
|
const bool bDedicated = IsDedicated();
|
|
|
|
|
if (bDedicated)
|
2023-05-13 18:07:05 +02:00
|
|
|
|
{
|
|
|
|
|
CommandLine()->AppendParm("-collate", "");
|
|
|
|
|
CommandLine()->AppendParm("-multiple", "");
|
|
|
|
|
CommandLine()->AppendParm("-noorigin", "");
|
|
|
|
|
CommandLine()->AppendParm("-nodiscord", "");
|
|
|
|
|
CommandLine()->AppendParm("-noshaderapi", "");
|
|
|
|
|
CommandLine()->AppendParm("-nobakedparticles", "");
|
|
|
|
|
CommandLine()->AppendParm("-novid", "");
|
|
|
|
|
CommandLine()->AppendParm("-nomenuvid", "");
|
|
|
|
|
CommandLine()->AppendParm("-nosound", "");
|
|
|
|
|
CommandLine()->AppendParm("-nomouse", "");
|
|
|
|
|
CommandLine()->AppendParm("-nojoy", "");
|
|
|
|
|
CommandLine()->AppendParm("-nosendtable", "");
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-16 00:30:46 +02:00
|
|
|
|
// Assume default configs if the game isn't launched with the SDKLauncher.
|
|
|
|
|
if (!CommandLine()->FindParm("-launcher"))
|
|
|
|
|
{
|
2023-06-01 23:44:55 +02:00
|
|
|
|
ParseAndApplyConfigFile(g_svCmdLine);
|
2022-04-16 00:30:46 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-01 23:44:55 +02:00
|
|
|
|
string LoadConfigFile(const char* svConfig)
|
2022-04-16 00:30:46 +02:00
|
|
|
|
{
|
|
|
|
|
fs::path cfgPath = fs::current_path() /= svConfig; // Get cfg path for default startup.
|
|
|
|
|
|
2023-06-01 23:44:55 +02:00
|
|
|
|
if (!FileExists(cfgPath))
|
2022-04-16 00:30:46 +02:00
|
|
|
|
{
|
2023-06-01 23:44:55 +02:00
|
|
|
|
// Load it from PLATFORM.
|
|
|
|
|
cfgPath = fs::current_path() /= string("platform/") + svConfig;
|
2022-04-16 00:30:46 +02:00
|
|
|
|
}
|
2023-06-01 23:44:55 +02:00
|
|
|
|
|
|
|
|
|
ifstream cfgFile(cfgPath);
|
|
|
|
|
|
|
|
|
|
if (!cfgFile)
|
2022-04-16 00:30:46 +02:00
|
|
|
|
{
|
2022-06-17 18:29:17 +02:00
|
|
|
|
spdlog::error("{:s}: '{:s}' does not exist!\n", __FUNCTION__, svConfig);
|
2022-04-16 00:30:46 +02:00
|
|
|
|
return "";
|
|
|
|
|
}
|
2023-06-01 23:44:55 +02:00
|
|
|
|
|
|
|
|
|
string svArguments;
|
|
|
|
|
stringstream ss;
|
|
|
|
|
ss << cfgFile.rdbuf();
|
|
|
|
|
svArguments = ss.str();
|
2022-04-16 00:30:46 +02:00
|
|
|
|
|
|
|
|
|
return svArguments;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ParseAndApplyConfigFile(const string& svConfig)
|
|
|
|
|
{
|
|
|
|
|
stringstream ss(svConfig);
|
|
|
|
|
string svInput;
|
|
|
|
|
|
2022-08-11 11:07:45 +02:00
|
|
|
|
if (!svConfig.empty())
|
2022-04-16 00:30:46 +02:00
|
|
|
|
{
|
|
|
|
|
while (std::getline(ss, svInput, '\n'))
|
|
|
|
|
{
|
2022-06-07 13:46:09 +02:00
|
|
|
|
string::size_type nPos = svInput.find(' ');
|
2022-04-16 00:30:46 +02:00
|
|
|
|
if (!svInput.empty()
|
|
|
|
|
&& nPos > 0
|
|
|
|
|
&& nPos < svInput.size()
|
|
|
|
|
&& nPos != svInput.size())
|
|
|
|
|
{
|
|
|
|
|
string svValue = svInput.substr(nPos + 1);
|
2022-06-07 13:46:09 +02:00
|
|
|
|
string svArgument = svInput.erase(svInput.find(' '));
|
2022-04-16 00:30:46 +02:00
|
|
|
|
|
|
|
|
|
CommandLine()->AppendParm(svArgument.c_str(), svValue.c_str());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CommandLine()->AppendParm(svInput.c_str(), "");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char* ExitCodeToString(int nCode)
|
|
|
|
|
{
|
|
|
|
|
switch (nCode)
|
|
|
|
|
{
|
|
|
|
|
case EXIT_SUCCESS:
|
|
|
|
|
return "EXIT_SUCCESS";
|
|
|
|
|
case EXIT_FAILURE:
|
2022-04-16 12:51:28 +02:00
|
|
|
|
return "EXIT_FAILURE";
|
2022-04-16 00:30:46 +02:00
|
|
|
|
default:
|
2022-12-28 21:44:51 +01:00
|
|
|
|
return "UNKNOWN_EXIT_CODE";
|
2022-04-16 00:30:46 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-28 21:44:51 +01:00
|
|
|
|
LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* pExceptionPointers)
|
|
|
|
|
{
|
|
|
|
|
// Don't run the unhandled exception filter from the
|
|
|
|
|
// game if we have a valid vectored exception filter.
|
|
|
|
|
if (g_CrashHandler && g_CrashHandler->Handled())
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return v_TopLevelExceptionFilter(pExceptionPointers);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-25 02:26:52 +01:00
|
|
|
|
void VLauncher::Attach(void) const
|
2022-04-16 00:30:46 +02:00
|
|
|
|
{
|
|
|
|
|
DetourAttach((LPVOID*)&v_WinMain, &HWinMain);
|
|
|
|
|
DetourAttach((LPVOID*)&v_LauncherMain, &LauncherMain);
|
2022-12-28 21:44:51 +01:00
|
|
|
|
DetourAttach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter);
|
2022-04-19 00:00:45 +02:00
|
|
|
|
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
|
2022-04-16 00:30:46 +02:00
|
|
|
|
DetourAttach((LPVOID*)&v_RemoveSpuriousGameParameters, &RemoveSpuriousGameParameters);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2023-01-25 02:26:52 +01:00
|
|
|
|
void VLauncher::Detach(void) const
|
2022-04-16 00:30:46 +02:00
|
|
|
|
{
|
|
|
|
|
DetourDetach((LPVOID*)&v_WinMain, &HWinMain);
|
|
|
|
|
DetourDetach((LPVOID*)&v_LauncherMain, &LauncherMain);
|
2022-12-28 21:44:51 +01:00
|
|
|
|
DetourDetach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter);
|
2022-04-19 00:00:45 +02:00
|
|
|
|
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
|
2022-04-16 00:30:46 +02:00
|
|
|
|
DetourDetach((LPVOID*)&v_RemoveSpuriousGameParameters, &RemoveSpuriousGameParameters);
|
|
|
|
|
#endif
|
|
|
|
|
}
|