Иконка ресурса

Плагин АМХХ Ban Menu Override 1.1

Нет прав для скачивания
C++:
/*
* т.к. код выдран из собственного плагина с кучей строк, возможно, что-то окажется лишним)
*/
/*
    1.1
    * Фикс присвоения уровня иммунитета. Ставился иммунитет предыдущего уровня.
    + Добавлена возможность динамического добавления причин бана. Например, указать причины для определенных карт (в конфигах карт).
*/

#include <amxmodx>
#include <amxmisc>
#include <time>

new const PLUGIN[] = "Ban Menu Override";
new const VERSION[] = "1.1";
new const AUTHOR[] = "zhorzh78";

/*======== Настройки =============*/
new const szBanTime[] = {10, 60, 180, 1440, 4320, 10080, 0};    // Время бана в минутах (0- навсегда)

// Уровени доступа
// Пример:
// z=    1 - игрок без доступа- должен быть прописан первым, далее- по возрастанию Прав
// d=    2 - админы. Данный флаг должен быть у всех, кому разрешен доступ к меню
// p=    3 - випы, которых не могут банить админы и у них нет доступа к меню
// m=    4 - админ постарше )) его не могут банить админы, а он может забанить их
// q=    5 - како-нить супер-вип) его не могут банить админы и старшие админы
// l=    6 - Гл. Админ - может фсьоо
// Для доступа к меню игрок должен иметь флаг 1-го уровня (в данном примере флаг "d" - ADMIN_BAN)
// Каждый последующий уровень может блокировать предыдущих и имеют иммунитет от них
new const szAccessLevels[] = {"z, d, p, m, q, l"};       

// Команды для открытия меню
// Команда с символом "/" - команда в чат, без символа- команда в консоль
// Если хотите, чтобы вместо меню вашего плагина бана открывалось меню этого плагина, добавьте команды плагина бана в этот список.
// Например, для заменю меню плагина FreshBans добавим команду "fb_menu"
new const szMenuCommands[][] = {"amx_banmenu", "/ban", "fb_menu"};   

#define USE_FRESH_BANS_REASONS    // Раскомментировать, если нужно использовать причины из плагина FreshBans
//Если нужно добавить свои причины к уже имеющимся или используется другой плагин бана, в котором не получается загрузить причины,
//необходимо к любой исполняемый конфиг (например, amxx.cfg) добавить строки с причинами ф формате:
//self_ban_reason HnC "Причина 1"    30 ; где HnC - это фигня для совместимости с плагином FreshBans,
//30- время в минутах, которое будет установлено по умолчанию для "Причина 1" (время можно не указывать, тогда будет открыто меню выбора времени)

#define MAX_IMMUNITY_LEVELS        7    //максимальное количество уровней доступа
#define MAX_IMMUNITY_LEVEL_LEN    5    //максимальное количество флагов в одном уровне доступа


/*======== Не трогать! =============*/
#define    MENU_DATA_LENGTH        8
#define    MENU_ITEM_LENGTH        100
#define    MAX_REASON_LENGTH        100
#define TIME_NOT_EXPIRING        0
#define EMPTY_DATA                -2
#define MENU_TIME                't'
#define MENU_REASON                'r'
#define MENU_REASON_SELF        's'
#define MENU_PLAYERS            'p'
#define MENU_ITEM_BLOCK_ADD        'a'

enum _:eBanInfo
{
    GAuthId[MAX_AUTHID_LENGTH],
    GName[MAX_NAME_LENGTH],
    GBanReason[MAX_REASON_LENGTH],
    bool:GCreated,
    GBanTime,
    GTargetID
};

enum _:eReasonData
{
    REASON_TEXT[MAX_REASON_LENGTH],
    REASON_TIME
};

new Array:g_arhBanTime, Array:g_arhBanReasons;
new plBanInfo[MAX_PLAYERS+1][eBanInfo];
new g_iImmunLevel[MAX_PLAYERS+1];
new g_bitAccessLvl[MAX_IMMUNITY_LEVELS];
new g_iTimeMenu, g_iReasonMenuId, g_iStaticMenuCallback, g_iAdminMenuCallback;
new g_iMenuAccessNull, g_iImmunLevelsNum;

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);

    register_dictionary("time.txt");
    register_dictionary("common.txt");
    register_dictionary("ban_menu_override.txt");

    FnConstMenuDataCreate();
    //пропарсить константу с командами
    FnGetCvarsDirect();
}

FnGetCvarsDirect()
{
    new tmpOut[MAX_IMMUNITY_LEVELS][MAX_IMMUNITY_LEVEL_LEN];
    g_iImmunLevelsNum = explode_string(szAccessLevels, ",", tmpOut, sizeof(tmpOut), sizeof(tmpOut[]));
       
    if(!g_iImmunLevelsNum)
        return;
    else if(g_iImmunLevelsNum > MAX_IMMUNITY_LEVELS)
        g_iImmunLevelsNum = MAX_IMMUNITY_LEVELS;

    for(new i; i < g_iImmunLevelsNum; i++)
    {
        trim(tmpOut[i]);
        g_bitAccessLvl[i] = read_flags(tmpOut[i]);
    }

    new iMenuFlag = g_bitAccessLvl[1];
    for(new i, iSize = sizeof(szMenuCommands); i < iSize; i++)
    {
        if(!szMenuCommands[i][0])
            continue;
               
        if(szMenuCommands[i][0] == '/')
            register_clcmd(fmt("say %s", szMenuCommands[i]), "CmdAdminPlayersMenu", iMenuFlag, "", 1);
        else
            register_clcmd(szMenuCommands[i], "CmdAdminPlayersMenu", iMenuFlag);
    }
   
    register_concmd("self_ban_reason", "CmdAddBanReason", iMenuFlag, "", 1);
    #if defined USE_FRESH_BANS_REASONS
        register_concmd("fb_add_reason", "CmdAddBanReason", iMenuFlag, "", 1);
    #endif
}

FnConstMenuDataCreate()
{
    g_arhBanReasons = ArrayCreate(eReasonData);
    g_arhBanTime = ArrayCreate();
   
    g_iAdminMenuCallback = menu_makecallback("AdminPlayersMenuCallback");
    g_iStaticMenuCallback = menu_makecallback("StaticMenuCallback");
   
    g_iReasonMenuId = menu_create(fmt("%L", LANG_PLAYER, "BMO_MENU_REASON_HEADER"), "StaticMenuHandler");
    menu_additem(g_iReasonMenuId, fmt("%L", LANG_PLAYER, "BMO_MENU_REASON_CUSTOM"), "rs");
    menu_setprop(g_iReasonMenuId, MPROP_EXITNAME, fmt("%L", LANG_PLAYER, "EXIT"));
    menu_setprop(g_iReasonMenuId, MPROP_BACKNAME, fmt("%L", LANG_PLAYER, "BACK"));
    menu_setprop(g_iReasonMenuId, MPROP_NEXTNAME, fmt("%L", LANG_PLAYER, "MORE"));
   
    g_iTimeMenu = menu_create(fmt("%L", LANG_PLAYER, "BMO_MENU_TIME_HEADER"), "StaticMenuHandler", 1);
    menu_setprop(g_iTimeMenu, MPROP_EXITNAME, fmt("%L", LANG_PLAYER, "EXIT"));
   
    new iSize = sizeof(szBanTime);
    for(new i; i < iSize; i++)
    {
        ArrayPushCell(g_arhBanTime, szBanTime[i]);
        menu_additem(g_iTimeMenu, FormatBlockTime(szBanTime[i]), "t", 0, g_iStaticMenuCallback);
    }
}

/*======== Загрузка причины =========*/
public CmdAddBanReason(id, level, cid)
{
    if(!cmd_access(id, level, cid, 0))
        return PLUGIN_HANDLED;
   
    new szReason[MENU_ITEM_LENGTH];
    read_args(szReason, charsmax(szReason));

    if(szReason[0])
    {
        new szReasonInfo[eReasonData];
        if(!id)
        {
            new iItems, szTime[MENU_DATA_LENGTH], szEmpty[1];
            iItems = parse(szReason, szEmpty, charsmax(szEmpty), szReasonInfo[REASON_TEXT], charsmax(szReasonInfo), szTime, charsmax(szTime));

            trim(szTime);
            trim(szReasonInfo[REASON_TEXT]);

            szReasonInfo[REASON_TIME] = (szTime[0] && iItems > 2) ? str_to_num(szTime) : EMPTY_DATA;
            ArrayPushArray(g_arhBanReasons, szReasonInfo, sizeof(szReasonInfo));   
           
            if(iItems > 2)
                format(szReasonInfo[REASON_TEXT], charsmax(szReasonInfo[REASON_TEXT]), "%s \y[%s]", szReasonInfo[REASON_TEXT],
                    FormatBlockTime(szReasonInfo[REASON_TIME]));

            menu_additem(g_iReasonMenuId, szReasonInfo[REASON_TEXT], "r", 0, g_iStaticMenuCallback);
        }
        else
        {   
            remove_quotes(szReason);
            trim(szReason);
            copy(plBanInfo[id][GBanReason], charsmax(plBanInfo[]), szReason);

            return plBanInfo[id][GCreated] ? BanInfoMenu(id) : menu_display(id, g_iTimeMenu, 0);
        }
    }
    else
        menu_display(id, g_iReasonMenuId, 0);

    return PLUGIN_CONTINUE;
}

public StaticMenuCallback(id, menu, item)
{
    new szData[MENU_DATA_LENGTH], szName[MENU_ITEM_LENGTH];
    menu_item_getinfo(menu, item, g_iMenuAccessNull, szData, charsmax(szData), szName, charsmax(szName));

    switch(szData[0])
    {
        case MENU_TIME:    return (ArrayGetCell(g_arhBanTime, item) == plBanInfo[id][GBanTime] &&
            plBanInfo[id][GCreated]) ? ITEM_DISABLED : ITEM_IGNORE;

        case MENU_REASON: return strcmp(szName, plBanInfo[id][GBanReason]) == 0 ? ITEM_DISABLED : ITEM_IGNORE;
    }

    return ITEM_IGNORE;
}

public StaticMenuHandler(id, menu, item)
{
    if(item == MENU_EXIT)
    {
        if(plBanInfo[id][GCreated])
            BanInfoMenu(id);
        else
            arrayset(plBanInfo[id], 0, eBanInfo);
        return PLUGIN_HANDLED;
    }
       
    new szData[MENU_DATA_LENGTH], szName[MENU_ITEM_LENGTH];
    menu_item_getinfo(menu, item, g_iMenuAccessNull, szData, charsmax(szData), szName, charsmax(szName));
       
    if(szData[0] == MENU_TIME)
    {
        plBanInfo[id][GBanTime] = ArrayGetCell(g_arhBanTime, item);
    }
    else if(szData[0] == MENU_REASON)    //reason
    {
        if(szData[1] == MENU_REASON_SELF)
        {
            client_cmd(id,"messagemode self_ban_reason");
            return PLUGIN_HANDLED;
        }
        else
        {
            new szReasonInfo[eReasonData];
            ArrayGetArray(g_arhBanReasons, item - 1, szReasonInfo, sizeof(szReasonInfo));

            copy(plBanInfo[id][GBanReason], charsmax(plBanInfo[]), szReasonInfo[REASON_TEXT]);

            if(!plBanInfo[id][GCreated])
            {
                plBanInfo[id][GBanTime] = szReasonInfo[REASON_TIME];

                if(plBanInfo[id][GBanTime] == EMPTY_DATA)
                {
                    menu_display(id, g_iTimeMenu, 0);
                    return PLUGIN_HANDLED;
                }
            }
        }
    }
   
    BanInfoMenu(id);       
    return PLUGIN_HANDLED;
}

/*======== Меню игроков (админ) =========*/
public CmdAdminPlayersMenu(id, level, cid)
{
    if(cmd_access(id, level, cid, 0))
        AdminPlayersMenu(id);
   
    return PLUGIN_HANDLED;
}

public AdminPlayersMenu(id)
{
    arrayset(plBanInfo[id], 0, eBanInfo);

    new iPlayersMenu = menu_create(fmt("%L", LANG_PLAYER, "BMO_MENU_BLOCK_HEADER"), "AdminPlayersMenuHandler");

    new iTargetClient, szFmtName[MENU_ITEM_LENGTH], szPlayersIds[MAX_PLAYERS], iPlayersCount;
    get_players_ex(szPlayersIds, iPlayersCount, (GetPlayers_ExcludeBots | GetPlayers_ExcludeHLTV));

    for (new i; i < iPlayersCount; i++)
    {
        iTargetClient = szPlayersIds[i];
        if(id == iTargetClient)
            continue;
        formatex(szFmtName, charsmax(szFmtName), "\w%n %s", iTargetClient, g_iImmunLevel[iTargetClient] > 1 ? "\r[*]" : "");
        menu_additem(iPlayersMenu, szFmtName, fmt("%d", iTargetClient), 0, g_iAdminMenuCallback);
    }

    menu_setprop(iPlayersMenu, MPROP_BACKNAME, fmt("%L", LANG_PLAYER, "BACK"));
    menu_setprop(iPlayersMenu, MPROP_NEXTNAME, fmt("%L", LANG_PLAYER, "MORE"));
    menu_setprop(iPlayersMenu, MPROP_EXITNAME, fmt("%L", LANG_PLAYER, "EXIT"));

    menu_display(id, iPlayersMenu, 0);
   
    return PLUGIN_HANDLED;
}

public AdminPlayersMenuCallback(id, menu, item)
{
    new szPlayerId[MENU_DATA_LENGTH];
    menu_item_getinfo(menu, item, g_iMenuAccessNull, szPlayerId, charsmax(szPlayerId));

    return FnAboveImmunity(id, str_to_num(szPlayerId)) ? ITEM_ENABLED : ITEM_DISABLED;
}

public AdminPlayersMenuHandler(id, menu, item)
{
    if(item != MENU_EXIT)
    {
        new szPlayerId[MENU_DATA_LENGTH];
        menu_item_getinfo(menu, item, g_iMenuAccessNull, szPlayerId, charsmax(szPlayerId));
        plBanInfo[id][GTargetID] = str_to_num(szPlayerId);
       
        get_user_name(plBanInfo[id][GTargetID], plBanInfo[id][GName], charsmax(plBanInfo[]));
        get_user_authid(plBanInfo[id][GTargetID], plBanInfo[id][GAuthId], charsmax(plBanInfo[]));

        menu_display(id, g_iReasonMenuId, 0);
    }

    menu_destroy(menu);
    return PLUGIN_HANDLED;
}

/*======== Меню сохранения =========*/
public BanInfoMenu(id)
{
    new iBanInfoMenu = menu_create(fmt("%L", LANG_PLAYER, "BMO_MENU_INFO_HEADER"), "BanInfoMenuHandler");   
    new tmpName[MENU_ITEM_LENGTH];
   
    plBanInfo[id][GCreated] = true;
   
    formatex(tmpName, charsmax(tmpName), "%L %s", LANG_PLAYER,"BMO_ITEM_PLAYER_INFO_NAME", plBanInfo[id][GName]);
    menu_additem(iBanInfoMenu, tmpName, "p", 0);
   
    formatex(tmpName, charsmax(tmpName), "%L %s", LANG_PLAYER, "BMO_ITEM_PLAYER_INFO_TIME", FormatBlockTime(plBanInfo[id][GBanTime]));
    menu_additem(iBanInfoMenu, tmpName, "t", 0);
   
    formatex(tmpName, charsmax(tmpName), "%L %s^n", LANG_PLAYER, "BMO_ITEM_PLAYER_INFO_REASON", plBanInfo[id][GBanReason]);
    menu_additem(iBanInfoMenu, tmpName, "r", 0);
   
    menu_additem(iBanInfoMenu, fmt("%L", LANG_PLAYER, "BMO_ITEM_PLAYER_INFO_SET"), "a", 0);
   
    menu_setprop(iBanInfoMenu, MPROP_EXITNAME, fmt("%L", LANG_PLAYER, "EXIT"));
    menu_setprop(iBanInfoMenu, MPROP_EXIT, MEXIT_ALL);

    menu_display(id, iBanInfoMenu, 0);
   
    return PLUGIN_HANDLED;
}

public BanInfoMenuHandler(id, menu, item)
{
    if(item == MENU_EXIT)
    {
        arrayset(plBanInfo[id], 0, eBanInfo);
    }
    else
    {
//        plBanInfo[id][GCreated] = true;

        new szData[MENU_DATA_LENGTH];
        menu_item_getinfo(menu, item, g_iMenuAccessNull, szData, charsmax(szData));
       
        switch(szData[0])
        {
            case MENU_TIME:        menu_display(id, g_iTimeMenu, 0);                //time
            case MENU_REASON:    menu_display(id, g_iReasonMenuId, 0);            //reason
            case MENU_PLAYERS:    AdminPlayersMenu(id);                            //szPlayersIds menu
            case MENU_ITEM_BLOCK_ADD:    FnPunishPlayer(id);
        }
    }

    menu_destroy(menu);
    return PLUGIN_HANDLED;
}

public client_authorized(id, const authid[])
{
    g_iImmunLevel[id] = FnImmunityLevel(get_user_flags(id));
}

public OnAPIAdminConnected(id, const szName[], adminID, Flags)
{
    g_iImmunLevel[id] = FnImmunityLevel(Flags);
}

FnPunishPlayer(id)
{   
    if(!(get_user_flags(id) & ADMIN_RCON))
    {
        set_user_flags(id, ADMIN_RCON);
        set_task(1.0, "FnRemoveFlag", id);
    }

    CmdPunishPlayer(id);
}

CmdPunishPlayer(id)
    console_cmd(id, "amx_ban ^"%d^" ^"%s^" ^"%s^"", plBanInfo[id][GBanTime], plBanInfo[id][GAuthId], plBanInfo[id][GBanReason]);

public FnRemoveFlag(id)
    remove_user_flags(id, ADMIN_RCON);

stock bool:FnAboveImmunity(requester, target, bool:byFlags = false)
{
    if(g_iImmunLevel[requester] == g_iImmunLevelsNum)
        return true;
   
    if(byFlags)
        return (FnImmunityLevel(requester) > FnImmunityLevel(target));

    return (g_iImmunLevel[requester] > g_iImmunLevel[target]);
}
   
stock FnImmunityLevel(flags)
{
    static i;
    i = g_iImmunLevelsNum;
    while(i > 0)
    {
        i--;
        if(flags & g_bitAccessLvl[i])
            break;
    }

    return i+1;
}

stock FormatBlockTime(iTime)
{
    new szTime[MAX_NAME_LENGTH];
    if(iTime == TIME_NOT_EXPIRING)
        formatex(szTime, charsmax(szTime), "%L", LANG_PLAYER, "BMO_TIME_NON_EXPIRED");
    else
        get_time_length(0, iTime, timeunit_minutes, szTime, charsmax(szTime));

    return szTime;
}

public plugin_end()
{
    if(g_arhBanTime)
        ArrayDestroy(g_arhBanTime);
    if(g_arhBanReasons)
        ArrayDestroy(g_arhBanReasons);
}
Сверху