From 0dc9aefd7d88d192ce8571712758e48d0184dfc1 Mon Sep 17 00:00:00 2001 From: Cedric Mercier Date: Mon, 19 Oct 2026 14:50:08 +0200 Subject: [PATCH 1/2] Support CS:S x86_64 - CBaseServer::GetClient returns a pointer: use SDKType_Address (64-bit Address, result through a by-ref argument) instead of PlainOldData, which truncated it. - The IClient -> CBaseClient adjustment is 8 on x86_64, not 4: read it from gamedata (CBaseClient::IClient). - gamedata: linux64 entries (same symbol and engine vtable indices as linux). - CI: build with SourceMod 1.13.0.7427 (production), the first with 64-bit Address. Checked on CS:S x86 and x86_64 (build 11003710): the computed CBaseClient's vtable is CGameClient's. --- .github/workflows/ci.yml | 3 ++- .../sourcemod/gamedata/FullUpdate.games.txt | 20 +++++++++++++++++++ addons/sourcemod/scripting/FullUpdate.sp | 16 +++++++++++---- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23e2566..e2261fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,8 @@ jobs: - name: Setup SourcePawn compiler uses: rumblefrog/setup-sp@v1.3.1 with: - version: "1.12.x" + # 1.13.0.7427 (production): 64-bit Address / SDKType_Address + version: "1.13.7427" github-token: ${{ secrets.GITHUB_TOKEN }} - name: Install dependencies diff --git a/addons/sourcemod/gamedata/FullUpdate.games.txt b/addons/sourcemod/gamedata/FullUpdate.games.txt index dd7a80c..e6b8e95 100644 --- a/addons/sourcemod/gamedata/FullUpdate.games.txt +++ b/addons/sourcemod/gamedata/FullUpdate.games.txt @@ -21,6 +21,10 @@ { "signature" "sv" } + "linux64" + { + "signature" "sv" + } "mac" { "signature" "sv" @@ -40,6 +44,7 @@ { "library" "engine" "linux" "@sv" + "linux64" "@sv" "mac" "@sv" } } @@ -67,6 +72,10 @@ { "signature" "sv" } + "linux64" + { + "signature" "sv" + } "mac" { "signature" "sv" @@ -86,6 +95,7 @@ { "library" "engine" "linux" "@sv" + "linux64" "@sv" "mac" "@sv" } } @@ -106,11 +116,21 @@ { "windows" "6" "linux" "7" + "linux64" "7" "mac" "7" } "CBaseClient::UpdateAcknowledgedFramecount" { "linux" "44" + "linux64" "44" + } + // IClient comes after the IGameEventListener2 vtable pointer in CBaseClient + "CBaseClient::IClient" + { + "windows" "4" + "linux" "4" + "linux64" "8" + "mac" "4" } } } diff --git a/addons/sourcemod/scripting/FullUpdate.sp b/addons/sourcemod/scripting/FullUpdate.sp index 3b478b3..86ddb8f 100644 --- a/addons/sourcemod/scripting/FullUpdate.sp +++ b/addons/sourcemod/scripting/FullUpdate.sp @@ -9,6 +9,7 @@ Handle g_hCBaseClient_UpdateAcknowledgedFramecount; Handle g_hGetClient; Address g_pBaseServer; +int g_iIClientOffset = 4; int g_iLastFullUpdate[MAXPLAYERS + 1] = { 0, ... }; @@ -45,7 +46,7 @@ public void OnPluginStart() SetFailState("PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, \"CBaseServer::GetClient\" failed!"); return; } - PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain); + PrepSDKCall_SetReturnInfo(SDKType_Address, SDKPass_Plain); PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain); g_hGetClient = EndPrepSDKCall(); #endif @@ -63,6 +64,10 @@ public void OnPluginStart() g_hCBaseClient_UpdateAcknowledgedFramecount = EndPrepSDKCall(); + int iOffset = hGameData.GetOffset("CBaseClient::IClient"); + if (iOffset != -1) + g_iIClientOffset = iOffset; + delete hGameData; RegConsoleCmd("fullupdate", Command_FullUpdate); @@ -142,7 +147,10 @@ public Action Command_FullUpdate(int client, int args) #if !defined GetClientIClient stock Address GetClientIClient(int client) { - return SDKCall(g_hGetClient, g_pBaseServer, client-1); + // SDKType_Address results come back through a by-ref argument (64-bit Address). + Address pIClient; + SDKCall(g_hGetClient, g_pBaseServer, pIClient, client-1); + return pIClient; } #endif @@ -152,6 +160,6 @@ stock Address GetBaseClient(int client) if(!pIClientTmp) return Address_Null; - // The IClient vtable is +4 from the IGameEventListener2 (CBaseClient) vtable due to multiple inheritance. - return pIClientTmp - view_as
(4); + // The IClient vtable comes after the IGameEventListener2 (CBaseClient) one due to multiple inheritance. + return pIClientTmp - view_as
(g_iIClientOffset); } From 2d8747ebea4aee8e5ac9503fe67c404081da2810 Mon Sep 17 00:00:00 2001 From: Cedric Mercier Date: Tue, 20 Oct 2026 00:11:24 +0200 Subject: [PATCH 2/2] chore: bump version to 1.4.0 --- addons/sourcemod/scripting/include/FullUpdate.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/include/FullUpdate.inc b/addons/sourcemod/scripting/include/FullUpdate.inc index 3312cc8..d749b72 100644 --- a/addons/sourcemod/scripting/include/FullUpdate.inc +++ b/addons/sourcemod/scripting/include/FullUpdate.inc @@ -4,8 +4,8 @@ #define _FullUpdate_Included #define FullUpdate_V_MAJOR "1" -#define FullUpdate_V_MINOR "3" -#define FullUpdate_V_PATCH "2" +#define FullUpdate_V_MINOR "4" +#define FullUpdate_V_PATCH "0" #define FullUpdate_VERSION FullUpdate_V_MAJOR..."."...FullUpdate_V_MINOR..."."...FullUpdate_V_PATCH