From 123341563d2563642a47edc8b443bb060eaae6f4 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 11 Jun 2021 03:00:39 -0700 Subject: [PATCH] bukkit: Update for Minecraft 1.17 --- buildSrc/src/main/kotlin/Versions.kt | 2 +- .../bukkit/BukkitBrigadierMapper.java | 44 +++--- .../internal/CraftBukkitReflection.java | 39 ++++++ .../internal/MinecraftArgumentTypes.java | 127 ++++++++++++++++++ .../parsers/BlockPredicateArgument.java | 45 +++++-- .../bukkit/parsers/ItemStackArgument.java | 22 ++- .../parsers/ItemStackPredicateArgument.java | 12 +- examples/example-bukkit/build.gradle.kts | 6 + .../examples/bukkit/ExamplePlugin.java | 5 +- settings.gradle.kts | 1 + 10 files changed, 253 insertions(+), 50 deletions(-) create mode 100644 cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/MinecraftArgumentTypes.java diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 16c03341..908e93d7 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -13,7 +13,7 @@ object Versions { // MINECRAFT DEPENDENCIES const val brigadier = "1.0.17" const val bukkit = "1.13.2-R0.1-SNAPSHOT" - const val commodore = "1.9" + const val commodore = "1.10-SNAPSHOT" const val bungeecord = "1.8-SNAPSHOT" const val cloudburst = "1.0.0-SNAPSHOT" const val adventureApi = "4.7.0" diff --git a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitBrigadierMapper.java b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitBrigadierMapper.java index ae6a6ef1..41e87a51 100644 --- a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitBrigadierMapper.java +++ b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitBrigadierMapper.java @@ -27,6 +27,7 @@ import cloud.commandframework.arguments.parser.ArgumentParser; import cloud.commandframework.arguments.standard.UUIDArgument; import cloud.commandframework.brigadier.CloudBrigadierManager; import cloud.commandframework.bukkit.internal.CraftBukkitReflection; +import cloud.commandframework.bukkit.internal.MinecraftArgumentTypes; import cloud.commandframework.bukkit.parsers.BlockPredicateArgument; import cloud.commandframework.bukkit.parsers.EnchantmentArgument; import cloud.commandframework.bukkit.parsers.ItemStackArgument; @@ -41,6 +42,7 @@ import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; import io.leangen.geantyref.GenericTypeReflector; import io.leangen.geantyref.TypeToken; +import org.bukkit.NamespacedKey; import org.checkerframework.checker.nullness.qual.NonNull; import java.lang.reflect.Constructor; @@ -59,7 +61,6 @@ public final class BukkitBrigadierMapper { private final BukkitCommandManager commandManager; private final CloudBrigadierManager brigadierManager; - /** * Class that handles mapping argument types to Brigadier for Bukkit (Commodore) and Paper. * @@ -87,19 +88,19 @@ public final class BukkitBrigadierMapper { if (CraftBukkitReflection.MAJOR_REVISION >= UUID_ARGUMENT_VERSION) { /* Map UUID */ this.mapSimpleNMS(new TypeToken>() { - }, "UUID"); + }, "uuid"); } /* Map Enchantment */ this.mapSimpleNMS(new TypeToken>() { - }, "Enchantment"); + }, "item_enchantment"); /* Map Item arguments */ this.mapSimpleNMS(new TypeToken>() { - }, "ItemStack"); + }, "item_stack"); this.mapSimpleNMS(new TypeToken>() { - }, "ItemPredicate"); + }, "item_predicate"); /* Map Block arguments */ this.mapSimpleNMS(new TypeToken>() { - }, "BlockPredicate"); + }, "block_predicate"); /* Map Entity Selectors */ this.mapNMS(new TypeToken>() { }, this.entitySelectorArgumentSupplier(true, false)); @@ -128,7 +129,8 @@ public final class BukkitBrigadierMapper { ) { return () -> { try { - final Constructor constructor = getNMSArgument("Entity").getDeclaredConstructors()[0]; + final Constructor constructor = + MinecraftArgumentTypes.getClassByKey(NamespacedKey.minecraft("entity")).getDeclaredConstructors()[0]; constructor.setAccessible(true); return (ArgumentType) constructor.newInstance(single, playersOnly); } catch (final Exception e) { @@ -140,7 +142,8 @@ public final class BukkitBrigadierMapper { private @NonNull ArgumentType argumentVec3() { try { - return (ArgumentType) getNMSArgument("Vec3").getDeclaredConstructor(boolean.class) + return MinecraftArgumentTypes.getClassByKey(NamespacedKey.minecraft("vec3")) + .getDeclaredConstructor(boolean.class) .newInstance(true); } catch (final Exception e) { this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Vec3D argument", e); @@ -150,45 +153,34 @@ public final class BukkitBrigadierMapper { private @NonNull ArgumentType argumentVec2() { try { - return (ArgumentType) getNMSArgument("Vec2").getDeclaredConstructor().newInstance(); + return MinecraftArgumentTypes.getClassByKey(NamespacedKey.minecraft("vec2")).getDeclaredConstructor().newInstance(); } catch (final Exception e) { this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Vec2 argument", e); return fallbackType(); } } - /** - * Attempt to retrieve an NMS argument type - * - * @param argument Argument type name - * @return Argument class - * @throws RuntimeException when the class is not found - */ - private static @NonNull Class getNMSArgument(final @NonNull String argument) throws RuntimeException { - return CraftBukkitReflection.needNMSClass("Argument" + argument); - } - /** * Attempt to register a mapping between a cloud argument parser type and an NMS brigadier argument type which * has a no-args constructor. * - * @param type Type to map - * @param argument parser type - * @param argumentName NMS Argument class name (without 'Argument' prefix) + * @param type Type to map + * @param argument parser type + * @param argumentId network id of argument type * @since 1.5.0 */ public > void mapSimpleNMS( final @NonNull TypeToken type, - final @NonNull String argumentName + final @NonNull String argumentId ) { final Constructor constructor; try { - final Class nmsArgument = getNMSArgument(argumentName); + final Class nmsArgument = MinecraftArgumentTypes.getClassByKey(NamespacedKey.minecraft(argumentId)); constructor = nmsArgument.getConstructor(); } catch (final RuntimeException | ReflectiveOperationException e) { this.commandManager.getOwningPlugin().getLogger().log( Level.WARNING, - String.format("Failed to create mapping for NMS brigadier argument type '%s'.", argumentName), + String.format("Failed to create mapping for NMS brigadier argument type '%s'.", argumentId), e ); return; diff --git a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/CraftBukkitReflection.java b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/CraftBukkitReflection.java index 2dd06926..e46677b6 100644 --- a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/CraftBukkitReflection.java +++ b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/CraftBukkitReflection.java @@ -31,6 +31,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.Arrays; /** * Utilities for doing reflection on CraftBukkit, used by the cloud implementation. @@ -41,6 +42,7 @@ import java.lang.reflect.Method; public final class CraftBukkitReflection { private static final String PREFIX_NMS = "net.minecraft.server"; + private static final String PREFIX_MC = "net.minecraft."; private static final String PREFIX_CRAFTBUKKIT = "org.bukkit.craftbukkit"; private static final String CRAFT_SERVER = "CraftServer"; private static final String VERSION; @@ -66,6 +68,31 @@ public final class CraftBukkitReflection { return MAJOR_REVISION != -1 && VERSION != null; } + public static @NonNull Class needNMSClassOrElse( + final @NonNull String nms, + final @NonNull String... classNames + ) throws RuntimeException { + final Class nmsClass = findNMSClass(nms); + if (nmsClass != null) { + return nmsClass; + } + for (final String name : classNames) { + final Class maybe = findClass(name); + if (maybe != null) { + return maybe; + } + } + throw new IllegalStateException(String.format( + "Couldn't find a class! NMS: '%s' or '%s'.", + nms, + Arrays.toString(classNames) + )); + } + + public static @NonNull Class needMCClass(final @NonNull String name) throws RuntimeException { + return needClass(PREFIX_MC + name); + } + public static @NonNull Class needNMSClass(final @NonNull String className) throws RuntimeException { return needClass(PREFIX_NMS + VERSION + className); } @@ -74,6 +101,18 @@ public final class CraftBukkitReflection { return needClass(PREFIX_CRAFTBUKKIT + VERSION + className); } + public static @Nullable Class findMCClass(final @NonNull String name) throws RuntimeException { + return findClass(PREFIX_MC + name); + } + + public static @Nullable Class findNMSClass(final @NonNull String className) throws RuntimeException { + return findClass(PREFIX_NMS + VERSION + className); + } + + public static @Nullable Class findOBCClass(final @NonNull String className) throws RuntimeException { + return findClass(PREFIX_CRAFTBUKKIT + VERSION + className); + } + public static @NonNull Class needClass(final @NonNull String className) throws RuntimeException { try { return Class.forName(className); diff --git a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/MinecraftArgumentTypes.java b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/MinecraftArgumentTypes.java new file mode 100644 index 00000000..63dbf9fa --- /dev/null +++ b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/MinecraftArgumentTypes.java @@ -0,0 +1,127 @@ +// +// MIT License +// +// Copyright (c) 2021 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. +// +/* + * This file is part of commodore, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) 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.internal; + +import com.mojang.brigadier.arguments.ArgumentType; +import org.bukkit.NamespacedKey; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Arrays; + +/** + * A registry of the {@link ArgumentType}s provided by Minecraft. + * + * This file is taken from MIT licensed code in commodore (https://github.com/lucko/commodore). + */ +public final class MinecraftArgumentTypes { + + private MinecraftArgumentTypes() { + } + + private static final Constructor MINECRAFT_KEY_CONSTRUCTOR; + private static final Method ARGUMENT_REGISTRY_GET_BY_KEY_METHOD; + private static final Field ARGUMENT_REGISTRY_ENTRY_CLASS_FIELD; + + static { + try { + final Class minecraftKey; + final Class argumentRegistry; + + if (CraftBukkitReflection.MAJOR_REVISION > 16) { + minecraftKey = CraftBukkitReflection.needMCClass("resources.MinecraftKey"); + argumentRegistry = CraftBukkitReflection.needMCClass("commands.synchronization.ArgumentRegistry"); + } else { + minecraftKey = CraftBukkitReflection.needNMSClass("MinecraftKey"); + argumentRegistry = CraftBukkitReflection.needNMSClass("ArgumentRegistry"); + } + + MINECRAFT_KEY_CONSTRUCTOR = minecraftKey.getConstructor(String.class, String.class); + MINECRAFT_KEY_CONSTRUCTOR.setAccessible(true); + + ARGUMENT_REGISTRY_GET_BY_KEY_METHOD = Arrays.stream(argumentRegistry.getDeclaredMethods()) + .filter(method -> method.getParameterCount() == 1) + .filter(method -> minecraftKey.equals(method.getParameterTypes()[0])) + .findFirst().orElseThrow(NoSuchMethodException::new); + ARGUMENT_REGISTRY_GET_BY_KEY_METHOD.setAccessible(true); + + Class argumentRegistryEntry = ARGUMENT_REGISTRY_GET_BY_KEY_METHOD.getReturnType(); + ARGUMENT_REGISTRY_ENTRY_CLASS_FIELD = Arrays.stream(argumentRegistryEntry.getDeclaredFields()) + .filter(field -> field.getType() == Class.class) + .findFirst().orElseThrow(NoSuchFieldException::new); + ARGUMENT_REGISTRY_ENTRY_CLASS_FIELD.setAccessible(true); + } catch (ReflectiveOperationException e) { + throw new ExceptionInInitializerError(e); + } + } + + /** + * Gets a registered argument type class by key. + * + * @param key the key + * @return the returned argument type class + * @throws IllegalArgumentException if no such argument is registered + */ + @SuppressWarnings("unchecked") + public static Class> getClassByKey(NamespacedKey key) throws IllegalArgumentException { + try { + Object minecraftKey = MINECRAFT_KEY_CONSTRUCTOR.newInstance(key.getNamespace(), key.getKey()); + Object entry = ARGUMENT_REGISTRY_GET_BY_KEY_METHOD.invoke(null, minecraftKey); + if (entry == null) { + throw new IllegalArgumentException(key.toString()); + } + + final Class argument = (Class) ARGUMENT_REGISTRY_ENTRY_CLASS_FIELD.get(entry); + return (Class>) argument; + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/BlockPredicateArgument.java b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/BlockPredicateArgument.java index ad60e7cc..723819f3 100644 --- a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/BlockPredicateArgument.java +++ b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/BlockPredicateArgument.java @@ -143,24 +143,45 @@ public final class BlockPredicateArgument extends CommandArgument= 16) { - TAG_REGISTRY_CLASS = CraftBukkitReflection.needNMSClass("ITagRegistry"); + TAG_REGISTRY_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "ITagRegistry", + "net.minecraft.tags.ITagRegistry" + ); } else { TAG_REGISTRY_CLASS = CraftBukkitReflection.needNMSClass("TagRegistry"); } } private static final Class CRAFT_WORLD_CLASS = CraftBukkitReflection.needOBCClass("CraftWorld"); - private static final Class MINECRAFT_SERVER_CLASS = CraftBukkitReflection.needNMSClass("MinecraftServer"); - private static final Class COMMAND_LISTENER_WRAPPER_CLASS = - CraftBukkitReflection.needNMSClass("CommandListenerWrapper"); - private static final Class ARGUMENT_BLOCK_PREDICATE_CLASS = - CraftBukkitReflection.needNMSClass("ArgumentBlockPredicate"); - private static final Class ARGUMENT_BLOCK_PREDICATE_RESULT_CLASS = - CraftBukkitReflection.needNMSClass("ArgumentBlockPredicate$b"); - private static final Class SHAPE_DETECTOR_BLOCK_CLASS = // BlockInWorld - CraftBukkitReflection.needNMSClass("ShapeDetectorBlock"); - private static final Class I_WORLD_READER_CLASS = CraftBukkitReflection.needNMSClass("IWorldReader"); - private static final Class BLOCK_POSITION_CLASS = CraftBukkitReflection.needNMSClass("BlockPosition"); + private static final Class MINECRAFT_SERVER_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "MinecraftServer", + "net.minecraft.server.MinecraftServer" + ); + private static final Class COMMAND_LISTENER_WRAPPER_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "CommandListenerWrapper", + "net.minecraft.commands.CommandListenerWrapper" + ); + private static final Class ARGUMENT_BLOCK_PREDICATE_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "ArgumentBlockPredicate", + "net.minecraft.commands.arguments.blocks.ArgumentBlockPredicate" + ); + private static final Class ARGUMENT_BLOCK_PREDICATE_RESULT_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "ArgumentBlockPredicate$b", + "net.minecraft.commands.arguments.blocks.ArgumentBlockPredicate$b" + ); + // BlockInWorld + private static final Class SHAPE_DETECTOR_BLOCK_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "ShapeDetectorBlock", + "net.minecraft.world.level.block.state.pattern.ShapeDetectorBlock" + ); + private static final Class I_WORLD_READER_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "IWorldReader", + "net.minecraft.world.level.IWorldReader" + ); + private static final Class BLOCK_POSITION_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "BlockPosition", + "net.minecraft.core.BlockPosition" + ); private static final Constructor BLOCK_POSITION_CTR = CraftBukkitReflection.needConstructor(BLOCK_POSITION_CLASS, int.class, int.class, int.class); private static final Constructor SHAPE_DETECTOR_BLOCK_CTR = CraftBukkitReflection diff --git a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/ItemStackArgument.java b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/ItemStackArgument.java index 44934ef3..d7664100 100644 --- a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/ItemStackArgument.java +++ b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/ItemStackArgument.java @@ -180,14 +180,24 @@ public final class ItemStackArgument extends CommandArgument implements ArgumentParser { - private static final Class NMS_ITEM_STACK_CLASS = CraftBukkitReflection.needNMSClass("ItemStack"); + private static final Class NMS_ITEM_STACK_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "ItemStack", + "net.minecraft.world.item.ItemStack" + ); private static final Class CRAFT_ITEM_STACK_CLASS = CraftBukkitReflection.needOBCClass("inventory.CraftItemStack"); - private static final Class ARGUMENT_ITEM_STACK_CLASS = - CraftBukkitReflection.needNMSClass("ArgumentItemStack"); - private static final Class ARGUMENT_PREDICATE_ITEM_STACK_CLASS = - CraftBukkitReflection.needNMSClass("ArgumentPredicateItemStack"); - private static final Class NMS_ITEM_CLASS = CraftBukkitReflection.needNMSClass("Item"); + private static final Class ARGUMENT_ITEM_STACK_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "ArgumentItemStack", + "net.minecraft.commands.arguments.item.ArgumentItemStack" + ); + private static final Class ARGUMENT_PREDICATE_ITEM_STACK_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "ArgumentPredicateItemStack", + "net.minecraft.commands.arguments.item.ArgumentPredicateItemStack" + ); + private static final Class NMS_ITEM_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "Item", + "net.minecraft.world.item.Item" + ); private static final Class CRAFT_MAGIC_NUMBERS_CLASS = CraftBukkitReflection.needOBCClass("util.CraftMagicNumbers"); private static final Method GET_MATERIAL_METHOD = CraftBukkitReflection diff --git a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/ItemStackPredicateArgument.java b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/ItemStackPredicateArgument.java index a26b22d7..05877aa6 100644 --- a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/ItemStackPredicateArgument.java +++ b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/ItemStackPredicateArgument.java @@ -142,10 +142,14 @@ public final class ItemStackPredicateArgument extends CommandArgument CRAFT_ITEM_STACK_CLASS = CraftBukkitReflection.needOBCClass("inventory.CraftItemStack"); - private static final Class ARGUMENT_ITEM_PREDICATE_CLASS = - CraftBukkitReflection.needNMSClass("ArgumentItemPredicate"); - private static final Class ARGUMENT_ITEM_PREDICATE_RESULT_CLASS = - CraftBukkitReflection.needNMSClass("ArgumentItemPredicate$b"); + private static final Class ARGUMENT_ITEM_PREDICATE_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "ArgumentItemPredicate", + "net.minecraft.commands.arguments.item.ArgumentItemPredicate" + ); + private static final Class ARGUMENT_ITEM_PREDICATE_RESULT_CLASS = CraftBukkitReflection.needNMSClassOrElse( + "ArgumentItemPredicate$b", + "net.minecraft.commands.arguments.item.ArgumentItemPredicate$b" + ); private static final Method CREATE_PREDICATE_METHOD = CraftBukkitReflection.needMethod( ARGUMENT_ITEM_PREDICATE_RESULT_CLASS, "create", diff --git a/examples/example-bukkit/build.gradle.kts b/examples/example-bukkit/build.gradle.kts index 3a25d508..57332ce9 100644 --- a/examples/example-bukkit/build.gradle.kts +++ b/examples/example-bukkit/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("com.github.johnrengelman.shadow") + id("xyz.jpenilla.run-paper") version "1.0.3-SNAPSHOT" } tasks { @@ -11,6 +12,11 @@ tasks { build { dependsOn(shadowJar) } + runServer { + minecraftVersion("1.17") + paperclip(file("spigot-1.17.jar")) + legacyPluginLoading() + } } dependencies { diff --git a/examples/example-bukkit/src/main/java/cloud/commandframework/examples/bukkit/ExamplePlugin.java b/examples/example-bukkit/src/main/java/cloud/commandframework/examples/bukkit/ExamplePlugin.java index ee39cb9e..eff44778 100644 --- a/examples/example-bukkit/src/main/java/cloud/commandframework/examples/bukkit/ExamplePlugin.java +++ b/examples/example-bukkit/src/main/java/cloud/commandframework/examples/bukkit/ExamplePlugin.java @@ -476,7 +476,10 @@ public final class ExamplePlugin extends JavaPlugin { }, ArgumentDescription.of("The ItemStack to give") ) - .handler(ctx -> ((Player) ctx.getSender()).getInventory().addItem(ctx.get("itemstack")))); + .handler(ctx -> { + final ItemStack stack = ctx.get("itemstack"); + ((Player) ctx.getSender()).getInventory().addItem(stack); + })); } @CommandMethod("example help [query]") diff --git a/settings.gradle.kts b/settings.gradle.kts index cbb805f6..089d7e56 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,6 +2,7 @@ pluginManagement { repositories { gradlePluginPortal() maven("https://maven.fabricmc.net") + maven("https://repo.jpenilla.xyz/snapshots") // todo - for run-paper snapshot } }