blur 2.1.3 → 2.1.6
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/executables/blur +16 -15
- data/library/blur/callbacks.rb +12 -16
- data/library/blur/channel.rb +11 -8
- data/library/blur/client.rb +36 -43
- data/library/blur/handling.rb +140 -113
- data/library/blur/network/connection.rb +24 -28
- data/library/blur/network/isupport.rb +38 -32
- data/library/blur/network.rb +87 -14
- data/library/blur/script.rb +21 -12
- data/library/blur/script_cache.rb +12 -10
- data/library/blur/user.rb +43 -26
- data/library/blur/version.rb +3 -3
- data/library/blur.rb +16 -14
- metadata +8 -10
- data/library/blur/enhancements.rb +0 -39
- data/library/blur/logging.rb +0 -41
@@ -1,20 +1,22 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'English'
|
2
4
|
|
3
5
|
module Blur
|
4
6
|
class Network
|
5
7
|
# ISupport class that enables servers to announce what they support.
|
6
|
-
#
|
8
|
+
#
|
7
9
|
# @see https://tools.ietf.org/html/draft-brocklesby-irc-isupport-03
|
8
10
|
class ISupport < Hash
|
9
11
|
# Return the network reference.
|
10
12
|
attr_accessor :network
|
11
13
|
|
12
14
|
# ISUPPORT parameters which should always be casted to numeric values.
|
13
|
-
|
14
|
-
|
15
|
+
NUMERIC_PARAMS = %w[CHANNELLEN MODES NICKLEN KICKLEN TOPICLEN AWAYLEN
|
16
|
+
MAXCHANNELS MAXBANS MAXPARA MAXTARGETS].freeze
|
15
17
|
|
16
18
|
# Our parsers for parameters that require special treatment.
|
17
|
-
|
19
|
+
PARSERS = {
|
18
20
|
# CHANLIMIT=pfx:num[,pfx:num,...]
|
19
21
|
#
|
20
22
|
# This parameter specifies the maximum number of channels that a client
|
@@ -24,10 +26,10 @@ module Blur
|
|
24
26
|
# the client may join in total. If there is no limit to the number of
|
25
27
|
# certain channel type(s) a client may join, the limit should be
|
26
28
|
# specified as the empty string, for example "#:".
|
27
|
-
%w[CHANLIMIT] =>
|
28
|
-
|
29
|
-
params = value.split
|
30
|
-
mappings = params.map{|param| param.split
|
29
|
+
%w[CHANLIMIT] => lambda do |value|
|
30
|
+
{}.tap do |result|
|
31
|
+
params = value.split ','
|
32
|
+
mappings = params.map { |param| param.split ':' }
|
31
33
|
|
32
34
|
mappings.each do |prefixes, limit|
|
33
35
|
prefixes.each_char do |prefix|
|
@@ -48,10 +50,12 @@ module Blur
|
|
48
50
|
#
|
49
51
|
# The order of the modes is from that which gives most privileges on
|
50
52
|
# the channel, to that which gives the least.
|
51
|
-
%w[PREFIX] =>
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
%w[PREFIX] => lambda do |value|
|
54
|
+
{}.tap do |result|
|
55
|
+
match = value.match(/^\((.+)\)(.*)/)
|
56
|
+
|
57
|
+
if match
|
58
|
+
modes, prefix = match[1..2]
|
55
59
|
|
56
60
|
modes.chars.each_with_index do |char, index|
|
57
61
|
result[char] = prefix[index]
|
@@ -77,39 +81,41 @@ module Blur
|
|
77
81
|
# mode is removed both in the client's and server's MODE command.
|
78
82
|
# o Type D: Modes that change a setting on the channel. These modes
|
79
83
|
# never take a parameter.
|
80
|
-
%w[CHANMODES] =>
|
81
|
-
|
82
|
-
r[
|
84
|
+
%w[CHANMODES] => lambda do |value|
|
85
|
+
{}.tap do |r|
|
86
|
+
r['A'], r['B'], r['C'], r['D'] = value.split(',').map &:chars
|
83
87
|
end
|
84
88
|
end,
|
85
89
|
|
86
90
|
# Cast known params that are numeric, to a numeric value.
|
87
|
-
|
91
|
+
NUMERIC_PARAMS => lambda do |value|
|
88
92
|
value.to_i
|
89
93
|
end
|
90
|
-
}
|
94
|
+
}.freeze
|
91
95
|
|
92
96
|
# Initialize a new ISupport with a network reference.
|
93
|
-
#
|
97
|
+
#
|
94
98
|
# @param network [Network] The parent network.
|
95
99
|
def initialize network
|
100
|
+
super
|
101
|
+
|
96
102
|
@network = network
|
97
103
|
|
98
104
|
# Set default ISUPPORT values.
|
99
105
|
#
|
100
106
|
# @see
|
101
107
|
# https://tools.ietf.org/html/draft-brocklesby-irc-isupport-03#appendix-A
|
102
|
-
self[
|
103
|
-
self[
|
104
|
-
self[
|
105
|
-
self[
|
106
|
-
self[
|
108
|
+
self['MODES'] = 3
|
109
|
+
self['PREFIX'] = { 'o' => '@', 'v' => '+' }
|
110
|
+
self['KICKLEN'] = 200
|
111
|
+
self['NICKLEN'] = 9
|
112
|
+
self['MAXLIST'] = { '#' => Float::INFINITY, '&' => Float::INFINITY }
|
107
113
|
self['TOPICLEN'] = 200
|
108
|
-
self[
|
109
|
-
self[
|
110
|
-
self[
|
111
|
-
self[
|
112
|
-
self[
|
114
|
+
self['CHANMODES'] = {}
|
115
|
+
self['CHANTYPES'] = %w[# &]
|
116
|
+
self['CHANLIMIT'] = { '#' => Float::INFINITY, '&' => Float::INFINITY }
|
117
|
+
self['CHANNELLEN'] = 200
|
118
|
+
self['CASEMAPPING'] = 'rfc1459'
|
113
119
|
end
|
114
120
|
|
115
121
|
# Parse a list of parameters to see what the server supports.
|
@@ -117,12 +123,12 @@ module Blur
|
|
117
123
|
# @param parameters [Array] The list of parameters.
|
118
124
|
def parse *params
|
119
125
|
params.each do |parameter|
|
120
|
-
name, value = parameter.split
|
126
|
+
name, value = parameter.split '='
|
121
127
|
|
122
128
|
if value
|
123
|
-
_, parser =
|
129
|
+
_, parser = PARSERS.find { |key, _value| key.include? name }
|
124
130
|
|
125
|
-
self[name] = parser.nil? ? value : parser.(value)
|
131
|
+
self[name] = parser.nil? ? value : parser.call(value)
|
126
132
|
else
|
127
133
|
self[name] = true
|
128
134
|
end
|
data/library/blur/network.rb
CHANGED
@@ -6,11 +6,12 @@ module Blur
|
|
6
6
|
# Although the connection is a part of the network module, it is mainly used
|
7
7
|
# for network-related structures, such as {User}, {Channel} and {Command}.
|
8
8
|
class Network
|
9
|
-
include Logging
|
10
|
-
|
11
9
|
# +ConnectionError+ should only be triggered from within {Connection}.
|
12
10
|
class ConnectionError < StandardError; end
|
13
11
|
|
12
|
+
DEFAULT_PING_INTERVAL = 30
|
13
|
+
DEFAULT_RECONNECT = true
|
14
|
+
|
14
15
|
# Returns a unique identifier for this network.
|
15
16
|
#
|
16
17
|
# You can override the id in your network configuration by setting an 'id'
|
@@ -20,6 +21,8 @@ module Blur
|
|
20
21
|
#
|
21
22
|
# @return [String] the unique identifier for this network.
|
22
23
|
attr_reader :id
|
24
|
+
# @return [String] the current nickname.
|
25
|
+
attr_accessor :nickname
|
23
26
|
# @return [Hash] the network options.
|
24
27
|
attr_accessor :options
|
25
28
|
# @return [Hash] the map of users that is known.
|
@@ -32,8 +35,19 @@ module Blur
|
|
32
35
|
attr_accessor :connection
|
33
36
|
# @return [Network::ISupport] the network isupport specs.
|
34
37
|
attr_accessor :isupport
|
38
|
+
# @return [Array<String>] list of capabilities supported by the network.
|
39
|
+
attr_accessor :capabilities
|
35
40
|
# @return [Boolean] true if we're waiting for a capability negotiation.
|
36
41
|
attr_reader :waiting_for_cap
|
42
|
+
# @return [Time] the last time a pong was sent or received.
|
43
|
+
attr_accessor :last_pong_time
|
44
|
+
# The max PING interval for the server. This is used to determine when the
|
45
|
+
# client will attempt to send its own PING command.
|
46
|
+
#
|
47
|
+
# @note the actual time until a client PING is sent can vary by an
|
48
|
+
# additional 0-30 seconds.
|
49
|
+
# @return [Number] the max interval between pings from a server.
|
50
|
+
attr_accessor :server_ping_interval_max
|
37
51
|
|
38
52
|
# Check whether or not connection is established.
|
39
53
|
def connected?
|
@@ -94,15 +108,21 @@ module Blur
|
|
94
108
|
def initialize options, client = nil
|
95
109
|
@client = client
|
96
110
|
@options = options
|
111
|
+
# @log = ::Logging.logger[self]
|
97
112
|
@users = {}
|
98
113
|
@channels = {}
|
99
114
|
@isupport = ISupport.new self
|
115
|
+
@capabilities = []
|
116
|
+
@reconnect_interval = 3
|
117
|
+
@server_ping_interval_max = @options.fetch('server_ping_interval',
|
118
|
+
150).to_i
|
100
119
|
|
101
120
|
unless options['nickname']
|
102
121
|
raise ArgumentError, 'Network configuration for ' \
|
103
122
|
"`#{id}' is missing a nickname"
|
104
123
|
end
|
105
124
|
|
125
|
+
@nickname = options['nickname']
|
106
126
|
@options['username'] ||= @options['nickname']
|
107
127
|
@options['realname'] ||= @options['username']
|
108
128
|
@options['channels'] ||= []
|
@@ -122,11 +142,11 @@ module Blur
|
|
122
142
|
# Called when the network connection has enough data to form a command.
|
123
143
|
def got_message message
|
124
144
|
@client.got_message self, message
|
125
|
-
rescue StandardError =>
|
126
|
-
puts "#{
|
145
|
+
rescue StandardError => e
|
146
|
+
puts "#{e.class}: #{e.message}"
|
127
147
|
puts
|
128
148
|
puts '---'
|
129
|
-
puts
|
149
|
+
puts e.backtrace
|
130
150
|
end
|
131
151
|
|
132
152
|
# Find a channel by its name.
|
@@ -171,27 +191,74 @@ module Blur
|
|
171
191
|
#
|
172
192
|
# @see Connection
|
173
193
|
def connect
|
174
|
-
@
|
194
|
+
# @log.info "Connecting to #{self}"
|
195
|
+
|
196
|
+
begin
|
197
|
+
@connection = EventMachine.connect host, port, Connection, self
|
198
|
+
rescue EventMachine::ConnectionError => e
|
199
|
+
warn "Establishing connection to #{self} failed!"
|
200
|
+
warn e.message
|
201
|
+
|
202
|
+
schedule_reconnect
|
203
|
+
return
|
204
|
+
end
|
205
|
+
|
206
|
+
@ping_timer = EventMachine.add_periodic_timer DEFAULT_PING_INTERVAL do
|
207
|
+
periodic_ping_check
|
208
|
+
end
|
175
209
|
end
|
176
210
|
|
177
|
-
#
|
178
|
-
def
|
179
|
-
|
180
|
-
|
211
|
+
# Schedules a reconnect after a user-specified number of seconds.
|
212
|
+
def schedule_reconnect
|
213
|
+
# @log.info "Reconnecting to #{self} in #{@reconnect_interval} seconds"
|
214
|
+
|
215
|
+
EventMachine.add_timer @reconnect_interval do
|
216
|
+
connect
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def server_connection_timeout
|
221
|
+
@connection.close_connection
|
181
222
|
|
182
|
-
|
223
|
+
warn "Connection to #{self} timed out"
|
224
|
+
end
|
225
|
+
|
226
|
+
def periodic_ping_check
|
227
|
+
now = Time.now
|
228
|
+
seconds_since_pong = now - @last_pong_time
|
229
|
+
|
230
|
+
return unless seconds_since_pong >= @server_ping_interval_max
|
231
|
+
|
232
|
+
# @log.info "No PING request from the server in #{seconds_since_pong}s!"
|
233
|
+
|
234
|
+
transmit 'PING', now.to_s
|
235
|
+
|
236
|
+
# Wait 15 seconds and declare a timeout if we didn't get a PONG.
|
237
|
+
previous_pong_time = @last_pong_time.dup
|
238
|
+
|
239
|
+
EventMachine.add_timer 15 do
|
240
|
+
server_connection_timeout if @last_pong_time == previous_pong_time
|
183
241
|
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# Called when the connection was successfully established.
|
245
|
+
def connected!
|
246
|
+
@waiting_for_cap = true
|
247
|
+
@capabilities.clear
|
184
248
|
|
249
|
+
transmit :CAP, 'LS'
|
185
250
|
transmit :PASS, @options['password'] if @options['password']
|
186
251
|
transmit :NICK, @options['nickname']
|
187
252
|
transmit :USER, @options['username'], 'void', 'void', @options['realname']
|
253
|
+
|
254
|
+
@last_pong_time = Time.now
|
188
255
|
end
|
189
256
|
|
190
257
|
# Called when the server doesn't support capability negotiation.
|
191
258
|
def abort_cap_neg
|
192
259
|
@waiting_for_cap = false
|
193
260
|
|
194
|
-
puts
|
261
|
+
puts 'Server does not support capability negotiation'
|
195
262
|
end
|
196
263
|
|
197
264
|
# Called when we're done with capability negotiation.
|
@@ -203,11 +270,17 @@ module Blur
|
|
203
270
|
|
204
271
|
# Called when the connection was closed.
|
205
272
|
def disconnected!
|
206
|
-
@channels.each { |
|
273
|
+
@channels.each { |_, channel| channel.users.clear }
|
207
274
|
@channels.clear
|
208
275
|
@users.clear
|
276
|
+
@ping_timer.cancel
|
209
277
|
|
278
|
+
# @log.debug "Connection to #{self} lost!"
|
210
279
|
@client.network_connection_closed self
|
280
|
+
|
281
|
+
return unless @options.fetch('reconnect', DEFAULT_RECONNECT)
|
282
|
+
|
283
|
+
schedule_reconnect
|
211
284
|
end
|
212
285
|
|
213
286
|
# Terminate the connection and clear all channels and users.
|
@@ -225,7 +298,7 @@ module Blur
|
|
225
298
|
if @client.verbose
|
226
299
|
formatted_command = message.command.to_s.ljust 8, ' '
|
227
300
|
formatted_params = message.parameters.map(&:inspect).join ' '
|
228
|
-
|
301
|
+
puts "→ #{formatted_command} #{formatted_params}"
|
229
302
|
end
|
230
303
|
|
231
304
|
@connection.send_data "#{message}\r\n"
|
data/library/blur/script.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Blur
|
4
4
|
module Commands
|
@@ -27,7 +27,7 @@ module Blur
|
|
27
27
|
# command! '!ping' do |user, channel, args|
|
28
28
|
# channel.say "#{user}: pong"
|
29
29
|
# end
|
30
|
-
def command! command, *
|
30
|
+
def command! command, *_args, &block
|
31
31
|
id = (command_lut << command)
|
32
32
|
define_method :"_command_#{id}", &block
|
33
33
|
end
|
@@ -40,11 +40,11 @@ module Blur
|
|
40
40
|
|
41
41
|
klass.extend ClassMethods
|
42
42
|
klass.command_lut = CommandLUT.new
|
43
|
-
klass.register! message:
|
43
|
+
klass.register! message: lambda { |script, user, channel, line|
|
44
44
|
command, args = line.split ' ', 2
|
45
45
|
return unless command
|
46
46
|
|
47
|
-
if id = klass.command_lut.commands[command.downcase]
|
47
|
+
if (id = klass.command_lut.commands[command.downcase])
|
48
48
|
script.__send__ :"_command_#{id}", user, channel, args
|
49
49
|
end
|
50
50
|
}
|
@@ -56,7 +56,7 @@ module Blur
|
|
56
56
|
attr_accessor :name, :authors, :version, :description, :events
|
57
57
|
|
58
58
|
# Sets the author.
|
59
|
-
#
|
59
|
+
#
|
60
60
|
# @example
|
61
61
|
# Author 'John Doe <john.doe@example.com>'
|
62
62
|
def Author *authors
|
@@ -104,11 +104,16 @@ module Blur
|
|
104
104
|
(@events[name] ||= []) << method_name
|
105
105
|
end
|
106
106
|
|
107
|
-
def to_s
|
108
|
-
|
107
|
+
def to_s
|
108
|
+
inspect
|
109
|
+
end
|
110
|
+
|
111
|
+
def inspect
|
112
|
+
%(#<SuperScript:0x#{object_id.to_s 16}>)
|
113
|
+
end
|
109
114
|
|
110
|
-
alias
|
111
|
-
alias
|
115
|
+
alias author authors
|
116
|
+
alias Authors Author
|
112
117
|
end
|
113
118
|
|
114
119
|
# Called when when the superscript has been loaded and added to the list of
|
@@ -122,7 +127,7 @@ module Blur
|
|
122
127
|
# Reference to the main client that holds the script.
|
123
128
|
attr_accessor :_client_ref
|
124
129
|
|
125
|
-
# Script-specific configuration that is read from the main configuration
|
130
|
+
# Script-specific configuration that is read from the main configuration
|
126
131
|
# file.
|
127
132
|
attr_accessor :config
|
128
133
|
|
@@ -132,7 +137,9 @@ module Blur
|
|
132
137
|
def unloaded; end
|
133
138
|
|
134
139
|
# Gets the instantiated script with +name+.
|
135
|
-
def script name
|
140
|
+
def script name
|
141
|
+
_client_ref.scripts[name]
|
142
|
+
end
|
136
143
|
|
137
144
|
# Gets a human-readable representation of the script.
|
138
145
|
def inspect
|
@@ -142,6 +149,8 @@ module Blur
|
|
142
149
|
"@description=#{self.class.description.inspect}>"
|
143
150
|
end
|
144
151
|
|
145
|
-
def to_s
|
152
|
+
def to_s
|
153
|
+
inspect
|
154
|
+
end
|
146
155
|
end
|
147
156
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Blur
|
4
|
-
class ScriptCache
|
4
|
+
class ScriptCache
|
5
5
|
def initialize script_name, path, hash
|
6
6
|
@script_name = script_name
|
7
7
|
@path = path
|
@@ -9,20 +9,22 @@ module Blur
|
|
9
9
|
end
|
10
10
|
|
11
11
|
# Gets a cache +value+ by its +key+.
|
12
|
-
def [] key
|
12
|
+
def [] key
|
13
|
+
@hash[key]
|
14
|
+
end
|
13
15
|
|
14
16
|
# Sets the cache +key+ to the provided +value+.
|
15
|
-
def []= key, value
|
17
|
+
def []= key, value
|
18
|
+
@hash[key] = value
|
19
|
+
end
|
16
20
|
|
17
21
|
# Saves the cache as a YAML file.
|
18
22
|
def save
|
19
23
|
directory = File.dirname @path
|
20
|
-
|
21
|
-
unless File.directory? directory
|
22
|
-
Dir.mkdir directory
|
23
|
-
end
|
24
24
|
|
25
|
-
|
25
|
+
Dir.mkdir directory unless File.directory? directory
|
26
|
+
|
27
|
+
File.open @path, 'w' do |file|
|
26
28
|
YAML.dump @hash, file
|
27
29
|
end
|
28
30
|
end
|
@@ -31,7 +33,7 @@ module Blur
|
|
31
33
|
def self.load script_name, cache_dir
|
32
34
|
cache_path = File.join cache_dir, "#{script_name}.yml"
|
33
35
|
|
34
|
-
if File.
|
36
|
+
if File.exist? cache_path
|
35
37
|
object = YAML.load_file cache_path
|
36
38
|
|
37
39
|
ScriptCache.new script_name, cache_path, object
|
data/library/blur/user.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Blur
|
4
4
|
# The +User+ class is used for encapsulating a user and its properties.
|
5
5
|
#
|
6
6
|
# The user owns a reference to its parent channel.
|
7
7
|
#
|
8
|
-
# Modes can be set for a user, but Blur is not
|
8
|
+
# Modes can be set for a user, but Blur is not
|
9
9
|
# {http://www.irc.org/tech_docs/005.html ISupport}-compliant yet.
|
10
10
|
#
|
11
11
|
# @todo make so that channels *and* users belongs to the network, and not
|
@@ -24,16 +24,39 @@ module Blur
|
|
24
24
|
attr_accessor :network
|
25
25
|
attr_accessor :channels
|
26
26
|
|
27
|
+
# @return [Hash<String, String>] a map of symbols to channel user modes.
|
28
|
+
COMMON_SYMBOL_MODES = {
|
29
|
+
'@' => 'o',
|
30
|
+
'+' => 'v',
|
31
|
+
'%' => 'h',
|
32
|
+
'&' => 'a',
|
33
|
+
'~' => 'q'
|
34
|
+
}.freeze
|
35
|
+
|
27
36
|
# Check to see if the user is an admin (+a)
|
28
|
-
def admin
|
37
|
+
def admin?
|
38
|
+
@modes.include? 'a'
|
39
|
+
end
|
40
|
+
|
29
41
|
# Check to see if the user has voice (+v)
|
30
|
-
def voice
|
42
|
+
def voice?
|
43
|
+
@modes.include? 'v'
|
44
|
+
end
|
45
|
+
|
31
46
|
# Check to see if the user is the owner (+q)
|
32
|
-
def owner
|
47
|
+
def owner?
|
48
|
+
@modes.include? 'q'
|
49
|
+
end
|
50
|
+
|
33
51
|
# Check to see if the user is an operator (+o)
|
34
|
-
def operator
|
52
|
+
def operator?
|
53
|
+
@modes.include? 'o'
|
54
|
+
end
|
55
|
+
|
35
56
|
# Check to see if the user is an half-operator (+h)
|
36
|
-
def half_operator
|
57
|
+
def half_operator?
|
58
|
+
@modes.include? 'h'
|
59
|
+
end
|
37
60
|
|
38
61
|
# Instantiate a user with a nickname.
|
39
62
|
def initialize nick, network = nil
|
@@ -41,11 +64,11 @@ module Blur
|
|
41
64
|
@modes = String.new
|
42
65
|
@channels = []
|
43
66
|
@network = network
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
67
|
+
|
68
|
+
return unless (modes = prefix_to_mode(nick[0]))
|
69
|
+
|
70
|
+
@nick = nick[1..]
|
71
|
+
@modes = modes
|
49
72
|
end
|
50
73
|
|
51
74
|
# Merge the users mode corresponding to the leading character (+ or -).
|
@@ -56,26 +79,26 @@ module Blur
|
|
56
79
|
|
57
80
|
modes.each_char do |char|
|
58
81
|
case char
|
59
|
-
when
|
82
|
+
when '+'
|
60
83
|
addition = true
|
61
|
-
when
|
84
|
+
when '-'
|
62
85
|
addition = false
|
63
86
|
else
|
64
87
|
addition ? @modes.concat(char) : @modes.delete!(char)
|
65
88
|
end
|
66
89
|
end
|
67
90
|
end
|
68
|
-
|
91
|
+
|
69
92
|
# Send a private message to the user.
|
70
93
|
#
|
71
94
|
# @param [String] message the message to send.
|
72
95
|
def say message
|
73
96
|
@network.say self, message
|
74
97
|
end
|
75
|
-
|
98
|
+
|
76
99
|
# Convert it to a debug-friendly format.
|
77
100
|
def inspect
|
78
|
-
%
|
101
|
+
%(#<#{self.class.name}:0x#{object_id.to_s 16} @nick=#{@nick.inspect}>)
|
79
102
|
end
|
80
103
|
|
81
104
|
# Called when YAML attempts to save the object, which happens when a
|
@@ -83,23 +106,17 @@ module Blur
|
|
83
106
|
def to_yaml options = {}
|
84
107
|
@nick.to_yaml options
|
85
108
|
end
|
86
|
-
|
109
|
+
|
87
110
|
# Get the users nickname.
|
88
111
|
def to_s
|
89
112
|
@nick
|
90
113
|
end
|
91
114
|
|
92
|
-
|
115
|
+
private
|
93
116
|
|
94
117
|
# Translate a nickname-prefix to a mode character.
|
95
118
|
def prefix_to_mode prefix
|
96
|
-
|
97
|
-
when '@' then 'o'
|
98
|
-
when '+' then 'v'
|
99
|
-
when '%' then 'h'
|
100
|
-
when '&' then 'a'
|
101
|
-
when '~' then 'q'
|
102
|
-
end
|
119
|
+
COMMON_SYMBOL_MODES[prefix]
|
103
120
|
end
|
104
121
|
end
|
105
122
|
end
|
data/library/blur/version.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Blur
|
4
4
|
# The current version of Blur.
|
5
|
-
|
5
|
+
VERSION = '2.1.6'
|
6
6
|
|
7
7
|
# Get the current version.
|
8
8
|
#
|
9
9
|
# @return [String] The current version of Blur.
|
10
10
|
def self.version
|
11
|
-
|
11
|
+
VERSION
|
12
12
|
end
|
13
13
|
end
|
data/library/blur.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'yaml'
|
4
4
|
require 'socket'
|
@@ -11,28 +11,30 @@ require 'eventmachine'
|
|
11
11
|
require 'ircparser'
|
12
12
|
|
13
13
|
# Require all library files.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
require 'blur/network/isupport'
|
25
|
-
require 'blur/network/connection'
|
14
|
+
require_relative './blur/version'
|
15
|
+
require_relative './blur/callbacks'
|
16
|
+
require_relative './blur/script'
|
17
|
+
require_relative './blur/script_cache'
|
18
|
+
require_relative './blur/network'
|
19
|
+
require_relative './blur/client'
|
20
|
+
require_relative './blur/user'
|
21
|
+
require_relative './blur/channel'
|
22
|
+
require_relative './blur/network/isupport'
|
23
|
+
require_relative './blur/network/connection'
|
26
24
|
|
27
25
|
# Blur is a very modular IRC-framework for ruby.
|
28
26
|
#
|
29
27
|
# It allows the developer to extend it in multiple ways.
|
30
28
|
# It can be by handlers, scripts, communications, and what have you.
|
31
29
|
module Blur
|
30
|
+
# Client error.
|
31
|
+
class ClientError < StandardError; end
|
32
|
+
|
33
|
+
# Configuration file error.
|
32
34
|
class ConfigError < StandardError; end
|
33
35
|
|
34
36
|
# Creates a new superscript class and inserts it into the list of scripts.
|
35
|
-
def self.Script name, *
|
37
|
+
def self.Script name, *_args, &block
|
36
38
|
klass = Class.new SuperScript
|
37
39
|
klass.name = name
|
38
40
|
klass.events = {}
|