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