This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

237 lines
8.4 KiB
C++

/*
*
* We do hooking here!
* Eventually you will be able to pass your function into here to do stuff
*with the hooked functions
*
*
*/
#include <stdlib.h> // Needed to get client mode
#include <chrono> // Sleep in thread
#include <thread>
// Stuff we use to hook with
#include "../../../hacks/hooking.hpp" // What we use to hook with
#include "interfaces.hpp" // We use offsets from interfaces to hook things
// So we can run the framework from the hooks
#include "../../../framework/game.hpp" // We set ingame state here
#include "../../../framework/gameticks.hpp" // We run the main cheat loops
// Stuff to do with features
#include "../../../util/catvars.hpp"
#include "../../../util/logging.hpp"
#include "../util/netvars.hpp"
#include "../util/worldtoscreen.hpp"
#if defined(CATHOOK_TF2)
#include "../util/conditions.hpp"
#endif
// platform specific offsets
#include "../../../util/platform.hpp"
#include "hooks.hpp"
// Contains offsets to vfuncs that we hook
namespace offsets {
const auto CreateMove = Platform<short>(22);
const auto PaintTraverse = Platform<short>(42);
const auto OverrideView = Platform<short>(17);
const auto FrameStageNotify = Platform<short>(35);
} // namespace offsets
namespace modules::source::hacks::hooks {
// Here we store our main hooks
static VMTHook clientmode;
static VMTHook client;
static VMTHook panel;
// Here we have our hooked functions
CUserCmd* g_UserCmd = nullptr; // UserInput
bool UsingSilent = false;
Vector LastAngles; // We save angles from CreateMove to use down in
// FrameStageNotify
static bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) {
typedef bool (*CreateMove_t)(
void*, float, CUserCmd*); // Type defs like these allow us to contain
// the original function
const CreateMove_t original = clientmode.GetMethod<CreateMove_t>(
offsets::CreateMove); // We call this on return so that we can process
// our stuff before create move
if (!cmd)
return original(thisptr, inputSample,
cmd); // Cant do anything without cmd
g_UserCmd = cmd; // Update the cmd
// Update ingame
if (!game::GetInGame()) return original(thisptr, inputSample, cmd);
// Run the frameworks worldtick
wtickmgr();
// Run the original to get result
bool ret = original(thisptr, inputSample, cmd);
// Save this so we can use it in FrameStageNotify to show angles in
// thirdperson
LastAngles = cmd->viewangles;
// If we are using silent aim, we return false
if (UsingSilent) {
// To use silent, we just dont return true, but we need to still correct
// movement so we do that too
auto local_ent =
g_IEntityList->GetClientEntity(g_IEngine->GetLocalPlayer());
if (local_ent) {
auto ang = [](CatVector forward)
-> CatVector { // Lambdas lmao :joy:, I had to rip this from
// cathook... Sad face...
CatVector ret;
if (forward.y == 0 && forward.x == 0) {
if (forward.z > 0)
ret.x = 270;
else
ret.x = 90;
} else {
ret.y = atan2(forward.y, forward.x) * 180 / PI;
if (ret.y < 0) ret.y += 360;
ret.x = atan2(-forward.z, sqrt(forward.x * forward.x +
forward.y * forward.y)) *
180 / PI;
if (ret.x < 0) ret.x += 360;
}
return ret;
}(CatVector(g_UserCmd->forwardmove, g_UserCmd->sidemove,
g_UserCmd->upmove));
auto yaw =
DEG2RAD(ang.y - GetCameraAngle((CatLocalPlayer*)local_ent).y +
g_UserCmd->viewangles.y);
auto speed = sqrt(g_UserCmd->forwardmove * g_UserCmd->forwardmove +
g_UserCmd->sidemove * g_UserCmd->sidemove);
g_UserCmd->forwardmove = cos(yaw) * speed;
g_UserCmd->sidemove = sin(yaw) * speed;
}
UsingSilent = false;
return false;
}
return ret;
}
#if defined(CATHOOK_TF2)
static CatVarBool no_zoom({"Visuals", "Misc"}, "no_zoom", false, "No Zoom",
"Disables scope overlay and zoom");
#endif
static void PaintTraverse_hook(void* _this, unsigned int vp, bool fr, bool ar) {
typedef void (*PaintTraverse_t)(void*, unsigned int, bool, bool);
const PaintTraverse_t original =
panel.GetMethod<PaintTraverse_t>(offsets::PaintTraverse);
static unsigned long panel_top = 0;
if (!panel_top && !strcmp("MatSystemTopPanel", g_IPanel->GetName(vp)))
panel_top = vp;
static unsigned long panel_focus = 0;
if (!panel_focus && !strcmp("FocusOverlayPanel", g_IPanel->GetName(vp)))
panel_focus = vp;
// No Zoom
#if defined(CATHOOK_TF2)
static unsigned long panel_scope = 0;
if (!panel_scope && !strcmp("HudScope", g_IPanel->GetName(vp)))
panel_scope = vp;
if (no_zoom && vp == panel_scope) return;
#endif
original(_this, vp, fr, ar); // Call the original function before we draw
// Logic to determine whether we should draw, no idea how it works
static bool draw_flag = false;
if (vp == panel_top) draw_flag = true;
if (vp != panel_focus) return;
g_IPanel->SetTopmostPopup(panel_focus, true);
if (!draw_flag) return;
draw_flag = false;
drawmgr(); // Call the managers draw tick
}
static CatVarInt fov_override({"Visuals", "Misc"}, "fov", 0, "Fov Override",
"Change fov");
static void OverrideView_hook(void* _this, CViewSetup* setup) {
typedef void (*OverrideView_t)(void*, CViewSetup*);
const OverrideView_t original =
clientmode.GetMethod<OverrideView_t>(offsets::OverrideView);
original(_this, setup);
// Set this for wts
wts::wts_viewsetup = setup;
// No-Zoom
#if defined(CATHOOK_TF2)
static ConVar* fov_desired = g_ICvar->FindVar("fov_desired");
auto local_ent =
g_IEntityList->GetClientEntity(g_IEngine->GetLocalPlayer());
if (no_zoom && local_ent && !local_ent->IsDormant() &&
HasCondition((CatEntity*)local_ent, TFCond_Zoomed)) {
if (fov_override)
setup->fov = fov_override;
else
setup->fov = fov_desired->GetFloat(); //
} else
#endif
if (fov_override)
setup->fov = fov_override;
}
static CatVarBool force_thirdperson(
{"Visuals", "Misc"}, "thirdperson", false, "Force Thirdperson",
"Forces thirdperson mode 99.9% of the time");
static void FrameStageNotify_hook(void* _this, int stage) {
typedef void (*FrameStageNotify_t)(void*, int);
const FrameStageNotify_t original =
client.GetMethod<FrameStageNotify_t>(offsets::FrameStageNotify);
if (stage == FRAME_RENDER_START) {
auto local_ent =
g_IEntityList->GetClientEntity(g_IEngine->GetLocalPlayer());
if (local_ent && !GetDormant((CatEntity*)local_ent) &&
GetAlive((CatEntity*)local_ent)) {
#if defined(CATHOOK_TF2)
// Force Thirdperson
NET_VAR(local_ent, netvars::m_nForceTauntCam, int) =
force_thirdperson;
#endif
// To show antiaim in thirdperson
if (force_thirdperson &&
stage == 5) { //&& g_IInput && g_IInput->CAM_IsThirdPerson()) {
NET_VAR(local_ent, netvars::deadflag + 4, float) = LastAngles.x;
NET_VAR(local_ent, netvars::deadflag + 8, float) = LastAngles.y;
}
}
}
original(_this, stage);
}
// Use this to init our hooks
void Init() {
// Client mode
clientmode.Set(g_IClientMode);
clientmode.HookMethod((void*)CreateMove_hook,
offsets::CreateMove); // World Tick
clientmode.HookMethod((void*)OverrideView_hook,
offsets::OverrideView); // Override View
clientmode.Apply();
// Panel
panel.Set(g_IPanel);
panel.HookMethod((void*)PaintTraverse_hook,
offsets::PaintTraverse); // Draw Tick
panel.Apply();
// Client
client.Set(g_IBaseClient);
client.HookMethod((void*)FrameStageNotify_hook, offsets::FrameStageNotify);
client.Apply();
}
} // namespace modules::source::hacks::hooks