Effective Repeat Kicker
Author: Kintar0
Date: August 14, 2000
Written for Clan X Scripterz

Kicking repeater's in a channel isn't a really difficult task; however, doing it when, where, and how you want it is a bit harder to do. For example, anyone may be able to kick a repeater after his second repeat but what if you want to kick him after the 4th time or even the 10th time? Well, that shouldn't be a problem, a script is only as good as it's scripter.

There are 2 common mistakes I have seen in repeat scripts. One is that the script is not channel specific, meaning the script doesn't count repeats on a certain channel. If the user is on 2 or more channels and says the same thing on 2 or more of those channels you are on, that will increase the user's repeat status even though the user actually didn't repeat. The other common problem I see is that most repeat kickers only kick after 2 repeats and that option is usually not changable.

Let's establish what an effective repeat kicker needs. First, it needs to be channel specific (as we stated above). It needs some error checking to see if you can kick the user(if you are an op), if the user is in the channel(it happens), and if the user is a op, voice, or regular user. Also, it needs to make sure the user repeated and make sure it repeated X  amount of times before you attempt to kick the user.

Now let us get into the coding. Before we get into the actual repeat kicker coding, we need to make sure we have a few objects defined. We must define the amount of repeats before kicking the user. We must define how much time before a user may repeat again without being kicked. And last, we must define the amount of time the ban will last. Three simple variables should do the job.

Here's how we can do this, in mIRC type:

  /set %rp_offences 3
  This will define the repeat limit.

  /set %rp_bantime 60
  This will define the ban time in seconds.

  /set %rp_duration 60
  This will define the time before the repeat is reset.
  For example, if the user repeats more than 3 times within 60 seconds, you will kick/ban them.

Now with those three variables set, we can get into the actual code which a repeat will trigger. Using an ON TEXT event is all we'll need here.
Here's the repeat kicker code using our three variables above to determine our repeat guidelines:

on @*:text:*:#: {
  if ( %rp_duration == $null ) { set %rp_duration 60 }
  if ( %rp_bantime == $null ) { set %rp_bantime 60 }
  if ( %rp_offences == $null ) { set %rp_offences 3 }
  if ( $nick isreg # ) {
    var %rp.repeats = rp. $+ $nick $+ . $+ $chan
    var %rp.text = rp. $+ $nick $+ . $+ $chan $+ .text
    if ( % [ $+ [ %rp.repeats ] ] == $null ) {
      set -u [ $+ [ %rp_duration ] ] % [ $+ [ %rp.repeats ] ] 1
      set -u [ $+ [ %rp_duration ] ] % [ $+ [ %rp.text ] ] $1-
    }
    elseif ( % [ $+ [ %rp.text ] ] == $1- ) {
      inc % [ $+ [ %rp.repeats ] ]
    }
    elseif ( % [ $+ [ %rp.text ] ] != $1- ) {
      set -u [ $+ [ %rp_duration ] ] % [ $+ [ %rp.text ] ] $1-
      set -u [ $+ [ %rp_duration ] ] % [ $+ [ %rp.repeats ] ] 1
    }
    if ( % [ $+ [ %rp.repeats ] ] > %rp_offences ) {
      ban -u [ $+ [ %rp_bantime ] ] # $nick 2
      kick # $nick % [ $+ [ %rp.repeats ] ] repeats in %rp_duration second(s
      unset % [ $+ [ %rp.repeats ] ]
      unset % [ $+ [ %rp.text ] ]
    }
  }
}

Does the code look confusing? Well let's get a brief explanation line by line. Remember to define the three variables which I showed above the repeat kick code. If you don't define any of those three variables, the code will set it to a predefined default. You may always modify those three settings when you desire.

Let's discuss the basic functions of the code first. The script simply checks if 3 variables are set, and if they are not, mIRC will set them to a predefined value. Next it checks if the user is a regular user on the channel (non op/voice). Once it establishes that and if the user who triggered the event is a regular user then mIRC checks if the user already has stats for repeating. If not, then it creates them. The script creates 2 variables for the nickname in that channel. If the user already has repeat stats, then it checks if the user's text matched previous text from the user. If it matches, the script increases the repeat count stats for that user and channel. Finally, it checks if the user has passed the limit of repeats which you specified, if the user is over the limit, it kick/ban's the user for the amount of time you may specify and remove that user's stats.

Now that you know what the code above does. Let's discuss the code itself and why it is set up as it is.
This event is pretty simple although it may seems little complex due to all the [ and ]'s. Evaluation brackets are explained fairly well in mIRC's help file. If you look at the coding closely, it is not very complex after all. There was just a few if-the-else statements and variable calls which make up most of the script.

The only problem you may encounter when making your own repeat kicker is getting identifiers to correctly evaluate when defining variables. You should've noticed how the code has %rp.repeats and %rp.text. These 2 variables are used with % [ $+ [ %rp.???? ] ] to correctly call up the nick/channel's status variables.

When working with variables, remember that variables are stored permanantly unless they are properly unset. Sometimes you may disconnect unexpectedly or the computer may crash leaving all these repeat variables around and manually removing them everytime gets annoying. So here's what we can do:

Method 1: on *:start: { unset %rp.* }
Method 2: on *:connect: { unset %rp.* }
Method 3: on *:disconnect: { unset %rp.* }
Method 4:
  on *:part:#: {
    var %rp.text = rp. $+ $nick $+ . $+ $chan $+ .text
    var %rp.repeats = rp. $+ $nick $+ . $+ $chan
    var %rp.me = rp. $+ * $+ . $+ $chan $+ *
    if ( $nick == $me ) { unset % [ $+ [ %rp.me ] ] | return }
    unset % [ $+ [ %rp.text ] ]
    unset % [ $+ [ %rp.repeats ] ]
  }

You can use all of these methods, all of them at once or any combination of them together. All of these methods will help you keep that variable list small. Using at least method 1 would be very much recommended.

Words for thought

Using variables to store important information can get rather heavy on the variable list. You may want to consider other alternatives. You can store information in a text file or ini files as well and work just as effectively. It may mean a bit more code but it has it's advantages, such as a more reliable source and it is less likely that you will remove this information by mistake.

You should consider using user levels to check if a user should be kicked rather than just checking to see if a user is a regular user on the channel.

A final thought, it may be a nice and usefull idea to create a system to warn users that they have been repeating and further violations will result in a kick/ban.

Either way, you can decide what you want to add, edit, and/or remove from what you see here. Be creative and work with it. It'll only make things better.