summaryrefslogtreecommitdiff
path: root/lib/rbot
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbot')
-rw-r--r--lib/rbot/httputil.rb3
-rw-r--r--lib/rbot/ircbot.rb78
-rw-r--r--lib/rbot/language.rb2
-rw-r--r--lib/rbot/messagemapper.rb4
-rw-r--r--lib/rbot/plugins.rb2
5 files changed, 47 insertions, 42 deletions
diff --git a/lib/rbot/httputil.rb b/lib/rbot/httputil.rb
index b49a42b1..c6f51d8e 100644
--- a/lib/rbot/httputil.rb
+++ b/lib/rbot/httputil.rb
@@ -1,4 +1,5 @@
module Irc
+module Utils
require 'resolv'
require 'net/http'
@@ -135,5 +136,5 @@ class HttpUtil
return nil
end
end
-
+end
end
diff --git a/lib/rbot/ircbot.rb b/lib/rbot/ircbot.rb
index d0010c2a..6bdf7bdf 100644
--- a/lib/rbot/ircbot.rb
+++ b/lib/rbot/ircbot.rb
@@ -81,7 +81,7 @@ class IrcBot
attr_reader :httputil
# create a new IrcBot with botclass +botclass+
- def initialize(botclass)
+ def initialize(botclass, params = {})
# BotConfig for the core bot
BotConfig.register BotConfigStringValue.new('server.name',
:default => "localhost", :requires_restart => true,
@@ -124,6 +124,8 @@ class IrcBot
:desc => "(flood prevention) max lines to burst to the server before throttling. Most ircd's allow bursts of up 5 lines, with non-burst limits of 512 bytes/2 seconds",
:on_change => Proc.new {|bot, v| bot.socket.sendq_burst = v })
+ @argv = params[:argv]
+
unless FileTest.directory? Config::DATADIR
puts "data directory '#{Config::DATADIR}' not found, did you install.rb?"
exit 2
@@ -144,22 +146,22 @@ class IrcBot
Dir.mkdir("#{botclass}/logs") unless File.exist?("#{botclass}/logs")
@startup_time = Time.new
- @config = Irc::BotConfig.new(self)
+ @config = BotConfig.new(self)
@timer = Timer::Timer.new(1.0) # only need per-second granularity
@registry = BotRegistry.new self
@timer.add(@config['core.save_every']) { save } if @config['core.save_every']
@channels = Hash.new
@logs = Hash.new
- @httputil = Irc::HttpUtil.new(self)
- @lang = Irc::Language.new(@config['core.language'])
- @keywords = Irc::Keywords.new(self)
- @auth = Irc::IrcAuth.new(self)
+ @httputil = Utils::HttpUtil.new(self)
+ @lang = Language::Language.new(@config['core.language'])
+ @keywords = Keywords.new(self)
+ @auth = IrcAuth.new(self)
Dir.mkdir("#{botclass}/plugins") unless File.exist?("#{botclass}/plugins")
- @plugins = Irc::Plugins.new(self, ["#{botclass}/plugins"])
+ @plugins = Plugins::Plugins.new(self, ["#{botclass}/plugins"])
- @socket = Irc::IrcSocket.new(@config['server.name'], @config['server.port'], @config['server.bindhost'], @config['server.sendq_delay'], @config['server.sendq_burst'])
+ @socket = IrcSocket.new(@config['server.name'], @config['server.port'], @config['server.bindhost'], @config['server.sendq_delay'], @config['server.sendq_burst'])
@nick = @config['irc.nick']
if @config['core.address_prefix']
@addressing_prefixes = @config['core.address_prefix'].split(" ")
@@ -167,7 +169,7 @@ class IrcBot
@addressing_prefixes = Array.new
end
- @client = Irc::IrcClient.new
+ @client = IrcClient.new
@client["PRIVMSG"] = proc { |data|
message = PrivMessage.new(self, data["SOURCE"], data["TARGET"], data["MESSAGE"])
onprivmsg(message)
@@ -339,9 +341,14 @@ class IrcBot
@client.process reply
end
end
+ rescue TimeoutError, SocketError => e
+ puts "network exception: connection closed: #{e}"
+ puts e.backtrace.join("\n")
+ @socket.close # now we reconnect
rescue => e # TODO be selective, only grab Network errors
- puts "connection closed: #{e}"
+ puts "unexpected exception: connection closed: #{e}"
puts e.backtrace.join("\n")
+ exit 2
end
puts "disconnected"
@@ -439,14 +446,12 @@ class IrcBot
def topic(where, topic)
sendq "TOPIC #{where} :#{topic}"
end
-
- # message:: optional IRC quit message
- # quit IRC, shutdown the bot
- def quit(message=nil)
+
+ def shutdown(message = nil)
trap("SIGTERM", "DEFAULT")
trap("SIGHUP", "DEFAULT")
trap("SIGINT", "DEFAULT")
- message = @lang.get("quit") if (!message || message.length < 1)
+ message = @lang.get("quit") if (message.nil? || message.empty?)
@socket.clearq
save
@plugins.cleanup
@@ -458,9 +463,23 @@ class IrcBot
@socket.shutdown
@registry.close
puts "rbot quit (#{message})"
+ end
+
+ # message:: optional IRC quit message
+ # quit IRC, shutdown the bot
+ def quit(message=nil)
+ shutdown(message)
exit 0
end
+ # totally shutdown and respawn the bot
+ def restart
+ shutdown("restarting, back in #{@config['server.reconnect_wait']}...")
+ sleep @config['server.reconnect_wait']
+ # now we re-exec
+ exec($0, *@argv)
+ end
+
# call the save method for bot's config, keywords, auth and all plugins
def save
@registry.flush
@@ -552,6 +571,8 @@ class IrcBot
case topic
when "quit"
return "quit [<message>] => quit IRC with message <message>"
+ when "restart"
+ return "restart => completely stop and restart the bot (including reconnect)"
when "join"
return "join <channel> [<key>] => join channel <channel> with secret key <key> if specified. #{@nick} also responds to invites if you have the required access level"
when "part"
@@ -581,7 +602,7 @@ class IrcBot
when "hello"
return "hello|hi|hey|yo [#{@nick}] => greet the bot"
else
- return "Core help topics: quit, join, part, hide, save, rescan, nick, say, action, topic, quiet, talk, version, botsnack, hello"
+ return "Core help topics: quit, restart, config, join, part, hide, save, rescan, nick, say, action, topic, quiet, talk, version, botsnack, hello"
end
end
@@ -623,6 +644,8 @@ class IrcBot
part $1 if(@auth.allow?("join", m.source, m.replyto))
when (/^quit(?:\s+(.*))?$/i)
quit $1 if(@auth.allow?("quit", m.source, m.replyto))
+ when (/^restart$/i)
+ restart if(@auth.allow?("quit", m.source, m.replyto))
when (/^hide$/i)
join 0 if(@auth.allow?("join", m.source, m.replyto))
when (/^save$/i)
@@ -671,29 +694,6 @@ class IrcBot
@channels[where].quiet = false if(@channels.has_key?(where))
m.okay
end
- # TODO break this out into a config module
- when (/^options get sendq_delay$/i)
- if auth.allow?("config", m.source, m.replyto)
- m.reply "options->sendq_delay = #{@socket.sendq_delay}"
- end
- when (/^options get sendq_burst$/i)
- if auth.allow?("config", m.source, m.replyto)
- m.reply "options->sendq_burst = #{@socket.sendq_burst}"
- end
- when (/^options set sendq_burst (.*)$/i)
- num = $1.to_i
- if auth.allow?("config", m.source, m.replyto)
- @socket.sendq_burst = num
- @config['irc.sendq_burst'] = num
- m.okay
- end
- when (/^options set sendq_delay (.*)$/i)
- freq = $1.to_f
- if auth.allow?("config", m.source, m.replyto)
- @socket.sendq_delay = freq
- @config['irc.sendq_delay'] = freq
- m.okay
- end
when (/^status\??$/i)
m.reply status if auth.allow?("status", m.source, m.replyto)
when (/^registry stats$/i)
diff --git a/lib/rbot/language.rb b/lib/rbot/language.rb
index d48607b8..c472c12e 100644
--- a/lib/rbot/language.rb
+++ b/lib/rbot/language.rb
@@ -1,4 +1,5 @@
module Irc
+module Language
class Language
BotConfig.register BotConfigEnumValue.new('core.language',
@@ -63,3 +64,4 @@ module Irc
end
end
+end
diff --git a/lib/rbot/messagemapper.rb b/lib/rbot/messagemapper.rb
index f83fafb2..445b80f5 100644
--- a/lib/rbot/messagemapper.rb
+++ b/lib/rbot/messagemapper.rb
@@ -9,7 +9,7 @@ module Irc
end
def map(*args)
- @routes << Route.new(*args)
+ @routes << Template.new(*args)
end
def each
@@ -53,7 +53,7 @@ module Irc
end
- class Route
+ class Template
attr_reader :defaults # The defaults hash
attr_reader :options # The options hash
attr_reader :items
diff --git a/lib/rbot/plugins.rb b/lib/rbot/plugins.rb
index d4e5be9f..ba01aa7d 100644
--- a/lib/rbot/plugins.rb
+++ b/lib/rbot/plugins.rb
@@ -1,4 +1,5 @@
module Irc
+module Plugins
require 'rbot/messagemapper'
# base class for all rbot plugins
@@ -284,3 +285,4 @@ module Irc
end
end
+end