Nickname Registration

From Soldat Community Wiki
Jump to: navigation, search

Script by Spkka uses Keydon's xSplit

const
//TEAMS
  ALPHA = 1;
  BRAVO = 2;
  CHARLIE = 3;
  DELTA = 4;
  SPECTATOR = 5;
//GAME MODES
  DEATHMATCH = 0;
  POINTMATCH = 1;
  TEAMMATCH = 2;
  CTF = 3;
  RAMBO = 4;
  INF = 5;
  HTF = 6;
//WEAPONS
  DEAGLES = 1;
  HKMP5 = 2;
  AK74 = 3;
  STEYR = 4;
  SPAS = 5;
  RUGER = 6;
  M79 = 7;
  BARRET = 8;
  MINIMI = 9;
  MINIGUN = 10;
  FLAMER = 11;
  BOW = 12;
  FLAMEBOW = 13;
  SOCOM = 0;
  KNIFE = 14;
  CHAINSAW = 15;
  LAW = 16;
  MAXTEAMS = 5;
  MAXPLAYER = 16;

var
ingameKills, ingameDeaths, ingameSelfkills: array [1..MAXPLAYER] of integer;
nickname_Password, nickname_IP: array [1..MAXPLAYER] of string;
nickname_Name, nickname_Kills, nickname_Deaths, nickname_Selfkills: array [1..MAXPLAYER] of string;
oldPassword, newPassword: array [1..MAXPLAYER] of string;
nickStatus: array [1..MAXPLAYER] of integer;
GOOD: longint;
BAD: longint;
kdKills, kdDeaths: array [1..MAXPLAYER] of integer;
kdRatio: array [1..MAXPLAYER] of single;

//ARRAYHIGH
function arrayHi( tester: TStringArray ): integer;
begin
	result := GetArrayLength( tester ) - 1;
end;

//XSPLIT
function xsplit(const source: string; const delimiter: string):TStringArray;
var
	i,x,d:integer;
	s:string;
begin
	d:=length(delimiter);
	x:=0;
	i:=1;
	SetArrayLength(Result,1);
	while(i<=length(source)) do begin
		s:=Copy(source,i,d);   	
	    	if(s=delimiter) then begin
	    		i:=i+d;		
	    		inc(x,1);
	    		SetArrayLength(result,x+1);
	    	end else begin  	     
	    		result[x]:= result[x]+copy(s,1,1);
	    		inc(i,1);
	  	end;
	end;
	if Result[ArrayHi(Result)]='' then SetArrayLength(result,x);
end;

//ACTIVATESERVER
procedure ActivateServer();
var
	b: byte;
begin
	//change these if you want a other colours for GOOD/BAD writeconsole messages
	GOOD := $EE00FF00;
	BAD:= $FFFF4444;

	//set all ID's logged out
	for b := 1 to MAXPLAYER do
	begin
		nickStatus[b] := 0;
	end
end;

//APPONIDLE
procedure AppOnIdle(Ticks: integer);
begin
end;

//FILTERFILENAME
function filterFilename(filename: string):string;
var
	i,len: byte;
	c: string;
begin
	len := length(filename);
	result := '';

	for i := 1 to len do
       	begin
		c := copy(filename,i,1);
		if (c=chr(92)) or (c='/') or (c='\') or (c=':') or (c='*') or (c='?') or (c='"') or (c='<') or (c='>') or (c='|') or (c='.') then
		result := result + '_'
		else
		result := result + c;
	end
end;

//LOADNICKNAME
function loadNickname(nick: string; ID: byte): string;
var
	temparray: TStringArray;
	fileData,fileName: string;
begin
	//filter player name
	fileName := filterFileName( nick );

	//check if player profile exists and load profile in string
	if FileExists('stats/nickreg/'+filename+'.txt') = true then
	begin
		filedata := ReadFile('stats/nickreg/'+filename+'.txt')
	
		//split all profile into a array
		temparray := xsplit(filedata,chr(13)+chr(10));
		nickname_Name[ID] := temparray[0];
		nickname_Password[ID] := temparray[1];
		nickname_IP[ID] := temparray[2];
		nickname_Kills[ID] := temparray[3];
		nickname_Deaths[ID] := temparray[4];
		nickname_Selfkills[ID] := temparray[5];
		result := nickname_Password[ID];
	end else
	begin
		//if file does't exist then ask player to create profile and set all his ID info empty
		WriteConsole(ID,'Type /create ''Your Password'' to create a profile!',GOOD);
		WriteConsole(ID,'Stats are not stored without a profile!',GOOD);
		WriteConsole(ID,'Do not use passwords you use elsewhere.', BAD);
		nickStatus[ID] := 0;
		nickname_Name[ID] := '';
		nickname_Password[ID] := '';
		nickname_Ip[ID] := '';
		result := '';
	end
end;		
	
//SAVE NICKNAME
procedure SaveNickname(name,password,ip: string; NewKills,NewDeaths,NewSelfkills: integer; currentDate:string; ID: byte);
var
	filename,outdata: string;
begin
	//filter player name
	filename := FilterFilename(name);
	
	//check is nickname doens't already exist
	if FileExists('stats/nickreg/'+filename+'.txt') = true then
	begin
		WriteConsole( ID, 'Nickname already exists!', BAD );
	end else 
	begin
		currentDate := FormatDate('dd:mm:yy');

		//set data to write
		outdata := name+chr(13)+chr(10)+
			   password+chr(13)+chr(10)+
	          	   ip+chr(13)+chr(10)+
		           inttostr(NewKills)+chr(13)+chr(10)+
               		   inttostr(NewDeaths)+chr(13)+chr(10)+
			   inttostr(NewSelfkills)+chr(13)+chr(10)+
		 	   currentDate+chr(13)+chr(10);
		
		//write new profile
		WriteFile('stats/nickreg/'+filename+'.txt',outdata);
	end
end;

//UPDATE NICKNAME
procedure UpdateNickname(nick: string; ID: byte);
var
	temparray: TStringArray;
	OldKills,OldDeaths,OldSelfkills: integer;
	NewKills,NewDeaths,NewSelfkills: integer;
	outdata: string;
	fileName, fileData: string;
	ip, currentDate: string;
begin
	filename := FilterFilename(nick);
	if getPlayerStat( ID, 'Active' ) then
	begin
		//if nickname exists
		filedata := ReadFile('stats/nickreg/'+filename+'.txt');	

		//check if player is logged in to update new stats
		if nickStatus[ID] = 1 then
		begin
			//check if file wasn't empty
			if filedata <> '' then
			begin
				//split data
				temparray := xsplit(filedata,chr(13)+chr(10));
				Nickname_IP[ID] := temparray[2];
				Nickname_Kills[ID] := temparray[3];
				Nickname_Deaths[ID] := temparray[4];
				Nickname_Selfkills[ID] := temparray[5];
		
				//get old kills/deaths/selfkills from data
				OldKills := strtoint(Nickname_Kills[ID]);
				OldDeaths := strtoint(Nickname_Deaths[ID]);
				OldSelfkills := strtoint(Nickname_Selfkills[ID]);
	
				//count new kills/deats/selfkills 
				NewKills := OldKills + IngameKills[ID];
				NewDeaths := OldDeaths + IngameDeaths[ID];
				NewSelfkills := OldSelfkills + IngameSelfkills[ID];
					
				//get player ip and currentdate
				ip := getPlayerStat( ID, 'ip');
				currentDate := FormatDate('dd:mm:yy');
					
				//set data to write
				outdata := 	nickname_Name[ID]+chr(13)+chr(10)+
						Nickname_Password[ID]+chr(13)+chr(10)+
						ip+chr(13)+chr(10)+
						inttostr(NewKills)+chr(13)+chr(10)+
						inttostr(NewDeaths)+chr(13)+chr(10)+
						inttostr(NewSelfkills)+chr(13)+chr(10)+
						currentDate+chr(13)+chr(10);
				
				//update the player profile
				WriteFile('stats/nickreg/'+nickname_Name[ID]+'.txt',outdata);
			end else 
			begin
				//if data inside profile was empty clear the name, pass and ip
				Nickname_Name[ID] := '';
				Nickname_Password[ID] := '';
				Nickname_IP[ID] := '';
			end
		end else
		begin
			Writeln('Player did not login for stats!');
		end
	end
end;

//ONCOMMAND
function OnCommand(ID: Byte; Text: string): boolean;
begin
	Result := false; 
end;

//ONPLAYERCOMMAND
function OnPlayerCommand(ID: Byte; Text: string): boolean;
var
	inputNick, InputPassword, InputPasswordLogin, nick: string;
	currentDate: string;
begin
	//displays player stats
	if (Copy(Text,1,6) = '/stats') then
       	begin
		if GetPlayerStat(ID, 'Active') = true then
		begin
			nick := GetPlayerStat(ID,'name');

			//check if player already got profile or not
			if FileExists('stats/nickreg/'+filterFileName(nick)+'.txt') = true then
		  	begin
				//load player profile
				LoadNickname(FilterFilename(GetPlayerStat(ID,'name')),ID);
			
				//display stats
				WriteConsole(ID,'Kills: ' +nickName_Kills[ID],GOOD);
				WriteConsole(ID,'Deaths: ' +nickName_Deaths[ID],GOOD);
				WriteConsole(ID,'SelfKills: '+nickName_SelfKills[ID],GOOD);
				
				//check if player has more then 0 deaths otherwise its divide by zero 
				if strtoint(nickName_Deaths[ID]) > 0 then 
				begin
					kdKills[ID] := strtoint(nickName_Kills[ID]);
					kdDeaths[ID] := strtoint(nickName_Deaths[ID]);
					kdRatio[ID] := kdKills[ID] / kdDeaths[ID];
					WriteConsole(ID,'K/D Ratio: '+floattostr(roundto(kdRatio[ID],2)),GOOD);
				end
			end else
			begin
				WriteConsole(ID,'You do not have a profile!',BAD);
			end
		end
	end

	//create new account
	if (Copy(Text,1,8) = '/create ') then
       	begin
		//check if player isn't logged in already
		if nickStatus[ID] = 0 then
		begin
			//check if player is active
			if GetPlayerStat(ID, 'Active') = true then
			begin
				//get player nick
				nick := GetPlayerStat(ID,'name');
			
				//check if player already got profile or not
				if FileExists('stats/nickreg/'+filterFileName(nick)+'.txt') = false then
			       	begin
					//get his password from text
					InputPassword := Text;
					delete(InputPassword,1,8);
		
					//if input isn't empty 
					if InputPassword <> '' then
					begin	
						//check password length
						if length(inputPassword) < 17 then 
						begin	
							//Get the current date
							currentDate := FormatDate('hh:nn:ss am/pm');
	
							//Save player account into file
							SaveNickname(GetPlayerStat(ID,'name'),InputPassword,GetPlayerStat(ID,'ip'),0,0,0,currentDate, ID);
							WriteConsole(ID,'Nickname ' + GetPlayerStat(ID,'name') + ' successfully registered!',GOOD);
							WriteConsole(ID,'Nickname ' + GetPlayerStat(ID,'name') + ' now logged in!',GOOD);
							WriteConsole(ID,'Your password is ' + InputPassword + ' - do not forget it!',GOOD);
							WriteLn('NickReg: ' + GetPlayerStat(ID,'name') + ' registered from ' + GetPlayerStat(ID,'ip'));
							//login player that registered
							nickStatus[ID] := 1;
						end else
						begin
						WriteConsole(ID,'Max length password is 16 characters!',BAD);
						end
					end else
					begin
						WriteConsole(ID,'No password found. Please try again.',BAD);
					end
				end else
				begin
					WriteConsole(ID,'You are already a registered user!',BAD);
				end
			end
		end
	end

	//change password
	if (Copy(Text,1,12) = '/changepass ') then
       	begin
		//check if player is logged in
		if nickStatus[ID] = 1 then
		begin
			//check if player is active
			if GetPlayerStat(ID, 'Active') = true then
			begin
				//get player nick
				nick := GetPlayerStat(ID,'name');
			
				//check if player already got profile or not
				if FileExists('stats/nickreg/'+filterFileName(nick)+'.txt') = true then
			       	begin
					//get his password from text
					InputPassword := Text;
					delete(InputPassword,1,12);

					//set old and new password
					oldPassword[ID] := GetPiece(InputPassword,' ',0);
					newPassword[ID] := GetPiece(InputPassword,' ',1);
		
					//check if old password match
					if oldPassword[ID] = nickName_Password[ID] then
					begin	
						//check length of his newpassword
						if length(newPassword[ID]) < 17 then 
						begin
							//set new password to ID
							nickName_Password[ID] := newPassWord[ID];
	
							//save new password to profile
							UpdateNickname(GetPlayerStat(ID,'name'),ID);
							WriteConsole(ID,'Password changed to: '+newPassword[ID],GOOD);
						end else
						begin
							WriteConsole(ID,'Max length password is 16 characters!',BAD);
						end
					end else
					begin
						WriteConsole(ID,'Wrong password!',BAD);
					end
				end else
				begin
					WriteConsole(ID,'No profile found!',BAD);
				end
			end
		end else
		begin
			WriteConsole(ID,'Please login first!',BAD);
		end
	end

	//change nickname
	if (Copy(Text,1,12) = '/changenick ') then
       	begin
		//check if player is logged in
		if nickStatus[ID] = 1 then
		begin
			//check if player is active
			if GetPlayerStat(ID, 'Active') = true then
			begin
				//get player nick
				nick := GetPlayerStat(ID,'name');
			
				//check if player already got profile or not
				if FileExists('stats/nickreg/'+filterFileName(nick)+'.txt') = true then
			       	begin
					//get his password and nick from text
					InputNick := Text;
					delete(InputNick,1,12);

					//check if password is right
					if nickName_Password[ID] = GetPiece(InputNick,' ',0) then
					begin
						//check length of his new nickname
						if length(GetPiece(InputNick,' ',1)) < 25 then 
						begin
							//set new nickname to ID
							nickName_Name[ID] := GetPiece(InputNick,' ',1);
				
							//save new password to profile
							UpdateNickname(GetPlayerStat(ID,'name'),ID);
							WriteConsole(ID,'NickName changed to: '+nickName_Name[ID],GOOD);
							WriteConsole(ID,'Please rejoin the server with your new nick to load your new profile',GOOD);
						end else
						begin
						WriteConsole(ID,'Nickname is over 24 characters, please pick another',BAD);
						end
					end else
					begin
						WriteConsole(ID,'Wrong Password!',BAD);
					end
				end else
				begin
					WriteConsole(ID,'No profile found!',BAD);
				end
			end
		end else
		begin
			WriteConsole(ID,'Please login first!',BAD);
		end
	end

	//login
	if (Copy(Text,1,7) = '/login ') then 
	begin
		//check if player isn't logged in yet
		if (nickStatus[ID] = 0) then 
		begin
			//if player is active
			if GetPlayerStat(ID, 'Active')= true then
			begin
				//get player nick
				nick := getPlayerStat(ID, 'Name' );
				
				if FileExists('stats/nickreg/'+filterFileName(nick)+'.txt') = true then
				begin
					//get password from text
					InputPasswordLogin := Text;
					delete(InputPasswordLogin,1,7);
		
					//Check password login
					if InputPasswordLogin = Nickname_Password[ID] then
					begin
						//login the player and set tasktimer
						nickStatus[ID] := 1;
						WriteConsole(ID,'You are now logged in!',GOOD);	
						WriteConsole(ID,'Type /apply to get started!',GOOD);
					end else
					begin 
						WriteConsole(ID,'Wrong password!',BAD);
					end
				end else 
				begin
					WriteConsole(ID,'No profile found!',BAD);
				end
			end	
		end else
		begin
			WriteConsole(ID,'You are already logged in!',BAD);
		end
	end

	//Logout
	if (Copy(Text,1,7) = '/logout') then 
	begin
		//check is player is logged in
		if (nickStatus[ID] = 1) then
		begin
			WriteConsole(ID,'You have been logged out!',GOOD);
			WriteConsole(ID,'Type /login ''password'' to login.',GOOD);

			//set player status to logged out
			nickStatus[ID] := 0;
		end else
		begin
			WriteConsole(ID,'Already logged out!',BAD);
		end
	end
  Result := false; 
end;

//ONPLAYERSPEAK
procedure OnPlayerSpeak(ID: byte; Text: string);
begin	
	if (copy(Text,1,9) = '!commands') then
	begin
		WriteConsole(ID,'Commands are: /login, /logout, /changepass, /changenick, /stats',GOOD);
		WriteConsole(ID,'!login for example will display info how to login',GOOD);
	end
	
	if (copy(Text,1,6) = '!login') then
	begin
		WriteConsole(ID,'Typ /login ''your password'' to login',GOOD);
	end
	
	if (copy(Text,1,7) = '!logout') then
	begin
		WriteConsole(ID,'Typ /logout ''your password'' to logout',GOOD);
	end

	if (copy(Text,1,11) = '!changepass') then
	begin
		WriteConsole(ID,'Typ /changepass ''old password'' ''new password'' to set a new password',GOOD);
	end

	if (copy(Text,1,11) = '!changenick') then
	begin
		WriteConsole(ID,'Typ /changenick ''your password'' ''new nickname'' to set a new nickname',GOOD);
	end

	if (copy(Text,1,6) = '!stats') then
	begin
		WriteConsole(ID,'Typ /stats to view your current stats',GOOD);
	end

end;

//JOINTEAM
procedure OnJoinTeam(ID, Team: byte);
begin	
	//check if player is active
	if getPlayerStat( ID, 'Active' ) = true then
	begin
		//kick player if nickname is above 24 characters
		if length(getPlayerStat( ID, 'name' )) > 24 then
		begin
			WriteConsole(ID,'...your name is over 24 characters, please change it.',BAD);
			KickPlayer(ID);
		end

		//load player profile
		LoadNickname(FilterFilename(GetPlayerStat(ID,'name')),ID);

		//check if the ip's match
		if nickname_IP[ID] <> '' then
		begin
			if (getPlayerStat( ID, 'ip' )) = nickname_IP[ID] then
			begin
				//login the player and set tasktimer
				nickStatus[ID] := 1;
				WriteConsole(ID,'Your profile was found. Autologin started!',GOOD);
				WriteConsole(ID,'Stats are now stored!',GOOD);
				WriteConsole(ID,'Type /logout to logout.',GOOD);
			end else
			begin
				nickStatus[ID] := 0;
				WriteConsole(ID,'IP changed. Type /login ''password'' to login!',GOOD);
			end
		end
	end
end;	

//ONLEAVEGAME
procedure OnLeaveGame(ID, Team: byte; Kicked: boolean);
begin
	//check is player is logged in
	if (nickStatus[ID] = 1) then
	begin
		//update his stats before he left
		UpdateNickname(GetPlayerStat(ID,'name'),ID);
	end
	
	//unset all player variables 
	nickStatus[ID] := 0;
	IngameKills[ID] := 0;
	IngameDeaths[ID] := 0;
	IngameSelfkills[ID] := 0;
	nickname_Name[ID] := '';
	nickname_Password[ID] := '';
	nickname_IP[ID] := '';
	nickname_Kills[ID] := ''; 
	nickname_Deaths[ID] := '';
	nickname_Selfkills[ID] := '';
	oldPassword[ID] := '';
	newPassword[ID] := '';
end;

//ONPLAYERKILL
procedure OnPlayerKill(Killer, Victim: byte; Weapon: string);
begin	 
	//if player is suicidal
	if (Killer = Victim) then 
	begin
		//check if player is logged in
		if nickStatus[Killer] = 1 then
		begin
			//increase selfkills with 1
			IngameSelfkills[killer] := IngameSelfkills[killer] +1;
		end
	end

	//if player isn't the victim
	if (killer <> victim) then 
	begin
		//check is killer is logged in
		if nickStatus[Killer] = 1 then
		begin
			//increase kills of killer with 1
			IngameKills[killer] := IngameKills[killer] +1;
		end

		//check is victim is logged in
		if nickStatus[victim] = 1 then
		begin
			//increase deaths of victim with 1
			IngameDeaths[victim] := IngameDeaths[victim] +1;
		end
	end
end;	

//ONFLAGSCORE
procedure OnFlagScore(ID, TeamFlag: byte);
begin
end;

//MAPCHANGE
procedure OnMapChange(NewMap: string);
var
	i: byte;	
begin	
	//reset kills,deaths,selfkills
	for i := 1 to MAXPLAYER do 
	begin
		IngameKills[i] := 0;
		IngameDeaths[i] := 0;
		IngameSelfkills[i] := 0;
	end
end;
NOTE! It will need 2 folders in the soldatserver directory like:
c:/soldatserver/stats/nickreg
Thanks to Toumaz and Sai`ke and some others i forgot!!!