GS-Client: Uid Ban System

GS-Client: Uid Ban System 1.0.8

Нет прав для скачивания
Автор
wellasgood
Требования
Установленный Модуль AuthEmu на сервере.
Внимание!
Плагин будет действовать только на GS-client игроков!
Публикация на сторонних ресурсах запрещена без согласования с автором!

Описание: Плагин работает по такому принципу: если на сервере злоумышленник (плохой игрок), и нужно его не пускать на сервер совсем, то выбираем нужного игрока через меню, далее узнается UID (уникальный идентификатор компьютера злоумышленника) с помощью модуля authemu. Происходит бан по этому идентификатору, он сохраняется. При последующем заходе на сервер такого игрока, его не будет пускать, так как плагин сверяет все хранимые идентификаторы, с идентификатором того кто заходит на сервер.
The Plugin works on this principle: if there is an attacker on the server (a bad player), and you need to not let him on the server at all, then select the desired player through the menu, then the UID (unique identifier of the attacker's computer) is recognized using the authemu module. There is a ban on this ID, it is saved. When you next visit the server of such a player, it will not be allowed, since the plugin checks all stored IDs with the ID of the one who comes to the server.

Все версии: Установленный Модуль AuthEmu на сервере.
Поддержка Sql: Наличие базы данных MySQL для подключения.
Поддержка nVault: Использование редакотора nVault.NET для редактирования файла UID кодов.
Amx Mod X 1.9.0, Amx Mod X 1.10.0 dev
RU, EN
Blacksword18 (помощь в реализации)
Adidasman (за модуль AuthEmu)
voed (подсказки по коду)
gyxoBka (за мануал работы со sql данными)
fantom
CrazyHackGUT
Плагин делится на 3 разных исходных кода, каждый поддерживает 1 тип хранения данных UID кодов игроков. Вам нужно выбрать любой какой хотите, по Вашим знаниям (опыту, удобству).

GS-Client Uid Ban System (txt support) - UID коды хранятся в .txt файле.
Легкое редактирование (удаление, внесение данных в ручную, например через текстовой блокнот или notepad++).
GS-Client Uid Ban System (sql support) - UID коды хранятся в MySql Data Base
Преимущественно в принципе, а также, при больших данных хранимых в бд (быстро, удобно, надежно). Еще явный жирный плюс, если у Вас больше 1 сервера, можно на всех серверах указать одинаковые данные подключения, тогда на всех серверах где установлен плагин, не будет пускать всех игроков с теми UID кодами которые хранятся в этой бд. (делать сетку серверов)
GS-Client Uid Ban System (nvault support)
Много споров на просторе интернета по поводу что лучше sql или nvault. Все же у всех свои различия и преимущества. nVault - это AMXX инструмент, предназначенный для простого хранения и извлечения данных из файла. Как действует: создается файл формата .vault, в него заносятся данные, а также ищутся для сравнения результата. Удобно редактировать через специальный редактор nVault.NET
Команды
/ubm - (использование в чате, открытие меню бана игроков)
gsc_uid_unban - (для консоли, разбан игроков, использование: command uid)
Дополнительная информация
C++:
#include <amxmodx>
#include <amxmisc>
#include <authemu>

#define AUTO_CONFIG //Авто-создание конфига.

new const PLUGIN[] = "GS-Client: Uid Ban System";
new const VERSION[] = "1.0.8";
new const AUTHOR[] = "wellasgood";

new const Folder[] = "addons/UID-Bans"; //Основная папка плагина (хранение Access файла и логов)
new const AccessFile[] = "UID-Bans.txt"; //Файл хранения информации о UID забаненных.
new const LoggingFolder[] = "UID-Bans_Logs"; //Название папки для хранения логов.

enum //Избавляемся от магический цифр (непонятных) по коду.
{
    NAME_LENGHT = 64,
    DATA_LENGHT = 11,
    INFO_LENGHT = 3,
    DATE_LENGHT = 16
};

enum _:CvarData
{
    Float:TIME_CHECK,
    Float:TIME_KICK_ONE,
    Float:TIME_KICK_TWO
};

new eCvarData[CvarData];

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);
    register_dictionary("gsc_uid_ban_system.txt");

    register_clcmd("say /ubm", "OpenUidBansMenu", ADMIN_RCON, "Access the Uid Ban System Menu");

    RegCvars();

    #if defined AUTO_CONFIG
    AutoExecConfig(true, "gsc_uid_ban_system");
    #endif
}
/*-----------------------------*/
RegCvars()
{
    bind_pcvar_float(create_cvar(
        .name = "gsc_time_check",
        .string = "3.0",
        .description = "Time to check the player after it is connected.", //Время до проверки игрока после его подключения.
        .has_min = false,
        .min_val = 0.0,
        .has_max = false,
        .max_val = 0.0),
        eCvarData[TIME_CHECK]
    );

    bind_pcvar_float(create_cvar(
        .name = "gsc_time_kick_one",
        .string = "1.0",
        .description = "Time to kick the player after performing the check.", //Время до кика игрока после выполнения проверки.
        .has_min = false,
        .min_val = 0.0,
        .has_max = false,
        .max_val = 0.0),
        eCvarData[TIME_KICK_ONE]
    );

    bind_pcvar_float(create_cvar(
        .name = "gsc_time_kick_two",
        .string = "1.0",
        .description = "Time to kick the player after selecting in the menu.", //Время до кика игрока после выбора в меню.
        .has_min = false,
        .min_val = 0.0,
        .has_max = false,
        .max_val = 0.0),
        eCvarData[TIME_KICK_TWO]
    );
}
/*-----------------------------*/
public plugin_cfg()
{
    if(!dir_exists(Folder)){
        mkdir(Folder);
    }

    if(!file_exists(fmt("%s/%s", Folder, AccessFile))){
        new File = fopen(fmt("%s/%s", Folder, AccessFile), "at");
        fclose(File);
    }

    if(!dir_exists(fmt("%s/%s", Folder, LoggingFolder))){
        mkdir(fmt("%s/%s", Folder, LoggingFolder));
    }

    new LogDate[DATE_LENGHT];
    get_time("%d_%m_%y", LogDate, charsmax(LogDate));

    if(!file_exists(fmt("%s/%s/uid_bans-log_%s.txt", Folder, LoggingFolder, LogDate))){
        new LogFile = fopen(fmt("%s/%s/uid_bans-log_%s.txt", Folder, LoggingFolder, LogDate), "at");
        fclose(LogFile);
    }
}
/*-----------------------------*/
public client_putinserver(Player)
{
    if(is_user_authemu(Player)){
        set_task_ex(eCvarData[TIME_CHECK], "CheckUidBan", Player);
    }
}
/*-----------------------------*/
public CheckUidBan(Player)
{
    new UIDHashOld[DATA_LENGHT], UIDHashNew[DATA_LENGHT], Data[DATA_LENGHT];

    aemu_get_clientinfo(Player, aci_unique_id, UIDHashNew, charsmax(UIDHashNew));

    new f = fopen(fmt("%s/%s", Folder, AccessFile), "rt");

    while(!feof(f)){
        fgets(f, Data, charsmax(Data));
        trim(Data);

        if(!Data[0]){
            continue;
        }

        parse(Data, UIDHashOld, charsmax(UIDHashOld));

        if(equal(UIDHashOld, UIDHashNew)){
            set_task_ex(eCvarData[TIME_KICK_ONE], "PlayerKick", Player);
        }
    }

    fclose(f);
}
/*-----------------------------*/
public OpenUidBansMenu(id, level, cid)
{
    if(!cmd_access(id, level, cid, 2, false)){
        return PLUGIN_HANDLED;
    }

    ShowUidBanMenu(id);
    return PLUGIN_HANDLED;
}
/*-----------------------------*/
ShowUidBanMenu(id)
{
    if(!is_user_connected(id)){
        return;
    }

    new UidBanPlayerMenu[NAME_LENGHT];
    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_TITLE");

    new Menu = menu_create(UidBanPlayerMenu, "Handle_ShowUidBanMenu");
    new Callback = menu_makecallback("Ignore_ShowUidBanMenu");

    new Name[MAX_NAME_LENGTH], Info[INFO_LENGHT], Players[MAX_PLAYERS], PlayersCount;

    get_players_ex(Players, PlayersCount, GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV);

    for(new Player, i; i < PlayersCount; i++){
        Player = Players[i];
        Info[0] = Player;

        get_user_name(Player, Name, charsmax(Name));
        menu_additem(Menu, Name, Info, .callback = Callback);
    }

    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_BACK");
    menu_setprop(Menu, MPROP_BACKNAME, UidBanPlayerMenu);

    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_NEXT");
    menu_setprop(Menu, MPROP_NEXTNAME, UidBanPlayerMenu);

    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_EXIT");
    menu_setprop(Menu, MPROP_EXITNAME, UidBanPlayerMenu);

    menu_display(id, Menu);
}
/*-----------------------------*/
public Handle_ShowUidBanMenu(id, Menu, Item)
{
    if(Item == MENU_EXIT){
        menu_destroy(Menu);
        return PLUGIN_HANDLED;
    }

    new Info[INFO_LENGHT], Buffer;

    menu_item_getinfo(Menu, Item, Buffer, Info, charsmax(Info), .callback = Buffer);
    menu_destroy(Menu);

    new Player = Info[0];

    WriteDataToFile(Player);

    ShowUidBanMenu(id);
    return PLUGIN_HANDLED;
}
/*-----------------------------*/
WriteDataToFile(Player)
{
    new Name[MAX_NAME_LENGTH], AuthID[MAX_AUTHID_LENGTH], Ip[MAX_IP_LENGTH+1];

    get_user_name(Player, Name, charsmax(Name));
    get_user_authid(Player, AuthID, charsmax(AuthID));
    get_user_ip(Player, Ip, charsmax(Ip), 1);

    new Data[DATA_LENGHT], UIDHash[DATA_LENGHT];

    aemu_get_clientinfo(Player, aci_unique_id, UIDHash, charsmax(UIDHash));

    formatex(Data, charsmax(Data), "%s", UIDHash);
    write_file(fmt("%s/%s", Folder, AccessFile), Data, -1);

    new LogDate[DATE_LENGHT];
    get_time("%d_%m_%y", LogDate, charsmax(LogDate));

    log_to_file(fmt("%s/%s/uid_bans-log_%s.txt", Folder, LoggingFolder, LogDate), "%L", LANG_SERVER, "UID_BAN_LOGS", Name, AuthID, Ip, UIDHash);

    set_task_ex(eCvarData[TIME_KICK_TWO], "PlayerKick", Player);
}
/*-----------------------------*/
public Ignore_ShowUidBanMenu(id, Menu, Item)
{
    new Info[INFO_LENGHT], Buffer;
    menu_item_getinfo(Menu, Item, Buffer, Info, charsmax(Info), .callback = Buffer);

    new Player = Info[0];

    if(!is_user_authemu(Player)){
        return ITEM_DISABLED;
    }

    if(Player == id){
        return ITEM_DISABLED;
    }

    return ITEM_IGNORE;
}
/*-----------------------------*/
public PlayerKick(Player)
{
    server_cmd("kick #%d %L", get_user_userid(Player), LANG_PLAYER, "UID_KICK_REASON");
}
/*-----------------------------*/
C++:
#include <amxmodx>
#include <amxmisc>
#include <sqlx>
#include <authemu>

#define ADMIN_ACCESS_FLAG ADMIN_BAN //Будет фигурировать в доступе для показа информации при коннекте игрока с пометкой о бане.
#define AUTO_CONFIG //Авто-создание конфига.

new const PLUGIN[] = "GS-Client: Uid Ban System";
new const VERSION[] = "1.0.8";
new const AUTHOR[] = "wellasgood";

new const Folder[] = "addons/UID-Bans"; //Основная папка плагина (хранение Access файла и логов)
new const LoggingFolder[] = "UID-Bans_Logs"; //Название папки для хранения логов.

enum //Избавляемся от магический цифр (непонятных) по коду.
{
    NAME_LENGHT = 64,
    STRING_LENGHT = 128,
    DATA_LENGHT = 11,
    INFO_LENGHT = 3,
    DATE_LENGHT = 16,
    QUERY_LENGHT = 1024
};

enum _:SqlCvarData
{
    SQL_HOST[64],
    SQL_USER[64],
    SQL_PASS[64],
    SQL_DB[64],
    SQL_TABLE_BANS[64],
    SQL_TABLE_SERVERS[64]
};

enum _:SqlType
{
    TYPE,
    ID,
    STATUS
};

enum //Типы для хендлера обработчика sql
{
    SQL_VOID,
    SQL_LOAD,
    SQL_INSERT,
    SQL_TIME,
    SQL_TYPE,
    SQL_STATUS,
    SQL_SERVER,
    SQL_SEARCH_UPDATE,
    SQL_SEARCH_MENU,
    SQL_ACTIVE,
    SQL_EXPIRED,
    SQL_REMOVE,
    SQL_UNBAN
};

enum _:RowIDs
{
    ROW_ID,
    ROW_NAME,
    ROW_STEAM,
    ROW_IP,
    ROW_UID,
    ROW_BAN_TIME_CREATED,
    ROW_BAN_TIME_LENGHT,
    ROW_TYPE,
    ROW_STATUS,
    ROW_SERVER,
    ROW_BANS_ACTIVE,
    ROW_BANS_EXPIRED,
    ROW_BANS_REMOVE
};

new const RowNames[RowIDs][] = //колонки должны быть как и в бд
{
    "id",
    "name",
    "steam",
    "ip",
    "uid",
    "ban_created",
    "ban_time",
    "ban_type",
    "ban_status",
    "server",
    "bans_active",
    "bans_expired",
    "bans_remove"
};

enum _:BansStatus
{
    STATUS_ACTIVE,
    STATUS_EXPIRED,
    STATUS_REMOVE
};

new const BansValue[BansStatus][] =
{
    "a",
    "b",
    "c"
};

enum _:BansHistoryData
{
    BANS_ACTIVE,
    BANS_EXPIRED,
    BANS_REMOVE
};

enum _:CvarData
{
    Float:TIME_CHECK,
    Float:TIME_KICK_ONE,
    Float:TIME_KICK_TWO,
    BAN_MESSAGE_HUD,
    BAN_MESSAGE_CHAT,
    ACCOUNT_EXPIRED_BANS,
    Float:TASK_TIME
};

new Handle:SQL_Tuple, eCvarData[CvarData], eSqlCvarData[SqlCvarData], GlobalPlayerID, CheckTypeBan[MAX_PLAYERS+1], GlobalBanType[MAX_PLAYERS+1];
new eBansHistoryData[BansHistoryData], bool:GlobalCheckSqlErr[MAX_PLAYERS+1], GlobalBanTime;

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);
    register_dictionary("gsc_uid_ban_system.txt");

    register_concmd("gsc_uid_unban", "RemoveBan", ADMIN_RCON, "Usage: command uid");
    register_clcmd("say /ubm", "OpenUidBansMenu", ADMIN_RCON, "Access the Uid Ban System Menu");

    RegCvars();

    #if defined AUTO_CONFIG
    AutoExecConfig(true, "gsc_uid_ban_system");
    #endif

    if(eCvarData[ACCOUNT_EXPIRED_BANS] || eCvarData[ACCOUNT_EXPIRED_BANS] == 2){
        set_task_ex(eCvarData[TASK_TIME], "ActivatedSearchTask", .flags = SetTask_Repeat); //Обновление истекших банов в бд через время.
    }
}
/*-----------------------------*/
RegCvars()
{
    bind_pcvar_float(create_cvar(
        .name = "gsc_time_check",
        .string = "3.0",
        .description = "Time to check the player after it is connected.", //Время до проверки игрока после его подключения.
        .has_min = false,
        .min_val = 0.0,
        .has_max = false,
        .max_val = 0.0),
        eCvarData[TIME_CHECK]
    );

    bind_pcvar_float(create_cvar(
        .name = "gsc_time_kick_one",
        .string = "1.0",
        .description = "Time to kick the player after performing the check.", //Время до кика игрока после выполнения проверки.
        .has_min = false,
        .min_val = 0.0,
        .has_max = false,
        .max_val = 0.0),
        eCvarData[TIME_KICK_ONE]
    );

    bind_pcvar_float(create_cvar(
        .name = "gsc_time_kick_two",
        .string = "1.0",
        .description = "Time to kick the player after selecting in the menu.", //Время до кика игрока после выбора в меню.
        .has_min = false,
        .min_val = 0.0,
        .has_max = false,
        .max_val = 0.0),
        eCvarData[TIME_KICK_TWO]
    );

    bind_pcvar_string(create_cvar(
        .name = "gsc_sql_host",
        .string = "127.0.0.1",
        .description = "Host where the database is located."), //Хост где расположена база данных.
        eSqlCvarData[SQL_HOST],
        charsmax(eSqlCvarData[SQL_HOST])
    );

    bind_pcvar_string(create_cvar(
        .name = "gsc_sql_user",
        .string = "user",
        .description = "Database User."), //Пользователь базы данных.
        eSqlCvarData[SQL_USER],
        charsmax(eSqlCvarData[SQL_USER])
    );

    bind_pcvar_string(create_cvar(
        .name = "gsc_sql_pass",
        .string = "12345",
        .description = "User password."), //Пароль пользователя.
        eSqlCvarData[SQL_PASS],
        charsmax(eSqlCvarData[SQL_PASS])
    );

    bind_pcvar_string(create_cvar(
        .name = "gsc_sql_db",
        .string = "gsc_uid_bans",
        .description = "Database name."), //Наименование базы данных.
        eSqlCvarData[SQL_DB],
        charsmax(eSqlCvarData[SQL_DB])
    );

    bind_pcvar_string(create_cvar(
        .name = "gsc_sql_table_bans",
        .string = "uid_bans",
        .description = "Name of the ban table. (as in the database)"), //Наименование таблицы банов. (как и в базе данных)
        eSqlCvarData[SQL_TABLE_BANS],
        charsmax(eSqlCvarData[SQL_TABLE_BANS])
    );

    bind_pcvar_string(create_cvar(
        .name = "gsc_sql_table_servers",
        .string = "uid_servers",
        .description = "Name of the server table. (as in the database)"), //Наименование таблицы серверов. (как и в базе данных)
        eSqlCvarData[SQL_TABLE_SERVERS],
        charsmax(eSqlCvarData[SQL_TABLE_SERVERS])
    );

    bind_pcvar_num(create_cvar(
        .name = "gsc_msg_ban_hud",
        .string = "1",
        .description = "Report about player’s bathhouse to HUD all? (off-0|on-1)", //Сообщить о бане игрока в ХУД всем
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[BAN_MESSAGE_HUD]
    );

    bind_pcvar_num(create_cvar(
        .name = "gsc_msg_ban_chat",
        .string = "1",
        .description = "Report about player’s bathhouse to CHAT all? (off-0|on-1)", //Сообщить о бане игрока в ЧАТ всем.
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[BAN_MESSAGE_CHAT]
    );

    bind_pcvar_num(create_cvar(
        .name = "gsc_account_expired_bans",
        .string = "2",
        .description = "Updating expired bans: 1. Starting a new card - 0; 2. Completing a task in time to the end of the card - 1; 3. All methods - 2;",
        //Обновление истекших банов разными методами (новая карта - 0, выполнение до конца карты через время - 1, все методы - 2)
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 2.0),
        eCvarData[ACCOUNT_EXPIRED_BANS]
    );

    bind_pcvar_float(create_cvar(
        .name = "gsc_task_time",
        .string = "300.0",
        .description = "The time between which the task of accounting for expired bans to the end of the card will be performed. (in seconds)",
        //Время между которым будет выполнена задача учета истекших банов до конца карты (в секундах).
        .has_min = false,
        .min_val = 0.0,
        .has_max = false,
        .max_val = 0.0),
        eCvarData[TASK_TIME]
    );
}
/*-----------------------------*/
public plugin_cfg()
{
    if(!dir_exists(Folder)){
        mkdir(Folder);
    }

    if(!dir_exists(fmt("%s/%s", Folder, LoggingFolder))){
        mkdir(fmt("%s/%s", Folder, LoggingFolder));
    }

    new LogDate[DATE_LENGHT];
    get_time("%d_%m_%y", LogDate, charsmax(LogDate));

    if(!file_exists(fmt("%s/%s/uid_bans-log_%s.txt", Folder, LoggingFolder, LogDate))){
        new LogFile = fopen(fmt("%s/%s/uid_bans-log_%s.txt", Folder, LoggingFolder, LogDate), "at");
        fclose(LogFile);
    }

    SQL_Tuple = SQL_MakeDbTuple(eSqlCvarData[SQL_HOST], eSqlCvarData[SQL_USER], eSqlCvarData[SQL_PASS], eSqlCvarData[SQL_DB]);

    CheckTableServers(); //Проверка на уже добавленный сервер (если нету то добавляем)

    if(!eCvarData[ACCOUNT_EXPIRED_BANS] || eCvarData[ACCOUNT_EXPIRED_BANS] == 2){
        SearchBans_Expired(); //Обновление истекших банов в бд при старте карты
    }
}
/*-----------------------------*/
public client_putinserver(Player)
{
    if(is_user_authemu(Player)){
        set_task_ex(eCvarData[TIME_CHECK], "CheckUidBanStatus", Player);
    }

    CheckTypeBan[Player] = 0;
}
/*-----------------------------*/
public RemoveBan(id, level, cid)
{
    if(!cmd_access(id, level, cid, 2)){
        return PLUGIN_HANDLED;
    }

    new UIDHash[DATA_LENGHT];
    read_argv(1, UIDHash, charsmax(UIDHash));

    new Query[QUERY_LENGHT];

    formatex(Query, charsmax(Query), "\
            SELECT `%s`\
            FROM `%s`\
            WHERE `%s` = '%s'",
            RowNames[ROW_UID],

            eSqlCvarData[SQL_TABLE_BANS],

            RowNames[ROW_UID],
            UIDHash
    );

    new SqlData[SqlType];

    SqlData[TYPE] = SQL_UNBAN;
    SqlData[ID] = id;

    SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", Query, SqlData, sizeof SqlData);

    return PLUGIN_HANDLED;
}
/*-----------------------------*/
public ActivatedSearchTask() //Обновление истекших банов в бд (Для задачи set_task функция обработчик public)
{
    SearchBans_Expired();
}
/*-----------------------------*/
SearchBans_ForHistoryMenu(Player)
{
    new Query[QUERY_LENGHT], HostName[MAX_NAME_LENGTH * 2], SqlData[SqlType];

    get_user_name(0, HostName, charsmax(HostName));

    formatex(Query, charsmax(Query), "\
            SELECT `%s`, `%s`, `%s`\
            FROM `%s`\
            WHERE `%s` = '%s'",
            RowNames[ROW_BANS_ACTIVE],
            RowNames[ROW_BANS_EXPIRED],
            RowNames[ROW_BANS_REMOVE],

            eSqlCvarData[SQL_TABLE_SERVERS],

            RowNames[ROW_SERVER],
            HostName
    );

    SqlData[TYPE] = SQL_SEARCH_MENU;
    SqlData[ID] = Player;

    SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", Query, SqlData, sizeof SqlData);
}
/*-----------------------------*/
SearchBans_Active()
{
    new Query[QUERY_LENGHT];

    new HostName[MAX_NAME_LENGTH * 2];
    get_user_name(0, HostName, charsmax(HostName));

    formatex(Query, charsmax(Query), "\
            SELECT COUNT(*)\
            FROM `%s`\
            WHERE `%s` = '%s'\
            AND `%s` = '%s';",
            eSqlCvarData[SQL_TABLE_BANS],

            RowNames[ROW_STATUS],
            BansValue[STATUS_ACTIVE],

            RowNames[ROW_SERVER],
            HostName
    );

    new SqlData[SqlType];

    SqlData[TYPE] = SQL_SEARCH_UPDATE;
    SqlData[STATUS] = SQL_ACTIVE;

    SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", Query, SqlData, sizeof SqlData);
}
/*-----------------------------*/
SearchBans_Expired()
{
    new Query[QUERY_LENGHT];

    new HostName[MAX_NAME_LENGTH * 2];
    get_user_name(0, HostName, charsmax(HostName));

    formatex(Query, charsmax(Query), "\
            SELECT COUNT(*)\
            FROM `%s`\
            WHERE `%s` = '%s'\
            AND `%s` = '%s';",
            eSqlCvarData[SQL_TABLE_BANS],

            RowNames[ROW_STATUS],
            BansValue[STATUS_EXPIRED],

            RowNames[ROW_SERVER],
            HostName
    );

    new SqlData[SqlType];

    SqlData[TYPE] = SQL_SEARCH_UPDATE;
    SqlData[STATUS] = SQL_EXPIRED;

    SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", Query, SqlData, sizeof SqlData);
}
/*-----------------------------*/
SearchBans_Remove()
{
    new Query[QUERY_LENGHT];

    new HostName[MAX_NAME_LENGTH * 2];
    get_user_name(0, HostName, charsmax(HostName));

    formatex(Query, charsmax(Query), "\
            SELECT COUNT(*)\
            FROM `%s`\
            WHERE `%s` = '%s'\
            AND `%s` = '%s';",
            eSqlCvarData[SQL_TABLE_BANS],

            RowNames[ROW_STATUS],
            BansValue[STATUS_REMOVE],

            RowNames[ROW_SERVER],
            HostName
    );

    new SqlData[SqlType];

    SqlData[TYPE] = SQL_SEARCH_UPDATE;
    SqlData[STATUS] = SQL_REMOVE;

    SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", Query, SqlData, sizeof SqlData);
}
/*-----------------------------*/
public CheckUidBanStatus(Player)
{
    new UIDHash[DATA_LENGHT], Query[QUERY_LENGHT];

    aemu_get_clientinfo(Player, aci_unique_id, UIDHash, charsmax(UIDHash));

    formatex(Query, charsmax(Query), "\
            SELECT `%s`, `%s`\
            FROM `%s`\
            WHERE `%s` = '%s'",
            RowNames[ROW_UID],
            RowNames[ROW_STATUS],

            eSqlCvarData[SQL_TABLE_BANS],

            RowNames[ROW_UID],
            UIDHash
    );

    new SqlData[SqlType];

    SqlData[TYPE] = SQL_STATUS;
    SqlData[ID] = Player;

    SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", Query, SqlData, sizeof SqlData);
}
/*-----------------------------*/
CheckUidBanType(Player)
{
    new UIDHash[DATA_LENGHT], Query[QUERY_LENGHT];

    aemu_get_clientinfo(Player, aci_unique_id, UIDHash, charsmax(UIDHash));

    formatex(Query, charsmax(Query), "\
            SELECT `%s`, `%s`\
            FROM `%s`\
            WHERE `%s` = '%s'",
            RowNames[ROW_UID],
            RowNames[ROW_TYPE],

            eSqlCvarData[SQL_TABLE_BANS],

            RowNames[ROW_UID],
            UIDHash
    );

    new SqlData[SqlType];

    SqlData[TYPE] = SQL_TYPE;
    SqlData[ID] = Player;

    SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", Query, SqlData, sizeof SqlData);
}
/*-----------------------------*/
CheckUidBan(Player)
{
    new UIDHash[DATA_LENGHT], Query[QUERY_LENGHT], AuthID[MAX_AUTHID_LENGTH], Ip[MAX_IP_LENGTH+1];

    aemu_get_clientinfo(Player, aci_unique_id, UIDHash, charsmax(UIDHash));
    get_user_authid(Player, AuthID, charsmax(AuthID));
    get_user_ip(Player, Ip, charsmax(Ip), 1);

    switch(GlobalBanType[Player])
    {
        case 0:
        {
            formatex(Query, charsmax(Query), "\
                    SELECT `%s`\
                    FROM `%s`\
                    WHERE `%s` = '%s'",
                    RowNames[ROW_UID],

                    eSqlCvarData[SQL_TABLE_BANS],

                    RowNames[ROW_UID],
                    UIDHash
            );
        }
        case 1:
        {
            formatex(Query, charsmax(Query), "\
                    SELECT `%s`, `%s`\
                    FROM `%s`\
                    WHERE `%s` = '%s'\
                    AND `%s` = '%s'\
                    OR `%s` = '%s'\
                    OR `%s` = '%s'",
                    RowNames[ROW_UID],
                    RowNames[ROW_STEAM],

                    eSqlCvarData[SQL_TABLE_BANS],

                    RowNames[ROW_STEAM],
                    AuthID,

                    RowNames[ROW_UID],
                    UIDHash,

                    RowNames[ROW_STEAM],
                    AuthID,

                    RowNames[ROW_UID],
                    UIDHash
            );
        }
        case 2:
        {
            formatex(Query, charsmax(Query), "\
                    SELECT `%s`, `%s`, `%s`\
                    FROM `%s`\
                    WHERE `%s` = '%s'\
                    AND `%s` = '%s'\
                    AND `%s` = '%s'\
                    OR `%s` = '%s'\
                    OR `%s` = '%s'\
                    OR `%s` = '%s'",
                    RowNames[ROW_UID],
                    RowNames[ROW_STEAM],
                    RowNames[ROW_IP],

                    eSqlCvarData[SQL_TABLE_BANS],

                    RowNames[ROW_STEAM],
                    AuthID,

                    RowNames[ROW_UID],
                    UIDHash,

                    RowNames[ROW_IP],
                    Ip,

                    RowNames[ROW_STEAM],
                    AuthID,

                    RowNames[ROW_UID],
                    UIDHash,

                    RowNames[ROW_IP],
                    Ip
            );
        }
    }

    new SqlData[SqlType];

    SqlData[TYPE] = SQL_LOAD;
    SqlData[ID] = Player;

    SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", Query, SqlData, sizeof SqlData);
}
/*-----------------------------*/
CheckUidBanTime(Player)
{
    new UIDHash[DATA_LENGHT], Query[QUERY_LENGHT];

    aemu_get_clientinfo(Player, aci_unique_id, UIDHash, charsmax(UIDHash));

    formatex(Query, charsmax(Query), "\
            SELECT `%s`, `%s`, `%s`\
            FROM `%s`\
            WHERE `%s` = '%s'\
            AND ((`%s` + `%s` * 60) < UNIX_TIMESTAMP(NOW())\
            OR `ban_time` = '0')",
            RowNames[ROW_UID],
            RowNames[ROW_BAN_TIME_CREATED],
            RowNames[ROW_BAN_TIME_LENGHT],

            eSqlCvarData[SQL_TABLE_BANS],

            RowNames[ROW_UID],
            UIDHash,

            RowNames[ROW_BAN_TIME_CREATED],
            RowNames[ROW_BAN_TIME_LENGHT]
    );

    new SqlData[SqlType];

    SqlData[TYPE] = SQL_TIME;
    SqlData[ID] = Player;

    SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", Query, SqlData, sizeof SqlData);
}
/*-----------------------------*/
public OpenUidBansMenu(id, level, cid)
{
    if(!cmd_access(id, level, cid, 2, false)){
        return PLUGIN_HANDLED;
    }

    ShowUidBanMenu(id);
    return PLUGIN_HANDLED;
}
/*-----------------------------*/
ShowUidBanMenu(id)
{
    if(!is_user_connected(id)){
        return;
    }

    new UidBanPlayerMenu[NAME_LENGHT];
    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_TITLE");

    new Menu = menu_create(UidBanPlayerMenu, "Handle_ShowUidBanMenu");
    new Callback = menu_makecallback("Ignore_ShowUidBanMenu");

    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L^n", id, "UID_BAN_MENU_ITEM_HISTORY");
    menu_additem(Menu, UidBanPlayerMenu, "1", 0);

    switch(CheckTypeBan[id])
    {
        case 0:
        {
            formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L: \r[\y%L\r]^n", id, "UID_BAN_MENU_ITEM_PREFIX", id, "UID_BAN_MENU_ITEM_UID");
        }
        case 1:
        {
            formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L: \r[\y%L\r]^n", id, "UID_BAN_MENU_ITEM_PREFIX", id, "UID_BAN_MENU_ITEM_UID-STEAM");
        }
        case 2:
        {
            formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L: \r[\y%L\r]^n", id, "UID_BAN_MENU_ITEM_PREFIX", id, "UID_BAN_MENU_ITEM_UID-STEAM-IP");
        }
    }

    menu_additem(Menu, UidBanPlayerMenu, "2", 0);

    new Name[MAX_NAME_LENGTH], Info[INFO_LENGHT], Players[MAX_PLAYERS], PlayersCount;

    get_players_ex(Players, PlayersCount, GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV);

    for(new Player, i; i < PlayersCount; i++){
        Player = Players[i];
        Info[0] = Player;

        get_user_name(Player, Name, charsmax(Name));
        menu_additem(Menu, Name, Info, .callback = Callback);
    }

    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_BACK");
    menu_setprop(Menu, MPROP_BACKNAME, UidBanPlayerMenu);

    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_NEXT");
    menu_setprop(Menu, MPROP_NEXTNAME, UidBanPlayerMenu);

    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_EXIT");
    menu_setprop(Menu, MPROP_EXITNAME, UidBanPlayerMenu);

    menu_display(id, Menu);
}
/*-----------------------------*/
public Handle_ShowUidBanMenu(id, Menu, Item)
{
    if(Item == MENU_EXIT){
        menu_destroy(Menu);
        CheckTypeBan[id] = 0;

        return PLUGIN_HANDLED;
    }

    new Info[INFO_LENGHT], Buffer;

    menu_item_getinfo(Menu, Item, Buffer, Info, charsmax(Info), .callback = Buffer);
    menu_destroy(Menu);

    if(str_to_num(Info) == 1){
        for(new i; i < sizeof eBansHistoryData; i++){
            eBansHistoryData[i] = 0;
        }

        ShowUidBanHistoryMenu(id);

        return PLUGIN_HANDLED;
    }

    if(str_to_num(Info) == 2){
        CheckTypeBan[id] = (CheckTypeBan[id] + 1) % 3;
        ShowUidBanMenu(id);

        return PLUGIN_HANDLED;
    }

    GlobalPlayerID = Info[0];

    ShowUidBanTimeMenu(id);

    return PLUGIN_HANDLED;
}
/*-----------------------------*/
ShowUidBanHistoryMenu(id)
{
    if(!is_user_connected(id)){
        return;
    }

    new UidBanHistoryMenu[NAME_LENGHT];
    formatex(UidBanHistoryMenu, charsmax(UidBanHistoryMenu), "%L", id, "UID_BAN_MENU_HISTORY_TITLE");

    new Menu = menu_create(UidBanHistoryMenu, "Handle_ShowUidBanHistoryMenu");

    formatex(UidBanHistoryMenu, charsmax(UidBanHistoryMenu), !GlobalCheckSqlErr[id] ? "%L^n" : "%L: \r[\y%L\r]^n", id, "UID_BAN_MENU_ITEM_HISTORY_ACTION", id, "UID_BAN_MENU_ITEM_HISTORY_ERROR");
    menu_additem(Menu, UidBanHistoryMenu, "1", 0);

    formatex(UidBanHistoryMenu, charsmax(UidBanHistoryMenu), (GlobalCheckSqlErr[id]) ? "\d%L^n" : "%L: \r[\y%d\r]^n", id, "UID_BAN_MENU_ITEM_HISTORY_ALL", eBansHistoryData[BANS_ACTIVE] + eBansHistoryData[BANS_EXPIRED] + eBansHistoryData[BANS_REMOVE]);
    menu_additem(Menu, UidBanHistoryMenu, "2", 0);

    formatex(UidBanHistoryMenu, charsmax(UidBanHistoryMenu), (GlobalCheckSqlErr[id]) ? "\d%L" : "%L: \r[\y%d\r]", id, "UID_BAN_MENU_ITEM_HISTORY_ACTIVE", eBansHistoryData[BANS_ACTIVE]);
    menu_additem(Menu, UidBanHistoryMenu, "3", 0);

    formatex(UidBanHistoryMenu, charsmax(UidBanHistoryMenu), (GlobalCheckSqlErr[id]) ? "\d%L" : "%L: \r[\y%d\r]", id, "UID_BAN_MENU_ITEM_HISTORY_EXPIRED", eBansHistoryData[BANS_EXPIRED]);
    menu_additem(Menu, UidBanHistoryMenu, "4", 0);

    formatex(UidBanHistoryMenu, charsmax(UidBanHistoryMenu), (GlobalCheckSqlErr[id]) ? "\d%L" : "%L: \r[\y%d\r]", id, "UID_BAN_MENU_ITEM_HISTORY_REMOVE", eBansHistoryData[BANS_REMOVE]);
    menu_additem(Menu, UidBanHistoryMenu, "5", 0);

    formatex(UidBanHistoryMenu, charsmax(UidBanHistoryMenu), "%L", id, "UID_BAN_MENU_BACK");
    menu_setprop(Menu, MPROP_EXITNAME, UidBanHistoryMenu);

    menu_display(id, Menu);
}
/*-----------------------------*/
public Handle_ShowUidBanHistoryMenu(id, Menu, Item)
{
    if(Item == MENU_EXIT){
        menu_destroy(Menu);
        ShowUidBanMenu(id);

        return PLUGIN_HANDLED;
    }

    new Info[INFO_LENGHT], Buffer;

    menu_item_getinfo(Menu, Item, Buffer, Info, charsmax(Info), .callback = Buffer);
    menu_destroy(Menu);

    if(str_to_num(Info) == 1){
        SearchBans_ForHistoryMenu(id);
    }

    ShowUidBanHistoryMenu(id);

    return PLUGIN_HANDLED;
}
/*-----------------------------*/
ShowUidBanTimeMenu(id)
{
    if(!is_user_connected(id)){
        return;
    }

    new UidBanTimePlayerMenu[NAME_LENGHT];
    formatex(UidBanTimePlayerMenu, charsmax(UidBanTimePlayerMenu), "%L", id, "UID_BAN_TIME_MENU_TITLE");

    new Menu = menu_create(UidBanTimePlayerMenu, "Handle_ShowUidBanTimeMenu");
    new Config[NAME_LENGHT], fp;

    formatex(Config, charsmax(Config), "%s/UID-times.ini", Folder);

    if(!file_exists(Config)){
        CreateDefaultStructFileTime();
    }

    fp = fopen(Config, "rt");

    new Buffer[190], array[3][64];

    while(!feof(fp)){
        fgets(fp, Buffer, charsmax(Buffer)); trim(Buffer);

        if(!Buffer[0] || Buffer[0] == ';'){
                continue;
        }

        if(parse(Buffer, array[0], charsmax(array[]), array[1], charsmax(array[])) == 2){
            menu_additem(Menu, array[0], array[1]);
        }
    }

    fclose(fp);

    formatex(UidBanTimePlayerMenu, charsmax(UidBanTimePlayerMenu), "%L", id, "UID_BAN_MENU_BACK");
    menu_setprop(Menu, MPROP_BACKNAME, UidBanTimePlayerMenu);

    formatex(UidBanTimePlayerMenu, charsmax(UidBanTimePlayerMenu), "%L", id, "UID_BAN_MENU_NEXT");
    menu_setprop(Menu, MPROP_NEXTNAME, UidBanTimePlayerMenu);

    formatex(UidBanTimePlayerMenu, charsmax(UidBanTimePlayerMenu), "%L", id, "UID_BAN_MENU_EXIT");
    menu_setprop(Menu, MPROP_EXITNAME, UidBanTimePlayerMenu);

    menu_display(id, Menu);
}
/*-----------------------------*/
public Handle_ShowUidBanTimeMenu(id, Menu, Item)
{
    if(Item == MENU_EXIT){
        menu_destroy(Menu);
        ShowUidBanMenu(id);

        return PLUGIN_HANDLED;
    }

    new Info[INFO_LENGHT * 3], Buffer;

    menu_item_getinfo(Menu, Item, Buffer, Info, charsmax(Info), .callback = Buffer);
    menu_destroy(Menu);

    new Player = GlobalPlayerID;
    new SysTime = get_systime();
    new CheckType = CheckTypeBan[id];
    GlobalBanTime = str_to_num(Info);

    GlobalPlayerID = 0;
    CheckTypeBan[id] = 0;

    WriteDataToDataBase(Player, SysTime, CheckType);

    return PLUGIN_HANDLED;
}
/*-----------------------------*/
WriteDataToDataBase(Player, SysTime, CheckType)
{
    new Name[MAX_NAME_LENGTH], AuthID[MAX_AUTHID_LENGTH], Ip[MAX_IP_LENGTH+1], HostName[MAX_NAME_LENGTH * 2];

    get_user_name(Player, Name, charsmax(Name));
    get_user_name(0, HostName, charsmax(HostName));
    get_user_authid(Player, AuthID, charsmax(AuthID));
    get_user_ip(Player, Ip, charsmax(Ip), 1);

    new UIDHash[DATA_LENGHT];

    aemu_get_clientinfo(Player, aci_unique_id, UIDHash, charsmax(UIDHash));

    new LogDate[DATE_LENGHT];

    get_time("%d_%m_%y", LogDate, charsmax(LogDate));

    log_to_file(fmt("%s/%s/uid_bans-log_%s.txt", Folder, LoggingFolder, LogDate), "%L", LANG_SERVER, "UID_BAN_LOGS", Name, AuthID, Ip, UIDHash, SysTime, GlobalBanTime, CheckType);

    new Query[QUERY_LENGHT];

    formatex(Query, charsmax(Query), "\
            INSERT INTO `%s` \
            (`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`)\
            VALUES('%s','%s','%s','%s','%d','%d','%d','%s','%s')",
            eSqlCvarData[SQL_TABLE_BANS],

            RowNames[ROW_NAME],
            RowNames[ROW_STEAM],
            RowNames[ROW_IP],
            RowNames[ROW_UID],
            RowNames[ROW_BAN_TIME_CREATED],
            RowNames[ROW_BAN_TIME_LENGHT],
            RowNames[ROW_TYPE],
            RowNames[ROW_STATUS],
            RowNames[ROW_SERVER],

            Name,
            AuthID,
            Ip,
            UIDHash,
            SysTime,
            GlobalBanTime,
            CheckType,
            BansValue[STATUS_ACTIVE],
            HostName
    );

    new SqlData[SqlType];

    SqlData[TYPE] = SQL_INSERT;
    SqlData[ID] = Player;

    SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", Query, SqlData, sizeof SqlData);

    SearchBans_Active(); //Обновление активных банов в бд
}
/*-----------------------------*/
public Ignore_ShowUidBanMenu(id, Menu, Item)
{
    new Info[INFO_LENGHT], Buffer;
    menu_item_getinfo(Menu, Item, Buffer, Info, charsmax(Info), .callback = Buffer);

    new Player = Info[0];

    if(!is_user_authemu(Player)){
        return ITEM_DISABLED;
    }

    if(Player == id){
        return ITEM_DISABLED;
    }

    return ITEM_IGNORE;
}
/*-----------------------------*/
public PlayerKick(Player)
{
    server_cmd("kick #%d %L", get_user_userid(Player), LANG_PLAYER, "UID_KICK_REASON");
}

/*-----------------------------*/
/*-----NEXT SQL FUNCTIONS------*/
/*-----------------------------*/

CheckTableServers()
{
    new HostName[MAX_NAME_LENGTH * 2];

    get_user_name(0, HostName, charsmax(HostName));

    new Query[QUERY_LENGHT];

    formatex(Query, charsmax(Query), "\
            SELECT `%s`\
            FROM `%s`\
            WHERE `%s` = '%s'",
            RowNames[ROW_SERVER],

            eSqlCvarData[SQL_TABLE_SERVERS],

            RowNames[ROW_SERVER],
            HostName
    );

    new SqlData[SqlType];

    SqlData[TYPE] = SQL_SERVER;

    SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", Query, SqlData, sizeof SqlData);
}
/*-----------------------------*/
public SQL_Handler(FailState, Handle:SqlQuery, Err[], ErrNum, Data[], Size)
{
    new Player = Data[ID];

    GlobalCheckSqlErr[Player] = false;

    if(FailState != TQUERY_SUCCESS){
        log_amx("[GS-Client: Uid Ban System]: SQL ERROR #%d, %s", ErrNum, Err);

        for(new i; i < sizeof eBansHistoryData; i++){
            eBansHistoryData[i] = 0;
        }

        GlobalCheckSqlErr[Player] = true;

        return PLUGIN_HANDLED;
    }

    switch(Data[TYPE])
    {
        case SQL_VOID:
        {
            return PLUGIN_HANDLED;
        }
        case SQL_TIME:
        {
            if(!SQL_NumResults(SqlQuery)){
                set_task_ex(eCvarData[TIME_KICK_ONE], "PlayerKick", Player);
            }
            else{
                new BanLenght = SQL_ReadResult(SqlQuery, 2);

                if(BanLenght == 0){
                    set_task_ex(eCvarData[TIME_KICK_ONE], "PlayerKick", Player);
                    return PLUGIN_HANDLED;
                }

                new NewQuery[QUERY_LENGHT], UIDHash[DATA_LENGHT];

                aemu_get_clientinfo(Player, aci_unique_id, UIDHash, charsmax(UIDHash));

                formatex(NewQuery, charsmax(NewQuery), "\
                        UPDATE `%s`\
                        SET `%s` = '%s'\
                        WHERE `%s` = '%s'",
                        eSqlCvarData[SQL_TABLE_BANS],

                        RowNames[ROW_STATUS],
                        BansValue[STATUS_EXPIRED],

                        RowNames[ROW_UID],
                        UIDHash
                );

                new SqlData[SqlType];

                SqlData[TYPE] = SQL_VOID;

                SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", NewQuery, SqlData, sizeof SqlData);

                SearchBans_Expired(); //обновление истекших банов в бд при заходе игрока (по умолчанию)
            }
        }
        case SQL_LOAD:
        {
            if(SQL_NumResults(SqlQuery)){
                CheckUidBanTime(Player);
            }
        }
        case SQL_INSERT:
        {
            if(eCvarData[BAN_MESSAGE_HUD]){
                set_dhudmessage(random_num(100, 255), random_num(100, 255), random_num(100, 255), 0.02, 0.30, 1, 0.2, 3.0, 0.5, 3.0);
                show_dhudmessage(0, "%l", "UID_BAN_INFO_HUD", Player, GlobalBanTime);
            }

            if(eCvarData[BAN_MESSAGE_CHAT]){
                client_print_color(0, print_team_default, "%l", "UID_BAN_INFO_CHAT", Player, GlobalBanTime);
            }

            set_task_ex(eCvarData[TIME_KICK_TWO], "PlayerKick", Player);
        }
        case SQL_TYPE:
        {
            if(SQL_NumResults(SqlQuery)){
                GlobalBanType[Player] = SQL_ReadResult(SqlQuery, 1);
                CheckUidBan(Player);
            }
        }
        case SQL_STATUS:
        {
            if(SQL_NumResults(SqlQuery)){
                new BanStatus[2];
                SQL_ReadResult(SqlQuery, 1, BanStatus, charsmax(BanStatus));

                if(equal(BanStatus, "b") || equal(BanStatus, "c")){
                    new PlayerStatus = BanStatus[0];
                    NotificationForAdmins(Player, PlayerStatus);

                    return PLUGIN_HANDLED;
                }

                CheckUidBanType(Player);
            }
        }
        case SQL_SERVER:
        {
            if(!SQL_NumResults(SqlQuery)){
                new NewQuery[QUERY_LENGHT], HostName[MAX_NAME_LENGTH * 2];

                get_user_name(0, HostName, charsmax(HostName));

                formatex(NewQuery, charsmax(NewQuery), "\
                        INSERT INTO `%s` \
                        (`%s`)\
                        VALUES('%s')",
                        eSqlCvarData[SQL_TABLE_SERVERS],

                        RowNames[ROW_SERVER],
                        HostName
                );

                new SqlData[SqlType];

                SqlData[TYPE] = SQL_VOID;

                SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", NewQuery, SqlData, sizeof SqlData);
            }
        }
        case SQL_SEARCH_UPDATE:
        {
            if(SQL_NumResults(SqlQuery)){
                new ResultValue = SQL_ReadResult(SqlQuery, 0);
                new NewQuery[QUERY_LENGHT], HostName[MAX_NAME_LENGTH * 2];

                get_user_name(0, HostName, charsmax(HostName));

                switch(Data[STATUS])
                {
                    case SQL_ACTIVE:
                    {
                        formatex(NewQuery, charsmax(NewQuery), "\
                                UPDATE `%s`\
                                SET `%s` = '%d'\
                                WHERE `%s` = '%s'",
                                eSqlCvarData[SQL_TABLE_SERVERS],

                                RowNames[ROW_BANS_ACTIVE],
                                ResultValue,

                                RowNames[ROW_SERVER],
                                HostName
                        );
                    }
                    case SQL_EXPIRED:
                    {
                        formatex(NewQuery, charsmax(NewQuery), "\
                                UPDATE `%s`\
                                SET `%s` = '%d'\
                                WHERE `%s` = '%s'",
                                eSqlCvarData[SQL_TABLE_SERVERS],

                                RowNames[ROW_BANS_EXPIRED],
                                ResultValue,

                                RowNames[ROW_SERVER],
                                HostName
                        );
                    }
                    case SQL_REMOVE:
                    {
                        formatex(NewQuery, charsmax(NewQuery), "\
                                UPDATE `%s`\
                                SET `%s` = '%d'\
                                WHERE `%s` = '%s'",
                                eSqlCvarData[SQL_TABLE_SERVERS],

                                RowNames[ROW_BANS_REMOVE],
                                ResultValue,

                                RowNames[ROW_SERVER],
                                HostName
                        );
                    }
                }

                new SqlData[SqlType];

                SqlData[TYPE] = SQL_VOID;

                SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", NewQuery, SqlData, sizeof SqlData);
            }
        }
        case SQL_SEARCH_MENU:
        {
            if(SQL_NumResults(SqlQuery)){
                eBansHistoryData[BANS_ACTIVE] = SQL_ReadResult(SqlQuery, 0);
                eBansHistoryData[BANS_EXPIRED] = SQL_ReadResult(SqlQuery, 1);
                eBansHistoryData[BANS_REMOVE] = SQL_ReadResult(SqlQuery, 2);

                ShowUidBanHistoryMenu(Player); //обновляем данные в меню еще раз, так как не успевает обновится с первого раза, функция ищет баны.
            }
        }
        case SQL_UNBAN:
        {
            if(!SQL_NumResults(SqlQuery)){
                console_print(Player, "%L", Player, "UID_UNBAN_CONSOLE_INFO_RESULT_NO");
            }
            else{
                new UIDHash[DATA_LENGHT], NewQuery[QUERY_LENGHT];

                aemu_get_clientinfo(Player, aci_unique_id, UIDHash, charsmax(UIDHash));

                formatex(NewQuery, charsmax(NewQuery), "\
                        UPDATE `%s`\
                        SET `%s` = '%s'\
                        WHERE `%s` = '%s'",
                        eSqlCvarData[SQL_TABLE_BANS],

                        RowNames[ROW_STATUS],
                        BansValue[STATUS_REMOVE],

                        RowNames[ROW_UID],
                        UIDHash
                );

                new SqlData[SqlType];

                SqlData[TYPE] = SQL_VOID;

                console_print(Player, "%L", Player, "UID_UNBAN_CONSOLE_INFO_RESULT_YES");

                SQL_ThreadQuery(SQL_Tuple, "SQL_Handler", NewQuery, SqlData, sizeof SqlData);

                SearchBans_Remove(); //обновление снятых банов в бд
            }
        }
    }

    return PLUGIN_HANDLED;
}
/*-----------------------------*/
NotificationForAdmins(Player, PlayerStatus)
{
    new Players[MAX_PLAYERS], PlayersCount;

    get_players_ex(Players, PlayersCount, GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV);

    for(new i; i < PlayersCount; i++){
        if(Players[i] != Player && get_user_flags(Players[i]) & ADMIN_ACCESS_FLAG){
            switch(PlayerStatus)
            {
                case 'b':
                {
                    client_print_color(Players[i], print_team_default, "%l", "UID_BAN_INFO_STATUS_EXPIRED", Player);
                }
                case 'c':
                {
                    client_print_color(Players[i], print_team_default, "%l", "UID_BAN_INFO_STATUS_REMOVE", Player);
                }
            }
        }
    }
}
/*-----------------------------*/
CreateDefaultStructFileTime()
{
    new StringDescription[3][MAX_NAME_LENGTH * 3] =
    {
        ";Время бана для плагина GS-client: Uid Ban System",
        ";Правила: 'название пункта' 'время бана в минутах'",
        ";0 > навсегда"
    };

    new StringStruct[7][MAX_NAME_LENGTH * 2] =
    {
        "^"15 минут^" ^"15^"",
        "^"30 минут^" ^"30^"",
        "^"1 час^" ^"60^"",
        "^"1 день^" ^"1440^"",
        "^"1 неделя^" ^"10080^"",
        "^"1 месяц^" ^"43200^"",
        "^"Навсегда^" ^"0^""
    };

    new Data[MAX_NAME_LENGTH * 3], StringBlank[1];

    for(new i; i < sizeof StringDescription; i++){
        formatex(Data, charsmax(Data), "%s", StringDescription[i]);
        write_file(fmt("%s/UID-times.ini", Folder), Data, -1);
    }

    write_file(fmt("%s/UID-times.ini", Folder), StringBlank, -1);

    for(new i; i < sizeof StringStruct; i++){
        formatex(Data, charsmax(Data), "%s", StringStruct[i]);
        write_file(fmt("%s/UID-times.ini", Folder), Data, -1);
    }
}
/*-----------------------------*/
C++:
#include <amxmodx>
#include <amxmisc>
#include <nvault>
#include <authemu>

#define AUTO_CONFIG //Авто-создание конфига.

new const PLUGIN[] = "GS-Client: Uid Ban System";
new const VERSION[] = "1.0.8";
new const AUTHOR[] = "wellasgood";

new const Folder[] = "addons/UID-Bans"; //Основная папка плагина (хранение Access файла и логов)
new const LoggingFolder[] = "UID-Bans_Logs"; //Название папки для хранения логов.

enum //Избавляемся от магический цифр (непонятных) по коду.
{
    NAME_LENGHT = 64,
    DATA_LENGHT = 11,
    INFO_LENGHT = 3,
    DATE_LENGHT = 16
};

enum _:CvarData
{
    Float:TIME_CHECK,
    Float:TIME_KICK_ONE,
    Float:TIME_KICK_TWO
};

new eCvarData[CvarData], Vault;

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);
    register_dictionary("gsc_uid_ban_system.txt");

    register_clcmd("say /ubm", "OpenUidBansMenu", ADMIN_RCON, "Access the Uid Ban System Menu");

    RegCvars();

    #if defined AUTO_CONFIG
    AutoExecConfig(true, "gsc_uid_ban_system");
    #endif
}
/*-----------------------------*/
RegCvars()
{
    bind_pcvar_float(create_cvar(
        .name = "gsc_time_check",
        .string = "3.0",
        .description = "Time to check the player after it is connected.", //Время до проверки игрока после его подключения.
        .has_min = false,
        .min_val = 0.0,
        .has_max = false,
        .max_val = 0.0),
        eCvarData[TIME_CHECK]
    );

    bind_pcvar_float(create_cvar(
        .name = "gsc_time_kick_one",
        .string = "1.0",
        .description = "Time to kick the player after performing the check.", //Время до кика игрока после выполнения проверки.
        .has_min = false,
        .min_val = 0.0,
        .has_max = false,
        .max_val = 0.0),
        eCvarData[TIME_KICK_ONE]
    );

    bind_pcvar_float(create_cvar(
        .name = "gsc_time_kick_two",
        .string = "1.0",
        .description = "Time to kick the player after selecting in the menu.", //Время до кика игрока после выбора в меню.
        .has_min = false,
        .min_val = 0.0,
        .has_max = false,
        .max_val = 0.0),
        eCvarData[TIME_KICK_TWO]
    );
}
/*-----------------------------*/
public plugin_cfg()
{
    if(!dir_exists(Folder)){
        mkdir(Folder);
    }

    if(!dir_exists(fmt("%s/%s", Folder, LoggingFolder))){
        mkdir(fmt("%s/%s", Folder, LoggingFolder));
    }

    new LogDate[DATE_LENGHT];
    get_time("%d_%m_%y", LogDate, charsmax(LogDate));

    if(!file_exists(fmt("%s/%s/uid_bans-log_%s.txt", Folder, LoggingFolder, LogDate))){
        new LogFile = fopen(fmt("%s/%s/uid_bans-log_%s.txt", Folder, LoggingFolder, LogDate), "at");
        fclose(LogFile);
    }

    Vault = nvault_open("UID-bans");

    if(Vault == INVALID_HANDLE){
        set_fail_state("[GS-Client: Uid Ban System]: Error opening nVault file!");
    }
}
/*-----------------------------*/
public plugin_end()
{
    nvault_close(Vault);
}
/*-----------------------------*/
public client_putinserver(Player)
{
    if(is_user_authemu(Player)){
        set_task_ex(eCvarData[TIME_CHECK], "CheckUidBan", Player);
    }
}
/*-----------------------------*/
public CheckUidBan(Player)
{
    new UIDHash[DATA_LENGHT], Data[DATA_LENGHT];

    aemu_get_clientinfo(Player, aci_unique_id, UIDHash, charsmax(UIDHash));

    new timestamp, AccessResult = nvault_lookup(Vault, UIDHash, Data, charsmax(Data), timestamp);

    if(AccessResult){
        set_task_ex(eCvarData[TIME_KICK_ONE], "PlayerKick", Player);
    }
}
/*-----------------------------*/
public OpenUidBansMenu(id, level, cid)
{
    if(!cmd_access(id, level, cid, 2, false)){
        return PLUGIN_HANDLED;
    }

    ShowUidBanMenu(id);
    return PLUGIN_HANDLED;
}
/*-----------------------------*/
ShowUidBanMenu(id)
{
    if(!is_user_connected(id)){
        return;
    }

    new UidBanPlayerMenu[NAME_LENGHT];
    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_TITLE");

    new Menu = menu_create(UidBanPlayerMenu, "Handle_ShowUidBanMenu");
    new Callback = menu_makecallback("Ignore_ShowUidBanMenu");

    new Name[MAX_NAME_LENGTH], Info[INFO_LENGHT], Players[MAX_PLAYERS], PlayersCount;

    get_players_ex(Players, PlayersCount, GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV);

    for(new Player, i; i < PlayersCount; i++){
        Player = Players[i];
        Info[0] = Player;

        get_user_name(Player, Name, charsmax(Name));
        menu_additem(Menu, Name, Info, .callback = Callback);
    }

    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_BACK");
    menu_setprop(Menu, MPROP_BACKNAME, UidBanPlayerMenu);

    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_NEXT");
    menu_setprop(Menu, MPROP_NEXTNAME, UidBanPlayerMenu);

    formatex(UidBanPlayerMenu, charsmax(UidBanPlayerMenu), "%L", id, "UID_BAN_MENU_EXIT");
    menu_setprop(Menu, MPROP_EXITNAME, UidBanPlayerMenu);

    menu_display(id, Menu);
}
/*-----------------------------*/
public Handle_ShowUidBanMenu(id, Menu, Item)
{
    if(Item == MENU_EXIT){
        menu_destroy(Menu);
        return PLUGIN_HANDLED;
    }

    new Info[INFO_LENGHT], Buffer;

    menu_item_getinfo(Menu, Item, Buffer, Info, charsmax(Info), .callback = Buffer);
    menu_destroy(Menu);

    new Player = Info[0];

    WriteDataToFile(Player);

    ShowUidBanMenu(id);
    return PLUGIN_HANDLED;
}
/*-----------------------------*/
WriteDataToFile(Player)
{
    new Name[MAX_NAME_LENGTH], AuthID[MAX_AUTHID_LENGTH], Ip[MAX_IP_LENGTH+1];

    get_user_name(Player, Name, charsmax(Name));
    get_user_authid(Player, AuthID, charsmax(AuthID));
    get_user_ip(Player, Ip, charsmax(Ip), 1);

    new UIDHash[DATA_LENGHT];

    aemu_get_clientinfo(Player, aci_unique_id, UIDHash, charsmax(UIDHash));

    nvault_set(Vault, UIDHash, AuthID);

    new LogDate[DATE_LENGHT];
    get_time("%d_%m_%y", LogDate, charsmax(LogDate));

    log_to_file(fmt("%s/%s/uid_bans-log_%s.txt", Folder, LoggingFolder, LogDate), "%L", LANG_SERVER, "UID_BAN_LOGS", Name, AuthID, Ip, UIDHash);

    set_task_ex(eCvarData[TIME_KICK_TWO], "PlayerKick", Player);
}
/*-----------------------------*/
public Ignore_ShowUidBanMenu(id, Menu, Item)
{
    new Info[INFO_LENGHT], Buffer;
    menu_item_getinfo(Menu, Item, Buffer, Info, charsmax(Info), .callback = Buffer);

    new Player = Info[0];

    if(!is_user_authemu(Player)){
        return ITEM_DISABLED;
    }

    if(Player == id){
        return ITEM_DISABLED;
    }

    return ITEM_IGNORE;
}
/*-----------------------------*/
public PlayerKick(Player)
{
    server_cmd("kick #%d %L", get_user_userid(Player), LANG_PLAYER, "UID_KICK_REASON");
}
/*-----------------------------*/
--
-- Структура таблицы банов (значения должны быть как и в плагине)
--
CREATE TABLE IF NOT EXISTS uid_bans (
id int(11) NOT NULL,
name varchar(100) NOT NULL,
steam varchar(32) NOT NULL,
ip varchar(16) NOT NULL,
uid varchar(10) NOT NULL,
ban_created int(32) NOT NULL,
ban_time int(32) NOT NULL,
ban_type int(1) NOT NULL,
ban_status varchar(1) NOT NULL,
server varchar(100) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Структура таблицы серверов (значения должны быть как и в плагине)
--
CREATE TABLE IF NOT EXISTS uid_servers (
id int(11) NOT NULL,
server varchar(100) NOT NULL,
bans_active int(11) NOT NULL,
bans_expired int(11) NOT NULL,
bans_remove int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Индексы таблицы банов
--
ALTER TABLE uid_bans
ADD PRIMARY KEY (id),
ADD KEY uid (uid);

--
-- Индексы таблицы серверов
--
ALTER TABLE uid_servers
ADD PRIMARY KEY (id);

--
-- AUTO_INCREMENT для таблицы uid_bans
--
ALTER TABLE uid_bans
MODIFY id int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT для таблицы uid_servers
--
ALTER TABLE uid_servers
MODIFY id int(11) NOT NULL AUTO_INCREMENT;
PHP:
<?php
    /*
     Описание: PHP скрипт для плагина: 'GS-client: Uid Ban System'
     Автор: wellasgood
     Версия: 1.0.1

     Функции начальной версии:

     - Подключение к бд
     - Создание таблиц
     - Создание индекса у часто используемой в плагине колонки. (для быстрой работы)

     * - Остальное в 'Журнале изменений'

     Установка:

     - Внимание! Что-бы избежать ошибки доступа при создании, сделайте следующее:
     - 1. Проверьте, есть ли доступ к IP адресу откуда запускается скрипт. (если все хорошо и не помогло, переходим ко второму пункту)
     - 2. Проверьте, нету ли ограничений доступа у пользователя бд, например доступ только с одного IP адреса.

     - Заливаем файлы на хостинг в корень, что бы файл sсript-install.php был доступен по адресу: ваш_сайт/sсript-install.php
     - Открываем в браузере ссылку: ваш_сайт/sсript-install.php
     - По окончанию появится информация с результатом.
     - При успехе, файл автоматически удалится в целях безопасности.

     - Заходим в бд, проверяем.
     - Готово.
    */

    /*
     Журнал изменений:

     Версия: 1.0.1:

     - Изменение наименования файла, в целях отличия от таких же похожих файлов.
     - Добавлена функция, для автоматического удаления файла.
     - Раздел установки был изменен с учетом новых изменений.
    */

    //Внимание! Данные должны быть точно такие же как и в настройках плагина.

    error_reporting(0);

    //Настройки подлкючения и таблиц
    $uid_ban_host = '';    // хост
    $uid_ban_user = '';    // юзер
    $uid_ban_pass = '';    // пароль
    $uid_ban_db = '';    // имя базы
    $uid_ban_tb_bans = 'uid_bans';    // имя создаваемой таблицы банов
    $uid_ban_tb_servers = 'uid_servers';    // имя создаваемой таблицы серверов

    //Настройки наименования колонок в таблицах
    $ROW_ID = 'id';
    $ROW_NAME = 'name';
    $ROW_STEAM = 'steam';
    $ROW_IP = 'ip';
    $ROW_UID = 'uid';
    $ROW_BAN_TIME_CREATED = 'ban_created';
    $ROW_BAN_TIME_LENGHT = 'ban_time';
    $ROW_TYPE = 'ban_type';
    $ROW_STATUS = 'ban_status';
    $ROW_SERVER = 'server';
    $ROW_BANS_ACTIVE = 'bans_active';
    $ROW_BANS_EXPIRED = 'bans_expired';
    $ROW_BANS_REMOVE = 'bans_remove';

    $db = new mysqli($uid_ban_host, $uid_ban_user, $uid_ban_pass, $uid_ban_db);

    if($db->connect_error)
    {
        echo '<br><br><br><center>Возникла ошибка при подключении к бд! Информация ниже:</center><br>';
        echo '<center>ERROR[#'.$db->connect_error.'] '.$db->connect_error.'</center><br><br><br><br><br><br><br><br>';
        HelpMe();
        exit();
    }
    else
    {
        if($db->query("CREATE TABLE IF NOT EXISTS $uid_ban_tb_bans (
            $ROW_ID int(11) NOT NULL AUTO_INCREMENT,
            $ROW_NAME varchar(100) NOT NULL,
            $ROW_STEAM varchar(32) NOT NULL,
            $ROW_IP varchar(16) NOT NULL,
            $ROW_UID varchar(10) NOT NULL,
            $ROW_BAN_TIME_CREATED int(32) NOT NULL,
            $ROW_BAN_TIME_LENGHT int(32) NOT NULL,
            $ROW_TYPE int(1) NOT NULL,
            $ROW_STATUS varchar(1) NOT NULL,
            $ROW_SERVER varchar(100) NOT NULL,
            PRIMARY KEY ($ROW_ID)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8;"))
        {
            echo '<br><br><center>Таблица банов "'.$uid_ban_tb_bans.'" создана.</center><br>';
        }

        if($db->query("CREATE TABLE IF NOT EXISTS $uid_ban_tb_servers (
            $ROW_ID int(11) NOT NULL AUTO_INCREMENT,
            $ROW_SERVER varchar(100) NOT NULL,
            $ROW_BANS_ACTIVE int(11) NOT NULL,
            $ROW_BANS_EXPIRED int(11) NOT NULL,
            $ROW_BANS_REMOVE int(11) NOT NULL,
            PRIMARY KEY ($ROW_ID)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8;"))
        {
            echo '<center>Таблица банов серверов "'.$uid_ban_tb_servers.'" создана.</center><br>';
        }

        if($db->query("CREATE INDEX $ROW_UID ON $uid_ban_tb_bans($ROW_UID)"))
        {
            echo '<center>Индекс для колонки '.$ROW_UID.' создан!</center><br><br>';
        }

        echo '<center>Скрипт выполнен.</center><br><br><br><br><br><br><br><br>';

        HelpMe();
        InstallerCleaning();
    }

    $db->close();

    function HelpMe()
    {
        echo '<center>В случае проблем, обратитесь в тему поддержки:</center>';
        echo '<center><a href="https://dev-cs.ru/threads/9360/page-2#post-77535" target="_blank">Перейти</a></center><br>';
        echo '<center>Или по контактам ниже:</center><br>';
        echo '<center>dev-cs: @wellasgood</center>';
        echo '<center>vk: https://vk.com/d1mkin</center>';
        echo '<center>telegram: @WellAsGood</center>';
    }

    function InstallerCleaning()
    {
        $file = 'sсript-install.php';

        if(unlink($file))
        {
            echo '<br><br><center>В целях безопасности, Файл установки: "'.$file.'" был удален автоматически!</center>';
        }
        else
        {
            echo '<br><br><center>К сожалению, не получилось в целях безопасности удалить файл: "'.$file.'" автоматически, удалите его вручную!</center>';
        }
    }
?>
  • Мне нравится
Симпатии: Vesuvius
Автор
wellasgood
Скачивания
36
Просмотры
2.723
Первый выпуск
Обновление
Оценка
0,00 звёзд 0 оценок

Другие ресурсы пользователя wellasgood

  • COVID mode
    COVID mode
    Коронавирус режим для сервера.
  • UpdateService_Lite
    UpdateService_Lite
    Обновление услуг на сервере без ручного вмешательства.
  • Spring
    Spring
    Создание пружин.
  • Drum-kit
    Drum-kit
    Барабанная установка
  • HNS-Distance
    HNS-Distance
    Показывает в HUD чате преследующих игроков

Последние обновления

  1. Обновление до версии (1.0.8)

    [Added]: Добавлена поддержка SQL dump, (импорт файла .sql с данными, создание таблиц и индекса...
  2. Обновление до версии (1.0.3)

    [Added]: Теперь причину выводимую при кике игрока, можно вносить в LANG файле. (не ставьте...
Сверху Снизу