Skip to content

Commit

Permalink
fix(mac-mouse): prevent erroneous hiding of cursor on macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
sam-kirby committed Jul 21, 2024
1 parent 5e2f49d commit 2241996
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -129,6 +132,9 @@ public void injectData(Map<String, Object> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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":
Expand Down Expand Up @@ -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;
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/tv/darkosto/sevpatches/core/hooks/MacMouseHook.java
Original file line number Diff line number Diff line change
@@ -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();
}
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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<AbstractInsnNode> insnsIter = insnList::iterator;
Stream<AbstractInsnNode> 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();
}
}

0 comments on commit 2241996

Please sign in to comment.