2025-07-18 15:14:02 +03:00

413 lines
18 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "../../../cs2/entity/C_CSPlayerPawn/C_CSPlayerPawn.h"
#include "../../../templeware/interfaces/CGameEntitySystem/CGameEntitySystem.h"
#include "../../../templeware/interfaces/interfaces.h"
#include "../../../templeware/hooks/hooks.h"
#include "../../../templeware/config/config.h"
#include "../../utils/memory/patternscan/patternscan.h"
#include <chrono>
#include <Windows.h>
#include "../../menu/hud.h"
#include "../../menu/menu.h"
#include <array>
#include <cmath>
// Индексы костей (актуально для CS2)
constexpr int BONE_INDEX_HEAD = 6; // Head
constexpr int BONE_INDEX_NECK = 5; // Neck
constexpr int BONE_INDEX_BODY = 4;//0; // Pelvis/Root
// --- lastBoneIdx теперь глобальный static ---
static int lastBoneIdx = -1;
inline QAngle_t CalcAngles(Vector_t viewPos, Vector_t aimPos)
{
QAngle_t angle = { 0, 0, 0 };
Vector_t delta = aimPos - viewPos;
angle.x = -asin(delta.z / delta.Length()) * (180.0f / 3.141592654f);
angle.y = atan2(delta.y, delta.x) * (180.0f / 3.141592654f);
return angle;
}
inline float GetFov(const QAngle_t& viewAngle, const QAngle_t& aimAngle)
{
QAngle_t delta = (aimAngle - viewAngle).Normalize();
return sqrtf(powf(delta.x, 2.0f) + powf(delta.y, 2.0f));
}
// // Сигнатура функции GetBonePosition (актуально для client.dll):
// // 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? 4D 8B F1
// using GetBonePositionFn = int64_t(__fastcall*)(void*, uint32_t, Vector_t*, Vector_t*);
// static GetBonePositionFn oGetBonePosition = nullptr;
// static void InitGetBonePositionSig() {
// if (!oGetBonePosition) {
// uintptr_t addr = M::patternScan("client.dll", "48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? 4D 8B F1");
// oGetBonePosition = reinterpret_cast<GetBonePositionFn>(addr);
// }
// }
Vector_t GetBonePosition(const C_CSPlayerPawn* Entity, int boneIdx) {
if (!Entity) return {};
// Внешний способ: читаем Vector3 по адресу boneMatrix + boneIdx * 0x20
uintptr_t pGameSceneNode = *reinterpret_cast<uintptr_t*>((uintptr_t)Entity + 0x328);
if (!pGameSceneNode) return {};
uintptr_t pBoneMatrix = *reinterpret_cast<uintptr_t*>(pGameSceneNode + 0x1F0);
if (!pBoneMatrix) return {};
return *reinterpret_cast<Vector_t*>(pBoneMatrix + boneIdx * 0x20);
}
// Получить позицию для аимбота в зависимости от выбора пользователя
Vector_t GetAimbotTargetPos(const C_CSPlayerPawn* Entity, const Vector_t& from, const QAngle_t& viewAngles) {
switch (Config::aimbot_bone) {
case Config::BONE_HEAD:
return GetBonePosition(Entity, BONE_INDEX_HEAD);
case Config::BONE_NECK:
return GetBonePosition(Entity, BONE_INDEX_NECK);
case Config::BONE_BODY:
return GetBonePosition(Entity, BONE_INDEX_BODY);
case Config::BONE_NEAREST:
default: {
// Каждый раз ищем ближайшую кость по FOV
std::array<int, 2> bones = {BONE_INDEX_HEAD, BONE_INDEX_BODY};
float bestFov = FLT_MAX;
int bestIdx = BONE_INDEX_HEAD;
for (int idx : bones) {
Vector_t pos = GetBonePosition(Entity, idx);
QAngle_t ang = CalcAngles(from, pos); // <-- Исправлено!
float fov = GetFov(viewAngles, ang);
if (fov < bestFov && std::isfinite(fov)) {
bestFov = fov;
bestIdx = idx;
}
}
return GetBonePosition(Entity, bestIdx);
}
}
}
Vector_t GetEntityEyePos(const C_CSPlayerPawn* Entity) {
if (!Entity)
return {};
uintptr_t game_scene_node = *reinterpret_cast<uintptr_t*>((uintptr_t)Entity + SchemaFinder::Get(hash_32_fnv1a_const("C_BaseEntity->m_pGameSceneNode")));
auto Origin = *reinterpret_cast<Vector_t*>(game_scene_node + SchemaFinder::Get(hash_32_fnv1a_const("CGameSceneNode->m_vecAbsOrigin")));
auto ViewOffset = *reinterpret_cast<Vector_t*>((uintptr_t)Entity + SchemaFinder::Get(hash_32_fnv1a_const("C_BaseModelEntity->m_vecViewOffset")));
Vector_t Result = Origin + ViewOffset;
if (!std::isfinite(Result.x) || !std::isfinite(Result.y) || !std::isfinite(Result.z))
return {};
return Result;
}
void Aimbot() {
static C_CSPlayerPawn* lockedTarget = nullptr;
static bool prevAimbotState = false;
static bool targetWasLost = false;
static QAngle_t last_punch_angle = {0,0,0};
static int shotCount = 0;
bool aimbotActive = Config::always_on_aimbot ? true : Config::aimbot;
// --- shooterAfterAim + triggerbot_key ---
if (Config::shooterAfterAim && (GetAsyncKeyState(Config::triggerbot_key) & 0x8000)) {
aimbotActive = true;
}
C_CSPlayerPawn* lp = H::oGetLocalPlayer(0);
Vector_t lep = GetEntityEyePos(lp);
QAngle_t* viewangles = (QAngle_t*)(modules.getModule("client") + 0x1A78650);
bool isShooting = (GetAsyncKeyState(Config::triggerbot_key) & 0x8000) || (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
int shotsFired = lp ? lp->getShotsFired() : 0;
shotCount = shotsFired;
g_DebugString = "debug: " + std::to_string(shotsFired);
if (Config::aimbot_on_lmb && !Config::always_on_aimbot) {
aimbotActive = isShooting;
}
// Получаем локального игрока и viewangles всегда, чтобы не дублировать код
// C_CSPlayerPawn* lp = H::oGetLocalPlayer(0);
// Vector_t lep = GetEntityEyePos(lp);
// QAngle_t* viewangles = (QAngle_t*)(modules.getModule("client") + 0x1A78650);
// Проверка: стреляет ли игрок (LMB)
// bool isShooting = (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
// --- Новый режим: always_on_aimbot ---
if (Config::always_on_aimbot) {
int nMaxHighestEntity = I::GameEntity->Instance->GetHighestEntityIndex();
float bestFov = Config::aimbot_fov;
C_CSPlayerPawn* bestTarget = nullptr;
QAngle_t bestAngle = { 0, 0, 0 };
for (int i = 1; i <= nMaxHighestEntity; i++) {
auto Entity = I::GameEntity->Instance->Get(i);
if (!Entity)
continue;
if (!Entity->handle().valid())
continue;
SchemaClassInfoData_t* _class = nullptr;
Entity->dump_class_info(&_class);
if (!_class)
continue;
const uint32_t hash = HASH(_class->szName);
if (hash == HASH("C_CSPlayerPawn")) {
C_CSPlayerPawn* pawn = (C_CSPlayerPawn*)Entity;
if (pawn->get_entity_by_handle() == lp->get_entity_by_handle())
continue;
if (pawn->getHealth() <= 0)
continue;
if (Config::team_check && pawn->getTeam() == lp->getTeam())
continue;
Vector_t target_pos = GetEntityEyePos(pawn);//GetAimbotTargetPos(pawn, lep);
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
const float fov = GetFov(*viewangles, angle);
if (!std::isfinite(fov) || fov > bestFov)
continue;
bestFov = fov;
bestTarget = pawn;
bestAngle = angle;
}
}
if (bestTarget) {
Vector_t target_pos = GetAimbotTargetPos(bestTarget, lep, *viewangles);
//Vector_t target_pos = GetEntityEyePos(bestTarget);
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
QAngle_t ang_punch_angle = *(QAngle_t*)((uintptr_t)lp + SchemaFinder::Get(hash_32_fnv1a_const("C_CSPlayerPawn->m_aimPunchAngle")));
if (isShooting) {
last_punch_angle = ang_punch_angle;
} else {
last_punch_angle = {0,0,0};
}
// --- RCS ---
bool rcsActive = (Config::rcs || Config::shooterAfterAim) && (shotCount > 1);
if (rcsActive)
angle -= last_punch_angle * 2.f;
angle.z = 0.f;
angle = angle.Normalize();
// --- RCS ---
QAngle_t delta = (angle - *viewangles).Normalize();
if (rcsActive) {
float smooth_rcs = Config::aimbot_smooth;
if (Config::aimbot_dynamic_smooth) {
float fov = sqrtf(delta.x * delta.x + delta.y * delta.y);
float maxFov = Config::aimbot_fov;
float factor = (maxFov > 0.01f) ? (fov / maxFov) : 0.f;
smooth_rcs = Config::aimbot_smooth + (Config::aimbot_smooth * factor * Config::aimbot_dynamic_smooth_factor);
}
smooth_rcs = std::fmax(smooth_rcs / 10.f, 1.0f);
angle -= last_punch_angle * 2.f * smooth_rcs;
}
// --- Smooth ---
if (Config::aimbot_smooth > 0.f) {
QAngle_t cur = *viewangles;
QAngle_t delta = (angle - cur).Normalize();
float smooth = Config::aimbot_smooth;
if (Config::aimbot_dynamic_smooth) {
float fov = sqrtf(delta.x * delta.x + delta.y * delta.y);
float maxFov = Config::aimbot_fov;
float factor = (maxFov > 0.01f) ? (fov / maxFov) : 0.f;
smooth = smooth + (smooth * factor * Config::aimbot_dynamic_smooth_factor);
}
angle = cur + delta * (1.f / smooth);
angle = angle.Normalize();
*viewangles = angle;
} else {
*viewangles = angle;
}
}
// В этом режиме не используем lockedTarget и не трогаем targetWasLost/prevAimbotState
return;
}
// Если кнопка только что нажата (переход с false на true) — ищем новую цель
if (aimbotActive && !prevAimbotState) {
lastBoneIdx = -1; // Сброс при новой активации
int nMaxHighestEntity = I::GameEntity->Instance->GetHighestEntityIndex();
float bestFov = Config::aimbot_fov;
C_CSPlayerPawn* bestTarget = nullptr;
QAngle_t bestAngle = { 0, 0, 0 };
for (int i = 1; i <= nMaxHighestEntity; i++) {
auto Entity = I::GameEntity->Instance->Get(i);
if (!Entity)
continue;
if (!Entity->handle().valid())
continue;
SchemaClassInfoData_t* _class = nullptr;
Entity->dump_class_info(&_class);
if (!_class)
continue;
const uint32_t hash = HASH(_class->szName);
if (hash == HASH("C_CSPlayerPawn")) {
C_CSPlayerPawn* pawn = (C_CSPlayerPawn*)Entity;
if (pawn->get_entity_by_handle() == lp->get_entity_by_handle())
continue;
if (pawn->getHealth() <= 0)
continue;
if (Config::team_check && pawn->getTeam() == lp->getTeam())
continue;
Vector_t target_pos = GetEntityEyePos(pawn);//GetAimbotTargetPos(pawn, lep);
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
const float fov = GetFov(*viewangles, angle);
if (!std::isfinite(fov) || fov > bestFov)
continue;
bestFov = fov;
bestTarget = pawn;
bestAngle = angle;
}
}
lockedTarget = bestTarget;
targetWasLost = false;
// Сброс punch_angle при смене цели
last_punch_angle = {0,0,0};
}
// Если кнопка отпущена — сбрасываем захват
if (!aimbotActive) {
lockedTarget = nullptr;
targetWasLost = false;
last_punch_angle = {0,0,0}; // сброс rcs
// Сброс lastBoneIdx при отпускании кнопки аимбота (например, в Aimbot()):
// if (!aimbotActive) lastBoneIdx = -1;
}
// Если есть захваченная цель и кнопка удерживается
if (aimbotActive && lockedTarget) {
// Проверяем, что цель всё ещё валидна
if (!lockedTarget->handle().valid() || lockedTarget->getHealth() <= 0) {
lockedTarget = nullptr;
targetWasLost = true;
// Не ищем новую цель до повторного нажатия!
last_punch_angle = {0,0,0}; // сброс rcs
}
else {
Vector_t target_pos = GetAimbotTargetPos(lockedTarget, lep, *viewangles);
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
QAngle_t ang_punch_angle = *(QAngle_t*)((uintptr_t)lp + SchemaFinder::Get(hash_32_fnv1a_const("C_CSPlayerPawn->m_aimPunchAngle")));
if (isShooting) {
last_punch_angle = ang_punch_angle;
} else {
last_punch_angle = {0,0,0};
}
// --- RCS ---
bool rcsActive = (Config::rcs || Config::shooterAfterAim) && (shotCount > 1);
if (rcsActive)
angle -= last_punch_angle * 2.f;
angle.z = 0.f;
angle = angle.Normalize();
// --- RCS ---
QAngle_t delta = (angle - *viewangles).Normalize();
if (rcsActive) {
float smooth_rcs = Config::aimbot_smooth;
if (Config::aimbot_dynamic_smooth) {
float fov = sqrtf(delta.x * delta.x + delta.y * delta.y);
float maxFov = Config::aimbot_fov;
float factor = (maxFov > 0.01f) ? (fov / maxFov) : 0.f;
smooth_rcs = Config::aimbot_smooth + (Config::aimbot_smooth * factor * Config::aimbot_dynamic_smooth_factor);
}
smooth_rcs = std::fmax(smooth_rcs / 10.f, 1.0f);
angle -= last_punch_angle * 2.f * smooth_rcs;
}
// --- Smooth ---
if (Config::aimbot_smooth > 0.f) {
QAngle_t cur = *viewangles;
QAngle_t delta = (angle - cur).Normalize();
float smooth = Config::aimbot_smooth;
if (Config::aimbot_dynamic_smooth) {
float fov = sqrtf(delta.x * delta.x + delta.y * delta.y);
float maxFov = Config::aimbot_fov;
float factor = (maxFov > 0.01f) ? (fov / maxFov) : 0.f;
smooth = smooth + (smooth * factor * Config::aimbot_dynamic_smooth_factor);
}
angle = cur + delta * (1.f / smooth);
angle = angle.Normalize();
*viewangles = angle;
} else {
*viewangles = angle;
}
}
}
//Если кнопка зажата, цели нет, и мы не теряли цель (т.е. только в начале или если цели не было вообще)
if (aimbotActive && !lockedTarget && !targetWasLost) {
int nMaxHighestEntity = I::GameEntity->Instance->GetHighestEntityIndex();
float bestFov = Config::aimbot_fov;
C_CSPlayerPawn* bestTarget = nullptr;
QAngle_t bestAngle = { 0, 0, 0 };
for (int i = 1; i <= nMaxHighestEntity; i++) {
auto Entity = I::GameEntity->Instance->Get(i);
if (!Entity)
continue;
if (!Entity->handle().valid())
continue;
SchemaClassInfoData_t* _class = nullptr;
Entity->dump_class_info(&_class);
if (!_class)
continue;
const uint32_t hash = HASH(_class->szName);
if (hash == HASH("C_CSPlayerPawn")) {
C_CSPlayerPawn* pawn = (C_CSPlayerPawn*)Entity;
if (pawn->get_entity_by_handle() == lp->get_entity_by_handle())
continue;
if (pawn->getHealth() <= 0)
continue;
if (Config::team_check && pawn->getTeam() == lp->getTeam())
continue;
Vector_t target_pos = GetEntityEyePos(pawn);//GetAimbotTargetPos(pawn, lep);
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
const float fov = GetFov(*viewangles, angle);
if (!std::isfinite(fov) || fov > bestFov)
continue;
bestFov = fov;
bestTarget = pawn;
bestAngle = angle;
}
}
lockedTarget = bestTarget;
// Сброс punch_angle при смене цели
last_punch_angle = {0,0,0};
}
prevAimbotState = aimbotActive;
//if (Config::shooterAfterAim) {
// if (g_ShowMenu) return;
// C_CSPlayerPawn* lp = H::oGetLocalPlayer(0);
// bool onEnemy = false;
// if (lp) {
// int crosshairIdx = *(int*)((uintptr_t)lp + 0x1458); // m_iIDEntIndex
// if (crosshairIdx > 0) {
// auto target = I::GameEntity->Instance->Get<C_CSPlayerPawn>(crosshairIdx);
// if (target && target->getHealth() > 0 && (!Config::team_check || target->getTeam() != lp->getTeam()))
// onEnemy = true;
// }
// }
// // Если врага нет под прицелом — всегда блокируем ЛКМ
// if (!onEnemy && (GetAsyncKeyState(VK_LBUTTON) & 0x8000)) {
// INPUT input = { 0 };
// input.type = INPUT_MOUSE;
// input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
// SendInput(1, &input, sizeof(INPUT));
// }
// // return; // Не делаем return, чтобы аимбот работал всегда
//}
}