Package org.schwering.irc.lib

Source Code of org.schwering.irc.lib.IRCConnection

/*
* IRClib -- A Java Internet Relay Chat library -- class IRCConnection
* Copyright (C) 2002 - 2006 Christoph Schwering <schwering@gmail.com>
*
* This library and the accompanying materials are made available under the
* terms of the
*   - GNU Lesser General Public License,
*   - Apache License, Version 2.0 and
*   - Eclipse Public License v1.0.
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY.
*/

package org.schwering.irc.lib;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;

/**
* Creates a new connection to an IRC server. It's the main class of the
* IRClib, the point everything starts.
* <p>
* The following sample code tries to establish an IRC connection to an
* IRC server:
* <p>
* <hr /><pre>
* /&#42;
*  &#42; The following code of a class which imports org.schwering.irc.lib.*
*  &#42; prepares an IRC connection and then tries to establish the connection.
*  &#42; The server is "irc.somenetwork.com", the default portrange (6667 and
*  &#42; 6669) is set, no password is used (null). The nickname is "Foo" and
*  &#42; the realname is "Mr. Foobar". The username "foobar".
*  &#42; Because of setDaemon(true), the JVM exits even if this thread is
*  &#42; running.
*  &#42; An instance of the class MyListener which must implement
*  &#42; IRCActionListener is added as only event-listener for the connection.
*  &#42; The connection is told to parse out mIRC color codes and to enable
*  &#42; automatic PING? PONG! replies.
*  &#42;/
* IRCConnection conn = new IRCConnection(
*                            "irc.somenetwork.com",
*                            6667,
*                            6669,
*                            null,
*                            "Foo",
*                            "Mr. Foobar",
*                            "foo@bar.com"
*                          );
*
* conn.addIRCEventListener(new MyListener());
* conn.setDaemon(true);
* conn.setColors(false);
* conn.setPong(true);
*
* try {
*   conn.connect(); // Try to connect!!! Don't forget this!!!
* } catch (IOException ioexc) {
*   ioexc.printStackTrace();
* }
* </pre><hr />
* <p>
* The serverpassword isn't needed in most cases. You can give
* <code>null</code> or <code>""</code> instead as done in this example.
* @author Christoph Schwering &lt;schwering@gmail.com&gt;
* @version 3.05
* @see IRCEventListener
* @see IRCParser
* @see IRCUtil
* @see SSLIRCConnection
*/
public class IRCConnection extends Thread {
 
  /**
   * This <code>Socket</code> is a connection to the IRC server.
   */
  private Socket socket;
 
  /**
   * This is like a UNIX-runlevel. Its value indicates the level of the
   * <code>IRCConnection</code> object. <code>0</code> means that the object
   * has not yet been connected, <code>1</code> means that it's connected but
   * not registered, <code>2</code> means that it's connected and registered
   * but still waiting to receive the nickname the first time, <code>3</code>
   * means that it's connected and registered, and <code>-1</code> means that
   * it was connected but is disconnected.
   * Therefore the defaultvalue is <code>0</code>.
   */
  protected byte level = 0;
 
  /**
   * The host of the IRC server.
   */
  protected String host;
 
  /**
   * The <code>int[]</code> contains all ports to which we are going to try to
   * connect. This can be a portrange from port 6667 to 6669, for example.
   */
  protected int[] ports;
 
  /**
   * The <code>BufferedReader</code> receives Strings from the IRC server.
   */
  private volatile BufferedReader in;
 
  /**
   * The <code>PrintWriter</code> sends Strings to the IRC server.
   */
  private PrintWriter out;
 
  /**
   * The <code>String</code> contains the name of the character encoding used
   * to talk to the server. This can be ISO-8859-1 or UTF-8 for example. The
   * default is ISO-8859-1.
   */
  protected String encoding = "ISO-8859-1";
 
  /**
   * This array contains <code>IRCEventListener</code> objects.
   */
  private IRCEventListener[] listeners = new IRCEventListener[0];
 
  /**
   * This <code>int</code> is the connection's timeout in milliseconds. It's
   * used in the <code>Socket.setSoTimeout</code> method. The default is
   * <code>1000 * 60 * 15</code> millis which are 15 minutes.
   */
  private int timeout = 1000 * 60 * 15;
 
  /**
   * This <code>boolean</code> stands for enabled (<code>true</code>) or
   * disabled (<code>false</code>) ColorCodes.<br />Default is enabled
   * (<code>false</code>).
   */
  private boolean colorsEnabled = false;
 
  /**
   * This <code>boolean</code> stands for enabled or disabled automatic PING?
   * PONG! support. <br />It means, that if the server asks with PING for the
   * ping, the PONG is automatically sent. Default is automatic PONG enabled
   * (<code>true</code>).
   */
  private boolean pongAutomatic = true;
 
  /**
   * The password, which is needed to get access to the IRC server.
   */
  private String pass;
 
  /**
   * The user's nickname, which is indispensably to connect.
   */
  private String nick;
 
  /**
   * The user's realname, which is indispensably to connect.
   */
  private String realname;
 
  /**
   * The user's username, which is indispensable to connect.
   */
  private String username;
 
// ------------------------------
 
  /**
   * Creates a new IRC connection. <br />
   * The difference to the other constructor is, that it transmits the ports in
   * an <code>int[]</code>. Thus, also ports like 1024, 2048, 6667 and
   * 6669 can be selected.<br /><br />
   * The constructor prepares a new IRC connection which can be really started
   * by invoking the <code>connect</code> method. Before invoking it, you should
   * set the <code>IRCEventListener</code> and other settings.<br />
   * Note that you do not need to set a password to connect to the large public
   * IRC networks like QuakeNet, EFNet etc. To use no password in your IRC
   * connection, use <code>""</code> or <code>null</code> for the password
   * argument in the constructor.
   * @param host The hostname of the server we want to connect to.
   * @param ports The portrange to which we want to connect.
   * @param pass The password of the IRC server. If your server isn't
   *             secured by a password (that's normal), use
   *             <code>null</code> or <code>""</code>.
   * @param nick The nickname for the connection. Is used to register the
   *             connection.
   * @param username The username. Is used to register the connection.
   * @param realname The realname. Is used to register the connection.
   * @throws IllegalArgumentException If the <code>host</code> or
   *                                  <code>ports</code> is <code>null</code> or
   *                                  <code>ports</code>' length is
   *                                  <code>0</code>.
   * @see #connect()
   */
  public IRCConnection(String host, int[] ports, String pass, String nick,
      String username, String realname) {
    if (host == null || ports == null || ports.length == 0)
      throw new IllegalArgumentException("Host and ports may not be null.");
    this.host = host;
    this.ports = ports;
    this.pass = (pass != null && pass.length() == 0) ? null : pass;
    this.nick = nick;
    this.username = username;
    this.realname = realname;
  }
 
// ------------------------------
 
  /**
   * Creates a new IRC connection. <br />
   * The difference to the other constructor is, that it transmits the ports as
   * two <code>int</code>s. Thus, only a portrange from port <code>x</code> to
   * port <code>y</code> like from port 6667 to 6669 can be selected.<br />
   * <br />
   * The constructor prepares a new IRC connection which can be really started
   * by invoking the <code>connect</code> method. Before invoking it, you should
   * set the <code>IRCEventListener</code> and other settings.<br />
   * Note that you do not need to set a password to connect to the large public
   * IRC networks like QuakeNet, EFNet etc. To use no password in your IRC
   * connection, use <code>""</code> or <code>null</code> for the password
   * argument in the constructor.
   * @param host The hostname of the server we want to connect to.
   * @param portMin The beginning of the port range we are going to connect
   *                to.
   * @param portMax The ending of the port range we are going to connect to.
   * @param pass The password of the IRC server. If your server isn't
   *             secured by a password (that's normal), use
   *             <code>null</code> or <code>""</code>.
   * @param nick The nickname for the connection. Is used to register the
   *             connection.
   * @param username The username. Is used to register the connection.
   * @param realname The realname. Is used to register the connection.
   * @throws IllegalArgumentException If the <code>host</code> is
   *                                  <code>null</code>.
   * @see #connect()
   */
  public IRCConnection(String host, int portMin, int portMax, String pass,
      String nick, String username, String realname) {
    this(host, portRangeToArray(portMin, portMax), pass, nick, username,
        realname);
  }
 
// ------------------------------
 
  /**
   * Converts a portrange which starts with a given <code>int</code> and ends
   * with a given <code>int</code> into an array which contains all
   * <code>int</code>s from the beginning to the ending (including beginning
   * and ending).<br />
   * If <code>portMin > portMax</code>, the portrange is turned arount
   * automatically.
   * @param portMin The beginning port of the portrange.
   * @param portMax The ending port of the portrange.
   */
  private static int[] portRangeToArray(int portMin, int portMax) {
    if (portMin > portMax) {
      int tmp = portMin;
      portMin = portMax;
      portMax = tmp;
    }
    int[] ports = new int[portMax - portMin + 1];
    for (int i = 0; i < ports.length; i++)
      ports[i] = portMin + i;
    return ports;
  }
 
// ------------------------------
 
  /**
   * Establish a connection to the server. <br />
   * This method must be invoked to start a connection; the constructor doesn't
   * do that!<br />
   * It tries all set ports until one is open. If all ports fail it throws an
   * <code>IOException</code>.<br />
   * You can invoke <code>connect</code> only one time.
   * @throws IOException If an I/O error occurs.
   * @throws SocketException If the <code>connect</code> method was already
   *                         invoked.
   * @see #isConnected()
   * @see #doQuit()
   * @see #doQuit(String)
   * @see #close()
   */
  public void connect() throws IOException {
    if (level != 0) // otherwise disconnected or connect
      throw new SocketException("Socket closed or already open ("+ level +")");
    IOException exception = null;
    Socket s = null;
    for (int i = 0; i < ports.length && s == null; i++) {
      try {
        s = new Socket(host, ports[i]);
        exception = null;
      } catch (IOException exc) {
        if (s != null)
          s.close();
        s = null;
        exception = exc;
      }
    }
    if (exception != null)
      throw exception; // connection wasn't successful at any port
   
    prepare(s);
  }
 
// ------------------------------
 
  /**
   * Invoked by the <code>connect</code> method, this method prepares the
   * connection. <br />
   * It initializes the class-vars for the inputstream and the outputstream of
   * the socket, starts the registration of at the IRC server by calling
   * <code>register()</code> and starts the receiving of lines from the server
   * by starting the thread with the <code>start</code> method.<br /><br />
   * This method must be protected, because it is used by extending classes,
   * which override the <code>connect</code> method.
   * @param s The socket which is used for the connection.
   * @throws IOException If an I/O error occurs.
   * @see #connect()
   * @see #run()
   */
  protected void prepare(Socket s) throws IOException {
    if (s == null)
      throw new SocketException("Socket s is null, not connected");
    socket = s;
    level = 1;
    s.setSoTimeout(timeout);
    in  = new BufferedReader(new InputStreamReader(s.getInputStream(),
        encoding));
    out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),
        encoding));
    start();
    register();
  }
 
// ------------------------------
 
  /**
   * Registers the connection with the IRC server. <br />
   * In fact, it sends a password (if set, else nothing), the nickname and the
   * user, the realname and the host which we're connecting to.<br />
   * The action synchronizes <code>code> so that no important messages
   * (like the first PING) come in before this registration is finished.<br />
   * The <code>USER</code> command's format is:<br /><code>
   * &lt;username&gt; &lt;localhost&gt; &lt;irchost&gt; &lt;realname&gt;
   * </code>
   */
  private void register() {
    if (pass != null)
      send("PASS "+ pass);
    send("NICK "+ nick);
    send("USER "+ username +" "+ socket.getLocalAddress() +" "+ host
        +" :"+ realname);
  }
 
// ------------------------------
 
  /**
   * The <code>Thread</code> is started by the <code>connect</code> method.
   * It's task is to receive strings from the IRC server and hand them over
   * to the <code>get</code> method.
   */
  public void run() {
    try {
      String line;
      while (!isInterrupted()) {
        line = in.readLine();
        if (line != null)
          get(line);
        else
          close();
      }
    } catch (IOException exc) {
      close();
    }
  }
 
// ------------------------------
 
  /**
   * Sends a String to the server.
   * You should use this method only, if you must do it. For most purposes,
   * there are <code>do*</code> methods (like <code>doJoin</code>). A carriage
   * return line feed (<code>\r\n</code>) is appended automatically.
   * @param line The line which should be send to the server without the
   *             trailing carriage return line feed (<code>\r\n</code>).
   */
  public void send(String line) {
    try {
      out.write(line +"\r\n");
      out.flush();
      if (level == 1) { // not registered
        IRCParser p = new IRCParser(line);
        if (p.getCommand().equalsIgnoreCase("NICK"))
          nick = p.getParameter(1).trim();
      }
    } catch (Exception exc) {
      exc.printStackTrace();
    }
  }
 
// ------------------------------
 
  /**
   * Just parses a String given as the only argument with the help of the
   * <code>IRCParser</code> class. Then it controls the command and fires events
   * through the <code>IRCEventListener</code>.<br />
   * @param line The line which is sent from the server.
   */
  private synchronized void get(String line) {
    IRCParser p;
    try {
      p = new IRCParser(line, colorsEnabled);
    } catch (Exception exc) {
      return;
    }
    String command = p.getCommand();
    int reply; // 3-digit reply will be parsed in the later if-condition
   
    if (command.equalsIgnoreCase("PRIVMSG")) { // MESSAGE
     
      IRCUser user = p.getUser();
      String middle = p.getMiddle();
      String trailing = p.getTrailing();
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onPrivmsg(middle, user, trailing);
     
    } else if (command.equalsIgnoreCase("MODE")) { // MODE
     
      String chan = p.getParameter(1);
      if (IRCUtil.isChan(chan)) {
        IRCUser user = p.getUser();
        String param2 = p.getParameter(2);
        String paramsFrom3 = p.getParametersFrom(3);
        for (int i = listeners.length - 1; i >= 0; i--)
          listeners[i].onMode(chan, user,
              new IRCModeParser(param2, paramsFrom3));
      } else {
        IRCUser user = p.getUser();
        String paramsFrom2 = p.getParametersFrom(2);
        for (int i = listeners.length - 1; i >= 0; i--)
          listeners[i].onMode(user, chan, paramsFrom2);
      }
     
    } else if (command.equalsIgnoreCase("PING")) { // PING
     
      String ping = p.getTrailing(); // no int cause sometimes it's text
      if (pongAutomatic)
        doPong(ping);
      else
        for (int i = listeners.length - 1; i >= 0; i--)
          listeners[i].onPing(ping);
     
      if (level == 1) { // not registered
        level = 2; // first PING received -> connection
        for (int i = listeners.length - 1; i >= 0; i--)
          listeners[i].onRegistered();
      }
     
    } else if (command.equalsIgnoreCase("JOIN")) { // JOIN
     
      IRCUser user = p.getUser();
      String trailing = p.getTrailing();
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onJoin(trailing, user);
     
    } else if (command.equalsIgnoreCase("NICK")) { // NICK
     
      IRCUser user = p.getUser();
      String changingNick = p.getNick();
      String newNick = p.getTrailing();
      if (changingNick.equalsIgnoreCase(nick))
        nick = newNick;
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onNick(user, newNick);
     
    } else if (command.equalsIgnoreCase("QUIT")) { // QUIT
     
      IRCUser user = p.getUser();
      String trailing = p.getTrailing();
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onQuit(user, trailing);
     
    } else if (command.equalsIgnoreCase("PART")) { // PART
     
      IRCUser user = p.getUser();
      String chan = p.getParameter(1);
      String msg = p.getParameterCount() > 1 ? p.getTrailing() : "";
      // not logic: "PART :#zentrum" is without msg, "PART #zentrum :cjo all"
      // is with msg. so we cannot use getMiddle and getTrailing :-/
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onPart(chan, user, msg);
     
    } else if (command.equalsIgnoreCase("NOTICE")) { // NOTICE
     
      IRCUser user = p.getUser();
      String middle = p.getMiddle();
      String trailing = p.getTrailing();
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onNotice(middle, user, trailing);
     
    } else if ((reply = IRCUtil.parseInt(command)) >= 1 && reply < 400) { // RPL
     
      String potNick = p.getParameter(1);
      if ((level == 1 || level == 2) && nick.length() > potNick.length() &&
          nick.substring(0, potNick.length()).equalsIgnoreCase(potNick)) {
        nick = potNick;
        if (level == 2)
          level = 3;
      }
     
      if (level == 1) { // not registered
        level = 2; // if first PING wasn't received, we're
        for (int i = listeners.length - 1; i >= 0; i--)
          listeners[i].onRegistered(); // connected now for sure
      }
     
      String middle = p.getMiddle();
      String trailing = p.getTrailing();
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onReply(reply, middle, trailing);
     
    } else if (reply >= 400 && reply < 600) { // ERROR
     
      String trailing = p.getTrailing();
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onError(reply, trailing);
     
    } else if (command.equalsIgnoreCase("KICK")) { // KICK
     
      IRCUser user = p.getUser();
      String param1 = p.getParameter(1);
      String param2 = p.getParameter(2);
      String msg = (p.getParameterCount() > 2) ? p.getTrailing() : "";
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onKick(param1, user, param2, msg);
     
    } else if (command.equalsIgnoreCase("INVITE")) { // INVITE
     
      IRCUser user = p.getUser();
      String middle = p.getMiddle();
      String trailing = p.getTrailing();
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onInvite(trailing, user, middle);
     
    } else if (command.equalsIgnoreCase("TOPIC")) { // TOPIC
     
      IRCUser user = p.getUser();
      String middle = p.getMiddle();
      String trailing = p.getTrailing();
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onTopic(middle, user, trailing);
     
    } else if (command.equalsIgnoreCase("ERROR")) { // ERROR
     
      String trailing = p.getTrailing();
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onError(trailing);
     
    } else { // OTHER
     
      String prefix = p.getPrefix();
      String middle = p.getMiddle();
      String trailing = p.getTrailing();
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].unknown(prefix, command, middle, trailing);
     
    }
  }
 
// ------------------------------
 
  /**
   * Close down the connection brutally. <br />
   * It does *NOT* send the proper IRC command <code>QUIT</code>. You should
   * always use the <code>doQuit</code> methods or <code>send("QUIT")</code>
   * instead of this method. <br />
   * You should use this method to close down the connection only when the IRC
   * server doesn't react to the <code>QUIT</code> command.
   * @see #connect()
   * @see #doQuit
   * @see #doQuit(String)
   */
  public synchronized void close() {
    try {
      if (!isInterrupted())
        interrupt();
    } catch (Exception exc) {
      exc.printStackTrace();
    }
    try {
      if (socket != null)
        socket.close();
    } catch (Exception exc) {
      exc.printStackTrace();
    }
    try {
      if (out != null)
        out.close();
    } catch (Exception exc) {
      exc.printStackTrace();
    }
    try {
      if (in != null)
        in.close();
    } catch (Exception exc) {
      exc.printStackTrace();
    }
    if (this.level != -1) {
      this.level = -1;
      for (int i = listeners.length - 1; i >= 0; i--)
        listeners[i].onDisconnected();
    }
    socket = null;
    in = null;
    out = null;
    listeners = new IRCEventListener[0];
  }
 
// ------------------------------
 
  /**
   * Adds a new {@link org.schwering.irc.lib.IRCEventListener} which listens
   * for actions coming from the IRC server.
   * @param l An instance of the
   *          {@link org.schwering.irc.lib.IRCEventListener} interface.
   * @throws IllegalArgumentException If <code>listener</code> is
   *                                  <code>null</code>.
   */
  public synchronized void addIRCEventListener(IRCEventListener l) {
    if (l == null)
      throw new IllegalArgumentException("Listener is null.");
    int len = listeners.length;
    IRCEventListener[] oldListeners = listeners;
    listeners = new IRCEventListener[len + 1];
    System.arraycopy(oldListeners, 0, listeners, 0, len);
    listeners[len] = l;
  }
 
// ------------------------------
 
  /**
   * Removes the first occurence of the given
   * {@link org.schwering.irc.lib.IRCEventListener} from the listener-vector.
   * @param l An instance of the
   *          {@link org.schwering.irc.lib.IRCEventListener} interface.
   * @return <code>true</code> if the listener was successfully removed;
   *         <code>false</code> if it was not found.
   */
  public synchronized boolean removeIRCEventListener(IRCEventListener l) {
    if (l == null)
      return false;
    int index = -1;
    for (int i = 0; i < listeners.length; i++)
      if (listeners[i].equals(l)) {
        index = i;
        break;
      }
    if (index == -1)
      return false;
    listeners[index] = null;
    int len = listeners.length - 1;
    IRCEventListener[] newListeners = new IRCEventListener[len];
    for (int i = 0, j = 0; i < len; j++)
      if (listeners[j] != null)
        newListeners[i++] = listeners[j];
    listeners = newListeners;
    return true;
  }
 
// ------------------------------
 
  /**
   * Enables or disables the mIRC colorcodes.
   * @param colors <code>true</code> to enable, <code>false</code> to disable
   *               colors.
   */
  public void setColors(boolean colors) {
    colorsEnabled = colors;
  }
 
// ------------------------------
 
  /**
   * Enables or disables the automatic PING? PONG! support.
   * @param pong <code>true</code> to enable automatic <code>PONG</code>
   *             reply, <code>false</code> makes the class fire
   *             <code>onPing</code> events.
   */
  public void setPong(boolean pong) {
    pongAutomatic = pong;
  }
 
// ------------------------------
 
  /**
   * Changes the character encoding used to talk to the server.
   * This can be ISO-8859-1 or UTF-8 for example.
   * This property must be set before a call to the <code>connect()</code>
   * method.
   * @param encoding
   */
  public void setEncoding(String encoding) {
    this.encoding  = encoding;
  }
 
// ------------------------------
 
  /**
   * Sets the connection's timeout in milliseconds. <br />
   * The default is <code>1000 * 60 15</code> millis which are 15 minutes.
   */
  public void setTimeout(int millis) {
    if (socket != null)
      try {
        socket.setSoTimeout(millis);
      } catch (IOException exc) {
        exc.printStackTrace();
      }
      timeout = millis;
  }
 
// ------------------------------
 
  /**
   * Tells whether there's a connection to the IRC network or not. <br />
   * If <code>connect</code> wasn't called yet, it returns <code>false</code>.
   * @return The status of the connection; <code>true</code> if it's connected.
   * @see #connect()
   * @see #doQuit()
   * @see #doQuit(String)
   * @see #close()
   */
  public boolean isConnected() {
    return level >= 1;
  }
 
// ------------------------------
 
  /**
   * Returns the nickname of this instance.
   * @return The nickname.
   */
  public String getNick() {
    return nick;
  }
 
// ------------------------------
 
  /**
   * Returns the realname of this instance.
   * @return The realname.
   */
  public String getRealname() {
    return realname;
  }
 
// ------------------------------
 
  /**
   * Returns the username of this instance.
   * @return The username.
   */
  public String getUsername() {
    return username;
  }
 
// ------------------------------
 
  /**
   * Returns the server of this instance.
   * @return The server's hostname.
   */
  public String getHost() {
    return host;
  }
 
// ------------------------------
 
  /**
   * Returns the password of this instance. If no password is set,
   * <code>null</code> is returned.
   * @return The password. If no password is set, <code>null</code> is
   *         returned.
   */
  public String getPassword() {
    return pass;
  }
 
// ------------------------------
 
  /**
   * Returns all ports to which the <code>IRCConnection</code> is going to try
   * or has tried to connect to.
   * @return The ports in an <code>int[]</code> array.
   */
  public int[] getPorts() {
    return ports;
 
 
// ------------------------------
 
  /**
   * Returns the port to which the <code>IRCConnection</code> connected, or
   * <code>0</code> if the connection failed or wasn't tried yet.
   * @return The port to which the <code>IRCConnection</code>, or
   *         <code>0</code> if the connection failed or wasn't tried yet.
   */
  public int getPort() {
    return (socket != null) ? socket.getPort() : 0;
  }
 
// ------------------------------
 
  /**
   * Indicates whether colors are stripped out or not.
   * @return <code>true</code> if colors are disabled.
   */
  public boolean getColors() {
    return colorsEnabled;
  }
 
// ------------------------------
 
  /**
   * Indicates whether automatic PING? PONG! is enabled or not.
   * @return <code>true</code> if PING? PONG! is done automatically.
   */
  public boolean getPong() {
    return pongAutomatic;
  }
 
// ------------------------------
 
  /**
   * Returns the encoding of the socket.
   * @return The socket's encoding.
   */
  public String getEncoding() {
    return encoding;
  }
 
// ------------------------------
 
  /**
   * Returns the timeout of the socket. <br />
   * If an error occurs, which is never the case, <code>-1</code> is returned.
   * @return The timeout.
   */
  public int getTimeout() {
    if (socket != null)
      try {
        return socket.getSoTimeout();
      } catch (IOException exc) {
        exc.printStackTrace();
        return -1;
      }
      else
        return timeout;
  }
 
// ------------------------------
 
  /**
   * Generates a <code>String</code> with some information about the instance of
   * <code>IRCConnection</code>.
   * Its format is: <code>
   * classname[host,portMin,portMax,username,nick,realname,pass,connected]
   * </code>.
   * @return A <code>String</code> with information about the instance.
   */
  public String toString() {
    return getClass().getName() +"["+ host +","+ getPort() +","+ username +","+
    nick +","+ realname +","+ pass +","+ isConnected() +"]";
  }
 
// ------------------------------
 
  /**
   * Removes away message.
   */
  public void doAway() {
    send("AWAY");
 
 
// ------------------------------
 
  /**
   * Sets away message.
   * @param msg The away message.
   */
  public void doAway(String msg) {
    send("AWAY :"+ msg);
 
 
// ------------------------------
 
  /**
   * Invites a user to a channel.
   * @param nick The nickname of the user who should be invited.
   * @param chan The channel the user should be invited to.
   */
  public void doInvite(String nick, String chan) {
    send("INVITE "+ nick +" "+ chan);
 
 
// ------------------------------
 
  /**
   * Checks if one or more nicks are used on the server.
   * @param nick The nickname of the user we search for.
   */
  public void doIson(String nick) {
    send("ISON "+ nick);
 
 
// ------------------------------
 
  /**
   * Joins a channel without a key.
   * @param chan The channel which is to join.
   */
  public void doJoin(String chan) {
    send("JOIN "+ chan);
 
 
// ------------------------------
 
  /**
   * Joins a channel with a key.
   * @param chan The channel which is to join.
   * @param key The key of the channel.
   */
  public void doJoin(String chan, String key) {
    send("JOIN "+ chan +" "+ key);
 
 
// ------------------------------
 
  /**
   * Kicks a user from a channel.
   * @param chan The channel somebody should be kicked from.
   * @param nick The nickname of the user who should be kicked.
   */
  public void doKick(String chan, String nick) {
    send("KICK "+ chan +" "+ nick);
  }
 
// ------------------------------
 
  /**
   * Kicks a user from a channel with a comment.
   * @param chan The channel somebody should be kicked from.
   * @param nick The nickname of the user who should be kicked.
   * @param msg The optional kickmessage.
   */
  public void doKick(String chan, String nick, String msg) {
    send("KICK "+ chan +" "+ nick +" :"+ msg);
 
 
// ------------------------------
 
  /**
   * Lists all channels with their topic and status.
   */
  public void doList() {
    send("LIST");
 
 
// ------------------------------
 
  /**
   * Lists channel(s) with their topic and status.
   * @param chan The channel the <code>LIST</code> refers to.
   */
  public void doList(String chan) {
    send("LIST "+ chan);
 
 
// ------------------------------
 
  /**
   * Lists all visible users.
   */
  public void doNames() {
    send("NAMES");
 
 
// ------------------------------
 
  /**
   * Lists all visible users of (a) channel(s).
   * @param chan The channel the <code>NAMES</code> command is refering to.
   */
  public void doNames(String chan) {
    send("NAMES "+ chan);
 
 
// ------------------------------
 
  /**
   * Sends a message to a person or a channel.
   * @param target The nickname or channel the message should be sent to.
   * @param msg The message which should be transmitted.
   */
  public void doPrivmsg(String target, String msg) {
    send("PRIVMSG "+ target +" :"+ msg);
  }
 
// ------------------------------
 
  /**
   * Requests a Reply 324 for the modes of a given channel.
   * @param chan The channel the <code>MODE</code> request is refering to.
   */
  public void doMode(String chan) {
    send("MODE "+ chan);
  }
 
// ------------------------------
 
  /**
   * Sends a mode to the server. <br />
   * The first argument is a nickname (user-mode) or a channel (channel-mode).
   * <code>String mode</code> must contain the operators (+/-), the modes
   * (o/v/i/k/l/p/s/w) and the possibly values (nicks/banmask/limit/key).
   * @param target The nickname or channel of the user whose modes will be
   *               changed.
   * @param mode The new modes.
   */
  public void doMode(String target, String mode) {
    send("MODE "+ target +" "+ mode);
  }
 
// ------------------------------
 
  /**
   * Changes the nickname.
   * @param nick The new nickname.
   */
  public void doNick(String nick) {
    send("NICK "+ nick);
 
 
// ------------------------------
 
  /**
   * Notices a message to a person or a channel.
   * @param target The nickname or channel (group) the message should be
   *               sent to.
   * @param msg The message which should be transmitted.
   */
  public void doNotice(String target, String msg) {
    send("NOTICE "+ target +" :"+ msg);
  }
 
// ------------------------------
 
  /**
   * Parts from a given channel.
   * @param chan The channel you want to part from.
   */
  public void doPart(String chan) {
    send("PART "+ chan);
  }
 
// ------------------------------
 
  /**
   * Parts from a given channel with a given parg-msg.
   * @param chan The channel you want to part from.
   * @param msg The optional partmessage.
   */
  public void doPart(String chan, String msg) {
    send("PART "+ chan +" :"+ msg);
  }
 
// ------------------------------
 
  /**
   * Quits from the IRC server with a quit-msg.
   * @param ping The ping which was received in <code>onPing</code>. It's a
   *             <code>String</code>, because sometimes on some networks
   *             the server-hostname (for example splatterworld.quakenet.org) is
   *             given as parameter which would throw an Exception if we
   *             gave the ping as long.
   */
  public void doPong(String ping) {
    send("PONG :"+ ping);
  }
 
// ------------------------------
 
  /**
   * Quits from the IRC server.
   * Calls the <code>disconnect</code>-method which does the work actually.
   * @see #isConnected()
   * @see #connect()
   * @see #doQuit(String)
   * @see #close()
   */
  public void doQuit() {
    send("QUIT");
  }
 
// ------------------------------
 
  /**
   * Quits from the IRC server with a quit-msg.
   * Calls the <code>disconnect</code>-method which does the work actually.
   * @param msg The optional quitmessage.
   * @see #isConnected()
   * @see #connect()
   * @see #doQuit()
   * @see #close()
   */
  public void doQuit(String msg) {
    send("QUIT :"+ msg);
  }
 
// ------------------------------
 
  /**
   * Requests the topic of a chan. The topic is given in a numeric reply.
   * @param chan The channel which topic should be requested.
   */
  public void doTopic(String chan) {
    send("TOPIC "+ chan);
 
 
// ------------------------------
 
  /**
   * Changes the topic of a chan.
   * @param chan The channel which topic is changed.
   * @param topic The new topic.
   */
  public void doTopic(String chan, String topic) {
    send("TOPIC "+ chan +" :"+ topic);
 
 
// ------------------------------
 
  /**
   * Requests information about users matching the given criteric,
   * for example a channel they are on.
   * @param criteric The criterics of the <code>WHO</code> query.
   */
  public void doWho(String criteric) {
    send("WHO "+ criteric);
 
 
// ------------------------------
 
  /**
   * Requires information about an existing user.
   * @param nick The nickname of the user the query is refering to.
   */
  public void doWhois(String nick) {
    send("WHOIS "+ nick);
 
 
// ------------------------------
 
  /**
   * Requires host-information about a user, who is not connected anymore.
   * @param nick The nickname of the user the query is refering to.
   */
  public void doWhowas(String nick) {
    send("WHOWAS "+ nick);
  }
 
// ------------------------------
 
  /**
   * Requires host-information about up to 5 users which must be listed and
   * divided by spaces.
   * @param nick The nickname of the user the query is refering to.
   */
  public void doUserhost(String nick) {
    send("USERHOST "+ nick);
  }
}
TOP

Related Classes of org.schwering.irc.lib.IRCConnection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.