]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - rbot/rfc2812.rb
initial import of rbot
[user/henk/code/ruby/rbot.git] / rbot / rfc2812.rb
1 module Irc
2   # RFC 2812   Internet Relay Chat: Client Protocol
3   # 
4   RPL_WELCOME=001
5   # "Welcome to the Internet Relay Network
6   # <nick>!<user>@<host>"
7   RPL_YOURHOST=002
8   # "Your host is <servername>, running version <ver>"
9   RPL_CREATED=003
10   # "This server was created <date>"
11   RPL_MYINFO=004
12   # "<servername> <version> <available user modes>
13   # <available channel modes>"
14   # 
15   # - The server sends Replies 001 to 004 to a user upon
16   # successful registration.
17   # 
18   RPL_BOUNCE=005
19   # "Try server <server name>, port <port number>"
20   # 
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.
24   # 
25   RPL_USERHOST=302
26   # ":*1<reply> *( " " <reply> )"
27   # 
28   # - Reply format used by USERHOST to list replies to
29   # the query list.  The reply string is composed as
30   # follows:
31   # 
32   # reply = nickname [ "*" ] "=" ( "+" / "-" ) hostname
33   # 
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
37   # respectively.
38   # 
39   RPL_ISON=303
40   # ":*1<nick> *( " " <nick> )"
41   # 
42   # - Reply format used by ISON to list replies to the
43   # query list.
44   # 
45   RPL_AWAY=301
46   # "<nick> :<away message>"
47   RPL_UNAWAY=305
48   # ":You are no longer marked as being away"
49   RPL_NOWAWAY=306
50   # ":You have been marked as being away"
51   # 
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.
58   # 
59   RPL_WHOISUSER=311
60   # "<nick> <user> <host> * :<real name>"
61   RPL_WHOISSERVER=312
62   # "<nick> <server> :<server info>"
63   RPL_WHOISOPERATOR=313
64   # "<nick> :is an IRC operator"
65   RPL_WHOISIDLE=317
66   # "<nick> <integer> :seconds idle"
67   RPL_ENDOFWHOIS=318
68   # "<nick> :End of WHOIS list"
69   RPL_WHOISCHANNELS=319
70   # "<nick> :*( ( "@" / "+" ) <channel> " " )"
71   # 
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.
86   # 
87   RPL_WHOWASUSER=314
88   # "<nick> <user> <host> * :<real name>"
89   RPL_ENDOFWHOWAS=369
90   # "<nick> :End of WHOWAS"
91   # 
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).
98   # 
99   RPL_LISTSTART=321
100   # Obsolete. Not used.
101   # 
102   RPL_LIST=322
103   # "<channel> <# visible> :<topic>"
104   RPL_LISTEND=323
105   # ":End of LIST"
106   # 
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.
111   # 
112   RPL_UNIQOPIS=325
113   # "<channel> <nickname>"
114   # 
115   RPL_CHANNELMODEIS=324
116   # "<channel> <mode> <mode params>"
117   # 
118   RPL_NOTOPIC=331
119   # "<channel> :No topic is set"
120   RPL_TOPIC=332
121   # "<channel> :<topic>"
122   # 
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
126   # RPL_NOTOPIC.
127   # 
128   RPL_TOPIC_INFO=333
129   # <channel> <set by> <unixtime>
130   RPL_INVITING=341
131   # "<channel> <nick>"
132   # 
133   # - Returned by the server to indicate that the
134   # attempted INVITE message was successful and is
135   # being passed onto the end client.
136   # 
137   RPL_SUMMONING=342
138   # "<user> :Summoning user to IRC"
139   # 
140   # - Returned by a server answering a SUMMON message to
141   # indicate that it is summoning that user.
142   # 
143   RPL_INVITELIST=346
144   # "<channel> <invitemask>"
145   RPL_ENDOFINVITELIST=347
146   # "<channel> :End of channel invite list"
147   # 
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.
154   # 
155   RPL_EXCEPTLIST=348
156   # "<channel> <exceptionmask>"
157   RPL_ENDOFEXCEPTLIST=349
158   # "<channel> :End of channel exception list"
159   # 
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.
166   # 
167   RPL_VERSION=351
168   # "<version>.<debuglevel> <server> :<comments>"
169   # 
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".
175   # 
176   # The "comments" field may contain any comments about
177   # the version or further version details.
178   # 
179   RPL_WHOREPLY=352
180   # "<channel> <user> <host> <server> <nick>
181   # ( "H" / "G" > ["*"] [ ( "@" / "+" ) ]
182   # :<hopcount> <real name>"
183   # 
184   RPL_ENDOFWHO=315
185   # "<name> :End of WHO list"
186   # 
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
193   # the item.
194   # 
195   RPL_NAMREPLY=353
196   # "( "=" / "*" / "@" ) <channel>
197   # :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )
198   # - "@" is used for secret channels, "*" for private
199   # channels, and "=" for others (public channels).
200   # 
201   RPL_ENDOFNAMES=366
202   # "<channel> :End of NAMES list"
203   # 
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
212   # the end.
213   # 
214   RPL_LINKS=364
215   # "<mask> <server> :<hopcount> <server info>"
216   RPL_ENDOFLINKS=365
217   # "<mask> :End of LINKS list"
218   # 
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.
222   # 
223   RPL_BANLIST=367
224   # "<channel> <banmask>"
225   RPL_ENDOFBANLIST=368
226   # "<channel> :End of channel ban list"
227   # 
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.
234   # 
235   RPL_INFO=371
236   # ":<string>"
237   RPL_ENDOFINFO=374
238   # ":End of INFO list"
239   # 
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
243   # replies.
244   # 
245   RPL_MOTDSTART=375
246   # ":- <server> Message of the day - "
247   RPL_MOTD=372
248   # ":- <text>"
249   RPL_ENDOFMOTD=376
250   # ":End of MOTD command"
251   # 
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).
258   # 
259   RPL_YOUREOPER=381
260   # ":You are now an IRC operator"
261   # 
262   # - RPL_YOUREOPER is sent back to a client which has
263   # just successfully issued an OPER message and gained
264   # operator status.
265   # 
266   RPL_REHASHING=382
267   # "<config file> :Rehashing"
268   # 
269   # - If the REHASH option is used and an operator sends
270   # a REHASH message, an RPL_REHASHING is sent back to
271   # the operator.
272   # 
273   RPL_YOURESERVICE=383
274   # "You are service <servicename>"
275   # 
276   # - Sent by the server to a service upon successful
277   # registration.
278   # 
279   RPL_TIME=391
280   # "<server> :<string showing server's local time>"
281   # 
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
286   # time string.
287   # 
288   RPL_USERSSTART=392
289   # ":UserID   Terminal  Host"
290   RPL_USERS=393
291   # ":<username> <ttyline> <hostname>"
292   RPL_ENDOFUSERS=394
293   # ":End of users"
294   RPL_NOUSERS=395
295   # ":Nobody logged in"
296   # 
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
302   # RPL_ENDOFUSERS.
303   # 
304   RPL_TRACELINK=200
305   # "Link <version & debug level> <destination>
306   # <next server> V<protocol version>
307   # <link uptime in seconds> <backstream sendq>
308   # <upstream sendq>"
309   RPL_TRACECONNECTING=201
310   # "Try. <class> <server>"
311   RPL_TRACEHANDSHAKE=202
312   # "H.S. <class> <server>"
313   RPL_TRACEUNKNOWN=203
314   # "???? <class> [<client IP address in dot form>]"
315   RPL_TRACEOPERATOR=204
316   # "Oper <class> <nick>"
317   RPL_TRACEUSER=205
318   # "User <class> <nick>"
319   RPL_TRACESERVER=206
320   # "Serv <class> <int>S <int>C <server>
321   # <nick!user|*!*>@<host|server> V<protocol version>"
322   RPL_TRACESERVICE=207
323   # "Service <class> <name> <type> <active type>"
324   RPL_TRACENEWTYPE=208
325   # "<newtype> 0 <client name>"
326   RPL_TRACECLASS=209
327   # "Class <class> <count>"
328   RPL_TRACERECONNECT=210
329   # Unused.
330   RPL_TRACELOG=261
331   # "File <logfile> <debug level>"
332   RPL_TRACEEND=262
333   # "<server name> <version & debug level> :End of TRACE"
334   # 
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.
351   # 
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.
356   # 
357   RPL_STATSLINKINFO=211
358   # "<linkname> <sendq> <sent messages>
359   # <sent Kbytes> <received messages>
360   # <received Kbytes> <time open>"
361   # 
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.
372   # 
373   RPL_STATSCOMMANDS=212
374   # "<command> <count> <byte count> <remote count>"
375   # 
376   # - reports statistics on commands usage.
377   # 
378   RPL_ENDOFSTATS=219
379   # "<stats letter> :End of STATS report"
380   # 
381   RPL_STATSUPTIME=242
382   # ":Server Up %d days %d:%02d:%02d"
383   # 
384   # - reports the server uptime.
385   # 
386   RPL_STATSOLINE=243
387   # "O <hostmask> * <name>"
388   # 
389   # - reports the allowed hosts from where user may become IRC
390   # operators.
391   # 
392   RPL_UMODEIS=221
393   # "<user mode string>"
394   # 
395   # - To answer a query about a client's own mode,
396   # RPL_UMODEIS is sent back.
397   # 
398   RPL_SERVLIST=234
399   # "<name> <server> <mask> <type> <hopcount> <info>"
400   # 
401   RPL_SERVLISTEND=235
402   # "<mask> <type> :End of service listing"
403   # 
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.
410   # 
411   RPL_LUSERCLIENT=251
412   # ":There are <integer> users and <integer>
413   # services on <integer> servers"
414   RPL_LUSEROP=252
415   # "<integer> :operator(s) online"
416   RPL_LUSERUNKNOWN=253
417   # "<integer> :unknown connection(s)"
418   RPL_LUSERCHANNELS=254
419   # "<integer> :channels formed"
420   RPL_LUSERME=255
421   # ":I have <integer> clients and <integer>
422   # servers"
423   # 
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
431   # is found for them.
432   # 
433   RPL_ADMINME=256
434   # "<server> :Administrative info"
435   RPL_ADMINLOC1=257
436   # ":<admin info>"
437   RPL_ADMINLOC2=258
438   # ":<admin info>"
439   RPL_ADMINEMAIL=259
440   # ":<admin info>"
441   # 
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)
451   # in RPL_ADMINEMAIL.
452   # 
453   RPL_TRYAGAIN=263
454   # "<command> :Please wait a while and try again."
455   # 
456   # - When a server drops a command without processing it,
457   # it MUST use the reply RPL_TRYAGAIN to inform the
458   # originating client.
459   # 
460   # 5.2 Error Replies
461   # 
462   # Error replies are found in the range from 400 to 599.
463   # 
464   ERR_NOSUCHNICK=401
465   # "<nickname> :No such nick/channel"
466   # 
467   # - Used to indicate the nickname parameter supplied to a
468   # command is currently unused.
469   # 
470   ERR_NOSUCHSERVER=402
471   # "<server name> :No such server"
472   # 
473   # - Used to indicate the server name given currently
474   # does not exist.
475   # 
476   ERR_NOSUCHCHANNEL=403
477   # "<channel name> :No such channel"
478   # 
479   # - Used to indicate the given channel name is invalid.
480   # 
481   ERR_CANNOTSENDTOCHAN=404
482   # "<channel name> :Cannot send to channel"
483   # 
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
488   # that channel.
489   # 
490   ERR_TOOMANYCHANNELS=405
491   # "<channel name> :You have joined too many channels"
492   # 
493   # - Sent to a user when they have joined the maximum
494   # number of allowed channels and they try to join
495   # another channel.
496   # 
497   ERR_WASNOSUCHNICK=406
498   # "<nickname> :There was no such nickname"
499   # 
500   # - Returned by WHOWAS to indicate there is no history
501   # information for that nickname.
502   # 
503   ERR_TOOMANYTARGETS=407
504   # "<target> :<error code> recipients. <abort message>"
505   # 
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.
509   # 
510   # - Returned to a client which trying to send a
511   # PRIVMSG/NOTICE to too many recipients.
512   # 
513   # - Returned to a client which is attempting to JOIN a safe
514   # channel using the shortname when there are more than one
515   # such channel.
516   # 
517   ERR_NOSUCHSERVICE=408
518   # "<service name> :No such service"
519   # 
520   # - Returned to a client which is attempting to send a SQUERY
521   # to a service which does not exist.
522   # 
523   ERR_NOORIGIN=409
524   # ":No origin specified"
525   # 
526   # - PING or PONG message missing the originator parameter.
527   # 
528   ERR_NORECIPIENT=411
529   # ":No recipient given (<command>)"
530   ERR_NOTEXTTOSEND=412
531   # ":No text to send"
532   ERR_NOTOPLEVEL=413
533   # "<mask> :No toplevel domain specified"
534   ERR_WILDTOPLEVEL=414
535   # "<mask> :Wildcard in toplevel domain"
536   ERR_BADMASK=415
537   # "<mask> :Bad Server/host mask"
538   # 
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.
544   # 
545   ERR_UNKNOWNCOMMAND=421
546   # "<command> :Unknown command"
547   # 
548   # - Returned to a registered client to indicate that the
549   # command sent is unknown by the server.
550   # 
551   ERR_NOMOTD=422
552   # ":MOTD File is missing"
553   # 
554   # - Server's MOTD file could not be opened by the server.
555   # 
556   ERR_NOADMININFO=423
557   # "<server> :No administrative info available"
558   # 
559   # - Returned by a server in response to an ADMIN message
560   # when there is an error in finding the appropriate
561   # information.
562   # 
563   ERR_FILEERROR=424
564   # ":File error doing <file op> on <file>"
565   # 
566   # - Generic error message used to report a failed file
567   # operation during the processing of a message.
568   # 
569   ERR_NONICKNAMEGIVEN=431
570   # ":No nickname given"
571   # 
572   # - Returned when a nickname parameter expected for a
573   # command and isn't found.
574   # 
575   ERR_ERRONEUSNICKNAME=432
576   # "<nick> :Erroneous nickname"
577   # 
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.
581   # 
582   ERR_NICKNAMEINUSE=433
583   # "<nick> :Nickname is already in use"
584   # 
585   # - Returned when a NICK message is processed that results
586   # in an attempt to change to a currently existing
587   # nickname.
588   # 
589   ERR_NICKCOLLISION=436
590   # "<nick> :Nickname collision KILL from <user>@<host>"
591   # 
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).
595   # 
596   ERR_UNAVAILRESOURCE=437
597   # "<nick/channel> :Nick/channel is temporarily unavailable"
598   # 
599   # - Returned by a server to a user trying to join a channel
600   # currently blocked by the channel delay mechanism.
601   # 
602   # - Returned by a server to a user trying to change nickname
603   # when the desired nickname is blocked by the nick delay
604   # mechanism.
605   # 
606   ERR_USERNOTINCHANNEL=441
607   # "<nick> <channel> :They aren't on that channel"
608   # 
609   # - Returned by the server to indicate that the target
610   # user of the command is not on the given channel.
611   # 
612   ERR_NOTONCHANNEL=442
613   # "<channel> :You're not on that channel"
614   # 
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.
618   # 
619   ERR_USERONCHANNEL=443
620   # "<user> <channel> :is already on channel"
621   # 
622   # - Returned when a client tries to invite a user to a
623   # channel they are already on.
624   # 
625   ERR_NOLOGIN=444
626   # "<user> :User not logged in"
627   # 
628   # - Returned by the summon after a SUMMON command for a
629   # user was unable to be performed since they were not
630   # logged in.
631   # 
632   # 
633   ERR_SUMMONDISABLED=445
634   # ":SUMMON has been disabled"
635   # 
636   # - Returned as a response to the SUMMON command.  MUST be
637   # returned by any server which doesn't implement it.
638   # 
639   ERR_USERSDISABLED=446
640   # ":USERS has been disabled"
641   # 
642   # - Returned as a response to the USERS command.  MUST be
643   # returned by any server which does not implement it.
644   # 
645   ERR_NOTREGISTERED=451
646   # ":You have not registered"
647   # 
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.
651   # 
652   ERR_NEEDMOREPARAMS=461
653   # "<command> :Not enough parameters"
654   # 
655   # - Returned by the server by numerous commands to
656   # indicate to the client that it didn't supply enough
657   # parameters.
658   # 
659   ERR_ALREADYREGISTRED=462
660   # ":Unauthorized command (already registered)"
661   # 
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).
665   # 
666   ERR_NOPERMFORHOST=463
667   # ":Your host isn't among the privileged"
668   # 
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
672   # is tried.
673   # 
674   ERR_PASSWDMISMATCH=464
675   # ":Password incorrect"
676   # 
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.
680   # 
681   ERR_YOUREBANNEDCREEP=465
682   # ":You are banned from this server"
683   # 
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.
687   # 
688   ERR_YOUWILLBEBANNED=466
689   # 
690   # - Sent by a server to a user to inform that access to the
691   # server will soon be denied.
692   # 
693   ERR_KEYSET=467
694   # "<channel> :Channel key already set"
695   ERR_CHANNELISFULL=471
696   # "<channel> :Cannot join channel (+l)"
697   ERR_UNKNOWNMODE=472
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)"
705   ERR_BADCHANMASK=476
706   # "<channel> :Bad Channel Mask"
707   ERR_NOCHANMODES=477
708   # "<channel> :Channel doesn't support modes"
709   ERR_BANLISTFULL=478
710   # "<channel> <char> :Channel list is full"
711   # 
712   ERR_NOPRIVILEGES=481
713   # ":Permission Denied- You're not an IRC operator"
714   # 
715   # - Any command requiring operator privileges to operate
716   # MUST return this error to indicate the attempt was
717   # unsuccessful.
718   # 
719   ERR_CHANOPRIVSNEEDED=482
720   # "<channel> :You're not channel operator"
721   # 
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
725   # channel.
726   # 
727   # 
728   ERR_CANTKILLSERVER=483
729   # ":You can't kill a server!"
730   # 
731   # - Any attempts to use the KILL command on a server
732   # are to be refused and this error returned directly
733   # to the client.
734   # 
735   ERR_RESTRICTED=484
736   # ":Your connection is restricted!"
737   # 
738   # - Sent by the server to a user upon connection to indicate
739   # the restricted nature of the connection (user mode "+r").
740   # 
741   ERR_UNIQOPPRIVSNEEDED=485
742   # ":You're not the original channel operator"
743   # 
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.
747   # 
748   ERR_NOOPERHOST=491
749   # ":No O-lines for your host"
750   # 
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
754   # returned.
755   # 
756   ERR_UMODEUNKNOWNFLAG=501
757   # ":Unknown MODE flag"
758   # 
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.
762   # 
763   ERR_USERSDONTMATCH=502
764   # ":Cannot change mode for other users"
765   # 
766   # - Error sent to any user trying to view or change the
767   # user mode for a user other than themselves.
768   # 
769   # 5.3 Reserved numerics
770   # 
771   # These numerics are not described above since they fall into one of
772   # the following categories:
773   # 
774   # 1. no longer in use;
775   # 
776   # 2. reserved for future planned use;
777   # 
778   # 3. in current use but are part of a non-generic 'feature' of
779   # the current IRC server.
780   RPL_SERVICEINFO=231 
781   RPL_ENDOFSERVICES=232
782   RPL_SERVICE=233
783   RPL_NONE=300     
784   RPL_WHOISCHANOP=316
785   RPL_KILLDONE=361    
786   RPL_CLOSING=362
787   RPL_CLOSEEND=363    
788   RPL_INFOSTART=373
789   RPL_MYPORTIS=384
790   RPL_STATSCLINE=213  
791   RPL_STATSNLINE=214
792   RPL_STATSILINE=215   
793   RPL_STATSKLINE=216
794   RPL_STATSQLINE=217
795   RPL_STATSYLINE=218
796   RPL_STATSVLINE=240   
797   RPL_STATSLLINE=241
798   RPL_STATSHLINE=244  
799   RPL_STATSSLINE=244
800   RPL_STATSPING=246  
801   RPL_STATSBLINE=247
802   RPL_STATSDLINE=250
803   ERR_NOSERVICEHOST=492
804   
805   # implements RFC 2812 and prior IRC RFCs.
806   # clients register handler proc{}s for different server events and IrcClient
807   # handles dispatch
808   class IrcClient
809     # create a new IrcClient instance
810     def initialize
811       @handlers = Hash.new
812       @users = Array.new
813     end
814   
815     # key::   server event to handle
816     # value:: proc object called when event occurs
817     # set a handler for a server event
818     #
819     # ==server events currently supported:
820     #
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
832     #               the public ones...
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
844     def []=(key, value)
845       @handlers[key] = value
846     end
847     
848     # key:: event name
849     # remove a handler for a server event
850     def deletehandler(key)
851       @handlers.delete(key)
852     end
853    
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)
858       data = Hash.new
859       data["SERVERSTRING"] = serverstring
860       
861       unless serverstring =~ /^(:(\S+)\s)?(\S+)(\s(.*))?/
862               raise "Unparseable Server Message!!!: #{serverstring}"
863       end
864  
865       prefix, command, params = $2, $3, $5
866       
867       if prefix != nil
868         data['SOURCE'] = prefix
869         if prefix =~ /^(\S+)!(\S+)$/
870           data['SOURCENICK'] = $1
871           data['SOURCEADDRESS'] = $2
872         end
873       end
874
875       # split parameters in an array
876       argv = []
877       params.scan(/(?!:)(\S+)|:(.*)/) { argv << ($1 || $2) } if params
878       
879       case command
880       when 'PING'
881         data['PINGID'] = argv[0]
882         handle('PING', data)
883       when /^(\d+)$/            # numeric server message
884         num=command.to_i
885         case num
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)
896         when RPL_TOPIC
897           data['CHANNEL'] = argv[1]
898           data['TOPIC'] = argv[2]
899           handle('TOPIC', data)
900         when RPL_TOPIC_INFO
901           data['NICK'] = argv[0]
902           data['CHANNEL'] = argv[1]
903           data['SOURCE'] = argv[2]
904           data['UNIXTIME'] = argv[3]
905           handle('TOPICINFO', data)
906         when RPL_NAMREPLY
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 =~ /^([@+])?(.*)$/)
913               umode = $1 || ""
914               user = $2
915               @users << [user, umode]
916             end
917           }
918         when RPL_ENDOFNAMES
919           data['CHANNEL'] = argv[1]
920           data['USERS'] = @users
921           handle('NAMES', data)
922           @users = Array.new
923         when RPL_WELCOME
924           # "Welcome to the Internet Relay Network
925           # <nick>!<user>@<host>"
926           case argv[1]
927           when /((\S+)!(\S+))/
928             data['NETMASK'] = $1
929             data['NICK'] = $2
930             data['ADDRESS'] = $3
931           when /Welcome to the Internet Relay Network\s(\S+)/
932             data['NICK'] = $1
933           when /Welcome.*\s+(\S+)$/
934             data['NICK'] = $1
935           when /^(\S+)$/
936             data['NICK'] = $1
937           end
938           handle('WELCOME', data)
939         when RPL_MOTDSTART
940           # "<nick> :- <server> Message of the Day -"
941           if argv[1] =~ /^-\s+(\S+)\s/
942             server = $1
943             @motd = ""
944           end
945         when RPL_MOTD
946           if(argv[1] =~ /^-\s+(.*)$/)
947             @motd << $1
948             @motd << "\n"
949           end
950         when RPL_ENDOFMOTD
951           data['MOTD'] = @motd
952           handle('MOTD', data)
953         else
954           handle('UNKNOWN', data)
955         end
956       # end of numeric replies
957       when 'PRIVMSG'
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)
964         
965         # Now we split it
966         if(data['TARGET'] =~ /^(#|&).*/)
967           handle('PUBLIC', data)
968         else
969           handle('MSG', data)
970         end
971       when 'KICK'
972         data['CHANNEL'] = argv[0]
973         data['TARGET'] = argv[1]
974         data['MESSAGE'] = argv[2]
975         handle('KICK', data)
976       when 'PART'
977         data['CHANNEL'] = argv[0]
978         data['MESSAGE'] = argv[1]
979         handle('PART', data)
980       when 'QUIT'
981         data['MESSAGE'] = argv[0]
982         handle('QUIT', data)
983       when 'JOIN'
984         data['CHANNEL'] = argv[0]
985         handle('JOIN', data)
986       when 'TOPIC'
987         data['CHANNEL'] = argv[0]
988         data['TOPIC'] = argv[1]
989         handle('CHANGETOPIC', data)
990       when 'INVITE'
991         data['TARGET'] = argv[0]
992         data['CHANNEL'] = argv[1]
993         handle('INVITE', data)
994       when 'NICK'
995         data['NICK'] = argv[0]
996         handle('NICK', data)
997       when 'MODE'
998         data['CHANNEL'] = argv[0]
999         data['MODESTRING'] = argv[1]
1000         data['TARGETS'] = argv[2]
1001         handle('MODE', data)
1002       when 'NOTICE'
1003         data['TARGET'] = argv[0]
1004         data['MESSAGE'] = argv[1]
1005         if data['SOURCENICK']
1006           handle('NOTICE', data)
1007         else
1008           # "server notice" (not from user, noone to reply to
1009           handle('SNOTICE', data)
1010         end
1011       else
1012         handle('UNKNOWN', data)
1013       end
1014     end
1015
1016     private
1017     
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)
1024       end
1025     end
1026   end
1027 end