]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - data/rbot/plugins/autoop.rb
webhook: typo preventing unwatch
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / autoop.rb
index c45419066a5bd585ec2cc56a1e48580ff1cc8ec8..7bff4c250bbef870d2797247a5e5b5bd6d2d83ad 100644 (file)
@@ -1,10 +1,23 @@
 class AutoOP < Plugin
-  BotConfig.register BotConfigBooleanValue.new('autoop.on_nick',
+  Config.register Config::BooleanValue.new('autoop.on_nick',
     :default => true,
-    :desc => "Determines if the bot should auto-op when someone changes nick and the new nick matches a listed netmask")
+    :desc => "Determines if the bot should auto-op when someone changes nick " +
+             "and the new nick matches a listed netmask")
+
+  Config.register Config::StringValue.new('autoop.seed_format',
+    :default => "*!%{user}@*",
+    :desc => "Hostmask format used when seeding channels. Recognized tokens: " +
+             "nick, user, host")
 
   def help(plugin, topic="")
-    return "perform autoop based on hostmask - usage: add <hostmask> [channel channel ...], rm <hostmask> [channel], list - list current ops. If you don't specify which channels, all channels are assumed"
+    return "perform autoop based on hostmask - usage:" +
+           "add <hostmask> [channel channel ...], rm <hostmask> [channel], " +
+             "If you don't specify which channels, all channels are assumed, " +
+           "list - list current ops, " +
+           "restore [channel] - op anybody that would " +
+             "have been opped if they had just joined, " +
+           "seed [channel] - Find current ops and make sure they will " +
+             "continue to be autoopped"
   end
 
   def join(m)
@@ -38,8 +51,72 @@ class AutoOP < Plugin
   end
 
   def add(m, params)
-    @registry[params[:mask]] = params[:channels].dup
-    m.okay
+    if params[:channels].empty? || !@registry.has_key?(params[:mask])
+      # if the channels parameter is omitted (meaning all channels), or the
+      # hostmask isn't present in the registry, we just (over)write the channels
+      # in the registry
+      @registry[params[:mask]] = params[:channels].dup
+      m.okay
+    else
+      # otherwise, merge the channels with the ones existing in the registry
+      current_channels = @registry[params[:mask]]
+      if current_channels.empty?
+        m.reply "#{params[:mask]} is already being auto-opped on all channels"
+      else
+        # merge the already set channels
+        @registry[params[:mask]] = (params[:channels] | current_channels).uniq
+        m.okay
+      end
+    end
+  end
+
+  def seed(m, params)
+    chan = params[:channel]
+    if chan == nil
+      if m.public?
+        chan = m.channel
+      else
+        m.reply _("Either specify a channel to seed, or ask in public")
+      end
+    end
+
+    current_ops = @bot.server.channel(chan).users.select { |u|
+        u.is_op?(chan) and u.nick != @bot.nick
+    }
+
+    netmasks = current_ops.map { |u|
+      @bot.config['autoop.seed_format'] % {
+        :user => u.user,
+        :nick => u.nick,
+        :host => u.host
+      }
+    }.uniq
+
+    to_add = netmasks.select { |mask|
+        @registry.key?(mask) == false or @registry[mask].empty? == false
+    }
+
+    if to_add.empty?
+      m.reply _("Nobody to add")
+      return
+    end
+
+    results = []
+    to_add.each { |mask|
+      if @registry.key? mask
+        if @registry[mask].include? chan
+          next
+        else
+          current_channels = @registry[mask].dup
+          @registry[mask] = ([chan] | current_channels).uniq
+          results << _("Added #{mask} in #{chan}")
+        end
+      else
+        @registry[mask] = [chan]
+        results << _("Created autoop entry for #{mask} and added #{chan}")
+      end
+    }
+    m.reply results.join ". "
   end
 
   def rm(m, params)
@@ -70,6 +147,31 @@ class AutoOP < Plugin
       m.reply "No entries"
     end
   end
+
+  def restore(m, params)
+    chan = params[:channel]
+    if chan == nil
+      if m.public?
+        chan = m.channel
+      else
+        m.reply _("Either specify a channel to restore, or ask in public")
+      end
+    end
+
+    current_non_ops = @bot.server.channel(chan).users.select { |u|
+      u.is_op?(chan) == nil and u.nick != @bot.nick
+    }
+
+    @registry.each { |mask,channels|
+      if channels.empty? || channels.include?(chan)
+        current_non_ops.each { |victim|
+          if victim.matches?(mask.to_irc_netmask(:server => m.server))
+            @bot.mode(chan, "+o", victim)
+          end
+        }
+      end
+    }
+  end
 end
 
 plugin = AutoOP.new
@@ -77,3 +179,7 @@ plugin = AutoOP.new
 plugin.map 'autoop list', :action => 'list'
 plugin.map 'autoop add :mask [*channels]', :action => 'add'
 plugin.map 'autoop rm :mask [*channels]', :action => 'rm'
+plugin.map 'autoop seed [:channel]', :action => 'seed'
+plugin.map 'autoop restore [:channel]', :action => 'restore'
+
+plugin.default_auth('*',false)