]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/rfc2812.rb
Improve NOTICE and PRIVMSG robustness when target is not a simple channel or user
[user/henk/code/ruby/rbot.git] / lib / rbot / rfc2812.rb
index 7832f9980a403d540c7c7d591738f99d32e1a3a1..26549539ef5dd3eee903edda46ad3ebdebe6a8ff 100644 (file)
@@ -820,8 +820,8 @@ module Irc
 
     # 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
 
@@ -1002,12 +1002,13 @@ module Irc
 
           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
@@ -1094,24 +1095,40 @@ 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)
 
         # 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'
@@ -1139,6 +1156,7 @@ module Irc
         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])
@@ -1151,7 +1169,7 @@ module Irc
         handle(:join, data)
       when 'TOPIC'
         data[:channel] = @server.channel(argv[0])
-        data[:topic] = ChannelTopic.new(argv[1], data[:source], Time.new)
+        data[:topic] = Channel::Topic.new(argv[1], data[:source], Time.new)
         data[:channel].topic.replace(data[:topic])
 
         handle(:changetopic, data)
@@ -1163,6 +1181,7 @@ module Irc
       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]