Skip to content

Commit

Permalink
Hidden annotation, revamped flags & switches (suggestions still broken)
Browse files Browse the repository at this point in the history
  • Loading branch information
Badbird5907 committed Jun 15, 2022
1 parent e8af32f commit 9e44b47
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.octopvp.commander.bukkit.impl;

import net.octopvp.commander.annotation.Hidden;
import net.octopvp.commander.command.CommandContext;
import net.octopvp.commander.command.CommandInfo;
import net.octopvp.commander.help.HelpService;
Expand All @@ -23,6 +24,9 @@ public void sendHelp(CommandInfo info, CoreCommandSender sender) {
sender.sendMessage(ChatColor.AQUA + "Help for " + ChatColor.GOLD + info.getName() + ChatColor.GRAY + " - " + info.getDescription());
if (info.isParentCommand()) {
for (CommandInfo subCommand : info.getSubCommands()) {
if (subCommand.getMethod().isAnnotationPresent(Hidden.class)) {
continue;
}
sender.sendMessage(ChatColor.GRAY + " " + subCommand.getFullUsage() + (subCommand.getDescription() != null || subCommand.getDescription().isEmpty() ? ChatColor.GRAY + " - " + subCommand.getDescription() : ""));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@
import java.util.stream.Collectors;

public class CommanderImpl implements Commander {
private CommanderPlatform platform;
private final CommanderPlatform platform;
private CommanderConfig config;

private Map<Class<?>, Provider<?>> argumentProviders = new HashMap<>();
private final Map<Class<?>, Provider<?>> argumentProviders = new HashMap<>();

private Map<Class<?>, Supplier<?>> dependencies = new HashMap<>();
private final Map<Class<?>, Supplier<?>> dependencies = new HashMap<>();

private Map<String, CommandInfo> commandMap = new HashMap<>();
private final Map<String, CommandInfo> commandMap = new HashMap<>();

private List<Consumer<CommandContext>> preProcessors = new ArrayList<>();
private List<BiConsumer<CommandContext, Object>> postProcessors = new ArrayList<>();
private final List<Consumer<CommandContext>> preProcessors = new ArrayList<>();
private final List<BiConsumer<CommandContext, Object>> postProcessors = new ArrayList<>();

private Map<Class<?>, Validator<Object>> validators = new HashMap<>();
private final Map<Class<?>, Validator<Object>> validators = new HashMap<>();

public CommanderImpl(CommanderPlatform platform) {
this.platform = platform;
Expand Down Expand Up @@ -99,7 +99,7 @@ public Commander init() {
minMax.append("max: ").append(max);
}
minMax.append(")");
throw new ValidateException("Value " + value.doubleValue() + " is not in valid range! " + minMax.toString());
throw new ValidateException("Value " + value.doubleValue() + " is not in valid range! " + minMax);
}
});
return this;
Expand Down Expand Up @@ -187,8 +187,7 @@ private void registerCmd(Object object) {
@Override
public Commander registerPackage(String packageName) {
register(platform.getClassesInPackage(packageName).stream().filter(clazz -> {
if (clazz.isAnnotationPresent(DontAutoInit.class)) return false;
return true;
return !clazz.isAnnotationPresent(DontAutoInit.class);
}).map(clazz -> {
try {
if (clazz.isEnum()) return null;
Expand Down Expand Up @@ -362,7 +361,7 @@ public void executeCommand(CoreCommandSender sender, String label, String[] args
try {
result = context.getCommandInfo().getMethod().invoke(context.getCommandInfo().getInstance(), arguments);
} catch (IllegalAccessException | IllegalArgumentException e) {
e.printStackTrace();
e.printStackTrace();
} catch (InvocationTargetException e) {
if (e.getCause() != null && e.getCause() instanceof CommandException) {
platform.handleCommandException(context, (CommandException) e.getCause());
Expand Down Expand Up @@ -393,7 +392,7 @@ private Map<String, String> extractFlags(final List<String> args, final Paramete
if (flags.containsKey(flag)) {
throw new CommandParseException("Flag " + flag + " is defined multiple times.");
}
if (paramsList.stream().noneMatch(p -> p.isFlag() && p.getFlag().equals(flag)))
if (paramsList.stream().noneMatch(p -> p.isFlag() && p.getFlags().contains(flag)))
continue;
iterator.remove();
if (iterator.hasNext()) {
Expand All @@ -419,7 +418,7 @@ private Map<String, Boolean> extractSwitches(final List<String> args, final Para
if (switches.containsKey(flag)) {
throw new CommandParseException("Switch " + flag + " is defined multiple times.");
}
if (paramsList.stream().noneMatch(p -> p.isSwitch() && p.getSwitch().equals(flag)))
if (paramsList.stream().noneMatch(p -> p.isSwitch() && p.getSwitches().contains(flag)))
continue;
iterator.remove();
switches.put(flag, true);
Expand Down Expand Up @@ -457,8 +456,7 @@ public List<String> getSuggestions(CoreCommandSender sender, final String input)
parent = command;
if (split.length == 1) {
return parent.getSubCommands().stream().map(CommandInfo::getName).collect(Collectors.toList());
}
else if (split.length == 2 && !input.endsWith(" ")){
} else if (split.length == 2 && !input.endsWith(" ")) {
List<String> suggestions = parent.getSubCommands().stream().map(CommandInfo::getName).collect(Collectors.toList());
suggestions.removeIf(s -> !s.trim().toLowerCase().startsWith(split[1].trim().toLowerCase()));
return suggestions;
Expand All @@ -480,11 +478,34 @@ else if (split.length == 2 && !input.endsWith(" ")){

if (!input.endsWith(" ") && config.isShowNextSuggestionOnlyIfEndsWithSpace()) index--;

//remove switches and flags from the index
for (int i = 0; i < index; i++) {
if (split[i].startsWith(config.getFlagPrefix())) {
index--;
} else if (split[i].startsWith(config.getSwitchPrefix())) {
index--;
}
}

if (index >= params.length || index < 0) {
return null;
}

ParameterInfo param = params[index];
ParameterInfo param = null;
boolean found = false;
while (!found) {
param = params[index];
if (param.isFlag() || param.isSwitch()) { //TODO add support for flag and switch suggestions
if (++index >= params.length) {
return null;
}
if (param.isFlag()) {
param = params[index];
}
} else {
found = true;
}
}
Provider<?> provider = param.getProvider();

if (provider == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@
@Target({ElementType.PARAMETER})
public @interface Flag {
String value() default "";

String[] aliases() default {};
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package net.octopvp.commander.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface GetArgumentFor {
/**
* The index of the processed user-entered argument to get. Starting at 0
*
* @return
*/
int value();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package net.octopvp.commander.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.METHOD})
public @interface Hidden {
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@
@Target({ElementType.PARAMETER})
public @interface Switch {
String value() default "";

String[] aliases() default {};

boolean defaultValue() default false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import net.octopvp.commander.util.Primitives;
import net.octopvp.commander.validator.Validator;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand All @@ -25,16 +26,31 @@ public static Object[] parseArguments(CommandContext ctx, CommandArgs cArgs) {
if (cArgs.getFlags() == null) {
throw new CommandParseException("Flags are null!");
}
String f = cArgs.getFlags().get(parameter.getFlag());
if (f != null) validate(f, parameter, ctx);
arguments[i] = f;
List<String> paramFlags = parameter.getFlags();
for (String paramFlag : paramFlags) {
String f = cArgs.getFlags().get(paramFlag);
if (f == null) {
arguments[i] = Primitives.getDefaultValue(parameter.getParameter().getType());
break;
}
ArrayDeque<String> deque = new ArrayDeque<>();
deque.add(f);
Object value = parameter.getProvider().provide(ctx, ctx.getCommandInfo(), parameter, deque);
if (value != null) {
validate(value, parameter, ctx);
arguments[i] = value;
break;
}
}
continue;
}
if (parameter.isSwitch()) {
if (cArgs.getSwitches() == null) {
throw new CommandParseException("Switches are null!");
}
Boolean b = cArgs.getSwitches().get(parameter.getSwitch());
List<String> switches = parameter.getSwitches();
Boolean b = cArgs.getSwitches().entrySet().stream().filter(e -> switches.contains(e.getKey())).map(Map.Entry::getValue).findFirst().orElse(null);
//Boolean b = cArgs.getSwitches().get(parameter.getSwitches());
if (b != null) validate(b, parameter, ctx);
arguments[i] = b != null && b;
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import lombok.Getter;
import lombok.Setter;
import net.octopvp.commander.Commander;
import net.octopvp.commander.annotation.*;
import net.octopvp.commander.annotation.Command;
import net.octopvp.commander.annotation.Cooldown;
import net.octopvp.commander.annotation.Dependency;
import net.octopvp.commander.annotation.Permission;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
Expand Down Expand Up @@ -37,6 +40,8 @@ public class CommandInfo { //This is the object that is stored in the command ma
private boolean subCommand = false, parentCommand = false;
private CommandInfo parent;
private List<CommandInfo> subCommands;
private boolean hasFlags, foundFlagsAlready;
private boolean hasSwitches, foundSwitchesAlready;

public CommandInfo(ParameterInfo[] parameters, String name, String description, String usage, String[] aliases, Method method, Object instance, Map<Class<? extends Annotation>, Annotation> annotations, Commander commander) {
this.parameters = parameters;
Expand All @@ -49,7 +54,7 @@ public CommandInfo(ParameterInfo[] parameters, String name, String description,
this.commander = commander;
if (isAnnotationPresent(Permission.class)) {
this.permission = getAnnotation(Permission.class).value();
}else {
} else {
this.permission = null;
}
if (isAnnotationPresent(Cooldown.class)) {
Expand All @@ -70,6 +75,8 @@ public Command getAnnotation() {

public String getUsage() {
if (usage == null || usage.equals("<<generate>>")) {
String optionalPrefix = commander.getConfig().getOptionalPrefix(), requiredPrefix = commander.getConfig().getRequiredPrefix(),
optionalSuffix = commander.getConfig().getOptionalSuffix(), requiredSuffix = commander.getConfig().getRequiredSuffix();
if (parentCommand) {
StringBuilder builder = new StringBuilder();
builder.append(commander.getConfig().getRequiredPrefix());
Expand All @@ -85,11 +92,23 @@ public String getUsage() {
if (parameter.hideFromUsage()) {
continue;
}
boolean optional = parameter.isOptional();
builder.append(optional ? commander.getConfig().getOptionalPrefix() : commander.getConfig().getRequiredPrefix())
.append(parameter.getName())
.append(optional ? commander.getConfig().getOptionalSuffix() : commander.getConfig().getRequiredSuffix())
.append(" ");
if (parameter.isSwitch()) {
builder.append(optionalPrefix)
.append("-").append(parameter.getSwitchUsageName())
.append(optionalSuffix)
.append(" ");
} else if (parameter.isFlag()) {
builder.append(optionalPrefix)
.append("-").append(parameter.getFlagUsageName())
.append(optionalSuffix)
.append(" ");
} else {
boolean optional = parameter.isOptional();
builder.append(optional ? optionalPrefix : requiredPrefix)
.append(parameter.getName())
.append(optional ? optionalSuffix : requiredSuffix)
.append(" ");
}
}
this.usage = builder.toString().trim();
}
Expand All @@ -112,9 +131,6 @@ public <T extends Annotation> T getAnnotation(Class<T> annotation) {
return (T) annotations.get(annotation);
}

private boolean hasFlags, foundFlagsAlready;
private boolean hasSwitches, foundSwitchesAlready;

public boolean hasFlags() {
if (foundFlagsAlready) {
return hasFlags;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package net.octopvp.commander.command;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import net.octopvp.commander.Commander;
import net.octopvp.commander.annotation.*;
import net.octopvp.commander.provider.Provider;

import java.lang.annotation.Annotation;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Getter
Expand Down Expand Up @@ -80,27 +80,62 @@ public String getName() {
public boolean isFlag() {
return parameter.isAnnotationPresent(Flag.class);
}
public String getFlag() {

public List<String> getFlags() {
if (parameter.isAnnotationPresent(Flag.class)) {
Flag f = parameter.getAnnotation(Flag.class);
return f.value() == null || f.value().isEmpty() ? parameter.getName() : f.value();
List<String> flags = new ArrayList<>();
flags.add(f.value());
for (String alias : f.aliases()) {
if (alias != null && !alias.isEmpty()) {
flags.add(alias);
}
}
return flags;
//return f.value() == null || f.value().isEmpty() ? parameter.getName() : f.value();
}
return null;
}

public boolean isSwitch() {
return parameter.isAnnotationPresent(Switch.class);
}
public String getSwitch() {

public List<String> getSwitches() {
if (parameter.isAnnotationPresent(Switch.class)) {
Switch s = parameter.getAnnotation(Switch.class);
List<String> switches = new ArrayList<>();
for (String alias : s.aliases()) {
if (alias != null && !alias.isEmpty()) {
switches.add(alias);
}
}
if (s.value() != null && !s.value().isEmpty()) {
switches.add(s.value());
}
return switches;
}
return null;
}

public String getSwitchUsageName() {
if (parameter.isAnnotationPresent(Switch.class)) {
Switch s = parameter.getAnnotation(Switch.class);
return s.value() == null || s.value().isEmpty() ? parameter.getName() : s.value();
return s.value();
}
return null;
}

public String getFlagUsageName() {
if (parameter.isAnnotationPresent(Flag.class)) {
Flag f = parameter.getAnnotation(Flag.class);
return f.value();
}
return null;
}

public boolean hideFromUsage() {
return commander.getPlatform().isSenderParameter(this) || parameter.isAnnotationPresent(Dependency.class);
return commander.getPlatform().isSenderParameter(this) || parameter.isAnnotationPresent(Dependency.class) || parameter.isAnnotationPresent(GetArgumentFor.class) || parameter.isAnnotationPresent(Hidden.class);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class StringProvider implements Provider<String> {
public String provide(CommandContext context, CommandInfo commandInfo, ParameterInfo parameterInfo, Deque<String> args) {
if (parameterInfo.getParameter().isAnnotationPresent(GetArgumentFor.class)) {
int index = parameterInfo.getParameter().getAnnotation(GetArgumentFor.class).value();
if (index >= args.size()) {
if (index >= context.getArgs().getPreservedArgs().size()) {
throw new InvalidArgsException("Missing argument for " + parameterInfo.getParameter().getName());
}
return context.getArgs().getPreservedArgs().get(index);
Expand Down
Loading

0 comments on commit 9e44b47

Please sign in to comment.