<feed xmlns='http://www.w3.org/2005/Atom'>
<title>hl2h/src/esp.cpp, branch master</title>
<subtitle>Simple internal C++ cheat for HL2 for GNU/Linux.
</subtitle>
<id>https://git.2137697.xyz/hl2h/atom?h=master</id>
<link rel='self' href='https://git.2137697.xyz/hl2h/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/hl2h/'/>
<updated>2026-11-06T15:25:48Z</updated>
<entry>
<title>ESP: finish the split into entity, combat, item and projectile units</title>
<updated>2026-11-06T15:25:48Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-11-06T15:25:48Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/hl2h/commit/?id=c43cb2e42a5ac1cc09f83cd72fa7e568c9ef37e1'/>
<id>urn:sha1:c43cb2e42a5ac1cc09f83cd72fa7e568c9ef37e1</id>
<content type='text'>
esp.cpp keeps the scan and drawing (~1000 lines, down from 3665). Entity
lookups and NPC classification move to entity_query.cpp together with the
per-map caches and the session reset; combat (aimbot, silent aim, melee,
spread, triggerbot) moves to combat.cpp. Shared helpers are declared in
esp_internal.h.
</content>
</entry>
<entry>
<title>ESP: extract item ESP into its own translation unit</title>
<updated>2026-11-06T15:23:29Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-11-06T15:23:29Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/hl2h/commit/?id=5a9fd14f9424d7f66b0454464be95b40b10ee5c4'/>
<id>urn:sha1:5a9fd14f9424d7f66b0454464be95b40b10ee5c4</id>
<content type='text'>
Second slice of the esp.cpp split. Model-name lookup joins the shared helpers in
esp_internal.h.
</content>
</entry>
<entry>
<title>ESP: extract projectile ESP into its own translation unit</title>
<updated>2026-11-06T15:23:01Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-11-06T15:23:01Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/hl2h/commit/?id=7352766582e140483ebcc1d8660a76e1bccbec0d'/>
<id>urn:sha1:7352766582e140483ebcc1d8660a76e1bccbec0d</id>
<content type='text'>
First slice of the esp.cpp split. Shared helpers move to esp_internal.h
(entity lookups, screen size, surf primitives, segment projection); esp.cpp
keeps the definitions and drops their static qualifiers.
</content>
</entry>
<entry>
<title>Fix audit findings: crash safety, correctness, rendering, performance</title>
<updated>2026-11-06T15:09:55Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-11-06T15:09:55Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/hl2h/commit/?id=33f5ed9ef58f26c6b3b52cf605dd4311d658a60d'/>
<id>urn:sha1:33f5ed9ef58f26c6b3b52cf605dd4311d658a60d</id>
<content type='text'>
Crash/UB:
- gate every hook behind an init-stage flag until config/surface/input are ready
- publish module maps as immutable atomic snapshots instead of reallocating
  shared vectors under unlocked readers
- validate the %ebp walk in the RandomSeed/RandomFloat hooks against the stack
- bounds-check every RecvTable/RecvProp/string dereference with module_range()
- preserve the Itanium vtable header when cloning (client, CInput, model render,
  studio render)
- reject negative usercmd sequence numbers; guard config_load against a null
  section target; cap the bone parent walk; check mprotect; drop PROT_EXEC on
  the GOT patch; absorb server.so .bss tail

Correctness:
- filter dormant entities across ESP, aimbot, triggerbot, melee, items and
  projectiles (slot self-tested against the local player)
- reset the server-health latch per map and only latch on valid model indices
- bone cache sized for the 128-target scan; set valid=false on every failure;
  head_position keeps searching past an invalid bone
- vischeck steps past glass by probing until clear, and ignores entities owned
  by the target (held weapons, bone followers)
- aimbot: maxs no longer disables it, AABB-aware FOV prefilter, lock hysteresis,
  lead point re-checked for FOV and visibility
- spread: seed hook arms on the no-spread toggle alone; engine toggle only
  controls the RandomFloat zeroing
- resolve m_hOwnerEntity/m_hOwner; NPC lead velocity from the server entity
- vector_angles pitch range, point_ground normal test, underwater jump+duck no
  longer skips combat, semi-auto press/release edge for synthetic fire
- item/projectile markers and blast rings refresh origin per frame while
  discovery stays at 10 Hz; trajectory uses the real m_DmgRadius and honours
  the blast-radius toggle

Rendering/GUI:
- one overlay draw per engine frame (FRAME_RENDER_START boundary), fixing
  alpha stacking and the speed-graph flicker
- clipped lines/outlines and ellipsised text instead of drawing past the
  content pane or shifting over neighbours
- dropdown dismissal consumes the click; hover ignores hidden controls
- chams: reset AlphaModulate, reference shared materials once, restore prop
  tint colour; fonts created once per handle
- projection uses Source's 4:3 aspect scaling and roll; screen size refreshed
  each frame; FOV circle gated on the aim toggles, not the bind

Performance:
- TTL caches for NPC relation, friendly/neutral and damage class
- model names memoised per model index
- entity pointer -&gt; index cache for the triggerbot (was a 4096-slot walk/tick)

Build:
- real Makefile with -MMD dependency tracking, debug/release objects and an
  always-relink rule; build.sh kept as a thin wrapper
</content>
</entry>
<entry>
<title>Items: log the usable ammo table once</title>
<updated>2026-11-05T19:33:33Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-11-05T19:33:33Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/hl2h/commit/?id=94745d7d11ecf24a582dd8860e14eb42c170185d'/>
<id>urn:sha1:94745d7d11ecf24a582dd8860e14eb42c170185d</id>
<content type='text'>
One line with each nonzero m_iAmmo type as "type:count/max" (0:270/270
8:3/3 11:5/5 ...) to diagnose any remaining "full ammo still shows" reports.
</content>
</entry>
<entry>
<title>Items: server ammo counts and frag-grenade type</title>
<updated>2026-11-05T19:32:59Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-11-05T19:32:59Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/hl2h/commit/?id=57b53d579f32f094c1cdefad62a6224baf270e0d'/>
<id>urn:sha1:57b53d579f32f094c1cdefad62a6224baf270e0d</id>
<content type='text'>
- local_ammo now prefers the authoritative server m_iAmmo array (header skip)
  and only falls back to the client netvar array. The client offset can be off
  by an element, which made "full" checks flicker as other ammo was spent.
- Frag grenade pickups were falling through to a generic "Ammo" label with
  ammo_type=-1, so the usable filter never ran. w_grenade/w_frag/
  items/grenade/frag_grenade are now "Frag grenade" and map to m_iAmmo[11]
  (sk_max_grenade, stock 5); AR2/SMG1 grenade variants map to m_iAmmo[8].
</content>
</entry>
<entry>
<title>Items: keep health chargers visible, add charger diagnostics</title>
<updated>2026-11-05T17:09:43Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-11-05T17:09:43Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/hl2h/commit/?id=a5d732920bd56c96e85db1ce2073bebf53e6b1ea'/>
<id>urn:sha1:a5d732920bd56c96e85db1ce2073bebf53e6b1ea</id>
<content type='text'>
The health charger's candidate m_iJuice offset (0x3c8) read 0 on a full
charger, so the empty-hide made health chargers disappear entirely. Restrict
the hide to suit chargers (verified 0x47c) until the health offset is
confirmed; health chargers stay visible.

Classify with the server class name when the client class is generic, accept
`healthcharger` in the health branch (maps use item_healthcharger /
CNewWallHealth, not the func_healthcharger brush), and log up to eight
`juice:` lines with the class and both candidate offsets/values.
</content>
</entry>
<entry>
<title>Grenade trajectory: actual grenade state, full-length path, rounder rings</title>
<updated>2026-11-04T22:46:58Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-11-04T22:46:58Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/hl2h/commit/?id=a224cc451233a487a3d931954b125f6e1736e710'/>
<id>urn:sha1:a224cc451233a487a3d931954b125f6e1736e710</id>
<content type='text'>
- Prefer the local player's thrown frag over the pre-throw estimate: resolve
  CBaseGrenade::m_hThrower from the server datamap (client owner handles as
  fallback), then seed the prediction from the live origin/velocity. The real
  frag is a spinning VPhysics box with a random Y angular impulse, so bounce
  points remain approximate; the doc now says so.
- Keep 512 path points sampled every other 20 ms step (up to 24 s) instead of
  127 points / ~2.5 s, so the line reaches the landing instead of stopping in
  mid-air.
- Radius rings use 36 segments; a segment whose near-plane-clipped endpoint
  the engine overlay refuses falls back to the local projection, and that
  projection now uses the configured camera FOV instead of a hardcoded 75
  degrees (the wide-FOV ring no longer kinks/drops pieces).
</content>
</entry>
<entry>
<title>Charger juice: resolve per-class offsets</title>
<updated>2026-11-04T22:32:00Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-11-04T22:32:00Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/hl2h/commit/?id=80a287910f3f77519c8243ba5f53d9c877fbddcb'/>
<id>urn:sha1:80a287910f3f77519c8243ba5f53d9c877fbddcb</id>
<content type='text'>
CWallHealth derives CBaseToggle and CNewRecharge derives CBaseAnimating, so
m_iJuice is at different offsets (0x3c8 and 0x47c here). Collect every
m_iJuice datamap match, derive the suit offset from m_iMaxJuice-20, and pick
by the server class name. Also detect health brushes via wallhealth/recharge
rather than the ESP label. Verified the offsets resolve distinctly on :99.
</content>
</entry>
<entry>
<title>Add grenade trajectory, RPG armour priority, empty chargers, mega gravity gun</title>
<updated>2026-11-04T22:26:53Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-11-04T22:26:53Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/hl2h/commit/?id=074e315c8550712dce0c7b530a90eee6aca29e63'/>
<id>urn:sha1:074e315c8550712dce0c7b530a90eee6aca29e63</id>
<content type='text'>
- Projectiles gets a "Grenade trajectory" toggle. While a frag grenade is
  held, simulate the weapon_frag throw (1200 u/s forward + 120 z, player
  velocity, gravity 600) and trace each step with a new
  trace_solid_segment(); reflect on impact, stop on a slow upward-normal hit,
  and draw the path, landing cross and a 300-unit blast ring. Verified on :99
  (arcs, bounces off the tunnel wall, lands).
- With the RPG equipped, armoured NPCs (striders, gunships, dropships,
  hunter-choppers) sort before normal enemies during target acquisition.
  Added helicopter/chopper to the ARMORED model list.
- Empty health/suit chargers are hidden: read m_iJuice from the server
  datamap (0 = depleted, -1 = unreadable/fail open).
- The citadel supercharged gravity gun (d3_citadel_03, d3_citadel_04,
  d3_breen_01 via IVEngineClient::GetLevelName) is treated as a normal
  weapon, so the melee aimbot no longer restricts it to VULNERABLE NPCs.
</content>
</entry>
</feed>
