warning "Server thinks client (#{@user.inspect}) has a different nick"
@user.nick = data[:target]
end
- if argv[1] =~ /(\S+)(?:!(\S+?))?@(\S+)/
+ if argv[1] =~ /([^@!\s]+)(?:!([^@!\s]+?))?@(\S+)/
nick = $1
user = $2
- host = $2
+ host = $3
warning "Welcome message nick mismatch (#{nick} vs #{data[:target]})" if nick != data[:target]
@user.user = user if user
@user.host = host if host
when RPL_TOPIC_INFO
data[:nick] = @server.user(argv[0])
data[:channel] = @server.get_channel(argv[1])
- data[:source] = @server.user(argv[2])
+
+ # This must not be an IRC::User because it might not be an actual User,
+ # and we risk overwriting valid User data
+ data[:source] = argv[2].to_irc_netmask(:server => @server)
+
data[:time] = Time.at(argv[3].to_i)
if data[:channel]
- data[:channel].topic.set_by = data[:nick]
+ data[:channel].topic.set_by = data[:source]
data[:channel].topic.set_on = data[:time]
else
warning "Received topic #{data[:topic].inspect} for channel #{data[:channel].inspect} I was not on"
# "<nick> :- <server> Message of the Day -"
if argv[1] =~ /^-\s+(\S+)\s/
server = $1
- @motd = ""
+ else
+ warning "Server doesn't have an RFC compliant MOTD start."
end
+ @motd = ""
when RPL_MOTD
if(argv[1] =~ /^-\s+(.*)$/)
@motd << $1
when RPL_DATASTR
data[:text] = argv[1]
handle(:datastr, data)
+ when RPL_WHOREPLY
+ data[:channel] = argv[1]
+ data[:user] = argv[2]
+ data[:host] = argv[3]
+ data[:userserver] = argv[4]
+ data[:nick] = argv[5]
+ if argv[6] =~ /^(H|G)(\*)?(.*)?$/
+ data[:away] = ($1 == 'G')
+ data[:ircop] = $2
+ data[:modes] = $3.scan(/./).map { |mode|
+ m = @server.supports[:prefix][:prefixes].index(mode.to_sym)
+ @server.supports[:prefix][:modes][m]
+ } rescue []
+ else
+ warning "Strange WHO reply: #{serverstring.inspect}"
+ end
+ data[:hopcount], data[:real_name] = argv[7].split(" ", 2)
+
+ user = @server.get_user(data[:nick])
+
+ user.user = data[:user]
+ user.host = data[:host]
+ user.away = data[:away] # FIXME doesn't provide the actual message
+ # TODO ircop status
+ # TODO userserver
+ # TODO hopcount
+ user.real_name = data[:real_name]
+
+ channel = @server.get_channel(data[:channel])
+
+ channel.add_user(user, :silent=>true)
+ data[:modes].map { |mode|
+ channel.mode[mode].set(user)
+ }
+
+ handle(:who, data)
+ when RPL_ENDOFWHO
+ handle(:eowho, data)
else
handle(:unknown, data)
end