diff --git a/src/main/java/io/github/simplexdev/simplexcore/SimplexCorePlugin.java b/src/main/java/io/github/simplexdev/simplexcore/SimplexCorePlugin.java
index 86178bf..a408707 100644
--- a/src/main/java/io/github/simplexdev/simplexcore/SimplexCorePlugin.java
+++ b/src/main/java/io/github/simplexdev/simplexcore/SimplexCorePlugin.java
@@ -42,7 +42,7 @@ public final class SimplexCorePlugin extends SimplexModule {
public void start() {
try {
getRegistry().register(this);
- getCommandLoader().classpath(Command_info.class).load(this);
+ getCommandLoader().classpath(this, Command_info.class).load();
getYamlConfig().reload();
getInternals().reload();
//
diff --git a/src/main/java/io/github/simplexdev/simplexcore/command/CommandLoader.java b/src/main/java/io/github/simplexdev/simplexcore/command/CommandLoader.java
index fa9eef3..cb83f5b 100644
--- a/src/main/java/io/github/simplexdev/simplexcore/command/CommandLoader.java
+++ b/src/main/java/io/github/simplexdev/simplexcore/command/CommandLoader.java
@@ -1,12 +1,13 @@
package io.github.simplexdev.simplexcore.command;
import io.github.simplexdev.api.annotations.CommandInfo;
-import io.github.simplexdev.simplexcore.command.defaults.DefaultCommand;
+import io.github.simplexdev.simplexcore.SimplexCorePlugin;
import io.github.simplexdev.simplexcore.module.SimplexModule;
import io.github.simplexdev.simplexcore.utils.ReflectionTools;
-import io.github.simplexdev.simplexcore.SimplexCorePlugin;
-import org.bukkit.Bukkit;
-import org.bukkit.command.*;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandMap;
+import org.bukkit.command.PluginCommand;
+import org.bukkit.command.TabCompleter;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.SimplePluginManager;
import org.jetbrains.annotations.NotNull;
@@ -20,7 +21,10 @@ import java.util.MissingResourceException;
public final class CommandLoader {
private Reflections reflections;
+ private ClassLoader classLoader;
+ private SimplexModule> plugin;
private static final CommandLoader instance = new CommandLoader();
+ private final Registry registry = new Registry();
/**
* @return A Singleton Pattern instance of this class.
@@ -38,15 +42,15 @@ public final class CommandLoader {
* If the class provided does not have the {@link CommandInfo} annotation, the loader will throw a new
* {@link MissingResourceException} and will not load your plugin's commands.
* If the class provided does not extend {@link SimplexCommand}, the loader will throw a new
- * {@link RuntimeException} and your commands will not be loaded.
+ * {@link CommandLoaderException} and your commands will not be loaded.
*
*
* @param clazz The command class to load from
* @return An instance of this where the classpath has been prepared for loading the commands.
*/
- public CommandLoader classpath(Class clazz) {
+ public CommandLoader classpath(SimplexModule> plugin, Class clazz) {
if (clazz == null) {
- throw new IllegalStateException("The class provided cannot be found!");
+ throw new IllegalArgumentException("The class provided cannot be found!");
}
if (!clazz.isAnnotationPresent(CommandInfo.class)) {
@@ -54,22 +58,26 @@ public final class CommandLoader {
}
if (!SimplexCommand.class.isAssignableFrom(clazz)) {
- throw new RuntimeException("Your command must extend SimplexCommand.class for it to be used as the reference point for loading commands.");
+ throw new CommandLoaderException("Your command must extend SimplexCommand.class for it to be used as the reference point for loading commands.");
}
- reflections = ReflectionTools.reflect(clazz);
+ this.reflections = ReflectionTools.reflect(clazz);
+ this.plugin = plugin;
+ this.classLoader = plugin.getClass().getClassLoader();
return this;
}
/**
* Loads all the commands from the specified classpath.
- * This should be used immediately after {@link CommandLoader#classpath(Class)} has been called.
+ * This should be used immediately after {@link CommandLoader#classpath(SimplexModule, Class)} has been called.
* If used before, an exception will be thrown, and your commands will not be loaded.
- *
- * @param plugin An instance of your plugin to assign as the parent plugin for each command.
*/
- public void load(SimplexModule> plugin) {
+ public void load() {
+ if (reflections == null || plugin == null || classLoader == null) {
+ throw new CommandLoaderException("Please run CommandLoader#classpath(SimplexModule, Class) first!");
+ }
+
reflections.getTypesAnnotatedWith(CommandInfo.class).forEach(annotated -> {
CommandInfo info = annotated.getDeclaredAnnotation(CommandInfo.class);
@@ -89,7 +97,7 @@ public final class CommandLoader {
return;
}
- PluginCommand command = Registry.create(plugin, info.name().toLowerCase());
+ PluginCommand command = registry.create(plugin, info.name().toLowerCase());
command.setAliases(Arrays.asList(info.aliases().split(",")));
command.setDescription(info.description());
command.setExecutor(getExecutorFromName(info.name()));
@@ -98,7 +106,7 @@ public final class CommandLoader {
command.setPermissionMessage(info.permissionMessage());
command.setTabCompleter(getTabFromName(info.name()));
command.setUsage(info.usage());
- Registry.registerCommand(command);
+ registry.registerCommand(command);
});
}
@@ -110,28 +118,27 @@ public final class CommandLoader {
* @param name The name of the command.
* @return An instance of the command class as a CommandExecutor.
*/
- public CommandExecutor getExecutorFromName(String name) {
- for (Class extends CommandExecutor> obj : reflections.getSubTypesOf(CommandExecutor.class)) {
+ private CommandExecutor getExecutorFromName(String name) {
+ for (Class extends SimplexCommand> obj : reflections.getSubTypesOf(SimplexCommand.class)) {
if (!obj.isAnnotationPresent(CommandInfo.class)) {
- SimplexCorePlugin.getInstance()
- .getLogger().warning(obj.getSimpleName()
+ plugin.getLogger().warning(obj.getSimpleName()
+ " is missing a required annotation: "
+ CommandInfo.class.getSimpleName());
+ continue;
}
CommandInfo info = obj.getDeclaredAnnotation(CommandInfo.class);
if (name.equalsIgnoreCase(info.name())) {
- try {
- Constructor extends CommandExecutor> constr = obj.getDeclaredConstructor();
- constr.setAccessible(true);
- return constr.newInstance();
- } catch (ReflectiveOperationException ignored) {
- return new DefaultCommand();
+ Constructor extends CommandExecutor> constr =
+ ReflectionTools.getDeclaredConstructor(obj, SimplexModule.class);
+ if (constr == null) {
+ throw new CommandLoaderException("Constructor does not exist! Are you extending SimplexCommand properly?");
}
+ return ReflectionTools.initConstructor(constr, plugin);
}
}
- throw new RuntimeException("Unable to assign a CommandExecutor from the provided classes!");
+ throw new CommandLoaderException("Unable to assign a CommandExecutor from the provided classes!");
}
/**
@@ -143,52 +150,50 @@ public final class CommandLoader {
* @return The command as an instance of TabCompleter
*/
@Nullable
- public TabCompleter getTabFromName(String name) {
- for (Class extends TabCompleter> obj : reflections.getSubTypesOf(TabCompleter.class)) {
+ private TabCompleter getTabFromName(String name) {
+ for (Class extends SimplexCommand> obj : reflections.getSubTypesOf(SimplexCommand.class)) {
if (!obj.isAnnotationPresent(CommandInfo.class)) {
- SimplexCorePlugin.getInstance()
- .getLogger().warning(obj.getSimpleName()
+ plugin.getLogger().warning(obj.getSimpleName()
+ " is missing required annotation: "
+ CommandInfo.class.getSimpleName());
continue;
}
CommandInfo info = obj.getDeclaredAnnotation(CommandInfo.class);
+
if (name.equalsIgnoreCase(info.name())) {
- try {
- Constructor extends TabCompleter> constr = obj.getDeclaredConstructor();
- constr.setAccessible(true);
- return constr.newInstance();
- } catch (ReflectiveOperationException ignored) {
- return new DefaultCommand();
+ Constructor extends TabCompleter> constr = ReflectionTools.getDeclaredConstructor(obj, SimplexModule.class);
+ if (constr == null) {
+ throw new CommandLoaderException("Constructor does not exist! Are you extending SimplexCommand properly?");
}
+ return ReflectionTools.initConstructor(constr, plugin);
}
}
- return null;
+ throw new CommandLoaderException("Unable to assign a TabCompleter from the provided classes!");
}
/**
* Registry class, which forces all necessary fields to accessible.
*/
- private static class Registry {
- private static final Constructor constructor;
- private static final Field cmdMapField;
+ private final class Registry {
+ private final Constructor constructor;
+ private final Field cmdMapField;
- static {
+ public Registry() {
constructor = ReflectionTools.getDeclaredConstructor(PluginCommand.class, String.class, Plugin.class);
cmdMapField = ReflectionTools.getDeclaredField(SimplePluginManager.class, "commandMap");
}
- public static PluginCommand create(@NotNull Plugin plugin, @NotNull String name) {
+ public PluginCommand create(@NotNull SimplexModule> plugin, @NotNull String name) {
return ReflectionTools.initConstructor(constructor, name, plugin);
}
- public static void registerCommand(PluginCommand command) {
+ public void registerCommand(PluginCommand command) {
try {
- CommandMap map = (CommandMap) cmdMapField.get(Bukkit.getPluginManager());
+ CommandMap map = (CommandMap) cmdMapField.get(plugin.getManager());
map.register(command.getName().toLowerCase(), command);
} catch (IllegalAccessException e) {
- throw new RuntimeException(e);
+ throw new CommandLoaderException(e);
}
}
}
diff --git a/src/main/java/io/github/simplexdev/simplexcore/command/CommandLoaderException.java b/src/main/java/io/github/simplexdev/simplexcore/command/CommandLoaderException.java
new file mode 100644
index 0000000..1965484
--- /dev/null
+++ b/src/main/java/io/github/simplexdev/simplexcore/command/CommandLoaderException.java
@@ -0,0 +1,19 @@
+package io.github.simplexdev.simplexcore.command;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+
+public class CommandLoaderException extends RuntimeException {
+ public CommandLoaderException() {
+ super("The Command Loader has encountered an exception and has failed to execute properly. " +
+ "Some commands may not be loaded.");
+ ExceptionUtils.getMessage(super.getCause());
+ }
+
+ public CommandLoaderException(String msg) {
+ super(msg);
+ }
+
+ public CommandLoaderException(Throwable th) {
+ super(th);
+ }
+}
diff --git a/src/main/java/io/github/simplexdev/simplexcore/command/SimplexCommand.java b/src/main/java/io/github/simplexdev/simplexcore/command/SimplexCommand.java
index 07f1c27..140d8d0 100644
--- a/src/main/java/io/github/simplexdev/simplexcore/command/SimplexCommand.java
+++ b/src/main/java/io/github/simplexdev/simplexcore/command/SimplexCommand.java
@@ -1,6 +1,7 @@
package io.github.simplexdev.simplexcore.command;
import io.github.simplexdev.simplexcore.SimplexCorePlugin;
+import io.github.simplexdev.simplexcore.module.SimplexModule;
import io.github.simplexdev.simplexcore.utils.Utilities;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -15,6 +16,15 @@ import java.util.List;
import java.util.UUID;
public abstract class SimplexCommand implements CommandExecutor, TabCompleter {
+ private final SimplexModule> plugin;
+
+ public SimplexCommand(SimplexModule> plugin) {
+ this.plugin = plugin;
+ }
+
+ public final SimplexModule> getPlugin() {
+ return plugin;
+ }
public boolean isPlayer(CommandSender sender) {
return sender instanceof Player;
@@ -22,6 +32,7 @@ public abstract class SimplexCommand implements CommandExecutor, TabCompleter {
/**
* Gets an online player from their username
+ *
* @param name The player's username
* @return An instance of {@link Player} which represents the online player in question.
*/
@@ -32,6 +43,7 @@ public abstract class SimplexCommand implements CommandExecutor, TabCompleter {
/**
* Gets an online player from their {@link UUID}.
+ *
* @param uuid The player's UUID
* @return An instance of {@link Player} which represents the online player in question.
*/
@@ -43,6 +55,7 @@ public abstract class SimplexCommand implements CommandExecutor, TabCompleter {
/**
* Gets an instance of {@link Player} based off an instance of {@link CommandSender}.
* This will be null if the condition {CommandSender instanceof Player} is false.
+ *
* @param sender The CommandSender to cast
* @return An instance of Player relating to CommandSender.
*/
@@ -54,7 +67,8 @@ public abstract class SimplexCommand implements CommandExecutor, TabCompleter {
/**
* Send a message or a group of messages to a {@link Player}.
* If you want the messages to send on new lines, put \n at the end of each message to send.
- * @param player The Player to send a message to
+ *
+ * @param player The Player to send a message to
* @param messages The messages to send.
*/
public void playerMsg(Player player, String... messages) {
@@ -66,7 +80,8 @@ public abstract class SimplexCommand implements CommandExecutor, TabCompleter {
/**
* Send a message or a group of messages to a {@link CommandSender}
* If you want the messages to send on new lines, put \n at the end of each message to send.
- * @param sender The CommandSender to send a message to.
+ *
+ * @param sender The CommandSender to send a message to.
* @param messages The messages to send.
*/
public void msg(CommandSender sender, String... messages) {
diff --git a/src/main/java/io/github/simplexdev/simplexcore/command/defaults/Command_info.java b/src/main/java/io/github/simplexdev/simplexcore/command/defaults/Command_info.java
index 7ddd0e9..b9de62e 100644
--- a/src/main/java/io/github/simplexdev/simplexcore/command/defaults/Command_info.java
+++ b/src/main/java/io/github/simplexdev/simplexcore/command/defaults/Command_info.java
@@ -1,16 +1,23 @@
package io.github.simplexdev.simplexcore.command.defaults;
import io.github.simplexdev.api.annotations.CommandInfo;
+import io.github.simplexdev.simplexcore.chat.Messages;
import io.github.simplexdev.simplexcore.command.SimplexCommand;
+import io.github.simplexdev.simplexcore.module.SimplexModule;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
@CommandInfo(name = "Info", description = "Gets info on this API / Library.", usage = "/", permission = "simplex.core.info")
public class Command_info extends SimplexCommand {
+
+ public Command_info(SimplexModule> plugin) {
+ super(plugin);
+ }
+
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
- sender.sendMessage("This is an API!");
+ sender.sendMessage(Messages.DISCORD.getMessage());
return true;
}
}
diff --git a/src/main/java/io/github/simplexdev/simplexcore/command/defaults/DefaultCommand.java b/src/main/java/io/github/simplexdev/simplexcore/command/defaults/DefaultCommand.java
index 6d09d8a..7443e01 100644
--- a/src/main/java/io/github/simplexdev/simplexcore/command/defaults/DefaultCommand.java
+++ b/src/main/java/io/github/simplexdev/simplexcore/command/defaults/DefaultCommand.java
@@ -2,12 +2,17 @@ package io.github.simplexdev.simplexcore.command.defaults;
import io.github.simplexdev.api.annotations.CommandInfo;
import io.github.simplexdev.simplexcore.command.SimplexCommand;
+import io.github.simplexdev.simplexcore.module.SimplexModule;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
@CommandInfo(name = "default", usage = "/", description = "Default plugin command.")
public final class DefaultCommand extends SimplexCommand {
+ public DefaultCommand(SimplexModule> plugin) {
+ super(plugin);
+ }
+
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
sender.sendMessage("If you are seeing this when running your command, your command didn't register properly.");