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");
// 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) {
// Check for annoying mesages.
if(message.startsWith("Playing: [") && message.endsWith(".mp3 ]")) {
// 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);
}
}
}
// 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( (String) 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++;
}
}
}