Class: Cinch::IRC

Inherits:
Object
  • Object
show all
Defined in:
lib/cinch/irc.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bot) ⇒ IRC

Returns a new instance of IRC.



8
9
10
11
# File 'lib/cinch/irc.rb', line 8

def initialize(bot)
  @bot      = bot
  @isupport = ISupport.new
end

Instance Attribute Details

#isupportISupport (readonly)

Returns:



7
8
9
# File 'lib/cinch/irc.rb', line 7

def isupport
  @isupport
end

Instance Method Details

#connectvoid

This method returns an undefined value.

Establish a connection.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/cinch/irc.rb', line 16

def connect
  @registration = []

  @whois_updates = Hash.new {|h, k| h[k] = {}}
  @in_lists      = Set.new

  tcp_socket = nil
  begin
    Timeout::timeout(@bot.config.timeouts.connect) do
      tcp_socket = TCPSocket.new(@bot.config.server, @bot.config.port, @bot.config.local_host)
    end
  rescue Timeout::Error
    @bot.logger.debug("Timed out while connecting")
    return
  rescue => e
    @bot.logger.log_exception(e)
    return
  end

  if @bot.config.ssl == true || @bot.config.ssl == false
    @bot.logger.debug "Deprecation warning: Beginning from version 1.1.0, @config.ssl should be a set of options, not a boolean value!"
  end

  if @bot.config.ssl == true || (@bot.config.ssl.is_a?(OpenStruct) && @bot.config.ssl.use)
    require 'openssl'

    ssl_context = OpenSSL::SSL::SSLContext.new

    if @bot.config.ssl.is_a?(OpenStruct)
      if @bot.config.ssl.client_cert
        ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(@bot.config.ssl.client_cert))
        ssl_context.key = OpenSSL::PKey::RSA.new(File.read(@bot.config.ssl.client_cert))
      end
      ssl_context.ca_path = @bot.config.ssl.ca_path
      ssl_context.verify_mode = @bot.config.ssl.verify ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
    else
      ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
    end
    @bot.logger.debug "Using SSL with #{@bot.config.server}:#{@bot.config.port}"

    @socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ssl_context)
    @socket.sync = true
    @socket.connect
  else
    @socket = tcp_socket
  end

  @socket = Net::BufferedIO.new(@socket)
  @socket.read_timeout = @bot.config.timeouts.read

  @queue = MessageQueue.new(@socket, @bot)
  message "PASS #{@bot.config.password}" if @bot.config.password
  message "NICK #{@bot.generate_next_nick}"
  message "USER #{@bot.config.user} 0 * :#{@bot.config.realname}"

  reading_thread = Thread.new do
    begin
      while line = @socket.readline
        begin
          line = Cinch.encode_incoming(line, @bot.config.encoding)
          parse line
        rescue => e
          @bot.logger.log_exception(e)
        end
      end
    rescue Timeout::Error
      @bot.logger.debug "Connection timed out."
    rescue EOFError
      @bot.logger.debug "Lost connection."
    rescue => e
      @bot.logger.log_exception(e)
    end

    @socket.close
    @bot.dispatch(:disconnect)
    @bot.handler_threads.each { |t| t.join(10); t.kill }
  end

  @sending_thread = Thread.new do
    begin
      @queue.process!
    rescue => e
      @bot.logger.log_exception(e)
    end
  end

  ping_thread = Thread.new do
    while true
      sleep @bot.config.ping_interval
      message("PING 0") # PING requires a single argument. In our
                        # case the value doesn't matter though.
    end
  end

  reading_thread.join
  @sending_thread.kill
  ping_thread.kill
end

#message(msg) ⇒ void

This method returns an undefined value.

Send a message.



165
166
167
# File 'lib/cinch/irc.rb', line 165

def message(msg)
  @queue.queue(msg)
end

#parse(input) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/cinch/irc.rb', line 117

def parse(input)
  @bot.logger.log(input, :incoming) if @bot.config.verbose
  msg          = Message.new(input, @bot)
  events       = [[:catchall]]

  if ("001".."004").include? msg.command
    @registration << msg.command
    if registered?
      events << [:connect]
      @bot.last_connection_was_successful = true
    end
  elsif ["PRIVMSG", "NOTICE"].include?(msg.command)
    events << [:ctcp] if msg.ctcp?
    if msg.channel?
      events << [:channel]
    else
      events << [:private]
    end

    if msg.command == "PRIVMSG"
      events << [:message] << [:privmsg]
    else
      events << [:notice]
    end
  else
    meth = "on_#{msg.command.downcase}"
    __send__(meth, msg, events) if respond_to?(meth, true)

    if msg.error?
      events << [:error]
    else
      events << [msg.command.downcase.to_sym]
    end
  end

  msg.instance_variable_set(:@events, events.map(&:first))
  events.each do |event, *args|
    @bot.dispatch(event, msg, *args)
  end
end

#registered?Boolean

Returns true if we successfully registered yet.

Returns:

  • (Boolean)

    true if we successfully registered yet



159
160
161
# File 'lib/cinch/irc.rb', line 159

def registered?
  (("001".."004").to_a - @registration).empty?
end