#include <amxmodx>
#include <amxmisc>
#include <engine>
 
#define PLUGIN "ADMIN Gag"
#define VERSION "1.0.1"
#define AUTHOR "RaZzoR"
 
#define GAG_FLAG ADMIN_BAN
#define GAG_IMMUNITY ADMIN_IMMUNITY
 
#define DICTIONARY "admin_gag.txt"
#define USE_COLOR_CHAT 
 
#if defined USE_COLOR_CHAT 
	#include <colorchat>
#endif
 
new const gag_file_name[] = "gagged_users.txt"
 
enum _:GagData {
	gag_name[32],
	gag_steamid[35],
	gag_length,
	ungag_time[32],
	gag_reason[128]
}
 
new Trie:g_trie
new Array:g_array
new total_gags, g_ungag_entity
new gag_file[64], Float:get_gag_time[33], tempid[33]
 
new gag_immunity, gag_ungagcheck
 
public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
 
	#if defined USE_COLOR_CHAT 
		register_dictionary_colored(DICTIONARY)	
	#else
		register_dictionary(DICTIONARY)	
	#endif
 
	gag_immunity = register_cvar("gag_immunity", "1")
	gag_ungagcheck = register_cvar("gag_ungagcheck", "1.0")
 
	register_clcmd("say /gag_menu", "gag_menu")
	register_clcmd("say /ungag_menu", "ungag_menu")	
 
	register_clcmd("say", "gag_say")
	register_clcmd("say_team", "gag_say")	
 
	register_clcmd("GAG_TIME", "clcmd_time")
	register_clcmd("GAG_REASON", "clcmd_reason")
 
	register_concmd("gag_authid", "concmd_gag_authid", GAG_FLAG, "<nev, #userid, authid> <ido percben> <ok>")
	register_concmd("gag_ip", "concmd_gag_ip", GAG_FLAG, "<nev, #userid, authid> <ido percben> <ok>")
	register_concmd("gag_add", "concmd_gag_add", GAG_FLAG, "<nev> <authid vagy ip> <ido percben> <ok>")
	register_concmd("gag_list", "concmd_gag_list", GAG_FLAG, "[start] -- megmutat minden nemitast")
	register_concmd("ungag", "concmd_ungag", GAG_FLAG, "<authid vagy ip>")
 
	get_datadir(gag_file, sizeof(gag_file) - 1)
	format(gag_file, sizeof(gag_file) - 1, "%s/%s", gag_file, gag_file_name)
 
	g_trie = TrieCreate()
	g_array = ArrayCreate(GagData)
 
	LoadGags()
}
 
public plugin_cfg() create_ungag_entity()
 
public client_PostThink(id) {
	static authid[35]
	get_user_authid(id, authid, sizeof(authid) - 1)
 
	static ip[35]
	get_user_ip(id, ip, sizeof(ip) - 1, 1)
 
	static array_pos	
	if(TrieGetCell(g_trie, authid, array_pos) || TrieGetCell(g_trie, ip, array_pos)) set_speak(id, SPEAK_MUTED)
	else set_speak(id, SPEAK_LISTENALL)
}
 
public create_ungag_entity() {
	static failtimes
 
	g_ungag_entity = create_entity("info_target")
 
	if(!is_valid_ent(g_ungag_entity)) {
		++failtimes
 
		log_amx("%L", LANG_SERVER, "FAILED_TO_CREATE_UNGAG_ENTITY", failtimes)
 
		if(failtimes < 10) set_task(1.0, "create_ungag_entity")
		else log_amx("%L", LANG_SERVER, "COULD_NOT_CREATE_UNGAG_ENTITY")
 
		return
	}
 
	entity_set_string(g_ungag_entity, EV_SZ_classname, "ungag_entity")
	entity_set_float(g_ungag_entity, EV_FL_nextthink, get_gametime() + 1.0)
 
	register_think("ungag_entity", "UnGag_Check")
}
 
public UnGag_Check(entity)
{
	if(entity != g_ungag_entity) return
 
	if(total_gags > 0)
	{
		static _hours[5], _minutes[5], _seconds[5], _month[5], _day[5], _year[7]
		format_time(_hours, sizeof(_hours) - 1, "%H")
		format_time(_minutes, sizeof(_minutes) - 1, "%M")
		format_time(_seconds, sizeof(_seconds) - 1, "%S")
		format_time(_month, sizeof(_month) - 1, "%m")
		format_time(_day, sizeof(_day) - 1, "%d")
		format_time(_year, sizeof(_year) - 1, "%Y")
 
 
		new c_hours = str_to_num(_hours)
		new c_minutes = str_to_num(_minutes)
		new c_seconds = str_to_num(_seconds)
		new c_month = str_to_num(_month)
		new c_day = str_to_num(_day)
		new c_year = str_to_num(_year)
 
		static load_ungag_time[32]
		static u_hours, u_minutes, u_seconds, u_month, u_day, u_year
 
		for(new i = 0; i < total_gags; i++) {
			static data[GagData]
			ArrayGetArray(g_array, i, data)
 
			if(data[gag_length] == 0) continue
 
			copy(load_ungag_time, sizeof(load_ungag_time) - 1, data[ungag_time])
 
			replace_all(load_ungag_time, sizeof(load_ungag_time) - 1, ":", " ")
			replace_all(load_ungag_time, sizeof(load_ungag_time) - 1, "/", " ")
 
			parse(load_ungag_time,\
				_hours, sizeof(_hours) - 1,\
				_minutes, sizeof(_minutes) - 1,\
				_seconds, sizeof(_seconds) - 1,\
				_month, sizeof(_month) - 1,\
				_day, sizeof(_day) - 1,\
				_year, sizeof(_year) - 1
				)
 
			u_hours = str_to_num(_hours)
			u_minutes = str_to_num(_minutes)
			u_seconds = str_to_num(_seconds)
			u_month = str_to_num(_month)
			u_day = str_to_num(_day)
			u_year = str_to_num(_year)
 
			if( u_year < c_year
			|| u_year == c_year && u_month < c_month
			|| u_year == c_year && u_month == c_month && u_day < c_day
			|| u_year == c_year && u_month == c_month && u_day == c_day && u_hours < c_hours
			|| u_year == c_year && u_month == c_month && u_day == c_day && u_hours == c_hours && u_minutes < c_minutes
			|| u_year == c_year && u_month == c_month && u_day == c_day && u_hours == c_hours && u_minutes == c_minutes && u_seconds <= c_seconds ) {
				#if defined USE_COLOR_CHAT 
					ColorChat(0, RED, "%L", LANG_PLAYER, "GAG_EXPIRED", data[gag_name], data[gag_steamid], data[gag_reason])
				#else
					NoColorChat(0, "%L", LANG_PLAYER, "GAG_EXPIRED", data[gag_name], data[gag_steamid], data[gag_reason])
				#endif
 
				RemoveGag(i, data[gag_steamid])
 
				i--
			}
		}
	}
 
	entity_set_float(g_ungag_entity, EV_FL_nextthink, get_gametime() + get_pcvar_float(gag_ungagcheck))
}
 
public concmd_gag_authid(id, level, cid) {
	if(!cmd_access(id, level, cid, 4)) return PLUGIN_HANDLED
 
	static arg[128]
	read_argv(1, arg, sizeof(arg) - 1)
 
	new target = cmd_target(id, arg, GetTargetFlags(id))
	if(!target) return PLUGIN_HANDLED
 
	static target_authid[35]
	get_user_authid(target, target_authid, sizeof(target_authid) - 1)
 
	if(TrieKeyExists(g_trie, target_authid)) {
		console_print(id, "%L", id, "ALREADY_GAGGED_STEAMID", target_authid)
		return PLUGIN_HANDLED
	}
 
	read_argv(2, arg, sizeof(arg) - 1)
	new Float:length = str_to_float(arg)
 
	static ungag_time2[64], gag_time2[64]
 
	if(length == 0.0) formatex(ungag_time2, sizeof(ungag_time2) - 1, "%L", id, "PERMANENT_GAG")
	else GenerateUnGagTime(length, ungag_time2, sizeof(ungag_time2) - 1)
 
	read_argv(3, arg, sizeof(arg) - 1)
 
	static admin_name[64], target_name[32]
	get_user_name(id, admin_name, sizeof(admin_name) - 1)
	get_user_name(target, target_name, sizeof(target_name) - 1)
 
	static admin_authid[35]
	get_user_authid(id, admin_authid, sizeof(admin_authid) - 1)
 
	GagAdd(target_name, target_authid, arg, floatround(length * 60.0, floatround_floor), ungag_time2)
 
	GetGagTime(id, length, gag_time2, sizeof(gag_time2) - 1)
 
	#if defined USE_COLOR_CHAT 
		ColorChat(0, RED, "%L", LANG_PLAYER, "GAG_PLAYER", admin_name, admin_authid, target_name, arg, gag_time2, ungag_time2)
	#else
		NoColorChat(0, "%L", LANG_PLAYER, "GAG_PLAYER", admin_name, admin_authid, target_name, arg, gag_time2, ungag_time2)
	#endif
 
	return PLUGIN_HANDLED
}
 
public concmd_gag_ip(id, level, cid) {
	if(!cmd_access(id, level, cid, 4)) return PLUGIN_HANDLED
 
	static arg[128]
	read_argv(1, arg, sizeof(arg) - 1)
 
	new target = cmd_target(id, arg, GetTargetFlags(id))
	if(!target) return PLUGIN_HANDLED
 
	static target_ip[35]
	get_user_ip(target, target_ip, sizeof(target_ip) - 1, 1)
 
	if(TrieKeyExists(g_trie, target_ip)) {
		console_print(id, "%L", id, "ALREADY_GAGGED_IP", target_ip)
		return PLUGIN_HANDLED
	}
 
	read_argv(2, arg, sizeof(arg) - 1)
	new Float:length = str_to_float(arg)
 
	static ungag_time2[64], gag_time2[64]
 
	if(length == 0.0) formatex(ungag_time2, sizeof(ungag_time2) - 1, "%L", id, "PERMANENT_GAG")
	else GenerateUnGagTime(length, ungag_time2, sizeof(ungag_time2) - 1)
 
	read_argv(3, arg, sizeof(arg) - 1)
 
	static admin_name[64], target_name[32]
	get_user_name(id, admin_name, sizeof(admin_name) - 1)
	get_user_name(target, target_name, sizeof(target_name) - 1)
 
	static admin_authid[35]
	get_user_authid(id, admin_authid, sizeof(admin_authid) - 1)
 
	GagAdd(target_name, target_ip, arg, floatround(length * 60.0, floatround_floor), ungag_time2)
 
	GetGagTime(id, length, gag_time2, sizeof(gag_time2) - 1)
 
	#if defined USE_COLOR_CHAT 
		ColorChat(0, RED, "%L", LANG_PLAYER, "GAG_PLAYER", admin_name, admin_authid, target_name, arg, gag_time2, ungag_time2)
	#else
		NoColorChat(0, "%L", LANG_PLAYER, "GAG_PLAYER", admin_name, admin_authid, target_name, arg, gag_time2, ungag_time2)
	#endif
 
	return PLUGIN_HANDLED
}
 
public concmd_gag_add(id, level, cid) {
	if(!cmd_access(id, level, cid, 5)) return PLUGIN_HANDLED
 
	static target_name[128], target_authid[128], gagtime[128], reason[128]
	read_argv(1, target_name, sizeof(target_name) - 1)
	read_argv(2, target_authid, sizeof(target_authid) - 1)
	read_argv(3, gagtime, sizeof(gagtime) - 1)
	read_argv(4, reason, sizeof(reason) - 1)
 
	new bool:is_ip = bool:(containi(target_authid, ".") != -1)
 
	if(TrieKeyExists(g_trie, target_authid)) {
		console_print(id, "%L", id, is_ip ? "ALREADY_GAGGED_IP" : "ALREADY_GAGGED_STEAMID", target_authid)
		return PLUGIN_HANDLED
	}
 
	new Float:length = str_to_float(gagtime) 
	static ungag_time2[64], gag_time2[64]
 
	if(length == 0.0) formatex(ungag_time2, sizeof(ungag_time2) - 1, "%L", id, "PERMANENT_GAG")
	else GenerateUnGagTime(length, ungag_time2, sizeof(ungag_time2) - 1)
 
	static admin_name[64]
	get_user_name(id, admin_name, sizeof(admin_name) - 1)
 
	static admin_authid[35]
	get_user_authid(id, admin_authid, sizeof(admin_authid) - 1)
 
	GagAdd(target_name, target_authid, reason, floatround(length * 60.0, floatround_floor), ungag_time2)
 
	GetGagTime(id, length, gag_time2, sizeof(gag_time2) - 1)
 
	#if defined USE_COLOR_CHAT 
		ColorChat(0, RED, "%L", LANG_PLAYER, "GAG_PLAYER", admin_name, admin_authid, target_name, reason, gag_time2, ungag_time2)
	#else
		NoColorChat(0, "%L", LANG_PLAYER, "GAG_PLAYER", admin_name, admin_authid, target_name, reason, gag_time2, ungag_time2)
	#endif
 
	return PLUGIN_HANDLED
}	
 
public concmd_ungag(id, level, cid) {
	if(!cmd_access(id, level, cid, 2)) return PLUGIN_HANDLED
 
	static arg[35]
	read_argv(1, arg, sizeof(arg) - 1)
 
	if(TrieKeyExists(g_trie, arg)) {
		static array_pos;
		TrieGetCell(g_trie, arg, array_pos);
 
		static data[GagData]
		ArrayGetArray(g_array, array_pos, data)
 
		static admin_name[64]
		get_user_name(id, admin_name, sizeof(admin_name) - 1)
 
		static authid[35]
		get_user_authid(id, authid, sizeof(authid) - 1)
 
		#if defined USE_COLOR_CHAT 
			ColorChat(0, RED, "%L", LANG_PLAYER, "UNGAG_PLAYER", admin_name, authid, data[gag_name], data[gag_steamid], data[gag_reason])
		#else
			NoColorChat(0, "%L", LANG_PLAYER, "UNGAG_PLAYER", admin_name, authid, data[gag_name], data[gag_steamid], data[gag_reason])
		#endif
 
		RemoveGag(array_pos, data[gag_steamid])
 
		return PLUGIN_HANDLED
	}
 
	console_print(id, "%L", id, "NOT_IN_GAG_LIST", arg)
 
	return PLUGIN_HANDLED
}
 
public concmd_gag_list(id, level, cid) {
	if(!cmd_access(id, level, cid, 1)) return PLUGIN_HANDLED
 
	if(!total_gags) {
		console_print(id, "%L", id, "NO_GAGS")
		return PLUGIN_HANDLED;
	}
 
	static start
	if(read_argc() > 1) {
		static arg[5]
		read_argv(1, arg, sizeof(arg) - 1)
 
		start = min(str_to_num(arg), total_gags) - 1
	}
 
	else start = 0
 
	new last = min(start + 10, total_gags)
 
	if(id == 0) server_cmd("echo ^"%L^"", id, "GAG_LIST_NUM", start + 1, last)
	else console_print(id, "%L", id, "GAG_LIST_NUM", start + 1, last)
 
	for(new i = start; i < last; i++) {
		static data[GagData]
		ArrayGetArray(g_array, i, data)
 
		PrintGagInfosToConsole(id, data[gag_name], data[gag_steamid], data[gag_length], data[gag_reason], data[ungag_time])
	}
 
	if(++last < total_gags) {
		if(id == 0) server_cmd("echo ^"%L^"", id, "GAG_LIST_NEXT", last)
		else console_print(id, "%L", id, "GAG_LIST_NEXT", last)
	}
 
	return PLUGIN_HANDLED
}	
 
public gag_menu(id) {
	if(!(get_user_flags(id) & GAG_FLAG))
		return PLUGIN_HANDLED
 
	new menu_line[64], menu_newline[64], id_data[64]
	format(menu_line, charsmax(menu_line), "\w%L^n%L", id, "GAG_MENU1", id, "GAG_MENU2")
 
	new menu = menu_create(menu_line, "gag_menu_handler")
 
	new players[32], name[32], num
	get_players(players, num, "c")
 
	for(new i = 0; i <num; i++) {
		new pid = players[i]
		get_user_name(pid, name, 31)
		num_to_str(pid, id_data, sizeof(id_data))
 
		format(menu_newline, charsmax(menu_newline), "%s", name)
		menu_additem(menu, menu_newline, id_data, 0)
	}
 
	menu_display(id, menu, 0)
	return PLUGIN_CONTINUE
}
 
public ungag_menu(id) {
	if(!(get_user_flags(id) & GAG_FLAG))
		return PLUGIN_HANDLED
 
	if(!total_gags) {
		#if defined USE_COLOR_CHAT
			ColorChat(id, RED, "%L", id, "NO_GAGS")
		#else
			client_print(id, print_chat, "%L", id, "NO_GAGS")
		#endif
 
		return PLUGIN_HANDLED
	}
 
	new menu_line[99], menu_newline[99]
	format(menu_line, charsmax(menu_line), "\w%L^n%L", id, "GAG_MENU3", id, "GAG_MENU4")
 
	new menu = menu_create(menu_line, "ungag_menu_handler")
 
	for(new i = 0; i < total_gags; i++) {
		static data[GagData]
		ArrayGetArray(g_array, i, data)
 
		format(menu_newline, charsmax(menu_newline), "\r%s \w[%s]", data[gag_steamid], data[gag_reason])
		menu_additem(menu, menu_newline, data[gag_steamid], 0)
	}
 
	menu_display(id, menu, 0)
	return PLUGIN_CONTINUE
}
 
public gag_menu_handler(id, menu, item) {
	if(item == MENU_EXIT) {
		menu_destroy(menu)
		return PLUGIN_HANDLED
	}
 
	new data[64], szName[64]
	new access, callback
	menu_item_getinfo(menu, item, access, data,charsmax(data), szName,charsmax(szName), callback)
 
	tempid[id] = str_to_num(data)
 
	static authid[35]
	get_user_authid(tempid[id], authid, sizeof(authid) - 1)
 
	static ip[35]
	get_user_ip(tempid[id], ip, sizeof(ip) - 1, 1)
	static array_pos	
 
	if(get_user_flags(tempid[id]) & GAG_IMMUNITY) {
		#if defined USE_COLOR_CHAT
			ColorChat(id, RED, "%L", id, "PLAYER_IMMUNITY")
		#else
			NoColorChat(id, "%L", id, "PLAYER_IMMUNITY")
		#endif
 
		gag_menu(id)
 
		return PLUGIN_HANDLED
	}
 
	else if(TrieGetCell(g_trie, authid, array_pos) || TrieGetCell(g_trie, ip, array_pos)) {
		static data[GagData]
		ArrayGetArray(g_array, array_pos, data)
 
		static gag_length2[64]
		new Float:gag_len = float(data[gag_length]) / 60.0
		GetGagTime(id, gag_len, gag_length2, sizeof(gag_length2) - 1)
 
		#if defined USE_COLOR_CHAT
			ColorChat(id, RED, "%L", id, "PLAYER_GAGGED", data[gag_reason], gag_length2, data[ungag_time])
		#else
			NoColorChat(id, "%L", id, "PLAYER_GAGGED", data[gag_reason], gag_length2, data[ungag_time])
		#endif
 
		return PLUGIN_HANDLED
	}
 
	else { 
		#if defined USE_COLOR_CHAT
			ColorChat(id, RED, "%L", id, "TYPE_TIME")
		#else
			NoColorChat(id, "%L", id, "TYPE_TIME")
		#endif
 
		client_cmd(id, "messagemode GAG_TIME")
	}
 
	return PLUGIN_CONTINUE
}
 
public ungag_menu_handler(id, menu, item) {
	if(item == MENU_EXIT) {
		menu_destroy(menu)
		return PLUGIN_HANDLED
	}
 
	new data[64], szName[64]
	new access, callback
	menu_item_getinfo(menu, item, access, data, charsmax(data), szName, charsmax(szName), callback)
 
	client_cmd(id, "ungag ^"%s^"", data)
 
	return PLUGIN_CONTINUE
}
 
public clcmd_time(id) {
	if(!(get_user_flags(id) & GAG_FLAG))
		return PLUGIN_HANDLED
 
	new gag_times[33][100]
	read_args(gag_times[id], 99)
	remove_quotes(gag_times[id])
 
	get_gag_time[id] = str_to_float(gag_times[id])
 
	#if defined USE_COLOR_CHAT
		ColorChat(id, RED, "%L", id, "TYPE_REASON")
	#else
		NoColorChat(id, "%L", id, "TYPE_REASON")
	#endif
 
	client_cmd(id, "messagemode GAG_REASON")
 
	return PLUGIN_HANDLED
}
 
public clcmd_reason(id) {
	if(!(get_user_flags(id) & GAG_FLAG))
		return PLUGIN_HANDLED
 
	new get_gag_reason[33][100]
	read_args(get_gag_reason[id], 99)
	remove_quotes(get_gag_reason[id])
 
	static target_name[32]
	get_user_name(tempid[id], target_name, sizeof(target_name) - 1)
 
	if(is_user_steam(tempid[id])) client_cmd(id, "gag_authid ^"%s^" ^"%f^" ^"%s^"", target_name, get_gag_time[id], get_gag_reason[id])
	else client_cmd(id, "gag_ip ^"%s^" ^"%f^" ^"%s^"", target_name, get_gag_time[id], get_gag_reason[id])
 
	return PLUGIN_HANDLED
}
 
public gag_say(id) {
	static authid[35]
	get_user_authid(id, authid, sizeof(authid) - 1)
 
	static ip[35]
	get_user_ip(id, ip, sizeof(ip) - 1, 1)
 
	static array_pos	
	if(TrieGetCell(g_trie, authid, array_pos) || TrieGetCell(g_trie, ip, array_pos)) {
		static data[GagData]
		ArrayGetArray(g_array, array_pos, data)
 
		static gag_length2[64]
		new Float:gag_len = float(data[gag_length]) / 60.0
		GetGagTime(id, gag_len, gag_length2, sizeof(gag_length2) - 1)
 
		#if defined USE_COLOR_CHAT
			ColorChat(id, RED, "%L", id, "YOU_GAGGED", data[gag_reason], gag_length2, data[ungag_time])
		#else
			NoColorChat(id, "%L", id, "YOU_GAGGED", data[gag_reason], gag_length2, data[ungag_time])
		#endif
 
		return PLUGIN_HANDLED
	}
 
	return PLUGIN_CONTINUE
}
 
public PrintGagInfosToConsole(index, const target_name[], const target_steamid[], const target_length, const target_reason[], const target_ungag_time[]) {
	static gag_length2[64]
	new bool:is_ip = bool:(containi(target_steamid, ".") != -1)
 
	if(index == 0) {
		server_print("************************************************")
		server_print("%L", index, "GAG_INFORMATION")
		server_print("%L: %s", index, "GAG_NAME", target_name)
		server_print("%L: %s", index, !is_ip ? "GAG_STEAMID" : "GAG_IP", target_steamid)
		server_print("%L: %s", index, "GAG_REASON", target_reason)
		if(target_length > 0) {
			new Float:gag_len = float(target_length) / 60.0
			GetGagTime(index, gag_len, gag_length2, sizeof(gag_length2) - 1)
 
			server_print("%L: %s", index, "GAG_TIME", gag_length2)
		}
		server_print("%L: %s", index, "UNGAG_TIME", target_ungag_time)
		server_print("************************************************")
	}
 
	else {
		console_print(index, "************************************************")
		console_print(index, "%L", index, "GAG_INFORMATION")
		console_print(index, "%L: %s", index, "GAG_NAME", target_name)
		console_print(index, "%L: %s", index, !is_ip ? "GAG_STEAMID" : "GAG_IP", target_steamid)
		console_print(index, "%L: %s", index, "GAG_REASON", target_reason)
		if(target_length > 0) {
			new Float:gag_len = float(target_length) / 60.0
			GetGagTime(index, gag_len, gag_length2, sizeof(gag_length2) - 1)
 
			console_print(index, "%L: %s", index, "GAG_TIME", gag_length2)
		}
		console_print(index, "%L: %s", index, "UNGAG_TIME", target_ungag_time)
		console_print(index, "************************************************")
	}
}
 
public LoadGags() {
	if(total_gags) {
		TrieClear(g_trie)
		ArrayClear(g_array)
		total_gags = 0
	}
 
	if(file_exists(gag_file)) {
		new f = fopen(gag_file, "rt")
		static filedata[512], length[10]
 
		static data[GagData]
		while(!feof(f)){
			fgets(f, filedata, sizeof(filedata) - 1)
 
			if(!filedata[0]) continue
 
			parse(filedata,\
				data[gag_steamid], sizeof(data[gag_steamid]) - 1,\
				data[gag_name], sizeof(data[gag_name]) - 1,\
				length, sizeof(length) - 1,\
				data[ungag_time], sizeof(data[ungag_time]) - 1,\
				data[gag_reason], sizeof(data[gag_reason]) - 1
				)
 
			data[gag_length] = str_to_num(length)
 
			ArrayPushArray(g_array, data)
			TrieSetCell(g_trie, data[gag_steamid], total_gags)
 
			total_gags++
		}
 
		fclose(f)
	}
}
 
public RemoveGag(pos, const authid[]) {
	TrieDeleteKey(g_trie, authid)
	ArrayDeleteItem(g_array, pos)
 
	total_gags--
 
	new f = fopen(gag_file, "wt")
	new data[GagData]
 
	for(new i = 0; i < total_gags; i++ ) {
		ArrayGetArray(g_array, i, data)
		TrieSetCell(g_trie, data[gag_steamid], i)
 
		fprintf(f, "^"%s^" ^"%s^" %i ^"%s^" ^"%s^"^n",\
			data[gag_steamid],\
			data[gag_name],\
			data[gag_length],\
			data[ungag_time],\
			data[gag_reason]
			)
	}
 
	fclose(f)
}
 
public GagAdd(const target_name[], const target_steamid[], const reason[], const length, const ungag_time3[]) {
	new f = fopen(gag_file, "a+")
 
	fprintf(f, "^"%s^" ^"%s^" %i ^"%s^" ^"%s^"^n",\
		target_steamid,\
		target_name,\
		length,\
		ungag_time3,\
		reason
		)
 
	fclose(f)
 
	static data[GagData]
	copy(data[gag_name], sizeof(data[gag_name]) - 1, target_name)
	copy(data[gag_steamid], sizeof(data[gag_steamid]) - 1, target_steamid)
	data[gag_length] = length
	copy(data[ungag_time], sizeof(data[ungag_time]) - 1, ungag_time3)
	copy(data[gag_reason], sizeof(data[gag_reason]) - 1, reason)
 
	TrieSetCell(g_trie, target_steamid, total_gags)
	ArrayPushArray(g_array, data)
 
	total_gags++
}
 
GetGagTime(index, Float:gagtime, length[], len) {
	new minutes = floatround(gagtime, floatround_floor)
	new seconds = floatround(floatfract(gagtime) * 60, floatround_floor)
	new hours = 0
	new days = 0
 
	while(minutes >= 60) {
		minutes -= 60
		hours++
	}
 
	while(hours >= 24) {
		hours -= 24
		days++
	}
 
	new bool:add_before
	if(seconds) {
		formatex(length, len, "%i %L", seconds, index, "GAG_SECONDS")	
		add_before = true
	}
 
	if(minutes) {
		if(add_before) format(length, len, "%i %L, %s", minutes, index, "GAG_MINUTES", length)
 
		else{
			formatex(length, len, "%i %L", minutes, index, "GAG_MINUTES")			
			add_before = true
		}
	}
 
	if(hours) {
		if(add_before) format(length, len, "%i %L, %s", hours, index, "GAG_HOURS", length)
 
		else{
			formatex(length, len, "%i %L", hours, index, "GAG_HOURS")			
			add_before = true
		}
	}
 
	if(days) {
		if(add_before) format(length, len, "%i %L, %s", days, index, "GAG_DAYS", length)
 
		else {
			formatex(length, len, "%i %L", days, index, "GAG_DAYS")			
			add_before = true
		}
	}
 
	if(!add_before) formatex(length, len, "%L", index, "PERMANENT_GAG")
}
 
GetTargetFlags(index) {
	static const flags_no_immunity = (CMDTARGET_ALLOW_SELF|CMDTARGET_NO_BOTS)
	static const flags_immunity = (CMDTARGET_ALLOW_SELF|CMDTARGET_NO_BOTS|CMDTARGET_OBEY_IMMUNITY)
 
	switch(get_pcvar_num(gag_immunity)) {
		case 1: return flags_immunity
		case 2: return access(index, GAG_IMMUNITY) ? flags_no_immunity : flags_immunity
	}
 
	return flags_no_immunity
}
 
GenerateUnGagTime(const Float:input, output[], const len) {
	static _hours[5], _minutes[5], _seconds[5], _month[5], _day[5], _year[7]
	format_time(_hours, sizeof(_hours) - 1, "%H")
	format_time(_minutes, sizeof(_minutes) - 1, "%M")
	format_time(_seconds, sizeof(_seconds) - 1, "%S")
	format_time(_month, sizeof(_month) - 1, "%m")
	format_time(_day, sizeof(_day) - 1, "%d")
	format_time(_year, sizeof(_year) - 1, "%Y")
 
	new hours = str_to_num(_hours)
	new month = str_to_num(_month)
	new day = str_to_num(_day)
	new year = str_to_num(_year)
 
	new minutes = floatround(input, floatround_floor) + str_to_num(_minutes)
	new seconds = floatround(floatfract(input) * 60, floatround_floor)
 
	while(minutes >= 60) {
		minutes -= 60
		hours++
	}
 
	while(hours >= 24) {
		hours -= 24
		day++
	}
 
	new max_days = GetDaysInMonth(month, year)
	while(day > max_days) {
		day -= max_days
		month++
	}
 
	while(month > 12) {
		month -= 12
		year++
	}
 
	seconds += str_to_num(_seconds)
	if(seconds > 59) {
		seconds -= 60
		if(minutes < 59) minutes++
 
		else {
			minutes = 0
			if(hours < 23) hours++
 
			else {
				hours = 0
				if(day < max_days) day++
 
				else {
					day = 1
					if(month < 12) month++
 
					else {
						month = 1
						year++
					}
				}
			}
		}
	}	
 
	formatex(output, len, "%i:%02i:%02i %i/%i/%i", hours, minutes, seconds, month, day, year)
}
 
GetDaysInMonth(month, year=0) {
	switch(month) {
		case 1:	return 31 // January
		case 2:	return ((year % 4) == 0) ? 29 : 28 // February
		case 3:	return 31; // March
		case 4:	return 30; // April
		case 5:	return 31; // May
		case 6:	return 30; // June
		case 7:	return 31; // July
		case 8:	return 31; // August
		case 9:	return 30; // September
		case 10: return 31; // October
		case 11: return 30; // November
		case 12: return 31; // December
	}
 
	return 30
}
 
stock NoColorChat(const id, const input[], any:...) {
	new count = 1, players[32], i
	static msg[191]
	vformat(msg, 190, input, 3)
 
	replace_all(msg, 190, "!g", "") 
	replace_all(msg, 190, "!n", "") 
	replace_all(msg, 190, "!t", "") 
 
	if(id)players[0] = id; else get_players(players, count, "ch") 
 
	for(i = 0; i < count; i++) {
		if(is_user_connected(players[i])) {
			message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("SayText"), _, players[i])
			write_byte(players[i])
			write_string(msg)
			message_end()
		}
	}
}
 
stock is_user_steam(id) {
        new g_Steam[32]
        get_user_authid(id, g_Steam, charsmax(g_Steam))
 
        return bool:('0' <= g_Steam[8] <= '1')
}