From 9f0724dcd25a06c5674d30d045dc485a341253b1 Mon Sep 17 00:00:00 2001 From: salmonik Date: Fri, 6 Nov 2026 16:19:25 +0100 Subject: Hooks: central vtable install with restore support Move vtable patching into hooks.cpp: one call clones the table, validates every slot, records the originals and installs the clone. Installs happen from the setup, game and paint threads, so the bookkeeping is mutex-protected. Client, CInput, IVModelRender, IStudioRender and ISurface all use it, and hooks_restore_all() can now put every interface back (previously impossible). --- src/studio.cpp | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'src/studio.cpp') diff --git a/src/studio.cpp b/src/studio.cpp index 8b0a710..275bfba 100644 --- a/src/studio.cpp +++ b/src/studio.cpp @@ -597,15 +597,17 @@ void chams_init() { (void *)g_force_override, (void *)g_orig_model_exec); return; } - void **nvt = vtable_clone(g_iface.modelrender, 32); - if (!nvt) { - logf("chams: vtable clone failed"); + VtablePatch patches[] = { + {1, (void *)&hkdForceOverride, + reinterpret_cast(&g_real_force_override)}, // track forced passes + {19, (void *)&hkdModelExecute, + reinterpret_cast(&g_orig_model_exec)}, + }; + if (!hooks_install_vtable(g_iface.modelrender, 32, patches, 2)) { + logf("chams: vtable patch failed"); return; } - nvt[1] = (void *)&hkdForceOverride; // track engine-forced passes - nvt[19] = (void *)&hkdModelExecute; g_modelrender = g_iface.modelrender; - *(void ***)g_modelrender = nvt; logf("chams: IVModelRender %p hooked (draw=%p override=%p)", g_modelrender, (void *)g_orig_model_exec, (void *)g_force_override); } @@ -641,24 +643,22 @@ void studio_props_init() { logf("studio: interface has no vtable"); return; } - void **vt = vtable_clone(sr, 49); - if (!vt) { - logf("studio: vtable clone failed"); + VtablePatch patches[] = { + {27, (void *)&hook_set_color, + reinterpret_cast(&g_orig_set_color)}, + {28, (void *)&hook_set_alpha, + reinterpret_cast(&g_orig_set_alpha)}, + {29, (void *)&hook_draw_model, + reinterpret_cast(&g_orig_draw_model)}, + {30, (void *)&hook_draw_static_prop, + reinterpret_cast(&g_orig_draw_static)}, + {46, (void *)&hook_draw_array, + reinterpret_cast(&g_orig_draw_array)}, + }; + if (!hooks_install_vtable(sr, 49, patches, 5)) { + logf("studio: vtable patch failed"); return; } - - g_orig_set_color = (SetColorFn)vt[27]; - g_orig_set_alpha = (SetAlphaFn)vt[28]; - g_orig_draw_model = (DrawModelFn)vt[29]; - g_orig_draw_static = (DrawStaticFn)vt[30]; - g_orig_draw_array = (DrawArrayFn)vt[46]; - vt[27] = (void *)&hook_set_color; - vt[28] = (void *)&hook_set_alpha; - vt[29] = (void *)&hook_draw_model; - vt[30] = (void *)&hook_draw_static_prop; - vt[46] = (void *)&hook_draw_array; - - *(void ***)sr = vt; g_installed = true; logf("studio: IStudioRender %p hooked (color=%p draw=%p static=%p " "array=%p)", sr, (void *)g_orig_set_color, (void *)g_orig_draw_model, -- cgit v1.2.3