From ee023b5d2c6010ef0e2144668fbf1accf76d6ab0 Mon Sep 17 00:00:00 2001 From: Marc Baloup Date: Sat, 23 Nov 2024 00:11:16 +0100 Subject: [PATCH] Trying again to do some shady reflection stuff to fix a Paper issue. Paper plugin should be able to register Brigadier commands that redirects to the root command node (similar to vanilla /execute run) --- .../paper/commands/PaperBrigadierCommand.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/commands/PaperBrigadierCommand.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/commands/PaperBrigadierCommand.java index 1c666d3..773720f 100644 --- a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/commands/PaperBrigadierCommand.java +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/commands/PaperBrigadierCommand.java @@ -23,6 +23,8 @@ import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.PluginCommandNode; import fr.pandacube.lib.players.standalone.AbstractOffPlayer; import fr.pandacube.lib.players.standalone.AbstractOnlinePlayer; import fr.pandacube.lib.players.standalone.AbstractPlayerManager; +import fr.pandacube.lib.reflect.Reflect; +import fr.pandacube.lib.reflect.ReflectClass; import fr.pandacube.lib.util.log.Log; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; @@ -37,6 +39,7 @@ import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; import org.bukkit.util.Vector; +import java.lang.reflect.InvocationTargetException; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -65,6 +68,19 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand newDispatcher) { if (vanillaPaperDispatcher == null || newDispatcher != vanillaPaperDispatcher) { vanillaPaperDispatcher = newDispatcher; + + // vanillaPaperDispatcher.getRoot() is not the real root but a wrapped root. Trying to map the fake root with the real one to trick the Paper/Brigadier (un)wrapper + RootCommandNode wrappedRoot = vanillaPaperDispatcher.getRoot(); + ReflectClass apiMirrorRootNodeClass = Reflect.ofClassOfInstance(wrappedRoot); + try { + RootCommandNode actualRoot = ((CommandDispatcher) apiMirrorRootNodeClass.method("getDispatcher").invoke(wrappedRoot)).getRoot(); + + Reflect.ofClass(CommandNode.class).field("unwrappedCached").setValue(wrappedRoot, actualRoot); + Reflect.ofClass(CommandNode.class).field("wrappedCached").setValue(actualRoot, wrappedRoot); + + } catch (InvocationTargetException|IllegalAccessException|NoSuchMethodException|NoSuchFieldException e) { + Log.severe("Unable to trick the Paper/Brigadier unwrapper to properly handle redirecting to root command node.", e); + } } }