bukkit: Update for Minecraft 1.17

This commit is contained in:
Jason Penilla 2021-06-11 03:00:39 -07:00 committed by Jason
parent f7e756e901
commit 123341563d
10 changed files with 253 additions and 50 deletions

View file

@ -13,7 +13,7 @@ object Versions {
// MINECRAFT DEPENDENCIES // MINECRAFT DEPENDENCIES
const val brigadier = "1.0.17" const val brigadier = "1.0.17"
const val bukkit = "1.13.2-R0.1-SNAPSHOT" 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 bungeecord = "1.8-SNAPSHOT"
const val cloudburst = "1.0.0-SNAPSHOT" const val cloudburst = "1.0.0-SNAPSHOT"
const val adventureApi = "4.7.0" const val adventureApi = "4.7.0"

View file

@ -27,6 +27,7 @@ import cloud.commandframework.arguments.parser.ArgumentParser;
import cloud.commandframework.arguments.standard.UUIDArgument; import cloud.commandframework.arguments.standard.UUIDArgument;
import cloud.commandframework.brigadier.CloudBrigadierManager; import cloud.commandframework.brigadier.CloudBrigadierManager;
import cloud.commandframework.bukkit.internal.CraftBukkitReflection; import cloud.commandframework.bukkit.internal.CraftBukkitReflection;
import cloud.commandframework.bukkit.internal.MinecraftArgumentTypes;
import cloud.commandframework.bukkit.parsers.BlockPredicateArgument; import cloud.commandframework.bukkit.parsers.BlockPredicateArgument;
import cloud.commandframework.bukkit.parsers.EnchantmentArgument; import cloud.commandframework.bukkit.parsers.EnchantmentArgument;
import cloud.commandframework.bukkit.parsers.ItemStackArgument; import cloud.commandframework.bukkit.parsers.ItemStackArgument;
@ -41,6 +42,7 @@ import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import io.leangen.geantyref.GenericTypeReflector; import io.leangen.geantyref.GenericTypeReflector;
import io.leangen.geantyref.TypeToken; import io.leangen.geantyref.TypeToken;
import org.bukkit.NamespacedKey;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
@ -59,7 +61,6 @@ public final class BukkitBrigadierMapper<C> {
private final BukkitCommandManager<C> commandManager; private final BukkitCommandManager<C> commandManager;
private final CloudBrigadierManager<C, ?> brigadierManager; private final CloudBrigadierManager<C, ?> brigadierManager;
/** /**
* Class that handles mapping argument types to Brigadier for Bukkit (Commodore) and Paper. * Class that handles mapping argument types to Brigadier for Bukkit (Commodore) and Paper.
* *
@ -87,19 +88,19 @@ public final class BukkitBrigadierMapper<C> {
if (CraftBukkitReflection.MAJOR_REVISION >= UUID_ARGUMENT_VERSION) { if (CraftBukkitReflection.MAJOR_REVISION >= UUID_ARGUMENT_VERSION) {
/* Map UUID */ /* Map UUID */
this.mapSimpleNMS(new TypeToken<UUIDArgument.UUIDParser<C>>() { this.mapSimpleNMS(new TypeToken<UUIDArgument.UUIDParser<C>>() {
}, "UUID"); }, "uuid");
} }
/* Map Enchantment */ /* Map Enchantment */
this.mapSimpleNMS(new TypeToken<EnchantmentArgument.EnchantmentParser<C>>() { this.mapSimpleNMS(new TypeToken<EnchantmentArgument.EnchantmentParser<C>>() {
}, "Enchantment"); }, "item_enchantment");
/* Map Item arguments */ /* Map Item arguments */
this.mapSimpleNMS(new TypeToken<ItemStackArgument.Parser<C>>() { this.mapSimpleNMS(new TypeToken<ItemStackArgument.Parser<C>>() {
}, "ItemStack"); }, "item_stack");
this.mapSimpleNMS(new TypeToken<ItemStackPredicateArgument.Parser<C>>() { this.mapSimpleNMS(new TypeToken<ItemStackPredicateArgument.Parser<C>>() {
}, "ItemPredicate"); }, "item_predicate");
/* Map Block arguments */ /* Map Block arguments */
this.mapSimpleNMS(new TypeToken<BlockPredicateArgument.Parser<C>>() { this.mapSimpleNMS(new TypeToken<BlockPredicateArgument.Parser<C>>() {
}, "BlockPredicate"); }, "block_predicate");
/* Map Entity Selectors */ /* Map Entity Selectors */
this.mapNMS(new TypeToken<SingleEntitySelectorArgument.SingleEntitySelectorParser<C>>() { this.mapNMS(new TypeToken<SingleEntitySelectorArgument.SingleEntitySelectorParser<C>>() {
}, this.entitySelectorArgumentSupplier(true, false)); }, this.entitySelectorArgumentSupplier(true, false));
@ -128,7 +129,8 @@ public final class BukkitBrigadierMapper<C> {
) { ) {
return () -> { return () -> {
try { try {
final Constructor<?> constructor = getNMSArgument("Entity").getDeclaredConstructors()[0]; final Constructor<?> constructor =
MinecraftArgumentTypes.getClassByKey(NamespacedKey.minecraft("entity")).getDeclaredConstructors()[0];
constructor.setAccessible(true); constructor.setAccessible(true);
return (ArgumentType<?>) constructor.newInstance(single, playersOnly); return (ArgumentType<?>) constructor.newInstance(single, playersOnly);
} catch (final Exception e) { } catch (final Exception e) {
@ -140,7 +142,8 @@ public final class BukkitBrigadierMapper<C> {
private @NonNull ArgumentType<?> argumentVec3() { private @NonNull ArgumentType<?> argumentVec3() {
try { try {
return (ArgumentType<?>) getNMSArgument("Vec3").getDeclaredConstructor(boolean.class) return MinecraftArgumentTypes.getClassByKey(NamespacedKey.minecraft("vec3"))
.getDeclaredConstructor(boolean.class)
.newInstance(true); .newInstance(true);
} catch (final Exception e) { } catch (final Exception e) {
this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Vec3D argument", e); this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Vec3D argument", e);
@ -150,45 +153,34 @@ public final class BukkitBrigadierMapper<C> {
private @NonNull ArgumentType<?> argumentVec2() { private @NonNull ArgumentType<?> argumentVec2() {
try { try {
return (ArgumentType<?>) getNMSArgument("Vec2").getDeclaredConstructor().newInstance(); return MinecraftArgumentTypes.getClassByKey(NamespacedKey.minecraft("vec2")).getDeclaredConstructor().newInstance();
} catch (final Exception e) { } catch (final Exception e) {
this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Vec2 argument", e); this.commandManager.getOwningPlugin().getLogger().log(Level.INFO, "Failed to retrieve Vec2 argument", e);
return fallbackType(); 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 * Attempt to register a mapping between a cloud argument parser type and an NMS brigadier argument type which
* has a no-args constructor. * has a no-args constructor.
* *
* @param type Type to map * @param type Type to map
* @param <T> argument parser type * @param <T> argument parser type
* @param argumentName NMS Argument class name (without 'Argument' prefix) * @param argumentId network id of argument type
* @since 1.5.0 * @since 1.5.0
*/ */
public <T extends ArgumentParser<C, ?>> void mapSimpleNMS( public <T extends ArgumentParser<C, ?>> void mapSimpleNMS(
final @NonNull TypeToken<T> type, final @NonNull TypeToken<T> type,
final @NonNull String argumentName final @NonNull String argumentId
) { ) {
final Constructor<?> constructor; final Constructor<?> constructor;
try { try {
final Class<?> nmsArgument = getNMSArgument(argumentName); final Class<?> nmsArgument = MinecraftArgumentTypes.getClassByKey(NamespacedKey.minecraft(argumentId));
constructor = nmsArgument.getConstructor(); constructor = nmsArgument.getConstructor();
} catch (final RuntimeException | ReflectiveOperationException e) { } catch (final RuntimeException | ReflectiveOperationException e) {
this.commandManager.getOwningPlugin().getLogger().log( this.commandManager.getOwningPlugin().getLogger().log(
Level.WARNING, 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 e
); );
return; return;

View file

@ -31,6 +31,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays;
/** /**
* Utilities for doing reflection on CraftBukkit, used by the cloud implementation. * Utilities for doing reflection on CraftBukkit, used by the cloud implementation.
@ -41,6 +42,7 @@ import java.lang.reflect.Method;
public final class CraftBukkitReflection { public final class CraftBukkitReflection {
private static final String PREFIX_NMS = "net.minecraft.server"; 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 PREFIX_CRAFTBUKKIT = "org.bukkit.craftbukkit";
private static final String CRAFT_SERVER = "CraftServer"; private static final String CRAFT_SERVER = "CraftServer";
private static final String VERSION; private static final String VERSION;
@ -66,6 +68,31 @@ public final class CraftBukkitReflection {
return MAJOR_REVISION != -1 && VERSION != null; 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 { public static @NonNull Class<?> needNMSClass(final @NonNull String className) throws RuntimeException {
return needClass(PREFIX_NMS + VERSION + className); return needClass(PREFIX_NMS + VERSION + className);
} }
@ -74,6 +101,18 @@ public final class CraftBukkitReflection {
return needClass(PREFIX_CRAFTBUKKIT + VERSION + className); 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 { public static @NonNull Class<?> needClass(final @NonNull String className) throws RuntimeException {
try { try {
return Class.forName(className); return Class.forName(className);

View file

@ -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) <luck@lucko.me>
* 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<? extends ArgumentType<?>> 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<? extends ArgumentType<?>>) argument;
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
}

View file

@ -143,24 +143,45 @@ public final class BlockPredicateArgument<C> extends CommandArgument<C, BlockPre
static { static {
if (CraftBukkitReflection.MAJOR_REVISION >= 16) { if (CraftBukkitReflection.MAJOR_REVISION >= 16) {
TAG_REGISTRY_CLASS = CraftBukkitReflection.needNMSClass("ITagRegistry"); TAG_REGISTRY_CLASS = CraftBukkitReflection.needNMSClassOrElse(
"ITagRegistry",
"net.minecraft.tags.ITagRegistry"
);
} else { } else {
TAG_REGISTRY_CLASS = CraftBukkitReflection.needNMSClass("TagRegistry"); TAG_REGISTRY_CLASS = CraftBukkitReflection.needNMSClass("TagRegistry");
} }
} }
private static final Class<?> CRAFT_WORLD_CLASS = CraftBukkitReflection.needOBCClass("CraftWorld"); private static final Class<?> CRAFT_WORLD_CLASS = CraftBukkitReflection.needOBCClass("CraftWorld");
private static final Class<?> MINECRAFT_SERVER_CLASS = CraftBukkitReflection.needNMSClass("MinecraftServer"); private static final Class<?> MINECRAFT_SERVER_CLASS = CraftBukkitReflection.needNMSClassOrElse(
private static final Class<?> COMMAND_LISTENER_WRAPPER_CLASS = "MinecraftServer",
CraftBukkitReflection.needNMSClass("CommandListenerWrapper"); "net.minecraft.server.MinecraftServer"
private static final Class<?> ARGUMENT_BLOCK_PREDICATE_CLASS = );
CraftBukkitReflection.needNMSClass("ArgumentBlockPredicate"); private static final Class<?> COMMAND_LISTENER_WRAPPER_CLASS = CraftBukkitReflection.needNMSClassOrElse(
private static final Class<?> ARGUMENT_BLOCK_PREDICATE_RESULT_CLASS = "CommandListenerWrapper",
CraftBukkitReflection.needNMSClass("ArgumentBlockPredicate$b"); "net.minecraft.commands.CommandListenerWrapper"
private static final Class<?> SHAPE_DETECTOR_BLOCK_CLASS = // BlockInWorld );
CraftBukkitReflection.needNMSClass("ShapeDetectorBlock"); private static final Class<?> ARGUMENT_BLOCK_PREDICATE_CLASS = CraftBukkitReflection.needNMSClassOrElse(
private static final Class<?> I_WORLD_READER_CLASS = CraftBukkitReflection.needNMSClass("IWorldReader"); "ArgumentBlockPredicate",
private static final Class<?> BLOCK_POSITION_CLASS = CraftBukkitReflection.needNMSClass("BlockPosition"); "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 = private static final Constructor<?> BLOCK_POSITION_CTR =
CraftBukkitReflection.needConstructor(BLOCK_POSITION_CLASS, int.class, int.class, int.class); CraftBukkitReflection.needConstructor(BLOCK_POSITION_CLASS, int.class, int.class, int.class);
private static final Constructor<?> SHAPE_DETECTOR_BLOCK_CTR = CraftBukkitReflection private static final Constructor<?> SHAPE_DETECTOR_BLOCK_CTR = CraftBukkitReflection

View file

@ -180,14 +180,24 @@ public final class ItemStackArgument<C> extends CommandArgument<C, ProtoItemStac
private static final class ModernParser<C> implements ArgumentParser<C, ProtoItemStack> { private static final class ModernParser<C> implements ArgumentParser<C, ProtoItemStack> {
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 = private static final Class<?> CRAFT_ITEM_STACK_CLASS =
CraftBukkitReflection.needOBCClass("inventory.CraftItemStack"); CraftBukkitReflection.needOBCClass("inventory.CraftItemStack");
private static final Class<?> ARGUMENT_ITEM_STACK_CLASS = private static final Class<?> ARGUMENT_ITEM_STACK_CLASS = CraftBukkitReflection.needNMSClassOrElse(
CraftBukkitReflection.needNMSClass("ArgumentItemStack"); "ArgumentItemStack",
private static final Class<?> ARGUMENT_PREDICATE_ITEM_STACK_CLASS = "net.minecraft.commands.arguments.item.ArgumentItemStack"
CraftBukkitReflection.needNMSClass("ArgumentPredicateItemStack"); );
private static final Class<?> NMS_ITEM_CLASS = CraftBukkitReflection.needNMSClass("Item"); 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 = private static final Class<?> CRAFT_MAGIC_NUMBERS_CLASS =
CraftBukkitReflection.needOBCClass("util.CraftMagicNumbers"); CraftBukkitReflection.needOBCClass("util.CraftMagicNumbers");
private static final Method GET_MATERIAL_METHOD = CraftBukkitReflection private static final Method GET_MATERIAL_METHOD = CraftBukkitReflection

View file

@ -142,10 +142,14 @@ public final class ItemStackPredicateArgument<C> extends CommandArgument<C, Item
private static final Class<?> CRAFT_ITEM_STACK_CLASS = private static final Class<?> CRAFT_ITEM_STACK_CLASS =
CraftBukkitReflection.needOBCClass("inventory.CraftItemStack"); CraftBukkitReflection.needOBCClass("inventory.CraftItemStack");
private static final Class<?> ARGUMENT_ITEM_PREDICATE_CLASS = private static final Class<?> ARGUMENT_ITEM_PREDICATE_CLASS = CraftBukkitReflection.needNMSClassOrElse(
CraftBukkitReflection.needNMSClass("ArgumentItemPredicate"); "ArgumentItemPredicate",
private static final Class<?> ARGUMENT_ITEM_PREDICATE_RESULT_CLASS = "net.minecraft.commands.arguments.item.ArgumentItemPredicate"
CraftBukkitReflection.needNMSClass("ArgumentItemPredicate$b"); );
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( private static final Method CREATE_PREDICATE_METHOD = CraftBukkitReflection.needMethod(
ARGUMENT_ITEM_PREDICATE_RESULT_CLASS, ARGUMENT_ITEM_PREDICATE_RESULT_CLASS,
"create", "create",

View file

@ -1,5 +1,6 @@
plugins { plugins {
id("com.github.johnrengelman.shadow") id("com.github.johnrengelman.shadow")
id("xyz.jpenilla.run-paper") version "1.0.3-SNAPSHOT"
} }
tasks { tasks {
@ -11,6 +12,11 @@ tasks {
build { build {
dependsOn(shadowJar) dependsOn(shadowJar)
} }
runServer {
minecraftVersion("1.17")
paperclip(file("spigot-1.17.jar"))
legacyPluginLoading()
}
} }
dependencies { dependencies {

View file

@ -476,7 +476,10 @@ public final class ExamplePlugin extends JavaPlugin {
}, },
ArgumentDescription.of("The ItemStack to give") 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]") @CommandMethod("example help [query]")

View file

@ -2,6 +2,7 @@ pluginManagement {
repositories { repositories {
gradlePluginPortal() gradlePluginPortal()
maven("https://maven.fabricmc.net") maven("https://maven.fabricmc.net")
maven("https://repo.jpenilla.xyz/snapshots") // todo - for run-paper snapshot
} }
} }