Код за потвърждение: Избери целия код
/*
======================================================
Version 2.0
--- First release
Version 2.1
--- Added better regex pattern
Version 2.2
--- Added
nms_nospam 0/1 disable/enable NoSpam function
nms_badwords 0/1 disable/enable BadWords function
nms_noadvert 0/1 disable/enable NoAdvert function
--- Removed colorchat include
Version 2.3
--- Added
Exception words that are skipped when checking for spam
Admin immunity from NoAdvert function
Better regex pattern
Version 2.3.1 HotFix
--Works with advanced bans
Version 2.4
--Added ADMIN_BAN immunity to the plugin
nms_adminimmune 1/0
Version 2.5
--Fixed a hole in detecting IP/DOMAINS
Version 2.5.1 HotFix
--Higher domain detection
Version 2.5.2 Hotfix
--nms_chatban "0" now works properly
Version 2.6
--IP/DOMAIN check in player's nick
--Better NoSpam detection
--Punish now stays after reconnection
--Optimized Colorchat
Version 3.0 BETA
--Faster & Lighter words detection
--Words will now detect properly
--Optimized regex pattern
--Regex patterns are now separated for better results
--nms_chataction cvar added
Version 3.01 BETA
--Fixed "replace buffer not big enough" when entering server
Version 3.02 BETA
--Replaced TrieGet* with TrieKeyExist
Version 3.1
--Added Old detection method
--Added nms_method cvar
--Added update notify
Version 3.2
--Punishment will stay after reconnect
--Some code refactored
======================================================
*/
#include <amxmodx>
#include <amxmisc>
#include <regex>
#include <fakemeta>
#define PLUGIN "NoMoreSh!t"
new const VERSION[] = "3.2";
#define AUTHOR "SpeeDeeR@amxmodxbg"
#pragma semicolon 1
#define SAY_BLOCK PLUGIN_HANDLED
#define SAY_OK PLUGIN_CONTINUE
#define MAXPLAYERS 32
#define IP_PATTERN "([0-9].*[*].*[1-9][0-9].*[*].*[0-9]{2}.*[*].*[0-9])"
#define DOMAIN_PATTERN "[a-zA-Z0-9\-\.]+\.(com|org|net|bg|info|COM|ORG|NET|BG|INFO)"
enum
{
BAD_WORD,
ADVERTISEMENT,
SPAM,
TOTAL_REASONS
};
new const szReasons[TOTAL_REASONS][] =
{
"Neprilichni dumi",
"IP/DOMAIN REKLAMA",
"SPAM"
};
new g_returnvalue;
new
Regex:g_IP_PATTERN,
Regex:g_DOMAIN_PATTERN;
new
pcvarTimesAllowed,
pcvarChatAction,
pcvarChatBan,
pcvarNoSpamEnabled,
pcvarBadWordsEnabled,
pcvarNoAdvertEnabled,
pcvarAdminImminuty,
pcvarDetectionMethod;
new
Trie:th_exc, //exceptions
Trie:th_punish, //punished players
Trie:th_words; //bad words
//cvar dependency
new Array: arr_words;
new
g_msg_SayText,
g_msg_TeamInfo;
new g_iMaxPlayers;
enum Data {
szName[32],
PunishStart,
LastSaid[128],
SpamCount,
bool: Connected,
bool: Immunity,
bool: Punished
};
new g_PData[MAXPLAYERS + 1][Data];
new g_iBadWordsNum; //replacing ArraySize()
enum Color
{
NORMAL = 1, // clients scr_concolor cvar color
GREEN, // Green Color
TEAM_COLOR, // Red, grey, blue
GREY, // grey
RED, // Red
BLUE, // Blue
}
new const g_prefix[] = "[NoMoreSh!t]";
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR);
register_clcmd("say", "SayHandle");
register_clcmd("say_team", "SayHandle");
register_concmd("nms_loadwords", "readBadWords");
register_concmd("nms_loadexceptions", "readExceptions");
pcvarTimesAllowed = register_cvar("nms_chatcount", "3");
pcvarChatAction = register_cvar("nms_chataction", "1");
pcvarChatBan = register_cvar("nms_chatban", "120");
pcvarNoSpamEnabled = register_cvar("nms_nospam", "1");
pcvarBadWordsEnabled = register_cvar("nms_badwords", "1");
pcvarNoAdvertEnabled = register_cvar("nms_noadvert", "1");
pcvarAdminImminuty = register_cvar("nms_adminimmune", "0");
pcvarDetectionMethod = register_cvar("nms_method", "1"); /* 1 - Array (old method) | 2 - Trie */
register_cvar( "nms_version", VERSION, FCVAR_SERVER | FCVAR_SPONLY );
set_cvar_string( "nms_version", VERSION );
register_forward(FM_ClientUserInfoChanged, "fwd_ClientUserInfoChanged");
th_exc = TrieCreate();
th_punish = TrieCreate();
new error[1];
g_IP_PATTERN = regex_compile(IP_PATTERN, g_returnvalue, error, charsmax(error) ,"s");
g_DOMAIN_PATTERN = regex_compile(DOMAIN_PATTERN, g_returnvalue, error, charsmax(error), "s");
g_msg_SayText = get_user_msgid("SayText");
g_msg_TeamInfo = get_user_msgid("TeamInfo");
g_iMaxPlayers = get_maxplayers();
readExceptions(0);
new ppcvar = get_pcvar_num(pcvarDetectionMethod);
if(ppcvar == 1)
{
arr_words = ArrayCreate(20);
}
else if(ppcvar == 2)
{
th_words = TrieCreate();
}
readBadWords(0);
}
public readBadWords(id)
{
if(!(get_user_flags(id) & ADMIN_RCON)) return;
new badwords_file[64];
get_configsdir( badwords_file, charsmax(badwords_file) );
add(badwords_file, charsmax(badwords_file), "/NMS_BADWORDS.ini");
if ( !file_exists(badwords_file) )
{
server_print ( "============================================" );
server_print ( "[NoMoreSh!t] %s file not found", badwords_file );
server_print ( "============================================" );
return;
}
g_iBadWordsNum = 0;
new ppcvar = get_pcvar_num(pcvarDetectionMethod);
if(ppcvar == 2 && th_words)
{
TrieClear(th_words);
}
else if(ppcvar == 1 && arr_words)
{
ArrayClear(arr_words);
}
new file = fopen(badwords_file,"r");
new badword[20], c;
while(fgets(file, badword, charsmax(badword)))
{
trim(badword);
if( !(c = badword[ 0 ])
|| c == ';'
|| c == '/') continue;
if(ppcvar == 1)
{
ArrayPushString(arr_words, badword);
}
else if(ppcvar == 2)
{
TrieSetCell(th_words, badword, true);
}
g_iBadWordsNum++;
}
server_print ("============================================");
server_print ("[NoMoreSh!t] %i bad words loaded", g_iBadWordsNum);
server_print ("============================================");
}
public readExceptions(id)
{
if(!(get_user_flags(id) & ADMIN_RCON)) return;
new exceptions_file[64];
get_configsdir( exceptions_file, charsmax(exceptions_file) );
add(exceptions_file, charsmax(exceptions_file), "/NMS_EXCEPTIONS.ini");
if ( !file_exists(exceptions_file) )
{
server_print ( "============================================" );
server_print ( "[NoMoreSh!t] %s file not found", exceptions_file );
server_print ( "============================================" );
return;
}
new ExceptionsNum;
new file = fopen(exceptions_file,"r");
new exception[30], c;
while(fgets(file, exception, charsmax(exception)))
{
trim(exception);
if( !(c = exception[ 0 ]) || c == '^n' || c == ';' ) continue;
TrieSetCell(th_exc, exception, ExceptionsNum++);
}
server_print ("============================================");
server_print ("[NoMoreSh!t] %i exceptions loaded", ExceptionsNum);
server_print ("============================================");
}
public SayHandle(id)
{
if(g_PData[id][Immunity] && get_pcvar_num( pcvarAdminImminuty ) ) return SAY_OK;
static arg[512];
read_args(arg, charsmax(arg));
remove_quotes(arg);
trim(arg);
strtolower(arg);
static len;
if(!(len = strlen(arg))) return SAY_BLOCK;
/*=========== Check for exceptions ======= */
if(TrieKeyExists(th_exc, arg))
return PLUGIN_CONTINUE;
new ppcvarChatBan = get_pcvar_num(pcvarChatBan);
/*=========== Check if user is punished ======= */
if(g_PData[id][Punished])
{
new punishtime = ppcvarChatBan - (time() - g_PData[id][PunishStart]);
if(punishtime > 0)
{
client_print(id, print_center, "Ostava%s %i sekund%s ot nakazanieto ti", punishtime > 1 ? "t":"", punishtime, punishtime > 1 ? "i":"a");
return SAY_BLOCK;
}
else
{
g_PData[id][Punished] = false;
}
}
/*=========== Check for IP/DOMAIN ======= */
if(get_pcvar_num(pcvarNoAdvertEnabled))
{
if(RegexCheck(id, arg, len, ppcvarChatBan))
{
return SAY_BLOCK;
}
}
/*=========== Clean the string ======= */
string_cleaner(arg, len);
/*=========== Check for bad words ======= */
if(get_pcvar_num(pcvarBadWordsEnabled))
{
if(BadWordCheck( id, arg, len, ppcvarChatBan, get_pcvar_num(pcvarDetectionMethod) ))
{
return SAY_BLOCK;
}
}
/*=========== Check for SPAM ======= */
if(get_pcvar_num(pcvarNoSpamEnabled))
{
if(SpamCheck(id, arg, ppcvarChatBan))
{
return SAY_BLOCK;
}
}
return SAY_OK;
}
public client_putinserver(id)
{
new szIP[20];
get_user_ip(id, szIP, charsmax(szIP), 1);
new punishtime;
TrieGetCell(th_punish, szIP, punishtime);
if((get_pcvar_num(pcvarChatBan) - (time() -punishtime)) > 0) {
g_PData[id][Punished] = true;
g_PData[id][PunishStart] = punishtime;
}
else {
g_PData[id][Punished] = false;
g_PData[id][PunishStart] = 0;
}
g_PData[id][Connected] = true;
g_PData[id][Immunity] = !!( get_user_flags(id) & ADMIN_BAN );
new len = charsmax(g_PData[]);
get_user_name(id, g_PData[id][szName], len);
new name[32];
copy(name, len, g_PData[id][szName]);
new ppcvar = get_pcvar_num(pcvarChatBan);
RegexCheck(id, name, len, ppcvar, true);
string_cleaner(name, len);
BadWordCheck(id, name, len, ppcvar, get_pcvar_num(pcvarDetectionMethod));
}
public client_disconnect(id)
{
if(g_PData[id][Punished])
{
if(get_pcvar_num(pcvarChatBan) - (time() - g_PData[id][PunishStart]) > 0)
{
new szIP[20];
get_user_ip(id, szIP, charsmax(szIP), 1);
TrieSetCell(th_punish, szIP, g_PData[id][PunishStart]);
}
}
g_PData[id][Punished] = false;
g_PData[id][Connected] = false;
g_PData[id][SpamCount]= 0;
}
public fwd_ClientUserInfoChanged(id, buffer)
{
static newname[32];
get_user_info(id, "name", newname, charsmax(newname));
if(equal(newname, g_PData[id][szName]))
{
return FMRES_IGNORED;
}
new name[32];
copy(name, charsmax(name), newname);
string_cleaner(name, charsmax(name), true);
if( regex_match_c( name, g_IP_PATTERN, g_returnvalue ) > 0 || regex_match_c( name, g_DOMAIN_PATTERN, g_returnvalue ) > 0 )
{
client_print(id, print_console, "IP/DOMAIN DETECTED IN NAME^nName change failed...");
engfunc(EngFunc_SetClientKeyValue, id, buffer, "name", g_PData[id][szName]);
return FMRES_SUPERCEDE;
}
else
{
copy(g_PData[id][szName], charsmax(g_PData[]), newname);
}
return FMRES_IGNORED;
}
string_cleaner( str[], len, bool:ip = false )
{
static i;
if(ip)
{
static const Special_IP_Chars[][]=
{
"~",
"!",
"@",
"#",
"$",
"%",
"^^",
"&",
"(",
")",
"-",
"+",
";",
":",
"/",
"\",
"|",
".",
",",
" "
};
for( i = 0; i < sizeof(Special_IP_Chars); i++ )
{
replace_all( str, len, Special_IP_Chars[i], "*");
}
return;
}
static const SpecialChars[][] =
{
"~",
"#",
"%",
"&",
";",
"*",
":",
"/",
"\",
".",
","
};
static ch;
for ( i = 0 ; i < len ; i++ )
{
ch = str[i];
if ( ch == '@')
{
ch = 'a';
}
if ( ch == '$' )
{
ch = 's';
}
if ( ch == '0' )
{
ch = 'o';
}
if ( ch == '7' )
{
ch = 't';
}
if ( ch == '5' )
{
ch = 's';
}
if ( ch == '<' )
{
ch = 'c';
}
if ( ch == '3' )
{
ch = 'e';
}
if ( ch == '!' )
{
ch = 'i';
}
if( ch == '+' )
{
ch = 't';
}
str[i] = ch;
}
for( i = 0; i < sizeof(SpecialChars); i++ )
{
replace_all( str, len, SpecialChars[i], "*");
}
replace_all( str, len, "(.)", ".");
replace_all( str, len, "|<", "k" );
replace_all( str, len, "|>", "p" );
replace_all( str, len, "()", "o" );
replace_all( str, len, "[]", "o" );
replace_all( str, len, "{}", "o" );
replace_all( str, len, "|-|", "h" );
replace_all( str, len, "\/\/", "w" );
replace_all( str, len, "\/", "v" );
}
RegexCheck(const id, const str[], len, iChatBan, bool:b_NameCheck = false)
{
static arg1[512];
copy(arg1, len, str);
string_cleaner(arg1, len, true);
if(regex_match_c( arg1, g_IP_PATTERN, g_returnvalue ) > 0 || regex_match_c( str, g_DOMAIN_PATTERN, g_returnvalue ) > 0)
{
if(!b_NameCheck)
{
if(iChatBan > 0)
{
g_PData[id][Punished] = true;
g_PData[id][PunishStart] = time();
if(get_pcvar_num(pcvarChatAction))
{
SendWarningMessage(g_PData[id][szName], iChatBan, ADVERTISEMENT);
}
}
}
else
{
server_cmd("kick #%d ^"IP/DOMAIN detected in name^"", get_user_userid(id));
}
return 1;
}
return 0;
}
BadWordCheck(const id, const str[], len, iChatBanLenght, method, bool: bNameCheck = false)
{
if(method == 1)
{
if(!arr_words)
{
arr_words = ArrayCreate(20);
readBadWords(0);
}
static word[20], lenght = charsmax(word);
static i;
for(i = 0 ; i < g_iBadWordsNum; i++)
{
ArrayGetString( arr_words, i, word, lenght);
if(containi ( str, word ) != -1 )
{
if(!bNameCheck)
{
if(iChatBanLenght)
{
if(get_pcvar_num(pcvarChatAction))
{
SendWarningMessage(g_PData[id][szName], iChatBanLenght, BAD_WORD);
}
g_PData[id][PunishStart] = time();
g_PData[id][Punished] = true;
}
}
else
{
server_cmd("kick #%d ^"Bad Word detected in name^"", get_user_userid(id));
}
return 1;
}
}
}
else if(method == 2)
{
if(!th_words)
{
th_words = TrieCreate();
readBadWords(0);
}
static spaces; spaces = 0;
for(new i; i < len; i++)
{
if(isspace(str[i]))
{
spaces++;
}
}
static word[32], i;
static arg1[512];
copy(arg1, len, str);
for(i = 0; i <= spaces; i++)
{
strbreak(arg1, word, charsmax(word), arg1, charsmax(arg1));
if(TrieKeyExists(th_words, word))
{
if(!bNameCheck)
{
if(iChatBanLenght)
{
if(get_pcvar_num(pcvarChatAction))
{
SendWarningMessage(g_PData[id][szName], iChatBanLenght, BAD_WORD);
}
g_PData[id][PunishStart] = time();
g_PData[id][Punished] = true;
}
}
else
{
server_cmd("kick #%d ^"Bad Word detected in name^"", get_user_userid(id));
}
return 1;
}
}
}
return 0;
}
SpamCheck(const id, const str[], iChatBan)
{
if(equal(g_PData[id][LastSaid], str))
{
if(++g_PData[id][SpamCount] >= get_pcvar_num(pcvarTimesAllowed))
{
if(iChatBan > 0)
{
if(get_pcvar_num(pcvarChatAction))
{
SendWarningMessage(g_PData[id][szName], iChatBan, SPAM);
}
g_PData[id][PunishStart] = time();
g_PData[id][Punished] = true;
}
return 1;
}
}
else
{
copy(g_PData[id][LastSaid], charsmax(g_PData[]), str);
g_PData[id][SpamCount] = 0;
}
return 0;
}
SendWarningMessage(const name[], iChatBan, iReason)
{
ColorChat(0, GREEN, "%s ^3%s ^1beshe nakazan za ^4%i ^1sekund%s lishavane ot chat ^4[%s]^1!", g_prefix, name , iChatBan, iChatBan > 1 ? "i" : "a", szReasons[iReason]);
}
/* Colorchat From Numb */
new TeamName[][] =
{
"",
"TERRORIST",
"CT",
"SPECTATOR"
};
ColorChat(id, Color:type, const msg[], {Float,Sql,Result,_}:...)
{
static message[256];
switch(type)
{
case NORMAL: // clients scr_concolor cvar color
{
message[0] = 0x01;
}
case GREEN: // Green
{
message[0] = 0x04;
}
default: // White, Red, Blue
{
message[0] = 0x03;
}
}
vformat(message[1], 251, msg, 4);
// Make sure message is not longer than 192 character. Will crash the server.
message[192] = '^0';
static team, ColorChange, index, MSG_Type;
if(id)
{
MSG_Type = MSG_ONE;
index = id;
}
else
{
index = FindPlayer();
MSG_Type = MSG_ALL;
}
team = get_user_team(index);
ColorChange = ColorSelection(index, MSG_Type, type);
ShowColorMessage(index, MSG_Type, message);
if(ColorChange)
{
Team_Info(index, MSG_Type, TeamName[team]);
}
}
ShowColorMessage(id, type, message[])
{
message_begin(type, g_msg_SayText, _, id);
write_byte(id);
write_string(message);
message_end();
}
Team_Info(id, type, team[])
{
message_begin(type, g_msg_TeamInfo, _, id);
write_byte(id);
write_string(team);
message_end();
return 1;
}
ColorSelection(index, type, Color:Type)
{
switch(Type)
{
case RED:
{
return Team_Info(index, type, TeamName[1]);
}
case BLUE:
{
return Team_Info(index, type, TeamName[2]);
}
case GREY:
{
return Team_Info(index, type, TeamName[0]);
}
}
return 0;
}
FindPlayer()
{
static i;
i = -1;
while(i <= g_iMaxPlayers)
{
if(g_PData[++i][Connected])
{
return i;
}
}
return -1;
}
/* ============== UPDATER ============== */
#include <sockets>
#define TASKID_GETANSWER 0
#define TASKID_CLOSECONNECTION 1
new g_Socket;
new g_Data[1000];
public plugin_cfg()
{
new error, getbuffer[512], len = charsmax(getbuffer);
g_Socket = socket_open("versionchecker.free.bg", 80, SOCKET_TCP, error);
switch (error)
{
case 1:
{
log_amx("[Version Checker] Unable to create socket.");
return;
}
case 2:
{
log_amx("[Version Checker] Unable to connect to hostname.");
return;
}
case 3:
{
log_amx("[Version Checker] Unable to connect to the HTTP port.");
return;
}
}
formatex(getbuffer, len, "GET %s HTTP/1.1^nHost:%s^r^n^r^n", "/nms.html" , "versionchecker.free.bg");
socket_send(g_Socket, getbuffer, len);
set_task(2.0, "task_waitanswer", TASKID_GETANSWER,. flags = "a",. repeat = 15);
set_task(16.0, "task_closeconnection", TASKID_CLOSECONNECTION);
}
public task_waitanswer()
{
if (socket_change(g_Socket,1))
{
socket_recv(g_Socket, g_Data, charsmax(g_Data));
new iPos = contain(g_Data, "Version") + strlen("Version :: ");
new version[20];
copyc(version, charsmax(version), g_Data[iPos], ';');
if(str_to_float(version) > str_to_float(VERSION))
{
iPos = contain(g_Data, "Last-Modified:");
new szLastModified[64];
copyc(szLastModified, charsmax(szLastModified), g_Data[iPos], 'C');
iPos = contain(g_Data, "Notes");
new szNotes[512];
copyc(szNotes, charsmax(szNotes), g_Data[iPos], ';');
server_print("^n======== NoMoreSh!t UPDATE AVAILABLE ========^n");
server_print("Your Version :: [%s]", VERSION);
server_print("New Version :: [%s]", version);
server_print(szNotes);
server_print(szLastModified);
server_print("======== NoMoreSh!t UPDATE AVAILABLE ========^n");
}
socket_close(g_Socket);
remove_task(TASKID_GETANSWER);
remove_task(TASKID_CLOSECONNECTION);
}
}
public task_closeconnection()
{
socket_close(g_Socket);
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1033\\ f0\\ fs16 \n\\ par }
*/