diff --git a/.gitignore b/.gitignore index 96b49a04..64ccb20d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /nbproject/private/ /build/ -#/dist/ -#/dist/JRobo.jar +/dist/ /src/jrobo/thepiratebay.php +.*.swo +.*.swp diff --git a/dist/JRobo.jar b/dist/JRobo.jar deleted file mode 100644 index 8e2bd41e..00000000 Binary files a/dist/JRobo.jar and /dev/null differ diff --git a/lib/dom4j-1.6.jar b/lib/dom4j-1.6.jar new file mode 100644 index 00000000..e19f4ce8 Binary files /dev/null and b/lib/dom4j-1.6.jar differ diff --git a/lib/google-collections-1.0.jar b/lib/google-collections-1.0.jar new file mode 100644 index 00000000..8e394fac Binary files /dev/null and b/lib/google-collections-1.0.jar differ diff --git a/lib/javassist-3.8.0.GA.jar b/lib/javassist-3.8.0.GA.jar new file mode 100644 index 00000000..1fa8dbf4 Binary files /dev/null and b/lib/javassist-3.8.0.GA.jar differ diff --git a/lib/nlog4j-1.2.25.jar b/lib/nlog4j-1.2.25.jar new file mode 100644 index 00000000..e398699b Binary files /dev/null and b/lib/nlog4j-1.2.25.jar differ diff --git a/lib/reflections-0.9.5-RC2.jar b/lib/reflections-0.9.5-RC2.jar new file mode 100644 index 00000000..cc7511d7 Binary files /dev/null and b/lib/reflections-0.9.5-RC2.jar differ diff --git a/lib/slf4j-api-1.5.6.jar b/lib/slf4j-api-1.5.6.jar new file mode 100644 index 00000000..d7942523 Binary files /dev/null and b/lib/slf4j-api-1.5.6.jar differ diff --git a/nbproject/project.properties b/nbproject/project.properties index 44871b76..fe4b4ea5 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -1,88 +1,100 @@ -annotation.processing.enabled=true -annotation.processing.enabled.in.editor=false -annotation.processing.processors.list= -annotation.processing.run.all.processors=true -annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output -application.title=JRobo -application.vendor=TESLA -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.test.classpath=\ - ${run.test.classpath} -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/JRobo.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -excludes= -file.reference.gson-2.2.2.jar=lib/gson-2.2.2.jar -includes=** -jar.archive.disabled=${jnlp.enabled} -jar.compress=false -jar.index=${jnlp.enabled} -javac.classpath=\ - ${file.reference.gson-2.2.2.jar} -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.processorpath=\ - ${javac.classpath} -javac.source=1.7 -javac.target=1.7 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -javac.test.processorpath=\ - ${javac.test.classpath} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.reference.gson-2.2.2.jar=lib/gson-2.2.2-javadoc.jar -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle= -jnlp.codebase.type=no.codebase -jnlp.descriptor=application -jnlp.enabled=false -jnlp.mixed.code=default -jnlp.offline-allowed=false -jnlp.signed=false -jnlp.signing= -jnlp.signing.alias= -jnlp.signing.keystore= -main.class=jrobo.JRobo -manifest.file=manifest.mf -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=false -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project. -# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. -# To set system properties for unit tests define test-sys-prop.name=value: -run.jvmargs= -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -source.encoding=UTF-8 -source.reference.gson-2.2.2.jar=lib/gson-2.2.2-sources.jar -src.dir=src -test.src.dir=test +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=JRobo +application.vendor=TESLA +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/JRobo.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.dom4j-1.6.jar=lib/dom4j-1.6.jar +file.reference.google-collections-1.0.jar=lib/google-collections-1.0.jar +file.reference.gson-2.2.2.jar=lib/gson-2.2.2.jar +file.reference.javassist-3.8.0.GA.jar=lib/javassist-3.8.0.GA.jar +file.reference.nlog4j-1.2.25.jar=lib/nlog4j-1.2.25.jar +file.reference.reflections-0.9.5-RC2.jar=lib/reflections-0.9.5-RC2.jar +file.reference.slf4j-api-1.5.6.jar=lib/slf4j-api-1.5.6.jar +includes=** +jar.archive.disabled=${jnlp.enabled} +jar.compress=false +jar.index=${jnlp.enabled} +javac.classpath=\ + ${file.reference.gson-2.2.2.jar}:\ + ${file.reference.google-collections-1.0.jar}:\ + ${file.reference.dom4j-1.6.jar}:\ + ${file.reference.javassist-3.8.0.GA.jar}:\ + ${file.reference.nlog4j-1.2.25.jar}:\ + ${file.reference.reflections-0.9.5-RC2.jar}:\ + ${file.reference.slf4j-api-1.5.6.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.7 +javac.target=1.7 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.reference.gson-2.2.2.jar=lib/gson-2.2.2-javadoc.jar +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +jnlp.codebase.type=no.codebase +jnlp.descriptor=application +jnlp.enabled=false +jnlp.mixed.code=default +jnlp.offline-allowed=false +jnlp.signed=false +jnlp.signing= +jnlp.signing.alias= +jnlp.signing.keystore= +main.class=jrobo.JRobo +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +source.reference.gson-2.2.2.jar=lib/gson-2.2.2-sources.jar +src.dir=src +test.src.dir=test diff --git a/src/jrobo/BotCommand.java b/src/jrobo/BotCommand.java deleted file mode 100644 index cd663f24..00000000 --- a/src/jrobo/BotCommand.java +++ /dev/null @@ -1,811 +0,0 @@ -/* - * JRobo - An Advanced IRC Bot written in Java - * - * Copyright (C) <2013> - * Copyright (C) <2013> - * Copyright (C) <2013> - * Copyright (C) <2013> - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -//TODO javadoc all -// http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html -package jrobo; - -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.Timer; -import java.util.TimerTask; - -/** - * - * @author bullshark - */ -public class BotCommand { - - private final Networking connection; - private final Config config; - private JRobo jRobo; - private String user; - private String bombHolder; - private String cmd; - private String cmdArgs; - private boolean hasArgs; - private ListColors lc; - private boolean threadCreated; - private boolean bombActive; - private boolean[] wire = new boolean[3]; - - /** - * - * @param connection - * @param reader - * @param jRobo - */ - public BotCommand(Networking connection, Config config, JRobo jRobo) { - /* Objects */ - this.connection = connection; - this.config = config; - this.jRobo = jRobo; - - /* Cmds */ - cmd = ""; - cmdArgs = ""; - hasArgs = false; - - /* Misc */ - lc = new ListColors(); - threadCreated = false; - - } - - /* - * This is called when a bot command is received - * - * user is the user who sent the command - * fullCmd includes the SYMB, command, and args - */ - public void bCommander(String user, String fullCmd) { - this.user = user; - cmd = getCmd(fullCmd); - cmdArgs = getCmdArgs(fullCmd); - hasArgs = cmdArgs.isEmpty() ? false : true; - - switch (cmd) { - case "wakeroom": /* Requires no args */ - case "wr": - wakeRoomHelper(); - break; - case "google": - case "g": - case "lmgtfy": - case "stfw": /* Show The Fucking World */ - googleHelper(); - break; - case "goto": - case "join": - moveToChannelHelper(); - case "greet": - greetHelper(); - break; - case "weather": - case "w": - weatherHelper(); - break; - case "mum": - case "m": - mumHelper(); - break; - case "next": - nextHelper(); - break; - case "invite-nick": - case "in": - inviteNickHelper(); - break; - case "invite-channel": - case "ic": - inviteChannelHelper(); - break; - case "raw": - case "r": - rawHelper(); - break; - case "urbandict": - case "ud": - urbanDictionaryHelper(); - break; - case "quit": - case "q": - quitHelper(); - break; - case ".": - case "..": - case "-.": - doNothingHelper(); - break; - case "list": - case "l": - listHelper(); - break; - case "help": - case "h": - helpHelper(); - break; - case "pirate": - pirateHelper(); - break; - case "isup": - isUpHelper(); - break; - case "version": - versionHelper(); - break; - case "driveby": - case "db": - driveBy(); - break; - case "bomb": - bomb(); - break; - case "pass": - pass(); - break; - case "defuse": - defuse(); - break; - default: - unknownCmdHelper(); - //@TODO Accept raw irc commands from bot owner to be sent by the bot - //@TODO Search for bots on irc and watch their behavior for ideas such as WifiHelper in #aircrack-ng - } // EOF switch - } // EOF function - - /* - * Puts together a String in the form - * test+a+b+c - * From fullCmd - * - * Takes a string and manipulates it - * By removing all starting and ending - * Whitespace and then - * Replacing all other whitespace - * No matter the length of that whitespace - * With one '+' - * - * TODO JavaDocs - */ - private String getFormattedQuery(String str) { - return str.replaceAll("\\s++", "+"); - } - - /* - * TODO Javadocs - */ - private String getCmdArgs(String fullCmd) { - //@TODO divded half of the work getFormattedQuery is doing to here - try { - return fullCmd.split("\\" + config.getCmdSymb() + "[a-zA-Z_0-9\\-]++", 2)[1].trim(); - } catch (ArrayIndexOutOfBoundsException ex) { - Logger.getLogger(BotCommand.class.getName()).log(Level.SEVERE, null, ex); - return ""; /* Means no args!!! */ - } // EOF try-catch - } // EOF function - - /* - * TODO JavaDocs - */ - private String getCmd(String fullCmd) { - return fullCmd.substring(1).replaceFirst("\\s.*+", ""); - } - - /* - * TODO JavaDocs - */ - private String getRandChanUser() { - - /* - * TODO: getUsers.split() and choose random index - * rand fn returns number within 0 and len-1 of arr - * - * TODO: Use with ^mum that's supplied no args - */ - String[] usersList; - - usersList = getUsers().split("\\s++"); - - if (usersList != null) { - //TODO Needs testing - return usersList[(int) (Math.random() * usersList.length + 1)]; - } else { - return "ChanServ"; - } - /* - public boolean getRandomBoolean() { - return ((((int)(Math.random() * 10)) % 2) == 1); - } - */ - } - - /** - * Wrapper - * - * @return - */ - private String getUsers() { - return getUsers(config.getChannel()); - } - - /** - * - * @param chan - * @return - */ - private String getUsers(String chan) { - //TODO This method needs testing. It might be broke. - String received = "", users = ""; - String first = "", last = ""; - int tries = 8; - - connection.sendln("NAMES " + chan); - do { - received = connection.recieveln(); - try { - first = received.split(" :", 2)[0]; - last = received.split(" :", 2)[1]; - } catch (ArrayIndexOutOfBoundsException ex) { - first = ""; - last = ""; - } - if (first.contains("353")) { - try { - users += last.replaceAll("@|\\+|&|~|%", ""); - } catch (ArrayIndexOutOfBoundsException ex) { - Logger.getLogger(BotCommand.class.getName()).log(Level.SEVERE, null, ex); - } - } else if (first.equals("PING")) { - connection.sendln("PONG " + last); - } - tries--; - } while (tries > 0 && !first.contains("366")); - - if (users.equals("")) { - connection.msgMasters("Could not get list of users!!!"); - } - - return users; - } - - /* - * Helper methods - */ - private void wakeRoomHelper() { - String users = getUsers(); - if (users != null) { - connection.msgChannel(config.getChannel(), users); - } else { - connection.msgChannel(config.getChannel(), "Failed to get a list of users; Try again or notify the developer!"); - } - } - - /* - * Starts timer for bomb. - * Sets an active wire - * Prints explosion and kicks user holding at [20] seconds - */ - public void bomb() { - bombHolder = user; - connection.msgChannel(config.getChannel(), MircColors.BOLD + bombHolder + MircColors.WHITE + " started the bomb!!!"); - connection.msgChannel(config.getChannel(), MircColors.WHITE + "You can pass it to another user with >pass [nick]."); - connection.msgChannel(config.getChannel(), MircColors.WHITE + "You can attempt to defuse with >defuse [" + MircColors.RED + "R" + MircColors.GREEN + "G" + MircColors.BLUE + "B" + MircColors.WHITE + "-color]."); - bombActive = true; - wire[0] = false; - wire[1] = false; - wire[2] = false; - wire[(int) (3.0 * Math.random())] = true; - final Timer timer; - - timer = new Timer(); - - class BombTask extends TimerTask { - - public void run() { - if (!bombActive) { - timer.cancel(); - } else { - connection.msgChannel(config.getChannel(), MircColors.BROWN + " ,_=~~:-" + MircColors.YELLOW + ")" + MircColors.BROWN + ",, "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " (" + MircColors.BROWN + "==?,::,:::::" + MircColors.YELLOW + ")" + MircColors.BROWN + "=:=" + MircColors.YELLOW + ") "); - connection.msgChannel(config.getChannel(), MircColors.BROWN + " ?:=" + MircColors.YELLOW + "(" + MircColors.BROWN + ",~:::::::" + MircColors.YELLOW + ")" + MircColors.BROWN + "~+=:I" + MircColors.YELLOW + ") "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " (" + MircColors.BROWN + "=:" + MircColors.YELLOW + "(" + MircColors.BROWN + ",=:~++" + MircColors.YELLOW + "=:" + MircColors.BROWN + "::~,:~:" + MircColors.YELLOW + "))" + MircColors.BROWN + "~~~." + MircColors.YELLOW + ") "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " (" + MircColors.BROWN + "+~" + MircColors.YELLOW + "(" + MircColors.BROWN + ",:" + MircColors.YELLOW + "(==:" + MircColors.BROWN + ":~~+~~" + MircColors.YELLOW + ")" + MircColors.BROWN + ",$,I?" + MircColors.YELLOW + ")) "); - connection.msgChannel(config.getChannel(), MircColors.BROWN + " `` ```" + MircColors.YELLOW + "~~" + MircColors.BROWN + "?" + MircColors.YELLOW + "~=" + MircColors.BROWN + "$.~~~ `` "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " :" + MircColors.BROWN + "S" + MircColors.YELLOW + "Z= "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " .-~~" + MircColors.BROWN + "?=:=" + MircColors.YELLOW + "``~-_ "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " `--=~=+~++=~` "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " ." + MircColors.BROWN + "~" + MircColors.YELLOW + ":" + MircColors.BROWN + "~ "); - connection.msgChannel(config.getChannel(), MircColors.BROWN + " ((.(\\.!/.):?) "); - connection.msgChannel(config.getChannel(), MircColors.DARK_GREEN + " .?~:?.?7::,::::+,,~+~=:... "); - connection.kickFromChannel(config.getChannel(), user + " KABOOM!!!"); - bombActive = false; - timer.cancel(); - } - } - } - timer.schedule(new BombTask(), 20000); - } - - /* - * Simply passes the bomb to another user. - * Returns it if they attempt to pass to JRobo. - */ - private void pass() { - String users = getUsers(); - if (users.contains(cmdArgs) && !cmdArgs.equals("") && user.equals(bombHolder) && bombActive == true) { - bombHolder = cmdArgs; - connection.msgChannel(config.getChannel(), "The Bomb has been passed to " + bombHolder + "!!!"); - if (cmdArgs.equals(config.getName())) { - try { - Thread.sleep(2500); - } catch (Exception ex) { //Find out exactly what exceptions are thrown - //Logger.getLogger(BotCommand.class.getName()).log(Level.SEVERE, null, ex); - } - connection.msgChannel(config.getChannel(), ">pass " + user); - bombHolder = user; - connection.msgChannel(config.getChannel(), "The Bomb has been passed to " + bombHolder + "!!!"); - } - } else { - connection.msgChannel(config.getChannel(), "Invalid."); - } - } - - /* - * This function will return a wire for a given color. - * It is only to be used within defuse. - */ - private boolean wire(String color) { - switch (color) { - case "red": - return wire[0]; - case "green": - return wire[1]; - case "blue": - return wire[2]; - } - return false; - } - - /* - * This is the defuse method, refers to a global boolean array of wires. - * Ative wire is set to true in bomb() function. - */ - public void defuse() { - if (bombActive && user.equals(bombHolder)) { - if (wire(cmdArgs) == true) { - connection.msgChannel(config.getChannel(), MircColors.WHITE + "Bomb defused."); - bombActive = false; - } else { - connection.msgChannel(config.getChannel(), MircColors.BROWN + " ,_=~~:-" + MircColors.YELLOW + ")" + MircColors.BROWN + ",, "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " (" + MircColors.BROWN + "==?,::,:::::" + MircColors.YELLOW + ")" + MircColors.BROWN + "=:=" + MircColors.YELLOW + ") "); - connection.msgChannel(config.getChannel(), MircColors.BROWN + " ?:=" + MircColors.YELLOW + "(" + MircColors.BROWN + ",~:::::::" + MircColors.YELLOW + ")" + MircColors.BROWN + "~+=:I" + MircColors.YELLOW + ") "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " (" + MircColors.BROWN + "=:" + MircColors.YELLOW + "(" + MircColors.BROWN + ",=:~++" + MircColors.YELLOW + "=:" + MircColors.BROWN + "::~,:~:" + MircColors.YELLOW + "))" + MircColors.BROWN + "~~~." + MircColors.YELLOW + ") "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " (" + MircColors.BROWN + "+~" + MircColors.YELLOW + "(" + MircColors.BROWN + ",:" + MircColors.YELLOW + "(==:" + MircColors.BROWN + ":~~+~~" + MircColors.YELLOW + ")" + MircColors.BROWN + ",$,I?" + MircColors.YELLOW + ")) "); - connection.msgChannel(config.getChannel(), MircColors.BROWN + " `` ```" + MircColors.YELLOW + "~~" + MircColors.BROWN + "?" + MircColors.YELLOW + "~=" + MircColors.BROWN + "$.~~~ `` "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " :" + MircColors.BROWN + "S" + MircColors.YELLOW + "Z= "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " .-~~" + MircColors.BROWN + "?=:=" + MircColors.YELLOW + "``~-_ "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " `--=~=+~++=~` "); - connection.msgChannel(config.getChannel(), MircColors.YELLOW + " ." + MircColors.BROWN + "~" + MircColors.YELLOW + ":" + MircColors.BROWN + "~ "); - connection.msgChannel(config.getChannel(), MircColors.BROWN + " ((.(\\.!/.):?) "); - connection.msgChannel(config.getChannel(), MircColors.DARK_GREEN + " .?~:?.?7::,::::+,,~+~=:... "); - connection.kickFromChannel(config.getChannel(), user + " KABOOM!!!"); - bombActive = false; - } - } else { - connection.msgChannel(config.getChannel(), "Invalid."); - } - } - - /** - * Does driveby lol's Parts and returns as well as try-sleeps in loop to avoid - * flooding. - */ - private void driveBy() { - if (cmdArgs.length() < 2 || !cmdArgs.startsWith("#")) { - connection.msgChannel(config.getChannel(), "Invalid channel: " + cmdArgs); - return; - } - config.setBaseChan(config.getChannel()); // The channel JRobo will return to - connection.moveToChannel(config.getChannel(), cmdArgs); - for (int i = 0; i < 25; i++) { - connection.moveToChannel(config.getChannel(), cmdArgs); - for (int z = 0; z < 5; z++) { - connection.msgChannel(config.getChannel(), "lol"); - try { - Thread.sleep(1000); - if (connection.recieveln().contains(":the_derp_knight!~JRobo@d-24-245-107-185.cpe.metrocast.net QUIT :Excess Flood")) { - break; - } - } catch (Exception ex) { //Find out exactly what exceptions are thrown - //Logger.getLogger(BotCommand.class.getName()).log(Level.SEVERE, null, ex); - } - } - connection.moveToChannel(cmdArgs, config.getBaseChan()); - try { - Thread.sleep(2500); - if (connection.recieveln().contains(":the_derp_knight!~JRobo@d-24-245-107-185.cpe.metrocast.net QUIT :Excess Flood")) { - break; - } - } catch (Exception ex) { //Find out exactly what exceptions are thrown - //Logger.getLogger(BotCommand.class.getName()).log(Level.SEVERE, null, ex); - } - } - // If not in basechannel he will return to Basechannel - if (config.getChannel() != config.getBaseChan()) { - connection.moveToChannel(cmdArgs, config.getBaseChan()); - } - } - - /** - * Puts together a String in the form http://lmgtfy.com/?q=test+a+b+c - */ - private void googleHelper() { - if (!hasArgs) { - helpWrapper(cmd); - } else { - String googleUrl = "http://lmgtfy.com/?q=".concat(getFormattedQuery(cmdArgs)); - connection.msgChannel(config.getChannel(), googleUrl); - } - } - - private void isUpHelper() { - if (!hasArgs) { - helpWrapper(cmd); - } else { - connection.msgChannel(config.getChannel(), new DownForEveryone().isUp(getFormattedQuery(cmdArgs), true)); - } - } - - private void weatherHelper() { - /* - * Put together a String in the form - * http://www.google.com/ig/api?weather=Mountain+View - */ -// connection.msgUser("BullShark", weatherUrl); -// if(!hasArgs) { -// helpWrapper(cmd); -// } else { -// connection.msgChannel(botC, new Weather().getSummary(cmdArgs)); -// connection.msgChannel(botC, "^g weather " + cmdArgs); -// } - //TODO Parse and return the formatted JSON or XML instead -// connection.msgChannel(botC, new Weather().getXml(cmdArgs)); -//TODO Re-implement all the use wunderground.net - } - - private void mumHelper() { - - Jokes joke = new Jokes(this.connection, config.getChannel()); - - try { - if (!hasArgs) { - connection.msgChannel(config.getChannel(), joke.getMommaJoke(getRandChanUser())); - } else { - int temp = cmdArgs.indexOf(' '); - if (temp != -1) { - connection.msgChannel(config.getChannel(), joke.getMommaJoke(cmdArgs.substring(0, temp))); - } else { - connection.msgChannel(config.getChannel(), joke.getMommaJoke(cmdArgs)); - } - } - } catch (NullPointerException ex) { - Logger.getLogger(BotCommand.class.getName()).log(Level.SEVERE, null, ex); - - //Inform masters in PM - connection.msgMasters("FIX ^mum; FileReader.java not reading input!!!"); - } - } - - private void nextHelper() { - connection.msgChannel(config.getChannel(), "Another satisfied customer, NEXT!!!"); - } - - private void inviteNickHelper() { - if (true) { - return; - } //TODO Fix this method - - if (!hasArgs || !(cmdArgs.split("\\s++").length > 0)) { // Min 1 Arg - //@TODO Replace code with getHelp(cmd); //Overloaded method - connection.msgChannel(config.getChannel(), "Usage: " + config.getCmdSymb() + "invite-nick {nick} [# of times]"); - } else { - connection.msgChannel(config.getChannel(), "Roger that."); - String cmdArgsArr[] = cmdArgs.split("\\s++"); - int numInvites = 50; // Default value - if (cmdArgsArr.length < 1) { - try { - Thread.sleep(1500); - numInvites = Integer.getInteger(cmdArgsArr[1]); - //TODO replace with FileReader.getMaster() - if (connection.recieveln().contains(":JRobo!~Tux@unaffiliated/robotcow QUIT :Excess Flood")) { - // this.jRobo. - } - } catch (Exception ex) { //Find out exactly what exceptions are thrown - Logger.getLogger(BotCommand.class.getName()).log(Level.SEVERE, null, ex); - } - } - for (int x = 0; x < numInvites; x++) { - connection.sendln("INVITE " + config.getChannel() + " " + cmdArgsArr[0]); - } - } - } - - private void inviteChannelHelper() { - String[] userArr; - if (!hasArgs) { -//TODO helpWrapper(cmd); - return; - } - - if (threadCreated) { - connection.msgChannel(config.getChannel(), "The invite thread is still active."); - return; - } - - - //TODO exclude duplicates from useray - if (cmdArgs.contains(" ")) { - final String[] chansArr = cmdArgs.split("\\s++"); - // Channel must begin with a # and be at least two characters long - for (int i = 0; i < chansArr.length; i++) { - if (chansArr[i].length() < 2 || !chansArr[i].startsWith("#")) { - connection.msgChannel(config.getChannel(), "Invalid channel: " + chansArr[i]); - return; - } - } - - config.setBaseChan(config.getChannel()); // The channel JRobo will return to - String usersList = ""; - for (int i = 0; i < chansArr.length; i++) { - connection.moveToChannel(config.getChannel(), chansArr[i]); - if (config.getChannel().equals(config.getBaseChan())) { - break; - } - usersList += getUsers(); - } - userArr = usersList.split("\\s"); - connection.moveToChannel(chansArr[chansArr.length - 1], config.getBaseChan()); - } //The command does not contain more than one channel argument - else { - // Channel must begin with a # and be at least two characters long - if (cmdArgs.length() < 2 || !cmdArgs.startsWith("#")) { - connection.msgChannel(config.getChannel(), "Invalid channel: " + cmdArgs); - return; - } - config.setBaseChan(config.getChannel()); // The channel JRobo will return to - connection.moveToChannel(config.getChannel(), cmdArgs); - userArr = getUsers().split("\\s"); - connection.moveToChannel(cmdArgs, config.getBaseChan()); - - } - //Statement required for Build (currently is workaround) - final String[] user2Arr = userArr; - - for (int i = 0; i < userArr.length; i++) { - System.out.println("userArray: " + userArr[i]); - } - - // Checking if ChanServ has opped JRobo - String first, last, received; - for (int tries = 4;;) { - received = connection.recieveln(); - try { - first = received.split(" :", 2)[0]; - last = received.split(" :", 2)[1]; - } catch (ArrayIndexOutOfBoundsException ex) { - first = ""; - last = ""; - } - if (first.equals("PING")) { - connection.sendln("PONG " + last); - } else if (received.equals(":ChanServ!ChanServ@services. MODE " + config.getChannel() + " +o " + config.getName()) - || tries < 0) { - break; - } - tries--; - } - - Thread inviteT = new Thread() { - public void run() { - - // Prevent multiple threads from being created - threadCreated = true; - - for (String user : user2Arr) { - try { - Thread.sleep(35000); //TODO Delay set by last command arg? - } catch (InterruptedException ex) { - Logger.getLogger(BotCommand.class.getName()).log(Level.SEVERE, null, ex); - } - connection.sendln("INVITE " + user + " " + config.getChannel()); - } - threadCreated = false; - } - }; - //Remove In a minute -projektile - inviteT.start(); - - -//TODO Implement and use FileReader.getNickAndHost() instead -//FIXME check all masters for-each loop if(jRobo.getFirst().startsWith(config.getMasters()[0]) && hasArgs ) { -//Use for multiple channels, array String[] channels = this.cmdArgs.split("\\s++"); -// if(channels.length ) - } - - private void rawHelper() { - /* We have received a message from the owner */ - //TODO Make the below string a variable that is mutable to be set by the XML configuration file - if (jRobo.getFirst().startsWith(":BullShark!debian-tor@gateway/tor-sasl/nanomachine")) { - connection.sendln("PRIVMSG " + config.getChannel() + " :Yes Sir Chief!"); - String rawStr = jRobo.getLast(); - rawStr = rawStr.substring(rawStr.indexOf(' ')); - connection.sendln(rawStr); - try { - Thread.sleep(500); - connection.msgChannel(config.getChannel(), connection.recieveln()); - - - } catch (InterruptedException | NullPointerException ex) { - Logger.getLogger(BotCommand.class - .getName()).log(Level.SEVERE, null, ex); - } - } - } - - private void urbanDictionaryHelper() { - connection.msgChannel(config.getChannel(), new UrbanDict(cmdArgs).getFormattedUrbanDef(true, 3), true, MircColors.BOLD); - } - - private void quitHelper() { - connection.msgChannel(config.getChannel(), "Detenation devices to nuclear reactors! (Zer0 is pressing the " - + "stupid BUTTOnN so GO OUT OF THIS FUCKING CHANNEL BITCHES!!!)"); - } - - /* - * Does nothing - */ - private void doNothingHelper() { - } - - private void pirateHelper() { - connection.msgChannel(config.getChannel(), new PirateBay(cmdArgs).getFormattedResult(true)); - } - - /** - * *************************************************************************** - * Help messages - */ - private void listHelper() { - /* - String str = "Available commands: google|g|lmgtfy|stfw , " + - "wakeroom|wr, weather|w , " + - "urbandict|ud help|h [cmd], " + - "next|n, mum|m [user], invite-channel|ic , " + - "invite-nick|in [# of times], pirate [-s|-l|-d] , " + - "isup , version, quit|q"; //@TODO update list for ALL commands - */ - - String noColorStr = "Available commands: google|g|lmgtfy|stfw , " - + "wakeroom|wr, weather|w , " - + "urbandict|ud , help|h [cmd], " - + "next|n, mum|m [user], invite-channel|ic , " - + "invite-nick|in [# of times], pirate [-s|-l|-d] , " - + "isup , version, quit|q"; //@TODO update list for ALL commands - - /* - * GREEN = dark color - * CYAN = light color - * - * cmds|alias = dark - * flags = dark - * args = light - * special characters = no bold, no color - * such as [] <> , ... - */ - String colorStr = lc.attributesSynopsisLine( - lc.colorToken("Available commands: ", MircColors.BOLD) - + lc.colorToken("google|g|lmgtfy|stfw ", MircColors.GREEN) - + lc.colorToken(", ", MircColors.CYAN) - + lc.colorToken("wakeroom|wr, ", MircColors.GREEN) - + lc.colorToken("weather|w ", MircColors.GREEN) - + lc.colorToken(", ", MircColors.CYAN) - + lc.colorToken("urbandict|ud ", MircColors.GREEN) - + lc.colorToken(", ", MircColors.CYAN) - + lc.colorToken("list|l, ", MircColors.GREEN) - + lc.colorToken("raw|r ", MircColors.GREEN) - + lc.colorToken(", ", MircColors.CYAN) - + lc.colorToken("help|h ", MircColors.GREEN) - + lc.colorToken("[cmd], ", MircColors.CYAN) - + lc.colorToken("next|n, ", MircColors.GREEN) - + lc.colorToken("mum|m ", MircColors.GREEN) - + lc.colorToken("[user], ", MircColors.CYAN) - + lc.colorToken("invite-channel|ic ", MircColors.GREEN) - + lc.colorToken(", ", MircColors.CYAN) - + lc.colorToken("invite-nick|in ", MircColors.GREEN) - + lc.colorToken(" ", MircColors.CYAN) - + lc.colorToken("[# of times], ", MircColors.CYAN) - + lc.colorToken("pirate ", MircColors.GREEN) - + lc.colorToken("[-s|-l|-d] ", MircColors.CYAN) - + lc.colorToken(", ", MircColors.CYAN) - + lc.colorToken("isup ", MircColors.GREEN) - + lc.colorToken(", ", MircColors.CYAN) - + lc.colorToken("version, ", MircColors.GREEN) - + lc.colorToken("quit|q", MircColors.GREEN)); - - connection.msgChannel(config.getChannel(), colorStr); - } - - private void unknownCmdHelper() { - connection.msgChannel(config.getChannel(), "Unknown command received: " + cmd); - } - - /* - * Wrapper Help command messages - */ - private void helpWrapper(String cmd) { - //TODO help string for each command - connection.msgChannel(config.getChannel(), "Invalid usage of command: " + cmd); - } - - private void helpHelper() { - //@TODO man page style usage for help blah - connection.msgChannel(config.getChannel(), "You implement it!"); - } - - private void versionHelper() { - connection.msgChannel(config.getChannel(), - MircColors.BOLD + MircColors.CYAN + "JRobo" - + MircColors.NORMAL + MircColors.BOLD + " - " - + MircColors.GREEN + "https://github.com/BullShark/JRobo"); - } - - private void greetHelper() { - Jokes joke = new Jokes(this.connection, config.getChannel()); - - try { - if (!hasArgs) { - connection.msgChannel(config.getChannel(), joke.getPhoneNumber(getRandChanUser())); - } else { - int temp = cmdArgs.indexOf(' '); - if (temp != -1) { - connection.msgChannel(config.getChannel(), joke.getPhoneNumber(cmdArgs.substring(0, temp))); - } else { - connection.msgChannel(config.getChannel(), joke.getPhoneNumber(cmdArgs)); - - - } - } - } catch (NullPointerException ex) { - Logger.getLogger(BotCommand.class - .getName()).log(Level.SEVERE, null, ex); - - //Inform masters in PM - connection.msgMasters( - "FIX ^mum; FileReader.java not reading input!!!"); - } - } - - private void moveToChannelHelper() { - //TODO Only Masters - connection.moveToChannel(config.getChannel(), cmdArgs); - } -} // EOF class diff --git a/src/jrobo/CommandFactory.java b/src/jrobo/CommandFactory.java new file mode 100644 index 00000000..37abf7d6 --- /dev/null +++ b/src/jrobo/CommandFactory.java @@ -0,0 +1,26 @@ +package jrobo; + +import jrobo.command.*; + +import java.util.Set; +import org.reflections.Reflections; + +public class CommandFactory { + public BotCommand newCommand(String command) throws InstantiationException, IllegalAccessException { + BotCommand botCommand = null; + Reflections reflections = new Reflections("jrobo.command"); + Set> annotated = reflections.getTypesAnnotatedWith(JRoboCommand.class); + + for(Class klass : annotated) { + JRoboCommand jRoboCommand = klass.getAnnotation(JRoboCommand.class); + for(String cmd : jRoboCommand.command().split(",")) { + if(command.equals(cmd)) { + botCommand = (BotCommand) klass.newInstance(); + break; + } + } + } + + return botCommand; + } +} diff --git a/src/jrobo/IRCTester.java b/src/jrobo/IRCTester.java deleted file mode 100644 index c869ff4b..00000000 --- a/src/jrobo/IRCTester.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * JRobo - An Advanced IRC Bot written in Java - * - * Copyright (C) <2013> - * Copyright (C) <2013> - * Copyright (C) <2013> - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package jrobo; - -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * - * @author bullshark - */ -public class IRCTester { - - /* Defined Objects */ - private Networking connection = null; - private Config config = null; - private Jokes jokes = null; - private BotCommand bCmd = null; - - /* Networking */ - private String first = null; - private String last = null; - private String received = null; - - /* JRobo Attributes */ - private String botN = null; - private String botP = null; - private String botC = null; - private final char SYMB = '$'; - - private int randomBoolean; - private final FileReader fReader; - - public IRCTester() { - this.fReader = new FileReader(); - this.config = this.fReader.getConfig(); - this.connection = new Networking(config); - this.jokes = new Jokes(connection,config.getChannel()); - - /* Set Attributes/State for this JRobo Object */ - this.botN = "ProtoAnazlyer"; - this.botP = ""; - this.botC = "#blackhats"; - - /* Misc */ - randomBoolean = 0; - } - - public void initiate() { - System.out.println("\u001b[1;44m *** INITIATED *** \u001b[m"); - - /* Identify to server */ - connection.sendln("NICK " + botN); -// connection.sendln("PASS " + botP); - connection.sendln("USER RTFM 0 * :Microsoft Exterminator!"); - -// /* -// * Give the server 4 seconds to identify JRobo -// * Before attempting to join a channel -// */ -// try { -// Thread.sleep(10000); -// } catch (InterruptedException ex) { -// Logger.getLogger(JRobo.class.getName()).log(Level.SEVERE, null, ex); -// } - /* - * Wait for server message: - * 001 JRobo :Welcome to the IRC Network - * Before attempting to join a channel - */ - while(( received = connection.recieveln()) != null ) { - this.divideTwo(); - - if(first.equals("PING")) { - connection.sendln("PONG " + last); - } - - if(first.contains("001")) { - break; - } - } - - connection.sendln("JOIN " + botC); - - while( (received = connection.recieveln()) != null ) { - - this.divideTwo(); - - /* Code to Test JRobo */ - - - /* We have received a message from the owner */ - if( first.startsWith( ":BullShark" ) && - ( last.charAt(0) == SYMB ) ) { - connection.msgChannel(botC, MircColors.RED + "Yes Sir Chief!" + MircColors.NORMAL); - } -/* Handle lines like these - * - * Received: PING :hubbard.freenode.net - * Received: :RobotCow!~User@unaffiliated/robotcow PRIVMSG ##sushi :^command - * Received: :RobotCow!~User@unaffiliated/robotcow PRIVMSG ProtoAnalyzer :cmd - * Received: :hubbard.freenode.net 366 ProtoAnalyzer ##sushi :End of /NAMES list. - */ - if(first.equals("PING")) { - connection.sendln("PONG :" + last); - } - - } - - System.out.println("\u001b[1;44m *** TERMINATED *** \u001b[m"); - } - - public void divideTwo() { - try { - first = received.split(" :", 2)[0]; - last = received.split(" :", 2)[1]; - } catch(ArrayIndexOutOfBoundsException ex) { - Logger.getLogger(JRobo.class.getName()).log(Level.SEVERE, null, ex); - first = ""; - last = ""; - } - - } //@TODO Get List of Users - public void getMumJoke() { - /* Code to Test JRobo */ - try { - Thread.sleep(30000); - } catch (InterruptedException ex) { - Logger.getLogger(JRobo.class.getName()).log(Level.SEVERE, null, ex); - } - - randomBoolean = (int) (Math.random() * 10 % 2); - - if(randomBoolean == 1) { - connection.sendln("PRIVMSG " + botC + " :" + jokes.getMommaJoke(null)); - } else { - connection.sendln("PRIVMSG " + botC + " :" + jokes.getPhoneNumber(null)); - } - } - - /** - * @param args the command line arguments - */ - public static void main(String[] args) { - new IRCTester().initiate(); - } -} diff --git a/src/jrobo/JRobo.java b/src/jrobo/JRobo.java index 9d94f496..a7d260a1 100644 --- a/src/jrobo/JRobo.java +++ b/src/jrobo/JRobo.java @@ -21,8 +21,13 @@ package jrobo; +import jrobo.command.*; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.Map; +import java.util.HashMap; +import java.util.Set; +import java.util.HashSet; /** * @@ -35,7 +40,7 @@ public class JRobo { private final FileReader reader; private final Config config; private final Jokes jokes; - private final BotCommand bCmd; + private final CommandFactory factory; /* Networking */ private String first = null; @@ -44,26 +49,17 @@ public class JRobo { /* Miscallenous */ private String user = null; + private Map> channelUsers; public JRobo() { reader = new FileReader(); config = reader.getConfig(); connection = new Networking(config); jokes = new Jokes (connection, config.getChannel()); - bCmd = new BotCommand(connection, config, this); - + factory = new CommandFactory(); + channelUsers = new HashMap>(); } - public JRobo(String proxy, int port) { //TODO - reader = new FileReader(); - config = reader.getConfig(); - connection = new Networking(config); - jokes = new Jokes (connection, config.getChannel()); - bCmd = new BotCommand(connection, config, this); - - } - - private void initiate() { //TODO: Use TermColors.java instead System.out.println("\u001b[1;44m *** INITIATED *** \u001b[m"); @@ -107,62 +103,198 @@ private void initiate() { */ if(first.equals("PING")) { //@TODO Implement with regex connection.sendln("PONG " + last); + continue; + } + + /* + * Lets break the first half the message down a bit more + */ + String ircMessage; + try { + ircMessage = first.split(" ")[1].toUpperCase(); + } catch(ArrayIndexOutOfBoundsException ex) { + ircMessage = ""; } /* * A message was sent either to the channel * Or to the bot; Could be a command */ - else if(first.contains("PRIVMSG")) { + if(ircMessage.equals("PRIVMSG")) { try { if(last.charAt(0) == config.getCmdSymb()) { String user = first.substring(1, first.indexOf('!')); - String fullCmd = last; - bCmd.bCommander(user, fullCmd); - } else { - - /* - * Match JRobo in any case typed by another user - * TODO Should we change this to last.contains(botN) with ignore case - * TODO Because the bot's name might be something other than JRobo - */ -// if(last.matches("(?i).*JR[0o]b[0o].*")) { -// try { -// user = first.substring(1, first.indexOf('!')); -// connection.msgChannel(config.getChannel(), jokes.getPhoneNumber(user)); -// } catch(StringIndexOutOfBoundsException ex) { -// Logger.getLogger(JRobo.class.getName()).log(Level.SEVERE, null, ex); -// } -// } + String cmd = getCommand(last); + BotCommand botCmd = factory.newCommand(cmd); + + botCmd.setJRobo(this); + botCmd.setInputCommand(cmd); + botCmd.execute(getTarget(first), getParameters(last)); } } catch(StringIndexOutOfBoundsException ex) { Logger.getLogger(Networking.class.getName()).log(Level.SEVERE, null, ex); + } catch(InstantiationException ex) { + Logger.getLogger(Networking.class.getName()).log(Level.SEVERE, null, ex); + } catch(IllegalAccessException ex) { + Logger.getLogger(Networking.class.getName()).log(Level.SEVERE, null, ex); + } + } + + /* + * A /NAMES list was received update the channelUsers list + * for the channel in question. + */ + + else if(ircMessage.equals("353")) { + String channel; + Set users = new HashSet(); + + try { + channel = first.split(" ")[4]; + } catch(ArrayIndexOutOfBoundsException ex) { + continue; + } + + last = last.replaceAll("@|\\+|&|~|%", ""); + for(String nickname : last.split(" ")) { + users.add(nickname); + } + + if(channelUsers.get(channel) != null) { + channelUsers.get(channel).addAll(users); + } else { + channelUsers.put(channel, users); } } /* - * A user has joined the channel - * Excluding the bot joining + * A JOIN message was received. Add that user to + * the channel's user list. */ - else if(first.contains("JOIN") && last.equals(config.getChannel()) && !first.contains(config.getName())) { - user = first.substring(1, first.indexOf('!')); + else if(ircMessage.equals("JOIN")) { + String nickname = getNickname(); + String channel = last; - // Inform masters in PM - connection.msgMasters(user + " joined " + config.getChannel()); + if(nickname != null) { + if(channelUsers.get(channel) != null) { + channelUsers.get(channel).add(nickname); + } else { + // TODO + } + } } - else if(received.matches("^:\\S+ KICK " + config.getChannel() + " " + config.getName() + " :.*")) { - connection.sendln("JOIN " + config.getChannel()); - user = first.substring(1, first.indexOf('!')); - //connection.msgChannel(config.getChannel(), user + " >>> I'll rip your head off and shit down your neck!"); - } // EOF if-else-if-else... - } // EOF while + /* + * A PART message was received. Remove that user from + * the channel's user list. + */ + else if(ircMessage.equals("PART")) { + try { + String nickname = getNickname(); + String channel = first.split(" ")[2]; + + if(nickname != null) { + if(nickname != myNickname()) { + channelUsers.get(channel).remove(nickname); + } else { + channelUsers.remove(channel); + } + } + } catch(ArrayIndexOutOfBoundsException ex) { + } + } + } - //@TODO Implement a Networking.killConnection() and call it here - //@TODO onUserJoin, ctcp version whois user System.out.println("\u001b[1;44m *** TERMINATED *** \u001b[m"); } + /** + * @author jotaki + * @param line The full message line received after the `:'. + * @return The command to be interpreted. + */ + private String getCommand(String line) { + try { + return line.substring(1, line.indexOf(' ')); + } catch(StringIndexOutOfBoundsException ex) { + return line.substring(1, line.length()); + } + } + + /** + * @author jotaki + * @param line The message line before the `:' + * @return The considered target + * TODO: If target == Bot.nick return FromLine.nick + */ + private String getTarget(String line) { + String[] lineSplit = line.split(" "); + try { + return lineSplit[lineSplit.length-1]; + } catch(ArrayIndexOutOfBoundsException ex) { + return ""; + } + } + + /** + * @author jotaki + * @param line the full message line received after the `:' + * @return the parameters to the bot command as a String array split by spaces. + */ + private String[] getParameters(String line) { + String[] fullArgs = line.split(" "); + String[] args = new String[fullArgs.length - 1]; + int i; + + for(i = 1; i < fullArgs.length; i++) { + args[i-1] = fullArgs[i]; + } + + return args; + } + + public String getNickname(String line) { + try { + return line.substring(1, line.indexOf('!')); + } catch(StringIndexOutOfBoundsException ex) { + return null; + } + } + + public String getNickname() { + return getNickname(first); + } + + public String getUsername(String line) { + try { + return line.substring(line.indexOf('!')+1, line.indexOf('@')); + } catch(StringIndexOutOfBoundsException ex) { + return null; + } + } + + public String getUsername() { + return getUsername(first); + } + + public String getHostname(String line) { + try { + return line.substring(line.indexOf('@')+1, line.indexOf(' ')); + } catch(StringIndexOutOfBoundsException ex) { + return null; + } + } + + public String getHostname() { + return getHostname(first); + } + + public String myNickname() { + /* XXX: TODO: Make smarter / better */ + return config.getName(); + } + + private void divideTwo() { try { first = received.split(" :", 2)[0]; @@ -187,4 +319,12 @@ public String getLast() { public static void main(String[] args) { new JRobo().initiate(); } + + public Networking getConnection() { + return connection; + } + + public Set getUsers(String channel) { + return channelUsers.get(channel); + } } diff --git a/src/jrobo/command/BotCommand.java b/src/jrobo/command/BotCommand.java new file mode 100644 index 00000000..0a48bd7e --- /dev/null +++ b/src/jrobo/command/BotCommand.java @@ -0,0 +1,103 @@ +/* + * JRobo - An Advanced IRC Bot written in Java + * + * Copyright (C) <2013> + * Copyright (C) <2013> + * Copyright (C) <2013> + * Copyright (C) <2013> + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +//TODO javadoc all +// http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html +package jrobo.command; + +import jrobo.Networking; +import jrobo.Config; +import jrobo.JRobo; +import java.util.Set; + +public abstract class BotCommand { + private JRobo jRobo; + protected String inputCommand; + + public BotCommand() { + } + + public void sendRaw(String message) { + jRobo.getConnection().sendln(message); + } + + public void privmsg(String target, String msg) { + sendRaw("PRIVMSG " + target + " :" + msg); + } + + public void notice(String target, String msg) { + sendRaw("NOTICE " + target + " :" + msg); + } + + public void join(String channel, String key) { + sendRaw("JOIN " + channel + " " + key); + } + + public void join(String channel) { + join(channel, ""); + } + + public void part(String channel, String msg) { + sendRaw("PART " + channel + " " + msg); + } + + public void part(String channel) { + part(channel, "Leaving"); + } + + public void quit(String msg) { + sendRaw("QUIT :" + msg); + } + + public void mode(String target, String... modes) { + sendRaw("MODE " + target + " " + strJoin(modes, " ")); + } + + public void setJRobo(JRobo jRobo) { + this.jRobo = jRobo; + } + + public void setInputCommand(String inputCommand) { + this.inputCommand = inputCommand; + } + + public String strJoin(String[] arr, String sep) { + String result = ""; + int i; + + for(i = 0; i < arr.length; i++) { + result += arr[i]; + if(i+1 < arr.length) + result += sep; + } + return result; + } + + public String[] getUsers(String channel) { + Set set = jRobo.getUsers(channel); + if(set == null) + return new String[0]; + + return set.toArray(new String[0]); + } + + public abstract void execute(String target, String[] args); +} diff --git a/src/jrobo/command/GoogleCommand.java b/src/jrobo/command/GoogleCommand.java new file mode 100644 index 00000000..08d1cedc --- /dev/null +++ b/src/jrobo/command/GoogleCommand.java @@ -0,0 +1,15 @@ +package jrobo.command; +import jrobo.JRobo; + +@JRoboCommand(author="jotaki",date="2013/09/27",command="google,g,lmgtfy,stfw") +public class GoogleCommand extends BotCommand { + public GoogleCommand() { + super(); + } + + public void execute(String target, String[] args) { + if(args.length > 0) { + privmsg(target, "http://lmgtfy.com/?q=" + strJoin(args, " ").replaceAll("\\s++", "+")); + } + } +} diff --git a/src/jrobo/command/JRoboCommand.java b/src/jrobo/command/JRoboCommand.java new file mode 100644 index 00000000..63b9f514 --- /dev/null +++ b/src/jrobo/command/JRoboCommand.java @@ -0,0 +1,10 @@ +package jrobo.command; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +public @interface JRoboCommand { + String author(); + String date(); + String command(); +} diff --git a/src/jrobo/command/OpCommands.java b/src/jrobo/command/OpCommands.java new file mode 100644 index 00000000..33ab752f --- /dev/null +++ b/src/jrobo/command/OpCommands.java @@ -0,0 +1,27 @@ +package jrobo.command; +import jrobo.JRobo; + +@JRoboCommand(author="jotaki",date="2013/09/27",command="join,goto") +public class OpCommands extends BotCommand { + public OpCommands() { + super(); + } + + public void execute(String target, String[] args) { + if(args.length == 0) { + help(target); + return; + } + + switch(inputCommand) { + case "goto": + part(target); + case "join": + join(args[0]); + } + } + + public void help(String target) { + privmsg(target, "Usage: " + inputCommand + " "); + } +} diff --git a/src/jrobo/command/TestCommand.java b/src/jrobo/command/TestCommand.java new file mode 100644 index 00000000..59f81985 --- /dev/null +++ b/src/jrobo/command/TestCommand.java @@ -0,0 +1,13 @@ +package jrobo.command; +import jrobo.JRobo; + +@JRoboCommand(author="jotaki",date="2013/09/25",command="test,alias") +public class TestCommand extends BotCommand { + public TestCommand() { + super(); + } + + public void execute(String target, String[] args) { + privmsg(target, "Hello " + strJoin(getUsers(target), ", ") + "!"); + } +}