]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/irc.rb
plugin(script): remove deprecated $SAFE
[user/henk/code/ruby/rbot.git] / lib / rbot / irc.rb
index c893fc2728d22b0d44383f755970390fa4c7faa8..17b7bc3e4b0cee684e9f44a37d1701b10666c744 100644 (file)
@@ -131,7 +131,7 @@ module Irc
       if self == other
         return true
       else
-        warn "Casemap mismatch (#{self.inspect} != #{other.inspect})"
+        warning "Casemap mismatch (#{self.inspect} != #{other.inspect})"
         return false
       end
     end
@@ -196,6 +196,7 @@ module Irc
           @casemap = nil
         end
       else
+        warning 'casemap fallback to rfc1459 without hints, correct?'
         @casemap = (@casemap || 'rfc1459').to_irc_casemap
       end
     end
@@ -273,7 +274,13 @@ class String
   # This method returns the Irc::Casemap whose name is the receiver
   #
   def to_irc_casemap
-    Irc::Casemap.get(self) rescue raise TypeError, "Unkown Irc::Casemap #{self.inspect}"
+    begin
+      Irc::Casemap.get(self)
+    rescue
+      # raise TypeError, "Unkown Irc::Casemap #{self.inspect}"
+      error "Unkown Irc::Casemap #{self.inspect} requested, defaulting to rfc1459"
+      Irc::Casemap.get('rfc1459')
+    end
   end
 
   # This method returns a string which is the downcased version of the
@@ -540,7 +547,7 @@ class Regexp
     RFC_CHAN = /#{CHAN_FIRST}#{CHAN_ANY}{1,49}|#{CHAN_SAFE}#{CHAN_ANY}{1,44}/
 
     # Nick-matching regexps
-    SPECIAL_CHAR = /[\x5b-\x60\x7b-\x7d]/
+    SPECIAL_CHAR = /[\[-\`\{-\}]/
     NICK_FIRST = /#{SPECIAL_CHAR}|[[:alpha:]]/
     NICK_ANY = /#{SPECIAL_CHAR}|[[:alnum:]]|-/
     GEN_NICK = /#{NICK_FIRST}#{NICK_ANY}+/
@@ -633,6 +640,12 @@ module Irc
     def initialize(str="", opts={})
       # First of all, check for server/casemap option
       #
+      debug 'new netmask "%s" casemap=%s server=%s server#casemap=%s' % [
+        str,
+        (opts[:casemap].class.to_s rescue 'null'),
+        (opts[:server].hostname.to_s rescue 'null'),
+        (opts[:server].casemap.class.to_s rescue 'null')
+      ]
       init_server_or_casemap(opts)
 
       # Now we can see if the given string _str_ is an actual Netmask
@@ -827,7 +840,7 @@ module Irc
         them = cmp.send(component).irc_downcase(casemap)
         if us.has_irc_glob? && them.has_irc_glob?
           next if us == them
-          warn NotImplementedError
+          warning NotImplementedError
           return false
         end
         return false if us.has_irc_glob? && !them.has_irc_glob?
@@ -1323,6 +1336,13 @@ module Irc
   #
   class Channel
 
+    # Return the non-prefixed part of a channel name.
+    # Also works with ## channels found on some networks
+    # (e.g. FreeNode)
+    def self.npname(str)
+      return str.to_s.sub(/^[&#+!]+/,'')
+    end
+
     include ServerOrCasemap
     attr_reader :name, :topic, :mode, :users
     alias :to_s :name
@@ -1367,7 +1387,7 @@ module Irc
     def add_user(user, opts={})
       silent = opts.fetch(:silent, false)
       if has_user?(user)
-        warn "Trying to add user #{user} to channel #{self} again" unless silent
+        warning "Trying to add user #{user} to channel #{self} again" unless silent
       else
         @users << user.to_irc_user(server_and_casemap)
       end
@@ -1381,7 +1401,7 @@ module Irc
     #
     def initialize(name, topic=nil, users=[], opts={})
       raise ArgumentError, "Channel name cannot be empty" if name.to_s.empty?
-      warn "Unknown channel prefix #{name[0,1]}" if name !~ /^[&#+!]/
+      warning "Unknown channel prefix #{name[0,1]}" if name !~ /^[&#+!]/
       raise ArgumentError, "Invalid character in #{name.inspect}" if name =~ /[ \x07,]/
 
       init_server_or_casemap(opts)
@@ -1512,7 +1532,6 @@ module Irc
   class Server
 
     attr_reader :hostname, :version, :usermodes, :chanmodes
-    alias :to_s :hostname
     attr_reader :supports, :capabilities
 
     attr_reader :channels, :users
@@ -1543,6 +1562,10 @@ module Irc
       str << ">"
     end
 
+    def to_s
+      hostname.nil? ? "<no hostname>" : hostname
+    end
+
     # Create a new Server, with all instance variables reset to nil (for
     # scalar variables), empty channel and user lists and @supports
     # initialized to the default values for all known supported features.
@@ -1641,7 +1664,7 @@ module Irc
       if val
         yield if block_given?
       else
-        warn "No #{key.to_s.upcase} value"
+        warning "No #{key.to_s.upcase} value"
       end
     end
 
@@ -1649,7 +1672,7 @@ module Irc
       if val == true or val == false or val.nil?
         yield if block_given?
       else
-        warn "No #{key.to_s.upcase} value must be specified, got #{val}"
+        warning "No #{key.to_s.upcase} value must be specified, got #{val}"
       end
     end
     private :noval_warn, :val_warn
@@ -1661,7 +1684,7 @@ module Irc
     def parse_isupport(line)
       debug "Parsing ISUPPORT #{line.inspect}"
       ar = line.split(' ')
-      reparse = ""
+      reparse = []
       ar.each { |en|
         prekey, val = en.split('=', 2)
         if prekey =~ /^-(.*)/
@@ -1673,7 +1696,15 @@ module Irc
         case key
         when :casemapping
           noval_warn(key, val) {
-            @supports[key] = val.to_irc_casemap
+            if val == 'charset'
+              reparse << "CASEMAPPING=(charset)"
+            else
+              # TODO some servers offer non-standard CASEMAPPINGs in the form
+              # locale.charset[-options], which indicate an extended set of
+              # allowed characters (mostly for nicks). This might be supported
+              # with hooks for the unicode core module
+              @supports[key] = val.to_irc_casemap
+            end
           }
         when :chanlimit, :idchan, :maxlist, :targmax
           noval_warn(key, val) {
@@ -1682,7 +1713,8 @@ module Irc
               k, v = g.split(':')
               @supports[key][k] = v.to_i || 0
               if @supports[key][k] == 0
-                warn "Deleting #{key} limit of 0 for #{k}"
+                # If no argument is given for a particular command (e.g. "WHOIS:"),
+                #  that command does not have a limit on the number of targets.)
                 @supports[key].delete(k)
               end
             }
@@ -1711,7 +1743,7 @@ module Irc
           @supports[key] = val
         when :maxchannels
           noval_warn(key, val) {
-            reparse += "CHANLIMIT=(chantypes):#{val} "
+            reparse << "CHANLIMIT=(chantypes):#{val} "
           }
         when :maxtargets
           noval_warn(key, val) {
@@ -1752,8 +1784,12 @@ module Irc
           @supports[key] =  val.nil? ? true : val
         end
       }
-      reparse.gsub!("(chantypes)",@supports[:chantypes])
-      parse_isupport(reparse) unless reparse.empty?
+      unless reparse.empty?
+        reparse_str = reparse.join(" ")
+        reparse_str.gsub!("(chantypes)",@supports[:chantypes])
+        reparse_str.gsub!("(charset)",@supports[:charset] || 'rfc1459')
+        parse_isupport(reparse_str)
+      end
     end
 
     # Returns the casemap of the server.
@@ -1824,8 +1860,8 @@ module Irc
         #
         # FIXME might need to raise an exception
         #
-        warn "#{self} doesn't support channel prefix #{prefix}" unless @supports[:chantypes].include?(prefix)
-        warn "#{self} doesn't support channel names this long (#{name.length} > #{@supports[:channellen]})" unless name.length <= @supports[:channellen]
+        warning "#{self} doesn't support channel prefix #{prefix}" unless @supports[:chantypes].include?(prefix)
+        warning "#{self} doesn't support channel names this long (#{name.length} > #{@supports[:channellen]})" unless name.length <= @supports[:channellen]
 
         # Next, we check if we hit the limit for channels of type +prefix+
         # if the server supports +chanlimit+
@@ -1837,7 +1873,7 @@ module Irc
             count += 1 if k.include?(n[0])
           }
           # raise IndexError, "Already joined #{count} channels with prefix #{k}" if count == @supports[:chanlimit][k]
-          warn "Already joined #{count}/#{@supports[:chanlimit][k]} channels with prefix #{k}, we may be going over server limits" if count >= @supports[:chanlimit][k]
+          warning "Already joined #{count}/#{@supports[:chanlimit][k]} channels with prefix #{k}, we may be going over server limits" if count >= @supports[:chanlimit][k]
         }
 
         # So far, everything is fine. Now create the actual Channel
@@ -1942,7 +1978,7 @@ module Irc
         end
         return old
       else
-        warn "#{self} doesn't support nicknames this long (#{tmp.nick.length} > #{@supports[:nicklen]})" unless tmp.nick.length <= @supports[:nicklen]
+        warning "#{self} doesn't support nicknames this long (#{tmp.nick.length} > #{@supports[:nicklen]})" unless tmp.nick.length <= @supports[:nicklen]
         @users << tmp
         return @users.last
       end