]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/rfc2812.rb
rss plugin: watching now relies on an ID built from title, link and description to...
[user/henk/code/ruby/rbot.git] / lib / rbot / rfc2812.rb
index 4a095dc8dac0b0dc0bfb95d812f702b53fedfd5a..5174203f590fd901384c82b4219e70058735f4c6 100644 (file)
@@ -812,16 +812,16 @@ module Irc
   RPL_DATASTR=290
 
   # implements RFC 2812 and prior IRC RFCs.
-  # clients register handler proc{}s for different server events and IrcClient
+  # clients register handler proc{}s for different server events and Client
   # handles dispatch
-  class IrcClient
+  class Client
 
-    attr_reader :server, :client
+    attr_reader :server, :user
 
-    # create a new IrcClient instance
+    # create a new Client instance
     def initialize
       @server = Server.new         # The Server
-      @client = @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
@@ -921,9 +928,9 @@ module Irc
        data[:target] = argv[0]
         # A numeric reply /should/ be directed at the client, except when we're connecting with a used nick, in which case
         # it's directed at '*'
-        not_us = !([@client.nick, '*'].include?(data[:target]))
+        not_us = !([@user.nick, '*'].include?(data[:target]))
         if not_us
-          warning "Server reply #{serverstring.inspect} directed at #{data[:target]} instead of client (#{@client.nick})"
+          warning "Server reply #{serverstring.inspect} directed at #{data[:target]} instead of client (#{@user.nick})"
         end
 
         num=command.to_i
@@ -932,16 +939,16 @@ module Irc
           # "Welcome to the Internet Relay Network
           # <nick>!<user>@<host>"
           if not_us
-            warning "Server thinks client (#{@client.inspect}) has a different nick"
-            @client.nick = data[:target]
+            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]
-            @client.user = user if user
-            @client.host = host if host
+            @user.user = user if user
+            @user.host = host if host
           end
           handle(:welcome, data)
         when RPL_YOURHOST
@@ -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"
@@ -1162,7 +1173,7 @@ module Irc
         data[:message] = argv[2]
 
         @server.delete_user_from_channel(data[:target], data[:channel])
-        if data[:target] == @client
+        if data[:target] == @user
           @server.delete_channel(data[:channel])
         end
 
@@ -1172,7 +1183,7 @@ module Irc
         data[:message] = argv[1]
 
         @server.delete_user_from_channel(data[:source], data[:channel])
-        if data[:source] == @client
+        if data[:source] == @user
           @server.delete_channel(data[:channel])
         end