O'Reilly Hacks
oreilly.comO'Reilly NetworkSafari BookshelfConferences Sign In/My Account | View Cart   
Book List Learning Lab PDFs O'Reilly Gear Newsletters Press Room Jobs  


 
Buy the book!
IRC Hacks
By Paul Mutton
July 2004
More Info

HACK
#68
Link Channels on Multiple Networks
How do you encourage a community on one network to talk to those on another network? Create a bot that can relay messages between the networks
The Code
[Discuss (0) | Link to this hack]

The Code

This hack will use the PircBot IRC API to connect to each IRC network. Each connection will be dealt with by its own PircBot subclass, with a single Controller class being used to pass on messages to the other connections. The Controller is essentially a collection of separate IRC bots and is used to link them together.

Each bot just has to listen for messages and pass them on to the Controller, so there is not too much code to write. Save the following as ChannelLinkBot.java:

import org.jibble.pircbot.*;

public class ChannelLinkBot extends PircBot {
    
    // This is the Controller that we will pass messages to.
    private Controller controller;
    
    public ChannelLinkBot(Controller c, String server) throws Exception {
        controller = c;
        setName("MyLinkBot");
        setVerbose(true);
        connect(server);
    }
    
    public void onMessage(String channel, String sender,
            String login, String hostname, String message) {
        
        // Pass the message on to the Controller.
        controller.shareMessage(this, Colors.BOLD + "<" + sender + "> " +
                Colors.NORMAL + message);
    }
    
}

As you can see from this code, whenever one of the bots receives a message, it shares that message with the Controller. Each bot is passed a reference to the Controller in its constructor, along with the name of the server to connect to.

All the Controller needs to do is maintain a list of all of its bots and allow each of those bots to send messages to all the other bots. A LinkedList is used to store the collection of bots.

Save the following as Controller.java:

import java.util.*;

public class Controller {
    
    private LinkedList bots = new LinkedList( );
    private String channel;
    
    public Controller(String channel) {
        this.channel = channel;
    }
    
    // Add a new bot to the list and make it join the channel.
    public synchronized void add(ChannelLinkBot bot) {
        bot.joinChannel(channel);
        bots.add(bot);
    }
    
    // Share a message with all other networks.
    public synchronized void shareMessage(ChannelLinkBot from, String message) {
        Iterator it = bots.iterator( );
        while (it.hasNext( )) {
            ChannelLinkBot bot = (ChannelLinkBot) it.next( );
            if (bot != from) {
                bot.sendMessage(channel, message);
            }
        }
    }
    
}

The add method in the Controller is used to add a new bot to the LinkedList. Each time a new bot is added, it is told to join the same channel. Note that this method is synchronized, so it is safe to add new bots while the program is running.

The shareMessage method can be called by each of the bots and the Controller then iterates through the list of bots and tells each bot to send that message to its network. The bot that called this method must not be told to send the message; otherwise, it will simply end up repeating everything that is said on its network.

The main method of this program must create a Controller object and add a bot for each network it will connect to. You can supply these arguments through the command line.

Save the following as ChannelLinkBotMain.java:

public class ChannelLinkBotMain {
    
    public static void main(String[] args) {
        String channel = args[0];
        Controller controller = new Controller(channel);
        
        for (int i = 1; i < args.length; i++) {
            try {
                ChannelLinkBot bot = new ChannelLinkBot(controller, args[i]);
                controller.add(bot);
            }
            catch (Exception e) {
                System.out.println("Could not add a bot: " + e);
            }
        }
    }
    
}


O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.