diff --git a/src/main/java/net/md_5/bungee/BungeeCord.java b/src/main/java/net/md_5/bungee/BungeeCord.java index 9aa59e3c..ed8dd895 100644 --- a/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/src/main/java/net/md_5/bungee/BungeeCord.java @@ -11,6 +11,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.logging.Level; import static net.md_5.bungee.Logger.$; import net.md_5.bungee.command.Command; import net.md_5.bungee.command.CommandEnd; @@ -20,6 +21,9 @@ import net.md_5.bungee.command.CommandServer; import net.md_5.bungee.command.ConsoleCommandSender; import net.md_5.bungee.plugin.JavaPluginManager; +/** + * Main BungeeCord proxy class. + */ public class BungeeCord { /** @@ -69,6 +73,12 @@ public class BungeeCord { commandMap.put("server", new CommandServer()); } + /** + * Starts a new instance of BungeeCord. + * + * @param args command line arguments, currently none are used + * @throws IOException when the server cannot be started + */ public static void main(String[] args) throws IOException { instance = new BungeeCord(); $().info("Enabled BungeeCord version " + instance.version); @@ -86,26 +96,38 @@ public class BungeeCord { } } + /** + * Dispatch a command by formatting the arguments and then executing it. + * + * @param commandLine the entire command and arguments string + * @param sender which executed the command + * @return whether the command was handled or not. + */ public boolean dispatchCommand(String commandLine, CommandSender sender) { String[] split = commandLine.trim().split(" "); String commandName = split[0].toLowerCase(); - if (commandMap.containsKey(commandName)) { + Command command = commandMap.get(commandName); + if (command != null) { String[] args = Arrays.copyOfRange(split, 1, split.length); - Command c = commandMap.get(commandName); try { - c.execute(sender, args); + command.execute(sender, args); } catch (Exception ex) { sender.sendMessage(ChatColor.RED + "An error occurred while executing this command!"); - System.err.println("----------------------- [Start of command error] -----------------------"); - ex.printStackTrace(); - System.err.println("----------------------- [End of command error] -----------------------"); + $().severe("----------------------- [Start of command error] -----------------------"); + $().log(Level.SEVERE, "", ex); + $().severe("----------------------- [End of command error] -----------------------"); } - return true; - } else { - return false; } + + return command != null; } + /** + * Start this proxy instance by loading the configuration, plugins and + * starting the connect thread. + * + * @throws IOException + */ public void start() throws IOException { config.load(); isRunning = true; @@ -120,6 +142,10 @@ public class BungeeCord { $().info("Listening on " + addr); } + /** + * Destroy this proxy instance cleanly by kicking all users, saving the + * configuration and closing all sockets. + */ public void stop() { this.isRunning = false; $().info("Disabling plugin"); @@ -151,6 +177,13 @@ public class BungeeCord { $().info("Thank you and goodbye"); } + /** + * Miscellaneous method to set options on a socket based on those in the + * configuration. + * + * @param socket to set the options on + * @throws IOException when the underlying set methods thrown an exception + */ public void setSocketOptions(Socket socket) throws IOException { socket.setSoTimeout(config.timeout); socket.setTrafficClass(0x18); diff --git a/src/main/java/net/md_5/bungee/ChatColor.java b/src/main/java/net/md_5/bungee/ChatColor.java index 771aa17b..fef7ce2f 100644 --- a/src/main/java/net/md_5/bungee/ChatColor.java +++ b/src/main/java/net/md_5/bungee/ChatColor.java @@ -1,133 +1,116 @@ package net.md_5.bungee; -import com.google.common.collect.Maps; -import java.util.Map; import java.util.regex.Pattern; /** - * All supported color values for chat + * Simplistic enumeration of all supported color values for chat. */ public enum ChatColor { /** - * Represents black + * Represents black. */ - BLACK('0', 0x00), + BLACK('0'), /** - * Represents dark blue + * Represents dark blue. */ - DARK_BLUE('1', 0x1), + DARK_BLUE('1'), /** - * Represents dark green + * Represents dark green. */ - DARK_GREEN('2', 0x2), + DARK_GREEN('2'), /** - * Represents dark blue (aqua) + * Represents dark blue (aqua). */ - DARK_AQUA('3', 0x3), + DARK_AQUA('3'), /** - * Represents dark red + * Represents dark red. */ - DARK_RED('4', 0x4), + DARK_RED('4'), /** - * Represents dark purple + * Represents dark purple. */ - DARK_PURPLE('5', 0x5), + DARK_PURPLE('5'), /** - * Represents gold + * Represents gold. */ - GOLD('6', 0x6), + GOLD('6'), /** - * Represents gray + * Represents gray. */ - GRAY('7', 0x7), + GRAY('7'), /** - * Represents dark gray + * Represents dark gray. */ - DARK_GRAY('8', 0x8), + DARK_GRAY('8'), /** - * Represents blue + * Represents blue. */ - BLUE('9', 0x9), + BLUE('9'), /** - * Represents green + * Represents green. */ - GREEN('a', 0xA), + GREEN('a'), /** - * Represents aqua + * Represents aqua. */ - AQUA('b', 0xB), + AQUA('b'), /** - * Represents red + * Represents red. */ - RED('c', 0xC), + RED('c'), /** - * Represents light purple + * Represents light purple. */ - LIGHT_PURPLE('d', 0xD), + LIGHT_PURPLE('d'), /** - * Represents yellow + * Represents yellow. */ - YELLOW('e', 0xE), + YELLOW('e'), /** - * Represents white + * Represents white. */ - WHITE('f', 0xF), + WHITE('f'), /** - * Represents magical characters that change around randomly + * Represents magical characters that change around randomly. */ - MAGIC('k', 0x10, true), + MAGIC('k'), /** * Makes the text bold. */ - BOLD('l', 0x11, true), + BOLD('l'), /** * Makes a line appear through the text. */ - STRIKETHROUGH('m', 0x12, true), + STRIKETHROUGH('m'), /** * Makes the text appear underlined. */ - UNDERLINE('n', 0x13, true), + UNDERLINE('n'), /** * Makes the text italic. */ - ITALIC('o', 0x14, true), + ITALIC('o'), /** * Resets all previous chat colors or formats. */ - RESET('r', 0x15); + RESET('r'); /** * The special character which prefixes all chat colour codes. Use this if * you need to dynamically convert colour codes from your custom format. */ public static final char COLOR_CHAR = '\u00A7'; - private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf(COLOR_CHAR) + "[0-9A-FK-OR]"); - private final int intCode; - private final char code; - private final boolean isFormat; - private final String toString; - private final static Map BY_ID = Maps.newHashMap(); - private final static Map BY_CHAR = Maps.newHashMap(); - - private ChatColor(char code, int intCode) { - this(code, intCode, false); - } - - private ChatColor(char code, int intCode, boolean isFormat) { - this.code = code; - this.intCode = intCode; - this.isFormat = isFormat; - this.toString = new String(new char[]{COLOR_CHAR, code}); - } - /** - * Gets the char value associated with this color - * - * @return A char value of this color code + * Pattern to remove all colour codes. */ - public char getChar() { - return code; + private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf(COLOR_CHAR) + "[0-9A-FK-OR]"); + /** + * This colour's colour char prefixed by the {@link #COLOR_CHAR}. + */ + private final String toString; + + private ChatColor(char code) { + this.toString = new String(new char[]{COLOR_CHAR, code}); } @Override @@ -135,31 +118,6 @@ public enum ChatColor { return toString; } - /** - * Checks if this code is a format code as opposed to a color code. - */ - public boolean isFormat() { - return isFormat; - } - - /** - * Checks if this code is a color code as opposed to a format code. - */ - public boolean isColor() { - return !isFormat && this != RESET; - } - - /** - * Gets the color represented by the specified color code - * - * @param code Code to check - * @return Associative {@link org.bukkit.ChatColor} with the given code, or - * null if it doesn't exist - */ - public static ChatColor getByChar(char code) { - return BY_CHAR.get(code); - } - /** * Strips the given message of all color codes * @@ -173,64 +131,4 @@ public enum ChatColor { return STRIP_COLOR_PATTERN.matcher(input).replaceAll(""); } - - /** - * Translates a string using an alternate color code character into a string - * that uses the internal ChatColor.COLOR_CODE color code character. The - * alternate color code character will only be replaced if it is immediately - * followed by 0-9, A-F, or a-f. - * - * @param altColorChar The alternate color code character to replace. Ex: & - * @param textToTranslate Text containing the alternate color code - * character. - * @return Text containing the ChatColor.COLOR_CODE color code character. - */ - public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) { - char[] b = textToTranslate.toCharArray(); - for (int i = 0; i < b.length - 1; i++) { - if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i + 1]) > -1) { - b[i] = ChatColor.COLOR_CHAR; - b[i + 1] = Character.toLowerCase(b[i + 1]); - } - } - return new String(b); - } - - /** - * Gets the ChatColors used at the end of the given input string. - * - * @param input Input string to retrieve the colors from. - * @return Any remaining ChatColors to pass onto the next line. - */ - public static String getLastColors(String input) { - String result = ""; - int length = input.length(); - - // Search backwards from the end as it is faster - for (int index = length - 1; index > -1; index--) { - char section = input.charAt(index); - if (section == COLOR_CHAR && index < length - 1) { - char c = input.charAt(index + 1); - ChatColor color = getByChar(c); - - if (color != null) { - result = color.toString() + result; - - // Once we find a color or reset we can stop searching - if (color.isColor() || color.equals(RESET)) { - break; - } - } - } - } - - return result; - } - - static { - for (ChatColor color : values()) { - BY_ID.put(color.intCode, color); - BY_CHAR.put(color.code, color); - } - } } diff --git a/src/main/java/net/md_5/bungee/Configuration.java b/src/main/java/net/md_5/bungee/Configuration.java index 9ef17ab9..d290b7cd 100644 --- a/src/main/java/net/md_5/bungee/Configuration.java +++ b/src/main/java/net/md_5/bungee/Configuration.java @@ -17,6 +17,9 @@ import static net.md_5.bungee.Logger.$; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; +/** + * Core configuration for the proxy. + */ public class Configuration { /** @@ -97,6 +100,9 @@ public class Configuration { */ public int logNumLines = 1 << 14; + /** + * Load the configuration and save default values. + */ public void load() { try { file.createNewFile(); @@ -172,11 +178,17 @@ public class Configuration { } } - public String getServerFor(String user, String requestedHost) { - String server; - if (forcedServers.containsKey(requestedHost)) { - server = servers.get(forcedServers.get(requestedHost)); - } else { + /** + * Get which server a user should be connected to, taking into account their + * name and virtual host. + * + * @param user to get a server for + * @param requestedHost the host which they connected to + * @return the name of the server which they should be connected to. + */ + public String getServer(String user, String requestedHost) { + String server = forcedServers.get(requestedHost); + if (server == null) { server = reconnectLocations.get(user); } if (server == null) { @@ -185,20 +197,30 @@ public class Configuration { return server; } - public void setHostFor(UserConnection user, String server) { + /** + * Save the last server which the user was on. + * + * @param user the name of the user + * @param server which they were last on + */ + public void setServer(UserConnection user, String server) { reconnectLocations.put(user.username, server); } + /** + * Gets the connectable address of a server defined in the configuration. + * + * @param name the friendly name of a server + * @return the usable {@link InetSocketAddress} mapped to this server + */ public InetSocketAddress getServer(String name) { - String hostline = (name == null) ? defaultServerName : name; - String server = servers.get(hostline); - if (server != null) { - return Util.getAddr(server); - } else { - return getServer(null); - } + String server = servers.get((name == null) ? defaultServerName : name); + return (server != null) ? Util.getAddr(server) : getServer(null); } + /** + * Save the current mappings of users to servers. + */ public void saveHosts() { save(reconnect, reconnectLocations); $().info("Saved reconnect locations to " + reconnect); diff --git a/src/main/java/net/md_5/bungee/EncryptionUtil.java b/src/main/java/net/md_5/bungee/EncryptionUtil.java index 32cc48b6..ee5526dd 100644 --- a/src/main/java/net/md_5/bungee/EncryptionUtil.java +++ b/src/main/java/net/md_5/bungee/EncryptionUtil.java @@ -35,6 +35,9 @@ import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.jce.provider.BouncyCastleProvider; +/** + * Class containing all encryption related methods for the proxy. + */ public class EncryptionUtil { private static final Random secure = new SecureRandom(); @@ -57,9 +60,7 @@ public class EncryptionUtil { return new PacketFDEncryptionRequest(hash, pubKey, verify); } - public static SecretKey getSecret(PacketFCEncryptionResponse resp, PacketFDEncryptionRequest request) throws BadPaddingException, IllegalBlockSizeException, - IllegalStateException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { - + public static SecretKey getSecret(PacketFCEncryptionResponse resp, PacketFDEncryptionRequest request) throws BadPaddingException, IllegalBlockSizeException, IllegalStateException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, keys.getPrivate()); byte[] decrypted = cipher.doFinal(resp.verifyToken); diff --git a/src/main/java/net/md_5/bungee/EntityMap.java b/src/main/java/net/md_5/bungee/EntityMap.java index 75f9f666..a7846e00 100644 --- a/src/main/java/net/md_5/bungee/EntityMap.java +++ b/src/main/java/net/md_5/bungee/EntityMap.java @@ -1,5 +1,8 @@ package net.md_5.bungee; +/** + * Class to rewrite integers within packets. + */ public class EntityMap { public final static int[][] entityIds = new int[256][]; diff --git a/src/main/java/net/md_5/bungee/GenericConnection.java b/src/main/java/net/md_5/bungee/GenericConnection.java index 436df98b..59bd89da 100644 --- a/src/main/java/net/md_5/bungee/GenericConnection.java +++ b/src/main/java/net/md_5/bungee/GenericConnection.java @@ -9,6 +9,9 @@ import static net.md_5.bungee.Logger.$; import net.md_5.bungee.packet.PacketFFKick; import net.md_5.bungee.packet.PacketInputStream; +/** + * Class to represent a Minecraft connection. + */ @EqualsAndHashCode @RequiredArgsConstructor public class GenericConnection { @@ -18,6 +21,11 @@ public class GenericConnection { protected final OutputStream out; public String username; + /** + * Close the socket with the specified reason. + * + * @param reason to disconnect + */ public void disconnect(String reason) { if (socket.isClosed()) { return; diff --git a/src/main/java/net/md_5/bungee/InitialHandler.java b/src/main/java/net/md_5/bungee/InitialHandler.java index 52b2ea3e..78a3f8d6 100644 --- a/src/main/java/net/md_5/bungee/InitialHandler.java +++ b/src/main/java/net/md_5/bungee/InitialHandler.java @@ -9,7 +9,7 @@ import net.md_5.bungee.packet.PacketFCEncryptionResponse; import net.md_5.bungee.packet.PacketFDEncryptionRequest; import net.md_5.bungee.packet.PacketFFKick; import net.md_5.bungee.packet.PacketInputStream; -import net.md_5.bungee.plugin.ConnectEvent; +import net.md_5.bungee.plugin.HandshakeEvent; import org.bouncycastle.crypto.io.CipherInputStream; import org.bouncycastle.crypto.io.CipherOutputStream; @@ -34,8 +34,8 @@ public class InitialHandler implements Runnable { case 0x02: Packet2Handshake handshake = new Packet2Handshake(packet); // fire connect event - ConnectEvent event = new ConnectEvent(handshake.username, socket.getInetAddress()); - BungeeCord.instance.pluginManager.onConnect(event); + HandshakeEvent event = new HandshakeEvent(handshake.username, socket.getInetAddress()); + BungeeCord.instance.pluginManager.onHandshake(event); if (event.isCancelled()) { throw new KickException(event.getCancelReason()); } @@ -59,8 +59,7 @@ public class InitialHandler implements Runnable { } UserConnection userCon = new UserConnection(socket, in, out, handshake); - userCon.register(); - userCon.connect(BungeeCord.instance.config.getServerFor(handshake.username, handshake.host)); + userCon.connect(BungeeCord.instance.config.getServer(handshake.username, handshake.host)); break; case 0xFE: throw new KickException(BungeeCord.instance.config.motd + ChatColor.COLOR_CHAR + BungeeCord.instance.connections.size() + ChatColor.COLOR_CHAR + BungeeCord.instance.config.maxPlayers); diff --git a/src/main/java/net/md_5/bungee/KickException.java b/src/main/java/net/md_5/bungee/KickException.java index 2ca59711..f7aa6c4c 100644 --- a/src/main/java/net/md_5/bungee/KickException.java +++ b/src/main/java/net/md_5/bungee/KickException.java @@ -1,5 +1,9 @@ package net.md_5.bungee; +/** + * Exception, which when thrown will disconnect the player from the proxy with + * the specified message. + */ public class KickException extends RuntimeException { public KickException(String message) { diff --git a/src/main/java/net/md_5/bungee/ListenThread.java b/src/main/java/net/md_5/bungee/ListenThread.java index e2f5b272..b6db8523 100644 --- a/src/main/java/net/md_5/bungee/ListenThread.java +++ b/src/main/java/net/md_5/bungee/ListenThread.java @@ -7,6 +7,9 @@ import java.net.Socket; import java.net.SocketException; import static net.md_5.bungee.Logger.$; +/** + * Thread to listen and dispatch incoming connections to the proxy. + */ public class ListenThread extends Thread { public final ServerSocket socket; diff --git a/src/main/java/net/md_5/bungee/Logger.java b/src/main/java/net/md_5/bungee/Logger.java index 6365c1f7..44174691 100644 --- a/src/main/java/net/md_5/bungee/Logger.java +++ b/src/main/java/net/md_5/bungee/Logger.java @@ -9,6 +9,9 @@ import java.util.logging.Formatter; import java.util.logging.Level; import java.util.logging.LogRecord; +/** + * Logger to handle formatting and storage of the proxy's logger. + */ public class Logger extends java.util.logging.Logger { private static final Formatter formatter = new ConsoleLogFormatter(); @@ -20,7 +23,7 @@ public class Logger extends java.util.logging.Logger { FileHandler handler = new FileHandler("proxy.log", BungeeCord.instance.config.logNumLines, 1, true); handler.setFormatter(formatter); addHandler(handler); - } catch (IOException | SecurityException ex) { + } catch (IOException ex) { System.err.println("Could not register logger!"); ex.printStackTrace(); } @@ -37,6 +40,11 @@ public class Logger extends java.util.logging.Logger { } } + /** + * Gets the current logger instance. + * + * @return the current logger instance + */ public static Logger $() { return instance; } diff --git a/src/main/java/net/md_5/bungee/ReconnectSaveThread.java b/src/main/java/net/md_5/bungee/ReconnectSaveThread.java index dc5f06f0..e9124f39 100644 --- a/src/main/java/net/md_5/bungee/ReconnectSaveThread.java +++ b/src/main/java/net/md_5/bungee/ReconnectSaveThread.java @@ -1,5 +1,9 @@ package net.md_5.bungee; +/** + * Class to call the {@link Configuration#saveHosts() } method at 5 minute + * intervals. + */ public class ReconnectSaveThread extends Thread { public ReconnectSaveThread() { diff --git a/src/main/java/net/md_5/bungee/ServerConnection.java b/src/main/java/net/md_5/bungee/ServerConnection.java index 047c6ac0..7168b387 100644 --- a/src/main/java/net/md_5/bungee/ServerConnection.java +++ b/src/main/java/net/md_5/bungee/ServerConnection.java @@ -16,6 +16,9 @@ import net.md_5.bungee.packet.PacketInputStream; import org.bouncycastle.crypto.io.CipherInputStream; import org.bouncycastle.crypto.io.CipherOutputStream; +/** + * Class representing a connection from the proxy to the server; ie upstream. + */ public class ServerConnection extends GenericConnection { public final String name; diff --git a/src/main/java/net/md_5/bungee/UserConnection.java b/src/main/java/net/md_5/bungee/UserConnection.java index df9e2110..4e3da51b 100644 --- a/src/main/java/net/md_5/bungee/UserConnection.java +++ b/src/main/java/net/md_5/bungee/UserConnection.java @@ -33,14 +33,11 @@ public class UserConnection extends GenericConnection implements CommandSender { super(socket, in, out); this.handshake = handshake; username = handshake.username; + BungeeCord.instance.connections.put(username, this); } public void connect(String server) { InetSocketAddress addr = BungeeCord.instance.config.getServer(server); - if (addr.equals(curServer())) { - sendMessage(ChatColor.RED + "You are already on this server"); - return; - } connect(server, addr); } @@ -83,14 +80,6 @@ public class UserConnection extends GenericConnection implements CommandSender { } } - public void register() { - BungeeCord.instance.connections.put(username, this); - } - - private InetSocketAddress curServer() { - return (server == null) ? null : new InetSocketAddress(server.socket.getInetAddress(), server.socket.getPort()); - } - private void destory(String reason) { if (BungeeCord.instance.isRunning) { BungeeCord.instance.connections.remove(username); @@ -98,9 +87,7 @@ public class UserConnection extends GenericConnection implements CommandSender { disconnect(reason); if (server != null) { server.disconnect("Quitting"); - } - if (server != null) { - BungeeCord.instance.config.setHostFor(this, server.name); + BungeeCord.instance.config.setServer(this, server.name); } } diff --git a/src/main/java/net/md_5/bungee/Util.java b/src/main/java/net/md_5/bungee/Util.java index 381f3135..3979ebae 100644 --- a/src/main/java/net/md_5/bungee/Util.java +++ b/src/main/java/net/md_5/bungee/Util.java @@ -2,13 +2,15 @@ package net.md_5.bungee; import java.net.InetSocketAddress; +/** + * Series of utility classes to perform various operations. + */ public class Util { private static final int DEFAULT_PORT = 25565; /** - * Basic method to transform human readable addresses into usable address - * objects. + * Method to transform human readable addresses into usable address objects. * * @param hostline in the format of 'host:port' * @return the constructed hostname + port. @@ -23,17 +25,11 @@ public class Util { } /** - * Turns a InetSocketAddress into a string that can be reconstructed later. + * Gets the value of the first unsigned byte of the specified array. Useful + * for getting the id of a packet array . * - * @param address the address to serialize - * @return - */ - public static String getAddr(InetSocketAddress address) { - return address.getAddress().getHostAddress() + ((address.getPort() != DEFAULT_PORT) ? ":" + address.getPort() : ""); - } - - /** - * Get the packet id of specified byte array. + * @param b the array to read from + * @return the unsigned value of the first byte */ public static int getId(byte[] b) { return b[0] & 0xFF; @@ -57,10 +53,23 @@ public class Util { return result.toString(); } + /** + * Formats an integer as a hex value. + * + * @param i the integer to format + * @return the hex representation of the integer + */ public static String hex(int i) { return String.format("0x%02X", i); } + /** + * Constructs a pretty one line version of a {@link Throwable}. Useful for + * debugging. + * + * @param t the {@link Throwable} to format. + * @return a string representing information about the {@link Throwable} + */ public static String exception(Throwable t) { return t.getClass().getSimpleName() + " : " + t.getMessage() + " @ " + t.getStackTrace()[0].getFileName() + ":" + t.getStackTrace()[0].getLineNumber(); } diff --git a/src/main/java/net/md_5/bungee/command/Command.java b/src/main/java/net/md_5/bungee/command/Command.java index 3b90d0c8..58e97c0a 100644 --- a/src/main/java/net/md_5/bungee/command/Command.java +++ b/src/main/java/net/md_5/bungee/command/Command.java @@ -1,7 +1,9 @@ package net.md_5.bungee.command; -import net.md_5.bungee.ChatColor; - +/** + * Class which represents a proxy command. The {@link #execute(net.md_5.bungee.command.CommandSender, java.lang.String[]) + * } method will be called to dispatch the command. + */ public abstract class Command { /** @@ -12,20 +14,4 @@ public abstract class Command { * the original command. */ public abstract void execute(CommandSender sender, String[] args); - - /** - * Check if the arg count is at least the specified amount - * - * @param sender sender to send message to if unsuccessful - * @param args to check - * @param count to compare - * @return if the arguments are valid - */ - public final boolean testArgs(CommandSender sender, String[] args, int count) { - boolean valid = args.length >= count; - if (!valid) { - sender.sendMessage(ChatColor.RED + "Please review your argument count"); - } - return valid; - } } diff --git a/src/main/java/net/md_5/bungee/command/CommandEnd.java b/src/main/java/net/md_5/bungee/command/CommandEnd.java index dc1aa0cf..3fb783be 100644 --- a/src/main/java/net/md_5/bungee/command/CommandEnd.java +++ b/src/main/java/net/md_5/bungee/command/CommandEnd.java @@ -3,6 +3,9 @@ package net.md_5.bungee.command; import net.md_5.bungee.BungeeCord; import net.md_5.bungee.ChatColor; +/** + * Command to terminate the proxy instance. May only be used by the console. + */ public class CommandEnd extends Command { @Override diff --git a/src/main/java/net/md_5/bungee/command/CommandList.java b/src/main/java/net/md_5/bungee/command/CommandList.java index 44cc3b9d..62795e43 100644 --- a/src/main/java/net/md_5/bungee/command/CommandList.java +++ b/src/main/java/net/md_5/bungee/command/CommandList.java @@ -5,6 +5,9 @@ import net.md_5.bungee.BungeeCord; import net.md_5.bungee.ChatColor; import net.md_5.bungee.UserConnection; +/** + * Command to list all players connected to the proxy. + */ public class CommandList extends Command { @Override @@ -14,7 +17,6 @@ public class CommandList extends Command { for (UserConnection con : connections) { users.append(con.username); - users.append(ChatColor.RESET.toString()); users.append(", "); } diff --git a/src/main/java/net/md_5/bungee/command/CommandServer.java b/src/main/java/net/md_5/bungee/command/CommandServer.java index f22ff386..78112e7a 100644 --- a/src/main/java/net/md_5/bungee/command/CommandServer.java +++ b/src/main/java/net/md_5/bungee/command/CommandServer.java @@ -5,6 +5,9 @@ import net.md_5.bungee.BungeeCord; import net.md_5.bungee.ChatColor; import net.md_5.bungee.UserConnection; +/** + * Command to list and switch a player between availible servers. + */ public class CommandServer extends Command { @Override diff --git a/src/main/java/net/md_5/bungee/command/ConsoleCommandSender.java b/src/main/java/net/md_5/bungee/command/ConsoleCommandSender.java index debfcb36..0a165be5 100644 --- a/src/main/java/net/md_5/bungee/command/ConsoleCommandSender.java +++ b/src/main/java/net/md_5/bungee/command/ConsoleCommandSender.java @@ -2,6 +2,9 @@ package net.md_5.bungee.command; import net.md_5.bungee.ChatColor; +/** + * Command sender representing the proxy console. + */ public class ConsoleCommandSender implements CommandSender { public static final ConsoleCommandSender instance = new ConsoleCommandSender(); diff --git a/src/main/java/net/md_5/bungee/packet/DefinedPacket.java b/src/main/java/net/md_5/bungee/packet/DefinedPacket.java index 7d519e34..74c51be5 100644 --- a/src/main/java/net/md_5/bungee/packet/DefinedPacket.java +++ b/src/main/java/net/md_5/bungee/packet/DefinedPacket.java @@ -8,6 +8,11 @@ import java.io.DataOutput; import lombok.Delegate; import net.md_5.bungee.Util; +/** + * This class represents a packet which has been given a special definition. All + * subclasses can read and write to the backing byte array which can be + * retrieved via the {@link #getPacket()} method. + */ public abstract class DefinedPacket implements DataInput, DataOutput { private interface Overriden { @@ -44,6 +49,12 @@ public abstract class DefinedPacket implements DataInput, DataOutput { writeByte(id); } + /** + * Gets the bytes that make up this packet. + * + * @return the bytes which make up this packet, either the original byte + * array or the newly written one. + */ public byte[] getPacket() { return packet == null ? out.toByteArray() : packet; } diff --git a/src/main/java/net/md_5/bungee/packet/PacketInputStream.java b/src/main/java/net/md_5/bungee/packet/PacketInputStream.java index 7e99e207..3202ed2c 100644 --- a/src/main/java/net/md_5/bungee/packet/PacketInputStream.java +++ b/src/main/java/net/md_5/bungee/packet/PacketInputStream.java @@ -8,6 +8,10 @@ import java.io.InputStream; import net.md_5.bungee.Util; import net.minecraft.server.Packet; +/** + * A specialized input stream to parse packets using the Mojang packet + * definitions and then return them as a byte array. + */ public class PacketInputStream { private final DataInputStream dataInput; @@ -18,6 +22,12 @@ public class PacketInputStream { dataInput = new DataInputStream(tracker); } + /** + * Read an entire packet from the stream and return it as a byte array. + * + * @return the read packet + * @throws IOException when the underlying input stream throws an exception + */ public byte[] readPacket() throws IOException { tracker.out.reset(); int id = tracker.read(); @@ -33,6 +43,10 @@ public class PacketInputStream { } + /** + * Input stream which will wrap another stream and copy all bytes read to a + * {@link ByteArrayOutputStream}. + */ private class TrackingInputStream extends InputStream { private final ByteArrayOutputStream out = new ByteArrayOutputStream(); diff --git a/src/main/java/net/md_5/bungee/packet/VanillaPackets.java b/src/main/java/net/md_5/bungee/packet/VanillaPackets.java index 78d7c92f..5908f176 100644 --- a/src/main/java/net/md_5/bungee/packet/VanillaPackets.java +++ b/src/main/java/net/md_5/bungee/packet/VanillaPackets.java @@ -80,13 +80,25 @@ import net.minecraft.server.Packet7UseEntity; import net.minecraft.server.Packet8UpdateHealth; import net.minecraft.server.Packet9Respawn; +/** + * Class containing instances of all Vanilla Minecraft packets. + */ public class VanillaPackets { + /** + * Array of packet instances ordered by packet id. + */ public static Packet[] packets = new Packet[256]; - private static void map(int id, Class clazz) { + /** + * Adds a new instance of a packet class to the array storage. + * + * @param id of the packet to add + * @param clazz class of the packet to add + */ + private static void map(int id, Class clazz) { try { - packets[id] = (Packet) clazz.getDeclaredConstructor().newInstance(); + packets[id] = clazz.getDeclaredConstructor().newInstance(); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException ex) { $().severe("Could not register packet id " + Util.hex(id)); } diff --git a/src/main/java/net/md_5/bungee/plugin/Cancellable.java b/src/main/java/net/md_5/bungee/plugin/Cancellable.java index 3c7359fd..416ab7d2 100644 --- a/src/main/java/net/md_5/bungee/plugin/Cancellable.java +++ b/src/main/java/net/md_5/bungee/plugin/Cancellable.java @@ -1,8 +1,21 @@ package net.md_5.bungee.plugin; +/** + * An event which may be canceled and this be prevented from happening. + */ public interface Cancellable { - public void setCancelled(boolean cancelled); + /** + * Sets the canceled state of this event. + * + * @param canceled whether this event is canceled or not + */ + public void setCancelled(boolean canceled); + /** + * Gets the canceled state of this event. + * + * @return whether this event is canceled or not + */ public boolean isCancelled(); } diff --git a/src/main/java/net/md_5/bungee/plugin/ConnectEvent.java b/src/main/java/net/md_5/bungee/plugin/ConnectEvent.java deleted file mode 100644 index 71c3830a..00000000 --- a/src/main/java/net/md_5/bungee/plugin/ConnectEvent.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.md_5.bungee.plugin; - -import java.net.InetAddress; -import lombok.Data; - -@Data -public class ConnectEvent implements Cancellable { - - private boolean cancelled; - private String cancelReason; - private final String username; - private final InetAddress address; -} diff --git a/src/main/java/net/md_5/bungee/plugin/HandshakeEvent.java b/src/main/java/net/md_5/bungee/plugin/HandshakeEvent.java new file mode 100644 index 00000000..417f3a06 --- /dev/null +++ b/src/main/java/net/md_5/bungee/plugin/HandshakeEvent.java @@ -0,0 +1,30 @@ +package net.md_5.bungee.plugin; + +import java.net.InetAddress; +import lombok.Data; + +/** + * Event called once a remote connection has begun the login procedure. This + * event is ideal for IP banning, however must be used with care in other places + * such as logging at the username has not yet been verified with Mojang. + */ +@Data +public class HandshakeEvent implements Cancellable { + + /** + * Canceled state. + */ + private boolean cancelled; + /** + * Message to use when kicking if this event is canceled. + */ + private String cancelReason; + /** + * Username which the player wishes to use. + */ + private final String username; + /** + * IP address of the remote connection. + */ + private final InetAddress address; +} diff --git a/src/main/java/net/md_5/bungee/plugin/InvalidPluginException.java b/src/main/java/net/md_5/bungee/plugin/InvalidPluginException.java index 1710fe1c..53d46c1d 100644 --- a/src/main/java/net/md_5/bungee/plugin/InvalidPluginException.java +++ b/src/main/java/net/md_5/bungee/plugin/InvalidPluginException.java @@ -1,5 +1,8 @@ package net.md_5.bungee.plugin; +/** + * Exception thrown when a plugin could not be loaded for any reason. + */ public class InvalidPluginException extends RuntimeException { private static final long serialVersionUID = 1L; diff --git a/src/main/java/net/md_5/bungee/plugin/JavaPlugin.java b/src/main/java/net/md_5/bungee/plugin/JavaPlugin.java index 6b7a3e6c..8ec7e258 100644 --- a/src/main/java/net/md_5/bungee/plugin/JavaPlugin.java +++ b/src/main/java/net/md_5/bungee/plugin/JavaPlugin.java @@ -3,6 +3,9 @@ package net.md_5.bungee.plugin; import net.md_5.bungee.BungeeCord; import net.md_5.bungee.command.Command; +/** + * Base class which all proxy plugins should extend. + */ public abstract class JavaPlugin { /** @@ -26,13 +29,13 @@ public abstract class JavaPlugin { * Called when a user connects with their name and address. To keep things * simple this name has not been checked with minecraft.net. */ - public void onConnect(ConnectEvent event) { + public void onHandshake(HandshakeEvent event) { } /** - * Register a command. + * Register a command for use with the proxy. */ - protected void registerCommand(String label, Command command) { + protected final void registerCommand(String label, Command command) { BungeeCord.instance.commandMap.put(label, command); } } diff --git a/src/main/java/net/md_5/bungee/plugin/JavaPluginManager.java b/src/main/java/net/md_5/bungee/plugin/JavaPluginManager.java index b4cb648f..9a306583 100644 --- a/src/main/java/net/md_5/bungee/plugin/JavaPluginManager.java +++ b/src/main/java/net/md_5/bungee/plugin/JavaPluginManager.java @@ -12,11 +12,22 @@ import java.util.zip.ZipEntry; import lombok.Getter; import static net.md_5.bungee.Logger.$; +/** + * Plugin manager to handle loading and saving other JavaPlugin's. This class is + * itself a plugin for ease of use. + */ public class JavaPluginManager extends JavaPlugin { + /** + * Set of loaded plugins. + */ @Getter private final Set plugins = new HashSet<>(); + /** + * Load all plugins from the plugins folder. This method must only be called + * once per instance. + */ public void loadPlugins() { File dir = new File("plugins"); dir.mkdir(); @@ -58,9 +69,9 @@ public class JavaPluginManager extends JavaPlugin { } @Override - public void onConnect(ConnectEvent event) { + public void onHandshake(HandshakeEvent event) { for (JavaPlugin p : plugins) { - p.onConnect(event); + p.onHandshake(event); } } } diff --git a/src/main/java/net/md_5/bungee/plugin/PluginDescription.java b/src/main/java/net/md_5/bungee/plugin/PluginDescription.java index fea40c77..e7169682 100644 --- a/src/main/java/net/md_5/bungee/plugin/PluginDescription.java +++ b/src/main/java/net/md_5/bungee/plugin/PluginDescription.java @@ -5,6 +5,10 @@ import java.lang.reflect.Field; import lombok.Data; import org.yaml.snakeyaml.Yaml; +/** + * File which contains information about a plugin, its authors, and how to load + * it. + */ @Data public class PluginDescription {