Reload cmd fix, parameter tabcomplete
Made reload cmd only for ButtonPlugins Implemented parameter tabcomplete using Commodore Only works for one subcommand at the moment #82
This commit is contained in:
parent
2cca2e2096
commit
3c4f9f6c7a
4 changed files with 124 additions and 23 deletions
|
@ -29,17 +29,27 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.2</version>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactSet>
|
||||
</artifactSet>
|
||||
</configuration>
|
||||
<configuration>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>me.lucko:commodore</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>me.lucko.commodore</pattern>
|
||||
<!-- vvv Replace with the package of your plugin vvv -->
|
||||
<shadedPattern>buttondevteam.core.commodore</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
@ -106,7 +116,7 @@
|
|||
<repository>
|
||||
<id>ess-repo</id>
|
||||
<url>https://ci.ender.zone/plugin/repository/everything/</url>
|
||||
</repository>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>Votifier</id>
|
||||
<url>https://dl.bintray.com/nuvotifier/maven/</url>
|
||||
|
@ -115,7 +125,11 @@
|
|||
<id>Multiverse-Core</id>
|
||||
<url>http://repo.onarandombox.com/content/repositories/multiverse/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<repository>
|
||||
<id>minecraft-repo</id>
|
||||
<url>https://libraries.minecraft.net/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.reflections</groupId>
|
||||
|
@ -176,7 +190,13 @@
|
|||
<version>4.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependency>
|
||||
<groupId>me.lucko</groupId>
|
||||
<artifactId>commodore</artifactId>
|
||||
<version>1.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<organization>
|
||||
<name>TBMCPlugins</name>
|
||||
<url>https://github.com/TBMCPlugins</url>
|
||||
|
|
|
@ -11,12 +11,12 @@ import org.bukkit.plugin.Plugin;
|
|||
public class ChromaCommand extends ICommand2MC {
|
||||
@Command2.Subcommand
|
||||
public void reload(CommandSender sender, @Command2.OptionalArg Plugin plugin) {
|
||||
if(plugin==null)
|
||||
plugin=MainPlugin.Instance;
|
||||
if(!(plugin instanceof ButtonPlugin))
|
||||
plugin.reloadConfig();
|
||||
if (plugin == null)
|
||||
plugin = MainPlugin.Instance;
|
||||
if (!(plugin instanceof ButtonPlugin)) //Probably not a good idea to allow reloading any plugin's config
|
||||
sender.sendMessage("§c" + plugin.getName() + " doesn't support this.");
|
||||
else if (((ButtonPlugin) plugin).tryReloadConfig())
|
||||
sender.sendMessage("§b"+plugin.getName()+" config reloaded.");
|
||||
sender.sendMessage("§b" + plugin.getName() + " config reloaded.");
|
||||
else
|
||||
sender.sendMessage("§cFailed to reload config. Check console.");
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
|||
helpText[0] = "§6---- Subcommands ----"; //TODO: There may be more to the help text
|
||||
int i = 1;
|
||||
for (Iterator<String> iterator = ht.iterator();
|
||||
iterator.hasNext() && i < helpText.length; i++) {
|
||||
iterator.hasNext() && i < helpText.length; i++) {
|
||||
String e = iterator.next();
|
||||
helpText[i] = e;
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
|||
|
||||
public abstract void registerCommand(TC command);
|
||||
|
||||
protected void registerCommand(TC command, @SuppressWarnings("SameParameterValue") char commandChar) {
|
||||
protected List<SubcommandData<TC>> registerCommand(TC command, @SuppressWarnings("SameParameterValue") char commandChar) {
|
||||
this.commandChar = commandChar;
|
||||
val path = command.getCommandPath();
|
||||
int x = path.indexOf(' ');
|
||||
|
@ -298,6 +298,7 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
|||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Could not register default handler for command /" + path, e);
|
||||
}
|
||||
var addedSubcommands = new ArrayList<SubcommandData<TC>>();
|
||||
for (val method : command.getClass().getMethods()) {
|
||||
val ann = method.getAnnotation(Subcommand.class);
|
||||
if (ann == null) continue; //Don't call the method on non-subcommands because they're not in the yaml
|
||||
|
@ -306,15 +307,20 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
|||
val subcommand = commandChar + path + //Add command path (class name by default)
|
||||
getCommandPath(method.getName(), ' '); //Add method name, unless it's 'def'
|
||||
ht = getParameterHelp(method, ht, subcommand);
|
||||
subcommands.put(subcommand, new SubcommandData<>(method, command, ht)); //Result of the above (def) is that it will show the help text
|
||||
var sd = new SubcommandData<>(method, command, ht);
|
||||
subcommands.put(subcommand, sd); //Result of the above (def) is that it will show the help text
|
||||
addedSubcommands.add(sd);
|
||||
scmdHelpList.add(subcommand);
|
||||
nosubs = false;
|
||||
}
|
||||
}
|
||||
if (nosubs && scmdHelpList.size() > 0)
|
||||
scmdHelpList.remove(scmdHelpList.size() - 1); //Remove Subcommands header
|
||||
if (mainMethod != null && !subcommands.containsKey(commandChar + path)) //Command specified by the class
|
||||
subcommands.put(commandChar + path, new SubcommandData<>(mainMethod, command, scmdHelpList.toArray(new String[0])));
|
||||
if (mainMethod != null && !subcommands.containsKey(commandChar + path)) { //Command specified by the class
|
||||
var sd = new SubcommandData<>(mainMethod, command, scmdHelpList.toArray(new String[0]));
|
||||
subcommands.put(commandChar + path, sd);
|
||||
addedSubcommands.add(sd);
|
||||
}
|
||||
if (mainMethod != null && !mainPath.equals(commandChar + path)) { //Main command, typically the same as the above
|
||||
if (isSubcommand) { //The class itself is a subcommand
|
||||
val scmd = subcommands.computeIfAbsent(mainPath, p -> new SubcommandData<>(null, null, new String[]{"§6---- Subcommands ----"}));
|
||||
|
@ -325,6 +331,7 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
|||
} else if (!subcommands.containsKey(mainPath))
|
||||
subcommands.put(mainPath, new SubcommandData<>(null, null, scmdHelpList.toArray(new String[0])));
|
||||
}
|
||||
return addedSubcommands;
|
||||
}
|
||||
|
||||
private String[] getParameterHelp(Method method, String[] ht, String subcommand) {
|
||||
|
|
|
@ -4,7 +4,13 @@ import buttondevteam.core.MainPlugin;
|
|||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.architecture.ButtonPlugin;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import com.mojang.brigadier.arguments.*;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||
import lombok.val;
|
||||
import me.lucko.commodore.Commodore;
|
||||
import me.lucko.commodore.CommodoreProvider;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.Command;
|
||||
|
@ -20,8 +26,10 @@ import org.bukkit.permissions.PermissionDefault;
|
|||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
@ -33,7 +41,7 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
|||
*/
|
||||
@Override
|
||||
public void registerCommand(ICommand2MC command) {
|
||||
super.registerCommand(command, '/');
|
||||
var subcmds = super.registerCommand(command, '/');
|
||||
var perm = "chroma.command." + command.getCommandPath().replace(' ', '.');
|
||||
if (Bukkit.getPluginManager().getPermission(perm) == null) //Check needed for plugin reset
|
||||
Bukkit.getPluginManager().addPermission(new Permission(perm,
|
||||
|
@ -55,7 +63,7 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
|||
PermissionDefault.OP)); //Do not allow any commands that belong to a group
|
||||
}
|
||||
|
||||
registerOfficially(command);
|
||||
registerOfficially(command, subcmds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -256,9 +264,14 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
|||
}
|
||||
}
|
||||
|
||||
private boolean shouldRegisterOfficially=true;
|
||||
private void registerOfficially(ICommand2MC command) {
|
||||
if(!shouldRegisterOfficially) return;
|
||||
private boolean shouldRegisterOfficially = true;
|
||||
|
||||
private void registerOfficially(ICommand2MC command, List<SubcommandData<ICommand2MC>> subcmds) {
|
||||
if (!shouldRegisterOfficially) return;
|
||||
if (CommodoreProvider.isSupported()) {
|
||||
TabcompleteHelper.registerTabcomplete(command, subcmds);
|
||||
return; //Commodore registers the command as well
|
||||
}
|
||||
try {
|
||||
var cmdmap = (SimpleCommandMap) Bukkit.getServer().getClass().getMethod("getCommandMap").invoke(Bukkit.getServer());
|
||||
var path = command.getCommandPath();
|
||||
|
@ -282,4 +295,65 @@ public class Command2MC extends Command2<ICommand2MC, Command2MCSender> implemen
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TabcompleteHelper {
|
||||
private static Commodore commodore;
|
||||
|
||||
private static void registerTabcomplete(ICommand2MC command2MC, List<SubcommandData<ICommand2MC>> subcmds) {
|
||||
if (commodore == null)
|
||||
commodore = CommodoreProvider.getCommodore(MainPlugin.Instance); //Register all to the Core, it's easier
|
||||
System.out.println("Registering tabcomplete for path: " + command2MC.getCommandPath());
|
||||
String[] path = command2MC.getCommandPath().split(" ");
|
||||
var maincmd = LiteralArgumentBuilder.literal(path[0]);
|
||||
var cmd = maincmd;
|
||||
for (int i = 1; i < path.length; i++) {
|
||||
var subcmd = LiteralArgumentBuilder.literal(path[i]);
|
||||
cmd.then(subcmd);
|
||||
cmd = subcmd; //Add each part of the path as a child of the previous one
|
||||
}
|
||||
for (SubcommandData<ICommand2MC> subcmd : subcmds) {
|
||||
String[] subpath = ButtonPlugin.getCommand2MC().getCommandPath(subcmd.method.getName(), ' ').trim().split(" ");
|
||||
ArgumentBuilder<Object, ?> scmd = cmd;
|
||||
if (subpath[0].length() > 0) { //If the method is def, it will contain one empty string
|
||||
for (String s : subpath) {
|
||||
var subsubcmd = LiteralArgumentBuilder.literal(s);
|
||||
scmd.then(subsubcmd);
|
||||
scmd = subsubcmd; //Add method name part of the path (could_be_multiple())
|
||||
}
|
||||
}
|
||||
Parameter[] parameters = subcmd.method.getParameters();
|
||||
for (int i = 1; i < parameters.length; i++) { //Skip sender
|
||||
Parameter parameter = parameters[i];
|
||||
ArgumentType<?> type;
|
||||
final Class<?> ptype = parameter.getType();
|
||||
if (ptype == String.class)
|
||||
if (parameter.isAnnotationPresent(TextArg.class))
|
||||
type = StringArgumentType.greedyString();
|
||||
else
|
||||
type = StringArgumentType.word();
|
||||
else if (ptype == int.class || ptype == Integer.class)
|
||||
type = IntegerArgumentType.integer(); //TODO: Min, max
|
||||
else if (ptype == long.class || ptype == Long.class)
|
||||
type = LongArgumentType.longArg();
|
||||
else if (ptype == float.class || ptype == Float.class)
|
||||
type = FloatArgumentType.floatArg();
|
||||
else if (ptype == double.class || ptype == Double.class)
|
||||
type = DoubleArgumentType.doubleArg();
|
||||
else if (ptype == char.class || ptype == Character.class)
|
||||
type = StringArgumentType.word();
|
||||
else if (ptype == boolean.class || ptype == Boolean.class)
|
||||
type = BoolArgumentType.bool();
|
||||
else //TODO: Custom parameter types
|
||||
type = StringArgumentType.word();
|
||||
var arg = RequiredArgumentBuilder.argument(parameter.getName(), type);
|
||||
scmd.then(arg);
|
||||
scmd = arg;
|
||||
}
|
||||
}
|
||||
System.out.println("maincmd: " + maincmd);
|
||||
System.out.println("Children:");
|
||||
maincmd.build().getChildren().forEach(System.out::println);
|
||||
commodore.register(maincmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue