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.24
Committed: Thu Mar 22 22:07:58 2001 UTC (23 years, 1 month ago) by ajm
Branch: MAIN
Changes since 1.23: +36 -4 lines
Log Message:
Rejigged to use the same queuing structure as the Monitors.

Changed all the alerters to use new structire.

Possibly need to create an alerter skeleton...

File Contents

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