X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=lib%2Frbot%2Firc.rb;h=0cf70d5a6253e7a086b2f8ad0ac868b7d3ac7cf2;hb=7f4e98a691ba6ee6f220fec982f17c900c929f1d;hp=8ef55712cf48affeb815482241a1635b3f26d51c;hpb=0d0f61e6e3185488c85a6805ff2f4d468d4a3935;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git diff --git a/lib/rbot/irc.rb b/lib/rbot/irc.rb index 8ef55712..0cf70d5a 100644 --- a/lib/rbot/irc.rb +++ b/lib/rbot/irc.rb @@ -4,6 +4,8 @@ # Channels is the User on (of those the client is on too)? # We may want this so that when a User leaves all Channels and he hasn't # sent us privmsgs, we know remove him from the Server @users list +# * Maybe ChannelList and UserList should be HashesOf instead of ArrayOf? +# See items marked as TODO Ho #++ # :title: IRC module # @@ -17,6 +19,16 @@ require 'singleton' +class Object + + # We extend the Object class with a method that + # checks if the receiver is nil or empty + def nil_or_empty? + return true unless self + return true if self.respond_to? :empty and self.empty? + return false + end +end # The Irc module is used to keep all IRC-related classes # in the same namespace @@ -851,6 +863,8 @@ module Irc # Channel modes of type A manipulate lists # + # Example: b (banlist) + # class ModeTypeA < Mode def initialize(ch) super @@ -872,6 +886,8 @@ module Irc # Channel modes of type B need an argument # + # Example: k (key) + # class ModeTypeB < Mode def initialize(ch) super @@ -916,6 +932,8 @@ module Irc # Channel modes of type C need an argument when set, # but not when they get reset # + # Example: l (limit) + # class ModeTypeC < Mode def initialize(ch) super @@ -939,6 +957,8 @@ module Irc # Channel modes of type D are basically booleans # + # Example: m (moderate) + # class ModeTypeD < Mode def initialize(ch) super @@ -1024,7 +1044,7 @@ module Irc str = "<#{self.class}:#{'0x%x' % self.object_id}:" str << " on server #{server}" if server str << " @name=#{@name.inspect} @topic=#{@topic.text.inspect}" - str << " @users=[#{@users.sort.join(', ')}]" + str << " @users=[#{user_nicks.sort.join(', ')}]" str << ">" end @@ -1034,6 +1054,35 @@ module Irc self end + # TODO Ho + def user_nicks + @users.map { |u| u.downcase } + end + + # Checks if the receiver already has a user with the given _nick_ + # + def has_user?(nick) + user_nicks.index(nick.irc_downcase(casemap)) + end + + # Returns the user with nick _nick_, if available + # + def get_user(nick) + idx = has_user?(nick) + @users[idx] if idx + end + + # Adds a user to the channel + # + def add_user(user, opts={}) + silent = opts.fetch(:silent, false) + if has_user?(user) && !silent + warn "Trying to add user #{user} to channel #{self} again" + else + @users << user.to_irc_user(server_and_casemap) + end + end + # Creates a new channel with the given name, optionally setting the topic # and an initial users list. # @@ -1054,7 +1103,7 @@ module Irc @users = UserList.new users.each { |u| - @users << u.to_irc_user(server_and_casemap) + add_user(u) } # Flags @@ -1079,25 +1128,25 @@ module Irc # A channel is local to a server if it has the '&' prefix # def local? - name[0] = 0x26 + name[0] == 0x26 end # A channel is modeless if it has the '+' prefix # def modeless? - name[0] = 0x2b + name[0] == 0x2b end # A channel is safe if it has the '!' prefix # def safe? - name[0] = 0x21 + name[0] == 0x21 end # A channel is normal if it has the '#' prefix # def normal? - name[0] = 0x23 + name[0] == 0x23 end # Create a new mode @@ -1150,10 +1199,12 @@ module Irc attr_reader :channels, :users + # TODO Ho def channel_names @channels.map { |ch| ch.downcase } end + # TODO Ho def user_nicks @users.map { |u| u.downcase } end @@ -1294,7 +1345,7 @@ module Irc groups = val.split(',') groups.each { |g| k, v = g.split(':') - @supports[key][k] = v.to_i + @supports[key][k] = v.to_i || 0 } } when :chanmodes @@ -1325,8 +1376,8 @@ module Irc } when :maxtargets noval_warn(key, val) { - @supports[key]['PRIVMSG'] = val.to_i - @supports[key]['NOTICE'] = val.to_i + @supports[:targmax]['PRIVMSG'] = val.to_i + @supports[:targmax]['NOTICE'] = val.to_i } when :network noval_warn(key, val) { @@ -1396,13 +1447,15 @@ module Irc # Checks if the receiver already has a channel with the given _name_ # def has_channel?(name) - channel_names.index(name.downcase) + return false if name.nil_or_empty? + channel_names.index(name.irc_downcase(casemap)) end alias :has_chan? :has_channel? # Returns the channel with name _name_, if available # def get_channel(name) + return nil if name.nil_or_empty? idx = has_channel?(name) channels[idx] if idx end @@ -1411,9 +1464,15 @@ module Irc # Create a new Channel object bound to the receiver and add it to the # list of Channels on the receiver, unless the channel was # present already. In this case, the default action is to raise an - # exception, unless _fails_ is set to false + # exception, unless _fails_ is set to false. An exception can also be + # raised if _str_ is nil or empty, again only if _fails_ is set to true; + # otherwise, the method just returns nil # def new_channel(name, topic=nil, users=[], fails=true) + if name.nil_or_empty? + raise "Tried to look for empty or nil channel name #{name.inspect}" if fails + return nil + end ex = get_chan(name) if ex raise "Channel #{name} already exists on server #{self}" if fails @@ -1500,7 +1559,8 @@ module Irc # Checks if the receiver already has a user with the given _nick_ # def has_user?(nick) - user_nicks.index(nick.downcase) + return false if nick.nil_or_empty? + user_nicks.index(nick.irc_downcase(casemap)) end # Returns the user with nick _nick_, if available @@ -1513,9 +1573,15 @@ module Irc # Create a new User object bound to the receiver and add it to the list # of Users on the receiver, unless the User was present # already. In this case, the default action is to raise an exception, - # unless _fails_ is set to false + # unless _fails_ is set to false. An exception can also be raised + # if _str_ is nil or empty, again only if _fails_ is set to true; + # otherwise, the method just returns nil # def new_user(str, fails=true) + if str.nil_or_empty? + raise "Tried to look for empty or nil user name #{str.inspect}" if fails + return nil + end tmp = str.to_irc_user(:server => self) old = get_user(tmp.nick) # debug "Tmp: #{tmp.inspect}" @@ -1582,7 +1648,7 @@ module Irc @users.inject(UserList.new) { |list, user| if user.user == "*" or user.host == "*" - list << user if user.nick.downcase =~ nm.nick.downcase.to_irc_regexp + list << user if user.nick.irc_downcase(casemap) =~ nm.nick.irc_downcase(casemap).to_irc_regexp else list << user if user.matches?(nm) end