Подробный гайд: Создание ASI-мода для мгновенной остановки транспорта в SA:MP
ASI-моды — это динамические библиотеки (.dll), загружаемые в процесс игры GTA San Andreas с помощью специального загрузчика (ASI Loader). Они позволяют изменять поведение игры, вызывать внутренние функции и работать с памятью напрямую. В SA:MP (San Andreas Multiplayer) ASI-моды часто используются для добавления новых возможностей, не предусмотренных клиентом.
В этом руководстве мы создадим ASI-мод, который по нажатию определённой клавиши мгновенно останавливает транспорт, в котором находится локальный игрок. Это может быть полезно для тренировок, ролевых ситуаций или просто для удобства.
Внимание!
Использование подобных модификаций на публичных серверах может быть расценено как читерство и привести к бану. Используйте только на серверах, где это разрешено, или в одиночной игре.
1. Подготовка окружения
Требования
- Visual Studio (2015, 2017, 2019 или 2022) с набором инструментов для C++.
- ASI Loader (например, встроенный в SA-MP).
- SAMPFUNCS (опционально, упрощает работу с SA-MP) — можно скачать с BlastHack - https://www.blasthack.net/.
- Базовые знания C++ и понимание работы памяти процесса.
Установка ASI Loader
- Скачайте ASI Loader.
- Поместите файл
vorbisFile.dll(илиd3d9.dllв зависимости от версии) в корневую папку с игрой (где находитсяgta_sa.exe). - Создайте папку
asiв корне игры, если её нет.
Теперь любой .asi файл, помещённый в папку asi (или в корень), будет автоматически загружен при запуске игры.
2. Создание проекта ASI
Шаг 1: Создание пустого проекта DLL
- Откройте Visual Studio → Создать проект → Библиотека динамической компоновки (DLL).
- Назовите проект, например
InstantStop. - Удалите все автоматически созданные файлы (
.cpp,.h,framework.hи т.д.), оставив только пустой проект.
Шаг 2: Настройка свойств проекта
Откройте Свойства проекта (правой кнопкой по проекту → Properties):
- Configuration → All Configurations.
- C/C++ → General → Additional Include Directories — добавьте путь к заголовкам SAMPFUNCS (если используете) и, при необходимости, к DirectX SDK.
- C/C++ → Preprocessor → Preprocessor Definitions — добавьте
_CRT_SECURE_NO_WARNINGS,_WINDLL,_UNICODE,UNICODE. - Linker → General → Output File — укажите расширение
.asiвместо.dll(например,$(OutDir)\$(ProjectName).asi). - Linker → Input → Additional Dependencies — добавьте
samp.lib(если работаете с SA-MP напрямую),sampfuncs.lib(если используете SAMPFUNCS). При использовании только адресов GTA SA дополнительные библиотеки не нужны. - C/C++ → Code Generation → Runtime Library — для Release лучше выбрать
/MT(статическая линковка), чтобы не зависеть от внешних DLL.
Шаг 3: Точка входа
ASI-мод должен экспортировать функцию DllMain, которая будет вызвана при загрузке. В ней мы создадим поток или зарегистрируем хук.
3. Вариант 1: Использование адресов GTA San Andreas (без SAMPFUNCS)
Этот метод не требует внешних библиотек, кроме стандартных. Мы будем напрямую обращаться к памяти игры и вызывать её внутренние функции.
Необходимые адреса (для GTA SA 1.0 US)
- FindPlayerPed (получение указателя на локального игрока) —
0xB6F5F0(функция, возвращаетCPed*). - Смещение до указателя на транспорт в CPed —
0x58C(CVehicle* m_pVehicle). - Смещение до вектора скорости в CVehicle —
0x44(float[3]m_vecMoveSpeed). - Смещение до вектора угловой скорости в CVehicle —
0x50(float[3]m_vecTurnSpeed). - Функция
CVehicle::SetMoveSpeed(опционально) —0x6D9F20(thiscall, принимает три float).
Код
#include <windows.h>
#include <cstdint>
// Прототип функции FindPlayerPed
typedef uintptr_t* (*FindPlayerPed_t)();
FindPlayerPed_t FindPlayerPed = (FindPlayerPed_t)0xB6F5F0;
// Функция для вызова CVehicle::SetMoveSpeed (thiscall)
typedef void(__thiscall* SetMoveSpeed_t)(uintptr_t vehicle, float x, float y, float z);
SetMoveSpeed_t SetMoveSpeed = (SetMoveSpeed_t)0x6D9F20;
// Глобальный флаг для контроля потока
bool g_shouldStopVehicle = false;
bool g_running = true;
// Поток, проверяющий нажатие клавиши
DWORD WINAPI MainThread(LPVOID lpParam)
{
while (g_running)
{
// Проверяем клавишу (например, клавиша 'X')
if (GetAsyncKeyState('X') & 0x8000)
{
if (!g_shouldStopVehicle) // защита от повторного срабатывания при удержании
{
g_shouldStopVehicle = true;
// Получаем указатель на игрока
uintptr_t* playerPtr = FindPlayerPed();
if (playerPtr)
{
uintptr_t player = *playerPtr;
if (player)
{
// Читаем указатель на транспорт из CPed + 0x58C
uintptr_t* vehiclePtr = reinterpret_cast<uintptr_t*>(player + 0x58C);
uintptr_t vehicle = *vehiclePtr;
if (vehicle)
{
// Останавливаем транспорт (вариант через прямое обнуление скорости)
float* moveSpeed = reinterpret_cast<float*>(vehicle + 0x44);
moveSpeed[0] = 0.0f;
moveSpeed[1] = 0.0f;
moveSpeed[2] = 0.0f;
float* turnSpeed = reinterpret_cast<float*>(vehicle + 0x50);
turnSpeed[0] = 0.0f;
turnSpeed[1] = 0.0f;
turnSpeed[2] = 0.0f;
// Альтернатива: вызов функции SetMoveSpeed
// SetMoveSpeed(vehicle, 0.0f, 0.0f, 0.0f);
}
}
}
}
}
else
{
g_shouldStopVehicle = false; // сброс, когда клавиша отпущена
}
Sleep(10); // небольшая задержка, чтобы не грузить процессор
}
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
// Создаём поток
CreateThread(NULL, 0, MainThread, NULL, 0, NULL);
break;
case DLL_PROCESS_DETACH:
g_running = false;
break;
}
return TRUE;
}
Пояснения
- GetAsyncKeyState — системная функция Windows, определяет, нажата ли клавиша в данный момент.
- FindPlayerPed — стандартная функция GTA SA, возвращает указатель на объект
CPedлокального игрока. - Смещение
0x58Cв структуреCPedуказывает на указатель наCVehicle(транспорт), в котором находится игрок (nullptr, если не в транспорте). - Поля
m_vecMoveSpeed(0x44) иm_vecTurnSpeed(0x50) — скорости линейного и углового движения транспорта. Обнуление мгновенно останавливает его. - Можно также вызвать
SetMoveSpeedпо адресу0x6D9F20, что эквивалентно обнулению.
4. Вариант 2: Использование SAMPFUNCS (более просто и надёжно)
SAMPFUNCS — библиотека, предоставляющая удобный API для работы с SA-MP. Она скрывает многие детали (адреса, смещения) и автоматически обновляется под новые версии.
Установка SAMPFUNCS
- Скачайте последнюю версию SAMPFUNCS (например, для SA-MP 0.3.7).
- Поместите
sampfuncs.asiв папку игры (или в папкуasi). - В проекте подключите заголовочные файлы и библиотеку
sampfuncs.lib.
Код с использованием SAMPFUNCS
#include <windows.h>
#include "SAMPFUNCS/SAMPFUNCS.h"
SAMPFUNCS* SF = new SAMPFUNCS();
bool g_shouldStop = false;
bool g_running = true;
DWORD WINAPI MainThread(LPVOID lpParam)
{
while (g_running)
{
if (GetAsyncKeyState('X') & 0x8000)
{
if (!g_shouldStop)
{
g_shouldStop = true;
// Получаем локального игрока
SAMP::CPlayer* localPlayer = SF->getSAMP()->getPlayers()->getLocalPlayer();
if (localPlayer)
{
// Проверяем, находится ли игрок в транспорте
if (localPlayer->isInVehicle())
{
// Получаем указатель на транспорт
SAMP::CVehicle* vehicle = localPlayer->getVehicle();
if (vehicle)
{
// Устанавливаем нулевую скорость
vehicle->setSpeedVector(CVector(0.0f, 0.0f, 0.0f));
// или vehicle->setMoveSpeedVector(...);
}
}
}
}
}
else
{
g_shouldStop = false;
}
Sleep(10);
}
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
CreateThread(NULL, 0, MainThread, NULL, 0, NULL);
break;
case DLL_PROCESS_DETACH:
g_running = false;
delete SF;
break;
}
return TRUE;
}
Пояснения
SAMPFUNCSпредоставляет готовые классы (SAMP::CPlayer,SAMP::CVehicle), методы которых используют актуальные адреса.setSpeedVector— метод, обнуляющий скорость транспорта.- Код получается короче и меньше зависит от версии игры/SA-MP.
5. Компиляция и установка
- Выберите конфигурацию Release и платформу x86 (GTA SA — 32-битное приложение).
- Нажмите Build Solution.
- В папке
Releaseпоявится файл с расширением.asi. - Скопируйте этот файл в корневую папку игры (где
gta_sa.exe) или в папкуasi(если ASI Loader это поддерживает). - Запустите игру, подключитесь к серверу SA-MP.
Тестирование:
- Сядьте в любой транспорт.
- Нажмите клавишу X (или ту, которую вы указали в коде).
- Транспорт должен мгновенно остановиться (скорость станет нулевой).
6. Возможные проблемы и их решение
1. ASI-файл не загружается
- Убедитесь, что ASI Loader установлен правильно (
vorbisFile.dllили другой заменён). - Проверьте, что файл имеет расширение
.asi, а не.dll. - Попробуйте поместить
.asiпрямо в корень игры.
2. Игра вылетает при нажатии клавиши
- Проверьте правильность адресов (для варианта 1). Возможно, у вас другая версия GTA SA (не 1.0 US). Используйте SAMPFUNCS для надёжности.
- Убедитесь, что вы работаете с 32-битным процессом (x86).
3. Транспорт не останавливается полностью
- Попробуйте также обнулить
m_vecTurnSpeed(смещение 0x50) или вызвать функциюSetMoveSpeed, как указано выше. - В SA-MP может быть серверная синхронизация, которая вернёт небольшую скорость. Это нормально.
4. Срабатывание слишком часто при удержании
- В коде используется флаг
g_shouldStop, который предотвращает повторное выполнение до отпускания клавиши. Если вы хотите, чтобы остановка происходила каждый кадр, уберите эту проверку.
5. Анти-чит сервера блокирует мод
- Некоторые серверы имеют собственные защитные механизмы. Используйте мод только на доверенных серверах или в одиночной игре.
Важно
Мы рассмотрели два способа создания ASI-мода для мгновенной остановки транспорта в SA-MP: через прямое обращение к памяти GTA San Andreas и через библиотеку SAMPFUNCS. Второй способ проще и безопаснее, но требует наличия этой библиотеки у пользователя. Первый способ полностью автономен, но зависит от точных адресов.
Вы можете модифицировать код: назначить другую клавишу, остановить только свой транспорт или транспорт перед вами, добавить звуковой сигнал и т.д. Помните об этичности использования подобных модов на публичных серверах.
Удачи в разработке!
Мы делимся этой технической информацией, чтобы помочь вам в решении задач — используйте её с пониманием. Статья носит рекомендательный характер, поэтому, пожалуйста, применяйте описанные методы осмотрительно.