/* AMX Mod X script. 
* 
* This file is provided as is (no warranties).
*
* (c) 2002-2003, OLO 
* Modified by shadow
* Modified again by Bo0m!
* Modified again by OT
* For use alongside with the AMX Super All-In-One Plugin. :)
*
*****************************************************************************
* Changelog:
* 7/21/07 - v0.20(OT)
* - renamed all cvars
* - remade all functions
* - added amx_hpm 
* - relooked at the plugin
* - remade configs
*
* 7/12/07 - v0.19 (OT)
* - remade the ban function
* - erased the delete text function
* - added amx_hpk_ban cvar
* - added amx_hpk_more cvar
* - added amx_hpb cmd
* - remade function (kick_player)
* - remade function (show_warn)
* - renamed amx_hpk_bantime in amx_hpb_bantime
* - renamed amx_hpk_ban in amx_hpb_ban
* - renamed amx_hpk_times in amx_hpb_limit1
* - renamed amx_hpk_more in amx_hpb_limit2
*
* 7/11/07 - v0.181 (OT)
* - remade function (show_warn)
* - remade banip part
*
* 7/8/07 - v0.18 (OT):
* - added retry times
* - added new service
*
* 4/28/07 - v0.17 (Bo0m!):
* - fixed check cvar never being used
* - fixed delay cvar check
* - switched to pcvars
* - adjusted some messages
* - added definable immunity flag
* - added logging when admins change HPK settings
*
*
* 4/19/04 - v0.16.2:
* - changed cvars
* amx_maxping -> amx_hpk_ping
* amx_maxping_check -> amx_hpk_check
* amx_maxping_tests -> amx_hpk_tests
*
* - added amx_command
* amx_hpk - displays status of the plugin and syntax to configure it
*
* - added cvar
* amx_hpk_delay - Delays ping checking after connect (default 1min, use amx_hpk to configure)
*
*
* 4/15/04 - v0.16.1:
* - added cvars
* amx_maxping //lowest average ping to be kicked
* amx_maxping_check //time between checks
* amx_maxping_tests //number of checks to be performed before kick
* amx_hpk_times //maximum of times allowed for a player to connect before receiving a banip for 20 minutes
*
* - modified the version from 0.9.4 (OLO) to 0.16.1 (amxx)
*
* - added log entry for amxx logging
*
* This modified plugin can be found at:
*/ 

#include <amxmodx> 
#include <amxmisc>
#include <string>
#include <file>

// Feel free to change this flag
#define HPK_IMMUNE ADMIN_IMMUNITY


// PCvars
new hpk_ping, hpk_check, hpk_tests, hpk_delay, hpb_limit1, hpb_bantime, hpb_ban, hpb_limit2, hpb_bpinc, hpk_immunity
new base[5000] = "addons\amxmodx\configs\hpklist.ini"
new g_Ping[33]
new g_Samples[33]

public plugin_init() {

	register_plugin("High Ping Punisher","1","Bo0m!/shadow/OT")

	register_concmd("amx_hpk","cmdHpk",ADMIN_CVAR,"- sets the high ping punisher general settings")
	register_concmd("amx_hpb","cmdHpb",ADMIN_CVAR,"- sets the high ping punisher mode settings")
	register_concmd("amx_hpm","cmdHpm",ADMIN_CVAR,"- sets the high ping punisher mode")
	register_concmd("amx_hpp_newlist","cmdRem",ADMIN_CVAR,"- makes a new list of the high ping users")

	hpk_ping = register_cvar("amx_hpp_ping","200")
	hpk_check = register_cvar("amx_hpp_check","12")
	hpk_tests = register_cvar("amx_hpp_tests","5")
	hpk_delay = register_cvar("amx_hpp_delay","60")
	hpb_ban = register_cvar("amx_hpp_mode","2")
	hpb_bantime = register_cvar("amx_hpp_bantime","5")
	hpb_limit1 = register_cvar("amx_hpp_limit1","2")
	hpb_limit2 = register_cvar("amx_hpp_limit2","5")
	hpb_bpinc = register_cvar("amx_hpp_bpinc","1")
	hpk_immunity = register_cvar("amx_hpp_immunity","1")
	
	if (get_pcvar_num(hpk_check) < 5) set_pcvar_num(hpk_check,5)
	if (get_pcvar_num(hpk_tests) < 3) set_pcvar_num(hpk_tests,3)
}

public plugin_cfg() {
	if(!file_exists(base)) write_file(base,"; Here will be the list of the clients with high ping")
}

public cmdRem(id,level,cid) {
	if (!cmd_access(id,level,cid,1))
		return PLUGIN_HANDLED
	delete_file(base)
	write_file(base,"; Here will be the list of the clients with high ping")
	console_print(id,"[HPP] The list was renewed")
	log_amx("HPP: List deleted! List renewed!")
	return PLUGIN_HANDLED

}

public client_disconnect(id) 
	remove_task(id)

public client_putinserver(id) {    
	g_Ping[id] = 0 
	g_Samples[id] = 0
	
	if ( !is_user_bot(id) ) 
	{
		new param[1]
		param[0] = id 
		set_task( 15.0 , "showWarn" , id , param , 1 )
    
		if (get_pcvar_num(hpk_delay) != 0) {
			set_task( float(get_pcvar_num(hpk_delay)), "taskSetting", id, param , 1)
		}
		else {
			set_task( float(get_pcvar_num(hpk_check)) , "checkPing" , id , param , 1 , "b" )
		}
	}
}

public showWarn(param[]) {
		if (get_cvar_num("amx_hpp_mode") == 0) client_print( param[0] ,print_chat,"[HPP] Players with ping higher than %d will be kicked!", get_cvar_num( "amx_hpp_ping" ) )
		if (get_cvar_num("amx_hpp_mode") == 1) { 
		client_print( param[0] ,print_chat,"[HPP] Players with ping higher than %d will be banned!", get_cvar_num( "amx_hpp_ping" ) )
		}
		if (get_cvar_num("amx_hpp_mode") == 2) {
		client_print( param[0] ,print_chat,"[HPP] Players with ping higher than %d will be kicked!", get_cvar_num( "amx_hpp_ping" ) )
		client_print( param[0] ,print_chat,"[HPP] Warning Smart Mode Enabled: HP Players will be banned if they reconnect!")
		}
	
}


public taskSetting(param[]) {
	new name[32]
	get_user_name(param[0],name,31)
	set_task( float(get_pcvar_num(hpk_check)) , "checkPing" , param[0] , param , 1 , "b" )
}

kickPlayer(id) {
	new name[32], authid[36], ip[20], ip2[20], len, text[60]
	get_user_name(id,name,31)
	get_user_authid(id,authid,35)
	get_user_ip(id,ip,19,1)
	new i=0
	new nr=0
	while (i <= file_size(base,1)) 
	{
		read_file(base,i,ip2, 19,len)
		if (equali(ip,ip2)) 
		{
			nr = nr + 1
		}
		i=i+1
	}
	
	if (get_pcvar_num(hpb_ban) == 0 ) {
		client_print(0,print_chat,"[HPP] Player %s disconnected due to high ping",name)
		server_cmd("kick #%d ^"Sorry but your ping is too high, try again later...(%d tries left)^"",get_user_userid(id),get_cvar_num("amx_hpp_limit1") - nr)
		log_amx("HPP: ^"%s<%d><%s>^" was kicked due high ping (Average Ping ^"%d^")", name,get_user_userid(id),authid,(g_Ping[id] / g_Samples[id]))
	}
	
	if (get_pcvar_num(hpb_ban) == 1 ) {
		client_print(0,print_chat,"[HPP] Player %s banned for %d minutes due to high ping",name,hpb_bantime)
		format(text,59,"amx_banip %s %d ^"Sorry but your ping is too high, try again later...^"",name,get_pcvar_num(hpb_bantime))
		server_cmd(text)
		log_amx("HPP: ^"%s<%d><%s>^" was banned temporarily due high ping (Average Ping ^"%d^")", name,get_user_userid(id),authid,(g_Ping[id] / g_Samples[id]))
	}	
	
	if (get_pcvar_num(hpb_ban) == 2 ) {
		if ((nr < get_pcvar_num(hpb_limit1)))
		{
			write_file(base,ip)
			client_print(0,print_chat,"[HPP] Player %s disconnected due to high ping",name)
			server_cmd("kick #%d ^"Sorry but your ping is too high, try again later...(%d tries left)^"",get_user_userid(id),get_cvar_num("amx_hpp_limit1") - nr)
			log_amx("HPP: ^"%s<%d><%s>^" was kicked due high ping (Average Ping ^"%d^")", name,get_user_userid(id),authid,(g_Ping[id] / g_Samples[id]))
		}
		if ((nr == get_pcvar_num(hpb_limit1)) && (nr  != get_pcvar_num(hpb_limit2)))
		{
			write_file(base,ip)
			client_print(0,print_chat,"[HPP] Player %s banned for %d minutes due to insistation",name,hpb_bantime)
			format(text,59,"amx_banip %s %d ^"Sorry but your ping is too high, try again later...^"",name,get_pcvar_num(hpb_bantime))
			server_cmd(text)
			log_amx("HPP: ^"%s<%d><%s>^" was banned temporarily due high ping (Average Ping ^"%d^")", name,get_user_userid(id),authid,(g_Ping[id] / g_Samples[id]))
		}
		if ((nr > get_pcvar_num(hpb_limit1)) && (nr < get_pcvar_num(hpb_limit2)))
		{
			write_file(base,ip)
			client_print(0,print_chat,"[HPP] Player %s banned for %d minutes due to insistation",name,hpb_bantime)
			if (get_pcvar_num(hpb_bpinc) == 0)
			format(text,59,"amx_banip %s %d ^"Sorry but your ping is too high, try again later...^"",name,get_pcvar_num(hpb_bantime))
			else
			format(text,59,"amx_banip %s %d ^"Sorry but your ping is too high, try again later...^"",name,get_pcvar_num(hpb_bantime) * (nr + 1 - get_pcvar_num(hpb_limit1)))
			server_cmd(text)
			log_amx("HPP: ^"%s<%d><%s>^" was banned temporarily due high ping (Average Ping ^"%d^")", name,get_user_userid(id),authid,(g_Ping[id] / g_Samples[id]))
		}
		if (nr == get_pcvar_num(hpb_limit2))
		{
			client_print(0,print_chat,"[HPP] Player %s banned for %d minutes due to insistation",name,hpb_bantime)
			format(text,59,"amx_banip %s %d ^"Sorry but your ping is too high, try again later...^"",name,0)
			server_cmd(text)
			log_amx("HPP: ^"%s<%d><%s>^" was banned permanently due high ping (Average Ping ^"%d^")", name,get_user_userid(id),authid,(g_Ping[id] / g_Samples[id]))
		}
	}

}

public checkPing(param[]) { 

	if (get_pcvar_num(hpk_tests) < 3)
		set_pcvar_num(hpk_tests,3)

	new id = param[ 0 ] 

	if ( get_user_flags(id) & HPK_IMMUNE && get_pcvar_num(hpk_immunity) == 1 ) {
		remove_task(id)
		client_print(id, print_chat, "[HPP] Ping checking disabled due to immunity...")
		return PLUGIN_CONTINUE
	}

	new ping, loss

	get_user_ping(id,ping,loss) 

	g_Ping[ id ] += ping
	++g_Samples[ id ]

	if ( (g_Samples[ id ] > get_pcvar_num(hpk_tests)) && (g_Ping[id] / g_Samples[id] > get_pcvar_num(hpk_ping))  )    
		kickPlayer(id)

	return PLUGIN_CONTINUE
}

  
public cmdHpk(id,level,cid) {
	if (!cmd_access(id,level,cid,1))
		return PLUGIN_HANDLED

	if (read_argc() < 6) {
		console_print(id,"Usage: amx_hpk <max ping> <total ping checks> <time between checks> <delay before starting checks> <1 to allow immunity|0 to disallow>")
		console_print(id,"Current High Ping Punisher General Settings:")
		console_print(id,"Max Ping: %d | Ping Checks: %d | Check Frequency: %d | Start Delay: %d | Immunity: %d",get_pcvar_num(hpk_ping),get_pcvar_num(hpk_tests),get_pcvar_num(hpk_check),get_pcvar_num(hpk_delay),get_pcvar_num(hpk_immunity))
		return PLUGIN_HANDLED
	}

	new name[32], authid[36]
	get_user_name(id,name,31)
	get_user_authid(id,authid,35)

	new ping_arg[5], check_arg[5], tests_arg[5], delay_arg[5], immune_arg[5]
	read_argv(1,ping_arg,4)
	read_argv(2,tests_arg,4)
	read_argv(3,check_arg,4)
	read_argv(4,delay_arg,4)
	read_argv(5,immune_arg,4)
  
	new ping = str_to_num(ping_arg)
	new tests = str_to_num(tests_arg)
	new check = str_to_num(check_arg)
	new delay = str_to_num(delay_arg)
	new immune = str_to_num(immune_arg)

	if ( check < 5 ) check = 5
	if ( tests < 3 ) tests = 3

	set_cvar_num("amx_hpp_ping",ping)
	set_cvar_num("amx_hpp_tests",tests)
	set_cvar_num("amx_hpp_check",check)
	set_cvar_num("amx_hpp_delay",delay)
	set_cvar_num("amx_hpp_immunity",immune)
	
	console_print(id,"The following HPP General Settings have been set:")
	console_print(id,"Max Ping: %d | Ping Checks: %d | Check Frequency: %d | Start Delay: %d | Immunity: %d",get_pcvar_num(hpk_ping),get_pcvar_num(hpk_tests),get_pcvar_num(hpk_check),get_pcvar_num(hpk_delay),get_pcvar_num(hpk_immunity))
	log_amx("HPP: ^"%s<%d><%s>^" has configured the HPP - Max Ping: %d | Ping Checks: %d | Check Frequency: %d | Start Delay: %d | Immunity: %d", name,get_user_userid(id),authid,get_pcvar_num(hpk_ping),get_pcvar_num(hpk_tests),get_pcvar_num(hpk_check),get_pcvar_num(hpk_delay),get_pcvar_num(hpk_immunity))

	return PLUGIN_HANDLED    
}


public cmdHpb(id,level,cid) {
	if (!cmd_access(id,level,cid,1))
		return PLUGIN_HANDLED
		
	new mode = get_pcvar_num(hpb_ban)
	
	if (mode == 0) {
	console_print (id,"There aren't any configuration for this mode {Kicker}")
	console_print (id,"The other 2 modes have configurations in here!")
	}
	if (mode == 1) {
	if (read_argc() < 2) {
		console_print(id,"Usage: amx_hpb <ban time>")
		console_print(id,"Current High Ping Punisher Mode {Temp Banner} Settings:")
		console_print(id,"Ban time: %d",get_pcvar_num(hpb_bantime))
		return PLUGIN_HANDLED
	}

	new name[32], authid[36]
	get_user_name(id,name,31)
	get_user_authid(id,authid,35)

	new  bantime_arg[5]
	read_argv(1,bantime_arg,4)
 
	new bantime = str_to_num(bantime_arg)
	if (bantime == 0) bantime = 5
	set_cvar_num("amx_hpp_bantime",bantime)
	
	console_print(id,"The following HPP Mode {Temp Banner} Settings have been set:")
	console_print(id,"Ban time: %d",get_pcvar_num(hpb_bantime))
	log_amx("HPP: ^"%s<%d><%s>^" has configured the HPP Special Settings - Ban time: %d", name,get_user_userid(id),authid,get_pcvar_num(hpb_bantime))
	}
	
	
	if (mode == 2) {
	if (read_argc() < 5) {
		console_print(id,"Usage: amx_hpb <ban time> <ban increace on/off> <limit before beeing temp banned> <limit before beeing totally banned>")
		console_print(id,"Current High Ping Punisher Mode {Smart} Settings:")
		console_print(id,"Ban time: %d | Ban Increace: %d | Limit before beeing temp banned: %d | Limit before beeing totally banned: %d",get_pcvar_num(hpb_bantime),get_pcvar_num(hpb_bpinc),get_pcvar_num(hpb_limit1),get_pcvar_num(hpb_limit2))
		return PLUGIN_HANDLED
	}

	new name[32], authid[36]
	get_user_name(id,name,31)
	get_user_authid(id,authid,35)

	new  bantime_arg[5], limit1_arg[5], limit2_arg[5], bpinc_arg[5]
	read_argv(1,bantime_arg,4)
	read_argv(2,limit1_arg,4)
	read_argv(3,limit2_arg,4)
	read_argv(4,bpinc_arg,4)
 
 
	new bantime = str_to_num(bantime_arg)
	new limit1 = str_to_num(limit1_arg)
	new limit2 = str_to_num(limit2_arg)
	new bpinc = str_to_num(bpinc_arg)

	set_cvar_num("amx_hpp_bantime",bantime)
	set_cvar_num("amx_hpp_limit1",limit1)
	set_cvar_num("amx_hpp_limit2",limit2)
	set_cvar_num("amx_hpp_bpinc",bpinc)
	
	console_print(id,"The following HPP Mode {Smart} Settings have been set:")
	console_print(id,"Ban time: %d | Ban Increace: %d | Limit before beeing temp banned: %d | Limit before beeing totally banned: %d",get_pcvar_num(hpb_bantime),get_pcvar_num(hpb_bpinc),get_pcvar_num(hpb_limit1),get_pcvar_num(hpb_limit2))
	log_amx("HPP: ^"%s<%d><%s>^" has configured the HPP Special Settings - Ban time: %d | Ban Increace: %d | Limit before beeing temp banned: %d | Limitt before beeing totally banned: %d", name,get_user_userid(id),authid,get_pcvar_num(hpb_bantime),get_pcvar_num(hpb_bpinc),get_pcvar_num(hpb_limit1),get_pcvar_num(hpb_limit2))
	}
	return PLUGIN_HANDLED    
}


public cmdHpm(id,level,cid) {
	if (!cmd_access(id,level,cid,1))
		return PLUGIN_HANDLED
	if (read_argc() < 2) {
		console_print(id,"Usage: amx_hpm <plugin mode 0/1/2  kicker/temp banner/smart>")
		console_print(id,"Current High Ping Punisher Mode:")
		if (get_pcvar_num(hpb_ban) == 0) console_print (id," -===[Kicker]===-")
		if (get_pcvar_num(hpb_ban) == 1) console_print (id," -===[Temp Banner]===-")
		if (get_pcvar_num(hpb_ban) == 2) console_print (id," -===[Smart Mode]===-")
		if ((get_pcvar_num(hpb_ban) > 2) || (get_pcvar_num(hpb_ban) < 0)) console_print (id,"Command is set to :%d. Error! Plugin won't work!",get_pcvar_num(hpb_ban))
		return PLUGIN_HANDLED
	}

	new name[32], authid[36]
	get_user_name(id,name,31)
	get_user_authid(id,authid,35)

	new ban_arg[5]
	read_argv(1,ban_arg,4)
 
	new ban = str_to_num(ban_arg)
	
	if ((ban > 2) || (ban < 0)) {
		console_print (id,"[HPP] Command is set to :%d. Error! Plugin won't work!",ban)
		console_print (id,"[HPP] Settings reseted")
		return PLUGIN_HANDLED
	}
	else {
	console_print(id,"The following HPP Mode has been set:")
	set_cvar_num("amx_hpp_mode",ban)
	if (get_pcvar_num(hpb_ban) == 0) { 
		console_print (id,"          -===[Kicker]===-")
		log_amx("HPP: ^"%s<%d><%s>^" has set the mode on HPP -> Kicker", name,get_user_userid(id),authid)
	}
	if (get_pcvar_num(hpb_ban) == 1) {
		console_print (id,"          -===[Temp Banner]===-")
		log_amx("HPP: ^"%s<%d><%s>^" has set the mode on HPP -> Temp Banner", name,get_user_userid(id),authid)
	}
	if (get_pcvar_num(hpb_ban) == 2) {
		console_print (id,"          -===[Smart Mode]===-")
		log_amx("HPP: ^"%s<%d><%s>^" has set the mode on HPP -> Smart", name,get_user_userid(id),authid)
	}
	}
	return PLUGIN_HANDLED    
}

