From ab0a9299e40f3034e94536c229c47a3c01a39876 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sun, 27 Jun 2021 17:07:58 -0700 Subject: [PATCH] bukkit: Check class presence for CloudBukkitCapabilities instead of using Minecraft version --- .../bukkit/BukkitBrigadierMapper.java | 7 +- .../bukkit/BukkitCommandManager.java | 66 ++----------------- .../bukkit/CloudBukkitCapabilities.java | 34 ++++++++-- .../examples/bukkit/ExamplePlugin.java | 8 +-- 4 files changed, 45 insertions(+), 70 deletions(-) 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 38863814..cc969868 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 @@ -74,13 +74,16 @@ public final class BukkitBrigadierMapper { this.registerMappings(); } + @SuppressWarnings("unused") private void registerMappings() { /* UUID nms argument is a 1.16+ feature */ - final Class> uuid = MinecraftArgumentTypes.getClassByKey(NamespacedKey.minecraft("uuid")); - if (uuid != null) { + try { + final Class> uuid = MinecraftArgumentTypes.getClassByKey(NamespacedKey.minecraft("uuid")); /* Map UUID */ this.mapSimpleNMS(new TypeToken>() { }, "uuid"); + } catch (final IllegalArgumentException ignore) { + // < 1.16 } /* Map Enchantment */ this.mapSimpleNMS(new TypeToken>() { diff --git a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitCommandManager.java b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitCommandManager.java index 7dae4987..fb10eff4 100644 --- a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitCommandManager.java +++ b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitCommandManager.java @@ -32,7 +32,6 @@ import cloud.commandframework.bukkit.arguments.selector.MultiplePlayerSelector; import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector; import cloud.commandframework.bukkit.arguments.selector.SinglePlayerSelector; import cloud.commandframework.bukkit.data.ProtoItemStack; -import cloud.commandframework.bukkit.internal.CraftBukkitReflection; import cloud.commandframework.bukkit.parsers.BlockPredicateArgument; import cloud.commandframework.bukkit.parsers.EnchantmentArgument; import cloud.commandframework.bukkit.parsers.ItemStackArgument; @@ -52,7 +51,6 @@ import cloud.commandframework.execution.CommandExecutionCoordinator; import cloud.commandframework.tasks.TaskFactory; import cloud.commandframework.tasks.TaskRecipe; import io.leangen.geantyref.TypeToken; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.OfflinePlayer; @@ -65,12 +63,9 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import java.lang.reflect.Method; -import java.util.EnumSet; import java.util.Set; import java.util.function.Function; import java.util.function.UnaryOperator; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * Command manager for the Bukkit platform @@ -80,14 +75,7 @@ import java.util.regex.Pattern; @SuppressWarnings("unchecked") public class BukkitCommandManager extends CommandManager implements BrigadierManagerHolder { - private static final int VERSION_RADIX = 10; - private static final int BRIGADIER_MINIMUM_VERSION = 13; - private static final int PAPER_BRIGADIER_VERSION = 15; - private static final int ASYNC_TAB_MINIMUM_VERSION = 12; - private final Plugin owningPlugin; - private final int minecraftVersion; - private final boolean paper = CraftBukkitReflection.classExists("com.destroystokyo.paper.PaperConfig"); private final Function commandSenderMapper; private final Function backwardsCommandSenderMapper; @@ -139,9 +127,6 @@ public class BukkitCommandManager extends CommandManager implements Brigad final BukkitSynchronizer bukkitSynchronizer = new BukkitSynchronizer(owningPlugin); this.taskFactory = new TaskFactory(bukkitSynchronizer); - /* Try to determine the Minecraft version */ - this.minecraftVersion = this.getMinecraftVersion(); - /* Register Bukkit Preprocessor */ this.registerCommandPreProcessor(new BukkitCommandPreprocessor<>(this)); @@ -173,7 +158,7 @@ public class BukkitCommandManager extends CommandManager implements Brigad new MultiplePlayerSelectorArgument.MultiplePlayerSelectorParser<>()); /* Register MC 1.13+ parsers */ - if (this.minecraftVersion >= BRIGADIER_MINIMUM_VERSION) { + if (this.queryCapability(CloudBukkitCapabilities.BRIGADIER)) { this.registerParserSupplierFor(ItemStackPredicateArgument.class); this.registerParserSupplierFor(BlockPredicateArgument.class); } @@ -187,19 +172,6 @@ public class BukkitCommandManager extends CommandManager implements Brigad this.setCaptionRegistry(new BukkitCaptionRegistryFactory().create()); } - private int getMinecraftVersion() { - try { - final Matcher matcher = Pattern.compile("\\(MC: (\\d)\\.(\\d+)\\.?(\\d+?)?\\)").matcher(Bukkit.getVersion()); - if (matcher.find()) { - return Integer.parseInt(matcher.toMatchResult().group(2), VERSION_RADIX); - } - } catch (final Exception e) { - this.owningPlugin.getLogger() - .severe("Failed to determine Minecraft version for cloud Bukkit capability detection"); - } - return -1; - } - /** * Create a command manager using Bukkit's {@link CommandSender} as the sender type. * @@ -288,7 +260,9 @@ public class BukkitCommandManager extends CommandManager implements Brigad if (!this.queryCapability(CloudBukkitCapabilities.BRIGADIER)) { throw new BrigadierFailureException( BrigadierFailureReason.VERSION_TOO_LOW, - new IllegalArgumentException("Version: " + this.minecraftVersion) + new IllegalArgumentException( + "Brigadier does not appear to be present on the currently running server. This is usually due to " + + "running too old a version of Minecraft (Brigadier is implemented in 1.13 and newer).") ); } } @@ -300,7 +274,7 @@ public class BukkitCommandManager extends CommandManager implements Brigad * @return {@code true} if the manager has the given capability, else {@code false} */ public final boolean queryCapability(final @NonNull CloudBukkitCapabilities capability) { - return this.queryCapabilities().contains(capability); + return capability.capable(); } /** @@ -309,33 +283,7 @@ public class BukkitCommandManager extends CommandManager implements Brigad * @return A set containing all capabilities of the instance */ public final @NonNull Set<@NonNull CloudBukkitCapabilities> queryCapabilities() { - if (this.paper) { - if (this.minecraftVersion >= ASYNC_TAB_MINIMUM_VERSION) { - if (this.minecraftVersion >= PAPER_BRIGADIER_VERSION) { - return EnumSet.of( - CloudBukkitCapabilities.NATIVE_BRIGADIER, - CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION, - CloudBukkitCapabilities.BRIGADIER - ); - } else if (this.minecraftVersion >= BRIGADIER_MINIMUM_VERSION) { - return EnumSet.of( - CloudBukkitCapabilities.COMMODORE_BRIGADIER, - CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION, - CloudBukkitCapabilities.BRIGADIER - ); - } else { - return EnumSet.of(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION); - } - } - } else { - if (this.minecraftVersion >= BRIGADIER_MINIMUM_VERSION) { - return EnumSet.of( - CloudBukkitCapabilities.COMMODORE_BRIGADIER, - CloudBukkitCapabilities.BRIGADIER - ); - } - } - return EnumSet.noneOf(CloudBukkitCapabilities.class); + return CloudBukkitCapabilities.CAPABLE; } /** @@ -424,7 +372,7 @@ public class BukkitCommandManager extends CommandManager implements Brigad } final void lockIfBrigadierCapable() { - if (this.minecraftVersion >= BRIGADIER_MINIMUM_VERSION) { + if (this.queryCapability(CloudBukkitCapabilities.BRIGADIER)) { this.lockRegistration(); } } diff --git a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/CloudBukkitCapabilities.java b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/CloudBukkitCapabilities.java index ba8e5516..97d4468b 100644 --- a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/CloudBukkitCapabilities.java +++ b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/CloudBukkitCapabilities.java @@ -23,12 +23,38 @@ // package cloud.commandframework.bukkit; +import cloud.commandframework.bukkit.internal.CraftBukkitReflection; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + /** * Capabilities for the Bukkit module */ public enum CloudBukkitCapabilities { - BRIGADIER, - COMMODORE_BRIGADIER, - NATIVE_BRIGADIER, - ASYNCHRONOUS_COMPLETION + BRIGADIER(CraftBukkitReflection.classExists("com.mojang.brigadier.tree.CommandNode") + && CraftBukkitReflection.findOBCClass("command.BukkitCommandWrapper") != null), + + NATIVE_BRIGADIER(CraftBukkitReflection.classExists( + "com.destroystokyo.paper.event.brigadier.CommandRegisteredEvent")), + + COMMODORE_BRIGADIER(BRIGADIER.capable() && !NATIVE_BRIGADIER.capable()), + + ASYNCHRONOUS_COMPLETION(CraftBukkitReflection.classExists( + "com.destroystokyo.paper.event.server.AsyncTabCompleteEvent")); + + static final Set CAPABLE = Arrays.stream(values()) + .filter(CloudBukkitCapabilities::capable) + .collect(Collectors.toSet()); + + private final boolean capable; + + CloudBukkitCapabilities(final boolean capable) { + this.capable = capable; + } + + boolean capable() { + return this.capable; + } } 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 eff44778..6658aa26 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 @@ -44,10 +44,8 @@ import cloud.commandframework.arguments.standard.StringArrayArgument; import cloud.commandframework.bukkit.BukkitCommandManager; import cloud.commandframework.bukkit.CloudBukkitCapabilities; import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector; -import cloud.commandframework.bukkit.data.BlockPredicate; import cloud.commandframework.bukkit.data.ItemStackPredicate; import cloud.commandframework.bukkit.data.ProtoItemStack; -import cloud.commandframework.bukkit.parsers.BlockPredicateArgument; import cloud.commandframework.bukkit.parsers.EnchantmentArgument; import cloud.commandframework.bukkit.parsers.ItemStackArgument; import cloud.commandframework.bukkit.parsers.ItemStackPredicateArgument; @@ -83,8 +81,6 @@ import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.data.BlockData; import org.bukkit.command.CommandSender; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.EntityType; @@ -386,8 +382,9 @@ public final class ExamplePlugin extends JavaPlugin { ))) ); - // MC 1.13+ commands + // MC 1.13+ commands todo: move to separate class if (this.manager.queryCapability(CloudBukkitCapabilities.BRIGADIER)) { + /* this.manager.command(builder.literal("replace") .senderType(Player.class) .argument(BlockPredicateArgument.of("predicate")) @@ -415,6 +412,7 @@ public final class ExamplePlugin extends JavaPlugin { } }).execute(); })); + */ this.manager.command(builder.literal("test_item") .argument(ItemStackArgument.of("item")) .literal("is")