Note: The mainteinance of the scripting examples is discontinued since I no longer have an interest to continue doing so. The pages will remain here, for now, but that might not be the case in the future. You are free to download all the material on these pages and set a up mirror, or even continue the maintenance of the material by enhancing the examples yourself.

All the material in these examples are for the mIRC version 6.03. It is very likely that some or most of these examples won't work in future versions.

Writing your own event handlers for channel events

On this page I'm going through all the named events that deal with channels. These include JOIN, PART, QUIT, MODE, TOPIC, KICK and NICK plus a few numerics related to the prementioned events. There are a few events that are not handled here, mainly PRIVMSG, NOTICE and INVITE and all derivants of those events. Naturally there are a few hundred numeric events not mentioned here as well.

The examples I'm presenting here try to use mIRC's internal settings whenever there is an identifier where the settings can be get from. Because someone reading this page is probably trying to achieve more informative output, some settings are assumed: addresses and channelmodes more often than in the default output. You might often see something like '@Fred (foo@bar.com)' instead of just 'Fred'. mIRC options allow you to define target windows for different events. For example you could have all nick changes to show in status window. However since reading the target windows would require acquiring information from mirc.ini, I will just assume that all events go to channel windows. mirc.ini follows no documented standard which is why I won't start hacking it. You can easily modify the target windows by yourself simply by halting event (hide), or adding -s switch to echo (show in status).

The scripts don't specify any colors - they use $color identifier to retrieve settings from Tools/Colors. All messages that might contain control codes are put through $strip(<message>,m) identifier which applies mIRC's internal stripping settings. If you have set mIRC to strip colors and bold, the script actually strips colors and bold from the messages. The messages that possibly have colors are followed by ASCII character 15 (Control+O on mIRC) which clears the effect of all control codes. If there is a nick included in a channel related event, the nick with channelmode is received from $nick(<channel>,<nick>).pnick which returns @nick for operators and +nick for voiced.

Note that from mIRC 5.9 upwards the .pnick property returns @+nick for someone who is operator and voiced. This is probably unwanted when writing visual display routines. You can get around this by writing your own alias to return nick with its channelmode. I'm using the .pnick property in the examples so that you can directly copy the script without extra aliases.

All the events halt the default output. You should have read what help file says about halting default text. Type '/help Halting default text' to see it. Basically it's done by using ^ prefix and haltdef. With numeric events there is no prefix. When you do halt on a numeric event, the default output is halted.

Some of the examples will take use of ! event prefix. The ! means that the event is not triggered for yourself. Because the events are executed from top to bottom, you can often first do an event with ! and then without it. Taking advantage of these prefixes allows more dynamic scripting. For example you might do your own event for other people but keep the default output for events you trigger yourself.

mIRC has a few default identifiers for every event.
$nick has the nickname of user triggering the event
$address has the address of user in username@hostname format
$fulladdress has the address in nickname!username@hostname format
$chan has the channel the event happened on (assuming the event happens on a channel)
$1- has the message passed along the event (quit message, part message, kick message, new topic, new modes)


Joins

on JOIN event is simple. It uses nothing more but the default identifiers for an event. A model example of a simple event. :-)

Example script

on ^*:JOIN:#: {
  if ( $nick == $me ) echo $color(join text) -t $chan * Now talking in $chan
  else echo $color(join text) -t $chan * $nick ( $+ $address $+ ) has joined $chan
  haltdef
}

Parts

on PART event is rather simple as well. It uses only default identifiers. The part message is in $1-.

Example script

on ^*:PART:#: {
  var %message
  if ( $0 > 0 ) %message = ( $+ $strip($1-,m) $+ $chr(15) $+ )

  echo $color(part text) -t $chan * $nick($chan,$nick).pnick ( $+ $address $+ ) has left $chan %message
  haltdef
}

Quits

Quit events often cause confusion for new scripters. The problem is that there is no channel associated with the QUIT message you get from the server. If someone is on #chat and #stars and the person quits, you will get only one quit message and therefore mIRC will trigger only one event. The solution is to do a while loop that takes advantage of the $comchan identifier. $comchan(<nick>,0) returns the number of shared channels and $comchan(<nick>,<N>) returns the Nth shared channel.

The QUIT message will be sent if you share at least one channel with the user who quits. However there are situations when the quit message is sent even when the client is not aware of the user being on any shared channels. Such situations include bugs in the IRC server or a channel desynchronization. If that happens, it is best to display the quit in the status window.

Example script

on ^*:QUIT: {
  var %message
  if ( $0 > 0 ) var %message = ( $+ $strip($1-,m) $+ $chr(15) $+ )

  if ( $comchan($nick,0) == 0 ) echo $color(quit text) -set $nick ( $+ $address $+ ) has quit IRC %message

  var %x = 1
  while ( $comchan($nick,%x) ) {
    echo $color(quit text) -t $comchan($nick,%x) * $nick($comchan($nick,%x),$nick).pnick ( $+ $address $+ ) has quit IRC %message
    inc %x
  }

  haltdef
}

Modes

You can catch mode changes with on RAWMODE event. There are other events for mode changes (such as on OP/DEOP, on MODE, etc.) but the on RAWMODE event is the one that has the mode changes just as they are sent from the server. Modes can be changed by a client or a server. You can see if the mode change was made by server by checking if there is a '.' in the $nick. '.' always appears on a server name but never on a normal nickname. Note that on many networks there are also channel services that may change modes. They nearly always have an address that is similar to a normal user.

The numeric 324 is sent after you join a channel. You can see more about the numerics you get during on JOIN on my dedicated page. Numeric 324 has all the modes that don't deal with the users. A typical mode would be +nt. On raw 324, $2 has the channel, and $3- the modes. Note that you can get 324 as a reply to /mode #channel command even if you are not on the channel. That's why it's necessary to check if you are on the channel before sending an echo to the channel window.

Example script

on ^*:RAWMODE:#: {
  if ( . isin $nick ) echo $color(mode text) -t $chan * Server $nick sets mode: $1-
  else echo $color(mode text) -t $chan * $nick ( $+ $address $+ ) sets mode: $1-
  haltdef
}

raw 324:*: {
  if ( $me ison $2 ) {
    echo $color(mode text) -t $2 * Modes: $3-
    halt
  }
}

Topics

on TOPIC event is (again) very simple event. It uses the default identifiers. The actual new topic is on $1-. If the new topic is empty, it means that the topic is unset.

The numerics 331, 332 and 333 are numerics that directly deal with channel topics. When you join a channel, you will always get 332 if there is a topic. If there is a topic, you will also get 333 on many servers. The 331 is used when you query channel's topic with /topic #channel after you have joined the channel. All the mentioned numerics have the channel in $2. 332 has the current topic in $3-. 333 has the user who set the topic in $3 and the time when the topic was set on $4. The time is a very large number. It's the number of seconds since 1.1.1970. You can convert it to human-readable form with $asctime(<number>)

Example script

on ^*:TOPIC:#: {
  if ( $0 == 0 ) echo $color(topic text) -t $chan * $nick($chan,$nick).pnick ( $+ $address $+ ) clears the topic
  else echo $color(topic text) -t $chan * $nick($chan,$nick).pnick ( $+ $address $+ ) changes topic to ' $+ $strip($1-,m) $+ $chr(15) $+ '
  haltdef
}

raw 331:*: {
  echo $color(topic text) -t $2 * No topic is set
  halt
}

raw 332:*: {
  echo $color(topic text) -t $2 * Topic is ' $strip($3-,m) $+ $chr(15) $+ '
  halt
}

raw 333:*: {
  echo $color(topic text) -t $2 * Topic set by $3 on $asctime($4)
  halt
}

Kícks

The on KICK event deals with two nicks. The operator who issued the kick is in $nick and the victim of the kick is in $knick. Note that $address will have the address of the operator who issued the kick. If the kick message is empty or the kick message is operator's nick, the message is hidden. If you are kicked, there is additional echo in the status window in case the channel window is closed.

Example script

on ^*:KICK:#: {
  var %message
  if ( $0 > 0 ) %message = ( $+ $strip($1-,m) $+ $chr(15) $+ )

  if ( $knick == $me ) echo $color(kick text) -set * You were kicked from $chan by $nick %message

  echo $color(kick text) -t $chan * $nick($chan,$knick).pnick was kicked by $nick %message

  haltdef
}

Nick changes

The on NICK event is very similar to QUIT event. There is no channel where nick change happens. It's sent only once even if you shared many channels with the user. The old nick is in $nick and the new nick is in $newnick. All the internal functions work only with $newnick.

Just like in on QUIT event, it's better to check if there are no shared channels just to be safe.

Example script

on ^*:NICK: {
  ; Display the nick change in the status window if you are changing nick
  ; or if you get a nick change with no shared channels
  if ( $newnick == $me ) echo $color(nick text) -set * You are now known as $newnick
  elseif ( $comchan($newnick,0) == 0 ) echo $color(nick text) -set * $nick is now known as $newnick

  ; Display the nick change in all shared channels
  var %x = 1
  while ( $comchan($newnick,%x) ) {
    echo $color(nick text) -t $comchan($newnick,%x) * $nick is now known as $newnick
    inc %x
  }

  haltdef
}

Last updated 2003-04-05, Janne 'Geetee' Nikula, jn-mirc@zkelvin.net