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;
|
package fr.xephi.authme.command;
|
||||||
|
|
||||||
import fr.xephi.authme.util.CollectionUtils;
|
import fr.xephi.authme.util.CollectionUtils;
|
||||||
|
import fr.xephi.authme.util.StringUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -10,6 +11,18 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class CommandMapper {
|
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.
|
* 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
|
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());
|
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);
|
CommandDescription childCommand = returnSuitableChild(base, remaining);
|
||||||
if (childCommand != null) {
|
if (childCommand != null) {
|
||||||
// return childcommand: it's valid...
|
// return childcommand: it's valid...
|
||||||
}
|
} else if (isSuitableArgumentCount(base, remaining.size())) {
|
||||||
|
|
||||||
// No child command found, check if parent is suitable
|
|
||||||
if (isSuitableArgumentCount(base, remaining.size())) {
|
|
||||||
// return base... it's valid
|
// 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;
|
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) {
|
private static boolean isSuitableArgumentCount(CommandDescription command, int argumentCount) {
|
||||||
int minArgs = CommandUtils.getMinNumberOfArguments(command);
|
int minArgs = CommandUtils.getMinNumberOfArguments(command);
|
||||||
int maxArgs = CommandUtils.getMaxNumberOfArguments(command);
|
int maxArgs = CommandUtils.getMaxNumberOfArguments(command);
|
||||||
@ -52,13 +81,32 @@ public class CommandMapper {
|
|||||||
return argumentCount >= minArgs && argumentCount <= maxArgs;
|
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]
|
// 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) {
|
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 String label = parts.get(0).toLowerCase();
|
||||||
final int argumentCount = parts.size() - 1;
|
final int argumentCount = parts.size() - 1;
|
||||||
|
|
||||||
List<String> args = parts.subList(1, parts.size());
|
|
||||||
for (CommandDescription child : baseCommand.getChildren()) {
|
for (CommandDescription child : baseCommand.getChildren()) {
|
||||||
if (child.getLabels().contains(label) && isSuitableArgumentCount(child, argumentCount)) {
|
if (child.getLabels().contains(label) && isSuitableArgumentCount(child, argumentCount)) {
|
||||||
return child;
|
return child;
|
||||||
|
Loading…
Reference in New Issue
Block a user