nadoka 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. data/.gitignore +5 -0
  2. data/ChangeLog.old +1553 -0
  3. data/Gemfile +4 -0
  4. data/README.org +31 -0
  5. data/Rakefile +1 -0
  6. data/bin/nadoka +13 -0
  7. data/lib/rss_check.rb +206 -0
  8. data/lib/tagparts.rb +206 -0
  9. data/nadoka.gemspec +29 -0
  10. data/nadoka.rb +123 -0
  11. data/nadokarc +267 -0
  12. data/ndk/bot.rb +241 -0
  13. data/ndk/client.rb +288 -0
  14. data/ndk/config.rb +571 -0
  15. data/ndk/error.rb +61 -0
  16. data/ndk/logger.rb +311 -0
  17. data/ndk/server.rb +784 -0
  18. data/ndk/server_state.rb +324 -0
  19. data/ndk/version.rb +44 -0
  20. data/plugins/autoawaybot.nb +66 -0
  21. data/plugins/autodumpbot.nb +227 -0
  22. data/plugins/autoop.nb +56 -0
  23. data/plugins/backlogbot.nb +88 -0
  24. data/plugins/checkbot.nb +64 -0
  25. data/plugins/cronbot.nb +20 -0
  26. data/plugins/dictbot.nb +53 -0
  27. data/plugins/drbcl.rb +39 -0
  28. data/plugins/drbot.nb +93 -0
  29. data/plugins/evalbot.nb +49 -0
  30. data/plugins/gonzuibot.nb +41 -0
  31. data/plugins/googlebot.nb +345 -0
  32. data/plugins/identifynickserv.nb +43 -0
  33. data/plugins/mailcheckbot.nb +0 -0
  34. data/plugins/marldiabot.nb +99 -0
  35. data/plugins/messagebot.nb +96 -0
  36. data/plugins/modemanager.nb +150 -0
  37. data/plugins/opensearchbot.nb +156 -0
  38. data/plugins/opshop.nb +23 -0
  39. data/plugins/pastebot.nb +46 -0
  40. data/plugins/roulettebot.nb +33 -0
  41. data/plugins/rss_checkbot.nb +121 -0
  42. data/plugins/samplebot.nb +24 -0
  43. data/plugins/sendpingbot.nb +17 -0
  44. data/plugins/shellbot.nb +59 -0
  45. data/plugins/sixamobot.nb +77 -0
  46. data/plugins/tenkibot.nb +111 -0
  47. data/plugins/timestampbot.nb +62 -0
  48. data/plugins/titlebot.nb +226 -0
  49. data/plugins/translatebot.nb +301 -0
  50. data/plugins/twitterbot.nb +138 -0
  51. data/plugins/weba.nb +209 -0
  52. data/plugins/xibot.nb +113 -0
  53. data/rice/irc.rb +780 -0
  54. metadata +102 -0
@@ -0,0 +1,780 @@
1
+ =begin
2
+
3
+ = rice - Ruby Irc interfaCE
4
+
5
+ Original Credit:
6
+
7
+ Original Id: irc.rb,v 1.9 2001/06/13 10:22:24 akira Exp
8
+
9
+ Copyright (c) 2001 akira yamada <akira@ruby-lang.org>
10
+ You can redistribute it and/or modify it under the same term as Ruby.
11
+
12
+ == Modified
13
+
14
+ Modified by K.Sasada.
15
+ $Id$
16
+
17
+ =end
18
+
19
+ require 'socket'
20
+ require 'thread'
21
+ require 'monitor'
22
+ begin
23
+ require "openssl"
24
+ rescue LoadError
25
+ end
26
+
27
+
28
+ module RICE
29
+ class Error < StandardError; end
30
+ class InvalidMessage < Error; end
31
+ class UnknownCommand < Error; end
32
+
33
+ =begin
34
+
35
+ == RICE::Connection
36
+
37
+ =end
38
+
39
+ class Connection
40
+ class Error < StandardError; end
41
+ class Closed < Error; end
42
+
43
+ =begin
44
+
45
+ --- RICE::Connection::new
46
+
47
+ =end
48
+
49
+ def initialize(server, port, eol = "\r\n", ssl_params = nil)
50
+ @conn = []
51
+ @conn.extend(MonitorMixin)
52
+ @main_th = nil
53
+
54
+ self.server = server
55
+ self.port = port
56
+ self.eol = eol
57
+ self.ssl_params = ssl_params
58
+
59
+ @read_q = Queue.new
60
+
61
+ @read_th = Thread.new(@read_q, @eol) do |read_q, eol|
62
+ read_thread(read_q, eol)
63
+ end
64
+
65
+ @threads = {}
66
+ @threads.extend(MonitorMixin)
67
+
68
+ @dispatcher = Thread.new(@read_q) do |read_q|
69
+ loop do
70
+ x = read_q.pop
71
+
72
+ ths = @threads.synchronize do
73
+ @threads.keys
74
+ end
75
+ ths.each do |th|
76
+ if th.status
77
+ @threads[th].q.push(x)
78
+ else
79
+ @threads.delete(th)
80
+ end
81
+ end
82
+ end # loop
83
+
84
+ end
85
+
86
+ @delay = 0.3
87
+ @prev_send_time = Time.now
88
+ end
89
+ attr :delay, true
90
+ attr_reader :server, :port, :ssl_params
91
+
92
+ =begin
93
+
94
+ --- RICE::Connection#server=(server)
95
+
96
+ =end
97
+
98
+ def server=(server)
99
+ raise RuntimeError,
100
+ "Already connected to #{@server}:#{@port}" unless @conn.empty?
101
+ @server = server
102
+ end
103
+
104
+ =begin
105
+
106
+ --- RICE::Connection#port=(port)
107
+
108
+ =end
109
+
110
+ def port=(port)
111
+ raise RuntimeError,
112
+ "Already connected to #{@server}:#{@port}" unless @conn.empty?
113
+ @port = port
114
+ end
115
+
116
+ =begin
117
+
118
+ --- RICE::Connection#eol=(eol)
119
+
120
+ =end
121
+
122
+ def eol=(eol)
123
+ raise RuntimeError,
124
+ "Already connected to #{@server}:#{@port}" unless @conn.empty?
125
+ @eol = eol
126
+ end
127
+
128
+ =begin
129
+
130
+ --- RICE::Connection#ssl_params=(ssl_params)
131
+
132
+ =end
133
+
134
+ def ssl_params=(ssl_params)
135
+ raise RuntimeError,
136
+ "Already connected to #{@server}:#{@port}" unless @conn.empty?
137
+ unless ssl_params
138
+ @ssl_params = false
139
+ return
140
+ end
141
+ raise 'openssl library not installed' unless defined?(OpenSSL)
142
+ ssl_params = ssl_params.to_hash
143
+ ssl_params[:verify_mode] ||= OpenSSL::SSL::VERIFY_PEER
144
+ store = OpenSSL::X509::Store.new
145
+ if ssl_params.key?(:ca_cert)
146
+ ca_cert = ssl_params.delete(:ca_cert)
147
+ if ca_cert
148
+ # auto setting ca_path or ca_file like open-uri.rb
149
+ if File.directory? ca_cert
150
+ store.add_path ca_cert
151
+ else
152
+ store.add_file ca_cert
153
+ end
154
+ else
155
+ # use ssl_params={:ca_cert=>nil} if you want to disable auto setting
156
+ store = nil
157
+ end
158
+ else
159
+ # use default of openssl
160
+ store.set_default_paths
161
+ end
162
+ if store
163
+ ssl_params[:cert_store] = store
164
+ end
165
+ @ssl_params = ssl_params
166
+ end
167
+
168
+ =begin
169
+
170
+ --- RICE::Connection#start(max_retry = 3, retry_wait = 30)
171
+
172
+ =end
173
+
174
+ def start(max_retry = 3, retry_wait = 30)
175
+ @client_th = Thread.current # caller thread
176
+ if alive?
177
+ #sleep retry_wait
178
+ return nil
179
+ end
180
+
181
+ @main_th = Thread.new do
182
+ begin
183
+ Thread.stop
184
+ ensure
185
+ yield(self) if block_given?
186
+
187
+ @read_th.raise(Closed) if @read_th.status
188
+ close(true)
189
+ @client_th.raise(Closed)
190
+ end
191
+ end
192
+
193
+ begin
194
+ open_conn
195
+ rescue SystemCallError
196
+ max_retry -= 1
197
+ if max_retry == 0
198
+ @main_th.kill
199
+ raise
200
+ end
201
+ sleep retry_wait
202
+ retry
203
+ ensure
204
+ @main_th.join
205
+ nil
206
+ end
207
+
208
+ end
209
+
210
+ def open_conn
211
+ @conn.synchronize do
212
+ conn = TCPSocket.new(@server, @port)
213
+ if ssl_params
214
+ context = OpenSSL::SSL::SSLContext.new
215
+ context.set_params(ssl_params)
216
+ conn = OpenSSL::SSL::SSLSocket.new(conn, context)
217
+ conn.sync_close = true
218
+ conn.connect
219
+ if context.verify_mode != OpenSSL::SSL::VERIFY_NONE
220
+ conn.post_connection_check(@server)
221
+ end
222
+ end
223
+ @conn[0] = conn
224
+ end
225
+ @conn[0].extend(MonitorMixin)
226
+
227
+ @read_th.run
228
+
229
+ ths = @threads.synchronize do
230
+ @threads.keys
231
+ end
232
+ ths.each do |th|
233
+ th.run if th.status && th.stop?
234
+ end
235
+ end
236
+ private :open_conn
237
+
238
+ =begin
239
+
240
+ --- RICE::Connection#regist(raise_on_close, *args) {...}
241
+
242
+ =end
243
+
244
+ USER_THREAD = Struct.new('User_Thread', :q, :raise_on_close)
245
+ def regist(raise_on_close = false, *args)
246
+ read_q = Queue.new
247
+ th = Thread.new(read_q, self, *args) do |read_q, conn, *args|
248
+ yield(read_q, conn, *args)
249
+ end
250
+ @threads.synchronize do
251
+ @threads[th] = USER_THREAD.new(read_q, raise_on_close)
252
+ end
253
+ th
254
+ end
255
+
256
+ =begin
257
+
258
+ --- RICE::Connection#unregist(thread)
259
+
260
+ =end
261
+
262
+ def unregist(thread)
263
+ th = nil
264
+ @threads.synchronize do
265
+ th = @threads.delete(th)
266
+ end
267
+ th.exit
268
+ th
269
+ end
270
+
271
+ def read_thread(read_q, eol)
272
+ begin
273
+ read_q.clear
274
+ Thread.stop
275
+
276
+ begin
277
+ conn = @conn[0]
278
+ while l = conn.gets(eol)
279
+ begin
280
+ read_q.push(Message.parse(l))
281
+ rescue UnknownCommand
282
+ $stderr.print l.inspect if $DEBUG
283
+ rescue InvalidMessage
284
+ begin
285
+ read_q.push(Message.parse(l.sub(/\s*#{eol}\z/o, eol)))
286
+ rescue
287
+ $stderr.print l.inspect if $DEBUG
288
+ end
289
+ end
290
+ end
291
+
292
+ rescue IOError#, SystemCallError
293
+ $stderr.print "#{self.inspect}: read_th get error #{$!}" if $DEBUG
294
+
295
+ ensure
296
+ raise Closed
297
+ end
298
+
299
+ rescue Closed
300
+ begin
301
+ @main_th.run if @main_th.alive?
302
+ rescue Closed
303
+ end
304
+ retry
305
+ end
306
+ end
307
+ private :read_thread
308
+
309
+ =begin
310
+
311
+ --- RICE::Connection#close(restart = false)
312
+
313
+ =end
314
+
315
+ def close(restart = false)
316
+ begin
317
+ unless restart
318
+ @main_th.exit if @main_th.alive?
319
+ @read_th.exit if @read_th.alive?
320
+ end
321
+
322
+ conn = nil
323
+ @conn.synchronize do
324
+ conn = @conn.shift
325
+ end
326
+ conn.close if conn
327
+
328
+ @threads.synchronize do
329
+ @threads.each_key do |th|
330
+ if restart
331
+ if @threads[th].raise_on_close
332
+ if @threads[th].raise_on_close.kind_of?(Exception)
333
+ th.raise(@threads[th].raise_on_close)
334
+ else
335
+ th.raise(Closed)
336
+ end
337
+ end
338
+
339
+ else
340
+ th.exit
341
+ end
342
+ end
343
+ end
344
+
345
+ end
346
+ end
347
+
348
+ =begin
349
+
350
+ --- RICE::Connection#alive?
351
+
352
+ =end
353
+
354
+ def alive?
355
+ @main_th && @main_th.alive?
356
+ end
357
+
358
+ =begin
359
+
360
+ --- RICE::Connection#push(message)
361
+
362
+ =end
363
+
364
+ def push(message)
365
+ conn = @conn[0]
366
+ if conn
367
+ conn.synchronize do
368
+ cmd = message.command
369
+ if cmd == 'PRIVMSG' || cmd == 'NOTICE'
370
+ # flood control
371
+ t = Time.now
372
+ if t.to_i <= @prev_send_time.to_i + 2
373
+ sleep 1
374
+ end
375
+ @prev_send_time = t
376
+ end
377
+ conn.print message.to_s unless conn.closed?
378
+ end
379
+ else
380
+ nil
381
+ end
382
+ end
383
+ alias << push
384
+ end # Connection
385
+
386
+ =begin
387
+
388
+ == RICE::Message
389
+
390
+ =end
391
+
392
+ class Message
393
+ module PATTERN
394
+ # letter = %x41-5A / %x61-7A ; A-Z / a-z
395
+ # digit = %x30-39 ; 0-9
396
+ # hexdigit = digit / "A" / "B" / "C" / "D" / "E" / "F"
397
+ # special = %x5B-60 / %x7B-7D
398
+ # ; "[", "]", "\", "`", "_", "^", "{", "|", "}"
399
+ LETTER = 'A-Za-z'
400
+ DIGIT = '\d'
401
+ HEXDIGIT = "#{DIGIT}A-Fa-f"
402
+ SPECIAL = '\x5B-\x60\x7B-\x7D'
403
+
404
+ # shortname = ( letter / digit ) *( letter / digit / "-" )
405
+ # *( letter / digit )
406
+ # ; as specified in RFC 1123 [HNAME]
407
+ # hostname = shortname *( "." shortname )
408
+ SHORTNAME = "[#{LETTER}#{DIGIT}](?:[-#{LETTER}#{DIGIT}\/]*[#{LETTER}#{DIGIT}])?"
409
+ HOSTNAME = "#{SHORTNAME}(?:\\.#{SHORTNAME})*\\.?"
410
+
411
+ # servername = hostname
412
+ SERVERNAME = HOSTNAME
413
+
414
+ # nickname = ( letter / special ) *8( letter / digit / special / "-" )
415
+ # (nickname starts with DIGIT may occur in split mode)
416
+ NICKNAME = "[#{LETTER}#{DIGIT}#{SPECIAL}][\-#{LETTER}#{DIGIT}#{SPECIAL}]*"
417
+
418
+ # user = 1*( %x01-09 / %x0B-0C / %x0E-1F / %x21-3F / %x41-FF )
419
+ # ; any octet except NUL, CR, LF, " " and "@"
420
+ USER = '[\x01-\x09\x0B-\x0C\x0E-\x1F\x21-\x3F\x41-\xFF]+'
421
+
422
+ # ip4addr = 1*3digit "." 1*3digit "." 1*3digit "." 1*3digit
423
+ IP4ADDR = "[#{DIGIT}]{1,3}(?:\\.[#{DIGIT}]{1,3}){3}"
424
+
425
+ H16 = "[#{HEXDIGIT}]{1,4}" # :nodoc:
426
+ LS32 = "(?:#{H16}:#{H16})|#{IP4ADDR}" # :nodoc:
427
+ # ip6addr from RFC3986
428
+ IP6ADDR = "(?:#{H16}:){6}#{LS32}|" \
429
+ "::(?:#{H16}:){5}#{LS32}|" \
430
+ "(?:#{H16})?::(?:#{H16}:){4}#{LS32}|" \
431
+ "(?:(?:#{H16}:)?#{H16})?::(?:#{H16}:){3}#{LS32}|" \
432
+ "(?:(?:#{H16}:){0,2}#{H16})?::(?:#{H16}:){2}#{LS32}|" \
433
+ "(?:(?:#{H16}:){0,3}#{H16})?::#{H16}:#{LS32}|" \
434
+ "(?:(?:#{H16}:){0,4}#{H16})?::#{LS32}|" \
435
+ "(?:(?:#{H16}:){0,5}#{H16})?::#{H16}|" \
436
+ "(?:(?:#{H16}:){0,6}#{H16})?::"
437
+
438
+ # hostaddr = ip4addr / ip6addr
439
+ HOSTADDR = "(?:#{IP4ADDR}|#{IP6ADDR})"
440
+
441
+ # host = hostname / hostaddr
442
+ HOST = "(?:#{HOSTNAME}|#{HOSTADDR})"
443
+
444
+ # prefix = servername / ( nickname [ [ "!" user ] "@" host ] )
445
+ PREFIX = "(?:#{NICKNAME}(?:(?:!#{USER})?@#{HOST})?|#{SERVERNAME})"
446
+
447
+ # nospcrlfcl = %x01-09 / %x0B-0C / %x0E-1F / %x21-39 / %x3B-FF
448
+ # ; any octet except NUL, CR, LF, " " and ":"
449
+ NOSPCRLFCL = '\x01-\x09\x0B-\x0C\x0E-\x1F\x21-\x39\x3B-\xFF'
450
+
451
+ # command = 1*letter / 3digit
452
+ COMMAND = "(?:[#{LETTER}]+|[#{DIGIT}]{3})"
453
+
454
+ # SPACE = %x20 ; space character
455
+ # middle = nospcrlfcl *( ":" / nospcrlfcl )
456
+ # trailing = *( ":" / " " / nospcrlfcl )
457
+ # params = *14( SPACE middle ) [ SPACE ":" trailing ]
458
+ # =/ 14( SPACE middle ) [ SPACE [ ":" ] trailing ]
459
+ MIDDLE = "[#{NOSPCRLFCL}][:#{NOSPCRLFCL}]*"
460
+ TRAILING = "[: #{NOSPCRLFCL}]*"
461
+ PARAMS = "(?:((?: +#{MIDDLE}){0,14})(?: +:(#{TRAILING}))?|((?: +#{MIDDLE}){14}):?(#{TRAILING}))"
462
+
463
+ # crlf = %x0D %x0A ; "carriage return" "linefeed"
464
+ # message = [ ":" prefix SPACE ] command [ params ] crlf
465
+ CRLF = '\x0D\x0A'
466
+ MESSAGE = "(?::(#{PREFIX}) +)?(#{COMMAND})#{PARAMS}\s*(#{CRLF}|\n|\r)"
467
+
468
+ CLIENT_PATTERN = /\A#{NICKNAME}(?:(?:!#{USER})?@#{HOST})\z/on
469
+ MESSAGE_PATTERN = /\A#{MESSAGE}\z/on
470
+ end # PATTERN
471
+
472
+ =begin
473
+
474
+ --- RICE::Message::parse(str)
475
+
476
+ =end
477
+
478
+ def self.parse(str)
479
+ unless PATTERN::MESSAGE_PATTERN =~ str
480
+ raise InvalidMessage, "Invalid message: #{str.inspect}"
481
+
482
+ else
483
+ prefix = $1
484
+ command = $2
485
+ if $3 && $3.size > 0
486
+ middle = $3
487
+ trailer = $4
488
+ elsif $5 && $5.size > 0
489
+ middle = $5
490
+ trailer = $6
491
+ elsif $4
492
+ params = []
493
+ trailer = $4
494
+ elsif $6
495
+ params = []
496
+ trailer = $6
497
+ else
498
+ params = []
499
+ end
500
+ end
501
+ params ||= middle.split(/ /)[1..-1]
502
+ params << trailer if trailer
503
+
504
+ self.build(prefix, command.upcase, params)
505
+ end
506
+
507
+ =begin
508
+
509
+ --- RICE::Message::build(prefix, command, params)
510
+
511
+ =end
512
+
513
+ def self.build(prefix, command, params)
514
+ if Command::Commands.include?(command)
515
+ Command::Commands[command].new(prefix, command, params)
516
+ elsif Reply::Replies.include?(command)
517
+ Reply::Replies[command].new(prefix, command, params)
518
+ else
519
+ raise UnknownCommand, "unknown command: #{command}"
520
+ end
521
+ end
522
+
523
+ =begin
524
+
525
+ --- RICE::Message#prefix
526
+
527
+ --- RICE::Message#command
528
+
529
+ --- RICE::Message#params
530
+
531
+ =end
532
+
533
+ def initialize(prefix, command, params)
534
+ @prefix = prefix
535
+ @command = command
536
+ @params = params
537
+ end
538
+ attr_accessor :prefix
539
+ attr_reader :command, :params
540
+
541
+ =begin
542
+
543
+ --- RICE::Message::#to_s
544
+
545
+ =end
546
+
547
+ def to_s
548
+ str = ''
549
+ if @prefix
550
+ str << ':'
551
+ str << @prefix
552
+ str << ' '
553
+ end
554
+
555
+ str << @command
556
+
557
+ if @params
558
+ f = false
559
+ @params.each do |param|
560
+ str << ' '
561
+ if (param == @params[-1]) && (param.size == 0 || /(^:)|(\s)/ =~ param)
562
+ str << ':'
563
+ str << param.to_s
564
+ f = true
565
+ else
566
+ str << param.to_s
567
+ end
568
+ end
569
+ end
570
+
571
+ str << "\x0D\x0A"
572
+
573
+ str
574
+ end
575
+
576
+ =begin
577
+
578
+ --- RICE::Message::#to_a
579
+
580
+ =end
581
+
582
+ def to_a
583
+ [@prefix, @command, @params]
584
+ end
585
+
586
+ def inspect
587
+ sprintf('#<%s:0x%x prefix:%s command:%s params:%s>',
588
+ self.class, self.object_id, @prefix, @command, @params.inspect)
589
+ end
590
+
591
+ end # Message
592
+
593
+ =begin
594
+
595
+ == RICE::Command
596
+
597
+ =end
598
+
599
+ module Command
600
+ class Command < Message
601
+ end # Command
602
+
603
+ def self.regist_command cmd
604
+ eval <<E
605
+ class #{cmd} < Command
606
+ end
607
+ Commands['#{cmd}'] = #{cmd}
608
+
609
+ def #{cmd.downcase}(*params)
610
+ #{cmd}.new(nil, '#{cmd}', params)
611
+ end
612
+ module_function :#{cmd.downcase}
613
+ E
614
+ end
615
+ Commands = {}
616
+ %w(PASS NICK USER OPER MODE SERVICE QUIT SQUIT
617
+ JOIN PART TOPIC NAMES LIST INVITE KICK
618
+ PRIVMSG NOTICE MOTD LUSERS VERSION STATS LINKS
619
+ TIME CONNECT TRACE ADMIN INFO SERVLIST SQUERY
620
+ WHO WHOIS WHOWAS KILL PING PONG ERROR
621
+ AWAY REHASH DIE RESTART SUMMON USERS WALLOPS USERHOST ISON
622
+ ).each do |cmd|
623
+ self.regist_command cmd
624
+ end
625
+
626
+ class NICK
627
+ def to_s
628
+ str = ''
629
+ if @prefix
630
+ str << ':'
631
+ str << @prefix
632
+ str << ' '
633
+ end
634
+
635
+ str << @command
636
+
637
+ str << ' '
638
+ str << ":#{@params[0]}"
639
+
640
+ str << "\x0D\x0A"
641
+ str
642
+ end
643
+ end
644
+
645
+ # XXX:
646
+ class PRIVMSG
647
+ def to_s
648
+ str = ''
649
+ if @prefix
650
+ str << ':'
651
+ str << @prefix
652
+ str << ' '
653
+ end
654
+
655
+ str << @command
656
+
657
+ str << ' '
658
+ str << @params[0]
659
+
660
+ str << ' :'
661
+ str << @params[1..-1].join(' ')
662
+
663
+ str << "\x0D\x0A"
664
+ str
665
+ end
666
+ end
667
+
668
+ end # Command
669
+
670
+ =begin
671
+
672
+ == RICE::Reply
673
+
674
+ == RICE::CommandResponse
675
+
676
+ == RICE::ErrorReply
677
+
678
+ =end
679
+
680
+ module Reply
681
+ class Reply < Message
682
+ end
683
+
684
+ class CommandResponse < Reply
685
+ end
686
+
687
+ class ErrorReply < Reply
688
+ end
689
+
690
+ Replies = {}
691
+ Replies_num_to_name = {}
692
+
693
+ %w(001,RPL_WELCOME
694
+ 002,RPL_YOURHOST
695
+ 003,RPL_CREATED
696
+ 004,RPL_MYINFO
697
+ 005,RPL_BOUNCE
698
+ 302,RPL_USERHOST 303,RPL_ISON 301,RPL_AWAY
699
+ 305,RPL_UNAWAY 306,RPL_NOWAWAY 311,RPL_WHOISUSER
700
+ 312,RPL_WHOISSERVER 313,RPL_WHOISOPERATOR
701
+ 317,RPL_WHOISIDLE 318,RPL_ENDOFWHOIS
702
+ 319,RPL_WHOISCHANNELS 314,RPL_WHOWASUSER
703
+ 369,RPL_ENDOFWHOWAS 321,RPL_LISTSTART
704
+ 322,RPL_LIST 323,RPL_LISTEND 325,RPL_UNIQOPIS
705
+ 324,RPL_CHANNELMODEIS 331,RPL_NOTOPIC
706
+ 332,RPL_TOPIC 341,RPL_INVITING 342,RPL_SUMMONING
707
+ 344,RPL_REOPLIST 345,RPL_ENDOFREOPLIST
708
+ 346,RPL_INVITELIST 347,RPL_ENDOFINVITELIST
709
+ 348,RPL_EXCEPTLIST 349,RPL_ENDOFEXCEPTLIST
710
+ 351,RPL_VERSION 352,RPL_WHOREPLY 315,RPL_ENDOFWHO
711
+ 353,RPL_NAMREPLY 366,RPL_ENDOFNAMES 364,RPL_LINKS
712
+ 365,RPL_ENDOFLINKS 367,RPL_BANLIST 368,RPL_ENDOFBANLIST
713
+ 371,RPL_INFO 374,RPL_ENDOFINFO 375,RPL_MOTDSTART
714
+ 372,RPL_MOTD 376,RPL_ENDOFMOTD 381,RPL_YOUREOPER
715
+ 382,RPL_REHASHING 383,RPL_YOURESERVICE 391,RPL_TIM
716
+ 392,RPL_ 393,RPL_USERS 394,RPL_ENDOFUSERS 395,RPL_NOUSERS
717
+ 200,RPL_TRACELINK 201,RPL_TRACECONNECTING
718
+ 202,RPL_TRACEHANDSHAKE 203,RPL_TRACEUNKNOWN
719
+ 204,RPL_TRACEOPERATOR 205,RPL_TRACEUSER 206,RPL_TRACESERVER
720
+ 207,RPL_TRACESERVICE 208,RPL_TRACENEWTYPE 209,RPL_TRACECLASS
721
+ 210,RPL_TRACERECONNECT 261,RPL_TRACELOG 262,RPL_TRACEEND
722
+ 211,RPL_STATSLINKINFO 212,RPL_STATSCOMMANDS 219,RPL_ENDOFSTATS
723
+ 242,RPL_STATSUPTIME 243,RPL_STATSOLINE 221,RPL_UMODEIS
724
+ 234,RPL_SERVLIST 235,RPL_SERVLISTEND 251,RPL_LUSERCLIENT
725
+ 252,RPL_LUSEROP 253,RPL_LUSERUNKNOWN 254,RPL_LUSERCHANNELS
726
+ 255,RPL_LUSERME 256,RPL_ADMINME 257,RPL_ADMINLOC1
727
+ 258,RPL_ADMINLOC2 259,RPL_ADMINEMAIL 263,RPL_TRYAGAIN
728
+ 401,ERR_NOSUCHNICK 402,ERR_NOSUCHSERVER 403,ERR_NOSUCHCHANNEL
729
+ 404,ERR_CANNOTSENDTOCHAN 405,ERR_TOOMANYCHANNELS
730
+ 406,ERR_WASNOSUCHNICK 407,ERR_TOOMANYTARGETS
731
+ 408,ERR_NOSUCHSERVICE 409,ERR_NOORIGIN 411,ERR_NORECIPIENT
732
+ 412,ERR_NOTEXTTOSEND 413,ERR_NOTOPLEVEL 414,ERR_WILDTOPLEVEL
733
+ 415,ERR_BADMASK 421,ERR_UNKNOWNCOMMAND 422,ERR_NOMOTD
734
+ 423,ERR_NOADMININFO 424,ERR_FILEERROR 431,ERR_NONICKNAMEGIVEN
735
+ 432,ERR_ERRONEUSNICKNAME 433,ERR_NICKNAMEINUSE
736
+ 436,ERR_NICKCOLLISION 437,ERR_UNAVAILRESOURCE
737
+ 441,ERR_USERNOTINCHANNEL 442,ERR_NOTONCHANNEL
738
+ 443,ERR_USERONCHANNEL 444,ERR_NOLOGIN 445,ERR_SUMMONDISABLED
739
+ 446,ERR_USERSDISABLED 451,ERR_NOTREGISTERED
740
+ 461,ERR_NEEDMOREPARAMS 462,ERR_ALREADYREGISTRED
741
+ 463,ERR_NOPERMFORHOST 464,ERR_PASSWDMISMATCH
742
+ 465,ERR_YOUREBANNEDCREEP 466,ERR_YOUWILLBEBANNED
743
+ 467,ERR_KEYSE 471,ERR_CHANNELISFULL 472,ERR_UNKNOWNMODE
744
+ 473,ERR_INVITEONLYCHAN 474,ERR_BANNEDFROMCHAN
745
+ 475,ERR_BADCHANNELKEY 476,ERR_BADCHANMASK 477,ERR_NOCHANMODES
746
+ 478,ERR_BANLISTFULL 481,ERR_NOPRIVILEGES 482,ERR_CHANOPRIVSNEEDED
747
+ 483,ERR_CANTKILLSERVER 484,ERR_RESTRICTED
748
+ 485,ERR_UNIQOPPRIVSNEEDED 491,ERR_NOOPERHOST
749
+ 501,ERR_UMODEUNKNOWNFLAG 502,ERR_USERSDONTMATCH
750
+ 231,RPL_SERVICEINFO 232,RPL_ENDOFSERVICES
751
+ 233,RPL_SERVICE 300,RPL_NONE 316,RPL_WHOISCHANOP
752
+ 361,RPL_KILLDONE 362,RPL_CLOSING 363,RPL_CLOSEEND
753
+ 373,RPL_INFOSTART 384,RPL_MYPORTIS 213,RPL_STATSCLINE
754
+ 214,RPL_STATSNLINE 215,RPL_STATSILINE 216,RPL_STATSKLINE
755
+ 217,RPL_STATSQLINE 218,RPL_STATSYLINE 240,RPL_STATSVLINE
756
+ 241,RPL_STATSLLINE 244,RPL_STATSHLINE 244,RPL_STATSSLINE
757
+ 246,RPL_STATSPING 247,RPL_STATSBLINE 250,RPL_STATSDLINE
758
+ 492,ERR_NOSERVICEHOST
759
+ ).each do |num_cmd|
760
+ num, cmd = num_cmd.split(',', 2)
761
+ eval <<E
762
+ class #{cmd} < #{if num[0] == ?0 || num[0] == ?2 || num[0] == ?3
763
+ 'CommandResponse'
764
+ elsif num[0] == ?4 || num[0] == ?5
765
+ 'ErrorReply'
766
+ end}
767
+ end
768
+ Replies['#{num}'] = #{cmd}
769
+ Replies_num_to_name['#{num}'] = '#{cmd.downcase}'
770
+
771
+ def #{cmd.downcase}(*params)
772
+ #{cmd}.new(nil, '#{num}', params)
773
+ end
774
+ module_function :#{cmd.downcase}
775
+ E
776
+ end
777
+
778
+ end # Reply
779
+ end # RICE
780
+