 |
|

31.03.2021, 15:38
|
|
Постоянный
Регистрация: 29.05.2017
Сообщений: 394
С нами:
4714653
Репутация:
98
|
|
Сообщение от KiN4StAt
urmem не пользовался, сказать не могу
__fastcall на обе функции нужен
C++:
Код:
//Убран код с подключением библиотек и mainloop().
urmem
::
hook urmemHook
;
void
__fastcall
UpdateAimingCoors
(
void
*
_this
,
void
*
edx
,
CVector
const
*
AimingTargetCoors
)
{
SF
->
getSAMP
(
)
->
getChat
(
)
->
AddChatMessage
(
-
1
,
"UpdateAimingCoors"
)
;
SF
->
getSAMP
(
)
->
getChat
(
)
->
AddChatMessage
(
-
1
,
"UpdateAimingCoors. posX: %f; posY: %f; posZ: %f"
,
AimingTargetCoors
->
fX
,
AimingTargetCoors
->
fY
,
AimingTargetCoors
->
fZ
)
;
urmemHook
.
call
(
_this
,
AimingTargetCoors
)
;
}
void
__fastcall
DoBulletImpact
(
void
*
_this
,
void
*
edx
,
CEntity
*
owner
,
CEntity
*
victim
,
CVector
*
startPoint
,
CVector
*
endPoint
,
CColPoint
*
colPoint
,
int
arg5
)
{
SF
->
getSAMP
(
)
->
getChat
(
)
->
AddChatMessage
(
-
1
,
"DoBulletImpact"
)
;
urmemHook
.
call
(
_this
,
owner
,
victim
,
startPoint
,
endPoint
,
colPoint
,
arg5
)
;
}
BOOL APIENTRY
DllMain
(
HMODULE hModule
,
DWORD dwReasonForCall
,
LPVOID lpReserved
)
{
switch
(
dwReasonForCall
)
{
case
DLL_PROCESS_ATTACH
:
SF
->
initPlugin
(
mainloop
,
hModule
)
;
urmemHook
.
install
(
0x50CB10
,
urmem
::
get_func_addr
(
&
UpdateAimingCoors
)
)
;
urmemHook
.
install
(
0x73B550
,
urmem
::
get_func_addr
(
&
DoBulletImpact
)
)
;
break
;
case
DLL_THREAD_ATTACH
:
case
DLL_THREAD_DETACH
:
case
DLL_PROCESS_DETACH
:
urmemHook
.
disable
(
)
;
break
;
}
return
TRUE
;
}
Вот так сделал, не работает.
|
|
|

31.03.2021, 23:10
|
|
Флудер
Регистрация: 18.03.2013
Сообщений: 4,080
С нами:
6921957
Репутация:
183
|
|
Сообщение от Ya Zaregalsya
C++:
Код:
//Убран код с подключением библиотек и mainloop().
urmem
::
hook urmemHook
;
urmemHook
.
install
(
0x50CB10
,
urmem
::
get_func_addr
(
&
UpdateAimingCoors
)
)
;
urmemHook
.
install
(
0x73B550
,
urmem
::
get_func_addr
(
&
DoBulletImpact
)
)
;
}
Вот так сделал, не работает.
Конечно, блять, не работает. На один обьект надо вешать один хук. У тебя на один обьект 2 хука.
|
|
|

01.04.2021, 03:57
|
|
Постоянный
Регистрация: 29.05.2017
Сообщений: 394
С нами:
4714653
Репутация:
98
|
|
Сообщение от Dark_Knight
Конечно, блять, не работает. На один обьект надо вешать один хук. У тебя на один обьект 2 хука.
Сделал так, ничего не изменилось:
C++:
Код:
urmem
::
hook urmemHookAimingCoords
;
void
__fastcall
UpdateAimingCoors
(
void
*
_this
,
void
*
edx
,
CVector
const
*
AimingTargetCoors
)
{
SF
->
getSAMP
(
)
->
getChat
(
)
->
AddChatMessage
(
-
1
,
"UpdateAimingCoors"
)
;
SF
->
getSAMP
(
)
->
getChat
(
)
->
AddChatMessage
(
-
1
,
"UpdateAimingCoors. posX: %f; posY: %f; posZ: %f"
,
AimingTargetCoors
->
fX
,
AimingTargetCoors
->
fY
,
AimingTargetCoors
->
fZ
)
;
urmemHookAimingCoords
.
call
(
_this
,
AimingTargetCoors
)
;
}
urmem
::
hook urmemHookDoBulletImpact
;
void
__fastcall
DoBulletImpact
(
void
*
_this
,
void
*
edx
,
CEntity
*
owner
,
CEntity
*
victim
,
CVector
*
startPoint
,
CVector
*
endPoint
,
CColPoint
*
colPoint
,
int
arg5
)
{
SF
->
getSAMP
(
)
->
getChat
(
)
->
AddChatMessage
(
-
1
,
"DoBulletImpact"
)
;
SF
->
getSAMP
(
)
->
getChat
(
)
->
AddChatMessage
(
-
1
,
"DoBulletImpact. posX: %f; posY: %f; posZ: %f"
,
endPoint
->
fX
,
endPoint
->
fY
,
endPoint
->
fZ
)
;
urmemHookDoBulletImpact
.
call
(
_this
,
owner
,
victim
,
startPoint
,
endPoint
,
colPoint
,
arg5
)
;
}
BOOL APIENTRY
DllMain
(
HMODULE hModule
,
DWORD dwReasonForCall
,
LPVOID lpReserved
)
{
switch
(
dwReasonForCall
)
{
case
DLL_PROCESS_ATTACH
:
SF
->
initPlugin
(
mainloop
,
hModule
)
;
urmemHookAimingCoords
.
install
(
0x50CB10
,
urmem
::
get_func_addr
(
&
UpdateAimingCoors
)
)
;
urmemHookDoBulletImpact
.
install
(
0x73B550
,
urmem
::
get_func_addr
(
&
DoBulletImpact
)
)
;
break
;
case
DLL_THREAD_ATTACH
:
case
DLL_THREAD_DETACH
:
case
DLL_PROCESS_DETACH
:
urmemHookAimingCoords
.
disable
(
)
;
urmemHookDoBulletImpact
.
disable
(
)
;
break
;
}
return
TRUE
;
}
Без соглашения __fastcall тоже ничего.
|
|
|

02.04.2021, 20:28
|
|
Постоянный
Регистрация: 29.05.2017
Сообщений: 394
С нами:
4714653
Репутация:
98
|
|
Сообщение от KiN4StAt
у меня на гитхабе в BulletTracer есть хук этой функции
kin4stat - Overview
20 y.o. student  . kin4stat has 55 repositories available. Follow their code on GitHub.
github.com
Пытаюсь разобраться с Вашим примером. «Трамплин» fpDoImpact совсем непонятный, можете объяснить что это, зачем нужно и как это объявить без классов?
|
|
|

02.04.2021, 20:33
|
|
Флудер
Регистрация: 06.11.2017
Сообщений: 2,759
С нами:
4483143
Репутация:
183
|
|
Сообщение от Ya Zaregalsya
Пытаюсь разобраться с Вашим примером. «Трамплин» fpDoImpact совсем непонятный, можете объяснить что это, зачем нужно и как это объявить без классов?
C++:
Код:
typedef
void
(
__fastcall
*
DoBulletImpact
)
(
void
*
,
void
*
,
CEntity
*
,
CEntity
*
,
CVector
*
,
CVector
*
,
CColPoint
*
,
int
)
;
DoBulletImpact fpDoImpact
=
0
;
void
__fastcall
DoBulletImpactHooked
(
void
*
weapon
,
void
*
EDX
,
CEntity
*
owner
,
CEntity
*
victim
,
CVector
*
startPoint
,
CVector
*
endPoint
,
CColPoint
*
colPoint
,
int
arg5
)
{
if
(
victim
!=
nullptr
)
{
}
return
fpDoImpact
(
weapon
,
EDX
,
owner
,
victim
,
startPoint
,
endPoint
,
colPoint
,
arg5
)
;
}
C++:
Код:
MH_CreateHook
(
(
void
*
)
0x73B550
,
&
DoBulletImpactHooked
,
reinterpret_cast
(
&
fpDoImpact
)
)
;
MH_EnableHook
(
(
void
*
)
0x73B550
)
;
|
|
|

02.04.2021, 23:43
|
|
Постоянный
Регистрация: 29.05.2017
Сообщений: 394
С нами:
4714653
Репутация:
98
|
|
Сообщение от KiN4StAt
C++:
Код:
typedef
void
(
__fastcall
*
DoBulletImpact
)
(
void
*
,
void
*
,
CEntity
*
,
CEntity
*
,
CVector
*
,
CVector
*
,
CColPoint
*
,
int
)
;
DoBulletImpact fpDoImpact
=
0
;
void
__fastcall
DoBulletImpactHooked
(
void
*
weapon
,
void
*
EDX
,
CEntity
*
owner
,
CEntity
*
victim
,
CVector
*
startPoint
,
CVector
*
endPoint
,
CColPoint
*
colPoint
,
int
arg5
)
{
if
(
victim
!=
nullptr
)
{
}
return
fpDoImpact
(
weapon
,
EDX
,
owner
,
victim
,
startPoint
,
endPoint
,
colPoint
,
arg5
)
;
}
C++:
Код:
MH_CreateHook
(
(
void
*
)
0x73B550
,
&
DoBulletImpactHooked
,
reinterpret_cast
(
&
fpDoImpact
)
)
;
MH_EnableHook
(
(
void
*
)
0x73B550
)
;
При запуске игры плагин жалуется на отсутствие файла minhook.x32.dll и выгружается. Видимо Минхук установлен неправильно, хотя я перепробовал всё, что знаю. Сначала устанавливал его через vcpkg (файлы там и лежат, не знаю как добавить к проекту) — не заработало, потом добавил к проекту все файлы, которые нашёл здесь (кроме исходников), и minhook.x32.dll там тоже есть, но всё равно не работает. Как правильно устанавливать такие библиотеки?
|
|
|

04.04.2021, 08:27
|
|
Познающий
Регистрация: 06.09.2018
Сообщений: 32
С нами:
4045092
Репутация:
23
|
|
Насколько я понимаю, тебе для начала нужно понять как подключать статические/динамические библиотеки в целом.
Нашёл один гайдик на msdn, он как раз под твой случай, разве что он ориентирован на подключение библиотеки динамической компоновки (DLL).
- Факин msdn (для начала стоит по нему пробежаться)
Вроде бы я понял, что тебя именно надо, так что можешь попробовать следовать этому гайдику:
1) Сперва тебе надо получить .lib библиотеку для включения в проект, а также заголовки этой библиотеки (.h).
2) Дальше я попытаюсь объяснить как их получить, но потом ты должен их по своему желанию распределить в проекте по папкам. Например создашь папку sdk (ужасная практика, но пусть будет так). Далее в ней создашь папочку MinHook и туда вставишь заголовочные файлы и файл библиотеки по папкам (includes и Libs соответственно). Опять же подмечу - это ужасная практика, я ее не рекомендую даже знать. Желательно так всё распределить, чтобы при подключении можно было видеть откуда эта шняга, к примеру: #include
Ниче сложного нет, но ты наверное потеряешь связь с реальностью после этого. Да и тем более проект не крупный. Так что мое предложение сойдет.
3) Давно не юзал минхук, но вроде помню, что изначально там нету файла либы (.lib). Тебе её надо получить. Идёшь в их репо на github, клонируешь его к себе. Берешь утилитку Cmake, фигачишь туда путь до CMakeList.txt и ставишь output каталог, можешь, к примеру, назвать как build2.0 (практика еще ужаснее, чем прошлая).
По итогу:
p.s: (это всё примеры, я на самом деле ниче не собирал, т.к мне лень. По памяти буду писать)
Тыкаешь Configure с дефолт пресетами, если у тебя жизнь мёдом, то всё будет ок, а если будут траблы, то гугли.
Помочь с пониманием того, какая у тебя жизнь, поможет лог снизу. Если там всё ДАН, то идешь дальше.
4) Идешь в папку build2.0, открываешь солюшн нашего минхука. Вроде minhook.sln или чёт такое, не помню. Собираешь солюшн (решение). Решений там дохуя наскок я помню. Все тебе их собирать вроде не нужно. Но т.к я не помню, что там за решения - собирай всё. Либо ищи minhook project, если он есть там, и собирай его.
Шлёпаешь в папку под названием... ... Если ты нихуя не менял, то она должна называться как конфигурация, под которой ты всё билдил. Debug там, release и вся эта шняга.
Вуаля, там лежит файл либы (статической).
Копируешь этот файл в свой проект в папку sdk\MinHook\Libs\Этотфайл.lib
5) Где ты на*** будешь брать определения функций, если у тебя их нет. Идёшь как Херлок Шолмс искать файл заголовка/ов от минхука в той же папке, куда ты отдельно должен был склонировать их репо с github. Ищешь там папку include, в ней лежит MinHook.h. Копируешь его в свой проект: \свой проект\sdk\MinHook\includes\MinHook.h.
Готово.
6) Тепешь идешь в проект -> Свойства проекта.
Тут у нас есть отдельный котёл для наших либ. Для всего допотопного говна
мелкомягкие (microsoft) предусмотрели отдельные 2 раздела в иерархии свойств
проекта, специально для линковки ДОПОЛНИТЕЛЬНЫХ либ!
Там всё тоже самое, но с оговоркой: либы тут ДОПОЛНИТЕЛЬНЫЕ.
Грубо говоря это и есть те самые 2 котла для наших дополнительных:
- Включаемых каталогов
- Каталогов либ
Они только имеют в названии "допольнительных"!
Расположение:
Доп.каталоги включаемых файлов: C/C++ -> Общие (General) (Сюда ты пихаешь путь sdk\MinHook\includes)
Доп.каталоги либ: Компоновщик (Linker) -> Общие (General) (Сюды пихаешь sdk\MinHook\Libs)
Далее тебе надо задать в Additional Dependency (я *** знает раздел, т.к вс не открыта). Поищи. Добавляешь название либы, которую ты получил с окончанием .lib
7) Идешь в файл с энтри поинтом или куда тебе там надо. В main.h может быть, я *** знает. И добавляешь MinHook.h
Плюсом через прагма комментируешь объектный файл (про объектник тебе знать не надо, но ты делаешь именно это, эта препроцессорная директива оставит коммент для объектника о том: какое название либы, юзер коммент (то самое название либы), версия компилятора, опции для линкера и т.п) (#pragma comment(lib, "название_либы.lib")). И всё, можешь юзать всё из минхуков.
Хочу подметить. Собирая это всё через gcc, он тебя пошлёт на***, т.к pragma comment - это фишка МелкоМягких.
8) Этот гайд написан новичком для новичка с целью осветить некоторые моменты, и самому въебать время на написание этой статьи. Но прийдется погуглить местами, т.к я наверное не всё описал.
Хочу чтобы меня крутые дяди по 15 лет, которые шарят больше, чем я, и могут что-то дополнить, - сделать это. Хочу посмотреть чего я не знаю и просветиться.
upd: по итогу я решил её собрать и подключить... BTW, эта d после разрядки - це debug версия значит.
А ваще юзайте детур от мелкомягких, чё вы как лопухи.
p.s: объезд.lib топ!
src:
- github minhook
- кодпроджект (тут можно глянуть как в коде выглядит комментирование либы для объектника и юзание)
- факин гуд тред о минхуке (старый вроде, p.s: забыл глянуть дату поста, перед тем как закрыть вкладку)
|
|
|

06.04.2021, 10:48
|
|
Постоянный
Регистрация: 29.05.2017
Сообщений: 394
С нами:
4714653
Репутация:
98
|
|
Сообщение от .deserve
Насколько я понимаю, тебе для начала нужно понять как подключать статические/динамические библиотеки в целом.
Нашёл один гайдик на msdn, он как раз под твой случай, разве что он ориентирован на подключение библиотеки динамической компоновки (DLL).
- Факин msdn (для начала стоит по нему пробежаться)
Вроде бы я понял, что тебя именно надо, так что можешь попробовать следовать этому гайдику:
1) Сперва тебе надо получить .lib библиотеку для включения в проект, а также заголовки этой библиотеки (.h).
2) Дальше я попытаюсь объяснить как их получить, но потом ты должен их по своему желанию распределить в проекте по папкам. Например создашь папку sdk (ужасная практика, но пусть будет так). Далее в ней создашь папочку MinHook и туда вставишь заголовочные файлы и файл библиотеки по папкам (includes и Libs соответственно). Опять же подмечу - это ужасная практика, я ее не рекомендую даже знать. Желательно так всё распределить, чтобы при подключении можно было видеть откуда эта шняга, к примеру: #include
Ниче сложного нет, но ты наверное потеряешь связь с реальностью после этого. Да и тем более проект не крупный. Так что мое предложение сойдет.
3) Давно не юзал минхук, но вроде помню, что изначально там нету файла либы (.lib). Тебе её надо получить. Идёшь в их репо на github, клонируешь его к себе. Берешь утилитку Cmake, фигачишь туда путь до CMakeList.txt и ставишь output каталог, можешь, к примеру, назвать как build2.0 (практика еще ужаснее, чем прошлая).
По итогу:
p.s: (это всё примеры, я на самом деле ниче не собирал, т.к мне лень. По памяти буду писать)
Тыкаешь Configure с дефолт пресетами, если у тебя жизнь мёдом, то всё будет ок, а если будут траблы, то гугли.
Помочь с пониманием того, какая у тебя жизнь, поможет лог снизу. Если там всё ДАН, то идешь дальше.
4) Идешь в папку build2.0, открываешь солюшн нашего минхука. Вроде minhook.sln или чёт такое, не помню. Собираешь солюшн (решение). Решений там дохуя наскок я помню. Все тебе их собирать вроде не нужно. Но т.к я не помню, что там за решения - собирай всё. Либо ищи minhook project, если он есть там, и собирай его.
Шлёпаешь в папку под названием... ... Если ты нихуя не менял, то она должна называться как конфигурация, под которой ты всё билдил. Debug там, release и вся эта шняга.
Вуаля, там лежит файл либы (статической).
Копируешь этот файл в свой проект в папку sdk\MinHook\Libs\Этотфайл.lib
5) Где ты на*** будешь брать определения функций, если у тебя их нет. Идёшь как Херлок Шолмс искать файл заголовка/ов от минхука в той же папке, куда ты отдельно должен был склонировать их репо с github. Ищешь там папку include, в ней лежит MinHook.h. Копируешь его в свой проект: \свой проект\sdk\MinHook\includes\MinHook.h.
Готово.
6) Тепешь идешь в проект -> Свойства проекта.
Тут у нас есть отдельный котёл для наших либ. Для всего допотопного говна
мелкомягкие (microsoft) предусмотрели отдельные 2 раздела в иерархии свойств
проекта, специально для линковки ДОПОЛНИТЕЛЬНЫХ либ!
Там всё тоже самое, но с оговоркой: либы тут ДОПОЛНИТЕЛЬНЫЕ.
Грубо говоря это и есть те самые 2 котла для наших дополнительных:
- Включаемых каталогов
- Каталогов либ
Они только имеют в названии "допольнительных"!
Расположение:
Доп.каталоги включаемых файлов: C/C++ -> Общие (General) (Сюда ты пихаешь путь sdk\MinHook\includes)
Доп.каталоги либ: Компоновщик (Linker) -> Общие (General) (Сюды пихаешь sdk\MinHook\Libs)
Далее тебе надо задать в Additional Dependency (я *** знает раздел, т.к вс не открыта). Поищи. Добавляешь название либы, которую ты получил с окончанием .lib
7) Идешь в файл с энтри поинтом или куда тебе там надо. В main.h может быть, я *** знает. И добавляешь MinHook.h
Плюсом через прагма комментируешь объектный файл (про объектник тебе знать не надо, но ты делаешь именно это, эта препроцессорная директива оставит коммент для объектника о том: какое название либы, юзер коммент (то самое название либы), версия компилятора, опции для линкера и т.п) (#pragma comment(lib, "название_либы.lib")). И всё, можешь юзать всё из минхуков.
Хочу подметить. Собирая это всё через gcc, он тебя пошлёт на***, т.к pragma comment - это фишка МелкоМягких.
8) Этот гайд написан новичком для новичка с целью осветить некоторые моменты, и самому въебать время на написание этой статьи. Но прийдется погуглить местами, т.к я наверное не всё описал.
Хочу чтобы меня крутые дяди по 15 лет, которые шарят больше, чем я, и могут что-то дополнить, - сделать это. Хочу посмотреть чего я не знаю и просветиться.
upd: по итогу я решил её собрать и подключить... BTW, эта d после разрядки - це debug версия значит.
А ваще юзайте детур от мелкомягких, чё вы как лопухи.
p.s: объезд.lib топ!
src:
- github minhook
- кодпроджект (тут можно глянуть как в коде выглядит комментирование либы для объектника и юзание)
- факин гуд тред о минхуке (старый вроде, p.s: забыл глянуть дату поста, перед тем как закрыть вкладку)
В папке build2.0 не появилось файла с расширением .sln. Уточните, в CMake в поле исходников нужно указывать папку, скачанную из ГитХаба или что-то другое? Я скачал архив и распаковал minhook-master в проект в папку SDK, теперь в папке SDK\Minhook всего четыре папки и один документ: Libs, Includes, build2.0, minhook-master и CMakeLists.txt. Зачем там Libs и Includes — пока непонятно.
|
|
|

06.04.2021, 11:37
|
|
Познающий
Регистрация: 06.09.2018
Сообщений: 32
С нами:
4045092
Репутация:
23
|
|
Сообщение от Ya Zaregalsya
В папке build2.0 не появилось файла с расширением .sln. Уточните, в CMake в поле исходников нужно указывать папку, скачанную из ГитХаба или что-то другое? Я скачал архив и распаковал minhook-master в проект в папку SDK, теперь в папке SDK\Minhook всего четыре папки и один документ: Libs, Includes, build2.0, minhook-master и CMakeLists.txt. Зачем там Libs и Includes — пока непонятно.
1) Да, объяснил ниже.
2) Ты не так разбил по папкам. Надо иначе, ниже объяснил.
Проект с гитхаба тебе нужно просто распаковать в любую другою папку. Но не в проект! И уж тем более не в SDK. SDK - это софт для разработки. Грубо говоря зависимости. Эта папка для зависимостей. А уже в ней есть папки MinHook и в ней Libs и includes. Ты должен собрать либу, которая у тебя должна быть абсолютно в другой папке. После чего ты получаешь файл либы и ищешь в папке github проекта хидер файлы .h. Их ты раскидываешь УЖЕ В СВОЙ проект в папку зависимостей - в нашем случае SDK/MinHook/Libs (для .lib), а SDK/MinHook/includes (для .h).
Почему в build2.0 не появилось файла sln? Перепроверьте то, как вы указали пути в Cmake. Там где source - там должен быть путь до папки github проекта. Там где папка для сбилженых бинарников - там указываешь тот же путь, но создаешь новую папку (но она вроде и сама должна создаться). Например build2.0.
Далее конфигурируешь через кнопку configure, там выбираешь версию vs которая у тебя стоит. После конфигурации нажимаешь Generate. Смотришь в лог снизу, чтобы было всё окей. Далее идешь в папку и там ищешь sln. Всё, дальше всё в гайде.
|
|
|

11.04.2021, 17:12
|
|
Постоянный
Регистрация: 29.05.2017
Сообщений: 394
С нами:
4714653
Репутация:
98
|
|
Сообщение от .deserve
1) Да, объяснил ниже.
2) Ты не так разбил по папкам. Надо иначе, ниже объяснил.
Проект с гитхаба тебе нужно просто распаковать в любую другою папку. Но не в проект! И уж тем более не в SDK. SDK - это софт для разработки. Грубо говоря зависимости. Эта папка для зависимостей. А уже в ней есть папки MinHook и в ней Libs и includes. Ты должен собрать либу, которая у тебя должна быть абсолютно в другой папке. После чего ты получаешь файл либы и ищешь в папке github проекта хидер файлы .h. Их ты раскидываешь УЖЕ В СВОЙ проект в папку зависимостей - в нашем случае SDK/MinHook/Libs (для .lib), а SDK/MinHook/includes (для .h).
Почему в build2.0 не появилось файла sln? Перепроверьте то, как вы указали пути в Cmake. Там где source - там должен быть путь до папки github проекта. Там где папка для сбилженых бинарников - там указываешь тот же путь, но создаешь новую папку (но она вроде и сама должна создаться). Например build2.0.
Далее конфигурируешь через кнопку configure, там выбираешь версию vs которая у тебя стоит. После конфигурации нажимаешь Generate. Смотришь в лог снизу, чтобы было всё окей. Далее идешь в папку и там ищешь sln. Всё, дальше всё в гайде.
Как собрать 32-битную версию?
|
|
|
|
 |
|
Предыдущая тема
Следующая тема
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|