From 8780460d970c7138c6b3e0722badb0d1e804ff83 Mon Sep 17 00:00:00 2001 From: SudoGool Date: Sat, 26 Sep 2026 16:59:42 -0500 Subject: [PATCH 1/7] Port STFixes to Metamod API 18 --- AMBuilder | 7 ++++ STFixes-API18-BUILD.md | 24 +++++++++++ sdk | 2 +- src/cs2fixes.cpp | 95 +++++++++++++++++++++++++++++------------- src/cs2fixes.h | 6 ++- 5 files changed, 101 insertions(+), 33 deletions(-) create mode 100644 STFixes-API18-BUILD.md diff --git a/AMBuilder b/AMBuilder index 500d4cc23..6be8dcf3a 100644 --- a/AMBuilder +++ b/AMBuilder @@ -11,6 +11,12 @@ for sdk_target in MMSPlugin.sdk_targets: binary = MMSPlugin.HL2Library(builder, cxx, MMSPlugin.plugin_name, sdk) + # Current CS2 SDK removed tier1.a; Metamod's older build helper still + # appends it to the link inputs. Drop only that obsolete archive. + binary.compiler.postlink = [ + item for item in binary.compiler.postlink if not str(item).endswith('/tier1.a') + ] + try: version = subprocess.check_output(['git', 'describe', '--tags', '--long']).decode('ascii').strip() except subprocess.SubprocessError as e: @@ -70,6 +76,7 @@ for sdk_target in MMSPlugin.sdk_targets: ] protoc_builder = builder.tools.Protoc(protoc = sdk_target.protoc, sources = [ + os.path.join(sdk['path'], 'common', 'valveextensions.proto'), os.path.join(sdk['path'], 'common', 'network_connection.proto'), os.path.join(sdk['path'], 'common', 'networkbasetypes.proto'), os.path.join(sdk['path'], 'common', 'engine_gcmessages.proto'), diff --git a/STFixes-API18-BUILD.md b/STFixes-API18-BUILD.md new file mode 100644 index 000000000..e8df8d453 --- /dev/null +++ b/STFixes-API18-BUILD.md @@ -0,0 +1,24 @@ +# STFixes Metamod API 18 port + +This branch ports STFixes-metamod to Metamod:Source 2.0 plugin API 18. + +It preserves the upstream GPLv3 license and attribution. The port replaces +the removed SourceHook hook declarations with KHook, builds against a current +CS2 SDK, and removes obsolete string-token imports from the old SDK. + +## Reproducible build + +The port was validated against the CS2 Linux `libserver.so` build used on +2026-09-26 and Metamod:Source build `05c5c63`. Build with the Steam Runtime +Sniper SDK and Clang 16. Do not load the resulting binary on a different CS2 +build without rechecking its gamedata and ABI. + +```bash +git clone --recurse-submodules https://github.com/SudoGool/STFixes-metamod.git +cd STFixes-metamod +git checkout metamod-api18 +git -C sdk fetch origin dadd5d70170fa94cf360ed3cbfffa511dfca87b4 +git -C sdk checkout --detach dadd5d70170fa94cf360ed3cbfffa511dfca87b4 +``` + +The original upstream project is [SharpTimer/STFixes-metamod](https://github.com/SharpTimer/STFixes-metamod). diff --git a/sdk b/sdk index 0df1f3b8e..dadd5d701 160000 --- a/sdk +++ b/sdk @@ -1 +1 @@ -Subproject commit 0df1f3b8e39a47b8840f5d5545ef5de37761683c +Subproject commit dadd5d70170fa94cf360ed3cbfffa511dfca87b4 diff --git a/src/cs2fixes.cpp b/src/cs2fixes.cpp index 2bb2ae49d..98deb822c 100644 --- a/src/cs2fixes.cpp +++ b/src/cs2fixes.cpp @@ -18,6 +18,7 @@ */ #include "cs2fixes.h" +#include "khook.hpp" #include "iserver.h" #include "appframework/IAppSystem.h" @@ -76,11 +77,6 @@ void Panic(const char *msg, ...) class GameSessionConfiguration_t { }; -SH_DECL_HOOK4_void(IServerGameClients, ClientActive, SH_NOATTRIB, 0, CPlayerSlot, bool, const char *, uint64); -SH_DECL_HOOK3_void(INetworkServerService, StartupServer, SH_NOATTRIB, 0, const GameSessionConfiguration_t&, ISource2WorldSession*, const char*); -SH_DECL_MANUALHOOK1_void(CTriggerGravityPrecache, 0, 0, 0, CEntityPrecacheContext*); -SH_DECL_MANUALHOOK1_void(CTriggerGravityEndTouch, 0, 0, 0, CBaseEntity*); - CS2Fixes g_CS2Fixes; CGameEntitySystem* g_pEntitySystem = nullptr; @@ -89,8 +85,51 @@ CPlayerManager *g_playerManager = nullptr; IVEngineServer2 *g_pEngineServer2 = nullptr; CGameConfig *g_GameConfig = nullptr; CCSGameRules *g_pGameRules = nullptr; -int g_iCTriggerGravityPrecacheId = -1; -int g_iCTriggerGravityEndTouchId = -1; + +// Metamod 2.0 build 1472 uses KHook (plugin API 18). SourceHook hooks from +// the original STFixes build cannot be loaded by this Metamod version. +static KHook::Return OnClientActivePost(IServerGameClients*, CPlayerSlot slot, + bool bLoadGame, const char* pszName, uint64 xuid) +{ + if (g_playerManager) + g_CS2Fixes.Hook_ClientActive(slot, bLoadGame, pszName, xuid); + return {KHook::Action::Ignore}; +} + +static KHook::Return OnStartupServerPost(INetworkServerService*, + const GameSessionConfiguration_t& config, ISource2WorldSession* pSession, + const char* pszMapName) +{ + if (g_pEntityListener) + g_CS2Fixes.Hook_StartupServer(config, pSession, pszMapName); + return {KHook::Action::Ignore}; +} + +static KHook::Return OnGravityPrecachePost(CBaseEntity* pThis, + CEntityPrecacheContext* param) +{ + g_CS2Fixes.Hook_CTriggerGravityPrecache(pThis, param); + return {KHook::Action::Ignore}; +} + +static KHook::Return OnGravityEndTouchPost(CBaseEntity* pThis, + CBaseEntity* pOther) +{ + g_CS2Fixes.Hook_CTriggerGravityEndTouch(pThis, pOther); + return {KHook::Action::Ignore}; +} + +static KHook::Virtual + g_ClientActiveHook(&IServerGameClients::ClientActive, nullptr, OnClientActivePost); +static KHook::Virtual + g_StartupServerHook(&INetworkServerService::StartupServer, nullptr, OnStartupServerPost); +static KHook::Virtual + g_GravityPrecacheHook(nullptr, OnGravityPrecachePost); +static KHook::Virtual + g_GravityEndTouchHook(nullptr, OnGravityEndTouchPost); +// KHook::AddGlobal reads a vtable pointer from the first word of this carrier. +static void* g_TriggerGravityVTable = nullptr; CGameEntitySystem* GameEntitySystem() { @@ -148,10 +187,6 @@ bool CS2Fixes::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool return false; } - SH_ADD_HOOK(IServerGameClients, ClientActive, g_pSource2GameClients, SH_MEMBER(this, &CS2Fixes::Hook_ClientActive), true); - SH_ADD_HOOK(INetworkServerService, StartupServer, g_pNetworkServerService, SH_MEMBER(this, &CS2Fixes::Hook_StartupServer), true); - META_CONPRINTF( "All hooks started!\n" ); - bool bRequiredInitLoaded = true; if (!addresses::Initialize(g_GameConfig)) @@ -179,33 +214,35 @@ bool CS2Fixes::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool if (!pTriggerGravityVTable) { snprintf(error, maxlen, "Failed to find TriggerGravity vtable\n"); - bRequiredInitLoaded = false; + return false; } int offset = g_GameConfig->GetOffset("CBaseEntity::Precache"); if (offset == -1) { snprintf(error, maxlen, "Failed to find CBaseEntity::Precache\n"); - bRequiredInitLoaded = false; + return false; } - SH_MANUALHOOK_RECONFIGURE(CTriggerGravityPrecache, offset, 0, 0); - g_iCTriggerGravityPrecacheId = SH_ADD_MANUALDVPHOOK(CTriggerGravityPrecache, pTriggerGravityVTable, SH_MEMBER(this, &CS2Fixes::Hook_CTriggerGravityPrecache), true); + g_GravityPrecacheHook.Configure(offset); offset = g_GameConfig->GetOffset("CBaseEntity::EndTouch"); if (offset == -1) { snprintf(error, maxlen, "Failed to find CBaseEntity::EndTouch\n"); - bRequiredInitLoaded = false; + return false; } - SH_MANUALHOOK_RECONFIGURE(CTriggerGravityEndTouch, offset, 0, 0); - g_iCTriggerGravityEndTouchId = SH_ADD_MANUALDVPHOOK(CTriggerGravityEndTouch, pTriggerGravityVTable, SH_MEMBER(this, &CS2Fixes::Hook_CTriggerGravityEndTouch), true); - - Message( "All hooks started!\n" ); + g_GravityEndTouchHook.Configure(offset); ConVar_Register(); g_playerManager = new CPlayerManager(); g_pEntityListener = new CEntityListener(); + g_TriggerGravityVTable = reinterpret_cast(pTriggerGravityVTable); + g_ClientActiveHook.Add(g_pSource2GameClients); + g_StartupServerHook.Add(g_pNetworkServerService); + g_GravityPrecacheHook.AddGlobal(reinterpret_cast(&g_TriggerGravityVTable)); + g_GravityEndTouchHook.AddGlobal(reinterpret_cast(&g_TriggerGravityVTable)); + Message("All KHook hooks started!\n"); // run our cfg g_pEngineServer2->ServerCommand("exec stfixes-metamod/cs2fixes"); @@ -225,10 +262,10 @@ bool CS2Fixes::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool bool CS2Fixes::Unload(char *error, size_t maxlen) { - SH_REMOVE_HOOK(IServerGameClients, ClientActive, g_pSource2GameClients, SH_MEMBER(this, &CS2Fixes::Hook_ClientActive), true); - SH_REMOVE_HOOK(INetworkServerService, StartupServer, g_pNetworkServerService, SH_MEMBER(this, &CS2Fixes::Hook_StartupServer), true); - SH_REMOVE_HOOK_ID(g_iCTriggerGravityPrecacheId); - SH_REMOVE_HOOK_ID(g_iCTriggerGravityEndTouchId); + g_ClientActiveHook.Remove(g_pSource2GameClients); + g_StartupServerHook.Remove(g_pNetworkServerService); + g_GravityPrecacheHook.RemoveGlobal(reinterpret_cast(&g_TriggerGravityVTable)); + g_GravityEndTouchHook.RemoveGlobal(reinterpret_cast(&g_TriggerGravityVTable)); ConVar_Unregister(); @@ -291,17 +328,15 @@ void CS2Fixes::Hook_StartupServer(const GameSessionConfiguration_t& config, ISou gpGlobals = g_pEngineServer2->GetServerGlobals(); } -void CS2Fixes::Hook_CTriggerGravityPrecache(CEntityPrecacheContext* param) +void CS2Fixes::Hook_CTriggerGravityPrecache(CBaseEntity* pThis, CEntityPrecacheContext* param) { const auto kv = param->m_pKeyValues; - CTriggerGravityHandler::OnPrecache(META_IFACEPTR(CBaseEntity), kv); - RETURN_META(MRES_IGNORED); + CTriggerGravityHandler::OnPrecache(pThis, kv); } -void CS2Fixes::Hook_CTriggerGravityEndTouch(CBaseEntity* pOther) +void CS2Fixes::Hook_CTriggerGravityEndTouch(CBaseEntity* pThis, CBaseEntity* pOther) { - CTriggerGravityHandler::OnEndTouch(META_IFACEPTR(CBaseEntity), pOther); - RETURN_META(MRES_IGNORED); + CTriggerGravityHandler::OnEndTouch(pThis, pOther); } void CS2Fixes::OnLevelInit(char const* pMapName, diff --git a/src/cs2fixes.h b/src/cs2fixes.h index 30d3c8507..7060a4a64 100644 --- a/src/cs2fixes.h +++ b/src/cs2fixes.h @@ -23,6 +23,8 @@ #include "networksystem/inetworkserializer.h" #include +class CEntityPrecacheContext; + class CS2Fixes : public ISmmPlugin, public IMetamodListener { public: @@ -34,8 +36,8 @@ class CS2Fixes : public ISmmPlugin, public IMetamodListener public: //hooks void Hook_ClientActive( CPlayerSlot slot, bool bLoadGame, const char *pszName, uint64 xuid ); void Hook_StartupServer(const GameSessionConfiguration_t& config, ISource2WorldSession *pSession, const char *pszMapName); - void Hook_CTriggerGravityPrecache(CEntityPrecacheContext* param); - void Hook_CTriggerGravityEndTouch(CBaseEntity* pOther); + void Hook_CTriggerGravityPrecache(CBaseEntity* pThis, CEntityPrecacheContext* param); + void Hook_CTriggerGravityEndTouch(CBaseEntity* pThis, CBaseEntity* pOther); void OnLevelInit(char const* pMapName, char const* pMapEntities, char const* pOldLevel, From df1348997518f319906c4347f95992be985dd975 Mon Sep 17 00:00:00 2001 From: SudoGool <76273607+SudoGool@users.noreply.github.com> Date: Sat, 26 Sep 2026 16:59:50 -0500 Subject: [PATCH 2/7] Add Windows API18 build workflow --- .github/workflows/build-windows-api18.yml | 64 +++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 .github/workflows/build-windows-api18.yml diff --git a/.github/workflows/build-windows-api18.yml b/.github/workflows/build-windows-api18.yml new file mode 100644 index 000000000..18f44f079 --- /dev/null +++ b/.github/workflows/build-windows-api18.yml @@ -0,0 +1,64 @@ +name: Build Windows API18 release + +on: + workflow_dispatch: + +jobs: + build: + runs-on: windows-latest + permissions: + contents: write + steps: + - name: Check out API18 source + uses: actions/checkout@v4 + with: + ref: metamod-api18 + submodules: recursive + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Prepare AMBuild and Metamod + shell: pwsh + run: | + git clone https://github.com/alliedmodders/ambuild.git "$env:RUNNER_TEMP\ambuild" + python -m pip install "$env:RUNNER_TEMP\ambuild" + git clone https://github.com/alliedmodders/metamod-source.git "$env:RUNNER_TEMP\mmsource-2.0" + git -C "$env:RUNNER_TEMP\mmsource-2.0" checkout 05c5c63 + git -C "$env:RUNNER_TEMP\mmsource-2.0" submodule update --init --recursive + "MMSOURCE20=$env:RUNNER_TEMP\mmsource-2.0" | Out-File -FilePath $env:GITHUB_ENV -Append + "HL2SDKCS2=$((Get-Location).Path)\sdk" | Out-File -FilePath $env:GITHUB_ENV -Append + + - name: Build Windows DLL + shell: pwsh + run: | + New-Item -ItemType Directory -Force build | Out-Null + Set-Location build + python ..\configure.py --enable-optimize --sdks cs2 --targets x86_64 --mms_path "$env:MMSOURCE20" --hl2sdk-root "$(Split-Path $env:HL2SDKCS2)" + ambuild + + - name: Package Windows asset + shell: pwsh + run: | + $dll = Get-ChildItem -Recurse -Path build\package -Filter stfixes-metamod.dll | Select-Object -First 1 + if (-not $dll) { throw 'Build produced no stfixes-metamod.dll' } + $stage = Join-Path $env:RUNNER_TEMP 'stfixes-stage' + New-Item -ItemType Directory -Force "$stage\addons\stfixes-metamod\bin\win64", "$stage\addons\stfixes-metamod\gamedata", "$stage\addons\metamod" | Out-Null + Copy-Item $dll.FullName "$stage\addons\stfixes-metamod\bin\win64\stfixes-metamod.dll" + Copy-Item gamedata\cs2fixes.games.txt "$stage\addons\stfixes-metamod\gamedata\cs2fixes.games.txt" + @' + "Metamod Plugin" + { + "alias" "stfixes-metamod" + "file" "addons/stfixes-metamod/bin/win64/stfixes-metamod" + } + '@ | Set-Content "$stage\addons\metamod\stfixes-metamod.vdf" + Compress-Archive -Path "$stage\*" -DestinationPath STFixes-metamod-api18-windows-x86_64.zip -Force + + - name: Upload release asset + shell: pwsh + env: + GH_TOKEN: ${{ github.token }} + run: gh release upload api18-1.0.0 STFixes-metamod-api18-windows-x86_64.zip --repo "${{ github.repository }}" --clobber From 66cb85064ed50518a3a4480ca4a290725cc82087 Mon Sep 17 00:00:00 2001 From: SudoGool <76273607+SudoGool@users.noreply.github.com> Date: Sat, 26 Sep 2026 17:06:12 -0500 Subject: [PATCH 3/7] Fix Windows KHook headers --- .github/workflows/build-windows-api18.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-windows-api18.yml b/.github/workflows/build-windows-api18.yml index 18f44f079..832c14a79 100644 --- a/.github/workflows/build-windows-api18.yml +++ b/.github/workflows/build-windows-api18.yml @@ -28,6 +28,9 @@ jobs: git clone https://github.com/alliedmodders/metamod-source.git "$env:RUNNER_TEMP\mmsource-2.0" git -C "$env:RUNNER_TEMP\mmsource-2.0" checkout 05c5c63 git -C "$env:RUNNER_TEMP\mmsource-2.0" submodule update --init --recursive + $khook = Join-Path $env:RUNNER_TEMP 'mmsource-2.0\third_party\khook\include' + Copy-Item (Join-Path $khook 'khook.hpp') (Join-Path $env:RUNNER_TEMP 'mmsource-2.0\core\khook.hpp') + Copy-Item (Join-Path $khook 'khook') (Join-Path $env:RUNNER_TEMP 'mmsource-2.0\core\khook') -Recurse "MMSOURCE20=$env:RUNNER_TEMP\mmsource-2.0" | Out-File -FilePath $env:GITHUB_ENV -Append "HL2SDKCS2=$((Get-Location).Path)\sdk" | Out-File -FilePath $env:GITHUB_ENV -Append From a94d69166d424b5ab7915e504c682bc17ab975ab Mon Sep 17 00:00:00 2001 From: SudoGool <76273607+SudoGool@users.noreply.github.com> Date: Sat, 26 Sep 2026 17:11:17 -0500 Subject: [PATCH 4/7] Build Windows SDK libraries before API18 DLL --- .github/workflows/build-windows-api18.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-windows-api18.yml b/.github/workflows/build-windows-api18.yml index 832c14a79..5bfe9f394 100644 --- a/.github/workflows/build-windows-api18.yml +++ b/.github/workflows/build-windows-api18.yml @@ -32,7 +32,14 @@ jobs: Copy-Item (Join-Path $khook 'khook.hpp') (Join-Path $env:RUNNER_TEMP 'mmsource-2.0\core\khook.hpp') Copy-Item (Join-Path $khook 'khook') (Join-Path $env:RUNNER_TEMP 'mmsource-2.0\core\khook') -Recurse "MMSOURCE20=$env:RUNNER_TEMP\mmsource-2.0" | Out-File -FilePath $env:GITHUB_ENV -Append - "HL2SDKCS2=$((Get-Location).Path)\sdk" | Out-File -FilePath $env:GITHUB_ENV -Append + + - name: Download Windows SDK libraries + shell: bash + run: | + mkdir -p "$RUNNER_TEMP/dependencies/metamod-source" + cd "$RUNNER_TEMP/dependencies" + "$RUNNER_TEMP/mmsource-2.0/support/checkout-deps.sh" -s cs2 + echo "HL2SDKCS2=$RUNNER_TEMP/dependencies/hl2sdk-cs2" >> "$GITHUB_ENV" - name: Build Windows DLL shell: pwsh From efd53ade3edf0e8a04221695ab7a505b2026e626 Mon Sep 17 00:00:00 2001 From: SudoGool <76273607+SudoGool@users.noreply.github.com> Date: Sat, 26 Sep 2026 17:19:15 -0500 Subject: [PATCH 5/7] Build Windows SDK support libraries before STFixes --- .github/workflows/build-windows-api18.yml | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.github/workflows/build-windows-api18.yml b/.github/workflows/build-windows-api18.yml index 5bfe9f394..9ef0a02cf 100644 --- a/.github/workflows/build-windows-api18.yml +++ b/.github/workflows/build-windows-api18.yml @@ -41,6 +41,33 @@ jobs: "$RUNNER_TEMP/mmsource-2.0/support/checkout-deps.sh" -s cs2 echo "HL2SDKCS2=$RUNNER_TEMP/dependencies/hl2sdk-cs2" >> "$GITHUB_ENV" + - name: Build Metamod SDK support libraries + shell: pwsh + run: | + $mm = Join-Path $env:RUNNER_TEMP 'mmsource-2.0' + $deps = Join-Path $env:RUNNER_TEMP 'dependencies' + $mmBuild = Join-Path $mm 'build-cs2' + New-Item -ItemType Directory -Force $mmBuild | Out-Null + Push-Location $mmBuild + python (Join-Path $mm 'configure.py') --enable-optimize --sdks cs2 --targets x86_64 --hl2sdk-root $deps + ambuild + Pop-Location + + $sdkLib = Join-Path $deps 'hl2sdk-cs2\lib\public\win64' + New-Item -ItemType Directory -Force $sdkLib | Out-Null + foreach ($name in @('tier0.lib', 'tier1.lib', 'mathlib.lib', 'interfaces.lib')) { + $candidate = Get-ChildItem -Path $mmBuild -Recurse -Filter $name -File | + Where-Object { $_.FullName -notmatch '\\package\\' } | + Select-Object -First 1 + if (-not $candidate) { + Write-Host "Metamod build tree:" + Get-ChildItem -Path $mmBuild -Recurse -File | Select-Object -ExpandProperty FullName + throw "Metamod build did not produce $name" + } + Copy-Item -LiteralPath $candidate.FullName -Destination (Join-Path $sdkLib $name) -Force + Write-Host "Installed $name from $($candidate.FullName)" + } + - name: Build Windows DLL shell: pwsh run: | From 6dc7b8931345f3fcce319bf46beeb179a33f9235 Mon Sep 17 00:00:00 2001 From: SudoGool <76273607+SudoGool@users.noreply.github.com> Date: Sat, 26 Sep 2026 17:25:06 -0500 Subject: [PATCH 6/7] Use current CS2 SDK manifest for Windows build --- .github/workflows/build-windows-api18.yml | 30 +++-------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build-windows-api18.yml b/.github/workflows/build-windows-api18.yml index 9ef0a02cf..c6d73317c 100644 --- a/.github/workflows/build-windows-api18.yml +++ b/.github/workflows/build-windows-api18.yml @@ -28,6 +28,9 @@ jobs: git clone https://github.com/alliedmodders/metamod-source.git "$env:RUNNER_TEMP\mmsource-2.0" git -C "$env:RUNNER_TEMP\mmsource-2.0" checkout 05c5c63 git -C "$env:RUNNER_TEMP\mmsource-2.0" submodule update --init --recursive + $manifest = Join-Path $env:RUNNER_TEMP 'mmsource-2.0\hl2sdk-manifests\manifests\cs2.json' + Invoke-WebRequest -UseBasicParsing 'https://raw.githubusercontent.com/alliedmodders/hl2sdk-manifests/master/manifests/cs2.json' -OutFile $manifest + if ((Get-Content -Raw $manifest) -match 'tier1\.lib') { throw 'CS2 manifest still requests obsolete tier1.lib' } $khook = Join-Path $env:RUNNER_TEMP 'mmsource-2.0\third_party\khook\include' Copy-Item (Join-Path $khook 'khook.hpp') (Join-Path $env:RUNNER_TEMP 'mmsource-2.0\core\khook.hpp') Copy-Item (Join-Path $khook 'khook') (Join-Path $env:RUNNER_TEMP 'mmsource-2.0\core\khook') -Recurse @@ -41,33 +44,6 @@ jobs: "$RUNNER_TEMP/mmsource-2.0/support/checkout-deps.sh" -s cs2 echo "HL2SDKCS2=$RUNNER_TEMP/dependencies/hl2sdk-cs2" >> "$GITHUB_ENV" - - name: Build Metamod SDK support libraries - shell: pwsh - run: | - $mm = Join-Path $env:RUNNER_TEMP 'mmsource-2.0' - $deps = Join-Path $env:RUNNER_TEMP 'dependencies' - $mmBuild = Join-Path $mm 'build-cs2' - New-Item -ItemType Directory -Force $mmBuild | Out-Null - Push-Location $mmBuild - python (Join-Path $mm 'configure.py') --enable-optimize --sdks cs2 --targets x86_64 --hl2sdk-root $deps - ambuild - Pop-Location - - $sdkLib = Join-Path $deps 'hl2sdk-cs2\lib\public\win64' - New-Item -ItemType Directory -Force $sdkLib | Out-Null - foreach ($name in @('tier0.lib', 'tier1.lib', 'mathlib.lib', 'interfaces.lib')) { - $candidate = Get-ChildItem -Path $mmBuild -Recurse -Filter $name -File | - Where-Object { $_.FullName -notmatch '\\package\\' } | - Select-Object -First 1 - if (-not $candidate) { - Write-Host "Metamod build tree:" - Get-ChildItem -Path $mmBuild -Recurse -File | Select-Object -ExpandProperty FullName - throw "Metamod build did not produce $name" - } - Copy-Item -LiteralPath $candidate.FullName -Destination (Join-Path $sdkLib $name) -Force - Write-Host "Installed $name from $($candidate.FullName)" - } - - name: Build Windows DLL shell: pwsh run: | From 17a3546c5b9b576c948017f0b912e3b318bfde48 Mon Sep 17 00:00:00 2001 From: SudoGool <76273607+SudoGool@users.noreply.github.com> Date: Sat, 26 Sep 2026 17:30:45 -0500 Subject: [PATCH 7/7] Use patched CS2 SDK manifest for Windows build --- .github/workflows/build-windows-api18.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows-api18.yml b/.github/workflows/build-windows-api18.yml index c6d73317c..54eb5ffbe 100644 --- a/.github/workflows/build-windows-api18.yml +++ b/.github/workflows/build-windows-api18.yml @@ -49,7 +49,7 @@ jobs: run: | New-Item -ItemType Directory -Force build | Out-Null Set-Location build - python ..\configure.py --enable-optimize --sdks cs2 --targets x86_64 --mms_path "$env:MMSOURCE20" --hl2sdk-root "$(Split-Path $env:HL2SDKCS2)" + python ..\configure.py --enable-optimize --sdks cs2 --targets x86_64 --mms_path "$env:MMSOURCE20" --hl2sdk-root "$(Split-Path $env:HL2SDKCS2)" --hl2sdk-manifests "$env:MMSOURCE20\hl2sdk-manifests" ambuild - name: Package Windows asset