ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/client/alerters/IRC__Alerter.java
Revision: 1.25
Committed: Fri Mar 23 01:09:51 2001 UTC (23 years, 1 month ago) by ajm
Branch: MAIN
Changes since 1.24: +39 -94 lines
Log Message:
All skeletorized and javadoc'd now.

File Contents

# User Rev Content
1 tdb 1.1 //---PACKAGE DECLARATION---
2 tdb 1.20 package uk.org.iscream.client.alerters;
3 tdb 1.1
4     //---IMPORTS---
5 tdb 1.20 import uk.org.iscream.client.*;
6     import uk.org.iscream.core.*;
7     import uk.org.iscream.util.*;
8     import uk.org.iscream.componentmanager.*;
9 tdb 1.1 import java.io.*;
10     import java.net.*;
11 tdb 1.9 import java.util.*;
12 ajm 1.25 import java.text.DateFormat;
13 tdb 1.1
14     /**
15     * This Alert sends an IRC message.
16     *
17 tdb 1.9 * Clean shutdown could be achieved by stopping the run() method in the
18     * IRCBot inner class.
19     *
20 ajm 1.25 * @author $Author: ajm4 $
21     * @version $Id: IRC__Alerter.java,v 1.24 2001/03/22 22:07:58 ajm4 Exp $
22 tdb 1.1 */
23 ajm 1.25 public class IRC__Alerter extends AlerterSkeleton {
24 tdb 1.1
25     //---FINAL ATTRIBUTES---
26    
27     /**
28     * The current CVS revision of this class
29     */
30 ajm 1.25 public final String REVISION = "$Revision: 1.24 $";
31 tdb 1.1
32 tdb 1.9 /**
33     * A description of this alerter
34     */
35 tdb 1.1 public final String DESC = "Sends alerts on an IRC channel";
36    
37 tdb 1.9 /**
38     * The default reconnect delay in seconds
39     */
40     public final int DEFAULT_RECONNECT_DELAY = 30;
41    
42 tdb 1.1 //---STATIC METHODS---
43    
44     //---CONSTRUCTORS---
45    
46     public IRC__Alerter() {
47 ajm 1.25 super();
48 tdb 1.1 // connect to the IRC server
49 tdb 1.9 _ircbot = new IRCBot();
50 tdb 1.19 // set it's name and start it
51     _ircbot.setName("client.IRC__Alerter$IRCBot");
52 tdb 1.9 _ircbot.start();
53 tdb 1.11 _startTime = System.currentTimeMillis();
54 tdb 1.5 _logger.write(toString(), Logger.SYSINIT, "IRC Alerter started");
55 tdb 1.1 }
56    
57     //---PUBLIC METHODS---
58    
59 ajm 1.25 /**
60     * Implements the abstract method from the skeleton class.
61     * This method will attempt to send an alert
62     * message over the IRC channel.
63     *
64     * @param alert the alert to send
65     */
66 tdb 1.1 public void sendAlert(Alert alert) {
67 tdb 1.9 // only send alerts if we're active
68     if(_active) {
69 ajm 1.25 // sort out the message
70     String alertType = Alert.alertLevels[alert.getLevel()];
71     String message;
72 tdb 1.16 try {
73 ajm 1.25 message = _cp.getProperty(_name, "Alerter.IRC.message");
74 tdb 1.16 } catch (PropertyNotFoundException e) {
75 ajm 1.25 message = NOT_CONFIGURED;
76     _logger.write(toString(), Logger.WARNING, "Alerter.IRC.message value unavailable using default of " + message);
77 tdb 1.16 }
78 ajm 1.25 message = processAlertMessage(message, alert);
79    
80     // send the message
81     _logger.write(toString(), Logger.DEBUG, "Sending " + _name + " at "+ alertType + " level");
82     _ircbot.sendMsg(message);
83     _lastAlert = message;
84     _lastAlertTime = System.currentTimeMillis();
85     _alertCount ++;
86     } else {
87 tdb 1.18 _ignoredCount ++;
88     }
89 tdb 1.1 }
90    
91     /**
92     * Overrides the {@link java.lang.Object#toString() Object.toString()}
93     * method to provide clean logging (every class should have this).
94     *
95 tdb 1.20 * This uses the uk.org.iscream.util.NameFormat class
96 tdb 1.1 * to format the toString()
97     *
98     * @return the name of this class and its CVS revision
99     */
100     public String toString() {
101     return FormatName.getName(
102     _name,
103     getClass().getName(),
104     REVISION);
105     }
106    
107 ajm 1.25 /**
108     * Return the String representation of what the alerter does
109     *
110     * @return the description
111 tdb 1.1 */
112     public String getDescription(){
113     return DESC;
114     }
115    
116     //---PRIVATE METHODS---
117 ajm 1.8
118 tdb 1.1 //---ACCESSOR/MUTATOR METHODS---
119    
120     //---ATTRIBUTES---
121    
122 tdb 1.7 /**
123     * A reference to the IRCBot
124     */
125 tdb 1.1 private IRCBot _ircbot;
126    
127     /**
128 tdb 1.9 * Are we "active"
129     */
130     private boolean _active = false;
131    
132     /**
133     * The last alert that was sent
134     */
135     private String _lastAlert = "no alerts have been sent";
136    
137     /**
138 tdb 1.11 * The time of the last alert
139     */
140     private long _lastAlertTime = -1;
141    
142     /**
143     * Number of alerts sent
144     */
145 tdb 1.18 private int _alertCount = 0;
146    
147     /**
148     * Number of alerts ignored when in "stopped" mode
149     */
150     private int _ignoredCount = 0;
151 tdb 1.11
152     /**
153     * Time of IRCBot startup
154     */
155     private long _startTime;
156    
157     /**
158 tdb 1.1 * This is the friendly identifier of the
159     * component this class is running in.
160     * eg, a Filter may be called "filter1",
161     * If this class does not have an owning
162     * component, a name from the configuration
163     * can be placed here. This name could also
164     * be changed to null for utility classes.
165     */
166 ajm 1.25 private String _name = "IRC";
167 tdb 1.1
168     //---STATIC ATTRIBUTES---
169    
170     //---INNER CLASSES---
171    
172     /**
173     * This class provides some basic IRCBot functionality. It connects
174     * to a specified server, and will remain there until told to
175     * leave. Whilst connected it can send a message or a notice to
176     * the server.
177     */
178     class IRCBot extends Thread {
179    
180 tdb 1.16 public static final String DEFAULT_STARTUP_NOTICE = "i-scream ircbot starting...";
181    
182 tdb 1.1 /**
183     * Main thread loop, this part of the class listens for
184     * messages from the server, and acts accordingly. At the
185     * present moment it only responds to pings.
186     */
187     public void run() {
188 tdb 1.9 // so we can stop if required
189 tdb 1.1 boolean run = true;
190     while(run) {
191 tdb 1.9 // flag so we can stop the loop
192     boolean doRead = true;
193 tdb 1.16 // get the startup notice
194     String startupNotice;
195     try {
196     startupNotice = ConfigurationProxy.getInstance().getProperty(_name, "Alerter.IRC.startupNotice");
197     } catch (PropertyNotFoundException e) {
198     startupNotice = DEFAULT_STARTUP_NOTICE;
199     _logger.write(this.toString(), Logger.WARNING, "Configuration error: "+e);
200     }
201 tdb 1.9 // connect to the IRC server
202 tdb 1.1 try {
203 tdb 1.9 connect();
204 tdb 1.16 sendNotice(startupNotice);
205 tdb 1.9 } catch(IOException e) {
206     doRead=false;
207     _logger.write(this.toString(), Logger.ERROR, "Error connecting: "+e);
208     }
209     while(doRead) {
210     try {
211     // read a command
212     String cmd = _socketIn.readLine();
213     // if we have a null, we've lost contact
214     if(cmd == null) {
215     throw new IOException("End of stream reached");
216     }
217     // let another method deal with the input
218     handleInput(cmd);
219     } catch (IOException e) {
220     // comms failure, maybe our link is dead.
221     _logger.write(this.toString(), Logger.ERROR, "Communication error: "+e);
222     // stop, and loop round for a reconnect.
223     doRead = false;
224 tdb 1.1 }
225 tdb 1.9 }
226     // make sure we're disconnected
227     try {
228     disconnect();
229 tdb 1.1 } catch (IOException e) {
230 tdb 1.9 _logger.write(this.toString(), Logger.ERROR, "Communication error: "+e);
231     }
232    
233     // comms have failed, so wait a while and reconnect
234     int delayTime = 0;
235     try {
236     delayTime = Integer.parseInt(ConfigurationProxy.getInstance().getProperty(_name, "Alerter.IRC.reconnectDelay"));
237     } catch (NumberFormatException e) {
238     delayTime = DEFAULT_RECONNECT_DELAY;
239     _logger.write(this.toString(), Logger.WARNING, "Erronous Alerter.IRC.reconnectDelay value in configuration using default of " + delayTime + " seconds");
240 tdb 1.16 } catch (PropertyNotFoundException e) {
241 tdb 1.9 delayTime = DEFAULT_RECONNECT_DELAY;
242     _logger.write(this.toString(), Logger.WARNING, "Alerter.IRC.reconnectDelay value unavailable using default of " + delayTime + " seconds");
243 tdb 1.1 }
244 tdb 1.9 try {
245     Thread.sleep(delayTime * 1000);
246     } catch (InterruptedException e) {}
247 tdb 1.1 }
248 tdb 1.9 // maybe disconnect here ? - shutdown method not implemented yet
249     //disconnect();
250 tdb 1.1 }
251    
252     /**
253     * Sends a message to the channel.
254     *
255     * @param msg The message to send
256     */
257     public void sendMsg(String msg) {
258     _socketOut.println("PRIVMSG "+_channel+" :"+msg);
259 tdb 1.13 // wait a second before returning...
260     // this ensures messages can't be sent too fast
261     try {Thread.sleep(1000);} catch (InterruptedException e) {}
262 tdb 1.1 }
263    
264     /**
265 tdb 1.9 * Sends a message to the channel.
266     *
267     * @param user The user to send to
268     * @param msg The message to send
269     */
270     public void sendPrivMsg(String user, String msg) {
271     _socketOut.println("PRIVMSG "+user+" :"+msg);
272 tdb 1.13 // wait a second before returning...
273     // this ensures messages can't be sent too fast
274     try {Thread.sleep(1000);} catch (InterruptedException e) {}
275 tdb 1.9 }
276    
277     /**
278     * Sends an action to the channel.
279     *
280     * @param msg the action message
281     */
282     public void sendAction(String msg) {
283     char esc = 001;
284     sendMsg(esc+"ACTION "+msg+esc);
285 tdb 1.13 // wait a second before returning...
286     // this ensures messages can't be sent too fast
287     try {Thread.sleep(1000);} catch (InterruptedException e) {}
288 tdb 1.9 }
289    
290     /**
291 tdb 1.1 * Sends a notice to the channel.
292     *
293     * @param msg The notice to send
294     */
295     public void sendNotice(String msg) {
296     _socketOut.println("NOTICE "+_channel+" :"+msg);
297 tdb 1.13 // wait a second before returning...
298     // this ensures messages can't be sent too fast
299     try {Thread.sleep(1000);} catch (InterruptedException e) {}
300 tdb 1.1 }
301    
302     /**
303     * Connect to the IRC server, log in, and join the channel.
304     *
305     * @throws IOException if the connection fails
306     */
307     public void connect() throws IOException {
308 tdb 1.7 ConfigurationProxy cp = ConfigurationProxy.getInstance();
309 tdb 1.1 // setup the socket, reader and writer
310 tdb 1.16 String server;
311     int port;
312     try {
313     server = cp.getProperty(_name, "Alerter.IRC.IRCServer");
314     port = Integer.parseInt(cp.getProperty(_name, "Alerter.IRC.IRCPort"));
315     } catch (PropertyNotFoundException e) {
316     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
317     throw new IOException("Can't get irc server details due to configuration error");
318     } catch (NumberFormatException e) {
319     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
320     throw new IOException("Can't get irc server details due to malformed configuration");
321     }
322 tdb 1.7 _socket = new Socket(server, port);
323 tdb 1.1 _socketIn = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
324     _socketOut = new PrintWriter(_socket.getOutputStream(), true);
325 tdb 1.9 //_socketOut.println("PASS");
326     // send USER details
327 tdb 1.16 String user, comment;
328     try {
329     user = cp.getProperty(_name, "Alerter.IRC.user");
330     comment = cp.getProperty(_name, "Alerter.IRC.comment");
331     } catch (PropertyNotFoundException e) {
332     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
333     throw new IOException("Can't get user details due to configuration error");
334     }
335 tdb 1.9 _socketOut.println("USER "+user+" 8 * :"+comment);
336     // attempt to get a nick
337 tdb 1.16 String nickList;
338     try {
339     nickList = cp.getProperty(_name, "Alerter.IRC.nickList");
340     } catch (PropertyNotFoundException e) {
341     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
342     throw new IOException("Can't get nickname due to configuration error");
343     }
344 tdb 1.9 StringTokenizer st = new StringTokenizer(nickList, ";");
345     boolean ok = false;
346     // try until we exhaust our list
347     while(!ok && st.hasMoreTokens()) {
348     String nick = st.nextToken();
349     _socketOut.println("NICK "+nick);
350     // get a "yes" or "no" response back
351     String response = "";
352     do {
353     response = _socketIn.readLine();
354     if(response==null) {
355     throw new IOException("Communication error whilst logging in");
356     }
357     } while(response.indexOf("001")==-1 && response.indexOf("433")==-1);
358     // see if it was a yes
359     if(response.indexOf("001")!=-1) {
360     // great, we're logged in !
361     ok = true;
362     // store the name we're using
363     _nickname = nick;
364     }
365     else {
366     // log we couldn't get the name
367     _logger.write(this.toString(), Logger.WARNING, "Nickname in use: "+nick);
368     }
369     }
370     if(!ok) {
371     // oh dear, we couldn't get on.
372     throw new IOException("All nicknames in use");
373     }
374 tdb 1.1 // join the channel
375 tdb 1.16 try {
376     _channel = cp.getProperty(_name, "Alerter.IRC.channel");
377     } catch (PropertyNotFoundException e) {
378     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
379     throw new IOException("Can't get channel name due to configuration error");
380     }
381 tdb 1.1 _socketOut.println("JOIN "+_channel);
382 tdb 1.9 // allow alerts
383     _active = true;
384 tdb 1.1 }
385    
386     /**
387     * Disconnect "nicely" from the IRC server.
388     *
389     * @throws IOException if the disconnection fails
390     */
391     public void disconnect() throws IOException {
392 tdb 1.9 // stop alerts
393     _active = false;
394 tdb 1.6 // send proper QUIT
395 tdb 1.1 _socketOut.println("QUIT : iscreamBot component shutting down...");
396     // close the socket
397     _socketOut.close();
398     _socketIn.close();
399     _socket.close();
400     }
401 tdb 1.7
402 tdb 1.1 /**
403 tdb 1.9 * Overrides the {@link java.lang.Object#toString() Object.toString()}
404     * method to provide clean logging (every class should have this).
405     *
406 tdb 1.20 * This uses the uk.org.iscream.util.NameFormat class
407 tdb 1.9 * to format the toString()
408     *
409     * @return the name of this class and its CVS revision
410     */
411     public String toString() {
412     return FormatName.getName(
413     _name,
414     getClass().getName(),
415     REVISION);
416     }
417    
418     /**
419     * Deals with incoming lines from the server.
420     *
421     * @param line the line to deal with
422     */
423     private void handleInput(String line) {
424     ConfigurationProxy cp = ConfigurationProxy.getInstance();
425     // if it's a PING...
426     if(line.startsWith("PING")) {
427     // ...send a PONG
428     _socketOut.println("PONG" + line.substring(4));
429     }
430     // see if it's for us
431 tdb 1.16 else if(getMsg(line).startsWith(_nickname+",") || getMsg(line).startsWith(_nickname+":") || getMsg(line).startsWith(_nickname+" ")) {
432     // setup some String's
433     String stopCommand, startCommand, timeSinceLastAlertCommand, lastAlertCommand, joinCommand;
434     String nickChangeCommand, versionCommand, helpCommand, statCommand, uptimeCommand;
435     // get the command set
436     try {
437     stopCommand = cp.getProperty(_name, "Alerter.IRC.stopCommand");
438     startCommand = cp.getProperty(_name, "Alerter.IRC.startCommand");
439     timeSinceLastAlertCommand = cp.getProperty(_name, "Alerter.IRC.timeSinceLastAlertCommand");
440     lastAlertCommand = cp.getProperty(_name, "Alerter.IRC.lastAlertCommand");
441     joinCommand = cp.getProperty(_name, "Alerter.IRC.joinCommand");
442     nickChangeCommand = cp.getProperty(_name, "Alerter.IRC.nickChangeCommand");
443     versionCommand = cp.getProperty(_name, "Alerter.IRC.versionCommand");
444     helpCommand = cp.getProperty(_name, "Alerter.IRC.helpCommand");
445     statCommand = cp.getProperty(_name, "Alerter.IRC.statCommand");
446     uptimeCommand = cp.getProperty(_name, "Alerter.IRC.uptimeCommand");
447     } catch (PropertyNotFoundException e) {
448     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
449     // lets bail from handling this line...
450     // ...it's gonna be hard without a command set!
451     return;
452     }
453    
454 tdb 1.9 // we have a message for us
455     String message = getMsg(line).substring(_nickname.length());
456 tdb 1.16 if(message.indexOf(stopCommand)!=-1) {
457 tdb 1.9 _active = false;
458     sendMsg(getMsgSender(line)+", alerts have been stopped");
459     }
460 tdb 1.16 else if(message.indexOf(startCommand)!=-1) {
461 tdb 1.9 _active = true;
462     sendMsg(getMsgSender(line)+", alerts have been activated");
463     }
464 tdb 1.11 // this needs to go here if it contains the same words as the lastAlertCommand
465 tdb 1.16 else if(message.indexOf(timeSinceLastAlertCommand)!=-1) {
466 tdb 1.11 if(_lastAlertTime != -1) {
467     long uptime = (System.currentTimeMillis() - _lastAlertTime) / 1000;
468     String uptimeText = DateUtils.formatTime(uptime, "%DAYS% days, %HOURS% hours, %MINS% mins, and %SECS% secs");
469     sendMsg(getMsgSender(line)+", I last sent an alert "+uptimeText+ " ago");
470     }
471     else {
472     sendMsg(getMsgSender(line)+", I've never sent an alert!");
473     }
474     }
475 tdb 1.16 else if(message.indexOf(lastAlertCommand)!=-1) {
476 tdb 1.11 if(_lastAlertTime != -1) {
477     String date = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.UK).format(new Date(_lastAlertTime));
478     sendMsg(getMsgSender(line)+", last alert was at "+date+"; "+_lastAlert);
479     }
480     else {
481     sendMsg(getMsgSender(line)+", I've never sent an alert!");
482     }
483    
484 tdb 1.9 }
485 tdb 1.16 else if(message.indexOf(joinCommand)!=-1) {
486     String joinCmd = joinCommand;
487 tdb 1.9 String newChan = message.substring(message.indexOf(joinCmd) + joinCmd.length() + 1);
488     int endOfChan = newChan.indexOf(" ");
489     if(endOfChan == -1) {
490     endOfChan = newChan.length();
491     }
492     newChan = newChan.substring(0, endOfChan);
493 tdb 1.21 if(newChan.equals(_channel)) {
494     sendMsg(getMsgSender(line)+", I'm already on "+newChan+"!");
495     } else {
496     sendMsg(getMsgSender(line)+", okay, I'm off to "+newChan);
497     _socketOut.println("PART "+_channel);
498     _socketOut.println("JOIN "+newChan);
499     _channel = newChan;
500     }
501 tdb 1.9 }
502 tdb 1.16 else if(message.indexOf(nickChangeCommand)!=-1) {
503     String nickChangeCmd = nickChangeCommand;
504 tdb 1.11 String newNick = message.substring(message.indexOf(nickChangeCmd) + nickChangeCmd.length() + 1);
505     int endOfNick = newNick.indexOf(" ");
506     if(endOfNick == -1) {
507     endOfNick = newNick.length();
508     }
509     newNick = newNick.substring(0, endOfNick);
510     sendMsg(getMsgSender(line)+", okay, changing my nickname to "+newNick);
511     _socketOut.println("NICK "+newNick);
512     _nickname = newNick;
513     }
514 tdb 1.16 else if(message.indexOf(versionCommand)!=-1) {
515 tdb 1.12 sendMsg(getMsgSender(line)+", I am version "+REVISION.substring(11, REVISION.length() -2)+" of the i-scream alerting bot");
516     }
517 tdb 1.16 else if(message.indexOf(helpCommand)!=-1) {
518 tdb 1.12 sendPrivMsg(getMsgSender(line), "Hello, I am the i-scream alerting bot version "+REVISION.substring(11, REVISION.length() -2));
519 tdb 1.9 sendPrivMsg(getMsgSender(line), "I understand the following commands;");
520 tdb 1.16 sendPrivMsg(getMsgSender(line), stopCommand);
521     sendPrivMsg(getMsgSender(line), startCommand);
522     sendPrivMsg(getMsgSender(line), lastAlertCommand);
523     sendPrivMsg(getMsgSender(line), joinCommand);
524     sendPrivMsg(getMsgSender(line), nickChangeCommand);
525     sendPrivMsg(getMsgSender(line), statCommand);
526     sendPrivMsg(getMsgSender(line), uptimeCommand);
527     sendPrivMsg(getMsgSender(line), timeSinceLastAlertCommand);
528     sendPrivMsg(getMsgSender(line), helpCommand);
529 tdb 1.11 }
530 tdb 1.16 else if(message.indexOf(statCommand)!=-1) {
531 tdb 1.18 sendMsg(getMsgSender(line)+", I have sent a total of "+_alertCount+" alerts, and ignored a total of "+_ignoredCount+"!");
532 tdb 1.11 }
533 tdb 1.16 else if(message.indexOf(uptimeCommand)!=-1) {
534 tdb 1.11 long uptime = (System.currentTimeMillis() - _startTime) / 1000;
535     String uptimeText = DateUtils.formatTime(uptime, "%DAYS% days, %HOURS% hours, %MINS% mins, and %SECS% secs");
536     sendMsg(getMsgSender(line)+", I have been running for "+uptimeText);
537 tdb 1.18 }
538     else if(message.indexOf("ping")!=-1) {
539     sendMsg("pong");
540 tdb 1.9 }
541     else if(message.indexOf("do a jibble dance")!=-1) {
542     // little joke :)
543     sendAction("jives to the funky beat shouting \"ii--screeeaaammm\"");
544     }
545     else {
546 tdb 1.16 String rejectMessage = NOT_CONFIGURED;
547     try {
548     rejectMessage = cp.getProperty(_name, "Alerter.IRC.rejectMessage");
549     } catch(PropertyNotFoundException e) {
550     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
551     }
552     sendMsg(getMsgSender(line)+", "+rejectMessage);
553 tdb 1.9 }
554     }
555     else if(line.indexOf(_nickname)!=-1 && line.indexOf(_channel)!=-1 && line.indexOf("KICK")!=-1) {
556     sendPrivMsg(getMsgSender(line), "That wasn't a nice thing to do...");
557 tdb 1.16 try {
558     _channel = cp.getProperty(_name, "Alerter.IRC.channel");
559     } catch(PropertyNotFoundException e) {
560     _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
561     }
562 tdb 1.9 _socketOut.println("JOIN "+_channel);
563     }
564     }
565    
566     /**
567     * Strips the header from a message line
568     *
569     * @param line the line to strip
570     * @return the message from the line
571     */
572     private String getMsg(String line) {
573     String result = "";
574     if(line.indexOf("PRIVMSG")!=-1) {
575     int firstColon = line.indexOf(":");
576     if(firstColon != -1) {
577     int secondColon = line.indexOf(":", firstColon+1);
578     if(secondColon != -1) {
579     result = line.substring(secondColon+1);
580     }
581     }
582     }
583     return result;
584     }
585    
586     /**
587     * Finds out the sender of the message
588     *
589     * @param line the line to look for a sender in
590     * @return the sender
591     */
592     private String getMsgSender(String line) {
593     String result = "";
594     int colon = line.indexOf(":");
595     int excl = line.indexOf("!");
596     if(colon!=-1 && excl!=-1) {
597     result = line.substring(colon+1, excl);
598     }
599     return result;
600     }
601    
602     /**
603 tdb 1.1 * The socket connected to the server
604     */
605     private Socket _socket;
606    
607     /**
608     * The writer
609     */
610     private PrintWriter _socketOut;
611    
612     /**
613     * The reader
614     */
615     private BufferedReader _socketIn;
616    
617 tdb 1.7 /**
618     * Just a reminder to what channel we're on...
619     * this can't be dynamic :)
620     */
621     private String _channel;
622 tdb 1.9
623     /**
624     * A reminder of our current nickname...
625     */
626     private String _nickname;
627 ajm 1.25
628     /**
629     * This holds a reference to the
630     * system logger that is being used.
631     */
632     protected Logger _logger = ReferenceManager.getInstance().getLogger();
633 tdb 1.9
634 tdb 1.1 }
635    
636     }