]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/irc.rb
basics botmodule: use #to_s to stringify multiword parameters
[user/henk/code/ruby/rbot.git] / lib / rbot / irc.rb
index c2c1e82fdd518c30889a1eed9cad0830857ea9de..129f947e61d1d9d906e1b02d7b7e7deb486fd5f3 100644 (file)
@@ -321,7 +321,7 @@ class String
         raise "Unexpected match #{m} when converting #{self}"\r
       end\r
     }\r
-    Regexp.new(regmask)\r
+    Regexp.new("^#{regmask}$")\r
   end\r
 \r
 end\r
@@ -629,24 +629,48 @@ module Irc
       end\r
     end\r
 \r
-    # A Netmask is easily converted to a String for the usual representation\r
+    # A Netmask is easily converted to a String for the usual representation.\r
+    # We skip the user or host parts if they are "*", unless we've been asked\r
+    # for the full form\r
     #\r
+    def to_s\r
+      ret = nick.dup\r
+      ret << "!" << user unless user == "*"\r
+      ret << "@" << host unless host == "*"\r
+      return ret\r
+    end\r
+\r
     def fullform\r
       "#{nick}!#{user}@#{host}"\r
     end\r
-    alias :to_s :fullform\r
+\r
+    # This method downcases the fullform of the netmask. While this may not be\r
+    # significantly different from the #downcase() method provided by the\r
+    # ServerOrCasemap mixin, it's significantly different for Netmask\r
+    # subclasses such as User whose simple downcasing uses the nick only.\r
+    #\r
+    def full_irc_downcase(cmap=casemap)\r
+      self.fullform.irc_downcase(cmap)\r
+    end\r
+\r
+    # full_downcase() will return the fullform downcased according to the\r
+    # User's own casemap\r
+    #\r
+    def full_downcase\r
+      self.full_irc_downcase\r
+    end\r
 \r
     # Converts the receiver into a Netmask with the given (optional)\r
     # server/casemap association. We return self unless a conversion\r
     # is needed (different casemap/server)\r
     #\r
-    # Subclasses of Netmask will return a new Netmask\r
+    # Subclasses of Netmask will return a new Netmask, using full_downcase\r
     #\r
     def to_irc_netmask(opts={})\r
       if self.class == Netmask\r
         return self if fits_with_server_and_casemap?(opts)\r
       end\r
-      return self.downcase.to_irc_netmask(opts)\r
+      return self.full_downcase.to_irc_netmask(opts)\r
     end\r
 \r
     # Converts the receiver into a User with the given (optional)\r
@@ -861,6 +885,8 @@ module Irc
   class User < Netmask\r
     alias :to_s :nick\r
 \r
+    attr_accessor :real_name\r
+\r
     # Create a new IRC User from a given Netmask (or anything that can be converted\r
     # into a Netmask) provided that the given Netmask does not have globs.\r
     #\r
@@ -870,6 +896,7 @@ module Irc
       raise ArgumentError, "#{str.inspect} must not have globs (unescaped * or ?)" if user.has_irc_glob? && user != "*"\r
       raise ArgumentError, "#{str.inspect} must not have globs (unescaped * or ?)" if host.has_irc_glob? && host != "*"\r
       @away = false\r
+      @real_name = String.new\r
     end\r
 \r
     # The nick of a User may be changed freely, but it must not contain glob patterns.\r
@@ -900,7 +927,7 @@ module Irc
     # Checks if a User is well-known or not by looking at the hostname and user\r
     #\r
     def known?\r
-      return nick!= "*" && user!="*" && host!="*"\r
+      return nick != "*" && user != "*" && host != "*"\r
     end\r
 \r
     # Is the user away?\r
@@ -920,21 +947,6 @@ module Irc
       end\r
     end\r
 \r
-    # Users can be either simply downcased (their nick only)\r
-    # or fully downcased: this will return the fullform downcased\r
-    # according to the given casemap.\r
-    #\r
-    def full_irc_downcase(cmap=casemap)\r
-      self.fullform.irc_downcase(cmap)\r
-    end\r
-\r
-    # full_downcase() will return the fullform downcased according to the\r
-    # User's own casemap\r
-    #\r
-    def full_downcase\r
-      self.full_irc_downcase\r
-    end\r
-\r
     # Since to_irc_user runs the same checks on server and channel as\r
     # to_irc_netmask, we just try that and return self if it works.\r
     #\r
@@ -961,6 +973,35 @@ module Irc
       end\r
     end\r
 \r
+    def modes_on(channel)\r
+      case channel\r
+      when Channel\r
+        channel.modes_of(self)\r
+      else\r
+        return @server.channel(channel).modes_of(self) if @server\r
+        raise "Can't resolve channel #{channel}"\r
+      end\r
+    end\r
+\r
+    def is_op?(channel)\r
+      case channel\r
+      when Channel\r
+        channel.has_op?(self)\r
+      else\r
+        return @server.channel(channel).has_op?(self) if @server\r
+        raise "Can't resolve channel #{channel}"\r
+      end\r
+    end\r
+\r
+    def is_voice?(channel)\r
+      case channel\r
+      when Channel\r
+        channel.has_voice?(self)\r
+      else\r
+        return @server.channel(channel).has_voice?(self) if @server\r
+        raise "Can't resolve channel #{channel}"\r
+      end\r
+    end\r
   end\r
 \r
 \r
@@ -1164,7 +1205,7 @@ module Irc
       #\r
       def initialize(text="", set_by="", set_on=Time.new)\r
         @text = text\r
-        @set_by = set_by.to_irc_user\r
+        @set_by = set_by.to_irc_netmask\r
         @set_on = set_on\r
       end\r
 \r
@@ -1234,7 +1275,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.irc_downcase(casemap))\r
+      @users.index(nick.to_irc_user(server_and_casemap))\r
     end\r
 \r
     # Returns the user with nick _nick_, if available\r
@@ -1248,8 +1289,8 @@ module Irc
     #\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
+      if has_user?(user)\r
+        warn "Trying to add user #{user} to channel #{self} again" unless silent\r
       else\r
         @users << user.to_irc_user(server_and_casemap)\r
       end\r
@@ -1327,6 +1368,21 @@ module Irc
       @mode[sym.to_sym] = kl.new(self)\r
     end\r
 \r
+    def modes_of(user)\r
+      l = []\r
+      @mode.map { |s, m|\r
+        l << s if (m.class <= UserMode and m.list[user])\r
+      }\r
+      l\r
+    end\r
+\r
+    def has_op?(user)\r
+      @mode.has_key?(:o) and @mode[:o].list[user]\r
+    end\r
+\r
+    def has_voice?(user)\r
+      @mode.has_key?(:v) and @mode[:v].list[user]\r
+    end\r
   end\r
 \r
 \r
@@ -1456,10 +1512,10 @@ module Irc
     # Resets the Channel and User list\r
     #\r
     def reset_lists\r
-      @users.each { |u|\r
+      @users.reverse_each { |u|\r
         delete_user(u)\r
       }\r
-      @channels.each { |u|\r
+      @channels.reverse_each { |u|\r
         delete_channel(u)\r
       }\r
     end\r
@@ -1526,6 +1582,10 @@ module Irc
             groups.each { |g|\r
               k, v = g.split(':')\r
               @supports[key][k] = v.to_i || 0\r
+              if @supports[key][k] == 0\r
+                warn "Deleting #{key} limit of 0 for #{k}"\r
+                @supports[key].delete(k)\r
+              end\r
             }\r
           }\r
         when :chanmodes\r
@@ -1677,7 +1737,8 @@ module Irc
           channel_names.each { |n|\r
             count += 1 if k.include?(n[0])\r
           }\r
-          raise IndexError, "Already joined #{count} channels with prefix #{k}" if count == @supports[:chanlimit][k]\r
+          # raise IndexError, "Already joined #{count} channels with prefix #{k}" if count == @supports[:chanlimit][k]\r
+          warn "Already joined #{count}/#{@supports[:chanlimit][k]} channels with prefix #{k}, we may be going over server limits" if count >= @supports[:chanlimit][k]\r
         }\r
 \r
         # So far, everything is fine. Now create the actual Channel\r