]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/rfc2812.rb
New Irc Framework: channel add_user was adding users indiscriminately when silent
[user/henk/code/ruby/rbot.git] / lib / rbot / rfc2812.rb
index bec3d322c706065e043127d92606f48443d7f179..2d4d323ba439db270d6fb188c3f62f6996ccfe7a 100644 (file)
@@ -942,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
@@ -1001,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"
@@ -1095,8 +1099,10 @@ module Irc
           # "<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
@@ -1108,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