Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Исходник [Сурс] EFT Aimbot — База на IL2CPP и фикс фликов

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
445
Реакции
10
Здарова, реверсеры.

Наткнулся на классическую проблему при написании аима под Тарков. Чел жалуется, что при наводке камеру разворачивает на 180 градусов. Знакомая ситуация? Это база для тех, кто лезет в MovementContext без понимания того, как EFT крутит ротации и как работают локальные координаты в Unity.

Что внутри этого сурса:
  1. Полная интеграция с IL2CPP для вызова нативных методов игры.
  2. Работа через MovementContext::set_Rotation — самый популярный метод для внутренних читов.
  3. Реализован VisCheck и выбор кости (в данном конфиге выбран Neck для более стабильного попадания).
  4. Настройки FOV, Smoothing и Sensitivity через ImGui.
  5. World-to-Screen отрисовка таргета и линий.

Техническое мясо:
Проблема с фликами, которую описывает автор кода, часто связана с тем, что дельта-расчет не учитывает нормализацию углов. В EFT MovementContext довольно капризный: если сетить углы напрямую без учета текущей ротации или с слишком резким шагом, BattlEye может и не сразу, но сервер точно начнет «лагать» для вас.

Код:
Expand Collapse Copy
#pragma once
#include "../eft_api.h"
#include "../game_state.h"
#include "../Module.h"
#include "../../config/ColorpickerValue.h"
#include "../../config/FloatSliderValue.h"
#include "../../config/IntSliderValue.h"
#include "../../config/KeybindValue.h"
#include "../../il2cpp/il2utils.h"
#include "../../il2cpp/Il2CppObjectInstance.h"
#include "../../il2cpp/unity.h"
#include "../../util/player_utils.h"
 
static unity::vector3 target_store = {};
static Il2CppObject* stored_player = nullptr;
 
class AimbotModule : Module
{
public:
    AimbotModule() : Module("Aimbot", Aimbot)
    {
    }
 
    CheckboxValue* aim = conf(new CheckboxValue(false, "Aim"));
    KeybindValue* aim_key = conf(new KeybindValue(VK_XBUTTON2, "Aim Key"));
    IntSliderValue* fov = conf(new IntSliderValue(200, 50, 400, "Fov"));
    CheckboxValue* show_fov = conf(new CheckboxValue(false, "Show Fov"));
    ColorpickerValue* fov_color = conf(new ColorpickerValue({ 1, 0, 1, 1 }, "Fov Color"));
    CheckboxValue* vis_check = conf(new CheckboxValue(false, "Vis Check"));
    FloatSliderValue* smooth = conf(new FloatSliderValue(5, 1, 10, "Smooth"));
    FloatSliderValue* sensitivity = conf(new FloatSliderValue(0.01f, 0.001f, 0.05f, "Sensitivity"));
    CheckboxValue* invert_x = conf(new CheckboxValue(false, "Invert X"));
    CheckboxValue* invert_y = conf(new CheckboxValue(false, "Invert Y"));
    CheckboxValue* show_target = conf(new CheckboxValue(true, "Show Target"));
    FloatSliderValue* target_size = conf(new FloatSliderValue(3, 1, 10, "Target Size"));
    ColorpickerValue* target_color = conf(new ColorpickerValue({ 1, 0, 1, 1 }, "Target Color"));
    CheckboxValue* show_line = conf(new CheckboxValue(false, "Show Line"));
    ColorpickerValue* line_color = conf(new ColorpickerValue({ 1, 0, 0, 1 }, "Line Color"));
 
    void draw_overlay(ImDrawList* draw_list) override
    {
        if (!game_state::is_in_raid) return;
 
        Il2CppObject* cam = unity::get_current_camera();
        if (!cam) return;
 
        const float screen_center_x = menu::get_width() / 2.0f;
        const float screen_center_y = menu::get_height() / 2.0f;
 
        if (aim->get_value() && show_target->get_value())
        {
            if (!(target_store.x == 0 && target_store.y == 0))
            {
                if (unity::vector3 screen_pos = eft_api::world_to_screen(cam, target_store, game_state::current_zoom);
                    eft_api::is_visible(screen_pos))
                {
                    draw_list->AddCircleFilled(
                        { screen_pos.x, screen_pos.y },
                        target_size->get_value() * menu::get_scale_factor(),
                        ImGui::GetColorU32(target_color->get_value())
                    );
 
                    if (show_line->get_value())
                    {
                        draw_list->AddLine(
                            { screen_center_x, screen_center_y },
                            { screen_pos.x, screen_pos.y },
                            ImGui::GetColorU32(line_color->get_value()), 2.0f
                        );
                    }
                }
            }
        }
 
        if (show_fov->get_value())
        {
            draw_list->AddCircle(
                { screen_center_x, screen_center_y },
                static_cast<float>(fov->get_value()) * menu::get_scale_factor(),
                ImGui::GetColorU32(fov_color->get_value())
            );
        }
 
        if (stored_player && game_state::is_in_raid)
        {
            Il2CppObjectInstance player_instance(stored_player);
            if (!player_instance.is_valid()) return;
 
            auto get_mc_fn = player_instance.get_method<Il2CppObject* (*)(Il2CppObject*)>("get_MovementContext", 0);
            if (!get_mc_fn) return;
 
            Il2CppObject* movement_context = get_mc_fn(stored_player);
 
            if (movement_context)
            {
                Il2CppObjectInstance mc(movement_context);
                if (!mc.is_valid()) return;
 
                auto get_rot_fn = mc.get_method<unity::vector2(*)(Il2CppObject*)>("get_Rotation", 0);
                if (!get_rot_fn) return;
 
                unity::vector2 rot = get_rot_fn(movement_context);
 
                Il2CppObject* debug_cam = unity::get_current_camera();
                unity::vector3 debug_screen = eft_api::world_to_screen(debug_cam, target_store, game_state::current_zoom);
 
                char buf[256];
                snprintf(buf, sizeof(buf),
                    "rot.x=%.2f rot.y=%.2f | diff_x=%.2f diff_y=%.2f",
                    rot.x, rot.y,
                    debug_screen.x - screen_center_x,
                    debug_screen.y - screen_center_y);
 
                draw_list->AddText({ 10, 10 }, IM_COL32(255, 255, 0, 255), buf);
            }
        }
    }
 
    void application_update() override
    {
        if (!game_state::is_in_raid) return;
        if (!aim->get_value()) return;
        if (!GetAsyncKeyState(aim_key->get_value())) return;
        if (target_store.x == 0 && target_store.y == 0) return;
        if (!stored_player) return;
 
        Il2CppObject* cam = unity::get_current_camera();
        if (!cam) return;
        unity::vector3 screen_pos = eft_api::world_to_screen(cam, target_store, 1.0f);
 
        if (!eft_api::is_visible(screen_pos)) return;
 
        const float screen_center_x = menu::get_width() / 2.0f;
        const float screen_center_y = menu::get_height() / 2.0f;
 
        // small left correction for head bone offset, tune if needed
        const float bone_offset_x = -5.0f;
        const float diff_x = (screen_pos.x + bone_offset_x) - screen_center_x;
        const float diff_y = screen_pos.y - screen_center_y;
 
        if (abs(diff_x) < 2.0f && abs(diff_y) < 2.0f) return;
 
        Il2CppObjectInstance player_instance(stored_player);
        if (!player_instance.is_valid()) return;
 
        auto get_mc_fn = player_instance.get_method<Il2CppObject* (*)(Il2CppObject*)>("get_MovementContext", 0);
        if (!get_mc_fn) return;
 
        Il2CppObject* movement_context = get_mc_fn(stored_player);
        if (!movement_context) return;
 
        Il2CppObjectInstance mc(movement_context);
        if (!mc.is_valid()) return;
 
        auto get_rot_fn = mc.get_method<unity::vector2(*)(Il2CppObject*)>("get_Rotation", 0);
        if (!get_rot_fn) return;
 
        unity::vector2 current_rotation = get_rot_fn(movement_context);
        
        auto set_rot_fn = mc.get_method<void(*)(Il2CppObject*, unity::vector2)>("set_Rotation", 1);
        if (!set_rot_fn) return;
 
        const float max_step = 1.5f; // Lowered to prevent hard flickering
 
        float delta_x = diff_x * sensitivity->get_value();
        float delta_y = diff_y * sensitivity->get_value();
 
        if (invert_x->get_value()) delta_x = -delta_x;
        if (invert_y->get_value()) delta_y = -delta_y;
 
        delta_x = max(-max_step, min(delta_x, max_step));
        delta_y = max(-max_step, min(delta_y, max_step));
 
        const float t = 1.0f / smooth->get_value();
        current_rotation.x -= delta_x * t;
        current_rotation.y += delta_y * t;
 
        current_rotation.y = max(-85.0f, min(current_rotation.y, 85.0f));
 
        set_rot_fn(movement_context, current_rotation);
    }
 
    void gameworld_update(const Il2CppClass* game_world_class, Il2CppObjectInstance game_world_instance,
        Il2CppObjectInstance main_player) override
    {
        const auto get_profile = main_player.get_method<Il2CppObject * (*)(Il2CppObject*)>("get_Profile", 0);
        Il2CppObjectInstance main_profile(get_profile(main_player.get_instance()));
 
        const std::string main_nickname = eft_api::to_english(il2utils::conv_wstring(
            main_profile.get_method<Il2CppString * (*)(Il2CppObject*)>("get_Nickname", 0)(
                main_profile.get_instance())));
 
        if (!game_state::is_in_raid || !aim->get_value())
        {
            target_store = {};
            stored_player = nullptr;
            return;
        }
 
        Il2CppObject* cam = unity::get_current_camera();
        if (!cam)
        {
            target_store = {};
            return;
        }
 
        const float screen_center_x = menu::get_width() / 2.0f;
        const float screen_center_y = menu::get_height() / 2.0f;
        const unity::vector3 screen_center = { screen_center_x, screen_center_y, 0 };
 
        const float fov_radius = static_cast<float>(fov->get_value());
 
        float closest = FLT_MAX;
        unity::vector3 closest_pos = {};
 
        Il2CppArray* alive_players = game_world_instance.get_field<unity::list*>("RegisteredPlayers")->
            m_p_list_array;
        for (size_t i = 0; i < alive_players->max_length; ++i)
        {
            Il2CppObject* player_object =
                reinterpret_cast<Il2CppObject**>(&alive_players->data)[i];
            if (!player_object) continue;
            Il2CppObjectInstance player_instance(player_object);
 
            Il2CppObject* profile_ptr = get_profile(player_instance.get_instance());
            std::string nickname;
            if (std::string(player_object->klass->name) == "ObservedPlayerView")
            {
                nickname = player_utils::get_networked_player_name(&player_instance);
            }
            else
            {
                Il2CppObjectInstance profile_instance(profile_ptr);
                nickname = eft_api::to_english(il2utils::conv_wstring(
                    profile_instance.get_method<Il2CppString * (*)(Il2CppObject*)>("get_Nickname", 0)(
                        profile_instance.get_instance())));
            }
 
            if (nickname == main_nickname) continue;
 
            Il2CppObjectInstance player_body(
                player_instance.get_method<Il2CppObject * (*)(Il2CppObject*)>("get_PlayerBody", 0)(player_object));
            Il2CppObjectInstance player_bones(player_body.get_field<Il2CppObject*>("PlayerBones"));
            // using Neck instead of Head for better center alignment
            Il2CppObjectInstance bifacial_transform_head(player_bones.get_field<Il2CppObject*>("Neck"));
            const unity::vector3 head_pos = bifacial_transform_head.get_method<unity::vector3(
                *)(Il2CppObject*)>("get_position", 0)(bifacial_transform_head.get_instance());
 
            unity::vector3 screen_pos = eft_api::world_to_screen(cam, head_pos, game_state::current_zoom);
 
            if (!eft_api::is_visible(screen_pos)) continue;
 
            screen_pos.z = 0;
 
            const float dist = screen_pos.distance(screen_center);
            if (dist > fov_radius) continue;
 
            if (dist < closest)
            {
                closest_pos = head_pos;
                closest = dist;
            }
        }
 
        target_store = closest_pos;
    }
 
    void init() override
    {
    }
};

Автор использует BifacialTransform для получения позиции костей. Это надежнее, чем старые методы, но не забывайте, что в последних патчах BSG добавили проверки на скорость изменения вектора взгляда. Если выставить smooth на минимум — аккаунт долго не проживет. Также обратите внимание на bone_offset_x — это костыль для компенсации смещения головы, который лучше настраивать динамически под конкретный FOV.

Кто уже допиливал этот метод, как сейчас обходите проверку на аномальные ротации в RAID?
 
Назад
Сверху Снизу