Class: Syndi::IRC::Protocol

Inherits:
Object
  • Object
show all
Defined in:
lib/syndi/irc/protocol.rb,
lib/syndi/irc/protocol/numerics.rb

Overview

A class for parsing of data per the specifications of the IRC protocol, v3.1.

Defined Under Namespace

Modules: Numerics

Instance Method Summary collapse

Constructor Details

#initialize(lib) ⇒ Protocol

Construct a new IRC data parser.

Parameters:

Since:

  • 4.0.0



21
22
23
24
# File 'lib/syndi/irc/protocol.rb', line 21

def initialize lib
  extend Syndi::IRC::Protocol::Numerics
  lib.events.on :receive, &method(:parse)
end

Instance Method Details

#cap_ack(irc, list) ⇒ Object (private)

CAP ACK

We must save all capabilities into +irc.supp.cap+, and initiate SASL if possible.

Parameters:

Since:

  • 4.0.0



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/syndi/irc/protocol.rb', line 138

def cap_ack irc, list

  irc.supp.cap = list
    
  if list.include? 'sasl'
    irc.supp.sasl_id << $m.clock.spawn($m.conf['irc'][irc.s]['SASL']['timeout']||10, :once, irc) do |s|
      $m.error "SASL authentication on #{s} failed: authentication procedure timed out."
      s.snd('AUTHENTICATE *')
      s.cap_end
    end
    irc.authenticate :dh_blowfish
  else
    irc.snd('CAP END') # end capability negotiation and complete registration
  end

end

#cap_ls(irc, list) ⇒ Object (private)

CAP LS

Currently, Syndi's capabilities include the multi-prefix, sasl, account-notify, away-notify, and extended-join extensions.

Parameters:

Since:

  • 4.0.0



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/syndi/irc/protocol.rb', line 111

def cap_ls irc, list

  req = []
    
  # Every extension possible will be used except SASL, which requires
  # special configuration.
  %w[multi-prefix account-notify away-notify extended-join].each do |ext|
    req.push ext if list.include? ext
  end

  if $m.conf['irc'][irc.s]['SASL'] and list.include? 'sasl'
    require 'syndi/irc/sasl/mech'
    req.push 'sasl'
  end

  # Send CAP REQ.
  irc.snd("CAP REQ :#{req.join(' ')}") unless req.empty?

end

#on_authenticate(irc, raw, params) ⇒ Object

AUTHENTICATE

Parameters:

  • irc (Syndi::IRC::Server)

    The IRC connection.

  • raw (String)

    The data received.

  • params (Array<String>)

    The data received divided by +\s+ through regexp.

Since:

  • 4.0.0



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/syndi/irc/protocol.rb', line 48

def on_authenticate irc, raw, params
  username = $m.conf['irc'][irc.s]['SASL']['username']
  password = $m.conf['irc'][irc.s]['SASL']['password']
  
  if irc.supp.sasl_method    == :dh_blowfish
    crypt = Syndi::IRC::SASL::Mech::DHBlowfish.encrypt(username, password, params.last)
  elsif irc.supp.sasl_method == :plain
    crypt = Syndi::IRC::SASL::Mech::Plain.encrypt(username, password, params.last)
  end

  while crypt.length >= 400
    irc.snd "AUTHENTICATE #{crypt.slice!(0, 400)}"
  end

  if crypt.length > 0
    irc.snd "AUTHENTICATE #{crypt}"
  else
    irc.snd('AUTHENTICATE +')
  end
  # And we're done!
end

#on_cap(irc, raw, params) ⇒ Object

CAP

Parameters:

  • irc (Syndi::IRC::Server)

    The IRC connection.

  • raw (String)

    The data received.

  • params (Array<String>)

    The data received divided by +\s+ through regexp.

Since:

  • 4.0.0



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/syndi/irc/protocol.rb', line 76

def on_cap irc, raw, params
  case params[3]

  when 'LS'
    params[4].gsub!(/^:/, '')
    cap_ls(irc, params[4..-1])
  when 'ACK'
    params[4].gsub!(/^:/, '')
    cap_ack(irc, params[4..-1])
  end
end

#on_ping(irc, raw, params) ⇒ Object

PING

Return a PONG.

Parameters:

  • irc (Syndi::IRC::Server)

    The IRC connection.

  • raw (String)

    The data received.

  • params (Array<String>)

    The data received divided by +\s+ through regexp.

Since:

  • 4.0.0



96
97
98
# File 'lib/syndi/irc/protocol.rb', line 96

def on_ping irc, raw, params
  irc.snd("PONG #{params[1]}")
end

#parse(irc, raw) ⇒ Object

Parse IRC data.

Parameters:

Since:

  • 4.0.0



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/syndi/irc/protocol.rb', line 30

def parse irc, raw
    
  params  = raw.split(/\s+/)
  command = (raw =~ /^:/ ? params[1] : params[0]).dc

  # Check if we process this command.
  if respond_to? "on_#{command}"
    send("on_#{command}", irc, raw, params)
  end

end