X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=lib%2Frbot%2Firc.rb;h=17b7bc3e4b0cee684e9f44a37d1701b10666c744;hb=41276911b95c934dd5f33ccef53b03bc9dd40975;hp=9a9998e7f391ce6c12a48b2c892d03063bc61c6f;hpb=0a44338d09e921440fac821b1db8d03e71a10ff0;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git diff --git a/lib/rbot/irc.rb b/lib/rbot/irc.rb index 9a9998e7..17b7bc3e 100644 --- a/lib/rbot/irc.rb +++ b/lib/rbot/irc.rb @@ -24,6 +24,7 @@ require 'singleton' # The following monkeypatch is to fix a bug in Singleton where marshaling would # fail when trying to restore a marshaled Singleton due to _load being declared # private. +if RUBY_VERSION < '1.9' module ::Singleton public :_dump end @@ -33,6 +34,7 @@ class << Singleton public :_load end end +end class Object @@ -129,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 @@ -194,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 @@ -271,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 @@ -538,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}+/ @@ -631,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 @@ -825,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? @@ -1321,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 @@ -1365,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 @@ -1379,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].chr}" 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) @@ -1416,31 +1438,31 @@ module Irc # The channel prefix # def prefix - name[0].chr + name[0,1] end # A channel is local to a server if it has the '&' prefix # def local? - name[0] == 0x26 + name[0,1] == '&' end # A channel is modeless if it has the '+' prefix # def modeless? - name[0] == 0x2b + name[0,1] == '+' end # A channel is safe if it has the '!' prefix # def safe? - name[0] == 0x21 + name[0,1] == '!' end # A channel is normal if it has the '#' prefix # def normal? - name[0] == 0x23 + name[0,1] == '#' end # Create a new mode @@ -1510,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 @@ -1541,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. @@ -1639,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 @@ -1647,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 @@ -1659,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 =~ /^-(.*)/ @@ -1671,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) { @@ -1680,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 } @@ -1709,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) { @@ -1750,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. @@ -1816,14 +1854,14 @@ module Irc return ex else - prefix = name[0].chr + prefix = name[0,1] # Give a warning if the new Channel goes over some server limits. # # 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+ @@ -1835,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 @@ -1940,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