Class: Syndi::IRC::Server

Inherits:
Object
  • Object
show all
Includes:
DSL::Base
Defined in:
lib/syndi/irc/server.rb

Overview

A class which maintains a connection to an IRC server and provides a highly usable interface for the IRC server.

@!attribute prefixes @return [Hash=> String] The IRC server's supported prefixes, with the key being the channel mode which represents the prefix, and the value being the prefix.

Author:

  • noxgirl

Since:

  • 4.0.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from DSL::Base

#clock_do, #clock_stop, #emit, #on, #undo_on

Constructor Details

#initialize(name) {|c| ... } ⇒ Server

Produce a new instance of Syndi::IRC::Server.

Configuration attributes are +address+, +port+, +nick+, +user+, +real+, +password+, +bind+, and +ssl+.

Examples:

irc = Syndi::IRC::Server.new('Freenode') do |c|
  c.address = 'irc.freenode.net'
  c.port    = 7000
  c.nick    = 'cowmoon'
  c.user    = 'foo1'
  c.real    = "The night is lovely."
  c.bind    = 'localhost'
  c.ssl     = true
end

Parameters:

  • name (String)

    The name of the server to which we should connect.

Yield Parameters:

Since:

  • 4.0.0



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/syndi/irc/server.rb', line 141

def initialize(name)

  # Prepare attributes.
  @name     = name
  @address  = nil
  @port     = nil
  @nick     = nil
  @user     = nil
  @real     = nil
  @password = nil
  @bind     = nil
  @ssl      = false

  # Yield for configuration.
  yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

  # Additional instance attributes.
  @in         = 0
  @out        = 0
  @socket     = nil
  @connected  = false
  @type       = :irc

  # Pull in commands.
  extend   Syndi::IRC::Std::Commands
  # State managers.
  @supp  = Syndi::IRC::State::Support.new
  @chans = nil
  @users = nil

  # Our receive queue remainder.
  @recv_rem = nil

  # Mutual exclusion for thread safety.
  @lock = Mutex.new

end

Instance Attribute Details

#addressString

Returns The address used to connect to the server.

Returns:

  • (String)

    The address used to connect to the server.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#await_self_whotrue, false

Returns Whether or not we are awaiting for a response to a /WHO on ourselves.

Returns:

  • (true, false)

    Whether or not we are awaiting for a response to a /WHO on ourselves.



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#bindString?

Note:

This appears to be unused at the moment.

Returns:

  • (String)

    If desired, the address to which to bind for this socket

  • (nil)

    If not desired.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#channel_modesHash{Symbol => Array<String>}

Returns The IRC server's supported channel modes, divided as thus:

  • +:list+ = A list of modes which add/remove a nickname or mask from a channel list, such as ops and bans.
  • +:always+ = A llst of modes which change a channel setting, and always have a parameter.
  • +:set+ = A list of modes which change a channel setting, and which have a parameter only when set.
  • +:never+ = A list of modes which change a channel setting, and which never have a parameter.

Returns:

  • (Hash{Symbol => Array<String>})

    The IRC server's supported channel modes, divided as thus:

    • +:list+ = A list of modes which add/remove a nickname or mask from a channel list, such as ops and bans.
    • +:always+ = A llst of modes which change a channel setting, and always have a parameter.
    • +:set+ = A list of modes which change a channel setting, and which have a parameter only when set.
    • +:never+ = A list of modes which change a channel setting, and which never have a parameter.


113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#channelsHash{String => IRC::Object::Channel}

Returns A list of channels in which we reside, with each key being the channel's name in all-lowercase, and the respective values being of IRC::Object::Channel.

Returns:



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#chansObject

Since:

  • 4.0.0



117
118
119
# File 'lib/syndi/irc/server.rb', line 117

def chans
  @chans
end

#connectedtrue, false

Returns Whether or not we are connected to the server.

Returns:

  • (true, false)

    Whether or not we are connected to the server.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#inInteger (readonly)

Returns The number of bytes received from the socket.

Returns:

  • (Integer)

    The number of bytes received from the socket.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#maskString

Returns The bot's own hostname or mask on the IRC server.

Returns:

  • (String)

    The bot's own hostname or mask on the IRC server.



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#max_modesInteger

Returns The maximum number of mode changes which may be specified in a /MODE query.

Returns:

  • (Integer)

    The maximum number of mode changes which may be specified in a /MODE query.



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#nameString

Returns The name of the server as specified by configuration.

Returns:

  • (String)

    The name of the server as specified by configuration.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#nickString

Returns The nickname of the bot on the server.

Returns:

  • (String)

    The nickname of the bot on the server.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#outInteger (readonly)

Returns The number of bytes sent to the socket.

Returns:

  • (Integer)

    The number of bytes sent to the socket.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#passwordString?

Returns:

  • (String)

    If needed, the password used to connect to the server

  • (nil)

    If not needed.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#portInteger

Returns The port used to connect to the server.

Returns:

  • (Integer)

    The port used to connect to the server

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#realString

Returns The real name or GECOS of the bot on the server.

Returns:

  • (String)

    The real name or GECOS of the bot on the server.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#recvqArray<String>

Returns The socket's receive queue, which is comprised of an array of strings which are pending processing.

Returns:

  • (Array<String>)

    The socket's receive queue, which is comprised of an array of strings which are pending processing.



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#sasl_idString?

Note:

This is seemingly deprecated?

Returns:

  • (String)

    If SASL is desired, the username with which to authenticate.

  • (nil)

    If not used.



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#socketTCPSocket (readonly)

Returns The TCP socket being used for the connection.

Returns:

  • (TCPSocket)

    The TCP socket being used for the connection.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#ssltrue, false

Returns If SSL should [not] be used for the connection.

Returns:

  • (true, false)

    If SSL should [not] be used for the connection.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#suppSyndi::IRC::State::Support (readonly)

Returns The IRCd capabilities.

Returns:

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#typeSymbol (readonly)

Returns +:irc+.

Returns:

  • (Symbol)

    +:irc+

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#userString

Returns The username of the bot on the server.

Returns:

  • (String)

    The username of the bot on the server.

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#usersHash{String => IRC::Object::User}

Returns A list of users who are known to us, with each key being the user's nickname in all-lowercase, and the respective values being of IRC::Object::User.

Returns:

Since:

  • 4.0.0



113
114
115
116
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
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 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

Instance Method Details

#attribute_checkObject (private)

Check the presence of all attributes.

Raises:

Since:

  • 4.0.0



278
279
280
281
282
283
284
# File 'lib/syndi/irc/server.rb', line 278

def attribute_check
  raise(ConfigError, "Missing server address")  unless @address
  raise(ConfigError, "Missing server port")     unless @port
  raise(ConfigError, "Missing nickname to use") unless @nick
  raise(ConfigError, "Missing username to use") unless @user
  raise(ConfigError, "Missing realname to use") unless @real
end

#connectObject

Establish (or attempt to) a connection with the server.

Since:

  • 4.0.0



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/syndi/irc/server.rb', line 180

def connect

  # Check for missing attributes.
  begin
    attribute_check
  rescue => e
    $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
  end

  $m.info("Connecting to #@name @ #@address:#@port...")

  # Create a new socket.
  begin
    socket = TCPSocket.new(@address, @port, @bind)
  rescue => e
    $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
    raise
  end

  # Wrap it in SSL if told to.
  if ssl
    begin
      socket = OpenSSL::SSL::SSLSocket.new(socket)
      socket.connect
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end
  end

  @socket = socket

  # Register.
  emit :irc, :preconnect, self
  pass @password if @password
  snd 'CAP LS'
  self.nickname = @nick
  user @user, Socket.gethostname, @address, @real

end

#connected?true, false (private)

Check if we are connected.

Returns:

  • (true, false)

Since:

  • 4.0.0



289
290
291
292
293
# File 'lib/syndi/irc/server.rb', line 289

def connected?
  return false unless @socket
  return false unless @connected
  true
end

#inspectObject

Since:

  • 4.0.0



270
# File 'lib/syndi/irc/server.rb', line 270

def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end

#recvObject

Receive data from the socket, and push it into the recvQ.

Since:

  • 4.0.0



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/syndi/irc/server.rb', line 231

def recv

  # Thread safety.
  @lock.synchronize do
  
    if @socket.nil? or @socket.eof?
      return
    end

    # Read the data.
    data = @socket.sysread(1024)
    # Increase in.
    @in += data.length

    # Split the data.
    recv = []
    until data !~ /\r\n/
      line, data = data.split(/(?<=\r\n)/, 2)
      recv.push line.chomp "\r\n"
    end

    # Check if there's a remainder in the recvQ.
    if @recv_rem != ''
      recv[0] = "#@recv_rem#{recv[0]}"
      @recv_rem = ''
    end
    @recv_rem = data if data != ''

    # Lastly, sent the data out
    recv.each do |dline|
      $m.foreground("{irc-recv} #@name >> #{dline}")
      emit :irc, :receive, self, dline # send it out to :receive
    end
  
  end

end

#snd(data) ⇒ Object

Send data to the socket.

Parameters:

  • data (String)

    The string of data, which should not exceed 512 in length.

Since:

  • 4.0.0



224
225
226
227
228
# File 'lib/syndi/irc/server.rb', line 224

def snd data
  $m.foreground("{irc-send} #@name << #{data}")
  @socket.write("#{data}\r\n")
  @out += "#{data}\r\n".length
end

#to_sObject Also known as: s

Since:

  • 4.0.0



269
# File 'lib/syndi/irc/server.rb', line 269

def to_s;    @name; end