diff --git a/src/main/java/me/lucko/commodore/CommodoreProvider.java b/src/main/java/me/lucko/commodore/CommodoreProvider.java index ab4036a..5b67baf 100644 --- a/src/main/java/me/lucko/commodore/CommodoreProvider.java +++ b/src/main/java/me/lucko/commodore/CommodoreProvider.java @@ -43,6 +43,7 @@ private static Throwable checkSupported() { try { Class.forName("com.mojang.brigadier.CommandDispatcher"); CommodoreImpl.ensureSetup(); + MinecraftArgumentType.ensureSetup(); return null; } catch (Throwable e) { if (System.getProperty("commodore.debug") != null) { diff --git a/src/main/java/me/lucko/commodore/MinecraftArgumentType.java b/src/main/java/me/lucko/commodore/MinecraftArgumentType.java new file mode 100644 index 0000000..33f55ff --- /dev/null +++ b/src/main/java/me/lucko/commodore/MinecraftArgumentType.java @@ -0,0 +1,377 @@ +package me.lucko.commodore; + +import com.mojang.brigadier.arguments.ArgumentType; + +import java.lang.reflect.Constructor; +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * An enumeration for containing Minecraft's built-in {@link ArgumentType}s + */ +@SuppressWarnings("rawtypes") +public enum MinecraftArgumentType { + + /** + * A selector, player name, or UUID. + *
+ * Parameters:
+ * - boolean single
+ * - boolean playerOnly
+ */
+ ENTITY("ArgumentEntity", boolean.class, boolean.class),
+
+ /**
+ * A player, online or not. Can also use a selector, which may match one or more
+ * players (but not entities).
+ */
+ GAME_PROFILE("ArgumentProfile"),
+
+ /**
+ * A chat color. One of the names from colors, or {@code reset}.
+ * Case-insensitive.
+ */
+ COLOR("ArgumentChatFormat"),
+
+ /**
+ * A JSON Chat component.
+ */
+ COMPONENT("ArgumentChatComponent"),
+
+ /**
+ * A regular message, potentially including selectors.
+ */
+ MESSAGE("ArgumentChat"),
+
+ /**
+ * An NBT value, parsed using JSON-NBT rules. This represents a full NBT tag.
+ */
+ NBT("ArgumentNBTTag"),
+
+ /**
+ * Represents a partial NBT tag, usable in data modify command.
+ */
+ NBT_TAG("ArgumentNBTBase"),
+
+ /**
+ * A path within an NBT value, allowing for array and member accesses.
+ */
+ NBT_PATH("ArgumentNBTKey"),
+
+ /**
+ * A scoreboard objective.
+ */
+ SCOREBOARD_OBJECTIVE("ArgumentScoreboardObjective"),
+
+ /**
+ * A single score criterion.
+ */
+ OBJECTIVE_CRITERIA("ArgumentScoreboardCriteria"),
+
+ /**
+ * A scoreboard operator.
+ */
+ SCOREBOARD_SLOT("ArgumentScoreboardSlot"),
+
+ /**
+ * Something that can join a team. Allows selectors and *.
+ */
+ SCORE_HOLDER("ArgumentScoreholder"),
+
+ /**
+ * The name of a team. Parsed as an unquoted string.
+ */
+ TEAM("ArgumentScoreboardTeam"),
+
+ /**
+ * A scoreboard operator.
+ */
+ OPERATION("ArgumentMathOperation"),
+
+ /**
+ * A particle effect (an identifier with extra information following it for
+ * specific particles, mirroring the Particle packet)
+ */
+ PARTICLE("ArgumentParticle"),
+
+ /**
+ * Represents an angle.
+ */
+ ANGLE("ArgumentAngle"),
+
+ /**
+ * A name for an inventory slot.
+ */
+ ITEM_SLOT("ArgumentInventorySlot"),
+
+ /**
+ * An Identifier.
+ */
+ RESOURCE_LOCATION("ArgumentMinecraftKeyRegistered"),
+
+ /**
+ * A potion effect.
+ */
+ POTION_EFFECT("ArgumentMobEffect"),
+
+ /**
+ * Represents a item enchantment.
+ */
+ ENCHANTMENT("ArgumentEnchantment"),
+
+ /**
+ * Represents an entity summon.
+ */
+ ENTITY_SUMMON("ArgumentEntitySummon"),
+
+ /**
+ * Represents a dimension.
+ */
+ DIMENSION("ArgumentDimension"),
+
+ /**
+ * Represents a time duration.
+ */
+ TIME("ArgumentTime"),
+
+ /**
+ * Represents a UUID value.
+ *
+ * @since Minecraft 1.16
+ */
+ UUID("ArgumentUUID"),
+
+ /**
+ * A location, represented as 3 numbers (which must be integers). May use relative locations
+ * with ~
+ */
+ BLOCK_POS("coordinates.ArgumentPosition"),
+
+ /**
+ * A column location, represented as 3 numbers (which must be integers). May use relative locations
+ * with ~.
+ */
+ COLUMN_POS("coordinates.ArgumentVec2I"),
+
+ /**
+ * A location, represented as 3 numbers (which may have a decimal point, but will be moved to the
+ * center of a block if none is specified). May use relative locations with ~.
+ */
+ VECTOR_3("coordinates.ArgumentVec3"),
+
+ /**
+ * A location, represented as 2 numbers (which may have a decimal point, but will be moved to the center
+ * of a block if none is specified). May use relative locations with ~.
+ */
+ VECTOR_2("coordinates.ArgumentVec2"),
+
+ /**
+ * An angle, represented as 2 numbers (which may have a decimal point, but will be moved to the
+ * center of a block if none is specified). May use relative locations with ~.
+ */
+ ROTATION("coordinates.ArgumentRotation"),
+
+ /**
+ * A collection of up to 3 axes.
+ */
+ SWIZZLE("coordinates.ArgumentRotationAxis"),
+
+ /**
+ * A block state, optionally including NBT and state information.
+ */
+ BLOCK_STATE("blocks.ArgumentTile"),
+
+ /**
+ * A block, or a block tag.
+ */
+ BLOCK_PREDICATE("blocks.ArgumentBlockPredicate"),
+
+ /**
+ * An item, optionally including NBT.
+ */
+ ITEM_STACK("item.ArgumentItemStack"),
+
+ /**
+ * An item, or an item tag.
+ */
+ ITEM_PREDICATE("item.ArgumentItemPredicate"),
+
+ /**
+ * A function.
+ */
+ FUNCTION("item.ArgumentTag"),
+
+ /**
+ * The entity anchor related to the facing argument in the teleport command,
+ * is feet or eyes.
+ */
+ ENTITY_ANCHOR("ArgumentAnchor"),
+
+ /**
+ * An integer range of values with a min and a max.
+ */
+ INT_RANGE("ArgumentCriterionValue$b"),
+
+ /**
+ * A floating-point range of values with a min and a max.
+ */
+ FLOAT_RANGE("ArgumentCriterionValue$a"),
+
+ /**
+ * Template mirror
+ *
+ * @since Minecraft 1.19
+ */
+ TEMPLATE_MIRROR("TemplateMirrorArgument"),
+
+ /**
+ * Template rotation
+ *
+ * @since Minecraft 1.19
+ */
+ TEMPLATE_ROTATION("TemplateRotationArgument");
+
+ /**
+ * A ready-to-use instance used for singleton argument types
+ */
+ private ArgumentType> argumentType;
+ private Constructor extends ArgumentType> argumentConstructor;
+ private final Class>[] parameters;
+
+ MinecraftArgumentType(String name, Class>... parameters) {
+ Class> argumentClass = resolveArgumentClass(name);
+ this.parameters = parameters;
+ if (argumentClass == null) {
+ argumentType = null;
+ argumentConstructor = null;
+ return;
+ }
+ try {
+ argumentConstructor = argumentClass.asSubclass(ArgumentType.class).getDeclaredConstructor(parameters);
+ if (!argumentConstructor.isAccessible())
+ argumentConstructor.setAccessible(true);
+ if (parameters.length == 0) {
+ argumentType = argumentConstructor.newInstance();
+ } else {
+ argumentType = null;
+ }
+ } catch (Throwable e) {
+ argumentType = null;
+ argumentConstructor = null;
+ }
+ }
+
+ /**
+ * Checks if this argument type is supported in this Minecraft version
+ *
+ * @return If this is supported
+ */
+ public boolean isSupported() {
+ return argumentConstructor != null;
+ }
+
+ /**
+ * Checks if this argument type requires parameters
+ *
+ * @return If this requires parameters
+ */
+ public boolean requiresParameters() {
+ return parameters.length != 0;
+ }
+
+ /**
+ * Returns the argument type represented by this enum value, otherwise
+ * throws an exception
+ *
+ * @param