/*
* т.к. код выдран из собственного плагина с кучей строк, возможно, что-то окажется лишним)
*/
/*
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);
}