Kick Spamers 1.0.3c от gyxoBka

Статус
Новые ответы в этой теме размещать нельзя.

Shadowless

Пользователь
Регистрация
24 Фев 2019
Сообщения
168
Симпатии
3
Пол
Мужской
#1
i want to add ban (15minutes) please tell me is it correct?

C++:
/**
* CREDITS: mazdan for better way to read config
*             Subb98 for way to do White List and for regex pattern
**/

#include <amxmodx>
#include <fakemeta>
#include <regex>
#if AMXX_VERSION_NUM < 183
#include <colorchat>
#endif   

#pragma semicolon 1

new const PLUGIN[] = "Kick Spamers";
new const VERSION[] = "1.0.3c";
new const AUTHOR[] = "gyxoBka";

/***************НАСТРОЙКИ***************/

#define MAXPLAYERS 32                                     // максимальное количество игроков на сервере
#define IMMUNITY ADMIN_IMMUNITY                                 // Флаг иммунитета ( по умолчанию 'd' ). Закомментируйте, чтобы убрать иммунитет
#define CHECK_CHAT                                         // Проверка сообщений в чате. закомментируйте, чтобы не проверять
#define CHECK_NICK                                       // Проверка ника игрока при входе на сервер
#define UNREADBLE_NAME                                // Агрессивная проверка ника игрока. Кикает игроков с нечитаемыми никами. Закомментируйте, чтобы отключить
#define MAX_NUMS 9                                     // Какое число цифр допустимо в сообщении и нике ( в нике только при UNREADBLE_NAME )
#define SLASH                                        // Закомментируйте, чтобы не скрывать сообщения начинающиеся со слэша '/'
#define BAN                                        // For Disable add '/' before line
#define NOTICE                                       // Закомментируйте строку, чтобы отключить оповещения в чате
#define SOUND                                      // Закомментируйте строку, чтобы отключить звуковое оповещение
#define LOG_TO "KickSpamers.log"                 // Логирование обнарежения спама. закомментируйте, чтобы не логировать
#define BAD_WORDS "bad_words.ini"                // Слова, которые следует считать спамом. закомментируйте, чтобы не использовать
#define WHITE_WORDS "white_list.ini"           // Слова, которые НЕ считаются спамом. закомментируйте, чтобы не использовать

/*****************КОНЕЦ*****************/

#define CheckFlag(%1,%2)              (%1 &   (1 << (%2 & 31)))
#define SetFlag(%1,%2)                (%1 |=  (1 << (%2 & 31)))
#define ClearFlag(%1,%2)            (%1 &= ~(1 << (%2 & 31)))

#define MAX_LEN 20

enum _:CVARS
{
    SITE_NAME,
    SITE_CHAT,
    WAIT,
    WARNINGS
};

stock Array:g_aBadWord, g_aBadWord_size;
stock Array:g_aWhiteWord, g_aWhiteWord_size;
stock Regex:g_RegexIP, Regex:g_RegexSite;

stock g_iNameWarns[MAXPLAYERS+1];
stock g_iMaxWaitTime;
stock Float:g_flWaitTime[MAXPLAYERS + 1];
stock bool:g_bRegexSite_Name;

stock g_szMessage[192];
stock g_iChatWarns[MAXPLAYERS+1];
stock bool:g_bRegexSite_Chat;

stock g_iCvars[CVARS];
stock g_iMaxWarnings;

stock IsImmunity;

stock g_iPos, g_szTemp[MAX_LEN+1];

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);
    register_cvar("kickspamers", VERSION, FCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED);
   
    #if defined CHECK_NICK
    register_forward(FM_ClientUserInfoChanged,"fw_ClientUserInfoChanged", false);
    #endif
   
    #if defined CHECK_CHAT
    register_clcmd("say","HookSay");
    register_clcmd("say_team","HookSay");
    #endif
}

public plugin_cfg()
{
    LoadCvars();
    LoadRegex();
    #if defined BAD_WORDS
    LoadBadWords();
    #endif
    #if defined WHITE_WORDS
    LoadWhiteWord();
    #endif
}

public client_putinserver(id)
{
    #if defined IMMUNITY
    if(get_user_flags(id) & IMMUNITY || is_user_hltv(id))
    {
        SetFlag(IsImmunity, id);
        return PLUGIN_HANDLED;
    }
    #else
    if(is_user_hltv(id)) return PLUGIN_HANDLED;
    #endif
   
    #if defined CHECK_NICK
    NickControl(id);
    #endif
   
    return PLUGIN_CONTINUE;
}

#if !defined client_disconnected
    #define client_disconnected client_disconnect
#endif

public client_disconnected(id)
{
    #if defined CHECK_NICK
    g_flWaitTime[id] = 0.0;
    g_iNameWarns[id] = 0;
    #endif
   
    #if defined CHECK_CHAT
    g_iChatWarns[id] = 0;
    #endif
}       

#if defined CHECK_NICK
public fw_ClientUserInfoChanged(id, szBuffer)
{
    if(!is_user_alive(id)) return FMRES_IGNORED;
    #if defined IMMUNITY
    if(CheckFlag(IsImmunity, id)) return FMRES_IGNORED;
    #endif
   
    static szOldName[32], szNewName[32];
    get_user_name(id, szOldName, 31);
    engfunc(EngFunc_InfoKeyValue, szBuffer, "name", szNewName, 31);
   
    if(equali(szOldName, szNewName)) return FMRES_IGNORED;
   
    static Float:flTime; flTime = get_gametime();

    if(g_flWaitTime[id] > flTime)
    {
        g_flWaitTime[id] = flTime + g_iMaxWaitTime;
           
        engfunc(EngFunc_SetClientKeyValue, id, szBuffer, "name", szOldName);
           
        if(++g_iNameWarns[id] >= g_iMaxWarnings)
        {
            KickPlayer(id, "[SPAM/SWEAR/ADVETS] Frequent change of nickname");
        }
        #if defined NOTICE
        client_print_color(id, 0, "^1[^4 WARNING^1 ]^3 You can not often change nickname ^1[^4%d^1/^4%d^1]^3!",g_iNameWarns[id], g_iMaxWarnings);
        #endif
        #if defined SOUND
        client_cmd(id, "spk buttons/button2");
        #endif
        return FMRES_SUPERCEDE;
    }   
    g_flWaitTime[id] = flTime + g_iMaxWaitTime;
    g_iNameWarns[id] = 0;
    NickControl(id, szNewName);
   
    return FMRES_IGNORED;
}
#endif

#if defined CHECK_CHAT
public HookSay(id)
{
    static ret;  ret = 0;
   
    read_args(g_szMessage, charsmax(g_szMessage));
    remove_quotes(g_szMessage);
   
    if(strlen(g_szMessage) == 0) return PLUGIN_HANDLED;
    #if defined SLASH
    if(g_szMessage[0] == '/') return PLUGIN_HANDLED_MAIN;
    #endif
   
    #if defined IMMUNITY
    if(CheckFlag(IsImmunity, id)) return PLUGIN_CONTINUE;
    #endif
   
    #if defined LOG_TO
    new szTemp[192];
    copy(szTemp, charsmax(szTemp), g_szMessage);
    #endif
   
    #if defined WHITE_WORDS
    g_iPos = g_aWhiteWord_size;
    while(g_iPos--)
    {
        ArrayGetString(g_aWhiteWord, g_iPos, g_szTemp, MAX_LEN);
        if(containi(g_szMessage, g_szTemp) != -1)
            while(replace(g_szMessage, charsmax(g_szMessage), g_szTemp, "")) {}
    }
    #endif
    static iChars, iNums;
    iChars = 0; iNums = 0;
    AnalyzeString(g_szMessage, iChars, iNums);
   
    if((g_bRegexSite_Chat && regex_match_c(g_szMessage, g_RegexSite, ret) > 0) || regex_match_c(g_szMessage, g_RegexIP, ret) > 0  || iNums > MAX_NUMS)
    {
        #if defined LOG_TO
        PrintLog(id, szTemp);
        #endif
        if(++g_iChatWarns[id] >= g_iMaxWarnings)
        {
            KickPlayer(id, "[SPAM/SWEAR/ADVETS] Restricted word(s) in chat");
        }
        #if defined NOTICE
        client_print_color(id, 0, "^1[^4 WARNING^1 ]^3 Restricted word(s) in chat^1[^4%d^1/^4%d^1]^3!",g_iChatWarns[id], g_iMaxWarnings);
        #endif
        #if defined SOUND
        client_cmd(id, "spk buttons/button2");
        #endif
        return PLUGIN_HANDLED;
    }

    #if defined BAD_WORDS
    if(BadWordCheck(id, g_iChatWarns[id], g_szMessage)) return PLUGIN_HANDLED;
    #endif
    return PLUGIN_CONTINUE;
}
#endif


stock NickControl(const id, szName[32] = "")
{
    #if defined IMMUNITY
    if(CheckFlag(IsImmunity, id)) return;
    #endif

    new ret;
    if(strlen(szName) == 0) get_user_name(id, szName, charsmax(szName));

    CheckIP(id, szName);
   
    if(g_bRegexSite_Name && regex_match_c(szName, g_RegexSite, ret) > 0)
    {
        KickPlayer(id, "[SPAM/SWEAR/ADVETS] Bad NickName...");
    }
}

stock CheckIP(const id, szName[32] = "")
{
    new iRet, iChars, iNums;
    AnalyzeString(szName, iChars, iNums);

    if(regex_match_c(szName, g_RegexIP, iRet) > 0)
    {
        KickPlayer(id, "[SPAM/SWEAR/ADVETS] Bad NickName. Too many digits...");
        return;
    }
   
    #if defined UNREADBLE_NAME
    if(iNums > iChars || iNums > MAX_NUMS)
    {
        KickPlayer(id, "[SPAM/SWEAR/ADVETS] Bad NickName. Too many digits...");
    }
    #endif
}

stock AnalyzeString(const szTemp[], &iChars, &iNums)
{
    new iLen = strlen(szTemp);
    new iTemp;
   
    for(new i; i < iLen; i++)
    {
        iTemp = szTemp[i];
       
        if ('0' <= iTemp <= '9') iNums++;
        else iChars++;
    }
}

stock KickPlayer(const id, szReason[] = "")
{
    server_cmd("kick #%d %s", get_user_userid(id), szReason);
   
    #if defined BAN
    server_cmd("amx_ban #%d 15 %s", get_user_userid(id), szReason);
    #endif
   
   
    #if defined LOG_TO
    PrintLog(id, szReason);
    #endif
}

LoadRegex()
{
    // Паттерн на IP
    //new szPatternIP[] = "(?:\s*\d+\s*\.){3}";
    new szPatternIP[] = "(?:\d{1,3}.){3}";
    // Паттерн на Site
    //new szPatternSite[] = "(?:\w{2,}\s*\.\s*(su|ru|by|kz|ua|eu|bg|de|fr|lt|lv|me|pl|ro|us|ws|com|net|org|biz|name|info)\b)";
    new szPatternSite[] = "(?:[-\w]{2,}\W(su|ru|by|kz|ua|eu|bg|de|fr|lt|lv|me|pl|ro|us|ws|com|net|org|biz|name|info)\b)";
   
    new ret, error[128];
   
    g_RegexIP = regex_compile(szPatternIP, ret, error, charsmax(error), "i");
    if(g_RegexIP == REGEX_PATTERN_FAIL) set_fail_state("|     Incorrect pattern IP.    |");   

    g_RegexSite = regex_compile(szPatternSite, ret, error, charsmax(error), "i");
    if(g_RegexSite == REGEX_PATTERN_FAIL) set_fail_state("|     Incorrect pattern SITE.    |");   
}

#if defined BAD_WORDS
LoadBadWords()
{
    new szFilePath[64];
    get_localinfo("amxx_configsdir", szFilePath, charsmax(szFilePath));
    formatex(szFilePath, charsmax(szFilePath), "%s/%s",szFilePath, BAD_WORDS);

    new FileHandle = fopen(szFilePath, "rt");

    if(!FileHandle)
    {   
        new szErrorMsg[256];
        formatex(szErrorMsg, charsmax(szErrorMsg), "[ERROR] File '%s' Not Exists here.", szFilePath);
        ErrorMessage(szErrorMsg);
    }

    new szTemp[20];
    g_aBadWord = ArrayCreate(MAX_LEN+1);
   
    while(!feof(FileHandle))
    {
        fgets(FileHandle, szTemp, charsmax(szTemp));
        trim(szTemp);
       
        if(!szTemp[0] || szTemp[0] == ';') continue;
       
        ArrayPushString(g_aBadWord, szTemp);
        g_aBadWord_size++;
    }
    fclose(FileHandle);
}
#endif

#if defined WHITE_WORDS
LoadWhiteWord()
{
    new szFilePath[64];
    get_localinfo("amxx_configsdir", szFilePath, charsmax(szFilePath));
    formatex(szFilePath, charsmax(szFilePath), "%s/%s",szFilePath, WHITE_WORDS);
   
    new FileHandle = fopen(szFilePath, "rt");
   
    if(!FileHandle)
    {   
        new szErrorMsg[256];
        formatex(szErrorMsg, charsmax(szErrorMsg), "[ERROR] File '%s' Not Exists here.", szFilePath);
        ErrorMessage(szErrorMsg);
    }
   
    new szTemp[20];
    g_aWhiteWord = ArrayCreate(MAX_LEN+1);
   
    while(!feof(FileHandle))
    {
        fgets(FileHandle, szTemp, charsmax(szTemp));
        trim(szTemp);
       
        if(!szTemp[0] || szTemp[0] == ';') continue;
       
        ArrayPushString(g_aWhiteWord, szTemp);
        g_aWhiteWord_size++;
    }
    fclose(FileHandle);
}
#endif

LoadCvars()
{
    #if defined CHECK_CHAT
    g_iCvars[SITE_CHAT]     = register_cvar("regex_match_site_chat",     "1");
    if(get_pcvar_num(g_iCvars[SITE_CHAT])) g_bRegexSite_Chat = true;
    #endif
    #if defined CHECK_NICK
    g_iCvars[SITE_NAME]     = register_cvar("regex_match_site_name",     "1");
    g_iCvars[WARNINGS]      = register_cvar("max_warnings",         "3");
    g_iCvars[WAIT]          = register_cvar("min_wait",             "10");
   
    g_iMaxWarnings         = get_pcvar_num(g_iCvars[WARNINGS]);
    g_iMaxWaitTime         = get_pcvar_num(g_iCvars[WAIT]);
   
    if(get_pcvar_num(g_iCvars[SITE_NAME])) g_bRegexSite_Name = true;
    #endif
}

stock bool:BadWordCheck(id, &iWarns, szTemp[])
{
    g_iPos = g_aBadWord_size;
   
    while(g_iPos--)
    {
        ArrayGetString(g_aBadWord, g_iPos, g_szTemp, MAX_LEN);
        if(containi(szTemp, g_szTemp) > -1)
        {
            #if defined LOG_TO
            PrintLog(id, szTemp);
            #endif
            if(++iWarns >= g_iMaxWarnings)
            {
                KickPlayer(id, "[SPAM/SWEAR/ADVETS] Restricted word(s) in chat");
            }
            #if defined NOTICE
            client_print_color(id, 0, "^1[^4 WARNING^1 ]^3 Restricted word(s) in chat ^1[^4%d^1/^4%d^1]^3!",g_iChatWarns[id], g_iMaxWarnings);
            #endif
            #if defined SOUND
            client_cmd(id, "spk buttons/button2");
            #endif
           
            return true;
        }
    }
   
    return false;
}

stock ErrorMessage(const szMessage[])
{
    #if defined LOG_TO
    log_to_file(LOG_TO, "%s", szMessage);
    #endif
    set_fail_state(szMessage);
}

#if defined LOG_TO
stock PrintLog(const id, const szMessage[])
{
    static szMsg[256];
    vformat(szMsg, charsmax(szMsg), szMessage, 2);
    new szName[32], szAuth[24];
    get_user_name(id, szName, charsmax(szName));
    get_user_authid(id, szAuth, charsmax(szAuth));
   
    log_to_file(LOG_TO, "%s <%s>: ^"%s^"", szName, szAuth, szMsg);
}
#endif

i maked this changes


#define BAN // For Disable add '/' before line


and


stock KickPlayer(const id, szReason[] = "")
{
server_cmd("kick #%d %s", get_user_userid(id), szReason);

#if defined BAN
server_cmd("amx_ban #%d 15 %s", get_user_userid(id), szReason);
#endif

#if defined LOG_TO
PrintLog(id, szReason);
#endif
}
 

Molodoi

Команда форума
Модератор
Регистрация
14 Июн 2017
Сообщения
593
Симпатии
122
#2
Shadowless, It depends on the ban system you have. This is not a forum of psychics and fortune-tellers.
 

Kobra

Пользователь
Регистрация
24 Июн 2017
Сообщения
5
Симпатии
3
Пол
Мужской
#4
Anyone knows where I can find the official link of this plugin ? I tried to use it compiling this source but it's not using warnings,it's kicking right away ,cvars are not readed
 

perfectblood0

Команда форума
Администратор
Регистрация
29 Окт 2017
Сообщения
1.777
Симпатии
574
#5

Shadowless

Пользователь
Регистрация
24 Фев 2019
Сообщения
168
Симпатии
3
Пол
Мужской
#6

Shadowless

Пользователь
Регистрация
24 Фев 2019
Сообщения
168
Симпатии
3
Пол
Мужской
#7
C++:
/**
 * CREDITS: mazdan for better way to read config
 *             Subb98 for way to do White List and for regex pattern
**/

#include <amxmodx>
#include <fakemeta>
#include <regex>
#if AMXX_VERSION_NUM < 183
#include <colorchat>
#endif   

#pragma semicolon 1

new const PLUGIN[] = "Kick Spamers";
new const VERSION[] = "1.0.3c";
new const AUTHOR[] = "gyxoBka";

/***************НАСТРОЙКИ***************/

#define MAXPLAYERS 32                                     // максимальное количество игроков на сервере
//#define IMMUNITY ADMIN_IMMUNITY                                 // Флаг иммунитета ( по умолчанию 'd' ). Закомментируйте, чтобы убрать иммунитет
#define CHECK_CHAT                                         // Проверка сообщений в чате. закомментируйте, чтобы не проверять
#define CHECK_NICK                                       // Проверка ника игрока при входе на сервер
#define UNREADBLE_NAME                                // Агрессивная проверка ника игрока. Кикает игроков с нечитаемыми никами. Закомментируйте, чтобы отключить
#define MAX_NUMS 9                                     // Какое число цифр допустимо в сообщении и нике ( в нике только при UNREADBLE_NAME )
/* #define SLASH */                                        // Закомментируйте, чтобы не скрывать сообщения начинающиеся со слэша '/'
#define BAN                                        // For Disable add '/' before line
#define NOTICE                                       // Закомментируйте строку, чтобы отключить оповещения в чате
#define SOUND                                      // Закомментируйте строку, чтобы отключить звуковое оповещение
#define LOG_TO "KickSpamers.log"                 // Логирование обнарежения спама. закомментируйте, чтобы не логировать
#define BAD_WORDS "bad_words.ini"                // Слова, которые следует считать спамом. закомментируйте, чтобы не использовать
#define WHITE_WORDS "white_list.ini"           // Слова, которые НЕ считаются спамом. закомментируйте, чтобы не использовать

/*****************КОНЕЦ*****************/

#define CheckFlag(%1,%2)              (%1 &   (1 << (%2 & 31)))
#define SetFlag(%1,%2)                (%1 |=  (1 << (%2 & 31)))
#define ClearFlag(%1,%2)            (%1 &= ~(1 << (%2 & 31)))

#define MAX_LEN 20

enum _:CVARS
{
    SITE_NAME,
    SITE_CHAT,
    WAIT,
    WARNINGS,
    BANTIME,
};

stock Array:g_aBadWord, g_aBadWord_size;
stock Array:g_aWhiteWord, g_aWhiteWord_size;
stock Regex:g_RegexIP, Regex:g_RegexSite;

stock g_iNameWarns[MAXPLAYERS+1];
stock g_iMaxWaitTime;
stock Float:g_flWaitTime[MAXPLAYERS + 1];
stock bool:g_bRegexSite_Name;

stock g_szMessage[192];
stock g_iChatWarns[MAXPLAYERS+1];
stock bool:g_bRegexSite_Chat;

stock g_iCvars[CVARS];
stock g_iMaxWarnings;
stock g_iBanTime;

stock IsImmunity;

stock g_iPos, g_szTemp[MAX_LEN+1];

new g_iBanType;

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);
    register_cvar("kickspamers", VERSION, FCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED);
    
    g_iBanType = register_cvar("iBanType", "AUTO");

    #if defined CHECK_NICK
    register_forward(FM_ClientUserInfoChanged,"fw_ClientUserInfoChanged", false);
    #endif
    
    #if defined CHECK_CHAT
    register_clcmd("say","HookSay");
    register_clcmd("say_team","HookSay");
    #endif
}

public plugin_cfg()
{
    LoadCvars();
    LoadRegex();
    #if defined BAD_WORDS
    LoadBadWords();
    #endif
    #if defined WHITE_WORDS
    LoadWhiteWord();
    #endif
}

public client_putinserver(id)
{
    #if defined IMMUNITY
    if(get_user_flags(id) & IMMUNITY || is_user_hltv(id))
    {
        SetFlag(IsImmunity, id);
        return PLUGIN_HANDLED;
    }
    #else
    if(is_user_hltv(id)) return PLUGIN_HANDLED;
    #endif
    
    #if defined CHECK_NICK
    NickControl(id);
    #endif
    
    return PLUGIN_CONTINUE;
}

#if !defined client_disconnected
    #define client_disconnected client_disconnect
#endif

public client_disconnected(id)
{
    #if defined CHECK_NICK
    g_flWaitTime[id] = 0.0;
    g_iNameWarns[id] = 0;
    #endif
    
    #if defined CHECK_CHAT
    g_iChatWarns[id] = 0;
    #endif
}       

#if defined CHECK_NICK
public fw_ClientUserInfoChanged(id, szBuffer)
{
    if(!is_user_alive(id)) return FMRES_IGNORED;
    #if defined IMMUNITY
    if(CheckFlag(IsImmunity, id)) return FMRES_IGNORED;
    #endif
    
    static szOldName[32], szNewName[32];
    get_user_name(id, szOldName, 31);
    engfunc(EngFunc_InfoKeyValue, szBuffer, "name", szNewName, 31);
    
    if(equali(szOldName, szNewName)) return FMRES_IGNORED;
    
    static Float:flTime; flTime = get_gametime();

    if(g_flWaitTime[id] > flTime)
    {
        g_flWaitTime[id] = flTime + g_iMaxWaitTime;
            
        engfunc(EngFunc_SetClientKeyValue, id, szBuffer, "name", szOldName);
            
        if(++g_iNameWarns[id] >= g_iMaxWarnings)
        {
            KickPlayer(id, "[SPAM/SWEAR/ADVERT] Frequent change of nickname");
        }
        #if defined NOTICE
        client_print_color(id, 0, "^1[^4 WARNING^1 ]^3 You can not often change nickname ^1[^4%d^1/^4%d^1]^3!",g_iNameWarns[id], g_iMaxWarnings);
        #endif
        #if defined SOUND
        client_cmd(id, "spk buttons/button2");
        #endif
        return FMRES_SUPERCEDE;
    }   
    g_flWaitTime[id] = flTime + g_iMaxWaitTime;
    g_iNameWarns[id] = 0;
    NickControl(id, szNewName);
    
    return FMRES_IGNORED;
}
#endif

#if defined CHECK_CHAT
public HookSay(id)
{
    static ret;  ret = 0;
    
    read_args(g_szMessage, charsmax(g_szMessage));
    remove_quotes(g_szMessage);
    
    if(strlen(g_szMessage) == 0) return PLUGIN_HANDLED;
    #if defined SLASH
    if(g_szMessage[0] == '/') return PLUGIN_HANDLED_MAIN;
    #endif
    
    #if defined IMMUNITY
    if(CheckFlag(IsImmunity, id)) return PLUGIN_CONTINUE;
    #endif
    
    #if defined LOG_TO
    new szTemp[192];
    copy(szTemp, charsmax(szTemp), g_szMessage);
    #endif
    
    #if defined WHITE_WORDS
    g_iPos = g_aWhiteWord_size;
    while(g_iPos--)
    {
        ArrayGetString(g_aWhiteWord, g_iPos, g_szTemp, MAX_LEN);
        if(containi(g_szMessage, g_szTemp) != -1)
            while(replace(g_szMessage, charsmax(g_szMessage), g_szTemp, "")) {}
    }
    #endif
    static iChars, iNums;
    iChars = 0; iNums = 0;
    AnalyzeString(g_szMessage, iChars, iNums);
    
    if((g_bRegexSite_Chat && regex_match_c(g_szMessage, g_RegexSite, ret) > 0) || regex_match_c(g_szMessage, g_RegexIP, ret) > 0  || iNums > MAX_NUMS)
    {
        #if defined LOG_TO
        PrintLog(id, szTemp);
        #endif
        if(++g_iChatWarns[id] >= g_iMaxWarnings)
        {
            KickPlayer(id, "[SPAM/SWEAR/ADVERT] Restricted word(s) in chat ");
        }
        #if defined NOTICE
        client_print_color(id, 0, "^1[^4 WARNING^1 ]^3 Restricted word(s) in chat^1[^4%d^1/^4%d^1]^3! ",g_iChatWarns[id], g_iMaxWarnings);
        #endif
        #if defined SOUND
        client_cmd(id, "spk buttons/button2");
        #endif
        return PLUGIN_HANDLED;
    }

    #if defined BAD_WORDS
    if(BadWordCheck(id, g_iChatWarns[id], g_szMessage)) return PLUGIN_HANDLED;
    #endif
    return PLUGIN_CONTINUE;
}
#endif


stock NickControl(const id, szName[32] = "")
{
    #if defined IMMUNITY
    if(CheckFlag(IsImmunity, id)) return;
    #endif

    new ret;
    if(strlen(szName) == 0) get_user_name(id, szName, charsmax(szName));

    CheckIP(id, szName);
    
    if(g_bRegexSite_Name && regex_match_c(szName, g_RegexSite, ret) > 0)
    {
        KickPlayer(id, "[SPAM/SWEAR/ADVERT] Bad NickName...");
    }
}

stock CheckIP(const id, szName[32] = "")
{
    new iRet, iChars, iNums;
    AnalyzeString(szName, iChars, iNums);

    if(regex_match_c(szName, g_RegexIP, iRet) > 0)
    {
        KickPlayer(id, "[SPAM/SWEAR/ADVERT] Bad NickName....");
        return;
    }
    
    #if defined UNREADBLE_NAME
    if(iNums > iChars || iNums > MAX_NUMS)
    {
        KickPlayer(id, "[SPAM/SWEAR/ADVERT] Bad NickName....");
    }
    #endif
}

stock AnalyzeString(const szTemp[], &iChars, &iNums)
{
    new iLen = strlen(szTemp);
    new iTemp;
    
    for(new i; i < iLen; i++)
    {
        iTemp = szTemp[i];
        
        if ('0' <= iTemp <= '9') iNums++;
        else iChars++;
    }
}

stock KickPlayer(const id, szReason[] = "")
{
     server_cmd("kick #%d %s", get_user_userid(id), szReason);
    
    #if defined BAN
    new BanType[64];
    get_pcvar_string(g_iBanType, BanType, 63);
    server_cmd("amx_ban #%d %i %s %s", get_user_userid(id), g_iBanTime, szReason, BanType);
    server_cmd("amx_banip #%d %i %s %s", get_user_userid(id), g_iBanTime, szReason, BanType);
    #endif
    
    #if defined LOG_TO
    PrintLog(id, szReason);
    #endif
}



LoadRegex()
{
    // Паттерн на IP
    //new szPatternIP[] = "(?:\s*\d+\s*\.){3}";
    new szPatternIP[] = "(?:\d{1,3}.){3}";
    // Паттерн на Site
    //new szPatternSite[] = "(?:\w{2,}\s*\.\s*(su|ru|by|kz|ua|eu|bg|de|fr|lt|lv|me|pl|ro|us|ws|com|net|org|biz|name|info)\b)";
    new szPatternSite[] = "(?:[-\w]{2,}\W(su|ru|by|kz|ua|eu|bg|de|fr|lt|lv|me|pl|ro|us|ws|com|net|org|biz|name|info)\b)";
    
    new ret, error[128];
    
    g_RegexIP = regex_compile(szPatternIP, ret, error, charsmax(error), "i");
    if(g_RegexIP == REGEX_PATTERN_FAIL) set_fail_state("|     Incorrect pattern IP.    |");   

    g_RegexSite = regex_compile(szPatternSite, ret, error, charsmax(error), "i");
    if(g_RegexSite == REGEX_PATTERN_FAIL) set_fail_state("|     Incorrect pattern SITE.    |");   
}

#if defined BAD_WORDS
LoadBadWords()
{
    new szFilePath[64];
    get_localinfo("amxx_configsdir", szFilePath, charsmax(szFilePath));
    formatex(szFilePath, charsmax(szFilePath), "%s/%s",szFilePath, BAD_WORDS);

    new FileHandle = fopen(szFilePath, "rt");

    if(!FileHandle)
    {   
        new szErrorMsg[256];
        formatex(szErrorMsg, charsmax(szErrorMsg), "[ERROR] File '%s' Not Exists here.", szFilePath);
        ErrorMessage(szErrorMsg);
    }

    new szTemp[20];
    g_aBadWord = ArrayCreate(MAX_LEN+1);
    
    while(!feof(FileHandle))
    {
        fgets(FileHandle, szTemp, charsmax(szTemp));
        trim(szTemp);
        
        if(!szTemp[0] || szTemp[0] == ';') continue;
        
        ArrayPushString(g_aBadWord, szTemp);
        g_aBadWord_size++;
    }
    fclose(FileHandle);
}
#endif

#if defined WHITE_WORDS
LoadWhiteWord()
{
    new szFilePath[64];
    get_localinfo("amxx_configsdir", szFilePath, charsmax(szFilePath));
    formatex(szFilePath, charsmax(szFilePath), "%s/%s",szFilePath, WHITE_WORDS);
    
    new FileHandle = fopen(szFilePath, "rt");
    
    if(!FileHandle)
    {   
        new szErrorMsg[256];
        formatex(szErrorMsg, charsmax(szErrorMsg), "[ERROR] File '%s' Not Exists here.", szFilePath);
        ErrorMessage(szErrorMsg);
    }
    
    new szTemp[20];
    g_aWhiteWord = ArrayCreate(MAX_LEN+1);
    
    while(!feof(FileHandle))
    {
        fgets(FileHandle, szTemp, charsmax(szTemp));
        trim(szTemp);
        
        if(!szTemp[0] || szTemp[0] == ';') continue;
        
        ArrayPushString(g_aWhiteWord, szTemp);
        g_aWhiteWord_size++;
    }
    fclose(FileHandle);
}
#endif

LoadCvars()
{
    #if defined CHECK_CHAT
    g_iCvars[SITE_CHAT]     = register_cvar("regex_match_site_chat",     "1");
    if(get_pcvar_num(g_iCvars[SITE_CHAT])) g_bRegexSite_Chat = true;
    #endif
    
    #if defined CHECK_NICK
    g_iCvars[SITE_NAME]     = register_cvar("regex_match_site_name",     "1");
    g_iCvars[WARNINGS]      = register_cvar("max_warnings",         "3");
    g_iCvars[WAIT]          = register_cvar("min_wait",             "10");
    g_iMaxWarnings         = get_pcvar_num(g_iCvars[WARNINGS]);
    g_iMaxWaitTime         = get_pcvar_num(g_iCvars[WAIT]);
    if(get_pcvar_num(g_iCvars[SITE_NAME])) g_bRegexSite_Name = true;
    #endif
    
    #if defined BAN
    g_iCvars[BANTIME] = register_cvar("ban_time", "5");
    g_iBanTime = get_pcvar_num(g_iCvars[BANTIME]);
    #endif
    
}

stock bool:BadWordCheck(id, &iWarns, szTemp[])
{
    g_iPos = g_aBadWord_size;
    
    while(g_iPos--)
    {
        ArrayGetString(g_aBadWord, g_iPos, g_szTemp, MAX_LEN);
        if(containi(szTemp, g_szTemp) > -1)
        {
            #if defined LOG_TO
            PrintLog(id, szTemp);
            #endif
            
            
            
            if(++iWarns >= g_iMaxWarnings)
            {
                KickPlayer(id, "[SPAM/SWEAR/ADVERT] Restricted word(s) in chat ");
            }
            
            
            
            #if defined NOTICE
            client_print_color(id, 0, "^1[^4 WARNING^1 ]^3 Restricted word(s) in chat ^1[^4%d^1/^4%d^1]^3! ",g_iChatWarns[id], g_iMaxWarnings);
            #endif
            #if defined SOUND
            client_cmd(id, "spk buttons/button2");
            #endif
            
            return true;
        }
    }
    
    return false;
}

stock ErrorMessage(const szMessage[])
{
    #if defined LOG_TO
    log_to_file(LOG_TO, "%s", szMessage);
    #endif
    set_fail_state(szMessage);
}

#if defined LOG_TO
stock PrintLog(const id, const szMessage[])
{
    static szMsg[256];
    vformat(szMsg, charsmax(szMsg), szMessage, 2);
    new szName[32], szAuth[24];
    get_user_name(id, szName, charsmax(szName));
    get_user_authid(id, szAuth, charsmax(szAuth));
    
    log_to_file(LOG_TO, "%s <%s>: ^"%s^"", szName, szAuth, szMsg);
}
#endif
11 Окт 2019
тему можно закрыть
 

Shadowless

Пользователь
Регистрация
24 Фев 2019
Сообщения
168
Симпатии
3
Пол
Мужской
#8
C++:
/**
 * CREDITS: mazdan for better way to read config
 *             Subb98 for way to do White List and for regex pattern
**/

#include <amxmodx>
#include <fakemeta>
#include <regex>
#if AMXX_VERSION_NUM < 183
#include <colorchat>
#endif   

#pragma semicolon 1

new const PLUGIN[] = "Kick Spamers";
new const VERSION[] = "1.0.3c";
new const AUTHOR[] = "gyxoBka";

/***************НАСТРОЙКИ***************/

#define MAXPLAYERS 32                                     // максимальное количество игроков на сервере
//#define IMMUNITY ADMIN_IMMUNITY                                 // Флаг иммунитета ( по умолчанию 'd' ). Закомментируйте, чтобы убрать иммунитет
#define CHECK_CHAT                                         // Проверка сообщений в чате. закомментируйте, чтобы не проверять
#define CHECK_NICK                                       // Проверка ника игрока при входе на сервер
#define UNREADBLE_NAME                                // Агрессивная проверка ника игрока. Кикает игроков с нечитаемыми никами. Закомментируйте, чтобы отключить
#define MAX_NUMS 9                                     // Какое число цифр допустимо в сообщении и нике ( в нике только при UNREADBLE_NAME )
/* #define SLASH */                                        // Закомментируйте, чтобы не скрывать сообщения начинающиеся со слэша '/'
#define BAN                                        // For Disable add '/' before line
#define NOTICE                                       // Закомментируйте строку, чтобы отключить оповещения в чате
#define SOUND                                      // Закомментируйте строку, чтобы отключить звуковое оповещение
#define LOG_TO "KickSpamers.log"                 // Логирование обнарежения спама. закомментируйте, чтобы не логировать
#define BAD_WORDS "bad_words.ini"                // Слова, которые следует считать спамом. закомментируйте, чтобы не использовать
#define WHITE_WORDS "white_list.ini"           // Слова, которые НЕ считаются спамом. закомментируйте, чтобы не использовать

/*****************КОНЕЦ*****************/

#define CheckFlag(%1,%2)              (%1 &   (1 << (%2 & 31)))
#define SetFlag(%1,%2)                (%1 |=  (1 << (%2 & 31)))
#define ClearFlag(%1,%2)            (%1 &= ~(1 << (%2 & 31)))

#define MAX_LEN 20

enum _:CVARS
{
    SITE_NAME,
    SITE_CHAT,
    WAIT,
    WARNINGS,
    BANTIME,
};

stock Array:g_aBadWord, g_aBadWord_size;
stock Array:g_aWhiteWord, g_aWhiteWord_size;
stock Regex:g_RegexIP, Regex:g_RegexSite;

stock g_iNameWarns[MAXPLAYERS+1];
stock g_iMaxWaitTime;
stock Float:g_flWaitTime[MAXPLAYERS + 1];
stock bool:g_bRegexSite_Name;

stock g_szMessage[192];
stock g_iChatWarns[MAXPLAYERS+1];
stock bool:g_bRegexSite_Chat;

stock g_iCvars[CVARS];
stock g_iMaxWarnings;
stock g_iBanTime;

stock IsImmunity;

stock g_iPos, g_szTemp[MAX_LEN+1];

new g_iBanType;

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);
    register_cvar("kickspamers", VERSION, FCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED);
    
    g_iBanType = register_cvar("iBanType", "AUTO");

    #if defined CHECK_NICK
    register_forward(FM_ClientUserInfoChanged,"fw_ClientUserInfoChanged", false);
    #endif
    
    #if defined CHECK_CHAT
    register_clcmd("say","HookSay");
    register_clcmd("say_team","HookSay");
    #endif
}

public plugin_cfg()
{
    LoadCvars();
    LoadRegex();
    #if defined BAD_WORDS
    LoadBadWords();
    #endif
    #if defined WHITE_WORDS
    LoadWhiteWord();
    #endif
}

public client_putinserver(id)
{
    #if defined IMMUNITY
    if(get_user_flags(id) & IMMUNITY || is_user_hltv(id))
    {
        SetFlag(IsImmunity, id);
        return PLUGIN_HANDLED;
    }
    #else
    if(is_user_hltv(id)) return PLUGIN_HANDLED;
    #endif
    
    #if defined CHECK_NICK
    NickControl(id);
    #endif
    
    return PLUGIN_CONTINUE;
}

#if !defined client_disconnected
    #define client_disconnected client_disconnect
#endif

public client_disconnected(id)
{
    #if defined CHECK_NICK
    g_flWaitTime[id] = 0.0;
    g_iNameWarns[id] = 0;
    #endif
    
    #if defined CHECK_CHAT
    g_iChatWarns[id] = 0;
    #endif
}       

#if defined CHECK_NICK
public fw_ClientUserInfoChanged(id, szBuffer)
{
    if(!is_user_alive(id)) return FMRES_IGNORED;
    #if defined IMMUNITY
    if(CheckFlag(IsImmunity, id)) return FMRES_IGNORED;
    #endif
    
    static szOldName[32], szNewName[32];
    get_user_name(id, szOldName, 31);
    engfunc(EngFunc_InfoKeyValue, szBuffer, "name", szNewName, 31);
    
    if(equali(szOldName, szNewName)) return FMRES_IGNORED;
    
    static Float:flTime; flTime = get_gametime();

    if(g_flWaitTime[id] > flTime)
    {
        g_flWaitTime[id] = flTime + g_iMaxWaitTime;
            
        engfunc(EngFunc_SetClientKeyValue, id, szBuffer, "name", szOldName);
            
        if(++g_iNameWarns[id] >= g_iMaxWarnings)
        {
            KickPlayer(id, "[SPAM/SWEAR/ADVERT] Frequent change of nickname");
        }
        #if defined NOTICE
        client_print_color(id, 0, "^1[^4 WARNING^1 ]^3 You can not often change nickname ^1[^4%d^1/^4%d^1]^3!",g_iNameWarns[id], g_iMaxWarnings);
        #endif
        #if defined SOUND
        client_cmd(id, "spk buttons/button2");
        #endif
        return FMRES_SUPERCEDE;
    }   
    g_flWaitTime[id] = flTime + g_iMaxWaitTime;
    g_iNameWarns[id] = 0;
    NickControl(id, szNewName);
    
    return FMRES_IGNORED;
}
#endif

#if defined CHECK_CHAT
public HookSay(id)
{
    static ret;  ret = 0;
    
    read_args(g_szMessage, charsmax(g_szMessage));
    remove_quotes(g_szMessage);
    
    if(strlen(g_szMessage) == 0) return PLUGIN_HANDLED;
    #if defined SLASH
    if(g_szMessage[0] == '/') return PLUGIN_HANDLED_MAIN;
    #endif
    
    #if defined IMMUNITY
    if(CheckFlag(IsImmunity, id)) return PLUGIN_CONTINUE;
    #endif
    
    #if defined LOG_TO
    new szTemp[192];
    copy(szTemp, charsmax(szTemp), g_szMessage);
    #endif
    
    #if defined WHITE_WORDS
    g_iPos = g_aWhiteWord_size;
    while(g_iPos--)
    {
        ArrayGetString(g_aWhiteWord, g_iPos, g_szTemp, MAX_LEN);
        if(containi(g_szMessage, g_szTemp) != -1)
            while(replace(g_szMessage, charsmax(g_szMessage), g_szTemp, "")) {}
    }
    #endif
    static iChars, iNums;
    iChars = 0; iNums = 0;
    AnalyzeString(g_szMessage, iChars, iNums);
    
    if((g_bRegexSite_Chat && regex_match_c(g_szMessage, g_RegexSite, ret) > 0) || regex_match_c(g_szMessage, g_RegexIP, ret) > 0  || iNums > MAX_NUMS)
    {
        #if defined LOG_TO
        PrintLog(id, szTemp);
        #endif
        if(++g_iChatWarns[id] >= g_iMaxWarnings)
        {
            KickPlayer(id, "[SPAM/SWEAR/ADVERT] Restricted word(s) in chat ");
        }
        #if defined NOTICE
        client_print_color(id, 0, "^1[^4 WARNING^1 ]^3 Restricted word(s) in chat^1[^4%d^1/^4%d^1]^3! ",g_iChatWarns[id], g_iMaxWarnings);
        #endif
        #if defined SOUND
        client_cmd(id, "spk buttons/button2");
        #endif
        return PLUGIN_HANDLED;
    }

    #if defined BAD_WORDS
    if(BadWordCheck(id, g_iChatWarns[id], g_szMessage)) return PLUGIN_HANDLED;
    #endif
    return PLUGIN_CONTINUE;
}
#endif


stock NickControl(const id, szName[32] = "")
{
    #if defined IMMUNITY
    if(CheckFlag(IsImmunity, id)) return;
    #endif

    new ret;
    if(strlen(szName) == 0) get_user_name(id, szName, charsmax(szName));

    CheckIP(id, szName);
    
    if(g_bRegexSite_Name && regex_match_c(szName, g_RegexSite, ret) > 0)
    {
        KickPlayer(id, "[SPAM/SWEAR/ADVERT] Bad NickName...");
    }
}

stock CheckIP(const id, szName[32] = "")
{
    new iRet, iChars, iNums;
    AnalyzeString(szName, iChars, iNums);

    if(regex_match_c(szName, g_RegexIP, iRet) > 0)
    {
        KickPlayer(id, "[SPAM/SWEAR/ADVERT] Bad NickName....");
        return;
    }
    
    #if defined UNREADBLE_NAME
    if(iNums > iChars || iNums > MAX_NUMS)
    {
        KickPlayer(id, "[SPAM/SWEAR/ADVERT] Bad NickName....");
    }
    #endif
}

stock AnalyzeString(const szTemp[], &iChars, &iNums)
{
    new iLen = strlen(szTemp);
    new iTemp;
    
    for(new i; i < iLen; i++)
    {
        iTemp = szTemp[i];
        
        if ('0' <= iTemp <= '9') iNums++;
        else iChars++;
    }
}

stock KickPlayer(const id, szReason[] = "")
{
    #if defined BAN
    new BanType[64];
    get_pcvar_string(g_iBanType, BanType, 63);
    server_cmd("amx_ban #%d %i %s %s", get_user_userid(id), g_iBanTime, szReason, BanType);
    server_cmd("amx_banip #%d %i %s %s", get_user_userid(id), g_iBanTime, szReason, BanType);
    #else
     server_cmd("kick #%d %s", get_user_userid(id), szReason);
    return PLUGIN_HANDLED;
    #endif
    server_cmd("kick #%d %s", get_user_userid(id), szReason);
    #if defined LOG_TO
    PrintLog(id, szReason);
    #endif
}



LoadRegex()
{
    // Паттерн на IP
    //new szPatternIP[] = "(?:\s*\d+\s*\.){3}";
    new szPatternIP[] = "(?:\d{1,3}.){3}";
    // Паттерн на Site
    //new szPatternSite[] = "(?:\w{2,}\s*\.\s*(su|ru|by|kz|ua|eu|bg|de|fr|lt|lv|me|pl|ro|us|ws|com|net|org|biz|name|info)\b)";
    new szPatternSite[] = "(?:[-\w]{2,}\W(su|ru|by|kz|ua|eu|bg|de|fr|lt|lv|me|pl|ro|us|ws|com|net|org|biz|name|info)\b)";
    
    new ret, error[128];
    
    g_RegexIP = regex_compile(szPatternIP, ret, error, charsmax(error), "i");
    if(g_RegexIP == REGEX_PATTERN_FAIL) set_fail_state("|     Incorrect pattern IP.    |");   

    g_RegexSite = regex_compile(szPatternSite, ret, error, charsmax(error), "i");
    if(g_RegexSite == REGEX_PATTERN_FAIL) set_fail_state("|     Incorrect pattern SITE.    |");   
}

#if defined BAD_WORDS
LoadBadWords()
{
    new szFilePath[64];
    get_localinfo("amxx_configsdir", szFilePath, charsmax(szFilePath));
    formatex(szFilePath, charsmax(szFilePath), "%s/%s",szFilePath, BAD_WORDS);

    new FileHandle = fopen(szFilePath, "rt");

    if(!FileHandle)
    {   
        new szErrorMsg[256];
        formatex(szErrorMsg, charsmax(szErrorMsg), "[ERROR] File '%s' Not Exists here.", szFilePath);
        ErrorMessage(szErrorMsg);
    }

    new szTemp[20];
    g_aBadWord = ArrayCreate(MAX_LEN+1);
    
    while(!feof(FileHandle))
    {
        fgets(FileHandle, szTemp, charsmax(szTemp));
        trim(szTemp);
        
        if(!szTemp[0] || szTemp[0] == ';') continue;
        
        ArrayPushString(g_aBadWord, szTemp);
        g_aBadWord_size++;
    }
    fclose(FileHandle);
}
#endif

#if defined WHITE_WORDS
LoadWhiteWord()
{
    new szFilePath[64];
    get_localinfo("amxx_configsdir", szFilePath, charsmax(szFilePath));
    formatex(szFilePath, charsmax(szFilePath), "%s/%s",szFilePath, WHITE_WORDS);
    
    new FileHandle = fopen(szFilePath, "rt");
    
    if(!FileHandle)
    {   
        new szErrorMsg[256];
        formatex(szErrorMsg, charsmax(szErrorMsg), "[ERROR] File '%s' Not Exists here.", szFilePath);
        ErrorMessage(szErrorMsg);
    }
    
    new szTemp[20];
    g_aWhiteWord = ArrayCreate(MAX_LEN+1);
    
    while(!feof(FileHandle))
    {
        fgets(FileHandle, szTemp, charsmax(szTemp));
        trim(szTemp);
        
        if(!szTemp[0] || szTemp[0] == ';') continue;
        
        ArrayPushString(g_aWhiteWord, szTemp);
        g_aWhiteWord_size++;
    }
    fclose(FileHandle);
}
#endif

LoadCvars()
{
    #if defined CHECK_CHAT
    g_iCvars[SITE_CHAT]     = register_cvar("regex_match_site_chat",     "1");
    if(get_pcvar_num(g_iCvars[SITE_CHAT])) g_bRegexSite_Chat = true;
    #endif
    
    #if defined CHECK_NICK
    g_iCvars[SITE_NAME]     = register_cvar("regex_match_site_name",     "1");
    g_iCvars[WARNINGS]      = register_cvar("max_warnings",         "3");
    g_iCvars[WAIT]          = register_cvar("min_wait",             "10");
    g_iMaxWarnings         = get_pcvar_num(g_iCvars[WARNINGS]);
    g_iMaxWaitTime         = get_pcvar_num(g_iCvars[WAIT]);
    if(get_pcvar_num(g_iCvars[SITE_NAME])) g_bRegexSite_Name = true;
    #endif
    
    #if defined BAN
    g_iCvars[BANTIME] = register_cvar("ban_time", "5");
    g_iBanTime = get_pcvar_num(g_iCvars[BANTIME]);
    #endif
    
}

stock bool:BadWordCheck(id, &iWarns, szTemp[])
{
    g_iPos = g_aBadWord_size;
    
    while(g_iPos--)
    {
        ArrayGetString(g_aBadWord, g_iPos, g_szTemp, MAX_LEN);
        if(containi(szTemp, g_szTemp) > -1)
        {
            #if defined LOG_TO
            PrintLog(id, szTemp);
            #endif
            
            
            
            if(++iWarns >= g_iMaxWarnings)
            {
                KickPlayer(id, "[SPAM/SWEAR/ADVERT] Restricted word(s) in chat ");
            }
            
            
            
            #if defined NOTICE
            client_print_color(id, 0, "^1[^4 WARNING^1 ]^3 Restricted word(s) in chat ^1[^4%d^1/^4%d^1]^3! ",g_iChatWarns[id], g_iMaxWarnings);
            #endif
            #if defined SOUND
            client_cmd(id, "spk buttons/button2");
            #endif
            
            return true;
        }
    }
    
    return false;
}

stock ErrorMessage(const szMessage[])
{
    #if defined LOG_TO
    log_to_file(LOG_TO, "%s", szMessage);
    #endif
    set_fail_state(szMessage);
}

#if defined LOG_TO
stock PrintLog(const id, const szMessage[])
{
    static szMsg[256];
    vformat(szMsg, charsmax(szMsg), szMessage, 2);
    new szName[32], szAuth[24];
    get_user_name(id, szName, charsmax(szName));
    get_user_authid(id, szAuth, charsmax(szAuth));
    
    log_to_file(LOG_TO, "%s <%s>: ^"%s^"", szName, szAuth, szMsg);
}
#endif
 
Статус
Новые ответы в этой теме размещать нельзя.