]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/commitdiff
Irc framework: fix errors in filling up the user lists for channels
authorGiuseppe Bilotta <giuseppe.bilotta@gmail.com>
Sat, 6 Jan 2007 21:29:44 +0000 (21:29 +0000)
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>
Sat, 6 Jan 2007 21:29:44 +0000 (21:29 +0000)
lib/rbot/irc.rb
lib/rbot/rfc2812.rb

index f2425d6a986b869a194722407297c2f05e35fac3..31c14802d4aa7c2f83d10cc38ec193b9bf6cb390 100644 (file)
@@ -4,6 +4,8 @@
 #   Channels is the User on (of those the client is on too)?\r
 #   We may want this so that when a User leaves all Channels and he hasn't\r
 #   sent us privmsgs, we know remove him from the Server @users list\r
+# * Maybe ChannelList and UserList should be HashesOf instead of ArrayOf?\r
+#   See items marked as TODO Ho\r
 #++\r
 # :title: IRC module\r
 #\r
@@ -851,6 +853,8 @@ module Irc
 \r
     # Channel modes of type A manipulate lists\r
     #\r
+    # Example: b (banlist)\r
+    #\r
     class ModeTypeA < Mode\r
       def initialize(ch)\r
         super\r
@@ -872,6 +876,8 @@ module Irc
 \r
     # Channel modes of type B need an argument\r
     #\r
+    # Example: k (key)\r
+    #\r
     class ModeTypeB < Mode\r
       def initialize(ch)\r
         super\r
@@ -916,6 +922,8 @@ module Irc
     # Channel modes of type C need an argument when set,\r
     # but not when they get reset\r
     #\r
+    # Example: l (limit)\r
+    #\r
     class ModeTypeC < Mode\r
       def initialize(ch)\r
         super\r
@@ -939,6 +947,8 @@ module Irc
 \r
     # Channel modes of type D are basically booleans\r
     #\r
+    # Example: m (moderate)\r
+    #\r
     class ModeTypeD < Mode\r
       def initialize(ch)\r
         super\r
@@ -1024,7 +1034,7 @@ module Irc
       str = "<#{self.class}:#{'0x%x' % self.object_id}:"\r
       str << " on server #{server}" if server\r
       str << " @name=#{@name.inspect} @topic=#{@topic.text.inspect}"\r
-      str << " @users=[#{@users.sort.join(', ')}]"\r
+      str << " @users=[#{user_nicks.sort.join(', ')}]"\r
       str << ">"\r
     end\r
 \r
@@ -1034,6 +1044,35 @@ module Irc
       self\r
     end\r
 \r
+    # TODO Ho\r
+    def user_nicks\r
+      @users.map { |u| u.downcase }\r
+    end\r
+\r
+    # Checks if the receiver already has a user with the given _nick_\r
+    #\r
+    def has_user?(nick)\r
+      user_nicks.index(nick.irc_downcase(casemap))\r
+    end\r
+\r
+    # Returns the user with nick _nick_, if available\r
+    #\r
+    def get_user(nick)\r
+      idx = has_user?(nick)\r
+      @users[idx] if idx\r
+    end\r
+\r
+    # Adds a user to the channel\r
+    #\r
+    def add_user(user, opts={})\r
+      silent = opts.fetch(:silent, false) \r
+      if has_user?(user) && !silent\r
+        warn "Trying to add user #{user} to channel #{self} again"\r
+      else\r
+        @users << user.to_irc_user(server_and_casemap)\r
+      end\r
+    end\r
+\r
     # Creates a new channel with the given name, optionally setting the topic\r
     # and an initial users list.\r
     #\r
@@ -1054,7 +1093,7 @@ module Irc
       @users = UserList.new\r
 \r
       users.each { |u|\r
-        @users << u.to_irc_user(server_and_casemap)\r
+        add_user(u)\r
       }\r
 \r
       # Flags\r
@@ -1079,25 +1118,25 @@ module Irc
     # A channel is local to a server if it has the '&' prefix\r
     #\r
     def local?\r
-      name[0] = 0x26\r
+      name[0] == 0x26\r
     end\r
 \r
     # A channel is modeless if it has the '+' prefix\r
     #\r
     def modeless?\r
-      name[0] = 0x2b\r
+      name[0] == 0x2b\r
     end\r
 \r
     # A channel is safe if it has the '!' prefix\r
     #\r
     def safe?\r
-      name[0] = 0x21\r
+      name[0] == 0x21\r
     end\r
 \r
     # A channel is normal if it has the '#' prefix\r
     #\r
     def normal?\r
-      name[0] = 0x23\r
+      name[0] == 0x23\r
     end\r
 \r
     # Create a new mode\r
@@ -1150,10 +1189,12 @@ module Irc
 \r
     attr_reader :channels, :users\r
 \r
+    # TODO Ho\r
     def channel_names\r
       @channels.map { |ch| ch.downcase }\r
     end\r
 \r
+    # TODO Ho\r
     def user_nicks\r
       @users.map { |u| u.downcase }\r
     end\r
@@ -1396,7 +1437,7 @@ module Irc
     # Checks if the receiver already has a channel with the given _name_\r
     #\r
     def has_channel?(name)\r
-      channel_names.index(name.downcase)\r
+      channel_names.index(name.irc_downcase(casemap))\r
     end\r
     alias :has_chan? :has_channel?\r
 \r
@@ -1500,7 +1541,7 @@ module Irc
     # Checks if the receiver already has a user with the given _nick_\r
     #\r
     def has_user?(nick)\r
-      user_nicks.index(nick.downcase)\r
+      user_nicks.index(nick.irc_downcase(casemap))\r
     end\r
 \r
     # Returns the user with nick _nick_, if available\r
@@ -1582,7 +1623,7 @@ module Irc
       @users.inject(UserList.new) {\r
         |list, user|\r
         if user.user == "*" or user.host == "*"\r
-          list << user if user.nick.downcase =~ nm.nick.downcase.to_irc_regexp\r
+          list << user if user.nick.irc_downcase(casemap) =~ nm.nick.irc_downcase(casemap).to_irc_regexp\r
         else\r
           list << user if user.matches?(nm)\r
         end\r
index 26549539ef5dd3eee903edda46ad3ebdebe6a8ff..900c750d8b3b2231644167bbdf89aac6034cceac 100644 (file)
@@ -1009,7 +1009,7 @@ module Irc
           users = []
           argv[3].scan(/\S+/).each { |u|
             # FIXME beware of servers that allow multiple prefixes
-            if(u =~ /^(#{@server.supports[:prefix][:prefixes].join})?(.*)$/)
+            if(u =~ /^([#{@server.supports[:prefix][:prefixes].join}])?(.*)$/)
               umode = $1
               user = $2
               users << [user, umode]
@@ -1018,11 +1018,13 @@ module Irc
 
           users.each { |ar|
             u = @server.user(ar[0])
-            chan.users << u unless chan.users.include?(u)
+            chan.add_user(u, :silent => true)
+            debug "Adding user #{u}"
             if ar[1]
               m = @server.supports[:prefix][:prefixes].index(ar[1].to_sym)
-              m = @server.supports[:prefix][:modes][m]
-              chan.mode[m.to_sym].set(u)
+              ms = @server.supports[:prefix][:modes][m]
+              debug "\twith mode #{ar[1]} (#{ms})"
+              chan.mode[ms].set(u)
             end
           }
           @tmpusers += users
@@ -1155,8 +1157,8 @@ module Irc
       when 'QUIT'
         data[:message] = argv[0]
         data[:was_on] = @server.channels.inject(ChannelList.new) { |list, ch|
-          list << ch if ch.users.include?(data[:source])
-         list
+          list << ch if ch.has_user?(data[:source])
+          list
         }
 
         @server.delete_user(data[:source])
@@ -1164,7 +1166,7 @@ module Irc
         handle(:quit, data)
       when 'JOIN'
         data[:channel] = @server.channel(argv[0])
-        data[:channel].users << data[:source]
+        data[:channel].add_user(data[:source])
 
         handle(:join, data)
       when 'TOPIC'
@@ -1180,7 +1182,7 @@ module Irc
         handle(:invite, data)
       when 'NICK'
         data[:is_on] = @server.channels.inject(ChannelList.new) { |list, ch|
-          list << ch if ch.users.include?(data[:source])
+          list << ch if ch.has_user?(data[:source])
           list
         }
 
@@ -1203,6 +1205,7 @@ module Irc
         case data[:channel]
         when User
           # TODO
+          warn "Unhandled user mode message '#{serverstring}'"
         else
           # data[:modes] is an array where each element
           # is either a flag which doesn't need parameters
@@ -1238,13 +1241,13 @@ module Irc
                   data[:modes] << [setting + m]
                   who_wants_params << data[:modes].length - 1
                 else
-                  warn "Unknown mode #{m} in #{serverstring}"
+                  warn "Unknown mode #{m} in #{serverstring.inspect}"
                 end
               }
             else
               idx = who_wants_params.shift
               if idx.nil?
-                warn "Oops, problems parsing #{serverstring}"
+                warn "Oops, problems parsing #{serverstring.inspect}"
                 break
               end
               data[:modes][idx] << arg
@@ -1268,6 +1271,7 @@ module Irc
 
         handle(:mode, data)
       else
+        warn "Unknown message #{serverstring.inspect}"
         handle(:unknown, data)
       end
     end