Files
sacred_k/src/re/hook.cpp
T
khallaandClaude Opus 5.5 ed3163d312 HUD: centre the taskbar, move the portrait/health panel to the right edge
New mods/hud: while a HUD window renders, screen-space vertices passed to
D3D7 DrawPrimitive/DrawIndexedPrimitive are shifted by dx; while it handles
an event, the UI event point (category 5, +0x48) is shifted by -dx. Applied
to cUI_Taskbar2 (centred) and cUI_Mercenary (portrait + health, right edge).
3D belt items line up without help (their projection is screen-centred).
re::AttachRuntimeHook hooks functions only known at runtime (COM methods).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-14 03:37:05 +02:00

81 lines
2.2 KiB
C++

#include "re/hook.h"
#include <vector>
#include <windows.h>
#include <detours.h>
#include "re/config.h"
#include "re/log.h"
namespace re {
namespace {
struct HookDef {
const char* name;
uint32_t address;
void** original;
void* replacement;
};
// Function-local static: registrations run during static initialisation, in
// unspecified order across translation units.
std::vector<HookDef>& Registry() {
static std::vector<HookDef> hooks;
return hooks;
}
} // namespace
HookRegistration::HookRegistration(const char* name, uint32_t address, void** original, void* replacement) {
Registry().push_back({name, address, original, replacement});
}
int InstallHooks() {
int failed = 0;
int installed = 0;
for (const HookDef& hook : Registry()) {
if (!ConfigInt("hooks", hook.name, 1)) {
Log("hook %-24s 0x%08x disabled by config", hook.name, hook.address);
continue;
}
// One transaction per hook, so a bad hook does not take the others down.
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
LONG error = DetourAttach(hook.original, hook.replacement);
if (error == NO_ERROR) {
error = DetourTransactionCommit();
} else {
DetourTransactionAbort();
}
if (error == NO_ERROR) {
++installed;
} else {
++failed;
Log("hook %-24s 0x%08x FAILED (error %ld)", hook.name, hook.address, error);
}
}
Log("%d hook(s) installed, %d failed", installed, failed);
return failed;
}
bool AttachRuntimeHook(const char* name, void** original, void* replacement) {
const void* target = *original;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
LONG error = DetourAttach(original, replacement);
if (error == NO_ERROR) {
error = DetourTransactionCommit();
} else {
DetourTransactionAbort();
}
if (error != NO_ERROR) {
Log("hook %-24s %p FAILED (error %ld)", name, target, error);
return false;
}
Log("hook %-24s %p attached at runtime", name, target);
return true;
}
} // namespace re