mScriptBox Tutorial
Introduction to RAW Events

Written by B0P
Published with permission.

Table Of Contents

  1. Introduction
  2. What are RAW Events?
  3. How do I use RAW Events?
  4. A closer look
  5. Example 1: Channel Statistics
  6. Example 2: Bad Channel Kicker
  7. Example 3: RAW Events Logger
  8. Conclusion

1. Introduction  Back to Top

Welcome to this little article on RAW Events. When talking about "raw", we either mean raw commands sent to the server (ie, /raw privmsg nickname :message goes here instead of /msg nickname message goes here), or raw events. In both cases we're talking about the native format of the IRC server, rather than the way mIRC or your client of choice presents or uses the information. In this article, we'll be talking about raw events, not raw commands.

Pre-requirements for this article is knowledge of remotes, identifiers, if-then-else, and variables


2. What are raw events?  Back to Top

Raw events are regular mIRC scripting events that trigger when the server sends you a message as a result of something you do, for instance joining a channel. When you do this, the server will send you

  1. the names on the channel (similar to /names),
  2. the current topic of the channel as well as
  3. the channel's creation time.

Raw events receive the information from the server in it's native form, and gives you maximum flexibility in regards to how you choose to use it or present it to the user of your script.


3. How do I use RAW Events?  Back to Top

Let's first look at the syntax of raw events:
raw NUMBER:MATCHTEXT:{ commands }

NUMBER here is the number of the numeric event you wish to define, these are set down in
RFC1459, RFC2810, RFC2811, RFC2812, RFC2813
which describe the IRC protocol, and are also listed more conveniently in our RAW Numeric Reference. If a raw event does not have a numeric, you can specify it's name instead. MATCHTEXT is which text should trigger the event, much like the MATCHTEXT parameter in an on text event.
From /help raw events:

raw 322:*mirc*:{ echo 5 $1- }
will filter out all channels matching "mirc" in a /list, and echo them to the status window.

To actually *use* raw events, you need to have a firm knowledge of raw events, or be able to look up information like the RAW Numeric Reference. In addition, as so many other things in scripting and programming, most of the trick with raw events is simply seeing where they can be useful


4. A closer look  Back to Top

Let's look at the raw output of a /who:

raw 352:*:{ echo -a Raw $numeric $+ : $1- }

mIRC will by default show this output (after /who #B0P's):

#B0P's B0T H@ bop@playing.with.my.pet.IRCop.com :5 B0P's B0T - http://mirc-egg.net
#B0P's B0P-away G@ bop@rad-pc-57.cablenet-va.com :0 B0P (http://mirc-egg.net)
but as already said, this reply has been formatted by mIRC, the message the server sends mIRC is actually the one below:

$1 $2 $3 $4 $5 $6 $7 $8 $9
B0P-away #B0P's bop playing.with.my.pet.IRCop.com lineone.uk.eu.dal.net B0T H@ 5 B0P's B0T - http://mirc-egg.net
B0P-away #B0P's bop rad-pc-57.cablenet-va.com liberty.nj.us.dal.net B0P-away G@ 0 B0P (http://mirc-egg.net)
This is the nick of the user requesting the /who This is the target for the /who This is the currently returned user's identd This is the host of the currently returned user. This is the server the user is connected to This is the user's nick. This represents status in the channel as well as away/not This is the number of hops (servers between you and target) This is the realname entry

Let's make a channel stats script and see if an example makes it clearer :)


5. Example 1: Channel Statistics  Back to Top

Let's do the code first:
alias cstat { 
  SET -u20 %bcs.target $active
  SET  -u20 %bcs.352 1
  .who %bcs.target 
}

raw 352:*:{
  IF (%bcs.352) {
    HALTDEF
    INC %bcs.total
    IF (G isin $7) { 
      INC %bcs.gone
      SET %bcs.anicks %bcs.anicks $6
    }
    IF ($chr(64) isin $7) { 
      INC %bcs.ops
    }
    ELSEIF ($chr(43) isin $7) { 
      INC %bcs.voice
    }
    IF ($chr(42) isin $7) { 
      INC %bcs.ircop
      SET %bcs.nicks %bcs.nicks $6
    }
    INC %bcs.hops $8
  }
}
raw 315:*:{
  IF (%bcs.352) {
    HALTDEF
    VAR %regs = $calc(%bcs.total - (%bcs.ops + %bcs.voice))
    echo -ea Channel stats for %bcs.target $+ :
    echo -a Total users: %bcs.total
    echo -a Away users: %bcs.gone ( $+ $round($calc((%bcs.gone * 100) / %bcs.total),1) $+ % $+ ) 
    $iif(%bcs.anicks,- [ %bcs.anicks ] )
    ; Note: The above two lines have to be a single line
    echo -a Op's: %bcs.ops ( $+ $round($calc((%bcs.ops * 100) / %bcs.total),1) $+ % $+ )
    echo -a Voices: %bcs.voice ( $+ $round($calc((%bcs.voice * 100) / %bcs.total),1) $+ % $+ )
    echo -a Regulars: %regs ( $+ $round($calc((%regs * 100) / %bcs.total),1) $+ % $+ )
    echo -a Ircop's: %bcs.ircop ( $+ $round($calc((%bcs.ircop * 100) / %bcs.total),1) $+ % $+ ) 
    $iif(%bcs.nicks,- [ %bcs.nicks ] )
    ; Note: The above two lines have to be a single line
    echo -a Average hops: $round($calc(%bcs.hops / (%bcs.total -1)),1)    
    .timer 1 2 unset %bcs.*
  }
}

This is a pretty simple and unformatted scriplet but it shows you how you can use raw's for practical purposes. RAW 352 is the raw for each /who output, RAW 315 is the raw for "end of /who list", we use raw 352 to gather information about each user, and when we receive raw 315, we know that there's no more users to gain information about, so we can present the output to the user. This scriplet also shows how we can use /haltdef (or even /halt) to prevent the default output from showing up, if we didn't do this, the user would see the output of the /who as well as the nice channel stats.

The more you script with raw events, the more you'll realize both how simple it is, as well as how much it means to be able to see that this or that can be done by using raw events. For instance, a common mistake in scripting is when the scripter wants the script to take action based on what channels a different user is on (a so called pervscan), he uses the if-then-else operator ISON to determine if the user is on a certain channel or not. ISON is fine if the user running the script is on that channel too, but in most cases, he won't be, and that's where raw events come in again.


6. Example 2: Bad Channel Kicker  Back to Top

Currently the only way to know what channels a specific nickname on IRC is on, is doing a /whois on them. ISON won't do it, because as already stated; ISON reacts only on channels you are on yourself. So we have to use /whois somehow to determine the channels the user is on. There's several problems that arises here, let's try to narrow it down a little:

First, let's find out which raw events triggers on a whois (there's a lot!). I stated previously that two major sources for more info on raw events was the RFC, as well as our RAW Numeric Reference.

Take a close look at the following RAW Event numbers:
311, 312, 317, 318, 319.
In addition you may also see RAW 301 (away), 307 (dalnet - registered nick), 313 (is an ircop).

Looking over the events, we quickly see that RAW 319 is RPL_WHOISCHANNELS; it returns the channels the user specified is on. We also see that raw 318 is end of whois, useful to know for when we will be taking action based on the channels in RAW 319.

We do not need to use any information returned by any of the other raw's from the WHOIS, so we will just silence these using /haltdef, to make sure our script is looking neat. For simplicity here, we will just kick the user from the channel we specify if his channels matches any of the keywords we will look for. We will also write the keywords to match the channels against in the code itself, instead of leaving this up to the user, this can be modified using $read or storing keywords in an .ini file or in variables.

First, let's look at a typical output of RAW 319:

raw 319:*:{ echo -a $1- }

I typed /whois B0T and got this output back...:

B0P B0T@#mystro @#B0P's @#scriptech @#hdtest @#HD-Helpers @#Korsfarer @#Mirc_Resources @#B0Ptest

Again, $1 is the nick of the requester (you), $2 is the target, B0T, and $3- contains the channels the target is on.

Using this, let's move on to creating this kicker.

alias chanscan {
  IF ($active ischan) { SET -u15 %bps.chan $active }
  ELSEIF ($2 ischan) { SET -u15 %bps.chan $2 }
  ;stores the channel to kick the user from in a variable
  SET -u15 %bps.319 1
  .whois $1
}

raw 311:*:{ IF (%bps.319) { HALTDEF } }
raw 312:*:{ IF (%bps.319) { HALTDEF } }
raw 317:*:{ IF (%bps.319) { HALTDEF } }
raw 301:*:{ IF (%bps.319) { HALTDEF } }
raw 307:*:{ IF (%bps.319) { HALTDEF } }
raw 313:*:{ IF (%bps.319) { HALTDEF } }
;prevents the normal output from the /whois being shown

raw 319:*:{
  IF (%bps.319) {
    HALTDEF
    IF ((*warez* iswm $3-) || (*sex* iswm $3-)) {
      SET -u10 %bps.found 1
      ;one of the channels the user is on is containing the word warez or the word sex
    }
  }
}

raw 318:*:{
  IF (%bps.319) {
    HALTDEF
    IF (%bps.found) { kick %bps.chan $2 I don't like your channels! }
    ;if the variable was set in raw 319, the user is in one or more bad channels, kick him.
    ELSE { echo -s $2 was not in any bad channels }
  }
  .timer 1 2 unset %bps.*
  ;this should be more common in scripts. Clean up variables after use.
}

Now type /chanscan B0P in any channel to kick B0P from that channel if he's in any channels containing the words "sex" or "warez". The alias sets the channel to kick the user from, and sets the controlvariable %bps.319 to use later in the raw events, if this variable is set, we will halt the default output from the event and in some cases present our own. Finally the alias does a /whois on the nick entered.

Raw 319 matches the channels in $3- against the words "warez" and "sex", and if found, it sets a variable that is carried into raw 318 (end of whois). When raw 318 triggers, it checks to see if the variable is set, if it is, it kicks the user specified, else it lets you know that the user was not in any bad channels.


7. Example 3: RAW Events Logger  Back to Top

This script has to be in the remotes section. If active it displays the detected RAW event in a Custom Window.

==================================================================================
Author  : Merlin
Function: Displays RAW Events in a Custom window.  
==================================================================================
alias rawlog {
  ; Check if the RawLogger is already enabled, if yes disable
  IF ($group(#rawlogger).status == on) { 
    .disable #rawlogger
    ; If the @RawLogger window is still open , close it
    IF ($window(@RawLogger)) { window -c @RawLogger }
    echo $colour(info text) -ts *** Raw Logger is Disabled!
  }
  ELSE {
    ; Enable the Rawlogger
    .enable #rawlogger
    echo $colour(info text) -ts *** Raw Logger is Enabled!
  }
}
#rawlogger off
RAW *:*:{ 
  ; If @RawLogger window isn't open, create it
  IF (!$window(@RawLogger)) { 
    window -ne @RawLogger
    ; Write the header into the window
    titlebar @Rawlogger Format: RawNumber: Nickname : Returned Values 
  }
  ; Add the numeric info
  aline @RawLogger $numeric $2- 
}
#rawlogger end

8. Conclusion  Back to Top

While not among the most obvious features of mIRC scripting, learning how to use raw events is one of the most valuable things you can do, it's easy, allows you to do many things you otherwise wouldn't be able to (such as the channelscanner), and is also an interesting tool for modifying the look and feel of mIRC. To effectively use it; a decent knowledge of raw events in general and being able to look up which event does what, will surely come handy, and I hope this article have got you started on the task of mastering raw events. Good luck :)