summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/rbot/irc.rb4
-rw-r--r--lib/rbot/ircbot.rb11
-rw-r--r--lib/rbot/message.rb15
-rw-r--r--lib/rbot/rfc2812.rb56
4 files changed, 85 insertions, 1 deletions
diff --git a/lib/rbot/irc.rb b/lib/rbot/irc.rb
index 23bd9e0d..2eb676e2 100644
--- a/lib/rbot/irc.rb
+++ b/lib/rbot/irc.rb
@@ -922,7 +922,7 @@ module Irc
class User < Netmask
alias :to_s :nick
- attr_accessor :real_name
+ attr_accessor :real_name, :idle_since, :signon
# Create a new IRC User from a given Netmask (or anything that can be converted
# into a Netmask) provided that the given Netmask does not have globs.
@@ -934,6 +934,8 @@ module Irc
raise ArgumentError, "#{str.inspect} must not have globs (unescaped * or ?)" if host.has_irc_glob? && host != "*"
@away = false
@real_name = String.new
+ @idle_since = nil
+ @signon = nil
end
# The nick of a User may be changed freely, but it must not contain glob patterns.
diff --git a/lib/rbot/ircbot.rb b/lib/rbot/ircbot.rb
index 0d934e33..4f5018e3 100644
--- a/lib/rbot/ircbot.rb
+++ b/lib/rbot/ircbot.rb
@@ -698,6 +698,12 @@ class Bot
m.modes = data[:modes]
@plugins.delegate "modechange", m
}
+ @client[:whois] = proc {|data|
+ source = data[:source]
+ target = server.get_user(data[:whois][:nick])
+ m = WhoisMessage.new(self, server, source, target, data[:whois])
+ @plugins.delegate "whois", m
+ }
@client[:join] = proc {|data|
m = JoinMessage.new(self, server, data[:source], data[:channel], data[:message])
sendq("MODE #{data[:channel]}", nil, 0) if m.address?
@@ -1209,6 +1215,11 @@ class Bot
sendq "MODE #{channel} #{mode} #{target}", channel, 2
end
+ # asking whois
+ def whois(nick, target=nil)
+ sendq "WHOIS #{target} #{nick}", nil, 0
+ end
+
# kicking a user
def kick(channel, user, msg)
sendq "KICK #{channel} #{user} :#{msg}", channel, 2
diff --git a/lib/rbot/message.rb b/lib/rbot/message.rb
index 5d6ea60f..6d14b213 100644
--- a/lib/rbot/message.rb
+++ b/lib/rbot/message.rb
@@ -553,6 +553,21 @@ module Irc
end
end
+ # class to manage WHOIS replies
+ class WhoisMessage < BasicUserMessage
+ attr_reader :whois
+ def initialize(bot, server, source, target, whois)
+ super(bot, server, source, target, "")
+ @address = (target == @bot.myself)
+ @whois = whois
+ end
+
+ def inspect
+ fields = ' whois=' << whois.inspect
+ super(fields)
+ end
+ end
+
# class to manage NAME replies
class NamesMessage < BasicUserMessage
attr_accessor :users
diff --git a/lib/rbot/rfc2812.rb b/lib/rbot/rfc2812.rb
index 758f574e..d781c0f1 100644
--- a/lib/rbot/rfc2812.rb
+++ b/lib/rbot/rfc2812.rb
@@ -1288,6 +1288,62 @@ module Irc
handle(:who, data)
when RPL_ENDOFWHO
handle(:eowho, data)
+ when RPL_WHOISUSER
+ @whois ||= Hash.new
+ @whois[:nick] = argv[1]
+ @whois[:user] = argv[2]
+ @whois[:host] = argv[3]
+ @whois[:real_name] = argv[-1]
+
+ user = @server.get_user(@whois[:nick])
+ user.user = @whois[:user]
+ user.host = @whois[:host]
+ user.real_name = @whois[:real_name]
+ when RPL_WHOISSERVER
+ @whois ||= Hash.new
+ @whois[:nick] = argv[1]
+ @whois[:server] = argv[2]
+ @whois[:server_info] = argv[-1]
+ # TODO update user info
+ when RPL_WHOISOPERATOR
+ @whois ||= Hash.new
+ @whois[:nick] = argv[1]
+ @whois[:operator] = argv[-1]
+ # TODO update user info
+ when RPL_WHOISIDLE
+ @whois ||= Hash.new
+ @whois[:nick] = argv[1]
+ user = @server.get_user(@whois[:nick])
+ @whois[:idle] = argv[2].to_i
+ user.idle_since = Time.now - @whois[:idle]
+ if argv[-1] == 'seconds idle, signon time'
+ @whois[:signon] = Time.at(argv[3].to_i)
+ user.signon = @whois[:signon]
+ end
+ when RPL_ENDOFWHOIS
+ @whois ||= Hash.new
+ @whois[:nick] = argv[1]
+ data[:whois] = @whois.dup
+ @whois.clear
+ handle(:whois, data)
+ when RPL_WHOISCHANNELS
+ @whois ||= Hash.new
+ @whois[:nick] = argv[1]
+ @whois[:channels] = []
+ user = @server.get_user(@whois[:nick])
+ argv[-1].split.each do |prechan|
+ pfx = prechan.scan(/[#{@server.supports[:prefix][:prefixes].join}]/)
+ modes = pfx.map { |p| @server.mode_for_prefix p }
+ chan = prechan[pfx.length..prechan.length]
+
+ channel = @server.get_channel(chan)
+ if channel
+ channel.add_user(user, :silent => true)
+ modes.map { |mode| channel.mode[mode].set(user) }
+ end
+
+ @whois[:channels] << [chan, modes]
+ end
when RPL_CHANNELMODEIS
parse_mode(serverstring, argv[1..-1], data)
handle(:mode, data)