Some command improvements

Removing commands on component/plugin disable
This commit is contained in:
Norbi Peti 2019-01-11 00:41:26 +01:00
parent 245f6bbf59
commit a6d1122f7f
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
7 changed files with 361 additions and 278 deletions

View file

@ -4,7 +4,6 @@
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" filepath="$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" /> <module fileurl="file://$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" filepath="$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" />
<module fileurl="file://$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" filepath="$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" /> <module fileurl="file://$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" filepath="$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" />
<module fileurl="file://$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" filepath="$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" />
<module fileurl="file://$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" filepath="$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" /> <module fileurl="file://$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" filepath="$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" />
</modules> </modules>
</component> </component>

View file

@ -21,41 +21,27 @@ public class CommandCaller implements CommandExecutor {
public static void RegisterCommand(TBMCCommandBase cmd) throws Exception { public static void RegisterCommand(TBMCCommandBase cmd) throws Exception {
if (instance == null) if (instance == null)
instance = new CommandCaller(); instance = new CommandCaller();
String topcmd = cmd.GetCommandPath(); String[] topcmd = new String[1]; //Holds out param
if (topcmd == null) PluginCommand pc = getPluginCommand(cmd, topcmd);
throw new Exception("Command " + cmd.getClass().getSimpleName() + " has no command path!"); pc.setExecutor(instance);
if (cmd.getPlugin() == null) String[] helptext = cmd.GetHelpText(topcmd[0]);
throw new Exception("Command " + cmd.GetCommandPath() + " has no plugin!"); if (helptext == null || helptext.length == 0)
int i; throw new Exception("Command " + cmd.GetCommandPath() + " has no help text!");
if ((i = topcmd.indexOf(' ')) != -1) // Get top-level command pc.setUsage(helptext.length > 1 ? helptext[1] : helptext[0]);
topcmd = topcmd.substring(0, i);
{
PluginCommand pc = ((JavaPlugin) cmd.getPlugin()).getCommand(topcmd);
if (pc == null)
throw new Exception("Top level command " + topcmd + " not registered in plugin.yml for plugin: "
+ cmd.getPlugin().getName());
else {
pc.setExecutor(instance);
String[] helptext = cmd.GetHelpText(topcmd);
if (helptext == null || helptext.length == 0)
throw new Exception("Command " + cmd.GetCommandPath() + " has no help text!");
pc.setUsage(helptext.length > 1 ? helptext[1] : helptext[0]);
}
}
} }
@Override @Override
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) { public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
String path = command.getName().toLowerCase(); StringBuilder path = new StringBuilder(command.getName().toLowerCase());
for (String arg : args) for (String arg : args)
path += " " + arg; path.append(" ").append(arg);
TBMCCommandBase cmd = TBMCChatAPI.GetCommands().get(path); TBMCCommandBase cmd = TBMCChatAPI.GetCommands().get(path.toString());
int argc = 0; int argc = 0;
String[] subcmds = null; String[] subcmds = null;
while (cmd == null && (subcmds = TBMCChatAPI.GetSubCommands(path, sender)).length == 0 && path.contains(" ")) { while (cmd == null && (subcmds = TBMCChatAPI.GetSubCommands(path.toString(), sender)).length == 0 && path.toString().contains(" ")) {
path = path.substring(0, path.lastIndexOf(' ')); path = new StringBuilder(path.substring(0, path.toString().lastIndexOf(' ')));
argc++; argc++;
cmd = TBMCChatAPI.GetCommands().get(path); cmd = TBMCChatAPI.GetCommands().get(path.toString());
} }
if (cmd == null) { if (cmd == null) {
if (subcmds.length > 0) //Subcmds will always have value here (see assignment above) if (subcmds.length > 0) //Subcmds will always have value here (see assignment above)
@ -85,4 +71,37 @@ public class CommandCaller implements CommandExecutor {
} }
return true; return true;
} }
public static void UnregisterCommand(TBMCCommandBase cmd) throws Exception {
PluginCommand pc = getPluginCommand(cmd, null);
pc.setExecutor(null); //Sets the executor to this plugin
}
/**
* Gets the plugin command from the TBMC command.
*
* @param cmd The TBMC command
* @param out_topcmd An array with at least 1 elements or null
* @return The Bukkit plugin command - an exception is generated if null
* @throws Exception If the command isn't set up properly (or a different error)
*/
public static PluginCommand getPluginCommand(TBMCCommandBase cmd, String[] out_topcmd) throws Exception {
String topcmd = cmd.GetCommandPath();
if (topcmd == null)
throw new Exception("Command " + cmd.getClass().getSimpleName() + " has no command path!");
if (cmd.getPlugin() == null)
throw new Exception("Command " + cmd.GetCommandPath() + " has no plugin!");
int i;
if ((i = topcmd.indexOf(' ')) != -1) // Get top-level command
topcmd = topcmd.substring(0, i);
if (out_topcmd != null && out_topcmd.length > 0)
out_topcmd[0] = topcmd;
{
PluginCommand pc = ((JavaPlugin) cmd.getPlugin()).getCommand(topcmd);
if (pc == null)
throw new Exception("Top level command " + topcmd + " not registered in plugin.yml for plugin: "
+ cmd.getPlugin().getName());
return pc;
}
}
} }

View file

@ -1,117 +1,125 @@
package buttondevteam.core; package buttondevteam.core;
import buttondevteam.component.restart.RestartComponent; import buttondevteam.component.restart.RestartComponent;
import buttondevteam.component.updater.PluginUpdater; import buttondevteam.component.updater.PluginUpdater;
import buttondevteam.component.updater.PluginUpdaterComponent; import buttondevteam.component.updater.PluginUpdaterComponent;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.Channel; import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.ChatRoom; import buttondevteam.lib.chat.ChatRoom;
import buttondevteam.lib.chat.Color; import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase; import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase; import buttondevteam.lib.player.TBMCPlayerBase;
import com.earth2me.essentials.Essentials; import com.earth2me.essentials.Essentials;
import net.milkbowl.vault.permission.Permission; import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.BlockCommandSender; import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.Command;
import org.bukkit.entity.Player; import org.bukkit.command.CommandSender;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.RegisteredServiceProvider;
import javax.annotation.Nullable; import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException; import javax.annotation.Nullable;
import java.nio.file.Files; import java.io.File;
import java.nio.file.StandardCopyOption; import java.io.IOException;
import java.util.Arrays; import java.nio.file.Files;
import java.util.Optional; import java.nio.file.StandardCopyOption;
import java.util.UUID; import java.util.Arrays;
import java.util.logging.Logger; import java.util.Optional;
import java.util.UUID;
public class MainPlugin extends JavaPlugin { import java.util.logging.Logger;
public static MainPlugin Instance;
@Nullable public class MainPlugin extends JavaPlugin {
public static Permission permission; public static MainPlugin Instance;
public static boolean Test; @Nullable
public static Essentials ess; public static Permission permission;
public static boolean Test;
private Logger logger; public static Essentials ess;
@Override private Logger logger;
public void onEnable() {
// Logs "Plugin Enabled", registers commands @Override
Instance = this; public void onEnable() {
PluginDescriptionFile pdf = getDescription(); // Logs "Plugin Enabled", registers commands
logger = getLogger(); Instance = this;
setupPermissions(); PluginDescriptionFile pdf = getDescription();
Test = getConfig().getBoolean("test", true); logger = getLogger();
saveConfig(); setupPermissions();
Component.registerComponent(this, new PluginUpdaterComponent()); Test = getConfig().getBoolean("test", true);
Component.registerComponent(this, new RestartComponent()); saveConfig();
ComponentManager.enableComponents(); Component.registerComponent(this, new PluginUpdaterComponent());
TBMCChatAPI.AddCommand(this, MemberCommand.class); Component.registerComponent(this, new RestartComponent());
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this); ComponentManager.enableComponents();
ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender TBMCChatAPI.AddCommand(this, MemberCommand.class);
? TBMCPlayer.getPlayer(new UUID(0, 0), TBMCPlayer.class) : null)); //Console & cmdblocks TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof Player ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender
? TBMCPlayer.getPlayer(((Player) sender).getUniqueId(), TBMCPlayer.class) : null)); //Players, has higher priority ? TBMCPlayer.getPlayer(new UUID(0, 0), TBMCPlayer.class) : null)); //Console & cmdblocks
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class); ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof Player
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fOOC§f", Color.White, "ooc", null)); ? TBMCPlayer.getPlayer(((Player) sender).getUniqueId(), TBMCPlayer.class) : null)); //Players, has higher priority
Channel.GlobalChat.IDs = new String[]{"g"}; //Support /g as well TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class);
TBMCChatAPI.RegisterChatChannel( TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fOOC§f", Color.White, "ooc", null));
Channel.AdminChat = new Channel("§cADMIN§f", Color.Red, "a", Channel.inGroupFilter(null))); Channel.GlobalChat.IDs = new String[]{"g"}; //Support /g as well
TBMCChatAPI.RegisterChatChannel( TBMCChatAPI.RegisterChatChannel(
Channel.ModChat = new Channel("§9MOD§f", Color.Blue, "mod", Channel.inGroupFilter("mod"))); Channel.AdminChat = new Channel("§cADMIN§f", Color.Red, "a", Channel.inGroupFilter(null)));
TBMCChatAPI.RegisterChatChannel(new Channel("§6DEV§f", Color.Gold, "dev", Channel.inGroupFilter("developer"))); TBMCChatAPI.RegisterChatChannel(
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§cRED§f", Color.DarkRed, "red")); Channel.ModChat = new Channel("§9MOD§f", Color.Blue, "mod", Channel.inGroupFilter("mod")));
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§6ORANGE§f", Color.Gold, "orange")); TBMCChatAPI.RegisterChatChannel(new Channel("§6DEV§f", Color.Gold, "dev", Channel.inGroupFilter("developer")));
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§eYELLOW§f", Color.Yellow, "yellow")); TBMCChatAPI.RegisterChatChannel(new ChatRoom("§cRED§f", Color.DarkRed, "red"));
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§aGREEN§f", Color.Green, "green")); TBMCChatAPI.RegisterChatChannel(new ChatRoom("§6ORANGE§f", Color.Gold, "orange"));
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§bBLUE§f", Color.Blue, "blue")); TBMCChatAPI.RegisterChatChannel(new ChatRoom("§eYELLOW§f", Color.Yellow, "yellow"));
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§5PURPLE§f", Color.DarkPurple, "purple")); TBMCChatAPI.RegisterChatChannel(new ChatRoom("§aGREEN§f", Color.Green, "green"));
try { TBMCChatAPI.RegisterChatChannel(new ChatRoom("§bBLUE§f", Color.Blue, "blue"));
Files.write(new File("plugins", "plugins.txt").toPath(), Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(p -> (CharSequence) p.getDataFolder().getName())::iterator); TBMCChatAPI.RegisterChatChannel(new ChatRoom("§5PURPLE§f", Color.DarkPurple, "purple"));
} catch (IOException e) { try {
TBMCCoreAPI.SendException("Failed to write plugin list!", e); Files.write(new File("plugins", "plugins.txt").toPath(), Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(p -> (CharSequence) p.getDataFolder().getName())::iterator);
} } catch (IOException e) {
ess = Essentials.getPlugin(Essentials.class); TBMCCoreAPI.SendException("Failed to write plugin list!", e);
new RandomTP().onEnable(this); //It registers it's command }
logger.info(pdf.getName() + " has been Enabled (V." + pdf.getVersion() + ") Test: " + Test + "."); ess = Essentials.getPlugin(Essentials.class);
} new RandomTP().onEnable(this); //It registers it's command
logger.info(pdf.getName() + " has been Enabled (V." + pdf.getVersion() + ") Test: " + Test + ".");
@Override }
public void onDisable() {
ComponentManager.disableComponents(); @Override
logger.info("Saving player data..."); public void onDisable() {
TBMCPlayerBase.savePlayers(); ComponentManager.disableComponents();
logger.info("Player data saved."); logger.info("Saving player data...");
new Thread(() -> { TBMCPlayerBase.savePlayers();
File[] files = PluginUpdater.updatedir.listFiles(); logger.info("Player data saved.");
if (files == null) new Thread(() -> {
return; File[] files = PluginUpdater.updatedir.listFiles();
System.out.println("Updating " + files.length + " plugins..."); if (files == null)
for (File file : files) { return;
try { System.out.println("Updating " + files.length + " plugins...");
Files.move(file.toPath(), new File("plugins", file.getName()).toPath(), StandardCopyOption.REPLACE_EXISTING); for (File file : files) {
System.out.println("Updated " + file.getName()); try {
} catch (IOException e) { Files.move(file.toPath(), new File("plugins", file.getName()).toPath(), StandardCopyOption.REPLACE_EXISTING);
e.printStackTrace(); System.out.println("Updated " + file.getName());
} } catch (IOException e) {
} e.printStackTrace();
System.out.println("Update complete!"); }
}).start(); }
} System.out.println("Update complete!");
}).start();
private boolean setupPermissions() { }
RegisteredServiceProvider<Permission> permissionProvider = getServer().getServicesManager()
.getRegistration(Permission.class); private boolean setupPermissions() {
if (permissionProvider != null) { RegisteredServiceProvider<Permission> permissionProvider = getServer().getServicesManager()
permission = permissionProvider.getProvider(); .getRegistration(Permission.class);
} if (permissionProvider != null) {
return (permission != null); permission = permissionProvider.getProvider();
} }
} return (permission != null);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
sender.sendMessage("§cThis command isn't available."); //In theory, unregistered commands use this method
return true;
}
}

View file

@ -1,6 +1,7 @@
package buttondevteam.lib.architecture; package buttondevteam.lib.architecture;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.TBMCChatAPI;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.experimental.var; import lombok.experimental.var;
@ -32,6 +33,7 @@ public abstract class ButtonPlugin extends JavaPlugin {
pluginDisable(); pluginDisable();
saveConfig(); saveConfig();
iConfig.resetConfigurationCache(); iConfig.resetConfigurationCache();
TBMCChatAPI.RemoveCommands(this);
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e); TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e);
} }

View file

@ -5,7 +5,6 @@ import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException; import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.chat.TBMCCommandBase; import buttondevteam.lib.chat.TBMCCommandBase;
import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.experimental.var; import lombok.experimental.var;
@ -26,7 +25,7 @@ public abstract class Component {
@Getter @Getter
private boolean enabled = false; private boolean enabled = false;
@Getter(value = AccessLevel.PROTECTED) @Getter
@NonNull @NonNull
private JavaPlugin plugin; private JavaPlugin plugin;
@NonNull @NonNull
@ -131,6 +130,7 @@ public abstract class Component {
component.disable(); component.disable();
component.plugin.saveConfig(); component.plugin.saveConfig();
component.config.resetConfigurationCache(); component.config.resetConfigurationCache();
TBMCChatAPI.RemoveCommands(component);
} }
} }

View file

@ -6,6 +6,7 @@ import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.TBMCChatPreprocessEvent; import buttondevteam.lib.TBMCChatPreprocessEvent;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.TBMCSystemChatEvent; import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.Channel.RecipientTestResult; import buttondevteam.lib.chat.Channel.RecipientTestResult;
import lombok.val; import lombok.val;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -119,10 +120,8 @@ public class TBMCChatAPI {
continue; continue;
TBMCCommandBase c = cmd.newInstance(); TBMCCommandBase c = cmd.newInstance();
c.plugin = plugin; c.plugin = plugin;
if (HasNulls(plugin, c)) CommandCaller.RegisterCommand(c); //Will check for nulls
continue;
commands.put(c.GetCommandPath(), c); commands.put(c.GetCommandPath(), c);
CommandCaller.RegisterCommand(c);
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getName(), e); TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getName(), e);
} }
@ -155,55 +154,106 @@ public class TBMCChatAPI {
else else
c = thecmdclass.newInstance(); c = thecmdclass.newInstance();
c.plugin = plugin; c.plugin = plugin;
if (HasNulls(plugin, c)) CommandCaller.RegisterCommand(c); //Will check for nulls
return;
commands.put(c.GetCommandPath(), c); commands.put(c.GetCommandPath(), c);
CommandCaller.RegisterCommand(c);
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while registering command " + thecmdclass.getSimpleName(), e); TBMCCoreAPI.SendException("An error occured while registering command " + thecmdclass.getSimpleName(), e);
} }
} } //TODO: onCommand(CommandSender sender, String alias, int arg1, String arg2) (planned for a while)
/** /**
* <p> * <p>
* This method adds a plugin's command to help and sets it's executor. * This method adds a plugin's command to help and sets its executor.
* </p> * </p>
* <p> * <p>
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console. * The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a message to console.
* </p> * </p>
* <p> * <p>
* <i>Using this method after the server is done loading will have no effect.</i> * <i>Using this method after the server is done loading will have no effect.</i>
* </p> * </p>
* *
* @param plugin * @param plugin
* The caller plugin * The caller plugin
* @param cmd * @param cmd
* The command to add * The command to add
*/ */
public static void AddCommand(JavaPlugin plugin, TBMCCommandBase cmd) { public static void AddCommand(JavaPlugin plugin, TBMCCommandBase cmd) {
if (HasNulls(plugin, cmd))
return;
// plugin.getLogger().info("Registering command /" + cmd.GetCommandPath() + " for " + plugin.getName());
try { try {
if (plugin == null) throw new IllegalArgumentException("The plugin is null!");
if (cmd == null) throw new IllegalArgumentException("The command is null!");
cmd.plugin = plugin; cmd.plugin = plugin;
CommandCaller.RegisterCommand(cmd); //Checks for other nulls
commands.put(cmd.GetCommandPath(), cmd); commands.put(cmd.GetCommandPath(), cmd);
CommandCaller.RegisterCommand(cmd);
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.GetCommandPath(), e); TBMCCoreAPI.SendException("An error occured while registering command " + (cmd == null ? "n u l l" : cmd.GetCommandPath()), e);
} }
} }
private static boolean HasNulls(JavaPlugin plugin, TBMCCommandBase cmd) { /**
if (cmd == null) { * <p>
TBMCCoreAPI.SendException("An error occured while registering a command for plugin " + plugin.getName(), * This method adds a plugin's command to help and sets its executor.
new Exception("The command is null!")); * </p>
return true; * <p>
} else if (cmd.GetCommandPath() == null) { * The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a message to console.
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getClass().getSimpleName() * </p>
+ " for plugin " + plugin.getName(), new Exception("The command path is null!")); * <p>
return true; * <i>Using this method after the server is done loading will have no effect.</i>
* </p>
*
* @param component The caller component
* @param cmd The command to add
*/
public static void AddCommand(Component component, TBMCCommandBase cmd) {
try {
if (component == null) throw new IllegalArgumentException("The component is null!");
if (cmd == null) throw new IllegalArgumentException("The command is null!");
cmd.plugin = component.getPlugin();
cmd.component = component;
CommandCaller.RegisterCommand(cmd); //Checks for other nulls
commands.put(cmd.GetCommandPath(), cmd);
} catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while registering command " + (cmd == null ? "n u l l" : cmd.GetCommandPath()), e);
} }
return false; }
/**
* Removes all commands from the plugin
*
* @param plugin The plugin to remove commands from
*/
public static void RemoveCommands(JavaPlugin plugin) {
commands.values().removeIf(c -> {
try {
if (c.plugin == plugin) {
CommandCaller.UnregisterCommand(c);
return true; //Remove
}
return false;
} catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while unregistering commands for " + plugin.getName(), e);
return true; //Remove if it couldn't get the plugin command
}
});
}
/**
* Removes all commands from the component
*
* @param component The component to remove commands from
*/
public static void RemoveCommands(Component component) {
commands.values().removeIf(c -> {
try {
if (c.component == component) {
CommandCaller.UnregisterCommand(c);
return true; //Remove
}
return false;
} catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while unregistering commands for " + component.getClass().getSimpleName(), e);
return true; //Remove if it couldn't get the plugin command
}
});
} }
/** /**

View file

@ -1,106 +1,111 @@
package buttondevteam.lib.chat; package buttondevteam.lib.chat;
import javassist.Modifier; import buttondevteam.lib.architecture.Component;
import org.bukkit.command.CommandSender; import javassist.Modifier;
import org.bukkit.plugin.Plugin; import lombok.Getter;
import org.bukkit.command.CommandSender;
import java.util.function.Function; import org.bukkit.plugin.Plugin;
/** import java.util.function.Function;
* Extend this class to create new TBMCCommand and use {@link TBMCChatAPI#AddCommand(org.bukkit.plugin.java.JavaPlugin, TBMCCommandBase)} to add it. <u><b>Note:</b></u> The command path (command name
* and subcommand arguments) will be the class name by default, removing any "command" from it. To change it (especially for subcommands), use the path field in the {@link CommandClass} annotation. /**
* * Extend this class to create new TBMCCommand and use {@link TBMCChatAPI#AddCommand(org.bukkit.plugin.java.JavaPlugin, TBMCCommandBase)} to add it. <u><b>Note:</b></u> The command path (command name
* @author Norbi * and subcommand arguments) will be the class name by default, removing any "command" from it. To change it (especially for subcommands), use the path field in the {@link CommandClass} annotation.
* *
*/ * @author Norbi
@TBMCCommandEnforcer *
public abstract class TBMCCommandBase { */
@TBMCCommandEnforcer
public TBMCCommandBase() { public abstract class TBMCCommandBase {
path = getcmdpath();
modonly = ismodonly(); public TBMCCommandBase() {
} path = getcmdpath();
modonly = ismodonly();
public abstract boolean OnCommand(CommandSender sender, String alias, String[] args); }
public abstract String[] GetHelpText(String alias); public abstract boolean OnCommand(CommandSender sender, String alias, String[] args);
private final String path; public abstract String[] GetHelpText(String alias);
/** private final String path;
* The command's path, or name if top-level command.<br>
* For example:<br> /**
* "u admin updateplugin" or "u" for the top level one<br> * The command's path, or name if top-level command.<br>
* <u>The path must be lowercase!</u><br> * For example:<br>
* <b>Abstract classes with no {@link CommandClass} annotations will be ignored.</b> * "u admin updateplugin" or "u" for the top level one<br>
* * <u>The path must be lowercase!</u><br>
* @return The command path, <i>which is the command class name by default</i> (removing any "command" from it) - Change via the {@link CommandClass} annotation * <b>Abstract classes with no {@link CommandClass} annotations will be ignored.</b>
*/ *
public final String GetCommandPath() { * @return The command path, <i>which is the command class name by default</i> (removing any "command" from it) - Change via the {@link CommandClass} annotation
return path; */
} public final String GetCommandPath() {
return path;
private String getcmdpath() { }
if (!getClass().isAnnotationPresent(CommandClass.class))
throw new RuntimeException( private String getcmdpath() {
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!"); if (!getClass().isAnnotationPresent(CommandClass.class))
Function<Class<?>, String> getFromClass = cl -> cl.getSimpleName().toLowerCase().replace("commandbase", "") // <-- ... throw new RuntimeException(
.replace("command", ""); "No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
String path = getClass().getAnnotation(CommandClass.class).path(), Function<Class<?>, String> getFromClass = cl -> cl.getSimpleName().toLowerCase().replace("commandbase", "") // <-- ...
prevpath = path = path.length() == 0 ? getFromClass.apply(getClass()) : path; .replace("command", "");
for (Class<?> cl = getClass().getSuperclass(); cl != null String path = getClass().getAnnotation(CommandClass.class).path(),
&& !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl prevpath = path = path.length() == 0 ? getFromClass.apply(getClass()) : path;
.getSuperclass()) { // for (Class<?> cl = getClass().getSuperclass(); cl != null
String newpath; && !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl
if (!cl.isAnnotationPresent(CommandClass.class) .getSuperclass()) { //
|| (newpath = cl.getAnnotation(CommandClass.class).path()).length() == 0 String newpath;
|| newpath.equals(prevpath)) { if (!cl.isAnnotationPresent(CommandClass.class)
if ((Modifier.isAbstract(cl.getModifiers()) && !cl.isAnnotationPresent(CommandClass.class)) || (newpath = cl.getAnnotation(CommandClass.class).path()).length() == 0
|| cl.getAnnotation(CommandClass.class).excludeFromPath()) // <-- || newpath.equals(prevpath)) {
continue; if ((Modifier.isAbstract(cl.getModifiers()) && !cl.isAnnotationPresent(CommandClass.class))
newpath = getFromClass.apply(cl); || cl.getAnnotation(CommandClass.class).excludeFromPath()) // <--
} continue;
path = (prevpath = newpath) + " " + path; newpath = getFromClass.apply(cl);
} }
return path; path = (prevpath = newpath) + " " + path;
} }
return path;
Plugin plugin; // Used By TBMCChatAPI }
public final Plugin getPlugin() { // Used by CommandCaller (ButtonChat) Plugin plugin; // Used By TBMCChatAPI
return plugin;
} public final Plugin getPlugin() { // Used by CommandCaller (ButtonChat)
return plugin;
public final boolean isPlayerOnly() { }
return this instanceof PlayerCommandBase ||
(this instanceof OptionallyPlayerCommandBase && public final boolean isPlayerOnly() {
(!getClass().isAnnotationPresent(OptionallyPlayerCommandClass.class) return this instanceof PlayerCommandBase ||
|| getClass().getAnnotation(OptionallyPlayerCommandClass.class).playerOnly())); (this instanceof OptionallyPlayerCommandBase &&
} (!getClass().isAnnotationPresent(OptionallyPlayerCommandClass.class)
|| getClass().getAnnotation(OptionallyPlayerCommandClass.class).playerOnly()));
private final boolean modonly; }
/** private final boolean modonly;
* Returns true if this class' or any superclass' modOnly property is set to true.
*/ /**
public final boolean isModOnly() { * Returns true if this class' or any superclass' modOnly property is set to true.
return modonly; */
} public final boolean isModOnly() {
return modonly;
private boolean ismodonly() { }
if (!getClass().isAnnotationPresent(CommandClass.class))
throw new RuntimeException( private boolean ismodonly() {
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!"); if (!getClass().isAnnotationPresent(CommandClass.class))
boolean modOnly = getClass().getAnnotation(CommandClass.class).modOnly(); throw new RuntimeException(
for (Class<?> cl = getClass().getSuperclass(); cl != null "No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
&& !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl boolean modOnly = getClass().getAnnotation(CommandClass.class).modOnly();
.getSuperclass()) { // for (Class<?> cl = getClass().getSuperclass(); cl != null
if (cl.isAnnotationPresent(CommandClass.class) && !modOnly && !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl
&& cl.getAnnotation(CommandClass.class).modOnly()) { .getSuperclass()) { //
modOnly = true; if (cl.isAnnotationPresent(CommandClass.class) && !modOnly
break; && cl.getAnnotation(CommandClass.class).modOnly()) {
} modOnly = true;
} break;
return modOnly; }
} }
} return modOnly;
}
@Getter
Component component; //May be null
}