diff options
author | Dmitry Kim <dmitry point kim at gmail point com> | 2007-03-17 19:42:48 +0000 |
---|---|---|
committer | Dmitry Kim <dmitry point kim at gmail point com> | 2007-03-17 19:42:48 +0000 |
commit | 4667198ec577276892f501ae37efc8f64c66c003 (patch) | |
tree | ff7250a7b49b554ea655879f4efe2436d78188c2 /lib | |
parent | 9e743517a8a8a7455d4186d63d545b34dd5419e8 (diff) |
+ added support for multiple servers to try (round-robin) for unreliable ircnets
* changed server.name/port to server.list (with config upgrade automation, too)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rbot/ircbot.rb | 28 | ||||
-rw-r--r-- | lib/rbot/ircsocket.rb | 26 |
2 files changed, 35 insertions, 19 deletions
diff --git a/lib/rbot/ircbot.rb b/lib/rbot/ircbot.rb index f4ddc8fa..58cbb46d 100644 --- a/lib/rbot/ircbot.rb +++ b/lib/rbot/ircbot.rb @@ -147,14 +147,10 @@ class Bot def initialize(botclass, params = {}) # BotConfig for the core bot # TODO should we split socket stuff into ircsocket, etc? - BotConfig.register BotConfigStringValue.new('server.name', - :default => "localhost", :requires_restart => true, - :desc => "What server should the bot connect to?", - :wizard => true) - BotConfig.register BotConfigIntegerValue.new('server.port', - :default => 6667, :type => :integer, :requires_restart => true, - :desc => "What port should the bot connect to?", - :validate => Proc.new {|v| v > 0}, :wizard => true) + BotConfig.register BotConfigArrayValue.new('server.list', + :default => ['irc://localhost'], :wizard => true, + :requires_restart => true, + :desc => "List of irc servers rbot should try to connect to. Use comma to separate values. Servers are in format 'server.doma.in:port'. If port is not specified, default value (6667) is used.") BotConfig.register BotConfigBooleanValue.new('server.ssl', :default => false, :requires_restart => true, :wizard => true, :desc => "Use SSL to connect to this server?") @@ -441,7 +437,17 @@ class Bot @plugins.bot_associate(self) setup_plugins_path() - @socket = IrcSocket.new(@config['server.name'], @config['server.port'], @config['server.bindhost'], @config['server.sendq_delay'], @config['server.sendq_burst'], :ssl => @config['server.ssl']) + if @config['server.name'] + debug "upgrading configuration (server.name => server.list)" + srv_uri = 'irc://' + @config['server.name'] + srv_uri += ":#{@config['server.port']}" if @config['server.port'] + @config.items['server.list'.to_sym].set_string(srv_uri) + @config.delete('server.name'.to_sym) + @config.delete('server.port'.to_sym) + debug "server.list is now #{@config['server.list'].inspect}" + end + + @socket = IrcSocket.new(@config['server.list'], @config['server.bindhost'], @config['server.sendq_delay'], @config['server.sendq_burst'], :ssl => @config['server.ssl']) @client = Client.new @plugins.scan @@ -716,7 +722,7 @@ class Bot quit if $interrupted > 0 @socket.connect rescue => e - raise e.class, "failed to connect to IRC server at #{@config['server.name']} #{@config['server.port']}: " + e + raise e.class, "failed to connect to IRC server at #{@socket.server_uri}: " + e end quit if $interrupted > 0 @@ -724,7 +730,7 @@ class Bot realname << ' ' + COPYRIGHT_NOTICE if @config['irc.name_copyright'] @socket.emergency_puts "PASS " + @config['server.password'] if @config['server.password'] - @socket.emergency_puts "NICK #{@config['irc.nick']}\nUSER #{@config['irc.user']} 4 #{@config['server.name']} :#{realname}" + @socket.emergency_puts "NICK #{@config['irc.nick']}\nUSER #{@config['irc.user']} 4 #{@socket.server_uri.host} :#{realname}" quit if $interrupted > 0 myself.nick = @config['irc.nick'] myself.user = @config['irc.user'] diff --git a/lib/rbot/ircsocket.rb b/lib/rbot/ircsocket.rb index 5163e0ef..e3586b70 100644 --- a/lib/rbot/ircsocket.rb +++ b/lib/rbot/ircsocket.rb @@ -262,6 +262,9 @@ module Irc # all incoming data and @filter.out(data) for all outgoing data attr_reader :filter + # normalized uri of the current server + attr_reader :server_uri + # default trivial filter class class IdentityFilter def in(x) @@ -278,17 +281,17 @@ module Irc @filter = f || IdentityFilter.new end - # server:: server to connect to - # port:: IRCd port + # server_list:: list of servers to connect to # host:: optional local host to bind to (ruby 1.7+ required) # create a new IrcSocket - def initialize(server, port, host, sendq_delay=2, sendq_burst=4, opts={}) + def initialize(server_list, host, sendq_delay=2, sendq_burst=4, opts={}) @timer = Timer::Timer.new @timer.add(0.2) do spool end - @server = server.dup - @port = port.to_i + @server_list = server_list.dup + @server_uri = nil + @conn_count = 0 @host = host @sock = nil @filter = IdentityFilter.new @@ -327,18 +330,25 @@ module Irc warning "reconnecting while connected" return end + srv_uri = @server_list[@conn_count % @server_list.size].dup + srv_uri = 'irc://' + srv_uri if !srv_uri =~ /:\/\// + @conn_count += 1 + @server_uri = URI.parse(srv_uri) + @server_uri.port = 6667 if !@server_uri.port + debug "connection attempt \##{@conn_count} (#{@server_uri.host}:#{@server_uri.port})" + if(@host) begin - @sock=TCPSocket.new(@server, @port, @host) + @sock=TCPSocket.new(@server_uri.host, @server_uri.port, @host) rescue ArgumentError => e error "Your version of ruby does not support binding to a " error "specific local address, please upgrade if you wish " error "to use HOST = foo" error "(this option has been disabled in order to continue)" - @sock=TCPSocket.new(@server, @port) + @sock=TCPSocket.new(@server_uri.host, @server_uri.port) end else - @sock=TCPSocket.new(@server, @port) + @sock=TCPSocket.new(@server_uri.host, @server_uri.port) end if(@ssl) require 'openssl' |