ircinch 2.4.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.
- checksums.yaml +7 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +298 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +23 -0
- data/README.md +195 -0
- data/Rakefile +14 -0
- data/docs/bot_options.md +454 -0
- data/docs/changes.md +541 -0
- data/docs/common_mistakes.md +60 -0
- data/docs/common_tasks.md +57 -0
- data/docs/encodings.md +69 -0
- data/docs/events.md +273 -0
- data/docs/getting_started.md +184 -0
- data/docs/logging.md +90 -0
- data/docs/migrating.md +267 -0
- data/docs/plugins.md +4 -0
- data/docs/readme.md +20 -0
- data/examples/basic/autovoice.rb +32 -0
- data/examples/basic/google.rb +35 -0
- data/examples/basic/hello.rb +14 -0
- data/examples/basic/join_part.rb +35 -0
- data/examples/basic/memo.rb +39 -0
- data/examples/basic/msg.rb +15 -0
- data/examples/basic/seen.rb +37 -0
- data/examples/basic/urban_dict.rb +36 -0
- data/examples/basic/url_shorten.rb +36 -0
- data/examples/plugins/autovoice.rb +37 -0
- data/examples/plugins/custom_prefix.rb +22 -0
- data/examples/plugins/dice_roll.rb +38 -0
- data/examples/plugins/google.rb +36 -0
- data/examples/plugins/hello.rb +21 -0
- data/examples/plugins/hooks.rb +34 -0
- data/examples/plugins/join_part.rb +41 -0
- data/examples/plugins/lambdas.rb +35 -0
- data/examples/plugins/last_nick.rb +24 -0
- data/examples/plugins/msg.rb +21 -0
- data/examples/plugins/multiple_matches.rb +32 -0
- data/examples/plugins/own_events.rb +37 -0
- data/examples/plugins/seen.rb +44 -0
- data/examples/plugins/timer.rb +22 -0
- data/examples/plugins/url_shorten.rb +34 -0
- data/ircinch.gemspec +43 -0
- data/lib/cinch/ban.rb +53 -0
- data/lib/cinch/bot.rb +476 -0
- data/lib/cinch/cached_list.rb +21 -0
- data/lib/cinch/callback.rb +22 -0
- data/lib/cinch/channel.rb +465 -0
- data/lib/cinch/channel_list.rb +31 -0
- data/lib/cinch/configuration/bot.rb +50 -0
- data/lib/cinch/configuration/dcc.rb +18 -0
- data/lib/cinch/configuration/plugins.rb +43 -0
- data/lib/cinch/configuration/sasl.rb +21 -0
- data/lib/cinch/configuration/ssl.rb +21 -0
- data/lib/cinch/configuration/timeouts.rb +16 -0
- data/lib/cinch/configuration.rb +75 -0
- data/lib/cinch/constants.rb +535 -0
- data/lib/cinch/dcc/dccable_object.rb +39 -0
- data/lib/cinch/dcc/incoming/send.rb +149 -0
- data/lib/cinch/dcc/incoming.rb +3 -0
- data/lib/cinch/dcc/outgoing/send.rb +123 -0
- data/lib/cinch/dcc/outgoing.rb +3 -0
- data/lib/cinch/dcc.rb +14 -0
- data/lib/cinch/exceptions.rb +48 -0
- data/lib/cinch/formatting.rb +127 -0
- data/lib/cinch/handler.rb +120 -0
- data/lib/cinch/handler_list.rb +92 -0
- data/lib/cinch/helpers.rb +230 -0
- data/lib/cinch/i_support.rb +100 -0
- data/lib/cinch/irc.rb +924 -0
- data/lib/cinch/log_filter.rb +23 -0
- data/lib/cinch/logger/formatted_logger.rb +100 -0
- data/lib/cinch/logger/zcbot_logger.rb +26 -0
- data/lib/cinch/logger.rb +171 -0
- data/lib/cinch/logger_list.rb +88 -0
- data/lib/cinch/mask.rb +69 -0
- data/lib/cinch/message.rb +397 -0
- data/lib/cinch/message_queue.rb +104 -0
- data/lib/cinch/mode_parser.rb +78 -0
- data/lib/cinch/network.rb +106 -0
- data/lib/cinch/open_ended_queue.rb +26 -0
- data/lib/cinch/pattern.rb +66 -0
- data/lib/cinch/plugin.rb +517 -0
- data/lib/cinch/plugin_list.rb +40 -0
- data/lib/cinch/rubyext/float.rb +5 -0
- data/lib/cinch/rubyext/module.rb +28 -0
- data/lib/cinch/rubyext/string.rb +35 -0
- data/lib/cinch/sasl/dh_blowfish.rb +73 -0
- data/lib/cinch/sasl/diffie_hellman.rb +50 -0
- data/lib/cinch/sasl/mechanism.rb +8 -0
- data/lib/cinch/sasl/plain.rb +29 -0
- data/lib/cinch/sasl.rb +36 -0
- data/lib/cinch/syncable.rb +83 -0
- data/lib/cinch/target.rb +199 -0
- data/lib/cinch/timer.rb +147 -0
- data/lib/cinch/user.rb +489 -0
- data/lib/cinch/user_list.rb +89 -0
- data/lib/cinch/utilities/deprecation.rb +18 -0
- data/lib/cinch/utilities/encoding.rb +39 -0
- data/lib/cinch/utilities/kernel.rb +15 -0
- data/lib/cinch/version.rb +6 -0
- data/lib/cinch.rb +7 -0
- data/lib/ircinch.rb +7 -0
- metadata +205 -0
@@ -0,0 +1,465 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "set"
|
4
|
+
|
5
|
+
require_relative "target"
|
6
|
+
|
7
|
+
module Cinch
|
8
|
+
# @attr limit
|
9
|
+
# @attr secret
|
10
|
+
# @attr moderated
|
11
|
+
# @attr invite_only
|
12
|
+
# @attr key
|
13
|
+
#
|
14
|
+
# @version 2.0.0
|
15
|
+
class Channel < Target
|
16
|
+
include Syncable
|
17
|
+
include Helpers
|
18
|
+
|
19
|
+
# Users are represented by a Hash, mapping individual users to an
|
20
|
+
# array of modes (e.g. "o" for opped).
|
21
|
+
#
|
22
|
+
# @return [Hash{User => Array<String}>] all users in the channel
|
23
|
+
# @version 1.1.0
|
24
|
+
attr_reader :users
|
25
|
+
synced_attr_reader :users
|
26
|
+
|
27
|
+
# @return [String] the channel's topic
|
28
|
+
attr_accessor :topic
|
29
|
+
synced_attr_reader :topic
|
30
|
+
|
31
|
+
# @return [Array<Ban>] all active bans
|
32
|
+
attr_reader :bans
|
33
|
+
synced_attr_reader :bans
|
34
|
+
|
35
|
+
# @return [Array<User>] all channel owners
|
36
|
+
# @note Only some networks implement this
|
37
|
+
attr_reader :owners
|
38
|
+
synced_attr_reader :owners
|
39
|
+
|
40
|
+
# This attribute describes all modes set in the channel. They're
|
41
|
+
# represented as a Hash, mapping the mode (e.g. "i", "k", …) to
|
42
|
+
# either a value in the case of modes that take an option (e.g.
|
43
|
+
# "k" for the channel key) or true.
|
44
|
+
#
|
45
|
+
# @return [Hash{String => Object}]
|
46
|
+
attr_reader :modes
|
47
|
+
synced_attr_reader :modes
|
48
|
+
|
49
|
+
# @note Generally, you shouldn't initialize new instances of this
|
50
|
+
# class. Use {ChannelList#find_ensured} instead.
|
51
|
+
def initialize(name, bot)
|
52
|
+
@bot = bot
|
53
|
+
@name = name
|
54
|
+
@users = Hash.new { |h, k| h[k] = [] }
|
55
|
+
@bans = []
|
56
|
+
@owners = []
|
57
|
+
|
58
|
+
@modes = {}
|
59
|
+
# TODO raise if not a channel
|
60
|
+
|
61
|
+
@topic = nil
|
62
|
+
|
63
|
+
@in_channel = false
|
64
|
+
|
65
|
+
@synced_attributes = Set.new
|
66
|
+
@when_requesting_synced_attribute = lambda { |attr|
|
67
|
+
if @in_channel && attr == :topic && !attribute_synced?(:topic)
|
68
|
+
# Even if we are in the channel, if there's no topic set,
|
69
|
+
# the attribute won't be synchronised yet. Explicitly
|
70
|
+
# request the topic.
|
71
|
+
@bot.irc.send "TOPIC #{@name}"
|
72
|
+
next
|
73
|
+
end
|
74
|
+
|
75
|
+
unless @in_channel
|
76
|
+
unsync(attr)
|
77
|
+
case attr
|
78
|
+
when :users
|
79
|
+
@bot.irc.send "NAMES #{@name}"
|
80
|
+
when :topic
|
81
|
+
@bot.irc.send "TOPIC #{@name}"
|
82
|
+
when :bans
|
83
|
+
@bot.irc.send "MODE #{@name} +b"
|
84
|
+
when :owners
|
85
|
+
if @bot.irc.network.owner_list_mode
|
86
|
+
@bot.irc.send "MODE #{@name} +#{@bot.irc.network.owner_list_mode}"
|
87
|
+
else
|
88
|
+
# the current IRCd does not support channel owners, so
|
89
|
+
# just mark the empty array as synced
|
90
|
+
mark_as_synced(:owners)
|
91
|
+
end
|
92
|
+
when :modes
|
93
|
+
@bot.irc.send "MODE #{@name}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
# @group Checks
|
100
|
+
|
101
|
+
# @param [User, String] user An {User}-object or a nickname
|
102
|
+
# @return [Boolean] Check if a user is in the channel
|
103
|
+
# @since 1.1.0
|
104
|
+
# @version 1.1.2
|
105
|
+
def has_user?(user)
|
106
|
+
@users.has_key?(User(user))
|
107
|
+
end
|
108
|
+
|
109
|
+
# @return [Boolean] true if `user` is opped in the channel
|
110
|
+
# @since 1.1.0
|
111
|
+
def opped?(user)
|
112
|
+
@users[User(user)].include? "o"
|
113
|
+
end
|
114
|
+
|
115
|
+
# @return [Boolean] true if `user` is half-opped in the channel
|
116
|
+
# @since 1.1.0
|
117
|
+
def half_opped?(user)
|
118
|
+
@users[User(user)].include? "h"
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [Boolean] true if `user` is voiced in the channel
|
122
|
+
# @since 1.1.0
|
123
|
+
def voiced?(user)
|
124
|
+
@users[User(user)].include? "v"
|
125
|
+
end
|
126
|
+
|
127
|
+
# @endgroup
|
128
|
+
|
129
|
+
# @group User groups
|
130
|
+
# @return [Array<User>] All ops in the channel
|
131
|
+
# @since 2.0.0
|
132
|
+
def ops
|
133
|
+
@users.select { |user, modes| modes.include?("o") }.keys
|
134
|
+
end
|
135
|
+
|
136
|
+
# @return [Array<User>] All half-ops in the channel
|
137
|
+
# @since 2.0.0
|
138
|
+
def half_ops
|
139
|
+
@users.select { |user, modes| modes.include?("h") }.keys
|
140
|
+
end
|
141
|
+
|
142
|
+
# @return [Array<User>] All voiced users in the channel
|
143
|
+
# @since 2.0.0
|
144
|
+
def voiced
|
145
|
+
@users.select { |user, modes| modes.include?("v") }.keys
|
146
|
+
end
|
147
|
+
|
148
|
+
# @return [Array<User>] All admins in the channel
|
149
|
+
# @since 2.0.0
|
150
|
+
def admins
|
151
|
+
@users.select { |user, modes| modes.include?("a") }.keys
|
152
|
+
end
|
153
|
+
# @endgroup
|
154
|
+
|
155
|
+
# @return [Integer] The maximum number of allowed users in the
|
156
|
+
# channel. 0 if unlimited.
|
157
|
+
def limit
|
158
|
+
@modes["l"].to_i
|
159
|
+
end
|
160
|
+
|
161
|
+
def limit=(val)
|
162
|
+
if val == -1 || val.nil?
|
163
|
+
mode "-l"
|
164
|
+
else
|
165
|
+
mode "+l #{val}"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# @return [Boolean] true if the channel is secret (+s)
|
170
|
+
def secret
|
171
|
+
@modes["s"]
|
172
|
+
end
|
173
|
+
alias_method :secret?, :secret
|
174
|
+
|
175
|
+
def secret=(bool)
|
176
|
+
if bool
|
177
|
+
mode "+s"
|
178
|
+
else
|
179
|
+
mode "-s"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# @return [Boolean] true if the channel is moderated
|
184
|
+
def moderated
|
185
|
+
@modes["m"]
|
186
|
+
end
|
187
|
+
alias_method :moderated?, :moderated
|
188
|
+
|
189
|
+
def moderated=(bool)
|
190
|
+
if bool
|
191
|
+
mode "+m"
|
192
|
+
else
|
193
|
+
mode "-m"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# @return [Boolean] true if the channel is invite only (+i)
|
198
|
+
def invite_only
|
199
|
+
@modes["i"]
|
200
|
+
end
|
201
|
+
alias_method :invite_only?, :invite_only
|
202
|
+
|
203
|
+
def invite_only=(bool)
|
204
|
+
if bool
|
205
|
+
mode "+i"
|
206
|
+
else
|
207
|
+
mode "-i"
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# @return [String, nil] The channel's key (aka password)
|
212
|
+
def key
|
213
|
+
@modes["k"]
|
214
|
+
end
|
215
|
+
|
216
|
+
def key=(new_key)
|
217
|
+
if new_key.nil?
|
218
|
+
mode "-k #{key}"
|
219
|
+
else
|
220
|
+
mode "+k #{new_key}"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# @api private
|
225
|
+
# @return [void]
|
226
|
+
def sync_modes
|
227
|
+
unsync :users
|
228
|
+
unsync :bans
|
229
|
+
unsync :modes
|
230
|
+
unsync :owners
|
231
|
+
|
232
|
+
if @bot.irc.isupport["WHOX"]
|
233
|
+
@bot.irc.send "WHO #{@name} %acfhnru"
|
234
|
+
else
|
235
|
+
@bot.irc.send "WHO #{@name}"
|
236
|
+
end
|
237
|
+
@bot.irc.send "MODE #{@name} +b" # bans
|
238
|
+
@bot.irc.send "MODE #{@name}"
|
239
|
+
if @bot.irc.network.owner_list_mode
|
240
|
+
@bot.irc.send "MODE #{@name} +#{@bot.irc.network.owner_list_mode}"
|
241
|
+
else
|
242
|
+
mark_as_synced :owners
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# @group Channel Manipulation
|
247
|
+
|
248
|
+
# Bans someone from the channel.
|
249
|
+
#
|
250
|
+
# @param [Mask, String, #mask] target the mask, or an object having a mask, to ban
|
251
|
+
# @return [Mask] the mask used for banning
|
252
|
+
# @see #unban #unban for unbanning users
|
253
|
+
def ban(target)
|
254
|
+
mask = Mask.from(target)
|
255
|
+
|
256
|
+
@bot.irc.send "MODE #{@name} +b #{mask}"
|
257
|
+
mask
|
258
|
+
end
|
259
|
+
|
260
|
+
# Unbans someone from the channel.
|
261
|
+
#
|
262
|
+
# @param [Mask, String, #mask] target the mask to unban
|
263
|
+
# @return [Mask] the mask used for unbanning
|
264
|
+
# @see #ban #ban for banning users
|
265
|
+
def unban(target)
|
266
|
+
mask = Mask.from(target)
|
267
|
+
|
268
|
+
@bot.irc.send "MODE #{@name} -b #{mask}"
|
269
|
+
mask
|
270
|
+
end
|
271
|
+
|
272
|
+
# Ops a user.
|
273
|
+
#
|
274
|
+
# @param [String, User] user the user to op
|
275
|
+
# @return [void]
|
276
|
+
def op(user)
|
277
|
+
@bot.irc.send "MODE #{@name} +o #{user}"
|
278
|
+
end
|
279
|
+
|
280
|
+
# Deops a user.
|
281
|
+
#
|
282
|
+
# @param [String, User] user the user to deop
|
283
|
+
# @return [void]
|
284
|
+
def deop(user)
|
285
|
+
@bot.irc.send "MODE #{@name} -o #{user}"
|
286
|
+
end
|
287
|
+
|
288
|
+
# Voices a user.
|
289
|
+
#
|
290
|
+
# @param [String, User] user the user to voice
|
291
|
+
# @return [void]
|
292
|
+
def voice(user)
|
293
|
+
@bot.irc.send "MODE #{@name} +v #{user}"
|
294
|
+
end
|
295
|
+
|
296
|
+
# Devoices a user.
|
297
|
+
#
|
298
|
+
# @param [String, User] user the user to devoice
|
299
|
+
# @return [void]
|
300
|
+
def devoice(user)
|
301
|
+
@bot.irc.send "MODE #{@name} -v #{user}"
|
302
|
+
end
|
303
|
+
|
304
|
+
# Invites a user to the channel.
|
305
|
+
#
|
306
|
+
# @param [String, User] user the user to invite
|
307
|
+
# @return [void]
|
308
|
+
def invite(user)
|
309
|
+
@bot.irc.send("INVITE #{user} #{@name}")
|
310
|
+
end
|
311
|
+
|
312
|
+
undef_method(:topic=)
|
313
|
+
# Sets the topic.
|
314
|
+
#
|
315
|
+
# @param [String] new_topic the new topic
|
316
|
+
# @raise [Exceptions::TopicTooLong] Raised if the bot is operating
|
317
|
+
# in {Bot#strict? strict mode} and when the new topic is too long.
|
318
|
+
def topic=(new_topic)
|
319
|
+
if new_topic.size > @bot.irc.isupport["TOPICLEN"] && @bot.strict?
|
320
|
+
raise Exceptions::TopicTooLong, new_topic
|
321
|
+
end
|
322
|
+
|
323
|
+
@bot.irc.send "TOPIC #{@name} :#{new_topic}"
|
324
|
+
end
|
325
|
+
|
326
|
+
# Kicks a user from the channel.
|
327
|
+
#
|
328
|
+
# @param [String, User] user the user to kick
|
329
|
+
# @param [String] reason a reason for the kick
|
330
|
+
# @raise [Exceptions::KickReasonTooLong]
|
331
|
+
# @return [void]
|
332
|
+
def kick(user, reason = nil)
|
333
|
+
if reason.to_s.size > @bot.irc.isupport["KICKLEN"] && @bot.strict?
|
334
|
+
raise Exceptions::KickReasonTooLong, reason
|
335
|
+
end
|
336
|
+
|
337
|
+
@bot.irc.send("KICK #{@name} #{user} :#{reason}")
|
338
|
+
end
|
339
|
+
|
340
|
+
# Removes a user from the channel.
|
341
|
+
#
|
342
|
+
# This uses the REMOVE command, which is a non-standardized
|
343
|
+
# extension. Unlike a kick, it makes a user part. This prevents
|
344
|
+
# auto-rejoin scripts from firing and might also be perceived as
|
345
|
+
# less aggressive by some. Not all IRC networks support this
|
346
|
+
# command.
|
347
|
+
#
|
348
|
+
# @param [User] user the user to remove
|
349
|
+
# @param [String] reason a reason for the removal
|
350
|
+
# @return [void]
|
351
|
+
def remove(user, reason = nil)
|
352
|
+
@bot.irc.send("REMOVE #{@name} #{user} :#{reason}")
|
353
|
+
end
|
354
|
+
|
355
|
+
# Sets or unsets modes. Most of the time you won't need this but
|
356
|
+
# use setter methods like {Channel#invite_only=}.
|
357
|
+
#
|
358
|
+
# @param [String] s a mode string
|
359
|
+
# @return [void]
|
360
|
+
# @example
|
361
|
+
# channel.mode "+n"
|
362
|
+
def mode(s)
|
363
|
+
@bot.irc.send "MODE #{@name} #{s}"
|
364
|
+
end
|
365
|
+
|
366
|
+
# Causes the bot to part from the channel.
|
367
|
+
#
|
368
|
+
# @param [String] message the part message.
|
369
|
+
# @return [void]
|
370
|
+
def part(message = nil)
|
371
|
+
@bot.irc.send "PART #{@name} :#{message}"
|
372
|
+
end
|
373
|
+
|
374
|
+
# Joins the channel
|
375
|
+
#
|
376
|
+
# @param [String] key the channel key, if any. If none is
|
377
|
+
# specified but @key is set, @key will be used
|
378
|
+
# @return [void]
|
379
|
+
def join(key = nil)
|
380
|
+
if key.nil? && self.key != true
|
381
|
+
key = self.key
|
382
|
+
end
|
383
|
+
@bot.irc.send "JOIN #{[@name, key].compact.join(" ")}"
|
384
|
+
end
|
385
|
+
|
386
|
+
# @endgroup
|
387
|
+
|
388
|
+
# @api private
|
389
|
+
# @return [User] The added user
|
390
|
+
def add_user(user, modes = [])
|
391
|
+
@in_channel = true if user == @bot
|
392
|
+
@users[user] = modes
|
393
|
+
user
|
394
|
+
end
|
395
|
+
|
396
|
+
# @api private
|
397
|
+
# @return [User, nil] The removed user
|
398
|
+
def remove_user(user)
|
399
|
+
@in_channel = false if user == @bot
|
400
|
+
@users.delete(user)
|
401
|
+
end
|
402
|
+
|
403
|
+
# Removes all users
|
404
|
+
#
|
405
|
+
# @api private
|
406
|
+
# @return [void]
|
407
|
+
def clear_users
|
408
|
+
@users.clear
|
409
|
+
end
|
410
|
+
|
411
|
+
# @note The aliases `msg` and `privmsg` are deprecated and will be
|
412
|
+
# removed in a future version.
|
413
|
+
def send(text, notice = false)
|
414
|
+
# TODO deprecate 'notice' argument
|
415
|
+
text = text.to_s
|
416
|
+
if @modes["c"]
|
417
|
+
# Remove all formatting and colors if the channel doesn't
|
418
|
+
# allow colors.
|
419
|
+
text = Cinch::Formatting.unformat(text)
|
420
|
+
end
|
421
|
+
super(text, notice)
|
422
|
+
end
|
423
|
+
alias_method :msg, :send # deprecated
|
424
|
+
alias_method :privmsg, :send # deprecated
|
425
|
+
undef_method(:msg) # yardoc hack
|
426
|
+
undef_method(:privmsg) # yardoc hack
|
427
|
+
|
428
|
+
# @deprecated
|
429
|
+
def msg(*args)
|
430
|
+
Cinch::Utilities::Deprecation.print_deprecation("2.2.0", "Channel#msg", "Channel#send")
|
431
|
+
send(*args)
|
432
|
+
end
|
433
|
+
|
434
|
+
# @deprecated
|
435
|
+
def privmsg(*args)
|
436
|
+
Cinch::Utilities::Deprecation.print_deprecation("2.2.0", "Channel#privmsg", "Channel#send")
|
437
|
+
send(*args)
|
438
|
+
end
|
439
|
+
|
440
|
+
# @return [Fixnum]
|
441
|
+
def hash
|
442
|
+
@name.hash
|
443
|
+
end
|
444
|
+
|
445
|
+
# @return [String]
|
446
|
+
# @note The alias `to_str` is deprecated and will be removed in a
|
447
|
+
# future version. Channel objects should not be treated like
|
448
|
+
# strings.
|
449
|
+
def to_s
|
450
|
+
@name
|
451
|
+
end
|
452
|
+
alias_method :to_str, :to_s # deprecated
|
453
|
+
undef_method(:to_str) # yardoc hack
|
454
|
+
|
455
|
+
def to_str
|
456
|
+
Cinch::Utilities::Deprecation.print_deprecation("2.2.0", "Channel#to_str", "Channel#to_s")
|
457
|
+
to_s
|
458
|
+
end
|
459
|
+
|
460
|
+
# @return [String]
|
461
|
+
def inspect
|
462
|
+
"#<Channel name=#{@name.inspect}>"
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "cached_list"
|
4
|
+
|
5
|
+
module Cinch
|
6
|
+
# @since 2.0.0
|
7
|
+
# @version 1.1.0
|
8
|
+
# @note In prior versions, this class was called ChannelManager
|
9
|
+
class ChannelList < CachedList
|
10
|
+
# Finds or creates a channel.
|
11
|
+
#
|
12
|
+
# @param [String] name name of a channel
|
13
|
+
# @return [Channel]
|
14
|
+
# @see Helpers#Channel
|
15
|
+
def find_ensured(name)
|
16
|
+
downcased_name = name.irc_downcase(@bot.irc.isupport["CASEMAPPING"])
|
17
|
+
@mutex.synchronize do
|
18
|
+
@cache[downcased_name] ||= Channel.new(name, @bot)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Finds a channel.
|
23
|
+
#
|
24
|
+
# @param [String] name name of a channel
|
25
|
+
# @return [Channel, nil]
|
26
|
+
def find(name)
|
27
|
+
downcased_name = name.irc_downcase(@bot.irc.isupport["CASEMAPPING"])
|
28
|
+
@cache[downcased_name]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../configuration"
|
4
|
+
|
5
|
+
module Cinch
|
6
|
+
class Configuration
|
7
|
+
# @since 2.0.0
|
8
|
+
class Bot < Configuration
|
9
|
+
KNOWN_OPTIONS = [:server, :port, :ssl, :password, :nick, :nicks,
|
10
|
+
:realname, :user, :messages_per_second, :server_queue_size,
|
11
|
+
:strictness, :message_split_start, :message_split_end,
|
12
|
+
:max_messages, :plugins, :channels, :encoding, :reconnect, :max_reconnect_delay,
|
13
|
+
:local_host, :timeouts, :ping_interval, :delay_joins, :dcc, :shared, :sasl, :default_logger_level]
|
14
|
+
|
15
|
+
# (see Configuration.default_config)
|
16
|
+
def self.default_config
|
17
|
+
{
|
18
|
+
server: "localhost",
|
19
|
+
port: 6667,
|
20
|
+
ssl: Configuration::SSL.new,
|
21
|
+
password: nil,
|
22
|
+
nick: "ircinch",
|
23
|
+
nicks: nil,
|
24
|
+
realname: "ircinch",
|
25
|
+
user: "ircinch",
|
26
|
+
modes: [],
|
27
|
+
messages_per_second: nil,
|
28
|
+
server_queue_size: nil,
|
29
|
+
strictness: :forgiving,
|
30
|
+
message_split_start: "... ",
|
31
|
+
message_split_end: " ...",
|
32
|
+
max_messages: nil,
|
33
|
+
plugins: Configuration::Plugins.new,
|
34
|
+
channels: [],
|
35
|
+
encoding: :irc,
|
36
|
+
reconnect: true,
|
37
|
+
max_reconnect_delay: 300,
|
38
|
+
local_host: nil,
|
39
|
+
timeouts: Configuration::Timeouts.new,
|
40
|
+
ping_interval: 120,
|
41
|
+
delay_joins: 0,
|
42
|
+
dcc: Configuration::DCC.new,
|
43
|
+
sasl: Configuration::SASL.new,
|
44
|
+
shared: {},
|
45
|
+
default_logger_level: :debug
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../configuration"
|
4
|
+
|
5
|
+
module Cinch
|
6
|
+
class Configuration
|
7
|
+
# @since 2.0.0
|
8
|
+
class DCC < Configuration
|
9
|
+
KNOWN_OPTIONS = [:own_ip]
|
10
|
+
|
11
|
+
def self.default_config
|
12
|
+
{
|
13
|
+
own_ip: nil
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../configuration"
|
4
|
+
|
5
|
+
module Cinch
|
6
|
+
class Configuration
|
7
|
+
# @since 2.0.0
|
8
|
+
class Plugins < Configuration
|
9
|
+
KNOWN_OPTIONS = [:plugins, :prefix, :suffix, :options]
|
10
|
+
|
11
|
+
def self.default_config
|
12
|
+
{
|
13
|
+
plugins: [],
|
14
|
+
prefix: /^!/,
|
15
|
+
suffix: nil,
|
16
|
+
options: Hash.new { |h, k| h[k] = {} }
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def load(new_config, from_default = false)
|
21
|
+
fresh_new_config = {}
|
22
|
+
new_config.each do |option, value|
|
23
|
+
case option
|
24
|
+
when :plugins
|
25
|
+
fresh_new_config[option] = value.map { |v| Cinch::Utilities::Kernel.string_to_const(v) }
|
26
|
+
when :options
|
27
|
+
fresh_value = self[:options]
|
28
|
+
value.each do |k, v|
|
29
|
+
k = Cinch::Utilities::Kernel.string_to_const(k)
|
30
|
+
v = self[:options][k].merge(v)
|
31
|
+
fresh_value[k] = v
|
32
|
+
end
|
33
|
+
fresh_new_config[option] = fresh_value
|
34
|
+
else
|
35
|
+
fresh_new_config[option] = value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
super(fresh_new_config, from_default)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../configuration"
|
4
|
+
require_relative "../sasl"
|
5
|
+
|
6
|
+
module Cinch
|
7
|
+
class Configuration
|
8
|
+
# @since 2.0.0
|
9
|
+
class SASL < Configuration
|
10
|
+
KNOWN_OPTIONS = [:username, :password, :mechanisms]
|
11
|
+
|
12
|
+
def self.default_config
|
13
|
+
{
|
14
|
+
username: nil,
|
15
|
+
password: nil,
|
16
|
+
mechanisms: [Cinch::SASL::DhBlowfish, Cinch::SASL::Plain]
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../configuration"
|
4
|
+
|
5
|
+
module Cinch
|
6
|
+
class Configuration
|
7
|
+
# @since 2.0.0
|
8
|
+
class SSL < Configuration
|
9
|
+
KNOWN_OPTIONS = [:use, :verify, :client_cert, :ca_path]
|
10
|
+
|
11
|
+
def self.default_config
|
12
|
+
{
|
13
|
+
use: false,
|
14
|
+
verify: false,
|
15
|
+
client_cert: nil,
|
16
|
+
ca_path: "/etc/ssl/certs"
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../configuration"
|
4
|
+
|
5
|
+
module Cinch
|
6
|
+
class Configuration
|
7
|
+
# @since 2.0.0
|
8
|
+
class Timeouts < Configuration
|
9
|
+
KNOWN_OPTIONS = [:read, :connect]
|
10
|
+
|
11
|
+
def self.default_config
|
12
|
+
{read: 240, connect: 10}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|