# Hack to manage reads on dAmn sockets in the select() loop class DamnSocket < TCPSocket; end module Potato module DAmn # Represents a connection to the dAmn server. class Client include Events # This instance's socket connection to the dAmn server. # @return [DamnSocket] attr_reader :server # An associative privclass level list. # @return [Hash] attr_reader :privclasses # Instance variable hack to prevent unwanted NAMES listing to the IRC client # @return [Boolean] attr_accessor :whoising # @param [IRC::Client] user a reference to the irc client object that owns this dAmn client def initialize user @user = user @privclasses = {} @whoising = false end # Handshake and login. # @param [String] user username to login with # @param [String] token authtoken to login with # @see DAmn::Token # @return [void] def connect_with user, token send_packet "dAmnClient", "0.3", :agent => "potato 0.1" send_packet "login", user, :pk => token end # Attempt to retrieve user information. # @param [String] user user to investigate # @return [void] def whois user send_packet "get", "login:#{user}", :p => "info" end # Attempt to join a room. # @param [String] room room to join # @return [void] def join room send_packet "join", "chat:#{room.sub("#", "")}" end # Attempt to part a room. # @param [String] room room to part # @return [void] def part room send_packet "part", "chat:#{room.sub("#", "")}" end # Attempt to say something in a room. # @param [String] room room to speak in # @param [String] line line to speak # @return [void] def say room, line send_packet "send", "chat:#{room.sub("#", "")}", :body => packet("msg", "main", :body => line) end # Attempt to say an action in a room. # @param [String] room room to action in # @param [String] line line to say # @return [void] def action room, line send_packet "send", "chat:#{room.sub("#", "")}", :body => packet("action", "main", :body => line) end # Attempt to set the topic in a room. # @param [String] room the room to set the topic of # @param [String] topic the topic to set # @return [void] def topic room, topic send_packet "set", "chat:#{room}", :p => "topic", :body => topic end # Disconnect (attempt gracefully) from the server. # @return [void] def quit send_packet "disconnect" @server.close end # Compose a dAmn packet. # @param [String] pktname the packet command ("login", "join", etc.) # @param [String] pktparam the packet parameter (usually a username or chatroom) # @param [Hash] opts a key-value store of packet arguments # @return [String] def packet pktname, pktparam = nil, opts = {} str = "" str << pktname.to_s if pktparam str << " #{pktparam.to_s}" end opts.each{|k,v| next if k == :body str << "\n#{k}=#{v}" } if opts[:body] str << "\n\n" str << opts.delete(:body).to_s end str << "\n" unless pktname == "send" str end # Write out a packet to the server. # @example Writes "login incluye\npk=my authtoken\n\0" # send_packet "login", "incluye", # :pk => "my authtoken" # @example Writes "send chat:Botdom\n\nmsg main\n\nHello world!\n\0" # send_packet "send", "chat:Botdom", # :body => packet("msg", "main", # :body => "Hello world!") # @see Client#packet # @return [String] def send_packet pktname, pktparam = nil, opts = {} @server ||= DamnSocket.new "chat.deviantart.com", 3900 str = packet(pktname, pktparam, opts) debug str @server.write(str + "\0") str end # Debug one or more messages. # @param [*String] strs any number of messages to print def debug *strs Server.debug *[strs, :damn_out] end end end end