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
(Generate patch)

Comparing projects/cms/source/server/uk/org/iscream/cms/server/client/alerters/IRC__Alerter.java (file contents):
Revision 1.30.2.2 by tdb, Mon Feb 4 23:14:38 2002 UTC vs.
Revision 1.30.2.3 by tdb, Tue Feb 5 18:00:15 2002 UTC

# Line 43 | Line 43 | public class IRC__Alerter extends AlerterSkeleton {
43          super();
44          // construct and initialise the bot
45          _ircbot = new IRCBot();
46 <        //_ircbot.setVerbose(true);
46 >        _ircbot.setVerbose(false);
47          Thread ircThread = new Thread(_ircbot);
48          // set it's name and start it
49          ircThread.setName("client.IRC__Alerter$IRCBot");
# Line 77 | Line 77 | public class IRC__Alerter extends AlerterSkeleton {
77          if(_active) {          
78              // send the message
79              _logger.write(toString(), Logger.DEBUG, "Sending " + _name + " at "+ alertType + " level");
80 <            _ircbot.sendMsg(message);
80 >            _ircbot.sendMessage(message);
81              // count sent alerts
82              _alertCount++;
83          } else {
# Line 195 | Line 195 | public class IRC__Alerter extends AlerterSkeleton {
195           */
196          public final int DEFAULT_RECONNECT_DELAY = 30;
197          
198 +        /**
199 +         * Attempt to kick-start the IRCBot into action. Will
200 +         * keep calling init() until it doesn't throw an
201 +         * an IOException (which will only be thrown if there
202 +         * is an error initialising). After a successful call
203 +         * to init() the method finishes.
204 +         */
205          public void run() {
206              while(true) {
207                  try {
# Line 203 | Line 210 | public class IRC__Alerter extends AlerterSkeleton {
210                  }
211                  catch (IOException e) {
212                      _logger.write(this.toString(), Logger.ERROR, "Error initialising IRCBot: "+e);
213 +                    // wait for a while, defined in the config
214                      reconnectSleep();
215                  }
216              }
209            //System.out.println("falling out!");
217          }
218          
219 +        /**
220 +         * Connects the bot to an irc server and joins a channel,
221 +         * using details supplied from the i-scream configuration
222 +         * system. If this method completes without an exception
223 +         * one can presume the bot is ready for use.
224 +         *
225 +         * @throws IOException if there is any problem initialising
226 +         */
227          public void init() throws IOException {
228              _logger.write(this.toString(), Logger.DEBUG, "Initialising IRCBot...");
229 +            
230 +            // get a hook on the configuration system
231              ConfigurationProxy cp = ConfigurationProxy.getInstance();
232 +            
233 +            // get hold of the server details
234              String server;
235              int port;
236              try {
# Line 224 | Line 243 | public class IRC__Alerter extends AlerterSkeleton {
243                  _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
244                  throw new IOException("Can't get irc server details due to malformed configuration");
245              }
246 <            String user, comment;
246 >            
247 >            // get hold of the user details and nickname list
248 >            String user, comment, finger, nickList;
249              try {
250                  user = cp.getProperty(_name, "Alerter.IRC.user");
251                  comment = cp.getProperty(_name, "Alerter.IRC.comment");
252 +                finger = cp.getProperty(_name, "Alerter.IRC.finger");
253 +                nickList = cp.getProperty(_name, "Alerter.IRC.nickList");
254              } catch (PropertyNotFoundException e) {
255                  _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
256 <                throw new IOException("Can't get user details due to configuration error");
256 >                throw new IOException("Can't get user/nickname details due to configuration error");
257              }
258 +            
259 +            // put these details into the bot
260              this.setLogin(user);
261              this.setVersion(comment);
262 <            this.setFinger(comment); // ?
263 <            String nickList;
264 <            try {
265 <                nickList = cp.getProperty(_name, "Alerter.IRC.nickList");
241 <            } catch (PropertyNotFoundException e) {
242 <                _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
243 <                throw new IOException("Can't get nickname due to configuration error");
244 <            }
262 >            this.setFinger(finger);
263 >            
264 >            // attempt to connect, trying each nickname
265 >            // in turn until sucessfully connected
266              StringTokenizer st = new StringTokenizer(nickList, ";");
267              boolean ok = false;
268              while(!ok && st.hasMoreTokens()) {
269                  String nick = st.nextToken();
270                  try {
271 +                    // try to connect with a nickname
272                      _logger.write(this.toString(), Logger.DEBUG, "Trying nick: "+nick);
273                      this.setName(nick);
274                      this.connect(server, port);
275 <                    // must be ok if we get here
275 >                    // at this point we know the nickname was accepted
276                      _nickname = nick;
277                      ok = true;
278                  }
# Line 264 | Line 286 | public class IRC__Alerter extends AlerterSkeleton {
286                  }
287                  catch(NickAlreadyInUseException e) {
288                      _logger.write(this.toString(), Logger.ERROR, "Nickname "+nick+" is already in use: "+e);
289 <                    // just carry on around while loop
289 >                    // don't do anything, instead just loop round
290 >                    // and try the next nickname in the list
291                  }
292              }
293              if(!ok) {
294 <                // oh dear, we couldn't get on.
294 >                // must have tried all the nicknames, best bail out
295                  _logger.write(this.toString(), Logger.ERROR, "All nicknames already in use");
296                  throw new IOException("All nicknames already in use");
297              }
298 +            
299 +            // get hold of the channel details, and attempt
300 +            // to join the specified channel
301              try {
302                  _channel = cp.getProperty(_name, "Alerter.IRC.channel");
303                  this.joinChannel(_channel);
# Line 280 | Line 306 | public class IRC__Alerter extends AlerterSkeleton {
306                  throw new IOException("Can't get channel name due to configuration error");
307              }
308              
309 +            // get hold of the startup notice, and send
310 +            // it if it's defined
311              String startupNotice;
312              try {
313                  startupNotice = ConfigurationProxy.getInstance().getProperty(_name, "Alerter.IRC.startupNotice");
# Line 288 | Line 316 | public class IRC__Alerter extends AlerterSkeleton {
316                  _logger.write(this.toString(), Logger.DEBUG, "Startup notice not defined, so not sending: "+e);
317              }
318              
319 <            // we should set this when all is ready!
319 >            // at this point initialisation is complete, so
320 >            // we can return and set this flag to allow alerts
321              _active = true;
293            //System.out.println("leaving init");
322          }
323          
324 <        public void sendMsg(String msg) {
325 <            sendMessage(_channel, msg);
324 >        /**
325 >         * Send a message to the current channel.
326 >         *
327 >         * @param message The message to send
328 >         */
329 >        public void sendMessage(String message) {
330 >            sendMessage(_channel, message);
331          }
332          
333 +        /**
334 +         * If we get disconnected this method will be
335 +         * called, so we must take action. We'll simply
336 +         * keep trying to reinitialise, and thus
337 +         * reconnect to the server.
338 +         */
339          public void onDisconnect() {
340 +            // stop alerts being sent for now
341              _active = false;
342              while(true) {
343 +                // wait for a while, defined in the config
344                  reconnectSleep();
345                  try {
346                      init();
# Line 309 | Line 350 | public class IRC__Alerter extends AlerterSkeleton {
350                      _logger.write(this.toString(), Logger.ERROR, "Error initialising IRCBot: "+e);
351                  }
352              }
312            //System.out.println("falling out of disconnect!");
353          }
354          
355 +        /**
356 +         * If we receive a message this method will
357 +         * be called. We'll check if the message is
358 +         * for us, and call handleInput if it is.
359 +         *
360 +         * @param channel The channel the message came from
361 +         * @param sender The sender of the message
362 +         * @param login The login of the sender
363 +         * @param hostname The hostname of the sender
364 +         * @param message The message sent
365 +         */
366          public void onMessage(String channel, String sender, String login, String hostname, String message) {
367              if(isForMe(message)) {
368                  handleInput(message, channel);
369              }
370          }
371          
372 +        /**
373 +         * If we receive a private message this method
374 +         * will be called. No need to check if it's for
375 +         * us -- it has to be if it's a private message.
376 +         *
377 +         * @param sender The sender of the message
378 +         * @param login The login of the sender
379 +         * @param hostname The hostname of the sender
380 +         * @param message The message sent
381 +         */
382          public void onPrivateMessage(String sender, String login, String hostname, String message) {
383              handleInput(message, sender);
384          }
385          
386 +        /**
387 +         * If we receive a nick change message, this
388 +         * method gets called. We don't care about
389 +         * other users changing their nick, so we only
390 +         * take notice if our nick changes. If it does
391 +         * we need to change our internal nickname
392 +         * state.
393 +         *
394 +         * @param oldNick the old nickname
395 +         * @param login the login of the nick changer
396 +         * @param hostname the hostname of the nick changer
397 +         * @param newNick the new nickname
398 +         */
399          public void onNickChange(String oldNick, String login, String hostname, String newNick) {
400              if(oldNick.equals(_nickname)) {
401                  _nickname = newNick;
402              }
403          }
404          
405 +        /**
406 +         * If we receive a kick message this method
407 +         * gets called. We only take notice if it's
408 +         * us getting kicked, and then we'll rejoin
409 +         * the channel after a short wait.
410 +         *
411 +         * @param channel the channel the kick happened on
412 +         * @param kickerNick the person who performed the kick
413 +         * @param kickerLogin the login of the person who performed the kick
414 +         * @param kickerHostname the hostname of the person who performed the kick
415 +         * @param recipientNick the nickname of the person being kicked
416 +         * @param reason the reason for the kick
417 +         */
418          public void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason) {
419              if(recipientNick.equals(_nickname) && channel.equals(_channel)) {
420 +                // remind the person it's not very nice :)
421                  sendMessage(kickerNick, "That wasn't a nice thing to do...");
422 +                // get hold of the channel details, in case they've changed
423                  try {
424                      _channel = ConfigurationProxy.getInstance().getProperty(_name, "Alerter.IRC.channel");
425                  } catch(PropertyNotFoundException e) {
426 <                    _logger.write(this.toString(), Logger.ERROR, "Configuration error: "+e);
426 >                    _logger.write(this.toString(), Logger.ERROR, "Can't get channel name due to configuration error: "+e);
427                  }
428 <                // should this be in the try?
428 >                // wait for a while, defined in the config
429 >                reconnectSleep();
430 >                // we'll try and rejoin the channel regardless
431 >                // otherwise we might end up doing nothing!
432                  joinChannel(_channel);
433              }
434          }
435          
436 +        /**
437 +         * This method handles input directed to us, and
438 +         * responds accordingly if required.
439 +         *
440 +         * nb. matching user input is quite bad right now,
441 +         *     and should be improved one day.
442 +         *
443 +         * @param message the message from someone
444 +         * @param source where the message came from, so we know where to send the response
445 +         */
446          private void handleInput(String message, String source) {
447 <            System.out.println("message: "+message);
346 <            System.out.println("from: "+source);
447 >            // get hold of the configuration system
448              ConfigurationProxy cp = ConfigurationProxy.getInstance();
449              // setup some String's
450              String stopCommand, startCommand, timeSinceLastAlertCommand, lastAlertCommand, joinCommand;
451              String nickChangeCommand, versionCommand, helpCommand, statCommand, uptimeCommand;
452 <            // get the command set
452 >            // get the command set from the configuration
453              try {
454                  stopCommand = cp.getProperty(_name, "Alerter.IRC.stopCommand");
455                  startCommand = cp.getProperty(_name, "Alerter.IRC.startCommand");
# Line 367 | Line 468 | public class IRC__Alerter extends AlerterSkeleton {
468                  return;
469              }
470              
471 +            // see if the message matches (loosely!) any
472 +            // of our known commands
473              if(message.indexOf(stopCommand) != -1) {
474                  _active = false;
475                  sendMessage(source, "alerts have been stopped");
# Line 375 | Line 478 | public class IRC__Alerter extends AlerterSkeleton {
478                  _active = true;
479                  sendMessage(source, "alerts have been activated");
480              }
481 <            // this needs to go here if it contains the same words as the lastAlertCommand
481 >            // this needs to go before lastAlertCommand if it contains
482 >            // the same words as the lastAlertCommand.
483              else if(message.indexOf(timeSinceLastAlertCommand) != -1) {
484                  if(_lastAlertTime != -1) {
485                      long uptime = (System.currentTimeMillis() - _lastAlertTime) / 1000;
# Line 410 | Line 514 | public class IRC__Alerter extends AlerterSkeleton {
514                      partChannel(_channel);
515                      joinChannel(newChan);
516                      _channel = newChan;
413                    //return null; // ???
517                  }
518              }
519              else if(message.indexOf(nickChangeCommand) != -1) {
# Line 422 | Line 525 | public class IRC__Alerter extends AlerterSkeleton {
525                  }
526                  newNick = newNick.substring(0, endOfNick);
527                  changeNick(newNick);
425                // should we check this worked?
426                //_nickname = newNick;
427                //return null; // ???
528              }
529              else if(message.indexOf(versionCommand) != -1) {
530                  sendMessage(source, "I am version "+REVISION.substring(11, REVISION.length() -2)+" of the i-scream alerting bot");
531              }
532              else if(message.indexOf(helpCommand) != -1) {
433                //System.out.println("--starting help");
533                  sendMessage(source, "Hello, I am the i-scream alerting bot version "+REVISION.substring(11, REVISION.length() -2));
534                  sendMessage(source, "I understand the following commands;");
535                  sendMessage(source, stopCommand);
# Line 442 | Line 541 | public class IRC__Alerter extends AlerterSkeleton {
541                  sendMessage(source, uptimeCommand);
542                  sendMessage(source, timeSinceLastAlertCommand);
543                  sendMessage(source, helpCommand);
445                //System.out.println("--ending help");
544              }
545              else if(message.indexOf(statCommand) != -1) {
546                  sendMessage(source, "I have sent a total of "+_alertCount+" alerts, and ignored a total of "+_ignoredCount+"!");
# Line 459 | Line 557 | public class IRC__Alerter extends AlerterSkeleton {
557                  // little joke :)
558                  sendAction(source, "jives to the funky beat shouting \"ii--screeeaaammm\"");
559              }
462            
560              else {
561                  String rejectMessage = NOT_CONFIGURED;
562                  try {
# Line 471 | Line 568 | public class IRC__Alerter extends AlerterSkeleton {
568              }
569          }
570          
571 +        /**
572 +         * Quick method to check if the message appears
573 +         * to be directed at us. We simply check to see
574 +         * if it starts with our nick in some fashion.
575 +         *
576 +         * @param message the message to check
577 +         * @return if the message is for us
578 +         */
579          private boolean isForMe(String message) {
475            // change this!
580              String nick = _nickname.toLowerCase();
581              String msg = message.toLowerCase();
582              if(msg.startsWith(nick + ", ") ||
# Line 485 | Line 589 | public class IRC__Alerter extends AlerterSkeleton {
589              }
590          }
591          
592 +        /**
593 +         * Sleep for a configurable amount of time and
594 +         * then return. This is used when reconnecting
595 +         * to the server or a channel.
596 +         */
597          private void reconnectSleep() {
598              int delayTime = 0;
599              try {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines