 |
|

12.09.2021, 20:42
|
|
Флудер
Регистрация: 06.11.2017
Сообщений: 2,759
С нами:
4483143
Репутация:
183
|
|
- Создание ASI-плагина с нуля
- Хуки – что это такое и как с ними работать
- Безопасная инициализация и работа с SAMP
- Работа с рендером и Directx9
- Обработка событий окна + ImGui
В этом гайде будет рассказано как инициализироваться без потоков, а также как работать с SAMP'ом
При использовании на других ресурсах необходимо указание авторства и ссылки на оригинальную темы!
Все действия производились на Visual Studio 2019 с параметром
, в других версиях интерфейс может отличаться.
И так, начнем:
Создаем новый проект, настраиваем его.
В свойствах проекта, в вкладке общие, стандарт языка C++ ставим /std:c++17
Добавляем sampapi в наш проект:
Первый способ:
- В верхнем меню жмем Git -> Создать репозиторий Git(Create git repository)
- В открывшемся окне выбираем либо github репозиторий, либо локальный репозиторий и жмем Создать.
- Снова жмем Git -> Открыть в командной строке (Open in command line).
- В консоли пишем
Код:
git submodule add https://github.com/BlastHackNet/SAMP-API.git
- Ждем завершения операции и далее жмем Файл(File) -> Добавить(Add) -> Существующий проект (Existing projeect). Открываем папку с нашим проектом, заходим в папку SAMP-API и выбираем sampapi.vcxproj.
- Открываем настройки проекта, выбираем C/C++ -> Общие -> Дополнительные каталоги включаемых файлов(Additional directories of included files). Жмем изменить
В открывшемся окне жмем на иконку файла со звездочкой, и жмем на появившуюся кнопку
Переходим в директорию
Код:
path_to_project\SAMP-API\include
и жмем выбор папки.
- Переходим в настройки проекта
Набор инструментов платформы(Build tools) - выбираем свое(у меня это v142
Версия пакета SDK для Windows - выбираем свое(у меня это 10.0)
- Заходим в настройки нашего основного проекта, Компоновщик(Linker) -> Дополнительные каталоги библиотек(Additional library directories)
Повторяем те же самые операции что в шаге 6, но выбираем папку
Код:
path_to_project\SAMP-API\build\bin
- Далее переходим в вкладку Ввод(Input) и в поле Дополнительные зависимости(Additional dependecies) в начало вписываем
Код:
Release\sampapi.lib;
для Release конфигурации проект, и
. Точка с запятой ОБЯЗАТЕЛЬНА
- Жмем правой кнопкой по проекту sampapi, Только проект -> Собрать только sampapi(делаем это для Release и Debug конфигураций)
Второй способ:
Скачиваем репозиторий, распаковываем по пути
Повторяем шаги 5-10 из первого способа.
Готово, мы подключили sampapi
Теперь добавим библиотеку для хуков в наш проект:
Начну свое описание с подключения моей библиотеки для хуков - kthook
- Скачиваем kthook из репозитория и распаковываем в себе в папку с кодом(Пкм по проекту -> открыть папку в проводнике).
Папку tests перекидывать к себе не нужно.
- Скачиваем ktsignal из репозитория и распаковываем содержимое
в папку
- Жмем показать все файлы
ПКМ по папке kthook -> Включить в проект
- Т.к. мы не используем CMake, тогда мы должны вручную переназначить все зависимости для kthook
- Добавляем папку kthook в Дополнительные каталоги включаемых файлов(Additional directories of included files) (как в шаге 6 у sampapi)
- В kthook.hpp изменяем
Код:
#include "ktsignal/ktsignal.hpp"
на
Код:
#include "ktsignal/include/ktsignal/ktsignal.hpp"
- Также ради собственного удобства добавляем
Дополнительные каталоги включаемых файлов(Additional directories of included files)
Вместо kthook могу посоветовать вам SRHook либо MinHook
SRHook подключается также как и kthook, MinHook можно подключить также двумя способами, как и sampapi.
Но я рекомендую установить его через vcpkg.
Код:
vcpkg install minhook
И теперь перейдем к написанию кода:
SAMP инициализирует свои структуры в вызове
, поэтому мы перехватим эту функцию, и после ее вызова будем уверены что самп инициализировался.
Для инициализации плагина лично я обычно использую хук на
Сообщение от Спойлер
C++:
Код:
using
CTimer__Update
=
void
(
__cdecl
*
)
(
)
;
void
*
func_addr
=
reinterpret_cast
(
0x561B10
)
;
Создаем хук:
C++:
Код:
#include "kthook/kthook.hpp"
using
CHud__DrawRadar
=
void
(
__cdecl
*
)
(
)
;
// Прототип CHud::DrawRadar
kthook
::
kthook_simple_t
samp_init_hook
{
reinterpret_cast
(
0x58A330
)
}
;
// хук на CHud::DrawRadar
Создаем функцию-коллбэк для хука:
C++:
Код:
#include "sampapi/CChat.h"
void
HOOK_after_samp_init
(
)
{
static
bool
inited
=
false
;
// переменная инициализации
namespace
samp
=
sampapi
::
v037r3
;
// Ваша версия сампа, у меня это 037r3
if
(
!
inited
&&
samp
::
RefChat
(
)
!=
nullptr
)
{
// если еще не инициализировались, и чат сампа уже инициализировался
samp
::
RefChat
(
)
->
AddMessage
(
0xFFFFFFFF
,
"Этот текст выведен после инициализации сампа"
)
;
// Выводим сообщение
samp
::
RefChat
(
)
->
m_debugColor
=
0xFFFF0000
;
// Меняем цвет системных сообщений сампа на красный
inited
=
true
;
// отмечаем что иницализировались
}
}
аналогичен
Код:
SF->getSAMP()->getChat()
Подключаем нашу функцию к хуку:
C++:
Код:
BOOL APIENTRY
DllMain
(
HMODULE hModule
,
DWORD ul_reason_for_call
,
LPVOID lpReserved
)
{
switch
(
ul_reason_for_call
)
{
case
DLL_PROCESS_ATTACH
:
DisableThreadLibraryCalls
(
hModule
)
;
samp_init_hook
.
after
.
connect
(
HOOK_after_samp_init
)
;
// Подключаем нашу функцию-коллбэк после вызова CHud::DrawRadar
break
;
case
DLL_PROCESS_DETACH
:
break
;
}
return
TRUE
;
}
Сообщение от Спойлер
C++:
Код:
#include
#include "sampapi/CChat.h"
#include "kthook/kthook.hpp"
using
CHud__DrawRadar
=
void
(
__cdecl
*
)
(
)
;
// Прототип CHud::DrawRadar
kthook
::
kthook_simple_t
samp_init_hook
{
reinterpret_cast
(
0x58A330
)
}
;
// хук на CHud::DrawRadar
void
HOOK_after_samp_init
(
)
{
static
bool
inited
=
false
;
// переменная инициализации
namespace
samp
=
sampapi
::
v037r3
;
// Ваша версия сампа, у меня это 037r3
if
(
!
inited
&&
samp
::
RefChat
(
)
!=
nullptr
)
{
// если еще не инициализировались, и чат сампа уже инициализировался
samp
::
RefChat
(
)
->
AddMessage
(
0xFFFFFFFF
,
"Этот текст выведен после инициализации сампа"
)
;
// Выводим сообщение
samp
::
RefChat
(
)
->
m_debugColor
=
0xFFFF0000
;
// Меняем цвет системных сообщений сампа на красный
inited
=
true
;
// отмечаем что иницализировались
}
}
BOOL APIENTRY
DllMain
(
HMODULE hModule
,
DWORD ul_reason_for_call
,
LPVOID lpReserved
)
{
switch
(
ul_reason_for_call
)
{
case
DLL_PROCESS_ATTACH
:
DisableThreadLibraryCalls
(
hModule
)
;
samp_init_hook
.
after
.
connect
(
HOOK_after_samp_init
)
;
// Подключаем нашу функцию-коллбэк после вызова CHud::DrawRadar
break
;
case
DLL_PROCESS_DETACH
:
break
;
}
return
TRUE
;
}
Компилируем, запускаем и видим:
|
|
|

12.09.2021, 22:24
|
|
Постоянный
Регистрация: 08.03.2016
Сообщений: 332
С нами:
5358262
Репутация:
213
|
|
Надеюсь, что всё не закончится на 3-ем уроке как обычно
1631471083580.pngetereon · 12 Сен 2021 в 21:24' data-fancybox="lb-post-841058" data-lb-caption-extra-html="" data-lb-sidebar-href="" data-single-image="1" data-src="https://www.blast.hk/attachments/114055/" style="cursor: pointer;" title="1631471083580.png">

|
|
|

12.09.2021, 23:18
|
|
Постоянный
Регистрация: 24.07.2017
Сообщений: 867
С нами:
4633764
Репутация:
148
|
|
simple хук чё сам после первого вызова убирается? надо бы после инициализации убрать хук
|
|
|

13.09.2021, 00:40
|
|
Флудер
Регистрация: 06.11.2017
Сообщений: 2,759
С нами:
4483143
Репутация:
183
|
|
Сообщение от loganhackerdff
simple хук чё сам после первого вызова убирается? надо бы после инициализации убрать хук
static bool inited же
Внутри самого слота нельзя делать дисконнект, т.к. это удаляет текущий итератор, в следовательно и при итерации все сломается
|
|
|

13.09.2021, 00:40
|
|
Постоянный
Регистрация: 24.07.2017
Сообщений: 867
С нами:
4633764
Репутация:
148
|
|
Сообщение от kin4stat
static bool inited же
Внутри самого слота нельзя делать дисконнект, т.к. это удаляет текущий итератор, в следовательно и при итерации все сломается
это то да, но зачем, можно же просто убрать хук после инициализации
|
|
|

13.09.2021, 00:45
|
|
Флудер
Регистрация: 06.11.2017
Сообщений: 2,759
С нами:
4483143
Репутация:
183
|
|
Сообщение от loganhackerdff
это то да, но зачем, можно же просто убрать хук после инициализации
И вероятно еще снести цепочку вызовов вместе с собой. Хорошее решение
|
|
|

13.09.2021, 01:00
|
|
Флудер
Регистрация: 02.02.2019
Сообщений: 5,070
С нами:
3831395
Репутация:
183
|
|
Новый гайд, по новой делать вид как будто я все понял и просто переписывать код в VS и думать что я пиздец програмист после того как код заработал
|
|
|

13.09.2021, 16:43
|
|
Постоянный
Регистрация: 08.03.2016
Сообщений: 332
С нами:
5358262
Репутация:
213
|
|
Сообщение от etereon
Надеюсь, что всё не закончится на 3-ем уроке как обычно
Вот мы смеемся, а 4-о гайда реально не будет, ведь моё сообщение собрало лайков больше, чем сам урок...

|
|
|

20.11.2021, 16:58
|
|
Постоянный
Регистрация: 16.08.2020
Сообщений: 553
С нами:
3022568
Репутация:
68
|
|
можно пожалуста проект, ничего не получается :сссссссссссссссссссссссс сссссссссссссссссссссссс ссссссс
|
|
|

20.11.2021, 18:55
|
|
Постоянный
Регистрация: 03.05.2020
Сообщений: 385
С нами:
3174020
Репутация:
213
|
|
Сообщение от Fufych
можно пожалуста проект, ничего не получается :сссссссссссссссссссссссс сссссссссссссссссссссссс ссссссс
если не получается, то проект тут не поможет
|
|
|
|
 |
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|