From f99435ce6105185ae0ae285c4540839db1ed8931 Mon Sep 17 00:00:00 2001 From: TutlaMC Date: Wed, 6 May 2026 18:38:49 +0530 Subject: [PATCH 1/9] i have an idea (js testing) --- gradle.properties | 2 +- .../clickcrystals/ClickCrystals.java | 1 + .../modules/scripts/macros/CraftCmd.java | 63 +++++++++++++++++++ .../util/minecraft/InvUtils.java | 6 ++ 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/github/itzispyder/clickcrystals/modules/scripts/macros/CraftCmd.java diff --git a/gradle.properties b/gradle.properties index 46fae1d4..824eb78d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx1G -org.gradle.java.home=/Program Files/java/jdk-21 +org.gradle.java.home=/usr/lib/jvm/java-21-openjdk # Fabric Properties # check these on https://modmuss50.me/fabric.html diff --git a/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java b/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java index 6e4f57db..68a31aac 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java @@ -203,6 +203,7 @@ public void initClickScript() { ClickScript.register(new AsCmd()); ClickScript.register(new CancelPacketCmd()); ClickScript.register(new UncancelPacketCmd()); + ClickScript.register(new CraftCmd()); ScriptedModule.runModuleScripts(); } diff --git a/src/main/java/io/github/itzispyder/clickcrystals/modules/scripts/macros/CraftCmd.java b/src/main/java/io/github/itzispyder/clickcrystals/modules/scripts/macros/CraftCmd.java new file mode 100644 index 00000000..495ab583 --- /dev/null +++ b/src/main/java/io/github/itzispyder/clickcrystals/modules/scripts/macros/CraftCmd.java @@ -0,0 +1,63 @@ +package io.github.itzispyder.clickcrystals.modules.scripts.macros; + +import io.github.itzispyder.clickcrystals.client.clickscript.ScriptArgs; +import io.github.itzispyder.clickcrystals.client.clickscript.ScriptCommand; +import io.github.itzispyder.clickcrystals.client.clickscript.ScriptParser; +import io.github.itzispyder.clickcrystals.modules.scripts.TargetType; +import io.github.itzispyder.clickcrystals.modules.scripts.ThenChainable; +import io.github.itzispyder.clickcrystals.util.minecraft.PlayerUtils; +import io.github.itzispyder.clickcrystals.util.minecraft.VectorParser; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.CraftingTableBlock; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.entity.Entity; +import net.minecraft.screen.CraftingScreenHandler; +import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; + +import java.util.function.Predicate; + +public class CraftCmd extends ScriptCommand implements ThenChainable { + + public CraftCmd() { + super("craft"); + } + + @Override + public void onCommand(ScriptCommand command, String line, ScriptArgs args) { + if (mc.interactionManager == null) { + return; + } + Predicate filter = ScriptParser.parseBlockPredicate(args.get(0).toString()); + PlayerUtils.runOnNearestBlock(32, filter, (pos, state) -> { + Vec3d vector = PlayerUtils.getEyes().subtract(pos.toCenterPos()); + Direction face = Direction.getFacing(vector); + BlockHitResult hit = new BlockHitResult(pos.toCenterPos(), face, pos, false); + ActionResult e = mc.interactionManager.interactBlock(mc.player, Hand.MAIN_HAND, hit); + if (PlayerUtils.getWorld().getBlockState(hit.getBlockPos()).isOf(Blocks.CRAFTING_TABLE)){ + if (mc.currentScreen instanceof HandledScreen screen && + screen.getScreenHandler() instanceof CraftingScreenHandler handler) { + System.out.println("E"); + mc.interactionManager.clickSlot( + handler.syncId, + 2, + 1, + SlotActionType.PICKUP, + mc.player + ); + } + } + }); + executeWithThen(args, 2); + + if (args.match(1, "then")) { + args.executeAll(2); + } + } +} \ No newline at end of file diff --git a/src/main/java/io/github/itzispyder/clickcrystals/util/minecraft/InvUtils.java b/src/main/java/io/github/itzispyder/clickcrystals/util/minecraft/InvUtils.java index 74474a5e..1451a4f8 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/util/minecraft/InvUtils.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/util/minecraft/InvUtils.java @@ -2,6 +2,8 @@ import io.github.itzispyder.clickcrystals.Global; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; +import net.minecraft.client.gui.screen.ingame.CrafterScreen; +import net.minecraft.client.gui.screen.ingame.CraftingScreen; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -165,4 +167,8 @@ public static boolean sendSlotPacket(int slot, int button, SlotActionType action PlayerUtils.sendPacket(swap); return true; } + + public static void craft(String recipie){ + + } } From 44724588fe79fda92720d539501df230d092451f Mon Sep 17 00:00:00 2001 From: TutlaMC Date: Wed, 6 May 2026 23:04:08 +0530 Subject: [PATCH 2/9] fuck you mojang mappings --- .../clickcrystals/ClickCrystals.java | 8 +-- .../scripting/syntax/macros/CraftCmd.java | 63 ------------------- .../syntax/macros/inventory/CraftCmd.java | 31 +++++++++ .../syntax/macros/inventory/CraftInvCmd.java | 30 +++++++++ .../util/minecraft/InvUtils.java | 44 +++++++++++++ 5 files changed, 108 insertions(+), 68 deletions(-) delete mode 100644 src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/CraftCmd.java create mode 100644 src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftCmd.java create mode 100644 src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java diff --git a/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java b/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java index 8212cced..b490888c 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java @@ -51,10 +51,7 @@ import io.github.itzispyder.clickcrystals.scripting.syntax.macros.*; import io.github.itzispyder.clickcrystals.scripting.syntax.macros.camera.SnapToCmd; import io.github.itzispyder.clickcrystals.scripting.syntax.macros.camera.TurnToCmd; -import io.github.itzispyder.clickcrystals.scripting.syntax.macros.inventory.GuiDropCmd; -import io.github.itzispyder.clickcrystals.scripting.syntax.macros.inventory.GuiQuickMoveCmd; -import io.github.itzispyder.clickcrystals.scripting.syntax.macros.inventory.GuiSwapCmd; -import io.github.itzispyder.clickcrystals.scripting.syntax.macros.inventory.GuiSwitchCmd; +import io.github.itzispyder.clickcrystals.scripting.syntax.macros.inventory.*; import io.github.itzispyder.clickcrystals.util.minecraft.ChatUtils; import io.github.itzispyder.clickcrystals.util.misc.TickScheduler; import net.fabricmc.api.ModInitializer; @@ -222,6 +219,8 @@ public void initClickScript() { ClickScript.register(new CancelPacketCmd()); ClickScript.register(new UncancelPacketCmd()); ClickScript.register(new ToggleInputCmd()); + ClickScript.register(new CraftCmd()); + ClickScript.register(new CraftInvCmd()); ScriptedModule.runModuleScripts(); } @@ -249,7 +248,6 @@ public void init() { system.addCommand(new KeybindsCommand()); system.addCommand(new RotateCommand()); system.addCommand(new LookCommand()); - system.addCommand(new ScriptCommand()); system.addCommand(new ReloadCommand()); system.addCommand(new FolderCommand()); system.addCommand(new ProfileCommand()); diff --git a/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/CraftCmd.java b/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/CraftCmd.java deleted file mode 100644 index 495ab583..00000000 --- a/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/CraftCmd.java +++ /dev/null @@ -1,63 +0,0 @@ -package io.github.itzispyder.clickcrystals.modules.scripts.macros; - -import io.github.itzispyder.clickcrystals.client.clickscript.ScriptArgs; -import io.github.itzispyder.clickcrystals.client.clickscript.ScriptCommand; -import io.github.itzispyder.clickcrystals.client.clickscript.ScriptParser; -import io.github.itzispyder.clickcrystals.modules.scripts.TargetType; -import io.github.itzispyder.clickcrystals.modules.scripts.ThenChainable; -import io.github.itzispyder.clickcrystals.util.minecraft.PlayerUtils; -import io.github.itzispyder.clickcrystals.util.minecraft.VectorParser; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.CraftingTableBlock; -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.entity.Entity; -import net.minecraft.screen.CraftingScreenHandler; -import net.minecraft.screen.slot.SlotActionType; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec3d; - -import java.util.function.Predicate; - -public class CraftCmd extends ScriptCommand implements ThenChainable { - - public CraftCmd() { - super("craft"); - } - - @Override - public void onCommand(ScriptCommand command, String line, ScriptArgs args) { - if (mc.interactionManager == null) { - return; - } - Predicate filter = ScriptParser.parseBlockPredicate(args.get(0).toString()); - PlayerUtils.runOnNearestBlock(32, filter, (pos, state) -> { - Vec3d vector = PlayerUtils.getEyes().subtract(pos.toCenterPos()); - Direction face = Direction.getFacing(vector); - BlockHitResult hit = new BlockHitResult(pos.toCenterPos(), face, pos, false); - ActionResult e = mc.interactionManager.interactBlock(mc.player, Hand.MAIN_HAND, hit); - if (PlayerUtils.getWorld().getBlockState(hit.getBlockPos()).isOf(Blocks.CRAFTING_TABLE)){ - if (mc.currentScreen instanceof HandledScreen screen && - screen.getScreenHandler() instanceof CraftingScreenHandler handler) { - System.out.println("E"); - mc.interactionManager.clickSlot( - handler.syncId, - 2, - 1, - SlotActionType.PICKUP, - mc.player - ); - } - } - }); - executeWithThen(args, 2); - - if (args.match(1, "then")) { - args.executeAll(2); - } - } -} \ No newline at end of file diff --git a/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftCmd.java b/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftCmd.java new file mode 100644 index 00000000..fca9f671 --- /dev/null +++ b/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftCmd.java @@ -0,0 +1,31 @@ +package io.github.itzispyder.clickcrystals.scripting.syntax.macros.inventory; + +import io.github.itzispyder.clickcrystals.scripting.ScriptArgs; +import io.github.itzispyder.clickcrystals.scripting.ScriptCommand; +import io.github.itzispyder.clickcrystals.scripting.syntax.ThenChainable; +import io.github.itzispyder.clickcrystals.util.minecraft.InvUtils; +import net.minecraft.client.gui.screens.inventory.CraftingScreen; +import net.minecraft.world.inventory.AbstractContainerMenu; + +// @Format craft 1 2 3 4 5 6 7 8 9 +// You need to be in a crafting table actually use it +public class CraftCmd extends ScriptCommand implements ThenChainable { + public CraftCmd() { + super("craft"); + } + + @Override + public void onCommand(ScriptCommand command, String line, ScriptArgs args) { + if (mc.gameMode == null || mc.player == null) + return; + + + AbstractContainerMenu menu = mc.player.containerMenu; + if (mc.screen instanceof CraftingScreen screen) { + InvUtils.craftCCS(menu, args, 9); + } + executeWithThen(args, 9); + } +} + +// sum mf said "i dont like crafting mods" - Server Owners probably \ No newline at end of file diff --git a/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java b/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java new file mode 100644 index 00000000..d27a0c20 --- /dev/null +++ b/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java @@ -0,0 +1,30 @@ +package io.github.itzispyder.clickcrystals.scripting.syntax.macros.inventory; + +import io.github.itzispyder.clickcrystals.scripting.ScriptArgs; +import io.github.itzispyder.clickcrystals.scripting.ScriptCommand; +import io.github.itzispyder.clickcrystals.scripting.syntax.ThenChainable; +import io.github.itzispyder.clickcrystals.util.minecraft.InvUtils; +import net.minecraft.client.gui.screens.inventory.CraftingScreen; +import net.minecraft.world.inventory.AbstractContainerMenu; + +// @Format craft 1 2 3 4 +// You DONT need to be in a crafting table actually use it +public class CraftInvCmd extends ScriptCommand implements ThenChainable { + public CraftInvCmd() { + super("craft_inv"); + } + + @Override + public void onCommand(ScriptCommand command, String line, ScriptArgs args) { + if (mc.gameMode == null || mc.player == null) + return; + if (!(mc.screen instanceof CraftingScreen screen)){ // cuz then it starts goofing around when you have both in same script + AbstractContainerMenu menu = mc.player.containerMenu; + InvUtils.craftCCS(menu, args, 4); + } + + + + executeWithThen(args, 9); + } +} diff --git a/src/main/java/io/github/itzispyder/clickcrystals/util/minecraft/InvUtils.java b/src/main/java/io/github/itzispyder/clickcrystals/util/minecraft/InvUtils.java index 932f269d..14d0d135 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/util/minecraft/InvUtils.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/util/minecraft/InvUtils.java @@ -1,13 +1,17 @@ package io.github.itzispyder.clickcrystals.util.minecraft; import io.github.itzispyder.clickcrystals.Global; +import io.github.itzispyder.clickcrystals.scripting.ScriptArgs; +import io.github.itzispyder.clickcrystals.scripting.ScriptParser; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import net.minecraft.network.HashedStack; import net.minecraft.network.protocol.game.ServerboundContainerClickPacket; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.ContainerInput; +import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -177,4 +181,44 @@ public static boolean sendSlotPacket(int slot, int button, ContainerInput action PlayerUtils.sendPacket(swap); return true; } + + public static void craftCCS(AbstractContainerMenu menu, ScriptArgs args, int gridSize){ + for (int i = 0; i < gridSize; i++) { + Predicate item = ScriptParser.parseItemPredicate(args.get(i).toString()); + + for (Slot slot : menu.slots) { + if (slot.index < 10) continue; + ItemStack stack = slot.getItem(); + + if (item.test(stack)) { + if (!menu.getCarried().isEmpty()) { + return; + } + + int from = slot.index; + + mc.gameMode.handleContainerInput(menu.containerId, from, 0, ContainerInput.PICKUP, mc.player); + mc.gameMode.handleContainerInput(menu.containerId, i+1, 1, ContainerInput.PICKUP, mc.player); + mc.gameMode.handleContainerInput(menu.containerId, from, 0, ContainerInput.PICKUP, mc.player); + + break; + } + } + } + + new Thread(() -> { + try { + Thread.sleep(100); // if your ping is over this, fuck you + mc.execute(() -> { + mc.gameMode.handleContainerInput( + menu.containerId, + 0, + 0, + ContainerInput.QUICK_MOVE, + mc.player + ); + }); + } catch (Exception ignored) {} + }).start(); + } } \ No newline at end of file From b5c3f5d61f151067f6fecdb1331295f406b4325a Mon Sep 17 00:00:00 2001 From: TutlaMC Date: Wed, 6 May 2026 23:07:16 +0530 Subject: [PATCH 3/9] format fix --- .../scripting/syntax/macros/inventory/CraftInvCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java b/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java index d27a0c20..8700a291 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java @@ -7,7 +7,7 @@ import net.minecraft.client.gui.screens.inventory.CraftingScreen; import net.minecraft.world.inventory.AbstractContainerMenu; -// @Format craft 1 2 3 4 +// @Format craft_inv 1 2 3 4 // You DONT need to be in a crafting table actually use it public class CraftInvCmd extends ScriptCommand implements ThenChainable { public CraftInvCmd() { From cda1622ebaced8491a46a680821e7ab18463af4a Mon Sep 17 00:00:00 2001 From: TutlaMC Date: Wed, 6 May 2026 23:52:17 +0530 Subject: [PATCH 4/9] goofy fix before i break everything --- gradle.properties | 2 +- .../textfield/TextFieldChange.java | 3 ++ .../textfield/TextFieldChangeType.java | 9 ++++++ .../{ => textfield}/TextFieldElement.java | 31 +++++++++++++++++-- .../gui/screens/scripts/ClickScriptIDE.java | 2 +- 5 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChange.java create mode 100644 src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChangeType.java rename src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/{ => textfield}/TextFieldElement.java (92%) diff --git a/gradle.properties b/gradle.properties index ffee144b..5bf4a07e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx1G -org.gradle.java.home=/Program Files/java/jdk-25.0.2 +org.gradle.java.home=/usr/lib/jvm/java-21-openjdk # Fabric Properties # check these on https://fabricmc.net/develop/ diff --git a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChange.java b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChange.java new file mode 100644 index 00000000..7f65c8fc --- /dev/null +++ b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChange.java @@ -0,0 +1,3 @@ +package io.github.itzispyder.clickcrystals.gui.elements.common.interactive.textfield; + +public record TextFieldChange(TextFieldChangeType type, String content, int cursor) {} \ No newline at end of file diff --git a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChangeType.java b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChangeType.java new file mode 100644 index 00000000..40880c3e --- /dev/null +++ b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChangeType.java @@ -0,0 +1,9 @@ +package io.github.itzispyder.clickcrystals.gui.elements.common.interactive.textfield; + +public enum TextFieldChangeType { + ADD, + REMOVE, + REMOVE_ALL, + UNDO, + REDO +} diff --git a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/TextFieldElement.java b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldElement.java similarity index 92% rename from src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/TextFieldElement.java rename to src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldElement.java index a28efcdc..fe0c9b13 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/TextFieldElement.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldElement.java @@ -1,8 +1,9 @@ -package io.github.itzispyder.clickcrystals.gui.elements.common.interactive; +package io.github.itzispyder.clickcrystals.gui.elements.common.interactive.textfield; import io.github.itzispyder.clickcrystals.gui.GuiElement; import io.github.itzispyder.clickcrystals.gui.GuiScreen; import io.github.itzispyder.clickcrystals.gui.elements.common.Typeable; +import io.github.itzispyder.clickcrystals.gui.elements.common.interactive.ScrollPanelElement; import io.github.itzispyder.clickcrystals.gui.misc.ChatColor; import io.github.itzispyder.clickcrystals.util.MathUtils; import io.github.itzispyder.clickcrystals.util.StringUtils; @@ -15,7 +16,9 @@ import org.lwjgl.glfw.GLFW; import java.awt.*; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Deque; import java.util.List; import java.util.function.Function; import java.util.function.Predicate; @@ -33,6 +36,10 @@ public class TextFieldElement extends GuiElement implements Typeable { private boolean selectionBlinking, selectedAll; private int selectionBlink; + private final Deque history = new ArrayDeque<>(); + private long lastEditTime = 0; + private final long historyInterval = 600; + public TextFieldElement(String preText, int x, int y, int width, int height) { super(x, y, width, height); this.selectedStartPoint = new Point(); @@ -129,6 +136,7 @@ else if (key == GLFW.GLFW_KEY_A && screen.ctrlKeyPressed) { return true; } else if (key == GLFW.GLFW_KEY_BACKSPACE) { + pushHistory(TextFieldChangeType.REMOVE); onInput(currentContent -> selectionStart > 0 && !currentContent.isEmpty() ? currentContent.substring(0, selectionStart - 1) + currentContent.substring(selectionStart) : currentContent); @@ -136,12 +144,16 @@ else if (key == GLFW.GLFW_KEY_BACKSPACE) { return true; } else if (key == GLFW.GLFW_KEY_DELETE) { + pushHistory(TextFieldChangeType.REMOVE); onInput(input -> StringUtils.insertString(content, selectionStart + 1, null)); return true; } else if (key == GLFW.GLFW_KEY_V && screen.ctrlKeyPressed) { - onInput(input -> insertInput(mc.keyboardHandler.getClipboard())); - shiftRight(); + String content = mc.keyboardHandler.getClipboard(); + onInput(input -> insertInput(content)); + for (int i = 0; i <= content.length()-1; i++){ + shiftRight(); + } return true; } else if (key == GLFW.GLFW_KEY_C && screen.ctrlKeyPressed && selectedAll) { @@ -175,6 +187,18 @@ else if (key == GLFW.GLFW_KEY_DOWN) { return false; } + private void pushHistory(TextFieldChangeType type) { + long now = System.currentTimeMillis(); + boolean expired = now - lastEditTime > historyInterval; + boolean typeChanged = !history.isEmpty() && history.peekLast().type() != type; + + if (expired || typeChanged) { + history.add(new TextFieldChange(type, content, selectionStart)); + } + + lastEditTime = now; + } + @Override public void mouseClicked(double mouseX, double mouseY, int button) { super.mouseClicked(mouseX, mouseY, button); @@ -406,4 +430,5 @@ public Pair process(String str) { } } } + } diff --git a/src/main/java/io/github/itzispyder/clickcrystals/gui/screens/scripts/ClickScriptIDE.java b/src/main/java/io/github/itzispyder/clickcrystals/gui/screens/scripts/ClickScriptIDE.java index 08eb16ac..04522612 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/gui/screens/scripts/ClickScriptIDE.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/gui/screens/scripts/ClickScriptIDE.java @@ -5,7 +5,7 @@ import io.github.itzispyder.clickcrystals.events.listeners.UserInputListener; import io.github.itzispyder.clickcrystals.gui.elements.common.AbstractElement; import io.github.itzispyder.clickcrystals.gui.elements.common.display.LoadingIconElement; -import io.github.itzispyder.clickcrystals.gui.elements.common.interactive.TextFieldElement; +import io.github.itzispyder.clickcrystals.gui.elements.common.interactive.textfield.TextFieldElement; import io.github.itzispyder.clickcrystals.gui.misc.ChatColor; import io.github.itzispyder.clickcrystals.gui.misc.Shades; import io.github.itzispyder.clickcrystals.gui.misc.Tex; From e94270f8e8112a155f1a2f2df383087501eff185 Mon Sep 17 00:00:00 2001 From: TutlaMC Date: Thu, 7 May 2026 00:06:23 +0530 Subject: [PATCH 5/9] undo/redo bs --- .../textfield/TextFieldElement.java | 51 ++++++++++++++----- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldElement.java b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldElement.java index fe0c9b13..adc4a6cc 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldElement.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldElement.java @@ -36,9 +36,9 @@ public class TextFieldElement extends GuiElement implements Typeable { private boolean selectionBlinking, selectedAll; private int selectionBlink; - private final Deque history = new ArrayDeque<>(); - private long lastEditTime = 0; - private final long historyInterval = 600; + private final List history = new ArrayList<>(); + private int historyIndex = -1; + public TextFieldElement(String preText, int x, int y, int width, int height) { super(x, y, width, height); @@ -58,6 +58,7 @@ public void onChar(char chr) { if (Character.isISOControl(chr)) { return; } + pushHistory(); onInput(input -> insertInput(String.valueOf(chr))); shiftRight(); } @@ -136,7 +137,7 @@ else if (key == GLFW.GLFW_KEY_A && screen.ctrlKeyPressed) { return true; } else if (key == GLFW.GLFW_KEY_BACKSPACE) { - pushHistory(TextFieldChangeType.REMOVE); + pushHistory(); onInput(currentContent -> selectionStart > 0 && !currentContent.isEmpty() ? currentContent.substring(0, selectionStart - 1) + currentContent.substring(selectionStart) : currentContent); @@ -144,11 +145,12 @@ else if (key == GLFW.GLFW_KEY_BACKSPACE) { return true; } else if (key == GLFW.GLFW_KEY_DELETE) { - pushHistory(TextFieldChangeType.REMOVE); + pushHistory(); onInput(input -> StringUtils.insertString(content, selectionStart + 1, null)); return true; } else if (key == GLFW.GLFW_KEY_V && screen.ctrlKeyPressed) { + pushHistory(); String content = mc.keyboardHandler.getClipboard(); onInput(input -> insertInput(content)); for (int i = 0; i <= content.length()-1; i++){ @@ -161,6 +163,7 @@ else if (key == GLFW.GLFW_KEY_C && screen.ctrlKeyPressed && selectedAll) { return true; } else if (key == GLFW.GLFW_KEY_ENTER) { + pushHistory(); onInput(input -> insertInput("\n")); shiftRight(); shiftRight(); @@ -183,20 +186,42 @@ else if (key == GLFW.GLFW_KEY_DOWN) { for (int i = 0; i < 10; i++) shiftRight(); return true; + } else if (key == GLFW.GLFW_KEY_Z && screen.ctrlKeyPressed) { + undo(); + return true; + } + else if (key == GLFW.GLFW_KEY_Y && screen.ctrlKeyPressed) { + redo(); + return true; } return false; } - private void pushHistory(TextFieldChangeType type) { - long now = System.currentTimeMillis(); - boolean expired = now - lastEditTime > historyInterval; - boolean typeChanged = !history.isEmpty() && history.peekLast().type() != type; + private void undo() { + if (historyIndex < 0) return; + historyIndex--; + content = historyIndex >= 0 ? history.get(historyIndex) : ""; + styledContent = style(content); + updateSelection(); + } + + private void redo() { + if (historyIndex >= history.size() - 1) return; + historyIndex++; + content = history.get(historyIndex); + styledContent = style(content); + updateSelection(); + } - if (expired || typeChanged) { - history.add(new TextFieldChange(type, content, selectionStart)); + private void pushHistory() { + history.subList(historyIndex + 1, history.size()).clear(); + history.add(content); + if (history.size() > 667) { // so it doesnt eat memory (unless your script has like 100k lines dw) + history.remove(0); + historyIndex = history.size() - 1; + } else { + historyIndex = history.size() - 1; } - - lastEditTime = now; } @Override From 496dfd6b0c6ac515a6d57408e36d9bbcdc8d82da Mon Sep 17 00:00:00 2001 From: TutlaMC Date: Thu, 7 May 2026 00:06:44 +0530 Subject: [PATCH 6/9] refactor --- .../interactive/{textfield => }/TextFieldElement.java | 5 +---- .../common/interactive/textfield/TextFieldChange.java | 3 --- .../interactive/textfield/TextFieldChangeType.java | 9 --------- .../gui/screens/scripts/ClickScriptIDE.java | 2 +- 4 files changed, 2 insertions(+), 17 deletions(-) rename src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/{textfield => }/TextFieldElement.java (98%) delete mode 100644 src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChange.java delete mode 100644 src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChangeType.java diff --git a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldElement.java b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/TextFieldElement.java similarity index 98% rename from src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldElement.java rename to src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/TextFieldElement.java index adc4a6cc..c3806358 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldElement.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/TextFieldElement.java @@ -1,9 +1,8 @@ -package io.github.itzispyder.clickcrystals.gui.elements.common.interactive.textfield; +package io.github.itzispyder.clickcrystals.gui.elements.common.interactive; import io.github.itzispyder.clickcrystals.gui.GuiElement; import io.github.itzispyder.clickcrystals.gui.GuiScreen; import io.github.itzispyder.clickcrystals.gui.elements.common.Typeable; -import io.github.itzispyder.clickcrystals.gui.elements.common.interactive.ScrollPanelElement; import io.github.itzispyder.clickcrystals.gui.misc.ChatColor; import io.github.itzispyder.clickcrystals.util.MathUtils; import io.github.itzispyder.clickcrystals.util.StringUtils; @@ -16,9 +15,7 @@ import org.lwjgl.glfw.GLFW; import java.awt.*; -import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Deque; import java.util.List; import java.util.function.Function; import java.util.function.Predicate; diff --git a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChange.java b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChange.java deleted file mode 100644 index 7f65c8fc..00000000 --- a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChange.java +++ /dev/null @@ -1,3 +0,0 @@ -package io.github.itzispyder.clickcrystals.gui.elements.common.interactive.textfield; - -public record TextFieldChange(TextFieldChangeType type, String content, int cursor) {} \ No newline at end of file diff --git a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChangeType.java b/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChangeType.java deleted file mode 100644 index 40880c3e..00000000 --- a/src/main/java/io/github/itzispyder/clickcrystals/gui/elements/common/interactive/textfield/TextFieldChangeType.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.itzispyder.clickcrystals.gui.elements.common.interactive.textfield; - -public enum TextFieldChangeType { - ADD, - REMOVE, - REMOVE_ALL, - UNDO, - REDO -} diff --git a/src/main/java/io/github/itzispyder/clickcrystals/gui/screens/scripts/ClickScriptIDE.java b/src/main/java/io/github/itzispyder/clickcrystals/gui/screens/scripts/ClickScriptIDE.java index 04522612..08eb16ac 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/gui/screens/scripts/ClickScriptIDE.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/gui/screens/scripts/ClickScriptIDE.java @@ -5,7 +5,7 @@ import io.github.itzispyder.clickcrystals.events.listeners.UserInputListener; import io.github.itzispyder.clickcrystals.gui.elements.common.AbstractElement; import io.github.itzispyder.clickcrystals.gui.elements.common.display.LoadingIconElement; -import io.github.itzispyder.clickcrystals.gui.elements.common.interactive.textfield.TextFieldElement; +import io.github.itzispyder.clickcrystals.gui.elements.common.interactive.TextFieldElement; import io.github.itzispyder.clickcrystals.gui.misc.ChatColor; import io.github.itzispyder.clickcrystals.gui.misc.Shades; import io.github.itzispyder.clickcrystals.gui.misc.Tex; From 446faab46d52869265e6642471d09e21db641102 Mon Sep 17 00:00:00 2001 From: TutlaMC Date: Thu, 7 May 2026 00:40:41 +0530 Subject: [PATCH 7/9] mb --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 5bf4a07e..ffee144b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx1G -org.gradle.java.home=/usr/lib/jvm/java-21-openjdk +org.gradle.java.home=/Program Files/java/jdk-25.0.2 # Fabric Properties # check these on https://fabricmc.net/develop/ From 70c10ad2c29438df6bcfe911f0d13112f6532ec4 Mon Sep 17 00:00:00 2001 From: TutlaMC Date: Fri, 8 May 2026 01:33:14 +0530 Subject: [PATCH 8/9] mb (again) --- .../java/io/github/itzispyder/clickcrystals/ClickCrystals.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java b/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java index b490888c..71ab1b93 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/ClickCrystals.java @@ -248,6 +248,7 @@ public void init() { system.addCommand(new KeybindsCommand()); system.addCommand(new RotateCommand()); system.addCommand(new LookCommand()); + system.addCommand(new ScriptCommand()); system.addCommand(new ReloadCommand()); system.addCommand(new FolderCommand()); system.addCommand(new ProfileCommand()); From 50236076363c0252cf1eb34a36c9b30c37648f89 Mon Sep 17 00:00:00 2001 From: TutlaMC Date: Fri, 8 May 2026 01:35:20 +0530 Subject: [PATCH 9/9] another bug fix --- .../scripting/syntax/macros/inventory/CraftInvCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java b/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java index 8700a291..9d737b26 100644 --- a/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java +++ b/src/main/java/io/github/itzispyder/clickcrystals/scripting/syntax/macros/inventory/CraftInvCmd.java @@ -25,6 +25,6 @@ public void onCommand(ScriptCommand command, String line, ScriptArgs args) { - executeWithThen(args, 9); + executeWithThen(args, 4); } }