]> git.somenet.org - irc/pjirc-ng.git/blob - src/main/java/irc/ServerProtocol.java
Pjirc 2.2.1 as available on the net, reformatted and made it compile.
[irc/pjirc-ng.git] / src / main / java / irc / ServerProtocol.java
1 /*****************************************************/
2 /*          This java file is a part of the          */
3 /*                                                   */
4 /*           -  Plouf's Java IRC Client  -           */
5 /*                                                   */
6 /*   Copyright (C)  2002 - 2005 Philippe Detournay   */
7 /*                                                   */
8 /*         All contacts : theplouf@yahoo.com         */
9 /*                                                   */
10 /*  PJIRC is free software; you can redistribute     */
11 /*  it and/or modify it under the terms of the GNU   */
12 /*  General Public License as published by the       */
13 /*  Free Software Foundation; version 2 or later of  */
14 /*  the License.                                     */
15 /*                                                   */
16 /*  PJIRC is distributed in the hope that it will    */
17 /*  be useful, but WITHOUT ANY WARRANTY; without     */
18 /*  even the implied warranty of MERCHANTABILITY or  */
19 /*  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   */
20 /*  General Public License for more details.         */
21 /*                                                   */
22 /*  You should have received a copy of the GNU       */
23 /*  General Public License along with PJIRC; if      */
24 /*  not, write to the Free Software Foundation,      */
25 /*  Inc., 59 Temple Place, Suite 330, Boston,        */
26 /*  MA  02111-1307  USA                              */
27 /*                                                   */
28 /*****************************************************/
29
30 package irc;
31
32 import java.io.BufferedInputStream;
33 import java.io.BufferedOutputStream;
34 import java.net.Socket;
35 import java.util.Vector;
36
37 /**
38  * The raw irc server protocol handler.
39  */
40 public class ServerProtocol extends IRCObject implements Runnable {
41         private ListenerGroup _listeners;
42         private String _host;
43         private int _port;
44         private Socket _socket;
45         private CodingHandler _handler;
46         private Thread _thread;
47         private boolean _connected;
48         private boolean _connecting;
49
50         /**
51          * Create a new ServerProtocol.
52          * 
53          * @param config
54          *          global irc configuration.
55          */
56         public ServerProtocol(IRCConfiguration config) {
57                 super(config);
58                 _connected = false;
59                 _connecting = false;
60                 _listeners = new ListenerGroup();
61         }
62
63         /**
64          * Connect to the server.
65          * 
66          * @param host
67          *          server host.
68          * @param port
69          *          server port.
70          */
71         public void connect(String host, int port) {
72                 if (_connected)
73                         disconnect();
74                 _connecting = true;
75                 _host = host;
76                 _port = port;
77                 _thread = new Thread(this, "Read thread");
78                 _thread.start();
79         }
80
81         /**
82          * Return connected status.
83          * 
84          * @return true if connected, false otherwise.
85          */
86         public boolean connected() {
87                 return _connected;
88         }
89
90         /**
91          * Return connecting status.
92          * 
93          * @return true if connecting, false otherwise.
94          */
95         public boolean connecting() {
96                 return _connecting;
97         }
98
99         /**
100          * Disconnect from server.
101          */
102         public synchronized void disconnect() {
103                 if (!_connected)
104                         return;
105                 if (_connecting)
106                         return;
107                 try {
108                         _socket.close();
109                         _handler.close();
110                 } catch (Exception e) {
111                         // System.out.println("disconnection");
112                         // System.out.println(e);
113                 }
114                 _connected = false;
115                 _listeners.sendEvent("disconnected", _host);
116         }
117
118         /**
119          * Get the local, client-side tcp port for the current connection.
120          * 
121          * @return the local port.
122          */
123         public int getLocalPort() {
124                 return _socket.getLocalPort();
125         }
126
127         private void decodeLine(String line) {
128                 Vector res = new Vector();
129                 while (line.length() != 0) {
130                         if (line.startsWith(":") && (res.size() != 0)) {
131                                 res.insertElementAt(line.substring(1), res.size());
132                                 line = "";
133                         } else {
134                                 int pos = line.indexOf(' ');
135                                 if (pos == -1) {
136                                         res.insertElementAt(StringParser.trim(line), res.size());
137                                         line = "";
138                                 } else {
139                                         String part = StringParser.trim(line.substring(0, pos));
140                                         line = StringParser.trim(line.substring(pos + 1));
141                                         res.insertElementAt(part, res.size());
142                                 }
143                         }
144                 }
145                 if (res.size() == 0)
146                         return;
147
148                 String source = "";
149                 if (((String) (res.elementAt(0))).startsWith(":")) {
150                         source = (String) res.elementAt(0);
151                         source = source.substring(1);
152                         res.removeElementAt(0);
153                 }
154                 if (res.size() == 0)
155                         return;
156
157                 String cmd = (String) res.elementAt(0);
158                 res.removeElementAt(0);
159
160                 String[] param = new String[res.size()];
161                 for (int i = 0; i < res.size(); i++)
162                         param[i] = (String) res.elementAt(i);
163
164                 if ((cmd.charAt(0) >= '0') && (cmd.charAt(0) <= '9')) {
165
166                         _listeners.sendEventAsync("replyReceived", source, cmd, param);
167                 } else {
168
169                         _listeners.sendEventAsync("messageReceived", source, cmd, param);
170                 }
171         }
172
173         @Override
174         public void run() {
175                 try {
176                         _socket = _ircConfiguration.getSecurityProvider().getSocket(_host, _port);
177
178                         _handler = new CodingHandler(_ircConfiguration, new BufferedInputStream(_socket.getInputStream()),
179                                         new BufferedOutputStream(_socket.getOutputStream()));
180                         _connected = true;
181                         _connecting = false;
182                         _listeners.sendEventAsync("connected", _host);
183                 } catch (Exception e) {
184                         // e.printStackTrace();
185                         _connecting = false;
186
187                         if (e.getMessage() != null)
188                                 _listeners.sendEventAsync("connectionFailed", e.getMessage(), _host);
189                         else
190                                 _listeners.sendEventAsync("connectionFailed", e.getClass().getName(), _host);
191
192                         return;
193                 }
194                 boolean terminated = false;
195                 while (!terminated) {
196                         try {
197                                 String line = _handler.read();
198                                 if (line == null)
199                                         throw new Exception();
200                                 // System.out.println("--> "+line);
201                                 try {
202                                         if (line != null)
203                                                 decodeLine(line);
204                                 } catch (Exception e) {
205                                         _ircConfiguration.internalError("internal error", e, "plouf@pjirc.com");
206                                 }
207                         } catch (Exception e) {
208                                 terminated = true;
209                         }
210                 }
211                 EventDispatcher.dispatchEventAsync(this, "disconnect", new Object[0]);
212         }
213
214         /**
215          * Add a listener.
216          * 
217          * @param lis
218          *          listener to add.
219          */
220         public void addServerProtocolListener(ServerProtocolListener lis) {
221                 _listeners.addListener(lis);
222         }
223
224         /**
225          * Remove a listener.
226          * 
227          * @param lis
228          *          listener to remove.
229          */
230         public void removeServerProtocolListener(ServerProtocolListener lis) {
231                 _listeners.removeListener(lis);
232         }
233
234         /**
235          * Send a raw string to the server.
236          * 
237          * @param str
238          *          string to send.
239          * @throws Exception
240          *           if something went wrong.
241          */
242         public void sendString(String str) throws Exception {
243                 if (!connected())
244                         throw new Exception(getText(IRCTextProvider.SERVER_NOT_CONNECTED));
245                 _handler.write(str);
246                 // System.out.println("<-- "+str);
247         }
248
249         /**
250          * Send a formatted string to the server.
251          * 
252          * @param command
253          *          comment to send.
254          * @param params
255          *          parameters list. Only the last parameter can contain blanks.
256          * @throws Exception
257          *           if something went wrong.
258          */
259         public void sendCommand(String command, String params[]) throws Exception {
260                 String toSend = command;
261
262                 for (int i = 0; i < params.length; i++) {
263                         toSend += " ";
264                         if (params[i].indexOf(' ') != -1)
265                                 toSend += ":";
266                         toSend += params[i];
267                 }
268                 sendString(toSend);
269         }
270
271 }