Made better cmd error msgs.
ArAbstractSelect will euggest a matching option if, an invalid arg was passed & a matching one exists at. If an invalid subcommand aliases were passed, a matching subcommand will be suggested. After feedback from MonMarty a few misc messages was changed.
This commit is contained in:
parent
f3ad2a40ba
commit
6176369f35
@ -7,7 +7,10 @@ public class Lang
|
|||||||
|
|
||||||
public static final String COMMAND_SENDER_MUST_BE_PLAYER = "<b>This command can only be used by ingame players.";
|
public static final String COMMAND_SENDER_MUST_BE_PLAYER = "<b>This command can only be used by ingame players.";
|
||||||
public static final String COMMAND_SENDER_MUSNT_BE_PLAYER = "<b>This command can not be used by ingame players.";
|
public static final String COMMAND_SENDER_MUSNT_BE_PLAYER = "<b>This command can not be used by ingame players.";
|
||||||
public static final String COMMAND_TO_FEW_ARGS = "<b>Too few arguments. <i>Use like this:";
|
public static final String COMMAND_TOO_FEW_ARGS = "<b>Not enough command input. <i>You should use it like this:";
|
||||||
public static final String COMMAND_TO_MANY_ARGS = "<b>Strange arguments %s<b>.";
|
public static final String COMMAND_TOO_MANY_ARGS = "<b>Too much command input %s<b>.";
|
||||||
public static final String COMMAND_TO_MANY_ARGS2 = "<i>Use the command like this:";
|
public static final String COMMAND_TOO_MANY_ARGS2 = "<i>You should use the command like this:";
|
||||||
|
public static final String COMMAND_NO_SUCH_SUB = "<b>The server couldn't find the command \"<c>%s<b>\".";
|
||||||
|
public static final String COMMAND_SUGGEST_SUB = "<i>Maybe you could try %s";
|
||||||
|
public static final String COMMAND_GET_HELP = "<i>Use %s <i>to see commands.";
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
@ -102,6 +103,7 @@ public class MassiveCommand
|
|||||||
protected List<MassiveCommand> subCommands;
|
protected List<MassiveCommand> subCommands;
|
||||||
public List<MassiveCommand> getSubCommands() { return this.subCommands; }
|
public List<MassiveCommand> getSubCommands() { return this.subCommands; }
|
||||||
public void setSubCommands(List<MassiveCommand> subCommands) { this.subCommands = subCommands; }
|
public void setSubCommands(List<MassiveCommand> subCommands) { this.subCommands = subCommands; }
|
||||||
|
public boolean isParentCommand() { return this.getSubCommands().size() > 0; }
|
||||||
|
|
||||||
public MassiveCommand getSubCommand(String alias)
|
public MassiveCommand getSubCommand(String alias)
|
||||||
{
|
{
|
||||||
@ -437,8 +439,8 @@ public class MassiveCommand
|
|||||||
{
|
{
|
||||||
if (sender != null)
|
if (sender != null)
|
||||||
{
|
{
|
||||||
msg(Lang.COMMAND_TO_FEW_ARGS);
|
msg(Lang.COMMAND_TOO_FEW_ARGS);
|
||||||
sender.sendMessage(this.getUseageTemplate());
|
sendMessage(this.getUseageTemplate());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -447,11 +449,33 @@ public class MassiveCommand
|
|||||||
{
|
{
|
||||||
if (sender != null)
|
if (sender != null)
|
||||||
{
|
{
|
||||||
// Get the to many string slice
|
if (this.isParentCommand())
|
||||||
List<String> theToMany = args.subList(this.getRequiredArgs().size() + this.optionalArgs.size(), args.size());
|
{
|
||||||
msg(Lang.COMMAND_TO_MANY_ARGS, Txt.implodeCommaAndDot(theToMany, Txt.parse("<aqua>%s"), Txt.parse("<b>, "), Txt.parse("<b> and "), ""));
|
String arg = this.arg(0);
|
||||||
msg(Lang.COMMAND_TO_MANY_ARGS2);
|
|
||||||
sender.sendMessage(this.getUseageTemplate());
|
// Try Levenshtein
|
||||||
|
List<String> matches = this.getSimilarSubcommandAliases(arg, this.getMaxLevenshteinDistanceForArg(arg));
|
||||||
|
|
||||||
|
msg(Lang.COMMAND_NO_SUCH_SUB, this.getUseageTemplate() + " " + arg);
|
||||||
|
if ( ! matches.isEmpty())
|
||||||
|
{
|
||||||
|
String suggest = Txt.parse(Txt.implodeCommaAnd(matches, "<i>, <c>", " <i>or <c>"));
|
||||||
|
msg(Lang.COMMAND_SUGGEST_SUB, this.getUseageTemplate() + " " + suggest);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg(Lang.COMMAND_GET_HELP, this.getUseageTemplate());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get the too many string slice
|
||||||
|
List<String> theTooMany = args.subList(this.getRequiredArgs().size() + this.optionalArgs.size(), args.size());
|
||||||
|
msg(Lang.COMMAND_TOO_MANY_ARGS, Txt.implodeCommaAndDot(theTooMany, Txt.parse("<aqua>%s"), Txt.parse("<b>, "), Txt.parse("<b> and "), ""));
|
||||||
|
msg(Lang.COMMAND_TOO_MANY_ARGS2);
|
||||||
|
sendMessage(this.getUseageTemplate());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -462,6 +486,47 @@ public class MassiveCommand
|
|||||||
return this.isArgsValid(args, null);
|
return this.isArgsValid(args, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// MATCHING SUGGESTIONS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public List<String> getSimilarAliases(String arg, int maxLevenshteinDistance)
|
||||||
|
{
|
||||||
|
arg = arg.toLowerCase();
|
||||||
|
|
||||||
|
List<String> matches = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (String alias : this.getAliases())
|
||||||
|
{
|
||||||
|
String aliaslc = alias.toLowerCase();
|
||||||
|
int distance = StringUtils.getLevenshteinDistance(arg, aliaslc);
|
||||||
|
if (distance > maxLevenshteinDistance) continue;
|
||||||
|
matches.add(alias);
|
||||||
|
}
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSimilarSubcommandAliases(String arg, int maxLevenshteinDistance)
|
||||||
|
{
|
||||||
|
// Try Levenshtein
|
||||||
|
List<String> matches = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (MassiveCommand sub : this.getSubCommands())
|
||||||
|
{
|
||||||
|
matches.addAll(sub.getSimilarAliases(arg, maxLevenshteinDistance));
|
||||||
|
}
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxLevenshteinDistanceForArg(String arg)
|
||||||
|
{
|
||||||
|
if (arg.length() <= 1) return 0; // When dealing with 1 character aliases, there is way too many options. So we don't suggest.
|
||||||
|
if (arg.length() <= 3) return 1; // When dealing with low length aliases, there too many options. So we won't suggest much
|
||||||
|
if (arg.length() < 8) return 2; // 2 is default.
|
||||||
|
|
||||||
|
return 3; // If it were 8 characters or more, we end up here. Because many characters allow for more typos.
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// HELP AND USAGE INFORMATION
|
// HELP AND USAGE INFORMATION
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package com.massivecraft.massivecore.cmd.arg;
|
package com.massivecraft.massivecore.cmd.arg;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
import com.massivecraft.massivecore.MassiveException;
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
@ -33,18 +36,28 @@ public abstract class ARAbstractSelect<T> extends ArgReaderAbstract<T>
|
|||||||
{
|
{
|
||||||
T result = this.select(arg, sender);
|
T result = this.select(arg, sender);
|
||||||
|
|
||||||
if (result == null)
|
if (result != null) return result;
|
||||||
{
|
|
||||||
MassiveException exception = new MassiveException();
|
MassiveException exception = new MassiveException();
|
||||||
exception.addMsg("<b>No %s matches \"<h>%s<b>\".", this.typename(), arg);
|
exception.addMsg("<b>No %s matches \"<h>%s<b>\".", this.typename(), arg);
|
||||||
|
|
||||||
if (this.canList(sender))
|
if (this.canList(sender))
|
||||||
{
|
{
|
||||||
Collection<String> names = this.altNames(sender);
|
Collection<String> names = this.altNames(sender);
|
||||||
if (names.size() == 0)
|
|
||||||
|
// Try Levenshtein
|
||||||
|
List<String> matches = this.getMatchingAltNames(arg, sender, this.getMaxLevenshteinDistanceForArg(arg));
|
||||||
|
|
||||||
|
if (names.isEmpty())
|
||||||
{
|
{
|
||||||
exception.addMsg("<i>Note: There is no %s available.", this.typename());
|
exception.addMsg("<i>Note: There is no %s available.", this.typename());
|
||||||
}
|
}
|
||||||
|
else if ( ! matches.isEmpty() && matches.size() < LIST_COUNT_MAX)
|
||||||
|
{
|
||||||
|
// For some reason the arguments doesn't get parsed.
|
||||||
|
String suggest = Txt.parse(Txt.implodeCommaAnd(matches, "<i>, <h>", " <i>or <h>"));
|
||||||
|
exception.addMsg("<i>Did you mean <h>%s<i>?", suggest);
|
||||||
|
}
|
||||||
else if (names.size() > LIST_COUNT_MAX)
|
else if (names.size() > LIST_COUNT_MAX)
|
||||||
{
|
{
|
||||||
exception.addMsg("<i>More than %d alternatives available.", LIST_COUNT_MAX);
|
exception.addMsg("<i>More than %d alternatives available.", LIST_COUNT_MAX);
|
||||||
@ -62,7 +75,29 @@ public abstract class ARAbstractSelect<T> extends ArgReaderAbstract<T>
|
|||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
public List<String> getMatchingAltNames(String arg, CommandSender sender, int maxLevenshteinDistance)
|
||||||
|
{
|
||||||
|
arg = arg.toLowerCase();
|
||||||
|
|
||||||
|
// Try Levenshtein
|
||||||
|
List<String> matches = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (String alias : this.altNames(sender))
|
||||||
|
{
|
||||||
|
String aliaslc = alias.toLowerCase();
|
||||||
|
int distance = StringUtils.getLevenshteinDistance(arg, aliaslc);
|
||||||
|
if (distance > maxLevenshteinDistance) continue;
|
||||||
|
matches.add(alias);
|
||||||
|
}
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxLevenshteinDistanceForArg(String arg)
|
||||||
|
{
|
||||||
|
if (arg.length() <= 1) return 0; // When dealing with 1 character aliases, there is way too many options.
|
||||||
|
if (arg.length() < 8) return 1; // 1 is default.
|
||||||
|
|
||||||
|
return 2; // If it were 8 characters or more, we end up here. Because many characters allow for more typos.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user