Advertisement
Guest User

Untitled

a guest
Sep 22nd, 2017
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 36.13 KB | None | 0 0
  1. /*
  2.  * IRClib -- A Java Internet Relay Chat library -- class IRCConnection
  3.  * Copyright (C) 2002 - 2006 Christoph Schwering <schwering@gmail.com>
  4.  *
  5.  * This library and the accompanying materials are made available under the
  6.  * terms of the
  7.  *  - GNU Lesser General Public License,
  8.  *  - Apache License, Version 2.0 and
  9.  *  - Eclipse Public License v1.0.
  10.  * This library is distributed in the hope that it will be useful, but WITHOUT
  11.  * ANY WARRANTY.
  12.  */
  13.  
  14. package org.schwering.irc.lib;
  15.  
  16. import java.io.BufferedReader;
  17. import java.io.IOException;
  18. import java.io.InputStreamReader;
  19. import java.io.OutputStreamWriter;
  20. import java.io.PrintWriter;
  21. import java.net.Socket;
  22. import java.net.SocketException;
  23.  
  24. /**
  25.  * Creates a new connection to an IRC server. It's the main class of the
  26.  * IRClib, the point everything starts.
  27.  * <p>
  28.  * The following sample code tries to establish an IRC connection to an
  29.  * IRC server:
  30.  * <p>
  31.  * <hr /><pre>
  32.  * /&#42;
  33.  *  &#42; The following code of a class which imports org.schwering.irc.lib.*
  34.  *  &#42; prepares an IRC connection and then tries to establish the connection.
  35.  *  &#42; The server is "irc.somenetwork.com", the default portrange (6667 and
  36.  *  &#42; 6669) is set, no password is used (null). The nickname is "Foo" and
  37.  *  &#42; the realname is "Mr. Foobar". The username "foobar".
  38.  *  &#42; Because of setDaemon(true), the JVM exits even if this thread is
  39.  *  &#42; running.
  40.  *  &#42; An instance of the class MyListener which must implement
  41.  *  &#42; IRCActionListener is added as only event-listener for the connection.
  42.  *  &#42; The connection is told to parse out mIRC color codes and to enable
  43.  *  &#42; automatic PING? PONG! replies.
  44.  *  &#42;/
  45.  * IRCConnection conn = new IRCConnection(
  46.  *                            "irc.somenetwork.com",
  47.  *                            6667,
  48.  *                            6669,
  49.  *                            null,
  50.  *                            "Foo",
  51.  *                            "Mr. Foobar",
  52.  *                            "foo@bar.com"
  53.  *                          );
  54.  *
  55.  * conn.addIRCEventListener(new MyListener());
  56.  * conn.setDaemon(true);
  57.  * conn.setColors(false);
  58.  * conn.setPong(true);
  59.  *
  60.  * try {
  61.  *   conn.connect(); // Try to connect!!! Don't forget this!!!
  62.  * } catch (IOException ioexc) {
  63.  *   ioexc.printStackTrace();
  64.  * }
  65.  * </pre><hr />
  66.  * <p>
  67.  * The serverpassword isn't needed in most cases. You can give
  68.  * <code>null</code> or <code>""</code> instead as done in this example.
  69.  * @author Christoph Schwering <schwering@gmail.com>
  70.  * @version 3.05
  71.  * @see IRCEventListener
  72.  * @see IRCParser
  73.  * @see IRCUtil
  74.  * @see SSLIRCConnection
  75.  */
  76. public class IRCConnection extends Thread {
  77.        
  78.  
  79.     /**
  80.      * Records data usage for in and out of IRCConnection.
  81.      */
  82.     private long data_in = 0;
  83.     private long data_out = 0;
  84.    
  85.     /**
  86.      * This <code>Socket</code> is a connection to the IRC server.
  87.      */
  88.     private Socket socket;
  89.    
  90.     /**
  91.      * This is like a UNIX-runlevel. Its value indicates the level of the
  92.      * <code>IRCConnection</code> object. <code>0</code> means that the object
  93.      * has not yet been connected, <code>1</code> means that it's connected but
  94.      * not registered, <code>2</code> means that it's connected and registered
  95.      * but still waiting to receive the nickname the first time, <code>3</code>
  96.      * means that it's connected and registered, and <code>-1</code> means that
  97.      * it was connected but is disconnected.
  98.      * Therefore the defaultvalue is <code>0</code>.
  99.      */
  100.     protected byte level = 0;
  101.    
  102.     /**
  103.      * The host of the IRC server.
  104.      */
  105.     protected String host;
  106.    
  107.     /**
  108.      * The <code>int[]</code> contains all ports to which we are going to try to
  109.      * connect. This can be a portrange from port 6667 to 6669, for example.
  110.      */
  111.     protected int[] ports;
  112.    
  113.     /**
  114.      * The <code>BufferedReader</code> receives Strings from the IRC server.
  115.      */
  116.     private volatile BufferedReader in;
  117.    
  118.     /**
  119.      * The <code>PrintWriter</code> sends Strings to the IRC server.
  120.      */
  121.     private PrintWriter out;
  122.    
  123.     /**
  124.      * The <code>String</code> contains the name of the character encoding used
  125.      * to talk to the server. This can be ISO-8859-1 or UTF-8 for example. The
  126.      * default is ISO-8859-1.
  127.      */
  128.     protected String encoding = "ISO-8859-1";
  129.    
  130.     /**
  131.      * This array contains <code>IRCEventListener</code> objects.
  132.      */
  133.     private IRCEventListener[] listeners = new IRCEventListener[0];
  134.    
  135.     /**
  136.      * This <code>int</code> is the connection's timeout in milliseconds. It's
  137.      * used in the <code>Socket.setSoTimeout</code> method. The default is
  138.      * <code>1000 * 60 * 15</code> millis which are 15 minutes.
  139.      */
  140.     private int timeout = 1000 * 60 * 15;
  141.    
  142.     /**
  143.      * This <code>boolean</code> stands for enabled (<code>true</code>) or
  144.      * disabled (<code>false</code>) ColorCodes.<br />Default is enabled
  145.      * (<code>false</code>).
  146.      */
  147.     private boolean colorsEnabled = false;
  148.    
  149.     /**
  150.      * This <code>boolean</code> stands for enabled or disabled automatic PING?
  151.      * PONG! support. <br />It means, that if the server asks with PING for the
  152.      * ping, the PONG is automatically sent. Default is automatic PONG enabled
  153.      * (<code>true</code>).
  154.      */
  155.     private boolean pongAutomatic = true;
  156.    
  157.     /**
  158.      * The password, which is needed to get access to the IRC server.
  159.      */
  160.     private String pass;
  161.    
  162.     /**
  163.      * The user's nickname, which is indispensably to connect.
  164.      */
  165.     private String nick;
  166.    
  167.     /**
  168.      * The user's realname, which is indispensably to connect.
  169.      */
  170.     private String realname;
  171.    
  172.     /**
  173.      * The user's username, which is indispensable to connect.
  174.      */
  175.     private String username;
  176.    
  177. // ------------------------------
  178.    
  179.     /**
  180.      * Creates a new IRC connection. <br />
  181.      * The difference to the other constructor is, that it transmits the ports in
  182.      * an <code>int[]</code>. Thus, also ports like 1024, 2048, 6667 and
  183.      * 6669 can be selected.<br /><br />
  184.      * The constructor prepares a new IRC connection which can be really started
  185.      * by invoking the <code>connect</code> method. Before invoking it, you should
  186.      * set the <code>IRCEventListener</code> and other settings.<br />
  187.      * Note that you do not need to set a password to connect to the large public
  188.      * IRC networks like QuakeNet, EFNet etc. To use no password in your IRC
  189.      * connection, use <code>""</code> or <code>null</code> for the password
  190.      * argument in the constructor.
  191.      * @param host The hostname of the server we want to connect to.
  192.      * @param ports The portrange to which we want to connect.
  193.      * @param pass The password of the IRC server. If your server isn't
  194.      *             secured by a password (that's normal), use
  195.      *             <code>null</code> or <code>""</code>.
  196.      * @param nick The nickname for the connection. Is used to register the
  197.      *             connection.
  198.      * @param username The username. Is used to register the connection.
  199.      * @param realname The realname. Is used to register the connection.
  200.      * @throws IllegalArgumentException If the <code>host</code> or
  201.      *                                  <code>ports</code> is <code>null</code> or
  202.      *                                  <code>ports</code>' length is
  203.      *                                  <code>0</code>.
  204.      * @see #connect()
  205.      */
  206.     public IRCConnection(String host, int[] ports, String pass, String nick,
  207.             String username, String realname) {
  208.         if (host == null || ports == null || ports.length == 0)
  209.             throw new IllegalArgumentException("Host and ports may not be null.");
  210.         this.host = host;
  211.         this.ports = ports;
  212.         this.pass = (pass != null && pass.length() == 0) ? null : pass;
  213.         this.nick = nick;
  214.         this.username = username;
  215.         this.realname = realname;
  216.     }
  217.    
  218. // ------------------------------
  219.    
  220.     /**
  221.      * Creates a new IRC connection. <br />
  222.      * The difference to the other constructor is, that it transmits the ports as
  223.      * two <code>int</code>s. Thus, only a portrange from port <code>x</code> to
  224.      * port <code>y</code> like from port 6667 to 6669 can be selected.<br />
  225.      * <br />
  226.      * The constructor prepares a new IRC connection which can be really started
  227.      * by invoking the <code>connect</code> method. Before invoking it, you should
  228.      * set the <code>IRCEventListener</code> and other settings.<br />
  229.      * Note that you do not need to set a password to connect to the large public
  230.      * IRC networks like QuakeNet, EFNet etc. To use no password in your IRC
  231.      * connection, use <code>""</code> or <code>null</code> for the password
  232.      * argument in the constructor.
  233.      * @param host The hostname of the server we want to connect to.
  234.      * @param portMin The beginning of the port range we are going to connect
  235.      *                to.
  236.      * @param portMax The ending of the port range we are going to connect to.
  237.      * @param pass The password of the IRC server. If your server isn't
  238.      *             secured by a password (that's normal), use
  239.      *             <code>null</code> or <code>""</code>.
  240.      * @param nick The nickname for the connection. Is used to register the
  241.      *             connection.
  242.      * @param username The username. Is used to register the connection.
  243.      * @param realname The realname. Is used to register the connection.
  244.      * @throws IllegalArgumentException If the <code>host</code> is
  245.      *                                  <code>null</code>.
  246.      * @see #connect()
  247.      */
  248.     public IRCConnection(String host, int portMin, int portMax, String pass,
  249.             String nick, String username, String realname) {
  250.         this(host, portRangeToArray(portMin, portMax), pass, nick, username,
  251.                 realname);
  252.     }
  253.    
  254. // ------------------------------
  255.    
  256.     /**
  257.      * Converts a portrange which starts with a given <code>int</code> and ends
  258.      * with a given <code>int</code> into an array which contains all
  259.      * <code>int</code>s from the beginning to the ending (including beginning
  260.      * and ending).<br />
  261.      * If <code>portMin > portMax</code>, the portrange is turned arount
  262.      * automatically.
  263.      * @param portMin The beginning port of the portrange.
  264.      * @param portMax The ending port of the portrange.
  265.      */
  266.     private static int[] portRangeToArray(int portMin, int portMax) {
  267.         if (portMin > portMax) {
  268.             int tmp = portMin;
  269.             portMin = portMax;
  270.             portMax = tmp;
  271.         }
  272.         int[] ports = new int[portMax - portMin + 1];
  273.         for (int i = 0; i < ports.length; i++)
  274.             ports[i] = portMin + i;
  275.         return ports;
  276.     }
  277.    
  278. // ------------------------------
  279.    
  280.     /**
  281.      * Establish a connection to the server. <br />
  282.      * This method must be invoked to start a connection; the constructor doesn't
  283.      * do that!<br />
  284.      * It tries all set ports until one is open. If all ports fail it throws an
  285.      * <code>IOException</code>.<br />
  286.      * You can invoke <code>connect</code> only one time.
  287.      * @throws IOException If an I/O error occurs.
  288.      * @throws SocketException If the <code>connect</code> method was already
  289.      *                         invoked.
  290.      * @see #isConnected()
  291.      * @see #doQuit()
  292.      * @see #doQuit(String)
  293.      * @see #close()
  294.      */
  295.     public void connect() throws IOException {
  296.         if (level != 0) // otherwise disconnected or connect
  297.             throw new SocketException("Socket closed or already open ("+ level +")");
  298.         IOException exception = null;
  299.         Socket s = null;
  300.         for (int i = 0; i < ports.length && s == null; i++) {
  301.             try {
  302.                 s = new Socket(host, ports[i]);
  303.                 exception = null;
  304.             } catch (IOException exc) {
  305.                 if (s != null)
  306.                     s.close();
  307.                 s = null;
  308.                 exception = exc;
  309.             }
  310.         }
  311.         if (exception != null)
  312.             throw exception; // connection wasn't successful at any port
  313.        
  314.         prepare(s);
  315.     }
  316.    
  317. // ------------------------------
  318.    
  319.     /**
  320.      * Invoked by the <code>connect</code> method, this method prepares the
  321.      * connection. <br />
  322.      * It initializes the class-vars for the inputstream and the outputstream of
  323.      * the socket, starts the registration of at the IRC server by calling
  324.      * <code>register()</code> and starts the receiving of lines from the server
  325.      * by starting the thread with the <code>start</code> method.<br /><br />
  326.      * This method must be protected, because it is used by extending classes,
  327.      * which override the <code>connect</code> method.
  328.      * @param s The socket which is used for the connection.
  329.      * @throws IOException If an I/O error occurs.
  330.      * @see #connect()
  331.      * @see #run()
  332.      */
  333.     protected void prepare(Socket s) throws IOException {
  334.         if (s == null)
  335.             throw new SocketException("Socket s is null, not connected");
  336.         socket = s;
  337.         level = 1;
  338.         s.setSoTimeout(timeout);
  339.         in  = new BufferedReader(new InputStreamReader(s.getInputStream(),
  340.                 encoding));
  341.         out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),
  342.                 encoding));
  343.         start();
  344.         register();
  345.     }
  346.    
  347. // ------------------------------
  348.    
  349.     /**
  350.      * Registers the connection with the IRC server. <br />
  351.      * In fact, it sends a password (if set, else nothing), the nickname and the
  352.      * user, the realname and the host which we're connecting to.<br />
  353.      * The action synchronizes <code>code> so that no important messages
  354.      * (like the first PING) come in before this registration is finished.<br />
  355.      * The <code>USER</code> command's format is:<br /><code>
  356.      * <username> <localhost> <irchost> <realname>
  357.      * </code>
  358.      */
  359.     private void register() {
  360.         if (pass != null)
  361.             send("PASS "+ pass);
  362.         send("NICK "+ nick);
  363.         send("USER "+ username +" "+ host
  364.                 +" bla :"+ realname);
  365.     }
  366.    
  367. // ------------------------------
  368.    
  369.     /**
  370.      * The <code>Thread</code> is started by the <code>connect</code> method.
  371.      * It's task is to receive strings from the IRC server and hand them over
  372.      * to the <code>get</code> method.
  373.      */
  374.     public void run() {
  375.         try {
  376.             String line;
  377.             while (!isInterrupted()) {
  378.                 line = in.readLine();
  379.                 if (line != null) {
  380.                     data_in += (line).getBytes("ISO-8859-1").length;
  381.                     get(line); }
  382.                 else {
  383.                     close(); }
  384.             }
  385.         } catch (IOException exc) {
  386.             close();
  387.         }
  388.     }
  389.    
  390. // ------------------------------
  391.    
  392.     /**
  393.      * Sends a String to the server.
  394.      * You should use this method only, if you must do it. For most purposes,
  395.      * there are <code>do*</code> methods (like <code>doJoin</code>). A carriage
  396.      * return line feed (<code>\r\n</code>) is appended automatically.
  397.      * @param line The line which should be send to the server without the
  398.      *             trailing carriage return line feed (<code>\r\n</code>).
  399.      */
  400.     public void send(String line) {
  401.         try {
  402.             out.write(line +"\r\n");
  403.             data_out += (line+"\r\n").getBytes("ISO-8859-1").length;
  404.             out.flush();
  405.             if (level == 1) { // not registered
  406.                 IRCParser p = new IRCParser(line);
  407.                 if (p.getCommand().equalsIgnoreCase("NICK"))
  408.                     nick = p.getParameter(1).trim();
  409.             }
  410.         } catch (Exception exc) {
  411.             exc.printStackTrace();
  412.         }
  413.     }
  414.    
  415. // ------------------------------
  416.    
  417.     /**
  418.      * Just parses a String given as the only argument with the help of the
  419.      * <code>IRCParser</code> class. Then it controls the command and fires events
  420.      * through the <code>IRCEventListener</code>.<br />
  421.      * @param line The line which is sent from the server.
  422.      */
  423.     private synchronized void get(String line) {
  424.         IRCParser p;
  425.         try {
  426.             p = new IRCParser(line, colorsEnabled);
  427.         } catch (Exception exc) {
  428.             return;
  429.         }
  430.         String command = p.getCommand();
  431.         int reply; // 3-digit reply will be parsed in the later if-condition
  432.        
  433.         if (command.equalsIgnoreCase("PRIVMSG")) { // MESSAGE
  434.            
  435.             IRCUser user = p.getUser();
  436.             String middle = p.getMiddle();
  437.             String trailing = p.getTrailing();
  438.             for (int i = 0; i < listeners.length; i++)
  439.                 listeners[i].onPrivmsg(middle, user, trailing);
  440.            
  441.         } else if (command.equalsIgnoreCase("MODE")) { // MODE
  442.            
  443.             String chan = p.getParameter(1);
  444.             if (IRCUtil.isChan(chan)) {
  445.                 IRCUser user = p.getUser();
  446.                 String param2 = p.getParameter(2);
  447.                 String paramsFrom3 = p.getParametersFrom(3);
  448.                 for (int i = 0; i < listeners.length; i++)
  449.                     listeners[i].onMode(chan, user,
  450.                             new IRCModeParser(param2, paramsFrom3));
  451.             } else {
  452.                 IRCUser user = p.getUser();
  453.                 String paramsFrom2 = p.getParametersFrom(2);
  454.                 for (int i = 0; i < listeners.length; i++)
  455.                     listeners[i].onMode(user, chan, paramsFrom2);
  456.             }
  457.            
  458.         } else if (command.equalsIgnoreCase("PING")) { // PING
  459.            
  460.             String ping = p.getTrailing(); // no int cause sometimes it's text
  461.             if (pongAutomatic)
  462.                 doPong(ping);
  463.             else
  464.                 for (int i = 0; i < listeners.length; i++)
  465.                     listeners[i].onPing(ping);
  466.            
  467.             if (level == 1) { // not registered
  468.                 level = 2; // first PING received -> connection
  469.                 for (int i = 0; i < listeners.length; i++)
  470.                     listeners[i].onRegistered();
  471.             }
  472.            
  473.         } else if (command.equalsIgnoreCase("JOIN")) { // JOIN
  474.            
  475.             IRCUser user = p.getUser();
  476.             String trailing = p.getTrailing();
  477.             for (int i = 0; i < listeners.length; i++)
  478.                 listeners[i].onJoin(trailing, user);
  479.            
  480.         } else if (command.equalsIgnoreCase("NICK")) { // NICK
  481.            
  482.             IRCUser user = p.getUser();
  483.             String changingNick = p.getNick();
  484.             String newNick = p.getTrailing();
  485.             if (changingNick.equalsIgnoreCase(nick))
  486.                 nick = newNick;
  487.             for (int i = 0; i < listeners.length; i++)
  488.                 listeners[i].onNick(user, newNick);
  489.            
  490.         } else if (command.equalsIgnoreCase("QUIT")) { // QUIT
  491.            
  492.             IRCUser user = p.getUser();
  493.             String trailing = p.getTrailing();
  494.             for (int i = 0; i < listeners.length; i++)
  495.                 listeners[i].onQuit(user, trailing);
  496.            
  497.         } else if (command.equalsIgnoreCase("PART")) { // PART
  498.            
  499.             IRCUser user = p.getUser();
  500.             String chan = p.getParameter(1);
  501.             String msg = p.getParameterCount() > 1 ? p.getTrailing() : "";
  502.             // not logic: "PART :#zentrum" is without msg, "PART #zentrum :cjo all"
  503.             // is with msg. so we cannot use getMiddle and getTrailing :-/
  504.             for (int i = 0; i < listeners.length; i++)
  505.                 listeners[i].onPart(chan, user, msg);
  506.            
  507.         } else if (command.equalsIgnoreCase("NOTICE")) { // NOTICE
  508.            
  509.             IRCUser user = p.getUser();
  510.             String middle = p.getMiddle();
  511.             String trailing = p.getTrailing();
  512.             for (int i = 0; i < listeners.length; i++)
  513.                 listeners[i].onNotice(middle, user, trailing);
  514.            
  515.         } else if ((reply = IRCUtil.parseInt(command)) >= 1 && reply < 400) { // RPL
  516.            
  517.             String potNick = p.getParameter(1);
  518.             if ((level == 1 || level == 2) && nick.length() > potNick.length() &&
  519.                     nick.substring(0, potNick.length()).equalsIgnoreCase(potNick)) {
  520.                 nick = potNick;
  521.                 if (level == 2)
  522.                     level = 3;
  523.             }
  524.            
  525.             if (level == 1) { // not registered
  526.                 level = 2; // if first PING wasn't received, we're
  527.                 for (int i = 0; i < listeners.length; i++)
  528.                     listeners[i].onRegistered(); // connected now for sure
  529.             }
  530.            
  531.             String middle = p.getMiddle();
  532.             String trailing = p.getTrailing();
  533.             for (int i = 0; i < listeners.length; i++)
  534.                 listeners[i].onReply(reply, middle, trailing);
  535.            
  536.         } else if (reply >= 400 && reply < 600) { // ERROR
  537.            
  538.             String trailing = p.getTrailing();
  539.             for (int i = 0; i < listeners.length; i++)
  540.                 listeners[i].onError(reply, trailing);
  541.            
  542.         } else if (command.equalsIgnoreCase("KICK")) { // KICK
  543.            
  544.             IRCUser user = p.getUser();
  545.             String param1 = p.getParameter(1);
  546.             String param2 = p.getParameter(2);
  547.             String msg = (p.getParameterCount() > 2) ? p.getTrailing() : "";
  548.             for (int i = 0; i < listeners.length; i++)
  549.                 listeners[i].onKick(param1, user, param2, msg);
  550.            
  551.         } else if (command.equalsIgnoreCase("INVITE")) { // INVITE
  552.            
  553.             IRCUser user = p.getUser();
  554.             String middle = p.getMiddle();
  555.             String trailing = p.getTrailing();
  556.             for (int i = 0; i < listeners.length; i++)
  557.                 listeners[i].onInvite(trailing, user, middle);
  558.            
  559.         } else if (command.equalsIgnoreCase("TOPIC")) { // TOPIC
  560.            
  561.             IRCUser user = p.getUser();
  562.             String middle = p.getMiddle();
  563.             String trailing = p.getTrailing();
  564.             for (int i = 0; i < listeners.length; i++)
  565.                 listeners[i].onTopic(middle, user, trailing);
  566.            
  567.         } else if (command.equalsIgnoreCase("ERROR")) { // ERROR
  568.            
  569.             String trailing = p.getTrailing();
  570.             for (int i = 0; i < listeners.length; i++)
  571.                 listeners[i].onError(trailing);
  572.            
  573.         } else { // OTHER
  574.            
  575.             String prefix = p.getPrefix();
  576.             String middle = p.getMiddle();
  577.             String trailing = p.getTrailing();
  578.             for (int i = 0; i < listeners.length; i++)
  579.                 listeners[i].unknown(prefix, command, middle, trailing);
  580.            
  581.         }
  582.     }
  583.    
  584. // ------------------------------
  585.    
  586.     /**
  587.      * Close down the connection brutally. <br />
  588.      * It does *NOT* send the proper IRC command <code>QUIT</code>. You should
  589.      * always use the <code>doQuit</code> methods or <code>send("QUIT")</code>
  590.      * instead of this method. <br />
  591.      * You should use this method to close down the connection only when the IRC
  592.      * server doesn't react to the <code>QUIT</code> command.
  593.      * @see #connect()
  594.      * @see #doQuit
  595.      * @see #doQuit(String)
  596.      */
  597.     public synchronized void close() {
  598.         try {
  599.             if (!isInterrupted()) {
  600.                 System.out.println("Interrupting thread...");
  601.                 interrupt();
  602.             }
  603.         } catch (Exception exc) {
  604.             exc.printStackTrace();
  605.         }
  606.         try {
  607.             if (socket != null) {
  608.                 System.out.println("Closing socket...");
  609.                 socket.close(); }
  610.         } catch (Exception exc) {
  611.             exc.printStackTrace();
  612.         }
  613.         try {
  614.             if (out != null) {
  615.                 System.out.println("Closing out stream...");
  616.                 out.close(); }
  617.         } catch (Exception exc) {
  618.             exc.printStackTrace();
  619.         }
  620.         try {
  621.             if (in != null) {
  622.                 System.out.println("Closing in stream...");
  623.                 in.close(); }
  624.         } catch (Exception exc) {
  625.             exc.printStackTrace();
  626.         }
  627.         if (this.level != 0) {
  628.             System.out.println("Setting level to 0...");
  629.             this.level = 0;
  630.             for (int i = 0; i < listeners.length; i++) {
  631.                 System.out.println("Doing listener");
  632.                 listeners[i].onDisconnected(); }
  633.         }
  634.         socket = null;
  635.         in = null;
  636.         out = null;
  637.         //listeners = new IRCEventListener[0];
  638.     }
  639.    
  640. // ------------------------------
  641.    
  642.     /**
  643.      * Adds a new {@link org.schwering.irc.lib.IRCEventListener} which listens
  644.      * for actions coming from the IRC server.
  645.      * @param l An instance of the
  646.      *          {@link org.schwering.irc.lib.IRCEventListener} interface.
  647.      * @throws IllegalArgumentException If <code>listener</code> is
  648.      *                                  <code>null</code>.
  649.      */
  650.     public synchronized void addIRCEventListener(IRCEventListener l) {
  651.         if (l == null)
  652.             throw new IllegalArgumentException("Listener is null.");
  653.         int len = listeners.length;
  654.         IRCEventListener[] oldListeners = listeners;
  655.         listeners = new IRCEventListener[len + 1];
  656.         System.arraycopy(oldListeners, 0, listeners, 0, len);
  657.         listeners[len] = l;
  658.     }
  659.    
  660. // ------------------------------
  661.    
  662.     /**
  663.      * Removes the first occurence of the given
  664.      * {@link org.schwering.irc.lib.IRCEventListener} from the listener-vector.
  665.      * @param l An instance of the
  666.      *          {@link org.schwering.irc.lib.IRCEventListener} interface.
  667.      * @return <code>true</code> if the listener was successfully removed;
  668.      *         <code>false</code> if it was not found.
  669.      */
  670.     public synchronized boolean removeIRCEventListener(IRCEventListener l) {
  671.         if (l == null)
  672.             return false;
  673.         int index = -1;
  674.         for (int i = 0; i < listeners.length; i++)
  675.             if (listeners[i].equals(l)) {
  676.                 index = i;
  677.                 break;
  678.             }
  679.         if (index == -1)
  680.             return false;
  681.         listeners[index] = null;
  682.         int len = listeners.length - 1;
  683.         IRCEventListener[] newListeners = new IRCEventListener[len];
  684.         for (int i = 0, j = 0; i < len; j++)
  685.             if (listeners[j] != null)
  686.                 newListeners[i++] = listeners[j];
  687.         listeners = newListeners;
  688.         return true;
  689.     }
  690.    
  691. // ------------------------------
  692.    
  693.     /**
  694.      * Enables or disables the mIRC colorcodes.
  695.      * @param colors <code>true</code> to enable, <code>false</code> to disable
  696.      *               colors.
  697.      */
  698.     public void setColors(boolean colors) {
  699.         colorsEnabled = colors;
  700.     }
  701.    
  702. // ------------------------------
  703.    
  704.     /**
  705.      * Enables or disables the automatic PING? PONG! support.
  706.      * @param pong <code>true</code> to enable automatic <code>PONG</code>
  707.      *             reply, <code>false</code> makes the class fire
  708.      *             <code>onPing</code> events.
  709.      */
  710.     public void setPong(boolean pong) {
  711.         pongAutomatic = pong;
  712.     }
  713.    
  714. // ------------------------------
  715.    
  716.     /**
  717.      * Changes the character encoding used to talk to the server.
  718.      * This can be ISO-8859-1 or UTF-8 for example.
  719.      * This property must be set before a call to the <code>connect()</code>
  720.      * method.
  721.      * @param encoding
  722.      */
  723.     public void setEncoding(String encoding) {
  724.         this.encoding   = encoding;
  725.     }
  726.    
  727. // ------------------------------
  728.    
  729.     /**
  730.      * Sets the connection's timeout in milliseconds. <br />
  731.      * The default is <code>1000 * 60 15</code> millis which are 15 minutes.
  732.      */
  733.     public void setTimeout(int millis) {
  734.         if (socket != null)
  735.             try {
  736.                 socket.setSoTimeout(millis);
  737.             } catch (IOException exc) {
  738.                 exc.printStackTrace();
  739.             }
  740.             timeout = millis;
  741.     }
  742.    
  743. // ------------------------------
  744.    
  745.     /**
  746.      * Tells whether there's a connection to the IRC network or not. <br />
  747.      * If <code>connect</code> wasn't called yet, it returns <code>false</code>.
  748.      * @return The status of the connection; <code>true</code> if it's connected.
  749.      * @see #connect()
  750.      * @see #doQuit()
  751.      * @see #doQuit(String)
  752.      * @see #close()
  753.      */
  754.     public boolean isConnected() {
  755.         return level >= 1;
  756.     }
  757.    
  758. // ------------------------------
  759.    
  760.     /**
  761.      * Returns the nickname of this instance.
  762.      * @return The nickname.
  763.      */
  764.     public String getNick() {
  765.         return nick;
  766.     }
  767.    
  768. // ------------------------------
  769.    
  770.     /**
  771.      * Returns the realname of this instance.
  772.      * @return The realname.
  773.      */
  774.     public String getRealname() {
  775.         return realname;
  776.     }
  777.    
  778. // ------------------------------
  779.    
  780.     /**
  781.      * Returns the username of this instance.
  782.      * @return The username.
  783.      */
  784.     public String getUsername() {
  785.         return username;
  786.     }
  787.    
  788. // ------------------------------
  789.    
  790.     /**
  791.      * Returns the server of this instance.
  792.      * @return The server's hostname.
  793.      */
  794.     public String getHost() {
  795.         return host;
  796.     }
  797.    
  798. // ------------------------------
  799.    
  800.     /**
  801.      * Returns the password of this instance. If no password is set,
  802.      * <code>null</code> is returned.
  803.      * @return The password. If no password is set, <code>null</code> is
  804.      *         returned.
  805.      */
  806.     public String getPassword() {
  807.         return pass;
  808.     }
  809.    
  810. // ------------------------------
  811.    
  812.     /**
  813.      * Returns all ports to which the <code>IRCConnection</code> is going to try
  814.      * or has tried to connect to.
  815.      * @return The ports in an <code>int[]</code> array.
  816.      */
  817.     public int[] getPorts() {
  818.         return ports;
  819.     }  
  820.    
  821. // ------------------------------
  822.    
  823.     /**
  824.      * Returns the port to which the <code>IRCConnection</code> connected, or
  825.      * <code>0</code> if the connection failed or wasn't tried yet.
  826.      * @return The port to which the <code>IRCConnection</code>, or
  827.      *         <code>0</code> if the connection failed or wasn't tried yet.
  828.      */
  829.     public int getPort() {
  830.         return (socket != null) ? socket.getPort() : 0;
  831.     }
  832.    
  833. // ------------------------------
  834.    
  835.     /**
  836.      * Indicates whether colors are stripped out or not.
  837.      * @return <code>true</code> if colors are disabled.
  838.      */
  839.     public boolean getColors() {
  840.         return colorsEnabled;
  841.     }
  842.    
  843. // ------------------------------
  844.    
  845.     /**
  846.      * Indicates whether automatic PING? PONG! is enabled or not.
  847.      * @return <code>true</code> if PING? PONG! is done automatically.
  848.      */
  849.     public boolean getPong() {
  850.         return pongAutomatic;
  851.     }
  852.    
  853. // ------------------------------
  854.    
  855.     /**
  856.      * Returns the encoding of the socket.
  857.      * @return The socket's encoding.
  858.      */
  859.     public String getEncoding() {
  860.         return encoding;
  861.     }
  862.    
  863. // ------------------------------
  864.    
  865.     /**
  866.      * Returns the timeout of the socket. <br />
  867.      * If an error occurs, which is never the case, <code>-1</code> is returned.
  868.      * @return The timeout.
  869.      */
  870.     public int getTimeout() {
  871.         if (socket != null)
  872.             try {
  873.                 return socket.getSoTimeout();
  874.             } catch (IOException exc) {
  875.                 exc.printStackTrace();
  876.                 return -1;
  877.             }
  878.             else
  879.                 return timeout;
  880.     }
  881.    
  882. // ------------------------------
  883.    
  884.     /**
  885.      * Generates a <code>String</code> with some information about the instance of
  886.      * <code>IRCConnection</code>.
  887.      * Its format is: <code>
  888.      * classname[host,portMin,portMax,username,nick,realname,pass,connected]
  889.      * </code>.
  890.      * @return A <code>String</code> with information about the instance.
  891.      */
  892.     public String toString() {
  893.         return getClass().getName() +"["+ host +","+ getPort() +","+ username +","+
  894.         nick +","+ realname +","+ pass +","+ isConnected() +"]";
  895.     }
  896.    
  897. // ------------------------------
  898.    
  899.     /**
  900.      * Removes away message.
  901.      */
  902.     public void doAway() {
  903.         send("AWAY");
  904.     }  
  905.    
  906. // ------------------------------
  907.    
  908.     /**
  909.      * Sets away message.
  910.      * @param msg The away message.
  911.      */
  912.     public void doAway(String msg) {
  913.         send("AWAY :"+ msg);
  914.     }  
  915.    
  916. // ------------------------------
  917.    
  918.     /**
  919.      * Invites a user to a channel.
  920.      * @param nick The nickname of the user who should be invited.
  921.      * @param chan The channel the user should be invited to.
  922.      */
  923.     public void doInvite(String nick, String chan) {
  924.         send("INVITE "+ nick +" "+ chan);
  925.     }  
  926.    
  927. // ------------------------------
  928.    
  929.     /**
  930.      * Checks if one or more nicks are used on the server.
  931.      * @param nick The nickname of the user we search for.
  932.      */
  933.     public void doIson(String nick) {
  934.         send("ISON "+ nick);
  935.     }  
  936.    
  937. // ------------------------------
  938.    
  939.     /**
  940.      * Joins a channel without a key.
  941.      * @param chan The channel which is to join.
  942.      */
  943.     public void doJoin(String chan) {
  944.         send("JOIN "+ chan);
  945.     }  
  946.    
  947. // ------------------------------
  948.    
  949.     /**
  950.      * Joins a channel with a key.
  951.      * @param chan The channel which is to join.
  952.      * @param key The key of the channel.
  953.      */
  954.     public void doJoin(String chan, String key) {
  955.         send("JOIN "+ chan +" "+ key);
  956.     }  
  957.    
  958. // ------------------------------
  959.    
  960.     /**
  961.      * Kicks a user from a channel.
  962.      * @param chan The channel somebody should be kicked from.
  963.      * @param nick The nickname of the user who should be kicked.
  964.      */
  965.     public void doKick(String chan, String nick) {
  966.         send("KICK "+ chan +" "+ nick);
  967.     }
  968.    
  969. // ------------------------------
  970.    
  971.     /**
  972.      * Kicks a user from a channel with a comment.
  973.      * @param chan The channel somebody should be kicked from.
  974.      * @param nick The nickname of the user who should be kicked.
  975.      * @param msg The optional kickmessage.
  976.      */
  977.     public void doKick(String chan, String nick, String msg) {
  978.         send("KICK "+ chan +" "+ nick +" :"+ msg);
  979.     }  
  980.    
  981. // ------------------------------
  982.    
  983.     /**
  984.      * Lists all channels with their topic and status.
  985.      */
  986.     public void doList() {
  987.         send("LIST");
  988.     }  
  989.    
  990. // ------------------------------
  991.    
  992.     /**
  993.      * Lists channel(s) with their topic and status.
  994.      * @param chan The channel the <code>LIST</code> refers to.
  995.      */
  996.     public void doList(String chan) {
  997.         send("LIST "+ chan);
  998.     }  
  999.    
  1000. // ------------------------------
  1001.    
  1002.     /**
  1003.      * Lists all visible users.
  1004.      */
  1005.     public void doNames() {
  1006.         send("NAMES");
  1007.     }  
  1008.    
  1009. // ------------------------------
  1010.    
  1011.     /**
  1012.      * Lists all visible users of (a) channel(s).
  1013.      * @param chan The channel the <code>NAMES</code> command is refering to.
  1014.      */
  1015.     public void doNames(String chan) {
  1016.         send("NAMES "+ chan);
  1017.     }  
  1018.    
  1019. // ------------------------------
  1020.    
  1021.     /**
  1022.      * Sends a message to a person or a channel.
  1023.      * @param target The nickname or channel the message should be sent to.
  1024.      * @param msg The message which should be transmitted.
  1025.      */
  1026.     public void doPrivmsg(String target, String msg) {
  1027.         send("PRIVMSG "+ target +" :"+ msg);
  1028.     }
  1029.    
  1030. // ------------------------------
  1031.    
  1032.     /**
  1033.      * Requests a Reply 324 for the modes of a given channel.
  1034.      * @param chan The channel the <code>MODE</code> request is refering to.
  1035.      */
  1036.     public void doMode(String chan) {
  1037.         send("MODE "+ chan);
  1038.     }
  1039.    
  1040. // ------------------------------
  1041.    
  1042.     /**
  1043.      * Sends a mode to the server. <br />
  1044.      * The first argument is a nickname (user-mode) or a channel (channel-mode).
  1045.      * <code>String mode</code> must contain the operators (+/-), the modes
  1046.      * (o/v/i/k/l/p/s/w) and the possibly values (nicks/banmask/limit/key).
  1047.      * @param target The nickname or channel of the user whose modes will be
  1048.      *               changed.
  1049.      * @param mode The new modes.
  1050.      */
  1051.     public void doMode(String target, String mode) {
  1052.         send("MODE "+ target +" "+ mode);
  1053.     }
  1054.    
  1055. // ------------------------------
  1056.    
  1057.     /**
  1058.      * Changes the nickname.
  1059.      * @param nick The new nickname.
  1060.      */
  1061.     public void doNick(String nick) {
  1062.         send("NICK "+ nick);
  1063.     }  
  1064.    
  1065. // ------------------------------
  1066.    
  1067.     /**
  1068.      * Notices a message to a person or a channel.
  1069.      * @param target The nickname or channel (group) the message should be
  1070.      *               sent to.
  1071.      * @param msg The message which should be transmitted.
  1072.      */
  1073.     public void doNotice(String target, String msg) {
  1074.         send("NOTICE "+ target +" :"+ msg);
  1075.     }
  1076.    
  1077. // ------------------------------
  1078.    
  1079.     /**
  1080.      * Parts from a given channel.
  1081.      * @param chan The channel you want to part from.
  1082.      */
  1083.     public void doPart(String chan) {
  1084.         send("PART "+ chan);
  1085.     }
  1086.    
  1087. // ------------------------------
  1088.    
  1089.     /**
  1090.      * Parts from a given channel with a given parg-msg.
  1091.      * @param chan The channel you want to part from.
  1092.      * @param msg The optional partmessage.
  1093.      */
  1094.     public void doPart(String chan, String msg) {
  1095.         send("PART "+ chan +" :"+ msg);
  1096.     }
  1097.    
  1098. // ------------------------------
  1099.    
  1100.     /**
  1101.      * Quits from the IRC server with a quit-msg.
  1102.      * @param ping The ping which was received in <code>onPing</code>. It's a
  1103.      *             <code>String</code>, because sometimes on some networks
  1104.      *             the server-hostname (for example splatterworld.quakenet.org) is
  1105.      *             given as parameter which would throw an Exception if we
  1106.      *             gave the ping as long.
  1107.      */
  1108.     public void doPong(String ping) {
  1109.         send("PONG :"+ ping);
  1110.     }
  1111.    
  1112. // ------------------------------
  1113.    
  1114.     /**
  1115.      * Quits from the IRC server.
  1116.      * Calls the <code>disconnect</code>-method which does the work actually.
  1117.      * @see #isConnected()
  1118.      * @see #connect()
  1119.      * @see #doQuit(String)
  1120.      * @see #close()
  1121.      */
  1122.     public void doQuit() {
  1123.         send("QUIT");
  1124.     }
  1125.    
  1126. // ------------------------------
  1127.    
  1128.     /**
  1129.      * Quits from the IRC server with a quit-msg.
  1130.      * Calls the <code>disconnect</code>-method which does the work actually.
  1131.      * @param msg The optional quitmessage.
  1132.      * @see #isConnected()
  1133.      * @see #connect()
  1134.      * @see #doQuit()
  1135.      * @see #close()
  1136.      */
  1137.     public void doQuit(String msg) {
  1138.         send("QUIT :"+ msg);
  1139.     }
  1140.    
  1141. // ------------------------------
  1142.    
  1143.     /**
  1144.      * Requests the topic of a chan. The topic is given in a numeric reply.
  1145.      * @param chan The channel which topic should be requested.
  1146.      */
  1147.     public void doTopic(String chan) {
  1148.         send("TOPIC "+ chan);
  1149.     }  
  1150.    
  1151. // ------------------------------
  1152.    
  1153.     /**
  1154.      * Changes the topic of a chan.
  1155.      * @param chan The channel which topic is changed.
  1156.      * @param topic The new topic.
  1157.      */
  1158.     public void doTopic(String chan, String topic) {
  1159.         send("TOPIC "+ chan +" :"+ topic);
  1160.     }  
  1161.    
  1162. // ------------------------------
  1163.    
  1164.     /**
  1165.      * Requests information about users matching the given criteric,
  1166.      * for example a channel they are on.
  1167.      * @param criteric The criterics of the <code>WHO</code> query.
  1168.      */
  1169.     public void doWho(String criteric) {
  1170.         send("WHO "+ criteric);
  1171.     }  
  1172.    
  1173. // ------------------------------
  1174.    
  1175.     /**
  1176.      * Requires information about an existing user.
  1177.      * @param nick The nickname of the user the query is refering to.
  1178.      */
  1179.     public void doWhois(String nick) {
  1180.         send("WHOIS "+ nick);
  1181.     }  
  1182.    
  1183. // ------------------------------
  1184.    
  1185.     /**
  1186.      * Requires host-information about a user, who is not connected anymore.
  1187.      * @param nick The nickname of the user the query is refering to.
  1188.      */
  1189.     public void doWhowas(String nick) {
  1190.         send("WHOWAS "+ nick);
  1191.     }
  1192.    
  1193. // ------------------------------
  1194.    
  1195.     /**
  1196.      * Requires host-information about up to 5 users which must be listed and
  1197.      * divided by spaces.
  1198.      * @param nick The nickname of the user the query is refering to.
  1199.      */
  1200.     public void doUserhost(String nick) {
  1201.         send("USERHOST "+ nick);
  1202.     }
  1203.    
  1204.     public long getDataReceived() {
  1205.         return data_in;
  1206.     }
  1207.    
  1208.     public long getDataSent() {
  1209.         return data_out;
  1210.     }  
  1211. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement