From af5aed78f2831f057bd2590dd682429e959c054a Mon Sep 17 00:00:00 2001 From: cattyn Date: Thu, 25 Dec 2025 14:23:47 +0300 Subject: [PATCH 1/6] refactor: watch your language sir --- src/main/java/me/alpha432/oyvey/util/EnchantmentUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/alpha432/oyvey/util/EnchantmentUtil.java b/src/main/java/me/alpha432/oyvey/util/EnchantmentUtil.java index 19bc7c7a..d4533326 100644 --- a/src/main/java/me/alpha432/oyvey/util/EnchantmentUtil.java +++ b/src/main/java/me/alpha432/oyvey/util/EnchantmentUtil.java @@ -11,7 +11,7 @@ public final class EnchantmentUtil implements Util { private EnchantmentUtil() { - throw new IllegalArgumentException("пошел нахуй"); + throw new IllegalArgumentException(); } public static int getLevel(ResourceKey key, ItemStack stack) { From 1362662f6651fb34cdebcb553c4cad594b47ddd1 Mon Sep 17 00:00:00 2001 From: cattyn Date: Thu, 25 Dec 2025 15:41:41 +0300 Subject: [PATCH 2/6] feat(InventoryUtil): add basic util for inventory search & interaction --- .../oyvey/util/inventory/InventoryUtil.java | 64 +++++++++++++++++++ .../alpha432/oyvey/util/inventory/Result.java | 22 +++++++ .../oyvey/util/inventory/ResultType.java | 8 +++ src/main/resources/oyvey.accesswidener | 1 + 4 files changed, 95 insertions(+) create mode 100644 src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java create mode 100644 src/main/java/me/alpha432/oyvey/util/inventory/Result.java create mode 100644 src/main/java/me/alpha432/oyvey/util/inventory/ResultType.java diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java b/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java new file mode 100644 index 00000000..e2ed743d --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java @@ -0,0 +1,64 @@ +package me.alpha432.oyvey.util.inventory; + +import me.alpha432.oyvey.util.traits.Util; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.item.ItemStack; + +import java.util.Set; +import java.util.function.BiPredicate; +import java.util.function.Predicate; + +public final class InventoryUtil implements Util { + public static final Result NONE = new Result(-1, ItemStack.EMPTY, ResultType.NONE); + + private InventoryUtil() { + throw new AssertionError(); + } + + public static ItemStack cursor() { + return mc.player.containerMenu.getCarried(); + } + + public static int selected() { + return mc.player.getInventory().getSelectedSlot(); + } + + public static void click(int slot, int button, ClickType type) { + int id = mc.player.containerMenu.containerId; + mc.gameMode.handleInventoryMouseClick(id, slot, button, type, mc.player); + } + + public static void swap(int to) { + if (to < 0 || to > 8) return; + mc.player.getInventory().setSelectedSlot(to); + mc.gameMode.ensureHasSentCarriedItem(); + } + + public static Result find(Predicate predicate, ResultType... types) { + final Set set = Set.of(types); + return find((item, type) -> set.contains(type) && predicate.test(item)); + } + + public static Result find(BiPredicate predicate) { + ItemStack offhand = mc.player.getOffhandItem(); + if (predicate.test(offhand, ResultType.OFFHAND)) { + return Result.fromOffhand(offhand); + } + + for (int i = 0; i < 9; i++) { + ItemStack item = mc.player.getInventory().getItem(i); + if (predicate.test(item, ResultType.HOTBAR)) { + return new Result(i, item, ResultType.HOTBAR); + } + } + + for (int i = 9; i < 36; i++) { + ItemStack item = mc.player.getInventory().getItem(i); + if (predicate.test(item, ResultType.INVENTORY)) { + return new Result(i, item, ResultType.INVENTORY); + } + } + + return NONE; + } +} diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/Result.java b/src/main/java/me/alpha432/oyvey/util/inventory/Result.java new file mode 100644 index 00000000..08d9223b --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/util/inventory/Result.java @@ -0,0 +1,22 @@ +package me.alpha432.oyvey.util.inventory; + +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; + +public record Result(int slot, ItemStack stack, ResultType type) { + static Result fromOffhand(ItemStack stack) { + return new Result(-1, stack, ResultType.OFFHAND); + } + + public InteractionHand getHand() { + return type == ResultType.OFFHAND ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; + } + + public boolean holding() { + return type == ResultType.OFFHAND || type == ResultType.HOTBAR && slot == InventoryUtil.selected(); + } + + public boolean found() { + return type != ResultType.NONE; + } +} diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/ResultType.java b/src/main/java/me/alpha432/oyvey/util/inventory/ResultType.java new file mode 100644 index 00000000..f73c447c --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/util/inventory/ResultType.java @@ -0,0 +1,8 @@ +package me.alpha432.oyvey.util.inventory; + +public enum ResultType { + HOTBAR, + INVENTORY, + OFFHAND, + NONE +} diff --git a/src/main/resources/oyvey.accesswidener b/src/main/resources/oyvey.accesswidener index 8b9085f1..a60449a6 100644 --- a/src/main/resources/oyvey.accesswidener +++ b/src/main/resources/oyvey.accesswidener @@ -5,3 +5,4 @@ accessible field net/minecraft/network/protocol/game/ServerboundInteractPacket e accessible method net/minecraft/network/protocol/game/ServerboundInteractPacket$Action getType ()Lnet/minecraft/network/protocol/game/ServerboundInteractPacket$ActionType; accessible class net/minecraft/network/protocol/game/ServerboundInteractPacket$ActionType accessible field net/minecraft/network/protocol/game/ServerboundInteractPacket action Lnet/minecraft/network/protocol/game/ServerboundInteractPacket$Action; +accessible method net/minecraft/client/multiplayer/MultiPlayerGameMode ensureHasSentCarriedItem ()V \ No newline at end of file From f3af88ffeaed393614be303ec3021ba4efc53b70 Mon Sep 17 00:00:00 2001 From: cattyn Date: Thu, 25 Dec 2025 20:42:53 +0300 Subject: [PATCH 3/6] feat: implement swap strategies --- .../oyvey/util/inventory/InventoryUtil.java | 25 +++++++++++++++ .../inventory/strategy/HoldingStrategy.java | 20 ++++++++++++ .../inventory/strategy/HotbarStrategy.java | 30 ++++++++++++++++++ .../inventory/strategy/InventoryStrategy.java | 31 +++++++++++++++++++ .../util/inventory/strategy/SwapStrategy.java | 9 ++++++ 5 files changed, 115 insertions(+) create mode 100644 src/main/java/me/alpha432/oyvey/util/inventory/strategy/HoldingStrategy.java create mode 100644 src/main/java/me/alpha432/oyvey/util/inventory/strategy/HotbarStrategy.java create mode 100644 src/main/java/me/alpha432/oyvey/util/inventory/strategy/InventoryStrategy.java create mode 100644 src/main/java/me/alpha432/oyvey/util/inventory/strategy/SwapStrategy.java diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java b/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java index e2ed743d..6cbb9b68 100644 --- a/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java +++ b/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java @@ -1,14 +1,25 @@ package me.alpha432.oyvey.util.inventory; +import me.alpha432.oyvey.util.inventory.strategy.HoldingStrategy; +import me.alpha432.oyvey.util.inventory.strategy.HotbarStrategy; +import me.alpha432.oyvey.util.inventory.strategy.InventoryStrategy; +import me.alpha432.oyvey.util.inventory.strategy.SwapStrategy; import me.alpha432.oyvey.util.traits.Util; import net.minecraft.world.inventory.ClickType; import net.minecraft.world.item.ItemStack; +import java.util.List; import java.util.Set; import java.util.function.BiPredicate; import java.util.function.Predicate; public final class InventoryUtil implements Util { + private static final List STRATEGIES = List.of( + HoldingStrategy.INSTANCE, + HotbarStrategy.INSTANCE, + InventoryStrategy.INSTANCE + ); + public static final Result NONE = new Result(-1, ItemStack.EMPTY, ResultType.NONE); private InventoryUtil() { @@ -34,6 +45,20 @@ public static void swap(int to) { mc.gameMode.ensureHasSentCarriedItem(); } + public static void swap(Result result) { + for (SwapStrategy strategy : STRATEGIES) { + if (strategy.swap(result)) + return; + } + } + + public static void swapBack(int last, Result result) { + for (SwapStrategy strategy : STRATEGIES) { + if (strategy.swapBack(last, result)) + return; + } + } + public static Result find(Predicate predicate, ResultType... types) { final Set set = Set.of(types); return find((item, type) -> set.contains(type) && predicate.test(item)); diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/strategy/HoldingStrategy.java b/src/main/java/me/alpha432/oyvey/util/inventory/strategy/HoldingStrategy.java new file mode 100644 index 00000000..63ff6a01 --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/util/inventory/strategy/HoldingStrategy.java @@ -0,0 +1,20 @@ +package me.alpha432.oyvey.util.inventory.strategy; + +import me.alpha432.oyvey.util.inventory.Result; + +public final class HoldingStrategy implements SwapStrategy{ + public static final HoldingStrategy INSTANCE = new HoldingStrategy(); + + private HoldingStrategy() { + } + + @Override + public boolean swap(Result result) { + return result.holding(); + } + + @Override + public boolean swapBack(int last, Result result) { + return result.holding(); + } +} diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/strategy/HotbarStrategy.java b/src/main/java/me/alpha432/oyvey/util/inventory/strategy/HotbarStrategy.java new file mode 100644 index 00000000..37013306 --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/util/inventory/strategy/HotbarStrategy.java @@ -0,0 +1,30 @@ +package me.alpha432.oyvey.util.inventory.strategy; + +import me.alpha432.oyvey.util.inventory.InventoryUtil; +import me.alpha432.oyvey.util.inventory.Result; +import me.alpha432.oyvey.util.inventory.ResultType; + +public final class HotbarStrategy implements SwapStrategy { + public static final HotbarStrategy INSTANCE = new HotbarStrategy(); + + private HotbarStrategy() { + } + + @Override + public boolean swap(Result result) { + if (result.type() == ResultType.HOTBAR) { + InventoryUtil.swap(result.slot()); + return true; + } + return false; + } + + @Override + public boolean swapBack(int last, Result result) { + if (result.type() == ResultType.HOTBAR) { + InventoryUtil.swap(result.slot()); + return true; + } + return false; + } +} diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/strategy/InventoryStrategy.java b/src/main/java/me/alpha432/oyvey/util/inventory/strategy/InventoryStrategy.java new file mode 100644 index 00000000..431b155b --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/util/inventory/strategy/InventoryStrategy.java @@ -0,0 +1,31 @@ +package me.alpha432.oyvey.util.inventory.strategy; + +import me.alpha432.oyvey.util.inventory.InventoryUtil; +import me.alpha432.oyvey.util.inventory.Result; +import me.alpha432.oyvey.util.inventory.ResultType; +import net.minecraft.world.inventory.ClickType; + +public final class InventoryStrategy implements SwapStrategy { + public static final InventoryStrategy INSTANCE = new InventoryStrategy(); + + private InventoryStrategy() { + } + + @Override + public boolean swap(Result result) { + if (result.type() != ResultType.INVENTORY && result.type() != ResultType.HOTBAR) + return false; + int slot = inventorySlot(result); + InventoryUtil.click(slot, InventoryUtil.selected(), ClickType.SWAP); + return true; + } + + @Override + public boolean swapBack(int last, Result result) { + return swap(result); + } + + private static int inventorySlot(Result result) { + return result.type() == ResultType.HOTBAR ? result.slot() + 36 : result.slot(); + } +} diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/strategy/SwapStrategy.java b/src/main/java/me/alpha432/oyvey/util/inventory/strategy/SwapStrategy.java new file mode 100644 index 00000000..3f571c3d --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/util/inventory/strategy/SwapStrategy.java @@ -0,0 +1,9 @@ +package me.alpha432.oyvey.util.inventory.strategy; + +import me.alpha432.oyvey.util.inventory.Result; + +public interface SwapStrategy { + boolean swap(Result result); + + boolean swapBack(int last, Result result); +} From 662475b0881cf051ee53c8d05fd5de8f8b09f197 Mon Sep 17 00:00:00 2001 From: cattyn Date: Thu, 25 Dec 2025 20:55:29 +0300 Subject: [PATCH 4/6] refactor: change vararg to `EnumSet` and more overloading --- .../alpha432/oyvey/util/inventory/InventoryUtil.java | 12 ++++++++---- .../me/alpha432/oyvey/util/inventory/Result.java | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java b/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java index 6cbb9b68..ec6ddb21 100644 --- a/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java +++ b/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java @@ -6,10 +6,11 @@ import me.alpha432.oyvey.util.inventory.strategy.SwapStrategy; import me.alpha432.oyvey.util.traits.Util; import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import java.util.EnumSet; import java.util.List; -import java.util.Set; import java.util.function.BiPredicate; import java.util.function.Predicate; @@ -59,9 +60,12 @@ public static void swapBack(int last, Result result) { } } - public static Result find(Predicate predicate, ResultType... types) { - final Set set = Set.of(types); - return find((item, type) -> set.contains(type) && predicate.test(item)); + public static Result find(Item target, EnumSet scopes) { + return find(stack -> stack.is(target), scopes); + } + + public static Result find(Predicate predicate, EnumSet scopes) { + return find((item, scope) -> scopes.contains(scope) && predicate.test(item)); } public static Result find(BiPredicate predicate) { diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/Result.java b/src/main/java/me/alpha432/oyvey/util/inventory/Result.java index 08d9223b..33aac6b2 100644 --- a/src/main/java/me/alpha432/oyvey/util/inventory/Result.java +++ b/src/main/java/me/alpha432/oyvey/util/inventory/Result.java @@ -8,7 +8,7 @@ static Result fromOffhand(ItemStack stack) { return new Result(-1, stack, ResultType.OFFHAND); } - public InteractionHand getHand() { + public InteractionHand hand() { return type == ResultType.OFFHAND ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; } From 8774eac6ab0439b01bd1e4dc49d18344ed07099a Mon Sep 17 00:00:00 2001 From: cattyn Date: Thu, 25 Dec 2025 21:10:20 +0300 Subject: [PATCH 5/6] fix: correct invalid strategies behaviour --- .../oyvey/util/inventory/InventoryUtil.java | 7 ++++++- .../me/alpha432/oyvey/util/inventory/Result.java | 14 +++++++++----- .../util/inventory/strategy/HotbarStrategy.java | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java b/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java index ec6ddb21..dac9d53c 100644 --- a/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java +++ b/src/main/java/me/alpha432/oyvey/util/inventory/InventoryUtil.java @@ -15,13 +15,18 @@ import java.util.function.Predicate; public final class InventoryUtil implements Util { + public static final Result NONE = new Result(-1, ItemStack.EMPTY, ResultType.NONE); + + public static final EnumSet HOTBAR_SCOPE = EnumSet.of(ResultType.OFFHAND, ResultType.HOTBAR); + public static final EnumSet INVENTORY_SCOPE = EnumSet.of(ResultType.OFFHAND, ResultType.INVENTORY); + public static final EnumSet FULL_SCOPE = EnumSet.of(ResultType.OFFHAND, ResultType.HOTBAR, ResultType.INVENTORY); + private static final List STRATEGIES = List.of( HoldingStrategy.INSTANCE, HotbarStrategy.INSTANCE, InventoryStrategy.INSTANCE ); - public static final Result NONE = new Result(-1, ItemStack.EMPTY, ResultType.NONE); private InventoryUtil() { throw new AssertionError(); diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/Result.java b/src/main/java/me/alpha432/oyvey/util/inventory/Result.java index 33aac6b2..a16a1592 100644 --- a/src/main/java/me/alpha432/oyvey/util/inventory/Result.java +++ b/src/main/java/me/alpha432/oyvey/util/inventory/Result.java @@ -3,7 +3,11 @@ import net.minecraft.world.InteractionHand; import net.minecraft.world.item.ItemStack; -public record Result(int slot, ItemStack stack, ResultType type) { +public record Result(int slot, ItemStack stack, ResultType type, boolean holding) { + public Result(int slot, ItemStack stack, ResultType type) { + this(slot, stack, type, isHolding(type, slot)); + } + static Result fromOffhand(ItemStack stack) { return new Result(-1, stack, ResultType.OFFHAND); } @@ -12,11 +16,11 @@ public InteractionHand hand() { return type == ResultType.OFFHAND ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; } - public boolean holding() { - return type == ResultType.OFFHAND || type == ResultType.HOTBAR && slot == InventoryUtil.selected(); - } - public boolean found() { return type != ResultType.NONE; } + + private static boolean isHolding(ResultType type, int slot) { + return type == ResultType.OFFHAND || type == ResultType.HOTBAR && slot == InventoryUtil.selected(); + } } diff --git a/src/main/java/me/alpha432/oyvey/util/inventory/strategy/HotbarStrategy.java b/src/main/java/me/alpha432/oyvey/util/inventory/strategy/HotbarStrategy.java index 37013306..ef29c0e3 100644 --- a/src/main/java/me/alpha432/oyvey/util/inventory/strategy/HotbarStrategy.java +++ b/src/main/java/me/alpha432/oyvey/util/inventory/strategy/HotbarStrategy.java @@ -22,7 +22,7 @@ public boolean swap(Result result) { @Override public boolean swapBack(int last, Result result) { if (result.type() == ResultType.HOTBAR) { - InventoryUtil.swap(result.slot()); + InventoryUtil.swap(last); return true; } return false; From fcf0aa95e70660af3095f81d07c1ea99c90890a8 Mon Sep 17 00:00:00 2001 From: cattyn Date: Thu, 25 Dec 2025 21:13:02 +0300 Subject: [PATCH 6/6] feat(ClickPearl): add `ClickPearl` module as a demo for inventory utils --- .../features/modules/combat/ClickPearl.java | 34 +++++++++++++++++++ .../alpha432/oyvey/manager/ModuleManager.java | 2 ++ 2 files changed, 36 insertions(+) create mode 100644 src/main/java/me/alpha432/oyvey/features/modules/combat/ClickPearl.java diff --git a/src/main/java/me/alpha432/oyvey/features/modules/combat/ClickPearl.java b/src/main/java/me/alpha432/oyvey/features/modules/combat/ClickPearl.java new file mode 100644 index 00000000..cb0853e0 --- /dev/null +++ b/src/main/java/me/alpha432/oyvey/features/modules/combat/ClickPearl.java @@ -0,0 +1,34 @@ +package me.alpha432.oyvey.features.modules.combat; + +import me.alpha432.oyvey.features.modules.Module; +import me.alpha432.oyvey.features.settings.Setting; +import me.alpha432.oyvey.util.inventory.InventoryUtil; +import me.alpha432.oyvey.util.inventory.Result; +import net.minecraft.world.item.Items; + +import static me.alpha432.oyvey.util.inventory.InventoryUtil.FULL_SCOPE; +import static me.alpha432.oyvey.util.inventory.InventoryUtil.HOTBAR_SCOPE; + +public class ClickPearl extends Module { + private final Setting inventory = bool("Inventory", false); + + public ClickPearl() { + super("ClickPearl", "Throws a pearl when enabled.", Category.COMBAT); + } + + @Override + public void onEnable() { + disable(); + + if (nullCheck()) return; + + int last = InventoryUtil.selected(); + Result result = InventoryUtil.find(Items.ENDER_PEARL, inventory.getValue() ? FULL_SCOPE : HOTBAR_SCOPE); + if (!result.found()) + return; + + InventoryUtil.swap(result); + mc.gameMode.useItem(mc.player, result.hand()); + InventoryUtil.swapBack(last, result); + } +} diff --git a/src/main/java/me/alpha432/oyvey/manager/ModuleManager.java b/src/main/java/me/alpha432/oyvey/manager/ModuleManager.java index 0213772d..ba437fca 100644 --- a/src/main/java/me/alpha432/oyvey/manager/ModuleManager.java +++ b/src/main/java/me/alpha432/oyvey/manager/ModuleManager.java @@ -9,6 +9,7 @@ import me.alpha432.oyvey.features.modules.client.ClickGui; import me.alpha432.oyvey.features.modules.client.HudEditor; import me.alpha432.oyvey.features.modules.client.Notifications; +import me.alpha432.oyvey.features.modules.combat.ClickPearl; import me.alpha432.oyvey.features.modules.combat.Criticals; import me.alpha432.oyvey.features.modules.hud.Coordinates; import me.alpha432.oyvey.features.modules.hud.Watermark; @@ -43,6 +44,7 @@ public void init() { register(new Velocity()); register(new BlockHighlight()); register(new NoFall()); + register(new ClickPearl()); } public void register(Module module) {