cloud.commandframework.bukkit.parsers.ItemStackPredicateArgument Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cloud-bukkit Show documentation
Show all versions of cloud-bukkit Show documentation
Command framework and dispatcher for the JVM
//
// MIT License
//
// Copyright (c) 2022 Alexander Söderberg & Contributors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package cloud.commandframework.bukkit.parsers;
import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.brigadier.argument.WrappedBrigadierParser;
import cloud.commandframework.bukkit.BukkitCommandManager;
import cloud.commandframework.bukkit.data.ItemStackPredicate;
import cloud.commandframework.bukkit.internal.CommandBuildContextSupplier;
import cloud.commandframework.bukkit.internal.CraftBukkitReflection;
import cloud.commandframework.bukkit.internal.MinecraftArgumentTypes;
import cloud.commandframework.context.CommandContext;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.StringRange;
import io.leangen.geantyref.TypeToken;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Argument type for parsing an {@link ItemStackPredicate}.
*
* This argument type is only usable on Minecraft 1.13+, as it depends on Minecraft internals added in that version.
*
* This argument type only provides basic suggestions by default. Enabling Brigadier compatibility through
* {@link BukkitCommandManager#registerBrigadier()} will allow client side validation and suggestions to be utilized.
*
* @param Command sender type
* @since 1.5.0
*/
public final class ItemStackPredicateArgument extends CommandArgument {
private ItemStackPredicateArgument(
final boolean required,
final @NonNull String name,
final @NonNull String defaultValue,
final @Nullable BiFunction<@NonNull CommandContext, @NonNull String,
@NonNull List<@NonNull String>> suggestionsProvider,
final @NonNull ArgumentDescription defaultDescription
) {
super(required, name, new Parser<>(), defaultValue, ItemStackPredicate.class, suggestionsProvider, defaultDescription);
}
/**
* Create a new {@link Builder}.
*
* @param name Name of the argument
* @param Command sender type
* @return Created builder
* @since 1.5.0
*/
public static ItemStackPredicateArgument.@NonNull Builder builder(final @NonNull String name) {
return new ItemStackPredicateArgument.Builder<>(name);
}
/**
* Create a new required {@link ItemStackPredicateArgument}.
*
* @param name Argument name
* @param Command sender type
* @return Created argument
* @since 1.5.0
*/
public static @NonNull ItemStackPredicateArgument of(final @NonNull String name) {
return ItemStackPredicateArgument.builder(name).build();
}
/**
* Create a new optional {@link ItemStackPredicateArgument}.
*
* @param name Argument name
* @param Command sender type
* @return Created argument
* @since 1.5.0
*/
public static @NonNull ItemStackPredicateArgument optional(final @NonNull String name) {
return ItemStackPredicateArgument.builder(name).asOptional().build();
}
/**
* Builder for {@link ItemStackPredicateArgument}.
*
* @param sender type
* @since 1.5.0
*/
public static final class Builder extends TypedBuilder> {
private Builder(final @NonNull String name) {
super(ItemStackPredicate.class, name);
}
@Override
public @NonNull ItemStackPredicateArgument build() {
return new ItemStackPredicateArgument<>(
this.isRequired(),
this.getName(),
this.getDefaultValue(),
this.getSuggestionsProvider(),
this.getDefaultDescription()
);
}
}
/**
* Parser for {@link ItemStackPredicateArgument}. Only supported on Minecraft 1.13 and newer CraftBukkit based servers.
*
* @param sender type
* @since 1.5.0
*/
public static final class Parser implements ArgumentParser {
private static final Class> CRAFT_ITEM_STACK_CLASS =
CraftBukkitReflection.needOBCClass("inventory.CraftItemStack");
private static final Class> ARGUMENT_ITEM_PREDICATE_CLASS =
MinecraftArgumentTypes.getClassByKey(NamespacedKey.minecraft("item_predicate"));
private static final Class> ARGUMENT_ITEM_PREDICATE_RESULT_CLASS = CraftBukkitReflection.firstNonNullOrNull(
CraftBukkitReflection.findNMSClass("ArgumentItemPredicate$b"),
CraftBukkitReflection.findMCClass("commands.arguments.item.ArgumentItemPredicate$b"),
CraftBukkitReflection.findMCClass("commands.arguments.item.ItemPredicateArgument$Result")
);
private static final @Nullable Method CREATE_PREDICATE_METHOD = ARGUMENT_ITEM_PREDICATE_RESULT_CLASS == null
? null
: CraftBukkitReflection.firstNonNullOrNull(
CraftBukkitReflection.findMethod(
ARGUMENT_ITEM_PREDICATE_RESULT_CLASS,
"create",
com.mojang.brigadier.context.CommandContext.class
),
CraftBukkitReflection.findMethod(
ARGUMENT_ITEM_PREDICATE_RESULT_CLASS,
"a",
com.mojang.brigadier.context.CommandContext.class
)
);
private static final Method AS_NMS_COPY_METHOD =
CraftBukkitReflection.needMethod(CRAFT_ITEM_STACK_CLASS, "asNMSCopy", ItemStack.class);
private final ArgumentParser parser;
/**
* Create a new {@link Parser}.
*
* @since 1.5.0
*/
public Parser() {
try {
this.parser = this.createParser();
} catch (final ReflectiveOperationException ex) {
throw new RuntimeException("Failed to initialize ItemPredicate parser.", ex);
}
}
@SuppressWarnings("unchecked")
private ArgumentParser createParser() throws ReflectiveOperationException {
final Constructor> ctr = ARGUMENT_ITEM_PREDICATE_CLASS.getDeclaredConstructors()[0];
final ArgumentType