]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/rfc2812.rb
fixed typo in help auth
[user/henk/code/ruby/rbot.git] / lib / rbot / rfc2812.rb
index f3dabf30ef5bb9d8b02fd8a9e818ddb6d1ac0922..3159759bf08e2777dcecdc82559168d322f5fd71 100644 (file)
@@ -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 = []
@@ -1426,26 +1448,29 @@ module Irc
           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
-                case m.to_sym
+                m = b.chr.intern
+                if m == :+
+                  setting = :set
+                  next
+                elsif m == :-
+                  setting = :reset
+                  next
+                end
+                data[:modes] << [setting, m]
+                case m
                 when *@server.supports[:chanmodes][:typea]
-                  data[:modes] << [setting + m]
                   who_wants_params << data[:modes].length - 1
                 when *@server.supports[:chanmodes][:typeb]
-                  data[:modes] << [setting + m]
                   who_wants_params << data[:modes].length - 1
                 when *@server.supports[:chanmodes][:typec]
-                  if setting == "+"
-                    data[:modes] << [setting + m]
+                  if setting == :set
                     who_wants_params << data[:modes].length - 1
-                  else
-                    data[:modes] << setting + m
                   end
                 when *@server.supports[:chanmodes][:typed]
-                  data[:modes] << setting + m
+                  # Nothing to do
                 when *@server.supports[:prefix][:modes]
-                  data[:modes] << [setting + m]
                   who_wants_params << data[:modes].length - 1
                 else
                   warning "Unknown mode #{m} in #{serverstring.inspect}"
@@ -1460,21 +1485,16 @@ module Irc
               data[:modes][idx] << arg
             end
           }
-        end
 
-        data[:modes].each { |mode|
-          case mode
-          when Array
-            set = mode[0][0].chr == "+" ? :set : :reset
-            key = mode[0][1].chr.to_sym
-            val = mode[1]
-            data[:channel].mode[key].send(set, val)
-          else
-            set = mode[0].chr == "+" ? :set : :reset
-            key = mode[1].chr.to_sym
-            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