1 package org.pileus.spades;
17 public String server = "irc.freenode.net";
18 public int port = 6667;
19 public int timeout = 240;
20 public String nickname = "SpadeGuest";
21 public String channel = "#rhnoise";
22 public boolean usesasl = false;
23 public String authname = "";
24 public String password = "";
25 public String username = "user";
26 public String hostname = "localhost";
29 public State state = State.INIT;
30 public String name = "";
33 private boolean pinging;
34 private Socket socket;
35 private BufferedReader input;
36 private PrintWriter output;
44 Os.debug("Client: create");
47 public void setServer(String server, int port)
53 public void setAuth(boolean usesasl, String authname, String password)
55 this.usesasl = usesasl;
56 this.authname = authname;
57 this.password = password;
60 public void setUser(String nickname, String channel)
62 this.nickname = nickname;
63 this.channel = channel;
67 public boolean connect()
69 Os.debug("Client: connect");
72 this.state = State.SETUP;
73 this.socket = new Socket();
74 this.socket.setSoTimeout(this.timeout/2 * 1000);
75 this.socket.connect(new InetSocketAddress(this.server, this.port));
76 this.input = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
77 this.output = new PrintWriter(this.socket.getOutputStream());
78 } catch (Exception e) {
79 Os.debug("Client: failed to create connection: " + e);
83 Os.debug("Client: connected");
85 this.raw("CAP REQ :sasl");
86 this.raw("USER "+this.username+" "+this.hostname+" "+this.server+" :"+this.name);
87 this.raw("NICK "+this.name);
94 Os.debug("Client: abort");
95 this.state = State.ABORT;
101 Os.debug("Client: reset");
102 this.state = State.INIT;
105 public void raw(String line)
108 if (this.validate() != State.SETUP &&
109 this.validate() != State.READY)
111 Os.debug("< " + line);
112 this.output.println(line);
114 } catch (Exception e) {
115 Os.debug("Client: error writing line", e);
119 public Message send(String dst, String txt)
121 if (txt == null || txt.length() == 0)
123 if (this.validate() != State.READY)
125 Message msg = new Message(dst, this.name, txt);
126 if (msg.type == Message.Type.JOIN)
127 this.channel = msg.msg;
132 public Message send(String txt)
134 return this.send(this.channel, txt);
137 public Message recv()
140 if (this.validate() != State.SETUP &&
141 this.validate() != State.READY)
143 String line = this.input.readLine();
146 Os.debug("> " + line);
147 Message msg = new Message(line, this.name);
151 if (!msg.cmd.equals("PING") &&
152 !msg.cmd.equals("PONG"))
155 catch (SocketTimeoutException e) {
161 this.raw("PING :" + hostname);
165 catch (SocketException e) {
166 this.state = State.INIT;
169 catch (Exception e) {
170 this.state = State.INIT;
171 Os.debug("Client: error in recv", e);
176 /* Private methods */
177 private State validate()
180 if (this.state == State.ABORT) {
181 if (this.socket != null) {
183 this.state = State.INIT;
186 } catch (Exception e) {
187 Os.debug("Client: error closing socket", e);
192 private void process(Message msg)
194 if (msg.cmd.equals("001") && msg.msg.matches("Welcome.*")) {
195 this.raw("JOIN " + this.channel);
196 this.raw("TOPIC " + this.channel);
197 this.state = State.READY;
199 if (msg.cmd.equals("433")) {
200 this.name = this.nickname + this.mangle;
201 this.mangle = this.mangle + 11;
202 this.raw("NICK " + this.name);
204 if (msg.cmd.equals("PING")) {
205 this.raw("PONG " + msg.msg);
207 if (msg.cmd.equals("PONG")) {
208 this.pinging = false;
212 private void dosasl(Message msg)
216 if (msg.msg.equals("sasl") && msg.arg.equals("ACK")) {
217 Os.debug("Client: sasl - starting auth");
218 this.raw("AUTHENTICATE PLAIN");
220 Os.debug("Client: sasl - Server does not support sasl");
224 if (msg.arg.equals("+")) {
225 Os.debug("Client: sasl - performin authentication");
226 this.raw("AUTHENTICATE " + Os.base64(
227 this.authname + "\0" +
228 this.authname + "\0" +
231 Os.debug("Client: sasl - unexpected authenticate response");
235 Os.debug("Client: SASL Auth Successful");
239 Os.debug("Client: SASL Auth Failed");