diff --git a/proxy/src/main/java/com/velocitypowered/proxy/command/VelocityCommand.java b/proxy/src/main/java/com/velocitypowered/proxy/command/VelocityCommand.java index ece4a834f..d3cc55df4 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/command/VelocityCommand.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/command/VelocityCommand.java @@ -1,5 +1,7 @@ package com.velocitypowered.proxy.command; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.velocitypowered.api.command.Command; import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.permission.Tristate; @@ -10,37 +12,103 @@ import net.kyori.text.format.TextColor; import net.kyori.text.format.TextDecoration; import org.checkerframework.checker.nullness.qual.NonNull; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + public class VelocityCommand implements Command { + private final Map subcommands = ImmutableMap.builder() + .put("version", Info.INSTANCE) + .build(); + + private void usage(CommandSource source) { + String commandText = "/velocity <" + String.join("|", subcommands.keySet()) + ">"; + source.sendMessage(TextComponent.of(commandText, TextColor.RED)); + } + @Override public void execute(CommandSource source, String[] args) { - String implVersion = VelocityServer.class.getPackage().getImplementationVersion(); - TextComponent velocity = TextComponent.builder("Velocity ") - .decoration(TextDecoration.BOLD, true) - .color(TextColor.DARK_AQUA) - .append(TextComponent.of(implVersion == null ? "" : implVersion).decoration(TextDecoration.BOLD, false)) - .build(); - TextComponent copyright = TextComponent.of("Copyright 2018 Velocity Contributors. Velocity is freely licensed under the terms of the " + - "MIT License."); - TextComponent velocityWebsite = TextComponent.builder() - .content("Visit the ") - .append(TextComponent.builder("Velocity website") - .color(TextColor.GREEN) - .clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.velocitypowered.com")) - .build()) - .append(TextComponent.of(" or the ").resetStyle()) - .append(TextComponent.builder("Velocity GitHub") - .color(TextColor.GREEN) - .clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/VelocityPowered/Velocity")) - .build()) - .build(); + if (args.length == 0) { + usage(source); + return; + } - source.sendMessage(velocity); - source.sendMessage(copyright); - source.sendMessage(velocityWebsite); + Command command = subcommands.get(args[0].toLowerCase(Locale.US)); + if (command == null) { + usage(source); + return; + } + command.execute(source, Arrays.copyOfRange(args, 1, args.length)); + } + + @Override + public List suggest(@NonNull CommandSource source, @NonNull String[] currentArgs) { + if (currentArgs.length == 0) { + return ImmutableList.copyOf(subcommands.keySet()); + } + + if (currentArgs.length == 1) { + return subcommands.keySet().stream() + .filter(name -> name.regionMatches(true, 0, currentArgs[0], 0, currentArgs[0].length())) + .collect(Collectors.toList()); + } + + Command command = subcommands.get(currentArgs[0].toLowerCase(Locale.US)); + if (command == null) { + return ImmutableList.of(); + } + return command.suggest(source, Arrays.copyOfRange(currentArgs, 1, currentArgs.length)); } @Override public boolean hasPermission(@NonNull CommandSource source, @NonNull String[] args) { - return source.getPermissionValue("velocity.command.info") != Tristate.FALSE; + if (args.length == 0) { + return true; + } + Command command = subcommands.get(args[0].toLowerCase(Locale.US)); + if (command == null) { + return true; + } + return command.hasPermission(source, Arrays.copyOfRange(args, 1, args.length)); + } + + private static class Info implements Command { + static final Info INSTANCE = new Info(); + private Info() {} + + @Override + public void execute(@NonNull CommandSource source, @NonNull String[] args) { + String implVersion = VelocityServer.class.getPackage().getImplementationVersion(); + TextComponent velocity = TextComponent.builder("Velocity ") + .decoration(TextDecoration.BOLD, true) + .color(TextColor.DARK_AQUA) + .append(TextComponent.of(implVersion == null ? "" : implVersion).decoration(TextDecoration.BOLD, false)) + .build(); + TextComponent copyright = TextComponent.of("Copyright 2018 Velocity Contributors. Velocity is freely licensed under the terms of the " + + "MIT License."); + TextComponent velocityWebsite = TextComponent.builder() + .content("Visit the ") + .append(TextComponent.builder("Velocity website") + .color(TextColor.GREEN) + .clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.velocitypowered.com")) + .build()) + .append(TextComponent.of(" or the ").resetStyle()) + .append(TextComponent.builder("Velocity GitHub") + .color(TextColor.GREEN) + .clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/VelocityPowered/Velocity")) + .build()) + .build(); + + source.sendMessage(velocity); + source.sendMessage(copyright); + source.sendMessage(velocityWebsite); + } + + @Override + public boolean hasPermission(@NonNull CommandSource source, @NonNull String[] args) { + return source.getPermissionValue("velocity.command.info") != Tristate.FALSE; + } } }