#include <amxmodx>
#include <amxmisc>

#define PLUGIN 		"Admin Chat Colors"
#define VERSION 	"2.0"
#define AUTHOR 		"Arion"

#define ACCESS_LEVEL	ADMIN_CHAT
#define ADMIN_LISTEN	ADMIN_BAN

new message[192]
new sayText
new teamInfo
new maxPlayers

new g_MessageColor
new g_NameColor
new g_AdminListen

new strName[191]
new strText[191]
new alive[11]

public plugin_init()
{
	register_plugin (PLUGIN, VERSION, AUTHOR)
	
	g_MessageColor = register_cvar ("amx_color", "2") // Message colors: [1] Default Yellow, [2] Green, [3] White, [4] Blue, [5] Red

	g_NameColor = register_cvar ("amx_namecolor", "6") // Name colors: [1] Default Yellow, [2] Green, [3] White, [4] Blue, [5] Red, [6] Team-color
	
	g_AdminListen = register_cvar ("amx_listen", "1") // Set whether admins see or not all messages (Alive, dead and team-only)
	
	
	sayText = get_user_msgid ("SayText")
	teamInfo = get_user_msgid ("TeamInfo")
	maxPlayers = get_maxplayers()
	
	
	register_message (sayText, "avoid_duplicated")
	
	register_clcmd ("amx_color", "set_color", ACCESS_LEVEL, "<color>")
	register_clcmd ("amx_namecolor", "set_name_color", ACCESS_LEVEL, "<color>")
	register_clcmd ("amx_listen", "set_listen", ACCESS_LEVEL, "<1 | 0>")
	
	register_clcmd ("say", "hook_say")
	register_clcmd ("say_team", "hook_teamsay")
}


public avoid_duplicated (msgId, msgDest, receiver)
{
	return PLUGIN_HANDLED
}


public hook_say(id)
{
	read_args (message, 191)
	remove_quotes (message)
	
	if (message[0] == '@' || message[0] == '/' || message[0] == '!' || equal (message, "")) // Ignores Admin Hud Messages, Admin Slash commands, 
											       // Gungame commands and empty messages
		return PLUGIN_CONTINUE

		
	new name[32]
	get_user_name (id, name, 31)
	
	new bool:admin = false
	
	if (get_user_flags(id) & ACCESS_LEVEL)
		admin = true
		
	
	new isAlive
	
	if (is_user_alive (id))
		{
			isAlive = 1
			alive = "^x01"
		}
	else
		{
			isAlive = 0
			alive = "^x01*DEAD* "
		}
	
	static color[10]
	

	
	if (admin)
		{
			// Name
			switch (get_pcvar_num (g_NameColor))
				{
					case 1:
						format (strName, 191, "%s%s", alive, name)

					case 2:
						format (strName, 191, "%s^x04%s", alive, name)
						
					case 3:
						{
							color = "SPECTATOR"
							format (strName, 191, "%s^x03%s", alive, name)
						}
						
					case 4:
						{
							color = "CT"
							format (strName, 191, "%s^x03%s", alive, name)
						}

					case 5:
						{
							color = "TERRORIST"
							format (strName, 191, "%s^x03%s", alive, name)
						}
					
					case 6:
						{
							get_user_team (id, color, 9)
								
							format (strName, 191, "%s^x03%s", alive, name)
						}
				}
			
			
			// Message
			switch (get_pcvar_num (g_MessageColor))
				{
					case 1:	// Yellow
						format (strText, 191, "%s", message)
						
					case 2:	// Green
						format (strText, 191, "^x04%s", message)
						
					case 3:	// White
						{
							copy (color, 9, "SPECTATOR")
							format (strText, 191, "^x03%s", message)
						}

					case 4:	// Blue
						{
							copy (color, 9, "CT")
							format (strText, 191, "^x03%s", message)
						}
						
					case 5:	// Red
						{
							copy (color, 9, "TERRORIST")
							format (strText, 191, "^x03%s", message)
						}
				}
		}
	
	else 	// Player is not admin. Team-color name : Yellow message
		{
			get_user_team (id, color, 9)
			
			format (strName, 191, "%s^x03%s", alive, name)
			
			format (strText, 191, "%s", message)
		}

	format (message, 191, "%s^x01 :  %s", strName, strText)
			
	sendMessage (color, isAlive)	// Sends the colored message
	
	return PLUGIN_CONTINUE
}


public hook_teamsay(id)
{
	new playerTeam = get_user_team(id)
	new playerTeamName[19]
	
	switch (playerTeam) // Team names which appear on team-only messages
		{
			case 1:
				copy (playerTeamName, 11, "Terrorists")
				
			case 2:
				copy (playerTeamName, 18, "Counter-Terrorists")
				
			default:
				copy (playerTeamName, 9, "Spectator")
		}
		
	read_args (message, 191)
	remove_quotes (message)
	
	if (message[0] == '@' || message[0] == '/' || message[0] == '!' || equal (message, "")) // Ignores Admin Hud Messages, Admin Slash commands, 
											       // Gungame commands and empty messages
		return PLUGIN_CONTINUE

		
	new name[32]
	get_user_name (id, name, 31)
	
	new bool:admin = false
	
	if (get_user_flags(id) & ACCESS_LEVEL)
		admin = true
		
	
	new isAlive
	
	if (is_user_alive (id))
		{
			isAlive = 1
			alive = "^x01"
		}
	else
		{
			isAlive = 0
			alive = "^x01*DEAD* "
		}
	
	static color[10]
	

	
	if (admin)
		{
			// Name
			switch (get_pcvar_num (g_NameColor))
				{
					case 1:
						format (strName, 191, "%s(%s) %s", alive, playerTeamName, name)

					case 2:
						format (strName, 191, "%s(%s) ^x04%s", alive, playerTeamName, name)
						
					case 3:
						{
							color = "SPECTATOR"
							format (strName, 191, "%s(%s) ^x03%s", alive, playerTeamName, name)
						}
						
					case 4:
						{
							color = "CT"
							format (strName, 191, "%s(%s) ^x03%s", alive, playerTeamName, name)
						}

					case 5:
						{
							color = "TERRORIST"
							format (strName, 191, "%s(%s) ^x03%s", alive, playerTeamName, name)
						}
					
					case 6:
						{
							get_user_team (id, color, 9)
								
							format (strName, 191, "%s(%s) ^x03%s", alive, playerTeamName, name)
						}
				}
			
			
			// Message
			switch (get_pcvar_num (g_MessageColor))
				{
					case 1:	// Yellow
						format (strText, 191, "%s", message)
						
					case 2:	// Green
						format (strText, 191, "^x04%s", message)
						
					case 3:	// White
						{
							copy (color, 9, "SPECTATOR")
							format (strText, 191, "^x03%s", message)
						}

					case 4:	// Blue
						{
							copy (color, 9, "CT")
							format (strText, 191, "^x03%s", message)
						}
						
					case 5:	// Red
						{
							copy (color, 9, "TERRORIST")
							format (strText, 191, "^x03%s", message)
						}
				}
		}
	
	else 	// Player is not admin. Team-color name : Yellow message
		{
			get_user_team (id, color, 9)
			
			format (strName, 191, "%s(%s) ^x03%s", alive, playerTeamName, name)
			
			format (strText, 191, "%s", message)
		}
	
	format (message, 191, "%s ^x01:  %s", strName, strText)
	
	sendTeamMessage (color, isAlive, playerTeam)	// Sends the colored message
	
	return PLUGIN_CONTINUE	
}


public set_color (id, level, cid)
{
	if (!cmd_access(id, level, cid, 2))
		return PLUGIN_HANDLED
		
	new arg[1], newColor
	read_argv (1, arg, 1)
	
	newColor = str_to_num (arg)
	
	if (newColor >= 1 && newColor <= 5)
		{
			set_cvar_num ("amx_color", newColor)
			set_pcvar_num (g_MessageColor, newColor)
	
			if (get_pcvar_num (g_NameColor) != 1 &&
			       ((newColor == 3 &&  get_pcvar_num (g_NameColor) != 3)
			     || (newColor == 4 &&  get_pcvar_num (g_NameColor) != 4)
			     || (newColor == 5 &&  get_pcvar_num (g_NameColor) != 5)))
				{
					set_cvar_num ("amx_namecolor", 2)
					set_pcvar_num (g_NameColor, 2)
				}
		}
		
	return PLUGIN_HANDLED
}


public set_name_color (id, level, cid)
{
	if (!cmd_access(id, level, cid, 2))
		return PLUGIN_HANDLED
		
	new arg[1], newColor
	read_argv (1, arg, 1)
	
	newColor = str_to_num (arg)
	
	if (newColor >= 1 && newColor <= 6)
		{
			set_cvar_num ("amx_namecolor", newColor)
			set_pcvar_num (g_NameColor, newColor)
			
			if ((get_pcvar_num (g_MessageColor) != 1
			    && ((newColor == 3 &&  get_pcvar_num (g_MessageColor) != 3)
			     || (newColor == 4 &&  get_pcvar_num (g_MessageColor) != 4)
			     || (newColor == 5 &&  get_pcvar_num (g_MessageColor) != 5)))
			     || get_pcvar_num (g_NameColor) == 6)
				{
					set_cvar_num ("amx_color", 2)
					set_pcvar_num (g_MessageColor, 2)
				}
		}
	
	return PLUGIN_HANDLED
}


public set_listen (id, level, cid)
{
	if (!cmd_access(id, level, cid, 2))
		return PLUGIN_HANDLED
		
	new arg[1], newListen
	read_argv(1, arg, 1)
	
	newListen = str_to_num (arg)
	
	set_cvar_num ("amx_listen", newListen)
	set_pcvar_num (g_AdminListen, newListen)
	
	return PLUGIN_HANDLED
}


public sendMessage (color[], alive)
{
	new teamName[10]
	
	for (new player = 1; player < maxPlayers; player++)
		{
			if (!is_user_connected(player))
				continue

			if (alive && is_user_alive(player) || !alive && !is_user_alive(player) || get_pcvar_num(g_AdminListen) && get_user_flags(player) & ADMIN_LISTEN)
				{
					get_user_team (player, teamName, 9)	// Stores user's team name to change back after sending the message
					
					changeTeamInfo (player, color)		// Changes user's team according to color choosen
					
					writeMessage (player, message)		// Writes the message on player's chat
					
					changeTeamInfo (player, teamName)	// Changes user's team back to original
				}
		}
}


public sendTeamMessage (color[], alive, playerTeam)
{
	new teamName[10]
	
	for (new player = 1; player < maxPlayers; player++)
		{
			if (!is_user_connected(player))
				continue

			if (get_user_team(player) == playerTeam || get_pcvar_num(g_AdminListen) && get_user_flags(player) & ADMIN_LISTEN)
				{
					if (alive && is_user_alive(player) || !alive && !is_user_alive(player) || get_pcvar_num(g_AdminListen) && get_user_flags(player) & ADMIN_LISTEN)
						{
							get_user_team (player, teamName, 9)	// Stores user's team name to change back after sending the message
							
							changeTeamInfo (player, color)		// Changes user's team according to color choosen
							
							writeMessage (player, message)		// Writes the message on player's chat
							
							changeTeamInfo (player, teamName)	// Changes user's team back to original
						}
				}
		}
}


public changeTeamInfo (player, team[])
{
	message_begin (MSG_ONE, teamInfo, _, player)	// Tells to to modify teamInfo (Which is responsable for which time player is)
	write_byte (player)				// Write byte needed
	write_string (team)				// Changes player's team
	message_end()					// Also Needed
}


public writeMessage (player, message[])
{
	message_begin (MSG_ONE, sayText, {0, 0, 0}, player)	// Tells to modify sayText (Which is responsable for writing colored messages)
	write_byte (player)					// Write byte needed
	write_string (message)					// Effectively write the message, finally, afterall
	message_end ()						// Needed as always
}
#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", "abd");
	
	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, "Warning!!! Possible IP / Website advertising! [%d/%d] - Kick", g_iWarnings[id], MAX_WARNINGS);
				#else
					client_print_color(id, RED, "^3Warning!!! ^1Possible ^4IP ^1/ ^4Website ^1advertising! ^4[^3%d^1/^3%d^4] ^1- Kick", g_iWarnings[id], MAX_WARNINGS);
				#endif
				
				if(g_iWarnings[id] == 3)
				{
					server_cmd("kick #%d ^"Advertising!^"", get_user_userid(id));
					g_iWarnings[id] = 0;
				}
			}
			else
			{
				#if !defined USE_COLORCHAT
					client_print(id, print_chat, "Warning!!! Possible IP / Website advertising!");
				#else
					client_print_color(id, RED, "^3Warning!!! ^1Possible ^4IP ^1/ ^4Website ^1advertising!");
				#endif
			}
		}
		if(iFlags & ADV_LOG)
		{
			new szName[32];
			get_user_name(id, szName, charsmax(szName));
			
			new iFile = fopen(g_szLogsFile, "a");
			fprintf(iFile, "Name: %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("Error loading configuration file!");
	
	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);
}
#include <amxmodx>
#include <amxmisc> 
 
// max number of words in word list 
#define MAX_WORDS 192 
 
new g_swearsNames[MAX_WORDS][32] 
new g_swearsNum 
 
public plugin_init() 
{ 
	register_plugin("Swear Filter","1.0a","SuicideDog") 
	register_clcmd("say","swearcheck") 
	register_clcmd("say_team","swearcheck")
	readList()
}
 
readList() 
{ 
    // file to read words from 
	new szCustomDir[64]
	new filename[64]
	get_customdir( szCustomDir, 63 )
	format(filename, 63, "%s/swear/swearwords.ini", szCustomDir )
 
	if(!file_exists(filename) ){
		log_message("Swear Filter: file %s not found", filename) 
		return 
	} 
	new iLen 
	while( g_swearsNum < MAX_WORDS && read_file(filename, g_swearsNum ,g_swearsNames[g_swearsNum][1],30,iLen) ) 
	{ 
	if( g_swearsNames[g_swearsNum][0] == ';') continue
	g_swearsNames[g_swearsNum][0] = iLen 
	++g_swearsNum 
	}
	log_message("Swear Filter: loaded %d words",g_swearsNum ) 
} 
 
public swearcheck(id) 
{
	new szSaid[192]
	read_args(szSaid,191)
	new bool:found = false
 
	new name[32],ip[32]
	get_user_name(id,name,31)
	get_user_ip(id,ip,31)
 
	new pos, i = 0
	while ( i < g_swearsNum )
	{
	if ( (pos = containi(szSaid,g_swearsNames[i][1])) != -1 ){ 
		new len = g_swearsNames[i][0] 
		while(len--)
		szSaid[pos++] = '*'
		log_amx("%s (%s) karomkodas",name,ip)
		found = true 
		continue
	}
	++i
	}
	if ( found ){ 
		new cmd[32]
		read_argv(0,cmd,31)          
		engclient_cmd(id,cmd,szSaid)    
	}
	return PLUGIN_CONTINUE 
} 
 
 
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ ansicpg1250\\ deff0\\ deflang1048{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ f0\\ fs16 \n\\ par }
*/
