From 76470b963ecd35a88f6107607cce63d983ab1db6 Mon Sep 17 00:00:00 2001 From: Marc Baloup Date: Wed, 10 Jul 2024 01:04:05 +0200 Subject: [PATCH] Trying to register our Brigadier commands by force if necessary --- .../paper/commands/PaperBrigadierCommand.java | 62 ++++++++++++++++--- .../paper/reflect/PandalibPaperReflect.java | 6 ++ .../paper/commands/BukkitCommandNode.java | 29 +++++++++ .../paper/commands/PaperBrigadier.java | 29 +++++++++ .../paper/commands/PluginCommandNode.java | 43 +++++++++++++ 5 files changed, 161 insertions(+), 8 deletions(-) create mode 100644 pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/BukkitCommandNode.java create mode 100644 pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/PaperBrigadier.java create mode 100644 pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/PluginCommandNode.java 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 eb7111b..e96119e 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 @@ -5,6 +5,7 @@ import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.suggestion.SuggestionProvider; +import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.LiteralCommandNode; import com.mojang.brigadier.tree.RootCommandNode; import fr.pandacube.lib.chat.Chat; @@ -15,10 +16,13 @@ import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftVector; import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.VanillaCommandWrapper; import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Coordinates; import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Vec3Argument; +import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.BukkitCommandNode; +import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.PaperBrigadier; +import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.PluginCommandNode; +import fr.pandacube.lib.paper.util.BukkitEvent; 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.wrapper.ReflectWrapper; import fr.pandacube.lib.util.log.Log; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; @@ -31,6 +35,7 @@ import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.PluginCommand; import org.bukkit.entity.Player; import org.bukkit.event.Listener; +import org.bukkit.event.server.ServerLoadEvent; import org.bukkit.plugin.Plugin; import org.bukkit.util.Vector; @@ -40,6 +45,8 @@ import java.util.Set; import java.util.function.Predicate; import java.util.stream.Stream; +import static fr.pandacube.lib.reflect.wrapper.ReflectWrapper.wrap; + /** * Abstract class to hold a command to be integrated into a Paper server vanilla command dispatcher. */ @@ -72,18 +79,29 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand c.getName().equals(commandNode.getName())); } @@ -161,6 +179,30 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand { + if (vanillaPaperDispatcher == null) + return; + + CommandNode actualNode = vanillaPaperDispatcher.getRoot().getChild(commandNode.getName()); + if (actualNode != null) { + if (PluginCommandNode.REFLECT.get().isInstance(actualNode)) { + PluginCommandNode pcn = wrap(actualNode, PluginCommandNode.class); + if (pcn.getPlugin().equals(plugin)) + return; + Log.info("Brigadier command /" + commandNode.getName() + " from " + pcn.getPlugin().getName() + " found in the dispatcher. Replacing it by force."); + } + else if (BukkitCommandNode.REFLECT.get().isInstance(actualNode)) { + Log.info("Bukkit command /" + commandNode.getName() + " found in the dispatcher. Replacing it by force."); + } + vanillaPaperDispatcher.getRoot().getChildren().removeIf(c -> c.getName().equals(commandNode.getName())); + unregisterBukkitCommand(commandNode.getName()); + } + LiteralCommandNode newPCN = new PluginCommandNode(commandNode.getName(), plugin.getPluginMeta(), commandNode, description).__getRuntimeInstance(); + vanillaPaperDispatcher.getRoot().addChild(newPCN); + Bukkit.getCommandMap().register(commandNode.getName(), PaperBrigadier.wrapNode(newPCN)); + + }); } @@ -183,6 +225,10 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand getRegisteredAliases() { + return Set.copyOf(registeredAliases); + } + @@ -373,7 +419,7 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand CraftVector.toBukkit( - ReflectWrapper.wrap(nmsCoordinate, Coordinates.class).getPosition(context.getSource()) + wrap(nmsCoordinate, Coordinates.class).getPosition(context.getSource()) ), deflt); } diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/PandalibPaperReflect.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/PandalibPaperReflect.java index 798e681..df5fd0a 100644 --- a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/PandalibPaperReflect.java +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/PandalibPaperReflect.java @@ -73,6 +73,9 @@ import fr.pandacube.lib.paper.reflect.wrapper.netty.ByteBuf; import fr.pandacube.lib.paper.reflect.wrapper.netty.Unpooled; import fr.pandacube.lib.paper.reflect.wrapper.paper.PaperAdventure; import fr.pandacube.lib.paper.reflect.wrapper.paper.QueuedChangesMapLong2Object; +import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.BukkitCommandNode; +import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.PaperBrigadier; +import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.PluginCommandNode; import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.ShadowBrigNode; import fr.pandacube.lib.paper.reflect.wrapper.paper.configuration.FallbackValue_Int; import fr.pandacube.lib.paper.reflect.wrapper.paper.configuration.WorldConfiguration; @@ -203,6 +206,9 @@ public class PandalibPaperReflect { thAcc.catchThrowable(() -> initWrapper(Unpooled.class, Unpooled.REFLECT.get())); // paper.commands + thAcc.catchThrowable(() -> initWrapper(BukkitCommandNode.class, BukkitCommandNode.REFLECT.get())); + thAcc.catchThrowable(() -> initWrapper(PaperBrigadier.class, PaperBrigadier.REFLECT.get())); + thAcc.catchThrowable(() -> initWrapper(PluginCommandNode.class, PluginCommandNode.REFLECT.get())); thAcc.catchThrowable(() -> initWrapper(ShadowBrigNode.class, ShadowBrigNode.REFLECT.get())); // paper.configuration thAcc.catchThrowable(() -> initWrapper(FallbackValue_Int.class, FallbackValue_Int.REFLECT.get())); diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/BukkitCommandNode.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/BukkitCommandNode.java new file mode 100644 index 0000000..9ca918e --- /dev/null +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/BukkitCommandNode.java @@ -0,0 +1,29 @@ +package fr.pandacube.lib.paper.reflect.wrapper.paper.commands; + +import com.mojang.brigadier.tree.LiteralCommandNode; +import fr.pandacube.lib.reflect.Reflect; +import fr.pandacube.lib.reflect.ReflectClass; +import fr.pandacube.lib.reflect.ReflectMethod; +import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import org.bukkit.command.Command; +import org.bukkit.plugin.Plugin; + +import static fr.pandacube.lib.util.ThrowableUtil.wrapEx; +import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx; + +public class BukkitCommandNode extends ReflectWrapperTyped> { + public static final ReflectClass REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.command.brigadier.bukkit.BukkitCommandNode")); + private static final ReflectMethod getBukkitCommand = wrapEx(() -> REFLECT.method("getBukkitCommand")); + + + public Command getBukkitCommand() { + return (Command) wrapReflectEx(() -> getBukkitCommand.invoke(__getRuntimeInstance())); + } + + + + protected BukkitCommandNode(Object obj) { + super(obj); + } +} diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/PaperBrigadier.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/PaperBrigadier.java new file mode 100644 index 0000000..f51d775 --- /dev/null +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/PaperBrigadier.java @@ -0,0 +1,29 @@ +package fr.pandacube.lib.paper.reflect.wrapper.paper.commands; + +import com.mojang.brigadier.tree.CommandNode; +import com.mojang.brigadier.tree.LiteralCommandNode; +import fr.pandacube.lib.reflect.Reflect; +import fr.pandacube.lib.reflect.ReflectClass; +import fr.pandacube.lib.reflect.ReflectMethod; +import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import org.bukkit.command.Command; + +import static fr.pandacube.lib.util.ThrowableUtil.wrapEx; +import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx; + +public class PaperBrigadier extends ReflectWrapperTyped> { + public static final ReflectClass REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.command.brigadier.PaperBrigadier")); + private static final ReflectMethod wrapNode = wrapEx(() -> REFLECT.method("wrapNode")); + + + public static Command wrapNode(CommandNode node) { + return (Command) wrapReflectEx(() -> wrapNode.invokeStatic(node)); + } + + + + protected PaperBrigadier(Object obj) { + super(obj); + } +} diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/PluginCommandNode.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/PluginCommandNode.java new file mode 100644 index 0000000..0e89244 --- /dev/null +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/paper/commands/PluginCommandNode.java @@ -0,0 +1,43 @@ +package fr.pandacube.lib.paper.reflect.wrapper.paper.commands; + +import com.mojang.brigadier.tree.LiteralCommandNode; +import fr.pandacube.lib.reflect.Reflect; +import fr.pandacube.lib.reflect.ReflectClass; +import fr.pandacube.lib.reflect.ReflectConstructor; +import fr.pandacube.lib.reflect.ReflectMethod; +import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.plugin.configuration.PluginMeta; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import static fr.pandacube.lib.util.ThrowableUtil.wrapEx; +import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx; + +public class PluginCommandNode extends ReflectWrapperTyped> { + public static final ReflectClass REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.command.brigadier.PluginCommandNode")); + private static final ReflectMethod getPlugin = wrapEx(() -> REFLECT.method("getPlugin")); + private static final ReflectMethod getDescription = wrapEx(() -> REFLECT.method("getDescription")); + private static final ReflectConstructor CONSTRUCTOR = wrapEx(() -> REFLECT.constructor(String.class, PluginMeta.class, LiteralCommandNode.class, String.class)); + + + public PluginCommandNode(@NotNull String literal, @NotNull PluginMeta plugin, @NotNull LiteralCommandNode rootLiteral, @Nullable String description) { + this(wrapReflectEx(() -> CONSTRUCTOR.instantiate(literal, plugin, rootLiteral, description))); + } + + + public Plugin getPlugin() { + return (Plugin) wrapReflectEx(() -> getPlugin.invoke(__getRuntimeInstance())); + } + + public String getDescription() { + return (String) wrapReflectEx(() -> getDescription.invoke(__getRuntimeInstance())); + } + + + + protected PluginCommandNode(Object obj) { + super(obj); + } +}