package org.pileus.spades;
-import java.io.BufferedReader;
-import java.io.PrintWriter;
+import java.io.*;
+import java.net.*;
public class Client
{
- /* Private data */
- private String server = null;
- private String nickname = null;
- private String channel = null;
- private String username = null;
- private String hostname = null;
-
- private BufferedReader input = null;
- private PrintWriter output = null;
+ /* Preference data */
+ public String server = "irc.freenode.net";
+ public int port = 6667;
+ public String nickname = "SpadeGuest";
+ public String channel = "#rhnoise";
+ public boolean usesasl = false;
+ public String authname = "";
+ public String password = "";
+ public String username = "user";
+ public String hostname = "localhost";
/* Public data */
- public boolean running = true;
+ public boolean ready = false;
+ public String name = "";
+
+ /* Connection data */
+ private Socket socket;
+ private BufferedReader input;
+ private PrintWriter output;
+
+ /* Private data */
+ private int mangle;
/* Public Methods */
- public Client(String server, String nickname, String channel,
- String username, String hostname)
+ public Client()
{
- this.server = server;
- this.nickname = nickname;
- this.channel = channel;
- this.username = username;
- this.hostname = hostname;
Os.debug("Client: create");
}
- public Client(String server, String nickname, String channel)
+ public void setServer(String server, int port)
{
- this(server, nickname, channel, "user", "localhost");
+ this.server = server;
+ this.port = port;
}
- public void connect(BufferedReader input, PrintWriter output)
+ public void setAuth(boolean usesasl, String authname, String password)
+ {
+ this.usesasl = usesasl;
+ this.authname = authname;
+ this.password = password;
+ }
+
+ public void setUser(String nickname, String channel)
+ {
+ this.nickname = nickname;
+ this.channel = channel;
+ this.name = nickname;
+ }
+
+ public boolean connect()
{
- this.input = input;
- this.output = output;
Os.debug("Client: connect");
- putline("USER "+username+" "+hostname+" "+server+" :"+nickname);
- putline("NICK "+nickname);
+
+ try {
+ this.socket = new Socket(this.server, this.port);
+ this.input = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
+ this.output = new PrintWriter(this.socket.getOutputStream());
+ } catch (Exception e) {
+ Os.debug("Client: failed to create connection: " + e);
+ return false;
+ }
+
+ Os.debug("Client: connected");
+ if (this.usesasl)
+ this.raw("CAP REQ :sasl");
+ this.raw("USER "+this.username+" "+this.hostname+" "+this.server+" :"+this.name);
+ this.raw("NICK "+this.name);
+
+ return true;
+ }
+
+ public boolean abort()
+ {
+ Os.debug("Client: abort");
+ try {
+ this.socket.close();
+ this.ready = false;
+ return true;
+ } catch (Exception e) {
+ Os.debug("Client: error closing socket", e);
+ return false;
+ }
+ }
+
+ public void raw(String line)
+ {
+ try {
+ Os.debug("< " + line);
+ this.output.println(line);
+ this.output.flush();
+ } catch (Exception e) {
+ Os.debug("Client: error writing line", e);
+ }
}
public Message send(String txt)
{
- Message msg = new Message(channel, nickname, txt);
- putline(msg.line);
+ Message msg = new Message(this.channel, this.name, txt);
+ this.raw(msg.line);
return msg;
}
public Message recv()
{
try {
- String line = getline();
- if (line == null) {
- this.running = false;
+ String line = input.readLine();
+ if (line == null)
return null;
- } else {
- Message msg = new Message(line);
- process(msg);
- return msg;
- }
+ Os.debug("> " + line);
+ Message msg = new Message(line, this.name);
+ this.process(msg);
+ if (this.usesasl)
+ this.dosasl(msg);
+ return msg;
+ } catch (SocketException e) {
+ this.ready = false;
+ return null;
} catch (Exception e) {
+ this.ready = false;
Os.debug("Client: error in recv", e);
- this.running = false;
return null;
}
}
private void process(Message msg)
{
if (msg.cmd.equals("001") && msg.msg.matches("Welcome.*")) {
- putline("JOIN " + channel);
- putline("TOPIC " + channel);
+ this.raw("JOIN " + this.channel);
+ this.raw("TOPIC " + this.channel);
+ this.ready = true;
}
- if (msg.cmd.equals("PING")) {
- putline("PING " + msg.msg);
+ if (msg.cmd.equals("433")) {
+ this.name = this.nickname + this.mangle;
+ this.mangle = this.mangle + 11;
+ this.raw("NICK " + this.name);
}
- }
-
- private String getline()
- {
- try {
- String line = input.readLine();
- if (line != null)
- Os.debug("> " + line);
- return line;
- } catch (Exception e) {
- Os.debug("Client: error reading line", e);
- this.running = false;
- return "";
+ if (msg.cmd.equals("PING")) {
+ this.raw("PING " + msg.msg);
}
}
- private void putline(String line)
+ private void dosasl(Message msg)
{
- try {
- Os.debug("< " + line);
- output.println(line);
- output.flush();
- } catch (Exception e) {
- Os.debug("Client: error writing line", e);
- this.running = false;
+ switch (msg.type) {
+ case CAP:
+ if (msg.msg.equals("sasl") && msg.arg.equals("ACK")) {
+ Os.debug("Client: sasl - starting auth");
+ this.raw("AUTHENTICATE PLAIN");
+ } else {
+ Os.debug("Client: sasl - Server does not support sasl");
+ }
+ break;
+ case AUTH:
+ if (msg.arg.equals("+")) {
+ Os.debug("Client: sasl - performin authentication");
+ this.raw("AUTHENTICATE " + Os.base64(
+ this.authname + "\0" +
+ this.authname + "\0" +
+ this.password));
+ } else {
+ Os.debug("Client: sasl - unexpected authenticate response");
+ }
+ break;
+ case AUTHOK:
+ Os.debug("Client: SASL Auth Successful");
+ this.raw("CAP END");
+ break;
+ case AUTHFAIL:
+ Os.debug("Client: SASL Auth Failed");
+ this.raw("CAP END");
+ break;
}
}
}