diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rbot/ircbot.rb | 4 | ||||
-rw-r--r-- | lib/rbot/message.rb | 4 | ||||
-rw-r--r-- | lib/rbot/rfc2812.rb | 56 |
3 files changed, 43 insertions, 21 deletions
diff --git a/lib/rbot/ircbot.rb b/lib/rbot/ircbot.rb index 0286ed1b..a22d1772 100644 --- a/lib/rbot/ircbot.rb +++ b/lib/rbot/ircbot.rb @@ -638,9 +638,9 @@ class Bot @plugins.irc_delegate("quit", m) } @client[:mode] = proc {|data| - m = ModeChangeMessage.new(self, server, data[:source], data[:channel], data[:modestring]) + m = ModeChangeMessage.new(self, server, data[:source], data[:target], data[:modestring]) m.modes = data[:modes] - irclog "@ Mode #{data[:modestring]} by #{data[:source]}", data[:channel] + irclog "@ Mode #{data[:modestring]} by #{data[:source]}", data[:target] @plugins.delegate "modechange", m } @client[:join] = proc {|data| diff --git a/lib/rbot/message.rb b/lib/rbot/message.rb index b3a8eb3b..494b6877 100644 --- a/lib/rbot/message.rb +++ b/lib/rbot/message.rb @@ -465,8 +465,8 @@ module Irc # class to manage mode changes class ModeChangeMessage < BasicUserMessage attr_accessor :modes - def initialize(bot, server, source, channel, message="") - super(bot, server, source, channel, message) + def initialize(bot, server, source, target, message="") + super(bot, server, source, target, message) @address = (source == @bot.myself) @modes = [] end diff --git a/lib/rbot/rfc2812.rb b/lib/rbot/rfc2812.rb index 030d04df..ab9d2856 100644 --- a/lib/rbot/rfc2812.rb +++ b/lib/rbot/rfc2812.rb @@ -1407,18 +1407,40 @@ module Irc # be able to consume parameters for all # but Type D modes - data[:channel] = @server.user_or_channel(argv[0]) + data[:target] = @server.user_or_channel(argv[0]) data[:modestring] = argv[1..-1].join(" ") - case data[:channel] + # data[:modes] is an array where each element + # is an array with two elements, the first of which + # is either :set or :reset, and the second symbol + # is the mode letter. An optional third element + # is present e.g. for channel modes that need + # a parameter + data[:modes] = [] + case data[:target] when User - # TODO + # User modes aren't currently handled internally, + # but we still parse them and delegate to the client warning "Unhandled user mode message '#{serverstring}'" + argv[1..-1].each { |arg| + setting = arg[0].chr + if "+-".include?(setting) + setting = setting == "+" ? :set : :reset + arg[1..-1].each_byte { |b| + m = b.chr.intern + data[:modes] << [setting, m] + } + else + # Although typically User modes don't take an argument, + # this is not true for all modes on all servers. Since + # we have no knowledge of which modes take parameters + # and which don't we just assign it to the last + # mode. This is not going to do strange things often, + # as usually User modes are only set one at a time + warning "Unhandled user mode parameter #{arg} found" + data[:modes].last << arg + end + } else - # data[:modes] is an array where each element - # is either a flag which doesn't need parameters - # or an array with a flag which needs parameters - # and the corresponding parameter - data[:modes] = [] # array of indices in data[:modes] where parameters # are needed who_wants_params = [] @@ -1456,16 +1478,16 @@ module Irc data[:modes][idx] << arg end } - end - data[:modes].each { |mode| - set, key, val = mode - if val - data[:channel].mode[key].send(set, val) - else - data[:channel].mode[key].send(set) - end - } if data[:modes] + data[:modes].each { |mode| + set, key, val = mode + if val + data[:target].mode[key].send(set, val) + else + data[:target].mode[key].send(set) + end + } + end handle(:mode, data) else |