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

Исходник [Сурс] APB Reloaded — Исходник Colorbot на C++ (BitBlt + Exclusion Area)

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
507
Реакции
13
Наткнулся на просторах на исходник простенького колорбота для APB Reloaded. Автор, судя по всему, решил завязать с проектом и выложил базу как есть. Самое то для тех, кто хочет поковырять логику захвата или ищет основу под свой проект.

Техническая часть:
  1. Захват изображения реализован через классический BitBlt (GDI). Это не самый быстрый метод, но для понимания основ вполне сойдет.
  2. Реализована так называемая Exclusion Area — зона исключения в центре экрана. Это критически важно для колорбота, чтобы аим не сходил с ума от собственного прицела или элементов UI в центре FOV.
  3. Доводка идет через mouse_event. В APB античит (BattlEye) к этому относится относительно лояльно, если не наглеть, но для серьезного обхода лучше переписать на драйвер.
  4. Разрешение игры подхватывается автоматически через FindWindowA и GetClientRect.

В коде захардкожены следующие значения (R: 210-255, G: 0-100, B: 0-100). Это рассчитано на красные/оранжевые ники или элементы скинов. Если планируете использовать под другие цели, крутите переменные RminValue, GminValue и т.д.

Код:
Expand Collapse Copy
#include "Windows.h"
#include "vector"
 
using namespace std;
 
HWND hwnd = 0;
 
POINT a, b; // top left and bottom right corners
int screenWidth; // width
int screenHeight; // height
const int width = 400; // aimfov width
const int height = 320; // aimfov height
 
RGBQUAD* capture(POINT a, POINT b) {
    // copy screen to bitmap
    HDC hScreen = GetDC(hwnd);
    HDC hDC = CreateCompatibleDC(hScreen);
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, abs(b.x - a.x), abs(b.y - a.y));
    HGDIOBJ old_obj = SelectObject(hDC, hBitmap);
    BOOL bRet = BitBlt(hDC, 0, 0, abs(b.x - a.x), abs(b.y - a.y), hScreen, a.x, a.y, SRCCOPY);
 
    // Array conversion:
    RGBQUAD* pixels = new RGBQUAD[width * height];
 
    BITMAPINFOHEADER bmi = { 0 };
    bmi.biSize = sizeof(BITMAPINFOHEADER);
    bmi.biPlanes = 1;
    bmi.biBitCount = 32;
    bmi.biWidth = width;
    bmi.biHeight = -height;
    bmi.biCompression = BI_RGB;
    bmi.biSizeImage = 0;
 
    GetDIBits(hDC, hBitmap, 0, height, pixels, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
 
    // clean up
    SelectObject(hDC, old_obj);
    DeleteDC(hDC);
    ReleaseDC(hwnd, hScreen);
    DeleteObject(hBitmap);
    return pixels;
}
 
bool checkColourInRange(RGBQUAD sample, byte minRed, byte maxRed, byte minGreen, byte maxGreen, byte minBlue, byte maxBlue) {
    int sampleRed = static_cast<int>(sample.rgbRed);
    int sampleGreen = static_cast<int>(sample.rgbGreen);
    int sampleBlue = static_cast<int>(sample.rgbBlue);
 
    return (sampleRed >= minRed && sampleRed <= maxRed &&
        sampleGreen >= minGreen && sampleGreen <= maxGreen &&
        sampleBlue >= minBlue && sampleBlue <= maxBlue);
}
 
byte RminValue = 210;
byte RmaxValue = 255;
byte GminValue = 0;
byte GmaxValue = 100;
byte BminValue = 0;
byte BmaxValue = 100;
 
 
 
void Aim() {
    RGBQUAD* pixels;
 
    while (true) {
        if (GetKeyState(VK_SHIFT) & 0x8000) {
            pixels = capture(a, b);
 
            int startX = -1;
            int endX = -1;
 
            // Find the first and last pixels in the specified color range
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    int index = y * width + x;
 
                    // Check if the current pixel is within the exception areas
                    int center_x = width / 2;
                    int center_y = height / 2;
                    if (
                        (x >= center_x && x < center_x + 126 && y >= center_y - 6 && y < center_y + 6) ||
                        (x >= center_x - 18 && x < center_x + 18 && y >= center_y - 18 && y < center_y + 18) ||
                        (x >= center_x - 126 && x < center_x && y >= center_y - 6 && y < center_y + 6) ||
                        (x >= center_x - 6 && x < center_x + 6 && y >= center_y && y < center_y + 126) ||
                        (x >= center_x - 6 && x < center_x + 6 && y >= center_y - 40 && y < center_y)
                        ) {
                        continue;  // Skip aiming if the pixel is in an exception area
                    }
 
                    if (checkColourInRange(pixels[index], RminValue, RmaxValue, GminValue, GmaxValue, BminValue, BmaxValue)) {
                        if (startX == -1) {
                            startX = x;
                        }
                        endX = x;
                    }
                }
            }
 
               // Calculate the middle of the range
                int middleX = (startX + endX) / 2;
                int middleY = height / 2;
 
                int xAdjust = middleX - width / 2;
                int yAdjust = middleY - height / 2;
 
                // Introduce a slight delay before making the adjustment
                Sleep(5);
 
                mouse_event(MOUSEEVENTF_MOVE, xAdjust, yAdjust, 0, 0);
            }
 
            delete[] pixels;
        }
        Sleep(1);
    }
 
 
void updateResolution() {
    while (1) {
        Sleep(4000);
        hwnd = GetForegroundWindow(); // get handle of currently active window
        hwnd = FindWindowA(0, "APB RELOADED");
 
        RECT windowsize;
        GetClientRect(hwnd, &windowsize);
        HDC monitor = GetDC(hwnd);
        int current = GetDeviceCaps(monitor, VERTRES);
        int total = GetDeviceCaps(monitor, DESKTOPVERTRES);
 
        screenWidth = (windowsize.right - windowsize.left) * total / current;
        screenHeight = (windowsize.bottom - windowsize.top) * total / current;
 
        a.x = screenWidth / 2 - width / 2;
        a.y = screenHeight / 2 - height / 2;
        b.x = screenWidth / 2 + width / 2;
        b.y = screenHeight / 2 + height / 2;
        Sleep(6000);
    }
}
 
int main() {
    printf("Ready");
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)updateResolution, 0, 0, 0);
    Aim();
    return 0;
}

По коду видно, что проект сыроват — например, память под массив pixels выделяется в цикле, а очистка идет не самым изящным образом. Я бы советовал переписать захват на DirectX или хотя бы оптимизировать цикл перебора пикселей, чтобы не ловить просадки FPS при большом FOV.

Инструкция:
Аим работает по зажатому SHIFT. В коде прописан поиск окна "APB RELOADED", так что если играете в оконном или полноэкранном в окне — должно подцепиться без проблем. Компилить лучше под x86/x64 в зависимости от билда игры, зависимости стандартные.

Для паблик-базы под допил вариант нормальный, особенно если прикрутить сюда нормальный фильтр цветов и сглаживание (smoothing), а то сейчас наводка может быть слишком резкой для BattlEye.
 
Назад
Сверху Снизу