Implement tab completion framework (#1203)

This commit is contained in:
Pokechu22 2017-04-13 18:46:43 -07:00 committed by Ali Moghnieh
parent 44ed1e2d44
commit 4c0857fbb5
No known key found for this signature in database
GPG Key ID: F09D3A1BAF2E6D70
6 changed files with 190 additions and 3 deletions

View File

@ -344,21 +344,79 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String commandLabel, String[] args) {
// Allow plugins to override the command via onCommand
return onTabCompleteEssentials(sender, command, commandLabel, args, Essentials.class.getClassLoader(),
"com.earth2me.essentials.commands.Command", "essentials.", null);
}
@Override
public List<String> onTabCompleteEssentials(final CommandSender cSender, final Command command, final String commandLabel, final String[] args,
final ClassLoader classLoader, final String commandPath, final String permissionPrefix,
final IEssentialsModule module) {
if (!getSettings().isCommandOverridden(command.getName()) && (!commandLabel.startsWith("e") || commandLabel.equalsIgnoreCase(command.getName()))) {
final PluginCommand pc = alternativeCommandsHandler.getAlternative(commandLabel);
if (pc != null) {
try {
TabCompleter completer = pc.getTabCompleter();
if (completer != null) {
return completer.onTabComplete(sender, command, commandLabel, args);
return completer.onTabComplete(cSender, command, commandLabel, args);
}
} catch (final Exception ex) {
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
}
}
}
return null;
try {
// Note: The tab completer is always a player, even when tab-completing in a command block
User user = null;
if (cSender instanceof Player) {
user = getUser((Player) cSender);
}
CommandSource sender = new CommandSource(cSender);
// Check for disabled commands
if (getSettings().isCommandDisabled(commandLabel)) {
return Collections.emptyList();
}
IEssentialsCommand cmd;
try {
cmd = (IEssentialsCommand) classLoader.loadClass(commandPath + command.getName()).newInstance();
cmd.setEssentials(this);
cmd.setEssentialsModule(module);
} catch (Exception ex) {
sender.sendMessage(tl("commandNotLoaded", commandLabel));
LOGGER.log(Level.SEVERE, tl("commandNotLoaded", commandLabel), ex);
return Collections.emptyList();
}
// Check authorization
if (user != null && !user.isAuthorized(cmd, permissionPrefix)) {
return Collections.emptyList();
}
if (user != null && user.isJailed() && !user.isAuthorized(cmd, "essentials.jail.allow.")) {
return Collections.emptyList();
}
// Run the command
try {
if (user == null) {
return cmd.tabComplete(getServer(), sender, commandLabel, command, args);
} else {
return cmd.tabComplete(getServer(), user, commandLabel, command, args);
}
} catch (Exception ex) {
showError(sender, ex, commandLabel);
// Tab completion shouldn't fail
LOGGER.log(Level.SEVERE, tl("commandFailed", commandLabel), ex);
return Collections.emptyList();
}
} catch (Throwable ex) {
LOGGER.log(Level.SEVERE, tl("commandFailed", commandLabel), ex);
return Collections.emptyList();
}
}
@Override

View File

@ -25,6 +25,8 @@ public interface IEssentials extends Plugin {
void reload();
List<String> onTabCompleteEssentials(CommandSender sender, Command command, String commandLabel, String[] args, ClassLoader classLoader, String commandPath, String permissionPrefix, IEssentialsModule module);
boolean onCommandEssentials(CommandSender sender, Command command, String commandLabel, String[] args, ClassLoader classLoader, String commandPath, String permissionPrefix, IEssentialsModule module);
@Deprecated

View File

@ -5,11 +5,15 @@ import com.earth2me.essentials.IEssentialsModule;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.FormatUtil;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import net.ess3.api.IEssentials;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
@ -160,6 +164,43 @@ public abstract class EssentialsCommand implements IEssentialsCommand {
throw new Exception(tl("onlyPlayers", commandLabel));
}
@Override
public final List<String> tabComplete(final Server server, final User user, final String commandLabel, final Command cmd, final String[] args) {
if (args.length == 0) {
// Shouldn't happen, but bail out early if it does so that args[0] can always be used
return Collections.emptyList();
}
List<String> options = getTabCompleteOptions(server, user, commandLabel, args);
if (options == null) {
return null;
}
return StringUtil.copyPartialMatches(args[args.length - 1], options, Lists.<String>newArrayList());
}
// Doesn't need to do any starts-with checks
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
return getTabCompleteOptions(server, user.getSource(), commandLabel, args);
}
@Override
public final List<String> tabComplete(final Server server, final CommandSource sender, final String commandLabel, final Command cmd, final String[] args) {
if (args.length == 0) {
// Shouldn't happen, but bail out early if it does so that args[0] can always be used
return Collections.emptyList();
}
List<String> options = getTabCompleteOptions(server, sender, commandLabel, args);
if (options == null) {
return null;
}
return StringUtil.copyPartialMatches(args[args.length - 1], options, Lists.<String>newArrayList());
}
// Doesn't need to do any starts-with checks
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
// No tab completion results
return Collections.emptyList();
}
public static String getFinalArg(final String[] args, final int start) {
final StringBuilder bldr = new StringBuilder();
for (int i = start; i < args.length; i++) {
@ -194,4 +235,41 @@ public abstract class EssentialsCommand implements IEssentialsCommand {
return interactor.getBase().canSee(interactee.getBase());
}
/**
* Gets a list of all player names that can be seen with by the given CommandSource,
* for tab completion.
*/
protected List<String> getPlayers(final Server server, final CommandSource interactor) {
List<String> players = Lists.newArrayList();
for (User user : ess.getOnlineUsers()) {
if (canInteractWith(interactor, user)) {
players.add(user.getName());
}
}
return players;
}
/**
* Gets a list of all player names that can be seen with by the given User,
* for tab completion.
*/
protected List<String> getPlayers(final Server server, final User interactor) {
List<String> players = Lists.newArrayList();
for (User user : ess.getOnlineUsers()) {
if (canInteractWith(interactor, user)) {
players.add(user.getName());
}
}
return players;
}
/**
* Common time durations (in seconds), for use in tab completion.
*/
protected static final List<String> COMMON_DURATIONS = ImmutableList.of("1", "60", "600", "3600", "86400");
/**
* Common date diffs, for use in tab completion
*/
protected static final List<String> COMMON_DATE_DIFFS = ImmutableList.of("1m", "15m", "1h", "3h", "12h", "1d", "1w", "1mo", "1y");
}

View File

@ -108,4 +108,20 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand {
}
protected abstract void updatePlayer(Server server, CommandSource sender, User user, String[] args) throws NotEnoughArgumentsException, PlayerExemptException, ChargeException, MaxMoneyException;
@Override
protected List<String> getPlayers(final Server server, final CommandSource interactor) {
List<String> players = super.getPlayers(server, interactor);
players.add("**");
players.add("*");
return players;
}
@Override
protected List<String> getPlayers(final Server server, final User interactor) {
List<String> players = super.getPlayers(server, interactor);
players.add("**");
players.add("*");
return players;
}
}

View File

@ -2,9 +2,11 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import com.google.common.collect.Lists;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.List;
@ -72,4 +74,30 @@ public abstract class EssentialsToggleCommand extends EssentialsCommand {
// Make sure when implementing this method that all 3 Boolean states are handled, 'null' should toggle the existing state.
abstract void togglePlayer(CommandSource sender, User user, Boolean enabled) throws NotEnoughArgumentsException;
@Override
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
if (args.length == 1) {
if (user.isAuthorized(othersPermission)) {
return getPlayers(server, user);
} else {
return Lists.newArrayList("enable", "disable");
}
} else if (args.length == 2 && user.isAuthorized(othersPermission)) {
return Lists.newArrayList("enable", "disable");
} else {
return Collections.emptyList();
}
}
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
return getPlayers(server, sender);
} else if (args.length == 2) {
return Lists.newArrayList("enable", "disable");
} else {
return Collections.emptyList();
}
}
}

View File

@ -6,6 +6,7 @@ import com.earth2me.essentials.User;
import net.ess3.api.IEssentials;
import org.bukkit.Server;
import org.bukkit.command.Command;
import java.util.List;
public interface IEssentialsCommand {
@ -15,6 +16,10 @@ public interface IEssentialsCommand {
void run(Server server, CommandSource sender, String commandLabel, Command cmd, String[] args) throws Exception;
List<String> tabComplete(Server server, User user, String commandLabel, Command cmd, String[] args);
List<String> tabComplete(Server server, CommandSource sender, String commandLabel, Command cmd, String[] args);
void setEssentials(IEssentials ess);
void setEssentialsModule(IEssentialsModule module);