Ошибка в коде

Broudy Rose

Участник
Сообщения
157
Реакции
22
Делаю отладку сервера v34, удаляя плагины по одному.
Ищу проблему падений сервера раз в 2 дня.
На данном этапе error-логов уже нет, crash-логи интересной информации не предоставляют.
После удаления простого плагина растворения тел Dissolve падения прекратились.
Перечитал код и не нашёл проблемных мест. Иных плагинов, удаляющих тела на сервере нет.
Ваши мысли?

C-подобный:
#include <sdktools>

public OnPluginStart()
{
    HookEvent("player_death", OnPlayerDeath);
}

public OnPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
    new Float:duration = 3.0;
    new ragdoll = GetEntPropEnt(GetClientOfUserId(GetEventInt(event, "userid")), Prop_Send, "m_hRagdoll");

    if (ragdoll <= MaxClients || !IsValidEdict(ragdoll))
        return;

    CreateTimer(duration, DissolveEntity, ragdoll, TIMER_FLAG_NO_MAPCHANGE);
}

public Action:DissolveEntity(Handle:event, any:ragdoll)
{
    if (!IsValidEdict(ragdoll))
        return;

    ExtinguishEntity(ragdoll);

    decl String:target[32];
    Format(target, sizeof(target), "target_%d", ragdoll);

    new ent = CreateEntityByName("env_entity_dissolver");
    if (ent > 0)
    {
        DispatchKeyValue(ragdoll, "targetname", target);
        DispatchKeyValue(ent, "dissolvetype", "3");
        DispatchKeyValue(ent, "target", target);
        AcceptEntityInput(ent, "Dissolve");
        AcceptEntityInput(ent, "kill");
    }
}
 
Решение
В таймер нужно передавать не индекс энтити, а референс.

Попробуй такой вариант:
C-подобный:
#pragma semicolon 1

#include <sdktools_entinput>
#include <sdktools_functions>

public OnPluginStart()
{
    HookEvent("player_death", OnPlayerDeath);
}

public void OnPlayerDeath(Event event, const char[] name, bool dontBroadcast)
{
    int buffer = GetClientOfUserId(event.GetInt("userid"));
    if(buffer && (buffer = GetEntPropEnt(buffer, Prop_Send, "m_hRagdoll")) > MaxClients)
        CreateTimer(3.0, DissolveEntity, EntIndexToEntRef(buffer), TIMER_FLAG_NO_MAPCHANGE);
}

public Action DissolveEntity(Handle event, int ragdoll)
{
    if((ragdoll = EntRefToEntIndex(ragdoll)) == INVALID_ENT_REFERENCE)
        return Plugin_Stop...

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
В таймер нужно передавать не индекс энтити, а референс.

Попробуй такой вариант:
C-подобный:
#pragma semicolon 1

#include <sdktools_entinput>
#include <sdktools_functions>

public OnPluginStart()
{
    HookEvent("player_death", OnPlayerDeath);
}

public void OnPlayerDeath(Event event, const char[] name, bool dontBroadcast)
{
    int buffer = GetClientOfUserId(event.GetInt("userid"));
    if(buffer && (buffer = GetEntPropEnt(buffer, Prop_Send, "m_hRagdoll")) > MaxClients)
        CreateTimer(3.0, DissolveEntity, EntIndexToEntRef(buffer), TIMER_FLAG_NO_MAPCHANGE);
}

public Action DissolveEntity(Handle event, int ragdoll)
{
    if((ragdoll = EntRefToEntIndex(ragdoll)) == INVALID_ENT_REFERENCE)
        return Plugin_Stop;

    ExtinguishEntity(ragdoll);

    int ent = CreateEntityByName("env_entity_dissolver");
    if(ent != -1)
    {
        decl String:target[32];
        Format(target, sizeof(target), "target_%d", ragdoll);

        DispatchKeyValue(ragdoll, "targetname", target);
        DispatchKeyValue(ent, "dissolvetype", "3");
        DispatchKeyValue(ent, "target", target);
        AcceptEntityInput(ent, "Dissolve");
        AcceptEntityInput(ent, "kill");
    }

    return Plugin_Stop;
}
 
Решение

Broudy Rose

Участник
Сообщения
157
Реакции
22
В таймер нужно передавать не индекс энтити, а референс.

Попробуй такой вариант:
C-подобный:
#pragma semicolon 1

#include <sdktools_entinput>
#include <sdktools_functions>

public OnPluginStart()
{
    HookEvent("player_death", OnPlayerDeath);
}

public void OnPlayerDeath(Event event, const char[] name, bool dontBroadcast)
{
    int buffer = GetClientOfUserId(event.GetInt("userid"));
    if(buffer && (buffer = GetEntPropEnt(buffer, Prop_Send, "m_hRagdoll")) > MaxClients)
        CreateTimer(3.0, DissolveEntity, EntIndexToEntRef(buffer), TIMER_FLAG_NO_MAPCHANGE);
}

public Action DissolveEntity(Handle event, int ragdoll)
{
    if((ragdoll = EntRefToEntIndex(ragdoll)) == INVALID_ENT_REFERENCE)
        return Plugin_Stop;

    ExtinguishEntity(ragdoll);

    int ent = CreateEntityByName("env_entity_dissolver");
    if(ent != -1)
    {
        decl String:target[32];
        Format(target, sizeof(target), "target_%d", ragdoll);

        DispatchKeyValue(ragdoll, "targetname", target);
        DispatchKeyValue(ent, "dissolvetype", "3");
        DispatchKeyValue(ent, "target", target);
        AcceptEntityInput(ent, "Dissolve");
        AcceptEntityInput(ent, "kill");
    }

    return Plugin_Stop;
}
Спасибо, потребуется время, чтобы сравнить частоту падений
 
Сверху Снизу