From 23d41cd6c8c497a519085d9c4b0437b1f0033d7c Mon Sep 17 00:00:00 2001 From: Jikoo Date: Sun, 15 Mar 2020 09:50:51 -0400 Subject: [PATCH] Simplify and expand tab completion --- .../main/java/com/lishid/openinv/OpenInv.java | 25 ++- ...mand.java => ContainerSettingCommand.java} | 20 +-- ...PluginCommand.java => OpenInvCommand.java} | 24 ++- ...Command.java => SearchEnchantCommand.java} | 22 ++- ...uginCommand.java => SearchInvCommand.java} | 26 +++- .../com/lishid/openinv/util/TabCompleter.java | 147 ++++++++++++++++++ plugin/src/main/resources/plugin.yml | 2 +- 7 files changed, 221 insertions(+), 45 deletions(-) rename plugin/src/main/java/com/lishid/openinv/commands/{ContainerSettingPluginCommand.java => ContainerSettingCommand.java} (82%) rename plugin/src/main/java/com/lishid/openinv/commands/{OpenInvPluginCommand.java => OpenInvCommand.java} (87%) rename plugin/src/main/java/com/lishid/openinv/commands/{SearchEnchantPluginCommand.java => SearchEnchantCommand.java} (85%) rename plugin/src/main/java/com/lishid/openinv/commands/{SearchInvPluginCommand.java => SearchInvCommand.java} (75%) create mode 100644 plugin/src/main/java/com/lishid/openinv/util/TabCompleter.java diff --git a/plugin/src/main/java/com/lishid/openinv/OpenInv.java b/plugin/src/main/java/com/lishid/openinv/OpenInv.java index 9553332..47b5d0c 100644 --- a/plugin/src/main/java/com/lishid/openinv/OpenInv.java +++ b/plugin/src/main/java/com/lishid/openinv/OpenInv.java @@ -18,10 +18,10 @@ package com.lishid.openinv; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; -import com.lishid.openinv.commands.ContainerSettingPluginCommand; -import com.lishid.openinv.commands.OpenInvPluginCommand; -import com.lishid.openinv.commands.SearchEnchantPluginCommand; -import com.lishid.openinv.commands.SearchInvPluginCommand; +import com.lishid.openinv.commands.ContainerSettingCommand; +import com.lishid.openinv.commands.OpenInvCommand; +import com.lishid.openinv.commands.SearchEnchantCommand; +import com.lishid.openinv.commands.SearchInvCommand; import com.lishid.openinv.internal.IAnySilentContainer; import com.lishid.openinv.internal.ISpecialEnderChest; import com.lishid.openinv.internal.ISpecialInventory; @@ -33,7 +33,6 @@ import com.lishid.openinv.listeners.PlayerListener; import com.lishid.openinv.listeners.PluginListener; import com.lishid.openinv.util.Cache; import com.lishid.openinv.util.ConfigUpdater; -import com.lishid.openinv.util.Function; import com.lishid.openinv.util.InternalAccessor; import com.lishid.openinv.util.Permissions; import java.util.HashMap; @@ -331,20 +330,16 @@ public class OpenInv extends JavaPlugin implements IOpenInv { pm.registerEvents(new InventoryDragListener(), this); // Register commands to their executors - OpenInvPluginCommand openInv = new OpenInvPluginCommand(this); + OpenInvCommand openInv = new OpenInvCommand(this); this.getCommand("openinv").setExecutor(openInv); this.getCommand("openender").setExecutor(openInv); - SearchInvPluginCommand searchInv = new SearchInvPluginCommand(this); + SearchInvCommand searchInv = new SearchInvCommand(this); this.getCommand("searchinv").setExecutor(searchInv); this.getCommand("searchender").setExecutor(searchInv); - this.getCommand("searchenchant").setExecutor(new SearchEnchantPluginCommand(this)); - ContainerSettingPluginCommand settingCommand = new ContainerSettingPluginCommand(this); - PluginCommand command = this.getCommand("silentcontainer"); - command.setExecutor(settingCommand); - command.setTabCompleter(settingCommand); - command = this.getCommand("anycontainer"); - command.setExecutor(settingCommand); - command.setTabCompleter(settingCommand); + this.getCommand("searchenchant").setExecutor(new SearchEnchantCommand(this)); + ContainerSettingCommand settingCommand = new ContainerSettingCommand(this); + this.getCommand("silentcontainer").setExecutor(settingCommand); + this.getCommand("anycontainer").setExecutor(settingCommand); } else { this.getLogger().info("Your version of CraftBukkit (" + this.accessor.getVersion() + ") is not supported."); diff --git a/plugin/src/main/java/com/lishid/openinv/commands/ContainerSettingPluginCommand.java b/plugin/src/main/java/com/lishid/openinv/commands/ContainerSettingCommand.java similarity index 82% rename from plugin/src/main/java/com/lishid/openinv/commands/ContainerSettingPluginCommand.java rename to plugin/src/main/java/com/lishid/openinv/commands/ContainerSettingCommand.java index d905d16..eb14e8b 100644 --- a/plugin/src/main/java/com/lishid/openinv/commands/ContainerSettingPluginCommand.java +++ b/plugin/src/main/java/com/lishid/openinv/commands/ContainerSettingCommand.java @@ -17,7 +17,7 @@ package com.lishid.openinv.commands; import com.lishid.openinv.OpenInv; -import java.util.ArrayList; +import com.lishid.openinv.util.TabCompleter; import java.util.Collections; import java.util.List; import java.util.function.BiConsumer; @@ -25,16 +25,15 @@ import java.util.function.Function; import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; +import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; -public class ContainerSettingPluginCommand implements CommandExecutor, TabCompleter { +public class ContainerSettingCommand implements TabExecutor { private final OpenInv plugin; - public ContainerSettingPluginCommand(final OpenInv plugin) { + public ContainerSettingCommand(final OpenInv plugin) { this.plugin = plugin; } @@ -78,16 +77,7 @@ public class ContainerSettingPluginCommand implements CommandExecutor, TabComple return Collections.emptyList(); } - String argument = args[0].toLowerCase(); - List completions = new ArrayList<>(); - - for (String subcommand : new String[] {"check", "on", "off"}) { - if (subcommand.startsWith(argument)) { - completions.add(subcommand); - } - } - - return completions; + return TabCompleter.completeString(args[0], new String[] {"check", "on", "off"}); } } diff --git a/plugin/src/main/java/com/lishid/openinv/commands/OpenInvPluginCommand.java b/plugin/src/main/java/com/lishid/openinv/commands/OpenInvCommand.java similarity index 87% rename from plugin/src/main/java/com/lishid/openinv/commands/OpenInvPluginCommand.java rename to plugin/src/main/java/com/lishid/openinv/commands/OpenInvCommand.java index 465b5ef..609e44f 100644 --- a/plugin/src/main/java/com/lishid/openinv/commands/OpenInvPluginCommand.java +++ b/plugin/src/main/java/com/lishid/openinv/commands/OpenInvCommand.java @@ -19,22 +19,25 @@ package com.lishid.openinv.commands; import com.lishid.openinv.OpenInv; import com.lishid.openinv.internal.ISpecialInventory; import com.lishid.openinv.util.Permissions; +import com.lishid.openinv.util.TabCompleter; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; -public class OpenInvPluginCommand implements CommandExecutor { +public class OpenInvCommand implements TabExecutor { private final OpenInv plugin; private final HashMap openInvHistory = new HashMap(); private final HashMap openEnderHistory = new HashMap(); - public OpenInvPluginCommand(final OpenInv plugin) { + public OpenInvCommand(final OpenInv plugin) { this.plugin = plugin; } @@ -73,7 +76,7 @@ public class OpenInvPluginCommand implements CommandExecutor { new BukkitRunnable() { @Override public void run() { - final OfflinePlayer offlinePlayer = OpenInvPluginCommand.this.plugin.matchPlayer(name); + final OfflinePlayer offlinePlayer = OpenInvCommand.this.plugin.matchPlayer(name); if (offlinePlayer == null || !offlinePlayer.hasPlayedBefore() && !offlinePlayer.isOnline()) { player.sendMessage(ChatColor.RED + "Player not found!"); @@ -86,9 +89,9 @@ public class OpenInvPluginCommand implements CommandExecutor { if (!player.isOnline()) { return; } - OpenInvPluginCommand.this.openInventory(player, offlinePlayer, openinv); + OpenInvCommand.this.openInventory(player, offlinePlayer, openinv); } - }.runTask(OpenInvPluginCommand.this.plugin); + }.runTask(OpenInvCommand.this.plugin); } }.runTaskAsynchronously(this.plugin); @@ -161,4 +164,13 @@ public class OpenInvPluginCommand implements CommandExecutor { plugin.openInventory(player, inv); } + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + if (!command.testPermissionSilent(sender) || args.length != 1) { + return Collections.emptyList(); + } + + return TabCompleter.completeOnlinePlayer(sender, args[0]); + } + } diff --git a/plugin/src/main/java/com/lishid/openinv/commands/SearchEnchantPluginCommand.java b/plugin/src/main/java/com/lishid/openinv/commands/SearchEnchantCommand.java similarity index 85% rename from plugin/src/main/java/com/lishid/openinv/commands/SearchEnchantPluginCommand.java rename to plugin/src/main/java/com/lishid/openinv/commands/SearchEnchantCommand.java index 636b8c9..c755185 100644 --- a/plugin/src/main/java/com/lishid/openinv/commands/SearchEnchantPluginCommand.java +++ b/plugin/src/main/java/com/lishid/openinv/commands/SearchEnchantCommand.java @@ -17,10 +17,13 @@ package com.lishid.openinv.commands; import com.lishid.openinv.OpenInv; +import com.lishid.openinv.util.TabCompleter; +import java.util.Collections; +import java.util.List; import org.bukkit.Material; import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; @@ -33,11 +36,11 @@ import org.bukkit.inventory.meta.ItemMeta; * * @author Jikoo */ -public class SearchEnchantPluginCommand implements CommandExecutor { +public class SearchEnchantCommand implements TabExecutor { private final OpenInv plugin; - public SearchEnchantPluginCommand(OpenInv plugin) { + public SearchEnchantCommand(OpenInv plugin) { this.plugin = plugin; } @@ -130,4 +133,17 @@ public class SearchEnchantPluginCommand implements CommandExecutor { return false; } + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + if (!command.testPermissionSilent(sender) || args.length < 1 || args.length > 2) { + return Collections.emptyList(); + } + + if (args.length == 1) { + return TabCompleter.completeObject(args[0], Enchantment::getName, Enchantment.values()); + } else { + return TabCompleter.completeInteger(args[1]); + } + } + } diff --git a/plugin/src/main/java/com/lishid/openinv/commands/SearchInvPluginCommand.java b/plugin/src/main/java/com/lishid/openinv/commands/SearchInvCommand.java similarity index 75% rename from plugin/src/main/java/com/lishid/openinv/commands/SearchInvPluginCommand.java rename to plugin/src/main/java/com/lishid/openinv/commands/SearchInvCommand.java index 14114c5..9a42ee9 100644 --- a/plugin/src/main/java/com/lishid/openinv/commands/SearchInvPluginCommand.java +++ b/plugin/src/main/java/com/lishid/openinv/commands/SearchInvCommand.java @@ -17,19 +17,22 @@ package com.lishid.openinv.commands; import com.lishid.openinv.OpenInv; +import com.lishid.openinv.util.TabCompleter; +import java.util.Collections; +import java.util.List; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; -public class SearchInvPluginCommand implements CommandExecutor { +public class SearchInvCommand implements TabExecutor { private final OpenInv plugin; - public SearchInvPluginCommand(OpenInv plugin) { + public SearchInvCommand(OpenInv plugin) { this.plugin = plugin; } @@ -40,8 +43,7 @@ public class SearchInvPluginCommand implements CommandExecutor { int count = 1; if (args.length >= 1) { - String[] gData = args[0].split(":"); - material = Material.matchMaterial(gData[0]); + material = Material.getMaterial(args[0]); } if (args.length >= 2) { @@ -77,4 +79,18 @@ public class SearchInvPluginCommand implements CommandExecutor { return true; } + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + if (args.length < 1 || args.length > 2 || !command.testPermissionSilent(sender)) { + return Collections.emptyList(); + } + + String argument = args[args.length - 1]; + if (args.length == 1) { + return TabCompleter.completeEnum(argument, Material.class); + } else { + return TabCompleter.completeInteger(argument); + } + } + } diff --git a/plugin/src/main/java/com/lishid/openinv/util/TabCompleter.java b/plugin/src/main/java/com/lishid/openinv/util/TabCompleter.java new file mode 100644 index 0000000..77538f9 --- /dev/null +++ b/plugin/src/main/java/com/lishid/openinv/util/TabCompleter.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2011-2020 lishid. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lishid.openinv.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.function.Function; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +/** + * Utility class for common tab completions. + */ +public class TabCompleter { + + /** + * Offer tab completions for whole numbers. + * + * @param argument the argument to complete + * @return integer options + */ + public static List completeInteger(String argument) { + // Ensure existing argument is actually a number + if (!argument.isEmpty()) { + try { + Integer.parseInt(argument); + } catch (NumberFormatException e) { + return Collections.emptyList(); + } + } + + List completions = new ArrayList<>(10); + for (int i = 0; i < 10; ++i) { + completions.add(argument + i); + } + + return completions; + } + + /** + * Offer tab completions for a given Enum. + * + * @param argument the argument to complete + * @param enumClazz the Enum to complete for + * @return the matching Enum values + */ + public static List completeEnum(String argument, Class> enumClazz) { + argument = argument.toLowerCase(Locale.ENGLISH); + List completions = new ArrayList<>(); + + for (Enum enumConstant : enumClazz.getEnumConstants()) { + String name = enumConstant.name().toLowerCase(); + if (name.startsWith(argument)) { + completions.add(name); + } + } + + return completions; + } + + /** + * Offer tab completions for a given array of Strings. + * + * @param argument the argument to complete + * @param options the Strings which may be completed + * @return the matching Strings + */ + public static List completeString(String argument, String[] options) { + argument = argument.toLowerCase(Locale.ENGLISH); + List completions = new ArrayList<>(); + + for (String option : options) { + if (option.startsWith(argument)) { + completions.add(option); + } + } + + return completions; + } + + /** + * Offer tab completions for visible online Players' names. + * + * @param sender the command's sender + * @param argument the argument to complete + * @return the matching Players' names + */ + public static List completeOnlinePlayer(CommandSender sender, String argument) { + List completions = new ArrayList<>(); + Player senderPlayer = sender instanceof Player ? (Player) sender : null; + + for (Player player : Bukkit.getOnlinePlayers()) { + if (senderPlayer != null && !senderPlayer.canSee(player)) { + continue; + } + + if (StringUtil.startsWithIgnoreCase(player.getName(), argument)) { + completions.add(player.getName()); + } + } + + return completions; + } + + /** + * Offer tab completions for a given array of Objects. + * + * @param argument the argument to complete + * @param converter the Function for converting the Object into a comparable String + * @param options the Objects which may be completed + * @return the matching Strings + */ + public static List completeObject(String argument, Function converter, T[] options) { + argument = argument.toLowerCase(Locale.ENGLISH); + List completions = new ArrayList<>(); + + for (T option : options) { + String optionString = converter.apply(option).toLowerCase(); + if (optionString.startsWith(argument)) { + completions.add(optionString); + } + } + + return completions; + } + + private TabCompleter() {} + +} diff --git a/plugin/src/main/resources/plugin.yml b/plugin/src/main/resources/plugin.yml index b6df8df..62053b1 100644 --- a/plugin/src/main/resources/plugin.yml +++ b/plugin/src/main/resources/plugin.yml @@ -49,7 +49,7 @@ commands: permission: OpenInv.search description: Searches and lists players having a specific item in their ender chest usage: |- - / [MinAmount] - Item is the ID or the Bukkit Material, MinAmount is the minimum amount required + / [MinAmount] - Item is the Bukkit Material, MinAmount is the minimum amount required silentcontainer: aliases: [sc, silent, silentchest] description: SilentContainer stops sounds and animations when using containers.