From 452311fb6967070fcde747df0730b664731b0d7c Mon Sep 17 00:00:00 2001 From: Tastybento Date: Thu, 28 Dec 2017 20:36:04 -0800 Subject: [PATCH] Boom! NMS is gone! (Again) Will it come back? Used reflection to get the command map from the server instead of using the NMS call. Also, more importantly, this commit enables CompositeCommands to auto-register their top-level command in the constructor. No need to separately obtain the command manager object. Yes, easy API. :-) --- pom.xml | 2 +- .../us/tastybento/bskyblock/BSkyBlock.java | 16 ++------- .../api/commands/CompositeCommand.java | 22 ++++++++++++ .../bskyblock/commands/AdminCommand.java | 7 ++-- .../bskyblock/commands/IslandCommand.java | 1 - .../bskyblock/managers/CommandsManager.java | 30 ++++++++++++++-- .../us/tastybento/bskyblock/util/Util.java | 35 ------------------- .../bskyblock/util/nms/NMSAbstraction.java | 21 ----------- .../util/nms/fallback/NMSHandler.java | 19 ---------- .../util/nms/v1_12_R1/NMSHandler.java | 21 ----------- src/test/java/bskyblock/TestBSkyBlock.java | 11 +++--- 11 files changed, 62 insertions(+), 123 deletions(-) delete mode 100644 src/main/java/us/tastybento/bskyblock/util/nms/NMSAbstraction.java delete mode 100644 src/main/java/us/tastybento/bskyblock/util/nms/fallback/NMSHandler.java delete mode 100644 src/main/java/us/tastybento/bskyblock/util/nms/v1_12_R1/NMSHandler.java diff --git a/pom.xml b/pom.xml index 22dc53c2c..3d0c7ffea 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ org.mockito mockito-all - 1.9.5 + 1.10.19 test diff --git a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java index 0b44850cb..f65a53d9e 100755 --- a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java +++ b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java @@ -21,8 +21,6 @@ import us.tastybento.bskyblock.listeners.PanelListener; import us.tastybento.bskyblock.managers.AddonsManager; import us.tastybento.bskyblock.managers.CommandsManager; import us.tastybento.bskyblock.managers.LocalesManager; -import us.tastybento.bskyblock.util.Util; -import us.tastybento.bskyblock.util.nms.NMSAbstraction; /** * Main BSkyBlock class - provides an island minigame in the sky @@ -66,8 +64,8 @@ public class BSkyBlock extends JavaPlugin implements BSBModule { // Set up commands commandsManager = new CommandsManager(); - commandsManager.registerCommand(this, new IslandCommand()); - commandsManager.registerCommand(this, new AdminCommand()); + new IslandCommand(); + new AdminCommand(); // These items have to be loaded when the server has done 1 tick. // Note Worlds are not loaded this early, so any Locations or World reference will be null @@ -206,16 +204,6 @@ public class BSkyBlock extends JavaPlugin implements BSBModule { return plugin; } - public NMSAbstraction getNMSHandler() { - NMSAbstraction nmsHandler = null; - try { - nmsHandler = Util.getNMSHandler(); - } catch(Exception e) { - e.printStackTrace(); - } - return nmsHandler; - } - public CommandsManager getCommandsManager() { return commandsManager; } diff --git a/src/main/java/us/tastybento/bskyblock/api/commands/CompositeCommand.java b/src/main/java/us/tastybento/bskyblock/api/commands/CompositeCommand.java index f1c848a0e..81d937d8b 100644 --- a/src/main/java/us/tastybento/bskyblock/api/commands/CompositeCommand.java +++ b/src/main/java/us/tastybento/bskyblock/api/commands/CompositeCommand.java @@ -90,6 +90,28 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi * @param string - aliases for this command */ public CompositeCommand(String label, String... string) { + super(label); + if (DEBUG) + Bukkit.getLogger().info("DEBUG: top level command registering..." + label); + this.setAliases(new ArrayList<>(Arrays.asList(string))); + this.parent = null; + setUsage(""); + this.subCommandLevel = 0; // Top level + this.subCommands = new LinkedHashMap<>(); + // Register command if it is not already registered + if (getPlugin().getCommand(label) == null) { + getPlugin().getCommandsManager().registerCommand(getPlugin(), this); + } + this.setup(); + if (!this.getSubCommand("help").isPresent() && !label.equals("help")) + new DefaultHelpCommand(this); + + } + + /** + * Used only for testing.... + */ + public CompositeCommand(BSkyBlock plugin, String label, String... string) { super(label); this.setAliases(new ArrayList<>(Arrays.asList(string))); this.parent = null; diff --git a/src/main/java/us/tastybento/bskyblock/commands/AdminCommand.java b/src/main/java/us/tastybento/bskyblock/commands/AdminCommand.java index 8510f7049..90f83bb54 100755 --- a/src/main/java/us/tastybento/bskyblock/commands/AdminCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/AdminCommand.java @@ -11,18 +11,19 @@ public class AdminCommand extends CompositeCommand { public AdminCommand() { super(Settings.ADMINCOMMAND, "bsb"); - this.setPermission(Settings.PERMPREFIX + "admin.*"); - this.setOnlyPlayer(false); } @Override public void setup() { + this.setPermission(Settings.PERMPREFIX + "admin.*"); + this.setOnlyPlayer(false); + this.setDescription("admin.help.description"); new AdminVersionCommand(this); } @Override public boolean execute(User user, List args) { - return true; + return this.getSubCommand("help").get().execute(user, args); } } diff --git a/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java b/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java index 57e633164..6cfbc227e 100755 --- a/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java @@ -43,7 +43,6 @@ public class IslandCommand extends CompositeCommand { @Override public boolean execute(User user, List args) { - user.sendLegacyMessage("You successfully did /is !"); if (!getPlugin().getIslands().hasIsland(user.getUniqueId())) { return this.getSubCommand("create").get().execute(user, args); } diff --git a/src/main/java/us/tastybento/bskyblock/managers/CommandsManager.java b/src/main/java/us/tastybento/bskyblock/managers/CommandsManager.java index abee1695f..3d9baa4fe 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/CommandsManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/CommandsManager.java @@ -1,20 +1,25 @@ package us.tastybento.bskyblock.managers; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.bukkit.Bukkit; import org.bukkit.command.Command; +import org.bukkit.command.CommandMap; -import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.BSBModule; public final class CommandsManager { + private static final boolean DEBUG = false; private Map> commands = new LinkedHashMap<>(); public void registerCommand(BSBModule module, Command command) { + if (DEBUG) + Bukkit.getLogger().info("DEBUG: registering command for " + module.getIdentifier() + " - " + command.getLabel()); List cmds = new ArrayList<>(); if (commands.containsKey(module)) { cmds = commands.get(module); @@ -22,17 +27,36 @@ public final class CommandsManager { cmds.add(command); commands.put(module, cmds); - BSkyBlock.getInstance().getNMSHandler().getServerCommandMap().register(command.getLabel(), command); + // Use reflection to obtain the commandMap method in Bukkit's server. It used to be visible, but isn't anymore. + try{ + Field commandMapField = Bukkit.getServer().getClass().getDeclaredField("commandMap"); + commandMapField.setAccessible(true); + CommandMap commandMap = (CommandMap) commandMapField.get(Bukkit.getServer()); + commandMap.register(command.getLabel(), command); + } + catch(Exception exception){ + Bukkit.getLogger().severe("Bukkit server commandMap method is not there! This means no commands can be registered!"); + } } public void unregisterCommand(Command command) { - + // TODO - is this ever going to be used? } + /** + * Get all of the commands for this + * @param module + * @return list of commands + */ public List getCommands(BSBModule module) { return commands.get(module); } + /** + * Get the command with the label + * @param label + * @return the command or null if it is not there + */ public Command getCommand(String label) { for (List cmds : commands.values()) { for (Command cmd : cmds) { diff --git a/src/main/java/us/tastybento/bskyblock/util/Util.java b/src/main/java/us/tastybento/bskyblock/util/Util.java index f2c4801d2..74fe1b4a4 100755 --- a/src/main/java/us/tastybento/bskyblock/util/Util.java +++ b/src/main/java/us/tastybento/bskyblock/util/Util.java @@ -1,7 +1,6 @@ package us.tastybento.bskyblock.util; import java.io.File; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -30,7 +29,6 @@ import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.commands.User; import us.tastybento.bskyblock.config.Settings; import us.tastybento.bskyblock.generators.IslandWorld; -import us.tastybento.bskyblock.util.nms.NMSAbstraction; /** * A set of utility methods @@ -42,7 +40,6 @@ public class Util { private static BSkyBlock plugin = BSkyBlock.getInstance(); private static String serverVersion = null; - private static NMSAbstraction nmsHandler = null; /** * Returns the server version @@ -56,38 +53,6 @@ public class Util { return serverVersion; } - /** - * Checks what version the server is running and picks the appropriate NMS handler, or fallback - * @return NMSAbstraction class - * @throws ClassNotFoundException - * @throws IllegalArgumentException - * @throws SecurityException - * @throws InstantiationException - * @throws IllegalAccessException - * @throws InvocationTargetException - * @throws NoSuchMethodException - */ - public static NMSAbstraction getNMSHandler() throws ClassNotFoundException, IllegalArgumentException, - SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - String pluginPackageName = plugin.getClass().getPackage().getName(); - String version = getServerVersion(); - Class clazz; - try { - clazz = Class.forName(pluginPackageName + ".util.nms." + version + ".NMSHandler"); - } catch (Exception e) { - plugin.getLogger().info("No NMS Handler found for " + version + ", falling back to Bukkit API."); - clazz = Class.forName(pluginPackageName + ".util.nms.fallback.NMSHandler"); - } - // Check if we have a NMSAbstraction implementing class at that location. - if (NMSAbstraction.class.isAssignableFrom(clazz)) { - if (nmsHandler == null) nmsHandler = (NMSAbstraction) clazz.getConstructor().newInstance(); - return nmsHandler; - } else { - throw new IllegalStateException("Class " + clazz.getName() + " does not implement NMSAbstraction"); - } - } - /** * Converts a serialized location to a Location. Returns null if string is * empty diff --git a/src/main/java/us/tastybento/bskyblock/util/nms/NMSAbstraction.java b/src/main/java/us/tastybento/bskyblock/util/nms/NMSAbstraction.java deleted file mode 100644 index dd9d9001d..000000000 --- a/src/main/java/us/tastybento/bskyblock/util/nms/NMSAbstraction.java +++ /dev/null @@ -1,21 +0,0 @@ -package us.tastybento.bskyblock.util.nms; - -import org.bukkit.command.CommandMap; -import org.bukkit.entity.Player; - -public interface NMSAbstraction { - - /** - * Send an action bar message to player - * @param player - * @param message - */ - void sendActionBar(Player player, String message); - - /** - * Returns the active {@link org.bukkit.command.CommandMap} of the Server. - * It is used by the {@link us.tastybento.bskyblock.api.commands.CompositeCommand} to register itself. - * @return the active CommandMap of the server - */ - CommandMap getServerCommandMap(); -} diff --git a/src/main/java/us/tastybento/bskyblock/util/nms/fallback/NMSHandler.java b/src/main/java/us/tastybento/bskyblock/util/nms/fallback/NMSHandler.java deleted file mode 100644 index e97bd4f2d..000000000 --- a/src/main/java/us/tastybento/bskyblock/util/nms/fallback/NMSHandler.java +++ /dev/null @@ -1,19 +0,0 @@ -package us.tastybento.bskyblock.util.nms.fallback; - -import org.bukkit.command.CommandMap; -import org.bukkit.entity.Player; - -import us.tastybento.bskyblock.util.nms.NMSAbstraction; - -public class NMSHandler implements NMSAbstraction { - - @Override - public void sendActionBar(Player player, String message) { - //TODO use /title command - } - - @Override - public CommandMap getServerCommandMap() { - return null; - } -} diff --git a/src/main/java/us/tastybento/bskyblock/util/nms/v1_12_R1/NMSHandler.java b/src/main/java/us/tastybento/bskyblock/util/nms/v1_12_R1/NMSHandler.java deleted file mode 100644 index 9d2ce8ab8..000000000 --- a/src/main/java/us/tastybento/bskyblock/util/nms/v1_12_R1/NMSHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package us.tastybento.bskyblock.util.nms.v1_12_R1; - -import org.bukkit.Bukkit; -import org.bukkit.command.CommandMap; -import org.bukkit.craftbukkit.v1_12_R1.CraftServer; -import org.bukkit.entity.Player; - -import us.tastybento.bskyblock.util.nms.NMSAbstraction; - -public class NMSHandler implements NMSAbstraction { - - @Override - public void sendActionBar(Player player, String message) { - - } - - @Override - public CommandMap getServerCommandMap() { - return ((CraftServer) Bukkit.getServer()).getCommandMap(); - } -} diff --git a/src/test/java/bskyblock/TestBSkyBlock.java b/src/test/java/bskyblock/TestBSkyBlock.java index d54ec40b5..ce81e652e 100644 --- a/src/test/java/bskyblock/TestBSkyBlock.java +++ b/src/test/java/bskyblock/TestBSkyBlock.java @@ -25,6 +25,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mockito; +import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.commands.CompositeCommand; import us.tastybento.bskyblock.api.commands.User; import us.tastybento.bskyblock.api.events.IslandBaseEvent; @@ -36,11 +37,10 @@ public class TestBSkyBlock { private final UUID playerUUID = UUID.randomUUID(); private static CommandSender sender; private static Player player; + private static BSkyBlock plugin; @BeforeClass public static void setUp() { - - //Plugin plugin = mock(Plugin.class); //Mockito.doReturn(plugin).when(BSkyBlock.getPlugin()); //Mockito.when().thenReturn(plugin); World world = mock(World.class); @@ -58,8 +58,9 @@ public class TestBSkyBlock { player = mock(Player.class); Mockito.when(player.hasPermission(Settings.PERMPREFIX + "default.permission")).thenReturn(true); + plugin = mock(BSkyBlock.class); + //Mockito.when(plugin.getServer()).thenReturn(server); - //Mockito.doReturn(Logger.getAnonymousLogger()).when(plugin.getLogger()); } @Test @@ -140,7 +141,7 @@ public class TestBSkyBlock { private class TestCommand extends CompositeCommand { public TestCommand() { - super("test", "t", "tt"); + super(plugin, "test", "t", "tt"); this.setParameters("test.params"); } @@ -243,7 +244,7 @@ public class TestBSkyBlock { private class Test3ArgsCommand extends CompositeCommand { public Test3ArgsCommand() { - super("args", ""); + super(plugin, "args", ""); } @Override