summaryrefslogtreecommitdiff
path: root/lib/rbot
diff options
context:
space:
mode:
authorGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2006-07-05 16:18:18 +0000
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2006-07-05 16:18:18 +0000
commit602da36df14da2cf1bab2b440e8f39018bba0b3f (patch)
treef175246393fbda21e4ec9f118d34f73f1e39a27c /lib/rbot
parent1f834f996fcf3e9ead0e1a4adcdebafc5b52c82e (diff)
Improve debug output for multiline error messages. Improve exception handling for socket and connection problems. Stop sending pings when disconnected.
Diffstat (limited to 'lib/rbot')
-rw-r--r--lib/rbot/ircbot.rb81
-rw-r--r--lib/rbot/ircsocket.rb35
2 files changed, 64 insertions, 52 deletions
diff --git a/lib/rbot/ircbot.rb b/lib/rbot/ircbot.rb
index 8f0a2646..0cfc3f12 100644
--- a/lib/rbot/ircbot.rb
+++ b/lib/rbot/ircbot.rb
@@ -7,7 +7,9 @@ $debug = false unless $debug
def debug(message=nil)
if ($debug && message)
stamp = Time.now.strftime("%Y/%m/%d %H:%M:%S")
- print "D: [#{stamp}] #{message}\n"
+ message.to_s.each_line { |l|
+ $stdout.puts "D: [#{stamp}] #{l}"
+ }
$stdout.flush
end
#yield
@@ -38,20 +40,20 @@ module Irc
class IrcBot
# the bot's current nickname
attr_reader :nick
-
+
# the bot's IrcAuth data
attr_reader :auth
-
+
# the bot's BotConfig data
attr_reader :config
-
+
# the botclass for this bot (determines configdir among other things)
attr_reader :botclass
-
+
# used to perform actions periodically (saves configuration once per minute
# by default)
attr_reader :timer
-
+
# bot's Language data
attr_reader :lang
@@ -79,7 +81,7 @@ class IrcBot
:wizard => true)
BotConfig.register BotConfigIntegerValue.new('server.port',
:default => 6667, :type => :integer, :requires_restart => true,
- :desc => "What port should the bot connect to?",
+ :desc => "What port should the bot connect to?",
:validate => Proc.new {|v| v > 0}, :wizard => true)
BotConfig.register BotConfigStringValue.new('server.password',
:default => false, :requires_restart => true,
@@ -124,7 +126,7 @@ class IrcBot
puts "data directory '#{Config::datadir}' not found, did you setup.rb?"
exit 2
end
-
+
botclass = "#{Etc.getpwuid(Process::Sys.geteuid)[:dir]}/.rbot" unless botclass
#botclass = "#{ENV['HOME']}/.rbot" unless botclass
botclass = File.expand_path(botclass)
@@ -138,7 +140,7 @@ class IrcBot
end
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")
@@ -179,11 +181,11 @@ class IrcBot
log "MOTD: #{line}", "server"
}
}
- @client[:nicktaken] = proc { |data|
+ @client[:nicktaken] = proc { |data|
nickchg "#{data[:nick]}_"
@plugins.delegate "nicktaken", data[:nick]
}
- @client[:badnick] = proc {|data|
+ @client[:badnick] = proc {|data|
puts "WARNING, bad nick (#{data[:nick]})"
}
@client[:ping] = proc {|data|
@@ -265,7 +267,7 @@ class IrcBot
onpart(m)
}
@client[:kick] = proc {|data|
- m = KickMessage.new(self, data[:source], data[:target],data[:channel],data[:message])
+ m = KickMessage.new(self, data[:source], data[:target],data[:channel],data[:message])
onkick(m)
}
@client[:invite] = proc {|data|
@@ -325,7 +327,7 @@ class IrcBot
begin
@socket.connect
rescue => e
- raise "failed to connect to IRC server at #{@config['server.name']} #{@config['server.port']}: " + e
+ raise e.class, "failed to connect to IRC server at #{@config['server.name']} #{@config['server.port']}: " + e
end
@socket.puts "PASS " + @config['server.password'] if @config['server.password']
@socket.puts "NICK #{@nick}\nUSER #{@config['irc.user']} 4 #{@config['server.name']} :Ruby bot. (c) Tom Gilbert"
@@ -338,7 +340,7 @@ class IrcBot
begin
connect
@timer.start
-
+
while @socket.connected?
if @socket.select
break unless reply = @socket.gets
@@ -351,8 +353,9 @@ class IrcBot
#rescue TimeoutError, SocketError => e
rescue SystemExit
exit 0
- rescue TimeoutError => e
- puts e
+ rescue TimeoutError, SocketError => e
+ puts "#{e.class}: #{e}"
+ debug e.backtrace.join("\n")
rescue Exception => e
puts "network exception: #{e.inspect}"
puts e.backtrace.join("\n")
@@ -362,17 +365,18 @@ class IrcBot
puts e.backtrace.join("\n")
exit 2
end
-
+
puts "disconnected"
- @last_ping = nil
+
+ stop_server_pings
@channels.clear
@socket.clearq
-
+
puts "waiting to reconnect"
sleep @config['server.reconnect_wait']
end
end
-
+
# type:: message type
# where:: message target
# message:: message text
@@ -456,7 +460,7 @@ class IrcBot
@logs[where].puts "[#{stamp}] #{message}"
#debug "[#{stamp}] <#{where}> #{message}"
end
-
+
# set topic of channel +where+ to +topic+
def topic(where, topic)
sendq "TOPIC #{where} :#{topic}"
@@ -494,7 +498,7 @@ class IrcBot
@socket.shutdown
puts "rbot quit (#{message})"
end
-
+
# message:: optional IRC quit message
# quit IRC, shutdown the bot
def quit(message=nil)
@@ -529,7 +533,7 @@ class IrcBot
@plugins.rescan
@keywords.rescan
end
-
+
# channel:: channel to join
# key:: optional channel key if channel is +s
# join a channel
@@ -555,7 +559,7 @@ class IrcBot
def mode(channel, mode, target)
sendq "MODE #{channel} #{mode} #{target}"
end
-
+
# m:: message asking for help
# topic:: optional topic help is requested for
# respond to online help requests
@@ -597,16 +601,7 @@ class IrcBot
# we'll ping the server every 30 seconds or so, and expect a response
# before the next one come around..
def start_server_pings
- @last_ping = nil
- # stop existing timers if running
- unless @ping_timer.nil?
- @timer.remove @ping_timer
- @ping_timer = nil
- end
- unless @pong_timer.nil?
- @timer.remove @pong_timer
- @pong_timer = nil
- end
+ stop_server_pings
return unless @config['server.ping_timeout'] > 0
# we want to respond to a hung server within 30 secs or so
@ping_timer = @timer.add(30) {
@@ -622,15 +617,27 @@ class IrcBot
@socket.shutdown
rescue
debug "couldn't shutdown connection (already shutdown?)"
- ensure
- raise TimeoutError, "no PONG from server in #{diff} seconds"
end
@last_ping = nil
+ raise TimeoutError, "no PONG from server in #{diff} seconds"
end
end
}
end
+ def stop_server_pings
+ @last_ping = nil
+ # stop existing timers if running
+ unless @ping_timer.nil?
+ @timer.remove @ping_timer
+ @ping_timer = nil
+ end
+ unless @pong_timer.nil?
+ @timer.remove @pong_timer
+ @pong_timer = nil
+ end
+ end
+
private
# handle help requests for "core" topics
@@ -849,7 +856,7 @@ class IrcBot
# exit 2
end
end
-
+
# delegate to plugins
@plugins.delegate("listen", m)
@plugins.delegate("part", m)
diff --git a/lib/rbot/ircsocket.rb b/lib/rbot/ircsocket.rb
index 6ff93725..6a5f281a 100644
--- a/lib/rbot/ircsocket.rb
+++ b/lib/rbot/ircsocket.rb
@@ -9,16 +9,16 @@ module Irc
class IrcSocket
# total number of lines sent to the irc server
attr_reader :lines_sent
-
+
# total number of lines received from the irc server
attr_reader :lines_received
-
+
# delay between lines sent
attr_reader :sendq_delay
-
+
# max lines to burst
attr_reader :sendq_burst
-
+
# server:: server to connect to
# port:: IRCd port
# host:: optional local host to bind to (ruby 1.7+ required)
@@ -48,7 +48,7 @@ module Irc
@sendq_burst = 4
end
end
-
+
def connected?
!@sock.nil?
end
@@ -56,7 +56,8 @@ module Irc
# open a TCP connection to the server
def connect
if connected?
- shutdown
+ debug "reconnecting socket while connected"
+ shutdown
end
if(@host)
begin
@@ -70,7 +71,7 @@ module Irc
end
else
@sock=TCPSocket.new(@server, @port)
- end
+ end
@qthread = false
@qmutex = Mutex.new
@sendq = Array.new
@@ -106,15 +107,19 @@ module Irc
# get the next line from the server (blocks)
def gets
+ if @sock.nil?
+ debug "socket get attempted while closed"
+ return nil
+ end
begin
- reply = @sock.gets
- @lines_received += 1
- reply.strip! if reply
- debug "RECV: #{reply.inspect}"
- return reply
+ reply = @sock.gets
+ @lines_received += 1
+ reply.strip! if reply
+ debug "RECV: #{reply.inspect}"
+ return reply
rescue => e
- debug "socket get failed: #{e}"
- return nil
+ debug "socket get failed: #{e.inspect}"
+ return nil
end
end
@@ -183,7 +188,7 @@ module Irc
end
private
-
+
# same as puts, but expects to be called with a mutex held on @qmutex
def puts_critical(message)
# debug "in puts_critical"