PDA

Просмотр полной версии : API SF | Урок 6 - ESP(рисуем на игроках)


CleanLegend
16.10.2018, 19:56
Введение

В этом уроке покажу как можно рисовать на игроках

Начало работы

Для начала нужно зарегистрировать callback present, в нем мы будем рисовать.

C++:






bool
CALLBACK Present
(
CONST RECT
*
pSourceRect
,
CONST RECT
*
pDestRect
,
HWND hDestWindowOverride
,
CONST RGNDATA
*
pDirtyRegion
)
{
if
(
SUCCEEDED
(
SF
->
getRender
(
)
->
BeginRender
(
)
)
)
// если рендер готов к рисованию
{
// рисуем
SF
->
getRender
(
)
->
EndRender
(
)
;
// завершаем рисование
}
;
return
true
;
// возвращаем положительный результат
}
;




в mainloop:

C++:






SF
->
getRender
(
)
->
registerD3DCallback
(
eDirect3DDeviceMethods
::
D3DMETHOD_PRESENT
,
Present
)
;




Создаем функцию для удобства и в ней начинаем с цикла:

C++:






void
ESP
(
)
{
for
(
int
i
=
0
;
i

getSAMP
(
)
->
getPlayers
(
)
->
iIsListed
[
i
]
!=
1
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
->
pGTA_Ped
==
NULL
)
continue
;
// Если игрок не существует или не в зоне стрима, то пропускаем
}
}




Можно сделать проверку на зону стрима вызовом одной функции:

C++:






if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
IsPlayerDefined
(
i
,
true
)
)
{
// Игрок в стриме
}




Теперь нужно получить координаты игрока, перевести их в экранные и проверить есть ли игрок на экране:

C++:






// Получаем координаты игрока
enpos
[
0
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
0
]
;
// X
enpos
[
1
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
1
]
;
// Y
enpos
[
2
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
2
]
;
// Z
// Переводим игровые координаты в экранные
SF
->
getGame
(
)
->
convert3DCoordsToScreen
(
enpos
[
0
]
,
enpos
[
1
]
,
enpos
[
2
]
,
&
screen
[
0
]
,
&
screen
[
1
]
)
;
// Получаем CPed
CPed
*
Ped
=
GAME
->
GetPools
(
)
->
GetPed
(
(
DWORD
*
)
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
->
pGTA_Ped
)
;
// Проверяем есть ли игрок на экране
if
(
Ped
->
IsOnScreen
(
)
)
{
// игрок на экране
}




Перейдем к рисованию, сначала с квадрата.

Для этого нужно вызвать функцию для рисования квадрата и указать экранные координаты:

C++:






SF
->
getRender
(
)
->
DrawBox
(
screen
[
0
]
,
screen
[
1
]
,
35
,
35
,
0xFF00FF00
)
;




получаем:



3bP8eMd.pngCleanLegend · 16 Окт 2018 в 18:56' data-fancybox="lb-post-262618" data-lb-caption-extra-html="" data-lb-sidebar-href="" data-single-image="1" data-src="/proxy.php?image=https%3A%2F%2Fi.imgur.com%2F3bP8eM d.png&hash=16bde79cd7e1ab838a9907f9e27e71b3" style="cursor: pointer;" title="3bP8eMd.png">
https://i.imgur.com/3bP8eMd.png


Рисуем линии:

C++:






SF
->
getRender
(
)
->
DrawLine
(
640
,
900
,
screen
[
0
]
,
screen
[
1
]
,
5
,
0xFF00FF00
)
;




получаем:



ltcertH.pngCleanLegend · 16 Окт 2018 в 18:56' data-fancybox="lb-post-262618" data-lb-caption-extra-html="" data-lb-sidebar-href="" data-single-image="1" data-src="/proxy.php?image=https%3A%2F%2Fi.imgur.com%2Fltcert H.png&hash=6600aa3330d048ac5a48f50b153a60bb" style="cursor: pointer;" title="ltcertH.png">
https://i.imgur.com/ltcertH.png


Рисуем текст:

C++:






char
buf
[
255
]
;
// Заполняем буфер ником и id
sprintf_s
(
buf
,
"%s[%d]"
,
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
GetPlayerName
(
i
)
,
i
)
;
// Рисуем текст
pFont
->
Print
(
buf
,
0xFF00FF00
,
screen
[
0
]
,
screen
[
1
]
,
false
)
;




для использования pFont нужно объявить и инициализировать его:

C++:






stFontInfo
*
pFont
;
//Затем один раз инициализируем шрифт:
pFont
=
SF
->
getRender
(
)
->
CreateNewFont
(
"Tahoma"
,
12
,
FCR_BORDER
)
;




получаем:




https://i.imgur.com/VCHsMSA.png


По такому принципу можно рисовать всё что угодно.

весь код функции:




C++:






void
ESP
(
)
{
float
enpos
[
3
]
;
// для координат игрока
float
screen
[
2
]
;
// для экранных координат
char
buf
[
255
]
;
// для текста
for
(
int
i
=
0
;
i

getSAMP
(
)
->
getPlayers
(
)
->
iIsListed
[
i
]
!=
1
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
->
pGTA_Ped
==
NULL
)
continue
;
// Если игрок не существует или не в зоне стрима, то пропускаем
// Можно сделать это одной функцией
/*if (SF->getSAMP()->getPlayers()->IsPlayerDefined(i, true))
{
// рисуем
}*/
// Тут подойдут два варианта, это уже как вам будет удобнее
// Получаем координаты игрока
enpos
[
0
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
0
]
;
// X
enpos
[
1
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
1
]
;
// Y
enpos
[
2
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
2
]
;
// Z
// Переводим игровые координаты в экранные
SF
->
getGame
(
)
->
convert3DCoordsToScreen
(
enpos
[
0
]
,
enpos
[
1
]
,
enpos
[
2
]
,
&
screen
[
0
]
,
&
screen
[
1
]
)
;
// Получаем CPed
CPed
*
Ped
=
GAME
->
GetPools
(
)
->
GetPed
(
(
DWORD
*
)
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
->
pGTA_Ped
)
;
// Проверяем есть ли игрок на экране
if
(
Ped
->
IsOnScreen
(
)
)
{
// начинаем рисовать
// Рисуем квадрат на игроках
// SF->getRender()->DrawBox(screen[0], screen[1], 35, 35, 0xFF00FF00);
// Рисуем линии
//SF->getRender()->DrawLine(640, 900, screen[0], screen[1], 5,0xFF00FF00);
// Заполняем буфер ником и id
sprintf_s
(
buf
,
"%s[%d]"
,
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
GetPlayerName
(
i
)
,
i
)
;
// Рисуем текст
pFont
->
Print
(
buf
,
0xFF00FF00
,
screen
[
0
]
,
screen
[
1
]
,
false
)
;
}
}
}

Livarka
16.10.2018, 22:52
Введение
В этом уроке покажу как можно рисовать на игроках

Начало работы
Для начала нужно зарегистрировать callback present, в нем мы будем рисовать.

C++:






bool
CALLBACK Present
(
CONST RECT
*
pSourceRect
,
CONST RECT
*
pDestRect
,
HWND hDestWindowOverride
,
CONST RGNDATA
*
pDirtyRegion
)
{
if
(
SUCCEEDED
(
SF
->
getRender
(
)
->
BeginRender
(
)
)
)
// если рендер готов к рисованию
{
// рисуем
SF
->
getRender
(
)
->
EndRender
(
)
;
// завершаем рисование
}
;
return
true
;
// возвращаем положительный результат
}
;




в mainloop:

C++:






SF
->
getRender
(
)
->
registerD3DCallback
(
eDirect3DDeviceMethods
::
D3DMETHOD_PRESENT
,
Present
)
;




Создаем функцию для удобства и в ней начинаем с цикла:

C++:






void
ESP
(
)
{
for
(
int
i
=
0
;
i

getSAMP
(
)
->
getPlayers
(
)
->
iIsListed
[
i
]
!=
1
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
->
pGTA_Ped
==
NULL
)
continue
;
// Если игрок не существует или не в зоне стрима, то пропускаем
}
}




Можно сделать проверку на зону стрима вызовом одной функции:

C++:






if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
IsPlayerDefined
(
i
,
true
)
)
{
// Игрок в стриме
}




Теперь нужно получить координаты игрока, перевести их в экранные и проверить есть ли игрок на экране:

C++:






// Получаем координаты игрока
enpos
[
0
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
0
]
;
// X
enpos
[
1
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
1
]
;
// Y
enpos
[
2
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
2
]
;
// Z
// Переводим игровые координаты в экранные
SF
->
getGame
(
)
->
convert3DCoordsToScreen
(
enpos
[
0
]
,
enpos
[
1
]
,
enpos
[
2
]
,
&
screen
[
0
]
,
&
screen
[
1
]
)
;
// Получаем CPed
CPed
*
Ped
=
GAME
->
GetPools
(
)
->
GetPed
(
(
DWORD
*
)
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
->
pGTA_Ped
)
;
// Проверяем есть ли игрок на экране
if
(
Ped
->
IsOnScreen
(
)
)
{
// игрок на экране
}




Перейдем к рисованию, сначала с квадрата.
Для этого нужно вызвать функцию для рисования квадрата и указать экранные координаты:

C++:






SF
->
getRender
(
)
->
DrawBox
(
screen
[
0
]
,
screen
[
1
]
,
35
,
35
,
0xFF00FF00
)
;




получаем:


3bP8eMd.pngLivarka · 16 Окт 2018 в 21:52' data-fancybox="lb-post-262727" data-lb-caption-extra-html="" data-lb-sidebar-href="" data-single-image="1" data-src="/proxy.php?image=https%3A%2F%2Fi.imgur.com%2F3bP8eM d.png&hash=16bde79cd7e1ab838a9907f9e27e71b3" style="cursor: pointer;" title="3bP8eMd.png">
https://i.imgur.com/3bP8eMd.png


Рисуем линии:

C++:






SF
->
getRender
(
)
->
DrawLine
(
640
,
900
,
screen
[
0
]
,
screen
[
1
]
,
5
,
0xFF00FF00
)
;




получаем:


ltcertH.pngLivarka · 16 Окт 2018 в 21:52' data-fancybox="lb-post-262727" data-lb-caption-extra-html="" data-lb-sidebar-href="" data-single-image="1" data-src="/proxy.php?image=https%3A%2F%2Fi.imgur.com%2Fltcert H.png&hash=6600aa3330d048ac5a48f50b153a60bb" style="cursor: pointer;" title="ltcertH.png">
https://i.imgur.com/ltcertH.png


Рисуем текст:

C++:






char
buf
[
255
]
;
// Заполняем буфер ником и id
sprintf_s
(
buf
,
"%s[%d]"
,
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
GetPlayerName
(
i
)
,
i
)
;
// Рисуем текст
pFont
->
Print
(
buf
,
0xFF00FF00
,
screen
[
0
]
,
screen
[
1
]
,
false
)
;




для использования pFont нужно объявить и инициализировать его:

C++:






stFontInfo
*
pFont
;
//Затем один раз инициализируем шрифт:
pFont
=
SF
->
getRender
(
)
->
CreateNewFont
(
"Tahoma"
,
12
,
FCR_BORDER
)
;




получаем:


VCHsMSA.pngLivarka · 16 Окт 2018 в 21:52' data-fancybox="lb-post-262727" data-lb-caption-extra-html="" data-lb-sidebar-href="" data-single-image="1" data-src="/proxy.php?image=https%3A%2F%2Fi.imgur.com%2FVCHsMS A.png&hash=09dee4000da4f5e36f3f9f9cc450ce9f" style="cursor: pointer;" title="VCHsMSA.png">
https://i.imgur.com/VCHsMSA.png


По такому принципу можно рисовать всё что угодно.
весь код функции:



C++:






void
ESP
(
)
{
float
enpos
[
3
]
;
// для координат игрока
float
screen
[
2
]
;
// для экранных координат
char
buf
[
255
]
;
// для текста
for
(
int
i
=
0
;
i

getSAMP
(
)
->
getPlayers
(
)
->
iIsListed
[
i
]
!=
1
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
==
NULL
)
continue
;
if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
->
pGTA_Ped
==
NULL
)
continue
;
// Если игрок не существует или не в зоне стрима, то пропускаем
// Можно сделать это одной функцией
/*if (SF->getSAMP()->getPlayers()->IsPlayerDefined(i, true))
{
// рисуем
}*/
// Тут подойдут два варианта, это уже как вам будет удобнее
// Получаем координаты игрока
enpos
[
0
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
0
]
;
// X
enpos
[
1
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
1
]
;
// Y
enpos
[
2
]
=
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
fOnFootPos
[
2
]
;
// Z
// Переводим игровые координаты в экранные
SF
->
getGame
(
)
->
convert3DCoordsToScreen
(
enpos
[
0
]
,
enpos
[
1
]
,
enpos
[
2
]
,
&
screen
[
0
]
,
&
screen
[
1
]
)
;
// Получаем CPed
CPed
*
Ped
=
GAME
->
GetPools
(
)
->
GetPed
(
(
DWORD
*
)
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
->
pGTA_Ped
)
;
// Проверяем есть ли игрок на экране
if
(
Ped
->
IsOnScreen
(
)
)
{
// начинаем рисовать
// Рисуем квадрат на игроках
// SF->getRender()->DrawBox(screen[0], screen[1], 35, 35, 0xFF00FF00);
// Рисуем линии
//SF->getRender()->DrawLine(640, 900, screen[0], screen[1], 5,0xFF00FF00);
// Заполняем буфер ником и id
sprintf_s
(
buf
,
"%s[%d]"
,
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
GetPlayerName
(
i
)
,
i
)
;
// Рисуем текст
pFont
->
Print
(
buf
,
0xFF00FF00
,
screen
[
0
]
,
screen
[
1
]
,
false
)
;
}
}
}








Дополни как рендер ника сделать чтобы он был равен цвету самого ника. Думаю у людей будет такой вопрос

клешь рояль
17.10.2018, 08:12
А нельзя это сделать с "if and" как в клео ?

C++:






void
ESP
(
)
{
for
(
int
i
=
0
;
i

getSAMP
(
)
->
getPlayers
(
)
->
iIsListed
[
i
]
!=
1
)
continue
;
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
==
NULL
)
continue
;
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
==
NULL
)
continue
;
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
==
NULL
)
continue
;
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
->
pSAMP_Actor
->
pGTA_Ped
==
NULL
)
continue
;
// Если игрок не существует или не в зоне стрима, то пропускаем
}
}

CleanLegend
17.10.2018, 16:36
Дополни как рендер ника сделать чтобы он был равен цвету самого ника. Думаю у людей будет такой вопрос



C++:






pFont
->
Print
(
buf
,
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
GetPlayerColor
(
i
)
,
screen
[
0
]
,
screen
[
1
]
,
false
)
;






А нельзя это сделать с "if and" как в клео ?


Всё можно упростить, но для понимания посчитал нужным сделать так.

Будет выглядеть примерно так:

C++:






if
(
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
iIsListed
[
i
]
!=
1
||
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
==
NULL
||
SF
->
getSAMP
(
)
->
getPlayers
(
)
->
pRemotePlayer
[
i
]
->
pPlayerData
==
NULL
)
continue
;