From ec2c0b198c6d543ea2fa392e18c1a23b44962575 Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Wed, 23 Mar 2022 22:26:35 +0100 Subject: [PATCH] Updated to add cycle functionality and extract scroll functionality to its own class. --- README.md | 9 +++ .../randomhotbar/BlockPlaceListener.java | 34 ++-------- .../nl/andrewl/randomhotbar/RandomHotbar.java | 53 +++++++++++++-- .../nl/andrewl/randomhotbar/Scroller.java | 66 +++++++++++++++++++ .../nl/andrewl/randomhotbar/SlotSetting.java | 3 +- 5 files changed, 127 insertions(+), 38 deletions(-) create mode 100644 src/main/java/nl/andrewl/randomhotbar/Scroller.java diff --git a/README.md b/README.md index fe14c4d..2fee50e 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,12 @@ For example: ``` java -jar RandomHotbar.jar 1:1, 2:1, 3:1.5, 4:0.75 ``` + +Alternatively, if you like spam-clicking to place randomized blocks, opt instead for the **cycle** option. It's used like so: +``` +java -jar RandomHotbar.jar cycle +``` +Using this setting, you will automatically cycle through all hotbar slots, shifting in random intervals to make sure that no patterns are introduced in the blocks you place. You can also restrict the cycle mode to the first N slots like so: +``` +java -jar RandomHotbar.jar cycle 3 +``` diff --git a/src/main/java/nl/andrewl/randomhotbar/BlockPlaceListener.java b/src/main/java/nl/andrewl/randomhotbar/BlockPlaceListener.java index 4aa9b3e..1562793 100644 --- a/src/main/java/nl/andrewl/randomhotbar/BlockPlaceListener.java +++ b/src/main/java/nl/andrewl/randomhotbar/BlockPlaceListener.java @@ -1,22 +1,16 @@ package nl.andrewl.randomhotbar; -import com.github.kwhat.jnativehook.GlobalScreen; import com.github.kwhat.jnativehook.mouse.NativeMouseEvent; import com.github.kwhat.jnativehook.mouse.NativeMouseInputListener; -import com.github.kwhat.jnativehook.mouse.NativeMouseWheelEvent; import java.util.List; import java.util.Random; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; public class BlockPlaceListener implements NativeMouseInputListener { private final Random rand = new Random(); - private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); private final List settings; + private final Scroller scroller; private float randSum; - private int currentSlot = 1; public BlockPlaceListener(List settings) { randSum = 0; @@ -30,7 +24,8 @@ public class BlockPlaceListener implements NativeMouseInputListener { System.out.printf("Will use slot %d, %.1f%% of the time.\n", v.slot(), percent); } System.out.println("-".repeat(20)); - System.out.printf("Starting at slot %d.\n! Please select this slot if it is not selected already, then start right-clicking.\n! Do not hold right-click.\n", currentSlot); + this.scroller = new Scroller(1); + System.out.printf("Starting at slot %d.\n! Please select this slot if it is not selected already, then start right-clicking.\n! Do not hold right-click.\n", scroller.getCurrentSlot()); } private int getNextSlot() { @@ -43,32 +38,11 @@ public class BlockPlaceListener implements NativeMouseInputListener { return settings.get(Math.max(0, i - 1)).slot(); } - private void moveToSlot(int slot) { - final int dir = slot < currentSlot ? 1 : -1; - int n = Math.abs(currentSlot - slot); - for (int i = 0; i < n; i++) { - executor.schedule(() -> { - GlobalScreen.postNativeEvent(new NativeMouseWheelEvent( - 2505, - 0, - 500, - 500, - 1, - NativeMouseWheelEvent.WHEEL_UNIT_SCROLL, - 1, - dir, - NativeMouseWheelEvent.WHEEL_VERTICAL_DIRECTION - )); - }, i * 50L, TimeUnit.MILLISECONDS); - } - currentSlot = slot; - } - @Override public void nativeMouseClicked(NativeMouseEvent nativeEvent) { if (nativeEvent.getButton() == 2) { int newSlot = getNextSlot(); - moveToSlot(newSlot); + this.scroller.moveToSlot(newSlot); } } } diff --git a/src/main/java/nl/andrewl/randomhotbar/RandomHotbar.java b/src/main/java/nl/andrewl/randomhotbar/RandomHotbar.java index 75fbec7..7d2e0e2 100644 --- a/src/main/java/nl/andrewl/randomhotbar/RandomHotbar.java +++ b/src/main/java/nl/andrewl/randomhotbar/RandomHotbar.java @@ -3,25 +3,36 @@ package nl.andrewl.randomhotbar; import com.github.kwhat.jnativehook.GlobalScreen; import com.github.kwhat.jnativehook.NativeHookException; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Random; +import java.util.concurrent.CompletableFuture; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RandomHotbar { - public static void main(String[] args) { + public static void main(String[] args) throws Exception { try { GlobalScreen.registerNativeHook(); } catch (NativeHookException e) { e.printStackTrace(); + System.err.println("Could not register native hooks; exiting."); + return; + } + + if (args.length > 0 && args[0].equalsIgnoreCase("cycle")) { + doCycle(args); + } else { + var settings = parseSlotSettings(String.join(",", args)); + var listener = new BlockPlaceListener(settings); + GlobalScreen.addNativeMouseListener(listener); } - var settings = parseSettings(String.join(",", args)); - var listener = new BlockPlaceListener(settings); - GlobalScreen.addNativeMouseListener(listener); } public static final Pattern SETTINGS_PATTERN = Pattern.compile("([1-9])\\s*:\\s*(\\d*\\.\\d+|\\d+)%?"); - public static List parseSettings(String s) { + public static List parseSlotSettings(String s) { List settings = new ArrayList<>(9); Matcher m = SETTINGS_PATTERN.matcher(s); while (m.find()) { @@ -42,4 +53,34 @@ public class RandomHotbar { } return settings; } + + public static void doCycle(String[] args) throws Exception { + int slots = 9; + if (args.length > 1) { + try { + slots = Integer.parseUnsignedInt(args[1]); + if (slots < 1 || slots > 9) throw new NumberFormatException("Invalid slot count."); + } catch (NumberFormatException e) { + System.err.println("Invalid slot count. Please specify a number from 1 to 9."); + return; + } + } + System.out.println("-".repeat(20)); + System.out.printf("Will cycle between the first %d slots.\n", slots); + System.out.println("-".repeat(20)); + System.out.println("Select slot 1. Will begin in 3 seconds."); + Thread.sleep(3000); + Scroller scroller = new Scroller(1); + Random rand = new Random(); + while (true) { + CompletableFuture cs; + if (scroller.getCurrentSlot() < slots) { + cs = scroller.incrementSlot(); + } else { + cs = scroller.moveToSlot(1); + } + cs.join(); + Thread.sleep(rand.nextLong(50, 250)); + } + } } diff --git a/src/main/java/nl/andrewl/randomhotbar/Scroller.java b/src/main/java/nl/andrewl/randomhotbar/Scroller.java new file mode 100644 index 0000000..08c6a67 --- /dev/null +++ b/src/main/java/nl/andrewl/randomhotbar/Scroller.java @@ -0,0 +1,66 @@ +package nl.andrewl.randomhotbar; + +import com.github.kwhat.jnativehook.GlobalScreen; +import com.github.kwhat.jnativehook.mouse.NativeMouseWheelEvent; + +import java.util.concurrent.*; + +public class Scroller { + public static final long SCROLL_DELAY_MS = 50L; + + private int currentSlot; + private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + + public Scroller(int currentSlot) { + this.currentSlot = currentSlot; + } + + public int getCurrentSlot() { + return this.currentSlot; + } + + public CompletableFuture incrementSlot() { + int slot = this.currentSlot + 1; + if (slot > 9) slot = 1; + return moveToSlot(slot); + } + + public CompletableFuture decrementSlot() { + int slot = this.currentSlot - 1; + if (slot < 1) slot = 9; + return moveToSlot(slot); + } + + public CompletableFuture moveToSlot(int slot) { + int tdir = slot < currentSlot ? 1 : -1; + int n = Math.abs(currentSlot - slot); + if (n > 4) { + tdir *= -1; + n = Math.abs(9 - n); + } + final int dir = tdir; + CompletableFuture cs = new CompletableFuture<>(); + for (int i = 0; i < n; i++) { + final int iF = i; + final int nF = n; + executor.schedule(() -> { + GlobalScreen.postNativeEvent(new NativeMouseWheelEvent( + 2505, + 0, + 500, + 500, + 1, + NativeMouseWheelEvent.WHEEL_UNIT_SCROLL, + 1, + dir, + NativeMouseWheelEvent.WHEEL_VERTICAL_DIRECTION + )); + if (iF == nF - 1) { + this.currentSlot = slot; + cs.complete(null); + } + }, i * SCROLL_DELAY_MS, TimeUnit.MILLISECONDS); + } + return cs; + } +} diff --git a/src/main/java/nl/andrewl/randomhotbar/SlotSetting.java b/src/main/java/nl/andrewl/randomhotbar/SlotSetting.java index 63fd094..7db7442 100644 --- a/src/main/java/nl/andrewl/randomhotbar/SlotSetting.java +++ b/src/main/java/nl/andrewl/randomhotbar/SlotSetting.java @@ -1,4 +1,3 @@ package nl.andrewl.randomhotbar; -public record SlotSetting(int slot, float chance) { -} +public record SlotSetting(int slot, float chance) {}