blur 2.1.2 → 2.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -15
- data/library/blur.rb +6 -6
- data/library/blur/callbacks.rb +11 -13
- data/library/blur/client.rb +54 -20
- data/library/blur/handling.rb +61 -0
- data/library/blur/network.rb +84 -37
- data/library/blur/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e3a0bf486ae6b8b30c925220195462b412e23bd62e767e2996c698273d5bf18
|
4
|
+
data.tar.gz: 733539cbd3f671eb799f541523031ca42303184db7866b5113058486c664c95a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8517510ecd51f045b995fcd42d00d1da7587d7fb2f36911e59bc6ed9f2478e7076b2bcdfca1290001e276392f3ad63dc9829fb90a0b67432e1223ca4bde5e48f
|
7
|
+
data.tar.gz: 0bac6a2de2bc5d1d8294ba2d9342ffde0d39fedc40b318d73a5c5e187c1de298ad371a94bf4c67bd6433ee7ba896d24cd945408c869d3c4a4149a289b54ac6fd
|
data/README.md
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
Blur
|
2
|
-
====
|
1
|
+
# Blur
|
3
2
|
Blur is an event-driven IRC-framework written in and for Ruby.
|
4
3
|
|
5
4
|
There are a bunch of other well-written, well-running IRC libraries made for
|
@@ -7,18 +6,16 @@ Ruby, but for me, they don't quite cut it as **the** library I wanted to use for
|
|
7
6
|
my IRC services. That's how Blur came to be.
|
8
7
|
|
9
8
|
[![Build Status](https://travis-ci.org/mkroman/blur.svg?branch=isupport)](https://travis-ci.org/mkroman/blur)
|
10
|
-
[![Dependency Status](https://gemnasium.com/mkroman/blur.svg)](https://gemnasium.com/mkroman/blur)
|
11
9
|
|
12
|
-
|
13
|
-
--------
|
14
|
-
* SSL/TLS encryption
|
15
|
-
* Connect to multiple networks
|
16
|
-
* Non-blocking connections (no threading)
|
17
|
-
* Extensible with scripts, (re)loadable during runtime
|
18
|
-
* Modular, makes it a piece of cake to extend its IRC-capability
|
10
|
+
## Getting started
|
19
11
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
12
|
+
|
13
|
+
## Documentation
|
14
|
+
|
15
|
+
Documentation is available [here](https://www.rubydoc.info/github/mkroman/blur)
|
16
|
+
|
17
|
+
## Features
|
18
|
+
* SSL/TLS connections
|
19
|
+
* Connect to multiple networks in a single process
|
20
|
+
* Non-blocking connections (no threading just for networking)
|
21
|
+
* Extensible with scripts that are (re)loadable during runtime
|
data/library/blur.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'yaml'
|
4
4
|
require 'socket'
|
5
|
+
require 'base64'
|
5
6
|
require 'ostruct'
|
6
7
|
require 'openssl'
|
7
8
|
|
@@ -28,8 +29,7 @@ require 'blur/network/connection'
|
|
28
29
|
# It allows the developer to extend it in multiple ways.
|
29
30
|
# It can be by handlers, scripts, communications, and what have you.
|
30
31
|
module Blur
|
31
|
-
|
32
|
-
@@scripts = {}
|
32
|
+
class ConfigError < StandardError; end
|
33
33
|
|
34
34
|
# Creates a new superscript class and inserts it into the list of scripts.
|
35
35
|
def self.Script name, *args, &block
|
@@ -39,12 +39,12 @@ module Blur
|
|
39
39
|
klass.class_exec &block
|
40
40
|
klass.init
|
41
41
|
|
42
|
-
|
42
|
+
scripts[name] = klass
|
43
43
|
end
|
44
44
|
|
45
45
|
# Gets all superscript classes.
|
46
46
|
def self.scripts
|
47
|
-
|
47
|
+
@scripts ||= {}
|
48
48
|
end
|
49
49
|
|
50
50
|
# Resets all scripts.
|
@@ -52,8 +52,8 @@ module Blur
|
|
52
52
|
# This method will call `deinit` on each script class before removing them to
|
53
53
|
# give them a chance to clean up.
|
54
54
|
def self.reset_scripts!
|
55
|
-
|
56
|
-
|
55
|
+
scripts.each_value &:deinit
|
56
|
+
scripts.clear
|
57
57
|
end
|
58
58
|
|
59
59
|
# Instantiates a client with given options and then makes the client instance
|
data/library/blur/callbacks.rb
CHANGED
@@ -2,29 +2,27 @@
|
|
2
2
|
|
3
3
|
module Blur
|
4
4
|
module Callbacks
|
5
|
-
# Our list of callbacks.
|
6
|
-
@@callbacks = {}
|
7
|
-
|
8
5
|
# Get a list of callbacks registered.
|
9
6
|
#
|
10
7
|
# @returns [Array] the list of callbacks
|
11
8
|
def callbacks
|
12
|
-
|
9
|
+
@callbacks ||= {}
|
13
10
|
end
|
14
11
|
|
15
12
|
# Emit a new event with given arguments.
|
16
13
|
#
|
17
14
|
# @param name [Symbol] The event name.
|
18
15
|
# @param args [optional, Array] The list of arguments to pass.
|
16
|
+
# @return [true, false] True if any callbacks were invoked, nil otherwise
|
19
17
|
def emit name, *args
|
20
|
-
|
21
|
-
|
22
|
-
end
|
18
|
+
# Trigger callbacks in scripts before triggering events in the client.
|
19
|
+
EM.defer { notify_scripts name, *args }
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
matching_callbacks = callbacks[name]
|
22
|
+
return false unless matching_callbacks&.any?
|
23
|
+
|
24
|
+
EM.defer do
|
25
|
+
matching_callbacks.each { |callback| callback.call *args }
|
28
26
|
end
|
29
27
|
end
|
30
28
|
|
@@ -33,10 +31,10 @@ module Blur
|
|
33
31
|
# @param name [Symbol] The event name.
|
34
32
|
# @yield [args, ...] The arguments passed from #emit.
|
35
33
|
def on name, &block
|
36
|
-
(
|
34
|
+
(callbacks[name] ||= []) << block
|
37
35
|
end
|
38
36
|
|
39
|
-
|
37
|
+
protected
|
40
38
|
|
41
39
|
def notify_scripts name, *args
|
42
40
|
scripts = @scripts.values.select{|script| script.class.events.key? name }
|
data/library/blur/client.rb
CHANGED
@@ -9,13 +9,14 @@ module Blur
|
|
9
9
|
# distributing the incoming commands to the right networks and scripts.
|
10
10
|
class Client
|
11
11
|
include Callbacks
|
12
|
-
include Handling
|
12
|
+
include Handling
|
13
|
+
include Logging
|
13
14
|
|
14
15
|
# Client error.
|
15
16
|
Error = Class.new StandardError
|
16
17
|
|
17
18
|
# The default environment.
|
18
|
-
ENVIRONMENT = ENV['BLUR_ENV'] || 'development'
|
19
|
+
ENVIRONMENT = ENV['BLUR_ENV'] || 'development'.freeze
|
19
20
|
|
20
21
|
# The default configuration.
|
21
22
|
DEFAULT_CONFIG = {
|
@@ -33,8 +34,10 @@ module Blur
|
|
33
34
|
attr_accessor :config
|
34
35
|
# @return [Hash] initialized scripts.
|
35
36
|
attr_accessor :scripts
|
36
|
-
|
37
|
+
# @return [Boolean] whether verbose logging is enabled.
|
37
38
|
attr_accessor :verbose
|
39
|
+
# @return [String] the path to the currently used config file.
|
40
|
+
attr_accessor :config_path
|
38
41
|
|
39
42
|
# Instantiates the client, stores the options, instantiates the networks
|
40
43
|
# and then loads available scripts.
|
@@ -49,11 +52,15 @@ module Blur
|
|
49
52
|
@environment = options[:environment]
|
50
53
|
@verbose = options[:verbose] == true
|
51
54
|
|
55
|
+
unless @config_path
|
56
|
+
raise ConfigError, 'missing config file path in :config_path option'
|
57
|
+
end
|
58
|
+
|
52
59
|
load_config!
|
53
60
|
|
54
61
|
networks = @config['blur']['networks']
|
55
62
|
|
56
|
-
if networks
|
63
|
+
if networks&.any?
|
57
64
|
networks.each do |network_options|
|
58
65
|
@networks.<< Network.new network_options, self
|
59
66
|
end
|
@@ -106,10 +113,10 @@ module Blur
|
|
106
113
|
# @param [optional, Symbol] signal The signal received by the system, if any.
|
107
114
|
def quit signal = :SIGINT
|
108
115
|
@networks.each do |network|
|
109
|
-
network.transmit :QUIT,
|
116
|
+
network.transmit :QUIT, 'Got SIGINT?'
|
110
117
|
network.disconnect
|
111
118
|
end
|
112
|
-
|
119
|
+
|
113
120
|
EventMachine.stop
|
114
121
|
end
|
115
122
|
|
@@ -127,20 +134,49 @@ module Blur
|
|
127
134
|
# Loads all scripts in the script directory.
|
128
135
|
def load_scripts!
|
129
136
|
scripts_dir = File.expand_path @config['blur']['scripts_dir']
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
end
|
137
|
+
script_file_paths = Dir.glob File.join scripts_dir, '*.rb'
|
138
|
+
|
139
|
+
# Sort the script file paths by file name so they load by alphabetical
|
140
|
+
# order.
|
141
|
+
#
|
142
|
+
# This will make it possible to create a script called '10_database.rb'
|
143
|
+
# which will be loaded before '20_settings.rb' and non-numeric prefixes
|
144
|
+
# will be loaded after that.
|
145
|
+
script_file_paths = script_file_paths.sort do |a, b|
|
146
|
+
File.basename(a) <=> File.basename(b)
|
141
147
|
end
|
142
148
|
|
149
|
+
script_file_paths.each { |script_path| load_script_file script_path }
|
150
|
+
|
151
|
+
initialize_superscripts
|
152
|
+
|
153
|
+
emit :scripts_loaded
|
154
|
+
end
|
155
|
+
|
156
|
+
# Loads the given +file_path+ as a Ruby script, wrapping it in an anonymous
|
157
|
+
# module to protect our global namespace.
|
158
|
+
#
|
159
|
+
# @param [String] file_path the path to the ruby script.
|
160
|
+
#
|
161
|
+
# @raise [Exception] if there was any problems loading the file
|
162
|
+
def load_script_file file_path
|
163
|
+
load file_path, true
|
164
|
+
rescue Exception => exception
|
165
|
+
warn "The script `#{file_path}' failed to load"
|
166
|
+
warn "#{exception.class}: #{exception.message}"
|
167
|
+
warn ''
|
168
|
+
warn 'Backtrace:', '---', exception.backtrace
|
169
|
+
end
|
170
|
+
|
171
|
+
# Instantiates each +SuperScript+ in the +Blur.scripts+ list by manually
|
172
|
+
# allocating an instance and calling #initialize on it, then the instance is
|
173
|
+
# stored in +Client#scripts+.
|
174
|
+
#
|
175
|
+
# @raise [Exception] any exception that might occur in any scripts'
|
176
|
+
# #initialize method.
|
177
|
+
def initialize_superscripts
|
143
178
|
scripts_config = @config['scripts']
|
179
|
+
scripts_cache_dir = File.expand_path @config['blur']['cache_dir']
|
144
180
|
|
145
181
|
Blur.scripts.each do |name, superscript|
|
146
182
|
script = superscript.allocate
|
@@ -151,8 +187,6 @@ module Blur
|
|
151
187
|
|
152
188
|
@scripts[name] = script
|
153
189
|
end
|
154
|
-
|
155
|
-
emit :scripts_loaded
|
156
190
|
end
|
157
191
|
|
158
192
|
# Unloads initialized scripts and superscripts.
|
@@ -167,7 +201,7 @@ module Blur
|
|
167
201
|
Blur.reset_scripts!
|
168
202
|
end
|
169
203
|
|
170
|
-
|
204
|
+
private
|
171
205
|
|
172
206
|
# Load the user-specified configuration file.
|
173
207
|
#
|
data/library/blur/handling.rb
CHANGED
@@ -247,6 +247,67 @@ module Blur
|
|
247
247
|
network.isupport.parse *params
|
248
248
|
end
|
249
249
|
|
250
|
+
# Received when the server supports capability negotiation.
|
251
|
+
def got_cap network, message
|
252
|
+
id, command = message.parameters[0..1]
|
253
|
+
|
254
|
+
case command
|
255
|
+
when 'ACK'
|
256
|
+
capabilities = message.parameters[2]&.split
|
257
|
+
|
258
|
+
if capabilities&.include? 'sasl' and network.sasl?
|
259
|
+
network.transmit :AUTHENTICATE, 'PLAIN'
|
260
|
+
else
|
261
|
+
network.cap_end
|
262
|
+
end
|
263
|
+
when 'NAK'
|
264
|
+
capabilities = message.parameters[2]&.split
|
265
|
+
|
266
|
+
if capabilities&.include? 'sasl' and network.sasl?
|
267
|
+
puts "The server does not support SASL, but you've configured it " \
|
268
|
+
"as such! Disconnecting!"
|
269
|
+
|
270
|
+
network.disconnect
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def got_001 network, message
|
277
|
+
if network.waiting_for_cap
|
278
|
+
network.abort_cap_neg
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def got_authenticate network, message
|
283
|
+
case message.parameters[0]
|
284
|
+
when '+'
|
285
|
+
return unless network.sasl?
|
286
|
+
sasl = network.options['sasl']
|
287
|
+
|
288
|
+
response = "#{sasl['username']}\x00#{sasl['username']}\x00#{sasl['password']}"
|
289
|
+
network.transmit :AUTHENTICATE, Base64.encode64(response).strip
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
# :server 900 <nick> <nick>!<ident>@<host> <account> :You are now logged in as <user>
|
294
|
+
# RPL_LOGGEDIN SASL
|
295
|
+
def got_900 network, message
|
296
|
+
if network.waiting_for_cap
|
297
|
+
network.cap_end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
# :server 904 <nick> :SASL authentication failed
|
302
|
+
# ERR_SASLFAIL
|
303
|
+
def got_904 network, message
|
304
|
+
nick, message = message.parameters
|
305
|
+
|
306
|
+
puts "SASL authentication failed! Disconnecting!"
|
307
|
+
|
308
|
+
network.disconnect
|
309
|
+
end
|
310
|
+
|
250
311
|
alias_method :got_353, :got_name_reply
|
251
312
|
alias_method :got_422, :got_end_of_motd
|
252
313
|
alias_method :got_376, :got_end_of_motd
|
data/library/blur/network.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Blur
|
4
4
|
# The +Network+ module is to be percieved as an IRC network.
|
@@ -7,13 +7,21 @@ module Blur
|
|
7
7
|
# for network-related structures, such as {User}, {Channel} and {Command}.
|
8
8
|
class Network
|
9
9
|
include Logging
|
10
|
-
|
10
|
+
|
11
11
|
# +ConnectionError+ should only be triggered from within {Connection}.
|
12
12
|
class ConnectionError < StandardError; end
|
13
13
|
|
14
|
+
# Returns a unique identifier for this network.
|
15
|
+
#
|
16
|
+
# You can override the id in your network configuration by setting an 'id'
|
17
|
+
# key with the id you want.. If no id is specified, the the id will be
|
18
|
+
# constructed from the hostname and port number
|
19
|
+
# in the format "<host>:<port>"
|
20
|
+
#
|
21
|
+
# @return [String] the unique identifier for this network.
|
22
|
+
attr_reader :id
|
14
23
|
# @return [Hash] the network options.
|
15
24
|
attr_accessor :options
|
16
|
-
|
17
25
|
# @return [Hash] the map of users that is known.
|
18
26
|
attr_accessor :users
|
19
27
|
# @return [Hash] the map of channels the client is in.
|
@@ -24,24 +32,41 @@ module Blur
|
|
24
32
|
attr_accessor :connection
|
25
33
|
# @return [Network::ISupport] the network isupport specs.
|
26
34
|
attr_accessor :isupport
|
35
|
+
# @return [Boolean] true if we're waiting for a capability negotiation.
|
36
|
+
attr_reader :waiting_for_cap
|
27
37
|
|
28
38
|
# Check whether or not connection is established.
|
29
|
-
def connected
|
39
|
+
def connected?
|
40
|
+
@connection&.established?
|
41
|
+
end
|
30
42
|
|
31
43
|
# Get the remote hostname.
|
32
44
|
#
|
33
45
|
# @return [String] the remote hostname.
|
34
|
-
def host
|
46
|
+
def host
|
47
|
+
@options['hostname']
|
48
|
+
end
|
35
49
|
|
36
50
|
# Get the remote port.
|
37
51
|
# If no port is specified, it returns 6697 if using a secure connection,
|
38
52
|
# returns 6667 otherwise.
|
39
53
|
#
|
40
54
|
# @return [Fixnum] the remote port
|
41
|
-
def port
|
42
|
-
|
55
|
+
def port
|
56
|
+
@options['port'] ||= secure? ? 6697 : 6667
|
57
|
+
end
|
58
|
+
|
43
59
|
# Check to see if it's a secure connection.
|
44
|
-
def secure
|
60
|
+
def secure?
|
61
|
+
@options['secure'] == true
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [Boolean] whether we want to authenticate with SASL.
|
65
|
+
def sasl?
|
66
|
+
@options['sasl'] &&
|
67
|
+
@options['sasl']['username'] &&
|
68
|
+
@options['sasl']['password']
|
69
|
+
end
|
45
70
|
|
46
71
|
# Instantiates the network.
|
47
72
|
#
|
@@ -52,17 +77,17 @@ module Blur
|
|
52
77
|
# @option options [optional, String] :username (Copies :nickname)
|
53
78
|
# The username to use. This is also known as the ident.
|
54
79
|
# @option options [optional, String] :realname (Copies :username)
|
55
|
-
# The
|
80
|
+
# The "real name" that we want to use. This is usually what shows up
|
56
81
|
# as "Name" when you whois a user.
|
57
82
|
# @option options [optional, String] :password The password for the network.
|
58
83
|
# This is sometimes needed for private networks.
|
59
|
-
# @option options [optional, Fixnum] :port (6697 if ssl, otherwise 6667)
|
84
|
+
# @option options [optional, Fixnum] :port (6697 if ssl, otherwise 6667)
|
60
85
|
# The remote port we want to connect to.
|
61
86
|
# @option options [optional, Boolean] :secure Set whether this is a secure
|
62
87
|
# (SSL-encrypted) connection.
|
63
88
|
# @option options [optional, String] :ssl_cert_file Local path of a
|
64
89
|
# readable file that contains a X509 CA certificate to validate against.
|
65
|
-
# @option options [optional, String] :ssl_fingerprint Validate that the
|
90
|
+
# @option options [optional, String] :ssl_fingerprint Validate that the
|
66
91
|
# remote certificate matches the specified fingerprint.
|
67
92
|
# @option options [optional, Boolean] :ssl_no_verify Disable verification
|
68
93
|
# alltogether.
|
@@ -72,20 +97,18 @@ module Blur
|
|
72
97
|
@users = {}
|
73
98
|
@channels = {}
|
74
99
|
@isupport = ISupport.new self
|
75
|
-
|
100
|
+
|
76
101
|
unless options['nickname']
|
77
|
-
|
78
|
-
|
79
|
-
else
|
80
|
-
raise ArgumentError, "Network configuration is missing a nickname"
|
81
|
-
end
|
102
|
+
raise ArgumentError, 'Network configuration for ' \
|
103
|
+
"`#{id}' is missing a nickname"
|
82
104
|
end
|
83
|
-
|
105
|
+
|
84
106
|
@options['username'] ||= @options['nickname']
|
85
107
|
@options['realname'] ||= @options['username']
|
86
108
|
@options['channels'] ||= []
|
109
|
+
@id = options.fetch 'id', "#{host}:#{port}"
|
87
110
|
end
|
88
|
-
|
111
|
+
|
89
112
|
# Send a message to a recipient.
|
90
113
|
#
|
91
114
|
# @param [String, #to_s] recipient the recipient.
|
@@ -93,53 +116,55 @@ module Blur
|
|
93
116
|
def say recipient, message
|
94
117
|
transmit :PRIVMSG, recipient.to_s, message
|
95
118
|
end
|
96
|
-
|
119
|
+
|
120
|
+
# Forwards the received message to the client instance.
|
121
|
+
#
|
97
122
|
# Called when the network connection has enough data to form a command.
|
98
123
|
def got_message message
|
99
124
|
@client.got_message self, message
|
100
|
-
rescue =>
|
101
|
-
puts "#{
|
125
|
+
rescue StandardError => exception
|
126
|
+
puts "#{exception.class}: #{exception.message}"
|
102
127
|
puts
|
103
|
-
puts
|
104
|
-
puts
|
128
|
+
puts '---'
|
129
|
+
puts exception.backtrace
|
105
130
|
end
|
106
|
-
|
131
|
+
|
107
132
|
# Find a channel by its name.
|
108
133
|
#
|
109
134
|
# @param [String] name the channel name.
|
110
135
|
# @return [Network::Channel] the matching channel, or nil.
|
111
136
|
def channel_by_name name
|
112
|
-
@channels.find {|channel| channel.name == name }
|
137
|
+
@channels.find { |channel| channel.name == name }
|
113
138
|
end
|
114
|
-
|
139
|
+
|
115
140
|
# Find all instances of channels in which there is a user with the nick
|
116
141
|
# +nick+.
|
117
142
|
#
|
118
143
|
# @param [String] nick the nickname.
|
119
144
|
# @return [Array] a list of channels in which the user is located, or nil.
|
120
145
|
def channels_with_user nick
|
121
|
-
@channels.select {|channel| channel.user_by_nick nick }
|
146
|
+
@channels.select { |channel| channel.user_by_nick nick }
|
122
147
|
end
|
123
148
|
|
124
149
|
# Returns a list of user prefixes that a nick might contain.
|
125
150
|
#
|
126
151
|
# @return [Array<String>] a list of user prefixes.
|
127
152
|
def user_prefixes
|
128
|
-
isupport[
|
153
|
+
isupport['PREFIX'].values
|
129
154
|
end
|
130
155
|
|
131
156
|
# Returns a list of user modes that also gives a users nick a prefix.
|
132
157
|
#
|
133
158
|
# @return [Array<String>] a list of user modes.
|
134
159
|
def user_prefix_modes
|
135
|
-
isupport[
|
160
|
+
isupport['PREFIX'].keys
|
136
161
|
end
|
137
162
|
|
138
163
|
# Returns a list of channel flags (channel mode D).
|
139
164
|
#
|
140
165
|
# @return [Array<String>] a list of channel flags.
|
141
166
|
def channel_flags
|
142
|
-
isupport[
|
167
|
+
isupport['CHANMODES']['D']
|
143
168
|
end
|
144
169
|
|
145
170
|
# Attempt to establish a connection and send initial data.
|
@@ -151,25 +176,45 @@ module Blur
|
|
151
176
|
|
152
177
|
# Called when the connection was successfully established.
|
153
178
|
def connected!
|
179
|
+
if sasl?
|
180
|
+
@waiting_for_cap = true
|
181
|
+
|
182
|
+
transmit :CAP, 'REQ', 'sasl'
|
183
|
+
end
|
184
|
+
|
154
185
|
transmit :PASS, @options['password'] if @options['password']
|
155
186
|
transmit :NICK, @options['nickname']
|
156
187
|
transmit :USER, @options['username'], 'void', 'void', @options['realname']
|
157
188
|
end
|
158
189
|
|
190
|
+
# Called when the server doesn't support capability negotiation.
|
191
|
+
def abort_cap_neg
|
192
|
+
@waiting_for_cap = false
|
193
|
+
|
194
|
+
puts "Server does not support capability negotiation"
|
195
|
+
end
|
196
|
+
|
197
|
+
# Called when we're done with capability negotiation.
|
198
|
+
def cap_end
|
199
|
+
@waiting_for_cap = false
|
200
|
+
|
201
|
+
transmit :CAP, 'END'
|
202
|
+
end
|
203
|
+
|
159
204
|
# Called when the connection was closed.
|
160
205
|
def disconnected!
|
161
|
-
@channels.each {|
|
206
|
+
@channels.each { |_name, channel| channel.users.clear }
|
162
207
|
@channels.clear
|
163
208
|
@users.clear
|
164
209
|
|
165
210
|
@client.network_connection_closed self
|
166
211
|
end
|
167
|
-
|
212
|
+
|
168
213
|
# Terminate the connection and clear all channels and users.
|
169
214
|
def disconnect
|
170
215
|
@connection.close_connection_after_writing
|
171
216
|
end
|
172
|
-
|
217
|
+
|
173
218
|
# Transmit a command to the server.
|
174
219
|
#
|
175
220
|
# @param [Symbol, String] name the command name.
|
@@ -178,9 +223,11 @@ module Blur
|
|
178
223
|
message = IRCParser::Message.new command: name.to_s, parameters: arguments
|
179
224
|
|
180
225
|
if @client.verbose
|
181
|
-
|
226
|
+
formatted_command = message.command.to_s.ljust 8, ' '
|
227
|
+
formatted_params = message.parameters.map(&:inspect).join ' '
|
228
|
+
log "#{'→' ^ :red} #{formatted_command} #{formatted_params}"
|
182
229
|
end
|
183
|
-
|
230
|
+
|
184
231
|
@connection.send_data "#{message}\r\n"
|
185
232
|
end
|
186
233
|
|
@@ -196,7 +243,7 @@ module Blur
|
|
196
243
|
|
197
244
|
# Convert it to a debug-friendly format.
|
198
245
|
def to_s
|
199
|
-
%
|
246
|
+
%(#<#{self.class.name} "#{host}":#{port}>)
|
200
247
|
end
|
201
248
|
end
|
202
249
|
end
|
data/library/blur/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blur
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mikkel Kroman
|
8
8
|
autorequire:
|
9
9
|
bindir: executables
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deep_merge
|
@@ -96,8 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
98
|
requirements: []
|
99
|
-
|
100
|
-
rubygems_version: 2.7.6
|
99
|
+
rubygems_version: 3.0.3
|
101
100
|
signing_key:
|
102
101
|
specification_version: 4
|
103
102
|
summary: An event-driven IRC-framework for Ruby.
|