2 # RFC 2812 Internet Relay Chat: Client Protocol
5 # "Welcome to the Internet Relay Network
6 # <nick>!<user>@<host>"
8 # "Your host is <servername>, running version <ver>"
10 # "This server was created <date>"
12 # "<servername> <version> <available user modes>
13 # <available channel modes>"
15 # - The server sends Replies 001 to 004 to a user upon
16 # successful registration.
19 # "Try server <server name>, port <port number>"
21 # - Sent by the server to a user to suggest an alternative
22 # server. This is often used when the connection is
23 # refused because the server is already full.
26 # ":*1<reply> *( " " <reply> )"
28 # - Reply format used by USERHOST to list replies to
29 # the query list. The reply string is composed as
32 # reply = nickname [ "*" ] "=" ( "+" / "-" ) hostname
34 # The '*' indicates whether the client has registered
35 # as an Operator. The '-' or '+' characters represent
36 # whether the client has set an AWAY message or not
40 # ":*1<nick> *( " " <nick> )"
42 # - Reply format used by ISON to list replies to the
46 # "<nick> :<away message>"
48 # ":You are no longer marked as being away"
50 # ":You have been marked as being away"
52 # - These replies are used with the AWAY command (if
53 # allowed). RPL_AWAY is sent to any client sending a
54 # PRIVMSG to a client which is away. RPL_AWAY is only
55 # sent by the server to which the client is connected.
56 # Replies RPL_UNAWAY and RPL_NOWAWAY are sent when the
57 # client removes and sets an AWAY message.
60 # "<nick> <user> <host> * :<real name>"
62 # "<nick> <server> :<server info>"
64 # "<nick> :is an IRC operator"
66 # "<nick> <integer> :seconds idle"
68 # "<nick> :End of WHOIS list"
70 # "<nick> :*( ( "@" / "+" ) <channel> " " )"
72 # - Replies 311 - 313, 317 - 319 are all replies
73 # generated in response to a WHOIS message. Given that
74 # there are enough parameters present, the answering
75 # server MUST either formulate a reply out of the above
76 # numerics (if the query nick is found) or return an
77 # error reply. The '*' in RPL_WHOISUSER is there as
78 # the literal character and not as a wild card. For
79 # each reply set, only RPL_WHOISCHANNELS may appear
80 # more than once (for long lists of channel names).
81 # The '@' and '+' characters next to the channel name
82 # indicate whether a client is a channel operator or
83 # has been granted permission to speak on a moderated
84 # channel. The RPL_ENDOFWHOIS reply is used to mark
85 # the end of processing a WHOIS message.
88 # "<nick> <user> <host> * :<real name>"
90 # "<nick> :End of WHOWAS"
92 # - When replying to a WHOWAS message, a server MUST use
93 # the replies RPL_WHOWASUSER, RPL_WHOISSERVER or
94 # ERR_WASNOSUCHNICK for each nickname in the presented
95 # list. At the end of all reply batches, there MUST
96 # be RPL_ENDOFWHOWAS (even if there was only one reply
97 # and it was an error).
100 # Obsolete. Not used.
103 # "<channel> <# visible> :<topic>"
107 # - Replies RPL_LIST, RPL_LISTEND mark the actual replies
108 # with data and end of the server's response to a LIST
109 # command. If there are no channels available to return,
110 # only the end reply MUST be sent.
113 # "<channel> <nickname>"
115 RPL_CHANNELMODEIS=324
116 # "<channel> <mode> <mode params>"
119 # "<channel> :No topic is set"
121 # "<channel> :<topic>"
123 # - When sending a TOPIC message to determine the
124 # channel topic, one of two replies is sent. If
125 # the topic is set, RPL_TOPIC is sent back else
129 # <channel> <set by> <unixtime>
133 # - Returned by the server to indicate that the
134 # attempted INVITE message was successful and is
135 # being passed onto the end client.
138 # "<user> :Summoning user to IRC"
140 # - Returned by a server answering a SUMMON message to
141 # indicate that it is summoning that user.
144 # "<channel> <invitemask>"
145 RPL_ENDOFINVITELIST=347
146 # "<channel> :End of channel invite list"
148 # - When listing the 'invitations masks' for a given channel,
149 # a server is required to send the list back using the
150 # RPL_INVITELIST and RPL_ENDOFINVITELIST messages. A
151 # separate RPL_INVITELIST is sent for each active mask.
152 # After the masks have been listed (or if none present) a
153 # RPL_ENDOFINVITELIST MUST be sent.
156 # "<channel> <exceptionmask>"
157 RPL_ENDOFEXCEPTLIST=349
158 # "<channel> :End of channel exception list"
160 # - When listing the 'exception masks' for a given channel,
161 # a server is required to send the list back using the
162 # RPL_EXCEPTLIST and RPL_ENDOFEXCEPTLIST messages. A
163 # separate RPL_EXCEPTLIST is sent for each active mask.
164 # After the masks have been listed (or if none present)
165 # a RPL_ENDOFEXCEPTLIST MUST be sent.
168 # "<version>.<debuglevel> <server> :<comments>"
170 # - Reply by the server showing its version details.
171 # The <version> is the version of the software being
172 # used (including any patchlevel revisions) and the
173 # <debuglevel> is used to indicate if the server is
174 # running in "debug mode".
176 # The "comments" field may contain any comments about
177 # the version or further version details.
180 # "<channel> <user> <host> <server> <nick>
181 # ( "H" / "G" > ["*"] [ ( "@" / "+" ) ]
182 # :<hopcount> <real name>"
185 # "<name> :End of WHO list"
187 # - The RPL_WHOREPLY and RPL_ENDOFWHO pair are used
188 # to answer a WHO message. The RPL_WHOREPLY is only
189 # sent if there is an appropriate match to the WHO
190 # query. If there is a list of parameters supplied
191 # with a WHO message, a RPL_ENDOFWHO MUST be sent
192 # after processing each list item with <name> being
196 # "( "=" / "*" / "@" ) <channel>
197 # :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )
198 # - "@" is used for secret channels, "*" for private
199 # channels, and "=" for others (public channels).
202 # "<channel> :End of NAMES list"
204 # - To reply to a NAMES message, a reply pair consisting
205 # of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the
206 # server back to the client. If there is no channel
207 # found as in the query, then only RPL_ENDOFNAMES is
208 # returned. The exception to this is when a NAMES
209 # message is sent with no parameters and all visible
210 # channels and contents are sent back in a series of
211 # RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark
215 # "<mask> <server> :<hopcount> <server info>"
217 # "<mask> :End of LINKS list"
219 # - In replying to the LINKS message, a server MUST send
220 # replies back using the RPL_LINKS numeric and mark the
221 # end of the list using an RPL_ENDOFLINKS reply.
224 # "<channel> <banmask>"
226 # "<channel> :End of channel ban list"
228 # - When listing the active 'bans' for a given channel,
229 # a server is required to send the list back using the
230 # RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate
231 # RPL_BANLIST is sent for each active banmask. After the
232 # banmasks have been listed (or if none present) a
233 # RPL_ENDOFBANLIST MUST be sent.
238 # ":End of INFO list"
240 # - A server responding to an INFO message is required to
241 # send all its 'info' in a series of RPL_INFO messages
242 # with a RPL_ENDOFINFO reply to indicate the end of the
246 # ":- <server> Message of the day - "
250 # ":End of MOTD command"
252 # - When responding to the MOTD message and the MOTD file
253 # is found, the file is displayed line by line, with
254 # each line no longer than 80 characters, using
255 # RPL_MOTD format replies. These MUST be surrounded
256 # by a RPL_MOTDSTART (before the RPL_MOTDs) and an
257 # RPL_ENDOFMOTD (after).
260 # ":You are now an IRC operator"
262 # - RPL_YOUREOPER is sent back to a client which has
263 # just successfully issued an OPER message and gained
267 # "<config file> :Rehashing"
269 # - If the REHASH option is used and an operator sends
270 # a REHASH message, an RPL_REHASHING is sent back to
274 # "You are service <servicename>"
276 # - Sent by the server to a service upon successful
280 # "<server> :<string showing server's local time>"
282 # - When replying to the TIME message, a server MUST send
283 # the reply using the RPL_TIME format above. The string
284 # showing the time need only contain the correct day and
285 # time there. There is no further requirement for the
289 # ":UserID Terminal Host"
291 # ":<username> <ttyline> <hostname>"
295 # ":Nobody logged in"
297 # - If the USERS message is handled by a server, the
298 # replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and
299 # RPL_NOUSERS are used. RPL_USERSSTART MUST be sent
300 # first, following by either a sequence of RPL_USERS
301 # or a single RPL_NOUSER. Following this is
305 # "Link <version & debug level> <destination>
306 # <next server> V<protocol version>
307 # <link uptime in seconds> <backstream sendq>
309 RPL_TRACECONNECTING=201
310 # "Try. <class> <server>"
311 RPL_TRACEHANDSHAKE=202
312 # "H.S. <class> <server>"
314 # "???? <class> [<client IP address in dot form>]"
315 RPL_TRACEOPERATOR=204
316 # "Oper <class> <nick>"
318 # "User <class> <nick>"
320 # "Serv <class> <int>S <int>C <server>
321 # <nick!user|*!*>@<host|server> V<protocol version>"
323 # "Service <class> <name> <type> <active type>"
325 # "<newtype> 0 <client name>"
327 # "Class <class> <count>"
328 RPL_TRACERECONNECT=210
331 # "File <logfile> <debug level>"
333 # "<server name> <version & debug level> :End of TRACE"
335 # - The RPL_TRACE* are all returned by the server in
336 # response to the TRACE message. How many are
337 # returned is dependent on the TRACE message and
338 # whether it was sent by an operator or not. There
339 # is no predefined order for which occurs first.
340 # Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
341 # RPL_TRACEHANDSHAKE are all used for connections
342 # which have not been fully established and are either
343 # unknown, still attempting to connect or in the
344 # process of completing the 'server handshake'.
345 # RPL_TRACELINK is sent by any server which handles
346 # a TRACE message and has to pass it on to another
347 # server. The list of RPL_TRACELINKs sent in
348 # response to a TRACE command traversing the IRC
349 # network should reflect the actual connectivity of
350 # the servers themselves along that path.
352 # RPL_TRACENEWTYPE is to be used for any connection
353 # which does not fit in the other categories but is
354 # being displayed anyway.
355 # RPL_TRACEEND is sent to indicate the end of the list.
357 RPL_STATSLINKINFO=211
358 # "<linkname> <sendq> <sent messages>
359 # <sent Kbytes> <received messages>
360 # <received Kbytes> <time open>"
362 # - reports statistics on a connection. <linkname>
363 # identifies the particular connection, <sendq> is
364 # the amount of data that is queued and waiting to be
365 # sent <sent messages> the number of messages sent,
366 # and <sent Kbytes> the amount of data sent, in
367 # Kbytes. <received messages> and <received Kbytes>
368 # are the equivalent of <sent messages> and <sent
369 # Kbytes> for received data, respectively. <time
370 # open> indicates how long ago the connection was
371 # opened, in seconds.
373 RPL_STATSCOMMANDS=212
374 # "<command> <count> <byte count> <remote count>"
376 # - reports statistics on commands usage.
379 # "<stats letter> :End of STATS report"
382 # ":Server Up %d days %d:%02d:%02d"
384 # - reports the server uptime.
387 # "O <hostmask> * <name>"
389 # - reports the allowed hosts from where user may become IRC
393 # "<user mode string>"
395 # - To answer a query about a client's own mode,
396 # RPL_UMODEIS is sent back.
399 # "<name> <server> <mask> <type> <hopcount> <info>"
402 # "<mask> <type> :End of service listing"
404 # - When listing services in reply to a SERVLIST message,
405 # a server is required to send the list back using the
406 # RPL_SERVLIST and RPL_SERVLISTEND messages. A separate
407 # RPL_SERVLIST is sent for each service. After the
408 # services have been listed (or if none present) a
409 # RPL_SERVLISTEND MUST be sent.
412 # ":There are <integer> users and <integer>
413 # services on <integer> servers"
415 # "<integer> :operator(s) online"
417 # "<integer> :unknown connection(s)"
418 RPL_LUSERCHANNELS=254
419 # "<integer> :channels formed"
421 # ":I have <integer> clients and <integer>
424 # - In processing an LUSERS message, the server
425 # sends a set of replies from RPL_LUSERCLIENT,
426 # RPL_LUSEROP, RPL_USERUNKNOWN,
427 # RPL_LUSERCHANNELS and RPL_LUSERME. When
428 # replying, a server MUST send back
429 # RPL_LUSERCLIENT and RPL_LUSERME. The other
430 # replies are only sent back if a non-zero count
434 # "<server> :Administrative info"
442 # - When replying to an ADMIN message, a server
443 # is expected to use replies RPL_ADMINME
444 # through to RPL_ADMINEMAIL and provide a text
445 # message with each. For RPL_ADMINLOC1 a
446 # description of what city, state and country
447 # the server is in is expected, followed by
448 # details of the institution (RPL_ADMINLOC2)
449 # and finally the administrative contact for the
450 # server (an email address here is REQUIRED)
454 # "<command> :Please wait a while and try again."
456 # - When a server drops a command without processing it,
457 # it MUST use the reply RPL_TRYAGAIN to inform the
458 # originating client.
462 # Error replies are found in the range from 400 to 599.
465 # "<nickname> :No such nick/channel"
467 # - Used to indicate the nickname parameter supplied to a
468 # command is currently unused.
471 # "<server name> :No such server"
473 # - Used to indicate the server name given currently
476 ERR_NOSUCHCHANNEL=403
477 # "<channel name> :No such channel"
479 # - Used to indicate the given channel name is invalid.
481 ERR_CANNOTSENDTOCHAN=404
482 # "<channel name> :Cannot send to channel"
484 # - Sent to a user who is either (a) not on a channel
485 # which is mode +n or (b) not a chanop (or mode +v) on
486 # a channel which has mode +m set or where the user is
487 # banned and is trying to send a PRIVMSG message to
490 ERR_TOOMANYCHANNELS=405
491 # "<channel name> :You have joined too many channels"
493 # - Sent to a user when they have joined the maximum
494 # number of allowed channels and they try to join
497 ERR_WASNOSUCHNICK=406
498 # "<nickname> :There was no such nickname"
500 # - Returned by WHOWAS to indicate there is no history
501 # information for that nickname.
503 ERR_TOOMANYTARGETS=407
504 # "<target> :<error code> recipients. <abort message>"
506 # - Returned to a client which is attempting to send a
507 # PRIVMSG/NOTICE using the user@host destination format
508 # and for a user@host which has several occurrences.
510 # - Returned to a client which trying to send a
511 # PRIVMSG/NOTICE to too many recipients.
513 # - Returned to a client which is attempting to JOIN a safe
514 # channel using the shortname when there are more than one
517 ERR_NOSUCHSERVICE=408
518 # "<service name> :No such service"
520 # - Returned to a client which is attempting to send a SQUERY
521 # to a service which does not exist.
524 # ":No origin specified"
526 # - PING or PONG message missing the originator parameter.
529 # ":No recipient given (<command>)"
533 # "<mask> :No toplevel domain specified"
535 # "<mask> :Wildcard in toplevel domain"
537 # "<mask> :Bad Server/host mask"
539 # - 412 - 415 are returned by PRIVMSG to indicate that
540 # the message wasn't delivered for some reason.
541 # ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that
542 # are returned when an invalid use of
543 # "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted.
545 ERR_UNKNOWNCOMMAND=421
546 # "<command> :Unknown command"
548 # - Returned to a registered client to indicate that the
549 # command sent is unknown by the server.
552 # ":MOTD File is missing"
554 # - Server's MOTD file could not be opened by the server.
557 # "<server> :No administrative info available"
559 # - Returned by a server in response to an ADMIN message
560 # when there is an error in finding the appropriate
564 # ":File error doing <file op> on <file>"
566 # - Generic error message used to report a failed file
567 # operation during the processing of a message.
569 ERR_NONICKNAMEGIVEN=431
570 # ":No nickname given"
572 # - Returned when a nickname parameter expected for a
573 # command and isn't found.
575 ERR_ERRONEUSNICKNAME=432
576 # "<nick> :Erroneous nickname"
578 # - Returned after receiving a NICK message which contains
579 # characters which do not fall in the defined set. See
580 # section 2.3.1 for details on valid nicknames.
582 ERR_NICKNAMEINUSE=433
583 # "<nick> :Nickname is already in use"
585 # - Returned when a NICK message is processed that results
586 # in an attempt to change to a currently existing
589 ERR_NICKCOLLISION=436
590 # "<nick> :Nickname collision KILL from <user>@<host>"
592 # - Returned by a server to a client when it detects a
593 # nickname collision (registered of a NICK that
594 # already exists by another server).
596 ERR_UNAVAILRESOURCE=437
597 # "<nick/channel> :Nick/channel is temporarily unavailable"
599 # - Returned by a server to a user trying to join a channel
600 # currently blocked by the channel delay mechanism.
602 # - Returned by a server to a user trying to change nickname
603 # when the desired nickname is blocked by the nick delay
606 ERR_USERNOTINCHANNEL=441
607 # "<nick> <channel> :They aren't on that channel"
609 # - Returned by the server to indicate that the target
610 # user of the command is not on the given channel.
613 # "<channel> :You're not on that channel"
615 # - Returned by the server whenever a client tries to
616 # perform a channel affecting command for which the
617 # client isn't a member.
619 ERR_USERONCHANNEL=443
620 # "<user> <channel> :is already on channel"
622 # - Returned when a client tries to invite a user to a
623 # channel they are already on.
626 # "<user> :User not logged in"
628 # - Returned by the summon after a SUMMON command for a
629 # user was unable to be performed since they were not
633 ERR_SUMMONDISABLED=445
634 # ":SUMMON has been disabled"
636 # - Returned as a response to the SUMMON command. MUST be
637 # returned by any server which doesn't implement it.
639 ERR_USERSDISABLED=446
640 # ":USERS has been disabled"
642 # - Returned as a response to the USERS command. MUST be
643 # returned by any server which does not implement it.
645 ERR_NOTREGISTERED=451
646 # ":You have not registered"
648 # - Returned by the server to indicate that the client
649 # MUST be registered before the server will allow it
650 # to be parsed in detail.
652 ERR_NEEDMOREPARAMS=461
653 # "<command> :Not enough parameters"
655 # - Returned by the server by numerous commands to
656 # indicate to the client that it didn't supply enough
659 ERR_ALREADYREGISTRED=462
660 # ":Unauthorized command (already registered)"
662 # - Returned by the server to any link which tries to
663 # change part of the registered details (such as
664 # password or user details from second USER message).
666 ERR_NOPERMFORHOST=463
667 # ":Your host isn't among the privileged"
669 # - Returned to a client which attempts to register with
670 # a server which does not been setup to allow
671 # connections from the host the attempted connection
674 ERR_PASSWDMISMATCH=464
675 # ":Password incorrect"
677 # - Returned to indicate a failed attempt at registering
678 # a connection for which a password was required and
679 # was either not given or incorrect.
681 ERR_YOUREBANNEDCREEP=465
682 # ":You are banned from this server"
684 # - Returned after an attempt to connect and register
685 # yourself with a server which has been setup to
686 # explicitly deny connections to you.
688 ERR_YOUWILLBEBANNED=466
690 # - Sent by a server to a user to inform that access to the
691 # server will soon be denied.
694 # "<channel> :Channel key already set"
695 ERR_CHANNELISFULL=471
696 # "<channel> :Cannot join channel (+l)"
698 # "<char> :is unknown mode char to me for <channel>"
699 ERR_INVITEONLYCHAN=473
700 # "<channel> :Cannot join channel (+i)"
701 ERR_BANNEDFROMCHAN=474
702 # "<channel> :Cannot join channel (+b)"
703 ERR_BADCHANNELKEY=475
704 # "<channel> :Cannot join channel (+k)"
706 # "<channel> :Bad Channel Mask"
708 # "<channel> :Channel doesn't support modes"
710 # "<channel> <char> :Channel list is full"
713 # ":Permission Denied- You're not an IRC operator"
715 # - Any command requiring operator privileges to operate
716 # MUST return this error to indicate the attempt was
719 ERR_CHANOPRIVSNEEDED=482
720 # "<channel> :You're not channel operator"
722 # - Any command requiring 'chanop' privileges (such as
723 # MODE messages) MUST return this error if the client
724 # making the attempt is not a chanop on the specified
728 ERR_CANTKILLSERVER=483
729 # ":You can't kill a server!"
731 # - Any attempts to use the KILL command on a server
732 # are to be refused and this error returned directly
736 # ":Your connection is restricted!"
738 # - Sent by the server to a user upon connection to indicate
739 # the restricted nature of the connection (user mode "+r").
741 ERR_UNIQOPPRIVSNEEDED=485
742 # ":You're not the original channel operator"
744 # - Any MODE requiring "channel creator" privileges MUST
745 # return this error if the client making the attempt is not
746 # a chanop on the specified channel.
749 # ":No O-lines for your host"
751 # - If a client sends an OPER message and the server has
752 # not been configured to allow connections from the
753 # client's host as an operator, this error MUST be
756 ERR_UMODEUNKNOWNFLAG=501
757 # ":Unknown MODE flag"
759 # - Returned by the server to indicate that a MODE
760 # message was sent with a nickname parameter and that
761 # the a mode flag sent was not recognized.
763 ERR_USERSDONTMATCH=502
764 # ":Cannot change mode for other users"
766 # - Error sent to any user trying to view or change the
767 # user mode for a user other than themselves.
769 # 5.3 Reserved numerics
771 # These numerics are not described above since they fall into one of
772 # the following categories:
774 # 1. no longer in use;
776 # 2. reserved for future planned use;
778 # 3. in current use but are part of a non-generic 'feature' of
779 # the current IRC server.
781 RPL_ENDOFSERVICES=232
803 ERR_NOSERVICEHOST=492
805 # implements RFC 2812 and prior IRC RFCs.
806 # clients register handler proc{}s for different server events and IrcClient
809 # create a new IrcClient instance
815 # key:: server event to handle
816 # value:: proc object called when event occurs
817 # set a handler for a server event
819 # ==server events currently supported:
821 # PING:: server pings you (default handler returns a pong)
822 # NICKTAKEN:: you tried to change nick to one that's in use
823 # BADNICK:: you tried to change nick to one that's invalid
824 # TOPIC:: someone changed the topic of a channel
825 # TOPICINFO:: on joining a channel or asking for the topic, tells you
826 # who set it and when
827 # NAMES:: server sends list of channel members when you join
828 # WELCOME:: server welcome message on connect
829 # MOTD:: server message of the day
830 # PRIVMSG:: privmsg, the core of IRC, a message to you from someone
831 # PUBLIC:: optionally instead of getting privmsg you can hook to only
833 # MSG:: or only the private ones, or both
834 # KICK:: someone got kicked from a channel
835 # PART:: someone left a channel
836 # QUIT:: someone quit IRC
837 # JOIN:: someone joined a channel
838 # CHANGETOPIC:: the topic of a channel changed
839 # INVITE:: you are invited to a channel
840 # NICK:: someone changed their nick
841 # MODE:: a mode change
842 # NOTICE:: someone sends you a notice
843 # UNKNOWN:: any other message not handled by the above
845 @handlers[key] = value
849 # remove a handler for a server event
850 def deletehandler(key)
851 @handlers.delete(key)
854 # takes a server string, checks for PING, PRIVMSG, NOTIFY, etc, and parses
855 # numeric server replies, calling the appropriate handler for each, and
856 # sending it a hash containing the data from the server
857 def process(serverstring)
859 data["SERVERSTRING"] = serverstring
861 unless serverstring =~ /^(:(\S+)\s)?(\S+)(\s(.*))?/
862 raise "Unparseable Server Message!!!: #{serverstring}"
865 prefix, command, params = $2, $3, $5
868 data['SOURCE'] = prefix
869 if prefix =~ /^(\S+)!(\S+)$/
870 data['SOURCENICK'] = $1
871 data['SOURCEADDRESS'] = $2
875 # split parameters in an array
877 params.scan(/(?!:)(\S+)|:(.*)/) { argv << ($1 || $2) } if params
881 data['PINGID'] = argv[0]
883 when /^(\d+)$/ # numeric server message
886 when ERR_NICKNAMEINUSE
887 # "* <nick> :Nickname is already in use"
888 data['NICK'] = argv[1]
889 data['MESSAGE'] = argv[2]
890 handle('NICKTAKEN', data)
891 when ERR_ERRONEUSNICKNAME
892 # "* <nick> :Erroneous nickname"
893 data['NICK'] = argv[1]
894 data['MESSAGE'] = argv[2]
895 handle('BADNICK', data)
897 data['CHANNEL'] = argv[1]
898 data['TOPIC'] = argv[2]
899 handle('TOPIC', data)
901 data['NICK'] = argv[0]
902 data['CHANNEL'] = argv[1]
903 data['SOURCE'] = argv[2]
904 data['UNIXTIME'] = argv[3]
905 handle('TOPICINFO', data)
907 # "( "=" / "*" / "@" ) <channel>
908 # :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )
909 # - "@" is used for secret channels, "*" for private
910 # channels, and "=" for others (public channels).
911 argv[3].scan(/\S+/).each { |u|
912 if(u =~ /^([@+])?(.*)$/)
915 @users << [user, umode]
919 data['CHANNEL'] = argv[1]
920 data['USERS'] = @users
921 handle('NAMES', data)
924 # "Welcome to the Internet Relay Network
925 # <nick>!<user>@<host>"
931 when /Welcome to the Internet Relay Network\s(\S+)/
933 when /Welcome.*\s+(\S+)$/
938 handle('WELCOME', data)
940 # "<nick> :- <server> Message of the Day -"
941 if argv[1] =~ /^-\s+(\S+)\s/
946 if(argv[1] =~ /^-\s+(.*)$/)
954 handle('UNKNOWN', data)
956 # end of numeric replies
958 # you can either bind to 'PRIVMSG', to get every one and
959 # parse it yourself, or you can bind to 'MSG', 'PUBLIC',
960 # etc and get it all nicely split up for you.
961 data['TARGET'] = argv[0]
962 data['MESSAGE'] = argv[1]
963 handle('PRIVMSG', data)
966 if(data['TARGET'] =~ /^(#|&).*/)
967 handle('PUBLIC', data)
972 data['CHANNEL'] = argv[0]
973 data['TARGET'] = argv[1]
974 data['MESSAGE'] = argv[2]
977 data['CHANNEL'] = argv[0]
978 data['MESSAGE'] = argv[1]
981 data['MESSAGE'] = argv[0]
984 data['CHANNEL'] = argv[0]
987 data['CHANNEL'] = argv[0]
988 data['TOPIC'] = argv[1]
989 handle('CHANGETOPIC', data)
991 data['TARGET'] = argv[0]
992 data['CHANNEL'] = argv[1]
993 handle('INVITE', data)
995 data['NICK'] = argv[0]
998 data['CHANNEL'] = argv[0]
999 data['MODESTRING'] = argv[1]
1000 data['TARGETS'] = argv[2]
1001 handle('MODE', data)
1003 data['TARGET'] = argv[0]
1004 data['MESSAGE'] = argv[1]
1005 if data['SOURCENICK']
1006 handle('NOTICE', data)
1008 # "server notice" (not from user, noone to reply to
1009 handle('SNOTICE', data)
1012 handle('UNKNOWN', data)
1018 # key:: server event name
1019 # data:: hash containing data about the event, passed to the proc
1020 # call client's proc for an event, if they set one as a handler
1021 def handle(key, data)
1022 if(@handlers.has_key?(key))
1023 @handlers[key].call(data)