Как создать asi скрипт для gta san andreas

Обновлено: 05.07.2024

Введение:
Для начала скажу, что вам понадобится Visual Studio(Так проще всего), и пакеты к ней, а именно - Разработка классических приложений на C++ и Разработка приложений на универсальной платформы Windows.
Все действия производились на Visual Studio 2019, в других версиях интерфейс может отличаться

Создание проекта:
И так, начнем с создания проекта. Жмем кнопку создать проект, и ищем "Библиотека динамической компоновки (DLL)" (Дело в том, что ASI это и есть DLL файл, только с измененным расширением).
Создаем проект. Я назвал его ASIPlugin.

После создания проекта мы видим перед собой окно редактора с подготовленным шаблоном. Шаблон содержит в себе подключение pch.h и функции DllMain.

Настройка проекта:
Начнем с настройки проекта.
В панели меню сверху жмем Проект, и выпадающем меню выбираем пункт Свойства: $ProjectName
Сверху, в выпадающем меню в открывшемся диалоге выбираем Конфигурация -> Все конфигурации.
После этого я обычно отключаю предварительно скомпилированные заголовки(pch.h), но вы можете их оставить(поэкспериментируйте сами)
Включить/Выключить можно в подменю C/C++ -> Предварительно откомпилированные заголовки -> Предварительно откомпилированный заголовок

После этого переходим в Дополнительно -> Расширение целевого файла, меняем .dll на .asi(чтобы подгружалось ASI Лоадером)
(ОПЦИОНАЛЬНО) После этого переходим в Общие -> Выходной каталог, здесь указываем путь до своей GTA

Настройка проекта окончена, переходим к написанию кода

Написание кода:
Функция DllMain - основная функция Dll библиотеки, которая в нашем случае играет роль Asi плагина. Эта функция вызывается при четырех условиях - создании/уничтожении потока, и при присоединении и отсоединении нашей библиотеки. Первые два условия в данный момент нас не особо интересуют, поэтому перейдем к другим двум. Функция принимает в себя 3 аргумента, один из которых зарезервирован системой(lpReserved). Остальные два аргумента показывают нам базовый адрес библиотеки(Адрес по которому начинается наша библиотека в оперативной памяти) и причину вызова функции. Причина вызова как я уже описал выше - имеет 4 значения: DLL_PROCESS_ATTACH, DLL_THREAD_ATTACH, DLL_THREAD_DETACH и DLL_PROCESS_DETACH. На данные момент нас интересуют первое и последнее из них. Первое вызывается при присоединении к процессу, последнее - при отсоединении.

Дальше работаем с DLL_PROCESS_ATTACH(В нашем случае оно будет выполнять функцию int main, как в консольном приложении C/C++).
DLL_PROCESS_DETACH на данный момент нам не нужен, т.к. нам нечего освобождать после выгрузки.
Начну с того, что DllMain с причиной DLL_PROCESS_ATTACH вызывается еще до появления окна GTA, когда игра еще не инициализирована, поэтому мы не можем взаимодействовать с игрой на этом моменте, и придется дождаться ее инициализации, это можно сделать разными путями, но на этот раз сделаем через создание потока, но так лучше не делать, и в дальнейшем я возможно покажу как сделать лучше.

Дело в том, что потоки на процессоре могут выполняться совершенно параллельно, и может возникнуть ситуация когда сразу несколько потоков(в нашем случае это поток игры и наш поток) обращаются к одной и той же памяти. Возникает состояние гонки потоков, и это приводит к Undefined Behaviour (по-русски - все пойдет по пизде)

Начнем с того, что к case DLL_PROCESS_ATTACH: добавим break; , чтобы выполнение кода не пошло по другим веткам. Так как нас не интересуют события с потоками, скажем Windows, чтобы она вообще не дергала нас по этому поводу, вызвав функцию DisableThreadLibraryCalls(hModule);

Или (для std::thread)

Далее переходим к инициализации.
Игра хранит свою стадию по адресу 0xC8D4C0
И пока значение по адресу не станет 9(полная инициализация игры) - спим и ждем

Далее спокойно вызываем функцию AddMessageJumpQ, ведь мы знаем, что игра уже инициализирована
Теперь создадим поток инициализации в DllMain, передав ему нашу функцию (не забывайте что для std::thread нужно подключить заголовок thread):
std::thread(InitializeAndLoad).detach();
Либо:
CreateThread(0, 0, &InitializeAndLoad, 0, 0, 0);
Итого должно выйти примерно так:

Либо так, в случае с CreateThread:


Жмем Ctrl+Shift+B, ждем окончания сборки, заходим в игру и видим:

kin4stat

Palapka
Активный
loganhackerdff
Режим чтения
kin4stat
Да господи я же написал что не в этот раз, ибо придется объяснять что такое хуки зачем куда и почему
loganhackerdff
Режим чтения
Да господи я же написал что не в этот раз, ибо придется объяснять что такое хуки зачем куда и почему
Gruzin Gang
Известный

Делать мне было нечего, а работать не хотелось, поэтому вы видите этот гайд

Введение:
Для начала скажу, что вам понадобится Visual Studio(Так проще всего), и пакеты к ней, а именно - Разработка классических приложений на C++ и Разработка приложений на универсальной платформы Windows.
Все действия производились на Visual Studio 2019, в других версиях интерфейс может отличаться

Создание проекта:
И так, начнем с создания проекта. Жмем кнопку создать проект, и ищем "Библиотека динамической компоновки (DLL)" (Дело в том, что ASI это и есть DLL файл, только с измененным расширением).
Создаем проект. Я назвал его ASIPlugin.

После создания проекта мы видим перед собой окно редактора с подготовленным шаблоном. Шаблон содержит в себе подключение pch.h и функции DllMain.

Настройка проекта:
Начнем с настройки проекта.
В панели меню сверху жмем Проект, и выпадающем меню выбираем пункт Свойства: $ProjectName
Сверху, в выпадающем меню в открывшемся диалоге выбираем Конфигурация -> Все конфигурации.
После этого я обычно отключаю предварительно скомпилированные заголовки(pch.h), но вы можете их оставить(поэкспериментируйте сами)
Включить/Выключить можно в подменю C/C++ -> Предварительно откомпилированные заголовки -> Предварительно откомпилированный заголовок

После этого переходим в Дополнительно -> Расширение целевого файла, меняем .dll на .asi(чтобы подгружалось ASI Лоадером)
(ОПЦИОНАЛЬНО) После этого переходим в Общие -> Выходной каталог, здесь указываем путь до своей GTA

Настройка проекта окончена, переходим к написанию кода

Написание кода:
Функция DllMain - основная функция Dll библиотеки, которая в нашем случае играет роль Asi плагина. Эта функция вызывается при четырех условиях - создании/уничтожении потока, и при присоединении и отсоединении нашей библиотеки. Первые два условия в данный момент нас не особо интересуют, поэтому перейдем к другим двум. Функция принимает в себя 3 аргумента, один из которых зарезервирован системой(lpReserved). Остальные два аргумента показывают нам базовый адрес библиотеки(Адрес по которому начинается наша библиотека в оперативной памяти) и причину вызова функции. Причина вызова как я уже описал выше - имеет 4 значения: DLL_PROCESS_ATTACH, DLL_THREAD_ATTACH, DLL_THREAD_DETACH и DLL_PROCESS_DETACH. На данные момент нас интересуют первое и последнее из них. Первое вызывается при присоединении к процессу, последнее - при отсоединении.

Дальше работаем с DLL_PROCESS_ATTACH(В нашем случае оно будет выполнять функцию int main, как в консольном приложении C/C++).
DLL_PROCESS_DETACH на данный момент нам не нужен, т.к. нам нечего освобождать после выгрузки.
Начну с того, что DllMain с причиной DLL_PROCESS_ATTACH вызывается еще до появления окна GTA, когда игра еще не инициализирована, поэтому мы не можем взаимодействовать с игрой на этом моменте, и придется дождаться ее инициализации, это можно сделать разными путями, но на этот раз сделаем через создание потока, но так лучше не делать, и в дальнейшем я возможно покажу как сделать лучше.

Дело в том, что потоки на процессоре могут выполняться совершенно параллельно, и может возникнуть ситуация когда сразу несколько потоков(в нашем случае это поток игры и наш поток) обращаются к одной и той же памяти. Возникает состояние гонки потоков, и это приводит к Undefined Behaviour (по-русски - все пойдет по пизде)

Начнем с того, что к case DLL_PROCESS_ATTACH: добавим break; , чтобы выполнение кода не пошло по другим веткам. Так как нас не интересуют события с потоками, скажем Windows, чтобы она вообще не дергала нас по этому поводу, вызвав функцию DisableThreadLibraryCalls(hModule);

Widescreen Fix (Лучшая версия от 24.04.2016)

Open Door Anim v.1.2 (Обновление от 04.04.2021)

Пишем свой первый CLEO скрипт для GTA San Andreas

Эта статья предназначена для тех, кто хочет освоить программирование под библиотеку CLEO в GTA San Andreas и не знает с чего начать.

Итак, поехали. Для начала вам необходимо установить в игру библиотеку CLEO4, скачать её можно с нашего сайта - скачать CLEO4. Думаю, как устанавливать моды с нашего сайта объяснять вам не придется, потому как проще уже ничего не придумаешь..
Далее качаем и устанавливаем Sanny Builder 3, многие из вас зададут вопрос - что это? Это та программа, в которой скриптеры творят свои чудеса! И сегодня мы вместе сотворим одно из чудес

Открываем Sanny Builder, в меню программы выбираем "Файл \ Создать новый", или щелкаем по иконке нового документа в панели инструментов вверху. Перед вами откроется новый документ, это и будет наш первый скрипт сохраним его в папку CLEO в игре (там где у нас установлена GTA) под именем MyFirstScript

Пишем свой первый CLEO скрипт

Теперь все готово и можно приступать к написанию кода, сегодня мы напишем скрипт, который добавляет 1000 монет при нажатии кнопки \"+\", ну и заодно сбрасывает уровень розыска у главного героя

С этой строки начинается любой скрипт. Копируем и вставляем..

Как вы думаете что нам нужно для этого скрипта, правильно! Нам нужно узнать в какой момент мы нажали на кнопку \"+\". Этим у нас будет заниматься функция KEY_SCAN
Копируем и вставляем следующие строки:

Итак, мы почти уже дописали наш скрипт, осталось прибавить денег и сбросить уровень розыска.

ASI плагины для GTA San Andreas

Оригинальная Анимация

У некоторых модов, таких как Tuning Mod, Real Traffic, Fix, Steering (Active Dashboard) и других, есть проблема: Из-за определенных функций этих модов Windows в конечном итоге блокирует их, используя так называемую DEP (Data Execution Prevention).

Данный ASI-плагин решает эту проблему, отключая DEP при запуске игры.

Widescreen Fix (Лучшая версия от 24.04.2016)

Open Door Anim v.1.2 (Обновление от 04.04.2021)

Данный ASI-плагин добавит чуточку реалистичности. Теперь Карл и прохожие смогут рукой открывать те двери, который открывались с помощью физики (когда CJ телом открывал). Подобный скрипт бал ранее, но написан на CLEO и вызывал ошибки.

Обновление от 04.04.2021:
- Исправлена ошибка, из-за которой невозможно было открывать миссии;
- Теперь анимация не будет срабатывать, если Карл находится в воздухе или присел.

Обновление от 11.11.2020:
- Исправлена несовместимость из новой версией SilentPatch, из-за чего модификация не работала.

Написание простого ASI плагина с plugin-sdk.

Для написания плагина с plugin-sdk необходимо следующее:

Итак, после того, как plugin-sdk настроен, мы можем создать плагин в Visual Studio. Для этого создаём новый проект и выбираем шаблон проекта Plugin-SDK в подразделе Visual C++ - Plugin-SDK:


Не забываем также указать название проекта и выбрать место его расположения. По умолчанию, у нас в проекте есть один файл исходного кода (.cpp). Открываем этот файл и подключаем нужные заголовочные файлы.

Для удобства, мы разместим все данные и функции в классе. В конструктор этого класса мы поместим код инициализации нашего плагина. В глобальной области видимости мы создадим экземпляр этого класса, таким образом, при подключении нашего плагина ( а плагин - это динамическая библиотека с расширением .asi ) ASI-loader'ом, будет вызван конструктор нашего класса.

Такой подход позволяет избавиться от явного использования функции DllMain, но, впрочем, никто вам не запрещает выполнять инициализацию плагина так, как вам удобно.

Инициализация плагина

В plugin-sdk реализована идея "событий" (events). Т.е., есть возможность выполнить свой код в какой-то определённый момент игры. Обращаться ко всем событиям можно из пространства имён plugin::Events. Вот как это выглядит:

Метод Add добавляет указанную функцию к конкретному игровому"событию". При этом, у метода Add есть альтернатива в виде оператора +=

Также, есть возможность указать - когда именно вызывать нашу функцию - до "события" или после:

Мы сделаем изменение времени после нажатия клавиши Delete . Вот так будет выглядеть наш код:

Код готов, переключаемся в Release-режим и компилируем проект ( F7 ).

Итак, что мы получаем в случае использования Plugin SDK? Чистые хуки без явно видимых патчей и работы напрямую с адресами памяти.

Читайте также: