]> Pileus Git - ~andy/spades/blob - src/org/pileus/spades/Client.java
f1657840c02924a06864a4b85e9ba885f4b69e72
[~andy/spades] / src / org / pileus / spades / Client.java
1 package org.pileus.spades;
2
3 import java.io.*;
4 import java.net.*;
5
6 public class Client
7 {
8         /* Preference data */
9         public  String         server   = "irc.freenode.net";
10         public  int            port     = 6667;
11         public  String         nickname = "SpadeGuest";
12         public  String         channel  = "#rhnoise";
13         public  boolean        usesasl  = false;
14         public  String         authname = "";
15         public  String         password = "";
16         public  String         username = "user";
17         public  String         hostname = "localhost";
18
19         /* Public data */
20         public  boolean        ready    = false;
21         public  String         name     = "";
22
23         /* Connection data */
24         private Socket         socket;
25         private BufferedReader input;
26         private PrintWriter    output;
27
28         /* Private data */
29         private int            mangle;
30
31         /* Public Methods */
32         public Client()
33         {
34                 Os.debug("Client: create");
35         }
36
37         public void setServer(String server, int port)
38         {
39                 this.server = server;
40                 this.port   = port;
41         }
42
43         public void setAuth(boolean usesasl, String authname, String password)
44         {
45                 this.usesasl  = usesasl;
46                 this.authname = authname;
47                 this.password = password;
48         }
49
50         public void setUser(String nickname, String channel)
51         {
52                 this.nickname = nickname;
53                 this.channel  = channel;
54                 this.name     = nickname;
55         }
56
57         public boolean connect()
58         {
59                 Os.debug("Client: connect");
60
61                 try {
62                         this.socket = new Socket(this.server, this.port);
63                         this.input  = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
64                         this.output = new PrintWriter(this.socket.getOutputStream());
65                 } catch (Exception e) {
66                         Os.debug("Client: failed to create connection: " + e);
67                         return false;
68                 }
69
70                 Os.debug("Client: connected");
71                 if (this.usesasl)
72                         this.raw("CAP REQ :sasl");
73                 this.raw("USER "+this.username+" "+this.hostname+" "+this.server+" :"+this.name);
74                 this.raw("NICK "+this.name);
75
76                 return true;
77         }
78
79         public boolean abort()
80         {
81                 Os.debug("Client: abort");
82                 try {
83                         this.socket.close();
84                         this.ready = false;
85                         return true;
86                 } catch (Exception e) {
87                         Os.debug("Client: error closing socket", e);
88                         return false;
89                 }
90         }
91
92         public void raw(String line)
93         {
94                 try {
95                         Os.debug("< " + line);
96                         this.output.println(line);
97                         this.output.flush();
98                 } catch (Exception e) {
99                         Os.debug("Client: error writing line", e);
100                 }
101         }
102
103         public Message send(String txt)
104         {
105                 if (!this.ready)
106                         return null;
107                 Message msg = new Message(this.channel, this.name, txt);
108                 if (msg.type == Message.Type.JOIN)
109                         this.channel = msg.msg;
110                 this.raw(msg.line);
111                 return msg;
112         }
113
114         public Message recv()
115         {
116                 try {
117                         String line = input.readLine();
118                         if (line == null)
119                                 return null;
120                         Os.debug("> " + line);
121                         Message msg = new Message(line, this.name);
122                         this.process(msg);
123                         if (this.usesasl)
124                                 this.dosasl(msg);
125                         return msg;
126                 } catch (SocketException e) {
127                         this.ready = false;
128                         return null;
129                 } catch (Exception e) {
130                         this.ready = false;
131                         Os.debug("Client: error in recv", e);
132                         return null;
133                 }
134         }
135
136         /* Private methods */
137         private void process(Message msg)
138         {
139                 if (msg.cmd.equals("001") && msg.msg.matches("Welcome.*")) {
140                         this.raw("JOIN "  + this.channel);
141                         this.raw("TOPIC " + this.channel);
142                         this.ready = true;
143                 }
144                 if (msg.cmd.equals("433")) {
145                         this.name   = this.nickname + this.mangle;
146                         this.mangle = this.mangle + 11;
147                         this.raw("NICK "  + this.name);
148                 }
149                 if (msg.cmd.equals("PING")) {
150                         this.raw("PING " + msg.msg);
151                 }
152         }
153
154         private void dosasl(Message msg)
155         {
156                 switch (msg.type) {
157                         case CAP:
158                                 if (msg.msg.equals("sasl") && msg.arg.equals("ACK")) {
159                                         Os.debug("Client: sasl - starting auth");
160                                         this.raw("AUTHENTICATE PLAIN");
161                                 } else {
162                                         Os.debug("Client: sasl - Server does not support sasl");
163                                 }
164                                 break;
165                         case AUTH:
166                                 if (msg.arg.equals("+")) {
167                                         Os.debug("Client: sasl - performin authentication");
168                                         this.raw("AUTHENTICATE " + Os.base64(
169                                                                 this.authname + "\0" +
170                                                                 this.authname + "\0" +
171                                                                 this.password));
172                                 } else {
173                                         Os.debug("Client: sasl - unexpected authenticate response");
174                                 }
175                                 break;
176                         case AUTHOK:
177                                 Os.debug("Client: SASL Auth Successful");
178                                 this.raw("CAP END");
179                                 break;
180                         case AUTHFAIL:
181                                 Os.debug("Client: SASL Auth Failed");
182                                 this.raw("CAP END");
183                                 break;
184                 }
185         }
186 }