diff --git a/src/org/jibble/pircbot/Colors.java b/src/org/jibble/pircbot/Colors.java index 29286a1..b8f7a60 100644 --- a/src/org/jibble/pircbot/Colors.java +++ b/src/org/jibble/pircbot/Colors.java @@ -1,293 +1,293 @@ -/* -Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/ - -This file is part of PircBot. - -This software is dual-licensed, allowing you to choose between the GNU -General Public License (GPL) and the www.jibble.org Commercial License. -Since the GPL may be too restrictive for use in a proprietary application, -a commercial license is also provided. Full license information can be -found at http://www.jibble.org/licenses/ - -*/ - - -package org.jibble.pircbot; - -/** - * The Colors class provides several static fields and methods that you may - * find useful when writing an IRC Bot. - *
- * This class contains constants that are useful for formatting lines - * sent to IRC servers. These constants allow you to apply various - * formatting to the lines, such as colours, boldness, underlining - * and reverse text. - *
- * The class contains static methods to remove colours and formatting - * from lines of IRC text. - *
- * Here are some examples of how to use the contants from within a - * class that extends PircBot and imports org.jibble.pircbot.*; - * - *
sendMessage("#cs", Colors.BOLD + "A bold hello!"); - * A bold hello! - * sendMessage("#cs", Colors.RED + "Red" + Colors.NORMAL + " text"); - * Red text - * sendMessage("#cs", Colors.BOLD + Colors.RED + "Bold and red"); - * Bold and red- * - * Please note that some IRC channels may be configured to reject any - * messages that use colours. Also note that older IRC clients may be - * unable to correctly display lines that contain colours and other - * control characters. - *
- * Note that this class name has been spelt in the American style in - * order to remain consistent with the rest of the Java API. - * - * - * @since 0.9.12 - * @author Paul James Mutton, - * http://www.jibble.org/ - * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007) - */ -public class Colors { - - - /** - * Removes all previously applied color and formatting attributes. - */ - public static final String NORMAL = "\u000f"; - - - /** - * Bold text. - */ - public static final String BOLD = "\u0002"; - - - /** - * Underlined text. - */ - public static final String UNDERLINE = "\u001f"; - - - /** - * Reversed text (may be rendered as italic text in some clients). - */ - public static final String REVERSE = "\u0016"; - - - /** - * White coloured text. - */ - public static final String WHITE = "\u000300"; - - - /** - * Black coloured text. - */ - public static final String BLACK = "\u000301"; - - - /** - * Dark blue coloured text. - */ - public static final String DARK_BLUE = "\u000302"; - - - /** - * Dark green coloured text. - */ - public static final String DARK_GREEN = "\u000303"; - - - /** - * Red coloured text. - */ - public static final String RED = "\u000304"; - - - /** - * Brown coloured text. - */ - public static final String BROWN = "\u000305"; - - - /** - * Purple coloured text. - */ - public static final String PURPLE = "\u000306"; - - - /** - * Olive coloured text. - */ - public static final String OLIVE = "\u000307"; - - - /** - * Yellow coloured text. - */ - public static final String YELLOW = "\u000308"; - - - /** - * Green coloured text. - */ - public static final String GREEN = "\u000309"; - - - /** - * Teal coloured text. - */ - public static final String TEAL = "\u000310"; - - - /** - * Cyan coloured text. - */ - public static final String CYAN = "\u000311"; - - - /** - * Blue coloured text. - */ - public static final String BLUE = "\u000312"; - - - /** - * Magenta coloured text. - */ - public static final String MAGENTA = "\u000313"; - - - /** - * Dark gray coloured text. - */ - public static final String DARK_GRAY = "\u000314"; - - - /** - * Light gray coloured text. - */ - public static final String LIGHT_GRAY = "\u000315"; - - - /** - * This class should not be constructed. - */ - private Colors() { - - } - - - /** - * Removes all colours from a line of IRC text. - * - * @since PircBot 1.2.0 - * - * @param line the input text. - * - * @return the same text, but with all colours removed. - */ - public static String removeColors(String line) { - int length = line.length(); - StringBuffer buffer = new StringBuffer(); - int i = 0; - while (i < length) { - char ch = line.charAt(i); - if (ch == '\u0003') { - i++; - // Skip "x" or "xy" (foreground color). - if (i < length) { - ch = line.charAt(i); - if (Character.isDigit(ch)) { - i++; - if (i < length) { - ch = line.charAt(i); - if (Character.isDigit(ch)) { - i++; - } - } - // Now skip ",x" or ",xy" (background color). - if (i < length) { - ch = line.charAt(i); - if (ch == ',') { - i++; - if (i < length) { - ch = line.charAt(i); - if (Character.isDigit(ch)) { - i++; - if (i < length) { - ch = line.charAt(i); - if (Character.isDigit(ch)) { - i++; - } - } - } - else { - // Keep the comma. - i--; - } - } - else { - // Keep the comma. - i--; - } - } - } - } - } - } - else if (ch == '\u000f') { - i++; - } - else { - buffer.append(ch); - i++; - } - } - return buffer.toString(); - } - - - /** - * Remove formatting from a line of IRC text. - * - * @since PircBot 1.2.0 - * - * @param line the input text. - * - * @return the same text, but without any bold, underlining, reverse, etc. - */ - public static String removeFormatting(String line) { - int length = line.length(); - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < length; i++) { - char ch = line.charAt(i); - if (ch == '\u000f' || ch == '\u0002' || ch == '\u001f' || ch == '\u0016') { - // Don't add this character. - } - else { - buffer.append(ch); - } - } - return buffer.toString(); - } - - - /** - * Removes all formatting and colours from a line of IRC text. - * - * @since PircBot 1.2.0 - * - * @param line the input text. - * - * @return the same text, but without formatting and colour characters. - * - */ - public static String removeFormattingAndColors(String line) { - return removeFormatting(removeColors(line)); - } - -} +/* +Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/ + +This file is part of PircBot. + +This software is dual-licensed, allowing you to choose between the GNU +General Public License (GPL) and the www.jibble.org Commercial License. +Since the GPL may be too restrictive for use in a proprietary application, +a commercial license is also provided. Full license information can be +found at http://www.jibble.org/licenses/ + +*/ + + +package org.jibble.pircbot; + +/** + * The Colors class provides several static fields and methods that you may + * find useful when writing an IRC Bot. + *
+ * This class contains constants that are useful for formatting lines + * sent to IRC servers. These constants allow you to apply various + * formatting to the lines, such as colours, boldness, underlining + * and reverse text. + *
+ * The class contains static methods to remove colours and formatting + * from lines of IRC text. + *
+ * Here are some examples of how to use the contants from within a + * class that extends PircBot and imports org.jibble.pircbot.*; + * + *
sendMessage("#cs", Colors.BOLD + "A bold hello!"); + * A bold hello! + * sendMessage("#cs", Colors.RED + "Red" + Colors.NORMAL + " text"); + * Red text + * sendMessage("#cs", Colors.BOLD + Colors.RED + "Bold and red"); + * Bold and red+ * + * Please note that some IRC channels may be configured to reject any + * messages that use colours. Also note that older IRC clients may be + * unable to correctly display lines that contain colours and other + * control characters. + *
+ * Note that this class name has been spelt in the American style in
+ * order to remain consistent with the rest of the Java API.
+ *
+ *
+ * @since 0.9.12
+ * @author Paul James Mutton,
+ * http://www.jibble.org/
+ * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
+ */
+public class Colors {
+
+
+ /**
+ * Removes all previously applied color and formatting attributes.
+ */
+ public static final String NORMAL = "\u000f";
+
+
+ /**
+ * Bold text.
+ */
+ public static final String BOLD = "\u0002";
+
+
+ /**
+ * Underlined text.
+ */
+ public static final String UNDERLINE = "\u001f";
+
+
+ /**
+ * Reversed text (may be rendered as italic text in some clients).
+ */
+ public static final String REVERSE = "\u0016";
+
+
+ /**
+ * White coloured text.
+ */
+ public static final String WHITE = "\u000300";
+
+
+ /**
+ * Black coloured text.
+ */
+ public static final String BLACK = "\u000301";
+
+
+ /**
+ * Dark blue coloured text.
+ */
+ public static final String DARK_BLUE = "\u000302";
+
+
+ /**
+ * Dark green coloured text.
+ */
+ public static final String DARK_GREEN = "\u000303";
+
+
+ /**
+ * Red coloured text.
+ */
+ public static final String RED = "\u000304";
+
+
+ /**
+ * Brown coloured text.
+ */
+ public static final String BROWN = "\u000305";
+
+
+ /**
+ * Purple coloured text.
+ */
+ public static final String PURPLE = "\u000306";
+
+
+ /**
+ * Olive coloured text.
+ */
+ public static final String OLIVE = "\u000307";
+
+
+ /**
+ * Yellow coloured text.
+ */
+ public static final String YELLOW = "\u000308";
+
+
+ /**
+ * Green coloured text.
+ */
+ public static final String GREEN = "\u000309";
+
+
+ /**
+ * Teal coloured text.
+ */
+ public static final String TEAL = "\u000310";
+
+
+ /**
+ * Cyan coloured text.
+ */
+ public static final String CYAN = "\u000311";
+
+
+ /**
+ * Blue coloured text.
+ */
+ public static final String BLUE = "\u000312";
+
+
+ /**
+ * Magenta coloured text.
+ */
+ public static final String MAGENTA = "\u000313";
+
+
+ /**
+ * Dark gray coloured text.
+ */
+ public static final String DARK_GRAY = "\u000314";
+
+
+ /**
+ * Light gray coloured text.
+ */
+ public static final String LIGHT_GRAY = "\u000315";
+
+
+ /**
+ * This class should not be constructed.
+ */
+ private Colors() {
+
+ }
+
+
+ /**
+ * Removes all colours from a line of IRC text.
+ *
+ * @since PircBot 1.2.0
+ *
+ * @param line the input text.
+ *
+ * @return the same text, but with all colours removed.
+ */
+ public static String removeColors(String line) {
+ int length = line.length();
+ StringBuffer buffer = new StringBuffer();
+ int i = 0;
+ while (i < length) {
+ char ch = line.charAt(i);
+ if (ch == '\u0003') {
+ i++;
+ // Skip "x" or "xy" (foreground color).
+ if (i < length) {
+ ch = line.charAt(i);
+ if (Character.isDigit(ch)) {
+ i++;
+ if (i < length) {
+ ch = line.charAt(i);
+ if (Character.isDigit(ch)) {
+ i++;
+ }
+ }
+ // Now skip ",x" or ",xy" (background color).
+ if (i < length) {
+ ch = line.charAt(i);
+ if (ch == ',') {
+ i++;
+ if (i < length) {
+ ch = line.charAt(i);
+ if (Character.isDigit(ch)) {
+ i++;
+ if (i < length) {
+ ch = line.charAt(i);
+ if (Character.isDigit(ch)) {
+ i++;
+ }
+ }
+ }
+ else {
+ // Keep the comma.
+ i--;
+ }
+ }
+ else {
+ // Keep the comma.
+ i--;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (ch == '\u000f') {
+ i++;
+ }
+ else {
+ buffer.append(ch);
+ i++;
+ }
+ }
+ return buffer.toString();
+ }
+
+
+ /**
+ * Remove formatting from a line of IRC text.
+ *
+ * @since PircBot 1.2.0
+ *
+ * @param line the input text.
+ *
+ * @return the same text, but without any bold, underlining, reverse, etc.
+ */
+ public static String removeFormatting(String line) {
+ int length = line.length();
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < length; i++) {
+ char ch = line.charAt(i);
+ if (ch == '\u000f' || ch == '\u0002' || ch == '\u001f' || ch == '\u0016') {
+ // Don't add this character.
+ }
+ else {
+ buffer.append(ch);
+ }
+ }
+ return buffer.toString();
+ }
+
+
+ /**
+ * Removes all formatting and colours from a line of IRC text.
+ *
+ * @since PircBot 1.2.0
+ *
+ * @param line the input text.
+ *
+ * @return the same text, but without formatting and colour characters.
+ *
+ */
+ public static String removeFormattingAndColors(String line) {
+ return removeFormatting(removeColors(line));
+ }
+
+}
diff --git a/src/org/jibble/pircbot/DccChat.java b/src/org/jibble/pircbot/DccChat.java
index 2119d2e..78ce9cf 100644
--- a/src/org/jibble/pircbot/DccChat.java
+++ b/src/org/jibble/pircbot/DccChat.java
@@ -1,227 +1,227 @@
-/*
-Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
-
-This file is part of PircBot.
-
-This software is dual-licensed, allowing you to choose between the GNU
-General Public License (GPL) and the www.jibble.org Commercial License.
-Since the GPL may be too restrictive for use in a proprietary application,
-a commercial license is also provided. Full license information can be
-found at http://www.jibble.org/licenses/
-
-*/
-
-
-package org.jibble.pircbot;
-
-import java.net.*;
-import java.io.*;
-
-/**
- * This class is used to allow the bot to interact with a DCC Chat session.
- *
- * @since 0.9c
- * @author Paul James Mutton,
- * http://www.jibble.org/
- * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
- */
-public class DccChat {
-
-
- /**
- * This constructor is used when we are accepting a DCC CHAT request
- * from somebody. It attempts to connect to the client that issued the
- * request.
- *
- * @param bot An instance of the underlying PircBot.
- * @param sourceNick The nick of the sender.
- * @param address The address to connect to.
- * @param port The port number to connect to.
- *
- * @throws IOException If the connection cannot be made.
- */
- DccChat(PircBot bot, String nick, String login, String hostname, long address, int port) {
- _bot = bot;
- _address = address;
- _port = port;
- _nick = nick;
- _login = login;
- _hostname = hostname;
- _acceptable = true;
- }
-
-
- /**
- * This constructor is used after we have issued a DCC CHAT request to
- * somebody. If the client accepts the chat request, then the socket we
- * obtain is passed to this constructor.
- *
- * @param bot An instance of the underlying PircBot.
- * @param sourceNick The nick of the user we are sending the request to.
- * @param socket The socket which will be used for the DCC CHAT session.
- *
- * @throws IOException If the socket cannot be read from.
- */
- DccChat(PircBot bot, String nick, Socket socket) throws IOException {
- _bot = bot;
- _nick = nick;
- _socket = socket;
- _reader = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
- _writer = new BufferedWriter(new OutputStreamWriter(_socket.getOutputStream()));
- _acceptable = false;
- }
-
-
- /**
- * Accept this DccChat connection.
- *
- * @since 1.2.0
- *
- */
- public synchronized void accept() throws IOException {
- if (_acceptable) {
- _acceptable = false;
- int[] ip = _bot.longToIp(_address);
- String ipStr = ip[0] + "." + ip[1] + "." + ip[2] + "." + ip[3];
- _socket = new Socket(ipStr, _port);
- _reader = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
- _writer = new BufferedWriter(new OutputStreamWriter(_socket.getOutputStream()));
- }
- }
-
-
- /**
- * Reads the next line of text from the client at the other end of our DCC Chat
- * connection. This method blocks until something can be returned.
- * If the connection has closed, null is returned.
- *
- * @return The next line of text from the client. Returns null if the
- * connection has closed normally.
- *
- * @throws IOException If an I/O error occurs.
- */
- public String readLine() throws IOException {
- if (_acceptable) {
- throw new IOException("You must call the accept() method of the DccChat request before you can use it.");
- }
- return _reader.readLine();
- }
-
-
- /**
- * Sends a line of text to the client at the other end of our DCC Chat
- * connection.
- *
- * @param line The line of text to be sent. This should not include
- * linefeed characters.
- *
- * @throws IOException If an I/O error occurs.
- */
- public void sendLine(String line) throws IOException {
- if (_acceptable) {
- throw new IOException("You must call the accept() method of the DccChat request before you can use it.");
- }
- // No need for synchronization here really...
- _writer.write(line + "\r\n");
- _writer.flush();
- }
-
-
- /**
- * Closes the DCC Chat connection.
- *
- * @throws IOException If an I/O error occurs.
- */
- public void close() throws IOException {
- if (_acceptable) {
- throw new IOException("You must call the accept() method of the DccChat request before you can use it.");
- }
- _socket.close();
- }
-
-
- /**
- * Returns the nick of the other user taking part in this file transfer.
- *
- * @return the nick of the other user.
- *
- */
- public String getNick() {
- return _nick;
- }
-
-
- /**
- * Returns the login of the DCC Chat initiator.
- *
- * @return the login of the DCC Chat initiator. null if we sent it.
- *
- */
- public String getLogin() {
- return _login;
- }
-
-
- /**
- * Returns the hostname of the DCC Chat initiator.
- *
- * @return the hostname of the DCC Chat initiator. null if we sent it.
- *
- */
- public String getHostname() {
- return _hostname;
- }
-
-
- /**
- * Returns the BufferedReader used by this DCC Chat.
- *
- * @return the BufferedReader used by this DCC Chat.
- */
- public BufferedReader getBufferedReader() {
- return _reader;
- }
-
-
- /**
- * Returns the BufferedReader used by this DCC Chat.
- *
- * @return the BufferedReader used by this DCC Chat.
- */
- public BufferedWriter getBufferedWriter() {
- return _writer;
- }
-
-
- /**
- * Returns the raw Socket used by this DCC Chat.
- *
- * @return the raw Socket used by this DCC Chat.
- */
- public Socket getSocket() {
- return _socket;
- }
-
-
- /**
- * Returns the address of the sender as a long.
- *
- * @return the address of the sender as a long.
- */
- public long getNumericalAddress() {
- return _address;
- }
-
-
- private PircBot _bot;
- private String _nick;
- private String _login = null;
- private String _hostname = null;
- private BufferedReader _reader;
- private BufferedWriter _writer;
- private Socket _socket;
- private boolean _acceptable;
- private long _address = 0;
- private int _port = 0;
-
-}
+/*
+Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
+
+This file is part of PircBot.
+
+This software is dual-licensed, allowing you to choose between the GNU
+General Public License (GPL) and the www.jibble.org Commercial License.
+Since the GPL may be too restrictive for use in a proprietary application,
+a commercial license is also provided. Full license information can be
+found at http://www.jibble.org/licenses/
+
+*/
+
+
+package org.jibble.pircbot;
+
+import java.net.*;
+import java.io.*;
+
+/**
+ * This class is used to allow the bot to interact with a DCC Chat session.
+ *
+ * @since 0.9c
+ * @author Paul James Mutton,
+ * http://www.jibble.org/
+ * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
+ */
+public class DccChat {
+
+
+ /**
+ * This constructor is used when we are accepting a DCC CHAT request
+ * from somebody. It attempts to connect to the client that issued the
+ * request.
+ *
+ * @param bot An instance of the underlying PircBot.
+ * @param sourceNick The nick of the sender.
+ * @param address The address to connect to.
+ * @param port The port number to connect to.
+ *
+ * @throws IOException If the connection cannot be made.
+ */
+ DccChat(PircBot bot, String nick, String login, String hostname, long address, int port) {
+ _bot = bot;
+ _address = address;
+ _port = port;
+ _nick = nick;
+ _login = login;
+ _hostname = hostname;
+ _acceptable = true;
+ }
+
+
+ /**
+ * This constructor is used after we have issued a DCC CHAT request to
+ * somebody. If the client accepts the chat request, then the socket we
+ * obtain is passed to this constructor.
+ *
+ * @param bot An instance of the underlying PircBot.
+ * @param sourceNick The nick of the user we are sending the request to.
+ * @param socket The socket which will be used for the DCC CHAT session.
+ *
+ * @throws IOException If the socket cannot be read from.
+ */
+ DccChat(PircBot bot, String nick, Socket socket) throws IOException {
+ _bot = bot;
+ _nick = nick;
+ _socket = socket;
+ _reader = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
+ _writer = new BufferedWriter(new OutputStreamWriter(_socket.getOutputStream()));
+ _acceptable = false;
+ }
+
+
+ /**
+ * Accept this DccChat connection.
+ *
+ * @since 1.2.0
+ *
+ */
+ public synchronized void accept() throws IOException {
+ if (_acceptable) {
+ _acceptable = false;
+ int[] ip = _bot.longToIp(_address);
+ String ipStr = ip[0] + "." + ip[1] + "." + ip[2] + "." + ip[3];
+ _socket = new Socket(ipStr, _port);
+ _reader = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
+ _writer = new BufferedWriter(new OutputStreamWriter(_socket.getOutputStream()));
+ }
+ }
+
+
+ /**
+ * Reads the next line of text from the client at the other end of our DCC Chat
+ * connection. This method blocks until something can be returned.
+ * If the connection has closed, null is returned.
+ *
+ * @return The next line of text from the client. Returns null if the
+ * connection has closed normally.
+ *
+ * @throws IOException If an I/O error occurs.
+ */
+ public String readLine() throws IOException {
+ if (_acceptable) {
+ throw new IOException("You must call the accept() method of the DccChat request before you can use it.");
+ }
+ return _reader.readLine();
+ }
+
+
+ /**
+ * Sends a line of text to the client at the other end of our DCC Chat
+ * connection.
+ *
+ * @param line The line of text to be sent. This should not include
+ * linefeed characters.
+ *
+ * @throws IOException If an I/O error occurs.
+ */
+ public void sendLine(String line) throws IOException {
+ if (_acceptable) {
+ throw new IOException("You must call the accept() method of the DccChat request before you can use it.");
+ }
+ // No need for synchronization here really...
+ _writer.write(line + "\r\n");
+ _writer.flush();
+ }
+
+
+ /**
+ * Closes the DCC Chat connection.
+ *
+ * @throws IOException If an I/O error occurs.
+ */
+ public void close() throws IOException {
+ if (_acceptable) {
+ throw new IOException("You must call the accept() method of the DccChat request before you can use it.");
+ }
+ _socket.close();
+ }
+
+
+ /**
+ * Returns the nick of the other user taking part in this file transfer.
+ *
+ * @return the nick of the other user.
+ *
+ */
+ public String getNick() {
+ return _nick;
+ }
+
+
+ /**
+ * Returns the login of the DCC Chat initiator.
+ *
+ * @return the login of the DCC Chat initiator. null if we sent it.
+ *
+ */
+ public String getLogin() {
+ return _login;
+ }
+
+
+ /**
+ * Returns the hostname of the DCC Chat initiator.
+ *
+ * @return the hostname of the DCC Chat initiator. null if we sent it.
+ *
+ */
+ public String getHostname() {
+ return _hostname;
+ }
+
+
+ /**
+ * Returns the BufferedReader used by this DCC Chat.
+ *
+ * @return the BufferedReader used by this DCC Chat.
+ */
+ public BufferedReader getBufferedReader() {
+ return _reader;
+ }
+
+
+ /**
+ * Returns the BufferedReader used by this DCC Chat.
+ *
+ * @return the BufferedReader used by this DCC Chat.
+ */
+ public BufferedWriter getBufferedWriter() {
+ return _writer;
+ }
+
+
+ /**
+ * Returns the raw Socket used by this DCC Chat.
+ *
+ * @return the raw Socket used by this DCC Chat.
+ */
+ public Socket getSocket() {
+ return _socket;
+ }
+
+
+ /**
+ * Returns the address of the sender as a long.
+ *
+ * @return the address of the sender as a long.
+ */
+ public long getNumericalAddress() {
+ return _address;
+ }
+
+
+ private PircBot _bot;
+ private String _nick;
+ private String _login = null;
+ private String _hostname = null;
+ private BufferedReader _reader;
+ private BufferedWriter _writer;
+ private Socket _socket;
+ private boolean _acceptable;
+ private long _address = 0;
+ private int _port = 0;
+
+}
diff --git a/src/org/jibble/pircbot/DccFileTransfer.java b/src/org/jibble/pircbot/DccFileTransfer.java
index dd8b2cc..bad4b7d 100644
--- a/src/org/jibble/pircbot/DccFileTransfer.java
+++ b/src/org/jibble/pircbot/DccFileTransfer.java
@@ -1,505 +1,505 @@
-/*
-Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
-
-This file is part of PircBot.
-
-This software is dual-licensed, allowing you to choose between the GNU
-General Public License (GPL) and the www.jibble.org Commercial License.
-Since the GPL may be too restrictive for use in a proprietary application,
-a commercial license is also provided. Full license information can be
-found at http://www.jibble.org/licenses/
-
-*/
-
-
-package org.jibble.pircbot;
-
-import java.net.*;
-import java.io.*;
-
-/**
- * This class is used to administer a DCC file transfer.
- *
- * @since 1.2.0
- * @author Paul James Mutton,
- * http://www.jibble.org/
- * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
- */
-public class DccFileTransfer {
-
- /**
- * The default buffer size to use when sending and receiving files.
- */
- public static final int BUFFER_SIZE = 1024;
-
-
- /**
- * Constructor used for receiving files.
- */
- DccFileTransfer(PircBot bot, DccManager manager, String nick, String login, String hostname, String type, String filename, long address, int port, long size) {
- _bot = bot;
- _manager = manager;
- _nick = nick;
- _login = login;
- _hostname = hostname;
- _type = type;
- _file = new File(filename);
- _address = address;
- _port = port;
- _size = size;
- _received = false;
-
- _incoming = true;
- }
-
-
- /**
- * Constructor used for sending files.
- */
- DccFileTransfer(PircBot bot, DccManager manager, File file, String nick, int timeout) {
- _bot = bot;
- _manager = manager;
- _nick = nick;
- _file = file;
- _size = file.length();
- _timeout = timeout;
- _received = true;
-
- _incoming = false;
- }
-
-
- /**
- * Receives a DccFileTransfer and writes it to the specified file.
- * Resuming allows a partial download to be continue from the end of
- * the current file contents.
- *
- * @param file The file to write to.
- * @param resume True if you wish to try and resume the download instead
- * of overwriting an existing file.
- *
- */
- public synchronized void receive(File file, boolean resume) {
- if (!_received) {
- _received = true;
- _file = file;
-
- if (_type.equals("SEND") && resume) {
- _progress = file.length();
- if (_progress == 0) {
- doReceive(file, false);
- }
- else {
- _bot.sendCTCPCommand(_nick, "DCC RESUME file.ext " + _port + " " + _progress);
- _manager.addAwaitingResume(this);
- }
- }
- else {
- _progress = file.length();
- doReceive(file, resume);
- }
- }
- }
-
-
- /**
- * Receive the file in a new thread.
- */
- void doReceive(final File file, final boolean resume) {
- new Thread() {
- public void run() {
-
- BufferedOutputStream foutput = null;
- Exception exception = null;
-
- try {
-
- // Convert the integer address to a proper IP address.
- int[] ip = _bot.longToIp(_address);
- String ipStr = ip[0] + "." + ip[1] + "." + ip[2] + "." + ip[3];
-
- // Connect the socket and set a timeout.
- _socket = new Socket(ipStr, _port);
- _socket.setSoTimeout(30*1000);
- _startTime = System.currentTimeMillis();
-
- // No longer possible to resume this transfer once it's underway.
- _manager.removeAwaitingResume(DccFileTransfer.this);
-
- BufferedInputStream input = new BufferedInputStream(_socket.getInputStream());
- BufferedOutputStream output = new BufferedOutputStream(_socket.getOutputStream());
-
- // Following line fixed for jdk 1.1 compatibility.
- foutput = new BufferedOutputStream(new FileOutputStream(file.getCanonicalPath(), resume));
-
- byte[] inBuffer = new byte[BUFFER_SIZE];
- byte[] outBuffer = new byte[4];
- int bytesRead = 0;
- while ((bytesRead = input.read(inBuffer, 0, inBuffer.length)) != -1) {
- foutput.write(inBuffer, 0, bytesRead);
- _progress += bytesRead;
- // Send back an acknowledgement of how many bytes we have got so far.
- outBuffer[0] = (byte) ((_progress >> 24) & 0xff);
- outBuffer[1] = (byte) ((_progress >> 16) & 0xff);
- outBuffer[2] = (byte) ((_progress >> 8) & 0xff);
- outBuffer[3] = (byte) ((_progress >> 0) & 0xff);
- output.write(outBuffer);
- output.flush();
- delay();
- }
- foutput.flush();
- }
- catch (Exception e) {
- exception = e;
- }
- finally {
- try {
- foutput.close();
- _socket.close();
- }
- catch (Exception anye) {
- // Do nothing.
- }
- }
-
- _bot.onFileTransferFinished(DccFileTransfer.this, exception);
- }
- }.start();
- }
-
-
- /**
- * Method to send the file inside a new thread.
- */
- void doSend(final boolean allowResume) {
- new Thread() {
- public void run() {
-
- BufferedInputStream finput = null;
- Exception exception = null;
-
- try {
-
- ServerSocket ss = null;
-
- int[] ports = _bot.getDccPorts();
- if (ports == null) {
- // Use any free port.
- ss = new ServerSocket(0);
- }
- else {
- for (int i = 0; i < ports.length; i++) {
- try {
- ss = new ServerSocket(ports[i]);
- // Found a port number we could use.
- break;
- }
- catch (Exception e) {
- // Do nothing; go round and try another port.
- }
- }
- if (ss == null) {
- // No ports could be used.
- throw new IOException("All ports returned by getDccPorts() are in use.");
- }
- }
-
- ss.setSoTimeout(_timeout);
- _port = ss.getLocalPort();
- InetAddress inetAddress = _bot.getDccInetAddress();
- if (inetAddress == null) {
- inetAddress = _bot.getInetAddress();
- }
- byte[] ip = inetAddress.getAddress();
- long ipNum = _bot.ipToLong(ip);
-
- // Rename the filename so it has no whitespace in it when we send it.
- // .... I really should do this a bit more nicely at some point ....
- String safeFilename = _file.getName().replace(' ', '_');
- safeFilename = safeFilename.replace('\t', '_');
-
- if (allowResume) {
- _manager.addAwaitingResume(DccFileTransfer.this);
- }
-
- // Send the message to the user, telling them where to connect to in order to get the file.
- _bot.sendCTCPCommand(_nick, "DCC SEND " + safeFilename + " " + ipNum + " " + _port + " " + _file.length());
-
- // The client may now connect to us and download the file.
- _socket = ss.accept();
- _socket.setSoTimeout(30000);
- _startTime = System.currentTimeMillis();
-
- // No longer possible to resume this transfer once it's underway.
- if (allowResume) {
- _manager.removeAwaitingResume(DccFileTransfer.this);
- }
-
- // Might as well close the server socket now; it's finished with.
- ss.close();
-
- BufferedOutputStream output = new BufferedOutputStream(_socket.getOutputStream());
- BufferedInputStream input = new BufferedInputStream(_socket.getInputStream());
- finput = new BufferedInputStream(new FileInputStream(_file));
-
- // Check for resuming.
- if (_progress > 0) {
- long bytesSkipped = 0;
- while (bytesSkipped < _progress) {
- bytesSkipped += finput.skip(_progress - bytesSkipped);
- }
- }
-
- byte[] outBuffer = new byte[BUFFER_SIZE];
- byte[] inBuffer = new byte[4];
- int bytesRead = 0;
- while ((bytesRead = finput.read(outBuffer, 0, outBuffer.length)) != -1) {
- output.write(outBuffer, 0, bytesRead);
- output.flush();
- input.read(inBuffer, 0, inBuffer.length);
- _progress += bytesRead;
- delay();
- }
- }
- catch (Exception e) {
- exception = e;
- }
- finally {
- try {
- finput.close();
- _socket.close();
- }
- catch (Exception e) {
- // Do nothing.
- }
- }
-
- _bot.onFileTransferFinished(DccFileTransfer.this, exception);
- }
- }.start();
- }
-
-
- /**
- * Package mutator for setting the progress of the file transfer.
- */
- void setProgress(long progress) {
- _progress = progress;
- }
-
-
- /**
- * Delay between packets.
- */
- private void delay() {
- if (_packetDelay > 0) {
- try {
- Thread.sleep(_packetDelay);
- }
- catch (InterruptedException e) {
- // Do nothing.
- }
- }
- }
-
-
- /**
- * Returns the nick of the other user taking part in this file transfer.
- *
- * @return the nick of the other user.
- *
- */
- public String getNick() {
- return _nick;
- }
-
-
- /**
- * Returns the login of the file sender.
- *
- * @return the login of the file sender. null if we are sending.
- *
- */
- public String getLogin() {
- return _login;
- }
-
-
- /**
- * Returns the hostname of the file sender.
- *
- * @return the hostname of the file sender. null if we are sending.
- *
- */
- public String getHostname() {
- return _hostname;
- }
-
-
- /**
- * Returns the suggested file to be used for this transfer.
- *
- * @return the suggested file to be used.
- *
- */
- public File getFile() {
- return _file;
- }
-
-
- /**
- * Returns the port number to be used when making the connection.
- *
- * @return the port number.
- *
- */
- public int getPort() {
- return _port;
- }
-
-
- /**
- * Returns true if the file transfer is incoming (somebody is sending
- * the file to us).
- *
- * @return true if the file transfer is incoming.
- *
- */
- public boolean isIncoming() {
- return _incoming;
- }
-
-
- /**
- * Returns true if the file transfer is outgoing (we are sending the
- * file to someone).
- *
- * @return true if the file transfer is outgoing.
- *
- */
- public boolean isOutgoing() {
- return !isIncoming();
- }
-
-
- /**
- * Sets the delay time between sending or receiving each packet.
- * Default is 0.
- * This is useful for throttling the speed of file transfers to maintain
- * a good quality of service for other things on the machine or network.
- *
- * @param millis The number of milliseconds to wait between packets.
- *
- */
- public void setPacketDelay(long millis) {
- _packetDelay = millis;
- }
-
-
- /**
- * returns the delay time between each packet that is send or received.
- *
- * @return the delay between each packet.
- *
- */
- public long getPacketDelay() {
- return _packetDelay;
- }
-
-
- /**
- * Returns the size (in bytes) of the file being transfered.
- *
- * @return the size of the file. Returns -1 if the sender did not
- * specify this value.
- */
- public long getSize() {
- return _size;
- }
-
-
- /**
- * Returns the progress (in bytes) of the current file transfer.
- * When resuming, this represents the total number of bytes in the
- * file, which may be greater than the amount of bytes resumed in
- * just this transfer.
- *
- * @return the progress of the transfer.
- */
- public long getProgress() {
- return _progress;
- }
-
-
- /**
- * Returns the progress of the file transfer as a percentage.
- * Note that this should never be negative, but could become
- * greater than 100% if you attempt to resume a larger file
- * onto a partially downloaded file that was smaller.
- *
- * @return the progress of the transfer as a percentage.
- */
- public double getProgressPercentage() {
- return 100 * (getProgress() / (double) getSize());
- }
-
-
- /**
- * Stops the DCC file transfer by closing the connection.
- */
- public void close() {
- try {
- _socket.close();
- }
- catch (Exception e) {
- // Let the DCC manager worry about anything that may go wrong.
- }
- }
-
-
- /**
- * Returns the rate of data transfer in bytes per second.
- * This value is an estimate based on the number of bytes
- * transfered since the connection was established.
- *
- * @return data transfer rate in bytes per second.
- */
- public long getTransferRate() {
- long time = (System.currentTimeMillis() - _startTime) / 1000;
- if (time <= 0) {
- return 0;
- }
- return getProgress() / time;
- }
-
- /**
- * Returns the address of the sender as a long.
- *
- * @return the address of the sender as a long.
- */
- public long getNumericalAddress() {
- return _address;
- }
-
-
- private PircBot _bot;
- private DccManager _manager;
- private String _nick;
- private String _login = null;
- private String _hostname = null;
- private String _type;
- private long _address;
- private int _port;
- private long _size;
- private boolean _received;
-
- private Socket _socket = null;
- private long _progress = 0;
- private File _file = null;
- private int _timeout = 0;
- private boolean _incoming;
- private long _packetDelay = 0;
-
- private long _startTime = 0;
-
-}
+/*
+Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
+
+This file is part of PircBot.
+
+This software is dual-licensed, allowing you to choose between the GNU
+General Public License (GPL) and the www.jibble.org Commercial License.
+Since the GPL may be too restrictive for use in a proprietary application,
+a commercial license is also provided. Full license information can be
+found at http://www.jibble.org/licenses/
+
+*/
+
+
+package org.jibble.pircbot;
+
+import java.net.*;
+import java.io.*;
+
+/**
+ * This class is used to administer a DCC file transfer.
+ *
+ * @since 1.2.0
+ * @author Paul James Mutton,
+ * http://www.jibble.org/
+ * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
+ */
+public class DccFileTransfer {
+
+ /**
+ * The default buffer size to use when sending and receiving files.
+ */
+ public static final int BUFFER_SIZE = 1024;
+
+
+ /**
+ * Constructor used for receiving files.
+ */
+ DccFileTransfer(PircBot bot, DccManager manager, String nick, String login, String hostname, String type, String filename, long address, int port, long size) {
+ _bot = bot;
+ _manager = manager;
+ _nick = nick;
+ _login = login;
+ _hostname = hostname;
+ _type = type;
+ _file = new File(filename);
+ _address = address;
+ _port = port;
+ _size = size;
+ _received = false;
+
+ _incoming = true;
+ }
+
+
+ /**
+ * Constructor used for sending files.
+ */
+ DccFileTransfer(PircBot bot, DccManager manager, File file, String nick, int timeout) {
+ _bot = bot;
+ _manager = manager;
+ _nick = nick;
+ _file = file;
+ _size = file.length();
+ _timeout = timeout;
+ _received = true;
+
+ _incoming = false;
+ }
+
+
+ /**
+ * Receives a DccFileTransfer and writes it to the specified file.
+ * Resuming allows a partial download to be continue from the end of
+ * the current file contents.
+ *
+ * @param file The file to write to.
+ * @param resume True if you wish to try and resume the download instead
+ * of overwriting an existing file.
+ *
+ */
+ public synchronized void receive(File file, boolean resume) {
+ if (!_received) {
+ _received = true;
+ _file = file;
+
+ if (_type.equals("SEND") && resume) {
+ _progress = file.length();
+ if (_progress == 0) {
+ doReceive(file, false);
+ }
+ else {
+ _bot.sendCTCPCommand(_nick, "DCC RESUME file.ext " + _port + " " + _progress);
+ _manager.addAwaitingResume(this);
+ }
+ }
+ else {
+ _progress = file.length();
+ doReceive(file, resume);
+ }
+ }
+ }
+
+
+ /**
+ * Receive the file in a new thread.
+ */
+ void doReceive(final File file, final boolean resume) {
+ new Thread() {
+ public void run() {
+
+ BufferedOutputStream foutput = null;
+ Exception exception = null;
+
+ try {
+
+ // Convert the integer address to a proper IP address.
+ int[] ip = _bot.longToIp(_address);
+ String ipStr = ip[0] + "." + ip[1] + "." + ip[2] + "." + ip[3];
+
+ // Connect the socket and set a timeout.
+ _socket = new Socket(ipStr, _port);
+ _socket.setSoTimeout(30*1000);
+ _startTime = System.currentTimeMillis();
+
+ // No longer possible to resume this transfer once it's underway.
+ _manager.removeAwaitingResume(DccFileTransfer.this);
+
+ BufferedInputStream input = new BufferedInputStream(_socket.getInputStream());
+ BufferedOutputStream output = new BufferedOutputStream(_socket.getOutputStream());
+
+ // Following line fixed for jdk 1.1 compatibility.
+ foutput = new BufferedOutputStream(new FileOutputStream(file.getCanonicalPath(), resume));
+
+ byte[] inBuffer = new byte[BUFFER_SIZE];
+ byte[] outBuffer = new byte[4];
+ int bytesRead = 0;
+ while ((bytesRead = input.read(inBuffer, 0, inBuffer.length)) != -1) {
+ foutput.write(inBuffer, 0, bytesRead);
+ _progress += bytesRead;
+ // Send back an acknowledgement of how many bytes we have got so far.
+ outBuffer[0] = (byte) ((_progress >> 24) & 0xff);
+ outBuffer[1] = (byte) ((_progress >> 16) & 0xff);
+ outBuffer[2] = (byte) ((_progress >> 8) & 0xff);
+ outBuffer[3] = (byte) ((_progress >> 0) & 0xff);
+ output.write(outBuffer);
+ output.flush();
+ delay();
+ }
+ foutput.flush();
+ }
+ catch (Exception e) {
+ exception = e;
+ }
+ finally {
+ try {
+ foutput.close();
+ _socket.close();
+ }
+ catch (Exception anye) {
+ // Do nothing.
+ }
+ }
+
+ _bot.onFileTransferFinished(DccFileTransfer.this, exception);
+ }
+ }.start();
+ }
+
+
+ /**
+ * Method to send the file inside a new thread.
+ */
+ void doSend(final boolean allowResume) {
+ new Thread() {
+ public void run() {
+
+ BufferedInputStream finput = null;
+ Exception exception = null;
+
+ try {
+
+ ServerSocket ss = null;
+
+ int[] ports = _bot.getDccPorts();
+ if (ports == null) {
+ // Use any free port.
+ ss = new ServerSocket(0);
+ }
+ else {
+ for (int i = 0; i < ports.length; i++) {
+ try {
+ ss = new ServerSocket(ports[i]);
+ // Found a port number we could use.
+ break;
+ }
+ catch (Exception e) {
+ // Do nothing; go round and try another port.
+ }
+ }
+ if (ss == null) {
+ // No ports could be used.
+ throw new IOException("All ports returned by getDccPorts() are in use.");
+ }
+ }
+
+ ss.setSoTimeout(_timeout);
+ _port = ss.getLocalPort();
+ InetAddress inetAddress = _bot.getDccInetAddress();
+ if (inetAddress == null) {
+ inetAddress = _bot.getInetAddress();
+ }
+ byte[] ip = inetAddress.getAddress();
+ long ipNum = _bot.ipToLong(ip);
+
+ // Rename the filename so it has no whitespace in it when we send it.
+ // .... I really should do this a bit more nicely at some point ....
+ String safeFilename = _file.getName().replace(' ', '_');
+ safeFilename = safeFilename.replace('\t', '_');
+
+ if (allowResume) {
+ _manager.addAwaitingResume(DccFileTransfer.this);
+ }
+
+ // Send the message to the user, telling them where to connect to in order to get the file.
+ _bot.sendCTCPCommand(_nick, "DCC SEND " + safeFilename + " " + ipNum + " " + _port + " " + _file.length());
+
+ // The client may now connect to us and download the file.
+ _socket = ss.accept();
+ _socket.setSoTimeout(30000);
+ _startTime = System.currentTimeMillis();
+
+ // No longer possible to resume this transfer once it's underway.
+ if (allowResume) {
+ _manager.removeAwaitingResume(DccFileTransfer.this);
+ }
+
+ // Might as well close the server socket now; it's finished with.
+ ss.close();
+
+ BufferedOutputStream output = new BufferedOutputStream(_socket.getOutputStream());
+ BufferedInputStream input = new BufferedInputStream(_socket.getInputStream());
+ finput = new BufferedInputStream(new FileInputStream(_file));
+
+ // Check for resuming.
+ if (_progress > 0) {
+ long bytesSkipped = 0;
+ while (bytesSkipped < _progress) {
+ bytesSkipped += finput.skip(_progress - bytesSkipped);
+ }
+ }
+
+ byte[] outBuffer = new byte[BUFFER_SIZE];
+ byte[] inBuffer = new byte[4];
+ int bytesRead = 0;
+ while ((bytesRead = finput.read(outBuffer, 0, outBuffer.length)) != -1) {
+ output.write(outBuffer, 0, bytesRead);
+ output.flush();
+ input.read(inBuffer, 0, inBuffer.length);
+ _progress += bytesRead;
+ delay();
+ }
+ }
+ catch (Exception e) {
+ exception = e;
+ }
+ finally {
+ try {
+ finput.close();
+ _socket.close();
+ }
+ catch (Exception e) {
+ // Do nothing.
+ }
+ }
+
+ _bot.onFileTransferFinished(DccFileTransfer.this, exception);
+ }
+ }.start();
+ }
+
+
+ /**
+ * Package mutator for setting the progress of the file transfer.
+ */
+ void setProgress(long progress) {
+ _progress = progress;
+ }
+
+
+ /**
+ * Delay between packets.
+ */
+ private void delay() {
+ if (_packetDelay > 0) {
+ try {
+ Thread.sleep(_packetDelay);
+ }
+ catch (InterruptedException e) {
+ // Do nothing.
+ }
+ }
+ }
+
+
+ /**
+ * Returns the nick of the other user taking part in this file transfer.
+ *
+ * @return the nick of the other user.
+ *
+ */
+ public String getNick() {
+ return _nick;
+ }
+
+
+ /**
+ * Returns the login of the file sender.
+ *
+ * @return the login of the file sender. null if we are sending.
+ *
+ */
+ public String getLogin() {
+ return _login;
+ }
+
+
+ /**
+ * Returns the hostname of the file sender.
+ *
+ * @return the hostname of the file sender. null if we are sending.
+ *
+ */
+ public String getHostname() {
+ return _hostname;
+ }
+
+
+ /**
+ * Returns the suggested file to be used for this transfer.
+ *
+ * @return the suggested file to be used.
+ *
+ */
+ public File getFile() {
+ return _file;
+ }
+
+
+ /**
+ * Returns the port number to be used when making the connection.
+ *
+ * @return the port number.
+ *
+ */
+ public int getPort() {
+ return _port;
+ }
+
+
+ /**
+ * Returns true if the file transfer is incoming (somebody is sending
+ * the file to us).
+ *
+ * @return true if the file transfer is incoming.
+ *
+ */
+ public boolean isIncoming() {
+ return _incoming;
+ }
+
+
+ /**
+ * Returns true if the file transfer is outgoing (we are sending the
+ * file to someone).
+ *
+ * @return true if the file transfer is outgoing.
+ *
+ */
+ public boolean isOutgoing() {
+ return !isIncoming();
+ }
+
+
+ /**
+ * Sets the delay time between sending or receiving each packet.
+ * Default is 0.
+ * This is useful for throttling the speed of file transfers to maintain
+ * a good quality of service for other things on the machine or network.
+ *
+ * @param millis The number of milliseconds to wait between packets.
+ *
+ */
+ public void setPacketDelay(long millis) {
+ _packetDelay = millis;
+ }
+
+
+ /**
+ * returns the delay time between each packet that is send or received.
+ *
+ * @return the delay between each packet.
+ *
+ */
+ public long getPacketDelay() {
+ return _packetDelay;
+ }
+
+
+ /**
+ * Returns the size (in bytes) of the file being transfered.
+ *
+ * @return the size of the file. Returns -1 if the sender did not
+ * specify this value.
+ */
+ public long getSize() {
+ return _size;
+ }
+
+
+ /**
+ * Returns the progress (in bytes) of the current file transfer.
+ * When resuming, this represents the total number of bytes in the
+ * file, which may be greater than the amount of bytes resumed in
+ * just this transfer.
+ *
+ * @return the progress of the transfer.
+ */
+ public long getProgress() {
+ return _progress;
+ }
+
+
+ /**
+ * Returns the progress of the file transfer as a percentage.
+ * Note that this should never be negative, but could become
+ * greater than 100% if you attempt to resume a larger file
+ * onto a partially downloaded file that was smaller.
+ *
+ * @return the progress of the transfer as a percentage.
+ */
+ public double getProgressPercentage() {
+ return 100 * (getProgress() / (double) getSize());
+ }
+
+
+ /**
+ * Stops the DCC file transfer by closing the connection.
+ */
+ public void close() {
+ try {
+ _socket.close();
+ }
+ catch (Exception e) {
+ // Let the DCC manager worry about anything that may go wrong.
+ }
+ }
+
+
+ /**
+ * Returns the rate of data transfer in bytes per second.
+ * This value is an estimate based on the number of bytes
+ * transfered since the connection was established.
+ *
+ * @return data transfer rate in bytes per second.
+ */
+ public long getTransferRate() {
+ long time = (System.currentTimeMillis() - _startTime) / 1000;
+ if (time <= 0) {
+ return 0;
+ }
+ return getProgress() / time;
+ }
+
+ /**
+ * Returns the address of the sender as a long.
+ *
+ * @return the address of the sender as a long.
+ */
+ public long getNumericalAddress() {
+ return _address;
+ }
+
+
+ private PircBot _bot;
+ private DccManager _manager;
+ private String _nick;
+ private String _login = null;
+ private String _hostname = null;
+ private String _type;
+ private long _address;
+ private int _port;
+ private long _size;
+ private boolean _received;
+
+ private Socket _socket = null;
+ private long _progress = 0;
+ private File _file = null;
+ private int _timeout = 0;
+ private boolean _incoming;
+ private long _packetDelay = 0;
+
+ private long _startTime = 0;
+
+}
diff --git a/src/org/jibble/pircbot/DccManager.java b/src/org/jibble/pircbot/DccManager.java
index 1fbd06d..f981bca 100644
--- a/src/org/jibble/pircbot/DccManager.java
+++ b/src/org/jibble/pircbot/DccManager.java
@@ -1,152 +1,152 @@
-/*
-Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
-
-This file is part of PircBot.
-
-This software is dual-licensed, allowing you to choose between the GNU
-General Public License (GPL) and the www.jibble.org Commercial License.
-Since the GPL may be too restrictive for use in a proprietary application,
-a commercial license is also provided. Full license information can be
-found at http://www.jibble.org/licenses/
-
-*/
-
-
-package org.jibble.pircbot;
-
-import java.util.*;
-
-/**
- * This class is used to process DCC events from the server.
- *
- * @since 1.2.0
- * @author Paul James Mutton,
- * http://www.jibble.org/
- * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
- */
-public class DccManager {
-
-
- /**
- * Constructs a DccManager to look after all DCC SEND and CHAT events.
- *
- * @param bot The PircBot whose DCC events this class will handle.
- */
- DccManager(PircBot bot) {
- _bot = bot;
- }
-
-
- /**
- * Processes a DCC request.
- *
- * @return True if the type of request was handled successfully.
- */
- boolean processRequest(String nick, String login, String hostname, String request) {
- StringTokenizer tokenizer = new StringTokenizer(request);
- tokenizer.nextToken();
- String type = tokenizer.nextToken();
- String filename = tokenizer.nextToken();
-
- if (type.equals("SEND")) {
- long address = Long.parseLong(tokenizer.nextToken());
- int port = Integer.parseInt(tokenizer.nextToken());
- long size = -1;
- try {
- size = Long.parseLong(tokenizer.nextToken());
- }
- catch (Exception e) {
- // Stick with the old value.
- }
-
- DccFileTransfer transfer = new DccFileTransfer(_bot, this, nick, login, hostname, type, filename, address, port, size);
- _bot.onIncomingFileTransfer(transfer);
-
- }
- else if (type.equals("RESUME")) {
- int port = Integer.parseInt(tokenizer.nextToken());
- long progress = Long.parseLong(tokenizer.nextToken());
-
- DccFileTransfer transfer = null;
- synchronized (_awaitingResume) {
- for (int i = 0; i < _awaitingResume.size(); i++) {
- transfer = (DccFileTransfer) _awaitingResume.elementAt(i);
- if (transfer.getNick().equals(nick) && transfer.getPort() == port) {
- _awaitingResume.removeElementAt(i);
- break;
- }
- }
- }
-
- if (transfer != null) {
- transfer.setProgress(progress);
- _bot.sendCTCPCommand(nick, "DCC ACCEPT file.ext " + port + " " + progress);
- }
-
- }
- else if (type.equals("ACCEPT")) {
- int port = Integer.parseInt(tokenizer.nextToken());
- // XXX: progress is not used?
- //long progress = Long.parseLong(tokenizer.nextToken());
-
- DccFileTransfer transfer = null;
- synchronized (_awaitingResume) {
- for (int i = 0; i < _awaitingResume.size(); i++) {
- transfer = (DccFileTransfer) _awaitingResume.elementAt(i);
- if (transfer.getNick().equals(nick) && transfer.getPort() == port) {
- _awaitingResume.removeElementAt(i);
- break;
- }
- }
- }
-
- if (transfer != null) {
- transfer.doReceive(transfer.getFile(), true);
- }
-
- }
- else if (type.equals("CHAT")) {
- long address = Long.parseLong(tokenizer.nextToken());
- int port = Integer.parseInt(tokenizer.nextToken());
-
- final DccChat chat = new DccChat(_bot, nick, login, hostname, address, port);
-
- new Thread() {
- public void run() {
- _bot.onIncomingChatRequest(chat);
- }
- }.start();
- }
- else {
- return false;
- }
-
- return true;
- }
-
-
- /**
- * Add this DccFileTransfer to the list of those awaiting possible
- * resuming.
- *
- * @param transfer the DccFileTransfer that may be resumed.
- */
- void addAwaitingResume(DccFileTransfer transfer) {
- synchronized (_awaitingResume) {
- _awaitingResume.addElement(transfer);
- }
- }
-
-
- /**
- * Remove this transfer from the list of those awaiting resuming.
- */
- void removeAwaitingResume(DccFileTransfer transfer) {
- _awaitingResume.removeElement(transfer);
- }
-
-
- private PircBot _bot;
- private Vector
- * Most IRC servers attempt to contact the ident server on connecting
- * hosts in order to determine the user's identity. A few IRC servers
- * will not allow you to connect unless this information is provided.
- *
- * So when a PircBot is run on a machine that does not run an ident server,
- * it may be necessary to provide a "faked" response by starting up its
- * own ident server and sending out apparently correct responses.
- *
- * An instance of this class can be used to start up an ident server
- * only if it is possible to do so. Reasons for not being able to do
- * so are if there is already an ident server running on port 113, or
- * if you are running as an unprivileged user who is unable to create
- * a server socket on that port number.
- *
- * @since 0.9c
- * @author Paul James Mutton,
- * http://www.jibble.org/
- * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
- */
-public class IdentServer extends Thread {
-
- /**
- * Constructs and starts an instance of an IdentServer that will
- * respond to a client with the provided login. Rather than calling
- * this constructor explicitly from your code, it is recommended that
- * you use the startIdentServer method in the PircBot class.
- *
- * The ident server will wait for up to 60 seconds before shutting
- * down. Otherwise, it will shut down as soon as it has responded
- * to an ident request.
- *
- * @param bot The PircBot instance that will be used to log to.
- * @param login The login that the ident server will respond with.
- */
- IdentServer(PircBot bot, String login) {
- _bot = bot;
- _login = login;
-
- try {
- _ss = new ServerSocket(113);
- _ss.setSoTimeout(60000);
- }
- catch (Exception e) {
- _bot.log("*** Could not start the ident server on port 113.");
- return;
- }
-
- _bot.log("*** Ident server running on port 113 for the next 60 seconds...");
- this.setName(this.getClass() + "-Thread");
- this.start();
- }
-
-
- /**
- * Waits for a client to connect to the ident server before making an
- * appropriate response. Note that this method is started by the class
- * constructor.
- */
- public void run() {
- try {
- Socket socket = _ss.accept();
- socket.setSoTimeout(60000);
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
-
- String line = reader.readLine();
- if (line != null) {
- _bot.log("*** Ident request received: " + line);
- line = line + " : USERID : UNIX : " + _login;
- writer.write(line + "\r\n");
- writer.flush();
- _bot.log("*** Ident reply sent: " + line);
- writer.close();
- }
- }
- catch (Exception e) {
- // We're not really concerned with what went wrong, are we?
- }
-
- try {
- _ss.close();
- }
- catch (Exception e) {
- // Doesn't really matter...
- }
-
- _bot.log("*** The Ident server has been shut down.");
- }
-
- private PircBot _bot;
- private String _login;
- private ServerSocket _ss = null;
-
-}
+/*
+Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
+
+This file is part of PircBot.
+
+This software is dual-licensed, allowing you to choose between the GNU
+General Public License (GPL) and the www.jibble.org Commercial License.
+Since the GPL may be too restrictive for use in a proprietary application,
+a commercial license is also provided. Full license information can be
+found at http://www.jibble.org/licenses/
+
+*/
+
+
+package org.jibble.pircbot;
+
+import java.net.*;
+import java.io.*;
+
+/**
+ * A simple IdentServer (also know as "The Identification Protocol").
+ * An ident server provides a means to determine the identity of a
+ * user of a particular TCP connection.
+ *
+ * Most IRC servers attempt to contact the ident server on connecting
+ * hosts in order to determine the user's identity. A few IRC servers
+ * will not allow you to connect unless this information is provided.
+ *
+ * So when a PircBot is run on a machine that does not run an ident server,
+ * it may be necessary to provide a "faked" response by starting up its
+ * own ident server and sending out apparently correct responses.
+ *
+ * An instance of this class can be used to start up an ident server
+ * only if it is possible to do so. Reasons for not being able to do
+ * so are if there is already an ident server running on port 113, or
+ * if you are running as an unprivileged user who is unable to create
+ * a server socket on that port number.
+ *
+ * @since 0.9c
+ * @author Paul James Mutton,
+ * http://www.jibble.org/
+ * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
+ */
+public class IdentServer extends Thread {
+
+ /**
+ * Constructs and starts an instance of an IdentServer that will
+ * respond to a client with the provided login. Rather than calling
+ * this constructor explicitly from your code, it is recommended that
+ * you use the startIdentServer method in the PircBot class.
+ *
+ * The ident server will wait for up to 60 seconds before shutting
+ * down. Otherwise, it will shut down as soon as it has responded
+ * to an ident request.
+ *
+ * @param bot The PircBot instance that will be used to log to.
+ * @param login The login that the ident server will respond with.
+ */
+ IdentServer(PircBot bot, String login) {
+ _bot = bot;
+ _login = login;
+
+ try {
+ _ss = new ServerSocket(113);
+ _ss.setSoTimeout(60000);
+ }
+ catch (Exception e) {
+ _bot.log("*** Could not start the ident server on port 113.");
+ return;
+ }
+
+ _bot.log("*** Ident server running on port 113 for the next 60 seconds...");
+ this.setName(this.getClass() + "-Thread");
+ this.start();
+ }
+
+
+ /**
+ * Waits for a client to connect to the ident server before making an
+ * appropriate response. Note that this method is started by the class
+ * constructor.
+ */
+ public void run() {
+ try {
+ Socket socket = _ss.accept();
+ socket.setSoTimeout(60000);
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
+
+ String line = reader.readLine();
+ if (line != null) {
+ _bot.log("*** Ident request received: " + line);
+ line = line + " : USERID : UNIX : " + _login;
+ writer.write(line + "\r\n");
+ writer.flush();
+ _bot.log("*** Ident reply sent: " + line);
+ writer.close();
+ }
+ }
+ catch (Exception e) {
+ // We're not really concerned with what went wrong, are we?
+ }
+
+ try {
+ _ss.close();
+ }
+ catch (Exception e) {
+ // Doesn't really matter...
+ }
+
+ _bot.log("*** The Ident server has been shut down.");
+ }
+
+ private PircBot _bot;
+ private String _login;
+ private ServerSocket _ss = null;
+
+}
diff --git a/src/org/jibble/pircbot/InputThread.java b/src/org/jibble/pircbot/InputThread.java
index a470eca..0dcfc7e 100644
--- a/src/org/jibble/pircbot/InputThread.java
+++ b/src/org/jibble/pircbot/InputThread.java
@@ -1,169 +1,169 @@
-/*
-Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
-
-This file is part of PircBot.
-
-This software is dual-licensed, allowing you to choose between the GNU
-General Public License (GPL) and the www.jibble.org Commercial License.
-Since the GPL may be too restrictive for use in a proprietary application,
-a commercial license is also provided. Full license information can be
-found at http://www.jibble.org/licenses/
-
-*/
-
-
-package org.jibble.pircbot;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-/**
- * A Thread which reads lines from the IRC server. It then
- * passes these lines to the PircBot without changing them.
- * This running Thread also detects disconnection from the server
- * and is thus used by the OutputThread to send lines to the server.
- *
- * @author Paul James Mutton,
- * http://www.jibble.org/
- * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
- */
-public class InputThread extends Thread {
-
- /**
- * The InputThread reads lines from the IRC server and allows the
- * PircBot to handle them.
- *
- * @param bot An instance of the underlying PircBot.
- * @param breader The BufferedReader that reads lines from the server.
- * @param bwriter The BufferedWriter that sends lines to the server.
- */
- InputThread(PircBot bot, Socket socket, BufferedReader breader, BufferedWriter bwriter) {
- _bot = bot;
- _socket = socket;
- _breader = breader;
- _bwriter = bwriter;
- this.setName(this.getClass() + "-Thread");
- }
-
-
- /**
- * Sends a raw line to the IRC server as soon as possible, bypassing the
- * outgoing message queue.
- *
- * @param line The raw line to send to the IRC server.
- */
- void sendRawLine(String line) {
- OutputThread.sendRawLine(_bot, _bwriter, line);
- }
-
-
- /**
- * Returns true if this InputThread is connected to an IRC server.
- * The result of this method should only act as a rough guide,
- * as the result may not be valid by the time you act upon it.
- *
- * @return True if still connected.
- */
- boolean isConnected() {
- return _isConnected;
- }
-
-
- /**
- * Called to start this Thread reading lines from the IRC server.
- * When a line is read, this method calls the handleLine method
- * in the PircBot, which may subsequently call an 'onXxx' method
- * in the PircBot subclass. If any subclass of Throwable (i.e.
- * any Exception or Error) is thrown by your method, then this
- * method will print the stack trace to the standard output. It
- * is probable that the PircBot may still be functioning normally
- * after such a problem, but the existance of any uncaught exceptions
- * in your code is something you should really fix.
- */
- public void run() {
- try {
- boolean running = true;
- while (running) {
- try {
- String line = null;
- while ((line = _breader.readLine()) != null) {
- try {
- _bot.handleLine(line);
- }
- catch (Throwable t) {
- // Stick the whole stack trace into a String so we can output it nicely.
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- t.printStackTrace(pw);
- pw.flush();
- StringTokenizer tokenizer = new StringTokenizer(sw.toString(), "\r\n");
- synchronized (_bot) {
- _bot.log("### Your implementation of PircBot is faulty and you have");
- _bot.log("### allowed an uncaught Exception or Error to propagate in your");
- _bot.log("### code. It may be possible for PircBot to continue operating");
- _bot.log("### normally. Here is the stack trace that was produced: -");
- _bot.log("### ");
- while (tokenizer.hasMoreTokens()) {
- _bot.log("### " + tokenizer.nextToken());
- }
- }
- }
- }
- if (line == null) {
- // The server must have disconnected us.
- running = false;
- }
- }
- catch (InterruptedIOException iioe) {
- // This will happen if we haven't received anything from the server for a while.
- // So we shall send it a ping to check that we are still connected.
- this.sendRawLine("PING " + (System.currentTimeMillis() / 1000));
- // Now we go back to listening for stuff from the server...
- }
- }
- }
- catch (Exception e) {
- // Do nothing.
- }
-
- // If we reach this point, then we must have disconnected.
- try {
- _socket.close();
- }
- catch (Exception e) {
- // Just assume the socket was already closed.
- }
-
- if (!_disposed) {
- _bot.log("*** Disconnected.");
- _isConnected = false;
- _bot.onDisconnect();
- }
-
- }
-
-
- /**
- * Closes the socket without onDisconnect being called subsequently.
- */
- public void dispose () {
- try {
- _disposed = true;
- _socket.close();
- }
- catch (Exception e) {
- // Do nothing.
- }
- }
-
- private PircBot _bot = null;
- private Socket _socket = null;
- private BufferedReader _breader = null;
- private BufferedWriter _bwriter = null;
- private boolean _isConnected = true;
- private boolean _disposed = false;
-
- public static final int MAX_LINE_LENGTH = 512;
-
-}
+/*
+Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
+
+This file is part of PircBot.
+
+This software is dual-licensed, allowing you to choose between the GNU
+General Public License (GPL) and the www.jibble.org Commercial License.
+Since the GPL may be too restrictive for use in a proprietary application,
+a commercial license is also provided. Full license information can be
+found at http://www.jibble.org/licenses/
+
+*/
+
+
+package org.jibble.pircbot;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+/**
+ * A Thread which reads lines from the IRC server. It then
+ * passes these lines to the PircBot without changing them.
+ * This running Thread also detects disconnection from the server
+ * and is thus used by the OutputThread to send lines to the server.
+ *
+ * @author Paul James Mutton,
+ * http://www.jibble.org/
+ * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
+ */
+public class InputThread extends Thread {
+
+ /**
+ * The InputThread reads lines from the IRC server and allows the
+ * PircBot to handle them.
+ *
+ * @param bot An instance of the underlying PircBot.
+ * @param breader The BufferedReader that reads lines from the server.
+ * @param bwriter The BufferedWriter that sends lines to the server.
+ */
+ InputThread(PircBot bot, Socket socket, BufferedReader breader, BufferedWriter bwriter) {
+ _bot = bot;
+ _socket = socket;
+ _breader = breader;
+ _bwriter = bwriter;
+ this.setName(this.getClass() + "-Thread");
+ }
+
+
+ /**
+ * Sends a raw line to the IRC server as soon as possible, bypassing the
+ * outgoing message queue.
+ *
+ * @param line The raw line to send to the IRC server.
+ */
+ void sendRawLine(String line) {
+ OutputThread.sendRawLine(_bot, _bwriter, line);
+ }
+
+
+ /**
+ * Returns true if this InputThread is connected to an IRC server.
+ * The result of this method should only act as a rough guide,
+ * as the result may not be valid by the time you act upon it.
+ *
+ * @return True if still connected.
+ */
+ boolean isConnected() {
+ return _isConnected;
+ }
+
+
+ /**
+ * Called to start this Thread reading lines from the IRC server.
+ * When a line is read, this method calls the handleLine method
+ * in the PircBot, which may subsequently call an 'onXxx' method
+ * in the PircBot subclass. If any subclass of Throwable (i.e.
+ * any Exception or Error) is thrown by your method, then this
+ * method will print the stack trace to the standard output. It
+ * is probable that the PircBot may still be functioning normally
+ * after such a problem, but the existance of any uncaught exceptions
+ * in your code is something you should really fix.
+ */
+ public void run() {
+ try {
+ boolean running = true;
+ while (running) {
+ try {
+ String line = null;
+ while ((line = _breader.readLine()) != null) {
+ try {
+ _bot.handleLine(line);
+ }
+ catch (Throwable t) {
+ // Stick the whole stack trace into a String so we can output it nicely.
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ t.printStackTrace(pw);
+ pw.flush();
+ StringTokenizer tokenizer = new StringTokenizer(sw.toString(), "\r\n");
+ synchronized (_bot) {
+ _bot.log("### Your implementation of PircBot is faulty and you have");
+ _bot.log("### allowed an uncaught Exception or Error to propagate in your");
+ _bot.log("### code. It may be possible for PircBot to continue operating");
+ _bot.log("### normally. Here is the stack trace that was produced: -");
+ _bot.log("### ");
+ while (tokenizer.hasMoreTokens()) {
+ _bot.log("### " + tokenizer.nextToken());
+ }
+ }
+ }
+ }
+ if (line == null) {
+ // The server must have disconnected us.
+ running = false;
+ }
+ }
+ catch (InterruptedIOException iioe) {
+ // This will happen if we haven't received anything from the server for a while.
+ // So we shall send it a ping to check that we are still connected.
+ this.sendRawLine("PING " + (System.currentTimeMillis() / 1000));
+ // Now we go back to listening for stuff from the server...
+ }
+ }
+ }
+ catch (Exception e) {
+ // Do nothing.
+ }
+
+ // If we reach this point, then we must have disconnected.
+ try {
+ _socket.close();
+ }
+ catch (Exception e) {
+ // Just assume the socket was already closed.
+ }
+
+ if (!_disposed) {
+ _bot.log("*** Disconnected.");
+ _isConnected = false;
+ _bot.onDisconnect();
+ }
+
+ }
+
+
+ /**
+ * Closes the socket without onDisconnect being called subsequently.
+ */
+ public void dispose () {
+ try {
+ _disposed = true;
+ _socket.close();
+ }
+ catch (Exception e) {
+ // Do nothing.
+ }
+ }
+
+ private PircBot _bot = null;
+ private Socket _socket = null;
+ private BufferedReader _breader = null;
+ private BufferedWriter _bwriter = null;
+ private boolean _isConnected = true;
+ private boolean _disposed = false;
+
+ public static final int MAX_LINE_LENGTH = 512;
+
+}
diff --git a/src/org/jibble/pircbot/IrcException.java b/src/org/jibble/pircbot/IrcException.java
index c34e9a1..a0dbcf7 100644
--- a/src/org/jibble/pircbot/IrcException.java
+++ b/src/org/jibble/pircbot/IrcException.java
@@ -1,36 +1,36 @@
-/*
-Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
-
-This file is part of PircBot.
-
-This software is dual-licensed, allowing you to choose between the GNU
-General Public License (GPL) and the www.jibble.org Commercial License.
-Since the GPL may be too restrictive for use in a proprietary application,
-a commercial license is also provided. Full license information can be
-found at http://www.jibble.org/licenses/
-
-*/
-
-package org.jibble.pircbot;
-
-/**
- * An IrcException class.
- *
- * @since 0.9
- * @author Paul James Mutton,
- * http://www.jibble.org/
- * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
- */
-public class IrcException extends Exception {
- private static final long serialVersionUID = -3705541066912475928L;
-
- /**
- * Constructs a new IrcException.
- *
- * @param e The error message to report.
- */
- public IrcException(String e) {
- super(e);
- }
-
-}
+/*
+Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
+
+This file is part of PircBot.
+
+This software is dual-licensed, allowing you to choose between the GNU
+General Public License (GPL) and the www.jibble.org Commercial License.
+Since the GPL may be too restrictive for use in a proprietary application,
+a commercial license is also provided. Full license information can be
+found at http://www.jibble.org/licenses/
+
+*/
+
+package org.jibble.pircbot;
+
+/**
+ * An IrcException class.
+ *
+ * @since 0.9
+ * @author Paul James Mutton,
+ * http://www.jibble.org/
+ * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
+ */
+public class IrcException extends Exception {
+ private static final long serialVersionUID = -3705541066912475928L;
+
+ /**
+ * Constructs a new IrcException.
+ *
+ * @param e The error message to report.
+ */
+ public IrcException(String e) {
+ super(e);
+ }
+
+}
diff --git a/src/org/jibble/pircbot/NickAlreadyInUseException.java b/src/org/jibble/pircbot/NickAlreadyInUseException.java
index 6e950ff..10343d2 100644
--- a/src/org/jibble/pircbot/NickAlreadyInUseException.java
+++ b/src/org/jibble/pircbot/NickAlreadyInUseException.java
@@ -1,39 +1,39 @@
-/*
-Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
-
-This file is part of PircBot.
-
-This software is dual-licensed, allowing you to choose between the GNU
-General Public License (GPL) and the www.jibble.org Commercial License.
-Since the GPL may be too restrictive for use in a proprietary application,
-a commercial license is also provided. Full license information can be
-found at http://www.jibble.org/licenses/
-
-*/
-
-
-package org.jibble.pircbot;
-
-/**
- * A NickAlreadyInUseException class. This exception is
- * thrown when the PircBot attempts to join an IRC server
- * with a user name that is already in use.
- *
- * @since 0.9
- * @author Paul James Mutton,
- * http://www.jibble.org/
- * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
- */
-public class NickAlreadyInUseException extends IrcException {
- private static final long serialVersionUID = -4724325464519465479L;
-
- /**
- * Constructs a new IrcException.
- *
- * @param e The error message to report.
- */
- public NickAlreadyInUseException(String e) {
- super(e);
- }
-
-}
+/*
+Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
+
+This file is part of PircBot.
+
+This software is dual-licensed, allowing you to choose between the GNU
+General Public License (GPL) and the www.jibble.org Commercial License.
+Since the GPL may be too restrictive for use in a proprietary application,
+a commercial license is also provided. Full license information can be
+found at http://www.jibble.org/licenses/
+
+*/
+
+
+package org.jibble.pircbot;
+
+/**
+ * A NickAlreadyInUseException class. This exception is
+ * thrown when the PircBot attempts to join an IRC server
+ * with a user name that is already in use.
+ *
+ * @since 0.9
+ * @author Paul James Mutton,
+ * http://www.jibble.org/
+ * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
+ */
+public class NickAlreadyInUseException extends IrcException {
+ private static final long serialVersionUID = -4724325464519465479L;
+
+ /**
+ * Constructs a new IrcException.
+ *
+ * @param e The error message to report.
+ */
+ public NickAlreadyInUseException(String e) {
+ super(e);
+ }
+
+}
diff --git a/src/org/jibble/pircbot/OutputThread.java b/src/org/jibble/pircbot/OutputThread.java
index e1e33bb..ffb4c5d 100644
--- a/src/org/jibble/pircbot/OutputThread.java
+++ b/src/org/jibble/pircbot/OutputThread.java
@@ -1,104 +1,104 @@
-/*
-Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
-
-This file is part of PircBot.
-
-This software is dual-licensed, allowing you to choose between the GNU
-General Public License (GPL) and the www.jibble.org Commercial License.
-Since the GPL may be too restrictive for use in a proprietary application,
-a commercial license is also provided. Full license information can be
-found at http://www.jibble.org/licenses/
-
-*/
-
-
-package org.jibble.pircbot;
-
-import java.io.*;
-
-/**
- * A Thread which is responsible for sending messages to the IRC server.
- * Messages are obtained from the outgoing message queue and sent
- * immediately if possible. If there is a flood of messages, then to
- * avoid getting kicked from a channel, we put a small delay between
- * each one.
- *
- * @author Paul James Mutton,
- * http://www.jibble.org/
- * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
- */
-public class OutputThread extends Thread {
-
-
- /**
- * Constructs an OutputThread for the underlying PircBot. All messages
- * sent to the IRC server are sent by this OutputThread to avoid hammering
- * the server. Messages are sent immediately if possible. If there are
- * multiple messages queued, then there is a delay imposed.
- *
- * @param bot The underlying PircBot instance.
- * @param outQueue The Queue from which we will obtain our messages.
- */
- OutputThread(PircBot bot, Queue outQueue) {
- _bot = bot;
- _outQueue = outQueue;
- this.setName(this.getClass() + "-Thread");
- }
-
-
- /**
- * A static method to write a line to a BufferedOutputStream and then pass
- * the line to the log method of the supplied PircBot instance.
- *
- * @param bot The underlying PircBot instance.
- * @param out The BufferedOutputStream to write to.
- * @param line The line to be written. "\r\n" is appended to the end.
- * @param encoding The charset to use when encoing this string into a
- * byte array.
- */
- static void sendRawLine(PircBot bot, BufferedWriter bwriter, String line) {
- if (line.length() > bot.getMaxLineLength() - 2) {
- line = line.substring(0, bot.getMaxLineLength() - 2);
- }
- synchronized(bwriter) {
- try {
- bwriter.write(line + "\r\n");
- bwriter.flush();
- bot.log(">>>" + line);
- }
- catch (Exception e) {
- // Silent response - just lose the line.
- }
- }
- }
-
-
- /**
- * This method starts the Thread consuming from the outgoing message
- * Queue and sending lines to the server.
- */
- public void run() {
- try {
- boolean running = true;
- while (running) {
- // Small delay to prevent spamming of the channel
- Thread.sleep(_bot.getMessageDelay());
-
- String line = (String) _outQueue.next();
- if (line != null) {
- _bot.sendRawLine(line);
- }
- else {
- running = false;
- }
- }
- }
- catch (InterruptedException e) {
- // Just let the method return naturally...
- }
- }
-
- private PircBot _bot = null;
- private Queue _outQueue = null;
-
-}
+/*
+Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
+
+This file is part of PircBot.
+
+This software is dual-licensed, allowing you to choose between the GNU
+General Public License (GPL) and the www.jibble.org Commercial License.
+Since the GPL may be too restrictive for use in a proprietary application,
+a commercial license is also provided. Full license information can be
+found at http://www.jibble.org/licenses/
+
+*/
+
+
+package org.jibble.pircbot;
+
+import java.io.*;
+
+/**
+ * A Thread which is responsible for sending messages to the IRC server.
+ * Messages are obtained from the outgoing message queue and sent
+ * immediately if possible. If there is a flood of messages, then to
+ * avoid getting kicked from a channel, we put a small delay between
+ * each one.
+ *
+ * @author Paul James Mutton,
+ * http://www.jibble.org/
+ * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
+ */
+public class OutputThread extends Thread {
+
+
+ /**
+ * Constructs an OutputThread for the underlying PircBot. All messages
+ * sent to the IRC server are sent by this OutputThread to avoid hammering
+ * the server. Messages are sent immediately if possible. If there are
+ * multiple messages queued, then there is a delay imposed.
+ *
+ * @param bot The underlying PircBot instance.
+ * @param outQueue The Queue from which we will obtain our messages.
+ */
+ OutputThread(PircBot bot, Queue outQueue) {
+ _bot = bot;
+ _outQueue = outQueue;
+ this.setName(this.getClass() + "-Thread");
+ }
+
+
+ /**
+ * A static method to write a line to a BufferedOutputStream and then pass
+ * the line to the log method of the supplied PircBot instance.
+ *
+ * @param bot The underlying PircBot instance.
+ * @param out The BufferedOutputStream to write to.
+ * @param line The line to be written. "\r\n" is appended to the end.
+ * @param encoding The charset to use when encoing this string into a
+ * byte array.
+ */
+ static void sendRawLine(PircBot bot, BufferedWriter bwriter, String line) {
+ if (line.length() > bot.getMaxLineLength() - 2) {
+ line = line.substring(0, bot.getMaxLineLength() - 2);
+ }
+ synchronized(bwriter) {
+ try {
+ bwriter.write(line + "\r\n");
+ bwriter.flush();
+ bot.log(">>>" + line);
+ }
+ catch (Exception e) {
+ // Silent response - just lose the line.
+ }
+ }
+ }
+
+
+ /**
+ * This method starts the Thread consuming from the outgoing message
+ * Queue and sending lines to the server.
+ */
+ public void run() {
+ try {
+ boolean running = true;
+ while (running) {
+ // Small delay to prevent spamming of the channel
+ Thread.sleep(_bot.getMessageDelay());
+
+ String line = (String) _outQueue.next();
+ if (line != null) {
+ _bot.sendRawLine(line);
+ }
+ else {
+ running = false;
+ }
+ }
+ }
+ catch (InterruptedException e) {
+ // Just let the method return naturally...
+ }
+ }
+
+ private PircBot _bot = null;
+ private Queue _outQueue = null;
+
+}
diff --git a/src/org/jibble/pircbot/PircBot.java b/src/org/jibble/pircbot/PircBot.java
index 95bb4cb..c059bab 100644
--- a/src/org/jibble/pircbot/PircBot.java
+++ b/src/org/jibble/pircbot/PircBot.java
@@ -1,3107 +1,3107 @@
-/*
-Copyright Paul James Mutton, 2001-2007, http://www.jibble.org/
-
-This file is part of PircBot.
-
-This software is dual-licensed, allowing you to choose between the GNU
-General Public License (GPL) and the www.jibble.org Commercial License.
-Since the GPL may be too restrictive for use in a proprietary application,
-a commercial license is also provided. Full license information can be
-found at http://www.jibble.org/licenses/
-
-Modified by: Sebastian Kaspari
- * It provides an event-driven architecture to handle common IRC
- * events, flood protection, DCC support, ident support, and more.
- * The comprehensive logfile format is suitable for use with pisg to generate
- * channel statistics.
- *
- * Methods of the PircBot class can be called to send events to the IRC server
- * that it connects to. For example, calling the sendMessage method will
- * send a message to a channel or user on the IRC server. Multiple servers
- * can be supported using multiple instances of PircBot.
- *
- * To perform an action when the PircBot receives a normal message from the IRC
- * server, you would override the onMessage method defined in the PircBot
- * class. All onXYZ methods in the PircBot class are automatically called
- * when the event XYZ happens, so you would override these if you wish
- * to do something when it does happen.
- *
- * Some event methods, such as onPing, should only really perform a specific
- * function (i.e. respond to a PING from the server). For your convenience, such
- * methods are already correctly implemented in the PircBot and should not
- * normally need to be overridden. Please read the full documentation for each
- * method to see which ones are already implemented by the PircBot class.
- *
- * Please visit the PircBot homepage at
- * http://www.jibble.org/pircbot.php
- * for full revision history, a beginners guide to creating your first PircBot
- * and a list of some existing Java IRC bots and clients that use the PircBot
- * framework.
- *
- * @author Paul James Mutton,
- * http://www.jibble.org/
- * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
- */
-public abstract class PircBot implements ReplyConstants {
- public static final String TAG = "Yaaic/PircBot";
- /**
- * The definitive version number of this release of PircBot.
- * (Note: Change this before automatically building releases)
- */
- public static final String VERSION = "1.4.6";
-
- private static final int OP_ADD = 1;
- private static final int OP_REMOVE = 2;
- private static final int VOICE_ADD = 3;
- private static final int VOICE_REMOVE = 4;
-
- /**
- * Constructs a PircBot with the default settings. Your own constructors
- * in classes which extend the PircBot abstract class should be responsible
- * for changing the default settings if required.
- */
- public PircBot() {}
-
- /**
- * Attempt to connect to the specified IRC server.
- * The onConnect method is called upon success.
- *
- * @param hostname The hostname of the server to connect to.
- *
- * @throws IOException if it was not possible to connect to the server.
- * @throws IrcException if the server would not let us join it.
- * @throws NickAlreadyInUseException if our nick is already in use on the server.
- */
- public final synchronized void connect(String hostname) throws IOException, IrcException, NickAlreadyInUseException {
- this.connect(hostname, 6667, null);
- }
-
-
- /**
- * Attempt to connect to the specified IRC server and port number.
- * The onConnect method is called upon success.
- *
- * @param hostname The hostname of the server to connect to.
- * @param port The port number to connect to on the server.
- *
- * @throws IOException if it was not possible to connect to the server.
- * @throws IrcException if the server would not let us join it.
- * @throws NickAlreadyInUseException if our nick is already in use on the server.
- */
- public final synchronized void connect(String hostname, int port) throws IOException, IrcException, NickAlreadyInUseException {
- this.connect(hostname, port, null);
- }
-
-
- /**
- * Attempt to connect to the specified IRC server using the supplied
- * password.
- * The onConnect method is called upon success.
- *
- * @param hostname The hostname of the server to connect to.
- * @param port The port number to connect to on the server.
- * @param password The password to use to join the server.
- *
- * @throws IOException if it was not possible to connect to the server.
- * @throws IrcException if the server would not let us join it.
- * @throws NickAlreadyInUseException if our nick is already in use on the server.
- */
- public final synchronized void connect(String hostname, int port, String password) throws IOException, IrcException, NickAlreadyInUseException {
-
- _server = hostname;
- _port = port;
- _password = password;
-
- if (isConnected()) {
- throw new IOException("The PircBot is already connected to an IRC server. Disconnect first.");
- }
-
- // Don't clear the outqueue - there might be something important in it!
-
- // Clear everything we may have know about channels.
- this.removeAllChannels();
-
- // Connect to the server.
- Socket socket = new Socket(hostname, port);
- this.log("*** Connected to server.");
-
- _inetAddress = socket.getLocalAddress();
-
- InputStreamReader inputStreamReader = null;
- OutputStreamWriter outputStreamWriter = null;
- if (getEncoding() != null) {
- // Assume the specified encoding is valid for this JVM.
- inputStreamReader = new InputStreamReader(socket.getInputStream(), getEncoding());
- outputStreamWriter = new OutputStreamWriter(socket.getOutputStream(), getEncoding());
- }
- else {
- // Otherwise, just use the JVM's default encoding.
- inputStreamReader = new InputStreamReader(socket.getInputStream());
- outputStreamWriter = new OutputStreamWriter(socket.getOutputStream());
- }
-
- BufferedReader breader = new BufferedReader(inputStreamReader);
- BufferedWriter bwriter = new BufferedWriter(outputStreamWriter);
-
- // Attempt to join the server.
- if (password != null && !password.equals("")) {
- OutputThread.sendRawLine(this, bwriter, "PASS " + password);
- }
- String nick = this.getName();
- OutputThread.sendRawLine(this, bwriter, "NICK " + nick);
- OutputThread.sendRawLine(this, bwriter, "USER " + this.getLogin() + " 8 * :" + this.getVersion());
-
- _inputThread = new InputThread(this, socket, breader, bwriter);
-
- // Read stuff back from the server to see if we connected.
- String line = null;
- int tries = 1;
- while ((line = breader.readLine()) != null) {
-
- this.handleLine(line);
-
- int firstSpace = line.indexOf(" ");
- int secondSpace = line.indexOf(" ", firstSpace + 1);
- if (secondSpace >= 0) {
- String code = line.substring(firstSpace + 1, secondSpace);
-
- if (code.equals("004")) {
- // We're connected to the server.
- break;
- }
- else if (code.equals("433")) {
- if (_autoNickChange) {
- tries++;
- nick = getName() + tries;
- OutputThread.sendRawLine(this, bwriter, "NICK " + nick);
- }
- else {
- socket.close();
- _inputThread = null;
- throw new NickAlreadyInUseException(line);
- }
- }
- else if (code.startsWith("5") || code.startsWith("4")) {
- socket.close();
- _inputThread = null;
- throw new IrcException("Could not log into the IRC server: " + line);
- }
- }
- this.setNick(nick);
-
- }
-
- this.log("*** Logged onto server.");
-
- // This makes the socket timeout on read operations after 5 minutes.
- // Maybe in some future version I will let the user change this at runtime.
- socket.setSoTimeout(5 * 60 * 1000);
-
- // Now start the InputThread to read all other lines from the server.
- _inputThread.start();
-
- // Now start the outputThread that will be used to send all messages.
- if (_outputThread == null) {
- _outputThread = new OutputThread(this, _outQueue);
- _outputThread.start();
- }
-
- this.onConnect();
-
- }
-
-
- /**
- * Reconnects to the IRC server that we were previously connected to.
- * If necessary, the appropriate port number and password will be used.
- * This method will throw an IrcException if we have never connected
- * to an IRC server previously.
- *
- * @since PircBot 0.9.9
- *
- * @throws IOException if it was not possible to connect to the server.
- * @throws IrcException if the server would not let us join it.
- * @throws NickAlreadyInUseException if our nick is already in use on the server.
- */
- public final synchronized void reconnect() throws IOException, IrcException, NickAlreadyInUseException{
- if (getServer() == null) {
- throw new IrcException("Cannot reconnect to an IRC server because we were never connected to one previously!");
- }
- connect(getServer(), getPort(), getPassword());
- }
-
-
- /**
- * This method disconnects from the server cleanly by calling the
- * quitServer() method. Providing the PircBot was connected to an
- * IRC server, the onDisconnect() will be called as soon as the
- * disconnection is made by the server.
- *
- * @see #quitServer() quitServer
- * @see #quitServer(String) quitServer
- */
- public final synchronized void disconnect() {
- this.quitServer();
- }
-
-
- /**
- * When you connect to a server and your nick is already in use and
- * this is set to true, a new nick will be automatically chosen.
- * This is done by adding numbers to the end of the nick until an
- * available nick is found.
- *
- * @param autoNickChange Set to true if you want automatic nick changes
- * during connection.
- */
- public void setAutoNickChange(boolean autoNickChange) {
- _autoNickChange = autoNickChange;
- }
-
-
- /**
- * Starts an ident server (Identification Protocol Server, RFC 1413).
- *
- * Most IRC servers attempt to contact the ident server on connecting
- * hosts in order to determine the user's identity. A few IRC servers
- * will not allow you to connect unless this information is provided.
- *
- * So when a PircBot is run on a machine that does not run an ident server,
- * it may be necessary to call this method to start one up.
- *
- * Calling this method starts up an ident server which will respond with
- * the login provided by calling getLogin() and then shut down immediately.
- * It will also be shut down if it has not been contacted within 60 seconds
- * of creation.
- *
- * If you require an ident response, then the correct procedure is to start
- * the ident server and then connect to the IRC server. The IRC server may
- * then contact the ident server to get the information it needs.
- *
- * The ident server will fail to start if there is already an ident server
- * running on port 113, or if you are running as an unprivileged user who
- * is unable to create a server socket on that port number.
- *
- * If it is essential for you to use an ident server when connecting to an
- * IRC server, then make sure that port 113 on your machine is visible to
- * the IRC server so that it may contact the ident server.
- *
- * @since PircBot 0.9c
- */
- public final void startIdentServer() {
- new IdentServer(this, getLogin());
- }
-
-
- /**
- * Joins a channel.
- *
- * @param channel The name of the channel to join (eg "#cs").
- */
- public final void joinChannel(String channel) {
- this.sendRawLine("JOIN " + channel);
- }
-
-
- /**
- * Joins a channel with a key.
- *
- * @param channel The name of the channel to join (eg "#cs").
- * @param key The key that will be used to join the channel.
- */
- public final void joinChannel(String channel, String key) {
- this.joinChannel(channel + " " + key);
- }
-
-
- /**
- * Parts a channel.
- *
- * @param channel The name of the channel to leave.
- */
- public final void partChannel(String channel) {
- this.sendRawLine("PART " + channel);
- }
-
-
- /**
- * Parts a channel, giving a reason.
- *
- * @param channel The name of the channel to leave.
- * @param reason The reason for parting the channel.
- */
- public final void partChannel(String channel, String reason) {
- this.sendRawLine("PART " + channel + " :" + reason);
- }
-
-
- /**
- * Quits from the IRC server.
- * Providing we are actually connected to an IRC server, the
- * onDisconnect() method will be called as soon as the IRC server
- * disconnects us.
- */
- public void quitServer() {
- this.quitServer("");
- }
-
-
- /**
- * Quits from the IRC server with a reason.
- * Providing we are actually connected to an IRC server, the
- * onDisconnect() method will be called as soon as the IRC server
- * disconnects us.
- *
- * @param reason The reason for quitting the server.
- */
- public final void quitServer(String reason) {
- this.sendRawLine("QUIT :" + reason);
- }
-
-
- /**
- * Sends a raw line to the IRC server as soon as possible, bypassing the
- * outgoing message queue.
- *
- * @param line The raw line to send to the IRC server.
- */
- public final synchronized void sendRawLine(String line) {
- if (isConnected()) {
- _inputThread.sendRawLine(line);
- }
- }
-
- /**
- * Sends a raw line through the outgoing message queue.
- *
- * @param line The raw line to send to the IRC server.
- */
- public final synchronized void sendRawLineViaQueue(String line) {
- if (line == null) {
- throw new NullPointerException("Cannot send null messages to server");
- }
- if (isConnected()) {
- _outQueue.add(line);
- }
- }
-
-
- /**
- * Sends a message to a channel or a private message to a user. These
- * messages are added to the outgoing message queue and sent at the
- * earliest possible opportunity.
- *
- * Some examples: -
- *
- * This method issues a raw NICKSERV command to the server, and is therefore
- * safer than the alternative approach of sending a private message to
- * NickServ. The latter approach is considered dangerous, as it may cause
- * you to inadvertently transmit your password to an untrusted party if you
- * connect to a network which does not run a NickServ service and where the
- * untrusted party has assumed the nick "NickServ". However, if your IRC
- * network is only compatible with the private message approach, you may
- * typically identify like so:
- *
- * Some IRC servers support certain parameters for LIST requests.
- * One example is a parameter of ">10" to list only those channels
- * that have more than 10 users in them. Whether these parameters
- * are supported or not will depend on the IRC server software.
- *
- * @param parameters The parameters to supply when requesting the
- * list.
- *
- * @see #onChannelInfo(String,int,String) onChannelInfo
- */
- public final void listChannels(String parameters) {
- if (parameters == null) {
- this.sendRawLine("LIST");
- }
- else {
- this.sendRawLine("LIST " + parameters);
- }
- }
-
-
- /**
- * Sends a file to another user. Resuming is supported.
- * The other user must be able to connect directly to your bot to be
- * able to receive the file.
- *
- * You may throttle the speed of this file transfer by calling the
- * setPacketDelay method on the DccFileTransfer that is returned.
- *
- * This method may not be overridden.
- *
- * @since 0.9c
- *
- * @param file The file to send.
- * @param nick The user to whom the file is to be sent.
- * @param timeout The number of milliseconds to wait for the recipient to
- * acccept the file (we recommend about 120000).
- *
- * @return The DccFileTransfer that can be used to monitor this transfer.
- *
- * @see DccFileTransfer
- *
- */
- public final DccFileTransfer dccSendFile(File file, String nick, int timeout) {
- DccFileTransfer transfer = new DccFileTransfer(this, _dccManager, file, nick, timeout);
- transfer.doSend(true);
- return transfer;
- }
-
-
- /**
- * Receives a file that is being sent to us by a DCC SEND request.
- * Please use the onIncomingFileTransfer method to receive files.
- *
- * @deprecated As of PircBot 1.2.0, use {@link #onIncomingFileTransfer(DccFileTransfer)}
- */
- protected final void dccReceiveFile(File file, long address, int port, int size) {
- throw new RuntimeException("dccReceiveFile is deprecated, please use sendFile");
- }
-
-
- /**
- * Attempts to establish a DCC CHAT session with a client. This method
- * issues the connection request to the client and then waits for the
- * client to respond. If the connection is successfully made, then a
- * DccChat object is returned by this method. If the connection is not
- * made within the time limit specified by the timeout value, then null
- * is returned.
- *
- * It is strongly recommended that you call this method within a new
- * Thread, as it may take a long time to return.
- *
- * This method may not be overridden.
- *
- * @since PircBot 0.9.8
- *
- * @param nick The nick of the user we are trying to establish a chat with.
- * @param timeout The number of milliseconds to wait for the recipient to
- * accept the chat connection (we recommend about 120000).
- *
- * @return a DccChat object that can be used to send and recieve lines of
- * text. Returns null if the connection could not be made.
- *
- * @see DccChat
- */
- public final DccChat dccSendChatRequest(String nick, int timeout) {
- DccChat chat = null;
- try {
- ServerSocket ss = null;
-
- int[] ports = getDccPorts();
- if (ports == null) {
- // Use any free port.
- ss = new ServerSocket(0);
- }
- else {
- for (int i = 0; i < ports.length; i++) {
- try {
- ss = new ServerSocket(ports[i]);
- // Found a port number we could use.
- break;
- }
- catch (Exception e) {
- // Do nothing; go round and try another port.
- }
- }
- if (ss == null) {
- // No ports could be used.
- throw new IOException("All ports returned by getDccPorts() are in use.");
- }
- }
-
- ss.setSoTimeout(timeout);
- int port = ss.getLocalPort();
-
- InetAddress inetAddress = getDccInetAddress();
- if (inetAddress == null) {
- inetAddress = getInetAddress();
- }
- byte[] ip = inetAddress.getAddress();
- long ipNum = ipToLong(ip);
-
- sendCTCPCommand(nick, "DCC CHAT chat " + ipNum + " " + port);
-
- // The client may now connect to us to chat.
- Socket socket = ss.accept();
-
- // Close the server socket now that we've finished with it.
- ss.close();
-
- chat = new DccChat(this, nick, socket);
- }
- catch (Exception e) {
- // Do nothing.
- }
- return chat;
- }
-
-
- /**
- * Attempts to accept a DCC CHAT request by a client.
- * Please use the onIncomingChatRequest method to receive files.
- *
- * @deprecated As of PircBot 1.2.0, use {@link #onIncomingChatRequest(DccChat)}
- */
- protected final DccChat dccAcceptChatRequest(String sourceNick, long address, int port) {
- throw new RuntimeException("dccAcceptChatRequest is deprecated, please use onIncomingChatRequest");
- }
-
-
- /**
- * Adds a line to the log. This log is currently output to the standard
- * output and is in the correct format for use by tools such as pisg, the
- * Perl IRC Statistics Generator. You may override this method if you wish
- * to do something else with log entries.
- * Each line in the log begins with a number which
- * represents the logging time (as the number of milliseconds since the
- * epoch). This timestamp and the following log entry are separated by
- * a single space character, " ". Outgoing messages are distinguishable
- * by a log entry that has ">>>" immediately following the space character
- * after the timestamp. DCC events use "+++" and warnings about unhandled
- * Exceptions and Errors use "###".
- *
- * This implementation of the method will only cause log entries to be
- * output if the PircBot has had its verbose mode turned on by calling
- * setVerbose(true);
- *
- * @param line The line to add to the log.
- */
- public void log(String line) {
- if (_verbose) {
- // XXX: PircBot Patch: Log to debug log instead of standard output
- Log.d(TAG, line);
- //System.out.println(System.currentTimeMillis() + " " + line);
- }
- }
-
-
- /**
- * This method handles events when any line of text arrives from the server,
- * then calling the appropriate method in the PircBot. This method is
- * protected and only called by the InputThread for this instance.
- *
- * This method may not be overridden!
- *
- * @param line The raw line of text from the server.
- */
- protected void handleLine(String line) {
- this.log(line);
-
- // Check for server pings.
- if (line.startsWith("PING ")) {
- // Respond to the ping and return immediately.
- this.onServerPing(line.substring(5));
- return;
- }
-
- String sourceNick = "";
- String sourceLogin = "";
- String sourceHostname = "";
-
- StringTokenizer tokenizer = new StringTokenizer(line);
- String senderInfo = tokenizer.nextToken();
- String command = tokenizer.nextToken();
- String target = null;
-
- int exclamation = senderInfo.indexOf("!");
- int at = senderInfo.indexOf("@");
- if (senderInfo.startsWith(":")) {
- if (exclamation > 0 && at > 0 && exclamation < at) {
- sourceNick = senderInfo.substring(1, exclamation);
- sourceLogin = senderInfo.substring(exclamation + 1, at);
- sourceHostname = senderInfo.substring(at + 1);
- }
- else {
-
- if (tokenizer.hasMoreTokens()) {
- String token = command;
-
- int code = -1;
- try {
- code = Integer.parseInt(token);
- }
- catch (NumberFormatException e) {
- // Keep the existing value.
- }
-
- if (code != -1) {
- String errorStr = token;
- String response = line.substring(line.indexOf(errorStr, senderInfo.length()) + 4, line.length());
- this.processServerResponse(code, response);
- // Return from the method.
- return;
- }
- else {
- // This is not a server response.
- // It must be a nick without login and hostname.
- // (or maybe a NOTICE or suchlike from the server)
- sourceNick = senderInfo;
- target = token;
- }
- }
- else {
- // We don't know what this line means.
- this.onUnknown(line);
- // Return from the method;
- return;
- }
-
- }
- }
-
- command = command.toUpperCase();
- if (sourceNick.startsWith(":")) {
- sourceNick = sourceNick.substring(1);
- }
- if (target == null) {
- target = tokenizer.nextToken();
- }
- if (target.startsWith(":")) {
- target = target.substring(1);
- }
-
- // Check for CTCP requests.
- if (command.equals("PRIVMSG") && line.indexOf(":\u0001") > 0 && line.endsWith("\u0001")) {
- String request = line.substring(line.indexOf(":\u0001") + 2, line.length() - 1);
- if (request.equals("VERSION")) {
- // VERSION request
- this.onVersion(sourceNick, sourceLogin, sourceHostname, target);
- }
- else if (request.startsWith("ACTION ")) {
- // ACTION request
- this.onAction(sourceNick, sourceLogin, sourceHostname, target, request.substring(7));
- }
- else if (request.startsWith("PING ")) {
- // PING request
- this.onPing(sourceNick, sourceLogin, sourceHostname, target, request.substring(5));
- }
- else if (request.equals("TIME")) {
- // TIME request
- this.onTime(sourceNick, sourceLogin, sourceHostname, target);
- }
- else if (request.equals("FINGER")) {
- // FINGER request
- this.onFinger(sourceNick, sourceLogin, sourceHostname, target);
- }
- else if ((tokenizer = new StringTokenizer(request)).countTokens() >= 5 && tokenizer.nextToken().equals("DCC")) {
- // This is a DCC request.
- boolean success = _dccManager.processRequest(sourceNick, sourceLogin, sourceHostname, request);
- if (!success) {
- // The DccManager didn't know what to do with the line.
- this.onUnknown(line);
- }
- }
- else {
- // An unknown CTCP message - ignore it.
- this.onUnknown(line);
- }
- }
- else if (command.equals("PRIVMSG") && _channelPrefixes.indexOf(target.charAt(0)) >= 0) {
- // This is a normal message to a channel.
- this.onMessage(target, sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2));
- }
- else if (command.equals("PRIVMSG")) {
- // This is a private message to us.
- this.onPrivateMessage(sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2));
- }
- else if (command.equals("JOIN")) {
- // Someone is joining a channel.
- String channel = target;
- this.addUser(channel, new User("", sourceNick));
- this.onJoin(channel, sourceNick, sourceLogin, sourceHostname);
- }
- else if (command.equals("PART")) {
- // Someone is parting from a channel.
- this.removeUser(target, sourceNick);
- if (sourceNick.equals(this.getNick())) {
- this.removeChannel(target);
- }
- this.onPart(target, sourceNick, sourceLogin, sourceHostname);
- }
- else if (command.equals("NICK")) {
- // Somebody is changing their nick.
- String newNick = target;
- this.renameUser(sourceNick, newNick);
- if (sourceNick.equals(this.getNick())) {
- // Update our nick if it was us that changed nick.
- this.setNick(newNick);
- }
- this.onNickChange(sourceNick, sourceLogin, sourceHostname, newNick);
- }
- else if (command.equals("NOTICE")) {
- // Someone is sending a notice.
- this.onNotice(sourceNick, sourceLogin, sourceHostname, target, line.substring(line.indexOf(" :") + 2));
- }
- else if (command.equals("QUIT")) {
- // Someone has quit from the IRC server.
-
- // XXX: Pircbot Patch - Call onQuit before removing the user. This way we
- // are able to know which channels the user was on.
- this.onQuit(sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2));
-
- if (sourceNick.equals(this.getNick())) {
- this.removeAllChannels();
- }
- else {
- this.removeUser(sourceNick);
- }
- }
- else if (command.equals("KICK")) {
- // Somebody has been kicked from a channel.
- String recipient = tokenizer.nextToken();
- if (recipient.equals(this.getNick())) {
- this.removeChannel(target);
- }
- this.removeUser(target, recipient);
- this.onKick(target, sourceNick, sourceLogin, sourceHostname, recipient, line.substring(line.indexOf(" :") + 2));
- }
- else if (command.equals("MODE")) {
- // Somebody is changing the mode on a channel or user.
- String mode = line.substring(line.indexOf(target, 2) + target.length() + 1);
- if (mode.startsWith(":")) {
- mode = mode.substring(1);
- }
- this.processMode(target, sourceNick, sourceLogin, sourceHostname, mode);
- }
- else if (command.equals("TOPIC")) {
- // Someone is changing the topic.
- this.onTopic(target, line.substring(line.indexOf(" :") + 2), sourceNick, System.currentTimeMillis(), true);
- }
- else if (command.equals("INVITE")) {
- // Somebody is inviting somebody else into a channel.
- this.onInvite(target, sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2));
- }
- else {
- // If we reach this point, then we've found something that the PircBot
- // Doesn't currently deal with.
- this.onUnknown(line);
- }
-
- }
-
-
- /**
- * This method is called once the PircBot has successfully connected to
- * the IRC server.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.6
- */
- protected void onConnect() {}
-
-
- /**
- * This method carries out the actions to be performed when the PircBot
- * gets disconnected. This may happen if the PircBot quits from the
- * server, or if the connection is unexpectedly lost.
- *
- * Disconnection from the IRC server is detected immediately if either
- * we or the server close the connection normally. If the connection to
- * the server is lost, but neither we nor the server have explicitly closed
- * the connection, then it may take a few minutes to detect (this is
- * commonly referred to as a "ping timeout").
- *
- * If you wish to get your IRC bot to automatically rejoin a server after
- * the connection has been lost, then this is probably the ideal method to
- * override to implement such functionality.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- */
- protected void onDisconnect() {}
-
-
- /**
- * This method is called by the PircBot when a numeric response
- * is received from the IRC server. We use this method to
- * allow PircBot to process various responses from the server
- * before then passing them on to the onServerResponse method.
- *
- * Note that this method is private and should not appear in any
- * of the javadoc generated documenation.
- *
- * @param code The three-digit numerical code for the response.
- * @param response The full response from the IRC server.
- */
- private final void processServerResponse(int code, String response) {
-
- if (code == RPL_LIST) {
- // This is a bit of information about a channel.
- int firstSpace = response.indexOf(' ');
- int secondSpace = response.indexOf(' ', firstSpace + 1);
- int thirdSpace = response.indexOf(' ', secondSpace + 1);
- int colon = response.indexOf(':');
- String channel = response.substring(firstSpace + 1, secondSpace);
- int userCount = 0;
- try {
- userCount = Integer.parseInt(response.substring(secondSpace + 1, thirdSpace));
- }
- catch (NumberFormatException e) {
- // Stick with the value of zero.
- }
- String topic = response.substring(colon + 1);
- this.onChannelInfo(channel, userCount, topic);
- }
- else if (code == RPL_TOPIC) {
- // This is topic information about a channel we've just joined.
- int firstSpace = response.indexOf(' ');
- int secondSpace = response.indexOf(' ', firstSpace + 1);
- int colon = response.indexOf(':');
- String channel = response.substring(firstSpace + 1, secondSpace);
- String topic = response.substring(colon + 1);
-
- _topics.put(channel, topic);
-
- // For backwards compatibility only - this onTopic method is deprecated.
- this.onTopic(channel, topic);
- }
- else if (code == RPL_TOPICINFO) {
- StringTokenizer tokenizer = new StringTokenizer(response);
- tokenizer.nextToken();
- String channel = tokenizer.nextToken();
- String setBy = tokenizer.nextToken();
- long date = 0;
- try {
- date = Long.parseLong(tokenizer.nextToken()) * 1000;
- }
- catch (NumberFormatException e) {
- // Stick with the default value of zero.
- }
-
- String topic = (String) _topics.get(channel);
- _topics.remove(channel);
-
- this.onTopic(channel, topic, setBy, date, false);
- }
- else if (code == RPL_NAMREPLY) {
- // This is a list of nicks in a channel that we've just joined.
- int channelEndIndex = response.indexOf(" :");
- String channel = response.substring(response.lastIndexOf(' ', channelEndIndex - 1) + 1, channelEndIndex);
-
- StringTokenizer tokenizer = new StringTokenizer(response.substring(response.indexOf(" :") + 2));
- while (tokenizer.hasMoreTokens()) {
- String nick = tokenizer.nextToken();
- String prefix = "";
- if (nick.startsWith("@")) {
- // User is an operator in this channel.
- prefix = "@";
- }
- else if (nick.startsWith("+")) {
- // User is voiced in this channel.
- prefix = "+";
- }
- else if (nick.startsWith(".")) {
- // Some wibbly status I've never seen before...
- prefix = ".";
- }
- nick = nick.substring(prefix.length());
- this.addUser(channel, new User(prefix, nick));
- }
- }
- else if (code == RPL_ENDOFNAMES) {
- // This is the end of a NAMES list, so we know that we've got
- // the full list of users in the channel that we just joined.
- String channel = response.substring(response.indexOf(' ') + 1, response.indexOf(" :"));
- User[] users = this.getUsers(channel);
- this.onUserList(channel, users);
- }
-
- this.onServerResponse(code, response);
- }
-
-
- /**
- * This method is called when we receive a numeric response from the
- * IRC server.
- *
- * Numerics in the range from 001 to 099 are used for client-server
- * connections only and should never travel between servers. Replies
- * generated in response to commands are found in the range from 200
- * to 399. Error replies are found in the range from 400 to 599.
- *
- * For example, we can use this method to discover the topic of a
- * channel when we join it. If we join the channel #test which
- * has a topic of "I am King of Test" then the response
- * will be "
- * PircBot implements the interface ReplyConstants, which contains
- * contstants that you may find useful here.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param code The three-digit numerical code for the response.
- * @param response The full response from the IRC server.
- *
- * @see ReplyConstants
- */
- protected void onServerResponse(int code, String response) {}
-
-
- /**
- * This method is called when we receive a user list from the server
- * after joining a channel.
- *
- * Shortly after joining a channel, the IRC server sends a list of all
- * users in that channel. The PircBot collects this information and
- * calls this method as soon as it has the full list.
- *
- * To obtain the nick of each user in the channel, call the getNick()
- * method on each User object in the array.
- *
- * At a later time, you may call the getUsers method to obtain an
- * up to date list of the users in the channel.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 1.0.0
- *
- * @param channel The name of the channel.
- * @param users An array of User objects belonging to this channel.
- *
- * @see User
- */
- protected void onUserList(String channel, User[] users) {}
-
-
- /**
- * This method is called whenever a message is sent to a channel.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param channel The channel to which the message was sent.
- * @param sender The nick of the person who sent the message.
- * @param login The login of the person who sent the message.
- * @param hostname The hostname of the person who sent the message.
- * @param message The actual message sent to the channel.
- */
- protected void onMessage(String channel, String sender, String login, String hostname, String message) {}
-
-
- /**
- * This method is called whenever a private message is sent to the PircBot.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param sender The nick of the person who sent the private message.
- * @param login The login of the person who sent the private message.
- * @param hostname The hostname of the person who sent the private message.
- * @param message The actual message.
- */
- protected void onPrivateMessage(String sender, String login, String hostname, String message) {}
-
-
- /**
- * This method is called whenever an ACTION is sent from a user. E.g.
- * such events generated by typing "/me goes shopping" in most IRC clients.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param sender The nick of the user that sent the action.
- * @param login The login of the user that sent the action.
- * @param hostname The hostname of the user that sent the action.
- * @param target The target of the action, be it a channel or our nick.
- * @param action The action carried out by the user.
- */
- protected void onAction(String sender, String login, String hostname, String target, String action) {}
-
-
- /**
- * This method is called whenever we receive a notice.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param sourceNick The nick of the user that sent the notice.
- * @param sourceLogin The login of the user that sent the notice.
- * @param sourceHostname The hostname of the user that sent the notice.
- * @param target The target of the notice, be it our nick or a channel name.
- * @param notice The notice message.
- */
- protected void onNotice(String sourceNick, String sourceLogin, String sourceHostname, String target, String notice) {}
-
-
- /**
- * This method is called whenever someone (possibly us) joins a channel
- * which we are on.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param channel The channel which somebody joined.
- * @param sender The nick of the user who joined the channel.
- * @param login The login of the user who joined the channel.
- * @param hostname The hostname of the user who joined the channel.
- */
- protected void onJoin(String channel, String sender, String login, String hostname) {}
-
-
- /**
- * This method is called whenever someone (possibly us) parts a channel
- * which we are on.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param channel The channel which somebody parted from.
- * @param sender The nick of the user who parted from the channel.
- * @param login The login of the user who parted from the channel.
- * @param hostname The hostname of the user who parted from the channel.
- */
- protected void onPart(String channel, String sender, String login, String hostname) {}
-
-
- /**
- * This method is called whenever someone (possibly us) changes nick on any
- * of the channels that we are on.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param oldNick The old nick.
- * @param login The login of the user.
- * @param hostname The hostname of the user.
- * @param newNick The new nick.
- */
- protected void onNickChange(String oldNick, String login, String hostname, String newNick) {}
-
-
- /**
- * This method is called whenever someone (possibly us) is kicked from
- * any of the channels that we are in.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param channel The channel from which the recipient was kicked.
- * @param kickerNick The nick of the user who performed the kick.
- * @param kickerLogin The login of the user who performed the kick.
- * @param kickerHostname The hostname of the user who performed the kick.
- * @param recipientNick The unfortunate recipient of the kick.
- * @param reason The reason given by the user who performed the kick.
- */
- protected void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason) {}
-
-
- /**
- * This method is called whenever someone (possibly us) quits from the
- * server. We will only observe this if the user was in one of the
- * channels to which we are connected.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param sourceNick The nick of the user that quit from the server.
- * @param sourceLogin The login of the user that quit from the server.
- * @param sourceHostname The hostname of the user that quit from the server.
- * @param reason The reason given for quitting the server.
- */
- protected void onQuit(String sourceNick, String sourceLogin, String sourceHostname, String reason) {}
-
-
- /**
- * This method is called whenever a user sets the topic, or when
- * PircBot joins a new channel and discovers its topic.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param channel The channel that the topic belongs to.
- * @param topic The topic for the channel.
- *
- * @deprecated As of 1.2.0, replaced by {@link #onTopic(String,String,String,long,boolean)}
- */
- protected void onTopic(String channel, String topic) {}
-
-
- /**
- * This method is called whenever a user sets the topic, or when
- * PircBot joins a new channel and discovers its topic.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param channel The channel that the topic belongs to.
- * @param topic The topic for the channel.
- * @param setBy The nick of the user that set the topic.
- * @param date When the topic was set (milliseconds since the epoch).
- * @param changed True if the topic has just been changed, false if
- * the topic was already there.
- *
- */
- protected void onTopic(String channel, String topic, String setBy, long date, boolean changed) {}
-
-
- /**
- * After calling the listChannels() method in PircBot, the server
- * will start to send us information about each channel on the
- * server. You may override this method in order to receive the
- * information about each channel as soon as it is received.
- *
- * Note that certain channels, such as those marked as hidden,
- * may not appear in channel listings.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param channel The name of the channel.
- * @param userCount The number of users visible in this channel.
- * @param topic The topic for this channel.
- *
- * @see #listChannels() listChannels
- */
- protected void onChannelInfo(String channel, int userCount, String topic) {}
-
-
- /**
- * Called when the mode of a channel is set. We process this in
- * order to call the appropriate onOp, onDeop, etc method before
- * finally calling the override-able onMode method.
- *
- * Note that this method is private and is not intended to appear
- * in the javadoc generated documentation.
- *
- * @param target The channel or nick that the mode operation applies to.
- * @param sourceNick The nick of the user that set the mode.
- * @param sourceLogin The login of the user that set the mode.
- * @param sourceHostname The hostname of the user that set the mode.
- * @param mode The mode that has been set.
- */
- private final void processMode(String target, String sourceNick, String sourceLogin, String sourceHostname, String mode) {
-
- if (_channelPrefixes.indexOf(target.charAt(0)) >= 0) {
- // The mode of a channel is being changed.
- String channel = target;
- StringTokenizer tok = new StringTokenizer(mode);
- String[] params = new String[tok.countTokens()];
-
- int t = 0;
- while (tok.hasMoreTokens()) {
- params[t] = tok.nextToken();
- t++;
- }
-
- char pn = ' ';
- int p = 1;
-
- // All of this is very large and ugly, but it's the only way of providing
- // what the users want :-/
- for (int i = 0; i < params[0].length(); i++) {
- char atPos = params[0].charAt(i);
-
- if (atPos == '+' || atPos == '-') {
- pn = atPos;
- }
- else if (atPos == 'o') {
- if (pn == '+') {
- this.updateUser(channel, OP_ADD, params[p]);
- onOp(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
- }
- else {
- this.updateUser(channel, OP_REMOVE, params[p]);
- onDeop(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
- }
- p++;
- }
- else if (atPos == 'v') {
- if (pn == '+') {
- this.updateUser(channel, VOICE_ADD, params[p]);
- onVoice(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
- }
- else {
- this.updateUser(channel, VOICE_REMOVE, params[p]);
- onDeVoice(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
- }
- p++;
- }
- else if (atPos == 'k') {
- if (pn == '+') {
- onSetChannelKey(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
- }
- else {
- onRemoveChannelKey(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
- }
- p++;
- }
- else if (atPos == 'l') {
- if (pn == '+') {
- onSetChannelLimit(channel, sourceNick, sourceLogin, sourceHostname, Integer.parseInt(params[p]));
- p++;
- }
- else {
- onRemoveChannelLimit(channel, sourceNick, sourceLogin, sourceHostname);
- }
- }
- else if (atPos == 'b') {
- if (pn == '+') {
- onSetChannelBan(channel, sourceNick, sourceLogin, sourceHostname,params[p]);
- }
- else {
- onRemoveChannelBan(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
- }
- p++;
- }
- else if (atPos == 't') {
- if (pn == '+') {
- onSetTopicProtection(channel, sourceNick, sourceLogin, sourceHostname);
- }
- else {
- onRemoveTopicProtection(channel, sourceNick, sourceLogin, sourceHostname);
- }
- }
- else if (atPos == 'n') {
- if (pn == '+') {
- onSetNoExternalMessages(channel, sourceNick, sourceLogin, sourceHostname);
- }
- else {
- onRemoveNoExternalMessages(channel, sourceNick, sourceLogin, sourceHostname);
- }
- }
- else if (atPos == 'i') {
- if (pn == '+') {
- onSetInviteOnly(channel, sourceNick, sourceLogin, sourceHostname);
- }
- else {
- onRemoveInviteOnly(channel, sourceNick, sourceLogin, sourceHostname);
- }
- }
- else if (atPos == 'm') {
- if (pn == '+') {
- onSetModerated(channel, sourceNick, sourceLogin, sourceHostname);
- }
- else {
- onRemoveModerated(channel, sourceNick, sourceLogin, sourceHostname);
- }
- }
- else if (atPos == 'p') {
- if (pn == '+') {
- onSetPrivate(channel, sourceNick, sourceLogin, sourceHostname);
- }
- else {
- onRemovePrivate(channel, sourceNick, sourceLogin, sourceHostname);
- }
- }
- else if (atPos == 's') {
- if (pn == '+') {
- onSetSecret(channel, sourceNick, sourceLogin, sourceHostname);
- }
- else {
- onRemoveSecret(channel, sourceNick, sourceLogin, sourceHostname);
- }
- }
- }
-
- this.onMode(channel, sourceNick, sourceLogin, sourceHostname, mode);
- }
- else {
- // The mode of a user is being changed.
- String nick = target;
- this.onUserMode(nick, sourceNick, sourceLogin, sourceHostname, mode);
- }
- }
-
-
- /**
- * Called when the mode of a channel is set.
- *
- * You may find it more convenient to decode the meaning of the mode
- * string by overriding the onOp, onDeOp, onVoice, onDeVoice,
- * onChannelKey, onDeChannelKey, onChannelLimit, onDeChannelLimit,
- * onChannelBan or onDeChannelBan methods as appropriate.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param channel The channel that the mode operation applies to.
- * @param sourceNick The nick of the user that set the mode.
- * @param sourceLogin The login of the user that set the mode.
- * @param sourceHostname The hostname of the user that set the mode.
- * @param mode The mode that has been set.
- *
- */
- protected void onMode(String channel, String sourceNick, String sourceLogin, String sourceHostname, String mode) {}
-
-
- /**
- * Called when the mode of a user is set.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 1.2.0
- *
- * @param targetNick The nick that the mode operation applies to.
- * @param sourceNick The nick of the user that set the mode.
- * @param sourceLogin The login of the user that set the mode.
- * @param sourceHostname The hostname of the user that set the mode.
- * @param mode The mode that has been set.
- *
- */
- protected void onUserMode(String targetNick, String sourceNick, String sourceLogin, String sourceHostname, String mode) {}
-
-
-
- /**
- * Called when a user (possibly us) gets granted operator status for a channel.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- * @param recipient The nick of the user that got 'opped'.
- */
- protected void onOp(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {}
-
-
- /**
- * Called when a user (possibly us) gets operator status taken away.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- * @param recipient The nick of the user that got 'deopped'.
- */
- protected void onDeop(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {}
-
-
- /**
- * Called when a user (possibly us) gets voice status granted in a channel.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- * @param recipient The nick of the user that got 'voiced'.
- */
- protected void onVoice(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {}
-
-
- /**
- * Called when a user (possibly us) gets voice status removed.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- * @param recipient The nick of the user that got 'devoiced'.
- */
- protected void onDeVoice(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {}
-
-
- /**
- * Called when a channel key is set. When the channel key has been set,
- * other users may only join that channel if they know the key. Channel keys
- * are sometimes referred to as passwords.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- * @param key The new key for the channel.
- */
- protected void onSetChannelKey(String channel, String sourceNick, String sourceLogin, String sourceHostname, String key) {}
-
-
- /**
- * Called when a channel key is removed.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- * @param key The key that was in use before the channel key was removed.
- */
- protected void onRemoveChannelKey(String channel, String sourceNick, String sourceLogin, String sourceHostname, String key) {}
-
-
- /**
- * Called when a user limit is set for a channel. The number of users in
- * the channel cannot exceed this limit.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- * @param limit The maximum number of users that may be in this channel at the same time.
- */
- protected void onSetChannelLimit(String channel, String sourceNick, String sourceLogin, String sourceHostname, int limit) {}
-
-
- /**
- * Called when the user limit is removed for a channel.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onRemoveChannelLimit(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when a user (possibly us) gets banned from a channel. Being
- * banned from a channel prevents any user with a matching hostmask from
- * joining the channel. For this reason, most bans are usually directly
- * followed by the user being kicked :-)
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- * @param hostmask The hostmask of the user that has been banned.
- */
- protected void onSetChannelBan(String channel, String sourceNick, String sourceLogin, String sourceHostname, String hostmask) {}
-
-
- /**
- * Called when a hostmask ban is removed from a channel.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- * @param hostmask
- */
- protected void onRemoveChannelBan(String channel, String sourceNick, String sourceLogin, String sourceHostname, String hostmask) {}
-
-
- /**
- * Called when topic protection is enabled for a channel. Topic protection
- * means that only operators in a channel may change the topic.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onSetTopicProtection(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when topic protection is removed for a channel.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onRemoveTopicProtection(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when a channel is set to only allow messages from users that
- * are in the channel.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onSetNoExternalMessages(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when a channel is set to allow messages from any user, even
- * if they are not actually in the channel.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onRemoveNoExternalMessages(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when a channel is set to 'invite only' mode. A user may only
- * join the channel if they are invited by someone who is already in the
- * channel.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onSetInviteOnly(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when a channel has 'invite only' removed.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onRemoveInviteOnly(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when a channel is set to 'moderated' mode. If a channel is
- * moderated, then only users who have been 'voiced' or 'opped' may speak
- * or change their nicks.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onSetModerated(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when a channel has moderated mode removed.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onRemoveModerated(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when a channel is marked as being in private mode.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onSetPrivate(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when a channel is marked as not being in private mode.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onRemovePrivate(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when a channel is set to be in 'secret' mode. Such channels
- * typically do not appear on a server's channel listing.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onSetSecret(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when a channel has 'secret' mode removed.
- *
- * This is a type of mode change and is also passed to the onMode
- * method in the PircBot class.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param channel The channel in which the mode change took place.
- * @param sourceNick The nick of the user that performed the mode change.
- * @param sourceLogin The login of the user that performed the mode change.
- * @param sourceHostname The hostname of the user that performed the mode change.
- */
- protected void onRemoveSecret(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
-
-
- /**
- * Called when we are invited to a channel by a user.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 0.9.5
- *
- * @param targetNick The nick of the user being invited - should be us!
- * @param sourceNick The nick of the user that sent the invitation.
- * @param sourceLogin The login of the user that sent the invitation.
- * @param sourceHostname The hostname of the user that sent the invitation.
- * @param channel The channel that we're being invited to.
- */
- protected void onInvite(String targetNick, String sourceNick, String sourceLogin, String sourceHostname, String channel) {}
-
-
- /**
- * This method used to be called when a DCC SEND request was sent to the PircBot.
- * Please use the onIncomingFileTransfer method to receive files, as it
- * has better functionality and supports resuming.
- *
- * @deprecated As of PircBot 1.2.0, use {@link #onIncomingFileTransfer(DccFileTransfer)}
- */
- protected void onDccSendRequest(String sourceNick, String sourceLogin, String sourceHostname, String filename, long address, int port, int size) {}
-
-
- /**
- * This method used to be called when a DCC CHAT request was sent to the PircBot.
- * Please use the onIncomingChatRequest method to accept chats, as it
- * has better functionality.
- *
- * @deprecated As of PircBot 1.2.0, use {@link #onIncomingChatRequest(DccChat)}
- */
- protected void onDccChatRequest(String sourceNick, String sourceLogin, String sourceHostname, long address, int port) {}
-
-
- /**
- * This method is called whenever a DCC SEND request is sent to the PircBot.
- * This means that a client has requested to send a file to us.
- * This abstract implementation performs no action, which means that all
- * DCC SEND requests will be ignored by default. If you wish to receive
- * the file, then you may override this method and call the receive method
- * on the DccFileTransfer object, which connects to the sender and downloads
- * the file.
- *
- * Example:
- *
- * Warning: Receiving an incoming file transfer will cause a file
- * to be written to disk. Please ensure that you make adequate security
- * checks so that this file does not overwrite anything important!
- *
- * Each time a file is received, it happens within a new Thread
- * in order to allow multiple files to be downloaded by the PircBot
- * at the same time.
- *
- * If you allow resuming and the file already partly exists, it will
- * be appended to instead of overwritten. If resuming is not enabled,
- * the file will be overwritten if it already exists.
- *
- * You can throttle the speed of the transfer by calling the setPacketDelay
- * method on the DccFileTransfer object, either before you receive the
- * file or at any moment during the transfer.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 1.2.0
- *
- * @param transfer The DcccFileTransfer that you may accept.
- *
- * @see DccFileTransfer
- *
- */
- protected void onIncomingFileTransfer(DccFileTransfer transfer) {}
-
-
- /**
- * This method gets called when a DccFileTransfer has finished.
- * If there was a problem, the Exception will say what went wrong.
- * If the file was sent successfully, the Exception will be null.
- *
- * Both incoming and outgoing file transfers are passed to this method.
- * You can determine the type by calling the isIncoming or isOutgoing
- * methods on the DccFileTransfer object.
- *
- * @since PircBot 1.2.0
- *
- * @param transfer The DccFileTransfer that has finished.
- * @param e null if the file was transfered successfully, otherwise this
- * will report what went wrong.
- *
- * @see DccFileTransfer
- *
- */
- protected void onFileTransferFinished(DccFileTransfer transfer, Exception e) {}
-
-
- /**
- * This method will be called whenever a DCC Chat request is received.
- * This means that a client has requested to chat to us directly rather
- * than via the IRC server. This is useful for sending many lines of text
- * to and from the bot without having to worry about flooding the server
- * or any operators of the server being able to "spy" on what is being
- * said. This abstract implementation performs no action, which means
- * that all DCC CHAT requests will be ignored by default.
- *
- * If you wish to accept the connection, then you may override this
- * method and call the accept() method on the DccChat object, which
- * connects to the sender of the chat request and allows lines to be
- * sent to and from the bot.
- *
- * Your bot must be able to connect directly to the user that sent the
- * request.
- *
- * Example:
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @since PircBot 1.2.0
- *
- * @param chat A DccChat object that represents the incoming chat request.
- *
- * @see DccChat
- *
- */
- protected void onIncomingChatRequest(DccChat chat) {}
-
-
- /**
- * This method is called whenever we receive a VERSION request.
- * This abstract implementation responds with the PircBot's _version string,
- * so if you override this method, be sure to either mimic its functionality
- * or to call super.onVersion(...);
- *
- * @param sourceNick The nick of the user that sent the VERSION request.
- * @param sourceLogin The login of the user that sent the VERSION request.
- * @param sourceHostname The hostname of the user that sent the VERSION request.
- * @param target The target of the VERSION request, be it our nick or a channel name.
- */
- protected void onVersion(String sourceNick, String sourceLogin, String sourceHostname, String target) {
- this.sendRawLine("NOTICE " + sourceNick + " :\u0001VERSION " + _version + "\u0001");
- }
-
-
- /**
- * This method is called whenever we receive a PING request from another
- * user.
- *
- * This abstract implementation responds correctly, so if you override this
- * method, be sure to either mimic its functionality or to call
- * super.onPing(...);
- *
- * @param sourceNick The nick of the user that sent the PING request.
- * @param sourceLogin The login of the user that sent the PING request.
- * @param sourceHostname The hostname of the user that sent the PING request.
- * @param target The target of the PING request, be it our nick or a channel name.
- * @param pingValue The value that was supplied as an argument to the PING command.
- */
- protected void onPing(String sourceNick, String sourceLogin, String sourceHostname, String target, String pingValue) {
- this.sendRawLine("NOTICE " + sourceNick + " :\u0001PING " + pingValue + "\u0001");
- }
-
-
- /**
- * The actions to perform when a PING request comes from the server.
- *
- * This sends back a correct response, so if you override this method,
- * be sure to either mimic its functionality or to call
- * super.onServerPing(response);
- *
- * @param response The response that should be given back in your PONG.
- */
- protected void onServerPing(String response) {
- this.sendRawLine("PONG " + response);
- }
-
-
- /**
- * This method is called whenever we receive a TIME request.
- *
- * This abstract implementation responds correctly, so if you override this
- * method, be sure to either mimic its functionality or to call
- * super.onTime(...);
- *
- * @param sourceNick The nick of the user that sent the TIME request.
- * @param sourceLogin The login of the user that sent the TIME request.
- * @param sourceHostname The hostname of the user that sent the TIME request.
- * @param target The target of the TIME request, be it our nick or a channel name.
- */
- protected void onTime(String sourceNick, String sourceLogin, String sourceHostname, String target) {
- this.sendRawLine("NOTICE " + sourceNick + " :\u0001TIME " + new Date().toString() + "\u0001");
- }
-
-
- /**
- * This method is called whenever we receive a FINGER request.
- *
- * This abstract implementation responds correctly, so if you override this
- * method, be sure to either mimic its functionality or to call
- * super.onFinger(...);
- *
- * @param sourceNick The nick of the user that sent the FINGER request.
- * @param sourceLogin The login of the user that sent the FINGER request.
- * @param sourceHostname The hostname of the user that sent the FINGER request.
- * @param target The target of the FINGER request, be it our nick or a channel name.
- */
- protected void onFinger(String sourceNick, String sourceLogin, String sourceHostname, String target) {
- this.sendRawLine("NOTICE " + sourceNick + " :\u0001FINGER " + _finger + "\u0001");
- }
-
-
- /**
- * This method is called whenever we receive a line from the server that
- * the PircBot has not been programmed to recognise.
- *
- * The implementation of this method in the PircBot abstract class
- * performs no actions and may be overridden as required.
- *
- * @param line The raw line that was received from the server.
- */
- protected void onUnknown(String line) {
- // And then there were none :)
- }
-
-
- /**
- * Sets the verbose mode. If verbose mode is set to true, then log entries
- * will be printed to the standard output. The default value is false and
- * will result in no output. For general development, we strongly recommend
- * setting the verbose mode to true.
- *
- * @param verbose true if verbose mode is to be used. Default is false.
- */
- public final void setVerbose(boolean verbose) {
- _verbose = verbose;
- }
-
-
- /**
- * Sets the name of the bot, which will be used as its nick when it
- * tries to join an IRC server. This should be set before joining
- * any servers, otherwise the default nick will be used. You would
- * typically call this method from the constructor of the class that
- * extends PircBot.
- *
- * The changeNick method should be used if you wish to change your nick
- * when you are connected to a server.
- *
- * @param name The new name of the Bot.
- */
- protected final void setName(String name) {
- _name = name;
- }
-
-
- /**
- * Sets the internal nick of the bot. This is only to be called by the
- * PircBot class in response to notification of nick changes that apply
- * to us.
- *
- * @param nick The new nick.
- */
- private final void setNick(String nick) {
- _nick = nick;
- }
-
-
- /**
- * Sets the internal login of the Bot. This should be set before joining
- * any servers.
- *
- * @param login The new login of the Bot.
- */
- protected final void setLogin(String login) {
- _login = login;
- }
-
-
- /**
- * Sets the internal version of the Bot. This should be set before joining
- * any servers.
- *
- * @param version The new version of the Bot.
- */
- protected final void setVersion(String version) {
- _version = version;
- }
-
-
- /**
- * Sets the interal finger message. This should be set before joining
- * any servers.
- *
- * @param finger The new finger message for the Bot.
- */
- protected final void setFinger(String finger) {
- _finger = finger;
- }
-
-
- /**
- * Gets the name of the PircBot. This is the name that will be used as
- * as a nick when we try to join servers.
- *
- * @return The name of the PircBot.
- */
- public final String getName() {
- return _name;
- }
-
-
- /**
- * Returns the current nick of the bot. Note that if you have just changed
- * your nick, this method will still return the old nick until confirmation
- * of the nick change is received from the server.
- *
- * The nick returned by this method is maintained only by the PircBot
- * class and is guaranteed to be correct in the context of the IRC server.
- *
- * @since PircBot 1.0.0
- *
- * @return The current nick of the bot.
- */
- public String getNick() {
- return _nick;
- }
-
-
- /**
- * Gets the internal login of the PircBot.
- *
- * @return The login of the PircBot.
- */
- public final String getLogin() {
- return _login;
- }
-
-
- /**
- * Gets the internal version of the PircBot.
- *
- * @return The version of the PircBot.
- */
- public final String getVersion() {
- return _version;
- }
-
-
- /**
- * Gets the internal finger message of the PircBot.
- *
- * @return The finger message of the PircBot.
- */
- public final String getFinger() {
- return _finger;
- }
-
-
- /**
- * Returns whether or not the PircBot is currently connected to a server.
- * The result of this method should only act as a rough guide,
- * as the result may not be valid by the time you act upon it.
- *
- * @return True if and only if the PircBot is currently connected to a server.
- */
- public final synchronized boolean isConnected() {
- return _inputThread != null && _inputThread.isConnected();
- }
-
-
- /**
- * Sets the number of milliseconds to delay between consecutive
- * messages when there are multiple messages waiting in the
- * outgoing message queue. This has a default value of 1000ms.
- * It is a good idea to stick to this default value, as it will
- * prevent your bot from spamming servers and facing the subsequent
- * wrath! However, if you do need to change this delay value (not
- * recommended), then this is the method to use.
- *
- * @param delay The number of milliseconds between each outgoing message.
- *
- */
- public final void setMessageDelay(long delay) {
- if (delay < 0) {
- throw new IllegalArgumentException("Cannot have a negative time.");
- }
- _messageDelay = delay;
- }
-
-
- /**
- * Returns the number of milliseconds that will be used to separate
- * consecutive messages to the server from the outgoing message queue.
- *
- * @return Number of milliseconds.
- */
- public final long getMessageDelay() {
- return _messageDelay;
- }
-
-
- /**
- * Gets the maximum length of any line that is sent via the IRC protocol.
- * The IRC RFC specifies that line lengths, including the trailing \r\n
- * must not exceed 512 bytes. Hence, there is currently no option to
- * change this value in PircBot. All lines greater than this length
- * will be truncated before being sent to the IRC server.
- *
- * @return The maximum line length (currently fixed at 512)
- */
- public final int getMaxLineLength() {
- return InputThread.MAX_LINE_LENGTH;
- }
-
-
- /**
- * Gets the number of lines currently waiting in the outgoing message Queue.
- * If this returns 0, then the Queue is empty and any new message is likely
- * to be sent to the IRC server immediately.
- *
- * @since PircBot 0.9.9
- *
- * @return The number of lines in the outgoing message Queue.
- */
- public final int getOutgoingQueueSize() {
- return _outQueue.size();
- }
-
-
- /**
- * Returns the name of the last IRC server the PircBot tried to connect to.
- * This does not imply that the connection attempt to the server was
- * successful (we suggest you look at the onConnect method).
- * A value of null is returned if the PircBot has never tried to connect
- * to a server.
- *
- * @return The name of the last machine we tried to connect to. Returns
- * null if no connection attempts have ever been made.
- */
- public final String getServer() {
- return _server;
- }
-
-
- /**
- * Returns the port number of the last IRC server that the PircBot tried
- * to connect to.
- * This does not imply that the connection attempt to the server was
- * successful (we suggest you look at the onConnect method).
- * A value of -1 is returned if the PircBot has never tried to connect
- * to a server.
- *
- * @since PircBot 0.9.9
- *
- * @return The port number of the last IRC server we connected to.
- * Returns -1 if no connection attempts have ever been made.
- */
- public final int getPort() {
- return _port;
- }
-
-
- /**
- * Returns the last password that we used when connecting to an IRC server.
- * This does not imply that the connection attempt to the server was
- * successful (we suggest you look at the onConnect method).
- * A value of null is returned if the PircBot has never tried to connect
- * to a server using a password.
- *
- * @since PircBot 0.9.9
- *
- * @return The last password that we used when connecting to an IRC server.
- * Returns null if we have not previously connected using a password.
- */
- public final String getPassword() {
- return _password;
- }
-
-
- /**
- * A convenient method that accepts an IP address represented as a
- * long and returns an integer array of size 4 representing the same
- * IP address.
- *
- * @since PircBot 0.9.4
- *
- * @param address the long value representing the IP address.
- *
- * @return An int[] of size 4.
- */
- public int[] longToIp(long address) {
- int[] ip = new int[4];
- for (int i = 3; i >= 0; i--) {
- ip[i] = (int) (address % 256);
- address = address / 256;
- }
- return ip;
- }
-
-
- /**
- * A convenient method that accepts an IP address represented by a byte[]
- * of size 4 and returns this as a long representation of the same IP
- * address.
- *
- * @since PircBot 0.9.4
- *
- * @param address the byte[] of size 4 representing the IP address.
- *
- * @return a long representation of the IP address.
- */
- public long ipToLong(byte[] address) {
- if (address.length != 4) {
- throw new IllegalArgumentException("byte array must be of length 4");
- }
- long ipNum = 0;
- long multiplier = 1;
- for (int i = 3; i >= 0; i--) {
- int byteVal = (address[i] + 256) % 256;
- ipNum += byteVal*multiplier;
- multiplier *= 256;
- }
- return ipNum;
- }
-
-
- /**
- * Sets the encoding charset to be used when sending or receiving lines
- * from the IRC server. If set to null, then the platform's default
- * charset is used. You should only use this method if you are
- * trying to send text to an IRC server in a different charset, e.g.
- * "GB2312" for Chinese encoding. If a PircBot is currently connected
- * to a server, then it must reconnect before this change takes effect.
- *
- * @since PircBot 1.0.4
- *
- * @param charset The new encoding charset to be used by PircBot.
- *
- * @throws UnsupportedEncodingException If the named charset is not
- * supported.
- */
- public void setEncoding(String charset) throws UnsupportedEncodingException {
- // Just try to see if the charset is supported first...
- "".getBytes(charset);
-
- _charset = charset;
- }
-
-
- /**
- * Returns the encoding used to send and receive lines from
- * the IRC server, or null if not set. Use the setEncoding
- * method to change the encoding charset.
- *
- * @since PircBot 1.0.4
- *
- * @return The encoding used to send outgoing messages, or
- * null if not set.
- */
- public String getEncoding() {
- return _charset;
- }
-
- /**
- * Returns the InetAddress used by the PircBot.
- * This can be used to find the I.P. address from which the PircBot is
- * connected to a server.
- *
- * @since PircBot 1.4.4
- *
- * @return The current local InetAddress, or null if never connected.
- */
- public InetAddress getInetAddress() {
- return _inetAddress;
- }
-
-
- /**
- * Sets the InetAddress to be used when sending DCC chat or file transfers.
- * This can be very useful when you are running a bot on a machine which
- * is behind a firewall and you need to tell receiving clients to connect
- * to a NAT/router, which then forwards the connection.
- *
- * @since PircBot 1.4.4
- *
- * @param dccInetAddress The new InetAddress, or null to use the default.
- */
- public void setDccInetAddress(InetAddress dccInetAddress) {
- _dccInetAddress = dccInetAddress;
- }
-
-
- /**
- * Returns the InetAddress used when sending DCC chat or file transfers.
- * If this is null, the default InetAddress will be used.
- *
- * @since PircBot 1.4.4
- *
- * @return The current DCC InetAddress, or null if left as default.
- */
- public InetAddress getDccInetAddress() {
- return _dccInetAddress;
- }
-
-
- /**
- * Returns the set of port numbers to be used when sending a DCC chat
- * or file transfer. This is useful when you are behind a firewall and
- * need to set up port forwarding. The array of port numbers is traversed
- * in sequence until a free port is found to listen on. A DCC tranfer will
- * fail if all ports are already in use.
- * If set to null, any free port number will be used.
- *
- * @since PircBot 1.4.4
- *
- * @return An array of port numbers that PircBot can use to send DCC
- * transfers, or null if any port is allowed.
- */
- public int[] getDccPorts() {
- if (_dccPorts == null || _dccPorts.length == 0) {
- return null;
- }
- // Clone the array to prevent external modification.
- return (int[]) _dccPorts.clone();
- }
-
-
- /**
- * Sets the choice of port numbers that can be used when sending a DCC chat
- * or file transfer. This is useful when you are behind a firewall and
- * need to set up port forwarding. The array of port numbers is traversed
- * in sequence until a free port is found to listen on. A DCC tranfer will
- * fail if all ports are already in use.
- * If set to null, any free port number will be used.
- *
- * @since PircBot 1.4.4
- *
- * @param ports The set of port numbers that PircBot may use for DCC
- * transfers, or null to let it use any free port (default).
- *
- */
- public void setDccPorts(int[] ports) {
- if (ports == null || ports.length == 0) {
- _dccPorts = null;
- }
- else {
- // Clone the array to prevent external modification.
- _dccPorts = (int[]) ports.clone();
- }
- }
-
-
- /**
- * Returns true if and only if the object being compared is the exact
- * same instance as this PircBot. This may be useful if you are writing
- * a multiple server IRC bot that uses more than one instance of PircBot.
- *
- * @since PircBot 0.9.9
- *
- * @return true if and only if Object o is a PircBot and equal to this.
- */
- public boolean equals(Object o) {
- // This probably has the same effect as Object.equals, but that may change...
- if (o instanceof PircBot) {
- PircBot other = (PircBot) o;
- return other == this;
- }
- return false;
- }
-
-
- /**
- * Returns the hashCode of this PircBot. This method can be called by hashed
- * collection classes and is useful for managing multiple instances of
- * PircBots in such collections.
- *
- * @since PircBot 0.9.9
- *
- * @return the hash code for this instance of PircBot.
- */
- public int hashCode() {
- return super.hashCode();
- }
-
-
- /**
- * Returns a String representation of this object.
- * You may find this useful for debugging purposes, particularly
- * if you are using more than one PircBot instance to achieve
- * multiple server connectivity. The format of
- * this String may change between different versions of PircBot
- * but is currently something of the form
- *
- * There are some important things to note about this method:-
- *
- * Each PircBot runs its own threads for dispatching messages from its
- * outgoing message queue and receiving messages from the server.
- * Calling dispose() ensures that these threads are
- * stopped, thus freeing up system resources and allowing the PircBot
- * object to be garbage collected if there are no other references to
- * it.
- *
- * Once a PircBot object has been disposed, it should not be used again.
- * Attempting to use a PircBot that has been disposed may result in
- * unpredictable behaviour.
- *
- * @since 1.2.2
- */
- public synchronized void dispose() {
- //System.out.println("disposing...");
- _outputThread.interrupt();
- _inputThread.dispose();
- }
-
-
- /**
- * Add a user to the specified channel in our memory.
- * Overwrite the existing entry if it exists.
- */
- private final void addUser(String channel, User user) {
- channel = channel.toLowerCase();
- synchronized (_channels) {
- Hashtable
+ * It provides an event-driven architecture to handle common IRC
+ * events, flood protection, DCC support, ident support, and more.
+ * The comprehensive logfile format is suitable for use with pisg to generate
+ * channel statistics.
+ *
+ * Methods of the PircBot class can be called to send events to the IRC server
+ * that it connects to. For example, calling the sendMessage method will
+ * send a message to a channel or user on the IRC server. Multiple servers
+ * can be supported using multiple instances of PircBot.
+ *
+ * To perform an action when the PircBot receives a normal message from the IRC
+ * server, you would override the onMessage method defined in the PircBot
+ * class. All onXYZ methods in the PircBot class are automatically called
+ * when the event XYZ happens, so you would override these if you wish
+ * to do something when it does happen.
+ *
+ * Some event methods, such as onPing, should only really perform a specific
+ * function (i.e. respond to a PING from the server). For your convenience, such
+ * methods are already correctly implemented in the PircBot and should not
+ * normally need to be overridden. Please read the full documentation for each
+ * method to see which ones are already implemented by the PircBot class.
+ *
+ * Please visit the PircBot homepage at
+ * http://www.jibble.org/pircbot.php
+ * for full revision history, a beginners guide to creating your first PircBot
+ * and a list of some existing Java IRC bots and clients that use the PircBot
+ * framework.
+ *
+ * @author Paul James Mutton,
+ * http://www.jibble.org/
+ * @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
+ */
+public abstract class PircBot implements ReplyConstants {
+ public static final String TAG = "Yaaic/PircBot";
+ /**
+ * The definitive version number of this release of PircBot.
+ * (Note: Change this before automatically building releases)
+ */
+ public static final String VERSION = "1.4.6";
+
+ private static final int OP_ADD = 1;
+ private static final int OP_REMOVE = 2;
+ private static final int VOICE_ADD = 3;
+ private static final int VOICE_REMOVE = 4;
+
+ /**
+ * Constructs a PircBot with the default settings. Your own constructors
+ * in classes which extend the PircBot abstract class should be responsible
+ * for changing the default settings if required.
+ */
+ public PircBot() {}
+
+ /**
+ * Attempt to connect to the specified IRC server.
+ * The onConnect method is called upon success.
+ *
+ * @param hostname The hostname of the server to connect to.
+ *
+ * @throws IOException if it was not possible to connect to the server.
+ * @throws IrcException if the server would not let us join it.
+ * @throws NickAlreadyInUseException if our nick is already in use on the server.
+ */
+ public final synchronized void connect(String hostname) throws IOException, IrcException, NickAlreadyInUseException {
+ this.connect(hostname, 6667, null);
+ }
+
+
+ /**
+ * Attempt to connect to the specified IRC server and port number.
+ * The onConnect method is called upon success.
+ *
+ * @param hostname The hostname of the server to connect to.
+ * @param port The port number to connect to on the server.
+ *
+ * @throws IOException if it was not possible to connect to the server.
+ * @throws IrcException if the server would not let us join it.
+ * @throws NickAlreadyInUseException if our nick is already in use on the server.
+ */
+ public final synchronized void connect(String hostname, int port) throws IOException, IrcException, NickAlreadyInUseException {
+ this.connect(hostname, port, null);
+ }
+
+
+ /**
+ * Attempt to connect to the specified IRC server using the supplied
+ * password.
+ * The onConnect method is called upon success.
+ *
+ * @param hostname The hostname of the server to connect to.
+ * @param port The port number to connect to on the server.
+ * @param password The password to use to join the server.
+ *
+ * @throws IOException if it was not possible to connect to the server.
+ * @throws IrcException if the server would not let us join it.
+ * @throws NickAlreadyInUseException if our nick is already in use on the server.
+ */
+ public final synchronized void connect(String hostname, int port, String password) throws IOException, IrcException, NickAlreadyInUseException {
+
+ _server = hostname;
+ _port = port;
+ _password = password;
+
+ if (isConnected()) {
+ throw new IOException("The PircBot is already connected to an IRC server. Disconnect first.");
+ }
+
+ // Don't clear the outqueue - there might be something important in it!
+
+ // Clear everything we may have know about channels.
+ this.removeAllChannels();
+
+ // Connect to the server.
+ Socket socket = new Socket(hostname, port);
+ this.log("*** Connected to server.");
+
+ _inetAddress = socket.getLocalAddress();
+
+ InputStreamReader inputStreamReader = null;
+ OutputStreamWriter outputStreamWriter = null;
+ if (getEncoding() != null) {
+ // Assume the specified encoding is valid for this JVM.
+ inputStreamReader = new InputStreamReader(socket.getInputStream(), getEncoding());
+ outputStreamWriter = new OutputStreamWriter(socket.getOutputStream(), getEncoding());
+ }
+ else {
+ // Otherwise, just use the JVM's default encoding.
+ inputStreamReader = new InputStreamReader(socket.getInputStream());
+ outputStreamWriter = new OutputStreamWriter(socket.getOutputStream());
+ }
+
+ BufferedReader breader = new BufferedReader(inputStreamReader);
+ BufferedWriter bwriter = new BufferedWriter(outputStreamWriter);
+
+ // Attempt to join the server.
+ if (password != null && !password.equals("")) {
+ OutputThread.sendRawLine(this, bwriter, "PASS " + password);
+ }
+ String nick = this.getName();
+ OutputThread.sendRawLine(this, bwriter, "NICK " + nick);
+ OutputThread.sendRawLine(this, bwriter, "USER " + this.getLogin() + " 8 * :" + this.getVersion());
+
+ _inputThread = new InputThread(this, socket, breader, bwriter);
+
+ // Read stuff back from the server to see if we connected.
+ String line = null;
+ int tries = 1;
+ while ((line = breader.readLine()) != null) {
+
+ this.handleLine(line);
+
+ int firstSpace = line.indexOf(" ");
+ int secondSpace = line.indexOf(" ", firstSpace + 1);
+ if (secondSpace >= 0) {
+ String code = line.substring(firstSpace + 1, secondSpace);
+
+ if (code.equals("004")) {
+ // We're connected to the server.
+ break;
+ }
+ else if (code.equals("433")) {
+ if (_autoNickChange) {
+ tries++;
+ nick = getName() + tries;
+ OutputThread.sendRawLine(this, bwriter, "NICK " + nick);
+ }
+ else {
+ socket.close();
+ _inputThread = null;
+ throw new NickAlreadyInUseException(line);
+ }
+ }
+ else if (code.startsWith("5") || code.startsWith("4")) {
+ socket.close();
+ _inputThread = null;
+ throw new IrcException("Could not log into the IRC server: " + line);
+ }
+ }
+ this.setNick(nick);
+
+ }
+
+ this.log("*** Logged onto server.");
+
+ // This makes the socket timeout on read operations after 5 minutes.
+ // Maybe in some future version I will let the user change this at runtime.
+ socket.setSoTimeout(5 * 60 * 1000);
+
+ // Now start the InputThread to read all other lines from the server.
+ _inputThread.start();
+
+ // Now start the outputThread that will be used to send all messages.
+ if (_outputThread == null) {
+ _outputThread = new OutputThread(this, _outQueue);
+ _outputThread.start();
+ }
+
+ this.onConnect();
+
+ }
+
+
+ /**
+ * Reconnects to the IRC server that we were previously connected to.
+ * If necessary, the appropriate port number and password will be used.
+ * This method will throw an IrcException if we have never connected
+ * to an IRC server previously.
+ *
+ * @since PircBot 0.9.9
+ *
+ * @throws IOException if it was not possible to connect to the server.
+ * @throws IrcException if the server would not let us join it.
+ * @throws NickAlreadyInUseException if our nick is already in use on the server.
+ */
+ public final synchronized void reconnect() throws IOException, IrcException, NickAlreadyInUseException{
+ if (getServer() == null) {
+ throw new IrcException("Cannot reconnect to an IRC server because we were never connected to one previously!");
+ }
+ connect(getServer(), getPort(), getPassword());
+ }
+
+
+ /**
+ * This method disconnects from the server cleanly by calling the
+ * quitServer() method. Providing the PircBot was connected to an
+ * IRC server, the onDisconnect() will be called as soon as the
+ * disconnection is made by the server.
+ *
+ * @see #quitServer() quitServer
+ * @see #quitServer(String) quitServer
+ */
+ public final synchronized void disconnect() {
+ this.quitServer();
+ }
+
+
+ /**
+ * When you connect to a server and your nick is already in use and
+ * this is set to true, a new nick will be automatically chosen.
+ * This is done by adding numbers to the end of the nick until an
+ * available nick is found.
+ *
+ * @param autoNickChange Set to true if you want automatic nick changes
+ * during connection.
+ */
+ public void setAutoNickChange(boolean autoNickChange) {
+ _autoNickChange = autoNickChange;
+ }
+
+
+ /**
+ * Starts an ident server (Identification Protocol Server, RFC 1413).
+ *
+ * Most IRC servers attempt to contact the ident server on connecting
+ * hosts in order to determine the user's identity. A few IRC servers
+ * will not allow you to connect unless this information is provided.
+ *
+ * So when a PircBot is run on a machine that does not run an ident server,
+ * it may be necessary to call this method to start one up.
+ *
+ * Calling this method starts up an ident server which will respond with
+ * the login provided by calling getLogin() and then shut down immediately.
+ * It will also be shut down if it has not been contacted within 60 seconds
+ * of creation.
+ *
+ * If you require an ident response, then the correct procedure is to start
+ * the ident server and then connect to the IRC server. The IRC server may
+ * then contact the ident server to get the information it needs.
+ *
+ * The ident server will fail to start if there is already an ident server
+ * running on port 113, or if you are running as an unprivileged user who
+ * is unable to create a server socket on that port number.
+ *
+ * If it is essential for you to use an ident server when connecting to an
+ * IRC server, then make sure that port 113 on your machine is visible to
+ * the IRC server so that it may contact the ident server.
+ *
+ * @since PircBot 0.9c
+ */
+ public final void startIdentServer() {
+ new IdentServer(this, getLogin());
+ }
+
+
+ /**
+ * Joins a channel.
+ *
+ * @param channel The name of the channel to join (eg "#cs").
+ */
+ public final void joinChannel(String channel) {
+ this.sendRawLine("JOIN " + channel);
+ }
+
+
+ /**
+ * Joins a channel with a key.
+ *
+ * @param channel The name of the channel to join (eg "#cs").
+ * @param key The key that will be used to join the channel.
+ */
+ public final void joinChannel(String channel, String key) {
+ this.joinChannel(channel + " " + key);
+ }
+
+
+ /**
+ * Parts a channel.
+ *
+ * @param channel The name of the channel to leave.
+ */
+ public final void partChannel(String channel) {
+ this.sendRawLine("PART " + channel);
+ }
+
+
+ /**
+ * Parts a channel, giving a reason.
+ *
+ * @param channel The name of the channel to leave.
+ * @param reason The reason for parting the channel.
+ */
+ public final void partChannel(String channel, String reason) {
+ this.sendRawLine("PART " + channel + " :" + reason);
+ }
+
+
+ /**
+ * Quits from the IRC server.
+ * Providing we are actually connected to an IRC server, the
+ * onDisconnect() method will be called as soon as the IRC server
+ * disconnects us.
+ */
+ public void quitServer() {
+ this.quitServer("");
+ }
+
+
+ /**
+ * Quits from the IRC server with a reason.
+ * Providing we are actually connected to an IRC server, the
+ * onDisconnect() method will be called as soon as the IRC server
+ * disconnects us.
+ *
+ * @param reason The reason for quitting the server.
+ */
+ public final void quitServer(String reason) {
+ this.sendRawLine("QUIT :" + reason);
+ }
+
+
+ /**
+ * Sends a raw line to the IRC server as soon as possible, bypassing the
+ * outgoing message queue.
+ *
+ * @param line The raw line to send to the IRC server.
+ */
+ public final synchronized void sendRawLine(String line) {
+ if (isConnected()) {
+ _inputThread.sendRawLine(line);
+ }
+ }
+
+ /**
+ * Sends a raw line through the outgoing message queue.
+ *
+ * @param line The raw line to send to the IRC server.
+ */
+ public final synchronized void sendRawLineViaQueue(String line) {
+ if (line == null) {
+ throw new NullPointerException("Cannot send null messages to server");
+ }
+ if (isConnected()) {
+ _outQueue.add(line);
+ }
+ }
+
+
+ /**
+ * Sends a message to a channel or a private message to a user. These
+ * messages are added to the outgoing message queue and sent at the
+ * earliest possible opportunity.
+ *
+ * Some examples: -
+ *
+ * This method issues a raw NICKSERV command to the server, and is therefore
+ * safer than the alternative approach of sending a private message to
+ * NickServ. The latter approach is considered dangerous, as it may cause
+ * you to inadvertently transmit your password to an untrusted party if you
+ * connect to a network which does not run a NickServ service and where the
+ * untrusted party has assumed the nick "NickServ". However, if your IRC
+ * network is only compatible with the private message approach, you may
+ * typically identify like so:
+ *
+ * Some IRC servers support certain parameters for LIST requests.
+ * One example is a parameter of ">10" to list only those channels
+ * that have more than 10 users in them. Whether these parameters
+ * are supported or not will depend on the IRC server software.
+ *
+ * @param parameters The parameters to supply when requesting the
+ * list.
+ *
+ * @see #onChannelInfo(String,int,String) onChannelInfo
+ */
+ public final void listChannels(String parameters) {
+ if (parameters == null) {
+ this.sendRawLine("LIST");
+ }
+ else {
+ this.sendRawLine("LIST " + parameters);
+ }
+ }
+
+
+ /**
+ * Sends a file to another user. Resuming is supported.
+ * The other user must be able to connect directly to your bot to be
+ * able to receive the file.
+ *
+ * You may throttle the speed of this file transfer by calling the
+ * setPacketDelay method on the DccFileTransfer that is returned.
+ *
+ * This method may not be overridden.
+ *
+ * @since 0.9c
+ *
+ * @param file The file to send.
+ * @param nick The user to whom the file is to be sent.
+ * @param timeout The number of milliseconds to wait for the recipient to
+ * acccept the file (we recommend about 120000).
+ *
+ * @return The DccFileTransfer that can be used to monitor this transfer.
+ *
+ * @see DccFileTransfer
+ *
+ */
+ public final DccFileTransfer dccSendFile(File file, String nick, int timeout) {
+ DccFileTransfer transfer = new DccFileTransfer(this, _dccManager, file, nick, timeout);
+ transfer.doSend(true);
+ return transfer;
+ }
+
+
+ /**
+ * Receives a file that is being sent to us by a DCC SEND request.
+ * Please use the onIncomingFileTransfer method to receive files.
+ *
+ * @deprecated As of PircBot 1.2.0, use {@link #onIncomingFileTransfer(DccFileTransfer)}
+ */
+ protected final void dccReceiveFile(File file, long address, int port, int size) {
+ throw new RuntimeException("dccReceiveFile is deprecated, please use sendFile");
+ }
+
+
+ /**
+ * Attempts to establish a DCC CHAT session with a client. This method
+ * issues the connection request to the client and then waits for the
+ * client to respond. If the connection is successfully made, then a
+ * DccChat object is returned by this method. If the connection is not
+ * made within the time limit specified by the timeout value, then null
+ * is returned.
+ *
+ * It is strongly recommended that you call this method within a new
+ * Thread, as it may take a long time to return.
+ *
+ * This method may not be overridden.
+ *
+ * @since PircBot 0.9.8
+ *
+ * @param nick The nick of the user we are trying to establish a chat with.
+ * @param timeout The number of milliseconds to wait for the recipient to
+ * accept the chat connection (we recommend about 120000).
+ *
+ * @return a DccChat object that can be used to send and recieve lines of
+ * text. Returns null if the connection could not be made.
+ *
+ * @see DccChat
+ */
+ public final DccChat dccSendChatRequest(String nick, int timeout) {
+ DccChat chat = null;
+ try {
+ ServerSocket ss = null;
+
+ int[] ports = getDccPorts();
+ if (ports == null) {
+ // Use any free port.
+ ss = new ServerSocket(0);
+ }
+ else {
+ for (int i = 0; i < ports.length; i++) {
+ try {
+ ss = new ServerSocket(ports[i]);
+ // Found a port number we could use.
+ break;
+ }
+ catch (Exception e) {
+ // Do nothing; go round and try another port.
+ }
+ }
+ if (ss == null) {
+ // No ports could be used.
+ throw new IOException("All ports returned by getDccPorts() are in use.");
+ }
+ }
+
+ ss.setSoTimeout(timeout);
+ int port = ss.getLocalPort();
+
+ InetAddress inetAddress = getDccInetAddress();
+ if (inetAddress == null) {
+ inetAddress = getInetAddress();
+ }
+ byte[] ip = inetAddress.getAddress();
+ long ipNum = ipToLong(ip);
+
+ sendCTCPCommand(nick, "DCC CHAT chat " + ipNum + " " + port);
+
+ // The client may now connect to us to chat.
+ Socket socket = ss.accept();
+
+ // Close the server socket now that we've finished with it.
+ ss.close();
+
+ chat = new DccChat(this, nick, socket);
+ }
+ catch (Exception e) {
+ // Do nothing.
+ }
+ return chat;
+ }
+
+
+ /**
+ * Attempts to accept a DCC CHAT request by a client.
+ * Please use the onIncomingChatRequest method to receive files.
+ *
+ * @deprecated As of PircBot 1.2.0, use {@link #onIncomingChatRequest(DccChat)}
+ */
+ protected final DccChat dccAcceptChatRequest(String sourceNick, long address, int port) {
+ throw new RuntimeException("dccAcceptChatRequest is deprecated, please use onIncomingChatRequest");
+ }
+
+
+ /**
+ * Adds a line to the log. This log is currently output to the standard
+ * output and is in the correct format for use by tools such as pisg, the
+ * Perl IRC Statistics Generator. You may override this method if you wish
+ * to do something else with log entries.
+ * Each line in the log begins with a number which
+ * represents the logging time (as the number of milliseconds since the
+ * epoch). This timestamp and the following log entry are separated by
+ * a single space character, " ". Outgoing messages are distinguishable
+ * by a log entry that has ">>>" immediately following the space character
+ * after the timestamp. DCC events use "+++" and warnings about unhandled
+ * Exceptions and Errors use "###".
+ *
+ * This implementation of the method will only cause log entries to be
+ * output if the PircBot has had its verbose mode turned on by calling
+ * setVerbose(true);
+ *
+ * @param line The line to add to the log.
+ */
+ public void log(String line) {
+ if (_verbose) {
+ // XXX: PircBot Patch: Log to debug log instead of standard output
+ Log.d(TAG, line);
+ //System.out.println(System.currentTimeMillis() + " " + line);
+ }
+ }
+
+
+ /**
+ * This method handles events when any line of text arrives from the server,
+ * then calling the appropriate method in the PircBot. This method is
+ * protected and only called by the InputThread for this instance.
+ *
+ * This method may not be overridden!
+ *
+ * @param line The raw line of text from the server.
+ */
+ protected void handleLine(String line) {
+ this.log(line);
+
+ // Check for server pings.
+ if (line.startsWith("PING ")) {
+ // Respond to the ping and return immediately.
+ this.onServerPing(line.substring(5));
+ return;
+ }
+
+ String sourceNick = "";
+ String sourceLogin = "";
+ String sourceHostname = "";
+
+ StringTokenizer tokenizer = new StringTokenizer(line);
+ String senderInfo = tokenizer.nextToken();
+ String command = tokenizer.nextToken();
+ String target = null;
+
+ int exclamation = senderInfo.indexOf("!");
+ int at = senderInfo.indexOf("@");
+ if (senderInfo.startsWith(":")) {
+ if (exclamation > 0 && at > 0 && exclamation < at) {
+ sourceNick = senderInfo.substring(1, exclamation);
+ sourceLogin = senderInfo.substring(exclamation + 1, at);
+ sourceHostname = senderInfo.substring(at + 1);
+ }
+ else {
+
+ if (tokenizer.hasMoreTokens()) {
+ String token = command;
+
+ int code = -1;
+ try {
+ code = Integer.parseInt(token);
+ }
+ catch (NumberFormatException e) {
+ // Keep the existing value.
+ }
+
+ if (code != -1) {
+ String errorStr = token;
+ String response = line.substring(line.indexOf(errorStr, senderInfo.length()) + 4, line.length());
+ this.processServerResponse(code, response);
+ // Return from the method.
+ return;
+ }
+ else {
+ // This is not a server response.
+ // It must be a nick without login and hostname.
+ // (or maybe a NOTICE or suchlike from the server)
+ sourceNick = senderInfo;
+ target = token;
+ }
+ }
+ else {
+ // We don't know what this line means.
+ this.onUnknown(line);
+ // Return from the method;
+ return;
+ }
+
+ }
+ }
+
+ command = command.toUpperCase();
+ if (sourceNick.startsWith(":")) {
+ sourceNick = sourceNick.substring(1);
+ }
+ if (target == null) {
+ target = tokenizer.nextToken();
+ }
+ if (target.startsWith(":")) {
+ target = target.substring(1);
+ }
+
+ // Check for CTCP requests.
+ if (command.equals("PRIVMSG") && line.indexOf(":\u0001") > 0 && line.endsWith("\u0001")) {
+ String request = line.substring(line.indexOf(":\u0001") + 2, line.length() - 1);
+ if (request.equals("VERSION")) {
+ // VERSION request
+ this.onVersion(sourceNick, sourceLogin, sourceHostname, target);
+ }
+ else if (request.startsWith("ACTION ")) {
+ // ACTION request
+ this.onAction(sourceNick, sourceLogin, sourceHostname, target, request.substring(7));
+ }
+ else if (request.startsWith("PING ")) {
+ // PING request
+ this.onPing(sourceNick, sourceLogin, sourceHostname, target, request.substring(5));
+ }
+ else if (request.equals("TIME")) {
+ // TIME request
+ this.onTime(sourceNick, sourceLogin, sourceHostname, target);
+ }
+ else if (request.equals("FINGER")) {
+ // FINGER request
+ this.onFinger(sourceNick, sourceLogin, sourceHostname, target);
+ }
+ else if ((tokenizer = new StringTokenizer(request)).countTokens() >= 5 && tokenizer.nextToken().equals("DCC")) {
+ // This is a DCC request.
+ boolean success = _dccManager.processRequest(sourceNick, sourceLogin, sourceHostname, request);
+ if (!success) {
+ // The DccManager didn't know what to do with the line.
+ this.onUnknown(line);
+ }
+ }
+ else {
+ // An unknown CTCP message - ignore it.
+ this.onUnknown(line);
+ }
+ }
+ else if (command.equals("PRIVMSG") && _channelPrefixes.indexOf(target.charAt(0)) >= 0) {
+ // This is a normal message to a channel.
+ this.onMessage(target, sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2));
+ }
+ else if (command.equals("PRIVMSG")) {
+ // This is a private message to us.
+ this.onPrivateMessage(sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2));
+ }
+ else if (command.equals("JOIN")) {
+ // Someone is joining a channel.
+ String channel = target;
+ this.addUser(channel, new User("", sourceNick));
+ this.onJoin(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ else if (command.equals("PART")) {
+ // Someone is parting from a channel.
+ this.removeUser(target, sourceNick);
+ if (sourceNick.equals(this.getNick())) {
+ this.removeChannel(target);
+ }
+ this.onPart(target, sourceNick, sourceLogin, sourceHostname);
+ }
+ else if (command.equals("NICK")) {
+ // Somebody is changing their nick.
+ String newNick = target;
+ this.renameUser(sourceNick, newNick);
+ if (sourceNick.equals(this.getNick())) {
+ // Update our nick if it was us that changed nick.
+ this.setNick(newNick);
+ }
+ this.onNickChange(sourceNick, sourceLogin, sourceHostname, newNick);
+ }
+ else if (command.equals("NOTICE")) {
+ // Someone is sending a notice.
+ this.onNotice(sourceNick, sourceLogin, sourceHostname, target, line.substring(line.indexOf(" :") + 2));
+ }
+ else if (command.equals("QUIT")) {
+ // Someone has quit from the IRC server.
+
+ // XXX: Pircbot Patch - Call onQuit before removing the user. This way we
+ // are able to know which channels the user was on.
+ this.onQuit(sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2));
+
+ if (sourceNick.equals(this.getNick())) {
+ this.removeAllChannels();
+ }
+ else {
+ this.removeUser(sourceNick);
+ }
+ }
+ else if (command.equals("KICK")) {
+ // Somebody has been kicked from a channel.
+ String recipient = tokenizer.nextToken();
+ if (recipient.equals(this.getNick())) {
+ this.removeChannel(target);
+ }
+ this.removeUser(target, recipient);
+ this.onKick(target, sourceNick, sourceLogin, sourceHostname, recipient, line.substring(line.indexOf(" :") + 2));
+ }
+ else if (command.equals("MODE")) {
+ // Somebody is changing the mode on a channel or user.
+ String mode = line.substring(line.indexOf(target, 2) + target.length() + 1);
+ if (mode.startsWith(":")) {
+ mode = mode.substring(1);
+ }
+ this.processMode(target, sourceNick, sourceLogin, sourceHostname, mode);
+ }
+ else if (command.equals("TOPIC")) {
+ // Someone is changing the topic.
+ this.onTopic(target, line.substring(line.indexOf(" :") + 2), sourceNick, System.currentTimeMillis(), true);
+ }
+ else if (command.equals("INVITE")) {
+ // Somebody is inviting somebody else into a channel.
+ this.onInvite(target, sourceNick, sourceLogin, sourceHostname, line.substring(line.indexOf(" :") + 2));
+ }
+ else {
+ // If we reach this point, then we've found something that the PircBot
+ // Doesn't currently deal with.
+ this.onUnknown(line);
+ }
+
+ }
+
+
+ /**
+ * This method is called once the PircBot has successfully connected to
+ * the IRC server.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.6
+ */
+ protected void onConnect() {}
+
+
+ /**
+ * This method carries out the actions to be performed when the PircBot
+ * gets disconnected. This may happen if the PircBot quits from the
+ * server, or if the connection is unexpectedly lost.
+ *
+ * Disconnection from the IRC server is detected immediately if either
+ * we or the server close the connection normally. If the connection to
+ * the server is lost, but neither we nor the server have explicitly closed
+ * the connection, then it may take a few minutes to detect (this is
+ * commonly referred to as a "ping timeout").
+ *
+ * If you wish to get your IRC bot to automatically rejoin a server after
+ * the connection has been lost, then this is probably the ideal method to
+ * override to implement such functionality.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ */
+ protected void onDisconnect() {}
+
+
+ /**
+ * This method is called by the PircBot when a numeric response
+ * is received from the IRC server. We use this method to
+ * allow PircBot to process various responses from the server
+ * before then passing them on to the onServerResponse method.
+ *
+ * Note that this method is private and should not appear in any
+ * of the javadoc generated documenation.
+ *
+ * @param code The three-digit numerical code for the response.
+ * @param response The full response from the IRC server.
+ */
+ private final void processServerResponse(int code, String response) {
+
+ if (code == RPL_LIST) {
+ // This is a bit of information about a channel.
+ int firstSpace = response.indexOf(' ');
+ int secondSpace = response.indexOf(' ', firstSpace + 1);
+ int thirdSpace = response.indexOf(' ', secondSpace + 1);
+ int colon = response.indexOf(':');
+ String channel = response.substring(firstSpace + 1, secondSpace);
+ int userCount = 0;
+ try {
+ userCount = Integer.parseInt(response.substring(secondSpace + 1, thirdSpace));
+ }
+ catch (NumberFormatException e) {
+ // Stick with the value of zero.
+ }
+ String topic = response.substring(colon + 1);
+ this.onChannelInfo(channel, userCount, topic);
+ }
+ else if (code == RPL_TOPIC) {
+ // This is topic information about a channel we've just joined.
+ int firstSpace = response.indexOf(' ');
+ int secondSpace = response.indexOf(' ', firstSpace + 1);
+ int colon = response.indexOf(':');
+ String channel = response.substring(firstSpace + 1, secondSpace);
+ String topic = response.substring(colon + 1);
+
+ _topics.put(channel, topic);
+
+ // For backwards compatibility only - this onTopic method is deprecated.
+ this.onTopic(channel, topic);
+ }
+ else if (code == RPL_TOPICINFO) {
+ StringTokenizer tokenizer = new StringTokenizer(response);
+ tokenizer.nextToken();
+ String channel = tokenizer.nextToken();
+ String setBy = tokenizer.nextToken();
+ long date = 0;
+ try {
+ date = Long.parseLong(tokenizer.nextToken()) * 1000;
+ }
+ catch (NumberFormatException e) {
+ // Stick with the default value of zero.
+ }
+
+ String topic = (String) _topics.get(channel);
+ _topics.remove(channel);
+
+ this.onTopic(channel, topic, setBy, date, false);
+ }
+ else if (code == RPL_NAMREPLY) {
+ // This is a list of nicks in a channel that we've just joined.
+ int channelEndIndex = response.indexOf(" :");
+ String channel = response.substring(response.lastIndexOf(' ', channelEndIndex - 1) + 1, channelEndIndex);
+
+ StringTokenizer tokenizer = new StringTokenizer(response.substring(response.indexOf(" :") + 2));
+ while (tokenizer.hasMoreTokens()) {
+ String nick = tokenizer.nextToken();
+ String prefix = "";
+ if (nick.startsWith("@")) {
+ // User is an operator in this channel.
+ prefix = "@";
+ }
+ else if (nick.startsWith("+")) {
+ // User is voiced in this channel.
+ prefix = "+";
+ }
+ else if (nick.startsWith(".")) {
+ // Some wibbly status I've never seen before...
+ prefix = ".";
+ }
+ nick = nick.substring(prefix.length());
+ this.addUser(channel, new User(prefix, nick));
+ }
+ }
+ else if (code == RPL_ENDOFNAMES) {
+ // This is the end of a NAMES list, so we know that we've got
+ // the full list of users in the channel that we just joined.
+ String channel = response.substring(response.indexOf(' ') + 1, response.indexOf(" :"));
+ User[] users = this.getUsers(channel);
+ this.onUserList(channel, users);
+ }
+
+ this.onServerResponse(code, response);
+ }
+
+
+ /**
+ * This method is called when we receive a numeric response from the
+ * IRC server.
+ *
+ * Numerics in the range from 001 to 099 are used for client-server
+ * connections only and should never travel between servers. Replies
+ * generated in response to commands are found in the range from 200
+ * to 399. Error replies are found in the range from 400 to 599.
+ *
+ * For example, we can use this method to discover the topic of a
+ * channel when we join it. If we join the channel #test which
+ * has a topic of "I am King of Test" then the response
+ * will be "
+ * PircBot implements the interface ReplyConstants, which contains
+ * contstants that you may find useful here.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param code The three-digit numerical code for the response.
+ * @param response The full response from the IRC server.
+ *
+ * @see ReplyConstants
+ */
+ protected void onServerResponse(int code, String response) {}
+
+
+ /**
+ * This method is called when we receive a user list from the server
+ * after joining a channel.
+ *
+ * Shortly after joining a channel, the IRC server sends a list of all
+ * users in that channel. The PircBot collects this information and
+ * calls this method as soon as it has the full list.
+ *
+ * To obtain the nick of each user in the channel, call the getNick()
+ * method on each User object in the array.
+ *
+ * At a later time, you may call the getUsers method to obtain an
+ * up to date list of the users in the channel.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 1.0.0
+ *
+ * @param channel The name of the channel.
+ * @param users An array of User objects belonging to this channel.
+ *
+ * @see User
+ */
+ protected void onUserList(String channel, User[] users) {}
+
+
+ /**
+ * This method is called whenever a message is sent to a channel.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param channel The channel to which the message was sent.
+ * @param sender The nick of the person who sent the message.
+ * @param login The login of the person who sent the message.
+ * @param hostname The hostname of the person who sent the message.
+ * @param message The actual message sent to the channel.
+ */
+ protected void onMessage(String channel, String sender, String login, String hostname, String message) {}
+
+
+ /**
+ * This method is called whenever a private message is sent to the PircBot.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param sender The nick of the person who sent the private message.
+ * @param login The login of the person who sent the private message.
+ * @param hostname The hostname of the person who sent the private message.
+ * @param message The actual message.
+ */
+ protected void onPrivateMessage(String sender, String login, String hostname, String message) {}
+
+
+ /**
+ * This method is called whenever an ACTION is sent from a user. E.g.
+ * such events generated by typing "/me goes shopping" in most IRC clients.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param sender The nick of the user that sent the action.
+ * @param login The login of the user that sent the action.
+ * @param hostname The hostname of the user that sent the action.
+ * @param target The target of the action, be it a channel or our nick.
+ * @param action The action carried out by the user.
+ */
+ protected void onAction(String sender, String login, String hostname, String target, String action) {}
+
+
+ /**
+ * This method is called whenever we receive a notice.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param sourceNick The nick of the user that sent the notice.
+ * @param sourceLogin The login of the user that sent the notice.
+ * @param sourceHostname The hostname of the user that sent the notice.
+ * @param target The target of the notice, be it our nick or a channel name.
+ * @param notice The notice message.
+ */
+ protected void onNotice(String sourceNick, String sourceLogin, String sourceHostname, String target, String notice) {}
+
+
+ /**
+ * This method is called whenever someone (possibly us) joins a channel
+ * which we are on.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param channel The channel which somebody joined.
+ * @param sender The nick of the user who joined the channel.
+ * @param login The login of the user who joined the channel.
+ * @param hostname The hostname of the user who joined the channel.
+ */
+ protected void onJoin(String channel, String sender, String login, String hostname) {}
+
+
+ /**
+ * This method is called whenever someone (possibly us) parts a channel
+ * which we are on.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param channel The channel which somebody parted from.
+ * @param sender The nick of the user who parted from the channel.
+ * @param login The login of the user who parted from the channel.
+ * @param hostname The hostname of the user who parted from the channel.
+ */
+ protected void onPart(String channel, String sender, String login, String hostname) {}
+
+
+ /**
+ * This method is called whenever someone (possibly us) changes nick on any
+ * of the channels that we are on.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param oldNick The old nick.
+ * @param login The login of the user.
+ * @param hostname The hostname of the user.
+ * @param newNick The new nick.
+ */
+ protected void onNickChange(String oldNick, String login, String hostname, String newNick) {}
+
+
+ /**
+ * This method is called whenever someone (possibly us) is kicked from
+ * any of the channels that we are in.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param channel The channel from which the recipient was kicked.
+ * @param kickerNick The nick of the user who performed the kick.
+ * @param kickerLogin The login of the user who performed the kick.
+ * @param kickerHostname The hostname of the user who performed the kick.
+ * @param recipientNick The unfortunate recipient of the kick.
+ * @param reason The reason given by the user who performed the kick.
+ */
+ protected void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason) {}
+
+
+ /**
+ * This method is called whenever someone (possibly us) quits from the
+ * server. We will only observe this if the user was in one of the
+ * channels to which we are connected.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param sourceNick The nick of the user that quit from the server.
+ * @param sourceLogin The login of the user that quit from the server.
+ * @param sourceHostname The hostname of the user that quit from the server.
+ * @param reason The reason given for quitting the server.
+ */
+ protected void onQuit(String sourceNick, String sourceLogin, String sourceHostname, String reason) {}
+
+
+ /**
+ * This method is called whenever a user sets the topic, or when
+ * PircBot joins a new channel and discovers its topic.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param channel The channel that the topic belongs to.
+ * @param topic The topic for the channel.
+ *
+ * @deprecated As of 1.2.0, replaced by {@link #onTopic(String,String,String,long,boolean)}
+ */
+ protected void onTopic(String channel, String topic) {}
+
+
+ /**
+ * This method is called whenever a user sets the topic, or when
+ * PircBot joins a new channel and discovers its topic.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param channel The channel that the topic belongs to.
+ * @param topic The topic for the channel.
+ * @param setBy The nick of the user that set the topic.
+ * @param date When the topic was set (milliseconds since the epoch).
+ * @param changed True if the topic has just been changed, false if
+ * the topic was already there.
+ *
+ */
+ protected void onTopic(String channel, String topic, String setBy, long date, boolean changed) {}
+
+
+ /**
+ * After calling the listChannels() method in PircBot, the server
+ * will start to send us information about each channel on the
+ * server. You may override this method in order to receive the
+ * information about each channel as soon as it is received.
+ *
+ * Note that certain channels, such as those marked as hidden,
+ * may not appear in channel listings.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param channel The name of the channel.
+ * @param userCount The number of users visible in this channel.
+ * @param topic The topic for this channel.
+ *
+ * @see #listChannels() listChannels
+ */
+ protected void onChannelInfo(String channel, int userCount, String topic) {}
+
+
+ /**
+ * Called when the mode of a channel is set. We process this in
+ * order to call the appropriate onOp, onDeop, etc method before
+ * finally calling the override-able onMode method.
+ *
+ * Note that this method is private and is not intended to appear
+ * in the javadoc generated documentation.
+ *
+ * @param target The channel or nick that the mode operation applies to.
+ * @param sourceNick The nick of the user that set the mode.
+ * @param sourceLogin The login of the user that set the mode.
+ * @param sourceHostname The hostname of the user that set the mode.
+ * @param mode The mode that has been set.
+ */
+ private final void processMode(String target, String sourceNick, String sourceLogin, String sourceHostname, String mode) {
+
+ if (_channelPrefixes.indexOf(target.charAt(0)) >= 0) {
+ // The mode of a channel is being changed.
+ String channel = target;
+ StringTokenizer tok = new StringTokenizer(mode);
+ String[] params = new String[tok.countTokens()];
+
+ int t = 0;
+ while (tok.hasMoreTokens()) {
+ params[t] = tok.nextToken();
+ t++;
+ }
+
+ char pn = ' ';
+ int p = 1;
+
+ // All of this is very large and ugly, but it's the only way of providing
+ // what the users want :-/
+ for (int i = 0; i < params[0].length(); i++) {
+ char atPos = params[0].charAt(i);
+
+ if (atPos == '+' || atPos == '-') {
+ pn = atPos;
+ }
+ else if (atPos == 'o') {
+ if (pn == '+') {
+ this.updateUser(channel, OP_ADD, params[p]);
+ onOp(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
+ }
+ else {
+ this.updateUser(channel, OP_REMOVE, params[p]);
+ onDeop(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
+ }
+ p++;
+ }
+ else if (atPos == 'v') {
+ if (pn == '+') {
+ this.updateUser(channel, VOICE_ADD, params[p]);
+ onVoice(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
+ }
+ else {
+ this.updateUser(channel, VOICE_REMOVE, params[p]);
+ onDeVoice(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
+ }
+ p++;
+ }
+ else if (atPos == 'k') {
+ if (pn == '+') {
+ onSetChannelKey(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
+ }
+ else {
+ onRemoveChannelKey(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
+ }
+ p++;
+ }
+ else if (atPos == 'l') {
+ if (pn == '+') {
+ onSetChannelLimit(channel, sourceNick, sourceLogin, sourceHostname, Integer.parseInt(params[p]));
+ p++;
+ }
+ else {
+ onRemoveChannelLimit(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ }
+ else if (atPos == 'b') {
+ if (pn == '+') {
+ onSetChannelBan(channel, sourceNick, sourceLogin, sourceHostname,params[p]);
+ }
+ else {
+ onRemoveChannelBan(channel, sourceNick, sourceLogin, sourceHostname, params[p]);
+ }
+ p++;
+ }
+ else if (atPos == 't') {
+ if (pn == '+') {
+ onSetTopicProtection(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ else {
+ onRemoveTopicProtection(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ }
+ else if (atPos == 'n') {
+ if (pn == '+') {
+ onSetNoExternalMessages(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ else {
+ onRemoveNoExternalMessages(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ }
+ else if (atPos == 'i') {
+ if (pn == '+') {
+ onSetInviteOnly(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ else {
+ onRemoveInviteOnly(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ }
+ else if (atPos == 'm') {
+ if (pn == '+') {
+ onSetModerated(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ else {
+ onRemoveModerated(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ }
+ else if (atPos == 'p') {
+ if (pn == '+') {
+ onSetPrivate(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ else {
+ onRemovePrivate(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ }
+ else if (atPos == 's') {
+ if (pn == '+') {
+ onSetSecret(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ else {
+ onRemoveSecret(channel, sourceNick, sourceLogin, sourceHostname);
+ }
+ }
+ }
+
+ this.onMode(channel, sourceNick, sourceLogin, sourceHostname, mode);
+ }
+ else {
+ // The mode of a user is being changed.
+ String nick = target;
+ this.onUserMode(nick, sourceNick, sourceLogin, sourceHostname, mode);
+ }
+ }
+
+
+ /**
+ * Called when the mode of a channel is set.
+ *
+ * You may find it more convenient to decode the meaning of the mode
+ * string by overriding the onOp, onDeOp, onVoice, onDeVoice,
+ * onChannelKey, onDeChannelKey, onChannelLimit, onDeChannelLimit,
+ * onChannelBan or onDeChannelBan methods as appropriate.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param channel The channel that the mode operation applies to.
+ * @param sourceNick The nick of the user that set the mode.
+ * @param sourceLogin The login of the user that set the mode.
+ * @param sourceHostname The hostname of the user that set the mode.
+ * @param mode The mode that has been set.
+ *
+ */
+ protected void onMode(String channel, String sourceNick, String sourceLogin, String sourceHostname, String mode) {}
+
+
+ /**
+ * Called when the mode of a user is set.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 1.2.0
+ *
+ * @param targetNick The nick that the mode operation applies to.
+ * @param sourceNick The nick of the user that set the mode.
+ * @param sourceLogin The login of the user that set the mode.
+ * @param sourceHostname The hostname of the user that set the mode.
+ * @param mode The mode that has been set.
+ *
+ */
+ protected void onUserMode(String targetNick, String sourceNick, String sourceLogin, String sourceHostname, String mode) {}
+
+
+
+ /**
+ * Called when a user (possibly us) gets granted operator status for a channel.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ * @param recipient The nick of the user that got 'opped'.
+ */
+ protected void onOp(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {}
+
+
+ /**
+ * Called when a user (possibly us) gets operator status taken away.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ * @param recipient The nick of the user that got 'deopped'.
+ */
+ protected void onDeop(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {}
+
+
+ /**
+ * Called when a user (possibly us) gets voice status granted in a channel.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ * @param recipient The nick of the user that got 'voiced'.
+ */
+ protected void onVoice(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {}
+
+
+ /**
+ * Called when a user (possibly us) gets voice status removed.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ * @param recipient The nick of the user that got 'devoiced'.
+ */
+ protected void onDeVoice(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {}
+
+
+ /**
+ * Called when a channel key is set. When the channel key has been set,
+ * other users may only join that channel if they know the key. Channel keys
+ * are sometimes referred to as passwords.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ * @param key The new key for the channel.
+ */
+ protected void onSetChannelKey(String channel, String sourceNick, String sourceLogin, String sourceHostname, String key) {}
+
+
+ /**
+ * Called when a channel key is removed.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ * @param key The key that was in use before the channel key was removed.
+ */
+ protected void onRemoveChannelKey(String channel, String sourceNick, String sourceLogin, String sourceHostname, String key) {}
+
+
+ /**
+ * Called when a user limit is set for a channel. The number of users in
+ * the channel cannot exceed this limit.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ * @param limit The maximum number of users that may be in this channel at the same time.
+ */
+ protected void onSetChannelLimit(String channel, String sourceNick, String sourceLogin, String sourceHostname, int limit) {}
+
+
+ /**
+ * Called when the user limit is removed for a channel.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onRemoveChannelLimit(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when a user (possibly us) gets banned from a channel. Being
+ * banned from a channel prevents any user with a matching hostmask from
+ * joining the channel. For this reason, most bans are usually directly
+ * followed by the user being kicked :-)
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ * @param hostmask The hostmask of the user that has been banned.
+ */
+ protected void onSetChannelBan(String channel, String sourceNick, String sourceLogin, String sourceHostname, String hostmask) {}
+
+
+ /**
+ * Called when a hostmask ban is removed from a channel.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ * @param hostmask
+ */
+ protected void onRemoveChannelBan(String channel, String sourceNick, String sourceLogin, String sourceHostname, String hostmask) {}
+
+
+ /**
+ * Called when topic protection is enabled for a channel. Topic protection
+ * means that only operators in a channel may change the topic.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onSetTopicProtection(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when topic protection is removed for a channel.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onRemoveTopicProtection(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when a channel is set to only allow messages from users that
+ * are in the channel.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onSetNoExternalMessages(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when a channel is set to allow messages from any user, even
+ * if they are not actually in the channel.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onRemoveNoExternalMessages(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when a channel is set to 'invite only' mode. A user may only
+ * join the channel if they are invited by someone who is already in the
+ * channel.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onSetInviteOnly(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when a channel has 'invite only' removed.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onRemoveInviteOnly(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when a channel is set to 'moderated' mode. If a channel is
+ * moderated, then only users who have been 'voiced' or 'opped' may speak
+ * or change their nicks.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onSetModerated(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when a channel has moderated mode removed.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onRemoveModerated(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when a channel is marked as being in private mode.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onSetPrivate(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when a channel is marked as not being in private mode.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onRemovePrivate(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when a channel is set to be in 'secret' mode. Such channels
+ * typically do not appear on a server's channel listing.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onSetSecret(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when a channel has 'secret' mode removed.
+ *
+ * This is a type of mode change and is also passed to the onMode
+ * method in the PircBot class.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param channel The channel in which the mode change took place.
+ * @param sourceNick The nick of the user that performed the mode change.
+ * @param sourceLogin The login of the user that performed the mode change.
+ * @param sourceHostname The hostname of the user that performed the mode change.
+ */
+ protected void onRemoveSecret(String channel, String sourceNick, String sourceLogin, String sourceHostname) {}
+
+
+ /**
+ * Called when we are invited to a channel by a user.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param targetNick The nick of the user being invited - should be us!
+ * @param sourceNick The nick of the user that sent the invitation.
+ * @param sourceLogin The login of the user that sent the invitation.
+ * @param sourceHostname The hostname of the user that sent the invitation.
+ * @param channel The channel that we're being invited to.
+ */
+ protected void onInvite(String targetNick, String sourceNick, String sourceLogin, String sourceHostname, String channel) {}
+
+
+ /**
+ * This method used to be called when a DCC SEND request was sent to the PircBot.
+ * Please use the onIncomingFileTransfer method to receive files, as it
+ * has better functionality and supports resuming.
+ *
+ * @deprecated As of PircBot 1.2.0, use {@link #onIncomingFileTransfer(DccFileTransfer)}
+ */
+ protected void onDccSendRequest(String sourceNick, String sourceLogin, String sourceHostname, String filename, long address, int port, int size) {}
+
+
+ /**
+ * This method used to be called when a DCC CHAT request was sent to the PircBot.
+ * Please use the onIncomingChatRequest method to accept chats, as it
+ * has better functionality.
+ *
+ * @deprecated As of PircBot 1.2.0, use {@link #onIncomingChatRequest(DccChat)}
+ */
+ protected void onDccChatRequest(String sourceNick, String sourceLogin, String sourceHostname, long address, int port) {}
+
+
+ /**
+ * This method is called whenever a DCC SEND request is sent to the PircBot.
+ * This means that a client has requested to send a file to us.
+ * This abstract implementation performs no action, which means that all
+ * DCC SEND requests will be ignored by default. If you wish to receive
+ * the file, then you may override this method and call the receive method
+ * on the DccFileTransfer object, which connects to the sender and downloads
+ * the file.
+ *
+ * Example:
+ *
+ * Warning: Receiving an incoming file transfer will cause a file
+ * to be written to disk. Please ensure that you make adequate security
+ * checks so that this file does not overwrite anything important!
+ *
+ * Each time a file is received, it happens within a new Thread
+ * in order to allow multiple files to be downloaded by the PircBot
+ * at the same time.
+ *
+ * If you allow resuming and the file already partly exists, it will
+ * be appended to instead of overwritten. If resuming is not enabled,
+ * the file will be overwritten if it already exists.
+ *
+ * You can throttle the speed of the transfer by calling the setPacketDelay
+ * method on the DccFileTransfer object, either before you receive the
+ * file or at any moment during the transfer.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 1.2.0
+ *
+ * @param transfer The DcccFileTransfer that you may accept.
+ *
+ * @see DccFileTransfer
+ *
+ */
+ protected void onIncomingFileTransfer(DccFileTransfer transfer) {}
+
+
+ /**
+ * This method gets called when a DccFileTransfer has finished.
+ * If there was a problem, the Exception will say what went wrong.
+ * If the file was sent successfully, the Exception will be null.
+ *
+ * Both incoming and outgoing file transfers are passed to this method.
+ * You can determine the type by calling the isIncoming or isOutgoing
+ * methods on the DccFileTransfer object.
+ *
+ * @since PircBot 1.2.0
+ *
+ * @param transfer The DccFileTransfer that has finished.
+ * @param e null if the file was transfered successfully, otherwise this
+ * will report what went wrong.
+ *
+ * @see DccFileTransfer
+ *
+ */
+ protected void onFileTransferFinished(DccFileTransfer transfer, Exception e) {}
+
+
+ /**
+ * This method will be called whenever a DCC Chat request is received.
+ * This means that a client has requested to chat to us directly rather
+ * than via the IRC server. This is useful for sending many lines of text
+ * to and from the bot without having to worry about flooding the server
+ * or any operators of the server being able to "spy" on what is being
+ * said. This abstract implementation performs no action, which means
+ * that all DCC CHAT requests will be ignored by default.
+ *
+ * If you wish to accept the connection, then you may override this
+ * method and call the accept() method on the DccChat object, which
+ * connects to the sender of the chat request and allows lines to be
+ * sent to and from the bot.
+ *
+ * Your bot must be able to connect directly to the user that sent the
+ * request.
+ *
+ * Example:
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @since PircBot 1.2.0
+ *
+ * @param chat A DccChat object that represents the incoming chat request.
+ *
+ * @see DccChat
+ *
+ */
+ protected void onIncomingChatRequest(DccChat chat) {}
+
+
+ /**
+ * This method is called whenever we receive a VERSION request.
+ * This abstract implementation responds with the PircBot's _version string,
+ * so if you override this method, be sure to either mimic its functionality
+ * or to call super.onVersion(...);
+ *
+ * @param sourceNick The nick of the user that sent the VERSION request.
+ * @param sourceLogin The login of the user that sent the VERSION request.
+ * @param sourceHostname The hostname of the user that sent the VERSION request.
+ * @param target The target of the VERSION request, be it our nick or a channel name.
+ */
+ protected void onVersion(String sourceNick, String sourceLogin, String sourceHostname, String target) {
+ this.sendRawLine("NOTICE " + sourceNick + " :\u0001VERSION " + _version + "\u0001");
+ }
+
+
+ /**
+ * This method is called whenever we receive a PING request from another
+ * user.
+ *
+ * This abstract implementation responds correctly, so if you override this
+ * method, be sure to either mimic its functionality or to call
+ * super.onPing(...);
+ *
+ * @param sourceNick The nick of the user that sent the PING request.
+ * @param sourceLogin The login of the user that sent the PING request.
+ * @param sourceHostname The hostname of the user that sent the PING request.
+ * @param target The target of the PING request, be it our nick or a channel name.
+ * @param pingValue The value that was supplied as an argument to the PING command.
+ */
+ protected void onPing(String sourceNick, String sourceLogin, String sourceHostname, String target, String pingValue) {
+ this.sendRawLine("NOTICE " + sourceNick + " :\u0001PING " + pingValue + "\u0001");
+ }
+
+
+ /**
+ * The actions to perform when a PING request comes from the server.
+ *
+ * This sends back a correct response, so if you override this method,
+ * be sure to either mimic its functionality or to call
+ * super.onServerPing(response);
+ *
+ * @param response The response that should be given back in your PONG.
+ */
+ protected void onServerPing(String response) {
+ this.sendRawLine("PONG " + response);
+ }
+
+
+ /**
+ * This method is called whenever we receive a TIME request.
+ *
+ * This abstract implementation responds correctly, so if you override this
+ * method, be sure to either mimic its functionality or to call
+ * super.onTime(...);
+ *
+ * @param sourceNick The nick of the user that sent the TIME request.
+ * @param sourceLogin The login of the user that sent the TIME request.
+ * @param sourceHostname The hostname of the user that sent the TIME request.
+ * @param target The target of the TIME request, be it our nick or a channel name.
+ */
+ protected void onTime(String sourceNick, String sourceLogin, String sourceHostname, String target) {
+ this.sendRawLine("NOTICE " + sourceNick + " :\u0001TIME " + new Date().toString() + "\u0001");
+ }
+
+
+ /**
+ * This method is called whenever we receive a FINGER request.
+ *
+ * This abstract implementation responds correctly, so if you override this
+ * method, be sure to either mimic its functionality or to call
+ * super.onFinger(...);
+ *
+ * @param sourceNick The nick of the user that sent the FINGER request.
+ * @param sourceLogin The login of the user that sent the FINGER request.
+ * @param sourceHostname The hostname of the user that sent the FINGER request.
+ * @param target The target of the FINGER request, be it our nick or a channel name.
+ */
+ protected void onFinger(String sourceNick, String sourceLogin, String sourceHostname, String target) {
+ this.sendRawLine("NOTICE " + sourceNick + " :\u0001FINGER " + _finger + "\u0001");
+ }
+
+
+ /**
+ * This method is called whenever we receive a line from the server that
+ * the PircBot has not been programmed to recognise.
+ *
+ * The implementation of this method in the PircBot abstract class
+ * performs no actions and may be overridden as required.
+ *
+ * @param line The raw line that was received from the server.
+ */
+ protected void onUnknown(String line) {
+ // And then there were none :)
+ }
+
+
+ /**
+ * Sets the verbose mode. If verbose mode is set to true, then log entries
+ * will be printed to the standard output. The default value is false and
+ * will result in no output. For general development, we strongly recommend
+ * setting the verbose mode to true.
+ *
+ * @param verbose true if verbose mode is to be used. Default is false.
+ */
+ public final void setVerbose(boolean verbose) {
+ _verbose = verbose;
+ }
+
+
+ /**
+ * Sets the name of the bot, which will be used as its nick when it
+ * tries to join an IRC server. This should be set before joining
+ * any servers, otherwise the default nick will be used. You would
+ * typically call this method from the constructor of the class that
+ * extends PircBot.
+ *
+ * The changeNick method should be used if you wish to change your nick
+ * when you are connected to a server.
+ *
+ * @param name The new name of the Bot.
+ */
+ protected final void setName(String name) {
+ _name = name;
+ }
+
+
+ /**
+ * Sets the internal nick of the bot. This is only to be called by the
+ * PircBot class in response to notification of nick changes that apply
+ * to us.
+ *
+ * @param nick The new nick.
+ */
+ private final void setNick(String nick) {
+ _nick = nick;
+ }
+
+
+ /**
+ * Sets the internal login of the Bot. This should be set before joining
+ * any servers.
+ *
+ * @param login The new login of the Bot.
+ */
+ protected final void setLogin(String login) {
+ _login = login;
+ }
+
+
+ /**
+ * Sets the internal version of the Bot. This should be set before joining
+ * any servers.
+ *
+ * @param version The new version of the Bot.
+ */
+ protected final void setVersion(String version) {
+ _version = version;
+ }
+
+
+ /**
+ * Sets the interal finger message. This should be set before joining
+ * any servers.
+ *
+ * @param finger The new finger message for the Bot.
+ */
+ protected final void setFinger(String finger) {
+ _finger = finger;
+ }
+
+
+ /**
+ * Gets the name of the PircBot. This is the name that will be used as
+ * as a nick when we try to join servers.
+ *
+ * @return The name of the PircBot.
+ */
+ public final String getName() {
+ return _name;
+ }
+
+
+ /**
+ * Returns the current nick of the bot. Note that if you have just changed
+ * your nick, this method will still return the old nick until confirmation
+ * of the nick change is received from the server.
+ *
+ * The nick returned by this method is maintained only by the PircBot
+ * class and is guaranteed to be correct in the context of the IRC server.
+ *
+ * @since PircBot 1.0.0
+ *
+ * @return The current nick of the bot.
+ */
+ public String getNick() {
+ return _nick;
+ }
+
+
+ /**
+ * Gets the internal login of the PircBot.
+ *
+ * @return The login of the PircBot.
+ */
+ public final String getLogin() {
+ return _login;
+ }
+
+
+ /**
+ * Gets the internal version of the PircBot.
+ *
+ * @return The version of the PircBot.
+ */
+ public final String getVersion() {
+ return _version;
+ }
+
+
+ /**
+ * Gets the internal finger message of the PircBot.
+ *
+ * @return The finger message of the PircBot.
+ */
+ public final String getFinger() {
+ return _finger;
+ }
+
+
+ /**
+ * Returns whether or not the PircBot is currently connected to a server.
+ * The result of this method should only act as a rough guide,
+ * as the result may not be valid by the time you act upon it.
+ *
+ * @return True if and only if the PircBot is currently connected to a server.
+ */
+ public final synchronized boolean isConnected() {
+ return _inputThread != null && _inputThread.isConnected();
+ }
+
+
+ /**
+ * Sets the number of milliseconds to delay between consecutive
+ * messages when there are multiple messages waiting in the
+ * outgoing message queue. This has a default value of 1000ms.
+ * It is a good idea to stick to this default value, as it will
+ * prevent your bot from spamming servers and facing the subsequent
+ * wrath! However, if you do need to change this delay value (not
+ * recommended), then this is the method to use.
+ *
+ * @param delay The number of milliseconds between each outgoing message.
+ *
+ */
+ public final void setMessageDelay(long delay) {
+ if (delay < 0) {
+ throw new IllegalArgumentException("Cannot have a negative time.");
+ }
+ _messageDelay = delay;
+ }
+
+
+ /**
+ * Returns the number of milliseconds that will be used to separate
+ * consecutive messages to the server from the outgoing message queue.
+ *
+ * @return Number of milliseconds.
+ */
+ public final long getMessageDelay() {
+ return _messageDelay;
+ }
+
+
+ /**
+ * Gets the maximum length of any line that is sent via the IRC protocol.
+ * The IRC RFC specifies that line lengths, including the trailing \r\n
+ * must not exceed 512 bytes. Hence, there is currently no option to
+ * change this value in PircBot. All lines greater than this length
+ * will be truncated before being sent to the IRC server.
+ *
+ * @return The maximum line length (currently fixed at 512)
+ */
+ public final int getMaxLineLength() {
+ return InputThread.MAX_LINE_LENGTH;
+ }
+
+
+ /**
+ * Gets the number of lines currently waiting in the outgoing message Queue.
+ * If this returns 0, then the Queue is empty and any new message is likely
+ * to be sent to the IRC server immediately.
+ *
+ * @since PircBot 0.9.9
+ *
+ * @return The number of lines in the outgoing message Queue.
+ */
+ public final int getOutgoingQueueSize() {
+ return _outQueue.size();
+ }
+
+
+ /**
+ * Returns the name of the last IRC server the PircBot tried to connect to.
+ * This does not imply that the connection attempt to the server was
+ * successful (we suggest you look at the onConnect method).
+ * A value of null is returned if the PircBot has never tried to connect
+ * to a server.
+ *
+ * @return The name of the last machine we tried to connect to. Returns
+ * null if no connection attempts have ever been made.
+ */
+ public final String getServer() {
+ return _server;
+ }
+
+
+ /**
+ * Returns the port number of the last IRC server that the PircBot tried
+ * to connect to.
+ * This does not imply that the connection attempt to the server was
+ * successful (we suggest you look at the onConnect method).
+ * A value of -1 is returned if the PircBot has never tried to connect
+ * to a server.
+ *
+ * @since PircBot 0.9.9
+ *
+ * @return The port number of the last IRC server we connected to.
+ * Returns -1 if no connection attempts have ever been made.
+ */
+ public final int getPort() {
+ return _port;
+ }
+
+
+ /**
+ * Returns the last password that we used when connecting to an IRC server.
+ * This does not imply that the connection attempt to the server was
+ * successful (we suggest you look at the onConnect method).
+ * A value of null is returned if the PircBot has never tried to connect
+ * to a server using a password.
+ *
+ * @since PircBot 0.9.9
+ *
+ * @return The last password that we used when connecting to an IRC server.
+ * Returns null if we have not previously connected using a password.
+ */
+ public final String getPassword() {
+ return _password;
+ }
+
+
+ /**
+ * A convenient method that accepts an IP address represented as a
+ * long and returns an integer array of size 4 representing the same
+ * IP address.
+ *
+ * @since PircBot 0.9.4
+ *
+ * @param address the long value representing the IP address.
+ *
+ * @return An int[] of size 4.
+ */
+ public int[] longToIp(long address) {
+ int[] ip = new int[4];
+ for (int i = 3; i >= 0; i--) {
+ ip[i] = (int) (address % 256);
+ address = address / 256;
+ }
+ return ip;
+ }
+
+
+ /**
+ * A convenient method that accepts an IP address represented by a byte[]
+ * of size 4 and returns this as a long representation of the same IP
+ * address.
+ *
+ * @since PircBot 0.9.4
+ *
+ * @param address the byte[] of size 4 representing the IP address.
+ *
+ * @return a long representation of the IP address.
+ */
+ public long ipToLong(byte[] address) {
+ if (address.length != 4) {
+ throw new IllegalArgumentException("byte array must be of length 4");
+ }
+ long ipNum = 0;
+ long multiplier = 1;
+ for (int i = 3; i >= 0; i--) {
+ int byteVal = (address[i] + 256) % 256;
+ ipNum += byteVal*multiplier;
+ multiplier *= 256;
+ }
+ return ipNum;
+ }
+
+
+ /**
+ * Sets the encoding charset to be used when sending or receiving lines
+ * from the IRC server. If set to null, then the platform's default
+ * charset is used. You should only use this method if you are
+ * trying to send text to an IRC server in a different charset, e.g.
+ * "GB2312" for Chinese encoding. If a PircBot is currently connected
+ * to a server, then it must reconnect before this change takes effect.
+ *
+ * @since PircBot 1.0.4
+ *
+ * @param charset The new encoding charset to be used by PircBot.
+ *
+ * @throws UnsupportedEncodingException If the named charset is not
+ * supported.
+ */
+ public void setEncoding(String charset) throws UnsupportedEncodingException {
+ // Just try to see if the charset is supported first...
+ "".getBytes(charset);
+
+ _charset = charset;
+ }
+
+
+ /**
+ * Returns the encoding used to send and receive lines from
+ * the IRC server, or null if not set. Use the setEncoding
+ * method to change the encoding charset.
+ *
+ * @since PircBot 1.0.4
+ *
+ * @return The encoding used to send outgoing messages, or
+ * null if not set.
+ */
+ public String getEncoding() {
+ return _charset;
+ }
+
+ /**
+ * Returns the InetAddress used by the PircBot.
+ * This can be used to find the I.P. address from which the PircBot is
+ * connected to a server.
+ *
+ * @since PircBot 1.4.4
+ *
+ * @return The current local InetAddress, or null if never connected.
+ */
+ public InetAddress getInetAddress() {
+ return _inetAddress;
+ }
+
+
+ /**
+ * Sets the InetAddress to be used when sending DCC chat or file transfers.
+ * This can be very useful when you are running a bot on a machine which
+ * is behind a firewall and you need to tell receiving clients to connect
+ * to a NAT/router, which then forwards the connection.
+ *
+ * @since PircBot 1.4.4
+ *
+ * @param dccInetAddress The new InetAddress, or null to use the default.
+ */
+ public void setDccInetAddress(InetAddress dccInetAddress) {
+ _dccInetAddress = dccInetAddress;
+ }
+
+
+ /**
+ * Returns the InetAddress used when sending DCC chat or file transfers.
+ * If this is null, the default InetAddress will be used.
+ *
+ * @since PircBot 1.4.4
+ *
+ * @return The current DCC InetAddress, or null if left as default.
+ */
+ public InetAddress getDccInetAddress() {
+ return _dccInetAddress;
+ }
+
+
+ /**
+ * Returns the set of port numbers to be used when sending a DCC chat
+ * or file transfer. This is useful when you are behind a firewall and
+ * need to set up port forwarding. The array of port numbers is traversed
+ * in sequence until a free port is found to listen on. A DCC tranfer will
+ * fail if all ports are already in use.
+ * If set to null, any free port number will be used.
+ *
+ * @since PircBot 1.4.4
+ *
+ * @return An array of port numbers that PircBot can use to send DCC
+ * transfers, or null if any port is allowed.
+ */
+ public int[] getDccPorts() {
+ if (_dccPorts == null || _dccPorts.length == 0) {
+ return null;
+ }
+ // Clone the array to prevent external modification.
+ return (int[]) _dccPorts.clone();
+ }
+
+
+ /**
+ * Sets the choice of port numbers that can be used when sending a DCC chat
+ * or file transfer. This is useful when you are behind a firewall and
+ * need to set up port forwarding. The array of port numbers is traversed
+ * in sequence until a free port is found to listen on. A DCC tranfer will
+ * fail if all ports are already in use.
+ * If set to null, any free port number will be used.
+ *
+ * @since PircBot 1.4.4
+ *
+ * @param ports The set of port numbers that PircBot may use for DCC
+ * transfers, or null to let it use any free port (default).
+ *
+ */
+ public void setDccPorts(int[] ports) {
+ if (ports == null || ports.length == 0) {
+ _dccPorts = null;
+ }
+ else {
+ // Clone the array to prevent external modification.
+ _dccPorts = (int[]) ports.clone();
+ }
+ }
+
+
+ /**
+ * Returns true if and only if the object being compared is the exact
+ * same instance as this PircBot. This may be useful if you are writing
+ * a multiple server IRC bot that uses more than one instance of PircBot.
+ *
+ * @since PircBot 0.9.9
+ *
+ * @return true if and only if Object o is a PircBot and equal to this.
+ */
+ public boolean equals(Object o) {
+ // This probably has the same effect as Object.equals, but that may change...
+ if (o instanceof PircBot) {
+ PircBot other = (PircBot) o;
+ return other == this;
+ }
+ return false;
+ }
+
+
+ /**
+ * Returns the hashCode of this PircBot. This method can be called by hashed
+ * collection classes and is useful for managing multiple instances of
+ * PircBots in such collections.
+ *
+ * @since PircBot 0.9.9
+ *
+ * @return the hash code for this instance of PircBot.
+ */
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+
+ /**
+ * Returns a String representation of this object.
+ * You may find this useful for debugging purposes, particularly
+ * if you are using more than one PircBot instance to achieve
+ * multiple server connectivity. The format of
+ * this String may change between different versions of PircBot
+ * but is currently something of the form
+ *
+ * There are some important things to note about this method:-
+ *
+ * Each PircBot runs its own threads for dispatching messages from its
+ * outgoing message queue and receiving messages from the server.
+ * Calling dispose() ensures that these threads are
+ * stopped, thus freeing up system resources and allowing the PircBot
+ * object to be garbage collected if there are no other references to
+ * it.
+ *
+ * Once a PircBot object has been disposed, it should not be used again.
+ * Attempting to use a PircBot that has been disposed may result in
+ * unpredictable behaviour.
+ *
+ * @since 1.2.2
+ */
+ public synchronized void dispose() {
+ //System.out.println("disposing...");
+ _outputThread.interrupt();
+ _inputThread.dispose();
+ }
+
+
+ /**
+ * Add a user to the specified channel in our memory.
+ * Overwrite the existing entry if it exists.
+ */
+ private final void addUser(String channel, User user) {
+ channel = channel.toLowerCase();
+ synchronized (_channels) {
+ Hashtable // Send the message "Hello!" to the channel #cs.
- * sendMessage("#cs", "Hello!");
- *
- * // Send a private message to Paul that says "Hi".
- * sendMessage("Paul", "Hi");
- *
- * You may optionally apply colours, boldness, underlining, etc to
- * the message by using the Colors
class.
- *
- * @param target The name of the channel or user nick to send to.
- * @param message The message to send.
- *
- * @see Colors
- */
- public final void sendMessage(String target, String message) {
- _outQueue.add("PRIVMSG " + target + " :" + message);
- }
-
-
- /**
- * Sends an action to the channel or to a user.
- *
- * @param target The name of the channel or user nick to send to.
- * @param action The action to send.
- *
- * @see Colors
- */
- public final void sendAction(String target, String action) {
- sendCTCPCommand(target, "ACTION " + action);
- }
-
-
- /**
- * Sends a notice to the channel or to a user.
- *
- * @param target The name of the channel or user nick to send to.
- * @param notice The notice to send.
- */
- public final void sendNotice(String target, String notice) {
- _outQueue.add("NOTICE " + target + " :" + notice);
- }
-
-
- /**
- * Sends a CTCP command to a channel or user. (Client to client protocol).
- * Examples of such commands are "PING sendCTCPCommand("Dave", "VERSION");
.
- * The type of response to such commands is largely dependant on the target
- * client software.
- *
- * @since PircBot 0.9.5
- *
- * @param target The name of the channel or user to send the CTCP message to.
- * @param command The CTCP command to send.
- */
- public final void sendCTCPCommand(String target, String command) {
- _outQueue.add("PRIVMSG " + target + " :\u0001" + command + "\u0001");
- }
-
-
- /**
- * Attempt to change the current nick (nickname) of the bot when it
- * is connected to an IRC server.
- * After confirmation of a successful nick change, the getNick method
- * will return the new nick.
- *
- * @param newNick The new nick to use.
- */
- public final void changeNick(String newNick) {
- this.sendRawLine("NICK " + newNick);
- }
-
-
- /**
- * Identify the bot with NickServ, supplying the appropriate password.
- * Some IRC Networks (such as freenode) require users to register and
- * identify with NickServ before they are able to send private messages
- * to other users, thus reducing the amount of spam. If you are using
- * an IRC network where this kind of policy is enforced, you will need
- * to make your bot identify itself to NickServ before you can send
- * private messages. Assuming you have already registered your bot's
- * nick with NickServ, this method can be used to identify with
- * the supplied password. It usually makes sense to identify with NickServ
- * immediately after connecting to a server.
- * sendMessage("NickServ", "identify PASSWORD");
- *
- * @param password The password which will be used to identify with NickServ.
- */
- public final void identify(String password) {
- this.sendRawLine("NICKSERV IDENTIFY " + password);
- }
-
-
- /**
- * Set the mode of a channel.
- * This method attempts to set the mode of a channel. This
- * may require the bot to have operator status on the channel.
- * For example, if the bot has operator status, we can grant
- * operator status to "Dave" on the #cs channel
- * by calling setMode("#cs", "+o Dave");
- * An alternative way of doing this would be to use the op method.
- *
- * @param channel The channel on which to perform the mode change.
- * @param mode The new mode to apply to the channel. This may include
- * zero or more arguments if necessary.
- *
- * @see #op(String,String) op
- */
- public final void setMode(String channel, String mode) {
- this.sendRawLine("MODE " + channel + " " + mode);
- }
-
-
- /**
- * Sends an invitation to join a channel. Some channels can be marked
- * as "invite-only", so it may be useful to allow a bot to invite people
- * into it.
- *
- * @param nick The nick of the user to invite
- * @param channel The channel you are inviting the user to join.
- *
- */
- public final void sendInvite(String nick, String channel) {
- this.sendRawLine("INVITE " + nick + " :" + channel);
- }
-
-
- /**
- * Bans a user from a channel. An example of a valid hostmask is
- * "*!*compu@*.18hp.net". This may be used in conjunction with the
- * kick method to permanently remove a user from a channel.
- * Successful use of this method may require the bot to have operator
- * status itself.
- *
- * @param channel The channel to ban the user from.
- * @param hostmask A hostmask representing the user we're banning.
- */
- public final void ban(String channel, String hostmask) {
- this.sendRawLine("MODE " + channel + " +b " + hostmask);
- }
-
-
- /**
- * Unbans a user from a channel. An example of a valid hostmask is
- * "*!*compu@*.18hp.net".
- * Successful use of this method may require the bot to have operator
- * status itself.
- *
- * @param channel The channel to unban the user from.
- * @param hostmask A hostmask representing the user we're unbanning.
- */
- public final void unBan(String channel, String hostmask) {
- this.sendRawLine("MODE " + channel + " -b " + hostmask);
- }
-
-
- /**
- * Grants operator privilidges to a user on a channel.
- * Successful use of this method may require the bot to have operator
- * status itself.
- *
- * @param channel The channel we're opping the user on.
- * @param nick The nick of the user we are opping.
- */
- public final void op(String channel, String nick) {
- this.setMode(channel, "+o " + nick);
- }
-
-
- /**
- * Removes operator privilidges from a user on a channel.
- * Successful use of this method may require the bot to have operator
- * status itself.
- *
- * @param channel The channel we're deopping the user on.
- * @param nick The nick of the user we are deopping.
- */
- public final void deOp(String channel, String nick) {
- this.setMode(channel, "-o " + nick);
- }
-
-
- /**
- * Grants voice privilidges to a user on a channel.
- * Successful use of this method may require the bot to have operator
- * status itself.
- *
- * @param channel The channel we're voicing the user on.
- * @param nick The nick of the user we are voicing.
- */
- public final void voice(String channel, String nick) {
- this.setMode(channel, "+v " + nick);
- }
-
-
- /**
- * Removes voice privilidges from a user on a channel.
- * Successful use of this method may require the bot to have operator
- * status itself.
- *
- * @param channel The channel we're devoicing the user on.
- * @param nick The nick of the user we are devoicing.
- */
- public final void deVoice(String channel, String nick) {
- this.setMode(channel, "-v " + nick);
- }
-
-
- /**
- * Set the topic for a channel.
- * This method attempts to set the topic of a channel. This
- * may require the bot to have operator status if the topic
- * is protected.
- *
- * @param channel The channel on which to perform the mode change.
- * @param topic The new topic for the channel.
- *
- */
- public final void setTopic(String channel, String topic) {
- this.sendRawLine("TOPIC " + channel + " :" + topic);
- }
-
-
- /**
- * Kicks a user from a channel.
- * This method attempts to kick a user from a channel and
- * may require the bot to have operator status in the channel.
- *
- * @param channel The channel to kick the user from.
- * @param nick The nick of the user to kick.
- */
- public final void kick(String channel, String nick) {
- this.kick(channel, nick, "");
- }
-
-
- /**
- * Kicks a user from a channel, giving a reason.
- * This method attempts to kick a user from a channel and
- * may require the bot to have operator status in the channel.
- *
- * @param channel The channel to kick the user from.
- * @param nick The nick of the user to kick.
- * @param reason A description of the reason for kicking a user.
- */
- public final void kick(String channel, String nick, String reason) {
- this.sendRawLine("KICK " + channel + " " + nick + " :" + reason);
- }
-
-
- /**
- * Issues a request for a list of all channels on the IRC server.
- * When the PircBot receives information for each channel, it will
- * call the onChannelInfo method, which you will need to override
- * if you want it to do anything useful.
- *
- * @see #onChannelInfo(String,int,String) onChannelInfo
- */
- public final void listChannels() {
- this.listChannels(null);
- }
-
-
- /**
- * Issues a request for a list of all channels on the IRC server.
- * When the PircBot receives information for each channel, it will
- * call the onChannelInfo method, which you will need to override
- * if you want it to do anything useful.
- * PircBot #test :I Am King of Test
"
- * with a code of 332 to signify that this is a topic.
- * (This is just an example - note that overriding the
- * onTopic
method is an easier way of finding the
- * topic for a channel). Check the IRC RFC for the full list of other
- * command response codes.
- * public void onIncomingFileTransfer(DccFileTransfer transfer) {
- * // Use the suggested file name.
- * File file = transfer.getFile();
- * // Receive the transfer and save it to the file, allowing resuming.
- * transfer.receive(file, true);
- * }
- * public void onIncomingChatRequest(DccChat chat) {
- * try {
- * // Accept all chat, whoever it's from.
- * chat.accept();
- * chat.sendLine("Hello");
- * String response = chat.readLine();
- * chat.close();
- * }
- * catch (IOException e) {}
- * }
- *
- * Each time this method is called, it is called from within a new Thread
- * so that multiple DCC CHAT sessions can run concurrently.
- *
- * Version{PircBot x.y.z Java IRC Bot - www.jibble.org}
- * Connected{true}
- * Server{irc.dal.net}
- * Port{6667}
- * Password{}
- *
- *
- * @since PircBot 0.9.10
- *
- * @return a String representation of this object.
- */
- public String toString() {
- return "Version{" + _version + "}" +
- " Connected{" + isConnected() + "}" +
- " Server{" + _server + "}" +
- " Port{" + _port + "}" +
- " Password{" + _password + "}";
- }
-
-
- /**
- * Returns an array of all users in the specified channel.
- *
- *
- *
- * @since PircBot 1.0.0
- *
- * @param channel The name of the channel to list.
- *
- * @return An array of User objects. This array is empty if we are not
- * in the channel.
- *
- * @see #onUserList(String,User[]) onUserList
- */
- public final User[] getUsers(String channel) {
- channel = channel.toLowerCase();
- User[] userArray = new User[0];
- synchronized (_channels) {
- Hashtable // Send the message "Hello!" to the channel #cs.
+ * sendMessage("#cs", "Hello!");
+ *
+ * // Send a private message to Paul that says "Hi".
+ * sendMessage("Paul", "Hi");
+ *
+ * You may optionally apply colours, boldness, underlining, etc to
+ * the message by using the Colors
class.
+ *
+ * @param target The name of the channel or user nick to send to.
+ * @param message The message to send.
+ *
+ * @see Colors
+ */
+ public final void sendMessage(String target, String message) {
+ _outQueue.add("PRIVMSG " + target + " :" + message);
+ }
+
+
+ /**
+ * Sends an action to the channel or to a user.
+ *
+ * @param target The name of the channel or user nick to send to.
+ * @param action The action to send.
+ *
+ * @see Colors
+ */
+ public final void sendAction(String target, String action) {
+ sendCTCPCommand(target, "ACTION " + action);
+ }
+
+
+ /**
+ * Sends a notice to the channel or to a user.
+ *
+ * @param target The name of the channel or user nick to send to.
+ * @param notice The notice to send.
+ */
+ public final void sendNotice(String target, String notice) {
+ _outQueue.add("NOTICE " + target + " :" + notice);
+ }
+
+
+ /**
+ * Sends a CTCP command to a channel or user. (Client to client protocol).
+ * Examples of such commands are "PING sendCTCPCommand("Dave", "VERSION");
.
+ * The type of response to such commands is largely dependant on the target
+ * client software.
+ *
+ * @since PircBot 0.9.5
+ *
+ * @param target The name of the channel or user to send the CTCP message to.
+ * @param command The CTCP command to send.
+ */
+ public final void sendCTCPCommand(String target, String command) {
+ _outQueue.add("PRIVMSG " + target + " :\u0001" + command + "\u0001");
+ }
+
+
+ /**
+ * Attempt to change the current nick (nickname) of the bot when it
+ * is connected to an IRC server.
+ * After confirmation of a successful nick change, the getNick method
+ * will return the new nick.
+ *
+ * @param newNick The new nick to use.
+ */
+ public final void changeNick(String newNick) {
+ this.sendRawLine("NICK " + newNick);
+ }
+
+
+ /**
+ * Identify the bot with NickServ, supplying the appropriate password.
+ * Some IRC Networks (such as freenode) require users to register and
+ * identify with NickServ before they are able to send private messages
+ * to other users, thus reducing the amount of spam. If you are using
+ * an IRC network where this kind of policy is enforced, you will need
+ * to make your bot identify itself to NickServ before you can send
+ * private messages. Assuming you have already registered your bot's
+ * nick with NickServ, this method can be used to identify with
+ * the supplied password. It usually makes sense to identify with NickServ
+ * immediately after connecting to a server.
+ * sendMessage("NickServ", "identify PASSWORD");
+ *
+ * @param password The password which will be used to identify with NickServ.
+ */
+ public final void identify(String password) {
+ this.sendRawLine("NICKSERV IDENTIFY " + password);
+ }
+
+
+ /**
+ * Set the mode of a channel.
+ * This method attempts to set the mode of a channel. This
+ * may require the bot to have operator status on the channel.
+ * For example, if the bot has operator status, we can grant
+ * operator status to "Dave" on the #cs channel
+ * by calling setMode("#cs", "+o Dave");
+ * An alternative way of doing this would be to use the op method.
+ *
+ * @param channel The channel on which to perform the mode change.
+ * @param mode The new mode to apply to the channel. This may include
+ * zero or more arguments if necessary.
+ *
+ * @see #op(String,String) op
+ */
+ public final void setMode(String channel, String mode) {
+ this.sendRawLine("MODE " + channel + " " + mode);
+ }
+
+
+ /**
+ * Sends an invitation to join a channel. Some channels can be marked
+ * as "invite-only", so it may be useful to allow a bot to invite people
+ * into it.
+ *
+ * @param nick The nick of the user to invite
+ * @param channel The channel you are inviting the user to join.
+ *
+ */
+ public final void sendInvite(String nick, String channel) {
+ this.sendRawLine("INVITE " + nick + " :" + channel);
+ }
+
+
+ /**
+ * Bans a user from a channel. An example of a valid hostmask is
+ * "*!*compu@*.18hp.net". This may be used in conjunction with the
+ * kick method to permanently remove a user from a channel.
+ * Successful use of this method may require the bot to have operator
+ * status itself.
+ *
+ * @param channel The channel to ban the user from.
+ * @param hostmask A hostmask representing the user we're banning.
+ */
+ public final void ban(String channel, String hostmask) {
+ this.sendRawLine("MODE " + channel + " +b " + hostmask);
+ }
+
+
+ /**
+ * Unbans a user from a channel. An example of a valid hostmask is
+ * "*!*compu@*.18hp.net".
+ * Successful use of this method may require the bot to have operator
+ * status itself.
+ *
+ * @param channel The channel to unban the user from.
+ * @param hostmask A hostmask representing the user we're unbanning.
+ */
+ public final void unBan(String channel, String hostmask) {
+ this.sendRawLine("MODE " + channel + " -b " + hostmask);
+ }
+
+
+ /**
+ * Grants operator privilidges to a user on a channel.
+ * Successful use of this method may require the bot to have operator
+ * status itself.
+ *
+ * @param channel The channel we're opping the user on.
+ * @param nick The nick of the user we are opping.
+ */
+ public final void op(String channel, String nick) {
+ this.setMode(channel, "+o " + nick);
+ }
+
+
+ /**
+ * Removes operator privilidges from a user on a channel.
+ * Successful use of this method may require the bot to have operator
+ * status itself.
+ *
+ * @param channel The channel we're deopping the user on.
+ * @param nick The nick of the user we are deopping.
+ */
+ public final void deOp(String channel, String nick) {
+ this.setMode(channel, "-o " + nick);
+ }
+
+
+ /**
+ * Grants voice privilidges to a user on a channel.
+ * Successful use of this method may require the bot to have operator
+ * status itself.
+ *
+ * @param channel The channel we're voicing the user on.
+ * @param nick The nick of the user we are voicing.
+ */
+ public final void voice(String channel, String nick) {
+ this.setMode(channel, "+v " + nick);
+ }
+
+
+ /**
+ * Removes voice privilidges from a user on a channel.
+ * Successful use of this method may require the bot to have operator
+ * status itself.
+ *
+ * @param channel The channel we're devoicing the user on.
+ * @param nick The nick of the user we are devoicing.
+ */
+ public final void deVoice(String channel, String nick) {
+ this.setMode(channel, "-v " + nick);
+ }
+
+
+ /**
+ * Set the topic for a channel.
+ * This method attempts to set the topic of a channel. This
+ * may require the bot to have operator status if the topic
+ * is protected.
+ *
+ * @param channel The channel on which to perform the mode change.
+ * @param topic The new topic for the channel.
+ *
+ */
+ public final void setTopic(String channel, String topic) {
+ this.sendRawLine("TOPIC " + channel + " :" + topic);
+ }
+
+
+ /**
+ * Kicks a user from a channel.
+ * This method attempts to kick a user from a channel and
+ * may require the bot to have operator status in the channel.
+ *
+ * @param channel The channel to kick the user from.
+ * @param nick The nick of the user to kick.
+ */
+ public final void kick(String channel, String nick) {
+ this.kick(channel, nick, "");
+ }
+
+
+ /**
+ * Kicks a user from a channel, giving a reason.
+ * This method attempts to kick a user from a channel and
+ * may require the bot to have operator status in the channel.
+ *
+ * @param channel The channel to kick the user from.
+ * @param nick The nick of the user to kick.
+ * @param reason A description of the reason for kicking a user.
+ */
+ public final void kick(String channel, String nick, String reason) {
+ this.sendRawLine("KICK " + channel + " " + nick + " :" + reason);
+ }
+
+
+ /**
+ * Issues a request for a list of all channels on the IRC server.
+ * When the PircBot receives information for each channel, it will
+ * call the onChannelInfo method, which you will need to override
+ * if you want it to do anything useful.
+ *
+ * @see #onChannelInfo(String,int,String) onChannelInfo
+ */
+ public final void listChannels() {
+ this.listChannels(null);
+ }
+
+
+ /**
+ * Issues a request for a list of all channels on the IRC server.
+ * When the PircBot receives information for each channel, it will
+ * call the onChannelInfo method, which you will need to override
+ * if you want it to do anything useful.
+ * PircBot #test :I Am King of Test
"
+ * with a code of 332 to signify that this is a topic.
+ * (This is just an example - note that overriding the
+ * onTopic
method is an easier way of finding the
+ * topic for a channel). Check the IRC RFC for the full list of other
+ * command response codes.
+ * public void onIncomingFileTransfer(DccFileTransfer transfer) {
+ * // Use the suggested file name.
+ * File file = transfer.getFile();
+ * // Receive the transfer and save it to the file, allowing resuming.
+ * transfer.receive(file, true);
+ * }
+ * public void onIncomingChatRequest(DccChat chat) {
+ * try {
+ * // Accept all chat, whoever it's from.
+ * chat.accept();
+ * chat.sendLine("Hello");
+ * String response = chat.readLine();
+ * chat.close();
+ * }
+ * catch (IOException e) {}
+ * }
+ *
+ * Each time this method is called, it is called from within a new Thread
+ * so that multiple DCC CHAT sessions can run concurrently.
+ *
+ * Version{PircBot x.y.z Java IRC Bot - www.jibble.org}
+ * Connected{true}
+ * Server{irc.dal.net}
+ * Port{6667}
+ * Password{}
+ *
+ *
+ * @since PircBot 0.9.10
+ *
+ * @return a String representation of this object.
+ */
+ public String toString() {
+ return "Version{" + _version + "}" +
+ " Connected{" + isConnected() + "}" +
+ " Server{" + _server + "}" +
+ " Port{" + _port + "}" +
+ " Password{" + _password + "}";
+ }
+
+
+ /**
+ * Returns an array of all users in the specified channel.
+ *
+ *
+ *
+ * @since PircBot 1.0.0
+ *
+ * @param channel The name of the channel to list.
+ *
+ * @return An array of User objects. This array is empty if we are not
+ * in the channel.
+ *
+ * @see #onUserList(String,User[]) onUserList
+ */
+ public final User[] getUsers(String channel) {
+ channel = channel.toLowerCase();
+ User[] userArray = new User[0];
+ synchronized (_channels) {
+ Hashtable