diff options
-rw-r--r-- | lib/rbot/irc.rb | 4 | ||||
-rw-r--r-- | lib/rbot/ircbot.rb | 11 | ||||
-rw-r--r-- | lib/rbot/message.rb | 15 | ||||
-rw-r--r-- | lib/rbot/rfc2812.rb | 56 |
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) |