X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=lib%2Frbot%2Fircbot.rb;h=6a1c8f6758472f9ba5da84ba432b594e298947b4;hb=96d13521d;hp=f15cb351807aa18f06c993fb2da13d49e4f1a23e;hpb=fc8a94f8368043f8162e2d2981e6ac6957a863e3;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git diff --git a/lib/rbot/ircbot.rb b/lib/rbot/ircbot.rb index f15cb351..6a1c8f67 100644 --- a/lib/rbot/ircbot.rb +++ b/lib/rbot/ircbot.rb @@ -18,6 +18,9 @@ $logger.datetime_format = $dateformat $logger.level = $cl_loglevel if defined? $cl_loglevel $logger.level = 0 if $debug +$log_queue = Queue.new +$log_thread = nil + require 'pp' unless Kernel.instance_methods.include?("pretty_inspect") @@ -55,18 +58,39 @@ def rawlog(level, message=nil, who_pos=1) else str = message.pretty_inspect end + qmsg = Array.new str.each_line { |l| - $logger.add(level, l.chomp, who) - who.gsub!(/./," ") + qmsg.push [level, l.chomp, who] + who = ' ' * who.size } + $log_queue.push qmsg +end + +def restart_logger + if $log_thread && $log_thread.alive? + $log_queue << nil + $log_thread.join + $log_thread = nil + end + + $log_thread = Thread.new do + ls = nil + while ls = $log_queue.pop + ls.each { |l| $logger.add(*l) } + end + end end +restart_logger + def log_session_start $logger << "\n\n=== #{botclass} session started on #{Time.now.strftime($dateformat)} ===\n\n" + restart_logger end def log_session_end $logger << "\n\n=== #{botclass} session ended on #{Time.now.strftime($dateformat)} ===\n\n" + $log_queue << nil end def debug(message=nil, who_pos=1) @@ -103,7 +127,6 @@ require 'rbot/rbotconfig' require 'rbot/load-gettext' require 'rbot/config' require 'rbot/config-compat' -# require 'rbot/utils' require 'rbot/irc' require 'rbot/rfc2812' @@ -111,12 +134,10 @@ require 'rbot/ircsocket' require 'rbot/botuser' require 'rbot/timer' require 'rbot/plugins' -# require 'rbot/channel' require 'rbot/message' require 'rbot/language' require 'rbot/dbhash' require 'rbot/registry' -# require 'rbot/httputil' module Irc @@ -397,7 +418,6 @@ class Bot FileUtils.cp_r Config::datadir+'/templates', botclass end - Dir.mkdir("#{botclass}/logs") unless File.exist?("#{botclass}/logs") Dir.mkdir("#{botclass}/registry") unless File.exist?("#{botclass}/registry") Dir.mkdir("#{botclass}/safe_save") unless File.exist?("#{botclass}/safe_save") @@ -443,17 +463,20 @@ class Bot Dir.chdir botclass # File.umask 0000 # Ensure sensible umask. Adjust as needed. log "Redirecting standard input/output/error" - begin - STDIN.reopen "/dev/null" - rescue Errno::ENOENT - # On Windows, there's not such thing as /dev/null - STDIN.reopen "NUL" + [$stdin, $stdout, $stderr].each do |fd| + begin + fd.reopen "/dev/null" + rescue Errno::ENOENT + # On Windows, there's not such thing as /dev/null + fd.reopen "NUL" + end end - def STDOUT.write(str=nil) + + def $stdout.write(str=nil) log str, 2 return str.to_s.size end - def STDERR.write(str=nil) + def $stdout.write(str=nil) if str.to_s.match(/:\d+: warning:/) warning str, 2 else @@ -487,8 +510,6 @@ class Bot end @quit_mutex = Mutex.new - @logs = Hash.new - @plugins = nil @lang = Language.new(self, @config['core.language']) @@ -531,8 +552,9 @@ class Bot @quiet = [] @client[:welcome] = proc {|data| - irclog "joined server #{@client.server} as #{myself}", "server" + m = WelcomeMessage.new(self, server, data[:source], data[:target], data[:message]) + @plugins.delegate("welcome", m) @plugins.delegate("connect") @config['irc.join_channels'].each { |c| @@ -569,34 +591,22 @@ class Bot # debug "Message target is #{data[:target].inspect}" # debug "Bot is #{myself.inspect}" - ignored = false @config['irc.ignore_users'].each { |mask| if m.source.matches?(server.new_netmask(mask)) - ignored = true - break + m.ignored = true end } - irclogprivmsg(m) - - unless ignored - @plugins.delegate "listen", m - @plugins.delegate("ctcp_listen", m) if m.ctcp - @plugins.privmsg(m) if m.address? - if not m.replied - @plugins.delegate "unreplied", m - end - end + @plugins.irc_delegate('privmsg', m) } @client[:notice] = proc { |data| message = NoticeMessage.new(self, server, data[:source], data[:target], data[:message]) # pass it off to plugins that want to hear everything - @plugins.delegate "listen", message + @plugins.irc_delegate "notice", message } @client[:motd] = proc { |data| - data[:motd].each_line { |line| - irclog "MOTD: #{line}", "server" - } + m = MotdMessage.new(self, server, data[:source], data[:target], data[:motd]) + @plugins.delegate "motd", m } @client[:nicktaken] = proc { |data| new = "#{data[:nick]}_" @@ -626,80 +636,65 @@ class Bot old = data[:oldnick] new = data[:newnick] m = NickMessage.new(self, server, source, old, new) + m.is_on = data[:is_on] if source == myself debug "my nick is now #{new}" end - data[:is_on].each { |ch| - irclog "@ #{old} is now known as #{new}", ch - } - @plugins.delegate("listen", m) - @plugins.delegate("nick", m) + @plugins.irc_delegate("nick", m) } @client[:quit] = proc {|data| source = data[:source] message = data[:message] m = QuitMessage.new(self, server, source, source, message) - data[:was_on].each { |ch| - irclog "@ Quit: #{source}: #{message}", ch - } - @plugins.delegate("listen", m) - @plugins.delegate("quit", m) + m.was_on = data[:was_on] + @plugins.irc_delegate("quit", m) } @client[:mode] = proc {|data| - irclog "@ Mode #{data[:modestring]} by #{data[:source]}", data[:channel] + m = ModeChangeMessage.new(self, server, data[:source], data[:target], data[:modestring]) + m.modes = data[:modes] + @plugins.delegate "modechange", m } @client[:join] = proc {|data| m = JoinMessage.new(self, server, data[:source], data[:channel], data[:message]) - irclogjoin(m) - - @plugins.delegate("listen", m) - @plugins.delegate("join", m) + @plugins.irc_delegate("join", m) sendq("WHO #{data[:channel]}", data[:channel], 2) if m.address? } @client[:part] = proc {|data| m = PartMessage.new(self, server, data[:source], data[:channel], data[:message]) - irclogpart(m) - - @plugins.delegate("listen", m) - @plugins.delegate("part", m) + @plugins.irc_delegate("part", m) } @client[:kick] = proc {|data| m = KickMessage.new(self, server, data[:source], data[:target], data[:channel],data[:message]) - irclogkick(m) - - @plugins.delegate("listen", m) - @plugins.delegate("kick", m) + @plugins.irc_delegate("kick", m) } @client[:invite] = proc {|data| - if data[:target] == myself - join data[:channel] if @auth.allow?("join", data[:source], data[:source].nick) - end + m = InviteMessage.new(self, server, data[:source], data[:target], data[:channel]) + @plugins.irc_delegate("invite", m) } @client[:changetopic] = proc {|data| m = TopicMessage.new(self, server, data[:source], data[:channel], data[:topic]) - irclogtopic(m) - - @plugins.delegate("listen", m) - @plugins.delegate("topic", m) - } - @client[:topic] = proc { |data| - irclog "@ Topic is \"#{data[:topic]}\"", data[:channel] + m.info_or_set = :set + @plugins.irc_delegate("topic", m) } + # @client[:topic] = proc { |data| + # irclog "@ Topic is \"#{data[:topic]}\"", data[:channel] + # } @client[:topicinfo] = proc { |data| channel = data[:channel] topic = channel.topic - irclog "@ Topic set by #{topic.set_by} on #{topic.set_on}", channel m = TopicMessage.new(self, server, data[:source], channel, topic) - - @plugins.delegate("listen", m) - @plugins.delegate("topic", m) + m.info_or_set = :info + @plugins.irc_delegate("topic", m) } @client[:names] = proc { |data| - @plugins.delegate "names", data[:channel], data[:users] + m = NamesMessage.new(self, server, server, data[:channel]) + m.users = data[:users] + @plugins.delegate "names", m } @client[:unknown] = proc { |data| #debug "UNKNOWN: #{data[:serverstring]}" - irclog data[:serverstring], ".unknown" + m = UnknownMessage.new(self, server, server, nil, data[:serverstring]) + @plugins.delegate "unknown_message", m } set_default_send_options :newlines => @config['send.newlines'].to_sym, @@ -974,7 +969,7 @@ class Bot lines.each { |line| sendq "#{fixed}#{line}", chan, ring - log_sent(type, where, line) + delegate_sent(type, where, line) } end @@ -1016,24 +1011,6 @@ class Bot say where, @lang.get("okay") end - # log IRC-related message +message+ to a file determined by +where+. - # +where+ can be a channel name, or a nick for private message logging - def irclog(message, where="server") - message = message.chomp - stamp = Time.now.strftime("%Y/%m/%d %H:%M:%S") - if where.class <= Server - where_str = "server" - else - where_str = where.downcase.gsub(/[:!?$*()\/\\<>|"']/, "_") - end - unless(@logs.has_key?(where_str)) - @logs[where_str] = File.new("#{@botclass}/logs/#{where_str}", "a") - @logs[where_str].sync = true - end - @logs[where_str].puts "[#{stamp}] #{message}" - #debug "[#{stamp}] <#{where}> #{message}" - end - # set topic of channel +where+ to +topic+ def topic(where, topic) sendq "TOPIC #{where} :#{topic}", where, 2 @@ -1047,6 +1024,8 @@ class Bot @socket.clearq debug "Sending quit message" @socket.emergency_puts "QUIT :#{message}" + debug "Logging quits" + delegate_sent('QUIT', myself, message) debug "Flushing socket" @socket.flush rescue SocketError => e @@ -1055,10 +1034,6 @@ class Bot debug "Shutting down socket" @socket.shutdown end - debug "Logging quits" - server.channels.each { |ch| - irclog "@ quit (#{message})", ch - } stop_server_pings @client.reset end @@ -1114,9 +1089,11 @@ class Bot # now we re-exec # Note, this fails on Windows debug "going to exec #{$0} #{@argv.inspect} from #{@run_dir}" + log_session_end Dir.chdir(@run_dir) exec($0, *@argv) rescue Errno::ENOENT + log_session_end exec("ruby", *(@argv.unshift $0)) rescue Exception => e $interrupted += 1 @@ -1236,75 +1213,18 @@ class Bot private - def irclogprivmsg(m) - if(m.action?) - if(m.private?) - irclog "* [#{m.source}(#{m.sourceaddress})] #{m.logmessage}", m.source - else - irclog "* #{m.source} #{m.logmessage}", m.target - end - else - if(m.public?) - irclog "<#{m.source}> #{m.logmessage}", m.target - else - irclog "[#{m.source}(#{m.sourceaddress})] #{m.logmessage}", m.source - end - end - end - - # log a message. Internal use only. - def log_sent(type, where, message) + # delegate sent messages + def delegate_sent(type, where, message) + args = [self, server, myself, server.user_or_channel(where.to_s), message] case type when "NOTICE" - case where - when Channel - irclog "-=#{myself}=- #{message}", where - else - irclog "[-=#{where}=-] #{message}", where - end + m = NoticeMessage.new(*args) when "PRIVMSG" - case where - when Channel - irclog "<#{myself}> #{message}", where - else - irclog "[msg(#{where})] #{message}", where - end - end - end - - def irclogjoin(m) - if m.address? - debug "joined channel #{m.channel}" - irclog "@ Joined channel #{m.channel}", m.channel - else - irclog "@ #{m.source} joined channel #{m.channel}", m.channel - end - end - - def irclogpart(m) - if(m.address?) - debug "left channel #{m.channel}" - irclog "@ Left channel #{m.channel} (#{m.logmessage})", m.channel - else - irclog "@ #{m.source} left channel #{m.channel} (#{m.logmessage})", m.channel - end - end - - def irclogkick(m) - if(m.address?) - debug "kicked from channel #{m.channel}" - irclog "@ You have been kicked from #{m.channel} by #{m.source} (#{m.logmessage})", m.channel - else - irclog "@ #{m.target} has been kicked from #{m.channel} by #{m.source} (#{m.logmessage})", m.channel - end - end - - def irclogtopic(m) - if m.source == myself - irclog "@ I set topic \"#{m.topic}\"", m.channel - else - irclog "@ #{m.source} set topic \"#{m.topic}\"", m.channel + m = PrivMessage.new(*args) + when "QUIT" + m = QuitMessage.new(*args) end + @plugins.delegate('sent', m) end end