PDA

Просмотр полной версии : [SA:MP Server Plugin] Проблема с указателем на amx


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 (https://github.com/katursis/samp-ptl)?

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

routefleeder
24.08.2025, 13:51
Использовал когда-нибудь samp-ptl (https://github.com/katursis/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
;
}