mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-12-20 23:57:34 +01:00
Add command similarity check to mapper (work in progress)
This commit is contained in:
parent
56c005587c
commit
550eecebdc
@ -1,6 +1,7 @@
|
||||
package fr.xephi.authme.command;
|
||||
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -10,6 +11,18 @@ import java.util.List;
|
||||
*/
|
||||
public class CommandMapper {
|
||||
|
||||
/**
|
||||
* The threshold for assuming an existing command. If the difference is below this value, we assume
|
||||
* that the user meant the similar command and we will run it.
|
||||
*/
|
||||
private static final double ASSUME_COMMAND_THRESHOLD = 0.12;
|
||||
|
||||
/**
|
||||
* The threshold for suggesting a similar command. If the difference is below this value, we will
|
||||
* ask the player whether he meant the similar command.
|
||||
*/
|
||||
private static final double SUGGEST_COMMAND_THRESHOLD = 0.75;
|
||||
|
||||
/**
|
||||
* Map incoming command parts to an actual command.
|
||||
*
|
||||
@ -26,25 +39,41 @@ public class CommandMapper {
|
||||
return null; // TODO Pass on the information that base could not be mapped
|
||||
}
|
||||
|
||||
//List<String> labels = CollectionUtils.getRange(parts, 0, 1);
|
||||
List<String> remaining = parts.subList(1, parts.size());
|
||||
|
||||
// Prefer labels: /register help goes to "Help command", not "Register command" with 'help'
|
||||
// Prefer labels: /register help goes to "Help command", not "Register command" with argument 'help'
|
||||
CommandDescription childCommand = returnSuitableChild(base, remaining);
|
||||
if (childCommand != null) {
|
||||
// return childcommand: it's valid...
|
||||
}
|
||||
|
||||
// No child command found, check if parent is suitable
|
||||
if (isSuitableArgumentCount(base, remaining.size())) {
|
||||
} else if (isSuitableArgumentCount(base, remaining.size())) {
|
||||
// return base... it's valid
|
||||
}
|
||||
|
||||
// TODO: We don't have a suitable command for the given parts, so find the most similar one
|
||||
// TODO: return getCommandWithSmallestDifference()
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
// TODO: Return FoundCommandDescription immediately
|
||||
private CommandDescription getCommandWithSmallestDifference(CommandDescription base, List<String> parts) {
|
||||
final String label = parts.get(0);
|
||||
final int argumentCount = parts.size() - 1;
|
||||
|
||||
double minDifference = Double.POSITIVE_INFINITY;
|
||||
CommandDescription closestCommand = null;
|
||||
for (CommandDescription child : base.getChildren()) {
|
||||
double argumentDifference = getArgumentCountDifference(child, argumentCount);
|
||||
double labelDifference = getLabelDifference(child, label);
|
||||
// Weigh argument difference less
|
||||
double difference = labelDifference + argumentCount / 2;
|
||||
if (difference < minDifference) {
|
||||
minDifference = difference;
|
||||
closestCommand = child;
|
||||
}
|
||||
}
|
||||
return closestCommand;
|
||||
}
|
||||
|
||||
private static boolean isSuitableArgumentCount(CommandDescription command, int argumentCount) {
|
||||
int minArgs = CommandUtils.getMinNumberOfArguments(command);
|
||||
int maxArgs = CommandUtils.getMaxNumberOfArguments(command);
|
||||
@ -52,13 +81,32 @@ public class CommandMapper {
|
||||
return argumentCount >= minArgs && argumentCount <= maxArgs;
|
||||
}
|
||||
|
||||
private static double getLabelDifference(CommandDescription command, String givenLabel) {
|
||||
double minDifference = Double.POSITIVE_INFINITY;
|
||||
for (String commandLabel : command.getLabels()) {
|
||||
double difference = StringUtils.getDifference(commandLabel, givenLabel);
|
||||
if (difference < minDifference) {
|
||||
minDifference = difference;
|
||||
}
|
||||
}
|
||||
return minDifference;
|
||||
}
|
||||
|
||||
private static int getArgumentCountDifference(CommandDescription commandDescription, int givenArgumentsCount) {
|
||||
return Math.min(
|
||||
Math.abs(givenArgumentsCount - CommandUtils.getMinNumberOfArguments(commandDescription)),
|
||||
Math.abs(givenArgumentsCount - CommandUtils.getMaxNumberOfArguments(commandDescription)));
|
||||
}
|
||||
|
||||
// Is the given command a suitable match for the given parts? parts is for example [changepassword, newpw, newpw]
|
||||
public CommandDescription returnSuitableChild(CommandDescription baseCommand, List<String> parts) {
|
||||
// TODO: Validate list + make case-insensitive
|
||||
if (CollectionUtils.isEmpty(parts)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String label = parts.get(0).toLowerCase();
|
||||
final int argumentCount = parts.size() - 1;
|
||||
|
||||
List<String> args = parts.subList(1, parts.size());
|
||||
for (CommandDescription child : baseCommand.getChildren()) {
|
||||
if (child.getLabels().contains(label) && isSuitableArgumentCount(child, argumentCount)) {
|
||||
return child;
|
||||
|
Loading…
Reference in New Issue
Block a user