From 60db00a94db3bd863944fcd26fe89635ce312824 Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Fri, 30 Oct 2020 17:05:47 +0100 Subject: [PATCH 1/7] Add support for command aliases in PlayerCommandPreProcessEvent --- .../com/earth2me/essentials/Essentials.java | 11 +++ .../essentials/EssentialsPlayerListener.java | 33 ++++++-- .../com/earth2me/essentials/IEssentials.java | 3 + .../FormattedCommandAliasProvider.java | 12 +++ .../src/net/ess3/nms/refl/ReflUtil.java | 4 + .../ReflFormattedCommandAliasProvider.java | 81 +++++++++++++++++++ 6 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 providers/BaseProviders/src/net/ess3/provider/FormattedCommandAliasProvider.java create mode 100644 providers/NMSReflectionProvider/src/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java index bb694c6f064..89a5611476b 100644 --- a/Essentials/src/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/com/earth2me/essentials/Essentials.java @@ -44,11 +44,13 @@ import net.ess3.api.IItemDb; import net.ess3.api.IJails; import net.ess3.api.ISettings; +import net.ess3.nms.refl.providers.ReflFormattedCommandAliasProvider; import net.ess3.nms.refl.providers.ReflServerStateProvider; import net.ess3.nms.refl.providers.ReflSpawnEggProvider; import net.ess3.nms.refl.providers.ReflSpawnerBlockProvider; import net.ess3.nms.refl.providers.ReflKnownCommandsProvider; import net.ess3.provider.ContainerProvider; +import net.ess3.provider.FormattedCommandAliasProvider; import net.ess3.provider.KnownCommandsProvider; import net.ess3.provider.PotionMetaProvider; import net.ess3.provider.ProviderListener; @@ -136,6 +138,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { private transient ServerStateProvider serverStateProvider; private transient ContainerProvider containerProvider; private transient KnownCommandsProvider knownCommandsProvider; + private transient FormattedCommandAliasProvider formattedCommandAliasProvider; private transient ProviderListener recipeBookEventProvider; private transient Kits kits; private transient RandomTeleport randomTeleport; @@ -329,6 +332,9 @@ public void onEnable() { knownCommandsProvider = new ReflKnownCommandsProvider(); } + //Command Alias provider + formattedCommandAliasProvider = new ReflFormattedCommandAliasProvider(PaperLib.isPaper()); + execTimer.mark("Init(Providers)"); reload(); @@ -1021,6 +1027,11 @@ public KnownCommandsProvider getKnownCommandsProvider() { return knownCommandsProvider; } + @Override + public FormattedCommandAliasProvider getFormattedCommandAliasProvider() { + return formattedCommandAliasProvider; + } + private AbstractItemDb getItemDbFromConfig() { final String setting = settings.getItemDbType(); diff --git a/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java index 77e784dfe38..50efc52138d 100644 --- a/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java @@ -18,6 +18,8 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.FormattedCommandAlias; import org.bukkit.command.PluginCommand; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; @@ -517,9 +519,30 @@ public void onPlayerBucketEmpty(final PlayerBucketEmptyEvent event) { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) { - final Player player = event.getPlayer(); final String cmd = event.getMessage().toLowerCase(Locale.ENGLISH).split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH); + final int argStartIndex = event.getMessage().indexOf(" "); + final String args = argStartIndex == -1 ? "" // No arguments present + : event.getMessage().substring(argStartIndex); // arguments start at argStartIndex; substring from there. + + // If the plugin command does not exist, check if it is an alias from commands.yml + if (ess.getServer().getPluginCommand(cmd) == null) { + final Command knownCommand = ess.getKnownCommandsProvider().getKnownCommands().get(cmd); + if (knownCommand instanceof FormattedCommandAlias) { + final FormattedCommandAlias command = (FormattedCommandAlias) knownCommand; + for (String fullCommand : ess.getFormattedCommandAliasProvider().createCommands(command, event.getPlayer(), args.split(" "))) { + handlePlayerCommandPreprocess(event, fullCommand); + } + return; + } + } + + // Handle the command given from the event. + handlePlayerCommandPreprocess(event, cmd + args); + } + public void handlePlayerCommandPreprocess(final PlayerCommandPreprocessEvent event, final String effectiveCommand) { + final Player player = event.getPlayer(); + final String cmd = effectiveCommand.toLowerCase(Locale.ENGLISH).split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH); final PluginCommand pluginCommand = ess.getServer().getPluginCommand(cmd); if (ess.getSettings().getSocialSpyCommands().contains(cmd) || ess.getSettings().getSocialSpyCommands().contains("*")) { @@ -572,12 +595,12 @@ public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) user.updateActivityOnInteract(broadcast); } - if (ess.getSettings().isCommandCooldownsEnabled() && pluginCommand != null + if (ess.getSettings().isCommandCooldownsEnabled() && !user.isAuthorized("essentials.commandcooldowns.bypass")) { - final int argStartIndex = event.getMessage().indexOf(" "); + final int argStartIndex = effectiveCommand.indexOf(" "); final String args = argStartIndex == -1 ? "" // No arguments present - : " " + event.getMessage().substring(argStartIndex); // arguments start at argStartIndex; substring from there. - final String fullCommand = pluginCommand.getName() + args; + : " " + effectiveCommand.substring(argStartIndex); // arguments start at argStartIndex; substring from there. + final String fullCommand = pluginCommand == null ? effectiveCommand : pluginCommand.getName() + args; // Used to determine whether a user already has an existing cooldown // If so, no need to check for (and write) new ones. diff --git a/Essentials/src/com/earth2me/essentials/IEssentials.java b/Essentials/src/com/earth2me/essentials/IEssentials.java index dda4eba61b2..4d484f1f133 100644 --- a/Essentials/src/com/earth2me/essentials/IEssentials.java +++ b/Essentials/src/com/earth2me/essentials/IEssentials.java @@ -5,6 +5,7 @@ import com.earth2me.essentials.api.IWarps; import com.earth2me.essentials.perm.PermissionsHandler; import net.ess3.provider.ContainerProvider; +import net.ess3.provider.FormattedCommandAliasProvider; import net.ess3.provider.KnownCommandsProvider; import net.ess3.provider.ServerStateProvider; import net.ess3.provider.SpawnerBlockProvider; @@ -118,4 +119,6 @@ public interface IEssentials extends Plugin { ContainerProvider getContainerProvider(); KnownCommandsProvider getKnownCommandsProvider(); + + FormattedCommandAliasProvider getFormattedCommandAliasProvider(); } diff --git a/providers/BaseProviders/src/net/ess3/provider/FormattedCommandAliasProvider.java b/providers/BaseProviders/src/net/ess3/provider/FormattedCommandAliasProvider.java new file mode 100644 index 00000000000..6793cbd44ea --- /dev/null +++ b/providers/BaseProviders/src/net/ess3/provider/FormattedCommandAliasProvider.java @@ -0,0 +1,12 @@ +package net.ess3.provider; + +import org.bukkit.command.CommandSender; +import org.bukkit.command.FormattedCommandAlias; + +import java.util.List; + +public interface FormattedCommandAliasProvider { + + List createCommands(FormattedCommandAlias command, CommandSender sender, String[] args); + +} diff --git a/providers/NMSReflectionProvider/src/net/ess3/nms/refl/ReflUtil.java b/providers/NMSReflectionProvider/src/net/ess3/nms/refl/ReflUtil.java index 30aa79e1b8b..a67d603ccea 100644 --- a/providers/NMSReflectionProvider/src/net/ess3/nms/refl/ReflUtil.java +++ b/providers/NMSReflectionProvider/src/net/ess3/nms/refl/ReflUtil.java @@ -56,6 +56,10 @@ public static Class getOBCClass(final String className) { return getClassCached("org.bukkit.craftbukkit." + getNMSVersion() + "." + className); } + public static Class getOBClass(final String className) { + return getClassCached("org.bukkit." + className); + } + public static Class getClassCached(final String className) { if (classCache.containsKey(className)) { return classCache.get(className); diff --git a/providers/NMSReflectionProvider/src/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java b/providers/NMSReflectionProvider/src/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java new file mode 100644 index 00000000000..3d27ac8bfe6 --- /dev/null +++ b/providers/NMSReflectionProvider/src/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java @@ -0,0 +1,81 @@ +package net.ess3.nms.refl.providers; + +import net.ess3.nms.refl.ReflUtil; +import net.ess3.provider.FormattedCommandAliasProvider; +import org.bukkit.command.CommandSender; +import org.bukkit.command.FormattedCommandAlias; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +public class ReflFormattedCommandAliasProvider implements FormattedCommandAliasProvider { + + private final boolean paper; + private final Field formatStringsField; + private final Method buildCommandMethod; + + public ReflFormattedCommandAliasProvider(boolean paper) { + this.paper = paper; + Field formatStringsField = null; + Method buildCommandMethod = null; + try { + @SuppressWarnings("unchecked") + final Class formattedCommandAliasClass = (Class) ReflUtil.getOBClass("command.FormattedCommandAlias"); + if (formattedCommandAliasClass != null) { + formatStringsField = ReflUtil.getFieldCached(formattedCommandAliasClass, "formatStrings"); + if (paper) { + buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", CommandSender.class, String.class, String[].class); + } else { + buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", String.class, String[].class); + } + } + } catch (final Exception ex) { + ex.printStackTrace(); + } finally { + this.formatStringsField = formatStringsField; + this.buildCommandMethod = buildCommandMethod; + } + } + + @Override + public List createCommands(FormattedCommandAlias command, CommandSender sender, String[] args) { + final List commands = new ArrayList<>(); + if (buildCommandMethod == null || formatStringsField == null) return commands; + + final String[] formatStrings; + try { + formatStrings = (String[]) formatStringsField.get(command); + } catch (ReflectiveOperationException ex) { + ex.printStackTrace(); + return commands; + } + + for (String formatString : formatStrings) { + final String cmd; + try { + cmd = buildCommand(command, sender, formatString, args); + } catch (Throwable th) { + continue; // Ignore, let server handle this. + } + + if (cmd == null) continue; + commands.add(cmd.trim()); + } + return commands; + } + + private String buildCommand(FormattedCommandAlias command, CommandSender sender, String formatString, String[] args) { + try { + if (paper) { + return (String) buildCommandMethod.invoke(command, sender, formatString, args); + } else { + return (String) buildCommandMethod.invoke(command, formatString, args); + } + } catch (ReflectiveOperationException ex) { + ex.printStackTrace(); + } + return null; + } +} From e637e66987b02ccbb1fa740f9e57d9e0e0ee0e90 Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Mon, 21 Dec 2020 09:49:53 +0100 Subject: [PATCH 2/7] Move new files into src/main/java folders (as a result of refactor upstream) --- .../java}/net/ess3/provider/FormattedCommandAliasProvider.java | 0 .../nms/refl/providers/ReflFormattedCommandAliasProvider.java | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename providers/BaseProviders/src/{ => main/java}/net/ess3/provider/FormattedCommandAliasProvider.java (100%) rename providers/NMSReflectionProvider/src/{ => main/java}/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java (100%) diff --git a/providers/BaseProviders/src/net/ess3/provider/FormattedCommandAliasProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/FormattedCommandAliasProvider.java similarity index 100% rename from providers/BaseProviders/src/net/ess3/provider/FormattedCommandAliasProvider.java rename to providers/BaseProviders/src/main/java/net/ess3/provider/FormattedCommandAliasProvider.java diff --git a/providers/NMSReflectionProvider/src/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java b/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java similarity index 100% rename from providers/NMSReflectionProvider/src/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java rename to providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java From b6c5cc3da6c9bee14c44c9c387dadf188b41e3f9 Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Mon, 4 Jan 2021 19:24:04 +0100 Subject: [PATCH 3/7] Refactor FormattedCommandAliasProvider - Split the provider up for both spigot/paper impl. --- .../com/earth2me/essentials/Essentials.java | 7 ++- .../FormattedCommandAliasProvider.java | 22 ++++++- .../ReflFormattedCommandAliasProvider.java | 61 +++++-------------- providers/PaperProvider/build.gradle | 1 + ...aperReflFormattedCommandAliasProvider.java | 22 +++++++ 5 files changed, 65 insertions(+), 48 deletions(-) create mode 100644 providers/PaperProvider/src/main/java/net/ess3/provider/providers/PaperReflFormattedCommandAliasProvider.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index 9c1e46687b0..45cf56b6397 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -65,6 +65,7 @@ import net.ess3.provider.providers.LegacyPotionMetaProvider; import net.ess3.provider.providers.LegacySpawnEggProvider; import net.ess3.provider.providers.PaperContainerProvider; +import net.ess3.provider.providers.PaperReflFormattedCommandAliasProvider; import net.ess3.provider.providers.PaperKnownCommandsProvider; import net.ess3.provider.providers.PaperRecipeBookListener; import net.ess3.provider.providers.PaperServerStateProvider; @@ -333,7 +334,11 @@ public void onEnable() { } //Command Alias provider - formattedCommandAliasProvider = new ReflFormattedCommandAliasProvider(PaperLib.isPaper()); + if (PaperLib.isPaper()) { + formattedCommandAliasProvider = new PaperReflFormattedCommandAliasProvider(); + } else { + formattedCommandAliasProvider = new ReflFormattedCommandAliasProvider(); + } execTimer.mark("Init(Providers)"); reload(); diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/FormattedCommandAliasProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/FormattedCommandAliasProvider.java index 6793cbd44ea..974b8c1d773 100644 --- a/providers/BaseProviders/src/main/java/net/ess3/provider/FormattedCommandAliasProvider.java +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/FormattedCommandAliasProvider.java @@ -3,10 +3,28 @@ import org.bukkit.command.CommandSender; import org.bukkit.command.FormattedCommandAlias; +import java.util.ArrayList; import java.util.List; -public interface FormattedCommandAliasProvider { +public abstract class FormattedCommandAliasProvider { - List createCommands(FormattedCommandAlias command, CommandSender sender, String[] args); + public List createCommands(FormattedCommandAlias command, CommandSender sender, String[] args) { + final List commands = new ArrayList<>(); + for (String formatString : getFormatStrings(command)) { + final String cmd; + try { + cmd = buildCommand(command, sender, formatString, args); + } catch (Throwable th) { + continue; // Ignore, let server handle this. + } + if (cmd == null) continue; + commands.add(cmd.trim()); + } + return commands; + } + + public abstract String[] getFormatStrings(FormattedCommandAlias command); + + public abstract String buildCommand(FormattedCommandAlias command, CommandSender sender, String formatString, String[] args); } diff --git a/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java b/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java index 3d27ac8bfe6..9b881d62acc 100644 --- a/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java +++ b/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java @@ -7,75 +7,46 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -public class ReflFormattedCommandAliasProvider implements FormattedCommandAliasProvider { +public class ReflFormattedCommandAliasProvider extends FormattedCommandAliasProvider { - private final boolean paper; + protected final Class formattedCommandAliasClass; private final Field formatStringsField; - private final Method buildCommandMethod; - public ReflFormattedCommandAliasProvider(boolean paper) { - this.paper = paper; + @SuppressWarnings("unchecked") + public ReflFormattedCommandAliasProvider() { + Class formattedCommandAliasClass = null; Field formatStringsField = null; - Method buildCommandMethod = null; try { - @SuppressWarnings("unchecked") - final Class formattedCommandAliasClass = (Class) ReflUtil.getOBClass("command.FormattedCommandAlias"); + formattedCommandAliasClass = (Class) ReflUtil.getOBClass("command.FormattedCommandAlias"); if (formattedCommandAliasClass != null) { formatStringsField = ReflUtil.getFieldCached(formattedCommandAliasClass, "formatStrings"); - if (paper) { - buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", CommandSender.class, String.class, String[].class); - } else { - buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", String.class, String[].class); - } } } catch (final Exception ex) { ex.printStackTrace(); } finally { + this.formattedCommandAliasClass = formattedCommandAliasClass; this.formatStringsField = formatStringsField; - this.buildCommandMethod = buildCommandMethod; } } @Override - public List createCommands(FormattedCommandAlias command, CommandSender sender, String[] args) { - final List commands = new ArrayList<>(); - if (buildCommandMethod == null || formatStringsField == null) return commands; - - final String[] formatStrings; + public String[] getFormatStrings(FormattedCommandAlias command) { try { - formatStrings = (String[]) formatStringsField.get(command); + return (String[]) formatStringsField.get(command); } catch (ReflectiveOperationException ex) { - ex.printStackTrace(); - return commands; + throw new RuntimeException(ex); // If this happens we have bigger problems... } - - for (String formatString : formatStrings) { - final String cmd; - try { - cmd = buildCommand(command, sender, formatString, args); - } catch (Throwable th) { - continue; // Ignore, let server handle this. - } - - if (cmd == null) continue; - commands.add(cmd.trim()); - } - return commands; } - private String buildCommand(FormattedCommandAlias command, CommandSender sender, String formatString, String[] args) { + @Override + public String buildCommand(FormattedCommandAlias command, CommandSender sender, String formatString, String[] args) { try { - if (paper) { - return (String) buildCommandMethod.invoke(command, sender, formatString, args); - } else { - return (String) buildCommandMethod.invoke(command, formatString, args); - } + final Method buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", String.class, String[].class); + if (buildCommandMethod == null) throw new ReflectiveOperationException("Method FormattedCommandAlias#buildCommand() not found"); + return (String) buildCommandMethod.invoke(command, formatString, args); } catch (ReflectiveOperationException ex) { - ex.printStackTrace(); + throw new RuntimeException(ex); // If this happens we have bigger problems... } - return null; } } diff --git a/providers/PaperProvider/build.gradle b/providers/PaperProvider/build.gradle index 32937ff0984..a7ca73d2175 100644 --- a/providers/PaperProvider/build.gradle +++ b/providers/PaperProvider/build.gradle @@ -1,4 +1,5 @@ dependencies { implementation project(':providers:BaseProviders') + implementation project(':providers:NMSReflectionProvider') compileOnly 'com.destroystokyo.paper:paper-api:1.16.3-R0.1-SNAPSHOT' } diff --git a/providers/PaperProvider/src/main/java/net/ess3/provider/providers/PaperReflFormattedCommandAliasProvider.java b/providers/PaperProvider/src/main/java/net/ess3/provider/providers/PaperReflFormattedCommandAliasProvider.java new file mode 100644 index 00000000000..05afaa8e1ab --- /dev/null +++ b/providers/PaperProvider/src/main/java/net/ess3/provider/providers/PaperReflFormattedCommandAliasProvider.java @@ -0,0 +1,22 @@ +package net.ess3.provider.providers; + +import net.ess3.nms.refl.ReflUtil; +import net.ess3.nms.refl.providers.ReflFormattedCommandAliasProvider; +import org.bukkit.command.CommandSender; +import org.bukkit.command.FormattedCommandAlias; + +import java.lang.reflect.Method; + +public class PaperReflFormattedCommandAliasProvider extends ReflFormattedCommandAliasProvider { + + @Override + public String buildCommand(FormattedCommandAlias command, CommandSender sender, String formatString, String[] args) { + try { + final Method buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", CommandSender.class, String.class, String[].class); + if (buildCommandMethod == null) throw new ReflectiveOperationException("Method FormattedCommandAlias#buildCommand() not found"); + return (String) buildCommandMethod.invoke(command, sender, formatString, args); + } catch (ReflectiveOperationException ex) { + throw new RuntimeException(ex); // If this happens we have bigger problems... + } + } +} From c27c8e0170168b47eeed34ab3e2e58621a7c51c7 Mon Sep 17 00:00:00 2001 From: MD <1917406+mdcfe@users.noreply.github.com> Date: Fri, 5 Feb 2021 19:47:08 +0000 Subject: [PATCH 4/7] Update Essentials/src/main/java/com/earth2me/essentials/Essentials.java --- .../src/main/java/com/earth2me/essentials/Essentials.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index 46fe1e08c0a..cf17852a00a 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -342,7 +342,7 @@ public void onEnable() { knownCommandsProvider = new ReflKnownCommandsProvider(); } - //Command Alias provider + // Command aliases provider if (PaperLib.isPaper()) { formattedCommandAliasProvider = new PaperReflFormattedCommandAliasProvider(); } else { From 32c65ea97f98f4399caf89a64c8464ba1c91939f Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Fri, 5 Feb 2021 21:40:19 +0100 Subject: [PATCH 5/7] Remove reflection call for FormattedCommandAlias class --- .../src/main/java/net/ess3/nms/refl/ReflUtil.java | 4 ---- .../refl/providers/ReflFormattedCommandAliasProvider.java | 6 ++---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/ReflUtil.java b/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/ReflUtil.java index 744d0522ef4..7515c3e8f35 100644 --- a/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/ReflUtil.java +++ b/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/ReflUtil.java @@ -59,10 +59,6 @@ public static Class getOBCClass(final String className) { return getClassCached("org.bukkit.craftbukkit." + getNMSVersion() + "." + className); } - public static Class getOBClass(final String className) { - return getClassCached("org.bukkit." + className); - } - public static Class getClassCached(final String className) { if (classCache.containsKey(className)) { return classCache.get(className); diff --git a/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java b/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java index 9b881d62acc..79bb7f27a03 100644 --- a/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java +++ b/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java @@ -18,10 +18,8 @@ public ReflFormattedCommandAliasProvider() { Class formattedCommandAliasClass = null; Field formatStringsField = null; try { - formattedCommandAliasClass = (Class) ReflUtil.getOBClass("command.FormattedCommandAlias"); - if (formattedCommandAliasClass != null) { - formatStringsField = ReflUtil.getFieldCached(formattedCommandAliasClass, "formatStrings"); - } + formattedCommandAliasClass = FormattedCommandAlias.class; + formatStringsField = ReflUtil.getFieldCached(formattedCommandAliasClass, "formatStrings"); } catch (final Exception ex) { ex.printStackTrace(); } finally { From 345e425c60de8c57497068994e3f8465ea3dfb7c Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Sat, 6 Feb 2021 17:17:21 +0100 Subject: [PATCH 6/7] Revert back to initial reflection call Removing PaperReflFormattedCommandAliasProvider.java and the need for the reflection library in paper providers. --- .../com/earth2me/essentials/Essentials.java | 7 +---- .../ReflFormattedCommandAliasProvider.java | 26 +++++++++++++------ providers/PaperProvider/build.gradle | 1 - ...aperReflFormattedCommandAliasProvider.java | 22 ---------------- 4 files changed, 19 insertions(+), 37 deletions(-) delete mode 100644 providers/PaperProvider/src/main/java/net/ess3/provider/providers/PaperReflFormattedCommandAliasProvider.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index 365cac95b21..626e8c1c87e 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -66,7 +66,6 @@ import net.ess3.provider.providers.LegacyPotionMetaProvider; import net.ess3.provider.providers.LegacySpawnEggProvider; import net.ess3.provider.providers.PaperContainerProvider; -import net.ess3.provider.providers.PaperReflFormattedCommandAliasProvider; import net.ess3.provider.providers.PaperKnownCommandsProvider; import net.ess3.provider.providers.PaperMaterialTagProvider; import net.ess3.provider.providers.PaperRecipeBookListener; @@ -347,11 +346,7 @@ public void onEnable() { } // Command aliases provider - if (PaperLib.isPaper()) { - formattedCommandAliasProvider = new PaperReflFormattedCommandAliasProvider(); - } else { - formattedCommandAliasProvider = new ReflFormattedCommandAliasProvider(); - } + formattedCommandAliasProvider = new ReflFormattedCommandAliasProvider(PaperLib.isPaper()); //Material Tag Providers if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_13_0_R01)) { diff --git a/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java b/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java index 79bb7f27a03..5133ce96b99 100644 --- a/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java +++ b/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java @@ -10,21 +10,29 @@ public class ReflFormattedCommandAliasProvider extends FormattedCommandAliasProvider { - protected final Class formattedCommandAliasClass; + private final boolean paper; private final Field formatStringsField; + private final Method buildCommandMethod; - @SuppressWarnings("unchecked") - public ReflFormattedCommandAliasProvider() { - Class formattedCommandAliasClass = null; + public ReflFormattedCommandAliasProvider(boolean paper) { + this.paper = paper; + + final Class formattedCommandAliasClass; Field formatStringsField = null; + Method buildCommandMethod = null; try { formattedCommandAliasClass = FormattedCommandAlias.class; formatStringsField = ReflUtil.getFieldCached(formattedCommandAliasClass, "formatStrings"); + if (paper) { + buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", CommandSender.class, String.class, String[].class); + } else { + buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", String.class, String[].class); + } } catch (final Exception ex) { ex.printStackTrace(); } finally { - this.formattedCommandAliasClass = formattedCommandAliasClass; this.formatStringsField = formatStringsField; + this.buildCommandMethod = buildCommandMethod; } } @@ -40,9 +48,11 @@ public String[] getFormatStrings(FormattedCommandAlias command) { @Override public String buildCommand(FormattedCommandAlias command, CommandSender sender, String formatString, String[] args) { try { - final Method buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", String.class, String[].class); - if (buildCommandMethod == null) throw new ReflectiveOperationException("Method FormattedCommandAlias#buildCommand() not found"); - return (String) buildCommandMethod.invoke(command, formatString, args); + if (paper) { + return (String) buildCommandMethod.invoke(command, sender, formatString, args); + } else { + return (String) buildCommandMethod.invoke(command, formatString, args); + } } catch (ReflectiveOperationException ex) { throw new RuntimeException(ex); // If this happens we have bigger problems... } diff --git a/providers/PaperProvider/build.gradle b/providers/PaperProvider/build.gradle index ea39fe0121a..af54c7b4a7b 100644 --- a/providers/PaperProvider/build.gradle +++ b/providers/PaperProvider/build.gradle @@ -1,5 +1,4 @@ dependencies { implementation project(':providers:BaseProviders') - implementation project(':providers:NMSReflectionProvider') compileOnly 'com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT' } diff --git a/providers/PaperProvider/src/main/java/net/ess3/provider/providers/PaperReflFormattedCommandAliasProvider.java b/providers/PaperProvider/src/main/java/net/ess3/provider/providers/PaperReflFormattedCommandAliasProvider.java deleted file mode 100644 index 05afaa8e1ab..00000000000 --- a/providers/PaperProvider/src/main/java/net/ess3/provider/providers/PaperReflFormattedCommandAliasProvider.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.ess3.provider.providers; - -import net.ess3.nms.refl.ReflUtil; -import net.ess3.nms.refl.providers.ReflFormattedCommandAliasProvider; -import org.bukkit.command.CommandSender; -import org.bukkit.command.FormattedCommandAlias; - -import java.lang.reflect.Method; - -public class PaperReflFormattedCommandAliasProvider extends ReflFormattedCommandAliasProvider { - - @Override - public String buildCommand(FormattedCommandAlias command, CommandSender sender, String formatString, String[] args) { - try { - final Method buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", CommandSender.class, String.class, String[].class); - if (buildCommandMethod == null) throw new ReflectiveOperationException("Method FormattedCommandAlias#buildCommand() not found"); - return (String) buildCommandMethod.invoke(command, sender, formatString, args); - } catch (ReflectiveOperationException ex) { - throw new RuntimeException(ex); // If this happens we have bigger problems... - } - } -} From b432c30105d24f059aa9a1f39609924452720480 Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Sat, 6 Feb 2021 19:15:21 +0100 Subject: [PATCH 7/7] Use MethodHandles instead of Method invocations + Make FormattedCommandAliasProvider an interface --- .../FormattedCommandAliasProvider.java | 23 ++------- .../ReflFormattedCommandAliasProvider.java | 50 +++++++++++++++---- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/FormattedCommandAliasProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/FormattedCommandAliasProvider.java index 974b8c1d773..77fd89f399c 100644 --- a/providers/BaseProviders/src/main/java/net/ess3/provider/FormattedCommandAliasProvider.java +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/FormattedCommandAliasProvider.java @@ -3,28 +3,13 @@ import org.bukkit.command.CommandSender; import org.bukkit.command.FormattedCommandAlias; -import java.util.ArrayList; import java.util.List; -public abstract class FormattedCommandAliasProvider { +public interface FormattedCommandAliasProvider extends Provider { - public List createCommands(FormattedCommandAlias command, CommandSender sender, String[] args) { - final List commands = new ArrayList<>(); - for (String formatString : getFormatStrings(command)) { - final String cmd; - try { - cmd = buildCommand(command, sender, formatString, args); - } catch (Throwable th) { - continue; // Ignore, let server handle this. - } + List createCommands(FormattedCommandAlias command, CommandSender sender, String[] args); - if (cmd == null) continue; - commands.add(cmd.trim()); - } - return commands; - } + String[] getFormatStrings(FormattedCommandAlias command); - public abstract String[] getFormatStrings(FormattedCommandAlias command); - - public abstract String buildCommand(FormattedCommandAlias command, CommandSender sender, String formatString, String[] args); + String buildCommand(FormattedCommandAlias command, CommandSender sender, String formatString, String[] args); } diff --git a/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java b/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java index 5133ce96b99..e7563ca274a 100644 --- a/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java +++ b/providers/NMSReflectionProvider/src/main/java/net/ess3/nms/refl/providers/ReflFormattedCommandAliasProvider.java @@ -5,35 +5,62 @@ import org.bukkit.command.CommandSender; import org.bukkit.command.FormattedCommandAlias; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; -public class ReflFormattedCommandAliasProvider extends FormattedCommandAliasProvider { +public class ReflFormattedCommandAliasProvider implements FormattedCommandAliasProvider { private final boolean paper; private final Field formatStringsField; - private final Method buildCommandMethod; + private final MethodHandle buildCommandMethodHandle; public ReflFormattedCommandAliasProvider(boolean paper) { this.paper = paper; final Class formattedCommandAliasClass; Field formatStringsField = null; - Method buildCommandMethod = null; + MethodHandle buildCommandMethodHandle = null; try { formattedCommandAliasClass = FormattedCommandAlias.class; formatStringsField = ReflUtil.getFieldCached(formattedCommandAliasClass, "formatStrings"); + + final Class[] parameterTypes; if (paper) { - buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", CommandSender.class, String.class, String[].class); + parameterTypes = new Class[] {CommandSender.class, String.class, String[].class}; } else { - buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", String.class, String[].class); + parameterTypes = new Class[] {String.class, String[].class}; } + + final Method buildCommandMethod = ReflUtil.getMethodCached(formattedCommandAliasClass, "buildCommand", parameterTypes); + buildCommandMethod.setAccessible(true); + buildCommandMethodHandle = MethodHandles.lookup().unreflect(buildCommandMethod); } catch (final Exception ex) { ex.printStackTrace(); } finally { this.formatStringsField = formatStringsField; - this.buildCommandMethod = buildCommandMethod; + this.buildCommandMethodHandle = buildCommandMethodHandle; + } + } + + @Override + public List createCommands(FormattedCommandAlias command, CommandSender sender, String[] args) { + final List commands = new ArrayList<>(); + for (String formatString : getFormatStrings(command)) { + final String cmd; + try { + cmd = buildCommand(command, sender, formatString, args); + } catch (Throwable th) { + continue; // Ignore, let server handle this. + } + + if (cmd == null) continue; + commands.add(cmd.trim()); } + return commands; } @Override @@ -49,12 +76,17 @@ public String[] getFormatStrings(FormattedCommandAlias command) { public String buildCommand(FormattedCommandAlias command, CommandSender sender, String formatString, String[] args) { try { if (paper) { - return (String) buildCommandMethod.invoke(command, sender, formatString, args); + return (String) buildCommandMethodHandle.invoke(command, sender, formatString, args); } else { - return (String) buildCommandMethod.invoke(command, formatString, args); + return (String) buildCommandMethodHandle.invoke(command, formatString, args); } - } catch (ReflectiveOperationException ex) { + } catch (Throwable ex) { throw new RuntimeException(ex); // If this happens we have bigger problems... } } + + @Override + public String getDescription() { + return "NMS Reflection Provider for FormattedCommandAlias methods"; + } }