#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 #include #include "../../menu/hud.h" #include "../../menu/menu.h" #include #include // Индексы костей (актуально для 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(addr); // } // } Vector_t GetBonePosition(const C_CSPlayerPawn* Entity, int boneIdx) { if (!Entity) return {}; // Внешний способ: читаем Vector3 по адресу boneMatrix + boneIdx * 0x20 uintptr_t pGameSceneNode = *reinterpret_cast((uintptr_t)Entity + 0x328); if (!pGameSceneNode) return {}; uintptr_t pBoneMatrix = *reinterpret_cast(pGameSceneNode + 0x1F0); if (!pBoneMatrix) return {}; return *reinterpret_cast(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 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)Entity + SchemaFinder::Get(hash_32_fnv1a_const("C_BaseEntity->m_pGameSceneNode"))); auto Origin = *reinterpret_cast(game_scene_node + SchemaFinder::Get(hash_32_fnv1a_const("CGameSceneNode->m_vecAbsOrigin"))); auto ViewOffset = *reinterpret_cast((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(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, чтобы аимбот работал всегда //} }