From 70045c30f3e790de112460ef42462eb07eaa532a Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sun, 24 Oct 2021 10:17:06 -0400 Subject: [PATCH] Migrate reflection in MetaItemStack to a provider (#4592) --- Essentials/build.gradle | 4 ++ .../com/earth2me/essentials/Essentials.java | 15 ++++++++ .../com/earth2me/essentials/IEssentials.java | 3 ++ .../earth2me/essentials/MetaItemStack.java | 38 ++----------------- providers/1_12Provider/build.gradle | 12 ++++++ .../com/earth2me/essentials/FakeAccessor.java | 0 .../com/earth2me/essentials/FakeServer.java | 0 .../com/earth2me/essentials/FakeWorld.java | 0 .../earth2me/essentials/OfflinePlayer.java | 0 providers/1_8Provider/build.gradle | 5 ++- .../LegacyItemUnbreakableProvider.java | 16 ++++++++ .../provider/ItemUnbreakableProvider.java | 7 ++++ .../ModernItemUnbreakableProvider.java | 16 ++++++++ settings.gradle.kts | 1 + 14 files changed, 82 insertions(+), 35 deletions(-) create mode 100644 providers/1_12Provider/build.gradle rename providers/{1_8Provider => 1_12Provider}/src/main/java/com/earth2me/essentials/FakeAccessor.java (100%) rename providers/{1_8Provider => 1_12Provider}/src/main/java/com/earth2me/essentials/FakeServer.java (100%) rename providers/{1_8Provider => 1_12Provider}/src/main/java/com/earth2me/essentials/FakeWorld.java (100%) rename providers/{1_8Provider => 1_12Provider}/src/main/java/com/earth2me/essentials/OfflinePlayer.java (100%) create mode 100644 providers/1_8Provider/src/main/java/net/ess3/provider/providers/LegacyItemUnbreakableProvider.java create mode 100644 providers/BaseProviders/src/main/java/net/ess3/provider/ItemUnbreakableProvider.java create mode 100644 providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernItemUnbreakableProvider.java diff --git a/Essentials/build.gradle b/Essentials/build.gradle index 86d46d439..f864f2c65 100644 --- a/Essentials/build.gradle +++ b/Essentials/build.gradle @@ -22,6 +22,9 @@ dependencies { exclude group: "org.bukkit", module: "bukkit" } api(project(':providers:1_8Provider')) { + exclude group: "org.spigotmc", module: "spigot" + } + api(project(':providers:1_12Provider')) { exclude group: "org.bukkit", module: "bukkit" } } @@ -40,6 +43,7 @@ shadowJar { include (project(':providers:PaperProvider')) include (project(':providers:NMSReflectionProvider')) include (project(':providers:1_8Provider')) + include (project(':providers:1_12Provider')) } relocate 'io.papermc.lib', 'com.earth2me.essentials.paperlib' relocate 'org.bstats', 'com.earth2me.essentials.libs.bstats' diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index ba26a7246..4305ed647 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -57,6 +57,7 @@ import net.ess3.nms.refl.providers.ReflSpawnerBlockProvider; import net.ess3.nms.refl.providers.ReflSyncCommandsProvider; import net.ess3.provider.ContainerProvider; import net.ess3.provider.FormattedCommandAliasProvider; +import net.ess3.provider.ItemUnbreakableProvider; import net.ess3.provider.KnownCommandsProvider; import net.ess3.provider.MaterialTagProvider; import net.ess3.provider.PersistentDataProvider; @@ -73,8 +74,10 @@ import net.ess3.provider.providers.BlockMetaSpawnerItemProvider; import net.ess3.provider.providers.BukkitMaterialTagProvider; import net.ess3.provider.providers.BukkitSpawnerBlockProvider; import net.ess3.provider.providers.FlatSpawnEggProvider; +import net.ess3.provider.providers.LegacyItemUnbreakableProvider; import net.ess3.provider.providers.LegacyPotionMetaProvider; import net.ess3.provider.providers.LegacySpawnEggProvider; +import net.ess3.provider.providers.ModernItemUnbreakableProvider; import net.ess3.provider.providers.ModernPersistentDataProvider; import net.ess3.provider.providers.PaperContainerProvider; import net.ess3.provider.providers.PaperKnownCommandsProvider; @@ -166,6 +169,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { private transient SyncCommandsProvider syncCommandsProvider; private transient PersistentDataProvider persistentDataProvider; private transient ReflOnlineModeProvider onlineModeProvider; + private transient ItemUnbreakableProvider unbreakableProvider; private transient Kits kits; private transient RandomTeleport randomTeleport; private transient UpdateChecker updateChecker; @@ -409,6 +413,12 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { onlineModeProvider = new ReflOnlineModeProvider(); + if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01)) { + unbreakableProvider = new ModernItemUnbreakableProvider(); + } else { + unbreakableProvider = new LegacyItemUnbreakableProvider(); + } + execTimer.mark("Init(Providers)"); reload(); @@ -1269,6 +1279,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { return onlineModeProvider; } + @Override + public ItemUnbreakableProvider getItemUnbreakableProvider() { + return unbreakableProvider; + } + @Override public PluginCommand getPluginCommand(final String cmd) { return this.getCommand(cmd); diff --git a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java index 73e09b8c7..1852eb9b6 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java @@ -10,6 +10,7 @@ import com.earth2me.essentials.updatecheck.UpdateChecker; import net.ess3.nms.refl.providers.ReflOnlineModeProvider; import net.ess3.provider.ContainerProvider; import net.ess3.provider.FormattedCommandAliasProvider; +import net.ess3.provider.ItemUnbreakableProvider; import net.ess3.provider.KnownCommandsProvider; import net.ess3.provider.MaterialTagProvider; import net.ess3.provider.PersistentDataProvider; @@ -159,5 +160,7 @@ public interface IEssentials extends Plugin { ReflOnlineModeProvider getOnlineModeProvider(); + ItemUnbreakableProvider getItemUnbreakableProvider(); + PluginCommand getPluginCommand(String cmd); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/MetaItemStack.java b/Essentials/src/main/java/com/earth2me/essentials/MetaItemStack.java index 5a727c084..015eb03f1 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/MetaItemStack.java +++ b/Essentials/src/main/java/com/earth2me/essentials/MetaItemStack.java @@ -33,7 +33,6 @@ import org.bukkit.potion.Potion; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -48,9 +47,6 @@ import static com.earth2me.essentials.I18n.tl; public class MetaItemStack { private static final Map colorMap = new HashMap<>(); private static final Map fireworkShape = new HashMap<>(); - private static int bukkitUnbreakableSupport = -1; - private static Method spigotMethod; - private static Method setUnbreakableMethod; private static boolean useNewSkullMethod = true; static { @@ -212,7 +208,7 @@ public class MetaItemStack { stack.setItemMeta(meta); } else if (split[0].equalsIgnoreCase("unbreakable") && hasMetaPermission(sender, "unbreakable", false, true, ess)) { final boolean value = split.length <= 1 || Boolean.parseBoolean(split[1]); - setUnbreakable(stack, value); + setUnbreakable(ess, stack, value); } else if (split.length > 1 && (split[0].equalsIgnoreCase("player") || split[0].equalsIgnoreCase("owner")) && hasMetaPermission(sender, "head", false, true, ess)) { if (MaterialUtil.isPlayerHead(stack.getType(), stack.getDurability())) { final String owner = split[1]; @@ -686,35 +682,9 @@ public class MetaItemStack { } } - private void setUnbreakable(final ItemStack is, final boolean unbreakable) { + private void setUnbreakable(final IEssentials ess, final ItemStack is, final boolean unbreakable) { final ItemMeta meta = is.getItemMeta(); - try { - if (bukkitUnbreakableSupport == -1) { - try { - ItemMeta.class.getDeclaredMethod("setUnbreakable", boolean.class); - bukkitUnbreakableSupport = 1; - } catch (final NoSuchMethodException | SecurityException ex) { - bukkitUnbreakableSupport = 0; - } - } - - if (bukkitUnbreakableSupport == 1) { - meta.setUnbreakable(unbreakable); - } else { - if (spigotMethod == null) { - spigotMethod = meta.getClass().getDeclaredMethod("spigot"); - spigotMethod.setAccessible(true); - } - final Object itemStackSpigot = spigotMethod.invoke(meta); - if (setUnbreakableMethod == null) { - setUnbreakableMethod = itemStackSpigot.getClass().getDeclaredMethod("setUnbreakable", Boolean.TYPE); - setUnbreakableMethod.setAccessible(true); - } - setUnbreakableMethod.invoke(itemStackSpigot, unbreakable); - } - is.setItemMeta(meta); - } catch (final Throwable t) { - t.printStackTrace(); - } + ess.getItemUnbreakableProvider().setUnbreakable(meta, unbreakable); + is.setItemMeta(meta); } } diff --git a/providers/1_12Provider/build.gradle b/providers/1_12Provider/build.gradle new file mode 100644 index 000000000..e04aa5426 --- /dev/null +++ b/providers/1_12Provider/build.gradle @@ -0,0 +1,12 @@ +plugins { + id("essentials.base-conventions") +} + +dependencies { + api project(':providers:NMSReflectionProvider') +} + +essentials { + injectBukkitApi.set(false) + injectBstats.set(false) +} diff --git a/providers/1_8Provider/src/main/java/com/earth2me/essentials/FakeAccessor.java b/providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeAccessor.java similarity index 100% rename from providers/1_8Provider/src/main/java/com/earth2me/essentials/FakeAccessor.java rename to providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeAccessor.java diff --git a/providers/1_8Provider/src/main/java/com/earth2me/essentials/FakeServer.java b/providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeServer.java similarity index 100% rename from providers/1_8Provider/src/main/java/com/earth2me/essentials/FakeServer.java rename to providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeServer.java diff --git a/providers/1_8Provider/src/main/java/com/earth2me/essentials/FakeWorld.java b/providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeWorld.java similarity index 100% rename from providers/1_8Provider/src/main/java/com/earth2me/essentials/FakeWorld.java rename to providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeWorld.java diff --git a/providers/1_8Provider/src/main/java/com/earth2me/essentials/OfflinePlayer.java b/providers/1_12Provider/src/main/java/com/earth2me/essentials/OfflinePlayer.java similarity index 100% rename from providers/1_8Provider/src/main/java/com/earth2me/essentials/OfflinePlayer.java rename to providers/1_12Provider/src/main/java/com/earth2me/essentials/OfflinePlayer.java diff --git a/providers/1_8Provider/build.gradle b/providers/1_8Provider/build.gradle index e04aa5426..931350593 100644 --- a/providers/1_8Provider/build.gradle +++ b/providers/1_8Provider/build.gradle @@ -3,7 +3,10 @@ plugins { } dependencies { - api project(':providers:NMSReflectionProvider') + implementation(project(':providers:BaseProviders')) { + exclude group: "org.spigotmc", module: "spigot-api" + } + implementation 'org.spigotmc:spigot-api:1.8.8-R0.1-SNAPSHOT' } essentials { diff --git a/providers/1_8Provider/src/main/java/net/ess3/provider/providers/LegacyItemUnbreakableProvider.java b/providers/1_8Provider/src/main/java/net/ess3/provider/providers/LegacyItemUnbreakableProvider.java new file mode 100644 index 000000000..f4781514d --- /dev/null +++ b/providers/1_8Provider/src/main/java/net/ess3/provider/providers/LegacyItemUnbreakableProvider.java @@ -0,0 +1,16 @@ +package net.ess3.provider.providers; + +import net.ess3.provider.ItemUnbreakableProvider; +import org.bukkit.inventory.meta.ItemMeta; + +public class LegacyItemUnbreakableProvider implements ItemUnbreakableProvider { + @Override + public void setUnbreakable(ItemMeta meta, boolean unbreakable) { + meta.spigot().setUnbreakable(unbreakable); + } + + @Override + public String getDescription() { + return "Legacy ItemMeta Unbreakable Provider"; + } +} diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/ItemUnbreakableProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/ItemUnbreakableProvider.java new file mode 100644 index 000000000..07d91437d --- /dev/null +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/ItemUnbreakableProvider.java @@ -0,0 +1,7 @@ +package net.ess3.provider; + +import org.bukkit.inventory.meta.ItemMeta; + +public interface ItemUnbreakableProvider extends Provider { + void setUnbreakable(ItemMeta meta, boolean unbreakable); +} diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernItemUnbreakableProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernItemUnbreakableProvider.java new file mode 100644 index 000000000..74775dd9c --- /dev/null +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernItemUnbreakableProvider.java @@ -0,0 +1,16 @@ +package net.ess3.provider.providers; + +import net.ess3.provider.ItemUnbreakableProvider; +import org.bukkit.inventory.meta.ItemMeta; + +public class ModernItemUnbreakableProvider implements ItemUnbreakableProvider { + @Override + public void setUnbreakable(ItemMeta meta, boolean unbreakable) { + meta.setUnbreakable(unbreakable); + } + + @Override + public String getDescription() { + return "1.11+ ItemMeta Unbreakable Provider"; + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 0ad3170fc..9e25c0594 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -50,3 +50,4 @@ include(":providers:BaseProviders") include(":providers:NMSReflectionProvider") include(":providers:PaperProvider") include(":providers:1_8Provider") +include(":providers:1_12Provider")