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