summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2006-08-01 13:42:27 +0000
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2006-08-01 13:42:27 +0000
commit83ced8b38fe07d425df7fa9b9fadee98a4cba19e (patch)
treec219c1c92893b4c3184d598eaf38b65ab4ff9680 /lib
parent5cc6ece3d483db28f92f82a78b926ba6ce62769d (diff)
New Irc framework: fix channel modes handling
Diffstat (limited to 'lib')
-rw-r--r--lib/rbot/irc.rb114
-rw-r--r--lib/rbot/ircbot.rb12
-rw-r--r--lib/rbot/rfc2812.rb9
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]