diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..f897e99 --- /dev/null +++ b/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + nl.andrewl. + randomhotbar + 1.0.0 + + + 17 + 17 + + + + + com.formdev + flatlaf + 2.0.2 + + + com.github.kwhat + jnativehook + 2.2.1 + + + + + + + maven-assembly-plugin + + + + nl.andrewl.randomhotbar.RandomHotbar + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + + \ No newline at end of file diff --git a/src/main/java/nl/andrewl/randomhotbar/BlockPlaceListener.java b/src/main/java/nl/andrewl/randomhotbar/BlockPlaceListener.java new file mode 100644 index 0000000..872a010 --- /dev/null +++ b/src/main/java/nl/andrewl/randomhotbar/BlockPlaceListener.java @@ -0,0 +1,72 @@ +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 float randSum; + private int currentSlot = 1; + + public BlockPlaceListener(List settings) { + randSum = 0; + for (var v : settings) { + randSum += v.chance(); + } + this.settings = settings; + for (var v : settings) { + float percent = (v.chance() / randSum) * 100.0f; + System.out.printf("Will use slot %d, %.1f%% of the time.\n", v.slot(), percent); + } + System.out.printf("Starting at slot %d. Please select this slot if it is not selected already, then start right-clicking. Do not hold right-click.\n", currentSlot); + } + + private int getNextSlot() { + float idx = rand.nextFloat(randSum); + float sum = 0; + int i = 0; + while (sum < idx) { + sum += settings.get(i++).chance(); + } + 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); + } + } +} diff --git a/src/main/java/nl/andrewl/randomhotbar/RandomHotbar.java b/src/main/java/nl/andrewl/randomhotbar/RandomHotbar.java new file mode 100644 index 0000000..75fbec7 --- /dev/null +++ b/src/main/java/nl/andrewl/randomhotbar/RandomHotbar.java @@ -0,0 +1,45 @@ +package nl.andrewl.randomhotbar; + +import com.github.kwhat.jnativehook.GlobalScreen; +import com.github.kwhat.jnativehook.NativeHookException; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class RandomHotbar { + public static void main(String[] args) { + try { + GlobalScreen.registerNativeHook(); + } catch (NativeHookException e) { + e.printStackTrace(); + } + 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) { + List settings = new ArrayList<>(9); + Matcher m = SETTINGS_PATTERN.matcher(s); + while (m.find()) { + int slot = Integer.parseInt(m.group(1)); + float value = Float.parseFloat(m.group(2)); + for (var setting : settings) { + if (setting.slot() == slot) { + throw new IllegalArgumentException("A setting for slot " + slot + " is already defined."); + } + } + settings.add(new SlotSetting(slot, value)); + } + settings.sort(Comparator.comparing(SlotSetting::slot)); + if (settings.isEmpty()) { + for (int i = 1; i <= 9; i++) { + settings.add(new SlotSetting(i, 1)); + } + } + return settings; + } +} diff --git a/src/main/java/nl/andrewl/randomhotbar/SlotSetting.java b/src/main/java/nl/andrewl/randomhotbar/SlotSetting.java new file mode 100644 index 0000000..63fd094 --- /dev/null +++ b/src/main/java/nl/andrewl/randomhotbar/SlotSetting.java @@ -0,0 +1,4 @@ +package nl.andrewl.randomhotbar; + +public record SlotSetting(int slot, float chance) { +}