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.26
Committed: Sat Mar 24 03:47:50 2001 UTC (23 years, 1 month ago) by tdb
Branch: MAIN
Changes since 1.25: +10 -6 lines
Log Message:
"last alert" will now display the last alert received... not the last one sent. This
means that alerts sent whilst in "stop alerts" mode will be included.

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