Command system fixes

Removed Vault repo as it seems to be offline and wasn't even used
Fixed CommandSender type, no subcommands handling
Made the default handler use the correct sender type (actually, the generic type might be completely unnecessary but oh well)
No longer checking param types to match methods (needed for generic types)
This commit is contained in:
Norbi Peti 2019-02-15 23:48:15 +01:00
parent 6b99bc22d7
commit d245d21a84
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
5 changed files with 21 additions and 15 deletions

View file

@ -12,6 +12,7 @@
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<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" />

View file

@ -103,10 +103,10 @@
<id>jitpack.io</id> <id>jitpack.io</id>
<url>https://jitpack.io/</url> <url>https://jitpack.io/</url>
</repository> </repository>
<repository> <!-- <repository>
<id>vault-repo</id> <id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url> <url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository> </repository> -->
<repository> <repository>
<id>ess-repo</id> <id>ess-repo</id>
<url>http://repo.ess3.net/content/repositories/essrel/</url> <url>http://repo.ess3.net/content/repositories/essrel/</url>

View file

@ -18,7 +18,6 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* The method name is the subcommand, use underlines (_) to add further subcommands. * The method name is the subcommand, use underlines (_) to add further subcommands.
@ -106,6 +105,8 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
final ChromaGamerBase cg; final ChromaGamerBase cg;
if (sendertype.isAssignableFrom(sender.getClass())) if (sendertype.isAssignableFrom(sender.getClass()))
params.add(sender); //The command either expects a CommandSender or it is a Player, or some other expected type params.add(sender); //The command either expects a CommandSender or it is a Player, or some other expected type
else if (CommandSender.class.isAssignableFrom(sendertype) && sender instanceof Command2MCSender)
params.add(((Command2MCSender) sender).getSender());
else if (ChromaGamerBase.class.isAssignableFrom(sendertype) else if (ChromaGamerBase.class.isAssignableFrom(sendertype)
&& sender instanceof Command2MCSender && sender instanceof Command2MCSender
&& (cg = ChromaGamerBase.getFromSender(((Command2MCSender) sender).getSender())) != null && (cg = ChromaGamerBase.getFromSender(((Command2MCSender) sender).getSender())) != null
@ -167,8 +168,9 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
//var scmdmap = subcommandStrings.computeIfAbsent(mainPath, k -> new HashSet<>()); //Used to display subcommands //var scmdmap = subcommandStrings.computeIfAbsent(mainPath, k -> new HashSet<>()); //Used to display subcommands
val scmdHelpList = new ArrayList<String>(); val scmdHelpList = new ArrayList<String>();
Method mainMethod = null; Method mainMethod = null;
boolean nosubs = true;
try { //Register the default handler first so it can be reliably overwritten try { //Register the default handler first so it can be reliably overwritten
mainMethod = command.getClass().getMethod("def", CommandSender.class, String.class); mainMethod = command.getClass().getMethod("def", Command2Sender.class, String.class);
val cc = command.getClass().getAnnotation(CommandClass.class); val cc = command.getClass().getAnnotation(CommandClass.class);
var ht = cc == null ? new String[0] : cc.helpText(); var ht = cc == null ? new String[0] : cc.helpText();
if (ht.length > 0) if (ht.length > 0)
@ -188,8 +190,11 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
ht = getHelpText(method, ht, subcommand); ht = getHelpText(method, ht, subcommand);
subcommands.put(subcommand, new SubcommandData<>(method, command, ht)); //Result of the above (def) is that it will show the help text subcommands.put(subcommand, new SubcommandData<>(method, command, ht)); //Result of the above (def) is that it will show the help text
scmdHelpList.add(subcommand); 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 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]))); subcommands.put(commandChar + path, new SubcommandData<>(mainMethod, command, scmdHelpList.toArray(new String[0])));
if (mainMethod != null && !subcommands.containsKey(mainPath)) //Main command, typically the same as the above if (mainMethod != null && !subcommands.containsKey(mainPath)) //Main command, typically the same as the above
@ -210,8 +215,9 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
if (cs != null) { if (cs != null) {
val mname = cs.getString("method"); val mname = cs.getString("method");
val params = cs.getString("params"); val params = cs.getString("params");
val goodname = method.getName() + "(" + Arrays.stream(method.getParameterTypes()).map(cl -> cl.getCanonicalName()).collect(Collectors.joining(",")) + ")"; //val goodname = method.getName() + "(" + Arrays.stream(method.getGenericParameterTypes()).map(cl -> cl.getTypeName()).collect(Collectors.joining(",")) + ")";
if (goodname.equals(mname) && params != null) { int i = mname.indexOf('('); //Check only the name - the whole method is still stored for backwards compatibility and in case it may be useful
if (i != -1 && method.getName().equals(mname.substring(0, i)) && params != null) {
String[] both = Arrays.copyOf(ht, ht.length + 1); String[] both = Arrays.copyOf(ht, ht.length + 1);
both[ht.length] = "§6Usage:§r " + subcommand + " " + params; both[ht.length] = "§6Usage:§r " + subcommand + " " + params;
ht = both; ht = both;

View file

@ -1,11 +1,10 @@
package buttondevteam.lib.chat; package buttondevteam.lib.chat;
import lombok.Getter; import lombok.Getter;
import org.bukkit.command.CommandSender;
import java.util.function.Function; import java.util.function.Function;
public abstract class ICommand2 { public abstract class ICommand2<TP extends Command2Sender> {
/** /**
* Default handler for commands, can be used to copy the args too. * Default handler for commands, can be used to copy the args too.
* *
@ -13,7 +12,7 @@ public abstract class ICommand2 {
* @param args All of the arguments passed as is * @param args All of the arguments passed as is
* @return The success of the command * @return The success of the command
*/ */
public boolean def(CommandSender sender, @Command2.TextArg String args) { public boolean def(TP sender, @Command2.TextArg String args) {
return false; return false;
} }
@ -24,16 +23,16 @@ public abstract class ICommand2 {
* @param message The message to send to the sender * @param message The message to send to the sender
* @return Always true so that the usage isn't shown * @return Always true so that the usage isn't shown
*/ */
protected boolean respond(CommandSender sender, String message) { protected boolean respond(TP sender, String message) {
sender.sendMessage(message); sender.sendMessage(message);
return true; return true;
} }
private final String path; private final String path;
@Getter @Getter
private final Command2<?, ?> manager; //TIL that if I use a raw type on a variable then none of the type args will work (including what's defined on a method, not on the type) private final Command2<?, TP> manager; //TIL that if I use a raw type on a variable then none of the type args will work (including what's defined on a method, not on the type)
public <T extends ICommand2> ICommand2(Command2<T, ?> manager) { public <T extends ICommand2> ICommand2(Command2<T, TP> manager) {
path = getcmdpath(); path = getcmdpath();
this.manager = manager; this.manager = manager;
} }

View file

@ -2,7 +2,7 @@ package buttondevteam.lib.chat;
import buttondevteam.lib.architecture.ButtonPlugin; import buttondevteam.lib.architecture.ButtonPlugin;
public class ICommand2MC extends ICommand2 { public class ICommand2MC extends ICommand2<Command2MCSender> {
public ICommand2MC() { public ICommand2MC() {
super(ButtonPlugin.getCommand2MC()); super(ButtonPlugin.getCommand2MC());
} }