Плагин - "Punishment disabled screen" // Rus: "Наказание отключенный экран"
Если какой-то игрок плохо себя ведет или какая-то другая причина, игроку можно отключить экран, таким образом он не сможет нормально играть.
Функционал и возможности начальной версии (остальное в разделе 'Журнал изменений'):
1. Через команду в консоли можно наказать игрока отключив ему экран.
2. Отключенный экран сохранится за игроком даже если он выйдет с сервера (попытается перезайти)
3. При вводе команды в консоли есть ряд защитных проверок, на введенные некорректные значения и тп.
4. Если при попытке наказать или освободить игрока, его не будет на сервере, то в ответ на команду будет соответствующее оповещение.
5. Если при попытке наказать игрока, его не будет на сервере, его AuthID сохранится. (т.е даже если он зайдет позже, то будет наказанный)
6. Если при попытке освободить игрока, его не будет на сервере, его AuthID удалится из сохраненных. (т.е даже если он зайдет позже, то будет освобожден)
7. В случае того, если при попытке наказать игрока, он будет на сервере, и он будет живой, то ему сразу будет предоставлено наказание, а также оповещение.
8. В случае того, если при попытке освободить игрока, он будет на сервере, и он будет живой, то сразу же будет применено освобождение, а также оповещение.
9. Если при попытке наказать игрока, он будет на сервере, и он будет мертвый, то ему будет оповещение, а наказание будет действовать с следующего спавна.
10. Если при попытке освободить игрока, он будет на сервере, и он будет мертвый, то ему будет оповещение, а освобождение будет действовать с следующего спавна.
11. При вводе команды, очень много оповещений касательно наказания/освобождения. (за каждым событием как бы следует результат)
12. Мультиязычность всех оповещений (HUD + console)
13. Если на игроке уже действует наказание/освобождение, то повторная команда на этого игрока не будет реализована. (защита)
14. Сделано 2 режима для установки цвета экрана, задается дефайном COLOR_MODE.
15. Если вы поставили значение режима цвета 1, то будет рандом цвет (мин и макс значения для рандом вычисления задается в конст VALUE_RANDOM)
16. Если вы поставили значение режима цвета 2, то необходимо в дефайн вписать RGB цвет. (по стандарту идет черный)
17. Выполнение команды на наказание и освобождение разрешено только по флагу доступа.
18. Если игроку назначено наказание, то после смерти и спавна оно ему будет возвращено. (т.е не исчезнет отключенный экран)
20. При вводе команды на authid, если игрока не будет на сервере, то он всеравно сохраняется/удаляется. (какой бы вы не ввели, необходимо использовать с осторожностью)
!!! Важная информация !!!
С обновления 1.4.0 плагину требуется наличие файла причин (.ini) по пути: 'addons\amxmodx\configs\'
Без этого файла плагин работать не будет, а также если в файле не будет ни одной причины.
1. Обнаружен баг, когда использовав флешку (ослепляющую гранату) отключенный экран сбрасывался у игрока, исправлено, thx: jumper
2. Убрана поддержка hamsandwich (в пользу reapi)
1. Добавлено логирование наказаний/освобождений (дата, время, кого, от кого; спасибо: present)
2. Включить или отключить логирование можно дефайном.
3. Изменен код, с учетом нового обновления.
1. Теперь можно назвать файл лога в конст. (не учтено из предыдущего обновления)
2. Изменен код, с учетом нового обновления.
1. Разработана система добавления наказаний на время.
а) К основной команде добавился 3 аргумент - время.
б) Если время не будет введено, то будет оповещение об этом.
в) Если Вы введете вместо время, буквы и тп, то будет оповещение.
г) Вводить можно только целочисленные значения в минутах.
д) Если Вы введете "0" - то такое расценивается что наказание будет навсегда.
е) Наказанному игроку будет оповещение (если включен режим
ж) После истечения времени, AuthID удаляется из сохраненных при новом спавне. (с оповещением что освобожден)
з) Каждый спавн время сверяется между временной отметкой nvailt 'timestamp' и системным временем (get_systime)
к) Теперь в логировании (если включен
л) Если у игрока остается чуть меньше 2 минут до освобождения, то в оповещение он будет видеть секунды до конца.
2. Разработана система причин наказаний.
а) К основной команде добавился 4 аргумент - номер причины.
б) Причины Вы вписываете сами в конст массив в исходнике сколько душе угодно..
в) Создана инструкция как что делать.
г) Сделана специальная команда на просмотр в консоли причин из конст массива с их номерами.
д) Что-бы активировать причину, нужно просто вписать допустимый номер из списка причин.
е) Что-бы активировать наказание без причины, нужно вписать "0".
ж) Если Вы введете вместо причины: буквы || номер больше размера массива || вообще не введете ничего, будет оповещение.
з) В случае успеха игрок будет наказан с этой причиной (в логах это укажется).
к) Игроку будет оповещение с указание причины при выдаче наказания, или если его не будет на сервере, то при следующем заходе. (+кжд спавн)
л) Что-бы посмотреть причины самому с помощью команды в консоли, достаточно ввести команду и через пробел любое значение.
3. Созданы две новые константы массивы, для наименований консольных команд.
4. Переделаны многие оповещения связанные с новыми обновлениями. (добавлены новые аргументы)
5. Дополнен и изменен LANG файл.
1. Реализована выдача наказаний/освобождений через меню.
а) Добавлен конст массив на команды для открытия меню (в plugin_init).
б) В главном меню необходимо выбрать что делать: Наказать или освободить.
в) После выбора нужного пункта, откроется следующее меню, с выбором игрока.
г) В случае выбора пункта наказать, будет еще 2 меню, с выбором времени и причины наказания.
д) В случае выбора пункта освобождения, нужно только нажать на игрока.
е) При пункте наказать, в меню времени, необходимо нажать на пункт, и вписать значение посредством messagemode
ж) При пункте наказать, меню причин формируется основываясь на конст массиве REASONS_PUNISHMENT, необходимо только нажать на пункт.
з) Реализована защита от того, если игрок уже наказан/освобожден. (при нажатии не будет выполнено действие и будет оповещение)
к) Если наказание/освобождение прошло успешно, то также будет оповещение.
л) Наказание/освобождение работает через консольные команды, подставляются значения, выбранные в меню.
м) После наказания/освобождения через меню, происходит все то же самое, как и через консольные команды (пишутся логи и инфа в консоли)
2. Сохранение AuthID игрока сделано в событие client_putinserver, дабы не узнавать каждый раз при спавне и тп. (спасибо: CSBishop)
3. Добавлена возможность очищать nVault записи, которые старше указанного значения (в днях) в define. (спасибо: CSBishop)
4. Переделаны многие оповещения связанные с новыми обновлениями. (добавлены новые аргументы)
5. Дополнен и изменен LANG файл.
6. Сделан define на выставления общего флага доступа к командам меню и консольным командам наказания/освобождения.
1. Вместо многих настроек плагина в define, сделаны квары.
2. Добавлен эффект заморозки игрока (настройка кваром)
3. Вместо const массива с причинами, сделан конфигурационный файл (.ini), причины теперь указываются там. (без файла плагин работать не будет)
4. Удалены лишние проверки по коду, вместо них проверятся по bool CheckPlayer (признак наказан/освобожден)
5. Добавлен define на авто-создание конфига + небольшая инструкция, что делать если описание к кварам получились не на нужном языке.
6. Сделаны новые функции обработчики, с учетом новых обновлений.
7. Добавлен макрос мультиязычности для описаний кваров и крит.ошибок работы плагина. (set_fail_state)
9. Был найден баг, когда через меню освобождался игрок, то освобождение не задействовалось. (исправлено)
1. Убраны set_task_ex на выполнение функций, вместо этого сделано быстрое чтение cfg в plugin_init (до вызова функций);
1. Исправлен хардкодный способ использования (написания) пути до папки configs.
Если откомментировано, то конфиг создается автоматически.
Если при запуске сервера описание к кварам не на нужном Вам языке:
1. Проверяем квар amx_language.
2. Удаляем конфиг по пути: 'amxmodx\configs\plugins\pd_screen' и меняем карту.
Флаг доступа к главному меню и консольным командам наказаний/освобождений.
После запуска сервера (смены карты), можно отредактировать флаг доступа в файле по пути: "amxmodx\configs\cmdaccess.ini"
Редактирование флагов доступа в файле cmdaccess.ini применимо только к консольным командам.
new const PLUGIN[] = "pd_screen";
new const VERSION[] = "1.4.2";
new const AUTHOR[] = "wellasgood";
new const CMD_PD_SCREEN[] = "pd_screen"; //наименование для главной команды наказаний/освобождений + выбора время и причины.
new const CMD_PD_SCREEN_REASONS[] = "pd_screen_reasons"; //наименование для команды просмотра причин.
new const LOG_DIR[] = "logs/pd_screen";
new const LOG_FILE_NAME[] = "pd_screen-log";
new const REASON_FILE_NAME[] = "pd_screen_reasons.ini"; //Наименование файла конфигурации причин, если меняете название, менять и название самого файла.
new eCvarData[CVAR_DATA], LogPath[MAX_RESOURCE_PATH_LENGTH * 2], Vault, bool:CheckPlayer[MAX_PLAYERS+1], Color[3];
new PlayerAuthID[MAX_PLAYERS+1][MAX_AUTHID_LENGTH], PlayersSaveID[MAX_PLAYERS+1], PlayerSaveTime[MAX_PLAYERS+1];
new Array:ReasonsPunishment, ReasonArraySize;
register_plugin(PLUGIN, VERSION, AUTHOR);
register_dictionary("pd_screen.txt");
Команды на вход в меню наказаний/освобождений. (можно менять/добавлять соблюдая структуру)
Если Вы укажите здесь консольную команду на открытие меню, то вводя команду в игре подставьте рядом любое значение.
Если будете указывать здесь консольные команды, то они не должны быть такими же как и (CMD_PD_SCREEN|CMD_PD_SCREEN_REASONS)
new const CMD_MENU_OPEN[][] =
for(new i; i < sizeof CMD_MENU_OPEN; i++)
register_clcmd(CMD_MENU_OPEN[i], "@Open_PD_Menu_Main", PD_SCREEN_ACCESS, "Usage console: command all value | Usage chat: command");
register_clcmd(CMD_PD_SCREEN, "@cmd_pd_screen", PD_SCREEN_ACCESS, "Usage: command AuthID 0/1 time reasons_number");
register_clcmd(CMD_PD_SCREEN_REASONS, "@cmd_pd_screen_reasons", PD_SCREEN_ACCESS, "Usage: command all value");
RegisterHookChain(RG_CBasePlayer_Spawn, "@EventSpawn", true);
RegisterHookChain(RG_PlayerBlind, "@PlayerBlind", false);
register_concmd("TimeValue", "@TimeValueHandler");
Vault = nvault_open("pd_screen");
if(Vault == INVALID_HANDLE)
set_fail_state(MULTI_DESC("PD_NVAULT_OPEN_FILE_ERROR"));
ReasonsPunishment = ArrayCreate(191);
AutoExecConfig(true, "pd_screen");
new Path[MAX_RESOURCE_PATH_LENGTH];
get_localinfo("amxx_configsdir", Path, charsmax(Path));
server_cmd("exec %s/pd_screen.cfg", Path); //Обновляем информацию кваров из cfg побыстрее.
server_exec(); //заставляем сервер немедленно выполнить очередь команд.
ParseReasons(Path, charsmax(Path));
NvaultCleaning(); //Чистка nVault записей.
PreparingForLogging(); //Подготовка к логированию.
ColorChaching(); //Кеширование цвета.
if(eCvarData[USE_NVAULT_CLEANING])
//thx: DJ_WEST (https://amx-x.ru/viewtopic.php?p=12940)
nvault_prune(Vault, 0, get_systime() - (86400 * eCvarData[NVAULT_CLEANING_RECORDS]));
get_localinfo("amxx_basedir", LogPath, charsmax(LogPath));
new Len = formatex(LogPath, charsmax(LogPath), "%s/%s", LogPath, LOG_DIR);
get_time("%d_%m_%y", Date, charsmax(Date));
formatex(LogPath[Len], charsmax(LogPath) - Len, "/%s_%s.txt", LOG_FILE_NAME, Date);
if(!eCvarData[COLOR_CACHING])
public client_putinserver(id)
if(is_user_bot(id) || is_user_hltv(id))
arrayset(PlayerAuthID[id], 0, charsmax(PlayerAuthID[]));
get_user_authid(id, PlayerAuthID[id], charsmax(PlayerAuthID[]));
new timestamp, AccessResult = nvault_lookup(Vault, PlayerAuthID[id], Data, charsmax(Data), timestamp);
@cmd_pd_screen_reasons(id, level, cid)
if(!cmd_access(id, level, cid, 2))
console_print(id, "=====================================");
console_print(id, "^n%L^n", id, "PD_SCREEN_REASONS_NAME");
console_print(id, "^n%L^n", id, "PD_SCREEN_ERROR_REASONS_NUM2", (ReasonArraySize - 1));
console_print(id, "=====================================");
@cmd_pd_screen(id, level, cid)
if(!cmd_access(id, level, cid, 2))
new DataAuthID[MAX_AUTHID_LENGTH], DataValue[6], DataTime[32], DataReasons[32];
read_argv(1, DataAuthID, charsmax(DataAuthID));
read_argv(2, DataValue, charsmax(DataValue));
read_argv(3, DataTime, charsmax(DataTime));
read_argv(4, DataReasons, charsmax(DataReasons));
if(is_str_num(DataAuthID))
console_print(id, "%L", id, "PD_SCREEN_ERROR_DATA_AUTHID");
console_print(id, "%L", id, "PD_SCREEN_ERROR_DATAVALUE");
if(!is_str_num(DataValue))
console_print(id, "%L", id, "PD_SCREEN_ERROR_VALUE_NUM1");
if(str_to_num(DataValue) >= 2)
console_print(id, "%L", id, "PD_SCREEN_ERROR_VALUE_NUM2");
if(str_to_num(DataValue) == 1)
console_print(id, "%L %L", id, "PD_SCREEN_ERROR_TIME", id, "PD_SCREEN_MINUTES");
if(!is_str_num(DataTime))
console_print(id, "%L", id, "PD_SCREEN_ERROR_TIME_NUM");
client_cmd(id, fmt("%s view", CMD_PD_SCREEN_REASONS));
console_print(id, "%L", id, "PD_SCREEN_ERROR_REASONS");
if(!is_str_num(DataReasons))
client_cmd(id, fmt("%s view", CMD_PD_SCREEN_REASONS));
console_print(id, "%L", id, "PD_SCREEN_ERROR_REASONS_NUM1");
if(str_to_num(DataReasons) > (ReasonArraySize - 1))
client_cmd(id, fmt("%s view", CMD_PD_SCREEN_REASONS));
new PlayersID[MAX_PLAYERS], PlayersCount;
get_players_ex(PlayersID, PlayersCount, GetPlayers_ExcludeHLTV|GetPlayers_ExcludeBots);
for(new i; i < PlayersCount; i++)
if(equal(PlayerAuthID[PlayersID[i]], DataAuthID))
SavePlayerID = PlayersID[i];
switch(str_to_num(DataValue))
console_print(id, "%L", id, "PD_SCREEN_ERROR_PLAYER_NOT_FOUND");
if(CheckPlayer[SavePlayerID])
if(is_user_alive(SavePlayerID))
PunishHandler(SavePlayerID);
console_print(id, "%L", id, "PD_SCREEN_PLAYER_UNLOCKED");
console_print(id, "%L", id, "PD_SCREEN_ERROR_ALIVE_PLAYER1");
CheckPlayer[SavePlayerID] = false;
if(eCvarData[USE_HUD_MESSAGE])
HudMessage(SavePlayerID);
log_to_file(LogPath, "%L", LANG_SERVER, "PD_SCREEN_LOG_UNPUNISHED1", SavePlayerID, id);
console_print(id, "%L", id, "PD_SCREEN_ERROR_RE_UNLOCKING");
new Data[MAX_AUTHID_LENGTH];
new timestamp, AccessResult = nvault_lookup(Vault, DataAuthID, Data, charsmax(Data), timestamp);
console_print(id, "%L", id, "PD_SCREEN_ERROR_SEARCH_AUTHID");
nvault_remove(Vault, DataAuthID);
console_print(id, "%L", id, "PD_SCREEN_SEARCH_AUTHID_NO");
log_to_file(LogPath, "%L", LANG_SERVER, "PD_SCREEN_LOG_UNPUNISHED2", DataAuthID, id);
new Time = str_to_num(DataTime);
new ReasonNum = str_to_num(DataReasons);
ArrayGetString(ReasonsPunishment, ReasonNum, Buffer, charsmax(Buffer));
console_print(id, "%L", id, "PD_SCREEN_ERROR_PLAYER_NOT_FOUND");
if(!CheckPlayer[SavePlayerID])
console_print(id, "%L %L (%L) | %L", id, "PD_SCREEN_PLAYER_PUNISHED_TIME", Time, id, "PD_SCREEN_MINUTES", id, "PD_SCREEN_PUNISHED_FOREVER", id, "PD_SCREEN_REASON", Buffer);
console_print(id, "%L %L | %L", id, "PD_SCREEN_PLAYER_PUNISHED_TIME", Time, id, "PD_SCREEN_MINUTES", id, "PD_SCREEN_REASON", Buffer);
if(is_user_alive(SavePlayerID))
PunishHandler(SavePlayerID);
console_print(id, "%L", id, "PD_SCREEN_ERROR_ALIVE_PLAYER2");
CheckPlayer[SavePlayerID] = true;
if(eCvarData[USE_HUD_MESSAGE])
HudMessage(SavePlayerID, Time, 0, ReasonNum, Time == 0 ? 1 : 2);
log_to_file(LogPath, "%L %L (%L) | %L", LANG_SERVER, "PD_SCREEN_LOG_PUNISHED1", SavePlayerID, id, Time, LANG_SERVER, "PD_SCREEN_MINUTES", LANG_SERVER, "PD_SCREEN_PUNISHED_FOREVER", LANG_SERVER, "PD_SCREEN_REASON", Buffer);
log_to_file(LogPath, "%L %L | %L", LANG_SERVER, "PD_SCREEN_LOG_PUNISHED1", SavePlayerID, id, Time, LANG_SERVER, "PD_SCREEN_MINUTES", LANG_SERVER, "PD_SCREEN_REASON", Buffer);
console_print(id, "%L", id, "PD_SCREEN_ERROR_RE_LOCKING");
new timestamp, AccessResult = nvault_lookup(Vault, DataAuthID, Data, charsmax(Data), timestamp);
nvault_set(Vault, DataAuthID, fmt("%d %d", Time, ReasonNum));
console_print(id, "%L", id, "PD_SCREEN_SAVE_NVAULT_AUTHID");
log_to_file(LogPath, "%L %L (%L) | %L", LANG_SERVER, "PD_SCREEN_LOG_PUNISHED2", DataAuthID, id, Time, LANG_SERVER, "PD_SCREEN_MINUTES", LANG_SERVER, "PD_SCREEN_PUNISHED_FOREVER", LANG_SERVER, "PD_SCREEN_REASON", Buffer);
log_to_file(LogPath, "%L %L | %L", LANG_SERVER, "PD_SCREEN_LOG_PUNISHED2", DataAuthID, id, Time, LANG_SERVER, "PD_SCREEN_MINUTES", LANG_SERVER, "PD_SCREEN_REASON", Buffer);
console_print(id, "%L", id, "PD_SCREEN_SEARCH_AUTHID_YES");
@Open_PD_Menu_Main(id, level, cid)
if(!cmd_access(id, level, cid, 2))
if(!is_user_connected(id))
new TempString[MAX_MENU_LENGTH];
formatex(TempString, charsmax(TempString), "%L", id, "PD_MENU_MAIN_TITLE");
new Menu = menu_create(TempString, "@Handle_PD_Menu_Main");
formatex(TempString, charsmax(TempString), "%L", id, "PD_MENU_MAIN_ITEM1");
menu_additem(Menu, TempString, "1");
formatex(TempString, charsmax(TempString), "%L", id, "PD_MENU_MAIN_ITEM2");
menu_additem(Menu, TempString, "2");
FormingItemMenu(id, Menu, TempString, charsmax(TempString), 2);
@Handle_PD_Menu_Main(id, Menu, Item)
menu_item_getinfo(Menu, Item, _, Info, charsmax(Info));
str_to_num(Info) == 1 ? @PD_Menu_punish(id) : @PD_Menu_unpunish(id);
if(!is_user_connected(id))
new TempString[MAX_MENU_LENGTH];
formatex(TempString, charsmax(TempString), "%L", id, "PD_MENU_UNPUNISH_TITLE");
new Menu = menu_create(TempString, "@Handle_PD_Menu_unpunish");
FormingItemMenu(id, Menu, TempString, charsmax(TempString), 1);
FormingItemMenu(id, Menu, TempString, charsmax(TempString), 2);
@Handle_PD_Menu_unpunish(id, Menu, Item)
menu_item_getinfo(Menu, Item, _, Info, charsmax(Info));
new PlayerID = str_to_num(Info);
set_dhudmessage(random_num(100, 255), random_num(100, 255), random_num(100, 255), -1.0, -0.55, 1, 1.5, 3.0, 2.0, 3.0);
show_dhudmessage(id, "%l", CheckPlayer[PlayerID] ? "PD_MENU_HUD_INFO_UNPUNISH1" : "PD_MENU_HUD_INFO_UNPUNISH2", PlayerID);
if(!CheckPlayer[PlayerID])
client_cmd(id, fmt("%s %s 0", CMD_PD_SCREEN, PlayerAuthID[PlayerID]));
set_task_ex(0.3, "@PD_Menu_unpunish", id); //небольшая задержка, так как не успевает обновиться bool CheckPlayer
if(!is_user_connected(id))
new TempString[MAX_MENU_LENGTH];
formatex(TempString, charsmax(TempString), "%L", id, "PD_MENU_PUNISH_TITLE");
new Menu = menu_create(TempString, "@Handle_PD_Menu_punish");
FormingItemMenu(id, Menu, TempString, charsmax(TempString), 1);
FormingItemMenu(id, Menu, TempString, charsmax(TempString), 2);
@Handle_PD_Menu_punish(id, Menu, Item)
menu_item_getinfo(Menu, Item, _, Info, charsmax(Info));
PlayersSaveID[id] = str_to_num(Info);
if(CheckPlayer[PlayersSaveID[id]])
set_dhudmessage(random_num(100, 255), random_num(100, 255), random_num(100, 255), -1.0, -0.45, 1, 1.5, 3.0, 0.9, 1.0);
show_dhudmessage(id, "%l", "PD_MENU_HUD_INFO_PUNISH2", PlayersSaveID[id]);
if(!is_user_connected(id))
new TempString[MAX_MENU_LENGTH];
formatex(TempString, charsmax(TempString), "%L", id, "PD_MENU_TIME_TITLE");
new Menu = menu_create(TempString, "@Handle_PD_Menu_Time");
formatex(TempString, charsmax(TempString), "%L \у[\r%d\y]", id, "PD_MENU_TIME_ITEM1", PlayerSaveTime[id]);
menu_additem(Menu, TempString);
formatex(TempString, charsmax(TempString), "%L", id, "PD_MENU_TIME_ITEM2");
menu_additem(Menu, TempString);
FormingItemMenu(id, Menu, TempString, charsmax(TempString), 2);
@Handle_PD_Menu_Time(id, Menu, Item)
client_cmd(id, "messagemode ^"TimeValue^"");
read_argv(1, String, charsmax(String));
PlayerSaveTime[id] = str_to_num(String);
if(!is_user_connected(id))
new TempString[MAX_MENU_LENGTH];
formatex(TempString, charsmax(TempString), "%L", id, "PD_MENU_REASON_TITLE");
new Menu = menu_create(TempString, "@Handle_PD_Menu_Reasons");
ReasonsHandler(1, 0, Menu);
FormingItemMenu(id, Menu, TempString, charsmax(TempString), 2);
@Handle_PD_Menu_Reasons(id, Menu, Item)
menu_item_getinfo(Menu, Item, _, Info, charsmax(Info));
new ReasonNum = str_to_num(Info);
client_cmd(id, fmt("%s %s 1 %d %d", CMD_PD_SCREEN, PlayerAuthID[PlayersSaveID[id]], PlayerSaveTime[id], ReasonNum));
ArrayGetString(ReasonsPunishment, ReasonNum, Buffer, charsmax(Buffer));
set_dhudmessage(random_num(100, 255), random_num(100, 255), random_num(100, 255), -1.0, -0.45, 1, 1.5, 3.0, 0.9, 1.0);
show_dhudmessage(id, "%l %l %l", "PD_MENU_HUD_INFO_PUNISH1", PlayersSaveID[id], PlayerSaveTime[id], "PD_SCREEN_MINUTES", "PD_SCREEN_REASON", Buffer);
set_task_ex(0.3, "@PD_Menu_punish", id); //небольшая задержка, так как не успевает обновиться bool CheckPlayer
if(!is_user_alive(id) || !CheckPlayer[id])
new timestamp, AccessResult = nvault_lookup(Vault, PlayerAuthID[id], Data, charsmax(Data), timestamp);
new Time = ReasonsAndTimeHandler(Data, 1);
if(((timestamp + (Time * 60)) < get_systime()) && Time != 0)
nvault_remove(Vault, PlayerAuthID[id]);
if(eCvarData[USE_HUD_MESSAGE])
if(eCvarData[USE_HUD_MESSAGE])
HudMessage(id, Time, timestamp, ReasonsAndTimeHandler(Data, 2), Time == 0 ? 1 : 2);
@PlayerBlind(const index, const inflictor, const Float:fadeTime, const Float:fadeHold, const alpha, Float:color[3])
return CheckPlayer[index] ? HC_SUPERCEDE : HC_CONTINUE;
HudMessage(id, time = 0, timestamp = 0, reason = 0, check = 0)
set_dhudmessage(random_num(100, 255), random_num(100, 255), random_num(100, 255), -1.0, -0.55, 1, 1.5, 3.0, 2.0, 3.0);
show_dhudmessage(id, "%l", "PD_SCREEN_HUD_MESSAGE_PUNISHED_FOREVER", id);
new time_format = timestamp > 1 ? ((((timestamp / 60) + time) - (get_systime() / 60)) < 2 ? (timestamp + (time * 60)) - get_systime() : (((timestamp / 60) + time) - (get_systime() / 60))) : time;
show_dhudmessage(id, "%l %l", "PD_SCREEN_HUD_MESSAGE_PUNISHED", id, time_format, timestamp > 1 ? ((((timestamp / 60) + time) - (get_systime() / 60)) < 2 ? "PD_SCREEN_SECOND" : "PD_SCREEN_MINUTES") : "PD_SCREEN_MINUTES");
ArrayGetString(ReasonsPunishment, reason, Buffer, charsmax(Buffer));
set_dhudmessage(random_num(100, 255), random_num(100, 255), random_num(100, 255), -1.0, -0.52, 1, 1.5, 3.0, 2.0, 3.0);
show_dhudmessage(id, "%l", "PD_SCREEN_REASON", Buffer);
show_dhudmessage(id, "%l", "PD_SCREEN_HUD_MESSAGE_UNPUNISHED", id);
FormingItemMenu(id, Menu, TempString[], len, check)
new PlayersID[MAX_PLAYERS], PlayersCount;
get_players_ex(PlayersID, PlayersCount, GetPlayers_ExcludeHLTV|GetPlayers_ExcludeBots);
for(new i; i < PlayersCount; i++)
new player_name[MAX_NAME_LENGTH];
get_user_name(PlayersID[i], player_name, charsmax(player_name));
if(CheckPlayer[PlayersID[i]])
formatex(TempString, len, "%s \y[\r%L\y]", player_name, id, "PD_MENU_PUNISH");
menu_additem(Menu, !CheckPlayer[PlayersID[i]] ? player_name : TempString, fmt("%d", PlayersID[i]));
formatex(TempString, len, "%L", id, "PD_MENU_BACK");
menu_setprop(Menu, MPROP_BACKNAME, TempString);
formatex(TempString, len, "%L", id, "PD_MENU_NEXT");
menu_setprop(Menu, MPROP_NEXTNAME, TempString);
formatex(TempString, len, "%L", id, "PD_MENU_EXIT");
menu_setprop(Menu, MPROP_EXITNAME, TempString);
ReasonsHandler(value, id = 0, menu = 0)
for(new i; i < ReasonArraySize; i++)
ArrayGetString(ReasonsPunishment, i, Buffer, charsmax(Buffer));
menu_additem(menu, Buffer, fmt("%d", i));
console_print(id, "[%d] - %s", i, Buffer);
msg_screenfade = get_user_msgid("ScreenFade");
message_begin(MSG_ONE, msg_screenfade, _, id);
write_short(!CheckPlayer[id] ? 4 : 1);
if(eCvarData[COLOR_CACHING])
if(eCvarData[USE_PLAYER_FROZEN])
set_entvar(id, var_flags, !CheckPlayer[id] ? get_entvar(id, var_flags) | FL_FROZEN : get_entvar(id, var_flags) & ~FL_FROZEN);
CheckPlayer[id] = !CheckPlayer[id];
ReasonsAndTimeHandler(value[], check)
parse(value, Num[0], charsmax(Num[]), Num[1], charsmax(Num[]));
return check == 1 ? str_to_num(Num[0]) : str_to_num(Num[1]);
if(eCvarData[COLOR_MODE] == 2)
parse(eCvarData[COLOR_VALUE], ColorValue[0], charsmax(ColorValue[]), ColorValue[1], charsmax(ColorValue[]), ColorValue[2], charsmax(ColorValue[]));
Color[0] = str_to_num(ColorValue[0]);
Color[1] = str_to_num(ColorValue[1]);
Color[2] = str_to_num(ColorValue[2]);
parse(eCvarData[COLOR_VALUE], ColorValue[0], charsmax(ColorValue[]), ColorValue[1], charsmax(ColorValue[]), ColorValue[2], charsmax(ColorValue[]), ColorValue[3], charsmax(ColorValue[]), ColorValue[4], charsmax(ColorValue[]), ColorValue[5], charsmax(ColorValue[]));
Color[0] = random_num(str_to_num(ColorValue[0]), str_to_num(ColorValue[1]));
Color[1] = random_num(str_to_num(ColorValue[2]), str_to_num(ColorValue[3]));
Color[2] = random_num(str_to_num(ColorValue[4]), str_to_num(ColorValue[5]));
ParseReasons(Path[], len)
formatex(Path, len, "%s/%s", Path, REASON_FILE_NAME);
set_fail_state(fmt("%s %s", MULTI_DESC("PD_REASON_FILE_ERROR_OPEN"), Path));
new ReasonData[191], f = fopen(Path, "rt");
fgets(f, ReasonData, charsmax(ReasonData));
log_amx("%s", ReasonData);
if(!ReasonData[0] || ReasonData[0] == ';')
ArrayPushString(ReasonsPunishment, ReasonData);
ReasonArraySize = ArraySize(ReasonsPunishment);
set_fail_state(fmt("%s %s", MULTI_DESC("PD_REASON_FILE_ERROR_SIZE"), Path));
bind_pcvar_num(create_cvar(
.name = "pd_use_nvault_cleaning",
.description = MULTI_DESC("PD_DESC_USE_NVAULT_CLEANING"),
eCvarData[USE_NVAULT_CLEANING]
bind_pcvar_num(create_cvar(
.name = "pd_nvault_cleaning_records",
.description = MULTI_DESC("PD_DESC_NVAULT_CLEANING_RECORDS")),
eCvarData[NVAULT_CLEANING_RECORDS]
bind_pcvar_num(create_cvar(
.name = "pd_use_hud_message",
.description = MULTI_DESC("PD_DESC_USE_HUD_MESSAGE"),
eCvarData[USE_HUD_MESSAGE]
bind_pcvar_num(create_cvar(
.description = MULTI_DESC("PD_DESC_USE_LOG"),
bind_pcvar_num(create_cvar(
.description = MULTI_DESC("PD_DESC_COLOR_MODE"),
bind_pcvar_num(create_cvar(
.name = "pd_color_caching",
.description = MULTI_DESC("PD_DESC_COLOR_CACHING"),
bind_pcvar_string(create_cvar(
.name = "pd_color_value",
.string = "0 255 100 200 50 255",
.description = MULTI_DESC("PD_DESC_COLOR_VALUE")),
charsmax(eCvarData[COLOR_VALUE])
bind_pcvar_num(create_cvar(
.name = "pd_use_player_frozen",
.description = MULTI_DESC("PD_DESC_USE_PLAYER_FROZEN"),
eCvarData[USE_PLAYER_FROZEN]