package com.briman0094.bribot;
import java.io.IOException;
import java.io.PrintStream;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.util.Stack;
import com.briman0094.bribot.modules.IModule;
import com.briman0094.irc.IRCConnection;
import com.briman0094.irc.IReadHandler;
import com.briman0094.irc.MessageType;
public class BriBot implements IReadHandler
{
public static final String USERNAME = "BriBot";
public static final String IDENT = "BriBot";
public static final String USERMODE = "0";
public static final String REALNAME = "Briman Bot";
public static final String COMMAND_PREFIX = "$";
public static final String OWNER_UN = "Briman";
public static final String VERSION = "0.2a";
/** Connection timeout in seconds */
public static final int CONNECT_TIMEOUT = 10;
public static final String DEFAULT_SERVER_IP = "irc.esper.net";
public static final int DEFAULT_SERVER_PORT = 6667;
public static final String DEFAULT_SERVER_PASS = "";
public static final String DEFAULT_CHANNELS = "#BrimansMods;#ccbots";
private IRCConnection irc;
private PrintStream out;
private String curChannel;
private ArrayList<String> joinedChannels;
private HashMap<String, IModule> registeredModules;
private String username;
public BriBot(String server, int port, PrintStream out) throws UnknownHostException, IOException
{
irc = new IRCConnection(server, port);
irc.setReadHandler(this);
irc.setDebug(false);
this.out = out;
curChannel = null;
joinedChannels = new ArrayList<String>();
registeredModules = new HashMap<String, IModule>();
username = USERNAME;
int timeout = 0;
while (!irc.isConnected())
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
timeout++;
if (timeout >= CONNECT_TIMEOUT)
{
System.exit(1);
}
}
authenticate();
identify();
}
public BriBot(String server, int port) throws UnknownHostException, IOException
{
this(server, port, System.out);
}
public BriBot(PrintStream out) throws UnknownHostException, IOException
{
this(DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT, out);
}
public BriBot() throws UnknownHostException, IOException
{
this(DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT, System.out);
}
private void authenticate()
{
irc.sendMessage(MessageType.PASS, new String[] { DEFAULT_SERVER_PASS });
irc.sendMessage(MessageType.USER, new String[] { IDENT, USERMODE, "*", ":" + REALNAME });
}
private void identify()
{
irc.sendMessage(MessageType.NICK, new String[] { getUsername() });
}
public void registerModule(String name, IModule module)
{
registeredModules.put(name, module);
module.setBotInstance(this);
}
public Set<String> getLoadedModules()
{
return registeredModules.keySet();
}
public boolean isConnected()
{
return irc.isConnected();
}
public String getUsername()
{
return username;
}
@Override
public void receiveMessage(MessageType type, String user, String channel, String[] args)
{
switch (type)
{
case ACTION:
{
String action = "";
for (int i = 0; i < args.length; i++)
{
action += (i == 0) ? args[i] : (" " + args[i]);
}
handleAction(channel, user, action);
break;
}
case MESSAGE:
{
String message = "";
for (int i = 0; i < args.length; i++)
{
message += (i == 0) ? args[i] : (" " + args[i]);
}
handleMessage(channel, user, message);
break;
}
case NOTICE:
{
String notice = "";
for (int i = 0; i < args.length; i++)
{
notice += (i == 0) ? args[i] : (" " + args[i]);
}
handleNotice(channel, user, notice);
break;
}
case KICK:
{
if (args.length >= 2)
{
String fromChan = args[0];
String kickedUser = args[1];
String reason = "No reason given";
if (args.length >= 3)
reason = args[2];
if (kickedUser.equalsIgnoreCase(getUsername()))
{
joinedChannels.remove(fromChan);
if (fromChan.equalsIgnoreCase(curChannel))
curChannel = null;
log("Kicked from " + fromChan + ": " + reason);
}
}
break;
}
case NICK:
{
if (args.length > 0)
{
if (user.equalsIgnoreCase(getUsername()))
{
if (args[0].startsWith(":"))
args[0] = args[0].substring(1);
username = args[0];
}
}
break;
}
case INVITE:
{
if (args.length == 1)
{
joinChannel(args[0]);
try
{
Thread.sleep(250);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
sendToChannel(args[0], "Hi " + user + "!");
}
break;
}
case WELCOME:
{
identify();
sendRawMessage(MessageType.NOTICE, new String[] { OWNER_UN, ":I'm alive!" });
String[] chans = DEFAULT_CHANNELS.split(";");
for (String chan : chans)
{
joinChannel(chan);
}
break;
}
case PASS_REQUIRED:
{
authenticate();
}
default:
break;
}
}
private void handleAction(String channel, String from, String message)
{
if (channel.equalsIgnoreCase(getUsername()))
channel = from;
for (IModule module : registeredModules.values())
{
module.handleChatAction(channel, from, message);
}
out.println(String.format("[%s] %s %s", channel, from, message));
}
private void handleNotice(String to, String from, String message)
{
if (to.equalsIgnoreCase("AUTH"))
{
authenticate();
}
else
{
for (IModule module : registeredModules.values())
{
module.handleChatNotice(from, message);
}
out.println(String.format("[%s] -%s- %s", to, from, message));
}
}
private void handleMessage(String channel, String from, String message)
{
if (channel.equalsIgnoreCase(getUsername()))
channel = from;
if (message.equals("VERSION"))
{
sendRawMessage(MessageType.NOTICE, new String[] { from, ":I am BriBot version " + VERSION });
}
else
{
for (IModule module : registeredModules.values())
{
module.handleChatMessage(channel, from, message);
}
out.println(String.format("[%s] <%s> %s", channel, from, message));
}
}
public void handleInput(String message)
{
if (message.startsWith("/"))
{
handleMessage(getUsername(), getUsername(), message.replace("/", COMMAND_PREFIX));
}
else
{
if (curChannel != null)
sendToChannel(curChannel, message);
else
{
out.println("Not talking in a channel");
}
}
}
public void sendRawMessage(MessageType type, String[] args)
{
irc.sendMessage(type, args);
}
public void sendToChannel(String channel, String message)
{
if (channel.startsWith("#"))
irc.sendMessage(MessageType.MESSAGE, new String[] { channel, ":" + message });
else
noticeUser(channel, message);
}
public void noticeUser(String user, String message)
{
irc.sendMessage(MessageType.NOTICE, new String[] { user, ":" + message });
}
public void sendToUser(String user, String message)
{
irc.sendMessage(MessageType.MESSAGE, new String[] { user, ":" + message });
}
public void disconnect() throws IOException
{
irc.disconnect();
}
public void joinChannel(String channel)
{
irc.sendMessage(MessageType.JOIN, new String[] { channel });
if (!joinedChannels.contains(channel))
joinedChannels.add(channel);
curChannel = channel;
}
public void partChannel(String channel)
{
irc.sendMessage(MessageType.PART, new String[] { channel });
joinedChannels.remove(channel);
if (channel.equalsIgnoreCase(curChannel))
curChannel = null;
}
public IRCConnection getIRCConnection()
{
return irc;
}
public String getCurrentChannel()
{
return curChannel;
}
public void log(String message)
{
out.println(message);
}
}