cinch 1.0.2 → 1.1.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.
- data/README.md +25 -44
- data/examples/basic/autovoice.rb +1 -1
- data/examples/basic/join_part.rb +0 -4
- data/examples/plugins/autovoice.rb +2 -5
- data/examples/plugins/google.rb +1 -2
- data/examples/plugins/hooks.rb +36 -0
- data/examples/plugins/lambdas.rb +35 -0
- data/examples/plugins/last_nick.rb +24 -0
- data/examples/plugins/multiple_matches.rb +1 -10
- data/examples/plugins/own_events.rb +37 -0
- data/examples/plugins/timer.rb +22 -0
- data/examples/plugins/url_shorten.rb +1 -1
- data/lib/cinch.rb +50 -1
- data/lib/cinch/ban.rb +5 -2
- data/lib/cinch/bot.rb +360 -193
- data/lib/cinch/cache_manager.rb +15 -0
- data/lib/cinch/callback.rb +6 -0
- data/lib/cinch/channel.rb +150 -96
- data/lib/cinch/channel_manager.rb +26 -0
- data/lib/cinch/constants.rb +6 -4
- data/lib/cinch/exceptions.rb +9 -0
- data/lib/cinch/irc.rb +197 -82
- data/lib/cinch/logger/formatted_logger.rb +8 -8
- data/lib/cinch/logger/zcbot_logger.rb +37 -0
- data/lib/cinch/mask.rb +17 -3
- data/lib/cinch/message.rb +14 -7
- data/lib/cinch/message_queue.rb +8 -4
- data/lib/cinch/mode_parser.rb +56 -0
- data/lib/cinch/pattern.rb +45 -0
- data/lib/cinch/plugin.rb +129 -34
- data/lib/cinch/rubyext/string.rb +4 -4
- data/lib/cinch/syncable.rb +8 -0
- data/lib/cinch/user.rb +68 -13
- data/lib/cinch/user_manager.rb +60 -0
- metadata +17 -35
- data/Rakefile +0 -66
- data/lib/cinch/PLANNED +0 -4
- data/spec/bot_spec.rb +0 -5
- data/spec/channel_spec.rb +0 -5
- data/spec/cinch_spec.rb +0 -5
- data/spec/irc_spec.rb +0 -5
- data/spec/message_spec.rb +0 -5
- data/spec/plugin_spec.rb +0 -5
- data/spec/spec.opts +0 -2
- data/spec/spec_helper.rb +0 -8
- data/spec/user_spec.rb +0 -5
data/lib/cinch/irc.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
require "timeout"
|
2
|
+
require "net/protocol"
|
3
|
+
|
1
4
|
module Cinch
|
2
5
|
class IRC
|
3
6
|
# @return [ISupport]
|
4
7
|
attr_reader :isupport
|
5
|
-
def initialize(bot
|
6
|
-
@bot
|
8
|
+
def initialize(bot)
|
9
|
+
@bot = bot
|
7
10
|
@isupport = ISupport.new
|
8
11
|
end
|
9
12
|
|
@@ -16,15 +19,39 @@ module Cinch
|
|
16
19
|
@whois_updates = Hash.new {|h, k| h[k] = {}}
|
17
20
|
@in_lists = Set.new
|
18
21
|
|
19
|
-
tcp_socket =
|
22
|
+
tcp_socket = nil
|
23
|
+
begin
|
24
|
+
Timeout::timeout(@bot.config.timeouts.connect) do
|
25
|
+
tcp_socket = TCPSocket.new(@bot.config.server, @bot.config.port, @bot.config.local_host)
|
26
|
+
end
|
27
|
+
rescue Timeout::Error
|
28
|
+
@bot.logger.debug("Timed out while connecting")
|
29
|
+
return
|
30
|
+
rescue => e
|
31
|
+
@bot.logger.log_exception(e)
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
35
|
+
if @bot.config.ssl == true || @bot.config.ssl == false
|
36
|
+
@bot.logger.debug "Deprecation warning: Beginning from version 1.1.0, @config.ssl should be a set of options, not a boolean value!"
|
37
|
+
end
|
20
38
|
|
21
|
-
if @config.ssl
|
39
|
+
if @bot.config.ssl == true || (@bot.config.ssl.is_a?(OpenStruct) && @bot.config.ssl.use)
|
22
40
|
require 'openssl'
|
23
41
|
|
24
42
|
ssl_context = OpenSSL::SSL::SSLContext.new
|
25
|
-
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
26
43
|
|
27
|
-
@bot.
|
44
|
+
if @bot.config.ssl.is_a?(OpenStruct)
|
45
|
+
if @bot.config.ssl.client_cert
|
46
|
+
ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(@bot.config.ssl.client_cert))
|
47
|
+
ssl_context.key = OpenSSL::PKey::RSA.new(File.read(@bot.config.ssl.client_cert))
|
48
|
+
end
|
49
|
+
ssl_context.ca_path = @bot.config.ssl.ca_path
|
50
|
+
ssl_context.verify_mode = @bot.config.ssl.verify ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
51
|
+
else
|
52
|
+
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
53
|
+
end
|
54
|
+
@bot.logger.debug "Using SSL with #{@bot.config.server}:#{@bot.config.port}"
|
28
55
|
|
29
56
|
@socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ssl_context)
|
30
57
|
@socket.sync = true
|
@@ -33,32 +60,56 @@ module Cinch
|
|
33
60
|
@socket = tcp_socket
|
34
61
|
end
|
35
62
|
|
63
|
+
@socket = Net::BufferedIO.new(@socket)
|
64
|
+
@socket.read_timeout = @bot.config.timeouts.read
|
65
|
+
|
36
66
|
@queue = MessageQueue.new(@socket, @bot)
|
37
|
-
message "PASS #{@config.password}" if @config.password
|
38
|
-
message "NICK #{@
|
39
|
-
message "USER #{@config.nick} 0 * :#{@config.realname}"
|
67
|
+
message "PASS #{@bot.config.password}" if @bot.config.password
|
68
|
+
message "NICK #{@bot.generate_next_nick}"
|
69
|
+
message "USER #{@bot.config.nick} 0 * :#{@bot.config.realname}"
|
40
70
|
|
41
|
-
Thread.new do
|
71
|
+
reading_thread = Thread.new do
|
42
72
|
begin
|
43
|
-
while line = @socket.
|
73
|
+
while line = @socket.readline
|
44
74
|
begin
|
45
|
-
line.
|
75
|
+
line = Cinch.encode_incoming(line, @bot.config.encoding)
|
46
76
|
parse line
|
47
77
|
rescue => e
|
48
78
|
@bot.logger.log_exception(e)
|
49
79
|
end
|
50
80
|
end
|
81
|
+
rescue Timeout::Error
|
82
|
+
@bot.logger.debug "Connection timed out."
|
83
|
+
rescue EOFError
|
84
|
+
@bot.logger.debug "Lost connection."
|
51
85
|
rescue => e
|
52
86
|
@bot.logger.log_exception(e)
|
53
87
|
end
|
54
88
|
|
89
|
+
@socket.close
|
55
90
|
@bot.dispatch(:disconnect)
|
91
|
+
@bot.handler_threads.each { |t| t.join(10); t.kill }
|
56
92
|
end
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
93
|
+
|
94
|
+
@sending_thread = Thread.new do
|
95
|
+
begin
|
96
|
+
@queue.process!
|
97
|
+
rescue => e
|
98
|
+
@bot.logger.log_exception(e)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
ping_thread = Thread.new do
|
103
|
+
while true
|
104
|
+
sleep @bot.config.ping_interval
|
105
|
+
message("PING 0") # PING requires a single argument. In our
|
106
|
+
# case the value doesn't matter though.
|
107
|
+
end
|
61
108
|
end
|
109
|
+
|
110
|
+
reading_thread.join
|
111
|
+
@sending_thread.kill
|
112
|
+
ping_thread.kill
|
62
113
|
end
|
63
114
|
|
64
115
|
# @api private
|
@@ -66,40 +117,41 @@ module Cinch
|
|
66
117
|
def parse(input)
|
67
118
|
@bot.logger.log(input, :incoming) if @bot.config.verbose
|
68
119
|
msg = Message.new(input, @bot)
|
69
|
-
events = []
|
120
|
+
events = [[:catchall]]
|
70
121
|
|
71
122
|
if ("001".."004").include? msg.command
|
72
123
|
@registration << msg.command
|
73
124
|
if registered?
|
74
|
-
events << :connect
|
125
|
+
events << [:connect]
|
126
|
+
@bot.last_connection_was_successful = true
|
75
127
|
end
|
76
128
|
elsif ["PRIVMSG", "NOTICE"].include?(msg.command)
|
77
|
-
events << :ctcp if msg.ctcp?
|
129
|
+
events << [:ctcp] if msg.ctcp?
|
78
130
|
if msg.channel?
|
79
|
-
events << :channel
|
131
|
+
events << [:channel]
|
80
132
|
else
|
81
|
-
events << :private
|
133
|
+
events << [:private]
|
82
134
|
end
|
83
135
|
|
84
136
|
if msg.command == "PRIVMSG"
|
85
|
-
events << :message
|
137
|
+
events << [:message]
|
86
138
|
else
|
87
|
-
events << :notice
|
139
|
+
events << [:notice]
|
88
140
|
end
|
89
141
|
else
|
90
142
|
meth = "on_#{msg.command.downcase}"
|
91
|
-
__send__(meth, msg) if respond_to?(meth, true)
|
143
|
+
__send__(meth, msg, events) if respond_to?(meth, true)
|
92
144
|
|
93
145
|
if msg.error?
|
94
|
-
events << :error
|
146
|
+
events << [:error]
|
95
147
|
else
|
96
|
-
events << msg.command.downcase.to_sym
|
148
|
+
events << [msg.command.downcase.to_sym]
|
97
149
|
end
|
98
150
|
end
|
99
151
|
|
100
|
-
msg.instance_variable_set(:@events, events)
|
101
|
-
events.each do |event|
|
102
|
-
@bot.dispatch(event, msg)
|
152
|
+
msg.instance_variable_set(:@events, events.map(&:first))
|
153
|
+
events.each do |event, *args|
|
154
|
+
@bot.dispatch(event, msg, *args)
|
103
155
|
end
|
104
156
|
end
|
105
157
|
|
@@ -115,7 +167,7 @@ module Cinch
|
|
115
167
|
end
|
116
168
|
|
117
169
|
private
|
118
|
-
def on_join(msg)
|
170
|
+
def on_join(msg, events)
|
119
171
|
if msg.user == @bot
|
120
172
|
@bot.channels << msg.channel
|
121
173
|
msg.channel.sync_modes
|
@@ -123,64 +175,125 @@ module Cinch
|
|
123
175
|
msg.channel.add_user(msg.user)
|
124
176
|
end
|
125
177
|
|
126
|
-
def on_kick(msg)
|
127
|
-
target =
|
178
|
+
def on_kick(msg, events)
|
179
|
+
target = @bot.user_manager.find_ensured(msg.params[1])
|
128
180
|
if target == @bot
|
129
181
|
@bot.channels.delete(msg.channel)
|
130
182
|
end
|
131
183
|
msg.channel.remove_user(target)
|
132
184
|
end
|
133
185
|
|
134
|
-
def on_kill(msg)
|
135
|
-
user =
|
136
|
-
|
186
|
+
def on_kill(msg, events)
|
187
|
+
user = @bot.user_manager.find_ensured(msg.params[1])
|
188
|
+
@bot.channel_manager.each do |channel|
|
137
189
|
channel.remove_user(user)
|
138
190
|
end
|
139
|
-
|
140
|
-
|
191
|
+
user.unsync_all
|
192
|
+
@bot.user_manager.delete(user)
|
193
|
+
end
|
194
|
+
|
195
|
+
def on_mode(msg, events)
|
196
|
+
if msg.channel?
|
197
|
+
add_and_remove = @bot.irc.isupport["CHANMODES"]["A"] + @bot.irc.isupport["CHANMODES"]["B"] + @bot.irc.isupport["PREFIX"].keys
|
198
|
+
|
199
|
+
param_modes = {:add => @bot.irc.isupport["CHANMODES"]["C"] + add_and_remove,
|
200
|
+
:remove => add_and_remove}
|
201
|
+
|
202
|
+
modes = ModeParser.parse_modes(msg.params[1], msg.params[2..-1], param_modes)
|
203
|
+
modes.each do |direction, mode, param|
|
204
|
+
if @bot.irc.isupport["PREFIX"].keys.include?(mode)
|
205
|
+
target = @bot.User(param)
|
206
|
+
# (un)set a user-mode
|
207
|
+
if direction == :add
|
208
|
+
msg.channel.users[target] << mode unless msg.channel.users[@bot.User(param)].include?(mode)
|
209
|
+
else
|
210
|
+
msg.channel.users[target].delete mode
|
211
|
+
end
|
141
212
|
|
142
|
-
|
143
|
-
|
213
|
+
user_events = {
|
214
|
+
"o" => "op",
|
215
|
+
"v" => "voice",
|
216
|
+
"h" => "halfop"
|
217
|
+
}
|
218
|
+
if user_events.has_key?(mode)
|
219
|
+
event = (direction == :add ? "" : "de") + user_events[mode]
|
220
|
+
events << [event.to_sym, target]
|
221
|
+
end
|
222
|
+
elsif @bot.irc.isupport["CHANMODES"]["A"].include?(mode)
|
223
|
+
case mode
|
224
|
+
when "b"
|
225
|
+
mask = param
|
226
|
+
ban = Ban.new(mask, msg.user, Time.now)
|
227
|
+
|
228
|
+
if direction == :add
|
229
|
+
msg.channel.bans_unsynced << ban
|
230
|
+
events << [:ban, ban]
|
231
|
+
else
|
232
|
+
msg.channel.bans_unsynced.delete_if {|b| b.mask == ban.mask}.first
|
233
|
+
events << [:unban, ban]
|
234
|
+
end
|
235
|
+
else
|
236
|
+
raise UnsupportedFeature, mode
|
237
|
+
end
|
238
|
+
else
|
239
|
+
# channel options
|
240
|
+
if direction == :add
|
241
|
+
msg.channel.modes_unsynced[mode] = param
|
242
|
+
else
|
243
|
+
msg.channel.modes_unsynced.delete(mode)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
events << [:mode_change, modes]
|
249
|
+
end
|
144
250
|
end
|
145
251
|
|
146
|
-
def on_nick(msg)
|
252
|
+
def on_nick(msg, events)
|
147
253
|
if msg.user == @bot
|
148
254
|
@bot.config.nick = msg.params.last
|
149
255
|
end
|
150
256
|
|
151
|
-
msg.user.
|
257
|
+
msg.user.update_nick(msg.params.last)
|
152
258
|
end
|
153
259
|
|
154
|
-
def on_part(msg)
|
260
|
+
def on_part(msg, events)
|
155
261
|
msg.channel.remove_user(msg.user)
|
156
262
|
if msg.user == @bot
|
157
263
|
@bot.channels.delete(msg.channel)
|
158
264
|
end
|
159
265
|
end
|
160
266
|
|
161
|
-
def on_ping(msg)
|
267
|
+
def on_ping(msg, events)
|
162
268
|
message "PONG :#{msg.params.first}"
|
163
269
|
end
|
164
270
|
|
165
|
-
def on_topic(msg)
|
271
|
+
def on_topic(msg, events)
|
166
272
|
msg.channel.sync(:topic, msg.params[1])
|
167
273
|
end
|
168
274
|
|
169
|
-
def on_quit(msg)
|
170
|
-
|
275
|
+
def on_quit(msg, events)
|
276
|
+
@bot.channel_manager.each do |channel|
|
171
277
|
channel.remove_user(msg.user)
|
172
278
|
end
|
173
279
|
msg.user.unsync_all
|
280
|
+
@bot.user_manager.delete(msg.user)
|
174
281
|
end
|
175
282
|
|
176
|
-
def on_005(msg)
|
283
|
+
def on_005(msg, events)
|
177
284
|
# ISUPPORT
|
178
285
|
@isupport.parse(*msg.params[1..-2].map {|v| v.split(" ")}.flatten)
|
179
286
|
end
|
180
287
|
|
181
|
-
def
|
288
|
+
def on_307(msg, events)
|
289
|
+
# RPL_WHOISREGNICK
|
290
|
+
user = @bot.user_manager.find_ensured(msg.params[1])
|
291
|
+
@whois_updates[user].merge!({:authname => user.nick})
|
292
|
+
end
|
293
|
+
|
294
|
+
def on_311(msg, events)
|
182
295
|
# RPL_WHOISUSER
|
183
|
-
user =
|
296
|
+
user = @bot.user_manager.find_ensured(msg.params[1])
|
184
297
|
@whois_updates[user].merge!({
|
185
298
|
:user => msg.params[2],
|
186
299
|
:host => msg.params[3],
|
@@ -188,18 +301,18 @@ module Cinch
|
|
188
301
|
})
|
189
302
|
end
|
190
303
|
|
191
|
-
def on_317(msg)
|
304
|
+
def on_317(msg, events)
|
192
305
|
# RPL_WHOISIDLE
|
193
|
-
user =
|
306
|
+
user = @bot.user_manager.find_ensured(msg.params[1])
|
194
307
|
@whois_updates[user].merge!({
|
195
308
|
:idle => msg.params[2].to_i,
|
196
309
|
:signed_on_at => Time.at(msg.params[3].to_i),
|
197
310
|
})
|
198
311
|
end
|
199
312
|
|
200
|
-
def on_318(msg)
|
313
|
+
def on_318(msg, events)
|
201
314
|
# RPL_ENDOFWHOIS
|
202
|
-
user =
|
315
|
+
user = @bot.user_manager.find_ensured(msg.params[1])
|
203
316
|
|
204
317
|
if @whois_updates[user].empty? && !user.attr(:unknown?, true, true)
|
205
318
|
user.end_of_whois(nil)
|
@@ -209,14 +322,14 @@ module Cinch
|
|
209
322
|
end
|
210
323
|
end
|
211
324
|
|
212
|
-
def on_319(msg)
|
325
|
+
def on_319(msg, events)
|
213
326
|
# RPL_WHOISCHANNELS
|
214
|
-
user =
|
215
|
-
channels = msg.params[2].scan(/#{@isupport["CHANTYPES"].join}[^ ]+/o).map {|c|
|
327
|
+
user = @bot.user_manager.find_ensured(msg.params[1])
|
328
|
+
channels = msg.params[2].scan(/#{@isupport["CHANTYPES"].join}[^ ]+/o).map {|c| @bot.channel_manager.find_ensured(c) }
|
216
329
|
user.sync(:channels, channels, true)
|
217
330
|
end
|
218
331
|
|
219
|
-
def on_324(msg)
|
332
|
+
def on_324(msg, events)
|
220
333
|
# RPL_CHANNELMODEIS
|
221
334
|
|
222
335
|
modes = {}
|
@@ -232,24 +345,24 @@ module Cinch
|
|
232
345
|
msg.channel.sync(:modes, modes, false)
|
233
346
|
end
|
234
347
|
|
235
|
-
def on_330(msg)
|
348
|
+
def on_330(msg, events)
|
236
349
|
# RPL_WHOISACCOUNT
|
237
|
-
user =
|
350
|
+
user = @bot.user_manager.find_ensured(msg.params[1])
|
238
351
|
authname = msg.params[2]
|
239
352
|
@whois_updates[user].merge!({:authname => authname})
|
240
353
|
end
|
241
354
|
|
242
|
-
def on_331(msg)
|
355
|
+
def on_331(msg, events)
|
243
356
|
# RPL_NOTOPIC
|
244
357
|
msg.channel.sync(:topic, "")
|
245
358
|
end
|
246
359
|
|
247
|
-
def on_332(msg)
|
360
|
+
def on_332(msg, events)
|
248
361
|
# RPL_TOPIC
|
249
362
|
msg.channel.sync(:topic, msg.params[2])
|
250
363
|
end
|
251
364
|
|
252
|
-
def on_353(msg)
|
365
|
+
def on_353(msg, events)
|
253
366
|
# RPL_NAMEREPLY
|
254
367
|
unless @in_lists.include?(:names)
|
255
368
|
msg.channel.clear_users
|
@@ -257,25 +370,26 @@ module Cinch
|
|
257
370
|
@in_lists << :names
|
258
371
|
|
259
372
|
msg.params[3].split(" ").each do |user|
|
260
|
-
|
261
|
-
|
262
|
-
|
373
|
+
m = user.match(/^([#{@isupport["PREFIX"].values.join}]+)/)
|
374
|
+
if m
|
375
|
+
prefixes = m[1].split.map {|s| @isupport["PREFIX"].key(s)}
|
376
|
+
nick = user[prefixes.size..-1]
|
263
377
|
else
|
264
378
|
nick = user
|
265
|
-
|
379
|
+
prefixes = []
|
266
380
|
end
|
267
|
-
user =
|
268
|
-
msg.channel.add_user(user,
|
381
|
+
user = @bot.user_manager.find_ensured(nick)
|
382
|
+
msg.channel.add_user(user, prefixes)
|
269
383
|
end
|
270
384
|
end
|
271
385
|
|
272
|
-
def on_366(msg)
|
386
|
+
def on_366(msg, events)
|
273
387
|
# RPL_ENDOFNAMES
|
274
388
|
@in_lists.delete :names
|
275
389
|
msg.channel.mark_as_synced(:users)
|
276
390
|
end
|
277
391
|
|
278
|
-
def on_367(msg)
|
392
|
+
def on_367(msg, events)
|
279
393
|
# RPL_BANLIST
|
280
394
|
unless @in_lists.include?(:bans)
|
281
395
|
msg.channel.bans_unsynced.clear
|
@@ -283,14 +397,14 @@ module Cinch
|
|
283
397
|
@in_lists << :bans
|
284
398
|
|
285
399
|
mask = msg.params[2]
|
286
|
-
by =
|
400
|
+
by = @bot.user_manager.find_ensured(msg.params[3].split("!").first)
|
287
401
|
at = Time.at(msg.params[4].to_i)
|
288
402
|
|
289
403
|
ban = Ban.new(mask, by, at)
|
290
404
|
msg.channel.bans_unsynced << ban
|
291
405
|
end
|
292
406
|
|
293
|
-
def on_368(msg)
|
407
|
+
def on_368(msg, events)
|
294
408
|
# RPL_ENDOFBANLIST
|
295
409
|
if @in_lists.include?(:bans)
|
296
410
|
@in_lists.delete :bans
|
@@ -302,14 +416,15 @@ module Cinch
|
|
302
416
|
msg.channel.mark_as_synced(:bans)
|
303
417
|
end
|
304
418
|
|
305
|
-
def on_396(msg)
|
419
|
+
def on_396(msg, events)
|
420
|
+
# RPL_HOSTHIDDEN
|
306
421
|
# note: designed for freenode
|
307
|
-
|
422
|
+
@bot.user_manager.find_ensured(msg.params[0]).sync(:host, msg.params[1], true)
|
308
423
|
end
|
309
424
|
|
310
|
-
def on_401(msg)
|
425
|
+
def on_401(msg, events)
|
311
426
|
# ERR_NOSUCHNICK
|
312
|
-
user =
|
427
|
+
user = @bot.user_manager.find_ensured(msg.params[1])
|
313
428
|
user.sync(:unknown?, true, true)
|
314
429
|
if @whois_updates.key?(user)
|
315
430
|
user.end_of_whois(nil, true)
|
@@ -317,23 +432,23 @@ module Cinch
|
|
317
432
|
end
|
318
433
|
end
|
319
434
|
|
320
|
-
def on_402(msg)
|
435
|
+
def on_402(msg, events)
|
321
436
|
# ERR_NOSUCHSERVER
|
322
437
|
|
323
|
-
if user =
|
438
|
+
if user = @bot.user_manager.find(msg.params[1]) # not _ensured, we only want a user that already exists
|
324
439
|
user.end_of_whois(nil, true)
|
325
440
|
@whois_updates.delete user
|
326
441
|
# TODO freenode specific, test on other IRCd
|
327
442
|
end
|
328
443
|
end
|
329
444
|
|
330
|
-
def on_433(msg)
|
445
|
+
def on_433(msg, events)
|
331
446
|
# ERR_NICKNAMEINUSE
|
332
|
-
@bot.nick = msg.params[1]
|
447
|
+
@bot.nick = @bot.generate_next_nick(msg.params[1])
|
333
448
|
end
|
334
449
|
|
335
|
-
def on_671(msg)
|
336
|
-
user =
|
450
|
+
def on_671(msg, events)
|
451
|
+
user = @bot.user_manager.find_ensured(msg.params[1])
|
337
452
|
@whois_updates[user].merge!({:secure? => true})
|
338
453
|
end
|
339
454
|
end
|