blur 1.5.3 → 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.
- data/library/blur.rb +27 -5
- data/library/blur/client.rb +56 -38
- data/library/blur/encryption.rb +17 -0
- data/library/blur/encryption/base64.rb +71 -0
- data/library/blur/encryption/fish.rb +80 -0
- data/library/blur/enhancements.rb +22 -0
- data/library/blur/handling.rb +108 -14
- data/library/blur/network.rb +78 -24
- data/library/blur/network/channel.rb +39 -1
- data/library/blur/network/command.rb +34 -1
- data/library/blur/network/connection.rb +53 -57
- data/library/blur/network/user.rb +44 -10
- data/library/blur/script.rb +35 -1
- data/library/blur/script/cache.rb +26 -1
- data/library/blur/script/messageparsing.rb +32 -1
- metadata +64 -14
data/library/blur.rb
CHANGED
@@ -5,15 +5,37 @@ require 'majic'
|
|
5
5
|
require 'socket'
|
6
6
|
require 'ostruct'
|
7
7
|
require 'openssl'
|
8
|
+
require 'eventmachine'
|
8
9
|
|
9
|
-
|
10
|
+
# Require all library files.
|
11
|
+
require 'blur/client'
|
12
|
+
require 'blur/script'
|
13
|
+
require 'blur/network'
|
14
|
+
require 'blur/encryption'
|
15
|
+
require 'blur/enhancements'
|
16
|
+
require 'blur/script/cache'
|
17
|
+
require 'blur/network/user'
|
18
|
+
require 'blur/network/channel'
|
19
|
+
require 'blur/network/command'
|
20
|
+
require 'blur/network/connection'
|
21
|
+
require 'blur/script/messageparsing'
|
10
22
|
|
23
|
+
# Blur is a very modular IRC-framework for ruby.
|
24
|
+
#
|
25
|
+
# It allows the developer to extend it in multiple ways.
|
26
|
+
# It can be by handlers, scripts, communications, and what have you.
|
11
27
|
module Blur
|
12
|
-
|
13
|
-
|
14
|
-
end
|
28
|
+
# The major and minor version-values of Blur.
|
29
|
+
Version = "1.6"
|
15
30
|
|
16
|
-
|
31
|
+
# Instantiates a client with given options and then makes the client instance
|
32
|
+
# evaluate the given block to form a DSL.
|
33
|
+
#
|
34
|
+
# @note The idea is that this should never stop or return anything.
|
35
|
+
# @param [Hash] options the options for the client.
|
36
|
+
# @option options [Array] networks list of hashes that contain network
|
37
|
+
# options.
|
38
|
+
def self.connect options = {}, &block
|
17
39
|
Client.new(options).tap do |client|
|
18
40
|
client.instance_eval &block
|
19
41
|
end.connect
|
data/library/blur/client.rb
CHANGED
@@ -3,35 +3,59 @@
|
|
3
3
|
require 'blur/handling'
|
4
4
|
|
5
5
|
module Blur
|
6
|
+
# The +Client+ class is the controller of the low-level access.
|
7
|
+
#
|
8
|
+
# It stores networks, scripts and callbacks, and is also encharge of
|
9
|
+
# distributing the incoming commands to the right networks and scripts.
|
6
10
|
class Client
|
7
11
|
include Handling
|
8
12
|
|
9
|
-
|
13
|
+
# @return [Array] the options that is passed upon initialization.
|
14
|
+
attr_accessor :options
|
15
|
+
# @return [Array] a list of scripts that is loaded during runtime.
|
16
|
+
attr_accessor :scripts
|
17
|
+
# @return [Array] a list of instantiated networks.
|
18
|
+
attr_accessor :networks
|
10
19
|
|
20
|
+
# Instantiates the client, stores the options, instantiates the networks
|
21
|
+
# and then loads available scripts.
|
22
|
+
#
|
23
|
+
# @param [Hash] options the options for the client.
|
24
|
+
# @option options [Array] networks list of hashes that contain network
|
25
|
+
# options.
|
11
26
|
def initialize options
|
12
27
|
@options = options
|
13
28
|
@scripts = []
|
14
29
|
@networks = []
|
15
30
|
@callbacks = {}
|
16
|
-
@connected = true
|
17
31
|
|
18
|
-
@networks = @options[:networks].map {
|
32
|
+
@networks = @options[:networks].map {|options| Network.new options }
|
19
33
|
|
20
34
|
load_scripts
|
21
35
|
trap 2, &method(:quit)
|
22
36
|
end
|
23
37
|
|
38
|
+
# Connect to each network available that is not already connected, then
|
39
|
+
# proceed to start the run-loop.
|
24
40
|
def connect
|
25
|
-
networks = @networks.select {
|
41
|
+
networks = @networks.select {|network| not network.connected? }
|
26
42
|
|
27
|
-
|
28
|
-
|
29
|
-
|
43
|
+
EventMachine.run do
|
44
|
+
networks.each do |network|
|
45
|
+
network.delegate = self
|
46
|
+
network.connect
|
47
|
+
end
|
48
|
+
|
49
|
+
EventMachine.error_handler{|e| p e }
|
30
50
|
end
|
31
|
-
|
32
|
-
run_loop
|
33
51
|
end
|
34
52
|
|
53
|
+
# Is called when a command have been received and parsed, this distributes
|
54
|
+
# the command to the loader, which then further distributes it to events
|
55
|
+
# and scripts.
|
56
|
+
#
|
57
|
+
# @param [Network] network the network that received the command.
|
58
|
+
# @param [Network::Command] command the received command.
|
35
59
|
def got_command network, command
|
36
60
|
puts "<- #{network.inspect ^ :bold} | #{command}"
|
37
61
|
name = :"got_#{command.name.downcase}"
|
@@ -41,6 +65,7 @@ module Blur
|
|
41
65
|
end
|
42
66
|
end
|
43
67
|
|
68
|
+
# Searches for scripts in working_directory/scripts and then loads them.
|
44
69
|
def load_scripts
|
45
70
|
script_path = File.dirname $0
|
46
71
|
|
@@ -52,50 +77,38 @@ module Blur
|
|
52
77
|
end
|
53
78
|
end
|
54
79
|
|
80
|
+
# Unload all scripts gracefully that have been loaded into the client.
|
81
|
+
#
|
82
|
+
# @see Script#unload!
|
55
83
|
def unload_scripts
|
56
84
|
@scripts.each do |script|
|
57
85
|
script.unload!
|
58
86
|
end.clear
|
59
87
|
end
|
60
88
|
|
61
|
-
|
89
|
+
# Try to gracefully disconnect from each network, unload all scripts and
|
90
|
+
# exit properly.
|
91
|
+
#
|
92
|
+
# @param [optional, Symbol] signal The signal received by the system, if any.
|
93
|
+
def quit signal = :SIGINT
|
62
94
|
@networks.each do |network|
|
63
95
|
network.transmit :QUIT, "Got SIGINT?"
|
64
|
-
network.transcieve
|
65
96
|
network.disconnect
|
66
97
|
end
|
67
98
|
|
68
|
-
@connected = false
|
69
99
|
unload_scripts
|
70
100
|
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
private
|
75
|
-
|
76
|
-
def run_loop
|
77
|
-
puts "Starting run loop ..."
|
78
|
-
|
79
|
-
while @connected
|
80
|
-
@networks.select(&:connected?).each do |network|
|
81
|
-
begin
|
82
|
-
network.transcieve
|
83
|
-
sleep 0.05
|
84
|
-
rescue StandardError => exception
|
85
|
-
if network.connected?
|
86
|
-
network.disconnect
|
87
|
-
end
|
88
|
-
|
89
|
-
emit :connection_terminated, network
|
90
|
-
|
91
|
-
puts "#{"Network error" ^ :red} (#{exception.class.name}): #{exception.message}"
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
puts "Ended run loop ..."
|
101
|
+
EventMachine.stop
|
97
102
|
end
|
98
103
|
|
104
|
+
private
|
105
|
+
# Finds all callbacks with name `name` and then calls them.
|
106
|
+
# It also sends `name` to {Script} if the script responds to `name`, to all
|
107
|
+
# available scripts.
|
108
|
+
#
|
109
|
+
# @param [Symbol] name the corresponding event-handlers name.
|
110
|
+
# @param [...] args Arguments that is passed to the event-handler.
|
111
|
+
# @private
|
99
112
|
def emit name, *args
|
100
113
|
@callbacks[name].each do |callback|
|
101
114
|
callback.call *args
|
@@ -110,6 +123,11 @@ module Blur
|
|
110
123
|
end
|
111
124
|
end
|
112
125
|
|
126
|
+
# Stores the block as an event-handler with name `name`.
|
127
|
+
#
|
128
|
+
# @param [Symbol] name the corresponding event-handlers name.
|
129
|
+
# @param [Block] block the event-handlers block that serves as a trigger.
|
130
|
+
# @private
|
113
131
|
def catch name, &block
|
114
132
|
(@callbacks[name] ||= []) << block
|
115
133
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Blur
|
4
|
+
# The +Encryption+ module extends the communication-functionality of
|
5
|
+
# the client. It is intended to enable helpers but also core functionality
|
6
|
+
# that encrypts the incoming and outgoing data of Blur.
|
7
|
+
#
|
8
|
+
# Encryption modules are not loaded into the VM until it's required.
|
9
|
+
module Encryption
|
10
|
+
# Indicates that user-input (a channel user message, e.g.) is in invalid
|
11
|
+
# format to a certain encryption algorithm.
|
12
|
+
class BadInputError < StandardError; end
|
13
|
+
|
14
|
+
autoload :FiSH, "blur/encryption/fish"
|
15
|
+
autoload :Base64, "blur/encryption/base64"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Blur
|
4
|
+
module Encryption
|
5
|
+
# The +Encryption::Base64+ module differs from the original Base64
|
6
|
+
# implementation. I'm not sure how exactly, perhaps the charset?
|
7
|
+
#
|
8
|
+
# I originally found the Ruby implementation of FiSH on a website where
|
9
|
+
# it was graciously submitted by an anonymous user, since then I've
|
10
|
+
# implemented it in a weechat script, and now I've refactored it for use in
|
11
|
+
# Blur.
|
12
|
+
#
|
13
|
+
# @see http://maero.dk/pub/sources/weechat/ruby/autoload/fish.rb
|
14
|
+
module Base64
|
15
|
+
# The difference I suspect between the original Base64 implementation
|
16
|
+
# and the one used in FiSH.
|
17
|
+
Charset = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
18
|
+
|
19
|
+
# Decode a base64-encoded string.
|
20
|
+
#
|
21
|
+
# @return [String] Base64-decoded string.
|
22
|
+
def self.decode string
|
23
|
+
unless string.length % 12 == 0
|
24
|
+
raise BadInputError, "input has to be a multiple of 12 characters."
|
25
|
+
end
|
26
|
+
|
27
|
+
String.new.tap do |buffer|
|
28
|
+
j = -1
|
29
|
+
|
30
|
+
while j < string.length - 1
|
31
|
+
right, left = 0, 0
|
32
|
+
|
33
|
+
6.times{|i| right |= Charset.index(string[j += 1]) << (i * 6) }
|
34
|
+
6.times{|i| left |= Charset.index(string[j += 1]) << (i * 6) }
|
35
|
+
|
36
|
+
4.times do |i|
|
37
|
+
buffer << ((left & (0xFF << ((3 - i) * 8))) >> ((3 - i) * 8)).chr
|
38
|
+
end
|
39
|
+
|
40
|
+
4.times do |i|
|
41
|
+
buffer << ((right & (0xFF << ((3 - i) * 8))) >> ((3 - i) * 8)).chr
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Encode a string-cipher.
|
48
|
+
#
|
49
|
+
# @return [String] Base64-encoded string.
|
50
|
+
def self.encode string
|
51
|
+
unless string.length % 8 == 0
|
52
|
+
raise BadInputError, "input has to be a multiple of 8 characters."
|
53
|
+
end
|
54
|
+
|
55
|
+
left = 0
|
56
|
+
right = 0
|
57
|
+
decimals = [24, 16, 8, 0]
|
58
|
+
|
59
|
+
String.new.tap do |buffer|
|
60
|
+
string.each_block do |block|
|
61
|
+
4.times{|i| left += (block[i].ord << decimals[i]) }
|
62
|
+
4.times{|i| right += (block[i+4].ord << decimals[i]) }
|
63
|
+
|
64
|
+
6.times{|i| buffer << Charset[right & 0x3F].chr; right = right >> 6 }
|
65
|
+
6.times{|i| buffer << Charset[left & 0x3F].chr; left = left >> 6 }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'crypt/blowfish'
|
4
|
+
|
5
|
+
module Blur
|
6
|
+
module Encryption
|
7
|
+
# The +FiSH+ algorithm is a combination of Base64 encoding
|
8
|
+
# and the blowfish encryption.
|
9
|
+
#
|
10
|
+
# Shared text messages are prepended by "++OK+", an older implementation
|
11
|
+
# prepends it with "+mcps+" - Blur drops support for that implementation.
|
12
|
+
#
|
13
|
+
# There's multiple client-implementations available on the official FiSH
|
14
|
+
# homepage.
|
15
|
+
#
|
16
|
+
# == DH1080 Key exchange
|
17
|
+
# The newer FiSH implementation introduces a 1080bit Diffie-Hellman
|
18
|
+
# key-exchange mechanism.
|
19
|
+
#
|
20
|
+
# Blur does currently not support key exchanges.
|
21
|
+
class FiSH
|
22
|
+
# The standard FiSH block-size.
|
23
|
+
BlockSize = 8
|
24
|
+
|
25
|
+
# @return [String] the blowfish salt-key.
|
26
|
+
attr_accessor :keyphrase
|
27
|
+
|
28
|
+
# Change the keyphrase and instantiate a new blowfish object.
|
29
|
+
def keyphrase= keyphrase
|
30
|
+
@keyphrase = keyphrase
|
31
|
+
@blowfish = Crypt::Blowfish.new @keyphrase
|
32
|
+
end
|
33
|
+
|
34
|
+
# Instantiate a new fish-encryption object.
|
35
|
+
def initialize keyphrase
|
36
|
+
@keyphrase = keyphrase
|
37
|
+
@blowfish = Crypt::Blowfish.new keyphrase
|
38
|
+
end
|
39
|
+
|
40
|
+
# Encrypt an input string using the keyphrase stored in the +@blowfish+
|
41
|
+
# object.
|
42
|
+
#
|
43
|
+
# @return [String] the encrypted string.
|
44
|
+
def encrypt string
|
45
|
+
String.new.tap do |buffer|
|
46
|
+
nullpad(string).each_block do |block|
|
47
|
+
chunk = @blowfish.encrypt_block block
|
48
|
+
buffer.concat Base64.encode chunk
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Decrypt an input string using the keyphrase stored in the +@blowfish+
|
54
|
+
# object.
|
55
|
+
#
|
56
|
+
# @return [String] the decrypted string.
|
57
|
+
def decrypt string
|
58
|
+
unless string.length % 12 == 0
|
59
|
+
raise BadInputError, "input has to be a multiple of 12 characters."
|
60
|
+
end
|
61
|
+
|
62
|
+
String.new.tap do |buffer|
|
63
|
+
string.each_block 12 do |block|
|
64
|
+
chunk = @blowfish.decrypt_block Base64.decode block
|
65
|
+
buffer.concat chunk
|
66
|
+
end
|
67
|
+
end.rstrip
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
# Fill up the last block with null-bytes until it's a multiple of 8.
|
72
|
+
#
|
73
|
+
# @return [String] the nullpadded string.
|
74
|
+
def nullpad string
|
75
|
+
length = string.length + BlockSize - string.length % BlockSize
|
76
|
+
string.ljust length, ?\0
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -1,17 +1,39 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
# Reopens the scope of the standard Exception-class to extend it with helpful
|
4
|
+
# methods.
|
3
5
|
class Exception
|
6
|
+
# The pattern to match against the backtrace log.
|
4
7
|
Pattern = /^.*?:(\d+):/
|
5
8
|
|
9
|
+
# Retrieve the line on which the exception was raised from when raised inside
|
10
|
+
# a script.
|
11
|
+
#
|
12
|
+
# @return Fixnum the line of the script the exception was raised on.
|
6
13
|
def line
|
7
14
|
backtrace[0].match(Pattern)[1].to_i + 1
|
8
15
|
end
|
9
16
|
end
|
10
17
|
|
18
|
+
# Reopens the scope of the standard String-class to extend it with helpful
|
19
|
+
# methods.
|
11
20
|
class String
|
21
|
+
# Checks if the string contains nothing but a numeric value.
|
22
|
+
#
|
23
|
+
# @return true if it is a numeric value.
|
12
24
|
def numeric?
|
13
25
|
self =~ /^\d+$/
|
14
26
|
end
|
15
27
|
|
28
|
+
# Split a string up in n chunks and then iterate through them, exactly like
|
29
|
+
# Enumerable#each_slice.
|
30
|
+
#
|
31
|
+
# @return [Enumerator] list of slices.
|
32
|
+
# @yieldreturn [Array] list of elements in each slice consecutively.
|
33
|
+
def each_slice size = 8
|
34
|
+
self.chars.each_slice(size).each{|slice| yield slice.join }
|
35
|
+
end
|
36
|
+
|
16
37
|
alias_method :starts_with?, :start_with?
|
38
|
+
alias_method :each_block, :each_slice
|
17
39
|
end
|
data/library/blur/handling.rb
CHANGED
@@ -2,11 +2,41 @@
|
|
2
2
|
|
3
3
|
module Blur
|
4
4
|
class Client
|
5
|
+
# The +Handling+ module is the very core of the IRC-part in Blur.
|
6
|
+
#
|
7
|
+
# When the client receives a parsed command instance, it immediately starts
|
8
|
+
# looking for a got_(the command name) method inside the client, which
|
9
|
+
# is implemented in this module.
|
10
|
+
#
|
11
|
+
# == Implementing a handler
|
12
|
+
# Implementing a handler is very, very easy.
|
13
|
+
#
|
14
|
+
# All you need to do is define a method named got_(command you want to
|
15
|
+
# implement) that accepts 2 parameters, +network+ and +command+.
|
16
|
+
#
|
17
|
+
# You can then do whatever you need to do with the command instance,
|
18
|
+
# you can access the parameters of it through {Network::Command#[]}.
|
19
|
+
#
|
20
|
+
# Don't forget that this module is inside the clients scope, so you can
|
21
|
+
# access all instance-variables and methods.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# # RPL_WHOISUSER
|
25
|
+
# # <nick> <user> <host> * :<real name>
|
26
|
+
# def got_whois_user network, command
|
27
|
+
# puts "nick: #{command[0]} user: #{command[1]} host: #{command[2]} …"
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# @see http://www.irchelp.org/irchelp/rfc/chapter6.html
|
5
31
|
module Handling
|
6
|
-
|
7
32
|
protected
|
8
33
|
|
9
|
-
#
|
34
|
+
# Called when the MOTD was received, which also means it is ready.
|
35
|
+
#
|
36
|
+
# == Callbacks:
|
37
|
+
# Emits +:connection_ready+ with the parameter +network+.
|
38
|
+
#
|
39
|
+
# Automatically joins the channels specified in +:channels+.
|
10
40
|
def got_end_of_motd network, command
|
11
41
|
emit :connection_ready, network
|
12
42
|
|
@@ -15,8 +45,8 @@ module Blur
|
|
15
45
|
end
|
16
46
|
end
|
17
47
|
|
18
|
-
#
|
19
|
-
def
|
48
|
+
# Called when the namelist of a channel was received.
|
49
|
+
def got_name_reply network, command
|
20
50
|
name = command[2]
|
21
51
|
users = command[3].split.map &Network::User.method(:new)
|
22
52
|
|
@@ -28,30 +58,46 @@ module Blur
|
|
28
58
|
channel.users << user
|
29
59
|
end
|
30
60
|
else
|
31
|
-
|
61
|
+
channel = Network::Channel.new name, network, users
|
62
|
+
|
63
|
+
if network.fish? and network.options[:fish].key? name
|
64
|
+
keyphrase = network.options[:fish][name]
|
65
|
+
channel.encryption = Encryption::FiSH.new keyphrase
|
66
|
+
end
|
67
|
+
|
68
|
+
network.channels << channel
|
32
69
|
end
|
33
70
|
end
|
34
71
|
|
35
|
-
#
|
36
|
-
|
72
|
+
# Called when a channel topic was changed.
|
73
|
+
#
|
74
|
+
# == Callbacks:
|
75
|
+
# Emits :topic_change with the parameters +channel+ and +topic+.
|
76
|
+
def got_channel_topic network, command
|
37
77
|
me, name, topic = command.params
|
38
78
|
|
39
79
|
if channel = network.channel_by_name(name)
|
80
|
+
emit :topic_change, channel, topic
|
40
81
|
channel.topic = topic
|
41
82
|
else
|
42
83
|
channel = Network::Channel.new name, network, []
|
84
|
+
emit :topic_change, channel, topic
|
43
85
|
channel.topic = topic
|
44
86
|
|
45
87
|
network.channels << channel
|
46
88
|
end
|
47
89
|
end
|
48
90
|
|
49
|
-
#
|
91
|
+
# Called when the server needs to verify that we're alive.
|
50
92
|
def got_ping network, command
|
51
93
|
network.transmit :PONG, command[0]
|
52
94
|
end
|
53
95
|
|
54
|
-
#
|
96
|
+
# Called when a user changed nickname.
|
97
|
+
#
|
98
|
+
# == Callbacks:
|
99
|
+
# Emits :user_rename with the parameters +channel+, +user+ and +nickname+
|
100
|
+
# where +nickname+ is the new name.
|
55
101
|
def got_nick network, command
|
56
102
|
nick = command.sender.nickname
|
57
103
|
|
@@ -65,7 +111,15 @@ module Blur
|
|
65
111
|
end
|
66
112
|
end
|
67
113
|
|
68
|
-
#
|
114
|
+
# Called when a message was received (both channel and private messages).
|
115
|
+
#
|
116
|
+
# == Callbacks:
|
117
|
+
# === When it's a channel message:
|
118
|
+
# Emits +:message+ with the parameters +user+, +channel+ and +message+.
|
119
|
+
# === When it's a private message:
|
120
|
+
# Emits +:private_message+ with the parameters +user+ and +message+.
|
121
|
+
#
|
122
|
+
# @note Messages are contained as strings.
|
69
123
|
def got_privmsg network, command
|
70
124
|
return if command.sender.is_a? String # Ignore all server privmsgs
|
71
125
|
name, message = command.params
|
@@ -74,6 +128,18 @@ module Blur
|
|
74
128
|
if user = channel.user_by_nick(command.sender.nickname)
|
75
129
|
user.name = command.sender.username
|
76
130
|
user.host = command.sender.hostname
|
131
|
+
|
132
|
+
begin
|
133
|
+
if message[0..3] == "+OK " and channel.encrypted?
|
134
|
+
message = channel.encryption.decrypt message[4..-1]
|
135
|
+
end
|
136
|
+
rescue Encryption::BadInputError
|
137
|
+
# …
|
138
|
+
rescue => exception
|
139
|
+
puts "-!- There was a problem with the FiSH encryption, disabling"
|
140
|
+
|
141
|
+
channel.encryption = nil
|
142
|
+
end
|
77
143
|
|
78
144
|
emit :message, user, channel, message
|
79
145
|
else
|
@@ -89,7 +155,10 @@ module Blur
|
|
89
155
|
end
|
90
156
|
end
|
91
157
|
|
92
|
-
#
|
158
|
+
# Called when a user joined a channel.
|
159
|
+
#
|
160
|
+
# == Callbacks:
|
161
|
+
# Emits +:user_entered+ with the parameters +channel+ and +user+.
|
93
162
|
def got_join network, command
|
94
163
|
name = command[0]
|
95
164
|
user = Network::User.new command.sender.nickname
|
@@ -106,7 +175,10 @@ module Blur
|
|
106
175
|
end
|
107
176
|
end
|
108
177
|
|
109
|
-
#
|
178
|
+
# Called when a user left a channel.
|
179
|
+
#
|
180
|
+
# == Callbacks:
|
181
|
+
# Emits +:user_left+ with the parameters +channel+ and +user+.
|
110
182
|
def got_part network, command
|
111
183
|
name = command[0]
|
112
184
|
|
@@ -119,7 +191,10 @@ module Blur
|
|
119
191
|
end
|
120
192
|
end
|
121
193
|
|
122
|
-
#
|
194
|
+
# Called when a user disconnected from a network.
|
195
|
+
#
|
196
|
+
# == Callbacks:
|
197
|
+
# Emits +:user_quit+ with the parameters +channel+ and +user+.
|
123
198
|
def got_quit network, command
|
124
199
|
nick = command.sender.nickname
|
125
200
|
|
@@ -134,7 +209,13 @@ module Blur
|
|
134
209
|
end
|
135
210
|
end
|
136
211
|
|
137
|
-
#
|
212
|
+
# Called when a user was kicked from a channel.
|
213
|
+
#
|
214
|
+
# == Callbacks:
|
215
|
+
# Emits +:user_kicked+ with the parameters +kicker+, +channel+, +kickee+
|
216
|
+
# and +reason+.
|
217
|
+
#
|
218
|
+
# +kicker+ is the user that kicked +kickee+.
|
138
219
|
def got_kick network, command
|
139
220
|
name, target, reason = command.params
|
140
221
|
|
@@ -149,6 +230,10 @@ module Blur
|
|
149
230
|
end
|
150
231
|
end
|
151
232
|
|
233
|
+
# Called when a topic was changed for a channel.
|
234
|
+
#
|
235
|
+
# == Callbacks:
|
236
|
+
# Emits :topic with the parameters +user+, +channel+ and +topic+.
|
152
237
|
def got_topic network, command
|
153
238
|
name, topic = command.params
|
154
239
|
|
@@ -161,6 +246,13 @@ module Blur
|
|
161
246
|
end
|
162
247
|
end
|
163
248
|
|
249
|
+
# Called when a channel or a users flags was altered.
|
250
|
+
#
|
251
|
+
# == Callbacks:
|
252
|
+
# === When it's channel modes:
|
253
|
+
# Emits +:channel_mode+ with the parameters +channel+ and +modes+.
|
254
|
+
# === When it's user modes:
|
255
|
+
# Emits +:user_mode+ with the parameters +user+ and +modes+.
|
164
256
|
def got_mode network, command
|
165
257
|
name, modes, limit, nick, mask = command.params
|
166
258
|
|
@@ -181,8 +273,10 @@ module Blur
|
|
181
273
|
end
|
182
274
|
end
|
183
275
|
|
276
|
+
alias_method :got_353, :got_name_reply
|
184
277
|
alias_method :got_422, :got_end_of_motd
|
185
278
|
alias_method :got_376, :got_end_of_motd
|
279
|
+
alias_method :got_332, :got_channel_topic
|
186
280
|
end
|
187
281
|
end
|
188
282
|
end
|