Advertisement
Guest User

Untitled

a guest
May 6th, 2017
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 33.14 KB | None | 0 0
  1. require "IRCHelp"
  2. require "IRCConnection"
  3. require "rfc2812"
  4. require "irc_numerics"
  5. #require "IRCInfoHolder"
  6. require "observer"
  7. require "rexml/document"
  8. require "IRCChannel"
  9. require "IRCModes"
  10. require "Mktree"
  11. require "IRCUserManager"
  12. #this class will maintain a single IRC session with a specified network.
  13. #Use IRCManager in order to create a session, rather than using solitary
  14. #IRCSession objects.
  15. class IRCSession < IRCConnection
  16.     @@debug = 2000
  17.     STATUS_DISCONNECTED = 0
  18.     STATUS_CONNECTING = 1
  19.     STATUS_CONNECTED = 2
  20.     include RFC2812
  21.     include Observable
  22.     include IRCModes
  23.     include Mktree
  24.     include IRCHelp
  25.     #This method is supplied with a pre-chewed
  26.     #REXML document object and a network
  27.     #name. If the network exists in the
  28.     #document, the session runs through a
  29.     #startup procedure. If not, the session
  30.     #object raises an error, and should be
  31.     #discarded at that point.
  32.     #=
  33.     #=
  34.     #Once started, two threads will handle input
  35.     #and output.
  36.     #=
  37.     #=
  38.     #tba: The session object should bar access
  39.     #to methods, and/or set an accessor to
  40.     #return a known constant if the connection
  41.     #is currently unavailable. Connections
  42.     #should have the capability to be
  43.     #re-initialized, maybe on a different
  44.     #server within the same group.
  45.     def initialize(network, conf_doc, rejoin=nil)
  46.         super()
  47.         @rejoin = rejoin    #Auto rejoin after kicks if non-nil.
  48.         @local_rejoins = {} #This hash will store true/nil values
  49.                     #indexed by downcased/stripped
  50.                     #channel name.
  51.         @user_mgr = IRCUserManager.instance #IRCUser objects will
  52.                             #work to handle some
  53.                             #user-specific
  54.                             #information and
  55.                             #processing.
  56.         STDERR.puts "#{self.class}:#{self} user manager object: #{@user_mgr}"
  57.         @doc = conf_doc.elements["*/networks/"]
  58.         @addr = nil
  59.         @port = nil
  60.         @nick = nil
  61.         @realname = nil
  62.         @userid = nil
  63.         @pass = nil
  64.         @ns_pass = nil      #Nickserv password. Will probably remove the
  65.                     #current nickserv auth system in favour of a
  66.                     #<insert service name here> authentication
  67.                     #system.
  68.         @doc.elements.each{|e|
  69.             puts e
  70.         }
  71.         @prefixes = ["@+", "ov"]    #Prefixes are used when parsing
  72.                         #channel information to quickly
  73.                         #decide who is an op or not.
  74.                         #The 005 info message will be parsed
  75.                         #and used to rewrite this variable.
  76.         @current_network = nil
  77.         @status = STATUS_DISCONNECTED
  78.         @current_server = nil
  79.         @quit_msg = "\0035IRCSession v0.01a\017 (closing link)"
  80.         STDERR.puts "#{self.class}:#{self} Loading details for #{network}"
  81.         count = 0
  82.         working_doc = nil
  83.         @doc.elements.each{|element|
  84.             STDERR.puts "#{self.class}:#{self} scanning element: #{element}"
  85.             STDERR.puts "#{self.class}:#{self} #{element.attributes['name']}"
  86.             if /^#{network}$/i.match(element.attributes['name'].strip) then
  87.                 STDERR.puts "#{self.class}:#{self} matched!"
  88.                 count += 1
  89.                 STDERR.puts "#{self.class}:attributes: #{@doc.attributes}"
  90.                 @current_network = element.attributes['name'].strip
  91.                 @nick = element.attributes['nick']
  92.                 @userid = element.attributes['userid']
  93.                 @realname = element.attributes['realname']
  94.                 @ns_pass = element.attributes['nickserv']
  95.                 STDERR.puts "#{self.class}:getting servers document" if @@debug < 1
  96.                 working_doc = element
  97.                 STDERR.puts "#{self.class}:working_doc is: #{working_doc}" if @@debug < 1
  98.                 STDERR.puts "#{self.class}:breaking out" if @@debug < 1
  99.                 break
  100.             end
  101.             if count > 0 then
  102.                 STDERR.puts "#{self.class}:breaking out." if @@debug < 1
  103.                 break
  104.             end
  105.         }
  106.         if count < 1 then
  107.             raise "#{self.class}: initialize: Could not find entry for network #{network}: #{$!}"
  108.         end
  109.         @server_list = []
  110.         working_doc.elements.each{|e|
  111.             STDERR.puts "#{self.class}:server: #{e}" if @@debug < 1
  112.             @server_list.push(e)
  113.         }
  114.        
  115.        
  116.         begin
  117.             log_in(network)
  118.         rescue
  119.             raise "#{self.class}: initialize: Failed to log into network #{network}: #{$!}"
  120.         end
  121.         #connect(@addr,@port,@nick,@realname,@userid,pass)
  122.         #@evcap = IRCEventCapturer.new(self)
  123.         #@info = IRCInfoHolder.new
  124.         @motd = ""
  125.         @motdwritten = 0
  126.         @motdwriting = 0
  127.         @writingnames = []
  128.         @statusbuffer = []
  129.         @statusbuffersize = 500
  130.  
  131.         #known_users hash table contains IRCChannel objects referenced
  132.         #by channel name.
  133.         @known_channels = Hash.new
  134.         #known_users hash table contains mode strings referenced by
  135.         #nickname.
  136.         @known_users = Hash.new
  137.         @anotherextendedinputthread = Thread.new {
  138.             while (true == true)
  139.                 @inputvalid = nil
  140.                 @input = getline
  141.                 irc_parsed = irc_parse(@input)
  142.                 if irc_parsed then
  143.                     STDERR.puts "#{self.class}:#{self.class}: irc_parsed[1] = #{irc_parsed[1]}" if @@debug < 1
  144.                     if irc_parsed[1] == RPL_WELCOME then
  145.                         STDERR.puts "#{self.class}:#{self} RPL_WELCOME intercepted." if @@debug < 5
  146.                         @status = STATUS_CONNECTED
  147.                         STDERR.puts "#{self.class}:#{self} Sending login details to Nickserv." if @@debug < 5
  148.                         cmd_privmsg("NickServ", "IDENTIFY #{@ns_pass}")
  149.                         STDERR.puts "#{self.class}:#{self} done!" if @@debug < 5
  150.                         STDERR.puts "#{self.class}:#{self} status is CONNECTED." if @@debug < 5
  151.                     end
  152.                     STDERR.puts "#{self.class}:#{self.class}: welcome match passed" if @@debug < 5
  153.                     if @@debug < 1 then
  154.                         STDERR.puts "#{self.class}:#{self.class}: irc_parsed contents:" if @@debug < 1
  155.                         irc_parsed.each{|el|
  156.                             STDERR.puts "#{self.class}:el: #{el}"
  157.                             STDERR.puts "#{self.class}:el class: #{el.class}"
  158.                         }
  159.                         STDERR.puts "#{self.class}:#{self.class}: current network: #{@current_network}"
  160.                     end
  161.                     changed
  162.                     STDERR.puts "#{self.class}:#{self.class}: changed" if @@debug < 1
  163.                     notify_observers(irc_parsed[0], irc_parsed[1], irc_parsed[2], @current_network)
  164.                     STDERR.puts "#{self.class}:#{self.class}: calling info parser" if @@debug < 1
  165.                     _info_parser(irc_parsed[0], irc_parsed[1], irc_parsed[2])
  166.                     STDERR.puts "#{self.class}:#{self.class}: info parser called" if @@debug < 1
  167.                 else
  168.                     sleep 0.1
  169.                 end
  170.             end
  171.         }
  172.         #@anotherextendedinputthread.join
  173.     end
  174.  
  175.     #this method will return true if the session is currently connected.
  176.     def is_active?
  177.         if @status == STATUS_CONNECTED then
  178.             return true
  179.         else
  180.             return nil
  181.         end
  182.     end
  183.  
  184.     #this method will set the bot mute on a specific channel.
  185.     def mute(chan)
  186.         return set_mute(chan)
  187.     end
  188.  
  189.     #this method will unset the bot mute on a specified channel.
  190.     def unmute(chan)
  191.         return set_mute(chan, 1)
  192.     end
  193.     def set_mute(chan, value)
  194.         dchan = chan.downcase
  195.         if !@known_channels.has_key?(dchan) then
  196.             return nil
  197.         end
  198.         @known_channels[dchan].set_mute(value)
  199.         return true
  200.     end
  201.  
  202.     #this method will return true or false depending on whether
  203.     #the session is currently listening to the specified channel.
  204.     def in_channel?(chan)
  205.         dchan = chan.downcase
  206.         if @known_channels.has_key?(dchan) then
  207.             if !@known_channels[dchan].joined then
  208.                 return nil
  209.             end
  210.             if nick != nil then
  211.                 if !@known_channels[dchan].is_here?(nick) then
  212.                     return nil
  213.                 end
  214.             end
  215.             return true
  216.         else
  217.             return nil
  218.         end
  219.         return nil
  220.     end
  221.    
  222.     #this method sends a raw IRC message, with trailing cr/lf attached.
  223.     def cmd_raw(msg)
  224.         STDERR.puts "#{self.class}:intercepted message." if @@debug < 1
  225.         msg = /^(.*)[\n\r]?$/.match(msg)[1]
  226.         print "sending: #{msg}\n\r" if @@debug < 1
  227.         putline("#{msg}\r\n")
  228.     end
  229.  
  230.     #This method will send an INVITE message to the intended target, to join the specified channel.
  231.     def cmd_invite(target, channel)
  232.         begin
  233.             output = "INVITE #{target.strip} #{channel.strip}\n\r"
  234.             STDERR.puts "#{self.class}:sending: #{output}" if @@debug < 3000
  235.             putline(output)
  236.             return true
  237.         rescue
  238.             STDERR.puts "#{self.class}:#{self.class}: cmd_privmsg: failure: #{$!}" if @@debug < 5
  239.             return nil
  240.         end
  241.     end
  242.  
  243.     #this method sends a PRIVMSG message to a specified target.
  244.     def cmd_privmsg(target, msg)
  245.         begin
  246.             output = "PRIVMSG #{target} :#{msg.strip}\n\r"
  247.             STDERR.puts "#{self.class}:sending: #{output}" if @@debug < 1
  248.             putline(output)
  249.             return true
  250.         rescue
  251.             STDERR.puts "#{self.class}:#{self.class}: cmd_privmsg: failure: #{$!}" if @@debug < 5
  252.             return nil
  253.         end
  254.     end
  255.  
  256.     #this method sends a CTCP ACTION message to a specified target.
  257.     def cmd_action(target, msg)
  258.         output = "\000PRIVMSG #{target} :#{msg.strip}\000\r\n"
  259.         STDERR.puts "#{self.class}:#{self.class}: sending: #{output}" if @@debug < 1
  260.         putline(output)
  261.     end
  262.  
  263.     #this method lists all visible IRC nicks/users.
  264.     def cmd_list_users
  265.         output = {}
  266.         @known_channels.each{|k, v|
  267.             output[k] = []
  268.             v.users.each{|u|
  269.                 STDERR.puts "#{self.class}:#{self.class}: channel #{k}: #{u}" if @@debug < 1
  270.                 output[k].push u
  271.             }
  272.         }
  273.         return output
  274.     end
  275.    
  276.     #this method lists all known channels.
  277.     def cmd_list_chans
  278.         output = []
  279.         @known_channels.each{|k, v|
  280.             output.push k
  281.         }
  282.         if output.length > 0 then
  283.             return output
  284.         end
  285.         return nil
  286.     end
  287.  
  288.     #this method lists all IRC nicks in a specified channel
  289.     def cmd_list_chan_users(chan)
  290.         STDERR.puts "#{self.class}:#{self.class}: returning info for channel #{chan}" if @@debug < 2
  291.         dchan = chan.downcase
  292.         if @known_channels.has_key?(dchan) then
  293.             STDERR.puts "#{self.class}:#{self.class}: channel is known." if @@debug < 2
  294.             out = []
  295.             @known_channels[dchan].users.each{|k, v|
  296.                 STDERR.puts "#{self.class}:#{self.class}: pushing: [#{v.dup.join(',')}][0]" if @@debug < 2
  297.                 out.push v[0]
  298.             }
  299.             return out
  300.         end
  301.         return nil
  302.     end
  303.  
  304.     #this method gets the current status feed for the session.
  305.     def cmd_get_status
  306.         if (@statusbuffer.length > 0) then
  307.             tmp = @statusbuffer.shift
  308.             STDERR.puts "#{self.class}:#{self.class}: getting value: #{tmp}" if @@debug < 1
  309.             return tmp
  310.         else
  311.             #puts "<statusgets@ExtendedIRCConnection> no value to get."
  312.             return nil
  313.         end
  314.     end
  315.  
  316.     #this method sends a JOIN command with the specified channel as a parameter.
  317.     def cmd_join_chan(chan)
  318.         puts "#{self.class}: cmd_join_chan triggered for channel #{chan}" if @@debug < 10000
  319.         cmd = "JOIN :#{chan}\r\n"
  320.         putline(cmd)
  321.         return true
  322.     end
  323.  
  324.     #this method sends a PART command with the specified channel as a parameter.
  325.     def cmd_part_chan(chan)
  326.         cmd = "PART :#{chan}\r\n"
  327.         putline(cmd)
  328.         return true
  329.     end
  330.  
  331.     #this method will disconnect from the server and close the session.
  332.     def cmd_quit(message=@quit_msg)
  333.         disconnect!(message)
  334.         @status = STATUS_DISCONNECTED
  335.     end
  336.    
  337.     #this method will send a WHOIS command.
  338.     def cmd_whois(nick, target=nil)
  339.         if target == nil then
  340.             cmd = "WHOIS #{nick}\r\n"
  341.         else
  342.             cmd = "WHOIS #{target} #{nick}\r\n"
  343.         end
  344.         putline(cmd)
  345.     end
  346.  
  347.     def rejoin
  348.         return @rejoin
  349.     end
  350.     def rejoin=(i)
  351.         if i then
  352.             @rejoin = true
  353.         else
  354.             @rejoin = nil
  355.         end
  356.         return @rejoin
  357.     end
  358.     def cmd_set_rejoin(chan, value=true)
  359.         v = nil
  360.         if value then
  361.             v = true
  362.         end
  363.         dchan = chan.downcase.strip
  364.         @local_rejoins[dchan] = v
  365.         puts "#{self.class}: cmd_set_rejoin: local rejoins set: #{dchan} = '#{v}'" if @@debug < 10000
  366.         return v
  367.     end
  368.     def cmd_unset_rejoin(chan)
  369.         @local_rejoins.delete(chan.downcase.strip)
  370.     end
  371.  
  372.     def cmd_whowas(nick, num=nil, target=nil)
  373.     end
  374.     def cmd_who(text, target=nil)
  375.     end
  376.     def cmd_squery(service, text)
  377.     end
  378.    
  379.     #this method will log into a specified network
  380.     def log_in(network)
  381.         STDERR.puts "#{self.class}:#{self.class}: attempting log in sequence for #{network}" if @@debug < 1
  382.         if @status == STATUS_DISCONNECTED then
  383.             @status = STATUS_CONNECTING
  384.             count = 0
  385.             begin
  386.                 e = @server_list[count]
  387.                 if @@debug < 1 then
  388.                     STDERR.puts "#{self.class}:#{self.object_id}: e.class: #{e.class}"
  389.                     STDERR.puts "#{self.class}:#{self.object_id}: e contents follow..."
  390.                     e.attributes.each{|k, v|    STDERR.puts "#{self.class}:#{k} => #{v}"}
  391.                 end
  392.                 @current_server = e.attributes['name']
  393.                 STDERR.puts "#{self.class}:#{self.object_id}: Opening connection to #{@current_server}"
  394.                 @addr = e.attributes['host']
  395.                 @port = e.attributes['port']
  396.                 STDERR.puts "#{self.class}:#{self.object_id}: #{@addr}:#{@port}"
  397.                 @known_channels = Hash.new
  398.                 if @@debug < 1 then
  399.                     puts @nick
  400.                     puts @userid
  401.                     puts @realname
  402.                     puts @ns_pass
  403.                 end
  404.                 connect(@addr, @port, @nick, @userid, @realname, nil, @ns_pass)
  405.                 STDERR.puts "#{self.class}:#{self.class}: starting up new network entry for #{network}" if @@debug < 1
  406.                 @user_mgr.new_network(network)
  407.             rescue
  408.                 STDERR.puts "#{self.class}:#{self.class}: Connection attempt failed: #{$!}"
  409.                 STDERR.puts "#{self.class}:#{self.class}: backtrace follows..."
  410.                 prefix = ""
  411.                 $!.backtrace.each{|tline|
  412.                     STDERR.puts "#{self.class}:#{prefix}#{tline}"
  413.                 }
  414.                 count += 1
  415.                 if count > @server_list.length then
  416.                     count = 0
  417.                 end
  418.                 retry
  419.             end
  420.             @status = STATUS_DISCONNECTED
  421.         else
  422.             return nil
  423.         end
  424.     end
  425.  
  426.     #this method will return true if the specified nick is an operator.
  427.     def is_op?(chan, nick)
  428.         STDERR.puts "#{self.class}:#{self.class}: #{@current_network}: checking #{chan} for ops on #{nick}" if @@debug < 1
  429.         dchan = chan.downcase
  430.         if @known_channels.has_key?(dchan) then
  431.             STDERR.puts "#{self.class}:#{self.class}: #{@current_network}: channel exists" if @@debug < 1
  432.             return @known_channels[dchan].is_op?(nick)
  433.         end
  434.         return nil
  435.     end
  436.    
  437.     attr_reader(:writingnames, :known_channels, :nick)
  438.     attr_accessor(:info)
  439.     protected
  440.     def statusputs(val)
  441.         #puts "<statusputs@ExtendedIRCConnection> Triggered"
  442.         if (@statusbuffer.length <= @statusbuffersize) then
  443.             #puts "<statusputs@ExtendedIRCConnection> putting value #{val}"
  444.             @statusbuffer.push(val)
  445.             return nil
  446.         else
  447.             #puts "<statusputs@ExtendedIRCConnection> shifting and putting value #{val}"
  448.             tmp = @statusbuffer.shift
  449.             @statusbuffer.push(val)
  450.             return val
  451.         end
  452.     end
  453.    
  454.     private
  455.     def _info_parser(prefix, cmd, params)
  456.         #changed
  457.         #notify_observers(prefix, cmd, params, @current_network)
  458.         begin
  459.             case cmd
  460.                 when "PRIVMSG"
  461.                     STDERR.puts "#{self.class}:#{self.class}: PRIVMSG" if @@debug < 2001
  462.                     _event_privmsg(prefix, cmd, params)
  463.                 when "NICK"
  464.                     STDERR.puts "#{self.class}:NICK" if @@debug < 2001
  465.                     _event_nick(prefix, cmd, params)
  466.                 when "JOIN"
  467.                     STDERR.puts "#{self.class}:JOIN" if @@debug < 2001
  468.                     _event_join(prefix, cmd, params)
  469.                 when "PART"
  470.                     STDERR.puts "#{self.class}:PART" if @@debug < 2001
  471.                     _event_part(prefix, cmd, params)
  472.                 when "QUIT"
  473.                     STDERR.puts "#{self.class}:QUIT" if @@debug < 2001
  474.                     _event_quit(prefix, cmd, params)
  475.                 when "MODE"
  476.                     STDERR.puts "#{self.class}:MODE" if @@debug < 2001
  477.                     _event_mode(prefix, cmd, params)
  478.                 when "KICK"
  479.                     STDERR.puts "#{self.class}:KICK" if @@debug < 3001
  480.                     _event_kick(prefix, cmd, params)
  481.                 when RPL_NAMREPLY
  482.                     STDERR.puts "#{self.class}:RPL_NAMREPLY" if @@debug < 2001
  483.                     _event_rpl_namreply(prefix, cmd, params)
  484.                 when RPL_ENDOFNAMES
  485.                     STDERR.puts "#{self.class}:RPL_ENDOFNAMES" if @@debug < 2001
  486.                     _event_rpl_endofnames(prefix, cmd, params)
  487.                 when RPL_BOUNCE
  488.                     STDERR.puts "#{self.class}:RPL_BOUNCE" if @@debug < 2001
  489.                     _event_rpl_bounce(prefix, cmd, params)
  490.                 when RPL_NICKSERV_AUTHED
  491.                     STDERR.puts "#{self.class}:RPL_NICKSERV_AUTHED" if @@debug < 2001
  492.                     _event_rpl_nickserv_authed(prefix, cmd, params)
  493.                 when RPL_WHOISUSER
  494.                     STDERR.puts "#{self.class}:RPL_WHOISUSER" if @@debug < 2001
  495.                 when RPL_WHOISSERVER
  496.                     STDERR.puts "#{self.class}:RPL_WHOISSERVER" if @@debug < 2001
  497.                 when RPL_WHOISOPERATOR
  498.                     STDERR.puts "#{self.class}:RPL_WHOISOPERATOR" if @@debug < 2001
  499.                 when RPL_WHOISCHANNELS
  500.                     STDERR.puts "#{self.class}: RPL_WHOISCHANNELS" if @@debug < 2001
  501.                 when RPL_WHOISIDLE
  502.                     STDERR.puts "#{self.class}: RPL_WHOISIDLE" if @@debug < 2001
  503.                 when RPL_ENDOFWHOIS
  504.                     STDERR.puts "#{self.class}: RPL_ENDOFWHOIS" if @@debug < 2001
  505.             end
  506.         rescue
  507.             if @@debug < 4000 then
  508.                 STDERR.puts "#{self.class}: Error in #_info_parser: #{$!}"
  509.                 STDERR.puts "#{self.class}: Backtrace follows..."
  510.                 pre = ""
  511.                 $!.backtrace.each{|tr|
  512.                     puts "#{self.class}: #{pre}#{tr}"
  513.                     pre << " "
  514.                 }
  515.             end
  516.         end
  517.     end
  518.     def _event_rpl_whoisuser(prefix, cmd, params)
  519.        
  520.     end
  521.     def _event_privmsg(prefix, cmd, params)
  522.         prematch = /^\:(.*)/.match(prefix)
  523.         if prematch then
  524.             prefix = prematch[1]
  525.         end
  526.         @user_mgr.new_user(@current_network, prefix)
  527.         return true
  528.     end
  529.     #This method needs to be improved so it will only rejoin if the kick
  530.     #target is the bot's current nick/mask.
  531.     def _event_kick(prefix, cmd, params)
  532.         STDERR.puts "#{self.class}:#{self} event KICK triggered." if @@debug < 10000
  533.         pmatch = /^(.*)\:(.*)$/.match(params)
  534.         STDERR.puts "#{self.class}:#{self} kick pmatch[1]: #{pmatch[1]}" if @@debug < 10000
  535.         chan, nick = pmatch[1].strip.downcase.split(/\s/)
  536.         #dnick = nick.tr!("^ -~", "")
  537.         #dchan = chan.tr!("^ -~", "")
  538.         dnick = nick.strip
  539.         dchan = chan.strip
  540.         if @rejoin then
  541.             puts "#{self.class}: _event_kick: @rejoin is non-nil." if @@debug < 10000
  542.             cmd_join_chan(dchan) if @local_rejoins[dchan] == nil
  543.         else
  544.             puts "#{self.class}: _event_kick: @rejoin is nil." if @@debug < 10000
  545.             puts "#{self.class}: local rejoins for #{dchan} is '#{@local_rejoins[dchan]}'"
  546.             if @local_rejoins[dchan] != nil
  547.                 puts "#{self.class}: _event_kick: local join enabled. Joining channel #{dchan}." if @@debug < 10000
  548.                 cmd_join_chan(dchan)
  549.             end
  550.         end
  551.         begin
  552.             return @known_channels[dchan].del_user(dnick)
  553.         rescue
  554.             STDERR.puts "#{self.class}:#{self} Error removing user: #{$!}" if @@debug < 5
  555.             #raise "#{self.class}: _event_kick: #{$!}"
  556.             return nil
  557.         end
  558.     end
  559.     #Updates user or channel mode strings.
  560.     def _event_mode(prefix, cmd, params)
  561.         STDERR.puts "#{self.class}:#{self} event MODE triggered." if @@debug < 1
  562.         p_prefix = irc_parse_prefix(prefix)
  563.         prefix = /^\:?(.*)$/.match(prefix)[1]
  564.         STDERR.puts "#{self.class}:#{self} prefix trimmed to: #{prefix}" if @@debug < 1
  565.         if p_prefix then
  566.             begin
  567.                 user = nil
  568.                 type = irc_obj_type(prefix)
  569.                 p_params = nil
  570.                 nicklist = nil
  571.                 case type[0]
  572.                     when IRC_TYPE_NICK
  573.                         STDERR.puts "#{self.class}:#{self} parsing parameters as USER MODE message" if @@debug < 1
  574.                         p_params = irc_parse_user_mode_params(params)
  575.                     when IRC_TYPE_MASK
  576.                         STDERR.puts "#{self.class}:#{self} parsing parameters as CHANNEL MODE message" if @@debug < 1
  577.                         p_params = irc_parse_chan_mode_params(params)
  578.                         modes = p_params[1].strip
  579.                         list = p_params[2]
  580.                         chan = p_params[0].strip
  581.                         dchan = chan.downcase
  582.                         nicklist = irc_calc_chan_modes(list, modes)
  583.                         if nicklist then
  584.                             STDERR.puts "#{self.class}:#{self} nick list:" if @@debug < 1
  585.                             nicklist.each{|k, v|
  586.                                
  587.                                 STDERR.puts "#{self.class}:#{self} #{k}: #{v}" if @@debug < 1
  588.                                 @user_mgr.new_user(@current_network, prefix)
  589.                                 if k != nil then
  590.                                     t_user = @user_mgr.get_user(@current_network, k.strip)
  591.                                     if t_user != nil then
  592.                                         #user = t_user.strip
  593.                                         t_user.put_message(prefix, cmd, params, @current_network)
  594.                                         #user.mod_chan_flags(chan, v)
  595.                                         @known_channels[dchan].set_user_mode(k, v)
  596.                                         STDERR.puts "#{self.class}:#{self} user modified. New channel modes: #{@known_channels[dchan].get_user_modes(k)}" if @@debug < 1
  597.                                     end
  598.                                 end
  599.                             }
  600.                             return true
  601.                         else
  602.                             STDERR.puts "#{self.class}:#{self} unable to parse nick list" if @@debug < 1
  603.                             return nil
  604.                         end
  605.                     else
  606.                         STDERR.puts "#{self.class}:type: #{type[0]}" if @@debug < 1
  607.                 end
  608.                
  609.                 STDERR.puts "#{self.class}:params parsed." if @@debug < 1
  610.            
  611.                 if p_params then
  612.                     if type[0] == IRC_TYPE_NICK then
  613.                         STDERR.puts "#{self.class}:#{self} parsing user mode params for #{p_params[0]}" if @@debug < 1
  614.                     else
  615.                         STDERR.puts "#{self.class}:#{self} parsing channel mode params for #{p_params[0]}" if @@debug < 1
  616.                     end
  617.                 else
  618.                     STDERR.puts "#{self.class}:#{self} invalid parameters." if @@debug < 1
  619.                 end
  620.             rescue
  621.                 STDERR.puts "#{self.class}:poo: #{$!}" if @@debug < 5
  622.                 STDERR.puts "#{self.class}:#{self.class}: backtrace follows"
  623.                 pre = ""
  624.                 $!.backtrace.each{|tr|
  625.                     STDERR.puts "#{self.class}:#{pre}#{tr}"
  626.                     pre << " "
  627.                 }
  628.                 return nil
  629.             end
  630.         else
  631.             STDERR.puts "#{self.class}:#{self} invalid prefix." if @@debug < 1
  632.         end
  633.     end
  634.     def _event_nick(prefix, cmd, params)
  635.         STDERR.puts "#{self.class}:#{self} event NICK triggered." if @@debug < 1
  636.         p_prefix = irc_parse_prefix(prefix)
  637.         newnick = /^\:?(.*)$/.match(params.strip)[1]
  638.         STDERR.puts "#{self.class}:#{self} #{p_prefix[0]}'s nick is now #{newnick}" if @@debug < 1
  639.         if /#{newnick}/i.match(@nick) then
  640.             STDERR.puts "#{self.class}:nick is own nick" if @@debug < 1
  641.             @nick = newnick
  642.         end
  643.         STDERR.puts "#{self.class}:#{self.class}: getting/creating new user" if @@debug < 1
  644.         begin
  645.             @user_mgr.new_user(@current_network, prefix)
  646.             @user_mgr.get_user(@current_network, p_prefix[0]).put_message(prefix, cmd, params, @current_network)
  647.             #@user_mgr.get_user!(@current_network, p_prefix[0]).put_message(prefix, cmd, params, @current_network)
  648.         rescue
  649.             STDERR.puts "#{self.class}:#{self.class}: ERROR IN NICK CHANGE: #{$!}: backtrace follows"
  650.             pre = ""
  651.             $!.backtrace.each{|tr|
  652.                 STDERR.puts "#{self.class}:#{pre}#{tr}"
  653.             }
  654.         end
  655.         STDERR.puts "#{self.class}:#{self.class}: new user got/created" if @@debug < 1
  656.         #@user_mgr.deactivate_user(@current_network, p_prefix[0])
  657.         #puts "#{self} old nick deactivated."
  658.         #newuser = @user_mgr.get_user!(@current_network, newnick)
  659.         #newuser.put_message(prefix, cmd, params, @current_network)
  660.         #puts "#{self} new user entry set."
  661.         #@user_mgr.activate_user(@current_network, newnick)
  662.         #puts "#{self} entry activated."
  663.         @user_mgr.get_user(@current_network, p_prefix[0]).name = newnick
  664.         STDERR.puts "#{self.class}:#{self.class}: user entry changed to #{newnick}" if @@debug < 1
  665.         @known_channels.each{|key, chan|
  666.             STDERR.puts "#{self.class}:#{self} examining channel #{chan.name}" if @@debug < 1
  667.             chan.nick_change(p_prefix[0], newnick)
  668.         }
  669.     end
  670.     def _event_join(prefix, cmd, params)
  671.         STDERR.puts "#{self.class}:#{self} _event_join triggered"
  672.         p_prefix = irc_parse_prefix(prefix)
  673.         if p_prefix then
  674.             if p_prefix.length > 1 then
  675.                 begin
  676.                     param_match = /^\:?(\S*)/.match(params.strip)[1]
  677.                     STDERR.puts "#{self.class}:#{self} params matched" if @@debug < 2
  678.                 rescue
  679.                     STDERR.puts "#{self.class}:#{self} invalid parameter" if @@debug < 2
  680.                     return nil
  681.                 end
  682.                 nick = p_prefix[0]
  683.                 STDERR.puts "#{self.class}:#{self} nick detected." if @@debug < 2
  684.                 chan = param_match
  685.                 STDERR.puts "#{self.class}:#{self} chan detected: #{chan}!" if @@debug < 2
  686.                 dchan = chan.downcase.strip
  687.                 dchan.tr!("^ -~", "")
  688.                 @user_mgr.new_user(@current_network, prefix)
  689.                 a = @user_mgr.get_user(@current_network, nick)
  690.                 a.put_message(prefix, cmd, params, @current_network)
  691.                 STDERR.puts "#{self.class}:#{self} user got from manager." if @@debug < 2
  692.                 STDERR.puts "#{self.class}:#{self} event_join: user #{p_prefix[0]} is joining channel #{chan} with entry name: #{dchan}!" if @@debug < 2
  693.                 if !@known_channels.has_key?(dchan) then
  694.                     STDERR.puts "#{self.class}:#{self} Creating record for channel #{dchan}" if @@debug < 2
  695.                     @known_channels[dchan] = IRCChannel.new(chan)
  696.                 else
  697.                     @known_channels[dchan].join
  698.                 end
  699.                 @known_channels[dchan].add_user(nick)
  700.                 if @@debug < 2 then
  701.                     STDERR.puts "#{self.class}:#{self} new channel list:"
  702.                     @known_channels.each{|k, v|
  703.                         puts v.name
  704.                         if v.users.length > 0 then
  705.                             STDERR.puts "#{self.class}: user list for #{v.name}"
  706.                             v.users.each{|e|
  707.                                 STDERR.puts "#{self.class}: #{e}"
  708.                             }
  709.                         end
  710.                     }
  711.                 end
  712.             else
  713.                 STDERR.puts "#{self.class}:#{self} invalid prefix type in _event_join" if @@debug < 2
  714.                 return nil
  715.             end
  716.         else
  717.             return nil
  718.         end
  719.     end
  720.     def _event_part(prefix, cmd, params)
  721.         parsed_prefix = irc_parse_prefix(prefix)
  722.         if parsed_prefix then
  723.             if parsed_prefix.length > 1 then
  724.                 if /\:/.match(params.strip) then
  725.                     chan, trailing = /^([^\:]*)\:(.*)$/.match(params.strip)[1..2]
  726.                 else
  727.                     chan = params.strip
  728.                 end
  729.                 if chan then
  730.                     dchan = chan.downcase.strip
  731.                     dchan.tr!("^ -~", "")
  732.                     nick = parsed_prefix[0]
  733.                     dnick = nick.downcase.strip
  734.                     dnick.tr!("^ -~", "")
  735.                     STDERR.puts "#{self.class}:#{self} user #{parsed_prefix[0]} parting from channel #{chan}" if @@debug < 2
  736.                     begin
  737.                         if !@known_channels.has_key?(dchan) then
  738.                             STDERR.puts "#{self.class}:#{self} Creating record for channel #{chan}" if @@debug < 2
  739.                             @known_channels[dchan] = IRCChannel.new(chan)
  740.                         end
  741.                     rescue
  742.                         STDERR.puts "#{self.class}:#{self} oops: #{$!}" if @@debug < 5
  743.                     end
  744.                     STDERR.puts "#{self.class}:#{self} removing user #{parsed_prefix[0]} from channel list #{dchan}" if @@debug < 2
  745.                     STDERR.puts "#{self.class}:#{self.class}: object class is: #{parsed_prefix[0].class}" if @@debug < 2
  746.                     begin
  747.                         @known_channels[dchan].del_user(parsed_prefix[0].to_s)
  748.                     rescue
  749.                         STDERR.puts "#{self.class}:#{self} Error removing user: #{$!}" if @@debug < 5
  750.                         raise "#{self.class}: _event_part: #{$!}"
  751.                     end
  752.                     if @@debug < 2 then
  753.                         STDERR.puts "#{self.class}:#{self} User removed. New channel list:"
  754.                         STDERR.puts "#{self.class}:#{self} new channel list:"
  755.                         @known_channels.each{|k, v|
  756.                             puts v.name
  757.                             if v.users.length > 0 then
  758.                                 STDERR.puts "#{self.class}: user list for #{v.name}"
  759.                                 v.users.each{|e|
  760.                                     STDERR.puts "#{self.class}: #{e}"
  761.                                 }
  762.                             end
  763.                         }
  764.                     end
  765.                     @user_mgr.new_user(@current_network, prefix)
  766.                     a = @user_mgr.get_user(@current_network, parsed_prefix[0])
  767.                     #puts "#{self} removing channel entry from IRCUser object"
  768.                     #@user_mgr.get_user!(@current_network, parsed_prefix[0]).del_chan(dchan)
  769.                     #puts "#{self} entry removed!"
  770.                 else
  771.                     STDERR.puts "#{self.class}:#{self} mangled params for part message!" if @@debug < 2
  772.                     return nil
  773.                 end
  774.             else
  775.                 return nil
  776.             end
  777.         else
  778.             return nil
  779.         end
  780.     end
  781.     def _event_quit(prefix, cmd, params)
  782.         parsed_prefix = irc_parse_prefix(prefix)
  783.         if parsed_prefix then
  784.             if parsed_prefix.length > 1 then
  785.                 parsed_params = /^\:?(.*)$/.match(params.strip)
  786.                 if parsed_params then
  787.                     nick = parsed_prefix[0]
  788.                     @known_channels.each{|k, v|
  789.                         v.del_user(nick)
  790.                     }
  791.                     STDERR.puts "#{self.class}:#{self} user #{nick} quit (#{parsed_params})" if @@debug < 2
  792.                 else
  793.                     STDERR.puts "#{self.class}:#{self} mangled params for quit message!" if @@debug < 2
  794.                     return nil
  795.                 end
  796.             else
  797.                 return nil
  798.             end
  799.         else
  800.             return nil
  801.         end
  802.     end
  803.     def _event_rpl_namreply(prefix, cmd, params)
  804.         begin
  805.             STDERR.puts "#{self.class}:#{self} event namreply..." if @@debug < 1
  806.             parsed_params = irc_parse_namreply_params(params)
  807.             if parsed_params.class == Array then
  808.                 chan = parsed_params[1].strip
  809.                 dchan = chan.downcase
  810.                 if !@writingnames.include?(dchan) then
  811.                     STDERR.puts "#{self.class}:#{self} new name list. Deleting old data." if @@debug < 1
  812.                     @known_channels[dchan].clear_users
  813.                     @writingnames.push dchan
  814.                 end
  815.                
  816.                
  817.                
  818.                 STDERR.puts "#{self.class}:#{self.class} scanning newly-recieved users list." if @@debug < 1
  819.                 parsed_params[2].each{|raw_name|
  820.                     begin
  821.                         user_prefixes = ""
  822.                         name = raw_name
  823.                         STDERR.puts "#{self.class}:#{self} matching first character: #{raw_name[0,1]}" if @@debug < 1
  824.                         @prefixes[0].each_byte{|bt|
  825.                             STDERR.puts "#{self.class}:#{self} matching against #{bt.chr}" if @@debug < 1
  826.                             if raw_name[0,1] == bt.chr then
  827.                                 STDERR.puts "#{self.class}:match!" if @@debug < 1
  828.                                 name = raw_name[1..raw_name.length]
  829.                                 user_prefixes << raw_name[0,1]
  830.                             end
  831.                         }
  832.                         user_modes = ""
  833.                         user_prefixes.split('').each{|el|
  834.                             STDERR.puts "#{self.class}:#{self} converting prefix #{el}" if @@debug < 1
  835.                             @prefixes[0].split('').each_index{|idx|
  836.                                 STDERR.puts "#{self.class}:#{self} is it #{@prefixes[0][idx].chr}?" if @@debug < 1
  837.                                 if el == @prefixes[0][idx].chr then
  838.                                     user_modes << @prefixes[1][idx].chr
  839.                                     STDERR.puts "#{self.class}:yes!" if @@debug < 1
  840.                                     STDERR.puts "#{self.class}:adding prefix: #{@prefixes[1][idx].chr}" if @@debug < 1
  841.                                 else
  842.                                     STDERR.puts "#{self.class}:no!" if @@debug < 1
  843.                                 end
  844.                             }
  845.                         }
  846.                        
  847.                         STDERR.puts "#{self.class}:#{self} getting/creating user #{name}" if @@debug < 1
  848.                         a_user = @user_mgr.get_user!(@current_network, name)
  849.                        
  850.                         #a_user.mod_chan_flags(chan, "+#{user_prefixes}") if user_prefixes != ""
  851.                         STDERR.puts "#{self.class}:#{self} adding name to session list" if @@debug < 1
  852.                         @known_channels[dchan].add_user(name)
  853.                         STDERR.puts "#{self.class}:#{self} applying modestring if needed. user_prefixes: #{user_prefixes}, user_modes: #{user_modes}" if @@debug < 1
  854.                         @known_channels[dchan].set_user_mode!(name, "+#{user_modes}")
  855.                     rescue
  856.                         STDERR.puts "#{self.class}:#{self} oh crap: #{$!}" if @@debug < 1
  857.                         raise $!
  858.                     end
  859.                 }
  860.             end
  861.         rescue
  862.             raise "#{self.class}: _event_rpl_namreply: #{$!}"
  863.         end
  864.     end
  865.     def _event_rpl_endofnames(prefix, cmd, params)
  866.         STDERR.puts "#{self.class}:#{self} event rpl_endofnames triggered." if @@debug < 1
  867.         parsed_params = irc_parse_twoarg_params(params)
  868.         STDERR.puts "#{self.class}:#{self} params preprocessed." if @@debug < 1
  869.         nick, chan = parsed_params[0], parsed_params[1]
  870.         STDERR.puts "#{self.class}:#{self} nick and chan assigned." if @@debug < 1
  871.         STDERR.puts "#{self.class}:#{self} nick value: #{nick}" if @@debug < 1
  872.         STDERR.puts "#{self.class}:#{self} chan value: #{chan}" if @@debug < 1
  873.         @writingnames.delete_if{|el| el == chan.downcase}
  874.         STDERR.puts "#{self.class}:#{self} channel #{chan} is no longer writing names." if @@debug < 1
  875.     end
  876.     def _event_rpl_bounce(prefix, cmd, params)
  877.         STDERR.puts "#{self.class}:#{self} _event_rpl_bounce: params:" if @@debug < 1
  878.         puts params
  879.         p_match1 = /^(\S*)\s(.*)(\:.*$)?/.match(params.strip)
  880.         if p_match1 then
  881.             if @@debug < 1
  882.                 STDERR.puts "#{self.class}:RPL_BOUNCE has extended info. Initial results:"
  883.                 STDERR.puts "#{self.class}:user: #{p_match1[1]}"
  884.                 STDERR.puts "#{self.class}:msg: #{p_match1[2]}"
  885.                 STDERR.puts "#{self.class}:end: #{p_match1[3]}" if p_match1[3]
  886.             end
  887.             p_match2 = p_match1[2].split(' ')
  888.             p_match_hsh = {}
  889.             p_match2.each{|el|
  890.                 k, v = el.split('=')
  891.                 p_match_hsh[k] = v
  892.             }
  893.             if @@debug < 1
  894.                 STDERR.puts "#{self.class}:RPL_BOUNCE filtered results:"
  895.                 p_match_hsh.each{|k, v|
  896.                     STDERR.puts "#{self.class}:#{k}: #{v}"
  897.                 }
  898.             end
  899.             if p_match_hsh.has_key?("PREFIX") then
  900.                 v = p_match_hsh["PREFIX"]
  901.                 prefix_match = /^\((\S)\)(\S)$/.match(v.strip)
  902.                 @prefixes = [prefix_match[1], prefix_match[2]] if prefix_match
  903.                 STDERR.puts "#{self.class}:#{self} changed prefix values." if @@debug < 1
  904.                 STDERR.puts "#{self.class}:chars: #{@prefixes[0]}, modes: #{@prefixes[1]}" if @@debug < 1
  905.             end
  906.         else
  907.             STDERR.puts "#{self.class}:#{self} This may be an rfc2812 RPL_BOUNCE. Write a fallback to cope here..." if @@debug < 5
  908.         end
  909.     end
  910.     def _event_rpl_nickserv_authed(prefix, cmd, params)
  911.         p_params = /^(\S)\s(\S)/.match(params.strip)
  912.         begin
  913.             @irc_mgr.get_user(p_params[2]).set_auth
  914.         rescue
  915.             STDERR.puts "#{self.class}:#{self} _event_rpl_nickserv_authed: #{$!}" if @@debug < 5
  916.         end
  917.     end
  918.    
  919.     def _save_channels
  920.         @known_channels.each{|k, v|
  921.         }
  922.     end
  923. end
  924. #(self.methods - Object.methods).each{|el|
  925. #   puts el
  926. #}
  927.  
  928.  
  929.  
  930. def login_test
  931.     doc = nil
  932.     File.open("bot_conf.xml", "r"){|fo|
  933.         STDERR.puts "#{self.class}:file open."
  934.         doc = REXML::Document.new(fo)
  935.         STDERR.puts "#{self.class}:document loaded."
  936.         puts doc.elements["*/networks/*"]
  937.     }
  938.     #umgr = IRCUserManager.instance
  939.     #umgr.start("test")
  940.     begin
  941.         a = IRCSession.new("Espernet", doc)
  942.         sleep 10
  943.         a.cmd_join_chan("#crystalbot")
  944.         sleep 1.0
  945.         a.cmd_privmsg("#crystalbot", "IRCSession object seems to be working.")
  946.         sleep 3.0
  947.         a.cmd_quit("test complete.")
  948.         sleep 1.0
  949.     rescue
  950.         STDERR.puts "#{self.class}:the shit hit the fan here: #{$!}"
  951.     end
  952. end
  953. def xmltest
  954.     doc = nil
  955.     File.open("irc_conf.xml", "r"){|fo|
  956.         STDERR.puts "#{self.class}:file open."
  957.         doc = REXML::Document.new(fo)
  958.         STDERR.puts "#{self.class}:document loaded."
  959.         puts doc
  960.         STDERR.puts "#{self.class}:filtered results:"
  961.         puts doc.elements["*/networks/*"]
  962.     }
  963.     return doc
  964. end
  965. def standalone_session
  966.     standalone = 1
  967.     if standalone > 0 then
  968.         #@a = IRCSession.new("192.168.0.1",6670,"RubyBot","RubyBot","RubyBot",nil, "lol")
  969.         @a = IRCSession.new("EsperNet", xmltest)
  970.         @t = Thread.new{
  971.             tstr = Time.now.strftime("%Y%m%d%H%M%S")
  972.             @fileobj = File.open("#{self.class}#{tstr}.txt", "w+"){|fobj|
  973.                 while true == true
  974.                     tmp = @a.cmd_get_status
  975.                     print "#{tmp.strip}\n" if tmp
  976.                     fobj.print "#{tmp.strip}\n" if tmp
  977.                     fobj.flush if fobj
  978.                 end
  979.                 STDERR.puts "#{self.class}:<@t-thread> Out of main loop."
  980.             }
  981.         }
  982.         STDERR.puts "#{self.class}:Bot awake. Joining channels."
  983.         @a.cmd_join_chan("#crystalbot")
  984.        
  985.         @a.cmd_join_chan("#crystalbot2")
  986.        
  987.         @a.cmd_join_chan("#crystalbot3")
  988.        
  989.         @a.cmd_privmsg("#crystalbot", "Hello, World.")
  990.         STDERR.puts "#{self.class}:Sent privmsg"
  991.        
  992.         @t.join
  993.         while true == true
  994.         end
  995.     end
  996. end
  997. #standalone_session
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement