diff --git a/src/main/java/ftbsc/bscv/patches/ChatPatch.java b/src/main/java/ftbsc/bscv/patches/ChatPatch.java index b8bc887..0441c28 100644 --- a/src/main/java/ftbsc/bscv/patches/ChatPatch.java +++ b/src/main/java/ftbsc/bscv/patches/ChatPatch.java @@ -3,29 +3,40 @@ package ftbsc.bscv.patches; import ftbsc.lll.processor.annotations.Injector; import ftbsc.lll.processor.annotations.Patch; import ftbsc.lll.processor.annotations.Target; -import net.minecraft.client.gui.NewChatGui; +import ftbsc.lll.tools.InsnSequence; +import ftbsc.lll.tools.PatternMatcher; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.Screen; + import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.*; public class ChatPatch { - @Patch(value = NewChatGui.class, reason = "add hook to prevent chat from being cleared") + @Patch(value = Minecraft.class, reason = "add hook to prevent chat from being cleared") public abstract static class ChatClearInterceptor implements Opcodes { - /* - * TODO this patch is pretty bad because it prevents everyone from clearing the chat history. - * - * A better (but more complex) approach would be to patch in Minecraft.setScreen() and prevent clearing - * chat history upon getting into main menu / multiplayer menu - */ + // TODO this should be optional @Target - abstract void clearMessages(boolean clearSent); + abstract void setScreen(Screen screen); @Injector public void inject(ClassNode clazz, MethodNode main) { - main.instructions.insert(new InsnNode(RETURN)); + InsnSequence match = PatternMatcher.builder() + .opcodes(ALOAD, GETFIELD, INVOKEVIRTUAL, ICONST_1, INVOKEVIRTUAL) + .ignoreLineNumbers() + .ignoreLabels() + .ignoreFrames() + .build() + .find(main); + + LabelNode skip = new LabelNode(); + JumpInsnNode jump = new JumpInsnNode(GOTO, skip); + + main.instructions.insertBefore(match.getFirst(), jump); + main.instructions.insert(match.getLast(), skip); } }