X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=lib%2Frbot%2Frfc2812.rb;h=2d4d323ba439db270d6fb188c3f62f6996ccfe7a;hb=c4502412f30f69c1ffa053b160e01d3974b338aa;hp=1a5adb846edf3419487d21489ed55fd0bcc6c3e0;hpb=7b7f1309e8c3dbc3bb4408d56489ae5fba77d57a;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git diff --git a/lib/rbot/rfc2812.rb b/lib/rbot/rfc2812.rb index 1a5adb84..2d4d323b 100644 --- a/lib/rbot/rfc2812.rb +++ b/lib/rbot/rfc2812.rb @@ -821,7 +821,7 @@ module Irc # create a new Client instance def initialize @server = Server.new # The Server - @user = @server.user("") # The User representing the client on this Server + @user = @server.user("") # The User representing the client on this Server @handlers = Hash.new @@ -830,6 +830,12 @@ module Irc @tmpusers = [] end + # clear the server and reset the User + def reset + @server.clear + @user = @server.user("") + end + # key:: server event to handle # value:: proc object called when event occurs # set a handler for a server event @@ -882,8 +888,8 @@ module Irc data = Hash.new data[:serverstring] = serverstring - unless serverstring =~ /^(:(\S+)\s)?(\S+)(\s(.*))?/ - raise "Unparseable Server Message!!!: #{serverstring}" + unless serverstring.chomp =~ /^(:(\S+)\s)?(\S+)(\s(.*))?$/ + raise "Unparseable Server Message!!!: #{serverstring.inspect}" end prefix, command, params = $2, $3, $5 @@ -896,18 +902,19 @@ module Irc # This is not always true, though, since some servers do not send a # full hostmask for user messages. # - if prefix =~ /^(?:\S+)(?:!\S+)?@(?:\S+)$/ + if prefix =~ /^#{Regexp::Irc::BANG_AT}$/ data[:source] = @server.user(prefix) else if @server.hostname if @server.hostname != prefix - debug "Origin #{prefix} for message\n\t#{serverstring.inspect}\nis neither a user hostmask nor the server hostname, assuming it's a nick" - data[:source] = @server.user(prefix) + # TODO do we want to be able to differentiate messages that are passed on to us from /other/ servers? + debug "Origin #{prefix} for message\n\t#{serverstring.inspect}\nis neither a user hostmask nor the server hostname\nI'll pretend that it's from the server anyway" + data[:source] = @server else data[:source] = @server end else - @server.instance_variable_set(:@hostname, data[:source]) + @server.instance_variable_set(:@hostname, prefix) data[:source] = @server end end @@ -935,10 +942,10 @@ module Irc 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 @@ -994,11 +1001,15 @@ module Irc 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" @@ -1088,8 +1099,10 @@ module Irc # " :- 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 @@ -1101,6 +1114,44 @@ module Irc 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