diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-04 11:39:18 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-04 11:39:18 +0100 |
| commit | b287fc803c73d3ae076c49d726e17e13faa15050 (patch) | |
| tree | 0e962adff452973119293345a643f6601a7c2c60 /src | |
| parent | Props: match the studio model name format (diff) | |
| download | hl2h-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.cpp | 56 | ||||
| -rw-r--r-- | src/netvars.cpp | 6 | ||||
| -rw-r--r-- | src/studio.cpp | 4 |
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.) | ||
| 1411 | void prop_tint_update() { | 1412 | void 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 | ||
| 1416 | void esp_draw() { | 1462 | void 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; |
