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.
# File lib/rbot/irc.rb, line 1563 def initialize @hostname = @version = @usermodes = @chanmodes = nil @channels = ChannelList.new @users = UserList.new reset_capabilities end
Returns the casemap of the server.
# File lib/rbot/irc.rb, line 1786 def casemap @supports[:casemapping] end
Returns the Channel with the given name on the server, creating it if necessary. This is a short form for new_channel(str, nil, [], false)
# File lib/rbot/irc.rb, line 1912 def channel(str) new_channel(str,nil,[],false) end
TODO Ho
# File lib/rbot/irc.rb, line 1534 def channel_names @channels.map { |ch| ch.downcase } end
Clears the server
# File lib/rbot/irc.rb, line 1637 def clear reset_lists reset_capabilities @hostname = @version = @usermodes = @chanmodes = nil end
Remove Channel name from the list of Channels
# File lib/rbot/irc.rb, line 1918 def delete_channel(name) idx = has_channel?(name) raise "Tried to remove unmanaged channel #{name}" unless idx @channels.delete_at(idx) end
Remove User someuser from the list of Users. someuser must be specified with the full Netmask.
# File lib/rbot/irc.rb, line 1993 def delete_user(someuser) idx = has_user?(someuser) raise "Tried to remove unmanaged user #{user}" unless idx have = self.user(someuser) @channels.each { |ch| delete_user_from_channel(have, ch) } @users.delete_at(idx) end
Finds all Users on server whose Netmask matches mask
# File lib/rbot/irc.rb, line 2011 def find_users(mask) nm = new_netmask(mask) @users.inject(UserList.new) { |list, user| if user.user == "*" or user.host == "*" list << user if user.nick.irc_downcase(casemap) =~ nm.nick.irc_downcase(casemap).to_irc_regexp else list << user if user.matches?(nm) end list } end
Returns the channel with name name, if available
# File lib/rbot/irc.rb, line 1821 def get_channel(name) return nil if name.nil_or_empty? idx = has_channel?(name) channels[idx] if idx end
Returns the user with nick nick, if available
# File lib/rbot/irc.rb, line 1933 def get_user(nick) idx = has_user?(nick) @users[idx] if idx end
Checks if the receiver already has a channel with the given name
# File lib/rbot/irc.rb, line 1813 def has_channel?(name) return false if name.nil_or_empty? channel_names.index(name.irc_downcase(casemap)) end
Checks if the receiver already has a user with the given nick
# File lib/rbot/irc.rb, line 1926 def has_user?(nick) return false if nick.nil_or_empty? user_nicks.index(nick.irc_downcase(casemap)) end
# File lib/rbot/irc.rb, line 1543 def inspect chans, users = [@channels, @users].map {|d| d.sort { |a, b| a.downcase <=> b.downcase }.map { |x| x.inspect } } str = self.__to_s__[0..-2] str << " @hostname=#{hostname}" str << " @channels=#{chans}" str << " @users=#{users}" str << ">" end
Convert a prefix (@, +, %, ...) to the corresponding mode (o, v, h, ...). See also prefix_for_mode
# File lib/rbot/irc.rb, line 1618 def mode_for_prefix(pfx) return @supports[:prefix][:modes][ @supports[:prefix][:prefixes].index(pfx.to_sym) ] end
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. 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
# File lib/rbot/irc.rb, line 1835 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 return ex else 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] # Next, we check if we hit the limit for channels of type +prefix+ # if the server supports +chanlimit+ # @supports[:chanlimit].keys.each { |k| next unless k.include?(prefix) count = 0 channel_names.each { |n| 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] } # So far, everything is fine. Now create the actual Channel # chan = Channel.new(name, topic, users, :server => self) # We wade through +prefix+ and +chanmodes+ to create appropriate # lists and flags for this channel @supports[:prefix][:modes].each { |mode| chan.create_mode(mode, Channel::UserMode) } if @supports[:prefix][:modes] @supports[:chanmodes].each { |k, val| if val case k when :typea val.each { |mode| chan.create_mode(mode, Channel::ModeTypeA) } when :typeb val.each { |mode| chan.create_mode(mode, Channel::ModeTypeB) } when :typec val.each { |mode| chan.create_mode(mode, Channel::ModeTypeC) } when :typed val.each { |mode| chan.create_mode(mode, Channel::ModeTypeD) } end end } @channels << chan # debug "Created channel #{chan.inspect}" return chan end end
Create a new Netmask object with the appropriate casemap
# File lib/rbot/irc.rb, line 2005 def new_netmask(str) str.to_irc_netmask(:server => self) end
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. 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
# File lib/rbot/irc.rb, line 1945 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}" # debug "Old: #{old.inspect}" if old # debug "User already existed as #{old.inspect}" if tmp.known? if old.known? # debug "Both were known" # Do not raise an error: things like Freenode change the hostname after identification warning "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 end if old.fullform.downcase != tmp.fullform.downcase old.replace(tmp) # debug "Known user now #{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 return @users.last end end
This method is used to parse a 005 RPL_ISUPPORT line
See the RPL_ISUPPORT draft
# File lib/rbot/irc.rb, line 1674 def parse_isupport(line) debug "Parsing ISUPPORT #{line.inspect}" ar = line.split(' ') reparse = [] ar.each { |en| prekey, val = en.split('=', 2) if prekey =~ /^-(.*)/ key = $1.downcase.to_sym val = false else key = prekey.downcase.to_sym end case key when :casemapping noval_warn(key, val) { 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) { groups = val.split(',') groups.each { |g| k, v = g.split(':') @supports[key][k] = v.to_i || 0 if @supports[key][k] == 0 warn "Deleting #{key} limit of 0 for #{k}" @supports[key].delete(k) end } } when :chanmodes noval_warn(key, val) { groups = val.split(',') @supports[key][:typea] = groups[0].scan(/./).map { |x| x.to_sym} @supports[key][:typeb] = groups[1].scan(/./).map { |x| x.to_sym} @supports[key][:typec] = groups[2].scan(/./).map { |x| x.to_sym} @supports[key][:typed] = groups[3].scan(/./).map { |x| x.to_sym} } when :channellen, :kicklen, :modes, :topiclen if val @supports[key] = val.to_i else @supports[key] = nil end when :chantypes @supports[key] = val # can also be nil when :excepts val ||= 'e' @supports[key] = val when :invex val ||= 'I' @supports[key] = val when :maxchannels noval_warn(key, val) { reparse << "CHANLIMIT=(chantypes):#{val} " } when :maxtargets noval_warn(key, val) { @supports[:targmax]['PRIVMSG'] = val.to_i @supports[:targmax]['NOTICE'] = val.to_i } when :network noval_warn(key, val) { @supports[key] = val } when :nicklen noval_warn(key, val) { @supports[key] = val.to_i } when :prefix if val val.scan(/\((.*)\)(.*)/) { |m, p| @supports[key][:modes] = m.scan(/./).map { |x| x.to_sym} @supports[key][:prefixes] = p.scan(/./).map { |x| x.to_sym} } else @supports[key][:modes] = nil @supports[key][:prefixes] = nil end when :safelist val_warn(key, val) { @supports[key] = val.nil? ? true : val } when :statusmsg noval_warn(key, val) { @supports[key] = val.scan(/./) } when :std noval_warn(key, val) { @supports[key] = val.split(',') } else @supports[key] = val.nil? ? true : val end } 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
This method is used to parse a 004 RPL_MY_INFO line
# File lib/rbot/irc.rb, line 1645 def parse_my_info(line) ar = line.split(' ') @hostname = ar[0] @version = ar[1] @usermodes = ar[2] @chanmodes = ar[3] end
Convert a mode (o, v, h, ...) to the corresponding prefix (@, +, %, ...). See also mode_for_prefix
# File lib/rbot/irc.rb, line 1610 def prefix_for_mode(mode) return @supports[:prefix][:prefixes][ @supports[:prefix][:modes].index(mode.to_sym) ] end
Resets the server capabilities
# File lib/rbot/irc.rb, line 1575 def reset_capabilities @supports = { :casemapping => 'rfc1459'.to_irc_casemap, :chanlimit => {}, :chanmodes => { :typea => nil, # Type A: address lists :typeb => nil, # Type B: needs a parameter :typec => nil, # Type C: needs a parameter when set :typed => nil # Type D: must not have a parameter }, :channellen => 50, :chantypes => "#&!+", :excepts => nil, :idchan => {}, :invex => nil, :kicklen => nil, :maxlist => {}, :modes => 3, :network => nil, :nicklen => 9, :prefix => { :modes => [:o, :v], :prefixes => [:"@", :+] }, :safelist => nil, :statusmsg => nil, :std => nil, :targmax => {}, :topiclen => nil } @capabilities = {} end
TODO Ho
# File lib/rbot/irc.rb, line 1539 def user_nicks @users.map { |u| u.downcase } end
Generated with the Darkfish Rdoc Generator 2.