rbot 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/AUTHORS +16 -0
  2. data/COPYING +21 -0
  3. data/ChangeLog +418 -0
  4. data/INSTALL +8 -0
  5. data/README +44 -0
  6. data/REQUIREMENTS +34 -0
  7. data/TODO +5 -0
  8. data/Usage_en.txt +129 -0
  9. data/bin/rbot +81 -0
  10. data/data/rbot/contrib/plugins/figlet.rb +20 -0
  11. data/data/rbot/contrib/plugins/ri.rb +83 -0
  12. data/data/rbot/contrib/plugins/stats.rb +232 -0
  13. data/data/rbot/contrib/plugins/vandale.rb +49 -0
  14. data/data/rbot/languages/dutch.lang +73 -0
  15. data/data/rbot/languages/english.lang +75 -0
  16. data/data/rbot/languages/french.lang +39 -0
  17. data/data/rbot/languages/german.lang +67 -0
  18. data/data/rbot/plugins/autoop.rb +68 -0
  19. data/data/rbot/plugins/autorejoin.rb +16 -0
  20. data/data/rbot/plugins/cal.rb +15 -0
  21. data/data/rbot/plugins/dice.rb +81 -0
  22. data/data/rbot/plugins/eightball.rb +19 -0
  23. data/data/rbot/plugins/excuse.rb +470 -0
  24. data/data/rbot/plugins/fish.rb +61 -0
  25. data/data/rbot/plugins/fortune.rb +22 -0
  26. data/data/rbot/plugins/freshmeat.rb +98 -0
  27. data/data/rbot/plugins/google.rb +51 -0
  28. data/data/rbot/plugins/host.rb +14 -0
  29. data/data/rbot/plugins/httpd.rb.disabled +35 -0
  30. data/data/rbot/plugins/insult.rb +258 -0
  31. data/data/rbot/plugins/karma.rb +85 -0
  32. data/data/rbot/plugins/lart.rb +181 -0
  33. data/data/rbot/plugins/math.rb +122 -0
  34. data/data/rbot/plugins/nickserv.rb +89 -0
  35. data/data/rbot/plugins/nslookup.rb +43 -0
  36. data/data/rbot/plugins/opme.rb +19 -0
  37. data/data/rbot/plugins/quakeauth.rb +51 -0
  38. data/data/rbot/plugins/quotes.rb +321 -0
  39. data/data/rbot/plugins/remind.rb +228 -0
  40. data/data/rbot/plugins/roshambo.rb +54 -0
  41. data/data/rbot/plugins/rot13.rb +10 -0
  42. data/data/rbot/plugins/roulette.rb +147 -0
  43. data/data/rbot/plugins/rss.rb.disabled +414 -0
  44. data/data/rbot/plugins/seen.rb +89 -0
  45. data/data/rbot/plugins/slashdot.rb +94 -0
  46. data/data/rbot/plugins/spell.rb +36 -0
  47. data/data/rbot/plugins/tube.rb +71 -0
  48. data/data/rbot/plugins/url.rb +88 -0
  49. data/data/rbot/plugins/weather.rb +649 -0
  50. data/data/rbot/plugins/wserver.rb +71 -0
  51. data/data/rbot/plugins/xmlrpc.rb.disabled +52 -0
  52. data/data/rbot/templates/keywords.rbot +4 -0
  53. data/data/rbot/templates/lart/larts +98 -0
  54. data/data/rbot/templates/lart/praises +5 -0
  55. data/data/rbot/templates/levels.rbot +30 -0
  56. data/data/rbot/templates/users.rbot +1 -0
  57. data/lib/rbot/auth.rb +203 -0
  58. data/lib/rbot/channel.rb +54 -0
  59. data/lib/rbot/config.rb +363 -0
  60. data/lib/rbot/dbhash.rb +112 -0
  61. data/lib/rbot/httputil.rb +141 -0
  62. data/lib/rbot/ircbot.rb +808 -0
  63. data/lib/rbot/ircsocket.rb +185 -0
  64. data/lib/rbot/keywords.rb +433 -0
  65. data/lib/rbot/language.rb +69 -0
  66. data/lib/rbot/message.rb +256 -0
  67. data/lib/rbot/messagemapper.rb +262 -0
  68. data/lib/rbot/plugins.rb +291 -0
  69. data/lib/rbot/post-install.rb +8 -0
  70. data/lib/rbot/rbotconfig.rb +36 -0
  71. data/lib/rbot/registry.rb +271 -0
  72. data/lib/rbot/rfc2812.rb +1104 -0
  73. data/lib/rbot/timer.rb +201 -0
  74. data/lib/rbot/utils.rb +83 -0
  75. data/setup.rb +1360 -0
  76. metadata +129 -0
@@ -0,0 +1,1104 @@
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
+ RPL_ISUPPORT=005
21
+ # "005 nick PREFIX=(ov)@+ CHANTYPES=#& :are supported by this server"
22
+ #
23
+ # - Sent by the server to a user to suggest an alternative
24
+ # server. This is often used when the connection is
25
+ # refused because the server is already full.
26
+ #
27
+ RPL_USERHOST=302
28
+ # ":*1<reply> *( " " <reply> )"
29
+ #
30
+ # - Reply format used by USERHOST to list replies to
31
+ # the query list. The reply string is composed as
32
+ # follows:
33
+ #
34
+ # reply = nickname [ "*" ] "=" ( "+" / "-" ) hostname
35
+ #
36
+ # The '*' indicates whether the client has registered
37
+ # as an Operator. The '-' or '+' characters represent
38
+ # whether the client has set an AWAY message or not
39
+ # respectively.
40
+ #
41
+ RPL_ISON=303
42
+ # ":*1<nick> *( " " <nick> )"
43
+ #
44
+ # - Reply format used by ISON to list replies to the
45
+ # query list.
46
+ #
47
+ RPL_AWAY=301
48
+ # "<nick> :<away message>"
49
+ RPL_UNAWAY=305
50
+ # ":You are no longer marked as being away"
51
+ RPL_NOWAWAY=306
52
+ # ":You have been marked as being away"
53
+ #
54
+ # - These replies are used with the AWAY command (if
55
+ # allowed). RPL_AWAY is sent to any client sending a
56
+ # PRIVMSG to a client which is away. RPL_AWAY is only
57
+ # sent by the server to which the client is connected.
58
+ # Replies RPL_UNAWAY and RPL_NOWAWAY are sent when the
59
+ # client removes and sets an AWAY message.
60
+ #
61
+ RPL_WHOISUSER=311
62
+ # "<nick> <user> <host> * :<real name>"
63
+ RPL_WHOISSERVER=312
64
+ # "<nick> <server> :<server info>"
65
+ RPL_WHOISOPERATOR=313
66
+ # "<nick> :is an IRC operator"
67
+ RPL_WHOISIDLE=317
68
+ # "<nick> <integer> :seconds idle"
69
+ RPL_ENDOFWHOIS=318
70
+ # "<nick> :End of WHOIS list"
71
+ RPL_WHOISCHANNELS=319
72
+ # "<nick> :*( ( "@" / "+" ) <channel> " " )"
73
+ #
74
+ # - Replies 311 - 313, 317 - 319 are all replies
75
+ # generated in response to a WHOIS message. Given that
76
+ # there are enough parameters present, the answering
77
+ # server MUST either formulate a reply out of the above
78
+ # numerics (if the query nick is found) or return an
79
+ # error reply. The '*' in RPL_WHOISUSER is there as
80
+ # the literal character and not as a wild card. For
81
+ # each reply set, only RPL_WHOISCHANNELS may appear
82
+ # more than once (for long lists of channel names).
83
+ # The '@' and '+' characters next to the channel name
84
+ # indicate whether a client is a channel operator or
85
+ # has been granted permission to speak on a moderated
86
+ # channel. The RPL_ENDOFWHOIS reply is used to mark
87
+ # the end of processing a WHOIS message.
88
+ #
89
+ RPL_WHOWASUSER=314
90
+ # "<nick> <user> <host> * :<real name>"
91
+ RPL_ENDOFWHOWAS=369
92
+ # "<nick> :End of WHOWAS"
93
+ #
94
+ # - When replying to a WHOWAS message, a server MUST use
95
+ # the replies RPL_WHOWASUSER, RPL_WHOISSERVER or
96
+ # ERR_WASNOSUCHNICK for each nickname in the presented
97
+ # list. At the end of all reply batches, there MUST
98
+ # be RPL_ENDOFWHOWAS (even if there was only one reply
99
+ # and it was an error).
100
+ #
101
+ RPL_LISTSTART=321
102
+ # Obsolete. Not used.
103
+ #
104
+ RPL_LIST=322
105
+ # "<channel> <# visible> :<topic>"
106
+ RPL_LISTEND=323
107
+ # ":End of LIST"
108
+ #
109
+ # - Replies RPL_LIST, RPL_LISTEND mark the actual replies
110
+ # with data and end of the server's response to a LIST
111
+ # command. If there are no channels available to return,
112
+ # only the end reply MUST be sent.
113
+ #
114
+ RPL_UNIQOPIS=325
115
+ # "<channel> <nickname>"
116
+ #
117
+ RPL_CHANNELMODEIS=324
118
+ # "<channel> <mode> <mode params>"
119
+ #
120
+ RPL_NOTOPIC=331
121
+ # "<channel> :No topic is set"
122
+ RPL_TOPIC=332
123
+ # "<channel> :<topic>"
124
+ #
125
+ # - When sending a TOPIC message to determine the
126
+ # channel topic, one of two replies is sent. If
127
+ # the topic is set, RPL_TOPIC is sent back else
128
+ # RPL_NOTOPIC.
129
+ #
130
+ RPL_TOPIC_INFO=333
131
+ # <channel> <set by> <unixtime>
132
+ RPL_INVITING=341
133
+ # "<channel> <nick>"
134
+ #
135
+ # - Returned by the server to indicate that the
136
+ # attempted INVITE message was successful and is
137
+ # being passed onto the end client.
138
+ #
139
+ RPL_SUMMONING=342
140
+ # "<user> :Summoning user to IRC"
141
+ #
142
+ # - Returned by a server answering a SUMMON message to
143
+ # indicate that it is summoning that user.
144
+ #
145
+ RPL_INVITELIST=346
146
+ # "<channel> <invitemask>"
147
+ RPL_ENDOFINVITELIST=347
148
+ # "<channel> :End of channel invite list"
149
+ #
150
+ # - When listing the 'invitations masks' for a given channel,
151
+ # a server is required to send the list back using the
152
+ # RPL_INVITELIST and RPL_ENDOFINVITELIST messages. A
153
+ # separate RPL_INVITELIST is sent for each active mask.
154
+ # After the masks have been listed (or if none present) a
155
+ # RPL_ENDOFINVITELIST MUST be sent.
156
+ #
157
+ RPL_EXCEPTLIST=348
158
+ # "<channel> <exceptionmask>"
159
+ RPL_ENDOFEXCEPTLIST=349
160
+ # "<channel> :End of channel exception list"
161
+ #
162
+ # - When listing the 'exception masks' for a given channel,
163
+ # a server is required to send the list back using the
164
+ # RPL_EXCEPTLIST and RPL_ENDOFEXCEPTLIST messages. A
165
+ # separate RPL_EXCEPTLIST is sent for each active mask.
166
+ # After the masks have been listed (or if none present)
167
+ # a RPL_ENDOFEXCEPTLIST MUST be sent.
168
+ #
169
+ RPL_VERSION=351
170
+ # "<version>.<debuglevel> <server> :<comments>"
171
+ #
172
+ # - Reply by the server showing its version details.
173
+ # The <version> is the version of the software being
174
+ # used (including any patchlevel revisions) and the
175
+ # <debuglevel> is used to indicate if the server is
176
+ # running in "debug mode".
177
+ #
178
+ # The "comments" field may contain any comments about
179
+ # the version or further version details.
180
+ #
181
+ RPL_WHOREPLY=352
182
+ # "<channel> <user> <host> <server> <nick>
183
+ # ( "H" / "G" > ["*"] [ ( "@" / "+" ) ]
184
+ # :<hopcount> <real name>"
185
+ #
186
+ RPL_ENDOFWHO=315
187
+ # "<name> :End of WHO list"
188
+ #
189
+ # - The RPL_WHOREPLY and RPL_ENDOFWHO pair are used
190
+ # to answer a WHO message. The RPL_WHOREPLY is only
191
+ # sent if there is an appropriate match to the WHO
192
+ # query. If there is a list of parameters supplied
193
+ # with a WHO message, a RPL_ENDOFWHO MUST be sent
194
+ # after processing each list item with <name> being
195
+ # the item.
196
+ #
197
+ RPL_NAMREPLY=353
198
+ # "( "=" / "*" / "@" ) <channel>
199
+ # :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )
200
+ # - "@" is used for secret channels, "*" for private
201
+ # channels, and "=" for others (public channels).
202
+ #
203
+ RPL_ENDOFNAMES=366
204
+ # "<channel> :End of NAMES list"
205
+ #
206
+ # - To reply to a NAMES message, a reply pair consisting
207
+ # of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the
208
+ # server back to the client. If there is no channel
209
+ # found as in the query, then only RPL_ENDOFNAMES is
210
+ # returned. The exception to this is when a NAMES
211
+ # message is sent with no parameters and all visible
212
+ # channels and contents are sent back in a series of
213
+ # RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark
214
+ # the end.
215
+ #
216
+ RPL_LINKS=364
217
+ # "<mask> <server> :<hopcount> <server info>"
218
+ RPL_ENDOFLINKS=365
219
+ # "<mask> :End of LINKS list"
220
+ #
221
+ # - In replying to the LINKS message, a server MUST send
222
+ # replies back using the RPL_LINKS numeric and mark the
223
+ # end of the list using an RPL_ENDOFLINKS reply.
224
+ #
225
+ RPL_BANLIST=367
226
+ # "<channel> <banmask>"
227
+ RPL_ENDOFBANLIST=368
228
+ # "<channel> :End of channel ban list"
229
+ #
230
+ # - When listing the active 'bans' for a given channel,
231
+ # a server is required to send the list back using the
232
+ # RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate
233
+ # RPL_BANLIST is sent for each active banmask. After the
234
+ # banmasks have been listed (or if none present) a
235
+ # RPL_ENDOFBANLIST MUST be sent.
236
+ #
237
+ RPL_INFO=371
238
+ # ":<string>"
239
+ RPL_ENDOFINFO=374
240
+ # ":End of INFO list"
241
+ #
242
+ # - A server responding to an INFO message is required to
243
+ # send all its 'info' in a series of RPL_INFO messages
244
+ # with a RPL_ENDOFINFO reply to indicate the end of the
245
+ # replies.
246
+ #
247
+ RPL_MOTDSTART=375
248
+ # ":- <server> Message of the day - "
249
+ RPL_MOTD=372
250
+ # ":- <text>"
251
+ RPL_ENDOFMOTD=376
252
+ # ":End of MOTD command"
253
+ #
254
+ # - When responding to the MOTD message and the MOTD file
255
+ # is found, the file is displayed line by line, with
256
+ # each line no longer than 80 characters, using
257
+ # RPL_MOTD format replies. These MUST be surrounded
258
+ # by a RPL_MOTDSTART (before the RPL_MOTDs) and an
259
+ # RPL_ENDOFMOTD (after).
260
+ #
261
+ RPL_YOUREOPER=381
262
+ # ":You are now an IRC operator"
263
+ #
264
+ # - RPL_YOUREOPER is sent back to a client which has
265
+ # just successfully issued an OPER message and gained
266
+ # operator status.
267
+ #
268
+ RPL_REHASHING=382
269
+ # "<config file> :Rehashing"
270
+ #
271
+ # - If the REHASH option is used and an operator sends
272
+ # a REHASH message, an RPL_REHASHING is sent back to
273
+ # the operator.
274
+ #
275
+ RPL_YOURESERVICE=383
276
+ # "You are service <servicename>"
277
+ #
278
+ # - Sent by the server to a service upon successful
279
+ # registration.
280
+ #
281
+ RPL_TIME=391
282
+ # "<server> :<string showing server's local time>"
283
+ #
284
+ # - When replying to the TIME message, a server MUST send
285
+ # the reply using the RPL_TIME format above. The string
286
+ # showing the time need only contain the correct day and
287
+ # time there. There is no further requirement for the
288
+ # time string.
289
+ #
290
+ RPL_USERSSTART=392
291
+ # ":UserID Terminal Host"
292
+ RPL_USERS=393
293
+ # ":<username> <ttyline> <hostname>"
294
+ RPL_ENDOFUSERS=394
295
+ # ":End of users"
296
+ RPL_NOUSERS=395
297
+ # ":Nobody logged in"
298
+ #
299
+ # - If the USERS message is handled by a server, the
300
+ # replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and
301
+ # RPL_NOUSERS are used. RPL_USERSSTART MUST be sent
302
+ # first, following by either a sequence of RPL_USERS
303
+ # or a single RPL_NOUSER. Following this is
304
+ # RPL_ENDOFUSERS.
305
+ #
306
+ RPL_TRACELINK=200
307
+ # "Link <version & debug level> <destination>
308
+ # <next server> V<protocol version>
309
+ # <link uptime in seconds> <backstream sendq>
310
+ # <upstream sendq>"
311
+ RPL_TRACECONNECTING=201
312
+ # "Try. <class> <server>"
313
+ RPL_TRACEHANDSHAKE=202
314
+ # "H.S. <class> <server>"
315
+ RPL_TRACEUNKNOWN=203
316
+ # "???? <class> [<client IP address in dot form>]"
317
+ RPL_TRACEOPERATOR=204
318
+ # "Oper <class> <nick>"
319
+ RPL_TRACEUSER=205
320
+ # "User <class> <nick>"
321
+ RPL_TRACESERVER=206
322
+ # "Serv <class> <int>S <int>C <server>
323
+ # <nick!user|*!*>@<host|server> V<protocol version>"
324
+ RPL_TRACESERVICE=207
325
+ # "Service <class> <name> <type> <active type>"
326
+ RPL_TRACENEWTYPE=208
327
+ # "<newtype> 0 <client name>"
328
+ RPL_TRACECLASS=209
329
+ # "Class <class> <count>"
330
+ RPL_TRACERECONNECT=210
331
+ # Unused.
332
+ RPL_TRACELOG=261
333
+ # "File <logfile> <debug level>"
334
+ RPL_TRACEEND=262
335
+ # "<server name> <version & debug level> :End of TRACE"
336
+ #
337
+ # - The RPL_TRACE* are all returned by the server in
338
+ # response to the TRACE message. How many are
339
+ # returned is dependent on the TRACE message and
340
+ # whether it was sent by an operator or not. There
341
+ # is no predefined order for which occurs first.
342
+ # Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
343
+ # RPL_TRACEHANDSHAKE are all used for connections
344
+ # which have not been fully established and are either
345
+ # unknown, still attempting to connect or in the
346
+ # process of completing the 'server handshake'.
347
+ # RPL_TRACELINK is sent by any server which handles
348
+ # a TRACE message and has to pass it on to another
349
+ # server. The list of RPL_TRACELINKs sent in
350
+ # response to a TRACE command traversing the IRC
351
+ # network should reflect the actual connectivity of
352
+ # the servers themselves along that path.
353
+ #
354
+ # RPL_TRACENEWTYPE is to be used for any connection
355
+ # which does not fit in the other categories but is
356
+ # being displayed anyway.
357
+ # RPL_TRACEEND is sent to indicate the end of the list.
358
+ #
359
+ RPL_LOCALUSERS=265
360
+ # ":Current local users: 3 Max: 4"
361
+ RPL_GLOBALUSERS=266
362
+ # ":Current global users: 3 Max: 4"
363
+ RPL_STATSCONN=250
364
+ # "::Highest connection count: 4 (4 clients) (251 since server was
365
+ # (re)started)"
366
+ RPL_STATSLINKINFO=211
367
+ # "<linkname> <sendq> <sent messages>
368
+ # <sent Kbytes> <received messages>
369
+ # <received Kbytes> <time open>"
370
+ #
371
+ # - reports statistics on a connection. <linkname>
372
+ # identifies the particular connection, <sendq> is
373
+ # the amount of data that is queued and waiting to be
374
+ # sent <sent messages> the number of messages sent,
375
+ # and <sent Kbytes> the amount of data sent, in
376
+ # Kbytes. <received messages> and <received Kbytes>
377
+ # are the equivalent of <sent messages> and <sent
378
+ # Kbytes> for received data, respectively. <time
379
+ # open> indicates how long ago the connection was
380
+ # opened, in seconds.
381
+ #
382
+ RPL_STATSCOMMANDS=212
383
+ # "<command> <count> <byte count> <remote count>"
384
+ #
385
+ # - reports statistics on commands usage.
386
+ #
387
+ RPL_ENDOFSTATS=219
388
+ # "<stats letter> :End of STATS report"
389
+ #
390
+ RPL_STATSUPTIME=242
391
+ # ":Server Up %d days %d:%02d:%02d"
392
+ #
393
+ # - reports the server uptime.
394
+ #
395
+ RPL_STATSOLINE=243
396
+ # "O <hostmask> * <name>"
397
+ #
398
+ # - reports the allowed hosts from where user may become IRC
399
+ # operators.
400
+ #
401
+ RPL_UMODEIS=221
402
+ # "<user mode string>"
403
+ #
404
+ # - To answer a query about a client's own mode,
405
+ # RPL_UMODEIS is sent back.
406
+ #
407
+ RPL_SERVLIST=234
408
+ # "<name> <server> <mask> <type> <hopcount> <info>"
409
+ #
410
+ RPL_SERVLISTEND=235
411
+ # "<mask> <type> :End of service listing"
412
+ #
413
+ # - When listing services in reply to a SERVLIST message,
414
+ # a server is required to send the list back using the
415
+ # RPL_SERVLIST and RPL_SERVLISTEND messages. A separate
416
+ # RPL_SERVLIST is sent for each service. After the
417
+ # services have been listed (or if none present) a
418
+ # RPL_SERVLISTEND MUST be sent.
419
+ #
420
+ RPL_LUSERCLIENT=251
421
+ # ":There are <integer> users and <integer>
422
+ # services on <integer> servers"
423
+ RPL_LUSEROP=252
424
+ # "<integer> :operator(s) online"
425
+ RPL_LUSERUNKNOWN=253
426
+ # "<integer> :unknown connection(s)"
427
+ RPL_LUSERCHANNELS=254
428
+ # "<integer> :channels formed"
429
+ RPL_LUSERME=255
430
+ # ":I have <integer> clients and <integer>
431
+ # servers"
432
+ #
433
+ # - In processing an LUSERS message, the server
434
+ # sends a set of replies from RPL_LUSERCLIENT,
435
+ # RPL_LUSEROP, RPL_USERUNKNOWN,
436
+ # RPL_LUSERCHANNELS and RPL_LUSERME. When
437
+ # replying, a server MUST send back
438
+ # RPL_LUSERCLIENT and RPL_LUSERME. The other
439
+ # replies are only sent back if a non-zero count
440
+ # is found for them.
441
+ #
442
+ RPL_ADMINME=256
443
+ # "<server> :Administrative info"
444
+ RPL_ADMINLOC1=257
445
+ # ":<admin info>"
446
+ RPL_ADMINLOC2=258
447
+ # ":<admin info>"
448
+ RPL_ADMINEMAIL=259
449
+ # ":<admin info>"
450
+ #
451
+ # - When replying to an ADMIN message, a server
452
+ # is expected to use replies RPL_ADMINME
453
+ # through to RPL_ADMINEMAIL and provide a text
454
+ # message with each. For RPL_ADMINLOC1 a
455
+ # description of what city, state and country
456
+ # the server is in is expected, followed by
457
+ # details of the institution (RPL_ADMINLOC2)
458
+ # and finally the administrative contact for the
459
+ # server (an email address here is REQUIRED)
460
+ # in RPL_ADMINEMAIL.
461
+ #
462
+ RPL_TRYAGAIN=263
463
+ # "<command> :Please wait a while and try again."
464
+ #
465
+ # - When a server drops a command without processing it,
466
+ # it MUST use the reply RPL_TRYAGAIN to inform the
467
+ # originating client.
468
+ #
469
+ # 5.2 Error Replies
470
+ #
471
+ # Error replies are found in the range from 400 to 599.
472
+ #
473
+ ERR_NOSUCHNICK=401
474
+ # "<nickname> :No such nick/channel"
475
+ #
476
+ # - Used to indicate the nickname parameter supplied to a
477
+ # command is currently unused.
478
+ #
479
+ ERR_NOSUCHSERVER=402
480
+ # "<server name> :No such server"
481
+ #
482
+ # - Used to indicate the server name given currently
483
+ # does not exist.
484
+ #
485
+ ERR_NOSUCHCHANNEL=403
486
+ # "<channel name> :No such channel"
487
+ #
488
+ # - Used to indicate the given channel name is invalid.
489
+ #
490
+ ERR_CANNOTSENDTOCHAN=404
491
+ # "<channel name> :Cannot send to channel"
492
+ #
493
+ # - Sent to a user who is either (a) not on a channel
494
+ # which is mode +n or (b) not a chanop (or mode +v) on
495
+ # a channel which has mode +m set or where the user is
496
+ # banned and is trying to send a PRIVMSG message to
497
+ # that channel.
498
+ #
499
+ ERR_TOOMANYCHANNELS=405
500
+ # "<channel name> :You have joined too many channels"
501
+ #
502
+ # - Sent to a user when they have joined the maximum
503
+ # number of allowed channels and they try to join
504
+ # another channel.
505
+ #
506
+ ERR_WASNOSUCHNICK=406
507
+ # "<nickname> :There was no such nickname"
508
+ #
509
+ # - Returned by WHOWAS to indicate there is no history
510
+ # information for that nickname.
511
+ #
512
+ ERR_TOOMANYTARGETS=407
513
+ # "<target> :<error code> recipients. <abort message>"
514
+ #
515
+ # - Returned to a client which is attempting to send a
516
+ # PRIVMSG/NOTICE using the user@host destination format
517
+ # and for a user@host which has several occurrences.
518
+ #
519
+ # - Returned to a client which trying to send a
520
+ # PRIVMSG/NOTICE to too many recipients.
521
+ #
522
+ # - Returned to a client which is attempting to JOIN a safe
523
+ # channel using the shortname when there are more than one
524
+ # such channel.
525
+ #
526
+ ERR_NOSUCHSERVICE=408
527
+ # "<service name> :No such service"
528
+ #
529
+ # - Returned to a client which is attempting to send a SQUERY
530
+ # to a service which does not exist.
531
+ #
532
+ ERR_NOORIGIN=409
533
+ # ":No origin specified"
534
+ #
535
+ # - PING or PONG message missing the originator parameter.
536
+ #
537
+ ERR_NORECIPIENT=411
538
+ # ":No recipient given (<command>)"
539
+ ERR_NOTEXTTOSEND=412
540
+ # ":No text to send"
541
+ ERR_NOTOPLEVEL=413
542
+ # "<mask> :No toplevel domain specified"
543
+ ERR_WILDTOPLEVEL=414
544
+ # "<mask> :Wildcard in toplevel domain"
545
+ ERR_BADMASK=415
546
+ # "<mask> :Bad Server/host mask"
547
+ #
548
+ # - 412 - 415 are returned by PRIVMSG to indicate that
549
+ # the message wasn't delivered for some reason.
550
+ # ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that
551
+ # are returned when an invalid use of
552
+ # "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted.
553
+ #
554
+ ERR_UNKNOWNCOMMAND=421
555
+ # "<command> :Unknown command"
556
+ #
557
+ # - Returned to a registered client to indicate that the
558
+ # command sent is unknown by the server.
559
+ #
560
+ ERR_NOMOTD=422
561
+ # ":MOTD File is missing"
562
+ #
563
+ # - Server's MOTD file could not be opened by the server.
564
+ #
565
+ ERR_NOADMININFO=423
566
+ # "<server> :No administrative info available"
567
+ #
568
+ # - Returned by a server in response to an ADMIN message
569
+ # when there is an error in finding the appropriate
570
+ # information.
571
+ #
572
+ ERR_FILEERROR=424
573
+ # ":File error doing <file op> on <file>"
574
+ #
575
+ # - Generic error message used to report a failed file
576
+ # operation during the processing of a message.
577
+ #
578
+ ERR_NONICKNAMEGIVEN=431
579
+ # ":No nickname given"
580
+ #
581
+ # - Returned when a nickname parameter expected for a
582
+ # command and isn't found.
583
+ #
584
+ ERR_ERRONEUSNICKNAME=432
585
+ # "<nick> :Erroneous nickname"
586
+ #
587
+ # - Returned after receiving a NICK message which contains
588
+ # characters which do not fall in the defined set. See
589
+ # section 2.3.1 for details on valid nicknames.
590
+ #
591
+ ERR_NICKNAMEINUSE=433
592
+ # "<nick> :Nickname is already in use"
593
+ #
594
+ # - Returned when a NICK message is processed that results
595
+ # in an attempt to change to a currently existing
596
+ # nickname.
597
+ #
598
+ ERR_NICKCOLLISION=436
599
+ # "<nick> :Nickname collision KILL from <user>@<host>"
600
+ #
601
+ # - Returned by a server to a client when it detects a
602
+ # nickname collision (registered of a NICK that
603
+ # already exists by another server).
604
+ #
605
+ ERR_UNAVAILRESOURCE=437
606
+ # "<nick/channel> :Nick/channel is temporarily unavailable"
607
+ #
608
+ # - Returned by a server to a user trying to join a channel
609
+ # currently blocked by the channel delay mechanism.
610
+ #
611
+ # - Returned by a server to a user trying to change nickname
612
+ # when the desired nickname is blocked by the nick delay
613
+ # mechanism.
614
+ #
615
+ ERR_USERNOTINCHANNEL=441
616
+ # "<nick> <channel> :They aren't on that channel"
617
+ #
618
+ # - Returned by the server to indicate that the target
619
+ # user of the command is not on the given channel.
620
+ #
621
+ ERR_NOTONCHANNEL=442
622
+ # "<channel> :You're not on that channel"
623
+ #
624
+ # - Returned by the server whenever a client tries to
625
+ # perform a channel affecting command for which the
626
+ # client isn't a member.
627
+ #
628
+ ERR_USERONCHANNEL=443
629
+ # "<user> <channel> :is already on channel"
630
+ #
631
+ # - Returned when a client tries to invite a user to a
632
+ # channel they are already on.
633
+ #
634
+ ERR_NOLOGIN=444
635
+ # "<user> :User not logged in"
636
+ #
637
+ # - Returned by the summon after a SUMMON command for a
638
+ # user was unable to be performed since they were not
639
+ # logged in.
640
+ #
641
+ #
642
+ ERR_SUMMONDISABLED=445
643
+ # ":SUMMON has been disabled"
644
+ #
645
+ # - Returned as a response to the SUMMON command. MUST be
646
+ # returned by any server which doesn't implement it.
647
+ #
648
+ ERR_USERSDISABLED=446
649
+ # ":USERS has been disabled"
650
+ #
651
+ # - Returned as a response to the USERS command. MUST be
652
+ # returned by any server which does not implement it.
653
+ #
654
+ ERR_NOTREGISTERED=451
655
+ # ":You have not registered"
656
+ #
657
+ # - Returned by the server to indicate that the client
658
+ # MUST be registered before the server will allow it
659
+ # to be parsed in detail.
660
+ #
661
+ ERR_NEEDMOREPARAMS=461
662
+ # "<command> :Not enough parameters"
663
+ #
664
+ # - Returned by the server by numerous commands to
665
+ # indicate to the client that it didn't supply enough
666
+ # parameters.
667
+ #
668
+ ERR_ALREADYREGISTRED=462
669
+ # ":Unauthorized command (already registered)"
670
+ #
671
+ # - Returned by the server to any link which tries to
672
+ # change part of the registered details (such as
673
+ # password or user details from second USER message).
674
+ #
675
+ ERR_NOPERMFORHOST=463
676
+ # ":Your host isn't among the privileged"
677
+ #
678
+ # - Returned to a client which attempts to register with
679
+ # a server which does not been setup to allow
680
+ # connections from the host the attempted connection
681
+ # is tried.
682
+ #
683
+ ERR_PASSWDMISMATCH=464
684
+ # ":Password incorrect"
685
+ #
686
+ # - Returned to indicate a failed attempt at registering
687
+ # a connection for which a password was required and
688
+ # was either not given or incorrect.
689
+ #
690
+ ERR_YOUREBANNEDCREEP=465
691
+ # ":You are banned from this server"
692
+ #
693
+ # - Returned after an attempt to connect and register
694
+ # yourself with a server which has been setup to
695
+ # explicitly deny connections to you.
696
+ #
697
+ ERR_YOUWILLBEBANNED=466
698
+ #
699
+ # - Sent by a server to a user to inform that access to the
700
+ # server will soon be denied.
701
+ #
702
+ ERR_KEYSET=467
703
+ # "<channel> :Channel key already set"
704
+ ERR_CHANNELISFULL=471
705
+ # "<channel> :Cannot join channel (+l)"
706
+ ERR_UNKNOWNMODE=472
707
+ # "<char> :is unknown mode char to me for <channel>"
708
+ ERR_INVITEONLYCHAN=473
709
+ # "<channel> :Cannot join channel (+i)"
710
+ ERR_BANNEDFROMCHAN=474
711
+ # "<channel> :Cannot join channel (+b)"
712
+ ERR_BADCHANNELKEY=475
713
+ # "<channel> :Cannot join channel (+k)"
714
+ ERR_BADCHANMASK=476
715
+ # "<channel> :Bad Channel Mask"
716
+ ERR_NOCHANMODES=477
717
+ # "<channel> :Channel doesn't support modes"
718
+ ERR_BANLISTFULL=478
719
+ # "<channel> <char> :Channel list is full"
720
+ #
721
+ ERR_NOPRIVILEGES=481
722
+ # ":Permission Denied- You're not an IRC operator"
723
+ #
724
+ # - Any command requiring operator privileges to operate
725
+ # MUST return this error to indicate the attempt was
726
+ # unsuccessful.
727
+ #
728
+ ERR_CHANOPRIVSNEEDED=482
729
+ # "<channel> :You're not channel operator"
730
+ #
731
+ # - Any command requiring 'chanop' privileges (such as
732
+ # MODE messages) MUST return this error if the client
733
+ # making the attempt is not a chanop on the specified
734
+ # channel.
735
+ #
736
+ #
737
+ ERR_CANTKILLSERVER=483
738
+ # ":You can't kill a server!"
739
+ #
740
+ # - Any attempts to use the KILL command on a server
741
+ # are to be refused and this error returned directly
742
+ # to the client.
743
+ #
744
+ ERR_RESTRICTED=484
745
+ # ":Your connection is restricted!"
746
+ #
747
+ # - Sent by the server to a user upon connection to indicate
748
+ # the restricted nature of the connection (user mode "+r").
749
+ #
750
+ ERR_UNIQOPPRIVSNEEDED=485
751
+ # ":You're not the original channel operator"
752
+ #
753
+ # - Any MODE requiring "channel creator" privileges MUST
754
+ # return this error if the client making the attempt is not
755
+ # a chanop on the specified channel.
756
+ #
757
+ ERR_NOOPERHOST=491
758
+ # ":No O-lines for your host"
759
+ #
760
+ # - If a client sends an OPER message and the server has
761
+ # not been configured to allow connections from the
762
+ # client's host as an operator, this error MUST be
763
+ # returned.
764
+ #
765
+ ERR_UMODEUNKNOWNFLAG=501
766
+ # ":Unknown MODE flag"
767
+ #
768
+ # - Returned by the server to indicate that a MODE
769
+ # message was sent with a nickname parameter and that
770
+ # the a mode flag sent was not recognized.
771
+ #
772
+ ERR_USERSDONTMATCH=502
773
+ # ":Cannot change mode for other users"
774
+ #
775
+ # - Error sent to any user trying to view or change the
776
+ # user mode for a user other than themselves.
777
+ #
778
+ # 5.3 Reserved numerics
779
+ #
780
+ # These numerics are not described above since they fall into one of
781
+ # the following categories:
782
+ #
783
+ # 1. no longer in use;
784
+ #
785
+ # 2. reserved for future planned use;
786
+ #
787
+ # 3. in current use but are part of a non-generic 'feature' of
788
+ # the current IRC server.
789
+ RPL_SERVICEINFO=231
790
+ RPL_ENDOFSERVICES=232
791
+ RPL_SERVICE=233
792
+ RPL_NONE=300
793
+ RPL_WHOISCHANOP=316
794
+ RPL_KILLDONE=361
795
+ RPL_CLOSING=362
796
+ RPL_CLOSEEND=363
797
+ RPL_INFOSTART=373
798
+ RPL_MYPORTIS=384
799
+ RPL_STATSCLINE=213
800
+ RPL_STATSNLINE=214
801
+ RPL_STATSILINE=215
802
+ RPL_STATSKLINE=216
803
+ RPL_STATSQLINE=217
804
+ RPL_STATSYLINE=218
805
+ RPL_STATSVLINE=240
806
+ RPL_STATSLLINE=241
807
+ RPL_STATSHLINE=244
808
+ RPL_STATSSLINE=244
809
+ RPL_STATSPING=246
810
+ RPL_STATSBLINE=247
811
+ ERR_NOSERVICEHOST=492
812
+
813
+ # implements RFC 2812 and prior IRC RFCs.
814
+ # clients register handler proc{}s for different server events and IrcClient
815
+ # handles dispatch
816
+ class IrcClient
817
+ # create a new IrcClient instance
818
+ def initialize
819
+ @handlers = Hash.new
820
+ @users = Array.new
821
+ end
822
+
823
+ # key:: server event to handle
824
+ # value:: proc object called when event occurs
825
+ # set a handler for a server event
826
+ #
827
+ # ==server events currently supported:
828
+ #
829
+ # created:: when the server was started
830
+ # yourhost:: your host details (on connection)
831
+ # ping:: server pings you (default handler returns a pong)
832
+ # nicktaken:: you tried to change nick to one that's in use
833
+ # badnick:: you tried to change nick to one that's invalid
834
+ # topic:: someone changed the topic of a channel
835
+ # topicinfo:: on joining a channel or asking for the topic, tells you
836
+ # who set it and when
837
+ # names:: server sends list of channel members when you join
838
+ # welcome:: server welcome message on connect
839
+ # motd:: server message of the day
840
+ # privmsg:: privmsg, the core of IRC, a message to you from someone
841
+ # public:: optionally instead of getting privmsg you can hook to only
842
+ # the public ones...
843
+ # msg:: or only the private ones, or both
844
+ # kick:: someone got kicked from a channel
845
+ # part:: someone left a channel
846
+ # quit:: someone quit IRC
847
+ # join:: someone joined a channel
848
+ # changetopic:: the topic of a channel changed
849
+ # invite:: you are invited to a channel
850
+ # nick:: someone changed their nick
851
+ # mode:: a mode change
852
+ # notice:: someone sends you a notice
853
+ # unknown:: any other message not handled by the above
854
+ def []=(key, value)
855
+ @handlers[key] = value
856
+ end
857
+
858
+ # key:: event name
859
+ # remove a handler for a server event
860
+ def deletehandler(key)
861
+ @handlers.delete(key)
862
+ end
863
+
864
+ # takes a server string, checks for PING, PRIVMSG, NOTIFY, etc, and parses
865
+ # numeric server replies, calling the appropriate handler for each, and
866
+ # sending it a hash containing the data from the server
867
+ def process(serverstring)
868
+ data = Hash.new
869
+ data[:serverstring] = serverstring
870
+
871
+ unless serverstring =~ /^(:(\S+)\s)?(\S+)(\s(.*))?/
872
+ raise "Unparseable Server Message!!!: #{serverstring}"
873
+ end
874
+
875
+ prefix, command, params = $2, $3, $5
876
+
877
+ if prefix != nil
878
+ data[:source] = prefix
879
+ if prefix =~ /^(\S+)!(\S+)$/
880
+ data[:sourcenick] = $1
881
+ data[:sourceaddress] = $2
882
+ end
883
+ end
884
+
885
+ # split parameters in an array
886
+ argv = []
887
+ params.scan(/(?!:)(\S+)|:(.*)/) { argv << ($1 || $2) } if params
888
+
889
+ case command
890
+ when 'PING'
891
+ data[:pingid] = argv[0]
892
+ handle(:ping, data)
893
+ when /^(\d+)$/ # numeric server message
894
+ num=command.to_i
895
+ case num
896
+ when RPL_YOURHOST
897
+ # "Your host is <servername>, running version <ver>"
898
+ # TODO how standard is this "version <ver>? should i parse it?
899
+ data[:message] = argv[1]
900
+ handle(:yourhost, data)
901
+ when RPL_CREATED
902
+ # "This server was created <date>"
903
+ data[:message] = argv[1]
904
+ handle(:created, data)
905
+ when RPL_MYINFO
906
+ # "<servername> <version> <available user modes>
907
+ # <available channel modes>"
908
+ data[:servername] = argv[1]
909
+ data[:version] = argv[2]
910
+ data[:usermodes] = argv[3]
911
+ data[:chanmodes] = argv[4]
912
+ when ERR_NICKNAMEINUSE
913
+ # "* <nick> :Nickname is already in use"
914
+ data[:nick] = argv[1]
915
+ data[:message] = argv[2]
916
+ handle(:nicktaken, data)
917
+ when ERR_ERRONEUSNICKNAME
918
+ # "* <nick> :Erroneous nickname"
919
+ data[:nick] = argv[1]
920
+ data[:message] = argv[2]
921
+ handle(:badnick, data)
922
+ when RPL_TOPIC
923
+ data[:channel] = argv[1]
924
+ data[:topic] = argv[2]
925
+ handle(:topic, data)
926
+ when RPL_TOPIC_INFO
927
+ data[:nick] = argv[0]
928
+ data[:channel] = argv[1]
929
+ data[:source] = argv[2]
930
+ data[:unixtime] = argv[3]
931
+ handle(:topicinfo, data)
932
+ when RPL_NAMREPLY
933
+ # "( "=" / "*" / "@" ) <channel>
934
+ # :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )
935
+ # - "@" is used for secret channels, "*" for private
936
+ # channels, and "=" for others (public channels).
937
+ argv[3].scan(/\S+/).each { |u|
938
+ if(u =~ /^([@+])?(.*)$/)
939
+ umode = $1 || ""
940
+ user = $2
941
+ @users << [user, umode]
942
+ end
943
+ }
944
+ when RPL_ENDOFNAMES
945
+ data[:channel] = argv[1]
946
+ data[:users] = @users
947
+ handle(:names, data)
948
+ @users = Array.new
949
+ when RPL_ISUPPORT
950
+ # "PREFIX=(ov)@+ CHANTYPES=#& :are supported by this server"
951
+ # "MODES=4 CHANLIMIT=#:20 NICKLEN=16 USERLEN=10 HOSTLEN=63
952
+ # TOPICLEN=450 KICKLEN=450 CHANNELLEN=30 KEYLEN=23 CHANTYPES=#
953
+ # PREFIX=(ov)@+ CASEMAPPING=ascii CAPAB IRCD=dancer :are available
954
+ # on this server"
955
+ #
956
+ argv.each {|a|
957
+ if a =~ /^(.*)=(.*)$/
958
+ data[$1.downcase.to_sym] = $2
959
+ end
960
+ }
961
+ handle(:isupport, data)
962
+ when RPL_LUSERCLIENT
963
+ # ":There are <integer> users and <integer>
964
+ # services on <integer> servers"
965
+ data[:message] = argv[1]
966
+ handle(:luserclient, data)
967
+ when RPL_LUSEROP
968
+ # "<integer> :operator(s) online"
969
+ data[:ops] = argv[1].to_i
970
+ handle(:luserop, data)
971
+ when RPL_LUSERUNKNOWN
972
+ # "<integer> :unknown connection(s)"
973
+ data[:unknown] = argv[1].to_i
974
+ handle(:luserunknown, data)
975
+ when RPL_LUSERCHANNELS
976
+ # "<integer> :channels formed"
977
+ data[:channels] = argv[1].to_i
978
+ handle(:luserchannels, data)
979
+ when RPL_LUSERME
980
+ # ":I have <integer> clients and <integer> servers"
981
+ data[:message] = argv[1]
982
+ handle(:luserme, data)
983
+ when ERR_NOMOTD
984
+ # ":MOTD File is missing"
985
+ data[:message] = argv[1]
986
+ handle(:motd_missing, data)
987
+ when RPL_LOCALUSERS
988
+ # ":Current local users: 3 Max: 4"
989
+ data[:message] = argv[1]
990
+ handle(:localusers, data)
991
+ when RPL_GLOBALUSERS
992
+ # ":Current global users: 3 Max: 4"
993
+ data[:message] = argv[1]
994
+ handle(:globalusers, data)
995
+ when RPL_STATSCONN
996
+ # ":Highest connection count: 4 (4 clients) (251 since server was
997
+ # (re)started)"
998
+ data[:message] = argv[1]
999
+ handle(:statsconn, data)
1000
+ when RPL_WELCOME
1001
+ # "Welcome to the Internet Relay Network
1002
+ # <nick>!<user>@<host>"
1003
+ case argv[1]
1004
+ when /((\S+)!(\S+))/
1005
+ data[:netmask] = $1
1006
+ data[:nick] = $2
1007
+ data[:address] = $3
1008
+ when /Welcome to the Internet Relay Network\s(\S+)/
1009
+ data[:nick] = $1
1010
+ when /Welcome.*\s+(\S+)$/
1011
+ data[:nick] = $1
1012
+ when /^(\S+)$/
1013
+ data[:nick] = $1
1014
+ end
1015
+ handle(:welcome, data)
1016
+ when RPL_MOTDSTART
1017
+ # "<nick> :- <server> Message of the Day -"
1018
+ if argv[1] =~ /^-\s+(\S+)\s/
1019
+ server = $1
1020
+ @motd = ""
1021
+ end
1022
+ when RPL_MOTD
1023
+ if(argv[1] =~ /^-\s+(.*)$/)
1024
+ @motd << $1
1025
+ @motd << "\n"
1026
+ end
1027
+ when RPL_ENDOFMOTD
1028
+ data[:motd] = @motd
1029
+ handle(:motd, data)
1030
+ else
1031
+ handle(:unknown, data)
1032
+ end
1033
+ # end of numeric replies
1034
+ when 'PRIVMSG'
1035
+ # you can either bind to 'PRIVMSG', to get every one and
1036
+ # parse it yourself, or you can bind to 'MSG', 'PUBLIC',
1037
+ # etc and get it all nicely split up for you.
1038
+ data[:target] = argv[0]
1039
+ data[:message] = argv[1]
1040
+ handle(:privmsg, data)
1041
+
1042
+ # Now we split it
1043
+ if(data[:target] =~ /^(#|&).*/)
1044
+ handle(:public, data)
1045
+ else
1046
+ handle(:msg, data)
1047
+ end
1048
+ when 'KICK'
1049
+ data[:channel] = argv[0]
1050
+ data[:target] = argv[1]
1051
+ data[:message] = argv[2]
1052
+ handle(:kick, data)
1053
+ when 'PART'
1054
+ data[:channel] = argv[0]
1055
+ data[:message] = argv[1]
1056
+ handle(:part, data)
1057
+ when 'QUIT'
1058
+ data[:message] = argv[0]
1059
+ handle(:quit, data)
1060
+ when 'JOIN'
1061
+ data[:channel] = argv[0]
1062
+ handle(:join, data)
1063
+ when 'TOPIC'
1064
+ data[:channel] = argv[0]
1065
+ data[:topic] = argv[1]
1066
+ handle(:changetopic, data)
1067
+ when 'INVITE'
1068
+ data[:target] = argv[0]
1069
+ data[:channel] = argv[1]
1070
+ handle(:invite, data)
1071
+ when 'NICK'
1072
+ data[:nick] = argv[0]
1073
+ handle(:nick, data)
1074
+ when 'MODE'
1075
+ data[:channel] = argv[0]
1076
+ data[:modestring] = argv[1]
1077
+ data[:targets] = argv[2]
1078
+ handle(:mode, data)
1079
+ when 'NOTICE'
1080
+ data[:target] = argv[0]
1081
+ data[:message] = argv[1]
1082
+ if data[:sourcenick]
1083
+ handle(:notice, data)
1084
+ else
1085
+ # "server notice" (not from user, noone to reply to
1086
+ handle(:snotice, data)
1087
+ end
1088
+ else
1089
+ handle(:unknown, data)
1090
+ end
1091
+ end
1092
+
1093
+ private
1094
+
1095
+ # key:: server event name
1096
+ # data:: hash containing data about the event, passed to the proc
1097
+ # call client's proc for an event, if they set one as a handler
1098
+ def handle(key, data)
1099
+ if(@handlers.has_key?(key))
1100
+ @handlers[key].call(data)
1101
+ end
1102
+ end
1103
+ end
1104
+ end