]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/rfc2812.rb
Fix casemap/server mismatch problems when moving the bots between servers with differ...
[user/henk/code/ruby/rbot.git] / lib / rbot / rfc2812.rb
index 5622dcf8e0ac84e18a721173e3c4e4e70188faa4..9ca6571a85b374e1f9723b0f3cd590344ab7ff71 100644 (file)
@@ -886,16 +886,27 @@ module Irc
       prefix, command, params = $2, $3, $5
 
       if prefix != nil
-        data[:source] = prefix
-        if prefix =~ /^(\S+)!(\S+)$/
+        # Most servers will send a full nick!user@host prefix for
+        # messages from users. Therefore, when the prefix doesn't match this
+        # syntax it's usually the server hostname.
+        #
+        # This is not always true, though, since some servers do not send a
+        # full hostmask for user messages.
+        #
+        if prefix =~ /^(?:\S+)(?:!\S+)?@(?:\S+)$/
           data[:source] = @server.user(prefix)
         else
-          if @server.hostname && @server.hostname != data[:source]
-            warning "Unknown origin #{data[:source]} for message\n#{serverstring.inspect}"
+          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)
+            else
+              data[:source] = @server
+            end
           else
             @server.instance_variable_set(:@hostname, data[:source])
+            data[:source] = @server
           end
-          data[:source] = @server
         end
       end
 
@@ -1009,7 +1020,7 @@ module Irc
           users = []
           argv[3].scan(/\S+/).each { |u|
             # FIXME beware of servers that allow multiple prefixes
-            if(u =~ /^(#{@server.supports[:prefix][:prefixes].join})?(.*)$/)
+            if(u =~ /^([#{@server.supports[:prefix][:prefixes].join}])?(.*)$/)
               umode = $1
               user = $2
               users << [user, umode]
@@ -1018,11 +1029,13 @@ module Irc
 
           users.each { |ar|
             u = @server.user(ar[0])
-            chan.users << u unless chan.users.include?(u)
+            chan.add_user(u, :silent => true)
+            debug "Adding user #{u}"
             if 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)
+              ms = @server.supports[:prefix][:modes][m]
+              debug "\twith mode #{ar[1]} (#{ms})"
+              chan.mode[ms].set(u)
             end
           }
           @tmpusers += users
@@ -1095,7 +1108,15 @@ module Irc
         # 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)
 
@@ -1106,7 +1127,15 @@ module Irc
           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
@@ -1139,7 +1168,8 @@ module Irc
       when 'QUIT'
         data[:message] = argv[0]
         data[:was_on] = @server.channels.inject(ChannelList.new) { |list, ch|
-          list << ch if ch.users.include?(data[:source])
+          list << ch if ch.has_user?(data[:source])
+          list
         }
 
         @server.delete_user(data[:source])
@@ -1147,7 +1177,7 @@ module Irc
         handle(:quit, data)
       when 'JOIN'
         data[:channel] = @server.channel(argv[0])
-        data[:channel].users << data[:source]
+        data[:channel].add_user(data[:source])
 
         handle(:join, data)
       when 'TOPIC'
@@ -1163,7 +1193,7 @@ module Irc
         handle(:invite, data)
       when 'NICK'
         data[:is_on] = @server.channels.inject(ChannelList.new) { |list, ch|
-          list << ch if ch.users.include?(data[:source])
+          list << ch if ch.has_user?(data[:source])
           list
         }
 
@@ -1186,6 +1216,7 @@ module Irc
         case data[:channel]
         when User
           # TODO
+          warn "Unhandled user mode message '#{serverstring}'"
         else
           # data[:modes] is an array where each element
           # is either a flag which doesn't need parameters
@@ -1221,13 +1252,13 @@ module Irc
                   data[:modes] << [setting + m]
                   who_wants_params << data[:modes].length - 1
                 else
-                  warn "Unknown mode #{m} in #{serverstring}"
+                  warn "Unknown mode #{m} in #{serverstring.inspect}"
                 end
               }
             else
               idx = who_wants_params.shift
               if idx.nil?
-                warn "Oops, problems parsing #{serverstring}"
+                warn "Oops, problems parsing #{serverstring.inspect}"
                 break
               end
               data[:modes][idx] << arg
@@ -1251,6 +1282,7 @@ module Irc
 
         handle(:mode, data)
       else
+        warn "Unknown message #{serverstring.inspect}"
         handle(:unknown, data)
       end
     end