Fixed list config, converted old cmds, removed old cmd system
#87 Fixed permission issue without perm plugin (#74) Checking Bukkit perms if Vault says no, so PEX works with default perms (#80) Most of the time it just means checking the perm plugin twice since the PermissibleBase is injected usually
This commit is contained in:
parent
1a4829e894
commit
a1919c04d0
24 changed files with 127 additions and 654 deletions
|
@ -24,6 +24,7 @@
|
||||||
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
||||||
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
||||||
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
||||||
|
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
||||||
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.10" level="project" />
|
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.10" level="project" />
|
||||||
<orderEntry type="library" name="Maven: com.google.code.findbugs:annotations:2.0.1" level="project" />
|
<orderEntry type="library" name="Maven: com.google.code.findbugs:annotations:2.0.1" level="project" />
|
||||||
<orderEntry type="library" name="Maven: org.javassist:javassist:3.20.0-GA" level="project" />
|
<orderEntry type="library" name="Maven: org.javassist:javassist:3.20.0-GA" level="project" />
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
package buttondevteam.core;
|
|
||||||
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandExecutor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.command.PluginCommand;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class CommandCaller implements CommandExecutor {
|
|
||||||
|
|
||||||
private CommandCaller() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private static CommandCaller instance;
|
|
||||||
|
|
||||||
public static void RegisterCommand(TBMCCommandBase cmd) throws Exception {
|
|
||||||
if (instance == null)
|
|
||||||
instance = new CommandCaller();
|
|
||||||
String[] topcmd = new String[1]; //Holds out param
|
|
||||||
PluginCommand pc = getPluginCommand(cmd, topcmd);
|
|
||||||
pc.setExecutor(instance);
|
|
||||||
String[] helptext = cmd.GetHelpText(topcmd[0]);
|
|
||||||
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
|
|
||||||
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
|
|
||||||
StringBuilder path = new StringBuilder(command.getName().toLowerCase());
|
|
||||||
for (String arg : args)
|
|
||||||
path.append(" ").append(arg);
|
|
||||||
TBMCCommandBase cmd = TBMCChatAPI.GetCommands().get(path.toString());
|
|
||||||
int argc = 0;
|
|
||||||
String[] subcmds = null;
|
|
||||||
while (cmd == null && (subcmds = TBMCChatAPI.GetSubCommands(path.toString(), sender)).length == 0 && path.toString().contains(" ")) {
|
|
||||||
path = new StringBuilder(path.substring(0, path.toString().lastIndexOf(' ')));
|
|
||||||
argc++;
|
|
||||||
cmd = TBMCChatAPI.GetCommands().get(path.toString());
|
|
||||||
}
|
|
||||||
if (cmd == null) {
|
|
||||||
if (subcmds.length > 0) //Subcmds will always have value here (see assignment above)
|
|
||||||
sender.sendMessage(subcmds);
|
|
||||||
else {
|
|
||||||
final String errormsg = "§cYou don't have access to any of this command's subcommands or it doesn't have any.";
|
|
||||||
sender.sendMessage(errormsg);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (cmd.isModOnly() && (MainPlugin.permission != null ? !MainPlugin.permission.has(sender, "tbmc.admin") : !sender.isOp())) {
|
|
||||||
sender.sendMessage("§cYou need to be a mod to use this command.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
final String[] cmdargs = args.length > 0 ? Arrays.copyOfRange(args, args.length - argc, args.length) : args;
|
|
||||||
try {
|
|
||||||
if (!cmd.OnCommand(sender, alias, cmdargs)) {
|
|
||||||
if (cmd.GetHelpText(alias) == null) {
|
|
||||||
sender.sendMessage("Wrong usage, but there's no help text! Error is being reported to devs.");
|
|
||||||
throw new NullPointerException("GetHelpText is null for comand /" + cmd.GetCommandPath());
|
|
||||||
} else
|
|
||||||
sender.sendMessage(cmd.GetHelpText(alias));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
TBMCCoreAPI.SendException("Failed to execute command /" + cmd.GetCommandPath() + " with arguments "
|
|
||||||
+ Arrays.toString(cmdargs), e);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -84,6 +84,15 @@ public class MainPlugin extends ButtonPlugin {
|
||||||
return getIConfig().getData("test", false);
|
return getIConfig().getData("test", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By default, the plugin uses Vault for all command permission checks, but this can have issues (with PEX for example) where default permissions aren't granted.
|
||||||
|
* When this setting is off, the plugin uses Bukkit's built-in way of handling permissions, which usually works fine for players.
|
||||||
|
* You can also grant chroma.command.* to each player (mod-only commands need another permission, chroma.mod).
|
||||||
|
*/
|
||||||
|
/*public ConfigData<Boolean> useVaultForCommands() {
|
||||||
|
return getIConfig().getData("useVaultForCommands", true);
|
||||||
|
}*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pluginEnable() {
|
public void pluginEnable() {
|
||||||
// Logs "Plugin Enabled", registers commands
|
// Logs "Plugin Enabled", registers commands
|
||||||
|
|
|
@ -64,11 +64,15 @@ public class MemberComponent extends Component<MainPlugin> implements Listener {
|
||||||
if (permission != null && !permission.playerInGroup(event.getPlayer(), memberGroup().get())
|
if (permission != null && !permission.playerInGroup(event.getPlayer(), memberGroup().get())
|
||||||
&& (new Date(event.getPlayer().getFirstPlayed()).toInstant().plus(registeredForDays().get(), ChronoUnit.DAYS).isBefore(Instant.now())
|
&& (new Date(event.getPlayer().getFirstPlayed()).toInstant().plus(registeredForDays().get(), ChronoUnit.DAYS).isBefore(Instant.now())
|
||||||
|| event.getPlayer().getStatistic(playtime.getKey()) > playtime.getValue() * playedHours().get())) {
|
|| event.getPlayer().getStatistic(playtime.getKey()) > playtime.getValue() * playedHours().get())) {
|
||||||
if (permission.playerAddGroup(null, event.getPlayer(), memberGroup().get())) {
|
try {
|
||||||
event.getPlayer().sendMessage("§bYou are a member now. YEEHAW");
|
if (permission.playerAddGroup(null, event.getPlayer(), memberGroup().get())) {
|
||||||
MainPlugin.Instance.getLogger().info("Added " + event.getPlayer().getName() + " as a member.");
|
event.getPlayer().sendMessage("§bYou are a member now. YEEHAW");
|
||||||
} else {
|
MainPlugin.Instance.getLogger().info("Added " + event.getPlayer().getName() + " as a member.");
|
||||||
MainPlugin.Instance.getLogger().warning("Failed to assign the member role! Please make sure the member group exists or disable the component if it's unused.");
|
} else {
|
||||||
|
MainPlugin.Instance.getLogger().warning("Failed to assign the member role! Please make sure the member group exists or disable the component if it's unused.");
|
||||||
|
}
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
MainPlugin.Instance.getLogger().warning("Failed to assign the member role! Groups are not supported by the permissions implementation.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package buttondevteam.core.component.randomtp;
|
package buttondevteam.core.component.randomtp;
|
||||||
|
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.chat.Command2;
|
||||||
import buttondevteam.lib.chat.CommandClass;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.ICommand2MC;
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
@ -11,8 +10,11 @@ import org.bukkit.entity.Player;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@SuppressWarnings("FieldCanBeLocal")@CommandClass
|
@SuppressWarnings("FieldCanBeLocal")@CommandClass(helpText = {
|
||||||
public class RandomTP extends TBMCCommandBase
|
"§6---- Random Teleport ----",
|
||||||
|
"Teleport player to random location within world border. Every five players teleport to the same general area, and then a new general area is randomly selected for the next five players."
|
||||||
|
})
|
||||||
|
public class RandomTP extends ICommand2MC
|
||||||
{
|
{
|
||||||
private final int radius = 70; //set how far apart the five teleport positions are
|
private final int radius = 70; //set how far apart the five teleport positions are
|
||||||
|
|
||||||
|
@ -53,10 +55,8 @@ public class RandomTP extends TBMCCommandBase
|
||||||
|
|
||||||
/*================================================================================================*/
|
/*================================================================================================*/
|
||||||
|
|
||||||
public void onEnable(Component component)
|
public void onEnable(RandomTPComponent component)
|
||||||
{
|
{
|
||||||
TBMCChatAPI.AddCommand(component, this);
|
|
||||||
|
|
||||||
world = Bukkit.getWorld("World");
|
world = Bukkit.getWorld("World");
|
||||||
border = world.getWorldBorder();
|
border = world.getWorldBorder();
|
||||||
Logger logger = component.getPlugin().getLogger();
|
Logger logger = component.getPlugin().getLogger();
|
||||||
|
@ -68,22 +68,10 @@ public class RandomTP extends TBMCCommandBase
|
||||||
|
|
||||||
/*================================================================================================*/
|
/*================================================================================================*/
|
||||||
|
|
||||||
public String[] GetHelpText(String alias)
|
@Command2.Subcommand
|
||||||
|
public boolean def(CommandSender sender, Player player)
|
||||||
{
|
{
|
||||||
return new String[]
|
if (sender.isOp()) return rtp(player);
|
||||||
{
|
|
||||||
"§6---- Random Teleport ----",
|
|
||||||
"Teleport player to random location within world border. Every five players teleport to the same general area, and then a new general area is randomly selected for the next five players."
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/*================================================================================================*/
|
|
||||||
|
|
||||||
public boolean OnCommand(CommandSender sender, String command, String[] args)
|
|
||||||
{
|
|
||||||
if (args.length == 0) return false;
|
|
||||||
|
|
||||||
if (sender.isOp()) return rtp(Bukkit.getPlayer(args[0]));
|
|
||||||
|
|
||||||
else sender.sendMessage("§7 hmm, " + sender.getName() + "... " + sender.getName() + "... nope, no operator permissions.");
|
else sender.sendMessage("§7 hmm, " + sender.getName() + "... " + sender.getName() + "... nope, no operator permissions.");
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,9 @@ import buttondevteam.lib.architecture.ComponentMetadata;
|
||||||
public class RandomTPComponent extends Component<MainPlugin> {
|
public class RandomTPComponent extends Component<MainPlugin> {
|
||||||
@Override
|
@Override
|
||||||
protected void enable() {
|
protected void enable() {
|
||||||
new RandomTP().onEnable(this); //It registers it's command
|
var rtp = new RandomTP();
|
||||||
|
registerCommand(rtp);
|
||||||
|
rtp.onEnable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,48 +1,43 @@
|
||||||
package buttondevteam.core.component.restart;
|
package buttondevteam.core.component.restart;
|
||||||
|
|
||||||
import buttondevteam.core.component.channel.Channel;
|
import buttondevteam.core.component.channel.Channel;
|
||||||
|
import buttondevteam.lib.chat.Command2;
|
||||||
import buttondevteam.lib.chat.CommandClass;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
|
import buttondevteam.lib.chat.ICommand2MC;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
@CommandClass(path = "primerestart", modOnly = true)
|
@CommandClass(path = "primerestart", modOnly = true, helpText = {
|
||||||
|
"§6---- Prime restart ----", //
|
||||||
|
"Restarts the server as soon as nobody is online.", //
|
||||||
|
"To be loud, type something after, like /primerestart lol (it doesn't matter what you write)", //
|
||||||
|
"To be silent, don't type anything" //
|
||||||
|
})
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PrimeRestartCommand extends TBMCCommandBase {
|
public class PrimeRestartCommand extends ICommand2MC {
|
||||||
private final RestartComponent component;
|
private final RestartComponent component;
|
||||||
@Override
|
|
||||||
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
|
public void def(CommandSender sender, @Command2.TextArg @Command2.OptionalArg String somethingrandom) {
|
||||||
loud = args.length > 0;
|
loud = somethingrandom != null;
|
||||||
if (Bukkit.getOnlinePlayers().size() > 0) {
|
if (Bukkit.getOnlinePlayers().size() > 0) {
|
||||||
sender.sendMessage("§bPlayers online, restart delayed.");
|
sender.sendMessage("§bPlayers online, restart delayed.");
|
||||||
if (loud)
|
if (loud)
|
||||||
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, ChatColor.DARK_RED + "The server will restart as soon as nobody is online.", component.getRestartBroadcast());
|
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, ChatColor.DARK_RED + "The server will restart as soon as nobody is online.", component.getRestartBroadcast());
|
||||||
plsrestart = true;
|
plsrestart = true;
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage("§bNobody is online. Restarting now.");
|
sender.sendMessage("§bNobody is online. Restarting now.");
|
||||||
if (loud)
|
if (loud)
|
||||||
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, "§cNobody is online. Restarting server.", component.getRestartBroadcast());
|
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, "§cNobody is online. Restarting server.", component.getRestartBroadcast());
|
||||||
Bukkit.spigot().restart();
|
Bukkit.spigot().restart();
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static boolean plsrestart = false;
|
private static boolean plsrestart = false;
|
||||||
@Getter
|
@Getter
|
||||||
private static boolean loud = false;
|
private static boolean loud = false;
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] GetHelpText(String alias) {
|
|
||||||
return new String[]{ //
|
|
||||||
"§6---- Prime restart ----", //
|
|
||||||
"Restarts the server as soon as nobody is online.", //
|
|
||||||
"To be loud, type something after, like /primerestart lol (it doesn't matter what you write)", //
|
|
||||||
"To be silent, don't type anything" //
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ public class RestartComponent extends Component<MainPlugin> implements Listener
|
||||||
@Override
|
@Override
|
||||||
public void enable() {
|
public void enable() {
|
||||||
registerCommand(new ScheduledRestartCommand(this));
|
registerCommand(new ScheduledRestartCommand(this));
|
||||||
TBMCChatAPI.AddCommand(this, new PrimeRestartCommand(this));
|
registerCommand(new PrimeRestartCommand(this));
|
||||||
registerListener(this);
|
registerListener(this);
|
||||||
restartBroadcast = TBMCSystemChatEvent.BroadcastTarget.add("restartCountdown");
|
restartBroadcast = TBMCSystemChatEvent.BroadcastTarget.add("restartCountdown");
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,15 @@ package buttondevteam.core.component.updater;
|
||||||
import buttondevteam.core.MainPlugin;
|
import buttondevteam.core.MainPlugin;
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import buttondevteam.lib.architecture.ComponentMetadata;
|
import buttondevteam.lib.architecture.ComponentMetadata;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads plugin updates built from their source using JitPack - older code
|
* Downloads plugin updates built from their source using JitPack - doesn't work anymore
|
||||||
*/
|
*/
|
||||||
@ComponentMetadata(enabledByDefault = false)
|
@ComponentMetadata(enabledByDefault = false)
|
||||||
public class PluginUpdaterComponent extends Component<MainPlugin> { //TODO: Config
|
public class PluginUpdaterComponent extends Component<MainPlugin> { //TODO: Config
|
||||||
@Override
|
@Override
|
||||||
public void enable() {
|
public void enable() {
|
||||||
TBMCChatAPI.AddCommand(this, new UpdatePluginCommand());
|
registerCommand(new UpdatePluginCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2,40 +2,41 @@ package buttondevteam.core.component.updater;
|
||||||
|
|
||||||
import buttondevteam.core.MainPlugin;
|
import buttondevteam.core.MainPlugin;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import buttondevteam.lib.chat.Command2;
|
||||||
import buttondevteam.lib.chat.CommandClass;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
import buttondevteam.lib.chat.ICommand2MC;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
@CommandClass(modOnly = true)
|
@CommandClass(modOnly = true)
|
||||||
public class UpdatePluginCommand extends TBMCCommandBase {
|
public class UpdatePluginCommand extends ICommand2MC {
|
||||||
@Override
|
public void def(CommandSender sender, @Command2.OptionalArg String plugin, @Command2.OptionalArg String branch) {
|
||||||
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
|
Bukkit.getScheduler().runTaskAsynchronously(MainPlugin.Instance, () -> {
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(MainPlugin.Instance, () -> {
|
if (plugin == null) {
|
||||||
if (args.length == 0) {
|
sender.sendMessage("Downloading plugin names...");
|
||||||
sender.sendMessage("Downloading plugin names...");
|
boolean first = true;
|
||||||
boolean first = true;
|
for (String plugin2 : PluginUpdater.GetPluginNames()) {
|
||||||
for (String plugin : PluginUpdater.GetPluginNames()) {
|
if (first) {
|
||||||
if (first) {
|
sender.sendMessage("§6---- Plugin names ----");
|
||||||
sender.sendMessage("§6---- Plugin names ----");
|
first = false;
|
||||||
first = false;
|
}
|
||||||
}
|
sender.sendMessage("- " + plugin2);
|
||||||
sender.sendMessage("- " + plugin);
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
TBMCCoreAPI.UpdatePlugin(plugin, sender, branch == null ? "master" : branch);
|
||||||
TBMCCoreAPI.UpdatePlugin(args[0], sender, args.length == 1 ? "master" : args[1]);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] GetHelpText(String alias) {
|
public String[] getHelpText(Method method, Command2.Subcommand ann) {
|
||||||
return new String[] { //
|
return new String[]{ //
|
||||||
"§6---- Update plugin ----", //
|
"§6---- Update plugin ----", //
|
||||||
"This command downloads the latest version of a TBMC plugin from GitHub", //
|
"This command downloads the latest version of a custom plugin from GitHub", //
|
||||||
"To update a plugin: /" + alias + " <plugin>", //
|
"To update a plugin: add its name", //
|
||||||
"To list the plugin names: /" + alias //
|
"To list the plugin names: don't type a name" //
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import buttondevteam.buttonproc.HasConfig;
|
||||||
import buttondevteam.core.ComponentManager;
|
import buttondevteam.core.ComponentManager;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.chat.Command2MC;
|
import buttondevteam.lib.chat.Command2MC;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
@ -85,7 +84,7 @@ public abstract class ButtonPlugin extends JavaPlugin {
|
||||||
if (ConfigData.saveNow(getConfig()))
|
if (ConfigData.saveNow(getConfig()))
|
||||||
getLogger().info("Saved configuration changes.");
|
getLogger().info("Saved configuration changes.");
|
||||||
iConfig = null; //Clearing the hashmap is not enough, we need to update the section as well
|
iConfig = null; //Clearing the hashmap is not enough, we need to update the section as well
|
||||||
TBMCChatAPI.RemoveCommands(this);
|
//TBMCChatAPI.RemoveCommands(this); - TODO
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e);
|
TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ import buttondevteam.core.ComponentManager;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
|
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
|
||||||
import buttondevteam.lib.chat.ICommand2MC;
|
import buttondevteam.lib.chat.ICommand2MC;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
|
@ -143,7 +141,7 @@ public abstract class Component<TP extends JavaPlugin> {
|
||||||
//System.out.println("Done enabling "+component.getClassName());
|
//System.out.println("Done enabling "+component.getClassName());
|
||||||
} else {
|
} else {
|
||||||
component.disable();
|
component.disable();
|
||||||
TBMCChatAPI.RemoveCommands(component);
|
//TBMCChatAPI.RemoveCommands(component); - TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,15 +211,6 @@ public abstract class Component<TP extends JavaPlugin> {
|
||||||
ButtonPlugin.getCommand2MC().registerCommand(commandBase);
|
ButtonPlugin.getCommand2MC().registerCommand(commandBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a TBMCCommand to the component. Make sure to add it to plugin.yml and use {@link buttondevteam.lib.chat.CommandClass}.
|
|
||||||
*
|
|
||||||
* @param commandBase Custom coded command class
|
|
||||||
*/
|
|
||||||
protected final void registerCommand(TBMCCommandBase commandBase) {
|
|
||||||
TBMCChatAPI.AddCommand(this, commandBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a Listener to this component
|
* Registers a Listener to this component
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package buttondevteam.lib.architecture;
|
package buttondevteam.lib.architecture;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -12,14 +11,25 @@ import java.util.function.Predicate;
|
||||||
import java.util.function.UnaryOperator;
|
import java.util.function.UnaryOperator;
|
||||||
|
|
||||||
public class ListConfigData<T> extends ConfigData<ListConfigData.List<T>> {
|
public class ListConfigData<T> extends ConfigData<ListConfigData.List<T>> {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
ListConfigData(ConfigurationSection config, String path, List<T> def, Runnable saveAction) {
|
ListConfigData(ConfigurationSection config, String path, List<T> def, Runnable saveAction) {
|
||||||
super(config, path, def, def, saveAction);
|
super(config, path, def, new ArrayList<>(def), list -> {
|
||||||
|
var l = new List<>((ArrayList<T>) list);
|
||||||
|
l.listConfig = def.listConfig;
|
||||||
|
return l;
|
||||||
|
}, ArrayList::new, saveAction);
|
||||||
def.listConfig = this; //Can't make the List class non-static or pass this in the super() constructor
|
def.listConfig = this; //Can't make the List class non-static or pass this in the super() constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class List<T> extends ArrayList<T> {
|
public static class List<T> extends ArrayList<T> {
|
||||||
@Setter(AccessLevel.PACKAGE)
|
private ListConfigData<T> listConfig;
|
||||||
ListConfigData<T> listConfig;
|
|
||||||
|
public List(@NotNull Collection<? extends T> c) {
|
||||||
|
super(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List() {
|
||||||
|
}
|
||||||
|
|
||||||
private void update() {
|
private void update() {
|
||||||
listConfig.set(this); //Update the config model and start save task if needed
|
listConfig.set(this); //Update the config model and start save task if needed
|
||||||
|
|
|
@ -135,7 +135,7 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
||||||
try {
|
try {
|
||||||
handleCommandAsync(sender, commandline, sd, subcommand, sync);
|
handleCommandAsync(sender, commandline, sd, subcommand, sync);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("Command execution failed for sender " + sender + " and message " + commandline, e);
|
TBMCCoreAPI.SendException("Command execution failed for sender " + sender.getName() + "(" + sender.getClass().getCanonicalName() + ") and message " + commandline, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true; //We found a method
|
return true; //We found a method
|
||||||
|
|
|
@ -6,6 +6,7 @@ import org.bukkit.Bukkit;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.server.TabCompleteEvent;
|
import org.bukkit.event.server.TabCompleteEvent;
|
||||||
|
@ -16,7 +17,6 @@ import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implements Listener {
|
public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implements Listener {
|
||||||
|
@ -26,7 +26,7 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
||||||
var perm = "chroma.command." + command.getCommandPath().replace(' ', '.');
|
var perm = "chroma.command." + command.getCommandPath().replace(' ', '.');
|
||||||
if (Bukkit.getPluginManager().getPermission(perm) == null) //Check needed for plugin reset
|
if (Bukkit.getPluginManager().getPermission(perm) == null) //Check needed for plugin reset
|
||||||
Bukkit.getPluginManager().addPermission(new Permission(perm,
|
Bukkit.getPluginManager().addPermission(new Permission(perm,
|
||||||
modOnly(command) ? PermissionDefault.OP : PermissionDefault.TRUE)); //Allow commands by default, unless it's mod only - TODO: Test
|
PermissionDefault.TRUE)); //Allow commands by default, it will check mod-only
|
||||||
for (val method : command.getClass().getMethods()) {
|
for (val method : command.getClass().getMethods()) {
|
||||||
if (!method.isAnnotationPresent(Subcommand.class)) continue;
|
if (!method.isAnnotationPresent(Subcommand.class)) continue;
|
||||||
String pg = permGroup(command, method);
|
String pg = permGroup(command, method);
|
||||||
|
@ -34,7 +34,6 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
||||||
perm = "chroma." + pg;
|
perm = "chroma." + pg;
|
||||||
if (Bukkit.getPluginManager().getPermission(perm) == null) //It may occur multiple times
|
if (Bukkit.getPluginManager().getPermission(perm) == null) //It may occur multiple times
|
||||||
Bukkit.getPluginManager().addPermission(new Permission(perm,
|
Bukkit.getPluginManager().addPermission(new Permission(perm,
|
||||||
//pg.equals(Subcommand.MOD_GROUP) ? PermissionDefault.OP : PermissionDefault.TRUE)); //Allow commands by default, unless it's mod only
|
|
||||||
PermissionDefault.OP)); //Do not allow any commands that belong to a group
|
PermissionDefault.OP)); //Do not allow any commands that belong to a group
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,16 +49,18 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
||||||
boolean p = true;
|
boolean p = true;
|
||||||
String[] perms = {
|
String[] perms = {
|
||||||
"chroma.command." + command.getCommandPath().replace(' ', '.'),
|
"chroma.command." + command.getCommandPath().replace(' ', '.'),
|
||||||
(pg = permGroup(command, method)).length() > 0 ? "chroma." + pg : null,
|
(pg = permGroup(command, method)).length() > 0 ? "chroma." + pg : null
|
||||||
modOnly(command) ? "tbmc.admin" : null
|
|
||||||
};
|
};
|
||||||
for (String perm : perms) {
|
for (String perm : perms) {
|
||||||
if (perm != null) {
|
if (perm != null) {
|
||||||
if (p) { //Use OfflinePlayer to avoid fetching player data
|
if (p) { //Use OfflinePlayer to avoid fetching player data
|
||||||
if (sender instanceof OfflinePlayer)
|
if (sender instanceof OfflinePlayer)
|
||||||
p = MainPlugin.permission.playerHas(null, (OfflinePlayer) sender, perm);
|
p = MainPlugin.permission.playerHas(sender instanceof Player ? ((Player) sender).getLocation().getWorld().getName() : null, (OfflinePlayer) sender, perm);
|
||||||
else
|
else
|
||||||
p = MainPlugin.permission.playerHas(null, Bukkit.getOfflinePlayer(new UUID(0, 0)), perm);
|
p = false; //Use sender's method
|
||||||
|
//System.out.println("playerHas " + perm + ": " + p);
|
||||||
|
//System.out.println("hasPermission: " + sender.hasPermission(perm));
|
||||||
|
if (!p) p = sender.hasPermission(perm);
|
||||||
} else break; //If any of the permissions aren't granted then don't allow
|
} else break; //If any of the permissions aren't granted then don't allow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,17 +68,7 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this class or <u>any</u> of the superclasses are mod only.
|
* Returns the first group found in the hierarchy starting from the command method <b>or</b> the mod group if <i>any</i></i> of the superclasses are mod only.
|
||||||
*
|
|
||||||
* @param command The command to check
|
|
||||||
* @return Whether the command is mod only
|
|
||||||
*/
|
|
||||||
private boolean modOnly(ICommand2MC command) {
|
|
||||||
return getAnnForValue(command.getClass(), CommandClass.class, CommandClass::modOnly, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if this class or <u>any</u> of the superclasses are mod only.
|
|
||||||
*
|
*
|
||||||
* @param method The subcommand to check
|
* @param method The subcommand to check
|
||||||
* @return The permission group for the subcommand or empty string
|
* @return The permission group for the subcommand or empty string
|
||||||
|
@ -87,6 +78,8 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
||||||
if (sc != null && sc.permGroup().length() > 0) {
|
if (sc != null && sc.permGroup().length() > 0) {
|
||||||
return sc.permGroup();
|
return sc.permGroup();
|
||||||
}
|
}
|
||||||
|
if (getAnnForValue(command.getClass(), CommandClass.class, CommandClass::modOnly, false))
|
||||||
|
return Subcommand.MOD_GROUP;
|
||||||
return getAnnForValue(command.getClass(), CommandClass.class, CommandClass::permGroup, "");
|
return getAnnForValue(command.getClass(), CommandClass.class, CommandClass::permGroup, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,4 +17,9 @@ public class Command2MCSender implements Command2Sender {
|
||||||
public void sendMessage(String[] message) {
|
public void sendMessage(String[] message) {
|
||||||
sender.sendMessage(message);
|
sender.sendMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return sender.getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,6 @@ public interface Command2Sender { //We don't need the 'extras' of CommandSender
|
||||||
void sendMessage(String message);
|
void sendMessage(String message);
|
||||||
|
|
||||||
void sendMessage(String[] message);
|
void sendMessage(String[] message);
|
||||||
|
|
||||||
|
String getName();
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ public abstract class ICommand2<TP extends Command2Sender> {
|
||||||
String path = getClass().getAnnotation(CommandClass.class).path(),
|
String path = getClass().getAnnotation(CommandClass.class).path(),
|
||||||
prevpath = path = path.length() == 0 ? getFromClass.apply(getClass()) : path;
|
prevpath = path = path.length() == 0 ? getFromClass.apply(getClass()) : path;
|
||||||
for (Class<?> cl = getClass().getSuperclass(); cl != null
|
for (Class<?> cl = getClass().getSuperclass(); cl != null
|
||||||
&& !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl
|
&& !cl.getPackage().getName().equals(ICommand2MC.class.getPackage().getName()); cl = cl
|
||||||
.getSuperclass()) { //
|
.getSuperclass()) { //
|
||||||
String newpath;
|
String newpath;
|
||||||
if (!cl.isAnnotationPresent(CommandClass.class)
|
if (!cl.isAnnotationPresent(CommandClass.class)
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
package buttondevteam.lib.chat;
|
|
||||||
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public abstract class OptionallyPlayerCommandBase extends TBMCCommandBase {
|
|
||||||
public boolean OnCommand(Player player, String alias, String[] args) {
|
|
||||||
if (getClass().isAnnotationPresent(OptionallyPlayerCommandClass.class)
|
|
||||||
&& getClass().getAnnotation(OptionallyPlayerCommandClass.class).playerOnly())
|
|
||||||
TBMCCoreAPI.SendException("Error while executing command " + getClass().getSimpleName() + "!",
|
|
||||||
new Exception(
|
|
||||||
"The PlayerCommand annotation is present and set to playerOnly but the Player overload isn't overriden!"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
|
|
||||||
if (sender instanceof Player)
|
|
||||||
return OnCommand((Player) sender, alias, args);
|
|
||||||
if (!getClass().isAnnotationPresent(OptionallyPlayerCommandClass.class)
|
|
||||||
|| !getClass().getAnnotation(OptionallyPlayerCommandClass.class).playerOnly())
|
|
||||||
TBMCCoreAPI.SendException("Error while executing command " + getClass().getSimpleName() + "!",
|
|
||||||
new Exception(
|
|
||||||
"Command class doesn't override the CommandSender overload and no PlayerCommandClass annotation is present or playerOnly is false!"));
|
|
||||||
sender.sendMessage("§cYou need to be a player to use this command.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package buttondevteam.lib.chat;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only needed to use with {@link OptionallyPlayerCommandBase} command classes
|
|
||||||
*
|
|
||||||
* @author NorbiPeti
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Inherited
|
|
||||||
public @interface OptionallyPlayerCommandClass {
|
|
||||||
boolean playerOnly();
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package buttondevteam.lib.chat;
|
|
||||||
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public abstract class PlayerCommandBase extends TBMCCommandBase {
|
|
||||||
public abstract boolean OnCommand(Player player, String alias, String[] args);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final boolean OnCommand(CommandSender sender, String alias, String[] args) {
|
|
||||||
if (sender instanceof Player)
|
|
||||||
return OnCommand((Player) sender, alias, args);
|
|
||||||
sender.sendMessage("§cYou need to be a player to use this command.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,250 +1,19 @@
|
||||||
package buttondevteam.lib.chat;
|
package buttondevteam.lib.chat;
|
||||||
|
|
||||||
import buttondevteam.core.CommandCaller;
|
|
||||||
import buttondevteam.core.MainPlugin;
|
|
||||||
import buttondevteam.core.component.channel.Channel;
|
import buttondevteam.core.component.channel.Channel;
|
||||||
import buttondevteam.core.component.channel.Channel.RecipientTestResult;
|
import buttondevteam.core.component.channel.Channel.RecipientTestResult;
|
||||||
import buttondevteam.lib.*;
|
import buttondevteam.lib.ChromaUtils;
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.TBMCChatEvent;
|
||||||
|
import buttondevteam.lib.TBMCChatPreprocessEvent;
|
||||||
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
import org.reflections.Reflections;
|
|
||||||
import org.reflections.scanners.SubTypesScanner;
|
|
||||||
import org.reflections.util.ClasspathHelper;
|
|
||||||
import org.reflections.util.ConfigurationBuilder;
|
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class TBMCChatAPI {
|
public class TBMCChatAPI {
|
||||||
|
|
||||||
private static final HashMap<String, TBMCCommandBase> commands = new HashMap<>();
|
|
||||||
|
|
||||||
public static HashMap<String, TBMCCommandBase> GetCommands() {
|
|
||||||
return commands;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns messages formatted for Minecraft chat listing the subcommands of the command.
|
|
||||||
*
|
|
||||||
* @param command The command which we want the subcommands of
|
|
||||||
* @param sender The sender for permissions
|
|
||||||
* @return The subcommands
|
|
||||||
*/
|
|
||||||
public static String[] GetSubCommands(TBMCCommandBase command, CommandSender sender) {
|
|
||||||
return GetSubCommands(command.GetCommandPath(), sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns messages formatted for Minecraft chat listing the subcommands of the command.<br>
|
|
||||||
* Returns a header if subcommands were found, otherwise returns an empty array.
|
|
||||||
*
|
|
||||||
* @param command The command which we want the subcommands of
|
|
||||||
* @param sender The sender for permissions
|
|
||||||
* @return The subcommands
|
|
||||||
*/
|
|
||||||
public static String[] GetSubCommands(String command, CommandSender sender) {
|
|
||||||
ArrayList<String> cmds = new ArrayList<String>();
|
|
||||||
Consumer<String> addToCmds = cmd -> {
|
|
||||||
if (cmds.size() == 0)
|
|
||||||
cmds.add("§6---- Subcommands ----");
|
|
||||||
cmds.add(cmd);
|
|
||||||
};
|
|
||||||
for (Entry<String, TBMCCommandBase> cmd : TBMCChatAPI.GetCommands().entrySet()) {
|
|
||||||
if (cmd.getKey().startsWith(command + " ")) {
|
|
||||||
if (cmd.getValue().isPlayerOnly() && !(sender instanceof Player))
|
|
||||||
continue;
|
|
||||||
if (cmd.getValue().isModOnly() && (MainPlugin.permission != null ? !MainPlugin.permission.has(sender, "tbmc.admin") : !sender.isOp()))
|
|
||||||
continue;
|
|
||||||
int ind = cmd.getKey().indexOf(' ', command.length() + 2);
|
|
||||||
if (ind >= 0) {
|
|
||||||
String newcmd = cmd.getKey().substring(0, ind);
|
|
||||||
if (!cmds.contains("/" + newcmd))
|
|
||||||
addToCmds.accept("/" + newcmd);
|
|
||||||
} else
|
|
||||||
addToCmds.accept("/" + cmd.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cmds.toArray(new String[0]); //Apparently it's faster to use an empty array in modern Java
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* This method adds a plugin's commands to help and sets their executor.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* </p>
|
|
||||||
* <b>The command classes have to have a constructor each with no parameters</b>
|
|
||||||
* <p>
|
|
||||||
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <i>Using this method after the server is done loading will have no effect.</i>
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param plugin The caller plugin
|
|
||||||
* @param acmdclass A command's class to get the package name for commands. The provided class's package and subpackages are scanned for commands.
|
|
||||||
*/
|
|
||||||
public static synchronized void AddCommands(JavaPlugin plugin, Class<? extends TBMCCommandBase> acmdclass) {
|
|
||||||
plugin.getLogger().info("Registering commands from " + acmdclass.getPackage().getName());
|
|
||||||
Reflections rf = new Reflections(new ConfigurationBuilder()
|
|
||||||
.setUrls(ClasspathHelper.forPackage(acmdclass.getPackage().getName(),
|
|
||||||
plugin.getClass().getClassLoader()))
|
|
||||||
.addUrls(
|
|
||||||
ClasspathHelper.forClass(OptionallyPlayerCommandBase.class,
|
|
||||||
OptionallyPlayerCommandBase.class.getClassLoader()),
|
|
||||||
ClasspathHelper.forClass(PlayerCommandBase.class, PlayerCommandBase.class.getClassLoader())) // http://stackoverflow.com/questions/12917417/using-reflections-for-finding-the-transitive-subtypes-of-a-class-when-not-all
|
|
||||||
.addClassLoader(plugin.getClass().getClassLoader()).addScanners(new SubTypesScanner()));
|
|
||||||
Set<Class<? extends TBMCCommandBase>> cmds = rf.getSubTypesOf(TBMCCommandBase.class);
|
|
||||||
for (Class<? extends TBMCCommandBase> cmd : cmds) {
|
|
||||||
try {
|
|
||||||
if (!cmd.getPackage().getName().startsWith(acmdclass.getPackage().getName()))
|
|
||||||
continue; // It keeps including the commands from here
|
|
||||||
if (Modifier.isAbstract(cmd.getModifiers()))
|
|
||||||
continue;
|
|
||||||
TBMCCommandBase c = cmd.newInstance();
|
|
||||||
c.plugin = plugin;
|
|
||||||
CommandCaller.RegisterCommand(c); //Will check for nulls
|
|
||||||
commands.put(c.GetCommandPath(), c);
|
|
||||||
} catch (Exception e) {
|
|
||||||
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getName(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* This method adds a plugin's command to help and sets it's executor. They will be automatically unregistered on plugin disable.
|
|
||||||
* </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.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <i>Using this method after the server is done loading will have no effect.</i>
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param plugin The caller plugin
|
|
||||||
* @param thecmdclass The command's class to create it (because why let you create the command class)
|
|
||||||
*/
|
|
||||||
public static void AddCommand(JavaPlugin plugin, Class<? extends TBMCCommandBase> thecmdclass, Object... params) {
|
|
||||||
// plugin.getLogger().info("Registering command " + thecmdclass.getSimpleName() + " for " + plugin.getName());
|
|
||||||
try {
|
|
||||||
TBMCCommandBase c;
|
|
||||||
if (params.length > 0)
|
|
||||||
c = thecmdclass.getConstructor(Arrays.stream(params).map(Object::getClass).toArray(Class[]::new))
|
|
||||||
.newInstance(params);
|
|
||||||
else
|
|
||||||
c = thecmdclass.newInstance();
|
|
||||||
c.plugin = plugin;
|
|
||||||
CommandCaller.RegisterCommand(c); //Will check for nulls
|
|
||||||
commands.put(c.GetCommandPath(), c);
|
|
||||||
} catch (Exception e) {
|
|
||||||
TBMCCoreAPI.SendException("An error occured while registering command " + thecmdclass.getSimpleName(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* This method adds a plugin's command to help and sets its executor. They will be automatically unregistered on plugin disable.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 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>
|
|
||||||
* <i>Using this method after the server is done loading will have no effect.</i>
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param plugin The caller plugin
|
|
||||||
* @param cmd The command to add
|
|
||||||
*/
|
|
||||||
public static void AddCommand(JavaPlugin plugin, TBMCCommandBase cmd) {
|
|
||||||
try {
|
|
||||||
if (plugin == null) throw new IllegalArgumentException("The plugin is null!");
|
|
||||||
if (cmd == null) throw new IllegalArgumentException("The command is null!");
|
|
||||||
cmd.plugin = plugin;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* This method adds a plugin's command to help and sets its executor. They will be automatically unregistered on component disable.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 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>
|
|
||||||
* <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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a chat message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.<br>
|
* Sends a chat message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.<br>
|
||||||
* This will also send the error message to the sender, if they can't send the message.
|
* This will also send the error message to the sender, if they can't send the message.
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
package buttondevteam.lib.chat;
|
|
||||||
|
|
||||||
import buttondevteam.lib.architecture.Component;
|
|
||||||
import javassist.Modifier;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
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.
|
|
||||||
*
|
|
||||||
* @author Norbi
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@TBMCCommandEnforcer
|
|
||||||
public abstract class TBMCCommandBase {
|
|
||||||
|
|
||||||
public TBMCCommandBase() {
|
|
||||||
path = getcmdpath();
|
|
||||||
modonly = ismodonly();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract boolean OnCommand(CommandSender sender, String alias, String[] args);
|
|
||||||
|
|
||||||
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>
|
|
||||||
* <u>The path must be lowercase!</u><br>
|
|
||||||
* <b>Abstract classes with no {@link CommandClass} annotations will be ignored.</b>
|
|
||||||
*
|
|
||||||
* @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
|
|
||||||
*/
|
|
||||||
public final String GetCommandPath() {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getcmdpath() {
|
|
||||||
if (!getClass().isAnnotationPresent(CommandClass.class))
|
|
||||||
throw new RuntimeException(
|
|
||||||
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
|
|
||||||
Function<Class<?>, String> getFromClass = cl -> cl.getSimpleName().toLowerCase().replace("commandbase", "") // <-- ...
|
|
||||||
.replace("command", "");
|
|
||||||
String path = getClass().getAnnotation(CommandClass.class).path(),
|
|
||||||
prevpath = path = path.length() == 0 ? getFromClass.apply(getClass()) : path;
|
|
||||||
for (Class<?> cl = getClass().getSuperclass(); cl != null
|
|
||||||
&& !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl
|
|
||||||
.getSuperclass()) { //
|
|
||||||
String newpath;
|
|
||||||
if (!cl.isAnnotationPresent(CommandClass.class)
|
|
||||||
|| (newpath = cl.getAnnotation(CommandClass.class).path()).length() == 0
|
|
||||||
|| newpath.equals(prevpath)) {
|
|
||||||
if ((Modifier.isAbstract(cl.getModifiers()) && !cl.isAnnotationPresent(CommandClass.class))
|
|
||||||
|| cl.getAnnotation(CommandClass.class).excludeFromPath()) // <--
|
|
||||||
continue;
|
|
||||||
newpath = getFromClass.apply(cl);
|
|
||||||
}
|
|
||||||
path = (prevpath = newpath) + " " + path;
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
Plugin plugin; // Used By TBMCChatAPI
|
|
||||||
|
|
||||||
public final Plugin getPlugin() { // Used by CommandCaller (ButtonChat)
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean isPlayerOnly() {
|
|
||||||
return this instanceof PlayerCommandBase ||
|
|
||||||
(this instanceof OptionallyPlayerCommandBase &&
|
|
||||||
(!getClass().isAnnotationPresent(OptionallyPlayerCommandClass.class)
|
|
||||||
|| getClass().getAnnotation(OptionallyPlayerCommandClass.class).playerOnly()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private final boolean modonly;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if this class' or any superclass' modOnly property is set to true.
|
|
||||||
*/
|
|
||||||
public final boolean isModOnly() {
|
|
||||||
return modonly;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean ismodonly() {
|
|
||||||
if (!getClass().isAnnotationPresent(CommandClass.class))
|
|
||||||
throw new RuntimeException(
|
|
||||||
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
|
|
||||||
boolean modOnly = getClass().getAnnotation(CommandClass.class).modOnly();
|
|
||||||
for (Class<?> cl = getClass().getSuperclass(); cl != null
|
|
||||||
&& !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl
|
|
||||||
.getSuperclass()) { //
|
|
||||||
if (cl.isAnnotationPresent(CommandClass.class) && !modOnly
|
|
||||||
&& cl.getAnnotation(CommandClass.class).modOnly()) {
|
|
||||||
modOnly = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return modOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
Component component; //May be null
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package buttondevteam.lib.chat;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Inherited;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.CLASS)
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Inherited
|
|
||||||
public @interface TBMCCommandEnforcer {
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue