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 , T extends ArgumentTypeInfo.Template> void serializeArgumentCap( JsonObject json, ArgumentTypeInfo type, ArgumentTypeInfo.Template template ) { type.serializeToJson((T)template, json); } private static > void serializeArgumentToJson(JsonObject json, T type) { ArgumentTypeInfo.Template 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 JsonObject serializeNodeToJson(CommandDispatcher dispatcher, CommandNode node) { JsonObject jsonObject = new JsonObject(); switch (node) { case RootCommandNode rootCommandNode: jsonObject.addProperty("type", "root"); break; case LiteralCommandNode literalCommandNode: jsonObject.addProperty("type", "literal"); break; case ArgumentCommandNode argumentCommandNode: serializeArgumentToJson(jsonObject, argumentCommandNode.getType()); break; default: LOGGER.error("Could not serialize node {} ({})!", node, node.getClass()); jsonObject.addProperty("type", "unknown"); } Collection> collection = node.getChildren(); if (!collection.isEmpty()) { JsonObject jsonObject2 = new JsonObject(); for (CommandNode 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 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 Set> findUsedArgumentTypes(CommandNode node) { Set> set = new ReferenceOpenHashSet<>(); Set> set2 = new HashSet(); findUsedArgumentTypes(node, set2, set); return set2; } private static void findUsedArgumentTypes(CommandNode node, Set> types, Set> nodes) { if (nodes.add(node)) { if (node instanceof ArgumentCommandNode argumentCommandNode) { types.add(argumentCommandNode.getType()); } node.getChildren().forEach(commandNodex -> findUsedArgumentTypes(commandNodex, types, nodes)); CommandNode commandNode = node.getRedirect(); if (commandNode != null) { findUsedArgumentTypes(commandNode, types, nodes); } } } }