# create a new IrcClient instance
def initialize
- @server = Server.new # The Server
- @client = User.new # The User representing the client on this Server
+ @server = Server.new # The Server
+ @client = @server.user("") # The User representing the client on this Server
@handlers = Hash.new
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}"
data[:nick] = $2
data[:address] = $3
@client = @server.user(data[:netmask])
+ set = true
when /Welcome to the Internet Relay Network\s(\S+)/
data[:nick] = $1
when /Welcome.*\s+(\S+)$/
when /^(\S+)$/
data[:nick] = $1
end
- @user ||= @server.user(data[:nick])
+ @client = @server.user(data[:nick]) unless set
handle(:welcome, data)
when RPL_YOURHOST
# "Your host is <servername>, running version <ver>"
# 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"
chan = @server.get_channel(data[:channel])
unless chan
- warning "Received topic #{data[:topic].inspect} for channel #{data[:channel].inspect} I was not on"
+ warning "Received names #{data[:topic].inspect} for channel #{data[:channel].inspect} I was not on"
return
end
users = []
argv[3].scan(/\S+/).each { |u|
+ # FIXME beware of servers that allow multiple prefixes
if(u =~ /^(#{@server.supports[:prefix][:prefixes].join})?(.*)$/)
umode = $1
user = $2
users.each { |ar|
u = @server.user(ar[0])
- chan.users << u
+ chan.users << u unless chan.users.include?(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
# parse it yourself, or you can bind to 'MSG', 'PUBLIC',
# etc and get it all nicely split up for you.
- data[:target] = @server.user_or_channel(argv[0])
+ begin
+ data[:target] = @server.user_or_channel(argv[0])
+ rescue
+ # The previous may fail e.g. when the target is a server or something
+ # like that (e.g. $<mask>). In any of these cases, we just use the
+ # String as a target
+ # FIXME we probably want to explicitly check for the #<mask> $<mask>
+ data[:target] = argv[0]
+ end
data[:message] = argv[1]
handle(:privmsg, data)
# Now we split it
- if(data[:target].class <= Channel)
+ if data[:target].kind_of?(Channel)
handle(:public, data)
else
handle(:msg, data)
end
when 'NOTICE'
- data[:target] = @server.user_or_channel(argv[0])
+ begin
+ data[:target] = @server.user_or_channel(argv[0])
+ rescue
+ # The previous may fail e.g. when the target is a server or something
+ # like that (e.g. $<mask>). In any of these cases, we just use the
+ # String as a target
+ # FIXME we probably want to explicitly check for the #<mask> $<mask>
+ data[:target] = argv[0]
+ end
data[:message] = argv[1]
case data[:source]
when User
handle(:notice, data)
else
- # "server notice" (not from user, noone to reply to
+ # "server notice" (not from user, noone to reply to)
handle(:snotice, data)
end
when 'KICK'
data[:message] = argv[0]
data[:was_on] = @server.channels.inject(ChannelList.new) { |list, ch|
list << ch if ch.users.include?(data[:source])
+ list
}
@server.delete_user(data[:source])
handle(:join, data)
when 'TOPIC'
data[:channel] = @server.channel(argv[0])
- data[:topic] = ChannelTopic.new(argv[1], data[:source], Time.new)
- data[:channel].topic = data[:topic]
+ data[:topic] = Channel::Topic.new(argv[1], data[:source], Time.new)
+ data[:channel].topic.replace(data[:topic])
handle(:changetopic, data)
when 'INVITE'
when 'NICK'
data[:is_on] = @server.channels.inject(ChannelList.new) { |list, ch|
list << ch if ch.users.include?(data[:source])
+ list
}
data[:newnick] = argv[0]
data[:oldnick] = data[:source].nick.dup
- data[:source].nick = data[:nick]
+ data[:source].nick = data[:newnick]
+
debug "#{data[:oldnick]} (now #{data[:newnick]}) was on #{data[:is_on].join(', ')}"
handle(:nick, data)
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]