• Гость, перед открытием темы прочитай описание раздела, чтобы не ошибиться. Любые вопросы по настройке сервера создаются в разделе Технической Поддержки.
Иконка ресурса

ReAPI AFK Control (менеджер AFK) 1.4.1

Нет прав для скачивания
Форматирование (BB-код):
// *************************************************************************************//
// Плагин загружен с  www.neugomon.ru                                                   //
// Автор: Neygomon  [ https://neugomon.ru/members/1/ ]                                  //
// Официальная тема поддержки: https://neugomon.ru/threads/34/                          //
// При копировании материала ссылка на сайт www.neugomon.ru ОБЯЗАТЕЛЬНА!                //
// *************************************************************************************//

/*
    Original code: Freedo.m
*/

#include <amxmodx>
#include <reapi>

#pragma semicolon 1

#define ACCESS_LEVEL_IMMUNITY (ADMIN_MENU|ADMIN_LEVEL_H)
    // Уровень доступа позволяющий беспрепятственно сидеть в зрителях

#define TIME_AFK_CHECK 15.0 
    // Интервал между проверками игроков, чем меньше значение, тем больше нагрузка на сервер.
    // В режиме NOROUND (для CSDM) ставьте маленькое значение TIME_AFK_CHECK, так как таймер обнуляется при спавне.

#define MAX_AFK_WARNING 3     // Количество предупреждений после которых последует наказание.
#define TIME_SPECT_CHECK 60.0     // Интервал между проверками зрителей, чем меньше значение, тем больше нагрузка на сервер.
#define MAX_SPECT_CHECK_PL 2     // Количество проверок игрока на нахождение в зрителях, после которых его кикнет
#define MIN_PLAYERS_CHECK 30     // Минимальное количество игроков, когда включается функция проверки зрителей.
// #define NOROUND        // Включает поддержку серверов с бесконечным раундом. Например CSDM, GunGame
#define BOMB_TRANSFER
    // Передавать ли бомбу игрокам, если игрок AFK.
    // Закомментируйте, если хотите, чтобы бомба просто выкидывалась
    // Игнорируется при включенном NOROUND

#define    get_bit(%1,%2)    (%1 & (1 << (%2 & 31)))
#define    set_bit(%1,%2)    %1 |= (1 << (%2 & 31))
#define    clr_bit(%1,%2)    %1 &= ~(1 << (%2 & 31))

new Float:g_fOldOrigin[33][3], Float:g_fOldAngles[33][3];
new g_bitValid;
#if defined NOROUND
new g_bitSpec;
#endif
new g_iWarning[33];
new pnum, players[32];
new g_count[33];

public plugin_init()
{
#if defined NOROUND
    RegisterHookChain(RG_CBasePlayer_Spawn, "PlrSpwn_Post", true);
    #define VERSION "1.4.1 [NoRnd]"
#else
    register_logevent("LeRoundStart", 2, "1=Round_Start");
    #define VERSION "1.4.1 [Rnd]"
#endif
    register_plugin("AFK Control", VERSION, "neygomon");
    set_task(TIME_SPECT_CHECK, "SpectatorCheck", .flags = "b");
}

public client_putinserver(id)
{
    if(is_user_bot(id) || is_user_hltv(id) || get_user_flags(id) & ACCESS_LEVEL_IMMUNITY)
        clr_bit(g_bitValid, id);
    else    set_bit(g_bitValid, id);
    g_count[id] = 0;
#if defined NOROUND
    clr_bit(g_bitSpec, id);
#endif
}
#if defined NOROUND
public client_disconnected(id)
    remove_task(id);

public PlrSpwn_Post(id)
    if(is_user_alive(id))
        LeRoundStart(id);
#endif
public LeRoundStart(id)
{
#if defined NOROUND
    if(!get_bit(g_bitSpec, id))
    {
        get_entvar(id, var_origin, g_fOldOrigin[id]);
        get_entvar(id, var_angles, g_fOldAngles[id]);

        if(!task_exists(id))
            set_task(TIME_AFK_CHECK, "AfkCheck", id, .flags = "b");
        else    change_task(id, TIME_AFK_CHECK);
    }
#else
    static freezetime;
    if(!freezetime) freezetime = get_cvar_pointer("mp_freezetime");
    if(get_pcvar_num(freezetime) > 0)
        GoCheckPlayers();
    else    set_task(1.0, "GoCheckPlayers");
#endif
}

public GoCheckPlayers()
{
    get_players(players, pnum, "ah");
    for(new i; i < pnum; i++)
    {
        g_iWarning[players] = 0;
        get_entvar(players, var_origin, g_fOldOrigin[players]);
        get_entvar(players, var_angles, g_fOldAngles[players]);
    }

    if(!task_exists(87892789))
        set_task(TIME_AFK_CHECK, "AfkCheck", 87892789, .flags = "b");
    else    change_task(87892789, TIME_AFK_CHECK);
}

public AfkCheck(id)
{
    if(id == 87892789)
        get_players(players, pnum, "ah");
    else if(!is_user_connected(id))
        return;
    else players[0] = id, pnum = 1;

    for(new i, Float:fNewOrigin[3], Float:fNewAngles[3], szName[32]; i < pnum; i++)
    {
        get_entvar(players, var_origin, fNewOrigin);
        get_entvar(players, var_angles, fNewAngles);
        
        if(!xs_vec_equal(g_fOldOrigin[players], fNewOrigin) || !xs_vec_equal(g_fOldAngles[players], fNewAngles))
        {
            g_iWarning[players] = 0;
            xs_vec_copy(fNewOrigin, g_fOldOrigin[players]);
            xs_vec_copy(fNewAngles, g_fOldAngles[players]);
            continue;
        }
        
        get_entvar(players, var_netname, szName, charsmax(szName));
        if(++g_iWarning[players] >= MAX_AFK_WARNING)
        {
            user_kill(players, 1);
            engclient_cmd(players, "jointeam", "6");
            client_cmd(players, "spk events/friend_died");
            ChatColor(0, players, "^1[^4AFKControl^1] ^4Игрок ^3%s ^4был перемещен в зрители, так как был ^3AFK", szName);
        #if defined NOROUND
            set_bit(g_bitSpec, players);
            remove_task(players);
        #endif
        }
        else
        {
            client_cmd(players, "spk events/tutor_msg");
            ChatColor(players, 0, "^1[^4AFKControl^1] ^4Вы не проявляете активность! Предупреждения: ^3%i/%i", g_iWarning[players], MAX_AFK_WARNING);
        }
#if !defined NOROUND
        if(get_entvar(players, var_weapons) & (1 << CSW_C4))
        {
            ChatColor(0, players, "^1[^4AFKControl^1] ^4У игрока ^3%s ^4отобрана бомба, так как находится ^3AFK", szName);
        #if defined BOMB_TRANSFER
            rg_transfer_c4(players, 0);
        #else
            engclient_cmd(players, "drop", "weapon_c4");
        #endif
        }
#endif   
    }   
}

public SpectatorCheck()
{
    if(get_playersnum() < MIN_PLAYERS_CHECK)
        return;

    new players[32], pnum;
    get_players(players, pnum, "h");
    for(new i, szName[32]; i < pnum; i++)
    {
        if(!get_bit(g_bitValid, players))
            continue;
        
        switch(get_member(players, m_iTeam))
        {
            case 0, 3:
            {
                if(++g_count[players] >= MAX_SPECT_CHECK_PL)
                {
                    get_entvar(players, var_netname, szName, charsmax(szName));
                    ChatColor(0, players, "^1[^4AFKControl^1] ^4Игрок^3 %s ^4удален за длительное нахождение в спектрах.", szName);
                    server_cmd("kick #%d Вы были кикнуты из-за длительного нахождения в зрителях.", get_user_userid(players));
                }
            }   
        }   
    }
}

stock bool:xs_vec_equal(const Float:vec1[], const Float:vec2[])
    return (vec1[0] == vec2[0]) && (vec1[1] == vec2[1]) && (vec1[2] == vec2[2]);

stock xs_vec_copy(const Float:vecIn[], Float:vecOut[])
{
    vecOut[0] = vecIn[0];
    vecOut[1] = vecIn[1];
    vecOut[2] = vecIn[2];
}

stock ChatColor(id, id2, const szMessage[], any:...)
{
    if(id && !is_user_connected(id))
        return;
        
    new szMsg[190]; vformat(szMsg, charsmax(szMsg), szMessage, 4);
    
    message_begin(id ? MSG_ONE : MSG_ALL, 76, .player = id);
    write_byte(id2 ? id2 : id);
    write_string(szMsg);
    message_end();
}
Сверху