Fix client.dll loading

* Moved dedicated server command line parameter init to 'init.cpp'.
* Registered 'SV_Main' on the client, this is engine code (lower level 'local' server wrappers).
* Disabled registration of Weapon_Bolt, although this is shared game code, this particular file is only used for the SERVER at this moment.
* Added the '-noserverdll' command lien parameter to instruct our loader.dll to load the client.dll instead.
* Adjusted the loader and sdklauncher project to support the loading of client.dll.
This commit is contained in:
Kawe Mazidjatari 2023-07-19 16:00:36 +02:00
parent a2d30e45f9
commit ddfaea6ce2
9 changed files with 107 additions and 86 deletions

View File

@ -159,18 +159,28 @@ add_custom_command( TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -P ${ENGINE_SOURCE_DIR}/cmake/PostBuild.cmake
)
if( NOT ${PROJECT_NAME} STREQUAL "dedicated" )
if( ${PROJECT_NAME} STREQUAL "dedicated" )
set_target_properties( ${PROJECT_NAME} PROPERTIES
VS_DEBUGGER_COMMAND "r5apex.exe"
VS_DEBUGGER_COMMAND "r5apex_ds.exe"
)
else()
set_target_properties( ${PROJECT_NAME} PROPERTIES
VS_DEBUGGER_COMMAND "r5apex_ds.exe"
VS_DEBUGGER_COMMAND "r5apex.exe"
)
endif()
if( ${PROJECT_NAME} STREQUAL "client" )
set_target_properties( ${PROJECT_NAME} PROPERTIES
VS_DEBUGGER_COMMAND_ARGUMENTS "-wconsole -ansicolor -dev -devsdk -noserverdll"
)
else()
set_target_properties( ${PROJECT_NAME} PROPERTIES
VS_DEBUGGER_COMMAND_ARGUMENTS "-wconsole -ansicolor -dev -devsdk"
VS_DEBUGGER_WORKING_DIRECTORY "$(ProjectDir)../../../${BUILD_OUTPUT_DIR}/"
)
endif()
set_target_properties( ${PROJECT_NAME} PROPERTIES
VS_DEBUGGER_COMMAND_ARGUMENTS "-wconsole -ansicolor -dev -devsdk"
VS_DEBUGGER_WORKING_DIRECTORY "$(ProjectDir)../../../${BUILD_OUTPUT_DIR}/"
)

View File

@ -196,6 +196,23 @@ void Systems_Init()
ConVar_StaticInit();
#ifdef DEDICATED
// These command line parameters disable a bunch of things in the engine that
// the dedicated server does not need, therefore, reducing a lot of overhead.
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", "");
#endif // DEDICATED
// Script context registration callbacks.
#ifndef CLIENT_DLL
ServerScriptRegister_Callback = Script_RegisterServerFunctions;
@ -537,11 +554,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
REGISTER(VGL_Screen);
#endif // !DEDICATED
#ifndef CLIENT_DLL
// !!! SERVER DLL ONLY !!!
REGISTER(HSV_Main);
// !!! END SERVER DLL ONLY !!!
#endif // !CLIENT_DLL
#ifndef DEDICATED
REGISTER(VGame); // REGISTER CLIENT ONLY!
@ -565,10 +578,11 @@ void DetourRegister() // Register detour classes to be searched and hooked.
REGISTER(VAnimation);
REGISTER(VUtil_Shared);
REGISTER(V_Weapon_Bolt);
#ifndef CLIENT_DLL
// In shared code, but weapon bolt is SERVER only.
REGISTER(V_Weapon_Bolt);
// Game/server
REGISTER(VAI_Network);
REGISTER(VAI_NetworkManager);

View File

@ -102,10 +102,10 @@ add_sources( SOURCE_GROUP "Server"
"server/persistence.h"
"server/server.cpp"
"server/server.h"
"server/sv_main.cpp"
"server/sv_main.h"
"server/sv_rcon.cpp"
"server/sv_rcon.h"
"server/sv_main.cpp"
"server/sv_main.h"
"server/vengineserver_impl.cpp"
"server/vengineserver_impl.h"
"server/datablock_sender.cpp"

View File

@ -192,20 +192,3 @@ void SV_BroadcastVoiceData(CClient* cl, int nBytes, char* data)
pClient->SendNetMsgEx(&voiceData, false, false, true);
}
}
///////////////////////////////////////////////////////////////////////////////
void HSV_Main::Attach(void) const
{
//DetourAttach(&v_SV_InitGameDLL, SV_InitGameDLL);
//DetourAttach(&v_SV_ShutdownGameDLL, SV_ShutdownGameDLL);
//DetourAttach(&v_SV_ActivateServer, SV_ActivateServer);
DetourAttach(&v_SV_BroadcastVoiceData, SV_BroadcastVoiceData);
}
void HSV_Main::Detach(void) const
{
//DetourDetach(&v_SV_InitGameDLL, SV_InitGameDLL);
//DetourDetach(&v_SV_ShutdownGameDLL, SV_ShutdownGameDLL);
//DetourDetach(&v_SV_ActivateServer, SV_ActivateServer);
DetourDetach(&v_SV_BroadcastVoiceData, SV_BroadcastVoiceData);
}

View File

@ -39,6 +39,7 @@ inline bool IsDedicated()
void SV_InitGameDLL();
void SV_ShutdownGameDLL();
bool SV_ActivateServer();
void SV_BroadcastVoiceData(CClient* cl, int nBytes, char* data);
void SV_IsClientBanned(CClient* pClient, const string& svIPAddr, const uint64_t nNucleusID, const string& svPersonaName, const int nPort);
void SV_CheckForBan(const BannedVec_t* pBannedVec = nullptr);
///////////////////////////////////////////////////////////////////////////////
@ -83,7 +84,25 @@ class HSV_Main : public IDetour
.FindPatternSelf("40 38 3D", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<bool*>();
}
virtual void GetCon(void) const { }
virtual void Attach(void) const;
virtual void Detach(void) const;
///////////////////////////////////////////////////////////////////////////////
virtual void Attach(void) const
{
//DetourAttach(&v_SV_InitGameDLL, SV_InitGameDLL);
//DetourAttach(&v_SV_ShutdownGameDLL, SV_ShutdownGameDLL);
//DetourAttach(&v_SV_ActivateServer, SV_ActivateServer);
#ifndef CLIENT_DLL
DetourAttach(&v_SV_BroadcastVoiceData, SV_BroadcastVoiceData);
#endif // !CLIENT_DLL
}
virtual void Detach(void) const
{
//DetourDetach(&v_SV_InitGameDLL, SV_InitGameDLL);
//DetourDetach(&v_SV_ShutdownGameDLL, SV_ShutdownGameDLL);
//DetourDetach(&v_SV_ActivateServer, SV_ActivateServer);
#ifndef CLIENT_DLL
DetourDetach(&v_SV_BroadcastVoiceData, SV_BroadcastVoiceData);
#endif // !CLIENT_DLL
}
};
///////////////////////////////////////////////////////////////////////////////

View File

@ -32,8 +32,6 @@ int LauncherMain(HINSTANCE hInstance)
// 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];
@ -56,29 +54,6 @@ void RemoveSpuriousGameParameters()
}
#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", "");
}
}
const char* ExitCodeToString(int nCode)
{
switch (nCode)

View File

@ -12,7 +12,6 @@ inline CMemory p_RemoveSpuriousGameParameters;
inline void*(*v_RemoveSpuriousGameParameters)(void);
#endif // !GAMEDLL_S0 || !GAMEDLL_S1
void AppendSDKParametersPreInit();
const char* ExitCodeToString(int nCode);
///////////////////////////////////////////////////////////////////////////////

View File

@ -47,7 +47,7 @@ static int (*v_WinMain)(HINSTANCE, HINSTANCE, LPSTR, int) = nullptr;
//-----------------------------------------------------------------------------
// Purpose: Terminates the process with an error when called
//-----------------------------------------------------------------------------
void FatalError(const char* fmt, ...)
static void FatalError(const char* fmt, ...)
{
va_list vArgs;
va_start(vArgs, fmt);
@ -65,7 +65,7 @@ void FatalError(const char* fmt, ...)
//-----------------------------------------------------------------------------
// Purpose: Loads the SDK module
//-----------------------------------------------------------------------------
void InitGameSDK(const LPSTR lpCmdLine)
static void InitGameSDK(const LPSTR lpCmdLine)
{
if (V_strstr(lpCmdLine, "-noworkerdll"))
return;
@ -78,13 +78,22 @@ void InitGameSDK(const LPSTR lpCmdLine)
// Prune the path.
const char* pModuleName = strrchr(moduleName, '\\') + 1;
const bool bDedicated = V_stricmp(pModuleName, SERVER_GAME_DLL) == NULL;
// The dedicated server has its own SDK module,
// so we need to check whether we are running
// the base game or the dedicated server.
if (V_stricmp(pModuleName, MAIN_GAME_DLL) == NULL)
s_SdkModule = LoadLibraryA(MAIN_WORKER_DLL);
else if (V_stricmp(pModuleName, SERVER_GAME_DLL) == NULL)
if (!bDedicated)
{
// Load the client dll if '-noserverdll' is passed,
// as this command lime parameter prevents the
// server dll from initializing in the engine.
if (V_strstr(lpCmdLine, "-noserverdll"))
s_SdkModule = LoadLibraryA(CLIENT_WORKER_DLL);
else
s_SdkModule = LoadLibraryA(MAIN_WORKER_DLL);
}
else
s_SdkModule = LoadLibraryA(SERVER_WORKER_DLL);
if (!s_SdkModule)
@ -103,6 +112,38 @@ int WINAPI hWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
return v_WinMain(hInstance, hPrevInstance, lpCmdLine, nShowCmd);
}
//-----------------------------------------------------------------------------
// Purpose: hooks the entry point
//-----------------------------------------------------------------------------
static void AttachEP()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&v_WinMain, &hWinMain);
HRESULT hr = DetourTransactionCommit();
if (hr != NO_ERROR) // Failed to hook into the process, terminate...
{
Assert(0);
FatalError("Failed to detour process: error code = %08x\n", hr);
}
}
//-----------------------------------------------------------------------------
// Purpose: unhooks the entry point
//-----------------------------------------------------------------------------
static void DetachEP()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&v_WinMain, &hWinMain);
HRESULT hr = DetourTransactionCommit();
Assert(hr != NO_ERROR);
}
//-----------------------------------------------------------------------------
// Purpose: APIENTRY
//-----------------------------------------------------------------------------
@ -120,36 +161,16 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
v_WinMain = CModule::GetExportedSymbol((QWORD)s_DosHeader, "WinMain")
.RCast<int (*)(HINSTANCE, HINSTANCE, LPSTR, int)>();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&v_WinMain, &hWinMain);
HRESULT hr = DetourTransactionCommit();
if (hr != NO_ERROR) // Failed to hook into the process, terminate...
{
Assert(0);
FatalError("Failed to detour process: error code = %08x\n", hr);
}
AttachEP();
break;
}
case DLL_PROCESS_DETACH:
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&v_WinMain, &hWinMain);
HRESULT hr = DetourTransactionCommit();
Assert(hr != NO_ERROR);
NOTE_UNUSED(hr);
if (s_SdkModule)
FreeLibrary(s_SdkModule);
DetachEP();
break;
}
}

View File

@ -1187,8 +1187,8 @@ eLaunchMode CSurface::BuildParameter(string& svParameters)
}
case eMode::CLIENT:
{
AppendParameterInternal(svParameters, "-noworkerdll"); // This prevents init of worker dll
//(this dll is always imported, but we want client.dll to do the work instead).
// Tells the loader module to only load the client dll.
AppendParameterInternal(svParameters, "-noserverdll");
// GAME ###############################################################
if (this->m_DeveloperToggle->Checked())