package net.minecraft.commands.synchronization; import com.google.common.collect.Sets; 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 java.util.Collection; import java.util.Set; import net.minecraft.core.registries.BuiltInRegistries; 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 > void serializeCap(JsonObject json, ArgumentTypeInfo.Template template) { serializeCap(json, template.type(), template); } private static , T extends ArgumentTypeInfo.Template> void serializeCap( JsonObject json, ArgumentTypeInfo argumentTypeInfo, ArgumentTypeInfo.Template template ) { argumentTypeInfo.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", BuiltInRegistries.COMMAND_ARGUMENT_TYPE.getKey(template.type()).toString()); JsonObject jsonObject = new JsonObject(); serializeCap(jsonObject, template); if (jsonObject.size() > 0) { json.add("properties", jsonObject); } } public static JsonObject serializeNodeToJson(CommandDispatcher dispatcher, CommandNode node) { JsonObject jsonObject = new JsonObject(); if (node instanceof RootCommandNode) { jsonObject.addProperty("type", "root"); } else if (node instanceof LiteralCommandNode) { jsonObject.addProperty("type", "literal"); } else if (node instanceof ArgumentCommandNode argumentCommandNode) { serializeArgumentToJson(jsonObject, argumentCommandNode.getType()); } else { LOGGER.error("Could not serialize node {} ({})!", node, node.getClass()); jsonObject.addProperty("type", "unknown"); } JsonObject jsonObject2 = new JsonObject(); for (CommandNode commandNode : node.getChildren()) { jsonObject2.add(commandNode.getName(), serializeNodeToJson(dispatcher, commandNode)); } if (jsonObject2.size() > 0) { jsonObject.add("children", jsonObject2); } if (node.getCommand() != null) { jsonObject.addProperty("executable", true); } if (node.getRedirect() != null) { Collection collection = dispatcher.getPath(node.getRedirect()); if (!collection.isEmpty()) { JsonArray jsonArray = new JsonArray(); for (String string : collection) { jsonArray.add(string); } jsonObject.add("redirect", jsonArray); } } return jsonObject; } public static Set> findUsedArgumentTypes(CommandNode node) { Set> set = Sets.newIdentityHashSet(); Set> set2 = Sets.>newHashSet(); 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); } } } }