From e1a81e3c06c3949c045e19b7d671369bc72a475c Mon Sep 17 00:00:00 2001 From: Nick Hastings Date: Sun, 21 May 2023 12:07:05 -0400 Subject: [PATCH] Improve CS2 support and S2 game detection --- AMBuildScript | 10 ++--- core/provider/source2/provider_source2.cpp | 4 +- loader/gamedll.cpp | 11 ++++- loader/loader.cpp | 52 ++++++++++++++++------ loader/loader.h | 5 ++- loader/serverplugin.cpp | 5 +-- 6 files changed, 60 insertions(+), 27 deletions(-) diff --git a/AMBuildScript b/AMBuildScript index 930cbd3..7e4a71c 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -78,7 +78,7 @@ PossibleSDKs = { 'mock': SDK('HL2SDK-MOCK', '2.mock', '999', 'MOCK', Mock, 'mock'), 'pvkii': SDK('HL2SDKPVKII', '2.pvkii', '10', 'PVKII', WinLinux, 'pvkii'), 'dota': SDK('HL2SDKDOTA', '2.dota', '24', 'DOTA', Source2, 'dota'), - 'cs2': SDK('HL2SDKCS2', '2.cs2', '25', 'CS2', [], 'cs2'), + 'cs2': SDK('HL2SDKCS2', '2.cs2', '25', 'CS2', Source2, 'cs2'), } def ResolveEnvPath(env, folder): @@ -391,7 +391,7 @@ class MMSConfig(object): if compiler.target.arch == 'x86_64': compiler.defines += ['X64BITS', 'PLATFORM_64BITS'] - if sdk.name in ['css', 'hl2dm', 'dods', 'sdk2013', 'bms', 'tf2', 'l4d', 'nucleardawn', 'l4d2', 'dota', 'pvkii']: + if sdk.name in ['css', 'hl2dm', 'dods', 'sdk2013', 'bms', 'tf2', 'l4d', 'nucleardawn', 'l4d2', 'dota', 'cs2', 'pvkii']: if compiler.target.platform in ['linux', 'mac']: compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE'] @@ -475,7 +475,7 @@ class MMSConfig(object): compiler.linkflags += ['-Wl,-z,origin'] compiler.postlink += [tier1] - if sdk.name in ['blade', 'insurgency', 'doi', 'csgo', 'dota']: + if sdk.name in ['blade', 'insurgency', 'doi', 'csgo', 'cs2', 'dota']: if compiler.target.arch == 'x86_64': compiler.postlink += [os.path.join(lib_folder, 'interfaces.a')] else: @@ -494,7 +494,7 @@ class MMSConfig(object): dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so'] elif compiler.target.arch == 'x86_64' and sdk.name in ['csgo', 'mock']: dynamic_libs = ['libtier0_client.so', 'libvstdlib_client.so'] - elif sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo', 'dota', 'pvkii']: + elif sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo', 'cs2', 'dota', 'pvkii']: dynamic_libs = ['libtier0.so'] if sdk.name not in ['dota', 'cs2']: dynamic_libs += ['libvstdlib.so'] @@ -509,7 +509,7 @@ class MMSConfig(object): libs = ['tier0', 'tier1'] if sdk.name not in ['dota', 'cs2']: libs += ['vstdlib'] - if sdk.name in ['swarm', 'blade', 'insurgency', 'doi', 'mcv', 'csgo', 'dota']: + if sdk.name in ['swarm', 'blade', 'insurgency', 'doi', 'mcv', 'csgo', 'cs2', 'dota']: libs.append('interfaces') if sdk.name == 'bms': libs.append('mathlib') diff --git a/core/provider/source2/provider_source2.cpp b/core/provider/source2/provider_source2.cpp index d81d3f3..13502fd 100644 --- a/core/provider/source2/provider_source2.cpp +++ b/core/provider/source2/provider_source2.cpp @@ -215,7 +215,9 @@ const char* Source2Provider::GetEngineDescription() const void Source2Provider::GetGamePath(char* pszBuffer, int len) { - ke::SafeSprintf(pszBuffer, len, "%s", Plat_GetGameDirectory()); + CBufferStringGrowable buf; + engine->GetGameDir(buf); + ke::SafeSprintf(pszBuffer, len, "%s", buf.Get()); } const char* Source2Provider::GetGameDescription() diff --git a/loader/gamedll.cpp b/loader/gamedll.cpp index 66b9c5d..8bf062b 100644 --- a/loader/gamedll.cpp +++ b/loader/gamedll.cpp @@ -328,7 +328,14 @@ public: virtual InitReturnVal_t Init() { - mm_backend = MMBackend_DOTA; + if (!stricmp("csgo", game_name)) + { + mm_backend = MMBackend_CS2; + } + else + { + mm_backend = MMBackend_DOTA; + } char error[255]; if (!mm_LoadMetamodLibrary(mm_backend, error, sizeof(error))) @@ -454,7 +461,7 @@ public: QueryValveInterface fileSystemFactory, void *pGlobals) { - mm_backend = mm_DetermineBackend(engineFactory, gamedll_qvi, game_name); + mm_backend = mm_DetermineBackendS1(engineFactory, gamedll_qvi, game_name); char error[255]; if (mm_backend == MMBackend_UNKNOWN) diff --git a/loader/loader.cpp b/loader/loader.cpp index 876b832..d554d00 100644 --- a/loader/loader.cpp +++ b/loader/loader.cpp @@ -2,7 +2,7 @@ * vim: set ts=4 sw=4 tw=99 noet : * ====================================================== * Metamod:Source - * Copyright (C) 2004-2015 AlliedModders LLC and authors. + * Copyright (C) 2004-2023 AlliedModders LLC and authors. * All rights reserved. * ====================================================== * @@ -29,6 +29,7 @@ #include #include #include +#include #include "loader.h" #include "serverplugin.h" #include "gamedll.h" @@ -93,7 +94,8 @@ static const char *backend_names[] = "2.doi", "2.mock", "2.pvkii", - "2.mcv" + "2.mcv", + "2.cs2", }; #if defined _WIN32 @@ -198,6 +200,8 @@ mm_GetProcAddress(const char *name) return mm_GetLibAddress(mm_library, name); } +typedef const char *(*GetGameInfoStringFn)(const char *pszKeyName, const char *pszDefaultValue, char *pszOut, uint64_t cbOut); + void mm_GetGameName(char *buffer, size_t size) { @@ -283,24 +287,44 @@ mm_GetGameName(char *buffer, size_t size) if (buffer[0] == 0) { - // HackHackHack - Different engines have different defaults if -game isn't specified - // we only use this for game detection, and not even in all cases. Old behavior was to - // give back ".", which was only really accurate for Dark Messiah. We'll add a special - // case for Source2 / Dota as well, since it only supports gameinfo loading, which relies - // on accuracy here more than VSP loading. - if (bHasDedicated) + char tier0_path[PLATFORM_MAX_PATH]; +#ifdef _WIN32 + if (mm_ResolvePath("tier0.dll", tier0_path, sizeof(tier0_path), false)) +#elif defined __linux__ + if (mm_ResolvePath("libtier0.so", tier0_path, sizeof(tier0_path), false)) +#elif defined __APPLE__ + if (mm_ResolvePath("libtier0.dylib", tier0_path, sizeof(tier0_path), false))#else +#error unsupported platform +#endif { - strncpy(buffer, "dota", size); - } - else - { - strncpy(buffer, ".", size); + char err[1024]; + void* pTier0 = mm_LoadLibrary(tier0_path, err, sizeof(err)); + if (pTier0) + { +#ifdef _WIN32 + GetGameInfoStringFn func = (GetGameInfoStringFn)mm_GetLibAddress(pTier0, "?GetGameInfoString@@YAPEBDPEBD0PEAD_K@Z"); +#else + GetGameInfoStringFn func = (GetGameInfoStringFn)mm_GetLibAddress(pTier0, "__Z17GetGameInfoStringPKcS0_Pcm"); +#endif + if (func != nullptr) + { + static char szTmp[260]; + strncpy(buffer, func("FileSystem/SearchPaths/Mod", "", szTmp, sizeof(szTmp)), size); + } + + mm_UnloadLibrary(pTier0); + } } } + + if (buffer[0] == 0) + { + strncpy(buffer, ".", size); + } } MetamodBackend -mm_DetermineBackend(QueryValveInterface engineFactory, QueryValveInterface serverFactory, const char *game_name) +mm_DetermineBackendS1(QueryValveInterface engineFactory, QueryValveInterface serverFactory, const char *game_name) { if (engineFactory("VEngineServer023", NULL) != NULL) { diff --git a/loader/loader.h b/loader/loader.h index a4b02a7..aac8ca3 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -2,7 +2,7 @@ * vim: set ts=4 sw=4 tw=99 noet : * ====================================================== * Metamod:Source - * Copyright (C) 2004-2015 AlliedModders LLC and authors. + * Copyright (C) 2004-2023 AlliedModders LLC and authors. * All rights reserved. * ====================================================== * @@ -106,6 +106,7 @@ enum MetamodBackend MMBackend_Mock, MMBackend_PVKII, MMBackend_MCV, + MMBackend_CS2, MMBackend_UNKNOWN }; @@ -125,7 +126,7 @@ extern void mm_GetGameName(char *buffer, size_t size); extern MetamodBackend -mm_DetermineBackend(QueryValveInterface engineFactory, QueryValveInterface serverFactory, const char *game_name); +mm_DetermineBackendS1(QueryValveInterface engineFactory, QueryValveInterface serverFactory, const char *game_name); extern MetamodBackend mm_backend; diff --git a/loader/serverplugin.cpp b/loader/serverplugin.cpp index 72164bd..c6bf4fd 100644 --- a/loader/serverplugin.cpp +++ b/loader/serverplugin.cpp @@ -90,7 +90,7 @@ public: { mm_GetGameName(game_name, sizeof(game_name)); - mm_backend = mm_DetermineBackend(engineFactory, gsFactory, game_name); + mm_backend = mm_DetermineBackendS1(engineFactory, gsFactory, game_name); if (mm_backend == MMBackend_Mock) strcpy(game_name, "mock"); } @@ -139,8 +139,7 @@ public: && mm_backend != MMBackend_Insurgency && mm_backend != MMBackend_DOI && mm_backend != MMBackend_CSGO - && mm_backend != MMBackend_MCV - && mm_backend != MMBackend_DOTA) + && mm_backend != MMBackend_MCV) { SourceHook::MemFuncInfo mfp_fconnect; mfp_fconnect.isVirtual = false;