nadoka 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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
+