#include <amxmodx>
#include <amxmisc>
#include <colorchat>
#define PLUGIN "Block Advertising"
#define VERSION "1.3"
#define AUTHOR "Alka"
#define USE_COLORCHAT
#define MAX_WARNINGS 3
#define MAX_LOGS 50
#define BYPASS_FLAG ADMIN_RCON
#define IsValidBlock(%0) (0 <= str_to_num(%0) <= 255)
enum (<<=1) {
ADV_BLOCK = 1,
ADV_WARN,
ADV_KICK,
ADV_LOG,
ADV_BYPASS
};
enum {
ADDR_VALID = 1,
ADDR_NOT_FOUND = -1
};
new g_pCvarMode;
new Trie:g_tChars, Trie:g_tBlocks;
new Array:g_aDomains, Array:g_aWhitelist;
new g_iWarnings[33];
new g_szLogsFile[64];
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHOR);
register_clcmd("say", "clcmd_HandleChat");
register_clcmd("say_team", "clcmd_HandleChat");
g_pCvarMode = register_cvar("amx_advblock", "abcde");
g_tChars = TrieCreate();
g_tBlocks = TrieCreate();
g_aDomains = ArrayCreate(6);
g_aWhitelist = ArrayCreate(32);
}
public plugin_cfg()
{
get_basedir(g_szLogsFile, charsmax(g_szLogsFile));
add(g_szLogsFile, charsmax(g_szLogsFile), "/logs/advblock_logs.log");
if(file_size(g_szLogsFile, 1) / 3 > MAX_LOGS)
fclose(fopen(g_szLogsFile, "w"));
else
fclose(fopen(g_szLogsFile, "a"));
LoadConfigs();
}
public plugin_end()
{
TrieDestroy(g_tChars);
TrieDestroy(g_tBlocks);
ArrayDestroy(g_aDomains);
ArrayDestroy(g_aWhitelist);
}
public client_disconnect(id)
{
if(g_iWarnings[id] > 0)
g_iWarnings[id] = 0;
}
public clcmd_HandleChat(id)
{
if((GetModFlags() & ADV_BYPASS) && get_user_flags(id) & BYPASS_FLAG)
return PLUGIN_CONTINUE;
new szText[191];
read_args(szText, charsmax(szText));
remove_quotes(szText);
if(strlen(szText) < 4)
return PLUGIN_CONTINUE;
TrieClear(g_tBlocks);
new szBlock[4], iLen;
new iNumSeq, iNumBlocks, iDel;
new iLastBlock;
new bool:bDuplicate;
for(new i = 0 ; i < sizeof szText ; i++)
{
if(isdigit(szText[i]) && (i + 1 < sizeof szText))
{
iLen += formatex(szBlock[iLen], charsmax(szBlock) - iLen, "%c", szText[i]);
if(isdigit(szText[i + 1]))
iNumSeq++;
else
{
if(IsValidBlock(szBlock))
{
if(!TrieKeyExists(g_tBlocks, szBlock))
{
TrieSetCell(g_tBlocks, szBlock, 1);
new iTo = strlen(szBlock) == 3 ? i - 2 : (strlen(szBlock) == 2 ? i - 1 : i);
if(FindDiffChars(szText, charsmax(szText), iLastBlock, iTo) < 8)
iNumBlocks++;
iLastBlock = i;
}
else if(TrieKeyExists(g_tBlocks, szBlock) && !bDuplicate)
{
new iTo = strlen(szBlock) == 3 ? i - 2 : (strlen(szBlock) == 2 ? i - 1 : i);
if(FindDiffChars(szText, charsmax(szText), iLastBlock, iTo) < 8)
iNumBlocks++;
iLastBlock = i;
bDuplicate = true;
}
}
iLen = 0;
}
}
else
{
if(szText[i] != 0)
{
iDel++;
}
}
}
if((iNumSeq > 0 && iNumBlocks > 3) || (iNumBlocks > 3 && iDel > 5) || CheckAddr(szText, charsmax(szText)) != ADDR_NOT_FOUND)
{
new iFlags = GetModFlags();
if(iFlags & ADV_WARN)
{
if(iFlags & ADV_KICK)
{
g_iWarnings[id]++;
#if !defined USE_COLORCHAT
client_print(id, print_chat, "Figyelem!!! IP / Weboldal hirdetés! [%d/%d] - Kick", g_iWarnings[id], MAX_WARNINGS);
#else
client_print_color(id, RED, "^3Figyelem!!! ^4IP ^1/ ^4Weboldal ^1hirdetés! ^4[^3%d^1/^3%d^4] ^1- Kick", g_iWarnings[id], MAX_WARNINGS);
#endif
if(g_iWarnings[id] == 3)
{
server_cmd("kick #%d ^"Hirdetes!^"", get_user_userid(id));
g_iWarnings[id] = 0;
}
}
else
{
#if !defined USE_COLORCHAT
client_print(id, print_chat, "Figyelem!!! IP / Weboldal hirdetes!");
#else
client_print_color(id, RED, "^3Figyelem!!! ^4IP ^1/ ^4Weboldal ^1hirdetés!");
#endif
}
}
if(iFlags & ADV_LOG)
{
new szName[32];
get_user_name(id, szName, charsmax(szName));
new iFile = fopen(g_szLogsFile, "a");
fprintf(iFile, "Nev: %s ^nChat: %s^n---------------------------------------^n", szName, szText);
fclose(iFile);
}
if(iFlags & ADV_BLOCK)
return PLUGIN_HANDLED;
else
return PLUGIN_CONTINUE;
}
return PLUGIN_CONTINUE;
}
stock FindDiffChars(szString[], iLen, iFrom, iTo)
{
TrieClear(g_tChars);
new iChars;
for(new i = 0 ; i < iLen ; i++)
{
if(iFrom < i < iTo)
{
new szChar[2];
formatex(szChar, charsmax(szChar), "%c", szString[i]);
if(!TrieKeyExists(g_tChars, szChar))
{
TrieSetCell(g_tChars, szChar, 1);
iChars++;
}
}
}
return iChars;
}
stock CheckAddr(szString[], iLen)
{
new szText[128], iLen2;
new i;
for(i = 0 ; i < iLen ; i++)
{
if(!isalpha(szString[i]) && !ValidAddrSeparator(szString[i]))
continue;
iLen2 += formatex(szText[iLen2], charsmax(szText) - iLen2, "%c", szString[i]);
}
new szTemp[6], szTemp1[32];
for(i = 0 ; i < ArraySize(g_aWhitelist) ; i++)
{
ArrayGetString(g_aWhitelist, i, szTemp1, charsmax(szTemp1));
if(containi(szText, szTemp1) != -1)
{
replace(szText, charsmax(szText), szTemp1, "");
i--;
}
}
for(i = 0 ; i < ArraySize(g_aDomains) ; i++)
{
ArrayGetString(g_aDomains, i, szTemp, charsmax(szTemp));
if(containi(szText, szTemp) > 0)
return ADDR_VALID;
}
return ADDR_NOT_FOUND;
}
stock bool:ValidAddrSeparator(iChar)
{
new iChars[] = { ':', '/', '.' };
for(new i = 0 ; i < sizeof iChars ; i++)
{
if(iChar == iChars[i])
return true;
}
return false;
}
stock GetModFlags()
{
new szVal[6];
get_pcvar_string(g_pCvarMode, szVal, charsmax(szVal));
return read_flags(szVal);
}
stock LoadConfigs()
{
new szFile[64];
get_configsdir(szFile, charsmax(szFile));
add(szFile, charsmax(szFile), "/advblock_config.ini");
new iFile = fopen(szFile, "r");
if(!iFile)
set_fail_state("Nem sikerult a konfig fajl betoltese!");
new szBuffer[32];
new iConfig;
while(!feof(iFile))
{
fgets(iFile, szBuffer, charsmax(szBuffer));
trim(szBuffer);
if(!szBuffer[0] || szBuffer[0] == ';')
continue;
if(equal(szBuffer, "#domains"))
{
iConfig = 1;
continue;
}
else if(equal(szBuffer, "#whitelist"))
{
iConfig = 2;
continue;
}
else
{
if(szBuffer[0] != '{' || szBuffer[0] != '}')
{
switch(iConfig)
{
case 1: ArrayPushString(g_aDomains, szBuffer);
case 2: ArrayPushString(g_aWhitelist, szBuffer);
}
}
}
}
fclose(iFile);
}