From 1991ea5fbae0df188992286b52a25b613fcb21d6 Mon Sep 17 00:00:00 2001 From: alemi Date: Sat, 4 Mar 2023 04:02:38 +0100 Subject: [PATCH] feat: add patch and event to add command hints finally /hints is no longer necessary since we fire an event every time the server makes us rebuild command hints. Still need to figure out how to namespace stuff --- src/main/java/ftbsc/bscv/Boscovicino.java | 8 +++ .../ftbsc/bscv/events/CommandsBuiltEvent.java | 19 +++++++ .../ftbsc/bscv/patches/CommandsPatch.java | 55 +++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 src/main/java/ftbsc/bscv/events/CommandsBuiltEvent.java create mode 100644 src/main/java/ftbsc/bscv/patches/CommandsPatch.java diff --git a/src/main/java/ftbsc/bscv/Boscovicino.java b/src/main/java/ftbsc/bscv/Boscovicino.java index d54a3d4..d0860bf 100644 --- a/src/main/java/ftbsc/bscv/Boscovicino.java +++ b/src/main/java/ftbsc/bscv/Boscovicino.java @@ -2,7 +2,10 @@ package ftbsc.bscv; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.tree.CommandNode; + import ftbsc.bscv.api.IModule; +import ftbsc.bscv.events.CommandsBuiltEvent; import ftbsc.bscv.system.Friends; import ftbsc.bscv.system.ModManager; import net.minecraft.client.entity.player.ClientPlayerEntity; @@ -123,6 +126,11 @@ public class Boscovicino implements ICommons { return 1; }) ); + @SubscribeEvent + public void onCommandSuggestionsBuilt(CommandsBuiltEvent event) { + for (CommandNode child : this.dispatcher.getRoot().getChildren()) { + event.dispatcher().getRoot().addChild(child); + } } @SubscribeEvent diff --git a/src/main/java/ftbsc/bscv/events/CommandsBuiltEvent.java b/src/main/java/ftbsc/bscv/events/CommandsBuiltEvent.java new file mode 100644 index 0000000..99a2dde --- /dev/null +++ b/src/main/java/ftbsc/bscv/events/CommandsBuiltEvent.java @@ -0,0 +1,19 @@ +package ftbsc.bscv.events; + +import com.mojang.brigadier.CommandDispatcher; + +import net.minecraft.command.CommandSource; +import net.minecraft.command.ISuggestionProvider; +import net.minecraftforge.eventbus.api.Event; + +public class CommandsBuiltEvent extends Event { + private CommandDispatcher dispatcher; + + public CommandDispatcher dispatcher() { + return this.dispatcher; + } + + public CommandsBuiltEvent(CommandDispatcher dispatcher) { + this.dispatcher = dispatcher; + } +} diff --git a/src/main/java/ftbsc/bscv/patches/CommandsPatch.java b/src/main/java/ftbsc/bscv/patches/CommandsPatch.java new file mode 100644 index 0000000..410b660 --- /dev/null +++ b/src/main/java/ftbsc/bscv/patches/CommandsPatch.java @@ -0,0 +1,55 @@ +package ftbsc.bscv.patches; + +import ftbsc.bscv.events.CommandsBuiltEvent; +import ftbsc.lll.processor.annotations.Injector; +import ftbsc.lll.processor.annotations.Patch; +import ftbsc.lll.processor.annotations.Target; +import ftbsc.lll.tools.InsnSequence; +import ftbsc.lll.tools.PatternMatcher; +import net.minecraft.client.network.play.ClientPlayNetHandler; +import net.minecraft.command.CommandSource; +import net.minecraft.network.play.server.SCommandListPacket; +import net.minecraftforge.common.MinecraftForge; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.*; + +import com.mojang.brigadier.CommandDispatcher; + +public class CommandsPatch { + + public static class CommandsHook { + public static void cmdBuilt(CommandDispatcher dispatcher) { + MinecraftForge.EVENT_BUS.post(new CommandsBuiltEvent(dispatcher)); + } + } + + @Patch(value = ClientPlayNetHandler.class, reason = "add hook to insert our command suggestions") + public abstract static class CommandsDispatcherCatcher implements Opcodes { + @Target + abstract void handleCommands(SCommandListPacket pkt); + + @Injector + public void inject(ClassNode clazz, MethodNode main) { + AbstractInsnNode found = PatternMatcher.builder() + .opcodes(ALOAD, INVOKEVIRTUAL, INVOKESPECIAL) + .ignoreFrames() + .ignoreLabels() + .ignoreLineNumbers() + .build() + .find(main) + .getLast() + .getNext(); // TODO temp fix!!! + + InsnSequence is = new InsnSequence(); + is.add(new InsnNode(DUP)); + is.add(new MethodInsnNode( + INVOKESTATIC, + "ftbsc/bscv/patches/CommandsPatch$CommandsHook", + "cmdBuilt", + "(Lcom/mojang/brigadier/CommandDispatcher;)V" + )); + + main.instructions.insert(found, is); + } + } +}