grinch 1.0.1 → 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.
- checksums.yaml +4 -4
- data/README.md +4 -2
- data/lib/cinch.rb +7 -5
- data/lib/cinch/ban.rb +6 -2
- data/lib/cinch/bot.rb +21 -31
- data/lib/cinch/cached_list.rb +2 -0
- data/lib/cinch/callback.rb +2 -0
- data/lib/cinch/channel.rb +43 -44
- data/lib/cinch/channel_list.rb +2 -0
- data/lib/cinch/configuration.rb +8 -6
- data/lib/cinch/configuration/bot.rb +35 -33
- data/lib/cinch/configuration/dcc.rb +4 -2
- data/lib/cinch/configuration/plugins.rb +8 -6
- data/lib/cinch/configuration/sasl.rb +6 -4
- data/lib/cinch/configuration/ssl.rb +7 -5
- data/lib/cinch/configuration/timeouts.rb +4 -2
- data/lib/cinch/constants.rb +3 -1
- data/lib/cinch/dcc.rb +2 -0
- data/lib/cinch/dcc/dccable_object.rb +6 -8
- data/lib/cinch/dcc/incoming.rb +2 -0
- data/lib/cinch/dcc/incoming/send.rb +10 -8
- data/lib/cinch/dcc/outgoing.rb +2 -0
- data/lib/cinch/dcc/outgoing/send.rb +13 -14
- data/lib/cinch/exceptions.rb +2 -0
- data/lib/cinch/formatting.rb +32 -30
- data/lib/cinch/handler.rb +15 -13
- data/lib/cinch/handler_list.rb +13 -13
- data/lib/cinch/helpers.rb +16 -16
- data/lib/cinch/irc.rb +118 -142
- data/lib/cinch/isupport.rb +22 -20
- data/lib/cinch/log_filter.rb +3 -2
- data/lib/cinch/logger.rb +7 -2
- data/lib/cinch/logger/formatted_logger.rb +17 -13
- data/lib/cinch/logger/zcbot_logger.rb +4 -0
- data/lib/cinch/logger_list.rb +15 -14
- data/lib/cinch/mask.rb +11 -9
- data/lib/cinch/message.rb +6 -6
- data/lib/cinch/message_queue.rb +5 -4
- data/lib/cinch/mode_parser.rb +7 -5
- data/lib/cinch/network.rb +2 -0
- data/lib/cinch/open_ended_queue.rb +5 -5
- data/lib/cinch/pattern.rb +11 -8
- data/lib/cinch/plugin.rb +43 -49
- data/lib/cinch/plugin_list.rb +4 -4
- data/lib/cinch/rubyext/float.rb +3 -3
- data/lib/cinch/rubyext/module.rb +2 -0
- data/lib/cinch/rubyext/string.rb +8 -6
- data/lib/cinch/sasl.rb +2 -0
- data/lib/cinch/sasl/dh_blowfish.rb +5 -3
- data/lib/cinch/sasl/diffie_hellman.rb +6 -3
- data/lib/cinch/sasl/mechanism.rb +2 -0
- data/lib/cinch/sasl/plain.rb +2 -0
- data/lib/cinch/syncable.rb +10 -9
- data/lib/cinch/target.rb +15 -17
- data/lib/cinch/timer.rb +9 -7
- data/lib/cinch/user.rb +52 -48
- data/lib/cinch/user_list.rb +8 -11
- data/lib/cinch/utilities/deprecation.rb +5 -5
- data/lib/cinch/utilities/encoding.rb +9 -9
- data/lib/cinch/utilities/kernel.rb +4 -1
- data/lib/cinch/version.rb +3 -1
- metadata +4 -4
data/lib/cinch/channel_list.rb
CHANGED
data/lib/cinch/configuration.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Cinch
|
2
4
|
# @since 2.0.0
|
3
5
|
class Configuration < OpenStruct
|
4
|
-
KnownOptions = []
|
6
|
+
KnownOptions = [].freeze
|
5
7
|
|
6
8
|
# Generate a default configuration.
|
7
9
|
#
|
@@ -21,14 +23,16 @@ module Cinch
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def [](key)
|
24
|
-
# FIXME also adjust method_missing
|
26
|
+
# FIXME: also adjust method_missing
|
25
27
|
raise ArgumentError, "Unknown option #{key}" unless self.class::KnownOptions.include?(key)
|
28
|
+
|
26
29
|
@table[key]
|
27
30
|
end
|
28
31
|
|
29
32
|
def []=(key, value)
|
30
|
-
# FIXME also adjust method_missing
|
33
|
+
# FIXME: also adjust method_missing
|
31
34
|
raise ArgumentError, "Unknown option #{key}" unless self.class::KnownOptions.include?(key)
|
35
|
+
|
32
36
|
modifiable[new_ostruct_member(key)] = value
|
33
37
|
end
|
34
38
|
|
@@ -42,9 +46,7 @@ module Cinch
|
|
42
46
|
# configuration.
|
43
47
|
# @return [void]
|
44
48
|
def load(new_config, from_default = false)
|
45
|
-
if from_default
|
46
|
-
@table = self.class.default_config
|
47
|
-
end
|
49
|
+
@table = self.class.default_config if from_default
|
48
50
|
|
49
51
|
new_config.each do |option, value|
|
50
52
|
if value.is_a?(Hash)
|
@@ -1,46 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cinch/configuration"
|
2
4
|
|
3
5
|
module Cinch
|
4
6
|
class Configuration
|
5
7
|
# @since 2.0.0
|
6
8
|
class Bot < Configuration
|
7
|
-
KnownOptions = [
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
KnownOptions = %i[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].freeze
|
12
14
|
|
13
15
|
# (see Configuration.default_config)
|
14
16
|
def self.default_config
|
15
17
|
{
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:
|
32
|
-
:
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
18
|
+
server: "localhost",
|
19
|
+
port: 6667,
|
20
|
+
ssl: Configuration::SSL.new,
|
21
|
+
password: nil,
|
22
|
+
nick: "cinch",
|
23
|
+
nicks: nil,
|
24
|
+
realname: "cinch",
|
25
|
+
user: "cinch",
|
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,
|
44
46
|
}
|
45
47
|
end
|
46
48
|
end
|
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cinch/configuration"
|
2
4
|
|
3
5
|
module Cinch
|
4
6
|
class Configuration
|
5
7
|
# @since 2.0.0
|
6
8
|
class DCC < Configuration
|
7
|
-
KnownOptions = [:own_ip]
|
9
|
+
KnownOptions = [:own_ip].freeze
|
8
10
|
|
9
11
|
def self.default_config
|
10
12
|
{
|
11
|
-
:
|
13
|
+
own_ip: nil,
|
12
14
|
}
|
13
15
|
end
|
14
16
|
end
|
@@ -1,17 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cinch/configuration"
|
2
4
|
|
3
5
|
module Cinch
|
4
6
|
class Configuration
|
5
7
|
# @since 2.0.0
|
6
8
|
class Plugins < Configuration
|
7
|
-
KnownOptions = [
|
9
|
+
KnownOptions = %i[plugins prefix suffix options].freeze
|
8
10
|
|
9
11
|
def self.default_config
|
10
12
|
{
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
13
|
+
plugins: [],
|
14
|
+
prefix: /^!/,
|
15
|
+
suffix: nil,
|
16
|
+
options: Hash.new { |h, k| h[k] = {} },
|
15
17
|
}
|
16
18
|
end
|
17
19
|
|
@@ -20,7 +22,7 @@ module Cinch
|
|
20
22
|
new_config.each do |option, value|
|
21
23
|
case option
|
22
24
|
when :plugins
|
23
|
-
_new_config[option] = value.map{|v| Cinch::Utilities::Kernel.string_to_const(v)}
|
25
|
+
_new_config[option] = value.map { |v| Cinch::Utilities::Kernel.string_to_const(v) }
|
24
26
|
when :options
|
25
27
|
_value = self[:options]
|
26
28
|
value.each do |k, v|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cinch/configuration"
|
2
4
|
require "cinch/sasl"
|
3
5
|
|
@@ -5,13 +7,13 @@ module Cinch
|
|
5
7
|
class Configuration
|
6
8
|
# @since 2.0.0
|
7
9
|
class SASL < Configuration
|
8
|
-
KnownOptions = [
|
10
|
+
KnownOptions = %i[username password mechanisms].freeze
|
9
11
|
|
10
12
|
def self.default_config
|
11
13
|
{
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
14
|
+
username: nil,
|
15
|
+
password: nil,
|
16
|
+
mechanisms: [Cinch::SASL::DH_Blowfish, Cinch::SASL::Plain],
|
15
17
|
}
|
16
18
|
end
|
17
19
|
end
|
@@ -1,17 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cinch/configuration"
|
2
4
|
|
3
5
|
module Cinch
|
4
6
|
class Configuration
|
5
7
|
# @since 2.0.0
|
6
8
|
class SSL < Configuration
|
7
|
-
KnownOptions = [
|
9
|
+
KnownOptions = %i[use verify client_cert ca_path].freeze
|
8
10
|
|
9
11
|
def self.default_config
|
10
12
|
{
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
13
|
+
use: false,
|
14
|
+
verify: false,
|
15
|
+
client_cert: nil,
|
16
|
+
ca_path: "/etc/ssl/certs",
|
15
17
|
}
|
16
18
|
end
|
17
19
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cinch/configuration"
|
2
4
|
|
3
5
|
module Cinch
|
4
6
|
class Configuration
|
5
7
|
# @since 2.0.0
|
6
8
|
class Timeouts < Configuration
|
7
|
-
KnownOptions = [
|
9
|
+
KnownOptions = %i[read connect].freeze
|
8
10
|
|
9
11
|
def self.default_config
|
10
|
-
{:
|
12
|
+
{ read: 240, connect: 10 }
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
data/lib/cinch/constants.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Cinch
|
2
4
|
# All standard and some non-standard numeric replies used by the IRC
|
3
5
|
# protocol.
|
@@ -274,7 +276,7 @@ module Cinch
|
|
274
276
|
# revisions) and the <debuglevel> is used to indicate if the
|
275
277
|
# server is running in "debug mode".
|
276
278
|
#
|
277
|
-
#The "comments" field may contain any comments about the version or
|
279
|
+
# The "comments" field may contain any comments about the version or
|
278
280
|
# further version details.
|
279
281
|
RPL_VERSION = 351
|
280
282
|
|
data/lib/cinch/dcc.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Cinch
|
2
4
|
module DCC
|
3
5
|
# This module describes the required interface for objects that should
|
@@ -12,26 +14,22 @@ module Cinch
|
|
12
14
|
# @param [Integer] number Read `number` bytes at most
|
13
15
|
# @return [String] The read data
|
14
16
|
# @return [nil] If no more data can be read
|
15
|
-
def read(number)
|
16
|
-
end
|
17
|
+
def read(number); end
|
17
18
|
|
18
19
|
# Seek to a specific position.
|
19
20
|
#
|
20
21
|
# @param [Integer] position The position in bytes to seek to
|
21
22
|
# @return [void]
|
22
|
-
def seek(position)
|
23
|
-
end
|
23
|
+
def seek(position); end
|
24
24
|
|
25
25
|
# @return [String] A string representing the object's path or name.
|
26
26
|
#
|
27
27
|
# @note This is only required if calling {User#dcc_send} with only
|
28
28
|
# one argument
|
29
|
-
def path
|
30
|
-
end
|
29
|
+
def path; end
|
31
30
|
|
32
31
|
# @return [Integer] The total size of the data, in bytes.
|
33
|
-
def size
|
34
|
-
end
|
32
|
+
def size; end
|
35
33
|
end
|
36
34
|
end
|
37
35
|
end
|
data/lib/cinch/dcc/incoming.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "socket"
|
2
4
|
require "ipaddr"
|
3
5
|
|
@@ -50,11 +52,11 @@ module Cinch
|
|
50
52
|
PRIVATE_NETS = [IPAddr.new("fc00::/7"),
|
51
53
|
IPAddr.new("10.0.0.0/8"),
|
52
54
|
IPAddr.new("172.16.0.0/12"),
|
53
|
-
IPAddr.new("192.168.0.0/16")]
|
55
|
+
IPAddr.new("192.168.0.0/16")].freeze
|
54
56
|
|
55
57
|
# @private
|
56
58
|
LOCAL_NETS = [IPAddr.new("127.0.0.0/8"),
|
57
|
-
IPAddr.new("::1/128")]
|
59
|
+
IPAddr.new("::1/128")].freeze
|
58
60
|
|
59
61
|
# @return [User]
|
60
62
|
attr_reader :user
|
@@ -123,23 +125,23 @@ module Cinch
|
|
123
125
|
end
|
124
126
|
|
125
127
|
socket.close
|
126
|
-
|
128
|
+
true
|
127
129
|
rescue EOFError
|
128
|
-
|
130
|
+
false
|
129
131
|
end
|
130
132
|
|
131
133
|
# @return [Boolean] True if the DCC originates from a private ip
|
132
134
|
# @see #from_localhost?
|
133
135
|
def from_private_ip?
|
134
|
-
ip
|
135
|
-
PRIVATE_NETS.any? {|n| n.include?(ip)}
|
136
|
+
ip = IPAddr.new(@ip)
|
137
|
+
PRIVATE_NETS.any? { |n| n.include?(ip) }
|
136
138
|
end
|
137
139
|
|
138
140
|
# @return [Boolean] True if the DCC originates from localhost
|
139
141
|
# @see #from_private_ip?
|
140
142
|
def from_localhost?
|
141
|
-
ip
|
142
|
-
LOCAL_NETS.any? {|n| n.include?(ip)}
|
143
|
+
ip = IPAddr.new(@ip)
|
144
|
+
LOCAL_NETS.any? { |n| n.include?(ip) }
|
143
145
|
end
|
144
146
|
end
|
145
147
|
end
|
data/lib/cinch/dcc/outgoing.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "socket"
|
2
4
|
require "ipaddr"
|
3
5
|
require "timeout"
|
@@ -73,16 +75,14 @@ module Cinch
|
|
73
75
|
# @return [void]
|
74
76
|
# @note This method blocks.
|
75
77
|
def listen
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
fd, _ = @socket.accept
|
80
|
-
end
|
81
|
-
send_data(fd)
|
82
|
-
fd.close
|
83
|
-
ensure
|
84
|
-
@socket.close
|
78
|
+
fd = nil
|
79
|
+
Timeout.timeout(30) do
|
80
|
+
fd, _ = @socket.accept
|
85
81
|
end
|
82
|
+
send_data(fd)
|
83
|
+
fd.close
|
84
|
+
ensure
|
85
|
+
@socket.close
|
86
86
|
end
|
87
87
|
|
88
88
|
# Seek to `pos` in the data.
|
@@ -100,16 +100,15 @@ module Cinch
|
|
100
100
|
end
|
101
101
|
|
102
102
|
private
|
103
|
+
|
103
104
|
def send_data(fd)
|
104
105
|
@io.advise(:sequential)
|
105
106
|
|
106
107
|
while chunk = @io.read(8096)
|
107
|
-
|
108
|
+
loop do
|
108
109
|
rs, ws = IO.select([fd], [fd])
|
109
|
-
|
110
|
-
|
111
|
-
end
|
112
|
-
if !ws.empty?
|
110
|
+
rs.first.recv(8096) unless rs.empty?
|
111
|
+
unless ws.empty?
|
113
112
|
ws.first.write(chunk)
|
114
113
|
break
|
115
114
|
end
|
data/lib/cinch/exceptions.rb
CHANGED
data/lib/cinch/formatting.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Cinch
|
2
4
|
# This module can be used for adding and removing colors and
|
3
5
|
# formatting to/from messages.
|
@@ -41,34 +43,34 @@ module Cinch
|
|
41
43
|
module Formatting
|
42
44
|
# @private
|
43
45
|
Colors = {
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
60
|
-
}
|
46
|
+
white: "00",
|
47
|
+
black: "01",
|
48
|
+
blue: "02",
|
49
|
+
green: "03",
|
50
|
+
red: "04",
|
51
|
+
brown: "05",
|
52
|
+
purple: "06",
|
53
|
+
orange: "07",
|
54
|
+
yellow: "08",
|
55
|
+
lime: "09",
|
56
|
+
teal: "10",
|
57
|
+
aqua: "11",
|
58
|
+
royal: "12",
|
59
|
+
pink: "13",
|
60
|
+
grey: "14",
|
61
|
+
silver: "15",
|
62
|
+
}.freeze
|
61
63
|
|
62
64
|
# @private
|
63
65
|
Attributes = {
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:
|
67
|
-
:
|
68
|
-
:
|
69
|
-
:
|
70
|
-
:
|
71
|
-
}
|
66
|
+
bold: 2.chr,
|
67
|
+
underlined: 31.chr,
|
68
|
+
underline: 31.chr,
|
69
|
+
reversed: 22.chr,
|
70
|
+
reverse: 22.chr,
|
71
|
+
italic: 29.chr,
|
72
|
+
reset: 15.chr,
|
73
|
+
}.freeze
|
72
74
|
|
73
75
|
# @param [Array<Symbol>] settings The colors and attributes to apply.
|
74
76
|
# When supplying two colors, the first will be used for the
|
@@ -82,10 +84,10 @@ module Cinch
|
|
82
84
|
# @example Nested formatting, combining text styles and colors
|
83
85
|
# reply = Format(:underline, "Hello %s! Is your favourite color %s?" % [Format(:bold, "stranger"), Format(:red, "red")])
|
84
86
|
def self.format(*settings, string)
|
85
|
-
string
|
87
|
+
string = string.dup
|
86
88
|
|
87
|
-
attributes = settings.select {|k| Attributes.
|
88
|
-
colors = settings.select {|k| Colors.
|
89
|
+
attributes = settings.select { |k| Attributes.key?(k) }.map { |k| Attributes[k] }
|
90
|
+
colors = settings.select { |k| Colors.key?(k) }.map { |k| Colors[k] }
|
89
91
|
if colors.size > 2
|
90
92
|
raise ArgumentError, "At most two colors (foreground and background) might be specified"
|
91
93
|
end
|
@@ -108,7 +110,7 @@ module Cinch
|
|
108
110
|
# Replace the reset code of nested strings to continue the
|
109
111
|
# formattings of the outer string.
|
110
112
|
string.gsub!(/#{Attributes[:reset]}/, Attributes[:reset] + prepend)
|
111
|
-
|
113
|
+
prepend + string + append
|
112
114
|
end
|
113
115
|
|
114
116
|
# Deletes all mIRC formatting codes from the string. This strips
|
@@ -119,7 +121,7 @@ module Cinch
|
|
119
121
|
# @return [String] The filtered string
|
120
122
|
# @since 2.2.0
|
121
123
|
def self.unformat(string)
|
122
|
-
string.gsub(/[\x02\x0f\x16\x1d\x1f\x12]|\x03(\d{1,2}(,\d{1,2})?)?/,
|
124
|
+
string.gsub(/[\x02\x0f\x16\x1d\x1f\x12]|\x03(\d{1,2}(,\d{1,2})?)?/, "")
|
123
125
|
end
|
124
126
|
end
|
125
127
|
end
|