diff options
author | Giuseppe Bilotta <giuseppe.bilotta@gmail.com> | 2006-08-01 13:42:27 +0000 |
---|---|---|
committer | Giuseppe Bilotta <giuseppe.bilotta@gmail.com> | 2006-08-01 13:42:27 +0000 |
commit | 83ced8b38fe07d425df7fa9b9fadee98a4cba19e (patch) | |
tree | c219c1c92893b4c3184d598eaf38b65ab4ff9680 /lib | |
parent | 5cc6ece3d483db28f92f82a78b926ba6ce62769d (diff) |
New Irc framework: fix channel modes handling
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rbot/irc.rb | 114 | ||||
-rw-r--r-- | lib/rbot/ircbot.rb | 12 | ||||
-rw-r--r-- | lib/rbot/rfc2812.rb | 9 |
3 files changed, 64 insertions, 71 deletions
diff --git a/lib/rbot/irc.rb b/lib/rbot/irc.rb index 6877af65..f9f3bc21 100644 --- a/lib/rbot/irc.rb +++ b/lib/rbot/irc.rb @@ -170,7 +170,7 @@ class ArrayOf < Array def internal_will_accept?(raising, *els)
els.each { |el|
unless el.class <= @element_class
- raise TypeError if raising
+ raise TypeError, "#{el.inspect} is not of class #{@element_class}" if raising
return false
end
}
@@ -485,34 +485,49 @@ module Irc @set_by = set_by
@set_on = Time.new
end
+
+ # Replace a ChannelTopic with another one
+ def replace(topic)
+ raise TypeError, "#{topic.inspect} is not an Irc::ChannelTopic" unless topic.class <= ChannelTopic
+ @text = topic.text.dup
+ @set_by = topic.set_by.dup
+ @set_on = topic.set_on.dup
+ end
end
# Mode on a channel
class ChannelMode
+ def initialize(ch)
+ @channel = ch
+ end
end
# Channel modes of type A manipulate lists
#
class ChannelModeTypeA < ChannelMode
- def initialize
+ def initialize(ch)
+ super
@list = NetmaskList.new
end
def set(val)
- @list << val unless @list.include?(val)
+ nm = @channel.server.new_netmask(val)
+ @list << nm unless @list.include?(nm)
end
def reset(val)
- @list.delete(val)
+ nm = @channel.server.new_netmask(val)
+ @list.delete(nm)
end
end
# Channel modes of type B need an argument
#
class ChannelModeTypeB < ChannelMode
- def initialize
+ def initialize(ch)
+ super
@arg = nil
end
@@ -531,16 +546,19 @@ module Irc # modes of type A
#
class ChannelUserMode < ChannelModeTypeB
- def initialize
+ def initialize(ch)
+ super
@list = UserList.new
end
def set(val)
- @list << val unless @list.include?(val)
+ u = @channel.server.user(val)
+ @list << u unless @list.include?(u)
end
def reset(val)
- @list.delete(val)
+ u = @channel.server.user(val)
+ @list.delete(u)
end
end
@@ -548,7 +566,8 @@ module Irc # but not when they get reset
#
class ChannelModeTypeC < ChannelMode
- def initialize
+ def initialize(ch)
+ super
@arg = false
end
@@ -562,8 +581,9 @@ module Irc end
# Channel modes of type D are basically booleans
- class ChannelModeTypeD
- def initialize
+ class ChannelModeTypeD < ChannelMode
+ def initialize(ch)
+ super
@set = false
end
@@ -587,13 +607,14 @@ module Irc # * a set of modes
#
class Channel
- attr_reader :name, :topic, :casemap, :mode, :users
+ attr_reader :name, :topic, :mode, :users, :server
alias :to_s :name
# A String describing the Channel and (some of its) internals
#
def inspect
str = "<#{self.class}:#{'0x%08x' % self.object_id}:"
+ str << " on server #{server}"
str << " @name=#{@name.inspect} @topic=#{@topic.text.inspect}"
str << " @users=<#{@users.join(', ')}>"
str
@@ -607,14 +628,15 @@ module Irc #
# FIXME doesn't check if users have the same casemap as the channel yet
#
- def initialize(name, topic=nil, users=[], casemap=nil)
- @casemap = casemap || 'rfc1459'
-
+ def initialize(server, name, topic=nil, users=[])
+ raise TypeError, "First parameter must be an Irc::Server" unless server.class <= Server
raise ArgumentError, "Channel name cannot be empty" if name.to_s.empty?
raise ArgumentError, "Unknown channel prefix #{name[0].chr}" if name !~ /^[&#+!]/
raise ArgumentError, "Invalid character in #{name.inspect}" if name =~ /[ \x07,]/
- @name = name.irc_downcase(@casemap)
+ @server = server
+
+ @name = name.irc_downcase(casemap)
@topic = topic || ChannelTopic.new
@@ -631,6 +653,11 @@ module Irc @mode = {}
end
+ # Returns the casemap of the originating server
+ def casemap
+ return @server.casemap
+ end
+
# Removes a user from the channel
#
def delete_user(user)
@@ -673,7 +700,7 @@ module Irc # Create a new mode
#
def create_mode(sym, kl)
- @mode[sym.to_sym] = kl.new
+ @mode[sym.to_sym] = kl.new(self)
end
end
@@ -802,6 +829,7 @@ module Irc # See the RPL_ISUPPORT draft[http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt]
#
def parse_isupport(line)
+ debug "Parsing ISUPPORT #{line.inspect}"
ar = line.split(' ')
reparse = ""
ar.each { |en|
@@ -837,10 +865,10 @@ module Irc when :chanmodes
noval_warn(key, val) {
groups = val.split(',')
- @supports[key][:typea] = groups[0].scan(/./)
- @supports[key][:typeb] = groups[1].scan(/./)
- @supports[key][:typec] = groups[2].scan(/./)
- @supports[key][:typed] = groups[3].scan(/./)
+ @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
@@ -863,8 +891,8 @@ module Irc when :prefix
if val
val.scan(/\((.*)\)(.*)/) { |m, p|
- @supports[key][:modes] = m.scan(/./)
- @supports[key][:prefixes] = p.scan(/./)
+ @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
@@ -965,7 +993,7 @@ module Irc # So far, everything is fine. Now create the actual Channel
#
- chan = Channel.new(name, topic, users, self.casemap)
+ chan = Channel.new(self, name, topic, users)
# We wade through +prefix+ and +chanmodes+ to create appropriate
# lists and flags for this channel
@@ -1126,41 +1154,3 @@ module Irc end
end
-# TODO test cases
-
-if __FILE__ == $0
-
-include Irc
-
- # puts " -- irc_regexp tests"
- # ["*", "a?b", "a*b", "a\\*b", "a\\?b", "a?\\*b", "*a*\\**b?"].each { |s|
- # puts " --"
- # puts s.inspect
- # puts s.to_irc_regexp.inspect
- # puts "aUb".match(s.to_irc_regexp)[0] if "aUb" =~ s.to_irc_regexp
- # }
-
- # puts " -- Netmasks"
- # masks = []
- # masks << Netmask.new("start")
- # masks << masks[0].dup
- # masks << Netmask.new(masks[0])
- # puts masks.join("\n")
-
- # puts " -- Changing 1"
- # masks[1].nick = "me"
- # puts masks.join("\n")
-
- # puts " -- Changing 2"
- # masks[2].nick = "you"
- # puts masks.join("\n")
-
- # puts " -- Channel example"
- # ch = Channel.new("#prova")
- # p ch
- # puts " -- Methods"
- # puts ch.methods.sort.join("\n")
- # puts " -- Instance variables"
- # puts ch.instance_variables.join("\n")
-
-end
diff --git a/lib/rbot/ircbot.rb b/lib/rbot/ircbot.rb index a42d27ba..42f39b16 100644 --- a/lib/rbot/ircbot.rb +++ b/lib/rbot/ircbot.rb @@ -442,9 +442,11 @@ class IrcBot @plugins.delegate("nick", m) } @client[:quit] = proc {|data| - m = QuitMessage.new(self, @server, data[:source], data[:source], data[:message]) + source = data[:source] + message = data[:message] + m = QuitMessage.new(self, @server, source, source, message) data[:was_on].each { |ch| - irclog "@ Quit: #{data[:source].nick}: #{message}", ch + irclog "@ Quit: #{source}: #{message}", ch } @plugins.delegate("listen", m) @plugins.delegate("quit", m) @@ -1012,10 +1014,10 @@ class IrcBot end def irclogtopic(m) - if source == myself - irclog "@ I set topic \"#{topic}\"", channel + if m.source == myself + irclog "@ I set topic \"#{m.topic}\"", m.channel else - irclog "@ #{source} set topic \"#{topic}\"", channel + irclog "@ #{m.source} set topic \"#{m.topic}\"", m.channel end end diff --git a/lib/rbot/rfc2812.rb b/lib/rbot/rfc2812.rb index c8e2e410..19b39159 100644 --- a/lib/rbot/rfc2812.rb +++ b/lib/rbot/rfc2812.rb @@ -954,7 +954,7 @@ module Irc # PREFIX=(ov)@+ CASEMAPPING=ascii CAPAB IRCD=dancer :are available # on this server" # - @server.parse_isupport(params.split(' ', 2).last) + @server.parse_isupport(argv[1..-2].join(' ')) handle(:isupport, data) when ERR_NICKNAMEINUSE # "* <nick> :Nickname is already in use" @@ -1018,7 +1018,7 @@ module Irc u = @server.user(ar[0]) chan.users << u if ar[1] - m = @server.supports[:prefix][:prefixes].index(ar[1]) + m = @server.supports[:prefix][:prefixes].index(ar[1].to_sym) m = @server.supports[:prefix][:modes][m] chan.mode[m.to_sym].set(u) end @@ -1151,7 +1151,7 @@ module Irc when 'TOPIC' data[:channel] = @server.channel(argv[0]) data[:topic] = ChannelTopic.new(argv[1], data[:source], Time.new) - data[:channel].topic = data[:topic] + data[:channel].topic.replace(data[:topic]) handle(:changetopic, data) when 'INVITE' @@ -1195,7 +1195,8 @@ module Irc argv[1..-1].each { |arg| setting = arg[0].chr if "+-".include?(setting) - arg[1..-1].each_byte { |m| + arg[1..-1].each_byte { |b| + m = b.chr case m.to_sym when *@server.supports[:chanmodes][:typea] data[:modes] << [setting + m] |