rbot 0.9.9 → 0.9.10

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 (72) hide show
  1. data/AUTHORS +8 -0
  2. data/ChangeLog +51 -0
  3. data/INSTALL +4 -0
  4. data/README +1 -0
  5. data/REQUIREMENTS +11 -0
  6. data/TODO +2 -0
  7. data/bin/rbot +21 -2
  8. data/data/rbot/languages/german.lang +4 -1
  9. data/data/rbot/languages/russian.lang +75 -0
  10. data/data/rbot/plugins/autoop.rb +42 -51
  11. data/data/rbot/plugins/bans.rb +205 -0
  12. data/data/rbot/plugins/bash.rb +56 -0
  13. data/data/rbot/plugins/chucknorris.rb +74 -0
  14. data/data/rbot/plugins/chucknorris.yml.gz +0 -0
  15. data/data/rbot/plugins/deepthoughts.rb +95 -0
  16. data/data/rbot/plugins/demauro.rb +95 -0
  17. data/data/rbot/plugins/digg.rb +51 -0
  18. data/data/rbot/plugins/figlet.rb +24 -0
  19. data/data/rbot/plugins/forecast.rb +133 -0
  20. data/data/rbot/plugins/freshmeat.rb +13 -7
  21. data/data/rbot/plugins/google.rb +2 -0
  22. data/data/rbot/plugins/grouphug.rb +36 -0
  23. data/data/rbot/plugins/imdb.rb +92 -0
  24. data/data/rbot/plugins/insult.rb +8 -1
  25. data/data/rbot/plugins/iplookup.rb +227 -0
  26. data/data/rbot/plugins/karma.rb +2 -2
  27. data/data/rbot/plugins/keywords.rb +470 -0
  28. data/data/rbot/plugins/lart.rb +132 -146
  29. data/data/rbot/plugins/lastfm.rb +25 -0
  30. data/data/rbot/plugins/markov.rb +204 -0
  31. data/data/rbot/plugins/math.rb +5 -1
  32. data/data/rbot/plugins/nickserv.rb +71 -11
  33. data/data/rbot/plugins/opme.rb +19 -19
  34. data/data/rbot/plugins/quakeauth.rb +2 -2
  35. data/data/rbot/plugins/quotes.rb +40 -25
  36. data/data/rbot/plugins/remind.rb +1 -1
  37. data/data/rbot/plugins/rot13.rb +2 -2
  38. data/data/rbot/plugins/roulette.rb +49 -15
  39. data/data/rbot/plugins/rss.rb +585 -0
  40. data/data/rbot/plugins/rubyurl.rb +39 -0
  41. data/data/rbot/plugins/seen.rb +2 -1
  42. data/data/rbot/plugins/slashdot.rb +5 -5
  43. data/data/rbot/plugins/spell.rb +5 -0
  44. data/data/rbot/plugins/theyfightcrime.rb +121 -0
  45. data/data/rbot/plugins/threat.rb +55 -0
  46. data/data/rbot/plugins/tinyurl.rb +39 -0
  47. data/data/rbot/plugins/topic.rb +204 -0
  48. data/data/rbot/plugins/urban.rb +71 -0
  49. data/data/rbot/plugins/url.rb +399 -4
  50. data/data/rbot/plugins/wow.rb +123 -0
  51. data/data/rbot/plugins/wserver.rb +1 -1
  52. data/data/rbot/templates/levels.rbot +2 -0
  53. data/lib/rbot/auth.rb +207 -96
  54. data/lib/rbot/channel.rb +5 -5
  55. data/lib/rbot/config.rb +125 -24
  56. data/lib/rbot/dbhash.rb +87 -21
  57. data/lib/rbot/httputil.rb +181 -13
  58. data/lib/rbot/ircbot.rb +525 -179
  59. data/lib/rbot/ircsocket.rb +330 -54
  60. data/lib/rbot/message.rb +66 -23
  61. data/lib/rbot/messagemapper.rb +25 -17
  62. data/lib/rbot/plugins.rb +244 -115
  63. data/lib/rbot/post-clean.rb +1 -0
  64. data/lib/rbot/{post-install.rb → post-config.rb} +1 -1
  65. data/lib/rbot/rbotconfig.rb +29 -14
  66. data/lib/rbot/registry.rb +111 -72
  67. data/lib/rbot/rfc2812.rb +208 -197
  68. data/lib/rbot/timer.rb +4 -0
  69. data/lib/rbot/utils.rb +2 -2
  70. metadata +127 -104
  71. data/data/rbot/plugins/rss.rb.disabled +0 -414
  72. data/lib/rbot/keywords.rb +0 -433
@@ -0,0 +1 @@
1
+ File.unlink("pkgconfig.rb") if FileTest.exist?("pkgconfig.rb")
@@ -1,5 +1,5 @@
1
1
  # write out our datadir so we can reference it at runtime
2
- File.open("#{config('rbdir')}/rbot/pkgconfig.rb", "w") {|f|
2
+ File.open("pkgconfig.rb", "w") {|f|
3
3
  f.puts "module Irc"
4
4
  f.puts " module PKGConfig"
5
5
  f.puts " DATADIR = '#{config('datadir')}/rbot'"
@@ -1,22 +1,37 @@
1
1
  module Irc
2
2
  module Config
3
3
  @@datadir = nil
4
+
5
+ # first try for the default path to the data dir
6
+ defaultdir = File.expand_path(File.dirname($0) + '/../data')
7
+
8
+ if File.directory? "#{defaultdir}/rbot"
9
+ @@datadir = "#{defaultdir}/rbot"
10
+ end
11
+
4
12
  # setup pkg-based configuration - i.e. where were we installed to, where
5
13
  # are our data files, etc.
6
- begin
7
- debug "trying to load rubygems"
8
- require 'rubygems'
9
- debug "loaded rubygems, looking for rbot-#$version"
10
- gemname, gem = Gem.source_index.find{|name, spec| spec.name == 'rbot' && spec.version.version == $version}
11
- debug "got gem #{gem}"
12
- if gem && path = gem.full_gem_path
13
- debug "installed via rubygems to #{path}"
14
- @@datadir = "#{path}/data/rbot"
15
- else
16
- debug "not installed via rubygems"
14
+ if @@datadir.nil?
15
+ begin
16
+ debug "trying to load rubygems"
17
+ require 'rubygems'
18
+ debug "loaded rubygems, looking for rbot-#$version"
19
+ if $version =~ /(.*)-svn\Z/
20
+ version = $1
21
+ else
22
+ version = $version
23
+ end
24
+ gemname, gem = Gem.source_index.find{|name, spec| spec.name == 'rbot' && spec.version.version == version}
25
+ debug "got gem #{gem}"
26
+ if gem && path = gem.full_gem_path
27
+ debug "installed via rubygems to #{path}"
28
+ @@datadir = "#{path}/data/rbot"
29
+ else
30
+ debug "not installed via rubygems"
31
+ end
32
+ rescue LoadError,NameError,NoMethodError
33
+ debug "no rubygems installed"
17
34
  end
18
- rescue LoadError
19
- debug "no rubygems installed"
20
35
  end
21
36
 
22
37
  if @@datadir.nil?
@@ -24,7 +39,7 @@ module Irc
24
39
  require 'rbot/pkgconfig'
25
40
  @@datadir = PKGConfig::DATADIR
26
41
  rescue LoadError
27
- puts "fatal - no way to determine data dir"
42
+ error "fatal - no way to determine data dir"
28
43
  exit 2
29
44
  end
30
45
  end
data/lib/rbot/registry.rb CHANGED
@@ -2,19 +2,13 @@ require 'rbot/dbhash'
2
2
 
3
3
  module Irc
4
4
 
5
- # this is the backend of the RegistryAccessor class, which ties it to a
6
- # DBHash object called plugin_registry(.db). All methods are delegated to
7
- # the DBHash.
5
+ # this class is now used purely for upgrading from prior versions of rbot
6
+ # the new registry is split into multiple DBHash objects, one per plugin
8
7
  class BotRegistry
9
8
  def initialize(bot)
10
9
  @bot = bot
11
10
  upgrade_data
12
- @db = DBTree.new @bot, "plugin_registry"
13
- end
14
-
15
- # delegation hack
16
- def method_missing(method, *args, &block)
17
- @db.send(method, *args, &block)
11
+ upgrade_data2
18
12
  end
19
13
 
20
14
  # check for older versions of rbot with data formats that require updating
@@ -22,24 +16,64 @@ module Irc
22
16
  # work with is @bot.botclass.
23
17
  def upgrade_data
24
18
  if File.exist?("#{@bot.botclass}/registry.db")
25
- puts "upgrading old-style (rbot 0.9.5 or earlier) plugin registry to new format"
26
- old = BDB::Hash.open "#{@bot.botclass}/registry.db", nil,
27
- "r+", 0600, "set_pagesize" => 1024,
28
- "set_cachesize" => [0, 32 * 1024, 0]
29
- new = BDB::CIBtree.open "#{@bot.botclass}/plugin_registry.db", nil,
30
- BDB::CREATE | BDB::EXCL | BDB::TRUNCATE,
31
- 0600, "set_pagesize" => 1024,
32
- "set_cachesize" => [0, 32 * 1024, 0]
19
+ log "upgrading old-style (rbot 0.9.5 or earlier) plugin registry to new format"
20
+ old = BDB::Hash.open("#{@bot.botclass}/registry.db", nil,
21
+ "r+", 0600)
22
+ new = BDB::CIBtree.open("#{@bot.botclass}/plugin_registry.db", nil,
23
+ BDB::CREATE | BDB::EXCL,
24
+ 0600)
33
25
  old.each {|k,v|
34
26
  new[k] = v
35
27
  }
36
28
  old.close
37
29
  new.close
38
- File.delete("#{@bot.botclass}/registry.db")
30
+ File.rename("#{@bot.botclass}/registry.db", "#{@bot.botclass}/registry.db.old")
31
+ end
32
+ end
33
+
34
+ def upgrade_data2
35
+ if File.exist?("#{@bot.botclass}/plugin_registry.db")
36
+ Dir.mkdir("#{@bot.botclass}/registry") unless File.exist?("#{@bot.botclass}/registry")
37
+ env = BDB::Env.open("#{@bot.botclass}", BDB::INIT_TRANSACTION | BDB::CREATE | BDB::RECOVER )
38
+ dbs = Hash.new
39
+ log "upgrading previous (rbot 0.9.9 or earlier) plugin registry to new split format"
40
+ old = BDB::CIBtree.open("#{@bot.botclass}/plugin_registry.db", nil,
41
+ "r+", 0600, "env" => env)
42
+ old.each {|k,v|
43
+ prefix,key = k.split("/", 2)
44
+ prefix.downcase!
45
+ # subregistries were split with a +, now they are in separate folders
46
+ if prefix.gsub!(/\+/, "/")
47
+ # Ok, this code needs to be put in the db opening routines
48
+ dirs = File.dirname("#{@bot.botclass}/registry/#{prefix}.db").split("/")
49
+ dirs.length.times { |i|
50
+ dir = dirs[0,i+1].join("/")+"/"
51
+ unless File.exist?(dir)
52
+ log "creating subregistry directory #{dir}"
53
+ Dir.mkdir(dir)
54
+ end
55
+ }
56
+ end
57
+ unless dbs.has_key?(prefix)
58
+ log "creating db #{@bot.botclass}/registry/#{prefix}.db"
59
+ dbs[prefix] = BDB::CIBtree.open("#{@bot.botclass}/registry/#{prefix}.db",
60
+ nil, BDB::CREATE | BDB::EXCL,
61
+ 0600, "env" => env)
62
+ end
63
+ dbs[prefix][key] = v
64
+ }
65
+ old.close
66
+ File.rename("#{@bot.botclass}/plugin_registry.db", "#{@bot.botclass}/plugin_registry.db.old")
67
+ dbs.each {|k,v|
68
+ log "closing db #{k}"
69
+ v.close
70
+ }
71
+ env.close
39
72
  end
40
73
  end
41
74
  end
42
75
 
76
+
43
77
  # This class provides persistent storage for plugins via a hash interface.
44
78
  # The default mode is an object store, so you can store ruby objects and
45
79
  # reference them with hash keys. This is because the default store/restore
@@ -54,7 +88,7 @@ module Irc
54
88
  # blah = @registry[:blah]
55
89
  # The registry can of course be used to store simple strings, fixnums, etc as
56
90
  # well, and should be useful to store or cache plugin data or dynamic plugin
57
- # configuration.
91
+ # configuration.
58
92
  #
59
93
  # WARNING:
60
94
  # in object store mode, don't make the mistake of treating it like a live
@@ -86,19 +120,29 @@ module Irc
86
120
  class BotRegistryAccessor
87
121
  # plugins don't call this - a BotRegistryAccessor is created for them and
88
122
  # is accessible via @registry.
89
- def initialize(bot, prefix)
123
+ def initialize(bot, name)
90
124
  @bot = bot
91
- @registry = @bot.registry
92
- @orig_prefix = prefix
93
- @prefix = prefix + "/"
125
+ @name = name.downcase
126
+ dirs = File.dirname("#{@bot.botclass}/registry/#{@name}").split("/")
127
+ dirs.length.times { |i|
128
+ dir = dirs[0,i+1].join("/")+"/"
129
+ unless File.exist?(dir)
130
+ debug "creating subregistry directory #{dir}"
131
+ Dir.mkdir(dir)
132
+ end
133
+ }
134
+ @registry = DBTree.new bot, "registry/#{@name}"
94
135
  @default = nil
95
- # debug "initializing registry accessor with prefix #{@prefix}"
136
+ # debug "initializing registry accessor with name #{@name}"
96
137
  end
97
138
 
98
- # use this to chop up your namespace into bits, so you can keep and
99
- # reference separate object stores under the same registry
100
- def sub_registry(prefix)
101
- return BotRegistryAccessor.new(@bot, @orig_prefix + "+" + prefix)
139
+ def flush
140
+ @registry.flush
141
+ @registry.sync
142
+ end
143
+
144
+ def close
145
+ @registry.close
102
146
  end
103
147
 
104
148
  # convert value to string form for storing in the registry
@@ -120,13 +164,28 @@ module Irc
120
164
  # val
121
165
  # end
122
166
  def restore(val)
123
- Marshal.restore(val)
167
+ begin
168
+ Marshal.restore(val)
169
+ rescue Exception => e
170
+ warning "failed to restore marshal data for #{val.inspect}, falling back to default"
171
+ debug e.inspect
172
+ debug e.backtrace.join("\n")
173
+ if @default != nil
174
+ begin
175
+ return Marshal.restore(@default)
176
+ rescue
177
+ return nil
178
+ end
179
+ else
180
+ return nil
181
+ end
182
+ end
124
183
  end
125
184
 
126
185
  # lookup a key in the registry
127
186
  def [](key)
128
- if @registry.has_key?(@prefix + key)
129
- return restore(@registry[@prefix + key])
187
+ if @registry.has_key?(key)
188
+ return restore(@registry[key])
130
189
  elsif @default != nil
131
190
  return restore(@default)
132
191
  else
@@ -136,7 +195,7 @@ module Irc
136
195
 
137
196
  # set a key in the registry
138
197
  def []=(key,value)
139
- @registry[@prefix + key] = store(value)
198
+ @registry[key] = store(value)
140
199
  end
141
200
 
142
201
  # set the default value for registry lookups, if the key sought is not
@@ -148,42 +207,36 @@ module Irc
148
207
  # just like Hash#each
149
208
  def each(&block)
150
209
  @registry.each {|key,value|
151
- if key.gsub!(/^#{Regexp.escape(@prefix)}/, "")
152
- block.call(key, restore(value))
153
- end
210
+ block.call(key, restore(value))
154
211
  }
155
212
  end
156
-
213
+
157
214
  # just like Hash#each_key
158
215
  def each_key(&block)
159
216
  @registry.each {|key, value|
160
- if key.gsub!(/^#{Regexp.escape(@prefix)}/, "")
161
- block.call(key)
162
- end
217
+ block.call(key)
163
218
  }
164
219
  end
165
-
220
+
166
221
  # just like Hash#each_value
167
222
  def each_value(&block)
168
223
  @registry.each {|key, value|
169
- if key =~ /^#{Regexp.escape(@prefix)}/
170
- block.call(restore(value))
171
- end
224
+ block.call(restore(value))
172
225
  }
173
226
  end
174
227
 
175
228
  # just like Hash#has_key?
176
229
  def has_key?(key)
177
- return @registry.has_key?(@prefix + key)
230
+ return @registry.has_key?(key)
178
231
  end
179
232
  alias include? has_key?
180
233
  alias member? has_key?
181
234
 
182
235
  # just like Hash#has_both?
183
236
  def has_both?(key, value)
184
- return @registry.has_both?(@prefix + key, store(value))
237
+ return @registry.has_both?(key, store(value))
185
238
  end
186
-
239
+
187
240
  # just like Hash#has_value?
188
241
  def has_value?(value)
189
242
  return @registry.has_value?(store(value))
@@ -192,58 +245,44 @@ module Irc
192
245
  # just like Hash#index?
193
246
  def index(value)
194
247
  ind = @registry.index(store(value))
195
- if ind && ind.gsub!(/^#{Regexp.escape(@prefix)}/, "")
248
+ if ind
196
249
  return ind
197
250
  else
198
251
  return nil
199
252
  end
200
253
  end
201
-
254
+
202
255
  # delete a key from the registry
203
256
  def delete(key)
204
- return @registry.delete(@prefix + key)
257
+ return @registry.delete(key)
205
258
  end
206
259
 
207
260
  # returns a list of your keys
208
261
  def keys
209
- return @registry.keys.collect {|key|
210
- if key.gsub!(/^#{Regexp.escape(@prefix)}/, "")
211
- key
212
- else
213
- nil
214
- end
215
- }.compact
262
+ return @registry.keys
216
263
  end
217
264
 
218
265
  # Return an array of all associations [key, value] in your namespace
219
266
  def to_a
220
267
  ret = Array.new
221
268
  @registry.each {|key, value|
222
- if key.gsub!(/^#{Regexp.escape(@prefix)}/, "")
223
- ret << [key, restore(value)]
224
- end
269
+ ret << [key, restore(value)]
225
270
  }
226
271
  return ret
227
272
  end
228
-
273
+
229
274
  # Return an hash of all associations {key => value} in your namespace
230
275
  def to_hash
231
276
  ret = Hash.new
232
277
  @registry.each {|key, value|
233
- if key.gsub!(/^#{Regexp.escape(@prefix)}/, "")
234
- ret[key] = restore(value)
235
- end
278
+ ret[key] = restore(value)
236
279
  }
237
280
  return ret
238
281
  end
239
282
 
240
283
  # empties the registry (restricted to your namespace)
241
284
  def clear
242
- @registry.each_key {|key|
243
- if key =~ /^#{Regexp.escape(@prefix)}/
244
- @registry.delete(key)
245
- end
246
- }
285
+ @registry.clear
247
286
  end
248
287
  alias truncate clear
249
288
 
@@ -256,16 +295,16 @@ module Irc
256
295
  return ret
257
296
  end
258
297
 
298
+ def sub_registry(prefix)
299
+ return BotRegistryAccessor.new(@bot, @name + "/" + prefix)
300
+ end
301
+
259
302
  # returns the number of keys in your registry namespace
260
303
  def length
261
304
  self.keys.length
262
305
  end
263
306
  alias size length
264
307
 
265
- def flush
266
- @registry.flush
267
- end
268
-
269
308
  end
270
309
 
271
310
  end
data/lib/rbot/rfc2812.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Irc
2
2
  # RFC 2812 Internet Relay Chat: Client Protocol
3
- #
3
+ #
4
4
  RPL_WELCOME=001
5
5
  # "Welcome to the Internet Relay Network
6
6
  # <nick>!<user>@<host>"
@@ -11,53 +11,53 @@ module Irc
11
11
  RPL_MYINFO=004
12
12
  # "<servername> <version> <available user modes>
13
13
  # <available channel modes>"
14
- #
14
+ #
15
15
  # - The server sends Replies 001 to 004 to a user upon
16
16
  # successful registration.
17
- #
17
+ #
18
18
  # RPL_BOUNCE=005
19
19
  # # "Try server <server name>, port <port number>"
20
20
  RPL_ISUPPORT=005
21
21
  # "005 nick PREFIX=(ov)@+ CHANTYPES=#& :are supported by this server"
22
- #
22
+ #
23
23
  # - Sent by the server to a user to suggest an alternative
24
24
  # server. This is often used when the connection is
25
25
  # refused because the server is already full.
26
- #
26
+ #
27
27
  RPL_USERHOST=302
28
28
  # ":*1<reply> *( " " <reply> )"
29
- #
29
+ #
30
30
  # - Reply format used by USERHOST to list replies to
31
31
  # the query list. The reply string is composed as
32
32
  # follows:
33
- #
33
+ #
34
34
  # reply = nickname [ "*" ] "=" ( "+" / "-" ) hostname
35
- #
35
+ #
36
36
  # The '*' indicates whether the client has registered
37
37
  # as an Operator. The '-' or '+' characters represent
38
38
  # whether the client has set an AWAY message or not
39
39
  # respectively.
40
- #
40
+ #
41
41
  RPL_ISON=303
42
42
  # ":*1<nick> *( " " <nick> )"
43
- #
43
+ #
44
44
  # - Reply format used by ISON to list replies to the
45
45
  # query list.
46
- #
46
+ #
47
47
  RPL_AWAY=301
48
48
  # "<nick> :<away message>"
49
49
  RPL_UNAWAY=305
50
50
  # ":You are no longer marked as being away"
51
51
  RPL_NOWAWAY=306
52
52
  # ":You have been marked as being away"
53
- #
53
+ #
54
54
  # - These replies are used with the AWAY command (if
55
55
  # allowed). RPL_AWAY is sent to any client sending a
56
56
  # PRIVMSG to a client which is away. RPL_AWAY is only
57
57
  # sent by the server to which the client is connected.
58
58
  # Replies RPL_UNAWAY and RPL_NOWAWAY are sent when the
59
59
  # client removes and sets an AWAY message.
60
- #
60
+ #
61
61
  RPL_WHOISUSER=311
62
62
  # "<nick> <user> <host> * :<real name>"
63
63
  RPL_WHOISSERVER=312
@@ -70,7 +70,7 @@ module Irc
70
70
  # "<nick> :End of WHOIS list"
71
71
  RPL_WHOISCHANNELS=319
72
72
  # "<nick> :*( ( "@" / "+" ) <channel> " " )"
73
- #
73
+ #
74
74
  # - Replies 311 - 313, 317 - 319 are all replies
75
75
  # generated in response to a WHOIS message. Given that
76
76
  # there are enough parameters present, the answering
@@ -85,107 +85,107 @@ module Irc
85
85
  # has been granted permission to speak on a moderated
86
86
  # channel. The RPL_ENDOFWHOIS reply is used to mark
87
87
  # the end of processing a WHOIS message.
88
- #
88
+ #
89
89
  RPL_WHOWASUSER=314
90
90
  # "<nick> <user> <host> * :<real name>"
91
91
  RPL_ENDOFWHOWAS=369
92
92
  # "<nick> :End of WHOWAS"
93
- #
93
+ #
94
94
  # - When replying to a WHOWAS message, a server MUST use
95
95
  # the replies RPL_WHOWASUSER, RPL_WHOISSERVER or
96
96
  # ERR_WASNOSUCHNICK for each nickname in the presented
97
97
  # list. At the end of all reply batches, there MUST
98
98
  # be RPL_ENDOFWHOWAS (even if there was only one reply
99
99
  # and it was an error).
100
- #
100
+ #
101
101
  RPL_LISTSTART=321
102
102
  # Obsolete. Not used.
103
- #
103
+ #
104
104
  RPL_LIST=322
105
105
  # "<channel> <# visible> :<topic>"
106
106
  RPL_LISTEND=323
107
107
  # ":End of LIST"
108
- #
108
+ #
109
109
  # - Replies RPL_LIST, RPL_LISTEND mark the actual replies
110
110
  # with data and end of the server's response to a LIST
111
111
  # command. If there are no channels available to return,
112
112
  # only the end reply MUST be sent.
113
- #
113
+ #
114
114
  RPL_UNIQOPIS=325
115
115
  # "<channel> <nickname>"
116
- #
116
+ #
117
117
  RPL_CHANNELMODEIS=324
118
118
  # "<channel> <mode> <mode params>"
119
- #
119
+ #
120
120
  RPL_NOTOPIC=331
121
121
  # "<channel> :No topic is set"
122
122
  RPL_TOPIC=332
123
123
  # "<channel> :<topic>"
124
- #
124
+ #
125
125
  # - When sending a TOPIC message to determine the
126
126
  # channel topic, one of two replies is sent. If
127
127
  # the topic is set, RPL_TOPIC is sent back else
128
128
  # RPL_NOTOPIC.
129
- #
129
+ #
130
130
  RPL_TOPIC_INFO=333
131
131
  # <channel> <set by> <unixtime>
132
132
  RPL_INVITING=341
133
133
  # "<channel> <nick>"
134
- #
134
+ #
135
135
  # - Returned by the server to indicate that the
136
136
  # attempted INVITE message was successful and is
137
137
  # being passed onto the end client.
138
- #
138
+ #
139
139
  RPL_SUMMONING=342
140
140
  # "<user> :Summoning user to IRC"
141
- #
141
+ #
142
142
  # - Returned by a server answering a SUMMON message to
143
143
  # indicate that it is summoning that user.
144
- #
144
+ #
145
145
  RPL_INVITELIST=346
146
146
  # "<channel> <invitemask>"
147
147
  RPL_ENDOFINVITELIST=347
148
148
  # "<channel> :End of channel invite list"
149
- #
149
+ #
150
150
  # - When listing the 'invitations masks' for a given channel,
151
151
  # a server is required to send the list back using the
152
152
  # RPL_INVITELIST and RPL_ENDOFINVITELIST messages. A
153
153
  # separate RPL_INVITELIST is sent for each active mask.
154
154
  # After the masks have been listed (or if none present) a
155
155
  # RPL_ENDOFINVITELIST MUST be sent.
156
- #
156
+ #
157
157
  RPL_EXCEPTLIST=348
158
158
  # "<channel> <exceptionmask>"
159
159
  RPL_ENDOFEXCEPTLIST=349
160
160
  # "<channel> :End of channel exception list"
161
- #
161
+ #
162
162
  # - When listing the 'exception masks' for a given channel,
163
163
  # a server is required to send the list back using the
164
164
  # RPL_EXCEPTLIST and RPL_ENDOFEXCEPTLIST messages. A
165
165
  # separate RPL_EXCEPTLIST is sent for each active mask.
166
166
  # After the masks have been listed (or if none present)
167
167
  # a RPL_ENDOFEXCEPTLIST MUST be sent.
168
- #
168
+ #
169
169
  RPL_VERSION=351
170
170
  # "<version>.<debuglevel> <server> :<comments>"
171
- #
171
+ #
172
172
  # - Reply by the server showing its version details.
173
173
  # The <version> is the version of the software being
174
174
  # used (including any patchlevel revisions) and the
175
175
  # <debuglevel> is used to indicate if the server is
176
176
  # running in "debug mode".
177
- #
177
+ #
178
178
  # The "comments" field may contain any comments about
179
179
  # the version or further version details.
180
- #
180
+ #
181
181
  RPL_WHOREPLY=352
182
182
  # "<channel> <user> <host> <server> <nick>
183
183
  # ( "H" / "G" > ["*"] [ ( "@" / "+" ) ]
184
184
  # :<hopcount> <real name>"
185
- #
185
+ #
186
186
  RPL_ENDOFWHO=315
187
187
  # "<name> :End of WHO list"
188
- #
188
+ #
189
189
  # - The RPL_WHOREPLY and RPL_ENDOFWHO pair are used
190
190
  # to answer a WHO message. The RPL_WHOREPLY is only
191
191
  # sent if there is an appropriate match to the WHO
@@ -193,16 +193,16 @@ module Irc
193
193
  # with a WHO message, a RPL_ENDOFWHO MUST be sent
194
194
  # after processing each list item with <name> being
195
195
  # the item.
196
- #
196
+ #
197
197
  RPL_NAMREPLY=353
198
198
  # "( "=" / "*" / "@" ) <channel>
199
199
  # :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )
200
200
  # - "@" is used for secret channels, "*" for private
201
201
  # channels, and "=" for others (public channels).
202
- #
202
+ #
203
203
  RPL_ENDOFNAMES=366
204
204
  # "<channel> :End of NAMES list"
205
- #
205
+ #
206
206
  # - To reply to a NAMES message, a reply pair consisting
207
207
  # of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the
208
208
  # server back to the client. If there is no channel
@@ -212,81 +212,81 @@ module Irc
212
212
  # channels and contents are sent back in a series of
213
213
  # RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark
214
214
  # the end.
215
- #
215
+ #
216
216
  RPL_LINKS=364
217
217
  # "<mask> <server> :<hopcount> <server info>"
218
218
  RPL_ENDOFLINKS=365
219
219
  # "<mask> :End of LINKS list"
220
- #
220
+ #
221
221
  # - In replying to the LINKS message, a server MUST send
222
222
  # replies back using the RPL_LINKS numeric and mark the
223
223
  # end of the list using an RPL_ENDOFLINKS reply.
224
- #
224
+ #
225
225
  RPL_BANLIST=367
226
226
  # "<channel> <banmask>"
227
227
  RPL_ENDOFBANLIST=368
228
228
  # "<channel> :End of channel ban list"
229
- #
229
+ #
230
230
  # - When listing the active 'bans' for a given channel,
231
231
  # a server is required to send the list back using the
232
232
  # RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate
233
233
  # RPL_BANLIST is sent for each active banmask. After the
234
234
  # banmasks have been listed (or if none present) a
235
235
  # RPL_ENDOFBANLIST MUST be sent.
236
- #
236
+ #
237
237
  RPL_INFO=371
238
238
  # ":<string>"
239
239
  RPL_ENDOFINFO=374
240
240
  # ":End of INFO list"
241
- #
241
+ #
242
242
  # - A server responding to an INFO message is required to
243
243
  # send all its 'info' in a series of RPL_INFO messages
244
244
  # with a RPL_ENDOFINFO reply to indicate the end of the
245
245
  # replies.
246
- #
246
+ #
247
247
  RPL_MOTDSTART=375
248
248
  # ":- <server> Message of the day - "
249
249
  RPL_MOTD=372
250
250
  # ":- <text>"
251
251
  RPL_ENDOFMOTD=376
252
252
  # ":End of MOTD command"
253
- #
253
+ #
254
254
  # - When responding to the MOTD message and the MOTD file
255
255
  # is found, the file is displayed line by line, with
256
256
  # each line no longer than 80 characters, using
257
257
  # RPL_MOTD format replies. These MUST be surrounded
258
258
  # by a RPL_MOTDSTART (before the RPL_MOTDs) and an
259
259
  # RPL_ENDOFMOTD (after).
260
- #
260
+ #
261
261
  RPL_YOUREOPER=381
262
262
  # ":You are now an IRC operator"
263
- #
263
+ #
264
264
  # - RPL_YOUREOPER is sent back to a client which has
265
265
  # just successfully issued an OPER message and gained
266
266
  # operator status.
267
- #
267
+ #
268
268
  RPL_REHASHING=382
269
269
  # "<config file> :Rehashing"
270
- #
270
+ #
271
271
  # - If the REHASH option is used and an operator sends
272
272
  # a REHASH message, an RPL_REHASHING is sent back to
273
273
  # the operator.
274
- #
274
+ #
275
275
  RPL_YOURESERVICE=383
276
276
  # "You are service <servicename>"
277
- #
277
+ #
278
278
  # - Sent by the server to a service upon successful
279
279
  # registration.
280
- #
280
+ #
281
281
  RPL_TIME=391
282
282
  # "<server> :<string showing server's local time>"
283
- #
283
+ #
284
284
  # - When replying to the TIME message, a server MUST send
285
285
  # the reply using the RPL_TIME format above. The string
286
286
  # showing the time need only contain the correct day and
287
287
  # time there. There is no further requirement for the
288
288
  # time string.
289
- #
289
+ #
290
290
  RPL_USERSSTART=392
291
291
  # ":UserID Terminal Host"
292
292
  RPL_USERS=393
@@ -295,14 +295,14 @@ module Irc
295
295
  # ":End of users"
296
296
  RPL_NOUSERS=395
297
297
  # ":Nobody logged in"
298
- #
298
+ #
299
299
  # - If the USERS message is handled by a server, the
300
300
  # replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and
301
301
  # RPL_NOUSERS are used. RPL_USERSSTART MUST be sent
302
302
  # first, following by either a sequence of RPL_USERS
303
303
  # or a single RPL_NOUSER. Following this is
304
304
  # RPL_ENDOFUSERS.
305
- #
305
+ #
306
306
  RPL_TRACELINK=200
307
307
  # "Link <version & debug level> <destination>
308
308
  # <next server> V<protocol version>
@@ -333,7 +333,7 @@ module Irc
333
333
  # "File <logfile> <debug level>"
334
334
  RPL_TRACEEND=262
335
335
  # "<server name> <version & debug level> :End of TRACE"
336
- #
336
+ #
337
337
  # - The RPL_TRACE* are all returned by the server in
338
338
  # response to the TRACE message. How many are
339
339
  # returned is dependent on the TRACE message and
@@ -350,12 +350,12 @@ module Irc
350
350
  # response to a TRACE command traversing the IRC
351
351
  # network should reflect the actual connectivity of
352
352
  # the servers themselves along that path.
353
- #
353
+ #
354
354
  # RPL_TRACENEWTYPE is to be used for any connection
355
355
  # which does not fit in the other categories but is
356
356
  # being displayed anyway.
357
357
  # RPL_TRACEEND is sent to indicate the end of the list.
358
- #
358
+ #
359
359
  RPL_LOCALUSERS=265
360
360
  # ":Current local users: 3 Max: 4"
361
361
  RPL_GLOBALUSERS=266
@@ -367,7 +367,7 @@ module Irc
367
367
  # "<linkname> <sendq> <sent messages>
368
368
  # <sent Kbytes> <received messages>
369
369
  # <received Kbytes> <time open>"
370
- #
370
+ #
371
371
  # - reports statistics on a connection. <linkname>
372
372
  # identifies the particular connection, <sendq> is
373
373
  # the amount of data that is queued and waiting to be
@@ -378,45 +378,45 @@ module Irc
378
378
  # Kbytes> for received data, respectively. <time
379
379
  # open> indicates how long ago the connection was
380
380
  # opened, in seconds.
381
- #
381
+ #
382
382
  RPL_STATSCOMMANDS=212
383
383
  # "<command> <count> <byte count> <remote count>"
384
- #
384
+ #
385
385
  # - reports statistics on commands usage.
386
- #
386
+ #
387
387
  RPL_ENDOFSTATS=219
388
388
  # "<stats letter> :End of STATS report"
389
- #
389
+ #
390
390
  RPL_STATSUPTIME=242
391
391
  # ":Server Up %d days %d:%02d:%02d"
392
- #
392
+ #
393
393
  # - reports the server uptime.
394
- #
394
+ #
395
395
  RPL_STATSOLINE=243
396
396
  # "O <hostmask> * <name>"
397
- #
397
+ #
398
398
  # - reports the allowed hosts from where user may become IRC
399
399
  # operators.
400
- #
400
+ #
401
401
  RPL_UMODEIS=221
402
402
  # "<user mode string>"
403
- #
403
+ #
404
404
  # - To answer a query about a client's own mode,
405
405
  # RPL_UMODEIS is sent back.
406
- #
406
+ #
407
407
  RPL_SERVLIST=234
408
408
  # "<name> <server> <mask> <type> <hopcount> <info>"
409
- #
409
+ #
410
410
  RPL_SERVLISTEND=235
411
411
  # "<mask> <type> :End of service listing"
412
- #
412
+ #
413
413
  # - When listing services in reply to a SERVLIST message,
414
414
  # a server is required to send the list back using the
415
415
  # RPL_SERVLIST and RPL_SERVLISTEND messages. A separate
416
416
  # RPL_SERVLIST is sent for each service. After the
417
417
  # services have been listed (or if none present) a
418
418
  # RPL_SERVLISTEND MUST be sent.
419
- #
419
+ #
420
420
  RPL_LUSERCLIENT=251
421
421
  # ":There are <integer> users and <integer>
422
422
  # services on <integer> servers"
@@ -429,7 +429,7 @@ module Irc
429
429
  RPL_LUSERME=255
430
430
  # ":I have <integer> clients and <integer>
431
431
  # servers"
432
- #
432
+ #
433
433
  # - In processing an LUSERS message, the server
434
434
  # sends a set of replies from RPL_LUSERCLIENT,
435
435
  # RPL_LUSEROP, RPL_USERUNKNOWN,
@@ -438,7 +438,7 @@ module Irc
438
438
  # RPL_LUSERCLIENT and RPL_LUSERME. The other
439
439
  # replies are only sent back if a non-zero count
440
440
  # is found for them.
441
- #
441
+ #
442
442
  RPL_ADMINME=256
443
443
  # "<server> :Administrative info"
444
444
  RPL_ADMINLOC1=257
@@ -447,7 +447,7 @@ module Irc
447
447
  # ":<admin info>"
448
448
  RPL_ADMINEMAIL=259
449
449
  # ":<admin info>"
450
- #
450
+ #
451
451
  # - When replying to an ADMIN message, a server
452
452
  # is expected to use replies RPL_ADMINME
453
453
  # through to RPL_ADMINEMAIL and provide a text
@@ -458,82 +458,82 @@ module Irc
458
458
  # and finally the administrative contact for the
459
459
  # server (an email address here is REQUIRED)
460
460
  # in RPL_ADMINEMAIL.
461
- #
461
+ #
462
462
  RPL_TRYAGAIN=263
463
463
  # "<command> :Please wait a while and try again."
464
- #
464
+ #
465
465
  # - When a server drops a command without processing it,
466
466
  # it MUST use the reply RPL_TRYAGAIN to inform the
467
467
  # originating client.
468
- #
468
+ #
469
469
  # 5.2 Error Replies
470
- #
470
+ #
471
471
  # Error replies are found in the range from 400 to 599.
472
- #
472
+ #
473
473
  ERR_NOSUCHNICK=401
474
474
  # "<nickname> :No such nick/channel"
475
- #
475
+ #
476
476
  # - Used to indicate the nickname parameter supplied to a
477
477
  # command is currently unused.
478
- #
478
+ #
479
479
  ERR_NOSUCHSERVER=402
480
480
  # "<server name> :No such server"
481
- #
481
+ #
482
482
  # - Used to indicate the server name given currently
483
483
  # does not exist.
484
- #
484
+ #
485
485
  ERR_NOSUCHCHANNEL=403
486
486
  # "<channel name> :No such channel"
487
- #
487
+ #
488
488
  # - Used to indicate the given channel name is invalid.
489
- #
489
+ #
490
490
  ERR_CANNOTSENDTOCHAN=404
491
491
  # "<channel name> :Cannot send to channel"
492
- #
492
+ #
493
493
  # - Sent to a user who is either (a) not on a channel
494
494
  # which is mode +n or (b) not a chanop (or mode +v) on
495
495
  # a channel which has mode +m set or where the user is
496
496
  # banned and is trying to send a PRIVMSG message to
497
497
  # that channel.
498
- #
498
+ #
499
499
  ERR_TOOMANYCHANNELS=405
500
500
  # "<channel name> :You have joined too many channels"
501
- #
501
+ #
502
502
  # - Sent to a user when they have joined the maximum
503
503
  # number of allowed channels and they try to join
504
504
  # another channel.
505
- #
505
+ #
506
506
  ERR_WASNOSUCHNICK=406
507
507
  # "<nickname> :There was no such nickname"
508
- #
508
+ #
509
509
  # - Returned by WHOWAS to indicate there is no history
510
510
  # information for that nickname.
511
- #
511
+ #
512
512
  ERR_TOOMANYTARGETS=407
513
513
  # "<target> :<error code> recipients. <abort message>"
514
- #
514
+ #
515
515
  # - Returned to a client which is attempting to send a
516
516
  # PRIVMSG/NOTICE using the user@host destination format
517
517
  # and for a user@host which has several occurrences.
518
- #
518
+ #
519
519
  # - Returned to a client which trying to send a
520
520
  # PRIVMSG/NOTICE to too many recipients.
521
- #
521
+ #
522
522
  # - Returned to a client which is attempting to JOIN a safe
523
523
  # channel using the shortname when there are more than one
524
524
  # such channel.
525
- #
525
+ #
526
526
  ERR_NOSUCHSERVICE=408
527
527
  # "<service name> :No such service"
528
- #
528
+ #
529
529
  # - Returned to a client which is attempting to send a SQUERY
530
530
  # to a service which does not exist.
531
- #
531
+ #
532
532
  ERR_NOORIGIN=409
533
533
  # ":No origin specified"
534
- #
534
+ #
535
535
  # - PING or PONG message missing the originator parameter.
536
- #
536
+ #
537
537
  ERR_NORECIPIENT=411
538
538
  # ":No recipient given (<command>)"
539
539
  ERR_NOTEXTTOSEND=412
@@ -544,161 +544,161 @@ module Irc
544
544
  # "<mask> :Wildcard in toplevel domain"
545
545
  ERR_BADMASK=415
546
546
  # "<mask> :Bad Server/host mask"
547
- #
547
+ #
548
548
  # - 412 - 415 are returned by PRIVMSG to indicate that
549
549
  # the message wasn't delivered for some reason.
550
550
  # ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that
551
551
  # are returned when an invalid use of
552
552
  # "PRIVMSG $<server>" or "PRIVMSG #<host>" is attempted.
553
- #
553
+ #
554
554
  ERR_UNKNOWNCOMMAND=421
555
555
  # "<command> :Unknown command"
556
- #
556
+ #
557
557
  # - Returned to a registered client to indicate that the
558
558
  # command sent is unknown by the server.
559
- #
559
+ #
560
560
  ERR_NOMOTD=422
561
561
  # ":MOTD File is missing"
562
- #
562
+ #
563
563
  # - Server's MOTD file could not be opened by the server.
564
- #
564
+ #
565
565
  ERR_NOADMININFO=423
566
566
  # "<server> :No administrative info available"
567
- #
567
+ #
568
568
  # - Returned by a server in response to an ADMIN message
569
569
  # when there is an error in finding the appropriate
570
570
  # information.
571
- #
571
+ #
572
572
  ERR_FILEERROR=424
573
573
  # ":File error doing <file op> on <file>"
574
- #
574
+ #
575
575
  # - Generic error message used to report a failed file
576
576
  # operation during the processing of a message.
577
- #
577
+ #
578
578
  ERR_NONICKNAMEGIVEN=431
579
579
  # ":No nickname given"
580
- #
580
+ #
581
581
  # - Returned when a nickname parameter expected for a
582
582
  # command and isn't found.
583
- #
583
+ #
584
584
  ERR_ERRONEUSNICKNAME=432
585
585
  # "<nick> :Erroneous nickname"
586
- #
586
+ #
587
587
  # - Returned after receiving a NICK message which contains
588
588
  # characters which do not fall in the defined set. See
589
589
  # section 2.3.1 for details on valid nicknames.
590
- #
590
+ #
591
591
  ERR_NICKNAMEINUSE=433
592
592
  # "<nick> :Nickname is already in use"
593
- #
593
+ #
594
594
  # - Returned when a NICK message is processed that results
595
595
  # in an attempt to change to a currently existing
596
596
  # nickname.
597
- #
597
+ #
598
598
  ERR_NICKCOLLISION=436
599
599
  # "<nick> :Nickname collision KILL from <user>@<host>"
600
- #
600
+ #
601
601
  # - Returned by a server to a client when it detects a
602
602
  # nickname collision (registered of a NICK that
603
603
  # already exists by another server).
604
- #
604
+ #
605
605
  ERR_UNAVAILRESOURCE=437
606
606
  # "<nick/channel> :Nick/channel is temporarily unavailable"
607
- #
607
+ #
608
608
  # - Returned by a server to a user trying to join a channel
609
609
  # currently blocked by the channel delay mechanism.
610
- #
610
+ #
611
611
  # - Returned by a server to a user trying to change nickname
612
612
  # when the desired nickname is blocked by the nick delay
613
613
  # mechanism.
614
- #
614
+ #
615
615
  ERR_USERNOTINCHANNEL=441
616
616
  # "<nick> <channel> :They aren't on that channel"
617
- #
617
+ #
618
618
  # - Returned by the server to indicate that the target
619
619
  # user of the command is not on the given channel.
620
- #
620
+ #
621
621
  ERR_NOTONCHANNEL=442
622
622
  # "<channel> :You're not on that channel"
623
- #
623
+ #
624
624
  # - Returned by the server whenever a client tries to
625
625
  # perform a channel affecting command for which the
626
626
  # client isn't a member.
627
- #
627
+ #
628
628
  ERR_USERONCHANNEL=443
629
629
  # "<user> <channel> :is already on channel"
630
- #
630
+ #
631
631
  # - Returned when a client tries to invite a user to a
632
632
  # channel they are already on.
633
- #
633
+ #
634
634
  ERR_NOLOGIN=444
635
635
  # "<user> :User not logged in"
636
- #
636
+ #
637
637
  # - Returned by the summon after a SUMMON command for a
638
638
  # user was unable to be performed since they were not
639
639
  # logged in.
640
- #
641
- #
640
+ #
641
+ #
642
642
  ERR_SUMMONDISABLED=445
643
643
  # ":SUMMON has been disabled"
644
- #
644
+ #
645
645
  # - Returned as a response to the SUMMON command. MUST be
646
646
  # returned by any server which doesn't implement it.
647
- #
647
+ #
648
648
  ERR_USERSDISABLED=446
649
649
  # ":USERS has been disabled"
650
- #
650
+ #
651
651
  # - Returned as a response to the USERS command. MUST be
652
652
  # returned by any server which does not implement it.
653
- #
653
+ #
654
654
  ERR_NOTREGISTERED=451
655
655
  # ":You have not registered"
656
- #
656
+ #
657
657
  # - Returned by the server to indicate that the client
658
658
  # MUST be registered before the server will allow it
659
659
  # to be parsed in detail.
660
- #
660
+ #
661
661
  ERR_NEEDMOREPARAMS=461
662
662
  # "<command> :Not enough parameters"
663
- #
663
+ #
664
664
  # - Returned by the server by numerous commands to
665
665
  # indicate to the client that it didn't supply enough
666
666
  # parameters.
667
- #
667
+ #
668
668
  ERR_ALREADYREGISTRED=462
669
669
  # ":Unauthorized command (already registered)"
670
- #
670
+ #
671
671
  # - Returned by the server to any link which tries to
672
672
  # change part of the registered details (such as
673
673
  # password or user details from second USER message).
674
- #
674
+ #
675
675
  ERR_NOPERMFORHOST=463
676
676
  # ":Your host isn't among the privileged"
677
- #
677
+ #
678
678
  # - Returned to a client which attempts to register with
679
679
  # a server which does not been setup to allow
680
680
  # connections from the host the attempted connection
681
681
  # is tried.
682
- #
682
+ #
683
683
  ERR_PASSWDMISMATCH=464
684
684
  # ":Password incorrect"
685
- #
685
+ #
686
686
  # - Returned to indicate a failed attempt at registering
687
687
  # a connection for which a password was required and
688
688
  # was either not given or incorrect.
689
- #
689
+ #
690
690
  ERR_YOUREBANNEDCREEP=465
691
691
  # ":You are banned from this server"
692
- #
692
+ #
693
693
  # - Returned after an attempt to connect and register
694
694
  # yourself with a server which has been setup to
695
695
  # explicitly deny connections to you.
696
- #
696
+ #
697
697
  ERR_YOUWILLBEBANNED=466
698
- #
698
+ #
699
699
  # - Sent by a server to a user to inform that access to the
700
700
  # server will soon be denied.
701
- #
701
+ #
702
702
  ERR_KEYSET=467
703
703
  # "<channel> :Channel key already set"
704
704
  ERR_CHANNELISFULL=471
@@ -717,99 +717,100 @@ module Irc
717
717
  # "<channel> :Channel doesn't support modes"
718
718
  ERR_BANLISTFULL=478
719
719
  # "<channel> <char> :Channel list is full"
720
- #
720
+ #
721
721
  ERR_NOPRIVILEGES=481
722
722
  # ":Permission Denied- You're not an IRC operator"
723
- #
723
+ #
724
724
  # - Any command requiring operator privileges to operate
725
725
  # MUST return this error to indicate the attempt was
726
726
  # unsuccessful.
727
- #
727
+ #
728
728
  ERR_CHANOPRIVSNEEDED=482
729
729
  # "<channel> :You're not channel operator"
730
- #
730
+ #
731
731
  # - Any command requiring 'chanop' privileges (such as
732
732
  # MODE messages) MUST return this error if the client
733
733
  # making the attempt is not a chanop on the specified
734
734
  # channel.
735
- #
736
- #
735
+ #
736
+ #
737
737
  ERR_CANTKILLSERVER=483
738
738
  # ":You can't kill a server!"
739
- #
739
+ #
740
740
  # - Any attempts to use the KILL command on a server
741
741
  # are to be refused and this error returned directly
742
742
  # to the client.
743
- #
743
+ #
744
744
  ERR_RESTRICTED=484
745
745
  # ":Your connection is restricted!"
746
- #
746
+ #
747
747
  # - Sent by the server to a user upon connection to indicate
748
748
  # the restricted nature of the connection (user mode "+r").
749
- #
749
+ #
750
750
  ERR_UNIQOPPRIVSNEEDED=485
751
751
  # ":You're not the original channel operator"
752
- #
752
+ #
753
753
  # - Any MODE requiring "channel creator" privileges MUST
754
754
  # return this error if the client making the attempt is not
755
755
  # a chanop on the specified channel.
756
- #
756
+ #
757
757
  ERR_NOOPERHOST=491
758
758
  # ":No O-lines for your host"
759
- #
759
+ #
760
760
  # - If a client sends an OPER message and the server has
761
761
  # not been configured to allow connections from the
762
762
  # client's host as an operator, this error MUST be
763
763
  # returned.
764
- #
764
+ #
765
765
  ERR_UMODEUNKNOWNFLAG=501
766
766
  # ":Unknown MODE flag"
767
- #
767
+ #
768
768
  # - Returned by the server to indicate that a MODE
769
769
  # message was sent with a nickname parameter and that
770
770
  # the a mode flag sent was not recognized.
771
- #
771
+ #
772
772
  ERR_USERSDONTMATCH=502
773
773
  # ":Cannot change mode for other users"
774
- #
774
+ #
775
775
  # - Error sent to any user trying to view or change the
776
776
  # user mode for a user other than themselves.
777
- #
777
+ #
778
778
  # 5.3 Reserved numerics
779
- #
779
+ #
780
780
  # These numerics are not described above since they fall into one of
781
781
  # the following categories:
782
- #
782
+ #
783
783
  # 1. no longer in use;
784
- #
784
+ #
785
785
  # 2. reserved for future planned use;
786
- #
786
+ #
787
787
  # 3. in current use but are part of a non-generic 'feature' of
788
788
  # the current IRC server.
789
- RPL_SERVICEINFO=231
789
+ RPL_SERVICEINFO=231
790
790
  RPL_ENDOFSERVICES=232
791
791
  RPL_SERVICE=233
792
- RPL_NONE=300
792
+ RPL_NONE=300
793
793
  RPL_WHOISCHANOP=316
794
- RPL_KILLDONE=361
794
+ RPL_KILLDONE=361
795
795
  RPL_CLOSING=362
796
- RPL_CLOSEEND=363
796
+ RPL_CLOSEEND=363
797
797
  RPL_INFOSTART=373
798
798
  RPL_MYPORTIS=384
799
- RPL_STATSCLINE=213
799
+ RPL_STATSCLINE=213
800
800
  RPL_STATSNLINE=214
801
- RPL_STATSILINE=215
801
+ RPL_STATSILINE=215
802
802
  RPL_STATSKLINE=216
803
803
  RPL_STATSQLINE=217
804
804
  RPL_STATSYLINE=218
805
- RPL_STATSVLINE=240
805
+ RPL_STATSVLINE=240
806
806
  RPL_STATSLLINE=241
807
- RPL_STATSHLINE=244
807
+ RPL_STATSHLINE=244
808
808
  RPL_STATSSLINE=244
809
- RPL_STATSPING=246
809
+ RPL_STATSPING=246
810
810
  RPL_STATSBLINE=247
811
811
  ERR_NOSERVICEHOST=492
812
-
812
+ RPL_DATASTR=290
813
+
813
814
  # implements RFC 2812 and prior IRC RFCs.
814
815
  # clients register handler proc{}s for different server events and IrcClient
815
816
  # handles dispatch
@@ -819,7 +820,7 @@ module Irc
819
820
  @handlers = Hash.new
820
821
  @users = Array.new
821
822
  end
822
-
823
+
823
824
  # key:: server event to handle
824
825
  # value:: proc object called when event occurs
825
826
  # set a handler for a server event
@@ -854,26 +855,26 @@ module Irc
854
855
  def []=(key, value)
855
856
  @handlers[key] = value
856
857
  end
857
-
858
+
858
859
  # key:: event name
859
860
  # remove a handler for a server event
860
861
  def deletehandler(key)
861
862
  @handlers.delete(key)
862
863
  end
863
-
864
+
864
865
  # takes a server string, checks for PING, PRIVMSG, NOTIFY, etc, and parses
865
866
  # numeric server replies, calling the appropriate handler for each, and
866
867
  # sending it a hash containing the data from the server
867
868
  def process(serverstring)
868
869
  data = Hash.new
869
870
  data[:serverstring] = serverstring
870
-
871
+
871
872
  unless serverstring =~ /^(:(\S+)\s)?(\S+)(\s(.*))?/
872
- raise "Unparseable Server Message!!!: #{serverstring}"
873
+ raise "Unparseable Server Message!!!: #{serverstring}"
873
874
  end
874
-
875
+
875
876
  prefix, command, params = $2, $3, $5
876
-
877
+
877
878
  if prefix != nil
878
879
  data[:source] = prefix
879
880
  if prefix =~ /^(\S+)!(\S+)$/
@@ -885,11 +886,14 @@ module Irc
885
886
  # split parameters in an array
886
887
  argv = []
887
888
  params.scan(/(?!:)(\S+)|:(.*)/) { argv << ($1 || $2) } if params
888
-
889
+
889
890
  case command
890
891
  when 'PING'
891
892
  data[:pingid] = argv[0]
892
893
  handle(:ping, data)
894
+ when 'PONG'
895
+ data[:pingid] = argv[0]
896
+ handle(:pong, data)
893
897
  when /^(\d+)$/ # numeric server message
894
898
  num=command.to_i
895
899
  case num
@@ -952,10 +956,14 @@ module Irc
952
956
  # TOPICLEN=450 KICKLEN=450 CHANNELLEN=30 KEYLEN=23 CHANTYPES=#
953
957
  # PREFIX=(ov)@+ CASEMAPPING=ascii CAPAB IRCD=dancer :are available
954
958
  # on this server"
955
- #
956
- argv.each {|a|
959
+ #
960
+ argv[0,argv.length-1].each {|a|
957
961
  if a =~ /^(.*)=(.*)$/
958
962
  data[$1.downcase.to_sym] = $2
963
+ debug "server's #{$1.downcase.to_sym} is #{$2}"
964
+ else
965
+ data[a.downcase.to_sym] = true
966
+ debug "server supports #{a.downcase.to_sym}"
959
967
  end
960
968
  }
961
969
  handle(:isupport, data)
@@ -1027,6 +1035,9 @@ module Irc
1027
1035
  when RPL_ENDOFMOTD
1028
1036
  data[:motd] = @motd
1029
1037
  handle(:motd, data)
1038
+ when RPL_DATASTR
1039
+ data[:text] = argv[1]
1040
+ handle(:datastr, data)
1030
1041
  else
1031
1042
  handle(:unknown, data)
1032
1043
  end
@@ -1038,9 +1049,9 @@ module Irc
1038
1049
  data[:target] = argv[0]
1039
1050
  data[:message] = argv[1]
1040
1051
  handle(:privmsg, data)
1041
-
1052
+
1042
1053
  # Now we split it
1043
- if(data[:target] =~ /^(#|&).*/)
1054
+ if(data[:target] =~ /^[#&!+].*/)
1044
1055
  handle(:public, data)
1045
1056
  else
1046
1057
  handle(:msg, data)
@@ -1091,7 +1102,7 @@ module Irc
1091
1102
  end
1092
1103
 
1093
1104
  private
1094
-
1105
+
1095
1106
  # key:: server event name
1096
1107
  # data:: hash containing data about the event, passed to the proc
1097
1108
  # call client's proc for an event, if they set one as a handler