+ attr_accessor :httputil
+
+ # server we are connected to
+ # TODO multiserver
+ def server
+ @client.server
+ end
+
+ # bot User in the client/server connection
+ # TODO multiserver
+ def myself
+ @client.user
+ end
+
+ # bot nick in the client/server connection
+ def nick
+ myself.nick
+ end
+
+ # bot channels in the client/server connection
+ def channels
+ myself.channels
+ end
+
+ # nick wanted by the bot. This defaults to the irc.nick config value,
+ # but may be overridden by a manual !nick command
+ def wanted_nick
+ @wanted_nick || config['irc.nick']
+ end
+
+ # set the nick wanted by the bot
+ def wanted_nick=(wn)
+ if wn.nil? or wn.to_s.downcase == config['irc.nick'].downcase
+ @wanted_nick = nil
+ else
+ @wanted_nick = wn.to_s.dup
+ end
+ end
+
+
+ # bot inspection
+ # TODO multiserver
+ def inspect
+ ret = self.to_s[0..-2]
+ ret << ' version=' << $version.inspect
+ ret << ' botclass=' << botclass.inspect
+ ret << ' lang="' << lang.language
+ if defined?(GetText)
+ ret << '/' << locale
+ end
+ ret << '"'
+ ret << ' nick=' << nick.inspect
+ ret << ' server='
+ if server
+ ret << (server.to_s + (socket ?
+ ' [' << socket.server_uri.to_s << ']' : '')).inspect
+ unless server.channels.empty?
+ ret << " channels="
+ ret << server.channels.map { |c|
+ "%s%s" % [c.modes_of(nick).map { |m|
+ server.prefix_for_mode(m)
+ }, c.name]
+ }.inspect
+ end
+ else
+ ret << '(none)'
+ end
+ ret << ' plugins=' << plugins.inspect
+ ret << ">"
+ end
+
+
+ # create a new Bot with botclass +botclass+
+ def initialize(botclass, params = {})
+ # Config for the core bot
+ # TODO should we split socket stuff into ircsocket, etc?
+ Config.register Config::ArrayValue.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.")
+ Config.register Config::BooleanValue.new('server.ssl',
+ :default => false, :requires_restart => true, :wizard => true,
+ :desc => "Use SSL to connect to this server?")
+ Config.register Config::StringValue.new('server.password',
+ :default => false, :requires_restart => true,
+ :desc => "Password for connecting to this server (if required)",
+ :wizard => true)
+ Config.register Config::StringValue.new('server.bindhost',
+ :default => false, :requires_restart => true,
+ :desc => "Specific local host or IP for the bot to bind to (if required)",
+ :wizard => true)
+ Config.register Config::IntegerValue.new('server.reconnect_wait',
+ :default => 5, :validate => Proc.new{|v| v >= 0},
+ :desc => "Seconds to wait before attempting to reconnect, on disconnect")
+ Config.register Config::IntegerValue.new('server.ping_timeout',
+ :default => 30, :validate => Proc.new{|v| v >= 0},
+ :desc => "reconnect if server doesn't respond to PING within this many seconds (set to 0 to disable)")
+ Config.register Config::ArrayValue.new('server.nocolor_modes',
+ :default => ['c'], :wizard => false,
+ :requires_restart => false,
+ :desc => "List of channel modes that require messages to be without colors")
+
+ Config.register Config::StringValue.new('irc.nick', :default => "rbot",
+ :desc => "IRC nickname the bot should attempt to use", :wizard => true,
+ :on_change => Proc.new{|bot, v| bot.sendq "NICK #{v}" })
+ Config.register Config::StringValue.new('irc.name',
+ :default => "Ruby bot", :requires_restart => true,
+ :desc => "IRC realname the bot should use")
+ Config.register Config::BooleanValue.new('irc.name_copyright',
+ :default => true, :requires_restart => true,
+ :desc => "Append copyright notice to bot realname? (please don't disable unless it's really necessary)")
+ Config.register Config::StringValue.new('irc.user', :default => "rbot",
+ :requires_restart => true,
+ :desc => "local user the bot should appear to be", :wizard => true)
+ Config.register Config::ArrayValue.new('irc.join_channels',
+ :default => [], :wizard => true,
+ :desc => "What channels the bot should always join at startup. List multiple channels using commas to separate. If a channel requires a password, use a space after the channel name. e.g: '#chan1, #chan2, #secretchan secritpass, #chan3'")
+ Config.register Config::ArrayValue.new('irc.ignore_users',
+ :default => [],
+ :desc => "Which users to ignore input from. This is mainly to avoid bot-wars triggered by creative people")
+ Config.register Config::ArrayValue.new('irc.ignore_channels',
+ :default => [],
+ :desc => "Which channels to ignore input in. This is mainly to turn the bot into a logbot that doesn't interact with users in any way (in the specified channels)")
+
+ Config.register Config::IntegerValue.new('core.save_every',
+ :default => 60, :validate => Proc.new{|v| v >= 0},
+ :on_change => Proc.new { |bot, v|
+ if @save_timer
+ if v > 0
+ @timer.reschedule(@save_timer, v)
+ @timer.unblock(@save_timer)
+ else
+ @timer.block(@save_timer)
+ end
+ else
+ if v > 0
+ @save_timer = @timer.add(v) { bot.save }
+ end
+ # Nothing to do when v == 0
+ end
+ },
+ :desc => "How often the bot should persist all configuration to disk (in case of a server crash, for example)")
+
+ Config.register Config::BooleanValue.new('core.run_as_daemon',
+ :default => false, :requires_restart => true,
+ :desc => "Should the bot run as a daemon?")