mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
This occurs when the game's unhandled exception handler is getting called after ours. both will create a crashmsg process. This happened as CCrashHandler::End() was called before the in-game exception filter was fired, and therefore CCrashHandler::Handled would return false, and this fire the in-game exception filter. This commit removes the additional check, we just use our vectored exception handler entirely over the game's one, as this one captures everything an unhandled exception handler will capture, and more. The 'Handled' function/fields in CCrashHandler have been renamed to 'Handling', as this is a more appropriate name.
193 lines
5.5 KiB
C++
193 lines
5.5 KiB
C++
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
|
//
|
|
// Purpose: Defines the entry point for the application.
|
|
//
|
|
// $NoKeywords: $
|
|
//===========================================================================//
|
|
#include "core/stdafx.h"
|
|
#include "core/logdef.h"
|
|
#include "tier0/crashhandler.h"
|
|
#include "tier0/commandline.h"
|
|
#include "tier1/strtools.h"
|
|
#include "launcher/launcher.h"
|
|
#include <eiface.h>
|
|
|
|
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)
|
|
return v_WinMain(hInstance, hPrevInstance, const_cast<LPSTR>(g_svCmdLine.c_str()), nShowCmd);
|
|
#else
|
|
return v_WinMain(hInstance, hPrevInstance, lpCmdLine, nShowCmd);
|
|
#endif
|
|
}
|
|
|
|
int LauncherMain(HINSTANCE hInstance)
|
|
{
|
|
SpdLog_PostInit();
|
|
|
|
int results = v_LauncherMain(hInstance);
|
|
spdlog::info("{:s} returned: {:s}\n", __FUNCTION__, ExitCodeToString(results));
|
|
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
|
|
// its own -game parameter, which would supersede the one we really want if we didn't intercede here.
|
|
void RemoveSpuriousGameParameters()
|
|
{
|
|
AppendSDKParametersPreInit();
|
|
|
|
// Find the last -game parameter.
|
|
int nGameArgs = 0;
|
|
char lastGameArg[MAX_PATH];
|
|
for (int i = 0; i < CommandLine()->ParmCount() - 1; i++)
|
|
{
|
|
if (Q_stricmp(CommandLine()->GetParm(i), "-game") == 0)
|
|
{
|
|
Q_snprintf(lastGameArg, sizeof(lastGameArg), "\"%s\"", CommandLine()->GetParm(i + 1));
|
|
++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()
|
|
{
|
|
const bool bDedicated = IsDedicated();
|
|
if (bDedicated)
|
|
{
|
|
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", "");
|
|
}
|
|
|
|
// Assume default configs if the game isn't launched with the SDKLauncher.
|
|
if (!CommandLine()->FindParm("-launcher"))
|
|
{
|
|
ParseAndApplyConfigFile(g_svCmdLine);
|
|
}
|
|
}
|
|
|
|
string LoadConfigFile(const char* svConfig)
|
|
{
|
|
fs::path cfgPath = fs::current_path() /= svConfig; // Get cfg path for default startup.
|
|
|
|
if (!FileExists(cfgPath))
|
|
{
|
|
// Load it from PLATFORM.
|
|
cfgPath = fs::current_path() /= string("platform/") + svConfig;
|
|
}
|
|
|
|
ifstream cfgFile(cfgPath);
|
|
|
|
if (!cfgFile)
|
|
{
|
|
spdlog::error("{:s}: '{:s}' does not exist!\n", __FUNCTION__, svConfig);
|
|
return "";
|
|
}
|
|
|
|
string svArguments;
|
|
stringstream ss;
|
|
ss << cfgFile.rdbuf();
|
|
svArguments = ss.str();
|
|
|
|
return svArguments;
|
|
}
|
|
|
|
void ParseAndApplyConfigFile(const string& svConfig)
|
|
{
|
|
stringstream ss(svConfig);
|
|
string svInput;
|
|
|
|
if (!svConfig.empty())
|
|
{
|
|
while (std::getline(ss, svInput, '\n'))
|
|
{
|
|
string::size_type nPos = svInput.find(' ');
|
|
if (!svInput.empty()
|
|
&& nPos > 0
|
|
&& nPos < svInput.size()
|
|
&& nPos != svInput.size())
|
|
{
|
|
string svValue = svInput.substr(nPos + 1);
|
|
string svArgument = svInput.erase(svInput.find(' '));
|
|
|
|
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:
|
|
return "EXIT_FAILURE";
|
|
default:
|
|
return "UNKNOWN_EXIT_CODE";
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return v_TopLevelExceptionFilter(pExceptionPointers);
|
|
}
|
|
|
|
void VLauncher::Attach(void) const
|
|
{
|
|
DetourAttach((LPVOID*)&v_WinMain, &HWinMain);
|
|
DetourAttach((LPVOID*)&v_LauncherMain, &LauncherMain);
|
|
DetourAttach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter);
|
|
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
|
|
DetourAttach((LPVOID*)&v_RemoveSpuriousGameParameters, &RemoveSpuriousGameParameters);
|
|
#endif
|
|
}
|
|
void VLauncher::Detach(void) const
|
|
{
|
|
DetourDetach((LPVOID*)&v_WinMain, &HWinMain);
|
|
DetourDetach((LPVOID*)&v_LauncherMain, &LauncherMain);
|
|
DetourDetach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter);
|
|
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
|
|
DetourDetach((LPVOID*)&v_RemoveSpuriousGameParameters, &RemoveSpuriousGameParameters);
|
|
#endif
|
|
} |