2025-07-24 20:48:02 +03:00

726 lines
27 KiB
C++
Raw 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 "../visuals/visuals.h"
#include "CUserCmd.h"
#include "../../../templeware/utils/schema/schema.h"
#include <chrono>
#include <Windows.h>
#include <array>
#include <cmath>
#include <Psapi.h>
#include "../../menu/hud.h"
#include "../../menu/menu.h"
#include <iostream>
// Адреса из дампа (актуально для 2024-07-18)
#define DW_SENSITIVITY 0x1A6A9D8
#define DW_SENSITIVITY_SENS 0x40
float GetGameSensitivity() {
static float fallback = 2.0f;
HMODULE hClient = GetModuleHandleA("client.dll");
if (!hClient) return fallback;
uintptr_t sensBase = reinterpret_cast<uintptr_t>(hClient) + DW_SENSITIVITY;
uintptr_t sensPtr = *reinterpret_cast<uintptr_t*>(sensBase);
if (!sensPtr) return fallback;
float sens = *reinterpret_cast<float*>(sensPtr + DW_SENSITIVITY_SENS);
if (sens < 0.01f || sens > 20.0f) return fallback;
return sens;
}
// Индексы костей (актуально для 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;
float sensitivity = GetGameSensitivity();
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);
if (cached_players.empty() || !lp || !lp->handle().valid() || lp->getHealth() <= 0)
return;
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) + "Sens: " + std::to_string(sensitivity);
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) {
float bestFov = Config::aimbot_fov;
PlayerCache* bestTarget = nullptr;
QAngle_t bestAngle = { 0, 0, 0 };
for (auto& Player : cached_players) {
if (!Player.handle.valid() || Player.health <= 0 || Player.handle.index() == INVALID_EHANDLE_INDEX)
continue;
if (Config::teamCheck && (Player.team_num == cached_local.team))
continue;
Vector_t target_pos = Player.position + Player.viewOffset;
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 = &Player;
bestAngle = angle;
}
if (bestTarget) {
Vector_t target_pos = bestTarget->position + bestTarget->viewOffset;
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
QAngle_t cur_punch_angle = *(QAngle_t*)((uintptr_t)lp + SchemaFinder::Get(hash_32_fnv1a_const("C_CSPlayerPawn->m_aimPunchAngle")));
// --- RCS ---
bool rcsActive = false;
if (Config::shooterAfterAim && (GetAsyncKeyState(Config::triggerbot_key) & 0x8000)) {
rcsActive = (Config::rcs || Config::shooterAfterAim) && (shotCount > Config::rcsActivationShots);
}
else {
rcsActive = (Config::rcs || Config::shooterAfterAim) && (shotCount > Config::rcsActivationShots);
}
if (rcsActive && shotsFired > 1) {
// Для прямого изменения viewangles: делить НЕ нужно
//QAngle_t punchDelta = cur_punch_angle - last_punch_angle;
//g_DebugString = "debug: " + std::to_string(punchDelta.x);
angle -= cur_punch_angle * 2.f;
last_punch_angle = cur_punch_angle;
}
else {
last_punch_angle = { 0,0,0 };
}
angle.z = 0.f;
angle = angle.Normalize();
// --- Smooth ---
QAngle_t delta = (angle - *viewangles).Normalize();
if (Config::aimbot_smooth > 0.f) {
QAngle_t cur = *viewangles;
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) continue;
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 (!lp || !lp->handle().valid() || lp->getHealth() <= 0) {
lockedTarget = nullptr;
targetWasLost = false;
last_punch_angle = { 0,0,0 };
return;
}
if (
lockedTarget->get_entity_by_handle() == lp->get_entity_by_handle() ||
lockedTarget->getHealth() <= 0 ||
!lockedTarget->handle().valid()
) {
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 cur_punch_angle = *(QAngle_t*)((uintptr_t)lp + SchemaFinder::Get(hash_32_fnv1a_const("C_CSPlayerPawn->m_aimPunchAngle")));
// --- RCS ---
bool rcsActive = false;
if (Config::shooterAfterAim && (GetAsyncKeyState(Config::triggerbot_key) & 0x8000)) {
rcsActive = (Config::rcs || Config::shooterAfterAim) && (shotCount > Config::rcsActivationShots);
}
else {
rcsActive = (Config::rcs || Config::shooterAfterAim) && (shotCount > Config::rcsActivationShots);
}
if (rcsActive && shotCount > 1) {
// Для прямого изменения viewangles: делить НЕ нужно
//QAngle_t punchDelta = cur_punch_angle - last_punch_angle;
//g_DebugString = "debug: " + std::to_string(punchDelta.x);
angle -= cur_punch_angle * 2.f;
last_punch_angle = cur_punch_angle;
}
else {
last_punch_angle = { 0,0,0 };
}
angle.z = 0.f;
angle = angle.Normalize();
// --- 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) continue;
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;
}
void Ver2Aimbot(CUserCmd* pCmd) {
// --- Silent Aim: чистая и безопасная реализация ---
if (!Config::silent_aim || !pCmd) return;
static C_CSPlayerPawn* lockedTarget = nullptr;
static bool prevSilentState = false;
static QAngle_t last_punch_angle = { 0,0,0 };
static int shotCount = 0;
static bool targetWasLost = false;
static bool targetWasLockedThisPress = false;
C_CSPlayerPawn* lp = H::oGetLocalPlayer(0);
if (!lp || !lp->handle().valid() || lp->getHealth() <= 0) return;
Vector_t lep = GetEntityEyePos(lp);
// Получаем viewangles только из CUserCmd!
QAngle_t* cur = nullptr;
if (pCmd->csgoUserCmd.pBaseCmd && pCmd->csgoUserCmd.pBaseCmd->pViewAngles) {
cur = &pCmd->csgoUserCmd.pBaseCmd->pViewAngles->angValue;
}
if (!cur) return;
// --- Кнопка активации ---
bool silentActive = Config::always_on_silent_aim ? true : (GetAsyncKeyState(Config::silent_aim_key) & 0x8000);
if (Config::silent_shooterAfterAim && (GetAsyncKeyState(Config::triggerbot_key) & 0x8000)) {
silentActive = true;
}
int shotsFired = lp ? lp->getShotsFired() : 0;
shotCount = shotsFired;
// --- Сброс флагов при новом нажатии ---
if (silentActive && !prevSilentState) {
targetWasLost = false;
targetWasLockedThisPress = false;
}
// --- Поиск цели ---
if (silentActive && !lockedTarget) {
if (Config::silent_rage || (!targetWasLost && !targetWasLockedThisPress)) {
int nMaxHighestEntity = I::GameEntity->Instance->GetHighestEntityIndex();
float bestFov = Config::silent_aim_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) continue;
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;
// --- Выбор кости для silent aim ---
Vector_t target_pos;
switch (Config::silent_aim_bone) {
case Config::BONE_HEAD:
target_pos = GetBonePosition(pawn, BONE_INDEX_HEAD); break;
case Config::BONE_NECK:
target_pos = GetBonePosition(pawn, BONE_INDEX_NECK); break;
case Config::BONE_BODY:
target_pos = GetBonePosition(pawn, BONE_INDEX_BODY); break;
case Config::BONE_NEAREST:
default:
target_pos = GetAimbotTargetPos(pawn, lep, *cur); break;
}
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
float fov = GetFov(*cur, angle);
if (!std::isfinite(fov) || fov > bestFov) continue;
bestFov = fov;
bestTarget = pawn;
bestAngle = angle;
}
}
lockedTarget = bestTarget;
last_punch_angle = { 0,0,0 };
if (!Config::silent_rage && lockedTarget) targetWasLockedThisPress = true;
if (!Config::silent_rage && !lockedTarget) targetWasLost = true;
}
}
// --- Сброс при отпускании кнопки ---
if (!silentActive) {
lockedTarget = nullptr;
last_punch_angle = { 0,0,0 };
targetWasLost = false;
targetWasLockedThisPress = false;
}
// --- Наведение на цель ---
if (silentActive && lockedTarget) {
// Проверка валидности цели
if (!lp || !lp->handle().valid() || lp->getHealth() <= 0 ||
lockedTarget->get_entity_by_handle() == lp->get_entity_by_handle() ||
lockedTarget->getHealth() <= 0 ||
!lockedTarget->handle().valid() ||
(Config::team_check && lockedTarget->getTeam() == lp->getTeam())) {
lockedTarget = nullptr;
last_punch_angle = { 0,0,0 };
targetWasLost = true;
prevSilentState = silentActive;
return;
}
// --- Выбор кости для silent aim ---
Vector_t target_pos;
switch (Config::silent_aim_bone) {
case Config::BONE_HEAD:
target_pos = GetBonePosition(lockedTarget, BONE_INDEX_HEAD); break;
case Config::BONE_NECK:
target_pos = GetBonePosition(lockedTarget, BONE_INDEX_NECK); break;
case Config::BONE_BODY:
target_pos = GetBonePosition(lockedTarget, BONE_INDEX_BODY); break;
case Config::BONE_NEAREST:
default:
target_pos = GetAimbotTargetPos(lockedTarget, lep, *cur); break;
}
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
// --- Smooth ---
if (Config::silent_aim_smooth > 0.f) {
QAngle_t delta = (angle - *cur).Normalize();
float smooth = Config::silent_aim_smooth;
angle = *cur + delta * (1.f / smooth);
angle = angle.Normalize();
}
*cur = angle;
}
prevSilentState = silentActive;
}
// --- Функция для вывода отладочной информации через ImGui ---
void ShowSilentAimDebugInfo(const CUserCmd* pCmd) {
char debugBuf[256];
_snprintf_s(debugBuf, sizeof(debugBuf),
"CUserCmd: size=%zu, csgoUserCmd@%zu, nButtons@%zu, nSubticks=%d, pRep=%p, pBaseCmd=%p",
sizeof(CUserCmd),
offsetof(CUserCmd, csgoUserCmd),
offsetof(CUserCmd, nButtons),
pCmd->csgoUserCmd.inputHistoryField.nCurrentSize,
(void*)pCmd->csgoUserCmd.inputHistoryField.pRep,
(void*)pCmd->csgoUserCmd.pBaseCmd);
g_DebugString = debugBuf;
// ImGui::SetTooltip("%s", debugBuf); // Можно включить при необходимости
}
void SilentAimbot(CUserCmd* pCmd) {
static bool printed = false;
if (!printed) {
std::cout << "RepeatedPtrFieldPB_CS2=" << sizeof(RepeatedPtrFieldPB_CS2<int>)
<< ", CBaseUserCmdPB_CS2=" << sizeof(CBaseUserCmdPB_CS2)
<< ", CCSGOUserCmdPB_CS2=" << sizeof(CCSGOUserCmdPB_CS2)
<< ", CUserCmd=" << sizeof(CUserCmd)
<< ", csgoUserCmd@0x" << std::hex << offsetof(CUserCmd, csgoUserCmd)
<< ", nButtons@0x" << std::hex << offsetof(CUserCmd, nButtons)
<< std::dec << std::endl;
printed = true;
}
char debugBuf[256];
if (!Config::silent_aim || !pCmd) return;
static C_CSPlayerPawn* lockedTarget = nullptr;
static bool prevSilentState = false;
static QAngle_t last_punch_angle = { 0,0,0 };
static int shotCount = 0;
static bool targetWasLost = false;
static bool targetWasLockedThisPress = false;
C_CSPlayerPawn* lp = H::oGetLocalPlayer(0);
if (!lp || !lp->handle().valid() || lp->getHealth() <= 0) return;
Vector_t lep = GetEntityEyePos(lp);
// --- Кнопка активации ---
bool silentActive = Config::always_on_silent_aim ? true : (GetAsyncKeyState(Config::silent_aim_key) & 0x8000);
if (Config::silent_shooterAfterAim && (GetAsyncKeyState(Config::triggerbot_key) & 0x8000)) {
silentActive = true;
}
int shotsFired = lp ? lp->getShotsFired() : 0;
shotCount = shotsFired;
if (silentActive && !prevSilentState) {
targetWasLost = false;
targetWasLockedThisPress = false;
}
if (silentActive && !lockedTarget) {
if (Config::silent_rage || (!targetWasLost && !targetWasLockedThisPress)) {
int nMaxHighestEntity = I::GameEntity->Instance->GetHighestEntityIndex();
float bestFov = Config::silent_aim_fov;
C_CSPlayerPawn* bestTarget = nullptr;
QAngle_t bestAngle{};
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) continue;
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;
switch (Config::silent_aim_bone) {
case Config::BONE_HEAD:
target_pos = GetBonePosition(pawn, BONE_INDEX_HEAD); break;
case Config::BONE_NECK:
target_pos = GetBonePosition(pawn, BONE_INDEX_NECK); break;
case Config::BONE_BODY:
target_pos = GetBonePosition(pawn, BONE_INDEX_BODY); break;
case Config::BONE_NEAREST:
default:
target_pos = GetAimbotTargetPos(pawn, lep, QAngle_t{}); break;
}
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
float fov = sqrtf(angle.x * angle.x + angle.y * angle.y);
if (!std::isfinite(fov) || fov > bestFov) continue;
bestFov = fov;
bestTarget = pawn;
bestAngle = angle;
}
}
lockedTarget = bestTarget;
last_punch_angle = { 0,0,0 };
if (!Config::silent_rage && lockedTarget) targetWasLockedThisPress = true;
if (!Config::silent_rage && !lockedTarget) targetWasLost = true;
}
}
if (!silentActive) {
lockedTarget = nullptr;
last_punch_angle = { 0,0,0 };
targetWasLost = false;
targetWasLockedThisPress = false;
}
if (silentActive && lockedTarget) {
if (!lp || !lp->handle().valid() || lp->getHealth() <= 0 ||
lockedTarget->get_entity_by_handle() == lp->get_entity_by_handle() ||
lockedTarget->getHealth() <= 0 ||
!lockedTarget->handle().valid() ||
(Config::team_check && lockedTarget->getTeam() == lp->getTeam())) {
lockedTarget = nullptr;
last_punch_angle = { 0,0,0 };
targetWasLost = true;
prevSilentState = silentActive;
return;
}
Vector_t target_pos;
switch (Config::silent_aim_bone) {
case Config::BONE_HEAD:
target_pos = GetBonePosition(lockedTarget, BONE_INDEX_HEAD); break;
case Config::BONE_NECK:
target_pos = GetBonePosition(lockedTarget, BONE_INDEX_NECK); break;
case Config::BONE_BODY:
target_pos = GetBonePosition(lockedTarget, BONE_INDEX_BODY); break;
case Config::BONE_NEAREST:
default:
target_pos = GetAimbotTargetPos(lockedTarget, lep, QAngle_t{}); break;
}
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
// --- Smooth ---
if (Config::silent_aim_smooth > 0.f) {
QAngle_t cur = angle;
bool found = false;
for (int i = 0; i < 8; ++i) {
CCSGOInputHistoryEntryPB_CS2* entry = pCmd->GetInputHistoryEntry(i);
if (entry && entry->pViewAngles) {
cur = entry->pViewAngles->angValue;
found = true;
break;
}
}
QAngle_t delta = (angle - cur).Normalize();
float smooth = Config::silent_aim_smooth;
angle = cur + delta * (1.f / smooth);
angle = angle.Normalize();
}
// --- Устанавливаем угол для всех сабтиков ---
int nSubticks = pCmd->csgoUserCmd.inputHistoryField.nCurrentSize;
_snprintf_s(debugBuf, sizeof(debugBuf), "nSubticks=%d, pRep=%p", nSubticks, (void*)pCmd->csgoUserCmd.inputHistoryField.pRep);
// g_DebugString = debugBuf; // Удалено
// --- Расширенный отладочный вывод ---
// char debugBuf[256]; // Удалено
// _snprintf_s(debugBuf, sizeof(debugBuf), // Удалено
// "CUserCmd: size=%zu, csgoUserCmd@%zu, nButtons@%zu, nSubticks=%d, pRep=%p, pBaseCmd=%p", // Удалено
// sizeof(CUserCmd), // Удалено
// offsetof(CUserCmd, csgoUserCmd), // Удалено
// offsetof(CUserCmd, nButtons), // Удалено
// pCmd->csgoUserCmd.inputHistoryField.nCurrentSize, // Удалено
// (void*)pCmd->csgoUserCmd.inputHistoryField.pRep, // Удалено
// (void*)pCmd->csgoUserCmd.pBaseCmd); // Удалено
// g_DebugString = debugBuf; // Удалено
ShowSilentAimDebugInfo(pCmd);
_snprintf_s(debugBuf, sizeof(debugBuf),
"sizeof(CUserCmd)=%zu, csgoUserCmd@0x%zX, nButtons@0x%zX",
sizeof(CUserCmd),
offsetof(CUserCmd, csgoUserCmd),
offsetof(CUserCmd, nButtons));
g_DebugString = debugBuf;
_snprintf_s(debugBuf, sizeof(debugBuf),
"sizeof(CUserCmd)=%zu, csgoUserCmd@0x%zX, nButtons@0x%zX, RepeatedPtrFieldPB_CS2=%zu, CBaseUserCmdPB_CS2=%zu",
sizeof(CUserCmd),
offsetof(CUserCmd, csgoUserCmd),
offsetof(CUserCmd, nButtons),
sizeof(RepeatedPtrFieldPB_CS2<int>),
sizeof(CBaseUserCmdPB_CS2));
g_DebugString = debugBuf;
_snprintf_s(debugBuf, sizeof(debugBuf),
"RepeatedPtrFieldPB_CS2=%zu, CBaseUserCmdPB_CS2=%zu, CCSGOUserCmdPB_CS2=%zu, CUserCmd=%zu, csgoUserCmd@0x%zX, nButtons@0x%zX",
sizeof(RepeatedPtrFieldPB_CS2<int>),
sizeof(CBaseUserCmdPB_CS2),
sizeof(CCSGOUserCmdPB_CS2),
sizeof(CUserCmd),
offsetof(CUserCmd, csgoUserCmd),
offsetof(CUserCmd, nButtons));
g_DebugString = debugBuf;
}
prevSilentState = silentActive;
}