Author Topic: Warn Script (finished) (thanks to Toumaz)  (Read 1265 times)

0 Members and 1 Guest are viewing this topic.

Offline Kavukamari

  • Camper
  • ***
  • Posts: 435
  • 3.14159265358979, mmm... pi
Warn Script (finished) (thanks to Toumaz)
« on: September 19, 2007, 10:33:16 pm »
Code: [Select]
var
warns: array[1..32] of byte;
warningfile: TStringArray;
warning_number: integer;

//This is the new fancy function we're gonna use; xsplit - made by KeYDoN.
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
inc(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;
end;

procedure ActivateServer();
begin
//Load the contents of warns.txt and split it into an array
warningfile:=xsplit(ReadFile('scripts/warns.txt'),#13+#10);
//Store the number of lines for later use.
warning_number:=GetArrayLength(warningfile)-1;
end;

function OnCommand(ID: Byte; Text: string):boolean;
var
w,i,warnkicks: byte;
found: boolean;
writestring: string;
begin
Result:=false;
if GetPiece(LowerCase(Text),' ',0) = '/warn' then begin
try
w:=strtoint(GetPiece((Text), ' ', 1));
except
exit;
end;

warns[w]:=warns[w]+1;

SayToPlayer(w,'You have been warned by admin, warnings: '+inttostr(warns[w]));
SayToPlayer(w,'Warns until warn kick: '+inttostr(5-warns[w]));

if warns[w]=5 then begin
found:=false;
//Loop through all the lines in the file.
for i:=0 to warning_number do
//In the file we're going to store data structured as <player IP><ascii char 1 = #1><number of warnings><#13><#10>.
//So get the first piece containing the player IP.
if GetPiece(warningfile[i],#1,0)=GetPlayerStat(w,'ip') then begin
//Yep, we found it.
found:=true;
//Update the existing entry.
warnkicks:=strtoint(GetPiece(warningfile[i],#1,1))+1;
warningfile[i]:=GetPiece(warningfile[i],#1,0)+#1+inttostr(warnkicks);
break;
end;

if found=false then begin
//Right, we didn't find it. Increase the size of the array...
warning_number:=warning_number+1;
SetArrayLength(warningfile,warning_number+1);
//... and add the new warning data to it.
warnkicks:=1;
warningfile[warning_number]:=GetPlayerStat(w,'ip')+#1+'1';
end;

//Kick/ban the player, and giggle afterwards.
if warnkicks=5 then begin
SayToPlayer(w,'You have been banned for 4320 minutes (3 days)');
SayToPlayer(w,'Try not to get warned so much, please');
BanPlayer(w,4320);
warnkicks:=strtoint(GetPiece(warningfile[i],#1,1))-5;
warningfile[i]:=GetPiece(warningfile[i],#1,0)+#1+inttostr(warnkicks);
end else begin
SayToPlayer(w,'You have been warn kicked, Warn kicks: '+inttostr(warnkicks));
SayToPlayer(w,'Warn kicks left until 3-day ban: '+inttostr(5-warnkicks));
KickPlayer(w);
end;

//And write everything back to the file. Smooth!
writestring:='';
for i:=0 to warning_number do
writestring:=writestring+warningfile[i]+#13+#10;
WriteFile('scripts/warns.txt',writestring);

end;
end;
end;

procedure OnLeaveGame(ID, Team: byte; Kicked: boolean);
begin
warns[ID]:=0;
Command('/say Warn script by Kavukamari, Script fixed/debuged by Toumaz');
end;

procedure OnJoinGame(ID, Team: byte);
begin
Command('/say Warn script by Kavukamari, Script fixed/debuged by Toumaz');
end;

It's fin'd, the whole script is attached to this post (extract to ...\soldat ) all files needed are included
« Last Edit: September 20, 2007, 09:06:14 pm by Kavukamari »
"Be mindful of fame, show a mighty courage, watch against foes. Nor shalt thou lack what thou desirest, if with thy life thou hast comest out from that heroic task."

Offline Toumaz

  • Veteran
  • *****
  • Posts: 1906
Re: Warn Script help
« Reply #1 on: September 19, 2007, 11:35:02 pm »
... Eh.

First off, I'd recommend using Xsplit instead of reading INI files in this case, because... well, it's somewhat cleaner, and the code you're using will not even work.

Code: [Select]
INI:=strtoint(INI)+1You've declared INI as a string, and you're trying to assign the value of an integer to it. This is what's causing the type mismatch. And you forgot the semicolon.
.. To be completely honest though, I really have no idea what the hell you're trying to do with said variable.

Code: [Select]
INI:=ReadINI('Scripts/Warn/Warns.ini','Warn Kicked',IDToIP(w),'0');Right. You read the number of "warning kicks" for the IP number from the .ini file. I'd also recommend you to use GetPlayerStat(w,'ip') instead of IDToIP(w) - it's a bit more reliable as I've heard.

Code: [Select]
if (ContainsString(INI,IDToIP(w)) = true) then beginWait, what? If the player's IP is found inside.. the string, of the number of warnings he had? Eh?

Code: [Select]
if (ContainsString(INI,IDToIP(w)) <> true) then beginGoogle "else". Learn it. Use it. ...not that I still know what that code is for, but nevermind.

Code: [Select]
KickPlayer(w);
SayToPlayer(w,'You have been warn kicked, Warn kicks: '+INI);
SayToPlayer(w,'Warn kicks left until 3-day ban: '+inttostr(5-strtoint(INI)));
Minor thing; you kick the player before the messages are sent, so he won't even see them.

Code: [Select]
if (strtoint(INI) = 5) then begin
      BanPlayer(w,4320);
      SayToPlayer(w,'You have been banned for 4320 minutes (3 days)');
      SayToPlayer(w,'Try not to get warned so much, please');
end;
And now you're trying to ban a player that's not in the game any more. And sending the message too late.

Code somewhat fixed up:

Code: [Select]
var
warns: array[1..32] of byte;
warnkicks: byte;

function OnCommand(ID: Byte; Text: string):boolean;
var
w: Byte;
begin
Result:=false;
if GetPiece(LowerCase(Text),' ',0) = '/warn' then begin
try
w:=strtoint(GetPiece((Text), ' ', 1));
except
exit;
end;

warns[w]:=warns[w]+1;

SayToPlayer(w,'You have been warned by admin, warnings: '+inttostr(warns[w]));
SayToPlayer(w,'Warns until warn kick: '+inttostr(5-warns[w]));

if warns[w]=5 then begin
warnkicks:=strtoint(ReadINI('Scripts/Warn/Warns.ini','Warn Kicked',GetPlayerStat(w,'ip'),'0'))+1;
//Stuff will break in so many ways with storing data in the .ini files. Hell, it won't work at all. Use Xsplit and manual loops to store the data instead.
WriteLnFile('scripts/warns.ini',IDToIP(w)+'='+inttostr(warnkicks));
if warnkicks=5 then begin
SayToPlayer(w,'You have been banned for 4320 minutes (3 days)');
SayToPlayer(w,'Try not to get warned so much, please');
BanPlayer(w,4320);
end else begin
SayToPlayer(w,'You have been warn kicked, Warn kicks: '+inttostr(warnkicks));
SayToPlayer(w,'Warn kicks left until 3-day ban: '+inttostr(5-warnkicks));
KickPlayer(w);
end;
end;
end;
end;

procedure OnLeaveGame(ID, Team: byte; Kicked: boolean);
begin
warns[ID]:=0;
end;

But, as I've commented it out in the code, storing data using .INI files in this scenario will not work. Use Xsplit instead.

Offline Kavukamari

  • Camper
  • ***
  • Posts: 435
  • 3.14159265358979, mmm... pi
Re: Warn Script help
« Reply #2 on: September 19, 2007, 11:44:40 pm »
how? (how do I use XSplit)

and why doesn't INI's work?

Date Posted: September 20, 2007, 12:43:37 am
P.S. I love how literal you are :P :P :P

it gives my coding funny criticism :P
"Be mindful of fame, show a mighty courage, watch against foes. Nor shalt thou lack what thou desirest, if with thy life thou hast comest out from that heroic task."

Offline Toumaz

  • Veteran
  • *****
  • Posts: 1906
Re: Warn Script help
« Reply #3 on: September 20, 2007, 05:02:38 am »
and why doesn't INI's work?
'Cos you'll end up storing duplicate entries.

how? (how do I use XSplit)

dfg;sdaf;fsad, okay then. Something like this:

Code: [Select]
var
warns: array[1..32] of byte;
warningfile: TStringArray;
warning_number: integer;

//This is the new fancy function we're gonna use; xsplit - made by KeYDoN.
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
inc(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;
end;

procedure ActivateServer();
begin
//Load the contents of warns.txt and split it into an array
warningfile:=xsplit(ReadFile('scripts/warns.txt'),#13+#10);
//Store the number of lines for later use.
warning_number:=GetArrayLength(warningfile)-1;
end;

function OnCommand(ID: Byte; Text: string):boolean;
var
w,i,warnkicks: byte;
found: boolean;
writestring: string;
begin
Result:=false;
if GetPiece(LowerCase(Text),' ',0) = '/warn' then begin
try
w:=strtoint(GetPiece((Text), ' ', 1));
except
exit;
end;

warns[w]:=warns[w]+1;

SayToPlayer(w,'You have been warned by admin, warnings: '+inttostr(warns[w]));
SayToPlayer(w,'Warns until warn kick: '+inttostr(5-warns[w]));

if warns[w]=5 then begin
found:=false;
//Loop through all the lines in the file.
for i:=0 to warning_number do
//In the file we're going to store data structured as <player IP><ascii char 1 = #1><number of warnings><#13><#10>.
//So get the first piece containing the player IP.
if GetPiece(warningfile[i],#1,0)=GetPlayerStat(w,'ip') then begin
//Yep, we found it.
found:=true;
//Update the existing entry.
warnkicks:=strtoint(GetPiece(warningfile[i],#1,1))+1;
warningfile[i]:=GetPiece(warningfile[i],#1,0)+#1+inttostr(warnkicks);
break;
end;

if found=false then begin
//Right, we didn't find it. Increase the size of the array...
warning_number:=warning_number+1;
SetArrayLength(warningfile,warning_number+1);
//... and add the new warning data to it.
warnkicks:=1;
warningfile[warning_number]:=GetPlayerStat(w,'ip')+#1+'1';
end;

//Kick/ban the player, and giggle afterwards.
if warnkicks=5 then begin
SayToPlayer(w,'You have been banned for 4320 minutes (3 days)');
SayToPlayer(w,'Try not to get warned so much, please');
BanPlayer(w,4320);
end else begin
SayToPlayer(w,'You have been warn kicked, Warn kicks: '+inttostr(warnkicks));
SayToPlayer(w,'Warn kicks left until 3-day ban: '+inttostr(5-warnkicks));
KickPlayer(w);
end;

//And write everything back to the file. Smooth!
writestring:='';
for i:=0 to warning_number do
writestring:=writestring+warningfile[i]+#13+#10;
WriteFile('scripts/warns.txt',writestring);

end;
end;
end;

procedure OnLeaveGame(ID, Team: byte; Kicked: boolean);
begin
warns[ID]:=0;
end;

I haven't tested the code, and I'm currently unable to (I'm in school as of now), but it should hopefully work properly. If not I'll fix it once I get home.

Offline Kavukamari

  • Camper
  • ***
  • Posts: 435
  • 3.14159265358979, mmm... pi
Re: Warn Script help
« Reply #4 on: September 20, 2007, 09:00:14 pm »
thanks, if it works I'll make some last adjustments (nothing too big, just adding some more functions and stuff, no editing of working code)

I'll put a big dedication in the file too, it'll say in the console (when someone joins, changes team, or leaves, or gets kicked or banned) that I made the warn script and you did ALL of the debugging

Date Posted: September 20, 2007, 02:00:50 pm
it works great! I edited it to reset warnkicks if the player is banned by the script

latest version in first post
"Be mindful of fame, show a mighty courage, watch against foes. Nor shalt thou lack what thou desirest, if with thy life thou hast comest out from that heroic task."