]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/ircbot.rb
rdocument Irc::MessageMapper and Irc::MessageTemplate
[user/henk/code/ruby/rbot.git] / lib / rbot / ircbot.rb
index c8b0d46f0ee4aa7ea4ac15317e66d54171f428d9..e171384008d1481cbbe3e633fa21c239146e7ff1 100644 (file)
@@ -1,3 +1,8 @@
+#-- vim:sw=2:et
+#++
+#
+# :title: rbot core
+
 require 'thread'
 
 require 'etc'
@@ -25,7 +30,10 @@ end
 class Exception
   def pretty_print(q)
     q.group(1, "#<%s: %s" % [self.class, self.message], ">") {
-      q.seplist(self.backtrace, lambda { "\n" }) { |v| v } if self.backtrace
+      if self.backtrace and not self.backtrace.empty?
+        q.text "\n"
+        q.seplist(self.backtrace, lambda { q.text "\n" } ) { |l| q.text l }
+      end
     }
   end
 end
@@ -90,10 +98,9 @@ fatal "fatal test"
 # The following global is used for the improved signal handling.
 $interrupted = 0
 
-require 'rbot/load-gettext'
-
 # these first
 require 'rbot/rbotconfig'
+require 'rbot/load-gettext'
 require 'rbot/config'
 # require 'rbot/utils'
 
@@ -116,6 +123,7 @@ module Irc
 # handles them or passes them to plugins, and contains core functionality.
 class Bot
   COPYRIGHT_NOTICE = "(c) Tom Gilbert and the rbot development team"
+  SOURCE_URL = "http://linuxbrit.co.uk/rbot"
   # the bot's Auth data
   attr_reader :auth
 
@@ -437,7 +445,7 @@ class Bot
 
     @registry = BotRegistry.new self
 
-    @timer = Timer::Timer.new(1.0) # only need per-second granularity
+    @timer = Timer.new
     @save_mutex = Mutex.new
     if @config['core.save_every'] > 0
       @save_timer = @timer.add(@config['core.save_every']) { save }
@@ -449,7 +457,7 @@ class Bot
     @logs = Hash.new
 
     @plugins = nil
-    @lang = Language::Language.new(self, @config['core.language'])
+    @lang = Language.new(self, @config['core.language'])
 
     begin
       @auth = Auth::authmanager
@@ -540,8 +548,9 @@ class Bot
 
       unless ignored
         @plugins.delegate "listen", m
+        @plugins.delegate("ctcp_listen", m) if m.ctcp
         @plugins.privmsg(m) if m.address?
-       if not m.replied
+        if not m.replied
           @plugins.delegate "unreplied", m
         end
       end
@@ -771,7 +780,6 @@ class Bot
       begin
         quit if $interrupted > 0
         connect
-        @timer.start
 
         quit_msg = nil
         while @socket.connected?
@@ -955,34 +963,19 @@ class Bot
     sendmsg "PRIVMSG", where, message, options
   end
 
+  def ctcp_notice(where, command, message, options={})
+    return if where.kind_of?(Channel) and quiet_on?(where)
+    sendmsg "NOTICE", where, "\001#{command} #{message}\001", options
+  end
+
+  def ctcp_say(where, command, message, options={})
+    return if where.kind_of?(Channel) and quiet_on?(where)
+    sendmsg "PRIVMSG", where, "\001#{command} #{message}\001", options
+  end
+
   # perform a CTCP action with message +message+ to channel/nick +where+
   def action(where, message, options={})
-    return if where.kind_of?(Channel) and quiet_on?(where)
-    mchan = options.fetch(:queue_channel, nil)
-    mring = options.fetch(:queue_ring, nil)
-    if mchan
-      chan = mchan
-    else
-      chan = where
-    end
-    if mring
-      ring = mring
-    else
-      case where
-      when User
-        ring = 1
-      else
-        ring = 2
-      end
-    end
-    # FIXME doesn't check message length. Can we make this exploit sendmsg?
-    sendq "PRIVMSG #{where} :\001ACTION #{message}\001", chan, ring
-    case where
-    when Channel
-      irclog "* #{myself} #{message}", where
-    else
-      irclog "* #{myself}[#{where}] #{message}", where
-    end
+    ctcp_say(where, 'ACTION', message, options)
   end
 
   # quick way to say "okay" (or equivalent) to +where+
@@ -1013,8 +1006,8 @@ class Bot
     sendq "TOPIC #{where} :#{topic}", where, 2
   end
 
-  def disconnect(message = nil)
-    message = @lang.get("quit") if (message.nil? || message.empty?)
+  def disconnect(message=nil)
+    message = @lang.get("quit") if (!message || message.empty?)
     if @socket.connected?
       debug "Clearing socket"
       @socket.clearq
@@ -1034,9 +1027,9 @@ class Bot
   end
 
   # disconnect from the server and cleanup all plugins and modules
-  def shutdown(message = nil)
+  def shutdown(message=nil)
     @quit_mutex.synchronize do
-      debug "Shutting down:"
+      debug "Shutting down: #{message}"
       ## No we don't restore them ... let everything run through
       # begin
       #   trap("SIGINT", "DEFAULT")
@@ -1046,15 +1039,17 @@ class Bot
       #   debug "failed to restore signals: #{e.inspect}\nProbably running on windows?"
       # end
       debug "\tdisconnecting..."
-      disconnect
+      disconnect(message)
+      debug "\tstopping timer..."
+      @timer.stop
       debug "\tsaving ..."
       save
       debug "\tcleaning up ..."
       @save_mutex.synchronize do
         @plugins.cleanup
       end
-      debug "\tstopping timers ..."
-      @timer.stop
+      debug "\tstopping timers ..."
+      @timer.stop
       # debug "Closing registries"
       # @registry.close
       debug "\t\tcleaning up the db environment ..."
@@ -1074,9 +1069,9 @@ class Bot
   end
 
   # totally shutdown and respawn the bot
-  def restart(message = false)
-    msg = message ? message : "restarting, back in #{@config['server.reconnect_wait']}..."
-    shutdown(msg)
+  def restart(message=nil)
+    message = "restarting, back in #{@config['server.reconnect_wait']}..." if (!message || message.empty?)
+    shutdown(message)
     sleep @config['server.reconnect_wait']
     begin
       # now we re-exec
@@ -1102,10 +1097,13 @@ class Bot
 
   # call the rescan method for all of the botmodules
   def rescan
+    debug "\tstopping timer..."
+    @timer.stop
     @save_mutex.synchronize do
       @lang.rescan
       @plugins.rescan
     end
+    @timer.start
   end
 
   # channel:: channel to join
@@ -1146,12 +1144,12 @@ class Bot
     topic = nil if topic == ""
     case topic
     when nil
-      helpstr = "help topics: "
+      helpstr = _("help topics: ")
       helpstr += @plugins.helptopics
-      helpstr += " (help <topic> for more info)"
+      helpstr += _(" (help <topic> for more info)")
     else
       unless(helpstr = @plugins.help(topic))
-        helpstr = "no help for topic #{topic}"
+        helpstr = _("no help for topic %{topic}") % { :topic => topic }
       end
     end
     return helpstr
@@ -1162,7 +1160,11 @@ class Bot
     secs_up = Time.new - @startup_time
     uptime = Utils.secs_to_string secs_up
     # return "Uptime #{uptime}, #{@plugins.length} plugins active, #{@registry.length} items stored in registry, #{@socket.lines_sent} lines sent, #{@socket.lines_received} received."
-    return "Uptime #{uptime}, #{@plugins.length} plugins active, #{@socket.lines_sent} lines sent, #{@socket.lines_received} received."
+    return (_("Uptime %{up}, %{plug} plugins active, %{sent} lines sent, %{recv} received.") %
+             {
+               :up => uptime, :plug => @plugins.length,
+               :sent => @socket.lines_sent, :recv => @socket.lines_received
+             })
   end
 
   # We want to respond to a hung server in a timely manner. If nothing was received