-#-- vim:sw=2:et\r
-#++\r
-#\r
-# :title: rbot basic management from IRC\r
-#\r
-# Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>\r
-# Copyright:: (C) 2006,2007 Giuseppe Bilotta\r
-# License:: GPL v2\r
-\r
-class BasicsModule < CoreBotModule\r
-\r
- def listen(m)\r
- return unless m.kind_of?(PrivMessage)\r
- if m.message =~ /^\001PING\s+(.+)\001/\r
- ping_id = $1\r
- if m.private?\r
- @bot.notice m.source, "\001PING #{ping_id}\001"\r
- @bot.irclog "@ #{m.source} pinged me"\r
- else\r
- @bot.notice m.source, "\001PING #{ping_id}\001"\r
- @bot.irclog "@ #{m.source} pinged #{m.target}"\r
- end\r
- end\r
- end\r
-\r
- def bot_join(m, param)\r
- if param[:pass]\r
- @bot.join param[:chan], param[:pass]\r
- else\r
- @bot.join param[:chan]\r
- end\r
- end\r
-\r
- def bot_part(m, param)\r
- if param[:chan]\r
- @bot.part param[:chan]\r
- else\r
- @bot.part m.target if m.public?\r
- end\r
- end\r
-\r
- def bot_quit(m, param)\r
- @bot.quit(param[:msg] ? param[:msg].join(" ") : nil)\r
- end\r
-\r
- def bot_restart(m, param)\r
- @bot.restart(param[:msg] ? param[:msg].join(" ") : nil)\r
- end\r
-\r
- def bot_hide(m, param)\r
- @bot.join 0\r
- end\r
-\r
- def bot_say(m, param)\r
- @bot.say param[:where], param[:what].join(" ")\r
- end\r
-\r
- def bot_action(m, param)\r
- @bot.action param[:where], param[:what].join(" ")\r
- end\r
-\r
- def bot_mode(m, param)\r
- @bot.mode param[:where], param[:what], param[:who].join(" ")\r
- end\r
-\r
- def bot_ping(m, param)\r
- m.reply "pong"\r
- end\r
-\r
- def bot_quiet(m, param)\r
- if param.has_key?(:where)\r
- @bot.set_quiet param[:where].sub(/^here$/, m.target.downcase)\r
- else\r
- @bot.set_quiet\r
- end\r
- # Make sense when the commmand is given in private or in a non-quieted\r
- # channel\r
- m.okay\r
- end\r
-\r
- def bot_talk(m, param)\r
- if param.has_key?(:where)\r
- @bot.reset_quiet param[:where].sub(/^here$/, m.target.downcase)\r
- else\r
- @bot.reset_quiet\r
- end\r
- # Make sense when the commmand is given in private or in a non-quieted\r
- # channel\r
- m.okay\r
- end\r
-\r
- def bot_help(m, param)\r
- m.reply @bot.help(param[:topic].join(" "))\r
- end\r
-\r
- #TODO move these to a "chatback" plugin\r
- # when (/^(botsnack|ciggie)$/i)\r
- # @bot.say m.replyto, @lang.get("thanks_X") % m.sourcenick if(m.public?)\r
- # @bot.say m.replyto, @lang.get("thanks") if(m.private?)\r
- # when (/^#{Regexp.escape(@bot.nick)}!*$/)\r
- # @bot.say m.replyto, @lang.get("hello_X") % m.sourcenick\r
-\r
- # handle help requests for "core" topics\r
- def help(cmd, topic="")\r
- case cmd\r
- when "quit"\r
- return "quit [<message>] => quit IRC with message <message>"\r
- when "restart"\r
- return "restart => completely stop and restart the bot (including reconnect)"\r
- when "join"\r
- return "join <channel> [<key>] => join channel <channel> with secret key <key> if specified. #{myself} also responds to invites if you have the required access level"\r
- when "part"\r
- return "part <channel> => part channel <channel>"\r
- when "hide"\r
- return "hide => part all channels"\r
- when "save"\r
- return "save => save current dynamic data and configuration"\r
- when "rescan"\r
- return "rescan => reload modules and static facts"\r
- when "nick"\r
- return "nick <nick> => attempt to change nick to <nick>"\r
- when "say"\r
- return "say <channel>|<nick> <message> => say <message> to <channel> or in private message to <nick>"\r
- when "action"\r
- return "action <channel>|<nick> <message> => does a /me <message> to <channel> or in private message to <nick>"\r
- when "quiet"\r
- return "quiet [in here|<channel>] => with no arguments, stop speaking in all channels, if \"in here\", stop speaking in this channel, or stop speaking in <channel>"\r
- when "talk"\r
- return "talk [in here|<channel>] => with no arguments, resume speaking in all channels, if \"in here\", resume speaking in this channel, or resume speaking in <channel>"\r
- when "version"\r
- return "version => describes software version"\r
- when "ping"\r
- return "ping => replies with a pong"\r
- # when "botsnack"\r
- # return "botsnack => reward #{myself} for being good"\r
- # when "hello"\r
- # return "hello|hi|hey|yo [#{myself}] => greet the bot"\r
- else\r
- return "#{name}: quit, restart, join, part, hide, save, rescan, nick, say, action, topic, quiet, talk, version, ping"#, botsnack, hello"\r
- end\r
- end\r
-end\r
-\r
-basics = BasicsModule.new\r
-\r
-basics.map "quit *msg",\r
- :action => 'bot_quit',\r
- :defaults => { :msg => nil },\r
- :auth_path => 'quit'\r
-basics.map "restart *msg",\r
- :action => 'bot_restart',\r
- :defaults => { :msg => nil },\r
- :auth_path => 'quit'\r
-\r
-basics.map "quiet [in] [:where]",\r
- :action => 'bot_quiet',\r
- :auth_path => 'talk::set'\r
-basics.map "talk [in] [:where]",\r
- :action => 'bot_talk',\r
- :auth_path => 'talk::set'\r
-\r
-basics.map "say :where *what",\r
- :action => 'bot_say',\r
- :auth_path => 'talk::do'\r
-basics.map "action :where *what",\r
- :action => 'bot_action',\r
- :auth_path => 'talk::do'\r
-basics.map "mode :where :what *who",\r
- :action => 'bot_mode',\r
- :auth_path => 'talk::do'\r
-\r
-basics.map "join :chan :pass", \r
- :action => 'bot_join',\r
- :defaults => {:pass => nil},\r
- :auth_path => 'move'\r
-basics.map "part :chan",\r
- :action => 'bot_part',\r
- :defaults => {:chan => nil},\r
- :auth_path => 'move'\r
-basics.map "hide",\r
- :action => 'bot_hide',\r
- :auth_path => 'move'\r
-\r
-basics.map "ping",\r
- :action => 'bot_ping',\r
- :auth_path => '!ping!'\r
-basics.map "help *topic",\r
- :action => 'bot_help',\r
- :defaults => { :topic => [""] },\r
- :auth_path => '!help!'\r
-\r
-basics.default_auth('*', false)\r
-\r
+#-- vim:sw=2:et
+#++
+#
+# :title: rbot basic management from IRC
+#
+# Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
+
+class BasicsModule < CoreBotModule
+
+ Config.register Config::BooleanValue.new('irc.join_after_identify',
+ :default => false, :wizard => true, :requires_restart => true,
+ :desc => "Should the bot wait until its identification is confirmed before joining any channels?")
+
+ def join_channels
+ @bot.config['irc.join_channels'].each { |c|
+ debug "autojoining channel #{c}"
+ if(c =~ /^(\S+)\s+(\S+)$/i)
+ @bot.join $1, $2
+ else
+ @bot.join c if(c)
+ end
+ }
+ end
+
+ def identified
+ join_channels
+ end
+
+ # on connect, we join the default channels unless we have to wait for
+ # identification. Observe that this means the bot may not connect any channels
+ # until the 'identified' method gets delegated
+ def connect
+ if @bot.config['irc.join_after_identify']
+ log "waiting for identififcation before JOINing default channels"
+ else
+ join_channels
+ end
+ end
+
+ def ctcp_listen(m)
+ who = m.private? ? "me" : m.target
+ case m.ctcp.intern
+ when :PING
+ m.ctcp_reply m.message
+ when :TIME
+ m.ctcp_reply Time.now.to_s
+ end
+ end
+
+ def bot_join(m, param)
+ if param[:pass]
+ @bot.join param[:chan], param[:pass]
+ else
+ @bot.join param[:chan]
+ end
+ end
+
+ def invite(m)
+ if @bot.auth.allow?(:"basics::move::join", m.source, m.source)
+ @bot.join m.channel
+ end
+ end
+
+ def bot_part(m, param)
+ if param[:chan]
+ @bot.part param[:chan]
+ else
+ @bot.part m.target if m.public?
+ end
+ end
+
+ def bot_channel_list(m, param)
+ ret = _('I am in: ')
+ # sort the channels by the base name and then map with prefixes for the
+ # mode and display.
+ ret << @bot.channels.compact.sort { |a,b|
+ a.name.downcase <=> b.name.downcase
+ }.map { |c|
+ c.modes_of(@bot.myself).map{ |mo|
+ m.server.prefix_for_mode(mo)
+ }.to_s + c.name
+ }.join(', ')
+ m.reply ret
+ end
+
+ def bot_quit(m, param)
+ @bot.quit param[:msg].to_s
+ end
+
+ def bot_restart(m, param)
+ @bot.restart param[:msg].to_s
+ end
+
+ def bot_reconnect(m, param)
+ @bot.reconnect param[:msg].to_s
+ end
+
+ def bot_hide(m, param)
+ @bot.join 0
+ end
+
+ def bot_say(m, param)
+ @bot.say param[:where], param[:what].to_s
+ end
+
+ def bot_notify(m, param)
+ @bot.notice param[:where], param[:what].to_s
+ end
+
+ def bot_action(m, param)
+ @bot.action param[:where], param[:what].to_s
+ end
+
+ def bot_mode(m, param)
+ @bot.mode param[:where], param[:what], param[:who].join(" ")
+ end
+
+ def bot_ping(m, param)
+ m.reply "pong"
+ end
+
+ def bot_quiet(m, param)
+ if param.has_key?(:where)
+ @bot.set_quiet param[:where].sub(/^here$/, m.target.downcase)
+ else
+ @bot.set_quiet
+ end
+ # Make sense when the commmand is given in private or in a non-quieted
+ # channel
+ m.okay
+ end
+
+ def bot_talk(m, param)
+ if param.has_key?(:where)
+ @bot.reset_quiet param[:where].sub(/^here$/, m.target.downcase)
+ else
+ @bot.reset_quiet
+ end
+ # Make sense when the commmand is given in private or in a non-quieted
+ # channel
+ m.okay
+ end
+
+ def bot_help(m, param)
+ m.reply @bot.help(param[:topic].join(" "))
+ end
+
+ #TODO move these to a "chatback" plugin
+ # when (/^(botsnack|ciggie)$/i)
+ # @bot.say m.replyto, @lang.get("thanks_X") % m.sourcenick if(m.public?)
+ # @bot.say m.replyto, @lang.get("thanks") if(m.private?)
+ # when (/^#{Regexp.escape(@bot.nick)}!*$/)
+ # @bot.say m.replyto, @lang.get("hello_X") % m.sourcenick
+
+ # handle help requests for "core" topics
+ def help(cmd, topic="")
+ case cmd
+ when "quit"
+ _("quit [<message>] => quit IRC with message <message>")
+ when "restart"
+ _("restart => completely stop and restart the bot (including reconnect)")
+ when "reconnect"
+ _("reconnect => ask the bot to disconnect and then connect again")
+ when "join"
+ _("join <channel> [<key>] => join channel <channel> with secret key <key> if specified. #{@bot.myself} also responds to invites if you have the required access level")
+ when "part"
+ _("part <channel> => part channel <channel>")
+ when "hide"
+ _("hide => part all channels")
+ when "say"
+ _("say <channel>|<nick> <message> => say <message> to <channel> or in private message to <nick>")
+ when "action"
+ _("action <channel>|<nick> <message> => does a /me <message> to <channel> or in private message to <nick>")
+ when "quiet"
+ _("quiet [in here|<channel>] => with no arguments, stop speaking in all channels, if \"in here\", stop speaking in this channel, or stop speaking in <channel>")
+ when "talk"
+ _("talk [in here|<channel>] => with no arguments, resume speaking in all channels, if \"in here\", resume speaking in this channel, or resume speaking in <channel>")
+ when "ping"
+ _("ping => replies with a pong")
+ when "mode"
+ _("mode <channel> <mode> <nicks> => set channel modes for <nicks> on <channel> to <mode>")
+ # when "botsnack"
+ # return "botsnack => reward #{@bot.myself} for being good"
+ # when "hello"
+ # return "hello|hi|hey|yo [#{@bot.myself}] => greet the bot"
+ else
+ _("%{name}: quit, restart, join, part, hide, save, say, action, topic, quiet, talk, ping, mode") % {:name=>name}
+ #, botsnack, hello
+ end
+ end
+end
+
+basics = BasicsModule.new
+
+basics.map "quit *msg",
+ :action => 'bot_quit',
+ :defaults => { :msg => nil },
+ :auth_path => 'quit'
+basics.map "restart *msg",
+ :action => 'bot_restart',
+ :defaults => { :msg => nil },
+ :auth_path => 'quit'
+basics.map "reconnect *msg",
+ :action => 'bot_reconnect',
+ :defaults => { :msg => nil },
+ :auth_path => 'quit'
+
+basics.map "quiet [in] [:where]",
+ :action => 'bot_quiet',
+ :auth_path => 'talk::set'
+basics.map "talk [in] [:where]",
+ :action => 'bot_talk',
+ :auth_path => 'talk::set'
+
+basics.map "say :where *what",
+ :action => 'bot_say',
+ :auth_path => 'talk::do'
+basics.map "notify :where *what",
+ :action => 'bot_notify',
+ :auth_path => 'talk::do'
+basics.map "action :where *what",
+ :action => 'bot_action',
+ :auth_path => 'talk::do'
+basics.map "mode :where :what *who",
+ :action => 'bot_mode',
+ :auth_path => 'talk::do'
+
+basics.map "join :chan :pass",
+ :action => 'bot_join',
+ :defaults => {:pass => nil},
+ :auth_path => 'move'
+basics.map "part :chan",
+ :action => 'bot_part',
+ :defaults => {:chan => nil},
+ :auth_path => 'move'
+basics.map "channels",
+ :action => 'bot_channel_list',
+ :auth_path => 'move'
+basics.map "hide",
+ :action => 'bot_hide',
+ :auth_path => 'move'
+
+basics.map "ping",
+ :action => 'bot_ping',
+ :auth_path => '!ping!'
+basics.map "help *topic",
+ :action => 'bot_help',
+ :defaults => { :topic => [""] },
+ :auth_path => '!help!'
+
+basics.default_auth('*', false)
+