package irc.bot.simplePircs; import org.jibble.pircbot.*; import javax.swing.*; import java.util.*; import java.util.Timer; import java.io.*; public class iKitty extends PircBot { // Our global variables. Used later to ban/unban someone. private Timer unbanTimer; private TimerUnbanTask unbanTask = new TimerUnbanTask(); // This will later help us rejoin if we get disconnected. private ReconnectHandler handler; // This is a list of channels that we were on, so we can rejoin them. public ArrayList channels = new ArrayList(); // The main bot constructor. public iKitty() { // Set our default nick. this.setName("iKitty"); // Set what shows up before the @ in our host name. this.setLogin("iKitty"); // Just in case we get sent a CTCP "FINGER" request. (More for fun than needed) this.setFinger("Don't point that finger at me!"); // This tells PircBot to change our name, if there is a conflict. // Beter than handeling it ourself. this.setAutoNickChange(true); // Not sure... sendMessage("nickserv", "identify Kitty_Cat"); // Housekeeping: Register our bot withteh task. this.unbanTask.setBot(this); } // This is called when we disconnect from the server. public void onDisconnect() { // Re name ourselves in case it was changed earleir, due to conflict. this.setName("iKitty"); sendMessage("nickserv", "identify Kitty_Cat"); // Create an object that will take car of readding us to the servers and channels. this.handler = new ReconnectHandler(this); } // This is called when anyone joins... including ourself!!?? (yes, it does...) public void onJoin(String channel, String sender, String login, String hostname) { // We only want to change ourself. if (sender.equalsIgnoreCase(this.getNick())) { // Close any reconnnect timers/objects. this.handler.close(); this.handler = null; // Add the new channel. this.channels.add(channel); // Give us the modes we are entitled to. setMode(getNick(), "+T"); setMode(getNick(), "+p"); setMode(getNick(), "+B"); } } // Anytime someone sends a normal message (not private), this method it called. public void onMessage(String channel, String sender, String login, String hostname, String message, String hostmask) { // Make all the same case. Remove inconsistencies. message = message.toLowerCase(); // Check for annoying mesages. if (message.contains("playing") && this.musicExtension(message)) { // Make sure that they can't talk on this channel for at least a minute. // "Nice" way to give them a hint. ban(channel, hostmask); kick(channel, sender, "The mp3 script isn't welcome. Turn it off. Your ban will be removed in 1 minute"); // Tell our handler what to allow again. this.unbanTask.setInfo(channel, hostmask); // Start their timer. this.unbanTimer = new Timer(); this.unbanTimer.schedule(unbanTask, 60 * 1000, 0); } } // private boolean musicExtension(String string) { boolean hasExt = false; // Store all the possible extensions. More can be added. ArrayList extensions = new ArrayList(); extensions.add("mp3"); extensions.add("wav"); // Loops through and check them all. for(int i = 0; i < extensions.size(); i++) { // Did we find the extension? if(string.contains(extensions.get(i))) { // Mark true, and don't bother checking the rest. hasExt = true; break; } } // Return if we found it or not. return hasExt; } } // This is what is fired when the timer is up. class TimerUnbanTask extends TimerTask { // Teh data we need to undo our ban. private String channel = ""; private String hostmask = ""; // The bot we are doing this for. private iKitty bot; // Default constructor. Doesn't do anything. public TimerUnbanTask() {} // Set the info at creation. public TimerUnbanTask(String channel, String hostmask) { this.setInfo(channel, hostmask); } // Set the info at creation, including the bot. public TimerUnbanTask(String channel, String hostmask, iKitty bot) { this.setInfo(channel, hostmask); this.setBot(bot); } // Set the info after the object has been created. public void setInfo(String channel, String hostmask) { this.channel = channel; this.hostmask = hostmask; } // Register a new bot. public void setBot(iKitty bot) { this.bot = bot; } // Unban the individual. public void run() { this.bot.unBan(this.channel, this.hostmask); } } class ReconnectHandler extends TimerTask { // This is how many times we try to reconnect before giving up. private final int totalTries = 20; private int currentTries = 0; // This is the bot we are trying to reconnect. private iKitty bot; // Attempt a reconnect every 30 seconds. Timer timer = new Timer(); public ReconnectHandler(iKitty bot) { this.bot = bot; this.timer.schedule(this, 0, 30 * 1000); } // Close the timer, so this can be garbage collected. public void close() { this.timer.cancel(); } // What do we do? public void run() { try { System.out.println("Attempting to connect again."); // Join the server we were disconnected from. this.bot.reconnect(); // Try to rejoin all of our previous channels. for(int i = 0; i < bot.channels.size(); i++) { bot.joinChannel(bot.channels.get(i)); } } catch(IrcException e) { // Not untill all tries have been exhausted. if(this.currentTries == this.totalTries) { // Allow us to be garbage collected. this.timer.cancel(); // Report to user, and exit. JOptionPane.showMessageDialog(null, "We could not reconnect in " + this.totalTries + ".\nThe bot will now close."); System.exit(0); } } catch(IOException E) { // Not sure what to do, so ... this.timer.cancel(); System.out.println(E); } finally { // Try again. this.currentTries++; } } }