added strict command matching
This commit is contained in:
1 parent
20b1470f1f
commit
5f9df1239a
3 files changed
+69
-6
No files matched your search
@@ -35,6 +35,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -226,23 +227,58 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class ListComparator<T extends Comparable<T>> implements Comparator<Pair<List<T>,?>>
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public int compare(Pair<List<T>,?> p1, Pair<List<T>,?> p2) {
|
||||||
|
List<T> o1 = p1.getKey();
|
||||||
|
List<T> o2 = p2.getKey();
|
||||||
|
for (int i = 0; i < Math.min(o1.size(), o2.size()); i++) {
|
||||||
|
int c = o1.get(i).compareTo(o2.get(i));
|
||||||
|
if (c != 0) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Integer.compare(o1.size(), o2.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public LiteralArgumentBuilder<ServerCommandSource> readCommands() throws CommandSyntaxException
|
public LiteralArgumentBuilder<ServerCommandSource> readCommands() throws CommandSyntaxException
|
||||||
{
|
{
|
||||||
Value commands = appConfig.get(StringValue.of("commands"));
|
Value commands = appConfig.get(StringValue.of("commands"));
|
||||||
|
|
||||||
if (commands == null) return null;
|
if (commands == null) return null;
|
||||||
if (!(commands instanceof MapValue))
|
if (!(commands instanceof MapValue))
|
||||||
throw CommandArgument.error("'commands' element in config should be a map");
|
throw CommandArgument.error("'commands' element in config should be a map");
|
||||||
List<Pair<List<CommandToken>,FunctionArgument<Value>>> commandEntries = new ArrayList<>();
|
List<Pair<List<CommandToken>,FunctionArgument<Value>>> commandEntries = new ArrayList<>();
|
||||||
|
|
||||||
for (Map.Entry<Value, Value> commandsData : ((MapValue)commands).getMap().entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toList()))
|
for (Map.Entry<Value, Value> commandsData : ((MapValue)commands).getMap().entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toList()))
|
||||||
{
|
{
|
||||||
List<CommandToken> elements = CommandToken.parseSpec(commandsData.getKey().getString(), this);
|
List<CommandToken> elements = CommandToken.parseSpec(commandsData.getKey().getString(), this);
|
||||||
FunctionArgument<Value> funSpec = FunctionArgument.fromCommandSpec(this, commandsData.getValue());
|
FunctionArgument<Value> funSpec = FunctionArgument.fromCommandSpec(this, commandsData.getValue());
|
||||||
commandEntries.add(Pair.of(elements, funSpec));
|
commandEntries.add(Pair.of(elements, funSpec));
|
||||||
}
|
}
|
||||||
// validate
|
commandEntries.sort(new ListComparator<>());
|
||||||
// ...
|
if (!appConfig.getOrDefault(StringValue.of("allow_command_conflicts"), Value.FALSE).getBoolean())
|
||||||
//
|
{
|
||||||
|
for (int i = 0; i < commandEntries.size()-1; i++)
|
||||||
|
{
|
||||||
|
List<CommandToken> first = commandEntries.get(i).getKey();
|
||||||
|
List<CommandToken> other = commandEntries.get(i+1).getKey();
|
||||||
|
int checkSize = Math.min(first.size(), other.size());
|
||||||
|
for (int t = 0; t < checkSize; t++)
|
||||||
|
{
|
||||||
|
CommandToken tik = first.get(t);
|
||||||
|
CommandToken tok = other.get(t);
|
||||||
|
if (tik.isArgument && tok.isArgument && !tik.surface.equals(tok.surface))
|
||||||
|
throw CommandArgument.error("Conflicting commands: \n"+
|
||||||
|
" - [" +first.stream().map(tt -> tt.surface).collect(Collectors.joining(" ")) + "] at "+tik.surface+"\n"+
|
||||||
|
" - [" +other.stream().map(tt -> tt.surface).collect(Collectors.joining(" ")) + "] at "+tok.surface+"\n");
|
||||||
|
if (!tik.equals(tok))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return this.getNewCommandTree(commandEntries);
|
return this.getNewCommandTree(commandEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ public class CarpetScriptServer
|
|||||||
|
|
||||||
for (String function : host.globaFunctionNames(host.main, s -> !s.startsWith("_")).sorted().collect(Collectors.toList()))
|
for (String function : host.globaFunctionNames(host.main, s -> !s.startsWith("_")).sorted().collect(Collectors.toList()))
|
||||||
{
|
{
|
||||||
if (host.appConfig.containsKey(StringValue.of("legacy_command_type_support"))) // temporary stuff for testing
|
if (host.appConfig.getOrDefault(StringValue.of("legacy_command_type_support"), Value.FALSE).getBoolean())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,17 +10,20 @@ import net.minecraft.server.command.ServerCommandSource;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static net.minecraft.server.command.CommandManager.literal;
|
import static net.minecraft.server.command.CommandManager.literal;
|
||||||
|
|
||||||
public class CommandToken
|
public class CommandToken implements Comparable<CommandToken>
|
||||||
{
|
{
|
||||||
public String surface;
|
public String surface;
|
||||||
public boolean isArgument;
|
public boolean isArgument;
|
||||||
|
public CommandArgument type;
|
||||||
|
|
||||||
private CommandToken(String surface, CommandArgument type )
|
private CommandToken(String surface, CommandArgument type )
|
||||||
{
|
{
|
||||||
this.surface = surface;
|
this.surface = surface;
|
||||||
|
this.type = type;
|
||||||
isArgument = type != null;
|
isArgument = type != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,4 +68,28 @@ public class CommandToken
|
|||||||
return literal(surface);
|
return literal(surface);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
CommandToken that = (CommandToken) o;
|
||||||
|
return surface.equals(that.surface) &&
|
||||||
|
Objects.equals(type, that.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return Objects.hash(surface, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(CommandToken o)
|
||||||
|
{
|
||||||
|
if (isArgument && !o.isArgument) return 1;
|
||||||
|
if (!isArgument && o.isArgument) return -1;
|
||||||
|
return surface.compareTo(o.surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user