Падения сервера с entity

Сообщения
73
Реакции
8
Всем привет.
Накидал код плагина "токсичный дым", который наносит урон игрокам, которые находятся в нем.
После, сервер стал падать в случайные промежутки времени.

Единственный, точно определенный момент падения - смена карты.
Также, сервер может упасть как сразу после создания entity, так и в конце раудна.

Код:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>

#define SPRITE_SMOKE        "sprites/poison_smoke.spr"            // Путь до спрайта

new g_Sprite, g_Players, g_Count[999];
new bool:g_HaveFlag[33];
new bool:g_HaveSmoke[33];
new const CLASSNAME[] =    "PoisonSmoke";

public plugin_init()
{
    register_plugin("Poison Smoke", "1.0", "TBONTB")
    
    register_forward(FM_EmitSound, "Emit_Sound");
    register_forward(FM_Think, "Fw_Think");
    
    RegisterHookChain(RG_CBasePlayer_Spawn, "Player_Spawn", true);
    RegisterHookChain(RG_CSGameRules_RestartRound, "Start_Round", false);
}

public plugin_precache()
    g_Sprite = precache_model(SPRITE_SMOKE);
    
public client_putinserver(id)
{
    g_HaveFlag[id] = (get_user_flags(id) & ADMIN_BAN) ? true : false;
    g_Players++;
}

public client_disconnected(id)
    g_Players--;

public Player_Spawn(id)
{
    if(!is_user_connected(id) || !g_HaveFlag[id]) return;
    
    g_HaveSmoke[id] = true;
    rg_give_item(id, "weapon_smokegrenade");
    client_print_color(id, print_team_default, "^1[^4INFO^1] Вы получили гранату ^3Ядовитый дым ^4!");
}

public Start_Round()
{
    new iEnt = -1;
    
    while((iEnt = engfunc(EngFunc_FindEntityByString, iEnt, "classname", CLASSNAME)))
    {
        if(pev_valid(iEnt))
            engfunc(EngFunc_RemoveEntity, iEnt);
    }
}

public Emit_Sound(iEnt, iChannel, const szSample[], Float:fVol, Float:fAttn, iFlags, iPitch)
{
    new iOwner = pev(iEnt, pev_owner);
    
    if(equal(szSample, "weapons/sg_explode.wav") && g_HaveSmoke[iOwner])
    {
        new Float:Origin[3], szModel[64];
        
        pev(iEnt, pev_origin, Origin);
        pev(iEnt, pev_model, szModel, charsmax(szModel))
        
        engfunc(EngFunc_RemoveEntity, iEnt);
        
        g_HaveSmoke[iOwner] = false;
        
        static a; a = engfunc(EngFunc_AllocString, "info_target");
        static iEntity; iEntity = engfunc(EngFunc_CreateNamedEntity, a);
        
        if(pev_valid(iEntity))
        {
            set_pev(iEntity, pev_classname, CLASSNAME);
            set_pev(iEntity, pev_owner, iOwner);
            set_pev(iEntity, pev_origin, Origin);
            
            set_pev(iEntity, pev_movetype, MOVETYPE_TOSS);
            set_pev(iEntity, pev_solid, SOLID_BBOX);
            
            engfunc(EngFunc_SetModel, iEntity, szModel);
            
            set_pev(iEntity, pev_nextthink, get_gametime() + 1.0);
            
            emit_sound(iEntity, iChannel, szSample, fVol, fAttn, iFlags, iPitch);
            
            message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
            write_byte(TE_FIREFIELD);
            engfunc(EngFunc_WriteCoord, Origin[0]);
            engfunc(EngFunc_WriteCoord, Origin[1]);
            engfunc(EngFunc_WriteCoord, Origin[2] + 50);
            write_short(100);
            write_short(g_Sprite);
            write_byte(100);
            write_byte(TEFIRE_FLAG_ALPHA);
            write_byte(20 * 10);
            message_end();
            
            message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
            write_byte(TE_FIREFIELD);
            engfunc(EngFunc_WriteCoord, Origin[0]);
            engfunc(EngFunc_WriteCoord, Origin[1]);
            engfunc(EngFunc_WriteCoord, Origin[2] + 50);
            write_short(150);
            write_short(g_Sprite);
            write_byte(10);
            write_byte(TEFIRE_FLAG_ALPHA | TEFIRE_FLAG_SOMEFLOAT);
            write_byte(20 * 10);
            message_end();
        }
        return FMRES_IGNORED;
    }
    return FMRES_IGNORED;
}

public Fw_Think(iEnt)
{
    if(!pev_valid(iEnt)) return FMRES_IGNORED;
    
    static szEntityClass[32];
    pev(iEnt, pev_classname, szEntityClass, charsmax(szEntityClass));
    
    if(!equali(szEntityClass, CLASSNAME)) return FMRES_IGNORED;
    
    if(++g_Count[iEnt] >= 20)
    {
        g_Count[iEnt] = 0;
        engfunc(EngFunc_RemoveEntity, iEnt);
    }
    else
    {
        new Float:iEntOrigin[3], Float:iPlayerOrigin[3], Float:iDistance;
        pev(iEnt, pev_origin, iEntOrigin);
        
        new iOwner = pev(iEnt, pev_owner);
        
        for(new id = 1; id <= get_maxplayers(); id++)
        {
            if(!is_user_alive(id)) continue;
                
            if(get_member(id, m_iTeam) == get_member(iOwner, m_iTeam)) continue;
            
            pev(id, pev_origin, iPlayerOrigin);
            iDistance = get_distance_f(iEntOrigin, iPlayerOrigin);
            
            if(iDistance <= 200.0)
                user_slap(id, 10);
        }
        set_pev(iEnt, pev_nextthink, get_gametime() + 1.0);
    }
    return FMRES_IGNORED;
}

Во время падения появляются следующие сообщения и больше ничего:
Segmentation fault (core dumped)

или

hlds_linux: malloc.c:3589: _int_malloc: Assertion `(bck->bk->size & NON_MAIN_ARENA) == 0' failed.
Aborted (core dumped) - такие, во время смены карты.

----------------------------------------------
CRASH: Tue Jan 7 19:07:38 +07 2020
Start Line: ./hlds_linux -debug -game cstrike -master -noipx -sys_ticrate 500 -secure +ip 95.188.88.74 +port 27037 +map de_dust2 -maxplayers 10 +rcon_password +sv_password zp70 -pidfile hlds.21091.pid
[New LWP 21098]
[New LWP 21101]
[New LWP 21099]
[New LWP 21129]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./hlds_linux -debug -game cstrike -master -noipx -sys_ticrate 500 -secure +ip 9'.
Program terminated with signal SIGABRT, Aborted.
#0 0xf7778c89 in __kernel_vsyscall ()
[Current thread is 1 (Thread 0xf744b940 (LWP 21098))]
#0 0xf7778c89 in __kernel_vsyscall ()
#1 0xf74e2dd0 in raise () from /lib/i386-linux-gnu/libc.so.6
#2 0xf74e4297 in abort () from /lib/i386-linux-gnu/libc.so.6
#3 0xf7524a30 in ?? () from /lib/i386-linux-gnu/libc.so.6
#4 0xf752763b in ?? () from /lib/i386-linux-gnu/libc.so.6
#5 0xf7528bf5 in malloc () from /lib/i386-linux-gnu/libc.so.6
#6 0xf751444f in _IO_file_doallocate () from /lib/i386-linux-gnu/libc.so.6
#7 0xf7522a86 in _IO_doallocbuf () from /lib/i386-linux-gnu/libc.so.6
#8 0xf7521d81 in _IO_file_overflow () from /lib/i386-linux-gnu/libc.so.6
#9 0xf7520de0 in _IO_file_xsputn () from /lib/i386-linux-gnu/libc.so.6
#10 0xf751597d in fwrite () from /lib/i386-linux-gnu/libc.so.6
#11 0xf2bb67cf in RankSystem::saveRank(char const*) () from cstrike/addons/amxmodx/modules/csx_amxx_i386.so
#12 0x0b0d8bc8 in ?? ()
#13 0xff94f310 in ?? ()
#14 0xf6df65d5 in Host_Changelevel_f() () from /home/srv944199/engine_i486.so
#15 0x00000000 in ?? ()
No symbol table info available.
From To Syms Read Shared Object Library
0xf76e7914 0xf772dc78 Yes ./libstdc++.so.6
0xf768ca30 0xf768d921 Yes (*) /lib/i386-linux-gnu/libdl.so.2
0xf76738c0 0xf7680f01 Yes (*) /lib/i386-linux-gnu/libpthread.so.0
0xf74ce800 0xf75fc01f Yes (*) /lib/i386-linux-gnu/libc.so.6
0xf74666e0 0xf749dfcb Yes (*) /lib/i386-linux-gnu/libm.so.6
0xf777a860 0xf7793f1d Yes (*) /lib/ld-linux.so.2
0xf744ee04 0xf745e490 Yes ./libgcc_s.so.1
0xf6d7e200 0xf6e64920 Yes (*) /home/srv944199/engine_i486.so
0xf6d42840 0xf6d45dfc Yes (*) /lib/i386-linux-gnu/librt.so.1
0xf6d305c0 0xf6d3ad74 Yes (*) ./libsteam_api.so
0xf6d16a00 0xf6d231b8 Yes /home/srv944199/filesystem_stdio.so
0xf5e0de80 0xf68f5040 Yes (*) /home/cs/hlds_6153/steamclient.so
0xf5c88670 0xf5cfe020 Yes (*) /home/cs/hlds_6153/crashhandler.so
0xf342b6a0 0xf346df70 Yes (*) /home/srv944199/./cstrike/addons/metamod/dlls/metamod.so
0xf31f73e0 0xf3373ec0 Yes (*) /home/srv944199/cstrike/dlls/cs.so
0xf2ed68c0 0xf3084571 Yes (*) /home/srv944199/cstrike/addons/vtc/dlls/vtc.so
0xf2e3f840 0xf2e634e0 Yes (*) /home/srv944199/cstrike/addons/reunion/dlls/reunion.so
0xf2c67890 0xf2cca907 Yes (*) /home/srv944199/cstrike/addons/amxmodx/dlls/amxmodx.so
0xf2c39d50 0xf2c49460 Yes (*) cstrike/addons/amxmodx/modules/cstrike_amxx_i386.so
0xf2bb4120 0xf2bba404 Yes (*) cstrike/addons/amxmodx/modules/csx_amxx_i386.so
0xf2b719d0 0xf2b9dd6c Yes (*) cstrike/addons/amxmodx/modules/fakemeta_amxx_i386.so
0xf2460790 0xf24f8fc5 Yes (*) cstrike/addons/amxmodx/modules/mysql_amxx_i386.so
0xf297cb60 0xf29c4624 Yes (*) cstrike/addons/amxmodx/modules/hamsandwich_amxx_i386.so
0xf28fb540 0xf293a670 Yes (*) cstrike/addons/amxmodx/modules/reapi_amxx_i386.so
0xf2a2ca80 0xf2a328f0 Yes (*) /lib/i386-linux-gnu/libnss_files.so.2
0xf01ffe80 0xf0ce7040 Yes (*) ./steamclient.so
0xefa60670 0xefad6020 Yes (*) ./crashhandler.so
(*): Shared library is missing debugging information.
Stack level 0, frame at 0xff94ecb0:
eip = 0xf7778c89 in __kernel_vsyscall; saved eip = 0xf74e2dd0
called by frame at 0xff94edd0
Arglist at 0xff94eca8, args:
Locals at 0xff94eca8, Previous frame's sp is 0xff94ecb0
Saved registers:
ecx at 0xff94eca8, edx at 0xff94eca4, ebp at 0xff94eca0, eip at 0xff94ecac
End of crash report
----------------------------------------------

Что не так с кодом ?
 
Сообщения
169
Реакции
462
Помог
2 раз(а)
В функции Emit_Sound нет проверки на валидность энтити.
Энтити лучше убивать флагом FL_KILLME (если конечно нет оснований юзать RemoveEntity).
 
Сообщения
73
Реакции
8
the_hunter, Спасибо за совет.
На 103 строчке я удаляю стандартный дым (серый). Пробовал удалять его с помощью FL_KILLME, но он не пропадал никуда :sclerosis:, а с engfunc(EngFunc_RemoveEntity, iEnt); все нормально работало.
 
Сообщения
169
Реакции
462
Помог
2 раз(а)
To_be_or_not_to_be
C++:
#include <amxmodx>
#include <reapi>

public plugin_init()
{
    RegisterHookChain(RG_CGrenade_ExplodeSmokeGrenade, "on_explode_smoke_grenade", false);
}

public on_explode_smoke_grenade(entGrenade)
{
    new Float:vecOrigin[3]; // Координаты точки взрыва гранаты (делаем дым тут).
    get_entvar(entGrenade, var_origin, vecOrigin);

    // Можем убить энтити сразу (флагом FL_KILLME)
    // или в синке, например через 5 сек.
    SetThink(entGrenade, "on_smoke_grenade_think");
    set_entvar(entGrenade, var_nextthink, get_gametime() + 5.0);

    // Не пускаем стандартный дым.
    return HC_SUPERCEDE;
}

public on_smoke_grenade_think(entGrenade)
{
    if (!is_nullent(entGrenade))
    {
        new flags = get_entvar(entGrenade, var_flags) | FL_KILLME;
        set_entvar(entGrenade, var_flags, flags);
    }
}
 
Сообщения
73
Реакции
8
the_hunter, ps Спасибо, уже сам додумался :d
7 Янв 2020
the_hunter, а, стоп.. Как так получилось?
20366
Код:
public Explode_Smoke(iEnt)
{
    if(is_nullent(iEnt)) return HC_CONTINUE;

    set_entvar(iEnt, var_flags, get_entvar(iEnt, var_flags) | FL_KILLME);
    
    // code ...
    
    return HC_SUPERCEDE;
}
 

Вложения

Сообщения
198
Реакции
16
Помог
1 раз(а)
To_be_or_not_to_be, как вариант
  • функция не была вызвана
  • сработала первая проверка
я бы задебажил)
 
Сообщения
1,701
Реакции
1,512
Помог
26 раз(а)
kucklovod, проверка бессмысленна, так как там всегда валидная энтити (если вы не Радиус).
8 Янв 2020
и вместо g_Count[999] юзать m_Grenade_SGSmoke.
8 Янв 2020
и вместо get_member(iOwner, m_iTeam) юзать m_Grenade_iTeam.
8 Янв 2020
и вместо
register_forward(FM_EmitSound, "Emit_Sound");
register_forward(FM_Think, "Fw_Think");
юзать SetThink с nextthink.
8 Янв 2020
и вместо user_slap(id, 10) юзать Ham_TakeDamage.
8 Янв 2020
и вместо
g_HaveSmoke[id] = true;
rg_give_item(id, "weapon_smokegrenade");
юзать var_impulse с rg_give_custom_item
8 Янв 2020
и вместо g_HaveFlag[33] юзать напрямую
8 Янв 2020
и вместо g_Players юзать ничего.
8 Янв 2020
и вместо #define SPRITE_SMOKE юзать new const.
8 Янв 2020
и вместо is_user_connected в спавне юзать is_user_alive.
8 Янв 2020
если юзать обычный смок как сказал выше, то Start_Round не нужен (тем более false).
8 Янв 2020
static a; a = engfunc(EngFunc_AllocString, "info_target");
static iEntity; iEntity = engfunc(EngFunc_CreateNamedEntity, a);

тоже не нужно.
8 Янв 2020
и вместо get_maxplayers() юзать MaxClients.
8 Янв 2020
Вроде про все мелочи написал.
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу