summaryrefslogtreecommitdiffstats
path: root/src/core.h
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-06 16:21:27 +0100
committersalmonik <salmonik@tuta.io>2026-11-06 16:21:27 +0100
commit3c27e7ce262e612fa75c6e6f090e04041a688861 (patch)
tree1c2bfd6accea27904dc9d81a61624905b220a8a0 /src/core.h
parentHooks: central vtable install with restore support (diff)
downloadhl2h-3c27e7ce262e612fa75c6e6f090e04041a688861.tar.gz
hl2h-3c27e7ce262e612fa75c6e6f090e04041a688861.zip
Headers: split the shared header by declaration group
hl2h.h becomes an umbrella over core.h (logging, init stage, module snapshots, interfaces, netvars, CUserCmd, engine constants, vector math), settings.h (feature ids, feature state, user settings) and features.h (cross-module declarations). Translation units keep including hl2h.h, so this only moves declarations.
Diffstat (limited to '')
-rw-r--r--src/core.h205
1 files changed, 205 insertions, 0 deletions
diff --git a/src/core.h b/src/core.h
new file mode 100644
index 0000000..320b62b
--- /dev/null
+++ b/src/core.h
@@ -0,0 +1,205 @@
1#ifndef HL2H_CORE_H
2#define HL2H_CORE_H
3
4#include <cstdint>
5#include <cstdio>
6#include <cstring>
7#include <string>
8#include <vector>
9
10#include <dlfcn.h>
11#include <pthread.h>
12#include <unistd.h>
13
14// Shared float-precision constant. More digits than a float can hold are
15// rounded at compile time and have no runtime cost; a coarse value would only
16// hurt angular accuracy, never performance.
17constexpr float PI_F = 3.14159265f;
18
19// ---------------------------------------------------------------------------
20// logging
21// ---------------------------------------------------------------------------
22
23void logf(const char *fmt, ...);
24void logd(const char *fmt, ...); // debug-only (HL2H_DEBUG=1)
25
26// ---------------------------------------------------------------------------
27// init readiness
28// ---------------------------------------------------------------------------
29//
30// setup_thread runs detached while the game threads are already live, and some
31// hooks are installed lazily from the game thread. Hooks therefore always stay
32// installed but pass straight through to the original until setup reaches
33// INIT_LIVE, so the game can never observe half-initialised state. INIT_FAILED
34// is terminal: the cheat stays inert instead of half-working.
35enum {
36 INIT_FAILED = -1,
37 INIT_NONE = 0,
38 INIT_INTERFACES = 1, // modules + interfaces + netvars resolved
39 INIT_READY = 2, // config loaded, ISurface/fonts resolved
40 INIT_LIVE = 3 // hooks may run their bodies
41};
42void init_set_stage(int stage);
43int init_stage(); // acquire load
44inline bool init_live() { return init_stage() == INIT_LIVE; }
45
46// Clone a vtable into a new array, preserving the Itanium ABI header at
47// [-2]/[-1] (offset-to-top and typeinfo) so RTTI on the hooked object still
48// works. Returns the slot-0 pointer to install (i.e. the clone + 2).
49void **vtable_clone(void *iface, size_t slots);
50
51// ---------------------------------------------------------------------------
52// on-screen toasts
53// ---------------------------------------------------------------------------
54
55enum ToastLevel { TOAST_INFO = 0, TOAST_WARN, TOAST_ERROR };
56void toastf(int level, const char *fmt, ...);
57bool gui_toasts_active();
58void gui_draw_toasts();
59
60// ---------------------------------------------------------------------------
61// module discovery
62// ---------------------------------------------------------------------------
63
64struct Module {
65 struct Range {
66 uintptr_t lo, hi;
67 bool file;
68 };
69 std::vector<Range> ranges;
70 std::string path;
71 bool valid() const { return !ranges.empty(); }
72 bool contains(uintptr_t p) const {
73 for (auto &r : ranges)
74 if (p >= r.lo && p < r.hi)
75 return true;
76 return false;
77 }
78};
79// Immutable module snapshots. A reader gets a reference that stays valid for
80// the whole process: find_modules() publishes a new snapshot instead of
81// mutating the old one, and retired snapshots are intentionally never freed, so
82// a concurrent refresh can never invalidate a reference already in use.
83const Module &mod_client();
84const Module &mod_engine();
85const Module &mod_server();
86
87// True only when the whole byte range [p, p+n) lies inside one known module
88// range. Use before dereferencing pointers read out of engine memory.
89bool module_range(uintptr_t p, size_t n);
90
91// ---------------------------------------------------------------------------
92// game interfaces
93// ---------------------------------------------------------------------------
94
95using CreateInterfaceFn = void *(*)(const char *, int *);
96
97struct GameInterfaces {
98 void *client = nullptr;
99 void *entitylist = nullptr;
100 void *engine = nullptr;
101 void *modelinfo = nullptr; // IVModelInfoClient006 (model index -> model name)
102 void *engineserver = nullptr; // IVEngineServer021 (edict access, incl. server entities)
103 void *debugoverlay = nullptr; // IVDebugOverlay003 (engine-accurate world->screen)
104 void *enginetrace = nullptr; // EngineTraceClient003 (world vischeck)
105 void *cvar = nullptr; // VEngineCvar004 (mat_fullbright etc.)
106 void *modelrender = nullptr; // VEngineModel016 (chams)
107 void *renderview = nullptr; // VEngineRenderView014 (alpha/color modulation)
108};
109extern GameInterfaces g_iface;
110
111#define VTABLE(obj) (*(void ***)(obj))
112template <typename Fn> inline Fn vfunc(void *obj, size_t idx) {
113 return reinterpret_cast<Fn>(VTABLE(obj)[idx]);
114}
115
116// ---------------------------------------------------------------------------
117// netvars
118// ---------------------------------------------------------------------------
119struct NetVars {
120 int flags = -1;
121 int velocity = -1;
122 int movetype = -1;
123 int health = -1;
124 int maxhealth = -1;
125 int teamnum = -1;
126 int origin = -1;
127 int viewoffset = -1;
128 int mins = -1;
129 int maxs = -1;
130 int lifestate = -1;
131 int modelindex = -1;
132 int absvelocity = -1; // client C_BaseEntity::m_vecAbsVelocity (prediction)
133 int activeweapon = -1; // client m_hActiveWeapon handle
134 int owner = -1; // client m_hOwnerEntity handle
135 int weapon_owner = -1; // client m_hOwner handle (C_BaseCombatWeapon)
136 int clr_render = -1; // client m_clrRender (entity render colour)
137 int punch = -1; // client m_vecPunchAngle (aim punch)
138 int default_fov = -1; // client m_iDefaultFOV (camera fov)
139 int dmg_radius = -1; // client C_BaseGrenade::m_DmgRadius
140 int my_weapons = -1; // client m_hMyWeapons[48] array base
141 int ammo = -1; // client m_iAmmo[] array base
142 // ponytail: mins/maxs may be absent from some HL2 netvar tables; esp.cpp falls back to h=72
143 bool ok() const { return flags >= 0 && velocity >= 0 && movetype >= 0; }
144 // ponytail: m_iMaxHealth isn't a netvar in HL2 SP; esp.cpp falls back to 100.
145 // m_iHealth only ever updates for players — NPCs are detected via m_lifeState.
146 bool esp_ok() const { return ok() && health >= 0 && teamnum >= 0 && origin >= 0 && viewoffset >= 0; }
147};
148extern NetVars g_net;
149
150// ---------------------------------------------------------------------------
151// CInput
152// ---------------------------------------------------------------------------
153
154extern uintptr_t g_input;
155
156// ---------------------------------------------------------------------------
157// console output
158// ---------------------------------------------------------------------------
159
160extern void (*g_conmsg)(const char *, ...);
161
162// ---------------------------------------------------------------------------
163// CUserCmd
164// ---------------------------------------------------------------------------
165
166struct CUserCmd {
167 void *vtable;
168 int command_number;
169 int tick_count;
170 float viewangles[3];
171 float forwardmove;
172 float sidemove;
173 float upmove;
174 int buttons;
175 uint8_t impulse;
176 int weaponselect;
177 int weaponsubtype;
178 int random_seed;
179 short mousedx;
180 short mousedy;
181 bool hasbeenpredicted;
182};
183
184// ---------------------------------------------------------------------------
185// engine constants
186// ---------------------------------------------------------------------------
187
188enum { IN_ATTACK = 1 << 0, IN_JUMP = 1 << 1, IN_DUCK = 1 << 2, IN_USE = 1 << 5, IN_ATTACK2 = 1 << 11, IN_SPEED = 1 << 17 };
189enum { FL_ONGROUND = 1 << 0, FL_DUCKING = 1 << 1, FL_INWATER = 1 << 9 };
190enum { MOVETYPE_WALK = 2, MOVETYPE_NOCLIP = 8, MOVETYPE_LADDER = 9 };
191
192// ---------------------------------------------------------------------------
193// vector math
194// ---------------------------------------------------------------------------
195
196struct Vector { float x, y, z; };
197struct QAngle { float x, y, z; };
198// camera state captured each CreateMove (used by ESP / future aimbot)
199extern Vector g_cam_eye;
200extern Vector g_cam_view;
201QAngle vector_angles(const Vector &forward);
202Vector angle_forward_vector(const QAngle &angles);
203float getfov(const QAngle &my_view, const QAngle &aim_ang);
204
205#endif