summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-04 11:39:18 +0100
committersalmonik <salmonik@tuta.io>2026-11-04 11:39:18 +0100
commitb287fc803c73d3ae076c49d726e17e13faa15050 (patch)
tree0e962adff452973119293345a643f6601a7c2c60 /src
parentProps: match the studio model name format (diff)
downloadhl2h-b287fc803c73d3ae076c49d726e17e13faa15050.tar.gz
hl2h-b287fc803c73d3ae076c49d726e17e13faa15050.zip
Props: disable StudioRender hooks, fix m_clrRender offset
Hooking IStudioRender's draw/setter slots made matched props render the error material and then crashed the material system ("debug/modelstats has bad reference count 0 when being bound"). Keep the hook code for reference but do not install it. Fix the m_clrRender netvar resolution: the walk picked an embedded table entry at offset 0, so the earlier entity writes stomped entity vtables. Only accept offsets inside C_BaseEntity (0x20..0x2000), then write the prop colour there for models/props entities. Restore white when disabled.
Diffstat (limited to 'src')
-rw-r--r--src/esp.cpp56
-rw-r--r--src/netvars.cpp6
-rw-r--r--src/studio.cpp4
3 files changed, 60 insertions, 6 deletions
diff --git a/src/esp.cpp b/src/esp.cpp
index 1fd4904..64c1525 100644
--- a/src/esp.cpp
+++ b/src/esp.cpp
@@ -1405,12 +1405,58 @@ bool triggerbot_apply(CUserCmd *cmd) {
1405 return false; 1405 return false;
1406} 1406}
1407 1407
1408// Props are tinted through IStudioRender (studio.cpp), which covers both 1408// Dynamic props are tinted through their client render colour. StudioRender
1409// dynamic prop_physics entities and map-static props. There is no per-entity 1409// feeds m_clrRender into the per-model colour modulation each draw, which is
1410// netvar write here: m_clrRender resolved to offset 0 in this build. 1410// why tinting the prop material alone had no effect. (The IStudioRender hook
1411// experiment corrupted materials and crashed; see studio.cpp.)
1411void prop_tint_update() { 1412void prop_tint_update() {
1412 if (feature_active(FEAT_WORLD_TINT) && g_tint_prop_on) 1413 static bool applied = false;
1413 studio_props_init(); 1414 static bool logged_missing = false;
1415 static bool logged_touched = false;
1416 bool on = feature_active(FEAT_WORLD_TINT) && g_tint_prop_on;
1417 if (!on && !applied)
1418 return;
1419 if (!g_iface.entitylist || g_net.clr_render < 0) {
1420 if (on && !logged_missing) {
1421 logged_missing = true;
1422 logf("prop tint: m_clrRender unavailable");
1423 }
1424 return;
1425 }
1426 static double last = 0.0;
1427 double now = esp_now();
1428 if (on && now - last < 0.01)
1429 return;
1430 last = now;
1431
1432 using Fn = int (*)(void *);
1433 int hi = vfunc<Fn>(g_iface.entitylist, 6)(g_iface.entitylist);
1434 if (hi < 0 || hi > 4096)
1435 hi = 4096;
1436 uint32_t col =
1437 on ? ((uint32_t)g_tint_prop_rgb[0] | ((uint32_t)g_tint_prop_rgb[1] << 8) |
1438 ((uint32_t)g_tint_prop_rgb[2] << 16) | (255u << 24))
1439 : 0xFFFFFFFFu;
1440 int touched = 0;
1441 for (int idx = 1; idx <= hi; idx++) {
1442 void *ent = entitylist_get(idx);
1443 if (!ent)
1444 continue;
1445 const char *model = entity_model_name(ent);
1446 if (!model)
1447 continue;
1448 bool prop = strncmp(model, "models/props", 12) == 0 ||
1449 strncmp(model, "props_", 6) == 0;
1450 if (!prop)
1451 continue;
1452 *(uint32_t *)((uintptr_t)ent + (uintptr_t)g_net.clr_render) = col;
1453 touched++;
1454 }
1455 applied = on;
1456 if (on && touched > 0 && !logged_touched) {
1457 logged_touched = true;
1458 logf("prop tint: %d prop entities", touched);
1459 }
1414} 1460}
1415 1461
1416void esp_draw() { 1462void esp_draw() {
diff --git a/src/netvars.cpp b/src/netvars.cpp
index 4578e52..8043674 100644
--- a/src/netvars.cpp
+++ b/src/netvars.cpp
@@ -93,7 +93,11 @@ static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth) {
93 g_net.activeweapon < 0) { 93 g_net.activeweapon < 0) {
94 g_net.activeweapon = (int)(base_off + (uint32_t)poff); 94 g_net.activeweapon = (int)(base_off + (uint32_t)poff);
95 } else if (strcmp(pname2, "m_clrRender") == 0 && g_net.clr_render < 0) { 95 } else if (strcmp(pname2, "m_clrRender") == 0 && g_net.clr_render < 0) {
96 g_net.clr_render = (int)(base_off + (uint32_t)poff); 96 int off = (int)(base_off + (uint32_t)poff);
97 // Reject the 0 offset some embedded tables report; the real render
98 // colour lives well inside C_BaseEntity.
99 if (off >= 0x20 && off <= 0x2000)
100 g_net.clr_render = off;
97 } else if (strcmp(pname2, "m_iTeamNum") == 0 && g_net.teamnum < 0) { 101 } else if (strcmp(pname2, "m_iTeamNum") == 0 && g_net.teamnum < 0) {
98 g_net.teamnum = (int)(base_off + (uint32_t)poff); 102 g_net.teamnum = (int)(base_off + (uint32_t)poff);
99 } else if (strcmp(pname2, "m_vecOrigin") == 0 && g_net.origin < 0) { 103 } else if (strcmp(pname2, "m_vecOrigin") == 0 && g_net.origin < 0) {
diff --git a/src/studio.cpp b/src/studio.cpp
index baabcfa..c63ddab 100644
--- a/src/studio.cpp
+++ b/src/studio.cpp
@@ -201,6 +201,10 @@ void studio_props_init() {
201 if (g_install_tried) 201 if (g_install_tried)
202 return; 202 return;
203 g_install_tried = true; 203 g_install_tried = true;
204 // Disabled: replacing IStudioRender draw/setter entries corrupted material
205 // state (error-material props, bad reference counts, crash). Prop tint uses
206 // the entity render colour path in esp.cpp instead.
207 return;
204 208
205 std::string path = loaded_module_path("studiorender"); 209 std::string path = loaded_module_path("studiorender");
206 void *h = nullptr; 210 void *h = nullptr;