/* SDAL ANTIFAKE

Man kann Spielernamen für Spieler festlegen, so dass sie nur diese
benutzen dürfen.

Installation:
-------------
- LogD muss installiert sein.
- file_access_read und file_access_write müssen in der adminmod.cfg auf 1 gesetzt werden.
- allow_client_exec muss auf 1 gesetzt werden, damit man die Namensänderung durchführen kann.
- ein Ordner namens "antifake" muss unter addons/adminmod/config angelegt werden. Dort werden
 dann später die User-Files abgelegt.
 
Benutzung:
-------------
- antifake <"Teil des Spielernamens"> [optional: <erlaubter Name>]:
Damit wird eine UserDatei angelegt, in der die erlaubten Namen gespeichert werden.
Gibt man keinen "erlaubten Namen" an, so wird der derzeitig benutze Name als
einzig erlaubter Name gespeichert. Die Namesrestriktion wird sofort durchgeführt
und ist somit auch sofort gültig.

- antifake_list:
Zeigt eine Liste aller Spieler auf dem Server, deren Namen restriktiert sind.

- antifake_show <PlayerName/Steam_ID>:
Zeigt die restriktierten Namen des Spielers an, welche er nur benutzen darf.

ACHTUNG: Der Teil des Spielernamens darf keine Leerzeichen beinhalten! Man muss dann
den Teil des Spielernamens in Anführungszeichen setzen, damit es funktioniert.

To Do:
-------------
- antifake_delname <PlayerName/Steam_ID> <ZeilenNr>:
Damit man restriktierte Namen in der UserDatei löschen kann.
- antifake_delfile <PlayerName/Steam_ID>:
Damit man die Namensrestriktion des Spielers löschen kann.
- antifake <"Teil des Spielernamens"/STEAM_ID> [optional: <erlaubter Name>]:
Damit man durch Angabe der STEAM_ID auch Namen für Spieler festlegen kann,
die sich zur Zeit nicht auf dem Server befinden.

*/

#include <core>
#include <console>
#include <string>
#include <admin>
#include <adminlib>

new STRING_VERSION[MAX_DATA_LENGTH] = "28.02.04_v.0.8";

#pragma dynamic 4096

#define ACCESS_LOOK 	128
#define ACCESS_CONSOLE	131072
/*
new g_Path[]="addons/adminmod/config/antifake/";
new g_Index[]="addons/adminmod/config/antifake/index.txt";
*/
new g_PlayerDB[]="addons/adminmod/config/antifake/";
new g_RestrictName[MAX_PLAYERS];
new g_ChangedName[MAX_PLAYERS];


public plugin_init() {
	new iwrite;
	new iread;
	new allow_exec;
	iread=getvar("file_access_read");
	iwrite=getvar("file_access_write");
	allow_exec=getvar("allow_client_exec");
	if(iread && iwrite && allow_exec){
		plugin_registerinfo("SDALs ANTIFAKE","Restricting player names",STRING_VERSION);
		plugin_registercmd("antifake","antifake",ACCESS_LOOK,"antifake <PlayerName> [<NewName>]: Restricts player to use this new name or his current name only.");
		plugin_registercmd("antifake_list","antifake_list",ACCESS_LOOK,"antifake_list: Displays a list, which players have a name restriction.");
		plugin_registercmd("antifake_show","antifake_show",ACCESS_LOOK,"antifake_show <PlayerName/STEAM_ID>: Displays the names, player X is allowed to use.");
		plugin_registercmd("sdal_af_enter", "enter", ACCESS_CONSOLE);
		plugin_registercmd("sdal_af_disc", "disc", ACCESS_CONSOLE);
		plugin_registercmd("sdal_af_world", "world", ACCESS_CONSOLE);
		exec( "logd_reg 51 admin_command sdal_af_enter" );
		exec( "logd_reg 52 admin_command sdal_af_disc" );
		exec( "logd_reg 62 admin_command sdal_af_world");
	}else{
		if(!iread){
			log("[SDAL-ANTIFAKE] ^"file_access_read^" is not set to 1 in adminmod.cfg");
		}
		if(!iwrite){
			log("[SDAL-ANTIFAKE] ^"file_access_write^" is not set to 1 in adminmod.cfg");
		}
		if(!allow_exec){
			log("[SDAL-ANTIFAKE] ^"allow_client_exec^" is not set to 1 in adminmod.cfg");
		}
		plugin_registerinfo("SDALs ANTIFAKE","Plugin is disabled! Please take a look into your log files!",STRING_VERSION);
	}
	return PLUGIN_CONTINUE;
}

//////////////////////////////
//// ADMIN MOD-FUNKTIONEN ////
//////////////////////////////	

public antifake(HLCommand,HLData,HLUserName,UserIndex) {
	new Data[MAX_DATA_LENGTH];
	new Text[MAX_TEXT_LENGTH];
	new User[MAX_NAME_LENGTH];
	new PlayerName[MAX_NAME_LENGTH];
	new RestrictName[MAX_NAME_LENGTH];
	new File[MAX_TEXT_LENGTH];
	new AuthID[MAX_AUTHID_LENGTH];
	new iFileSize;
	
	convert_string(HLData,Data,MAX_DATA_LENGTH);
	convert_string(HLUserName,User,MAX_DATA_LENGTH);
	
	strsep(Data," ",PlayerName,MAX_NAME_LENGTH,RestrictName,MAX_DATA_LENGTH);
	
	if(check_user(PlayerName)){
		get_username(PlayerName,PlayerName,MAX_NAME_LENGTH);
		get_userAuthID(PlayerName,AuthID,MAX_AUTHID_LENGTH);
		strsubst(AuthID, ":", "-",MAX_AUTHID_LENGTH);
		snprintf(File,MAX_DATA_LENGTH,"%s%s.txt",g_PlayerDB,AuthID);
		if(strlen(RestrictName)!=0){
			writefile(File,RestrictName,-1);
		}else{
			writefile(File,PlayerName,-1);
			strcpy(RestrictName,PlayerName,MAX_NAME_LENGTH);
		}
		iFileSize=filesize(File);
		snprintf(Text,MAX_TEXT_LENGTH,"[SDAL-ANTIFAKE] %s restricted %s to use nick %s",User,PlayerName,RestrictName);
		log(Text);
		restrict_player(PlayerName,File,iFileSize);
	}else{
		snprintf(Text,MAX_TEXT_LENGTH,"[SDAL-ANTIFAKE] Player ^"%s^" not found on the server!",PlayerName);
		selfmessage(Text);
	}
	return PLUGIN_HANDLED;
}

public antifake_list(HLCommand,HLData,HLUserName,UserIndex) {
	new Player[MAX_NAME_LENGTH];
	new AuthID[MAX_AUTHID_LENGTH];
	new Text[MAX_TEXT_LENGTH];
	new maxplayers=maxplayercount();
	new i;
	selfmessage("---------------------");
	selfmessage("[SDAL-ANTIFAKE]");
	selfmessage("---------------------");
	selfmessage("RESTRICTED PLAYERS:");
	for(i=1;i<=maxplayers;i++){
		if(g_RestrictName[i]==1){
			if(playerinfo(i,Player,MAX_NAME_LENGTH,_,_,_,_,AuthID)){
				snprintf(Text,MAX_TEXT_LENGTH,"* %s (%s)",Player,AuthID);
				selfmessage(Text);
			}
			strinit(Text);
		}
	}
	return PLUGIN_HANDLED;
}

public antifake_show(HLCommand,HLData,HLUserName,UserIndex) {
	new Data[MAX_NAME_LENGTH];
	new Text[MAX_TEXT_LENGTH];
	new AuthID[MAX_AUTHID_LENGTH];
	new PlayerName[MAX_NAME_LENGTH];
	new File[MAX_TEXT_LENGTH];
	new i;
	new iFileSize;
	
	convert_string(HLData,Data,MAX_DATA_LENGTH);
	
	if(check_user(Data)){
		get_username(Data,PlayerName,MAX_NAME_LENGTH);
		get_userAuthID(PlayerName,AuthID,MAX_AUTHID_LENGTH);
	}else{
		new ichar;
		ichar=strcount(Data, ':');
		if(strncasecmp(Data, "STEAM_", 6)==0 && ichar==2){
			strcpy(PlayerName,Data,MAX_NAME_LENGTH);
			strcpy(AuthID,Data,MAX_AUTHID_LENGTH);
		}else{
			snprintf(Text,MAX_TEXT_LENGTH,"[SDAL-ANTIFAKE] Player ^"%s^" not found!",Data);
			selfmessage(Text);
			return PLUGIN_HANDLED;
		}
	}
	
	strsubst(AuthID, ":", "-",MAX_AUTHID_LENGTH);
	snprintf(File,MAX_DATA_LENGTH,"%s%s.txt",g_PlayerDB,AuthID);
	selfmessage("---------------------");
	selfmessage("[SDAL-ANTIFAKE]");
	selfmessage("---------------------");
	snprintf(Text,MAX_TEXT_LENGTH,"RESTRICTED NAME(S) OF %s:",PlayerName);
	selfmessage(Text);
	if(fileexists(File)){
		iFileSize=filesize(File);
		for(i=1;i<=iFileSize;i++){
			readfile(File,Data,i,MAX_DATA_LENGTH);
			snprintf(Text,MAX_TEXT_LENGTH," *%i. %s", i, Data);
			selfmessage(Text);
			strinit(Text);
		}
	}
	return PLUGIN_HANDLED;
}

//////////////////////////
//// HILFS-FUNKTIONEN ////
//////////////////////////				
	
/*Logd-Enter Funktion*/
public enter(HLCommand,HLUserIndex){
	new strUserIndex[MAX_NAME_LENGTH];
	new UserIndex;
	convert_string(HLUserIndex, strUserIndex, MAX_NAME_LENGTH);
	UserIndex=strtonum(strUserIndex);
	reset_array(UserIndex);
	check_player(UserIndex);
	return PLUGIN_CONTINUE; 
}

/*Logd-World Funktion*/
public world(HLCommand,HLData){
	new Data[MAX_DATA_LENGTH];
	new maxplayers=maxplayercount();
	new i;
	convert_string(HLData, Data, MAX_DATA_LENGTH);
	if(Data[6]=='S'){
		for(i=1;i<=maxplayers;i++){
			if(g_RestrictName[i]==1 && g_ChangedName[i]==1){
				g_ChangedName[i]=0;
				check_player(i);
			}
		}
	}					
	return PLUGIN_CONTINUE; 
}

public plugin_info(HLOldName,HLNewName,UserIndex) {
	new Data[MAX_DATA_LENGTH];
	new NewName[MAX_NAME_LENGTH];
	new OldName[MAX_NAME_LENGTH];
	new File[MAX_TEXT_LENGTH];
	new Player[MAX_NAME_LENGTH];
	new AuthID[MAX_AUTHID_LENGTH];
	new iDead;
	new iFileSize;
	new i;
	new check;

	convert_string(HLNewName, NewName, MAX_NAME_LENGTH);
	convert_string(HLOldName, OldName, MAX_NAME_LENGTH);
	
	if(streq(OldName,NewName)==0) {
		if(g_RestrictName[UserIndex]==1){
			if(playerinfo(UserIndex,Player,MAX_NAME_LENGTH,_,_,_,iDead,AuthID)){
				if(iDead){
					g_ChangedName[UserIndex]=1;
				}else{
					/*
					Faszinierendes Problem:
					Die Namensänderung scheint sehr langsam zu sein. Wenn ich
					nämlich hier anhand des UserIndex die Funktion check_player aufrufe,
					wird der neu angenommene Spielername in der Funktion check_player
					nicht erkannt. Daher muss ich nun hier nochmal die selbe Funktionen
					hinterlegen und mit dem "New Name" im File überprüfen.
					Ein Delay-Timer, um dann check_player aufzurufen, würde zu unnötigen 
					Fehlern führen, wenn der Spieler mehrmals seinen Namen nacheinander
					ändert.
					*/
					strsubst(AuthID, ":", "-",MAX_AUTHID_LENGTH);
					snprintf(File,MAX_DATA_LENGTH,"%s%s.txt",g_PlayerDB,AuthID);
					if(fileexists(File)){
						iFileSize=filesize(File);
						for(i=0;i<=iFileSize;i++){
							readfile(File,Data,i,MAX_DATA_LENGTH);
							if(strcmp(NewName,Data)==0){
								check=0;
								break;
							}else{
								check=1;
							}
						}
						if(check){
							/*Spieler wird mit ersten gespeicherten Namen umbenannt*/
							restrict_player(Player,File,1);
						}
					}
				}
			}
		}
	}
	return PLUGIN_CONTINUE;
}

check_player(UserIndex){
	new Data[MAX_DATA_LENGTH];
	new File[MAX_TEXT_LENGTH];
	new AuthID[MAX_AUTHID_LENGTH];
	new Player[MAX_NAME_LENGTH];
	new iFileSize;
	new i;
	new check;
	
	if(playerinfo(UserIndex,Player,MAX_NAME_LENGTH,_,_,_,_,AuthID)){
		strsubst(AuthID, ":", "-",MAX_AUTHID_LENGTH);
		snprintf(File,MAX_DATA_LENGTH,"%s%s.txt",g_PlayerDB,AuthID);
		if(fileexists(File)){
			g_RestrictName[UserIndex]=1;
			iFileSize=filesize(File);
			for(i=0;i<=iFileSize;i++){
				readfile(File,Data,i,MAX_DATA_LENGTH);
				if(strcmp(Player,Data)==0){
					check=0;
					break;
				}else{
					check=1;
				}
			}
			if(check){
				/*Spieler wird mit ersten gespeicherten Namen umbenannt*/
				restrict_player(Player,File,1);
			}
		}
	}
}

restrict_player(Player[],File[],LineNr){
	new Data[MAX_DATA_LENGTH];
	new ReName[MAX_TEXT_LENGTH];
	messageex(Player,"[ANTIFAKE] Du darfst keinen Fakenamen benutzen!",print_chat);
	readfile(File,Data,LineNr,MAX_DATA_LENGTH);
	snprintf(ReName,MAX_TEXT_LENGTH,"setinfo name ^"%s^"",Data);
	execclient(Player,ReName);
}

/*Logd-Disconnect Funktion*/
public disc(HLCommand,HLUserIndex){
	new strUserIndex[MAX_NAME_LENGTH];
	new UserIndex;
	convert_string(HLUserIndex, strUserIndex, MAX_NAME_LENGTH);
	UserIndex=strtonum(strUserIndex);
	reset_array(UserIndex);
	return PLUGIN_CONTINUE; 
}

reset_array(UserIndex){
	g_RestrictName[UserIndex]=0;
}