From b4105f80819f04fd54b7c137a5478b3b014e8bb0 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 12 Jan 2013 12:03:59 +1100 Subject: [PATCH] Finish up command API, with permissions and aliases! --- .../java/net/md_5/bungee/api}/ChatColor.java | 2 +- .../net/md_5/bungee/api/plugin/Command.java | 42 ++++++++++++ .../md_5/bungee/api/plugin/PluginManager.java | 67 +++++++++++++++++++ .../main/java/net/md_5/bungee/BungeeCord.java | 1 + .../java/net/md_5/bungee/Configuration.java | 1 + .../java/net/md_5/bungee/InitialHandler.java | 2 +- .../net/md_5/bungee/command/CommandAlert.java | 2 +- .../md_5/bungee/command/CommandBungee.java | 2 +- .../net/md_5/bungee/command/CommandEnd.java | 2 +- .../net/md_5/bungee/command/CommandIP.java | 2 +- .../net/md_5/bungee/command/CommandList.java | 2 +- .../net/md_5/bungee/command/CommandMotd.java | 2 +- .../md_5/bungee/command/CommandReload.java | 2 +- .../md_5/bungee/command/CommandServer.java | 2 +- .../bungee/command/ConsoleCommandSender.java | 2 +- 15 files changed, 122 insertions(+), 11 deletions(-) rename {proxy/src/main/java/net/md_5/bungee => api/src/main/java/net/md_5/bungee/api}/ChatColor.java (99%) create mode 100644 api/src/main/java/net/md_5/bungee/api/plugin/Command.java diff --git a/proxy/src/main/java/net/md_5/bungee/ChatColor.java b/api/src/main/java/net/md_5/bungee/api/ChatColor.java similarity index 99% rename from proxy/src/main/java/net/md_5/bungee/ChatColor.java rename to api/src/main/java/net/md_5/bungee/api/ChatColor.java index ca157672c..a72c01d14 100644 --- a/proxy/src/main/java/net/md_5/bungee/ChatColor.java +++ b/api/src/main/java/net/md_5/bungee/api/ChatColor.java @@ -1,4 +1,4 @@ -package net.md_5.bungee; +package net.md_5.bungee.api; import java.util.regex.Pattern; diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/Command.java b/api/src/main/java/net/md_5/bungee/api/plugin/Command.java new file mode 100644 index 000000000..d89a910d6 --- /dev/null +++ b/api/src/main/java/net/md_5/bungee/api/plugin/Command.java @@ -0,0 +1,42 @@ +package net.md_5.bungee.api.plugin; + +import lombok.AccessLevel; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import net.md_5.bungee.api.CommandSender; + +/** + * A command that can be executed by a {@link CommandSender}. + */ +@Data +@RequiredArgsConstructor(access = AccessLevel.NONE) +public abstract class Command +{ + + private final String name; + private final String permission; + private final String[] aliases; + + /** + * Construct a new command. + * + * @param name primary name of this command + * @param permission the permission node required to execute this command, + * null or empty string allows it to be executed by everyone + * @param aliases aliases which map back to this command + */ + public Command(String name, String permission, String... aliases) + { + this.name = name; + this.permission = permission; + this.aliases = aliases; + } + + /** + * Execute this command with the specified sender and arguments. + * + * @param sender the executor of this command + * @param args arguments used to invoke this command + */ + public abstract void execute(CommandSender sender, String[] args); +} diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java index 8974c0a25..89ec5aa06 100644 --- a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java +++ b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java @@ -7,12 +7,16 @@ import java.io.File; import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Level; +import java.util.regex.Pattern; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import org.yaml.snakeyaml.Yaml; @@ -23,9 +27,72 @@ import org.yaml.snakeyaml.Yaml; public class PluginManager { + private static final Pattern argsSplit = Pattern.compile(" "); + /*========================================================================*/ private final Yaml yaml = new Yaml(); private final EventBus eventBus = new EventBus(); private final Map plugins = new HashMap<>(); + private final Map commandMap = new HashMap<>(); + + /** + * Register a command so that it may be executed. + * + * @param command the command to register + */ + public void registerCommand(Command command) + { + commandMap.put(command.getName(), command); + for (String alias : command.getAliases()) + { + commandMap.put(alias, command); + } + } + + /** + * Unregister a command so it will no longer be executed. + * + * @param command the command to unregister + */ + public void unregisterCommand(Command command) + { + commandMap.values().remove(command); + } + + /** + * Execute a command if it is registered, else return false. + * + * @param sender the sender executing the command + * @param commandLine the complete command line including command name and + * arguments + * @return whether the command was handled + */ + public boolean dispatchCommand(CommandSender sender, String commandLine) + { + String[] split = argsSplit.split(commandLine); + Command command = commandMap.get(split[0]); + if (command == null) + { + return false; + } + + String permission = command.getPermission(); + if (permission != null && !permission.isEmpty() && !sender.hasPermission(permission)) + { + sender.sendMessage(ChatColor.RED + "You do not have permission to execute this command!"); + return true; + } + + String[] args = Arrays.copyOfRange(split, 1, split.length); + try + { + command.execute(sender, args); + } catch (Exception ex) + { + sender.sendMessage(ChatColor.RED + "An internal error occurred whilst executing this command, please check the console log for details."); + ProxyServer.getInstance().getLogger().log(Level.WARNING, "Error in dispatching command", ex); + } + return true; + } /** * Returns the {@link Plugin} objects corresponding to all loaded plugins. diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java index b25ef1805..c8d9fdf2a 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -16,6 +16,7 @@ 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.api.ChatColor; import net.md_5.bungee.command.*; import net.md_5.bungee.packet.DefinedPacket; import net.md_5.bungee.packet.PacketFAPluginMessage; diff --git a/proxy/src/main/java/net/md_5/bungee/Configuration.java b/proxy/src/main/java/net/md_5/bungee/Configuration.java index 23ec2af37..01b507b0c 100644 --- a/proxy/src/main/java/net/md_5/bungee/Configuration.java +++ b/proxy/src/main/java/net/md_5/bungee/Configuration.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; import static net.md_5.bungee.Logger.$; +import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.command.CommandSender; import net.md_5.bungee.command.ConsoleCommandSender; import org.yaml.snakeyaml.DumperOptions; diff --git a/proxy/src/main/java/net/md_5/bungee/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/InitialHandler.java index 28872d341..b2fe6660c 100644 --- a/proxy/src/main/java/net/md_5/bungee/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/InitialHandler.java @@ -1,12 +1,12 @@ package net.md_5.bungee; -import java.io.BufferedOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.util.ArrayList; import java.util.List; import javax.crypto.SecretKey; +import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.packet.Packet2Handshake; import net.md_5.bungee.packet.PacketFCEncryptionResponse; import net.md_5.bungee.packet.PacketFDEncryptionRequest; diff --git a/proxy/src/main/java/net/md_5/bungee/command/CommandAlert.java b/proxy/src/main/java/net/md_5/bungee/command/CommandAlert.java index 270e89c1f..f8d1c761b 100644 --- a/proxy/src/main/java/net/md_5/bungee/command/CommandAlert.java +++ b/proxy/src/main/java/net/md_5/bungee/command/CommandAlert.java @@ -1,9 +1,9 @@ package net.md_5.bungee.command; import net.md_5.bungee.BungeeCord; -import net.md_5.bungee.ChatColor; import net.md_5.bungee.Permission; import net.md_5.bungee.UserConnection; +import net.md_5.bungee.api.ChatColor; public class CommandAlert extends Command { diff --git a/proxy/src/main/java/net/md_5/bungee/command/CommandBungee.java b/proxy/src/main/java/net/md_5/bungee/command/CommandBungee.java index 8ea902dfa..7e34debb6 100644 --- a/proxy/src/main/java/net/md_5/bungee/command/CommandBungee.java +++ b/proxy/src/main/java/net/md_5/bungee/command/CommandBungee.java @@ -1,7 +1,7 @@ package net.md_5.bungee.command; import net.md_5.bungee.BungeeCord; -import net.md_5.bungee.ChatColor; +import net.md_5.bungee.api.ChatColor; public class CommandBungee extends Command { diff --git a/proxy/src/main/java/net/md_5/bungee/command/CommandEnd.java b/proxy/src/main/java/net/md_5/bungee/command/CommandEnd.java index 3750dfd1f..570d308cf 100644 --- a/proxy/src/main/java/net/md_5/bungee/command/CommandEnd.java +++ b/proxy/src/main/java/net/md_5/bungee/command/CommandEnd.java @@ -1,8 +1,8 @@ package net.md_5.bungee.command; import net.md_5.bungee.BungeeCord; -import net.md_5.bungee.ChatColor; import net.md_5.bungee.Permission; +import net.md_5.bungee.api.ChatColor; /** * Command to terminate the proxy instance. May only be used by the console. diff --git a/proxy/src/main/java/net/md_5/bungee/command/CommandIP.java b/proxy/src/main/java/net/md_5/bungee/command/CommandIP.java index d1b75f4be..755f7b6c7 100644 --- a/proxy/src/main/java/net/md_5/bungee/command/CommandIP.java +++ b/proxy/src/main/java/net/md_5/bungee/command/CommandIP.java @@ -1,9 +1,9 @@ package net.md_5.bungee.command; import net.md_5.bungee.BungeeCord; -import net.md_5.bungee.ChatColor; import net.md_5.bungee.Permission; import net.md_5.bungee.UserConnection; +import net.md_5.bungee.api.ChatColor; public class CommandIP extends Command { diff --git a/proxy/src/main/java/net/md_5/bungee/command/CommandList.java b/proxy/src/main/java/net/md_5/bungee/command/CommandList.java index 42584a4db..988106dd6 100644 --- a/proxy/src/main/java/net/md_5/bungee/command/CommandList.java +++ b/proxy/src/main/java/net/md_5/bungee/command/CommandList.java @@ -2,8 +2,8 @@ package net.md_5.bungee.command; import java.util.Collection; import net.md_5.bungee.BungeeCord; -import net.md_5.bungee.ChatColor; import net.md_5.bungee.UserConnection; +import net.md_5.bungee.api.ChatColor; /** * Command to list all players connected to the proxy. diff --git a/proxy/src/main/java/net/md_5/bungee/command/CommandMotd.java b/proxy/src/main/java/net/md_5/bungee/command/CommandMotd.java index 3d26c0667..3acab4c17 100644 --- a/proxy/src/main/java/net/md_5/bungee/command/CommandMotd.java +++ b/proxy/src/main/java/net/md_5/bungee/command/CommandMotd.java @@ -1,8 +1,8 @@ package net.md_5.bungee.command; import net.md_5.bungee.BungeeCord; -import net.md_5.bungee.ChatColor; import net.md_5.bungee.Permission; +import net.md_5.bungee.api.ChatColor; /** * Command to set a temp copy of the motd in real-time without stopping the diff --git a/proxy/src/main/java/net/md_5/bungee/command/CommandReload.java b/proxy/src/main/java/net/md_5/bungee/command/CommandReload.java index 18c922d0d..337fdf1eb 100644 --- a/proxy/src/main/java/net/md_5/bungee/command/CommandReload.java +++ b/proxy/src/main/java/net/md_5/bungee/command/CommandReload.java @@ -1,8 +1,8 @@ package net.md_5.bungee.command; import net.md_5.bungee.BungeeCord; -import net.md_5.bungee.ChatColor; import net.md_5.bungee.Permission; +import net.md_5.bungee.api.ChatColor; public class CommandReload extends Command { diff --git a/proxy/src/main/java/net/md_5/bungee/command/CommandServer.java b/proxy/src/main/java/net/md_5/bungee/command/CommandServer.java index a2956b567..f7bdce4db 100644 --- a/proxy/src/main/java/net/md_5/bungee/command/CommandServer.java +++ b/proxy/src/main/java/net/md_5/bungee/command/CommandServer.java @@ -2,8 +2,8 @@ package net.md_5.bungee.command; import java.util.Collection; import net.md_5.bungee.BungeeCord; -import net.md_5.bungee.ChatColor; import net.md_5.bungee.UserConnection; +import net.md_5.bungee.api.ChatColor; /** * Command to list and switch a player between available servers. diff --git a/proxy/src/main/java/net/md_5/bungee/command/ConsoleCommandSender.java b/proxy/src/main/java/net/md_5/bungee/command/ConsoleCommandSender.java index 79401a030..52d2216c4 100644 --- a/proxy/src/main/java/net/md_5/bungee/command/ConsoleCommandSender.java +++ b/proxy/src/main/java/net/md_5/bungee/command/ConsoleCommandSender.java @@ -1,6 +1,6 @@ package net.md_5.bungee.command; -import net.md_5.bungee.ChatColor; +import net.md_5.bungee.api.ChatColor; /** * Command sender representing the proxy console.