//============================================================================//
//                   MAKE SURE TO READ THE README FILE FOR                    //
//                IMPORTANT INSTRUCTIONS ON CONFIGURING THIS FILE!!           //
//============================================================================//
//                                                                            //
//  I've been over most of the stuff you'll need to know in README.TXT        //
//  So I'm going to keep this short, and to the point of configuring this     //
//  file if you plan to compile it yourself.                                  //
//                                                                            //
//  MAX COMMANDS: This is the maximum number of commands that will be read    //
//                from cvars.ini                                              //
//                                                                            //
//  DefaultAction: This is what the script should do if it is run with no     //
//                 paramaters. Acceptable values are help, version, list,     //
//                 or any cvar thats in the list. You COULD use a filtered    //
//                 command or one not in the list, but it would be pointless. //
//                                                                            //
//  ReadCfgFile: The file that admin_cvar should read to get its list.        //
//                                                                            //
//  CfgFileDelim: The Delimiter used to seperate fields in the config file.   //
//                                                                            //
//  Best of luck, Questions? Ask in the AM Script forum. I'll check it.       //
//  ~Cheek                                                                    //
//                                                                            //
//============================================================================//
//                   MAKE SURE TO READ THE README FILE FOR                    //
//                IMPORTANT INSTRUCTIONS ON CONFIGURING THIS FILE!!           //
//============================================================================//
 
#include <core>
#include <console>
#include <string>
#include <admin>
#include <adminlib>
 
//============================================================================//
//                                                                            //
//                 CONFIG OPTIONS BEGIN HERE                                  //
//                                                                            //
//============================================================================//
 
#define MAX_COMMANDS 30				
#define ACCESS_MINIMUM ACCESS_ALL		
 
new DefaultAction[MAX_COMMAND_LENGTH] = "list";
new ReadCfgFile[MAX_DATA_LENGTH] = "cvar.ini";
new CfgFileDelim[2] = "|";
 
 
//============================================================================//
// /////////////// DO NOT EDIT BELOW THIS POINT ///////////////////////////// //
// /////////////// DO NOT EDIT BELOW THIS POINT ///////////////////////////// //
// /////////////// DO NOT EDIT BELOW THIS POINT ///////////////////////////// //
//============================================================================//
new STRING_VERSION[MAX_DATA_LENGTH] = "2.51.0";
new flag=0;
new Cvar[MAX_COMMANDS][MAX_COMMAND_LENGTH];
new CvarCmd[MAX_COMMANDS][MAX_COMMAND_LENGTH];
new CvarAcc[MAX_COMMANDS];
new CvarHelp[MAX_COMMANDS][MAX_TEXT_LENGTH];
 
 
public admin_cvar(HLCommand, HLData, HLUserName, UserIndex){
	new User[MAX_NAME_LENGTH];
	new FullData[MAX_DATA_LENGTH];
	new Data[MAX_DATA_LENGTH];
	new Command[MAX_COMMAND_LENGTH];
	new Text[MAX_DATA_LENGTH];
	new Value[MAX_NUMBER_LENGTH];
	new i;
	flag=0;
 
	convert_string(HLUserName, User, MAX_NAME_LENGTH);
	convert_string(HLCommand,Command,MAX_COMMAND_LENGTH);
	convert_string(HLData,FullData,MAX_DATA_LENGTH);
 
	if (strlen(FullData)==0) { strcpy(FullData, DefaultAction, MAX_COMMAND_LENGTH); }
	strsplit(FullData," ",Data,MAX_DATA_LENGTH,Value,MAX_NUMBER_LENGTH);
 
	/* This is where bad commands get filtered out. You can add lines here if you know you dont want certain commands being run, and are worried about security or misconfiguration */
	if ( (strcasestr(Data, "rcon") 		!= -1) ) { admin_cvar_bye(User); }
	if ( (strcasestr(Data, "exit")		!= -1) ) { admin_cvar_bye(User); }
	if ( (strcasestr(Data, "quit")		!= -1) ) { admin_cvar_bye(User); }
	if ( (strcasestr(Data, "killserver")	!= -1) ) { admin_cvar_bye(User); }
	if ( (strcasestr(Data, "password")	!= -1) ) { admin_cvar_bye(User); }
	if ( (strcasestr(Data, "exec")		!= -1) ) { admin_cvar_bye(User); }
	if ( (strcasestr(Data, "log")		!= -1) ) { admin_cvar_bye(User); }
	if ( (strcasestr(Data, "startmovie")	!= -1) ) { admin_cvar_bye(User); }
 
	/* Special parameter to show version */
	if ( (strcasecmp(Data, "version")==0) ) {
		selfmessage("[ADMIN_CVAR] Cheek's Cvar Managment v1.0");
		flag=1;
	}
 
	/* In game help system. If necessary, you can add extra info here :o) */
	if ( (strcasecmp(Data, "help")==0) ) {
		selfmessage("[ADMIN_CVAR] Usage: admin_cvar [<cvar>|help|version|list] [value]");
		selfmessage("[ADMIN_CVAR] For list of available commands, use: admin_cvar list");
		selfmessage("[ADMIN_CVAR] For admin_cvar version, use: admin_cvar version");
		selfmessage("");
		selfmessage("[ADMIN_CVAR] About:");
		selfmessage("[ADMIN_CVAR] This plugin allows you to edit any server Cvar, that's listed in cvar.ini");
		selfmessage("[ADMIN_CVAR] It is completely customizable, and can be tailored to let any level admin");
		selfmessage("[ADMIN_CVAR] change any cvar. Only cvars you have access to, will show up when you admin_cvar list");
		flag=1;
	}
 
	if ( (strcasecmp(Data, "list")==0) ) {
		selfmessage("[ADMIN_CVAR] Command List:");
		strcpy(Text, "[ADMIN_CVAR]", MAX_TEXT_LENGTH);
		for (i=0;((i<MAX_COMMANDS) && (strlen(Cvar[i]) != 0));i++){
			if (check_auth(CvarAcc[i])) {
				strcat(Text, " ", MAX_TEXT_LENGTH);
				strcat(Text, Cvar[i], MAX_TEXT_LENGTH);
				flag=2;
			}
		}
		if (flag==2) {
			selfmessage(Text);
		} else {
			selfmessage("[ADMIN_CVAR] You do not have access to any settings through admin_cvar.");
			flag=1;
		}
	}
 
	for (i=0;(i<MAX_COMMANDS && strlen(Cvar[i]) != 0 && flag==0);i++){
		if (strcasecmp(Data,Cvar[i])==0) {
			//snprintf(Text,MAX_TEXT_LENGTH,"[ADMIN_CVAR] Checking access level of %s for %s against %i", User, Cvar[i], CvarAcc[i]);
			//selfmessage(Text);
			if (!check_auth(CvarAcc[i])) {
				//snprintf(Text,MAX_TEXT_LENGTH,"[ADMIN_CVAR] %s, Your current auth level is not set for %s (Needed %i)", User, Cvar[i], CvarAcc[i]);
				snprintf(Text,MAX_TEXT_LENGTH,"[ADMIN_CVAR] %s, Your current auth level is not set for %s", User, Cvar[i]);
				selfmessage(Text);
				flag=3;
			} else {
				if (strlen(Value)==0) {
					new helptext[MAX_TEXT_LENGTH];
					new gValue[MAX_TEXT_LENGTH];
 
					getstrvar(CvarCmd[i], gValue, MAX_TEXT_LENGTH);
					snprintf(Text,MAX_TEXT_LENGTH,"[ADMIN_CVAR] Current Value: %s = %s", CvarCmd[i], gValue);
					selfmessage(Text);
					strcpy(helptext, "[ADMIN_CVAR] ", MAX_TEXT_LENGTH);
					strcat(helptext, CvarHelp[i], MAX_TEXT_LENGTH);
					selfmessage(helptext);
					exec(CvarCmd[i]);
					flag=1;
				} else {
					new sRconCmd[MAX_DATA_LENGTH];
 
					say_command(User, Command, FullData);
					snprintf(sRconCmd, MAX_DATA_LENGTH, "%s %s", CvarCmd[i], Value);
					exec(sRconCmd);
					flag=1;
				}
			}
		}
	}
 
	if(i<=MAX_COMMANDS && flag==0) {
		snprintf(Text,MAX_TEXT_LENGTH,"[ADMIN_CVAR] You may not admin_cvar %s because it's not listed.",Data);
		selfmessage(Text);
	}
 
	if(i<=MAX_COMMANDS && flag==3) {
		snprintf(Text,MAX_TEXT_LENGTH,"[ADMIN_CVAR] You may not admin_cvar %s because you don't have access.",Data);
		selfmessage(Text);
	}
 
	return PLUGIN_HANDLED;
}
 
/* Function to make the calling user quit if he decides he wants to try to abuse admin_cvar as rcon */
admin_cvar_bye(User[]){
	new Text[MAX_DATA_LENGTH];
 
	snprintf(Text, MAX_TEXT_LENGTH, "[ADMIN] %s, dont screw with the server!", User);
	say(Text);
	execclient(User,"quit");
	flag=1;
}
 
/* This function reads the config file, and stores all the cvars into arrays for reading later, when called. */
readcfg(filename[]){
	new sData[MAX_DATA_LENGTH];
	new sData1[MAX_COMMAND_LENGTH];
	new sData2[MAX_COMMAND_LENGTH];
	new sData3[MAX_NUMBER_LENGTH];
	new sData4[MAX_TEXT_LENGTH];
	new i;
	new CvN=0;
	new Text[MAX_DATA_LENGTH];
 
	/*Loops until it runs out of memory or runs out of file*/
	if (fileexists(filename)){
		for (i=0;(i<=MAX_COMMANDS && readfile(filename,sData,(i+1),MAX_DATA_LENGTH));i++){
			strsep(sData, CfgFileDelim, sData1, MAX_COMMAND_LENGTH, sData2, MAX_COMMAND_LENGTH, sData3, MAX_NUMBER_LENGTH, sData4, MAX_TEXT_LENGTH);
			if (strncmp(sData, "//", 2)!=0 && strncmp(sData, ";", 1)!=0 && strlen(sData1)>0 && strlen(sData2)>0 && strlen(sData3)>0 && strlen(sData4)>0){
				strcpy(Cvar[CvN],sData1,MAX_COMMAND_LENGTH);
				strcpy(CvarCmd[CvN],sData2,MAX_COMMAND_LENGTH);
				CvarAcc[CvN] = strtonum(sData3);
/* Until i can figure out a way to display lines longer than 100, this is replaced by the next line so its trimmed */
// 				strcpy(CvarHelp[CvN],sData4,MAX_TEXT_LENGTH);
				strncpy(CvarHelp[CvN],sData4,80,MAX_TEXT_LENGTH);
 
/*
// These are debug messages to test if records are getting read into arrays correctly.
//				snprintf(Text, MAX_TEXT_LENGTH, "== Cvar#%i = Alias: %s = Cmd: %s = Access: %i", CvN, Cvar[CvN], CvarCmd[CvN], CvarAcc[CvN]);
//				selfmessage(Text);
//				snprintf(Text, MAX_TEXT_LENGTH, "== sData#%i = Alias: %s = Cmd: %s = Access: %i", CvN, sData1, sData2, sData3);
//				selfmessage(Text);
*/
				CvN++;
			}
		}
		snprintf(Text,MAX_TEXT_LENGTH,"[ADMIN_CVAR] File found and processed (%s): %i cvars added to admin_cvar", ReadCfgFile, CvN);
		selfmessage(Text);
	} else {
		snprintf(Text,MAX_TEXT_LENGTH,"[ADMIN_CVAR] File Not Found (%s).", ReadCfgFile);
		selfmessage(Text);
	}
}
 
public plugin_init() {
	plugin_registerinfo("Cheek's cvar executer","Enables admins to execute server vars that are in the cvar.ini",STRING_VERSION);
	plugin_registercmd("admin_cvar","admin_cvar",ACCESS_MINIMUM,"admin_cvar [<var>|help|version|list]:  Enables you to execute any server variable that is listed in the cvar.ini.");
 
	readcfg(ReadCfgFile);
	return PLUGIN_CONTINUE;
}