Skip to content

Commit

Permalink
Merge pull request #102 from boholder/1.20.x-fix-simulate-mouse-with-…
Browse files Browse the repository at this point in the history
…keyboard

Fix simulate mouse with keyboard for 1.20
  • Loading branch information
khanshoaib3 authored Aug 2, 2023
2 parents 3d047fd + e9edaf4 commit f27245f
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import net.minecraft.client.MinecraftClient;
import org.apache.commons.lang3.tuple.Triple;

import java.util.List;
import java.util.Set;

/**
* Bind four mouse operations with customizable keys:<br><br>
Expand All @@ -24,13 +24,9 @@ public class MouseKeySimulation {

private boolean enabled;
/**
* How these values are chosen:
* Creative mode, standing three blocks away from a wall,
* comparing (listening) block breaking and placing speeds between using real mouse and using keyboard.
* index 0,1,2 for left, middle, right mouse key
*/
private static final TimeUtils.Interval leftKeyDelay = TimeUtils.Interval.inMilliseconds(300);
private static final TimeUtils.Interval middleKeyDelay = TimeUtils.Interval.inMilliseconds(200);
private static final TimeUtils.Interval rightKeyDelay = TimeUtils.Interval.inMilliseconds(180);
private final boolean[] isMouseKeyPressedPreviousTick = new boolean[]{false, false, false};
private TimeUtils.Interval scrollUpDelay;
private TimeUtils.Interval scrollDownDelay;

Expand Down Expand Up @@ -73,16 +69,34 @@ private void loadConfigurations() {

private void execute() {
KeyBindingsHandler kbh = KeyBindingsHandler.getInstance();
List.of(
Triple.<Boolean, TimeUtils.Interval, Runnable>of(KeyUtils.isAnyPressed(kbh.mouseSimulationLeftMouseKey), leftKeyDelay, MouseUtils::leftClick),
Triple.<Boolean, TimeUtils.Interval, Runnable>of(KeyUtils.isAnyPressed(kbh.mouseSimulationMiddleMouseKey), middleKeyDelay, MouseUtils::middleClick),
Triple.<Boolean, TimeUtils.Interval, Runnable>of(KeyUtils.isAnyPressed(kbh.mouseSimulationRightMouseKey), rightKeyDelay, MouseUtils::rightClick),

Set.of(
Triple.<Boolean, TimeUtils.Interval, Runnable>of(KeyUtils.isAnyPressed(kbh.mouseSimulationScrollUpKey), scrollUpDelay, MouseUtils::scrollUp),
Triple.<Boolean, TimeUtils.Interval, Runnable>of(KeyUtils.isAnyPressed(kbh.mouseSimulationScrollDownKey), scrollDownDelay, MouseUtils::scrollDown)
).forEach(t -> {
if (t.getLeft() && t.getMiddle().isReady()) {
t.getRight().run();
}
});

Set.of(
new MouseKeyDTO(KeyUtils.isAnyPressed(kbh.mouseSimulationLeftMouseKey), 0, MouseUtils::leftDown, MouseUtils::leftUp),
new MouseKeyDTO(KeyUtils.isAnyPressed(kbh.mouseSimulationMiddleMouseKey), 1, MouseUtils::middleDown, MouseUtils::middleUp),
new MouseKeyDTO(KeyUtils.isAnyPressed(kbh.mouseSimulationRightMouseKey), 2, MouseUtils::rightDown, MouseUtils::rightUp)
).forEach(dto -> {
if (dto.keyPressed && !isMouseKeyPressedPreviousTick[dto.keyPressedPreviouslyIndex]) {
// key pressed
dto.keyDown.run();
} else if (!dto.keyPressed && isMouseKeyPressedPreviousTick[dto.keyPressedPreviouslyIndex]) {
// key released
dto.keyUp.run();
}

// update state
isMouseKeyPressedPreviousTick[dto.keyPressedPreviouslyIndex] = dto.keyPressed;
});
}

private record MouseKeyDTO(Boolean keyPressed, int keyPressedPreviouslyIndex, Runnable keyDown, Runnable keyUp) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,12 @@ public static void moveAndRightClick(int x, int y) {
* @param y the y position of the pixel location
*/
public static void move(int x, int y) {
try {
MainClass.infoLog("Moving mouse to x:%d y:%d".formatted(x, y));

if (OsUtils.isLinux()) {
Runtime.getRuntime().exec("xdotool mousemove %d %d".formatted(x, y));
}

if (OsUtils.isWindows()) {
if (mainInterface == null) initializeUser32dll();

if (!mainInterface.SetCursorPos(x, y))
MainClass.errorLog("\nError encountered on moving mouse.");
}
} catch (Exception e) {
MainClass.errorLog("\nError encountered on moving mouse.");
e.printStackTrace();
}
doNativeMouseAction("mouse moving", true,
"xdotool mousemove %d %d".formatted(x, y),
(i) -> {
if (!i.SetCursorPos(x, y)) MainClass.errorLog("\nError encountered on moving mouse.");
}
);
}

/**
Expand Down Expand Up @@ -107,135 +96,144 @@ public void run() {
* Perform left click at the current pixel location.
*/
public static void leftClick() {
MinecraftClient minecraftClient = MinecraftClient.getInstance();
if (minecraftClient == null)
return;

try {
int x = (int) minecraftClient.mouse.getX(), y = (int) minecraftClient.mouse.getY();
MainClass.infoLog("Performing left click at x:%d y:%d".formatted(x, y));

if (OsUtils.isLinux()) {
Runtime.getRuntime().exec("xdotool click 1");
}

if (OsUtils.isWindows()) {
if (mainInterface == null) initializeUser32dll();
doNativeMouseAction("left click", true,
"xdotool click 1",
(i) -> {
i.mouse_event(MouseEventFlags.LEFTDOWN.getValue(), 0, 0, 0, 0);
i.mouse_event(MouseEventFlags.LEFTUP.getValue(), 0, 0, 0, 0);
}
);
}

mainInterface.mouse_event(MouseEventFlags.LEFTDOWN.getValue(), 0, 0, 0, 0);
mainInterface.mouse_event(MouseEventFlags.LEFTUP.getValue(), 0, 0, 0, 0);
}
} catch (Exception e) {
MainClass.errorLog("\nError encountered on performing left mouse click.");
e.printStackTrace();
}
/**
* Press left mouse key down at the current pixel location.
*/
public static void leftDown() {
doNativeMouseAction("left down", true,
"xdotool mousedown 1",
(i) -> i.mouse_event(MouseEventFlags.LEFTDOWN.getValue(), 0, 0, 0, 0)
);
}

/**
* Press left mouse key up at the current pixel location.
*/
public static void leftUp() {
doNativeMouseAction("left up", true,
"xdotool mouseup 1",
(i) -> i.mouse_event(MouseEventFlags.LEFTUP.getValue(), 0, 0, 0, 0)
);
}

/**
* Perform middle click at the current pixel location.
*/
@SuppressWarnings("unused")
public static void middleClick() {
MinecraftClient minecraftClient = MinecraftClient.getInstance();
if (minecraftClient == null)
return;

try {
int x = (int) minecraftClient.mouse.getX(), y = (int) minecraftClient.mouse.getY();
MainClass.infoLog("Performing middle click at x:%d y:%d".formatted(x, y));

if (OsUtils.isLinux()) {
Runtime.getRuntime().exec("xdotool click 2");
}
doNativeMouseAction("middle click", true,
"xdotool click 2",
(i) -> {
i.mouse_event(MouseEventFlags.MIDDLEDOWN.getValue(), 0, 0, 0, 0);
i.mouse_event(MouseEventFlags.MIDDLEUP.getValue(), 0, 0, 0, 0);
}
);
}

if (OsUtils.isWindows()) {
if (mainInterface == null) initializeUser32dll();
/**
* Press middle mouse key down at the current pixel location.
*/
public static void middleDown() {
doNativeMouseAction("middle down", true,
"xdotool mousedown 2",
(i) -> i.mouse_event(MouseEventFlags.MIDDLEDOWN.getValue(), 0, 0, 0, 0)
);
}

mainInterface.mouse_event(MouseEventFlags.MIDDLEDOWN.getValue(), 0, 0, 0, 0);
mainInterface.mouse_event(MouseEventFlags.MIDDLEUP.getValue(), 0, 0, 0, 0);
}
} catch (Exception e) {
MainClass.errorLog("\nError encountered on performing middle mouse click.");
e.printStackTrace();
}
/**
* Press middle mouse key up at the current pixel location.
*/
public static void middleUp() {
doNativeMouseAction("middle up", true,
"xdotool mouseup 2",
(i) -> i.mouse_event(MouseEventFlags.MIDDLEUP.getValue(), 0, 0, 0, 0)
);
}

/**
* Perform right click at the current pixel location.
*/
public static void rightClick() {
MinecraftClient minecraftClient = MinecraftClient.getInstance();
if (minecraftClient == null)
return;

try {
int x = (int) minecraftClient.mouse.getX(), y = (int) minecraftClient.mouse.getY();
MainClass.infoLog("Performing right click at x:%d y:%d".formatted(x, y));

if (OsUtils.isLinux()) {
Runtime.getRuntime().exec("xdotool click 3");
}
doNativeMouseAction("right click", true,
"xdotool click 3",
(i) -> {
i.mouse_event(MouseEventFlags.RIGHTDOWN.getValue(), 0, 0, 0, 0);
i.mouse_event(MouseEventFlags.RIGHTUP.getValue(), 0, 0, 0, 0);
}
);
}

if (OsUtils.isWindows()) {
if (mainInterface == null) initializeUser32dll();
/**
* Press right mouse key down at the current pixel location.
*/
public static void rightDown() {
doNativeMouseAction("right down", true,
"xdotool mousedown 3",
(i) -> i.mouse_event(MouseEventFlags.RIGHTDOWN.getValue(), 0, 0, 0, 0)
);
}

mainInterface.mouse_event(MouseEventFlags.RIGHTDOWN.getValue(), 0, 0, 0, 0);
mainInterface.mouse_event(MouseEventFlags.RIGHTUP.getValue(), 0, 0, 0, 0);
}
} catch (Exception e) {
MainClass.errorLog("\nError encountered on performing right mouse click.");
e.printStackTrace();
}
/**
* Press right mouse key up at the current pixel location.
*/
public static void rightUp() {
doNativeMouseAction("right up", true,
"xdotool mouseup 3",
(i) -> i.mouse_event(MouseEventFlags.RIGHTUP.getValue(), 0, 0, 0, 0)
);
}

/**
* Performs mouse scroll up
*/
public static void scrollUp(){
MinecraftClient minecraftClient = MinecraftClient.getInstance();
if (minecraftClient == null)
return;

try {
MainClass.infoLog("Performing scroll up");

if (OsUtils.isLinux()) {
Runtime.getRuntime().exec("xdotool click 4");
}

if (OsUtils.isWindows()) {
if (mainInterface == null) initializeUser32dll();

mainInterface.mouse_event(MouseEventFlags.WHEEL.getValue(), 0, 0, 120, 0);
}
} catch (Exception e) {
MainClass.errorLog("\nError encountered on performing scroll up.");
e.printStackTrace();
}
public static void scrollUp() {
doNativeMouseAction("scroll up", false,
"xdotool click 4",
(i) -> i.mouse_event(MouseEventFlags.WHEEL.getValue(), 0, 0, 120, 0)
);
}

/**
* Performs mouse scroll down
*/
public static void scrollDown(){
public static void scrollDown() {
doNativeMouseAction("scroll down", false,
"xdotool click 5",
(i) -> i.mouse_event(MouseEventFlags.WHEEL.getValue(), 0, 0, -120, 0));
}

private static void doNativeMouseAction(String name, boolean logCoordinates, String linuxXdotCommand, Consumer<user32dllInterface> windowsAction) {
MinecraftClient minecraftClient = MinecraftClient.getInstance();
if (minecraftClient == null)
return;

try {
MainClass.infoLog("Performing scroll down");

if (OsUtils.isLinux()) {
Runtime.getRuntime().exec("xdotool click 5");
try {
String coordinates = "";
if (logCoordinates) {
int x = (int) minecraftClient.mouse.getX(), y = (int) minecraftClient.mouse.getY();
coordinates = " on x:%d y:%d".formatted(x, y);
}
MainClass.infoLog("Performing " + name + coordinates);

if (OsUtils.isWindows()) {
if (mainInterface == null) initializeUser32dll();

mainInterface.mouse_event(MouseEventFlags.WHEEL.getValue(), 0, 0, -120, 0);
if (OsUtils.isLinux()) {
Runtime.getRuntime().exec(linuxXdotCommand);
} else if (OsUtils.isWindows()) {
if (mainInterface == null) initializeUser32dll();
windowsAction.accept(mainInterface);
}
} catch (Exception e) {
MainClass.errorLog("\nError encountered on performing scroll up.");
MainClass.errorLog("\nError encountered on performing " + name + ".");
e.printStackTrace();
}
}
Expand Down

0 comments on commit f27245f

Please sign in to comment.