Author Topic: Set up a chat command, how can i limit it to prevent spam?  (Read 1296 times)

Creating a command that simply makes you say something in chat when you type in something, but I don't want it to be spammable, like have a 5 second cooldown or something. Can you tell me what to do with it? Not going to paste the code since all I need to do is have the template for spam pretection.

Creating a command that simply makes you say something in chat when you type in something, but I don't want it to be spammable, like have a 5 second cooldown or something. Can you tell me what to do with it? Not going to paste the code since all I need to do is have the template for spam pretection.
When it's used, store the current time - $Sim::Time - to the client that used it under a unique variable. Then, at the very start of the command, check if the current time is greater than time + 5 seconds.

Give the client a variable (.commandCooldown)
whenever the function is run
if(!%client.commandCooldown)
%client.commandCooldown = true;

then add a schedule for setting the cooldown back to false.

There should be an example in the shotgun's code.

Give the client a variable (.commandCooldown)
whenever the function is run
if(!%client.commandCooldown)
%client.commandCooldown = true;

then add a schedule for setting the cooldown back to false.
Do not do this. All you need to know to decide if the client can use the command is how much time has passed since the client used it previously.

When it's used, store the current time - $Sim::Time - to the client that used it under a unique variable. Then, at the very start of the command, check if the current time is greater than time + 5 seconds.
Format that, please? (I'm extremely new to this)

Do not do this. All you need to know to decide if the client can use the command is how much time has passed since the client used it previously.
Could you tell me why that's not a good idea? I would like to know (I've sort of been using it for a while.)

Format that, please? (I'm extremely new to this)
In your command, put something like
%client.lastCommandTime = $Sim::Time;
Changing the variable name to something specific to your mod of course.
At the top of the command, put something like
if(%client.lastCommandTime + 5 > $Sim::Time)
   return;


If it doesn't work, post it, and we'll go from there.

Could you tell me why that's not a good idea? I would like to know (I've sort of been using it for a while.)
That way involves a variable stored on the client, an if statement to check it, a schedule, and a new function defined solely for the purpose of setting the value back (or a scheduled eval which is also pretty bad practice). This way simply involves the variable and the if statement. Simply put, it's a less complex procedure. Generally, minimizing function calls and schedule use is the best way to go.

Code: [Select]
//A
if(!%client.lastCmdtime)
%client.lastCmdtime = $sim::time - 15;

//B
if(%client.lastCmdtime + 15 < $sim::time)
{
//Stuffs goes here
messageClient(%client, '', "\c3You executed your command!");
%client.lastCmdtime = $sim::time;
}
//C
else
{
messageClient(%client, '', "\c3No Spamming");
return;
}
Heres a quick breakdown:
A -- Checks if the variable "%client.lastCmdtime" exists.  If it does not, it creates the variable and assigns &sim::time to it (The current time).
B -- If the variable %client.lastCmdtime plus 15 is less than the current time it executes the stuff and sets %client.lastCmdtime to the current time.  The 15 in the if statement is saying: "If 15 seconds have gone by then execute it".
C -- Well, i'm sure you already know this: "Else message the client and 'return;' the script (stop it)

Hope this helps!

EDIT: Just saw Jetz's post.  Yeah, instead of putting "//B" in an if statement, you could just:
Code: [Select]
if(%client.lastCmdtime + 15 > $sim::time)
       messageClient(%client, '', "\c3No Spamming");
return;
And remove "//C"

Either way would work fine.
« Last Edit: April 19, 2013, 09:10:44 PM by Vaux »

Code: [Select]
//A
if(!%client.lastCmdtime)
%client.lastCmdtime = $sim::time - 15;

//B
if(%client.lastCmdtime + 15 < $sim::time)
{
//Stuffs goes here
messageClient(%client, '', "\c3You executed your command!");
%client.lastCmdtime = $sim::time;
}
//C
else
{
messageClient(%client, '', "\c3No Spamming");
return;
}
Heres a quick breakdown:
A -- Checks if the variable "%client.lastCmdtime" exists.  If it does not, it creates the variable and assigns &sim::time to it (The current time).
B -- If the variable %client.lastCmdtime plus 15 is less than the current time it executes the stuff and sets %client.lastCmdtime to the current time.  The 15 in the if statement is saying: "If 15 seconds have gone by then execute it".
C -- Well, i'm sure you already know this: "Else message the client and 'return;' the script (stop it)

Hope this helps!

EDIT: Just saw Jetz's post.  Yeah, instead of putting "//B" in an if statement, you could just:
Code: [Select]
if(%client.lastCmdtime + 15 > $sim::time)
       messageClient(%client, '', "\c3No Spamming");
return;
And remove "//C"

Either way would work fine.
Well, you'd need brackets around it if you wanted to throw a "No spamming" message, but usually you don't need one. Additionally, A is unnecessary, since if the last use time doesn't exist, it'll be treated as 0, and if it's treated as 0, that'll be well behind you by the time you have anyone using the command. Finally, another coding practice tip: if your if statement exits the method in one case, and proceeds normally in the other, it's best to write it using a return statement in the exit case, rather than putting the entire rest of the method in a block after the continue case.

An example:
Code: [Select]
if(%client.isAdmin)
{
if(isObject(%client.player))
{
if(%client.team $= "Blue")
{
if(%client.score >= 500)
{
//stuff
}
else
messageClient(%client, '', "Not enough points!");
}
else
messageClient(%client, '', "You are not on the blue team!");
}
}
Looks worse and gets harder to read the more conditions you add.

Instead:
Code: [Select]
if(!%client.isAdmin)
return;
if(!isObject(%client.player))
return;
if(%client.team !$= "Blue")
{
messageClient(%client, '', "You are not on the blue team!");
return;
}
if(%client.score < 500)
{
messageClient(%client, '', "Not enough points!");
return;
}

//Stuff
Easier to understand and debug.

Well, you'd need brackets around it if you wanted to throw a "No spamming" message, but usually you don't need one.
Worked fine for me when I tested it.

An example:
Code: [Select]
if(%client.isAdmin)
{
if(isObject(%client.player))
{
if(%client.team $= "Blue")
{
if(%client.score >= 500)
{
//stuff
}
else
messageClient(%client, '', "Not enough points!");
}
else
messageClient(%client, '', "You are not on the blue team!");
}
}
Looks worse and gets harder to read the more conditions you add.

Instead:
Code: [Select]
if(!%client.isAdmin)
return;
if(!isObject(%client.player))
return;
if(%client.team !$= "Blue")
{
messageClient(%client, '', "You are not on the blue team!");
return;
}
if(%client.score < 500)
{
messageClient(%client, '', "Not enough points!");
return;
}

//Stuff
Easier to understand and debug.
I'm aware of both.  It is mainly a preference of your style of coding.  Just like how you format your code: tabs, spaces, no brackets, brackets.
Finally, another coding practice tip: if your if statement exits the method in one case, and proceeds normally in the other, it's best to write it using a return statement in the exit case, rather than putting the entire rest of the method in a block after the continue case.
I said either the return usage or the if usage would work.  But, overall thanks for correcting me.  Nobodys perfect.

Worked fine for me when I tested it.
Was referring to that second code section, the one with the message Client followed by the return. Since those aren't in brackets, it will message the client if they're spamming, but it will always read the return and exit the function after.

I'm aware of both.  It is mainly a preference of your style of coding.  Just like how you format your code: tabs, spaces, no brackets, brackets.I said either the return usage or the if usage would work.  But, overall thanks for correcting me.  Nobodys perfect.
Yeah, they don't have any real impact on performance, but when someone has like 10 of them all around a 500 line function and you're expected to debug it, it makes you want to track them down and revoke their coding license forever.