package ircbotgui;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.List;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.lang.reflect.Method;
import java.util.Random;
/**
* @author Malte
*/
public class BorBot extends BaseBot{
//Password is *snip*
public boolean fooneticBotFlag = false; //Set mode +b on foonetic?
public boolean borBotIdent = false; //Identified if using nick BorBot?
public String version = "v0.3"; //Current version
public String owner = "Boreeas"; //Whoose bot it is
public String pw = "*snip*"; //Password
public String prefix = "-"; //Command prefix: -time
public String prefixPriv = ">"; //Command prefix 2 for privately send commands: ->Boreeas time
private String[] sendable = {"random"}; //Sendable Commands
private String[] unsendable = {"addrandom"}; //Unsendable Commands
private boolean isPrivate = false; //Will the command be sent to user or channel
private String[] cmdArgs; //Command and arguments
public String user, channel, lastSent; //Connecction control variables
String t = "\t", n = "\n", r = "\r", rn = "\r\n"; //tabs, newlines
List rand;
Random random = new Random();
BufferedReader rd;
BufferedWriter w;
public BorBot() {
try {
rd = new BufferedReader(new InputStreamReader(new FileInputStream(System.getProperty("user.dir") + "/src/ircbotgui/rand.txt")));
w = new BufferedWriter(new FileWriter(System.getProperty("user.dir") + "/src/ircbotgui/rand.txt"));
while (true) {
String line;
if ((line = rd.readLine()) != null) {
rand.add(line);
}
else {
break;
}
}
} catch (FileNotFoundException ex) {
gui.logError(ex);
} catch (java.io.IOException ioe) {
gui.logError(ioe);
}
}
@Override
public void read(){
try {
while (true) {
String line;
if ((line = reader.readLine()) != null) {
gui.appendRaw(line);
String[] results = parse(line); //0 = Sender, 1 = Message [, 2 = Channel]
updateInformation(results);
checkForServerCommands(results);
if (results[1].startsWith(prefix)) {
if (results[1].startsWith(prefixPriv, 1)) {
results[1] = results[1].substring(2);
checkForSendableCommands(results, true);
}
else {
results[1] = results[1].substring(1);
checkForUnsendableCommands(results);
checkForSendableCommands(results, false);
}
}
}
else{
break;
}
writer.flush();
}
} catch (IOException e) {
gui.logError(e);
}
}
@Override
//Append messages, etc
public void updateInformation(String[] args) throws IOException{
//Append to Server
if(args[0].equalsIgnoreCase("PING")) {
gui.appendServer("PING:" + args[1] + rn + "PONG:" + args[1]);
}
else if(args[0].substring(args[0].indexOf(".") + 1).equalsIgnoreCase(server.substring(server.indexOf(".") + 1))) {
gui.appendServer(args[0]+":"+t+t+args[1]);
}
//Append to channel, update control variables
else if(args.length > 2) {
user = args[0];
channel = args[2];
lastSent = args[1];
gui.appendChan("[" + gui.getTime("mm:ss") + "][" + channel + "] " + user + ": \t\t"+ lastSent);
}
}
@Override
//Commands not issued by persons, e.g. PING
public void checkForServerCommands(String[] args) throws IOException{
//PING
if(args[0].equalsIgnoreCase("PING")) {
writer.write("PONG :"+args[1]+rn);
}
//Foonetic Bot Flag
if(args[0].contains("foonetic")) { //Foonetic asks for a +B flag to indicate Bots
if (!fooneticBotFlag) {
gui.appendSys("Setting mode +b");
fooneticBotFlag = true;
}
}
}
@Override
//Commands that don' require a reply, e.g. disconnect
public void checkForUnsendableCommands(String[] args) throws IOException{
cmdArgs = args[1].split(" ", 1); //0 = recipient, 1 = command 2+ = args. If not priv, recipient does not appear, all indices -1
String cmd = cmdArgs[0];
boolean inList = false;
for (int i = 0; i < unsendable.length; i++) {
if (unsendable[i].equalsIgnoreCase(cmd)) {
inList = true;
}
}
Method[] m = BorBot.class.getMethods();
for (int i = 0; i < m.length; i++) {
if (m[i].getName().equalsIgnoreCase(cmd) && inList) {
try {
m[i].invoke(this);
} catch (IllegalAccessException ex) {
gui.logError(ex);
} catch (InvocationTargetException ex) {
gui.logError(ex);
} catch (IllegalArgumentException ex) {
gui.logError(ex);
}
}
}
}
@Override
//Commands that require a reply, e.g. time
public void checkForSendableCommands(String[] args, boolean priv) throws IOException{
isPrivate = priv;
int index = 1;
if (priv) {
index += 1;
}
cmdArgs = args[1].split(" ", index); //0 = recipient, 1 = command 2+ = args. If not priv, recipient does not appear, all indices -1
String cmd = cmdArgs[index - 1];
boolean inList = false;
for (int i = 0; i < sendable.length; i++) {
if (sendable[i].equalsIgnoreCase(cmd)) {
inList = true;
}
}
Method[] m = BorBot.class.getMethods();
for (int i = 0; i < m.length; i++) {
if (m[i].getName().equalsIgnoreCase(cmd) && inList) {
try {
gui.appendParseDebug("Invoking command: " + cmd);
m[i].invoke(this);
System.out.println("Invoking succesful");
} catch (IllegalAccessException ex) {
System.out.println("Got exception Access");
gui.logError(ex);
} catch (InvocationTargetException ex) {
System.out.println("Got exception Invocation Target");
System.out.println(ex.getTargetException());
gui.logError(ex);
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
}
}
}
}
@Override
public String[] parse(String line) {
//Remove leading ":"
if(line.startsWith(":")) {
line = line.substring(1);
}
//This can either be PING, the server, or the user
//If it contains an '@', it is a user - user will be parsed
String userLoc = line.substring(0, line.indexOf(" "));
if (userLoc.contains("@")) {
userLoc = userLoc.substring(0, userLoc.indexOf("!"));
}
//Channel will be parsed by the '#', and only if the line does not start with a server name
//JOINS/PARTS will be caught and ignored as well as a few lines from the server that would lead to an exception
String channel = null;
try {
String garbage = line.substring(0, line.indexOf(":"));
if (line.contains("#") && !(line.substring(line.indexOf(".")).startsWith(server.substring(server.indexOf("."))))) {
int index = line.indexOf("#");
String tempStr = line.substring(index);
gui.appendParseDebug("Got temporary channel string: " + tempStr);
channel = tempStr.substring(0, tempStr.indexOf(" "));
}
} catch (StringIndexOutOfBoundsException oobe) {
}
//This is the actuall message, starting after the ':' in the line
String message = line.substring(line.indexOf(":") + 1).trim();
//Since there might be no channel, channel cannot be appended
String parseOut = "User: " + userLoc + t + t + "Message: " + message;
gui.appendParseDebug(parseOut);
//Returning the variables
String[] temp;
if (channel != null) {
String[] temp2 = {userLoc, message, channel};
temp = temp2.clone();
}
else {
String[] temp2 = {userLoc, message};
temp = temp2.clone();
}
return temp;
}
public void say(String message, String recipient) {
try {
writer.write("PRIVMSG " + recipient + " :" + message + rn);
writer.flush();
} catch (IOException ex) {
gui.logError(ex);
}
}
public void random() {
System.out.println("Command random triggered");
String message = (String)rand.get(random.nextInt(rand.size()));
if (isPrivate) {
say(message, (cmdArgs[1]));
}
else {
say(message, channel);
}
}
public void addrandom() {
try {
w.write(cmdArgs[1] + n);
w.flush();
} catch (IOException ex) {
gui.logError(ex);
}
}
}