ANTICHAT

ANTICHAT (https://forum.antichat.xyz/index.php)
-   Общие вопросы программирования (https://forum.antichat.xyz/forumdisplay.php?f=206)
-   -   [SA:MP Server Plugin] Проблема с указателем на amx (https://forum.antichat.xyz/showthread.php?t=1541489)

routefleeder 23.08.2025 17:11

Всем ку. Вторые сутки не могу решить одну проблему с кастомным коллбеком в серверном плагине. Наверняка на бластхаке найдутся шарящие за структуру работы плагинов. Так вот, ближе к сути. Ниже покажу код функции которая должна вызывать коллбек в amx'е и то как я получаю указатель на него. Вероятно проблема как раз-таки с невалидностью указателя AMX*, у меня просто крашит сервер в момент выполнения OnPlayerPressKey. Буду премного благодарен, если кто-то сможет помочь.

Custom Amx Callback:





Код:

#include "sampgdk.h"
#include "Callbacks.h"
// тут есть инклуд CGameMode.h со структурой
cell PluginCallbacks
::
OnPlayerPressKey
(
CGameMode
*
gamemode
,
int
key
,
int
playerid
)
{
if
(
!
gamemode
->
m_bInitialised
)
return
0
;
int
amx_id
=
0
;
cell retval
=
0
;
// Amx-Callback return value
if
(
!
amx_FindPublic
(
&
gamemode
->
m_amx
,
"OnPlayerPressKey"
,
&
amx_id
)
)
{
amx_Push
(
&
gamemode
->
m_amx
,
key
)
;
amx_Push
(
&
gamemode
->
m_amx
,
playerid
)
;
amx_Exec
(
&
gamemode
->
m_amx
,
&
retval
,
amx_id
)
;
}
return
retval
;
}



получаем указатель и вызываем функцию:

Call callback-function:





Код:

CNetGame
*
netgame_ptr
=
PluginPointers
::
GetCNetGamePointer
(
)
;
// я на сто процентов уверен, что получаю валидный глобальный указатель на CNetGame, потому что он прекрасно работает в других местах кода
CGameMode
*
gm_ptrr
=
netgame_ptr
->
m_pGameMode
;
PluginCallbacks
::
OnPlayerPressKey
(
gm_ptrr
,
key
,
playerid
)
;
// параметры key и playerid так же точно валидны, ведь я вижу вывод их в консоль сервера


swlm 24.08.2025 00:54

Использовал когда-нибудь samp-ptl?

Никаких указателей не надо, сделано всё за тебя :)

routefleeder 24.08.2025 13:51

Цитата:

Сообщение от daun.daunovich.01

Использовал когда-нибудь samp-ptl?
Никаких указателей не надо, сделано всё за тебя :)

Ну я sampgdk юзаю, там всё как в samp-ptl, да и с samp-ptl оригинальным тоже игрался. В общем я принял решение хукать OnGameModeInit и OnFilterscriptInit для получения валидного указателя

вайега52 24.08.2025 16:23

Вот пример с samp-ptl:

C++:





Код:

#include "ptl.h"
class
Script
:
public
ptl
::
AbstractScript

{
private
:
std
::
shared_ptr

onTest_
;
public
:
// враппер для вызова каллбека из amx
void
OnTest
(
std
::
uint32_t
playerId
)
{
if
(
onTest_
&&
onTest_
->
Exists
(
)
)
{
onTest_
->
Exec
(
playerId
)
;
}
}
bool
OnLoad
(
)
{
int
numPublics
{
}
;
amx_
->
NumPublics
(
&
numPublics
)
;
for
(
int
index
{
}
;
index

{
private
:
public
:
const
char
*
Name
(
)
;
bool
OnLoad
(
)
;
}
;
// А также вызовы:
PLUGIN_EXPORT
void
PLUGIN_CALL
AmxLoad
(
AMX
*
amx
)
{
Plugin
::
DoAmxLoad
(
amx
)
;
}
PLUGIN_EXPORT
unsigned
int
PLUGIN_CALL
Supports
(
)
{
return
SUPPORTS_VERSION
|
SUPPORTS_AMX_NATIVES
;
}



Время: 18:29