Awaiting server replies

From Scriptwiki
Jump to: navigation, search

Often times you may find yourself writing a script that requires knowledge from the server. For example, you may try to change your nick name and find that the nickname is in use, or join a channel only to find that you are banned. This raises a question: How do I make my script compensate for these things.

Catching the Raw

First of all, you have no way of knowing if you are banned from a channel until you try to join, or if a nickname is taken until you try to take it yourself. After all, how can mIRC know every channel's banlist or the nickname of everyone on the server? It cannot. You must wait on the server to tell you with what is called a raw event.

For this tutorial we are going to use the above example of trying to take a nickname which is already in use, or contains bad characters. Consider the following script for use on a bot:

; When someone types !nick [Word]
On *:TEXT:!nick &:#: {
  ; If they are an op on the channel they are speaking from
  if ($nick isop $chan) {
     ; Tell them I am changing my name
     msg $chan Changing my nickname...
     ; Change my name to the second word they said
     nick $2
  }
}

This will work just fine, but if something goes wrong we will never know what - did the command not work? Is it just laggy? Is the nickname taken? Is the nickname not allowed?

As you know, if you tried to take someones nick or use an invalid one, you would see one of the two following messages:

<Name> Nickname is already in use.
<Nick> Erroneous Nickname

These are messages from the server telling us that our request to change our nickname has failed. We must use these to tell the channel of such a failure. To do this, two events, one to catch each message from the server, these are called raw events. These particular raw events are #432 ERR_ERRONEUSNICKNAME, and #433 ERR_NICKNAMEINUSE. A full list of the standard RAW events can be found here. The debug command can also be used to find other raw events and exactly what they look like - however that is beside the point for this tutorial.

Let's make two raw events to catch these:

raw 432:*:echo -atg The nickname $2 has illegal characters in it.
raw 433:*:echo -atg The nickname $2 is taken.

These events will echo an error message on failure. $2 here represents the nickname that you tried to use. To find these, we take a look at each raw's format. These can be found on their wiki pages or in the debug window. If you look on their wiki pages you see:

Raw 432 Format: <source> 432 <target> <nick> :Erroneous Nickname
Raw 433 Format: <source> 433 <target> <nick> :Nickname is already in use.

For mIRC raw events the tokenization ($N) starts after the raw number. So here, $1 is the target (Your current nickname), $2 is the nickname you are trying to use, and $3- are the messages "Erroneous Nickname" and "Nickname is already in use."

Reporting the Response

Now this is all well and good, but we cannot message these to $chan, after all, there is no channel in any of these raw events. These have nothing to do with our !nick command! Well, that's where variables come in. For either of these raw events to tell the channel about themselves, they must know which channel to use. For this to happen, we need to set a variable:

; When someone types !nick [Word]
On *:TEXT:!nick &:#: {
  ; If they are an op on the channel they are speaking from
  if ($nick isop $chan) {
     ; Tell them I am changing my name
     msg $chan Changing my nickname...
     ; Set a variable with this channel in it for our raw events
     set -u10 %_tutorial.nickChangeChannel $chan
     ; Change my name to the second word they said
     nick $2
  }
}


And now, for ten seconds, %_totial.nickChangeChannel is set to the channel we are changing out nickname for. Now, in our raw events, we can tell this channel of their failure:

 raw 432:*:if (%_tutorial.nickChangeChannel) { msg %_tutorial.nickChangeChannel The nickname $2 has illegal characters in it. }
 raw 433:*:if (%_tutorial.nickChangeChannel) { msg %_tutorial.nickChangeChannel The nickname $2 is taken. }

With all three of these events, the script is done.

<User> !nick aca20031
<Bot> Changing my nickname...
<Bot> The nickname aca20031 is taken.
User !nick @c@20031
<Bot> Changing my nickname...
<Bot> The nickname @c@20031 has illegal characters in it.


Examples

The nick change script:

; When someone types !nick [Word]
On *:TEXT:!nick &:#: {
  ; If they are an op on the channel they are speaking from
  if ($nick isop $chan) {
     ; Tell them I am changing my name
     msg $chan Changing my nickname...
     ; Set a variable with this channel in it for our raw events
     set -u10 %_tutorial.nickChangeChannel $chan
     ; Change my name to the second word they said
     nick $2
  }
}
raw 432:*:if (%_tutorial.nickChangeChannel) { msg %_tutorial.nickChangeChannel The nickname $2 has illegal characters in it. }
raw 433:*:if (%_tutorial.nickChangeChannel) { msg %_tutorial.nickChangeChannel The nickname $2 is taken. }

The banned from channel script:

; When we get the !join channel command
on *:TEXT:!join &:#: {
   ; Set a dynamically named variable to this channel, for the channel we are attempting to join
   set -u5 %_tutorial.chanJoin $+ $2 $chan
   ; Attempt to join $2
   join $2
 }
; On ERR_BANNEDFROMCHAN (When we get the message saying we are banned)
raw 474:*: {
  ; If this channel was joined as a result of !join (And our variable was set)
  if (%_tutorial.chanJoin [ $+ [ $2 ] ]) { 
     ; Tell the channel (Stored in the variable) of our failure
     msg $v1 I am banned from $2 
  } 
}

See Also