minecraft-src/net/minecraft/commands/synchronization/ArgumentUtils.java
2025-09-18 12:27:44 +00:00

135 lines
4.2 KiB
Java

package net.minecraft.commands.synchronization;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.tree.ArgumentCommandNode;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
import com.mojang.logging.LogUtils;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.commands.PermissionCheck;
import org.slf4j.Logger;
public class ArgumentUtils {
private static final Logger LOGGER = LogUtils.getLogger();
private static final byte NUMBER_FLAG_MIN = 1;
private static final byte NUMBER_FLAG_MAX = 2;
public static int createNumberFlags(boolean min, boolean max) {
int i = 0;
if (min) {
i |= 1;
}
if (max) {
i |= 2;
}
return i;
}
public static boolean numberHasMin(byte number) {
return (number & 1) != 0;
}
public static boolean numberHasMax(byte number) {
return (number & 2) != 0;
}
private static <A extends ArgumentType<?>, T extends ArgumentTypeInfo.Template<A>> void serializeArgumentCap(
JsonObject json, ArgumentTypeInfo<A, T> type, ArgumentTypeInfo.Template<A> template
) {
type.serializeToJson((T)template, json);
}
private static <T extends ArgumentType<?>> void serializeArgumentToJson(JsonObject json, T type) {
ArgumentTypeInfo.Template<T> template = ArgumentTypeInfos.unpack(type);
json.addProperty("type", "argument");
json.addProperty("parser", String.valueOf(BuiltInRegistries.COMMAND_ARGUMENT_TYPE.getKey(template.type())));
JsonObject jsonObject = new JsonObject();
serializeArgumentCap(jsonObject, template.type(), template);
if (!jsonObject.isEmpty()) {
json.add("properties", jsonObject);
}
}
public static <S> JsonObject serializeNodeToJson(CommandDispatcher<S> dispatcher, CommandNode<S> node) {
JsonObject jsonObject = new JsonObject();
switch (node) {
case RootCommandNode<S> rootCommandNode:
jsonObject.addProperty("type", "root");
break;
case LiteralCommandNode<S> literalCommandNode:
jsonObject.addProperty("type", "literal");
break;
case ArgumentCommandNode<S, ?> argumentCommandNode:
serializeArgumentToJson(jsonObject, argumentCommandNode.getType());
break;
default:
LOGGER.error("Could not serialize node {} ({})!", node, node.getClass());
jsonObject.addProperty("type", "unknown");
}
Collection<CommandNode<S>> collection = node.getChildren();
if (!collection.isEmpty()) {
JsonObject jsonObject2 = new JsonObject();
for (CommandNode<S> commandNode : collection) {
jsonObject2.add(commandNode.getName(), serializeNodeToJson(dispatcher, commandNode));
}
jsonObject.add("children", jsonObject2);
}
if (node.getCommand() != null) {
jsonObject.addProperty("executable", true);
}
if (node.getRequirement() instanceof PermissionCheck<?> permissionCheck) {
jsonObject.addProperty("required_level", permissionCheck.requiredLevel());
}
if (node.getRedirect() != null) {
Collection<String> collection2 = dispatcher.getPath(node.getRedirect());
if (!collection2.isEmpty()) {
JsonArray jsonArray = new JsonArray();
for (String string : collection2) {
jsonArray.add(string);
}
jsonObject.add("redirect", jsonArray);
}
}
return jsonObject;
}
public static <T> Set<ArgumentType<?>> findUsedArgumentTypes(CommandNode<T> node) {
Set<CommandNode<T>> set = new ReferenceOpenHashSet<>();
Set<ArgumentType<?>> set2 = new HashSet();
findUsedArgumentTypes(node, set2, set);
return set2;
}
private static <T> void findUsedArgumentTypes(CommandNode<T> node, Set<ArgumentType<?>> types, Set<CommandNode<T>> nodes) {
if (nodes.add(node)) {
if (node instanceof ArgumentCommandNode<T, ?> argumentCommandNode) {
types.add(argumentCommandNode.getType());
}
node.getChildren().forEach(commandNodex -> findUsedArgumentTypes(commandNodex, types, nodes));
CommandNode<T> commandNode = node.getRedirect();
if (commandNode != null) {
findUsedArgumentTypes(commandNode, types, nodes);
}
}
}
}