From 3538de46fb71b69e74106f0056ded7bb9beafd89 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Wed, 2 Aug 2006 19:06:29 +0000 Subject: Fix User selection/creation --- lib/rbot/irc.rb | 76 +++++++++++++++++++++++++++++++++++++++-------------- lib/rbot/rfc2812.rb | 2 +- 2 files changed, 58 insertions(+), 20 deletions(-) diff --git a/lib/rbot/irc.rb b/lib/rbot/irc.rb index f9f3bc21..87f3c93f 100644 --- a/lib/rbot/irc.rb +++ b/lib/rbot/irc.rb @@ -14,6 +14,11 @@ # Author:: Giuseppe Bilotta (giuseppe.bilotta@gmail.com) # Copyright:: Copyright (c) 2006 Giuseppe Bilotta # License:: GPLv2 +# +# TODO User should have associated Server too +# +# TODO rather than the complex init methods, we should provide a single one (having a String parameter) +# and then provide to_irc_netmask(casemap), to_irc_user(server), to_irc_channel(server) etc # We start by extending the String class @@ -280,7 +285,7 @@ module Irc @nick = nil @user = nil @host = nil - when /(\S+)(?:!(\S+)@(?:(\S+))?)?/ + when /^(\S+?)(?:!(\S+)@(?:(\S+))?)?$/ @casemap = casemap || 'rfc1459' @nick = $1.irc_downcase(@casemap) @user = $2 @@ -297,6 +302,12 @@ module Irc @host = "*" if @host.to_s.empty? end + # Equality: two Netmasks are equal if they have the same @nick, @user, @host and @casemap + # + def ==(other) + self.class == other.class && @nick == other.nick && @user == other.user && @host == other.host && @casemap == other.casemap + end + # This method changes the nick of the Netmask, downcasing the argument # following IRC rules and defaulting to the generic glob pattern if # the result is the null string. @@ -322,6 +333,14 @@ module Irc @host = "*" if @host.empty? end + # This method changes the casemap of a Netmask, which is needed in some + # extreme circumstances. Please use sparingly + # + def casemap=(newcmap) + @casemap = newcmap.to_s + @casemap = "rfc1459" if @casemap.empty? + end + # This method checks if a Netmask is definite or not, by seeing if # any of its components are defined by globs # @@ -332,7 +351,7 @@ module Irc # A Netmask is easily converted to a String for the usual representation # def fullform - return "#{nick}@#{user}!#{host}" + return "#{nick}!#{user}@#{host}" end alias :to_s :fullform @@ -844,6 +863,10 @@ module Irc when :casemapping, :network noval_warn(key, val) { @supports[key] = val + @users.each { |u| + debug "Resetting casemap of #{u} from #{u.casemap} to #{val}" + u.casemap = val + } } when :chanlimit, :idchan, :maxlist, :targmax noval_warn(key, val) { @@ -968,7 +991,11 @@ module Irc # The Channel is automatically created with the appropriate casemap # def new_channel(name, topic=nil, users=[], fails=true) - if !has_chan?(name) + ex = get_chan(name) + if ex + raise "Channel #{name} already exists on server #{self}" if fails + return ex + else prefix = name[0].chr @@ -977,7 +1004,7 @@ 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} > #{@support[:channellen]}" unless name.length <= @supports[:channellen] + warn "#{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+ @@ -1031,9 +1058,6 @@ module Irc debug "Managing channels #{@channel_names.join(', ')}" return chan end - - raise "Channel #{name} already exists on server #{self}" if fails - return get_channel(name) end # Returns the Channel with the given _name_ on the server, @@ -1080,21 +1104,27 @@ module Irc else tmp = User.new(str, self.casemap) end - if !has_user?(tmp.nick) - warn "#{self} doesn't support nicknames this long (#{tmp.nick.length} > #{@support[:nicklen]}" unless tmp.nick.length <= @supports[:nicklen] + debug "Creating or selecting user #{tmp.inspect} from #{str.inspect}" + old = get_user(tmp.nick) + if old + debug "User already existed as #{old.inspect}" + if tmp.known? + if old.known? + raise "User #{tmp.nick} has inconsistent Netmasks! #{self} knows #{old.inspect} but access was tried with #{tmp.inspect}" if old != tmp + raise "User #{tmp} already exists on server #{self}" if fails + else + old.user = tmp.user + old.host = tmp.host + debug "User improved to #{old.inspect}" + end + end + return old + else + warn "#{self} doesn't support nicknames this long (#{tmp.nick.length} > #{@supports[:nicklen]})" unless tmp.nick.length <= @supports[:nicklen] @users << tmp @user_nicks << tmp.nick return @users.last end - old = get_user(tmp.nick) - if old.known? - raise "User #{tmp.nick} has inconsistent Netmasks! #{self} knows #{old} but access was tried with #{tmp}" if old != tmp - raise "User #{tmp} already exists on server #{self}" if fails - else - old.user = tmp.user - old.host = tmp.host - end - return old end # Returns the User with the given Netmask on the server, @@ -1102,7 +1132,15 @@ module Irc # new_user(_str_, +false+) # def user(str) - new_user(str, false) + # This method can get called before server has been initialized (e.g. on + # Freenode there is a NOTICE from AUTH on connect). In this case we just + # return the string + # + if defined?(@supports) + new_user(str, false) + else + str + end end # Remove User _someuser_ from the list of Users. diff --git a/lib/rbot/rfc2812.rb b/lib/rbot/rfc2812.rb index 19b39159..e2438210 100644 --- a/lib/rbot/rfc2812.rb +++ b/lib/rbot/rfc2812.rb @@ -888,7 +888,7 @@ module Irc if prefix != nil data[:source] = prefix if prefix =~ /^(\S+)!(\S+)$/ - data[:source] = @server.user($1) + data[:source] = @server.user(prefix) else if @server.hostname && @server.hostname != data[:source] warning "Unknown origin #{data[:source]} for message\n#{serverstring.inspect}" -- cgit v1.2.3