/*
TITLE:		Ultimate RSlots
AUTHOR:		OneEyed
VERSION:	1.0
	
NOTE: Disable adminslots.amxx if you use this!

-- Copy & Paste settings below to server.cfg and fill them out!

// 0 = disabled
// 1 = no booting but fill rslots (Recommended 2-6 slots)
// 2 = kick/redirect when full or to free slot (Recommended 1 slot)
rslot_on <0|1|2>

//number of slots to reserve
rslot_slots <# of slots>

//if enabled will hide reserved slots 
//(ex. 21 maxplayers will show 20/20 if rslot_slots = 1 )
rslot_hideslots <0|1>

//enable server redirection
rslot_redirect <0|1>

//ip and port of the server players will be redirected to
rslot_ip "ip:port"

//(optional) password of the server players will be redirected to
rslot_pw "none"

//--- below used for amx_reservation 2---//
//kills for rslot kicking protection (comment out #define KILLS to disable)
rslot_kills "kills"

//played time for rslot kicking protection (comment out #define PLAYEDTIME to disable)
rslot_playedtime "minutes"

*/

#include <amxmodx>

//comment to not use
#define KILLS
#define PLAYEDTIME

//List size of remembered players who were booted, 
//to prevent the same players getting booted again so quickly.
#define LAST_KICKED		15

/*--------------------- DO NOT TOUCH BELOW HERE OR JACK BAUER WILL HUNT YOU DOWN ---------------*/
/*---------------------     DO NOT TOUCH BELOW HERE OR GABEN WILL TOUCH YOU      ---------------*/
new maxplayers
new cvar_rsloton
new cvar_reservedslots
new cvar_hideslots
new cvar_redirect
new cvar_redirectip
new cvar_redirectpw
#if defined KILLS
new cvar_kills
#endif
#if defined PLAYEDTIME
new cvar_playedtime
#endif
new lastkicked[LAST_KICKED][32]
new kickcount

public plugin_init()
{
	register_plugin("Ultimate RSlots","1.0","OneEyed")
	register_cvar("ultimate_rslots", "1.0",FCVAR_SERVER)
	register_dictionary("ultimate_rslot.txt")
	
	cvar_rsloton = register_cvar("rslot_on","0")
	cvar_reservedslots = register_cvar("rslot_slots","1")
	cvar_hideslots = register_cvar("rslot_hideslots", "0")
	cvar_redirect = register_cvar("rslot_redirect","0")
	cvar_redirectip = register_cvar("rslot_ip","127.0.0.1")
	cvar_redirectpw = register_cvar("rslot_pw","none")
	
	#if defined KILLS
		cvar_kills = register_cvar("rslot_kills", "35")
	#endif
	
	#if defined PLAYEDTIME
		cvar_playedtime = register_cvar("rslot_playedtime", "60")
	#endif
	
	maxplayers = get_maxplayers()
}

public plugin_cfg()
	if(get_pcvar_num(cvar_hideslots))
		set_cvar_num("sv_visiblemaxplayers", maxplayers-get_pcvar_num(cvar_reservedslots))

public client_authorized(id)
{
	if(is_user_bot(id)) return PLUGIN_CONTINUE
	new rslots_on = get_pcvar_num(cvar_rsloton)
	new players = get_playersnum(1)
	new limit = maxplayers - get_pcvar_num(cvar_reservedslots)
	
	if(players > limit) 
	{
		switch(rslots_on)
		{
			case 1: 
			{
				if( !(get_user_flags(id) & ADMIN_RESERVATION) ) 
					if(get_pcvar_num(cvar_redirect) == 1)
						redirect_player(id)
					else {
						new lReason[128]
						format(lReason, 127, "%L", id, "CANT_JOIN_REASON")
						server_cmd("kick #%d %s", get_user_userid(id), lReason)
					}
			}
			case 2:
			{
				new sucker = id
				
				if(get_user_flags(id) & ADMIN_RESERVATION)
					sucker = player_to_kick()
			
				if(get_pcvar_num(cvar_redirect) == 1)
					redirect_player(sucker)
				else 
				{
					new player[32], admin[32], authid[32]
					
					get_user_authid(id,authid,31)
					get_user_name(id,admin,31)
					get_user_name(sucker,player,31)
					
					if(sucker != id) 
					{
						format(lastkicked[kickcount++], 31, "%s", authid)
						if(kickcount >= LAST_KICKED)
							kickcount = 0

						new lReason[128]
						format(lReason, 127, "%L", sucker, "KICKED_REASON")
						server_cmd("kick #%d %s", get_user_userid(sucker), lReason)
					}
					else {
						new lReason[128]
						format(lReason, 127, "%L", id, "CANT_JOIN_REASON")
						server_cmd("kick #%d %s", get_user_userid(id), lReason)
					}
				}
			}
		}
	}
	return PLUGIN_CONTINUE
}

stock player_to_kick()
{
	new players[33], count, authid[32], x, id, played_time
	for(id = 1; id <= maxplayers; id++) 
	{
		if (!is_user_connected(id) || is_user_connecting(id) || is_user_bot(id)) continue
		if (get_user_flags(id) & ADMIN_RESERVATION) continue
		
		#if defined KILLS
			new kills = get_pcvar_num(cvar_kills)
			if(kills && get_user_frags(id) >= kills) continue
		#endif
		
		#if defined PLAYEDTIME
			new pltime = get_pcvar_num(cvar_playedtime)
			played_time = get_user_time(id, 1) / 60
			if(pltime && played_time >= pltime) continue
		#endif
		
		get_user_authid(id,authid,31)
		
		for(x=0;x<LAST_KICKED;x++)
			if(equal(lastkicked[x], authid)) continue 

		players[count++] = id
	}
	return players[random_num(0,(count-1))]
}

stock redirect_player(id)
{
	new redirectip[64], redirectpw[32]
	
	get_pcvar_string(cvar_redirectip,redirectip,63)
	get_pcvar_string(cvar_redirectpw,redirectpw,31)
	
	if(!equal(redirectpw, "none"))
		client_cmd(id,"setinfo password %s",redirectpw)
		
	client_cmd(id,"disconnect; connect %s",redirectip)
}