#include <core>
#include <console>
#include <string>
#include <admin>
#include <adminlib>
 
new STRING_VERSION[MAX_DATA_LENGTH] = "Dead_Redirect";
 
new boolReservedUsers[MAX_PLAYERS];							//a global array for if a user is going to use the reserved slot
new numReservedUsers = 0;								//a global number of reserved slot users
new strRedirect[MAX_DATA_LENGTH] = "12.154.0.7:27015";			//set default server to direct too
new numRedirectSlots = 0;								//a global for number of reserved to take
new numRedirected = 0;									//total # redirected, yes it will roll over
new numConnected = 0;									//number of connected peeps
 
new FILENAME[MAX_DATA_LENGTH] = "redirect.lst";					//File to list players that have been redirectd
 
public admin_redirect(HLCommand,HLData,HLUserName,UserIndex) {
	new strUser[MAX_NAME_LENGTH];
	new strData[MAX_TEXT_LENGTH];
	new strCommand[MAX_TEXT_LENGTH];
	new strMessage[MAX_TEXT_LENGTH];
 
	convert_string(HLUserName,strUser,MAX_NAME_LENGTH);
	convert_string(HLData,strData,MAX_NAME_LENGTH);
	convert_string(HLCommand,strCommand,MAX_NAME_LENGTH);
 
	if (strlen(strData) > 0) {
		set_vaultdata("ADMIN_REDIRECT", strData);
		snprintf(strRedirect, MAX_TEXT_LENGTH, "%s", strData);
	}
 
	snprintf(strMessage, MAX_TEXT_LENGTH, "[ADMIN] Redirect Server Changed to %s", strData);
	selfmessage(strMessage);	
 
	log_command(strUser, strCommand, strData);
 
	return PLUGIN_HANDLED;
}
 
write_redirect(UserIndex) {
	new strTemp[MAX_TEXT_LENGTH];							// for cancatination
	new strName[MAX_NAME_LENGTH];							//1 Dead_One <494303> ==> 12.154.0.7:27015 @ Fri Mar 15 22:20:53 2002
	new strAuthID[MAX_AUTHID_LENGTH];						// is the format i am after
	new strTimeStamp[MAX_TEXT_LENGTH];						// for the time stamp
	new strNumber[MAX_NUMBER_LENGTH];						// yes, this should reset each time the server restarts :D
	new WONID;										// for thier wonid
	new Team,Dead;
	new numUserID;									// no apparent reason
 
	numRedirected++;									//increment counter
 
	if ( getvar("file_access_write") == 0 )					//check if write access is enabled
	{
		return (0);									//bleh why even try
	}
 
	playerinfo(UserIndex,strName,MAX_NAME_LENGTH,numUserID,WONID,Team,Dead,strAuthID);	//convert thier name and grab wonid
	get_userAuthID(strName,strAuthID,MAX_AUTHID_LENGTH);
	numtostr(numRedirected,strNumber);						//print the number to a string
	servertime(strTimeStamp, MAX_TEXT_LENGTH);				//make time stamp
 
	snprintf(strTemp, MAX_TEXT_LENGTH, "%s %s <%s> ==> %s @ %s", strNumber, strName, strAuthID, strRedirect, strTimeStamp);
	writefile(FILENAME, strTemp);							//belch it out to a file
 
	numtostr(numRedirected, strTemp);
	set_vaultdata("ADMIN_REDIRECT_NUM", strTemp);				//set the vault data
 
	return (1);
}
 
public admin_redirect_slot(HLCommand,HLData,HLUserName,UserIndex) {
	new strUser[MAX_NAME_LENGTH];
	new strData[MAX_TEXT_LENGTH];
	new strCommand[MAX_TEXT_LENGTH];
	new strMessage[MAX_TEXT_LENGTH];
 
	convert_string(HLUserName,strUser,MAX_NAME_LENGTH);
	convert_string(HLData,strData,MAX_NAME_LENGTH);
	convert_string(HLCommand,strCommand,MAX_NAME_LENGTH);
 
	if (strlen(strData) > 0) {
		numRedirectSlots = strtonum(strData);
		set_vaultdata("ADMIN_REDIRECT_SLOTS", strData);
	} else {
		set_vaultdata("ADMIN_REDIRECT_SLOTS", "0");
		numRedirectSlots = 0;
	}
 
	snprintf(strMessage, MAX_TEXT_LENGTH, "[ADMIN] Redirect Server Changed to %i", numRedirectSlots);
	selfmessage(strMessage);	
 
	log_command(strUser, strCommand, strData);
 
	return PLUGIN_HANDLED;
}
 
isReserved(strName[], UserIndex) {							//modular, yes
	if (access(32768,strName)) {
		boolReservedUsers[UserIndex - 1] = 1;				//mark this, reserved_type might change
		numReservedUsers++;							//incrememnt the counter
		return 1;
	} else { 
		boolReservedUsers[UserIndex - 1] = 0;				//mark them as NOT being reserved
		return 0;
	}
	return 0;
}
 
DoRedirect(HLName) {
	new strName[MAX_NAME_LENGTH];							//the players name
	new strMessage[MAX_TEXT_LENGTH];						//the messages to consgreet
	new strHost[MAX_TEXT_LENGTH];							//our hostname
	new strCommand[MAX_TEXT_LENGTH];						//for execclient connect 12.154.0.7:27015
 
	getstrvar("hostname",strHost,MAX_TEXT_LENGTH);				//grab the host name
	convert_string(HLName, strName,MAX_NAME_LENGTH);			//convert the users name so we can appologize formally
 
	consgreet("================================================================");
	snprintf(strMessage, MAX_TEXT_LENGTH, "Sorry, %s, but this server '%s' is currently full.", strName, strHost);
	consgreet(strMessage);								//print my new string
 
	snprintf(strMessage, MAX_TEXT_LENGTH, "We are redirecting you to: '%s'", strRedirect);
	consgreet(strMessage);								//tell them what server ip
 
	consgreet("If you wish not to, please disconnect now.");		//warn them reall good
 
	snprintf(strMessage, MAX_TEXT_LENGTH, "connect %s", strCommand);
	execclient(strName, strCommand);						//kick them out, send them away
}
 
public plugin_connect(HLUserName,HLIP,UserIndex) {
	new strName[MAX_NAME_LENGTH];							//the players name
	new ReservedType = getvar("reserve_type");				//grab the reserved type
	new numOpenSlots = getvar("public_slots_free");				//grab the current slots free
	new numReservedSlots = getvar("reserve_slots");				//grab this cvar as well
	new numMaxSlots= getvar("maxplayers");					//grab the max players variable
	convert_string(HLUserName, strName,MAX_NAME_LENGTH);
 
	numConnected++;									//count this person they are taking a slot as we work
 
	if (ReservedType == 2) {							//admin slots fill be fore public
		if ((numOpenSlots-numRedirectSlots)>0) {				//there are open slots
			isReserved(strName, UserIndex);				//count reserves
			return PLUGIN_CONTINUE;						//person should have no problems getting in
		} else {
			if ((numReservedSlots - numRedirectSlots - numReservedUsers)>0) {
				if (isReserved(strName, UserIndex)) {		//person is accessing a reserved slot
					return PLUGIN_CONTINUE;				//they are reserved access
				} else {
					write_redirect(UserIndex);			//log to file
					DoRedirect(HLUserName);				//kick them outa da house
					return PLUGIN_CONTINUE;				//they will disconnect
				}
			} else {								//this server is full
				write_redirect(UserIndex);				//log to file
				DoRedirect(HLUserName);					//begone
				return PLUGIN_CONTINUE;					//they will disconnect
			}
		} 
	} else {										//other reserved type(s) fill public slots first
		if ((numOpenSlots-numRedirectSlots)>0) {				//plenty of room
			isReserved(strName, UserIndex);				//count reserves
			return PLUGIN_CONTINUE;						//person should have no problems getting in
		} else {
			if (isReserved(strName, UserIndex)) {			//this person is reserved
				if ((numMaxSlots - numConnected - numRedirectSlots) >= numRedirectSlots) {
					return PLUGIN_CONTINUE;				//this person is taking a valid open slot on the server
				} else {
					write_redirect(UserIndex);			//log to file
					DoRedirect(HLUserName);				//send them off to die
					return PLUGIN_CONTINUE;				//they will disconnect
				}
			}
		}
	}
	return PLUGIN_CONTINUE;
}
 
public plugin_disconnect(HLUserName, UserIndex) {
	if (boolReservedUsers[UserIndex - 1]) {					//was this person using a reserved slot ?
		boolReservedUsers[UserIndex - 1] = -1;				//clear the flag
		numReservedUsers--;							//decrement the counter
	} else {
		boolReservedUsers[UserIndex - 1] = 0;
	}
	numConnected--;
	return PLUGIN_CONTINUE;
}
 
public plugin_init() {
	plugin_registerinfo("Dead_Redirect","Lets the connecting peeps connect to allied server.",STRING_VERSION);
	plugin_registercmd("admin_redirect","admin_redirect",ACCESS_RCON,"admin_redirect 'hlip:port': Changes the server redirection.");
	plugin_registercmd("admin_redirect_slot","admin_redirect_slot",ACCESS_RCON,"admin_redirect_slot <num>: Changes the redirect # of grabed slots.");
	new VaultData[MAX_DATA_LENGTH];
 
	for(new i = 0; i < MAX_PLAYERS; i++) {					//this should initialize the list on startup
		boolReservedUsers[i] = -1;						//set it to zero, no player should be in yet
	}
	numReservedUsers = 0;								//initialize this too
 
	if(get_vaultdata("ADMIN_REDIRECT", VaultData, MAX_DATA_LENGTH) != 0) {
		snprintf(strRedirect, MAX_TEXT_LENGTH, "%s", VaultData);
	} else {
		snprintf(strRedirect, MAX_TEXT_LENGTH, "12.154.0.7:27015");
		set_vaultdata("ADMIN_REDIRECT", strRedirect);			//set the vault data if not already set
	}
 
	if(get_vaultdata("ADMIN_REDIRECT_SLOT", VaultData, MAX_DATA_LENGTH) != 0) {
		numRedirectSlots = strtonum(VaultData);
	} else {
		numRedirectSlots = 0;
		set_vaultdata("ADMIN_REDIRECT_SLOT", "0");			//set the vault data if it hasn't already set
	}
 
	if(get_vaultdata("ADMIN_REDIRECT_NUM", VaultData, MAX_DATA_LENGTH) != 0) {
		numRedirected = strtonum(VaultData);
	} else {
		set_vaultdata("ADMIN_REDIRECT_NUM", "0");				//set the vault data if not already set
	}
	return PLUGIN_CONTINUE;								//continue
}