diff --git a/src/main/java/tv/darkosto/sevpatches/core/SevPatchesLoadingPlugin.java b/src/main/java/tv/darkosto/sevpatches/core/SevPatchesLoadingPlugin.java index 3e66e1b..d20e98e 100644 --- a/src/main/java/tv/darkosto/sevpatches/core/SevPatchesLoadingPlugin.java +++ b/src/main/java/tv/darkosto/sevpatches/core/SevPatchesLoadingPlugin.java @@ -59,6 +59,9 @@ public class SevPatchesLoadingPlugin implements IFMLLoadingPlugin { public static String POSITIVE_MODULO; public static String FLOOR; + public static String GRAB_MOUSE_CURSOR; + public static String UNGRAB_MOUSE_CURSOR; + public SevPatchesLoadingPlugin() { LOGGER.info("setting up mixin environment"); MixinBootstrap.init(); @@ -129,6 +132,9 @@ public void injectData(Map data) { SevPatchesLoadingPlugin.ENTITY_ROTATION_YAW = dev ? "rotationYaw" : "field_70177_z"; SevPatchesLoadingPlugin.POSITIVE_MODULO = dev ? "positiveModulo" : "func_188207_b"; SevPatchesLoadingPlugin.FLOOR = dev ? "floor" : "func_76141_d"; + + SevPatchesLoadingPlugin.GRAB_MOUSE_CURSOR = dev ? "grabMouseCursor" : "a"; + SevPatchesLoadingPlugin.UNGRAB_MOUSE_CURSOR = dev ? "ungrabMouseCursor" : "b"; } @Override diff --git a/src/main/java/tv/darkosto/sevpatches/core/SevPatchesTransformer.java b/src/main/java/tv/darkosto/sevpatches/core/SevPatchesTransformer.java index 94f8253..3983671 100644 --- a/src/main/java/tv/darkosto/sevpatches/core/SevPatchesTransformer.java +++ b/src/main/java/tv/darkosto/sevpatches/core/SevPatchesTransformer.java @@ -7,6 +7,8 @@ public class SevPatchesTransformer implements IClassTransformer { @Override public byte[] transform(String name, String transformedName, byte[] basicClass) { switch (transformedName) { + case "net.minecraft.util.MouseHelper": + return new PatchMacMouse(basicClass).apply(); case "net.minecraft.world.WorldEntitySpawner": return new PatchMinecraftSpawnChunkSpawning(basicClass).apply(); case "com.tmtravlr.jaff.JAFFMod": @@ -43,6 +45,9 @@ public byte[] transform(String name, String transformedName, byte[] basicClass) case "net.darkhax.infoaccessories.info.InfoType": return new PatchInfoAccCompass(basicClass).apply(); default: + if (transformedName.contains("com.TominoCZ.FBP")) { + return new PatchMacMouseFBP(basicClass).apply(); + } return basicClass; } } diff --git a/src/main/java/tv/darkosto/sevpatches/core/hooks/MacMouseHook.java b/src/main/java/tv/darkosto/sevpatches/core/hooks/MacMouseHook.java new file mode 100644 index 0000000..a03cda8 --- /dev/null +++ b/src/main/java/tv/darkosto/sevpatches/core/hooks/MacMouseHook.java @@ -0,0 +1,16 @@ +package tv.darkosto.sevpatches.core.hooks; + +import net.minecraft.client.Minecraft; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class MacMouseHook { + public static void setGrabbed(boolean grab) { + if (grab) { + Minecraft.getMinecraft().mouseHelper.grabMouseCursor(); + } else { + Minecraft.getMinecraft().mouseHelper.ungrabMouseCursor(); + } + } +} diff --git a/src/main/java/tv/darkosto/sevpatches/core/patches/PatchMacMouse.java b/src/main/java/tv/darkosto/sevpatches/core/patches/PatchMacMouse.java new file mode 100644 index 0000000..33e7730 --- /dev/null +++ b/src/main/java/tv/darkosto/sevpatches/core/patches/PatchMacMouse.java @@ -0,0 +1,47 @@ +package tv.darkosto.sevpatches.core.patches; + +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.*; +import tv.darkosto.sevpatches.core.utils.AsmUtils; + +import java.util.Locale; + +import static tv.darkosto.sevpatches.core.SevPatchesLoadingPlugin.*; + +public class PatchMacMouse extends Patch { + public PatchMacMouse(byte[] inputClass) { + super(inputClass); + } + + @Override + protected boolean patch() { + MethodNode grabMouse = AsmUtils.findMethod(this.classNode, GRAB_MOUSE_CURSOR); + MethodNode ungrabMouse = AsmUtils.findMethod(this.classNode, UNGRAB_MOUSE_CURSOR); + if (grabMouse == null || ungrabMouse == null) return false; + grabMouse.instructions.insert(generateInsns(true)); + ungrabMouse.instructions.insert(generateInsns(false)); + + return true; + } + + @Override + public byte[] apply() { + String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT); + if (!osName.contains("mac")) { + LOGGER.info("Skipping mouse patch; os is not macOS"); + return inputClassBytes; + } + return super.apply(); + } + + private InsnList generateInsns(boolean checkGrab) { + LabelNode label = new LabelNode(); + InsnList insns = new InsnList(); + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "org/lwjgl/input/Mouse", "isGrabbed", "()Z", false)); + insns.add(new JumpInsnNode(checkGrab ? Opcodes.IFEQ : Opcodes.IFNE, label)); + insns.add(new InsnNode(Opcodes.RETURN)); + insns.add(label); + + return insns; + } +} diff --git a/src/main/java/tv/darkosto/sevpatches/core/patches/PatchMacMouseFBP.java b/src/main/java/tv/darkosto/sevpatches/core/patches/PatchMacMouseFBP.java new file mode 100644 index 0000000..3211bd2 --- /dev/null +++ b/src/main/java/tv/darkosto/sevpatches/core/patches/PatchMacMouseFBP.java @@ -0,0 +1,44 @@ +package tv.darkosto.sevpatches.core.patches; + +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class PatchMacMouseFBP extends PatchMacMouse { + public PatchMacMouseFBP(byte[] inputClass) { + super(inputClass); + } + + @Override + protected boolean patch() { + AtomicInteger count = new AtomicInteger(); + for (MethodNode method : classNode.methods) { + InsnList insnList = method.instructions; + Iterable insnsIter = insnList::iterator; + Stream insns = StreamSupport.stream(insnsIter.spliterator(), true); + + insns.filter(insn -> insn instanceof MethodInsnNode) + .map(insn -> (MethodInsnNode) insn) + .filter(insn -> insn.owner.equals("org/lwjgl/input/Mouse") && insn.name.equals("setGrabbed")) + .forEach(insn -> { + count.getAndIncrement(); + insn.owner = "tv/darkosto/sevpatches/core/hooks/MacMouseHook"; + }); + } + + return count.get() > 0; + } + + @Override + protected byte[] writeClass() { + ClassWriter classWriter = new ClassWriter(0); + classNode.accept(classWriter); + return classWriter.toByteArray(); + } +}