diff --git a/classes/.Util.rb.swp b/classes/.Util.rb.swp new file mode 100644 index 00000000..2d68cf89 Binary files /dev/null and b/classes/.Util.rb.swp differ diff --git a/classes/Forget.rb b/classes/Forget.rb new file mode 100644 index 00000000..13eefdd7 --- /dev/null +++ b/classes/Forget.rb @@ -0,0 +1,27 @@ +require 'cinch' +require 'open-uri' +require_relative '../classes/Util.rb' +class Forget + include Cinch::Plugin + include Hooks::ACLHook + include Util::PluginHelper + set :prefix, /^:/ + @@commands["forget"] = ":forget - 'forget' a plugin (disable )" + @@levelRequired = 10 + match /forget ([a-zA-Z][a-zA-Z0-9]+)/; + + def execute(m, modname) + aclcheck(m) + if(!aclcheck(m)) + m.reply("#{m.user.nick}: your access level is not high enough for this command.") + return + end + ibot = Util::BotFamily.instance.get(Util::Util.instance.hton(m.bot.config.server)).bot + plug = Kernel.const_get(modname) + require "/var/src/ruby/extendobot/plugins/#{modname}.rb" + ibot.plugins.unregister_plugin(plug) + m.reply("#{modname} forgotten successfully") + end +end + + diff --git a/classes/Hooks.rb b/classes/Hooks.rb index 93cb385a..fff5d46b 100644 --- a/classes/Hooks.rb +++ b/classes/Hooks.rb @@ -3,7 +3,7 @@ require_relative 'Util.rb' module Hooks module AuthHook include Cinch::Plugin - hook :pre, method: :is_authed + hook :pre, { method: :is_authed } def is_authed(m) user = m.user; if m.authed? @@ -17,17 +17,15 @@ module Hooks end module ACLHook include Cinch::Plugin - @cmdname = "" - @levelRequired = "" - hook :pre, method: :aclcheck + @@levelRequired = 0 def aclcheck(m) - debug "performing aclcheck against #{m.user.name}" - user = m.user.name + user = m.user.nick acl = Util::Util.instance.getDB("acl") users = acl.collection("users") - res = users.find_one({'user' => user}) + name = Util::Util.instance.hton(m.bot.config.server) + res = users.find_one({'user' => user, 'server' => name}) Thread.current[:result] = res - if res['level'] >= @levelRequired + if res['level'].to_i >= @@levelRequired.to_i Thread.current[:aclpass] = true return true else diff --git a/classes/Util.rb b/classes/Util.rb index 416782b3..0964bbee 100644 --- a/classes/Util.rb +++ b/classes/Util.rb @@ -21,22 +21,84 @@ module Util def getCollection(dbn,col) return @@mongo.db(dbn).collection(col) end - end - class Bot - def self.instance - @@instance ||= new + def getServers() + servers = Array.new() + col = self.getCollection("chans","servers") + col.find.each { |row| + servers.push(row) + } + return servers end + def hton(host) + col = getCollection("chans","servers") + return col.find_one({ "host" => host })['name'] + end + def MainLoop + Thread.list.each { |thr| + thr.join + } + end + end + class BotFamily + def self.instance + @@instance ||= new + end + def initialize + @@family = Hash.new + @@workers = Hash.new + end + def get(name) + return @@family[name] + end + def self.add(opts) + host = opts['host'] || nil; + name = opts['name'] || nil; + @@family[name] = Bot.new(host) + end + def add(opts) + host = opts['host'] || nil; + name = opts['name'] || nil; + @@family[name] = Bot.new(host) + end + def spawn(opts) + add(opts) + start(opts['name']) + end + def start(name) + @@workers[name] ||= Thread.new(@@family[name]) { |bot| + bot.start + } + end + def startAll() + @@family.each { |k, v| + start(k) + } + end + def stop(name) + @@workers[name].kill + @@workers[name] = nil + @@family[name].stop + end + def stopAll() + @@workers.each { |k, v| + stop(k) + } + end + + end + class Bot attr_accessor :bot - def initialize + def initialize(host) @bot = Cinch::Bot.new do configure do |c| - c.server = "irc.wtfux.org" + c.server = host mong = Util.instance conf = mong.getCollection("extendobot","config"); - nick = conf.find_one({'key' => "nick"}) + name = Util.instance.hton(host) + nick = conf.find_one({ 'key' => 'nick', 'server' => name }) c.nick = nick['val'] chans = mong.getCollection("chans","channels") - cList = chans.find({'autojoin' => true}).collect { |x| + cList = chans.find({'autojoin' => true, 'server' => name}).collect { |x| x['channel'] } c.channels = cList @@ -48,10 +110,26 @@ module Util c.plugins.plugins = pList; end end + end def start @bot.start - end + end + def stop + @bot.stop + end + end + module PluginHelper + @@commands = Hash.new + @@levelRequired = 0 + def commands + ret = Array.new + @@commands.each { |k, v| + ret.push k + } + return ret + end + end end diff --git a/extendobot b/extendobot index 146b5319..16ed12ae 100755 --- a/extendobot +++ b/extendobot @@ -4,5 +4,14 @@ require 'cinch' require_relative './classes/Util' utils = Util::Util.instance; -bot = Util::Bot.instance; -bot.start +bots = Util::BotFamily.instance +servers = utils.getServers() +servers.each { |serv| + bots.add( { + "host" => serv['host'], + "name" => serv['name'] + } + ) if serv['autoconnect'] +} +bots.startAll +utils.MainLoop diff --git a/hooktest b/hooktest new file mode 100755 index 00000000..85a45b69 --- /dev/null +++ b/hooktest @@ -0,0 +1,47 @@ +#!/usr/bin/ruby1.9.1 +require 'cinch' + +module RandHook + include Cinch::Plugin + def self.generate_random_number(m) + # Hooks are called in the same thread as the handler and thus + # using thread local variables is possible. + Thread.current[:rand] = Kernel.rand + end + def self.prehook(method) + hook :pre, method: method.to_sym + end + prehook("generate_random_number") + + def self.cheer(m) + m.reply "Yay, I successfully ran a command" + end + def initialize(*args) + super + self.hook :pre, method: :generate_random_number + self.hook :post, method: :cheer + end + end + +class HooksDemo + include Cinch::Plugin + include RandHook + + match "rand" + def execute(m) + m.reply "Random number: " + Thread.current[:rand].to_s + end +end + +bot = Cinch::Bot.new do + configure do |c| + c.nick = "cinch_hooks" + c.server = "irc.freenode.org" + c.channels = ["#dacleeze"] + c.verbose = true + c.plugins.plugins = [HooksDemo] + end +end + + +bot.start diff --git a/plugins/.Help.rb.swp b/plugins/.Help.rb.swp new file mode 100644 index 00000000..0748400e Binary files /dev/null and b/plugins/.Help.rb.swp differ diff --git a/plugins/DynPlug.rb b/plugins/DynPlug.rb index beba2afc..c18c20c4 100644 --- a/plugins/DynPlug.rb +++ b/plugins/DynPlug.rb @@ -4,15 +4,16 @@ require_relative '../classes/Util.rb' class DynPlug include Cinch::Plugin include Hooks::ACLHook + include Util::PluginHelper set :prefix, /^:/ - @commandName = "dynload" - @levelRequired = 10 + @@commands["dynload"] = ":dynload - dynamically load a plugin from url" + @@levelRequired = 10 match /dynload ([a-zA-Z][a-zA-Z0-9]+) (.+)/; def execute(m, modname, url) - if(!Thread.current[:aclpass]) - m.reply("#{m.user.name}: your access level is not high enough for this command.") - debug Thread.current.inspect + aclcheck(m) + if(!aclcheck(m)) + m.reply("#{m.user.nick}: your access level is not high enough for this command.") return end if(File.exist?("/var/src/ruby/extendobot/plugins/#{modname}.rb")) @@ -28,7 +29,7 @@ class DynPlug end end require "/var/src/ruby/extendobot/plugins/#{modname}.rb"; - ibot = Util::Bot.instance + ibot = Util::BotFamily.instance.get(Util::Util.instance.hton(m.bot.config.server)) ibot.bot.plugins.register_plugin(Object.const_get(modname)) m.reply("#{modname} added successfully") end diff --git a/plugins/Helo.rb b/plugins/Helo.rb index d7e445bb..8ac6b6d6 100644 --- a/plugins/Helo.rb +++ b/plugins/Helo.rb @@ -2,8 +2,9 @@ require 'cinch' require_relative '../classes/Util.rb' class Helo include Cinch::Plugin + include Util::PluginHelper set :prefix, /^:/ - extend Hooks::ACLHook + @@commands["helo"] = ":helo - say hi!" match /helo/; def execute(m) diff --git a/plugins/Help.rb b/plugins/Help.rb new file mode 100644 index 00000000..bd274225 --- /dev/null +++ b/plugins/Help.rb @@ -0,0 +1,21 @@ +require 'cinch' +require_relative '../classes/Util.rb' +class Help + include Cinch::Plugin + include Util::PluginHelper + @@commands["help"] = ":help [] - produce help for " + set :prefix, /^:/ + match /help (.+)?/, method: :gethelp + + def gethelp(m, mdl = nil) + case mdl + when nil + m.reply("try :help to get help for a command.") + else + cmds = self.class.class_eval { @@commands } + m.reply(cmds[mdl]) + end + end +end + + diff --git a/plugins/PlugTool.rb b/plugins/PlugTool.rb new file mode 100644 index 00000000..a1e8080b --- /dev/null +++ b/plugins/PlugTool.rb @@ -0,0 +1,58 @@ +require 'cinch' +require_relative '../classes/Util.rb' +class PlugTool + include Cinch::Plugin + include Util::PluginHelper + @@commands["plugs"] = ":plugs - produce list of plugins available" + @@commands["commands"] = ":commands - produce list of commands" + set :prefix, /^:/ + match /commands/, method: :pluginfo + match /plugs/, method: :interstitial + + def interstitial(m, sub = nil) + debug "in interstitial, for sub to #{sub.to_s}" + case sub + when ".enabled" + plugs(m,:enabled) + when ".disabled" + plugs(m,:disabled) + else + plugs(m, :all) + end + end + def plugs(m, opt) + debug "in plugs, got opt as #{opt.to_s}" + plugs = Hash.new + Pathname.glob("/var/src/ruby/extendobot/plugins/*.rb").each { |plugin| + plugname = File.basename(plugin.basename,File.extname(plugin)) + plugs[plugname] = Hash.new + plugs[plugname]["enabled"] = m.bot.config.plugins.plugins.include? Object.const_get plugname + debug plugs[plugname].inspect + } + msg = '' + plugs.each { |k, v| + case opt + when :all + debug "all plugs pls" + msg += "#{k} " + when :disabled + debug "only disabled pls" + msg += "#{k} " if !v['enabled'] + when :enabled + debug "only enabled pls" + msg += "#{k} " if v['enabled'] + end + } + m.reply(msg) + end + def pluginfo(m) + cmds = self.class.class_eval { @@commands } + str = "" + cmds.each { |k, v| + str << "#{k} " + } + m.reply(str) + end +end + + diff --git a/plugins/Say.rb b/plugins/Say.rb new file mode 100644 index 00000000..0e315f37 --- /dev/null +++ b/plugins/Say.rb @@ -0,0 +1,14 @@ +require 'cinch' +require_relative '../classes/Util.rb' +class Say + include Cinch::Plugin + include Util::PluginHelper + set :prefix, /^:/ + @@commands["say"] = ":say :shyt - say :shyt bro!" + extend Hooks::ACLHook + match /say (.+)/; + + def execute(m, phr) + m.reply "#{phr}" + end +end