X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=lib%2Frbot%2Firc.rb;h=17b7bc3e4b0cee684e9f44a37d1701b10666c744;hb=6cf365c49ce5fbe24c0a4ff0663550390b501fea;hp=c893fc2728d22b0d44383f755970390fa4c7faa8;hpb=34ca2ba507e4246f1bc1851b04d2ecdffd433a19;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git diff --git a/lib/rbot/irc.rb b/lib/rbot/irc.rb index c893fc27..17b7bc3e 100644 --- a/lib/rbot/irc.rb +++ b/lib/rbot/irc.rb @@ -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? ? "" : 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