Module: Blur::Client::Handling

Included in:
Blur::Client
Defined in:
library/blur/handling.rb

Overview

The Handling module is the very core of the IRC-part in Blur.

When the client receives a parsed message instance, it immediately starts looking for a got_(the message name) method inside the client, which is implemented in this module.

Implementing a handler

Implementing a handler is very, very easy.

All you need to do is define a method named got_(message you want to implement) that accepts 2 parameters, network and message.

You can then do whatever you need to do with the message instance, you can access the parameters of it through Network::message#[].

Don’t forget that this module is inside the clients scope, so you can access all instance-variables and methods.

Examples:

# RPL_WHOISUSER
# <nick> <user> <host> * :<real name>
def got_whois_user network, message
  puts "nick: #{message.parameters[0]} user: #{message.parameters[1]} host: #{message.parameters[2]} ..."
end

See Also:

Instance Method Summary collapse

Instance Method Details

#got_001(network, message) ⇒ Object



297
298
299
300
301
302
303
# File 'library/blur/handling.rb', line 297

def got_001 network, message
  network.abort_cap_neg if network.waiting_for_cap

  # Get our nickname from the server
  nickname = message.parameters[0]
  network.nickname = nickname
end

#got_005(network, message) ⇒ Object

Called when the network announces its ISUPPORT parameters.



253
254
255
256
257
# File 'library/blur/handling.rb', line 253

def got_005 network, message
  params = message.parameters[1..-2]

  network.isupport.parse(*params)
end

#got_900(network, _message) ⇒ Object

:server 900 <nick> <nick>!<ident>@<host> <account> :You are now logged in as <user> RPL_LOGGEDIN SASL



319
320
321
# File 'library/blur/handling.rb', line 319

def got_900 network, _message
  network.cap_end if network.waiting_for_cap
end

#got_904(network, message) ⇒ Object

:server 904 <nick> :SASL authentication failed ERR_SASLFAIL



325
326
327
328
329
330
331
# File 'library/blur/handling.rb', line 325

def got_904 network, message
  _nick, _message = message.parameters

  puts 'SASL authentication failed! Disconnecting!'

  network.disconnect
end

#got_authenticate(network, message) ⇒ Object



305
306
307
308
309
310
311
312
313
314
315
# File 'library/blur/handling.rb', line 305

def got_authenticate network, message
  case message.parameters[0]
  when '+'
    return unless network.sasl?

    sasl = network.options['sasl']

    response = "#{sasl['username']}\x00#{sasl['username']}\x00#{sasl['password']}"
    network.transmit :AUTHENTICATE, Base64.encode64(response).strip
  end
end

#got_cap(network, message) ⇒ Object

Received when the server supports capability negotiation.

CAP * LS :multi-prefix sasl



262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'library/blur/handling.rb', line 262

def got_cap network, message
  _id, command = message.parameters[0..1]

  case command
  when 'LS'
    capabilities = message.parameters[2]&.split
    req = []

    req << 'sasl' if network.sasl? && capabilities.include?('sasl')
    req << 'account-tag' if capabilities.include?('account-tag')

    network.transmit :CAP, 'REQ', req.join(' ') if req.any?

    capabilities.each { |name| network.capabilities.push name }

    emit :network_capabilities, network, capabilities

  when 'ACK'
    capabilities = message.parameters[2]&.split

    network.transmit :AUTHENTICATE, 'PLAIN' if capabilities&.include?('sasl') && network.sasl?

    network.cap_end if network.waiting_for_cap
  when 'NAK'
    capabilities = message.parameters[2]&.split

    if capabilities&.include?('sasl') && network.sasl?
      puts "The server does not support SASL, but you've configured it " \
        'as such! Disconnecting!'

      network.disconnect
    end
  end
end

#got_channel_topic(network, message) ⇒ Object Also known as: got_332

Called when a channel topic was changed.

Callbacks:

Emits :topic_change with the parameters channel and topic.



71
72
73
74
75
76
77
78
79
# File 'library/blur/handling.rb', line 71

def got_channel_topic network, message
  _, channel_name, topic = message.parameters

  return unless (channel = find_or_create_channel(channel_name, network))

  emit :channel_topic, channel, topic

  channel.topic = topic
end

#got_end_of_motd(network, _message) ⇒ Object Also known as: got_422, got_376

Called when the MOTD was received, which also means it is ready.

Callbacks:

Emits :connection_ready with the parameter network.

Automatically joins the channels specified in :channels.



38
39
40
41
42
43
44
# File 'library/blur/handling.rb', line 38

def got_end_of_motd network, _message
  emit :connection_ready, network

  network.options['channels'].each do |channel|
    network.join channel
  end
end

#got_join(network, message) ⇒ Object

Called when a user joined a channel.

Callbacks:

Emits :user_entered with the parameters channel and user.



157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'library/blur/handling.rb', line 157

def got_join network, message
  channel_name = message.parameters[0]

  user = find_or_create_user message.prefix.nick, network
  user.name = message.prefix.user
  user.host = message.prefix.host

  return unless (channel = find_or_create_channel(channel_name, network))

  _user_join_channel user, channel

  emit :user_entered, channel, user
end

#got_kick(network, message) ⇒ Object

Called when a user was kicked from a channel.

Callbacks:

Emits :user_kicked with the parameters kicker, channel, kickee and reason.

kicker is the user that kicked kickee.



211
212
213
214
215
216
217
218
219
220
221
# File 'library/blur/handling.rb', line 211

def got_kick network, message
  name, target, reason = message.parameters

  return unless (channel = network.channels[name])
  return unless (kicker = network.users[message.prefix.nick])
  return unless (kickee = network.users[target])

  _user_part_channel kickee, channel

  emit :user_kicked, kicker, channel, kickee, reason
end

#got_mode(network, message) ⇒ Object

Called when a channel or a users flags was altered.

Callbacks:

When it’s channel modes:

Emits :channel_mode with the parameters channel and modes.

When it’s user modes:

Emits :user_mode with the parameters user and modes.



246
247
248
249
250
# File 'library/blur/handling.rb', line 246

def got_mode network, message
  name, _modes, _limit, _nick, _mask = message.parameters

  return unless (_channel = network.channels[name])
end

#got_name_reply(network, message) ⇒ Object Also known as: got_353

Called when the namelist of a channel was received.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'library/blur/handling.rb', line 47

def got_name_reply network, message
  name  = message.parameters[2] # Channel name.
  nicks = message.parameters[3].split.map do |nick|
    # Slice the nick if the first character is a user mode prefix.
    nick.slice! 0 if network.user_prefixes.include? nick.chr

    nick
  end

  return unless (channel = find_or_create_channel(name, network))

  users = nicks.map { |nick| find_or_create_user nick, network }
  users.each do |user|
    user.channels << channel
    channel.users << user unless channel.users.include? user
  end

  emit :channel_who_reply, channel
end

#got_nick(network, message) ⇒ Object

Called when a user changed nickname.

Callbacks:

Emits :user_rename with the parameters channel, user and new_nick



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'library/blur/handling.rb', line 100

def got_nick network, message
  old_nick = message.prefix.nick

  # Update or own nickname if has been changed by the server
  if network.nickname == old_nick
    new_nick = message.parameters[0]

    emit :nick, new_nick
    network.nickname = new_nick
  end

  return unless (user = network.users.delete(old_nick))

  new_nick = message.parameters[0]
  emit :user_rename, user, new_nick
  user.nick = new_nick
  network.users[new_nick] = user
end

#got_nickname_in_use(network, message) ⇒ Object Also known as: got_433



333
334
335
336
# File 'library/blur/handling.rb', line 333

def got_nickname_in_use network, message
  nickname = network.options['nickname']
  network.transmit :NICK, "#{nickname}_"
end

#got_part(network, message) ⇒ Object

Called when a user left a channel.

Callbacks:

Emits :user_left with the parameters channel and user.



175
176
177
178
179
180
181
182
183
184
# File 'library/blur/handling.rb', line 175

def got_part network, message
  channel_name = message.parameters[0]

  return unless (channel = network.channels[channel_name])
  return unless (user = network.users[message.prefix.nick])

  _user_part_channel user, channel

  emit :user_left, channel, user
end

#got_ping(network, message) ⇒ Object

Called when the server needs to verify that we’re alive.



82
83
84
85
86
87
# File 'library/blur/handling.rb', line 82

def got_ping network, message
  network.last_pong_time = Time.now
  network.transmit :PONG, message.parameters[0]

  emit :network_ping, network, message.parameters[0]
end

#got_pong(network, message) ⇒ Object

Called when the server reponds to our periodic PINGs.



90
91
92
93
94
# File 'library/blur/handling.rb', line 90

def got_pong network, message
  network.last_pong_time = Time.now

  emit :network_pong, network, message.parameters[0]
end

#got_privmsg(network, message) ⇒ Object

Note:

Messages are contained as strings.

Called when a message was received (both channel and private messages).

Callbacks:

When it’s a channel message:

Emits :message with the parameters user, channel and message.

When it’s a private message:

Emits :private_message with the parameters user and message.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'library/blur/handling.rb', line 128

def got_privmsg network, message
  return unless message.prefix.nick # Ignore all server privmsgs

  name, msg = message.parameters

  if (channel = network.channels[name])
    unless (user = network.users[message.prefix.nick])
      user = User.new message.prefix.nick, network
    end

    user.name = message.prefix.user
    user.host = message.prefix.host

    emit :message, user, channel, msg
  else # This is a private message
    unless (user = network.users[message.prefix.nick])
      user = User.new message.prefix.nick, network
      user.name = message.prefix.user
      user.host = message.prefix.host
    end

    emit :private_message, user, msg
  end
end

#got_quit(network, message) ⇒ Object

Called when a user disconnected from a network.

Callbacks:

Emits :user_quit with the parameters channel and user.



190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'library/blur/handling.rb', line 190

def got_quit network, message
  nick = message.prefix.nick
  reason = message.parameters[2]

  return unless (user = network.users[nick])

  user.channels.each do |channel|
    channel.users.delete user
  end

  emit :user_quit, user, reason
  network.users.delete nick
end

#got_topic(network, message) ⇒ Object

Called when a topic was changed for a channel.

Callbacks:

Emits :topic with the parameters user, channel and topic.



227
228
229
230
231
232
233
234
235
236
237
# File 'library/blur/handling.rb', line 227

def got_topic network, message
  _channel_name, topic = message.parameters

  return unless (channel = network.channels[channel.name])

  if (user = network.users[message.prefix.nick])
    emit :topic, user, channel, topic
  end

  channel.topic = topic
end