From 0e6d34f816a7cdef12f90ef16417d030a4f515a0 Mon Sep 17 00:00:00 2001 From: sectersion Date: Sun, 11 Oct 2026 16:41:36 +0100 Subject: [PATCH] Refactor: extract MacroLifecycle from MacroExecutor (upstream #4) Move 56 run-lifecycle methods (flow control, step overrides, client resources, run-list management, execute/track/stop) verbatim into MacroLifecycle. The public lifecycle API stays reachable via MacroExecutor delegates; all 150+ cross-helper call sites re-pointed. All bodies verified identical against HEAD modulo mechanical MacroExecutor./MacroLifecycle. qualification. --- .../util/macro/MacroActionRunner.java | 54 +- .../autismclient/util/macro/MacroBreak.java | 30 +- .../util/macro/MacroCaptureAutofill.java | 40 +- .../util/macro/MacroChatObserve.java | 4 +- .../util/macro/MacroClientThread.java | 10 +- .../util/macro/MacroDispatcher.java | 130 ++-- .../util/macro/MacroDurability.java | 2 +- .../util/macro/MacroExecutor.java | 651 ++---------------- .../util/macro/MacroLifecycle.java | 623 +++++++++++++++++ .../util/macro/MacroPacketObserve.java | 6 +- .../util/macro/MacroPacketWait.java | 4 +- .../autismclient/util/macro/MacroPrearm.java | 8 +- .../autismclient/util/macro/MacroRace.java | 68 +- .../autismclient/util/macro/MacroRender.java | 4 +- .../autismclient/util/macro/MacroRunLoop.java | 250 +++---- .../util/macro/MacroVariables.java | 2 +- .../util/macro/MacroWorldActions.java | 62 +- .../autismclient/util/macro/MacroXCarry.java | 34 +- 18 files changed, 1025 insertions(+), 957 deletions(-) create mode 100644 src/main/java/autismclient/util/macro/MacroLifecycle.java diff --git a/src/main/java/autismclient/util/macro/MacroActionRunner.java b/src/main/java/autismclient/util/macro/MacroActionRunner.java index e0f9a3e..413ab8d 100644 --- a/src/main/java/autismclient/util/macro/MacroActionRunner.java +++ b/src/main/java/autismclient/util/macro/MacroActionRunner.java @@ -75,8 +75,8 @@ final class MacroActionRunner { return postGuiFuture; } - MacroExecutor.setCurrentStatus("Waiting target: " + action.getDisplayName()); - while (MacroExecutor.isCurrentRunActive()) { + MacroLifecycle.setCurrentStatus("Waiting target: " + action.getDisplayName()); + while (MacroLifecycle.isCurrentRunActive()) { if (!canRunTargetInteractionNow(mc, action)) { java.util.concurrent.locks.LockSupport.parkNanos(MacroExecutor.MACRO_WAIT_POLL_NANOS); if (Thread.interrupted()) throw new InterruptedException(); @@ -172,7 +172,7 @@ final class MacroActionRunner { private static void waitForCurrentGuiReady(Minecraft mc) throws InterruptedException { long deadline = System.nanoTime() + 500_000_000L; - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { Boolean ready = MacroClientThread.callOnClientThread(mc, () -> { if (mc.player == null || mc.gui.screen() == null) return false; if (mc.player.containerMenu != null && mc.player.containerMenu != mc.player.inventoryMenu) { @@ -206,17 +206,17 @@ final class MacroActionRunner { } public static void runItemActionPaced(Minecraft mc, ItemAction ia) throws InterruptedException { - MacroExecutor.setCurrentStatus(ia.getDisplayName()); + MacroLifecycle.setCurrentStatus(ia.getDisplayName()); java.util.List plan = MacroClientThread.callOnClientThread(mc, () -> ia.buildClickPlan(mc), java.util.Collections.emptyList()); if (plan == null || plan.isEmpty()) return; long delayMs = Math.max(0, ia.clickDelayMs); MacroExecutor.RunState scheduledRun = MacroExecutor.CURRENT_RUN.get(); boolean first = true; for (Runnable op : plan) { - if (!MacroExecutor.isCurrentRunActive()) break; + if (!MacroLifecycle.isCurrentRunActive()) break; if (!first && delayMs > 0) Thread.sleep(delayMs); first = false; - mc.execute(() -> MacroExecutor.withRunContext(scheduledRun, () -> { + mc.execute(() -> MacroLifecycle.withRunContext(scheduledRun, () -> { if (PackHideState.isHardLocked()) return; try { op.run(); @@ -260,7 +260,7 @@ final class MacroActionRunner { @Override public void runOnClientThread(Runnable r) { if (r == null) return; - Runnable safe = () -> MacroExecutor.withRunContext(run, () -> { + Runnable safe = () -> MacroLifecycle.withRunContext(run, () -> { try { r.run(); } catch (Throwable t) { AutismClientMessaging.sendPrefixed("\u00a7cAddon action (client task) error: " + (t.getMessage() == null ? t.getClass().getSimpleName() : t.getMessage())); } }); @@ -272,7 +272,7 @@ final class MacroActionRunner { if (s == null) return null; java.util.function.Supplier safe = () -> { AtomicReference value = new AtomicReference<>(); - MacroExecutor.withRunContext(run, () -> { + MacroLifecycle.withRunContext(run, () -> { try { value.set(s.get()); } catch (Throwable t) { AutismClientMessaging.sendPrefixed("\u00a7cAddon action (client task) error: " + (t.getMessage() == null ? t.getClass().getSimpleName() : t.getMessage())); } }); @@ -283,24 +283,24 @@ final class MacroActionRunner { } @Override public void waitTicks(int ticks) { - MacroExecutor.withRunContext(run, () -> { - for (int i = 0; i < ticks && MacroExecutor.isCurrentRunActive(); i++) { + MacroLifecycle.withRunContext(run, () -> { + for (int i = 0; i < ticks && MacroLifecycle.isCurrentRunActive(); i++) { MacroRunLoop.waitForCondition(MacroConditionRegistry.waitForNextTick()); } }); } @Override public void awaitCondition(CompletableFuture future) { - if (future != null) MacroExecutor.withRunContext(run, () -> MacroRunLoop.waitForCondition(future)); + if (future != null) MacroLifecycle.withRunContext(run, () -> MacroRunLoop.waitForCondition(future)); } @Override public void awaitCondition(autismclient.api.macro.AddonCondition condition) { - if (condition != null) MacroExecutor.withRunContext(run, () -> MacroRunLoop.waitForCondition(MacroConditionRegistry.await(condition))); + if (condition != null) MacroLifecycle.withRunContext(run, () -> MacroRunLoop.waitForCondition(MacroConditionRegistry.await(condition))); } @Override public boolean isActive() { return run != null && run.running.get() && !PackHideState.isHardLocked(); } - @Override public void setStatus(String status) { MacroExecutor.withRunContext(run, () -> MacroExecutor.setCurrentStatus(status)); } + @Override public void setStatus(String status) { MacroLifecycle.withRunContext(run, () -> MacroLifecycle.setCurrentStatus(status)); } @Override public void sendPacket(net.minecraft.network.protocol.Packet packet) { if (packet == null) return; @@ -333,7 +333,7 @@ final class MacroActionRunner { public static void runUseItemPhaseAction(Minecraft mc, UseItemPhaseAction action) throws InterruptedException { int times = action.repeatTimes(); - for (int i = 0; i < times && MacroExecutor.isCurrentRunActive(); i++) { + for (int i = 0; i < times && MacroLifecycle.isCurrentRunActive(); i++) { MacroClientThread.runOnClientThread(mc, () -> { try { action.sendUsePacket(mc); } @@ -349,7 +349,7 @@ final class MacroActionRunner { } try { - for (int t = 0; t < action.holdTicks && MacroExecutor.isCurrentRunActive(); t++) { + for (int t = 0; t < action.holdTicks && MacroLifecycle.isCurrentRunActive(); t++) { CompletableFuture tf = MacroConditionRegistry.waitForNextTick(); MacroRunLoop.waitForCondition(tf); } @@ -363,7 +363,7 @@ final class MacroActionRunner { } } } - if (!MacroExecutor.isCurrentRunActive()) break; + if (!MacroLifecycle.isCurrentRunActive()) break; MacroClientThread.runOnClientThread(mc, () -> { try { action.finishRelease(mc); } @@ -376,7 +376,7 @@ final class MacroActionRunner { int times = Math.max(1, action.clickCount); MacroClientThread.runOnClientThread(mc, () -> { - for (int c = 0; c < times && MacroExecutor.isCurrentRunActive(); c++) { + for (int c = 0; c < times && MacroLifecycle.isCurrentRunActive(); c++) { try { action.execute(mc); } catch (Exception e) { @@ -407,7 +407,7 @@ final class MacroActionRunner { } List slots = MacroClientThread.callOnClientThread(mc, () -> action.collectTransferSlots(mc), List.of()); - for (int i = 0; i < slots.size() && MacroExecutor.isCurrentRunActive(); i++) { + for (int i = 0; i < slots.size() && MacroLifecycle.isCurrentRunActive(); i++) { AutismInventoryClickHelper.click(mc, slots.get(i), 0, net.minecraft.world.inventory.ContainerInput.QUICK_MOVE); if (i + 1 < slots.size()) waitTicks(delayTicks); } @@ -418,7 +418,7 @@ final class MacroActionRunner { } private static void waitTicks(int ticks) { - for (int i = 0; i < ticks && MacroExecutor.isCurrentRunActive(); i++) { + for (int i = 0; i < ticks && MacroLifecycle.isCurrentRunActive(); i++) { CompletableFuture tickFuture = MacroConditionRegistry.waitForNextTick(); MacroRunLoop.waitForCondition(tickFuture); } @@ -439,7 +439,7 @@ final class MacroActionRunner { }, action.isTickAligned()); if (action.holdTicks > 0) { waitTicks(action.holdTicks); - if (!MacroExecutor.isCurrentRunActive()) return; + if (!MacroLifecycle.isCurrentRunActive()) return; MacroClientThread.runOnClientThread(mc, () -> { try { action.sendRelease(mc); } catch (Exception e) { AutismClientMessaging.sendPrefixed("\u00a7cError in UseItem release: " + e.getMessage()); } @@ -450,7 +450,7 @@ final class MacroActionRunner { } int times = Math.max(1, action.useCount); - for (int i = 0; i < times && MacroExecutor.isCurrentRunActive(); i++) { + for (int i = 0; i < times && MacroLifecycle.isCurrentRunActive(); i++) { MacroClientThread.runOnClientThread(mc, () -> { try { if (sneaking) autismclient.util.AutismMacroSneak.forceSneak(mc, true); @@ -459,7 +459,7 @@ final class MacroActionRunner { catch (Exception e) { AutismClientMessaging.sendPrefixed("\u00a7cError in UseItem: " + e.getMessage()); } }, action.isTickAligned()); if (action.waitForFinish) waitForUseItemFinish(mc, 0); - if (i + 1 < times && MacroExecutor.isCurrentRunActive()) MacroExecutor.waitOneTick(); + if (i + 1 < times && MacroLifecycle.isCurrentRunActive()) MacroExecutor.waitOneTick(); } } finally { if (sneaking) mc.execute(() -> autismclient.util.AutismMacroSneak.forceSneak(mc, false)); @@ -473,9 +473,9 @@ final class MacroActionRunner { int delay = Math.max(0, action.delayTicks); int total = repeats * slots.size(); int sent = 0; - for (int repeat = 0; repeat < repeats && MacroExecutor.isCurrentRunActive(); repeat++) { + for (int repeat = 0; repeat < repeats && MacroLifecycle.isCurrentRunActive(); repeat++) { for (int slot : slots) { - if (!MacroExecutor.isCurrentRunActive()) return; + if (!MacroLifecycle.isCurrentRunActive()) return; MacroClientThread.runOnClientThread(mc, () -> action.executeClick(mc, slot)); sent++; if (delay > 0 && sent < total) waitTicks(delay); @@ -488,14 +488,14 @@ final class MacroActionRunner { if (action.flushBefore) AutismSharedState.get().flushDelayedPackets(mc.getConnection()); int total = action.effectiveCount(); int delay = Math.max(0, action.delayTicks); - for (int i = 0; i < total && MacroExecutor.isCurrentRunActive(); i++) { + for (int i = 0; i < total && MacroLifecycle.isCurrentRunActive(); i++) { action.sendOne(mc); if (delay > 0 && i + 1 < total) waitTicks(delay); } } private static void waitForUseItemFinish(Minecraft mc, int fallbackTicks) throws InterruptedException { - if (mc == null || !MacroExecutor.isCurrentRunActive()) return; + if (mc == null || !MacroLifecycle.isCurrentRunActive()) return; if (!Boolean.TRUE.equals(MacroClientThread.callOnClientThread(mc, () -> mc.player != null && mc.player.isUsingItem(), @@ -508,7 +508,7 @@ final class MacroActionRunner { 0); int maxTicks = Math.max(8, remaining > 0 ? remaining + 8 : fallbackTicks + 8); maxTicks = Math.min(maxTicks, 72000); - for (int i = 0; i < maxTicks && MacroExecutor.isCurrentRunActive(); i++) { + for (int i = 0; i < maxTicks && MacroLifecycle.isCurrentRunActive(); i++) { if (!Boolean.TRUE.equals(MacroClientThread.callOnClientThread(mc, () -> mc.player != null && mc.player.isUsingItem(), Boolean.FALSE))) { diff --git a/src/main/java/autismclient/util/macro/MacroBreak.java b/src/main/java/autismclient/util/macro/MacroBreak.java index 0edf3de..f296c51 100644 --- a/src/main/java/autismclient/util/macro/MacroBreak.java +++ b/src/main/java/autismclient/util/macro/MacroBreak.java @@ -39,7 +39,7 @@ final class MacroBreak { try { long lastAttemptTick = AutismSharedState.get().getClientTickCounter() - (delayTicks + 1L); long lastSneakTick = Long.MIN_VALUE; - while (MacroExecutor.isCurrentRunActive() && isActionStillInCurrentMacro(action)) { + while (MacroLifecycle.isCurrentRunActive() && isActionStillInCurrentMacro(action)) { if (action.sneak) { long sneakTick = AutismSharedState.get().getClientTickCounter(); @@ -53,7 +53,7 @@ final class MacroBreak { boolean isAir = isInstaBreakAir(mc, target); if (wasSolid && isAir) { completed++; - MacroExecutor.setCurrentStatus("InstaBreak " + completed + "/" + (targetTimes == 0 ? "\u221e" : targetTimes)); + MacroLifecycle.setCurrentStatus("InstaBreak " + completed + "/" + (targetTimes == 0 ? "\u221e" : targetTimes)); if (targetTimes > 0 && completed >= targetTimes) return; wasSolid = false; } else if (!isAir) { @@ -91,7 +91,7 @@ final class MacroBreak { } } - MacroExecutor.setCurrentStatus("InstaBreak " + target.getX() + "," + target.getY() + "," + target.getZ() + MacroLifecycle.setCurrentStatus("InstaBreak " + target.getX() + "," + target.getY() + "," + target.getZ() + " " + completed + "/" + (targetTimes == 0 ? "\u221e" : targetTimes)); Thread.sleep(1); @@ -191,7 +191,7 @@ final class MacroBreak { AutismInstaBreakRenderer.setTarget(target); long lastTick = -1L; try { - while (MacroExecutor.isCurrentRunActive() && isActionStillInCurrentMacro(action)) { + while (MacroLifecycle.isCurrentRunActive() && isActionStillInCurrentMacro(action)) { long now = AutismSharedState.get().getClientTickCounter(); if (now == lastTick) { Thread.sleep(1); @@ -225,13 +225,13 @@ final class MacroBreak { MacroClientThread.runOnClientThread(mc, () -> sendBlockInteract(mc, target, direction), action.isTickAligned()); } completed++; - MacroExecutor.setCurrentStatus("Break " + completed + "/" + (targetTimes == 0 ? "\u221e" : targetTimes)); + MacroLifecycle.setCurrentStatus("Break " + completed + "/" + (targetTimes == 0 ? "\u221e" : targetTimes)); if (targetTimes > 0 && completed >= targetTimes) return; started[0] = false; nextStepsFired[0] = false; waitForBreakSolid(mc, target); } else { - MacroExecutor.setCurrentStatus("Break " + target.getX() + "," + target.getY() + "," + target.getZ() + MacroLifecycle.setCurrentStatus("Break " + target.getX() + "," + target.getY() + "," + target.getZ() + " " + completed + "/" + (targetTimes == 0 ? "\u221e" : targetTimes)); } } @@ -253,7 +253,7 @@ final class MacroBreak { if (plan.instant() && plan.interactFirst()) { runBreakNextStepsOnce(mc, action, nextStepsFired, missingNextStepsWarned); - if (!MacroExecutor.isCurrentRunActive()) return -1; + if (!MacroLifecycle.isCurrentRunActive()) return -1; } int result = MacroClientThread.callOnClientThread(mc, () -> startPreparedBreakOnClient(mc, action, pos, dir, started), -1, action.isTickAligned()); @@ -326,11 +326,11 @@ final class MacroBreak { InteractTiming timing = action.interactTiming; if (timing == InteractTiming.BEFORE && plan.breaksNextTick()) { runBreakNextStepsOnce(mc, action, nextStepsFired, missingNextStepsWarned); - if (!MacroExecutor.isCurrentRunActive()) return -1; + if (!MacroLifecycle.isCurrentRunActive()) return -1; } if (timing == InteractTiming.WITH && plan.breaksThisTick()) { runBreakNextStepsOnce(mc, action, nextStepsFired, missingNextStepsWarned); - if (!MacroExecutor.isCurrentRunActive()) return -1; + if (!MacroLifecycle.isCurrentRunActive()) return -1; } int result = MacroClientThread.callOnClientThread(mc, () -> continueBreakOnClient(mc, action, pos, dir), -1, action.isTickAligned()); @@ -396,7 +396,7 @@ final class MacroBreak { int broke; if (action.interactCustomMs < 0) { runBreakNextStepsOnce(mc, action, nextStepsFired, missingNextStepsWarned); - if (!MacroExecutor.isCurrentRunActive()) return -1; + if (!MacroLifecycle.isCurrentRunActive()) return -1; if (ns > 0) java.util.concurrent.locks.LockSupport.parkNanos(ns); broke = MacroClientThread.callOnClientThread(mc, () -> breakAndDetectOnClient(mc, pos, dir), -1, action.isTickAligned()); } else { @@ -475,13 +475,13 @@ final class MacroBreak { if (fired != null) fired[0] = true; action.markNextActionsRan(); String names = actions.size() == 1 ? actions.get(0).getDisplayName() : actions.size() + " steps"; - MacroExecutor.setCurrentStatus("Break: next " + names); + MacroLifecycle.setCurrentStatus("Break: next " + names); AutismModule module = AutismModule.get(); boolean previousSuppressPostGui = Boolean.TRUE.equals(MacroExecutor.SUPPRESS_POST_GUI_AFTER.get()); try { MacroExecutor.SUPPRESS_POST_GUI_AFTER.set(true); for (MacroAction next : actions) { - if (next == null || !next.isEnabled() || !MacroExecutor.isCurrentRunActive()) continue; + if (next == null || !next.isEnabled() || !MacroLifecycle.isCurrentRunActive()) continue; try { MacroDispatcher.executeSingleActionWithWaits(mc, next, module); } catch (InterruptedException e) { @@ -524,7 +524,7 @@ final class MacroBreak { } private static void waitForBreakSolid(Minecraft mc, BlockPos pos) throws InterruptedException { - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { if (!isInstaBreakAir(mc, pos)) return; Thread.sleep(1); } @@ -532,7 +532,7 @@ final class MacroBreak { private static void waitBreakClientTicks(int ticks) throws InterruptedException { long start = AutismSharedState.get().getClientTickCounter(); - while (MacroExecutor.isCurrentRunActive() && (AutismSharedState.get().getClientTickCounter() - start) < ticks) { + while (MacroLifecycle.isCurrentRunActive() && (AutismSharedState.get().getClientTickCounter() - start) < ticks) { Thread.sleep(1); } } @@ -543,6 +543,6 @@ final class MacroBreak { private static void releaseMacroSneak(Minecraft mc, String mode) { autismclient.util.AutismMacroSneak.release(mc, mode); - if (!autismclient.util.AutismMacroSneak.isPacket(mode)) MacroExecutor.applyAggregateSneakState(mc); + if (!autismclient.util.AutismMacroSneak.isPacket(mode)) MacroLifecycle.applyAggregateSneakState(mc); } } diff --git a/src/main/java/autismclient/util/macro/MacroCaptureAutofill.java b/src/main/java/autismclient/util/macro/MacroCaptureAutofill.java index dc3c500..0bc688c 100644 --- a/src/main/java/autismclient/util/macro/MacroCaptureAutofill.java +++ b/src/main/java/autismclient/util/macro/MacroCaptureAutofill.java @@ -172,11 +172,11 @@ final class MacroCaptureAutofill { if (action.autofillCacheList) { CachedSuggestions listCache = SUGGESTION_CACHE.get(query); if (listCache != null && listCache.connection() == connection && !listCache.suggestions().isEmpty()) { - MacroExecutor.setCurrentStatus("Using cached suggestions"); + MacroLifecycle.setCurrentStatus("Using cached suggestions"); applyCaptureSuggestions(run, action, listCache.suggestions(), query); return; } - MacroExecutor.setCurrentStatus("Sweeping command suggestions"); + MacroLifecycle.setCurrentStatus("Sweeping command suggestions"); java.util.List all = sweepAutofillCommand(connection, query); if (all.isEmpty()) return; if (SUGGESTION_CACHE.size() >= SUGGESTION_CACHE_MAX) SUGGESTION_CACHE.clear(); @@ -191,13 +191,13 @@ final class MacroCaptureAutofill { if (cached != null) { - MacroExecutor.setCurrentStatus("Using cached suggestions"); + MacroLifecycle.setCurrentStatus("Using cached suggestions"); applyCaptureSuggestions(run, action, capturePool(connection, action, query, cached.suggestions()), query); fireSuggestionFetch(connection, query, action.autofillTimeoutMs); return; } - MacroExecutor.setCurrentStatus("Requesting command suggestions"); + MacroLifecycle.setCurrentStatus("Requesting command suggestions"); PendingFetch pending = fireSuggestionFetch(connection, query, action.autofillTimeoutMs); if (pending == null) return; if (!MacroRace.waitForFutureDone(pending.future(), 0)) return; @@ -210,7 +210,7 @@ final class MacroCaptureAutofill { autismclient.util.AutismNameHarvest.Control control = new autismclient.util.AutismNameHarvest.Control() { @Override public boolean cancelled() { Minecraft mc = Minecraft.getInstance(); - return !MacroExecutor.isCurrentRunActive() || mc == null || mc.getConnection() != connection; + return !MacroLifecycle.isCurrentRunActive() || mc == null || mc.getConnection() != connection; } @Override public boolean paused() { return false; } @Override public int limit() { return MAX_SWEEP_NAMES; } @@ -230,11 +230,11 @@ final class MacroCaptureAutofill { String cacheKey = "namescrape"; CachedSuggestions cached = SUGGESTION_CACHE.get(cacheKey); if (cached != null && cached.connection() == connection && !cached.suggestions().isEmpty()) { - MacroExecutor.setCurrentStatus("Using cached names"); + MacroLifecycle.setCurrentStatus("Using cached names"); applyCaptureSuggestions(run, action, cached.suggestions(), ""); return; } - MacroExecutor.setCurrentStatus("Scraping player names"); + MacroLifecycle.setCurrentStatus("Scraping player names"); java.util.List names = scrapeAllNames(mc, connection); if (names.isEmpty()) return; if (SUGGESTION_CACHE.size() >= SUGGESTION_CACHE_MAX) SUGGESTION_CACHE.clear(); @@ -250,7 +250,7 @@ final class MacroCaptureAutofill { autismclient.util.AutismNameHarvest.Control control = new autismclient.util.AutismNameHarvest.Control() { @Override public boolean cancelled() { Minecraft m = Minecraft.getInstance(); - return !MacroExecutor.isCurrentRunActive() || m == null || m.getConnection() != connection; + return !MacroLifecycle.isCurrentRunActive() || m == null || m.getConnection() != connection; } @Override public boolean paused() { return false; } @Override public int limit() { return MAX_SWEEP_NAMES; } @@ -267,25 +267,25 @@ final class MacroCaptureAutofill { String modifierError = action.numberModifierError(); if (!modifierError.isBlank()) { - MacroExecutor.setCurrentStatus("Capture failed: " + modifierError); + MacroLifecycle.setCurrentStatus("Capture failed: " + modifierError); autismclient.util.AutismNotifications.error("Capture Value: " + modifierError); return; } if (action.source == CaptureValueAction.Source.COMMAND_AUTOFILL) { - MacroExecutor.setCurrentStatus("Requesting command suggestions"); + MacroLifecycle.setCurrentStatus("Requesting command suggestions"); runCaptureCommandAutofill(mc, action); reportMissingCapture(action); return; } if (action.source == CaptureValueAction.Source.NAMESCRAPE) { - MacroExecutor.setCurrentStatus("Scraping player names"); + MacroLifecycle.setCurrentStatus("Scraping player names"); runCaptureNamescrape(mc, action); reportMissingCapture(action); return; } if (action.waitForTrigger) { CaptureValueAction.Source source = action.source == null ? CaptureValueAction.Source.GUI_TITLE : action.source; - MacroExecutor.setCurrentStatus("Waiting for capture: " + source.name().toLowerCase(Locale.ROOT).replace('_', ' ')); + MacroLifecycle.setCurrentStatus("Waiting for capture: " + source.name().toLowerCase(Locale.ROOT).replace('_', ' ')); if (source == CaptureValueAction.Source.RECENT_CHAT) MacroPacketWait.awaitCaptureValueChat(action); else if (source == CaptureValueAction.Source.SCOREBOARD) awaitCaptureValueScoreboard(mc, action); else awaitCaptureValueState(mc, action); @@ -296,9 +296,9 @@ final class MacroCaptureAutofill { new java.util.concurrent.atomic.AtomicReference<>(CaptureValueAction.Preview.unavailable("Not available")); long deadline = System.nanoTime() + MacroExecutor.CAPTURE_SETTLE_MS * 1_000_000L; - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { CompletableFuture done = new CompletableFuture<>(); - mc.execute(() -> MacroExecutor.withRunContext(run, () -> { + mc.execute(() -> MacroLifecycle.withRunContext(run, () -> { try { result.set(action.run(mc)); done.complete(null); @@ -314,7 +314,7 @@ final class MacroCaptureAutofill { CaptureValueAction.Preview preview = result.get(); if (!preview.success()) { - MacroExecutor.setCurrentStatus("Capture failed: " + preview.message()); + MacroLifecycle.setCurrentStatus("Capture failed: " + preview.message()); autismclient.util.AutismNotifications.error( "Capture " + captureOutputLabel(action) + ": " + preview.message()); } @@ -323,7 +323,7 @@ final class MacroCaptureAutofill { private static void reportMissingCapture(CaptureValueAction action) { String name = MacroVariableContext.cleanRootName(action.saveAs); if (name.isBlank() || MacroVariables.value(name).isPresent()) return; - MacroExecutor.setCurrentStatus("Capture failed: nothing captured"); + MacroLifecycle.setCurrentStatus("Capture failed: nothing captured"); autismclient.util.AutismNotifications.error( "Capture " + captureOutputLabel(action) + ": nothing captured"); } @@ -337,7 +337,7 @@ final class MacroCaptureAutofill { MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); MacroPrearm.clearCaptureOutputs(action); String lastMessage = ""; - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { CaptureValueAction.Preview preview; try { preview = MacroClientThread.callOnClientThread(mc, () -> action.previewCurrent(mc), @@ -353,7 +353,7 @@ final class MacroCaptureAutofill { } if (!preview.message().isBlank() && !preview.message().equals(lastMessage)) { lastMessage = preview.message(); - MacroExecutor.setCurrentStatus("Capture waiting: " + lastMessage); + MacroLifecycle.setCurrentStatus("Capture waiting: " + lastMessage); } MacroExecutor.waitOneTick(); } @@ -368,7 +368,7 @@ final class MacroCaptureAutofill { String previousText = null; String lastMessage = ""; boolean baselineReady = false; - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { CaptureValueAction.ScoreboardLine line; try { String keySnapshot = trackedKey; @@ -397,7 +397,7 @@ final class MacroCaptureAutofill { } if (!preview.message().isBlank() && !preview.message().equals(lastMessage)) { lastMessage = preview.message(); - MacroExecutor.setCurrentStatus("Capture waiting: " + lastMessage); + MacroLifecycle.setCurrentStatus("Capture waiting: " + lastMessage); } previousText = currentText; } diff --git a/src/main/java/autismclient/util/macro/MacroChatObserve.java b/src/main/java/autismclient/util/macro/MacroChatObserve.java index 8e0144c..8ac23bf 100644 --- a/src/main/java/autismclient/util/macro/MacroChatObserve.java +++ b/src/main/java/autismclient/util/macro/MacroChatObserve.java @@ -122,11 +122,11 @@ final class MacroChatObserve { } private static boolean matchesChatAction(WaitForChatAction action, MacroExecutor.ChatCapture capture) { - return captureChatAction(action, capture, MacroExecutor.currentVariableContext()).isPresent(); + return captureChatAction(action, capture, MacroLifecycle.currentVariableContext()).isPresent(); } private static java.util.Optional> captureChatAction(WaitForChatAction action, MacroExecutor.ChatCapture capture) { - return captureChatAction(action, capture, MacroExecutor.currentVariableContext()); + return captureChatAction(action, capture, MacroLifecycle.currentVariableContext()); } public static java.util.Optional> captureChatAction(WaitForChatAction action, MacroExecutor.ChatCapture capture, diff --git a/src/main/java/autismclient/util/macro/MacroClientThread.java b/src/main/java/autismclient/util/macro/MacroClientThread.java index 8bf5582..c42eaa5 100644 --- a/src/main/java/autismclient/util/macro/MacroClientThread.java +++ b/src/main/java/autismclient/util/macro/MacroClientThread.java @@ -14,7 +14,7 @@ final class MacroClientThread { static void runOnClientThread(Minecraft mc, Runnable runnable) throws InterruptedException { if (PackHideState.isHardLocked()) return; MacroExecutor.RunState scheduledRun = MacroExecutor.CURRENT_RUN.get(); - Runnable contextual = () -> MacroExecutor.withRunContext(scheduledRun, runnable); + Runnable contextual = () -> MacroLifecycle.withRunContext(scheduledRun, runnable); if (mc.isSameThread()) { if (PackHideState.isHardLocked()) return; contextual.run(); @@ -48,14 +48,14 @@ final class MacroClientThread { MacroExecutor.RunState scheduledRun = MacroExecutor.CURRENT_RUN.get(); mc.execute(() -> { if (PackHideState.isHardLocked()) return; - MacroExecutor.withRunContext(scheduledRun, runnable); + MacroLifecycle.withRunContext(scheduledRun, runnable); }); } static void runOnClientTick(Minecraft mc, Runnable runnable) throws InterruptedException { if (PackHideState.isHardLocked()) return; MacroExecutor.RunState scheduledRun = MacroExecutor.CURRENT_RUN.get(); - Runnable contextual = () -> MacroExecutor.withRunContext(scheduledRun, runnable); + Runnable contextual = () -> MacroLifecycle.withRunContext(scheduledRun, runnable); if (mc.isSameThread()) { if (PackHideState.isHardLocked()) return; @@ -97,7 +97,7 @@ final class MacroClientThread { MacroExecutor.RunState scheduledRun = MacroExecutor.CURRENT_RUN.get(); java.util.function.Supplier contextual = () -> { AtomicReference value = new AtomicReference<>(fallback); - MacroExecutor.withRunContext(scheduledRun, () -> value.set(supplier.get())); + MacroLifecycle.withRunContext(scheduledRun, () -> value.set(supplier.get())); return value.get(); }; if (mc.isSameThread()) { @@ -130,7 +130,7 @@ final class MacroClientThread { MacroExecutor.RunState scheduledRun = MacroExecutor.CURRENT_RUN.get(); java.util.function.Supplier contextual = () -> { AtomicReference value = new AtomicReference<>(fallback); - MacroExecutor.withRunContext(scheduledRun, () -> value.set(supplier.get())); + MacroLifecycle.withRunContext(scheduledRun, () -> value.set(supplier.get())); return value.get(); }; if (mc.isSameThread()) { diff --git a/src/main/java/autismclient/util/macro/MacroDispatcher.java b/src/main/java/autismclient/util/macro/MacroDispatcher.java index 0e7f531..7ede02d 100644 --- a/src/main/java/autismclient/util/macro/MacroDispatcher.java +++ b/src/main/java/autismclient/util/macro/MacroDispatcher.java @@ -17,7 +17,7 @@ final class MacroDispatcher { if (!MacroDynamicBindings.apply(action, mc)) return; if (!MacroActionRunner.dynamicTextInputsAvailable(action, mc)) return; MacroPrearm.clearOwnCaptureOutput(action); - EnumSet heldResources = MacroExecutor.acquireClientResources(action); + EnumSet heldResources = MacroLifecycle.acquireClientResources(action); try { if (!MacroActionRunner.waitForGuiBeforeAction(mc, action)) return; @@ -28,7 +28,7 @@ final class MacroDispatcher { if (action instanceof DelayAction) { DelayAction da = (DelayAction) action; if (da.useTicks) { - for (int t = 0; t < da.delayTicks && MacroExecutor.isCurrentRunActive(); t++) { + for (int t = 0; t < da.delayTicks && MacroLifecycle.isCurrentRunActive(); t++) { CompletableFuture tf = MacroConditionRegistry.waitForNextTick(); MacroRunLoop.waitForCondition(tf); } @@ -36,7 +36,7 @@ final class MacroDispatcher { Thread.sleep(da.delayMs); } } else if (action instanceof CustomMenuAction customMenu) { - MacroExecutor.setCurrentStatus(customMenu.getDisplayName()); + MacroLifecycle.setCurrentStatus(customMenu.getDisplayName()); customMenu.execute(mc); } else if (action instanceof WaitForPacketAction packetAction) { packetAction.matchedPacket = null; @@ -51,29 +51,29 @@ final class MacroDispatcher { MacroPacketWait.awaitPacket(""); } else { for (String target : targets) { - if (!MacroExecutor.isCurrentRunActive()) break; + if (!MacroLifecycle.isCurrentRunActive()) break; MacroPacketWait.awaitPacket(target); } } MacroPrearm.copyLastMatchedPacket(packetAction); } else if (action instanceof WaitPacketMatchAction wpma) { - MacroExecutor.setCurrentStatus(wpma.getDisplayName()); + MacroLifecycle.setCurrentStatus(wpma.getDisplayName()); MacroPrearm.waitForPacketMatch(wpma); } else if (action instanceof WaitInventoryPredicateAction wipa) { - MacroExecutor.setCurrentStatus(wipa.getDisplayName()); + MacroLifecycle.setCurrentStatus(wipa.getDisplayName()); MacroRunLoop.waitForPredicate(() -> wipa.matches(mc), wipa.timeoutMs); } else if (action instanceof WaitDurabilityAction wda) { - MacroExecutor.setCurrentStatus(wda.getDisplayName()); + MacroLifecycle.setCurrentStatus(wda.getDisplayName()); if (wda.useNext) MacroDurability.waitForDurabilityUseNext(mc, wda); else MacroRunLoop.waitForPredicate(() -> wda.matches(mc), wda.timeoutMs); } else if (action instanceof WaitFreeSlotsAction wfsa) { - MacroExecutor.setCurrentStatus(wfsa.getDisplayName()); + MacroLifecycle.setCurrentStatus(wfsa.getDisplayName()); MacroRunLoop.waitForPredicate(() -> wfsa.matches(mc), wfsa.timeoutMs); } else if (action instanceof WaitEntityTargetAction weta) { - MacroExecutor.setCurrentStatus(weta.getDisplayName()); + MacroLifecycle.setCurrentStatus(weta.getDisplayName()); MacroRunLoop.waitForPredicate(() -> weta.matches(mc), weta.timeoutMs); } else if (action instanceof WaitGuiTypeAction wgta) { - MacroExecutor.setCurrentStatus(wgta.getDisplayName()); + MacroLifecycle.setCurrentStatus(wgta.getDisplayName()); MacroPrearm.clearCaptureOutputs(wgta); if (wgta.waitMode == WaitGuiTypeAction.WaitMode.CLOSE) MacroRunLoop.waitForPredicate(MacroRunLoop.guiClosePredicate(wgta, mc), wgta.timeoutMs); else MacroRunLoop.waitForPredicate(() -> { @@ -88,14 +88,14 @@ final class MacroDispatcher { postGuiFuture = MacroActionRunner.runTargetWaitInteractionAction(mc, action); } else if (action instanceof WaitForHealthAction) { WaitForHealthAction wh = (WaitForHealthAction) action; - MacroExecutor.setCurrentStatus(wh.waitingStatusText()); + MacroLifecycle.setCurrentStatus(wh.waitingStatusText()); try { CompletableFuture future = MacroConditionRegistry.waitForHealth(wh.healthThreshold, wh.below); MacroRunLoop.waitForCondition(future); } catch (CancellationException e) { } } else if (action instanceof WaitForBlockAction) { WaitForBlockAction wba = (WaitForBlockAction) action; - MacroExecutor.setCurrentStatus(wba.getDisplayName()); + MacroLifecycle.setCurrentStatus(wba.getDisplayName()); try { CompletableFuture future = MacroConditionRegistry.waitForBlock(wba); MacroRunLoop.waitForCondition(future); @@ -104,10 +104,10 @@ final class MacroDispatcher { WaitForGuiAction wga = (WaitForGuiAction) action; MacroPrearm.clearCaptureOutputs(wga); if (wga.waitMode == WaitForGuiAction.WaitMode.CLOSE) { - MacroExecutor.setCurrentStatus("Waiting for GUI close: " + wga.guiTitle); + MacroLifecycle.setCurrentStatus("Waiting for GUI close: " + wga.guiTitle); MacroRunLoop.waitForPredicate(MacroRunLoop.guiClosePredicate(wga, mc), wga.timeoutMs); } else { - MacroExecutor.setCurrentStatus("Waiting for GUI: " + wga.guiTitle); + MacroLifecycle.setCurrentStatus("Waiting for GUI: " + wga.guiTitle); MacroRunLoop.waitForPredicate(() -> { var captured = wga.captureGui(mc.gui.screen()); captured.ifPresent(values -> MacroPrearm.stageCapture(wga, values)); @@ -120,7 +120,7 @@ final class MacroDispatcher { ItemTarget cooldownTarget = MacroWorldActions.resolveItemTarget(wca.itemTarget, wca.itemName).resolveTemplate(mc); if (cooldownTarget == null) return; String cooldownLabel = MacroWorldActions.describeItemTarget(cooldownTarget); - MacroExecutor.setCurrentStatus("Waiting for cooldown: " + + MacroLifecycle.setCurrentStatus("Waiting for cooldown: " + (!cooldownLabel.isEmpty() ? cooldownLabel : (wca.checkMainInteractionHand ? "Main Hand" : "Off Hand"))); try { CompletableFuture future = MacroConditionRegistry.waitForCooldown(cooldownTarget, wca.checkMainInteractionHand); @@ -128,7 +128,7 @@ final class MacroDispatcher { } catch (CancellationException e) { } } else if (action instanceof WaitPosAction) { WaitPosAction wpa = (WaitPosAction) action; - MacroExecutor.setCurrentStatus("Waiting for Pos: " + String.format("%.0f, %.0f, %.0f", wpa.x, wpa.y, wpa.z)); + MacroLifecycle.setCurrentStatus("Waiting for Pos: " + String.format("%.0f, %.0f, %.0f", wpa.x, wpa.y, wpa.z)); try { CompletableFuture future = MacroConditionRegistry.waitForPos( wpa.x, wpa.y, wpa.z, wpa.leeway, wpa.checkRotation, wpa.yaw, wpa.pitch, wpa.rotLeeway); @@ -138,69 +138,69 @@ final class MacroDispatcher { MacroCaptureAutofill.runCaptureValueAction(mc, captureValue); } else if (action instanceof WaitForChatAction) { WaitForChatAction wca = (WaitForChatAction) action; - MacroExecutor.setCurrentStatus("Waiting for chat: " + wca.pattern); + MacroLifecycle.setCurrentStatus("Waiting for chat: " + wca.pattern); MacroPacketWait.awaitChat(wca); } else if (action instanceof WaitForEntityAction) { WaitForEntityAction wea = (WaitForEntityAction) action; - MacroExecutor.setCurrentStatus(wea.getDisplayName()); + MacroLifecycle.setCurrentStatus(wea.getDisplayName()); try { MacroRunLoop.waitForPredicate(() -> wea.matchesEntityTarget(mc), wea.timeoutMs); } catch (CancellationException e) { } } else if (action instanceof WaitForSoundAction) { WaitForSoundAction wsa = (WaitForSoundAction) action; String sndDesc = wsa.soundIds.isEmpty() ? "any" : wsa.soundIds.get(0); - MacroExecutor.setCurrentStatus("Waiting for sound: " + sndDesc); + MacroLifecycle.setCurrentStatus("Waiting for sound: " + sndDesc); try { CompletableFuture future = MacroConditionRegistry.waitForSound(wsa); MacroRunLoop.waitForCondition(future); } catch (CancellationException e) { } } else if (action instanceof WaitForSlotChangeAction) { WaitForSlotChangeAction wsca = (WaitForSlotChangeAction) action; - MacroExecutor.setCurrentStatus(wsca.getDisplayName()); + MacroLifecycle.setCurrentStatus(wsca.getDisplayName()); try { CompletableFuture future = MacroConditionRegistry.waitForSlotChange(wsca); MacroRunLoop.waitForCondition(future); } catch (CancellationException e) { } } else if (action instanceof WaitForWorldChangeAction world) { - MacroExecutor.setCurrentStatus(world.getDisplayName()); + MacroLifecycle.setCurrentStatus(world.getDisplayName()); try { CompletableFuture future = MacroRace.raceConditionFuture(mc, world); MacroRace.waitForFutureDone(future, 0); } catch (CancellationException e) { } } else if (action instanceof WaitForPositionDeltaAction wpda) { - MacroExecutor.setCurrentStatus(wpda.getDisplayName()); + MacroLifecycle.setCurrentStatus(wpda.getDisplayName()); try { CompletableFuture future = MacroConditionRegistry.waitForPositionDelta(wpda.distance, wpda.horizontalOnly); MacroRunLoop.waitForCondition(future); } catch (CancellationException e) { } } else if (action instanceof WaitForTeleportAction teleport) { - MacroExecutor.setCurrentStatus(teleport.getDisplayName()); + MacroLifecycle.setCurrentStatus(teleport.getDisplayName()); try { CompletableFuture future = MacroRace.raceConditionFuture(mc, teleport); MacroRace.waitForFutureDone(future, 0); } catch (CancellationException e) { } } else if (action instanceof WaitGamemodeChangeAction gm) { - MacroExecutor.setCurrentStatus(gm.getDisplayName()); + MacroLifecycle.setCurrentStatus(gm.getDisplayName()); try { CompletableFuture future = MacroConditionRegistry.waitForGamemodeChange(gm); MacroRace.waitForFutureDone(future, gm.timeoutMs); } catch (CancellationException e) { } } else if (action instanceof WaitMovementAction wm) { - MacroExecutor.setCurrentStatus(wm.getDisplayName()); + MacroLifecycle.setCurrentStatus(wm.getDisplayName()); try { CompletableFuture future = MacroRace.raceConditionFuture(mc, wm.resolveSubAction()); MacroRace.waitForFutureDone(future, 0); } catch (CancellationException e) { } } else if (action instanceof WaitForLanStepAction) { WaitForLanStepAction wla = (WaitForLanStepAction) action; - MacroExecutor.setCurrentStatus(wla.getDisplayName()); + MacroLifecycle.setCurrentStatus(wla.getDisplayName()); try { CompletableFuture future = MacroConditionRegistry.waitForLanStep(wla); MacroRunLoop.waitForCondition(future); } catch (CancellationException e) { } } else if (action instanceof WaitForMacroStepAction) { WaitForMacroStepAction wma = (WaitForMacroStepAction) action; - MacroExecutor.setCurrentStatus(wma.getDisplayName()); + MacroLifecycle.setCurrentStatus(wma.getDisplayName()); MacroRace.waitForMacroStep(wma); } else if (action instanceof GoToAction) { GoToAction ga = (GoToAction) action; @@ -209,15 +209,15 @@ final class MacroDispatcher { MoveAction ma = (MoveAction) action; if (ma.nonBlocking) { mc.execute(() -> ma.execute(mc)); - MacroExecutor.currentBackgroundMoves().put(ma, new int[]{ma.durationTicks - 1}); + MacroLifecycle.currentBackgroundMoves().put(ma, new int[]{ma.durationTicks - 1}); } else { - for (int t = 0; t < ma.durationTicks && MacroExecutor.isCurrentRunActive(); t++) { + for (int t = 0; t < ma.durationTicks && MacroLifecycle.isCurrentRunActive(); t++) { mc.execute(() -> ma.execute(mc)); CompletableFuture tickFuture = MacroConditionRegistry.waitForNextTick(); MacroRunLoop.waitForCondition(tickFuture); } MacroExecutor.RunState movementRun = MacroExecutor.CURRENT_RUN.get(); - mc.execute(() -> MacroExecutor.releaseMoveIfUnused(movementRun, ma, mc)); + mc.execute(() -> MacroLifecycle.releaseMoveIfUnused(movementRun, ma, mc)); } } else if (action instanceof LookAtBlockAction) { LookAtBlockAction la = (LookAtBlockAction) action; @@ -265,7 +265,7 @@ final class MacroDispatcher { CompletableFuture tickFuture = MacroConditionRegistry.waitForNextTick(); MacroRunLoop.waitForCondition(tickFuture); } else { - for (int t = 0; t < ja.durationTicks && MacroExecutor.isCurrentRunActive(); t++) { + for (int t = 0; t < ja.durationTicks && MacroLifecycle.isCurrentRunActive(); t++) { CompletableFuture tickFuture = MacroConditionRegistry.waitForNextTick(); MacroRunLoop.waitForCondition(tickFuture); } @@ -274,29 +274,29 @@ final class MacroDispatcher { } else if (action instanceof SneakAction) { SneakAction sna = (SneakAction) action; if (sna.persistent && sna.sneak) { - MacroExecutor.currentPersistentActions().removeIf(p -> p instanceof SneakAction); - MacroExecutor.currentPersistentActions().add(sna); + MacroLifecycle.currentPersistentActions().removeIf(p -> p instanceof SneakAction); + MacroLifecycle.currentPersistentActions().add(sna); } else if (!sna.sneak) { - MacroExecutor.currentPersistentActions().removeIf(p -> p instanceof SneakAction); + MacroLifecycle.currentPersistentActions().removeIf(p -> p instanceof SneakAction); } - if (sna.persistent || !sna.sneak) MacroClientThread.postOnClientThread(mc, () -> MacroExecutor.applyAggregateSneakState(mc), sna.isTickAligned()); + if (sna.persistent || !sna.sneak) MacroClientThread.postOnClientThread(mc, () -> MacroLifecycle.applyAggregateSneakState(mc), sna.isTickAligned()); else MacroClientThread.postOnClientThread(mc, () -> sna.execute(mc), sna.isTickAligned()); } else if (action instanceof SprintAction) { SprintAction spa = (SprintAction) action; if (spa.persistent && spa.sprint) { - MacroExecutor.currentPersistentActions().removeIf(p -> p instanceof SprintAction); - MacroExecutor.currentPersistentActions().add(spa); + MacroLifecycle.currentPersistentActions().removeIf(p -> p instanceof SprintAction); + MacroLifecycle.currentPersistentActions().add(spa); } else if (!spa.sprint) { - MacroExecutor.currentPersistentActions().removeIf(p -> p instanceof SprintAction); + MacroLifecycle.currentPersistentActions().removeIf(p -> p instanceof SprintAction); } - if (spa.persistent || !spa.sprint) MacroClientThread.postOnClientThread(mc, () -> MacroExecutor.applyAggregateSprintState(mc), spa.isTickAligned()); + if (spa.persistent || !spa.sprint) MacroClientThread.postOnClientThread(mc, () -> MacroLifecycle.applyAggregateSprintState(mc), spa.isTickAligned()); else MacroClientThread.postOnClientThread(mc, () -> spa.execute(mc), spa.isTickAligned()); } else if (action instanceof NbtBookAction nba) { int totalBooks = Math.max(1, nba.bookCount); long delayMs = Math.max(1, nba.delayTicks) * 50L; boolean signedAny = false; for (int b = 0; b < totalBooks; b++) { - if (!MacroExecutor.isCurrentRunActive()) break; + if (!MacroLifecycle.isCurrentRunActive()) break; final int bookIdx = b; java.util.concurrent.CompletableFuture result = new java.util.concurrent.CompletableFuture<>(); mc.execute(() -> result.complete(nba.executeSingleBook(mc, bookIdx, totalBooks))); @@ -354,14 +354,14 @@ final class MacroDispatcher { && (xsa.transferMode == XCarryAction.TransferMode.CLICK || xsa.transferMode == XCarryAction.TransferMode.SAFE_CLICK)) { if (xsa.transferMode == XCarryAction.TransferMode.SAFE_CLICK) { - MacroExecutor.setCurrentStatus("XCarry Safe"); + MacroLifecycle.setCurrentStatus("XCarry Safe"); MacroXCarry.runXCarrySafeClickPutIn(mc, xsa); } else { - MacroExecutor.setCurrentStatus("XCarry Click"); + MacroLifecycle.setCurrentStatus("XCarry Click"); MacroXCarry.runXCarryClickPutIn(mc, xsa); } } else { - MacroExecutor.setCurrentStatus(switch (xsa.mode) { + MacroLifecycle.setCurrentStatus(switch (xsa.mode) { case PUT_IN -> "XCarry"; case TAKE_OUT -> "XCarry Out"; case DROP -> "XCarry Drop"; @@ -378,10 +378,10 @@ final class MacroDispatcher { MacroWorldActions.runCraftAction(mc, (CraftAction) action); } else if (action instanceof autismclient.util.macro.StoreItemAction) { autismclient.util.macro.StoreItemAction sia = (autismclient.util.macro.StoreItemAction) action; - MacroExecutor.setCurrentStatus((sia.mode == autismclient.util.macro.StoreItemAction.Mode.LOOT ? "Looting" : "Storing") + MacroLifecycle.setCurrentStatus((sia.mode == autismclient.util.macro.StoreItemAction.Mode.LOOT ? "Looting" : "Storing") + (sia.persistent ? " \u221e" : "")); if (sia.persistent) { - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { try { MacroActionRunner.runStoreItemAction(mc, sia); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } catch (Exception e) { AutismClientMessaging.sendPrefixed("Store error: " + e.getMessage()); } @@ -396,7 +396,7 @@ final class MacroDispatcher { } else if (action instanceof InventoryAuditAction auditAction && (auditAction.mode == InventoryAuditAction.Mode.DUPE || auditAction.mode == InventoryAuditAction.Mode.DUPE_SPAM)) { - MacroExecutor.setCurrentStatus("Dupe: " + auditAction.dupeVector.name() + " " + auditAction.openMode.name()); + MacroLifecycle.setCurrentStatus("Dupe: " + auditAction.dupeVector.name() + " " + auditAction.openMode.name()); try { auditAction.executeDupe(mc); } catch (InterruptedException ie) { @@ -414,11 +414,11 @@ final class MacroDispatcher { java.util.List> preGenerated = MacroActionRunner.preGeneratePacketsForRepeat(tsa.preGenCount, mc); long targetTick = mc.level.getGameTime() + tsa.tickOffset; - MacroExecutor.setCurrentStatus("Tick Sync -> " + targetTick + " (" + preGenerated.size() + " pkts)"); - while (MacroExecutor.isCurrentRunActive() && mc.level.getGameTime() < targetTick) { + MacroLifecycle.setCurrentStatus("Tick Sync -> " + targetTick + " (" + preGenerated.size() + " pkts)"); + while (MacroLifecycle.isCurrentRunActive() && mc.level.getGameTime() < targetTick) { java.util.concurrent.locks.LockSupport.parkNanos(1_000_000L); } - if (MacroExecutor.isCurrentRunActive()) { + if (MacroLifecycle.isCurrentRunActive()) { MacroRender.executePreGeneratedBurst(mc, preGenerated); MacroExecutor.RepeatPacketContext context = MacroExecutor.REPEAT_PACKET_CONTEXT.get(); if (context != null) MacroExecutor.REPEAT_PACKET_SKIP.set(MacroRender.countPreGeneratedActions(context.macro(), context.startIdx(), preGenerated.size(), context.endIdx())); @@ -430,13 +430,13 @@ final class MacroDispatcher { MacroActionRunner.preGeneratePacketsForRepeat(rsa.preGenCount, mc); int baseRevision = mc.player.containerMenu.getStateId(); int targetRevision = baseRevision + rsa.revisionOffset; - MacroExecutor.setCurrentStatus("Rev Sync -> " + targetRevision + " (" + preGenerated.size() + " pkts)"); - while (MacroExecutor.isCurrentRunActive()) { + MacroLifecycle.setCurrentStatus("Rev Sync -> " + targetRevision + " (" + preGenerated.size() + " pkts)"); + while (MacroLifecycle.isCurrentRunActive()) { if (mc.player == null || mc.player.containerMenu == null) break; if (mc.player.containerMenu.getStateId() >= targetRevision) break; java.util.concurrent.locks.LockSupport.parkNanos(500_000L); } - if (MacroExecutor.isCurrentRunActive() && mc.player != null && mc.player.containerMenu != null) { + if (MacroLifecycle.isCurrentRunActive() && mc.player != null && mc.player.containerMenu != null) { MacroRender.executePreGeneratedBurst(mc, preGenerated); MacroExecutor.RepeatPacketContext context = MacroExecutor.REPEAT_PACKET_CONTEXT.get(); if (context != null) MacroExecutor.REPEAT_PACKET_SKIP.set(MacroRender.countPreGeneratedActions(context.macro(), context.startIdx(), preGenerated.size(), context.endIdx())); @@ -447,22 +447,22 @@ final class MacroDispatcher { java.util.List> preGenerated = MacroActionRunner.preGeneratePacketsForRepeat(stsa.preGenCount, mc); int sampleWaitMs = 0; - while (MacroExecutor.isCurrentRunActive() && !ServerTickTracker.isReady() && sampleWaitMs < stsa.maxWaitMs) { + while (MacroLifecycle.isCurrentRunActive() && !ServerTickTracker.isReady() && sampleWaitMs < stsa.maxWaitMs) { float progress = ServerTickTracker.getWarmupProgress(); - MacroExecutor.setCurrentStatus(String.format("ServerSync warmup %.0f%% (%d samples, %dms)", + MacroLifecycle.setCurrentStatus(String.format("ServerSync warmup %.0f%% (%d samples, %dms)", progress * 100, ServerTickTracker.getSampleCount(), ServerTickTracker.getTrackingTimeMs())); Thread.sleep(50); sampleWaitMs += 50; } - if (!MacroExecutor.isCurrentRunActive()) return; + if (!MacroLifecycle.isCurrentRunActive()) return; long optimalTime = ServerTickTracker.getOptimalSendTime(stsa.bufferMs, stsa.ignorePing); long msUntil = (optimalTime - System.nanoTime()) / 1_000_000L; int ping = ServerTickTracker.getPingMs(); String pingStr = stsa.ignorePing ? " (no ping)" : " ping:" + ping + "ms"; - MacroExecutor.setCurrentStatus("ServerSync in " + Math.max(0, msUntil) + "ms" + pingStr + " (" + preGenerated.size() + " pkts)"); + MacroLifecycle.setCurrentStatus("ServerSync in " + Math.max(0, msUntil) + "ms" + pingStr + " (" + preGenerated.size() + " pkts)"); long startWait = System.nanoTime(); long maxWaitNanos = stsa.maxWaitMs * 1_000_000L; - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { long now = System.nanoTime(); if ((now - startWait) >= maxWaitNanos) break; if (now >= optimalTime) break; @@ -473,7 +473,7 @@ final class MacroDispatcher { Thread.onSpinWait(); } } - if (MacroExecutor.isCurrentRunActive()) { + if (MacroLifecycle.isCurrentRunActive()) { MacroRender.executePreGeneratedBurst(mc, preGenerated); MacroExecutor.RepeatPacketContext context = MacroExecutor.REPEAT_PACKET_CONTEXT.get(); if (context != null) MacroExecutor.REPEAT_PACKET_SKIP.set(MacroRender.countPreGeneratedActions(context.macro(), context.startIdx(), preGenerated.size(), context.endIdx())); @@ -481,10 +481,10 @@ final class MacroDispatcher { AutismClientMessaging.sendPrefixed("ServerSync: " + preGenerated.size() + " pkts (+" + actualDelay + "ms)"); } } else if (action instanceof BundleDupeV2Action bundleV2) { - MacroExecutor.setCurrentStatus("Bundle Dupe V2"); + MacroLifecycle.setCurrentStatus("Bundle Dupe V2"); bundleV2.execute(mc); } else if (action instanceof RollbackAction rollback) { - MacroExecutor.setCurrentStatus("Rollback"); + MacroLifecycle.setCurrentStatus("Rollback"); try { rollback.executeRollback(mc); } catch (InterruptedException e) { @@ -494,7 +494,7 @@ final class MacroDispatcher { } } else if (action instanceof StopMacroAction) { StopMacroAction stopAction = (StopMacroAction) action; - if (stopAction.target == StopMacroAction.StopTarget.SELF) MacroExecutor.stopCurrentRun(); + if (stopAction.target == StopMacroAction.StopTarget.SELF) MacroLifecycle.stopCurrentRun(); else stopAction.execute(mc); } else if (action instanceof UseItemPhaseAction phaseAction) { MacroActionRunner.runUseItemPhaseAction(mc, phaseAction); @@ -508,7 +508,7 @@ final class MacroDispatcher { } else if (module != null && module.useInstantExecutionMode()) { java.util.concurrent.CountDownLatch latch = new java.util.concurrent.CountDownLatch(1); MacroExecutor.RunState scheduledRun = MacroExecutor.CURRENT_RUN.get(); - mc.execute(() -> MacroExecutor.withRunContext(scheduledRun, () -> { + mc.execute(() -> MacroLifecycle.withRunContext(scheduledRun, () -> { try { action.execute(mc); } catch (Exception e) { @@ -529,20 +529,20 @@ final class MacroDispatcher { MacroPrearm.commitConditionOutput(action, mc); - if (postGuiFuture != null && MacroExecutor.isCurrentRunActive()) { + if (postGuiFuture != null && MacroLifecycle.isCurrentRunActive()) { try { MacroRunLoop.waitForCondition(postGuiFuture); } catch (java.util.concurrent.CancellationException e) { } } - if (MacroExecutor.isCurrentRunActive() && !MacroActionRunner.isInstantInventoryAction(action) && module != null && module.useInstantExecutionMode()) { + if (MacroLifecycle.isCurrentRunActive() && !MacroActionRunner.isInstantInventoryAction(action) && module != null && module.useInstantExecutionMode()) { int delayUs = module.getActionDelayUs(); if (delayUs > 0) java.util.concurrent.locks.LockSupport.parkNanos(delayUs * 1000L); else Thread.onSpinWait(); } } finally { MacroRaycastAim.release(); - MacroExecutor.releaseClientResources(heldResources); + MacroLifecycle.releaseClientResources(heldResources); } } } diff --git a/src/main/java/autismclient/util/macro/MacroDurability.java b/src/main/java/autismclient/util/macro/MacroDurability.java index d88147a..cf5eaf9 100644 --- a/src/main/java/autismclient/util/macro/MacroDurability.java +++ b/src/main/java/autismclient/util/macro/MacroDurability.java @@ -15,7 +15,7 @@ final class MacroDurability { public static void waitForDurabilityUseNext(Minecraft mc, WaitDurabilityAction action) throws InterruptedException { AtomicReference sessionRef = new AtomicReference<>(); long start = System.currentTimeMillis(); - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { if (Boolean.TRUE.equals(MacroClientThread.callOnClientThread(mc, () -> tickDurabilityUseNext(mc, action, sessionRef), Boolean.FALSE))) { return; } diff --git a/src/main/java/autismclient/util/macro/MacroExecutor.java b/src/main/java/autismclient/util/macro/MacroExecutor.java index 293e05d..c0d91b4 100644 --- a/src/main/java/autismclient/util/macro/MacroExecutor.java +++ b/src/main/java/autismclient/util/macro/MacroExecutor.java @@ -92,22 +92,22 @@ public class MacroExecutor { SHARED_RESOURCE_LOCKS.put(resource, new ReentrantLock(true)); } } - private static final AtomicLong NEXT_RUN_ID = new AtomicLong(1L); + static final AtomicLong NEXT_RUN_ID = new AtomicLong(1L); static final java.util.LinkedHashMap ACTIVE_RUNS = new java.util.LinkedHashMap<>(); - private static final java.util.concurrent.ConcurrentHashMap RUNS_BY_ID = new java.util.concurrent.ConcurrentHashMap<>(); - private static final AtomicLong RUN_STATE_REVISION = new AtomicLong(); + static final java.util.concurrent.ConcurrentHashMap RUNS_BY_ID = new java.util.concurrent.ConcurrentHashMap<>(); + static final AtomicLong RUN_STATE_REVISION = new AtomicLong(); static final ThreadLocal CURRENT_RUN = new ThreadLocal<>(); static final ThreadLocal SUPPRESS_POST_GUI_AFTER = ThreadLocal.withInitial(() -> false); - private static volatile RunState primaryRun = null; - private static volatile boolean visibleRunActive; - private static AutismMacro currentMacro = null; - private static Thread macroThread = null; + static volatile RunState primaryRun = null; + static volatile boolean visibleRunActive; + static AutismMacro currentMacro = null; + static Thread macroThread = null; static final AtomicReference lastReceivedPacket = new AtomicReference<>(""); - private static String currentStatus = ""; + static String currentStatus = ""; - private static volatile int currentStepIndex = -1; + static volatile int currentStepIndex = -1; static volatile int totalSteps = 0; static final AtomicBoolean isWaitingForPacket = new AtomicBoolean(false); @@ -142,10 +142,10 @@ public class MacroExecutor { static volatile double rotationSpeed; static volatile int rotationAlignedFrames; - private static final java.util.concurrent.CopyOnWriteArrayList persistentActions = + static final java.util.concurrent.CopyOnWriteArrayList persistentActions = new java.util.concurrent.CopyOnWriteArrayList<>(); - private static final java.util.concurrent.ConcurrentHashMap backgroundMoves = + static final java.util.concurrent.ConcurrentHashMap backgroundMoves = new java.util.concurrent.ConcurrentHashMap<>(); static final ThreadLocal REPEAT_PACKET_CONTEXT = new ThreadLocal<>(); static final ThreadLocal REPEAT_PACKET_SKIP = ThreadLocal.withInitial(() -> 0); @@ -262,609 +262,54 @@ public class MacroExecutor { } } - private static final int FLOW_JUMP_BURST_CAP = 100_000; - private static final int FLOW_JUMP_HARD_CAP = 5_000_000; - - private static java.util.Map flowLabels(RunState run, AutismMacro macro) { - java.util.Map cached = run.labelIndex; - if (cached != null) return cached; - java.util.LinkedHashMap built = new java.util.LinkedHashMap<>(); - for (int k = 0; k < macro.actions.size(); k++) { - if (macro.actions.get(k) instanceof LabelAction la) { - String key = la.normalizedName(); - if (!key.isEmpty() && !built.containsKey(key)) built.put(key, k); - } - } - run.labelIndex = built; - return built; - } - - private static Integer resolveFlowTarget(RunState run, AutismMacro macro, int i, FlowAction flow, Minecraft mc) { - return switch (flow.target) { - case STOP -> null; - case TOP -> 0; - case END -> macro.actions.size(); - case FORWARD -> i + 1 + Math.max(0, flow.amount); - case BACK -> i - Math.max(0, flow.amount); - case STEP -> Math.max(1, flow.amount) - 1; - case LABEL -> { - String name = LabelAction.normalize(MacroVariables.expand(flow.labelName, mc)); - Integer idx = flowLabels(run, macro).get(name); - if (idx == null) { - AutismClientMessaging.sendPrefixed("§eFlow: label '" + flow.labelName + "' not found."); - yield flow.onMissingLabel == FlowAction.MissingPolicy.STOP ? null : i + 1; - } - yield idx; - } - }; - } - - static int performFlowJump(RunState run, AutismMacro macro, int currentI, FlowAction flow, Minecraft mc) { - run.branchElseStart = -1; - run.branchElseCount = 0; - Integer dest = resolveFlowTarget(run, macro, currentI, flow, mc); - if (dest == null) return Integer.MIN_VALUE; - int size = macro.actions.size(); - int target = Math.max(0, Math.min(size, dest)); - if (target <= currentI) { - run.totalJumpsThisRun++; - run.jumpBudget++; - if (FLOW_JUMP_HARD_CAP >= 0 && run.totalJumpsThisRun > FLOW_JUMP_HARD_CAP) { - AutismClientMessaging.sendPrefixed("§cMacro aborted: jump limit exceeded (runaway loop)."); - return Integer.MIN_VALUE; - } - if (run.jumpBudget >= FLOW_JUMP_BURST_CAP) { - run.jumpBudget = 0; - - try { MacroRunLoop.waitForCondition(MacroConditionRegistry.waitForNextTick()); } catch (Exception ignored) { } - } - } else { - run.jumpBudget = 0; - } - return target - 1; - } - - static boolean isCurrentRunActive() { - if (PackHideState.isHardLocked()) return false; - RunState run = CURRENT_RUN.get(); - if (run != null) return run.running.get(); - return isRunning.get(); - } + static final int FLOW_JUMP_BURST_CAP = 100_000; + static final int FLOW_JUMP_HARD_CAP = 5_000_000; public static boolean isCurrentActionRunActive() { - return isCurrentRunActive(); - } - - static CopyOnWriteArrayList currentPersistentActions() { - RunState run = CURRENT_RUN.get(); - return run != null ? run.persistentActions : persistentActions; - } - - static ConcurrentHashMap currentBackgroundMoves() { - RunState run = CURRENT_RUN.get(); - return run != null ? run.backgroundMoves : backgroundMoves; - } - - static void setCurrentStatus(String status) { - RunState run = CURRENT_RUN.get(); - if (run != null) run.status = status == null ? "" : status; - currentStatus = status == null ? "" : status; - } - - static void setCurrentStep(int step, int total) { - RunState run = CURRENT_RUN.get(); - if (run != null) { - run.currentStepIndex = step; - run.totalSteps = total; - } - currentStepIndex = step; - totalSteps = total; - } - - static void markStepCompleted(int stepOneBased) { - RunState run = CURRENT_RUN.get(); - if (run != null) { - run.lastCompletedStep = Math.max(run.lastCompletedStep, stepOneBased); - } - } - - static int stepOverrideEndIndex(AutismMacro macro, int headerIndex, int coveredRows) { - int last = macro == null ? headerIndex : macro.actions.size() - 1; - long end = (long) headerIndex + Math.max(0, coveredRows); - return (int) Math.max(headerIndex, Math.min(last, end)); - } - - static void armFpsStepOverride(RunState run, int headerIndex, int endIndexInclusive, int fpsLimit) { - if (run == null) return; - run.fpsStepHeaderIndex = headerIndex; - run.fpsStepEndIndex = endIndexInclusive; - FpsLimitController.applyUntilCleared(run.id, fpsLimit); - } - - static void armPingStepOverride(RunState run, int headerIndex, int endIndexInclusive, - int delayMs, boolean realIncoming, boolean realOutgoing) { - if (run == null) return; - run.pingStepHeaderIndex = headerIndex; - run.pingStepEndIndex = endIndexInclusive; - PingSpoofController.applyUntilCleared(run.id, delayMs, realIncoming, realOutgoing); - } - - static void clearFpsStepOverride(RunState run) { - if (run == null || run.fpsStepHeaderIndex < 0) return; - run.fpsStepHeaderIndex = -1; - run.fpsStepEndIndex = -1; - FpsLimitController.clear(run.id); - } - - static void clearPingStepOverride(RunState run) { - if (run == null || run.pingStepHeaderIndex < 0) return; - run.pingStepHeaderIndex = -1; - run.pingStepEndIndex = -1; - PingSpoofController.clearMacro(run.id); - } - - static void awaitBackgroundTimedOverrides(RunState run) throws InterruptedException { - if (run == null) return; - - long deadline = Math.max(run.fpsBackgroundDeadlineNanos, run.pingBackgroundDeadlineNanos); - long remaining; - while (isCurrentRunActive() && (remaining = deadline - System.nanoTime()) > 0L) { - Thread.sleep(Math.min(25L, remaining / 1_000_000L + 1L)); - } - } - - static void updateStepBoundOverrides(RunState run, int index) { - if (run == null) return; - if (run.fpsStepHeaderIndex >= 0 && (index > run.fpsStepEndIndex || index <= run.fpsStepHeaderIndex)) { - clearFpsStepOverride(run); - } - if (run.pingStepHeaderIndex >= 0 && (index > run.pingStepEndIndex || index <= run.pingStepHeaderIndex)) { - clearPingStepOverride(run); - } - } - - static void stopCurrentRun() { - RunState run = CURRENT_RUN.get(); - if (run != null) { - run.running.set(false); - } else { - stop(); - } - } - - static void stopCurrentActionRun() { - stopCurrentRun(); - } - - private static EnumSet resourcesForAction(MacroAction action) { - return MacroActionResources.resourcesForAction(action); - } - - static EnumSet acquireClientResources(MacroAction action) throws InterruptedException { - return acquireClientResources(resourcesForAction(action)); - } - - static EnumSet acquireClientResources(EnumSet resources) throws InterruptedException { - EnumSet acquired = EnumSet.noneOf(SharedClientResource.class); - try { - for (SharedClientResource resource : SharedClientResource.values()) { - if (resources.contains(resource)) { - if (!isCurrentRunActive()) throw new InterruptedException("Macro stopped"); - SHARED_RESOURCE_LOCKS.get(resource).lockInterruptibly(); - acquired.add(resource); - if (!isCurrentRunActive()) throw new InterruptedException("Macro stopped"); - } - } - } catch (InterruptedException e) { - releaseClientResources(acquired); - throw e; - } - return acquired; - } - - static EnumSet resourcesForActions(java.util.List actions) { - return MacroActionResources.resourcesForActions(actions); - } - - static void releaseClientResources(EnumSet resources) { - if (resources == null || resources.isEmpty()) return; - SharedClientResource[] ordered = SharedClientResource.values(); - for (int i = ordered.length - 1; i >= 0; i--) { - SharedClientResource resource = ordered[i]; - if (resources.contains(resource)) { - ReentrantLock lock = SHARED_RESOURCE_LOCKS.get(resource); - if (lock.isHeldByCurrentThread()) lock.unlock(); - } - } - } - - static MacroVariableContext currentVariableContext() { - RunState run = CURRENT_RUN.get(); - return run == null ? null : run.variables; - } - - static void withRunContext(RunState run, Runnable task) { - RunState previous = CURRENT_RUN.get(); - if (run != null) CURRENT_RUN.set(run); - try { - task.run(); - } finally { - if (previous != null) CURRENT_RUN.set(previous); - else CURRENT_RUN.remove(); - } - } - - static InlineNextActions collectInlineNextActions(java.util.List actions, int currentIndex) { - if (actions == null || currentIndex < 0 || currentIndex >= actions.size() - 1) return InlineNextActions.empty(); - java.util.ArrayList collected = new java.util.ArrayList<>(); - int lastIndex = -1; - for (int j = currentIndex + 1; j < actions.size(); j++) { - MacroAction candidate = actions.get(j); - if (candidate instanceof DisconnectAction - || candidate instanceof RaceAction - || candidate instanceof ReportAction - || candidate instanceof RepeatAction - || candidate instanceof BranchAction - || candidate instanceof FinallyAction) { - break; - } - if (candidate == null || !candidate.isEnabled()) continue; - if (!RaceAction.isBodyAction(candidate)) continue; - collected.add(candidate); - lastIndex = j; - } - return collected.isEmpty() ? InlineNextActions.empty() : new InlineNextActions(java.util.List.copyOf(collected), lastIndex); - } - - private static volatile java.util.List ACTIVE_RUN_LIST = java.util.List.of(); - - private static void rebuildActiveRunListLocked() { - ACTIVE_RUN_LIST = java.util.List.copyOf(ACTIVE_RUNS.values()); - } - - static java.util.List activeRunSnapshot() { - return ACTIVE_RUN_LIST; - } - - static void finishCurrentRun() { - RunState run = CURRENT_RUN.get(); - if (run == null) return; - if (!run.finished.compareAndSet(false, true)) return; - requestStop(run, false); - - clearFpsStepOverride(run); - clearPingStepOverride(run); - - synchronized (RUN_LOCK) { - ACTIVE_RUNS.remove(run.id); - RUNS_BY_ID.remove(run.id); - rebuildActiveRunListLocked(); - if (ACTIVE_RUNS.isEmpty()) MacroCaptureAutofill.allRunsStoppedAtMs = System.currentTimeMillis(); - RUN_STATE_REVISION.incrementAndGet(); - refreshPrimaryRunLocked(); - } - if (!isRunning.get()) { - AutismInstaBreakRenderer.clear(); - - FpsLimitController.clearAll(); - PingSpoofController.clearAllMacros(); - } - CURRENT_RUN.remove(); - } - - private static boolean hasRunningRunsLocked() { - for (RunState run : ACTIVE_RUNS.values()) { - if (run.running.get()) return true; - } - return false; - } - - private static RunState firstVisibleRunLocked() { - for (RunState run : ACTIVE_RUNS.values()) { - if (run.running.get() && !run.options.hiddenFromProgressHud()) return run; - } - return null; - } - - private static int activeRunCountLocked() { - int count = 0; - for (RunState run : ACTIVE_RUNS.values()) { - if (run.running.get()) count++; - } - return count; - } - - static boolean hasMacroCapacity(int activeCount) { - return Math.max(0, activeCount) < MAX_CONCURRENT_MACROS; - } - - private static void refreshPrimaryRunLocked() { - primaryRun = firstVisibleRunLocked(); - visibleRunActive = primaryRun != null; - currentMacro = primaryRun != null ? primaryRun.macro : null; - currentStatus = primaryRun != null ? primaryRun.status : ""; - currentStepIndex = primaryRun != null ? primaryRun.currentStepIndex : -1; - totalSteps = primaryRun != null ? primaryRun.totalSteps : 0; - isRunning.set(hasRunningRunsLocked()); - } - - private static boolean hasRunningRuns() { - synchronized (RUN_LOCK) { - return hasRunningRunsLocked(); - } + return MacroLifecycle.isCurrentActionRunActive(); } public static boolean isVisibleRunning() { - return visibleRunActive; + return MacroLifecycle.isVisibleRunning(); } public static boolean isControllingInput() { - ReentrantLock inputLock = SHARED_RESOURCE_LOCKS.get(SharedClientResource.INPUT); - if (inputLock != null && inputLock.isLocked()) return true; - if (!backgroundMoves.isEmpty()) return true; - for (MacroAction action : persistentActions) { - if (action instanceof MoveAction || action instanceof JumpAction || action instanceof SneakAction || action instanceof SprintAction) return true; - } - synchronized (RUN_LOCK) { - for (RunState run : ACTIVE_RUNS.values()) { - if (run == null || !run.running.get()) continue; - if (!run.backgroundMoves.isEmpty()) return true; - for (MacroAction action : run.persistentActions) { - if (action instanceof MoveAction || action instanceof JumpAction || action instanceof SneakAction || action instanceof SprintAction) return true; - } - } - } - return false; - } - - static void broadcastStepProgress(RunState run, int step, int total, String macroName) { - if (run != null && run.options.skipLanProgress()) return; - try { - autismclient.util.AutismLANSync sync = autismclient.util.AutismLANSync.getInstance(); - if (sync.isInSession()) { - sync.broadcastStepProgress(step, total, macroName); - } - } catch (Exception ignored) { } - } - - private static void requestStop(RunState run, boolean interruptThread) { - if (run == null) return; - if (run.running.getAndSet(false)) { - RUN_STATE_REVISION.incrementAndGet(); - } - run.persistentActions.clear(); - for (PrearmedWait wait : new ArrayList<>(run.prearmedWaits.values())) { - wait.cleanup(); - } - run.prearmedWaits.clear(); - releaseBackgroundMoves(run.backgroundMoves, Minecraft.getInstance(), run); - run.backgroundMoves.clear(); - reconcilePersistentInput(Minecraft.getInstance()); - synchronized (run.packetWaitLock) { - if (run.packetFuture != null) run.packetFuture.cancel(true); - run.packetFuture = null; - run.waitingForPacket.set(false); - run.waitingPacketName.set(""); - } - CompletableFuture chatFuture = run.chatFuture; - if (chatFuture != null) chatFuture.cancel(true); - run.chatFuture = null; - run.waitingForChat.set(false); - run.waitingChatAction = null; - CompletableFuture baritoneFuture = run.baritoneGoalFuture; - if (baritoneFuture != null) baritoneFuture.cancel(true); - run.baritoneGoalFuture = null; - run.activeMineTracker = null; - Minecraft mc = Minecraft.getInstance(); - PacketGateManager.clearOwnerAndFlushConfigured(run.id, mc == null ? null : mc.getConnection()); - FpsLimitController.clear(run.id); - PingSpoofController.clearMacro(run.id); - MacroRender.cancelRotation(run); - MacroWorldActions.requestOwnedBaritoneStop(run, mc); - Thread thread = run.macroThread; - if (interruptThread && thread != null && thread != Thread.currentThread()) { - thread.interrupt(); - } - } - - static void releaseBackgroundMoves(ConcurrentHashMap moves, Minecraft mc, RunState owner) { - if (moves == null || moves.isEmpty() || mc == null) return; - List toRelease = new ArrayList<>(moves.keySet()); - mc.execute(() -> { - for (MoveAction move : toRelease) { - try { - releaseMoveIfUnused(owner, move, mc); - } catch (Exception ignored) { } - } - }); - } - - static void releaseMoveIfUnused(RunState owner, MoveAction move, Minecraft mc) { - if (move == null || mc == null) return; - boolean stillOwned = false; - synchronized (RUN_LOCK) { - for (RunState active : ACTIVE_RUNS.values()) { - if (active == owner || !active.running.get()) continue; - for (MoveAction other : active.backgroundMoves.keySet()) { - if (other.direction == move.direction) { - stillOwned = true; - break; - } - } - if (stillOwned) break; - } - } - if (!stillOwned && owner != null) { - for (MoveAction other : backgroundMoves.keySet()) { - if (other.direction == move.direction) { - stillOwned = true; - break; - } - } - } - if (!stillOwned) move.release(mc); - } - - private static void reconcilePersistentInput(Minecraft mc) { - if (mc == null) return; - mc.execute(() -> { - applyAggregateSneakState(mc); - applyAggregateSprintState(mc); - }); - } - - static void applyAggregateSneakState(Minecraft mc) { - if (mc == null || mc.options == null || mc.options.keyShift == null) return; - boolean held = hasPersistentInput(SneakAction.class); - mc.options.keyShift.setDown(held); - } - - static void applyAggregateSprintState(Minecraft mc) { - if (mc == null) return; - boolean held = hasPersistentInput(SprintAction.class); - if (mc.options != null && mc.options.keySprint != null) mc.options.keySprint.setDown(held); - if (mc.player != null) mc.player.setSprinting(held); - } - - private static boolean hasPersistentInput(Class type) { - for (MacroAction action : persistentActions) { - if (type.isInstance(action)) return true; - } - synchronized (RUN_LOCK) { - for (RunState run : ACTIVE_RUNS.values()) { - if (!run.running.get()) continue; - for (MacroAction action : run.persistentActions) { - if (type.isInstance(action)) return true; - } - } - } - return false; - } - - private static String macroKey(String macroName) { - return macroName == null ? "" : macroName.trim().toLowerCase(Locale.ROOT); - } - - private static String macroName(AutismMacro macro) { - return macro != null && macro.name != null ? macro.name : ""; - } - - private static boolean matchesMacro(RunState run, AutismMacro macro, String macroName) { - if (run == null || !run.running.get()) return false; - if (macro != null && (run.sourceMacro == macro || run.macro == macro)) return true; - String targetKey = macroKey(macroName); - if (targetKey.isEmpty() && macro != null) targetKey = macroKey(macro.name); - return !targetKey.isEmpty() && macroKey(macroName(run.macro)).equals(targetKey); + return MacroLifecycle.isControllingInput(); } public static void execute(AutismMacro macro) { - executeTracked(macro); + MacroLifecycle.execute(macro); } public static long executeTracked(AutismMacro macro) { - return executeTracked(macro, RunOptions.NORMAL); + return MacroLifecycle.executeTracked(macro); } public static long executeTracked(AutismMacro macro, RunOptions options) { - if (PackHideState.isHardLocked()) return -1L; - RunOptions runOptions = options == null ? RunOptions.NORMAL : options; - if (macro == null || macro.actions == null || macro.actions.isEmpty()) { - if (runOptions.silentLifecycle()) return -1L; - AutismClientMessaging.sendPrefixed("\u00a7cMacro has no actions!"); - return -1L; - } - - AutismMacro executionMacro; - try { - executionMacro = macro.deepCopy(); - } catch (Throwable copyError) { - if (!runOptions.silentLifecycle()) AutismClientMessaging.sendPrefixed("\u00a7cCould not prepare macro run."); - return -1L; - } - if (executionMacro == null || executionMacro.actions == null || executionMacro.actions.isEmpty()) return -1L; - - RunState runState; - synchronized (RUN_LOCK) { - String name = macro.name == null ? "" : macro.name; - String nameKey = macroKey(name); - if (!runOptions.backgroundRun()) { - for (RunState active : ACTIVE_RUNS.values()) { - if (active.options.backgroundRun()) continue; - String activeName = active.macro != null && active.macro.name != null ? active.macro.name : ""; - if (active.running.get() && macroKey(activeName).equals(nameKey)) { - if (!runOptions.silentLifecycle()) AutismClientMessaging.sendPrefixed("\u00a7eMacro already running: " + name); - return -1L; - } - } - if (!hasMacroCapacity(activeRunCountLocked())) { - if (!runOptions.silentLifecycle()) AutismClientMessaging.sendPrefixed("\u00a7cOnly " + MAX_CONCURRENT_MACROS + " macros can run at the same time."); - return -1L; - } - } else if (!hasMacroCapacity(activeRunCountLocked())) { - return -1L; - } - runState = new RunState(NEXT_RUN_ID.getAndIncrement(), macro, executionMacro, runOptions); - if (ACTIVE_RUNS.isEmpty()) MacroCaptureAutofill.expireSuggestionCacheAfterIdle(); - ACTIVE_RUNS.put(runState.id, runState); - RUNS_BY_ID.put(runState.id, runState); - rebuildActiveRunListLocked(); - RUN_STATE_REVISION.incrementAndGet(); - refreshPrimaryRunLocked(); - } - if (!runOptions.silentLifecycle()) AutismClientMessaging.sendPrefixed("\u00a7aStarted macro: " + macro.name); - - broadcastStepProgress(runState, 0, executionMacro.actions.size(), executionMacro.name); - - Thread thread = new Thread(() -> MacroRunLoop.run(runState), "Autism-Macro-" + runState.id); - thread.setDaemon(true); - macroThread = thread; - runState.macroThread = thread; - try { - thread.start(); - } catch (Throwable startError) { - - requestStop(runState, false); - synchronized (RUN_LOCK) { - ACTIVE_RUNS.remove(runState.id); - RUNS_BY_ID.remove(runState.id); - rebuildActiveRunListLocked(); - if (ACTIVE_RUNS.isEmpty()) MacroCaptureAutofill.allRunsStoppedAtMs = System.currentTimeMillis(); - RUN_STATE_REVISION.incrementAndGet(); - refreshPrimaryRunLocked(); - } - return -1L; - } - return runState.id; + return MacroLifecycle.executeTracked(macro, options); } public static boolean isRunActive(long id) { - if (id < 0L) return false; - RunState run = RUNS_BY_ID.get(id); - return run != null && run.running.get(); + return MacroLifecycle.isRunActive(id); } public static long runStateRevision() { - return RUN_STATE_REVISION.get(); + return MacroLifecycle.runStateRevision(); } public static long currentRunId() { - RunState run = CURRENT_RUN.get(); - return run == null ? -1L : run.id; + return MacroLifecycle.currentRunId(); } public static void stopRun(long id) { - if (id < 0L) return; - RunState run; - synchronized (RUN_LOCK) { - run = ACTIVE_RUNS.get(id); - } - if (run == null) return; - requestStop(run, true); - synchronized (RUN_LOCK) { - refreshPrimaryRunLocked(); - } + MacroLifecycle.stopRun(id); } + static void stopCurrentActionRun() { + MacroLifecycle.stopCurrentActionRun(); + } + + @@ -898,13 +343,13 @@ public class MacroExecutor { public static void stop() { String macroName = (currentMacro != null && currentMacro.name != null) ? currentMacro.name : ""; - for (RunState run : activeRunSnapshot()) { - requestStop(run, true); + for (RunState run : MacroLifecycle.activeRunSnapshot()) { + MacroLifecycle.requestStop(run, true); } synchronized (RUN_LOCK) { ACTIVE_RUNS.clear(); RUNS_BY_ID.clear(); - rebuildActiveRunListLocked(); + MacroLifecycle.rebuildActiveRunListLocked(); primaryRun = null; visibleRunActive = false; } @@ -914,9 +359,9 @@ public class MacroExecutor { autismclient.util.AutismContainerHold.releaseAllAndFlush(mcInst == null ? null : mcInst.getConnection()); } catch (Throwable ignored) { } persistentActions.clear(); - releaseBackgroundMoves(backgroundMoves, Minecraft.getInstance(), null); + MacroLifecycle.releaseBackgroundMoves(backgroundMoves, Minecraft.getInstance(), null); backgroundMoves.clear(); - reconcilePersistentInput(Minecraft.getInstance()); + MacroLifecycle.reconcilePersistentInput(Minecraft.getInstance()); MacroConditionRegistry.cancelAll(); MacroPacketObserve.drainOneShotListeners(); isWaitingForChat.set(false); @@ -948,7 +393,7 @@ public class MacroExecutor { macroThread = null; currentMacro = null; - setCurrentStatus(""); + MacroLifecycle.setCurrentStatus(""); synchronized (ROTATION_STATE_LOCK) { ROTATION_OWNER.set(null); isRotating.set(false); @@ -967,7 +412,7 @@ public class MacroExecutor { public static int getActiveRunCount() { synchronized (RUN_LOCK) { - return activeRunCountLocked(); + return MacroLifecycle.activeRunCountLocked(); } } @@ -984,9 +429,9 @@ public class MacroExecutor { public static boolean isMacroRunning(String macroName) { if (macroName == null) return false; - String targetKey = macroKey(macroName); + String targetKey = MacroLifecycle.macroKey(macroName); for (RunState run : RUNS_BY_ID.values()) { - if (run.running.get() && macroKey(macroName(run.macro)).equals(targetKey)) return true; + if (run.running.get() && MacroLifecycle.macroKey(MacroLifecycle.macroName(run.macro)).equals(targetKey)) return true; } return false; } @@ -994,7 +439,7 @@ public class MacroExecutor { public static boolean isMacroRunning(AutismMacro macro) { if (macro == null) return false; for (RunState run : RUNS_BY_ID.values()) { - if (matchesMacro(run, macro, macro.name)) return true; + if (MacroLifecycle.matchesMacro(run, macro, macro.name)) return true; } return false; } @@ -1022,17 +467,17 @@ public class MacroExecutor { public static void stopMacro(String macroName) { if (macroName == null || macroName.isBlank()) return; - String targetKey = macroKey(macroName); + String targetKey = MacroLifecycle.macroKey(macroName); boolean stopped = false; - for (RunState run : activeRunSnapshot()) { - if (run.running.get() && macroKey(macroName(run.macro)).equals(targetKey)) { - requestStop(run, true); + for (RunState run : MacroLifecycle.activeRunSnapshot()) { + if (run.running.get() && MacroLifecycle.macroKey(MacroLifecycle.macroName(run.macro)).equals(targetKey)) { + MacroLifecycle.requestStop(run, true); stopped = true; } } if (stopped) { synchronized (RUN_LOCK) { - refreshPrimaryRunLocked(); + MacroLifecycle.refreshPrimaryRunLocked(); } AutismClientMessaging.sendPrefixed("\u00a7cMacro stopped: " + macroName); } @@ -1041,16 +486,16 @@ public class MacroExecutor { public static void stopMacro(AutismMacro macro) { if (macro == null) return; boolean stopped = false; - String displayName = macroName(macro); - for (RunState run : activeRunSnapshot()) { - if (matchesMacro(run, macro, displayName)) { - requestStop(run, true); + String displayName = MacroLifecycle.macroName(macro); + for (RunState run : MacroLifecycle.activeRunSnapshot()) { + if (MacroLifecycle.matchesMacro(run, macro, displayName)) { + MacroLifecycle.requestStop(run, true); stopped = true; } } if (stopped) { synchronized (RUN_LOCK) { - refreshPrimaryRunLocked(); + MacroLifecycle.refreshPrimaryRunLocked(); } AutismClientMessaging.sendPrefixed("\u00a7cMacro stopped: " + (displayName.isBlank() ? "macro" : displayName)); } diff --git a/src/main/java/autismclient/util/macro/MacroLifecycle.java b/src/main/java/autismclient/util/macro/MacroLifecycle.java new file mode 100644 index 0000000..9856e1c --- /dev/null +++ b/src/main/java/autismclient/util/macro/MacroLifecycle.java @@ -0,0 +1,623 @@ +package autismclient.util.macro; + +import autismclient.modules.PackHideState; +import autismclient.util.AutismClientMessaging; +import autismclient.util.AutismInstaBreakRenderer; +import autismclient.util.AutismMacro; +import autismclient.util.macro.MacroActionResources.SharedClientResource; +import net.minecraft.client.Minecraft; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReentrantLock; + +final class MacroLifecycle { + private MacroLifecycle() { + } + private static java.util.Map flowLabels(MacroExecutor.RunState run, AutismMacro macro) { + java.util.Map cached = run.labelIndex; + if (cached != null) return cached; + java.util.LinkedHashMap built = new java.util.LinkedHashMap<>(); + for (int k = 0; k < macro.actions.size(); k++) { + if (macro.actions.get(k) instanceof LabelAction la) { + String key = la.normalizedName(); + if (!key.isEmpty() && !built.containsKey(key)) built.put(key, k); + } + } + run.labelIndex = built; + return built; + } + + private static Integer resolveFlowTarget(MacroExecutor.RunState run, AutismMacro macro, int i, FlowAction flow, Minecraft mc) { + return switch (flow.target) { + case STOP -> null; + case TOP -> 0; + case END -> macro.actions.size(); + case FORWARD -> i + 1 + Math.max(0, flow.amount); + case BACK -> i - Math.max(0, flow.amount); + case STEP -> Math.max(1, flow.amount) - 1; + case LABEL -> { + String name = LabelAction.normalize(MacroVariables.expand(flow.labelName, mc)); + Integer idx = flowLabels(run, macro).get(name); + if (idx == null) { + AutismClientMessaging.sendPrefixed("§eFlow: label '" + flow.labelName + "' not found."); + yield flow.onMissingLabel == FlowAction.MissingPolicy.STOP ? null : i + 1; + } + yield idx; + } + }; + } + + static int performFlowJump(MacroExecutor.RunState run, AutismMacro macro, int currentI, FlowAction flow, Minecraft mc) { + run.branchElseStart = -1; + run.branchElseCount = 0; + Integer dest = resolveFlowTarget(run, macro, currentI, flow, mc); + if (dest == null) return Integer.MIN_VALUE; + int size = macro.actions.size(); + int target = Math.max(0, Math.min(size, dest)); + if (target <= currentI) { + run.totalJumpsThisRun++; + run.jumpBudget++; + if (MacroExecutor.FLOW_JUMP_HARD_CAP >= 0 && run.totalJumpsThisRun > MacroExecutor.FLOW_JUMP_HARD_CAP) { + AutismClientMessaging.sendPrefixed("§cMacro aborted: jump limit exceeded (runaway loop)."); + return Integer.MIN_VALUE; + } + if (run.jumpBudget >= MacroExecutor.FLOW_JUMP_BURST_CAP) { + run.jumpBudget = 0; + + try { MacroRunLoop.waitForCondition(MacroConditionRegistry.waitForNextTick()); } catch (Exception ignored) { } + } + } else { + run.jumpBudget = 0; + } + return target - 1; + } + + static boolean isCurrentRunActive() { + if (PackHideState.isHardLocked()) return false; + MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); + if (run != null) return run.running.get(); + return MacroExecutor.isRunning.get(); + } + + public static boolean isCurrentActionRunActive() { + return isCurrentRunActive(); + } + + static CopyOnWriteArrayList currentPersistentActions() { + MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); + return run != null ? run.persistentActions : MacroExecutor.persistentActions; + } + + static ConcurrentHashMap currentBackgroundMoves() { + MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); + return run != null ? run.backgroundMoves : MacroExecutor.backgroundMoves; + } + + static void setCurrentStatus(String status) { + MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); + if (run != null) run.status = status == null ? "" : status; + MacroExecutor.currentStatus = status == null ? "" : status; + } + + static void setCurrentStep(int step, int total) { + MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); + if (run != null) { + run.currentStepIndex = step; + run.totalSteps = total; + } + MacroExecutor.currentStepIndex = step; + MacroExecutor.totalSteps = total; + } + + static void markStepCompleted(int stepOneBased) { + MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); + if (run != null) { + run.lastCompletedStep = Math.max(run.lastCompletedStep, stepOneBased); + } + } + + static int stepOverrideEndIndex(AutismMacro macro, int headerIndex, int coveredRows) { + int last = macro == null ? headerIndex : macro.actions.size() - 1; + long end = (long) headerIndex + Math.max(0, coveredRows); + return (int) Math.max(headerIndex, Math.min(last, end)); + } + + static void armFpsStepOverride(MacroExecutor.RunState run, int headerIndex, int endIndexInclusive, int fpsLimit) { + if (run == null) return; + run.fpsStepHeaderIndex = headerIndex; + run.fpsStepEndIndex = endIndexInclusive; + FpsLimitController.applyUntilCleared(run.id, fpsLimit); + } + + static void armPingStepOverride(MacroExecutor.RunState run, int headerIndex, int endIndexInclusive, + int delayMs, boolean realIncoming, boolean realOutgoing) { + if (run == null) return; + run.pingStepHeaderIndex = headerIndex; + run.pingStepEndIndex = endIndexInclusive; + PingSpoofController.applyUntilCleared(run.id, delayMs, realIncoming, realOutgoing); + } + + static void clearFpsStepOverride(MacroExecutor.RunState run) { + if (run == null || run.fpsStepHeaderIndex < 0) return; + run.fpsStepHeaderIndex = -1; + run.fpsStepEndIndex = -1; + FpsLimitController.clear(run.id); + } + + static void clearPingStepOverride(MacroExecutor.RunState run) { + if (run == null || run.pingStepHeaderIndex < 0) return; + run.pingStepHeaderIndex = -1; + run.pingStepEndIndex = -1; + PingSpoofController.clearMacro(run.id); + } + + static void awaitBackgroundTimedOverrides(MacroExecutor.RunState run) throws InterruptedException { + if (run == null) return; + + long deadline = Math.max(run.fpsBackgroundDeadlineNanos, run.pingBackgroundDeadlineNanos); + long remaining; + while (isCurrentRunActive() && (remaining = deadline - System.nanoTime()) > 0L) { + Thread.sleep(Math.min(25L, remaining / 1_000_000L + 1L)); + } + } + + static void updateStepBoundOverrides(MacroExecutor.RunState run, int index) { + if (run == null) return; + if (run.fpsStepHeaderIndex >= 0 && (index > run.fpsStepEndIndex || index <= run.fpsStepHeaderIndex)) { + clearFpsStepOverride(run); + } + if (run.pingStepHeaderIndex >= 0 && (index > run.pingStepEndIndex || index <= run.pingStepHeaderIndex)) { + clearPingStepOverride(run); + } + } + + static void stopCurrentRun() { + MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); + if (run != null) { + run.running.set(false); + } else { + MacroExecutor.stop(); + } + } + + static void stopCurrentActionRun() { + stopCurrentRun(); + } + + private static EnumSet resourcesForAction(MacroAction action) { + return MacroActionResources.resourcesForAction(action); + } + + static EnumSet acquireClientResources(MacroAction action) throws InterruptedException { + return acquireClientResources(resourcesForAction(action)); + } + + static EnumSet acquireClientResources(EnumSet resources) throws InterruptedException { + EnumSet acquired = EnumSet.noneOf(SharedClientResource.class); + try { + for (SharedClientResource resource : SharedClientResource.values()) { + if (resources.contains(resource)) { + if (!isCurrentRunActive()) throw new InterruptedException("Macro stopped"); + MacroExecutor.SHARED_RESOURCE_LOCKS.get(resource).lockInterruptibly(); + acquired.add(resource); + if (!isCurrentRunActive()) throw new InterruptedException("Macro stopped"); + } + } + } catch (InterruptedException e) { + releaseClientResources(acquired); + throw e; + } + return acquired; + } + + static EnumSet resourcesForActions(java.util.List actions) { + return MacroActionResources.resourcesForActions(actions); + } + + static void releaseClientResources(EnumSet resources) { + if (resources == null || resources.isEmpty()) return; + SharedClientResource[] ordered = SharedClientResource.values(); + for (int i = ordered.length - 1; i >= 0; i--) { + SharedClientResource resource = ordered[i]; + if (resources.contains(resource)) { + ReentrantLock lock = MacroExecutor.SHARED_RESOURCE_LOCKS.get(resource); + if (lock.isHeldByCurrentThread()) lock.unlock(); + } + } + } + + static MacroVariableContext currentVariableContext() { + MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); + return run == null ? null : run.variables; + } + + static void withRunContext(MacroExecutor.RunState run, Runnable task) { + MacroExecutor.RunState previous = MacroExecutor.CURRENT_RUN.get(); + if (run != null) MacroExecutor.CURRENT_RUN.set(run); + try { + task.run(); + } finally { + if (previous != null) MacroExecutor.CURRENT_RUN.set(previous); + else MacroExecutor.CURRENT_RUN.remove(); + } + } + + static MacroExecutor.InlineNextActions collectInlineNextActions(java.util.List actions, int currentIndex) { + if (actions == null || currentIndex < 0 || currentIndex >= actions.size() - 1) return MacroExecutor.InlineNextActions.empty(); + java.util.ArrayList collected = new java.util.ArrayList<>(); + int lastIndex = -1; + for (int j = currentIndex + 1; j < actions.size(); j++) { + MacroAction candidate = actions.get(j); + if (candidate instanceof DisconnectAction + || candidate instanceof RaceAction + || candidate instanceof ReportAction + || candidate instanceof RepeatAction + || candidate instanceof BranchAction + || candidate instanceof FinallyAction) { + break; + } + if (candidate == null || !candidate.isEnabled()) continue; + if (!RaceAction.isBodyAction(candidate)) continue; + collected.add(candidate); + lastIndex = j; + } + return collected.isEmpty() ? MacroExecutor.InlineNextActions.empty() : new MacroExecutor.InlineNextActions(java.util.List.copyOf(collected), lastIndex); + } + + private static volatile java.util.List ACTIVE_RUN_LIST = java.util.List.of(); + + public static void rebuildActiveRunListLocked() { + ACTIVE_RUN_LIST = java.util.List.copyOf(MacroExecutor.ACTIVE_RUNS.values()); + } + + static java.util.List activeRunSnapshot() { + return ACTIVE_RUN_LIST; + } + + static void finishCurrentRun() { + MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); + if (run == null) return; + if (!run.finished.compareAndSet(false, true)) return; + requestStop(run, false); + + clearFpsStepOverride(run); + clearPingStepOverride(run); + + synchronized (MacroExecutor.RUN_LOCK) { + MacroExecutor.ACTIVE_RUNS.remove(run.id); + MacroExecutor.RUNS_BY_ID.remove(run.id); + rebuildActiveRunListLocked(); + if (MacroExecutor.ACTIVE_RUNS.isEmpty()) MacroCaptureAutofill.allRunsStoppedAtMs = System.currentTimeMillis(); + MacroExecutor.RUN_STATE_REVISION.incrementAndGet(); + refreshPrimaryRunLocked(); + } + if (!MacroExecutor.isRunning.get()) { + AutismInstaBreakRenderer.clear(); + + FpsLimitController.clearAll(); + PingSpoofController.clearAllMacros(); + } + MacroExecutor.CURRENT_RUN.remove(); + } + + private static boolean hasRunningRunsLocked() { + for (MacroExecutor.RunState run : MacroExecutor.ACTIVE_RUNS.values()) { + if (run.running.get()) return true; + } + return false; + } + + private static MacroExecutor.RunState firstVisibleRunLocked() { + for (MacroExecutor.RunState run : MacroExecutor.ACTIVE_RUNS.values()) { + if (run.running.get() && !run.options.hiddenFromProgressHud()) return run; + } + return null; + } + + public static int activeRunCountLocked() { + int count = 0; + for (MacroExecutor.RunState run : MacroExecutor.ACTIVE_RUNS.values()) { + if (run.running.get()) count++; + } + return count; + } + + static boolean hasMacroCapacity(int activeCount) { + return Math.max(0, activeCount) < MacroExecutor.MAX_CONCURRENT_MACROS; + } + + public static void refreshPrimaryRunLocked() { + MacroExecutor.primaryRun = firstVisibleRunLocked(); + MacroExecutor.visibleRunActive = MacroExecutor.primaryRun != null; + MacroExecutor.currentMacro = MacroExecutor.primaryRun != null ? MacroExecutor.primaryRun.macro : null; + MacroExecutor.currentStatus = MacroExecutor.primaryRun != null ? MacroExecutor.primaryRun.status : ""; + MacroExecutor.currentStepIndex = MacroExecutor.primaryRun != null ? MacroExecutor.primaryRun.currentStepIndex : -1; + MacroExecutor.totalSteps = MacroExecutor.primaryRun != null ? MacroExecutor.primaryRun.totalSteps : 0; + MacroExecutor.isRunning.set(hasRunningRunsLocked()); + } + + public static boolean hasRunningRuns() { + synchronized (MacroExecutor.RUN_LOCK) { + return hasRunningRunsLocked(); + } + } + + public static boolean isVisibleRunning() { + return MacroExecutor.visibleRunActive; + } + + public static boolean isControllingInput() { + ReentrantLock inputLock = MacroExecutor.SHARED_RESOURCE_LOCKS.get(SharedClientResource.INPUT); + if (inputLock != null && inputLock.isLocked()) return true; + if (!MacroExecutor.backgroundMoves.isEmpty()) return true; + for (MacroAction action : MacroExecutor.persistentActions) { + if (action instanceof MoveAction || action instanceof JumpAction || action instanceof SneakAction || action instanceof SprintAction) return true; + } + synchronized (MacroExecutor.RUN_LOCK) { + for (MacroExecutor.RunState run : MacroExecutor.ACTIVE_RUNS.values()) { + if (run == null || !run.running.get()) continue; + if (!run.backgroundMoves.isEmpty()) return true; + for (MacroAction action : run.persistentActions) { + if (action instanceof MoveAction || action instanceof JumpAction || action instanceof SneakAction || action instanceof SprintAction) return true; + } + } + } + return false; + } + + static void broadcastStepProgress(MacroExecutor.RunState run, int step, int total, String macroName) { + if (run != null && run.options.skipLanProgress()) return; + try { + autismclient.util.AutismLANSync sync = autismclient.util.AutismLANSync.getInstance(); + if (sync.isInSession()) { + sync.broadcastStepProgress(step, total, macroName); + } + } catch (Exception ignored) { } + } + + public static void requestStop(MacroExecutor.RunState run, boolean interruptThread) { + if (run == null) return; + if (run.running.getAndSet(false)) { + MacroExecutor.RUN_STATE_REVISION.incrementAndGet(); + } + run.persistentActions.clear(); + for (MacroExecutor.PrearmedWait wait : new ArrayList<>(run.prearmedWaits.values())) { + wait.cleanup(); + } + run.prearmedWaits.clear(); + releaseBackgroundMoves(run.backgroundMoves, Minecraft.getInstance(), run); + run.backgroundMoves.clear(); + reconcilePersistentInput(Minecraft.getInstance()); + synchronized (run.packetWaitLock) { + if (run.packetFuture != null) run.packetFuture.cancel(true); + run.packetFuture = null; + run.waitingForPacket.set(false); + run.waitingPacketName.set(""); + } + CompletableFuture chatFuture = run.chatFuture; + if (chatFuture != null) chatFuture.cancel(true); + run.chatFuture = null; + run.waitingForChat.set(false); + run.waitingChatAction = null; + CompletableFuture baritoneFuture = run.baritoneGoalFuture; + if (baritoneFuture != null) baritoneFuture.cancel(true); + run.baritoneGoalFuture = null; + run.activeMineTracker = null; + Minecraft mc = Minecraft.getInstance(); + PacketGateManager.clearOwnerAndFlushConfigured(run.id, mc == null ? null : mc.getConnection()); + FpsLimitController.clear(run.id); + PingSpoofController.clearMacro(run.id); + MacroRender.cancelRotation(run); + MacroWorldActions.requestOwnedBaritoneStop(run, mc); + Thread thread = run.macroThread; + if (interruptThread && thread != null && thread != Thread.currentThread()) { + thread.interrupt(); + } + } + + static void releaseBackgroundMoves(ConcurrentHashMap moves, Minecraft mc, MacroExecutor.RunState owner) { + if (moves == null || moves.isEmpty() || mc == null) return; + List toRelease = new ArrayList<>(moves.keySet()); + mc.execute(() -> { + for (MoveAction move : toRelease) { + try { + releaseMoveIfUnused(owner, move, mc); + } catch (Exception ignored) { } + } + }); + } + + static void releaseMoveIfUnused(MacroExecutor.RunState owner, MoveAction move, Minecraft mc) { + if (move == null || mc == null) return; + boolean stillOwned = false; + synchronized (MacroExecutor.RUN_LOCK) { + for (MacroExecutor.RunState active : MacroExecutor.ACTIVE_RUNS.values()) { + if (active == owner || !active.running.get()) continue; + for (MoveAction other : active.backgroundMoves.keySet()) { + if (other.direction == move.direction) { + stillOwned = true; + break; + } + } + if (stillOwned) break; + } + } + if (!stillOwned && owner != null) { + for (MoveAction other : MacroExecutor.backgroundMoves.keySet()) { + if (other.direction == move.direction) { + stillOwned = true; + break; + } + } + } + if (!stillOwned) move.release(mc); + } + + public static void reconcilePersistentInput(Minecraft mc) { + if (mc == null) return; + mc.execute(() -> { + applyAggregateSneakState(mc); + applyAggregateSprintState(mc); + }); + } + + static void applyAggregateSneakState(Minecraft mc) { + if (mc == null || mc.options == null || mc.options.keyShift == null) return; + boolean held = hasPersistentInput(SneakAction.class); + mc.options.keyShift.setDown(held); + } + + static void applyAggregateSprintState(Minecraft mc) { + if (mc == null) return; + boolean held = hasPersistentInput(SprintAction.class); + if (mc.options != null && mc.options.keySprint != null) mc.options.keySprint.setDown(held); + if (mc.player != null) mc.player.setSprinting(held); + } + + private static boolean hasPersistentInput(Class type) { + for (MacroAction action : MacroExecutor.persistentActions) { + if (type.isInstance(action)) return true; + } + synchronized (MacroExecutor.RUN_LOCK) { + for (MacroExecutor.RunState run : MacroExecutor.ACTIVE_RUNS.values()) { + if (!run.running.get()) continue; + for (MacroAction action : run.persistentActions) { + if (type.isInstance(action)) return true; + } + } + } + return false; + } + + public static String macroKey(String macroName) { + return macroName == null ? "" : macroName.trim().toLowerCase(Locale.ROOT); + } + + public static String macroName(AutismMacro macro) { + return macro != null && macro.name != null ? macro.name : ""; + } + + public static boolean matchesMacro(MacroExecutor.RunState run, AutismMacro macro, String macroName) { + if (run == null || !run.running.get()) return false; + if (macro != null && (run.sourceMacro == macro || run.macro == macro)) return true; + String targetKey = macroKey(macroName); + if (targetKey.isEmpty() && macro != null) targetKey = macroKey(macro.name); + return !targetKey.isEmpty() && macroKey(macroName(run.macro)).equals(targetKey); + } + + public static void execute(AutismMacro macro) { + executeTracked(macro); + } + + public static long executeTracked(AutismMacro macro) { + return executeTracked(macro, MacroExecutor.RunOptions.NORMAL); + } + + public static long executeTracked(AutismMacro macro, MacroExecutor.RunOptions options) { + if (PackHideState.isHardLocked()) return -1L; + MacroExecutor.RunOptions runOptions = options == null ? MacroExecutor.RunOptions.NORMAL : options; + if (macro == null || macro.actions == null || macro.actions.isEmpty()) { + if (runOptions.silentLifecycle()) return -1L; + AutismClientMessaging.sendPrefixed("\u00a7cMacro has no actions!"); + return -1L; + } + + AutismMacro executionMacro; + try { + executionMacro = macro.deepCopy(); + } catch (Throwable copyError) { + if (!runOptions.silentLifecycle()) AutismClientMessaging.sendPrefixed("\u00a7cCould not prepare macro run."); + return -1L; + } + if (executionMacro == null || executionMacro.actions == null || executionMacro.actions.isEmpty()) return -1L; + + MacroExecutor.RunState runState; + synchronized (MacroExecutor.RUN_LOCK) { + String name = macro.name == null ? "" : macro.name; + String nameKey = macroKey(name); + if (!runOptions.backgroundRun()) { + for (MacroExecutor.RunState active : MacroExecutor.ACTIVE_RUNS.values()) { + if (active.options.backgroundRun()) continue; + String activeName = active.macro != null && active.macro.name != null ? active.macro.name : ""; + if (active.running.get() && macroKey(activeName).equals(nameKey)) { + if (!runOptions.silentLifecycle()) AutismClientMessaging.sendPrefixed("\u00a7eMacro already running: " + name); + return -1L; + } + } + if (!hasMacroCapacity(activeRunCountLocked())) { + if (!runOptions.silentLifecycle()) AutismClientMessaging.sendPrefixed("\u00a7cOnly " + MacroExecutor.MAX_CONCURRENT_MACROS + " macros can run at the same time."); + return -1L; + } + } else if (!hasMacroCapacity(activeRunCountLocked())) { + return -1L; + } + runState = new MacroExecutor.RunState(MacroExecutor.NEXT_RUN_ID.getAndIncrement(), macro, executionMacro, runOptions); + if (MacroExecutor.ACTIVE_RUNS.isEmpty()) MacroCaptureAutofill.expireSuggestionCacheAfterIdle(); + MacroExecutor.ACTIVE_RUNS.put(runState.id, runState); + MacroExecutor.RUNS_BY_ID.put(runState.id, runState); + rebuildActiveRunListLocked(); + MacroExecutor.RUN_STATE_REVISION.incrementAndGet(); + refreshPrimaryRunLocked(); + } + if (!runOptions.silentLifecycle()) AutismClientMessaging.sendPrefixed("\u00a7aStarted macro: " + macro.name); + + broadcastStepProgress(runState, 0, executionMacro.actions.size(), executionMacro.name); + + Thread thread = new Thread(() -> MacroRunLoop.run(runState), "Autism-Macro-" + runState.id); + thread.setDaemon(true); + MacroExecutor.macroThread = thread; + runState.macroThread = thread; + try { + thread.start(); + } catch (Throwable startError) { + + requestStop(runState, false); + synchronized (MacroExecutor.RUN_LOCK) { + MacroExecutor.ACTIVE_RUNS.remove(runState.id); + MacroExecutor.RUNS_BY_ID.remove(runState.id); + rebuildActiveRunListLocked(); + if (MacroExecutor.ACTIVE_RUNS.isEmpty()) MacroCaptureAutofill.allRunsStoppedAtMs = System.currentTimeMillis(); + MacroExecutor.RUN_STATE_REVISION.incrementAndGet(); + refreshPrimaryRunLocked(); + } + return -1L; + } + return runState.id; + } + + public static boolean isRunActive(long id) { + if (id < 0L) return false; + MacroExecutor.RunState run = MacroExecutor.RUNS_BY_ID.get(id); + return run != null && run.running.get(); + } + + public static long runStateRevision() { + return MacroExecutor.RUN_STATE_REVISION.get(); + } + + public static long currentRunId() { + MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); + return run == null ? -1L : run.id; + } + + public static void stopRun(long id) { + if (id < 0L) return; + MacroExecutor.RunState run; + synchronized (MacroExecutor.RUN_LOCK) { + run = MacroExecutor.ACTIVE_RUNS.get(id); + } + if (run == null) return; + requestStop(run, true); + synchronized (MacroExecutor.RUN_LOCK) { + refreshPrimaryRunLocked(); + } + } +} diff --git a/src/main/java/autismclient/util/macro/MacroPacketObserve.java b/src/main/java/autismclient/util/macro/MacroPacketObserve.java index 4c7914d..098a39a 100644 --- a/src/main/java/autismclient/util/macro/MacroPacketObserve.java +++ b/src/main/java/autismclient/util/macro/MacroPacketObserve.java @@ -147,7 +147,7 @@ final class MacroPacketObserve { if (PackHideState.isHardLocked()) return; MacroChatObserve.syncRecentChatServerContext(); - java.util.List runs = MacroExecutor.activeRunSnapshot(); + java.util.List runs = MacroLifecycle.activeRunSnapshot(); boolean s2c = "S2C".equals(direction); boolean chatWork = false; boolean mineWork = false; @@ -174,7 +174,7 @@ final class MacroPacketObserve { if (f != null) f.complete(null); } } - if (MacroExecutor.isCurrentRunActive() && MacroExecutor.isWaitingForChat.get() && MacroChatObserve.matchesWaitingChat(capture)) { + if (MacroLifecycle.isCurrentRunActive() && MacroExecutor.isWaitingForChat.get() && MacroChatObserve.matchesWaitingChat(capture)) { MacroExecutor.lastMatchedChat.set(capture.displayText()); CompletableFuture f = MacroExecutor.activeChatFuture; if (f != null) f.complete(null); @@ -190,7 +190,7 @@ final class MacroPacketObserve { } } - if (!MacroExecutor.isCurrentRunActive()) return; + if (!MacroLifecycle.isCurrentRunActive()) return; if (packetWork) { for (MacroExecutor.RunState run : runs) { diff --git a/src/main/java/autismclient/util/macro/MacroPacketWait.java b/src/main/java/autismclient/util/macro/MacroPacketWait.java index 344b7d1..9765c66 100644 --- a/src/main/java/autismclient/util/macro/MacroPacketWait.java +++ b/src/main/java/autismclient/util/macro/MacroPacketWait.java @@ -78,7 +78,7 @@ final class MacroPacketWait { run.waitingForPacket.set(true); } try { - MacroExecutor.setCurrentStatus(normalizedTarget.isEmpty() + MacroLifecycle.setCurrentStatus(normalizedTarget.isEmpty() ? "Waiting for packet: Any" : "Waiting for packet: " + WaitForPacketAction.getDisplayLabel(normalizedTarget)); MacroRunLoop.waitForCondition(future); @@ -102,7 +102,7 @@ final class MacroPacketWait { MacroExecutor.isWaitingForPacket.set(true); } try { - MacroExecutor.setCurrentStatus(normalizedTarget.isEmpty() + MacroLifecycle.setCurrentStatus(normalizedTarget.isEmpty() ? "Waiting for packet: Any" : "Waiting for packet: " + WaitForPacketAction.getDisplayLabel(normalizedTarget)); MacroRunLoop.waitForCondition(future); diff --git a/src/main/java/autismclient/util/macro/MacroPrearm.java b/src/main/java/autismclient/util/macro/MacroPrearm.java index 1bb86d4..661ca7c 100644 --- a/src/main/java/autismclient/util/macro/MacroPrearm.java +++ b/src/main/java/autismclient/util/macro/MacroPrearm.java @@ -22,9 +22,9 @@ final class MacroPrearm { public static CompletableFuture predicateFuture(java.util.function.BooleanSupplier predicate, int timeoutMs) { CompletableFuture future = new CompletableFuture<>(); MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); - Thread worker = new Thread(() -> MacroExecutor.withRunContext(run, () -> { + Thread worker = new Thread(() -> MacroLifecycle.withRunContext(run, () -> { long start = System.currentTimeMillis(); - while (!future.isDone() && MacroExecutor.isCurrentRunActive()) { + while (!future.isDone() && MacroLifecycle.isCurrentRunActive()) { try { if (predicate.getAsBoolean()) { future.complete(null); @@ -400,9 +400,9 @@ final class MacroPrearm { java.util.concurrent.atomic.AtomicBoolean active = new java.util.concurrent.atomic.AtomicBoolean(true); CompletableFuture future = new CompletableFuture<>(); MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); - Thread worker = new Thread(() -> MacroExecutor.withRunContext(run, () -> { + Thread worker = new Thread(() -> MacroLifecycle.withRunContext(run, () -> { long start = System.currentTimeMillis(); - while (active.get() && MacroExecutor.isCurrentRunActive() && !future.isDone()) { + while (active.get() && MacroLifecycle.isCurrentRunActive() && !future.isDone()) { try { if (predicate.getAsBoolean()) { future.complete(null); diff --git a/src/main/java/autismclient/util/macro/MacroRace.java b/src/main/java/autismclient/util/macro/MacroRace.java index 56af6f5..4d3a9cc 100644 --- a/src/main/java/autismclient/util/macro/MacroRace.java +++ b/src/main/java/autismclient/util/macro/MacroRace.java @@ -92,7 +92,7 @@ final class MacroRace { public static void waitForMacroStep(WaitForMacroStepAction action) { long startMs = System.currentTimeMillis(); - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { if (isMacroStepSatisfied(action)) return; if (action.timeoutMs > 0 && System.currentTimeMillis() - startMs >= action.timeoutMs) return; CompletableFuture tick = MacroConditionRegistry.waitForNextTick(); @@ -129,7 +129,7 @@ final class MacroRace { else if (RaceAction.isBodyAction(child)) bodyActions.add(child); } - MacroExecutor.setCurrentStatus(conditions.isEmpty() + MacroLifecycle.setCurrentStatus(conditions.isEmpty() ? "Race: dispatching" : "Race: waiting for " + (conditions.size() == 1 ? conditions.get(0).getDisplayName() : conditions.size() + " conditions")); @@ -154,11 +154,11 @@ final class MacroRace { triggerFuture.cancel(true); bodyFuture.cancel(true); AutismClientMessaging.sendPrefixed("\u00A7eRace timed out: " + (race.label == null || race.label.isBlank() ? "Race" : race.label)); - MacroExecutor.setCurrentStatus("Race: timeout"); + MacroLifecycle.setCurrentStatus("Race: timeout"); return bodyCount; } - MacroExecutor.setCurrentStatus("Race: fired"); + MacroLifecycle.setCurrentStatus("Race: fired"); waitForTimedFuture(bodyFuture, 250); return bodyCount; } @@ -208,7 +208,7 @@ final class MacroRace { public static int runReportGroup(Minecraft mc, java.util.List actions, int headerIndex, ReportAction report) throws InterruptedException { int conditionCount = report.normalizedConditionCount(actions, headerIndex); if (conditionCount < 2 || headerIndex + 2 >= actions.size()) { - MacroExecutor.setCurrentStatus(report.getDisplayName()); + MacroLifecycle.setCurrentStatus(report.getDisplayName()); report.execute(mc); return conditionCount; } @@ -218,13 +218,13 @@ final class MacroRace { if (RaceAction.isBodyAction(startCondition) && RaceAction.isConditionAction(endCondition)) { int timeoutMs = Math.max(100, report.timeoutMs); String label = report.reportLabel == null || report.reportLabel.isBlank() ? "Report" : report.reportLabel.trim(); - MacroExecutor.setCurrentStatus("Report: start " + startCondition.getDisplayName()); + MacroLifecycle.setCurrentStatus("Report: start " + startCondition.getDisplayName()); CompletableFuture startAnchor = startActionAnchorFuture(startCondition); MacroDispatcher.executeSingleActionWithWaits(mc, startCondition, null); - if (!MacroExecutor.isCurrentRunActive()) return conditionCount; + if (!MacroLifecycle.isCurrentRunActive()) return conditionCount; MacroExecutor.MacroEvent startEvent = waitForAnchorOrNow(startAnchor, 250, startCondition.getDisplayName(), "client action"); - MacroExecutor.setCurrentStatus("Report: waiting end " + endCondition.getDisplayName()); + MacroLifecycle.setCurrentStatus("Report: waiting end " + endCondition.getDisplayName()); CompletableFuture endFuture = timedConditionFuture(mc, endCondition); MacroExecutor.MacroEvent endEvent = waitForTimedEvent(endFuture, timeoutMs); if (endEvent == null) { @@ -251,7 +251,7 @@ final class MacroRace { int timeoutMs = Math.max(100, report.timeoutMs); long startWaitNanos = System.nanoTime(); - MacroExecutor.setCurrentStatus("Report: waiting start " + startCondition.getDisplayName()); + MacroLifecycle.setCurrentStatus("Report: waiting start " + startCondition.getDisplayName()); boolean startFired = waitForMacroCondition(mc, startCondition, timeoutMs); if (!startFired) { AutismClientMessaging.sendPrefixed("\u00A7eReport \"" + report.reportLabel + "\": timeout waiting for start condition"); @@ -261,7 +261,7 @@ final class MacroRace { MacroExecutor.MacroEvent startEvent = new MacroExecutor.MacroEvent(null, "condition " + startCondition.getDisplayName(), System.nanoTime(), null); long spentMs = (startEvent.nanoTime() - startWaitNanos) / 1_000_000L; int remainingMs = (int) Math.max(1, timeoutMs - spentMs); - MacroExecutor.setCurrentStatus("Report: waiting end " + endCondition.getDisplayName()); + MacroLifecycle.setCurrentStatus("Report: waiting end " + endCondition.getDisplayName()); CompletableFuture endFuture = timedConditionFuture(mc, endCondition); MacroExecutor.MacroEvent endEvent = waitForTimedEvent(endFuture, remainingMs); if (endEvent == null) { @@ -318,7 +318,7 @@ final class MacroRace { if (multi.connectIfDown) { if (!manager.isActive()) { - MacroExecutor.setCurrentStatus("Multi: starting batch"); + MacroLifecycle.setCurrentStatus("Multi: starting batch"); autismclient.util.multi.MultiManager.StartResult started = manager.start(profile); if (!started.ok()) { @@ -335,17 +335,17 @@ final class MacroRace { } } } - if (!MacroExecutor.isCurrentRunActive()) return stepCount; + if (!MacroLifecycle.isCurrentRunActive()) return stepCount; int waitMs = Math.max(0, multi.waitMs); if (MultiAction.WAIT_UNTIL_READY.equals(multi.waitMode)) { - MacroExecutor.setCurrentStatus("Multi: waiting for " + scope.size() + (scope.size() == 1 ? " account" : " accounts")); + MacroLifecycle.setCurrentStatus("Multi: waiting for " + scope.size() + (scope.size() == 1 ? " account" : " accounts")); multiWaitUntilReady(manager, scope, waitMs); } else if (MultiAction.WAIT_FIXED_DELAY.equals(multi.waitMode) && waitMs > 0) { - MacroExecutor.setCurrentStatus("Multi: delay " + waitMs + " ms"); + MacroLifecycle.setCurrentStatus("Multi: delay " + waitMs + " ms"); multiSleepCancellable(waitMs); } - if (!MacroExecutor.isCurrentRunActive()) return stepCount; + if (!MacroLifecycle.isCurrentRunActive()) return stepCount; AutismMacro subMacro = new AutismMacro(); subMacro.name = (macroName == null || macroName.isBlank() ? "Macro" : macroName) + " (Multi)"; @@ -356,13 +356,13 @@ final class MacroRace { if (copy != null) subMacro.actions.add(copy); } - MacroExecutor.setCurrentStatus("Multi: running on " + scope.size() + (scope.size() == 1 ? " account" : " accounts")); + MacroLifecycle.setCurrentStatus("Multi: running on " + scope.size() + (scope.size() == 1 ? " account" : " accounts")); autismclient.util.multi.MultiManager.BroadcastResult result = manager.runMacroDirect(subMacro, scope); AutismClientMessaging.sendPrefixed("\u00A7bMulti: " + result.summary()); - MacroExecutor.setCurrentStatus("Multi: waiting for completion"); + MacroLifecycle.setCurrentStatus("Multi: waiting for completion"); multiWaitForCompletion(manager, scope, subMacro.name); - if (!MacroExecutor.isCurrentRunActive()) return stepCount; + if (!MacroLifecycle.isCurrentRunActive()) return stepCount; if (multi.disconnectAfter) { for (String accountId : scope) { @@ -386,14 +386,14 @@ final class MacroRace { long deadline = System.nanoTime() + Math.max(0L, totalMs) * 1_000_000L; long remaining; while ((remaining = deadline - System.nanoTime()) > 0L) { - if (!MacroExecutor.isCurrentRunActive()) return; + if (!MacroLifecycle.isCurrentRunActive()) return; Thread.sleep(Math.min(100L, Math.max(1L, remaining / 1_000_000L))); } } private static void multiWaitUntilReady(autismclient.util.multi.MultiManager manager, java.util.Set scope, long timeoutMs) throws InterruptedException { long deadline = System.nanoTime() + Math.max(0L, timeoutMs) * 1_000_000L; - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { boolean allReady = true; java.util.Map byId = multiSnapshotsById(manager); for (String accountId : scope) { @@ -415,7 +415,7 @@ final class MacroRace { private static void multiWaitForCompletion(autismclient.util.multi.MultiManager manager, java.util.Set scope, String subMacroName) throws InterruptedException { long deadline = System.nanoTime() + 10L * 60L * 1_000_000_000L; Thread.sleep(200L); - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { boolean anyPending = false; java.util.Map byId = multiSnapshotsById(manager); for (String accountId : scope) { @@ -464,7 +464,7 @@ final class MacroRace { if (run != null) MacroExecutor.CURRENT_RUN.set(run); EnumSet heldResources = EnumSet.noneOf(SharedClientResource.class); try { - heldResources = MacroExecutor.acquireClientResources(MacroExecutor.resourcesForActions(bodyActions)); + heldResources = MacroLifecycle.acquireClientResources(MacroLifecycle.resourcesForActions(bodyActions)); Throwable firstFailure = null; for (MacroAction body : bodyActions) { if (body == null || !body.isEnabled() || !RaceAction.isBodyAction(body)) continue; @@ -490,7 +490,7 @@ final class MacroRace { AutismClientMessaging.sendPrefixed("\u00A7cRace action failed: " + safeThrowableMessage(t)); bodyFuture.completeExceptionally(t); } finally { - MacroExecutor.releaseClientResources(heldResources); + MacroLifecycle.releaseClientResources(heldResources); if (previous != null) MacroExecutor.CURRENT_RUN.set(previous); else MacroExecutor.CURRENT_RUN.remove(); } @@ -564,7 +564,7 @@ final class MacroRace { try { if (timeoutMs <= 0) future.get(); else future.get(timeoutMs, TimeUnit.MILLISECONDS); - return !future.isCancelled() && MacroExecutor.isCurrentRunActive(); + return !future.isCancelled() && MacroLifecycle.isCurrentRunActive(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); future.cancel(true); @@ -594,7 +594,7 @@ final class MacroRace { return CompletableFuture.completedFuture(new MacroExecutor.MacroEvent(null, "condition", System.nanoTime(), null)); } if (trigger instanceof WaitForChatAction chat) { - MacroVariableContext context = MacroExecutor.currentVariableContext(); + MacroVariableContext context = MacroLifecycle.currentVariableContext(); java.util.concurrent.atomic.AtomicReference> captures = new java.util.concurrent.atomic.AtomicReference<>(java.util.Map.of()); MacroPacketObserve.TimedOneShotPacketListener listener = MacroPacketObserve.awaitTimedReceive((packet, direction, now) -> { @@ -693,7 +693,7 @@ final class MacroRace { if (base == null) { CompletableFuture done = new CompletableFuture<>(); MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); - mc.execute(() -> MacroExecutor.withRunContext(run, () -> { + mc.execute(() -> MacroLifecycle.withRunContext(run, () -> { try { MacroDispatcher.executeSingleActionWithWaits(mc, trigger, null); done.complete(new MacroExecutor.MacroEvent(null, trigger.getDisplayName(), System.nanoTime(), null)); @@ -726,10 +726,10 @@ final class MacroRace { } if (trigger instanceof DelayAction delay) { MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); - return CompletableFuture.runAsync(() -> MacroExecutor.withRunContext(run, () -> { + return CompletableFuture.runAsync(() -> MacroLifecycle.withRunContext(run, () -> { try { if (delay.useTicks) { - for (int i = 0; i < delay.delayTicks && MacroExecutor.isCurrentRunActive(); i++) { + for (int i = 0; i < delay.delayTicks && MacroLifecycle.isCurrentRunActive(); i++) { MacroRunLoop.waitForCondition(MacroConditionRegistry.waitForNextTick()); } } else { @@ -743,11 +743,11 @@ final class MacroRace { if (trigger instanceof WaitForGuiAction gui) { CompletableFuture done = new CompletableFuture<>(); MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); - Thread worker = new Thread(() -> MacroExecutor.withRunContext(run, () -> { + Thread worker = new Thread(() -> MacroLifecycle.withRunContext(run, () -> { long start = System.currentTimeMillis(); boolean saw = false; java.util.Map observed = java.util.Map.of(); - while (!done.isDone() && MacroExecutor.isCurrentRunActive()) { + while (!done.isDone() && MacroLifecycle.isCurrentRunActive()) { var captured = gui.captureGui(Minecraft.getInstance().gui.screen()); if (captured.isPresent()) { saw = true; @@ -773,7 +773,7 @@ final class MacroRace { return done; } if (trigger instanceof WaitForChatAction chat) { - MacroVariableContext context = MacroExecutor.currentVariableContext(); + MacroVariableContext context = MacroLifecycle.currentVariableContext(); MacroExecutor.OneShotPacketListener listener = MacroExecutor.awaitReceive(packet -> { MacroExecutor.ChatCapture capture = MacroChatObserve.extractIncomingChat(packet); return capture != null && MacroChatObserve.captureChatAction(chat, capture, context).isPresent(); @@ -900,7 +900,7 @@ final class MacroRace { } if (trigger instanceof RevisionSyncAction) { MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); - return CompletableFuture.runAsync(() -> MacroExecutor.withRunContext(run, () -> { + return CompletableFuture.runAsync(() -> MacroLifecycle.withRunContext(run, () -> { try { MacroDispatcher.executeSingleActionWithWaits(mc, trigger, null); } catch (InterruptedException e) { @@ -916,11 +916,11 @@ final class MacroRace { long start = System.nanoTime(); long timeoutNanos = timeoutMs <= 0 ? Long.MAX_VALUE : timeoutMs * 1_000_000L; future.whenComplete((v, e) -> java.util.concurrent.locks.LockSupport.unpark(t)); - while (!future.isDone() && MacroExecutor.isCurrentRunActive()) { + while (!future.isDone() && MacroLifecycle.isCurrentRunActive()) { if (System.nanoTime() - start >= timeoutNanos) break; java.util.concurrent.locks.LockSupport.parkNanos(MacroExecutor.MACRO_WAIT_POLL_NANOS); if (Thread.interrupted()) break; } - return future.isDone() && !future.isCancelled() && MacroExecutor.isCurrentRunActive(); + return future.isDone() && !future.isCancelled() && MacroLifecycle.isCurrentRunActive(); } } diff --git a/src/main/java/autismclient/util/macro/MacroRender.java b/src/main/java/autismclient/util/macro/MacroRender.java index 550b5a5..cf93258 100644 --- a/src/main/java/autismclient/util/macro/MacroRender.java +++ b/src/main/java/autismclient/util/macro/MacroRender.java @@ -92,7 +92,7 @@ final class MacroRender { static void waitForSmoothRotationCompletion() { MacroExecutor.RunState run = MacroExecutor.CURRENT_RUN.get(); - while (MacroExecutor.isCurrentRunActive() && MacroExecutor.isRotating.get() + while (MacroLifecycle.isCurrentRunActive() && MacroExecutor.isRotating.get() && (run == null || MacroExecutor.ROTATION_OWNER.get() == run)) { java.util.concurrent.locks.LockSupport.parkNanos(1_000_000L); } @@ -119,7 +119,7 @@ final class MacroRender { latch.countDown(); } }); - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { try { if (latch.await(10, java.util.concurrent.TimeUnit.MILLISECONDS)) { break; diff --git a/src/main/java/autismclient/util/macro/MacroRunLoop.java b/src/main/java/autismclient/util/macro/MacroRunLoop.java index 2c30f9c..2e290a0 100644 --- a/src/main/java/autismclient/util/macro/MacroRunLoop.java +++ b/src/main/java/autismclient/util/macro/MacroRunLoop.java @@ -29,7 +29,7 @@ final class MacroRunLoop { try { AutismClientMessaging.sendPrefixed("\u00a7cMacro crashed: " + fatal.getMessage()); } catch (Throwable ignored) { } } } finally { - MacroExecutor.finishCurrentRun(); + MacroLifecycle.finishCurrentRun(); MacroExecutor.CURRENT_RUN.remove(); } } @@ -42,24 +42,24 @@ final class MacroRunLoop { int loopCount = 0; int maxLoops = macro.loop ? (macro.loopCount == -1 ? Integer.MAX_VALUE : macro.loopCount) : 1; - MacroExecutor.currentPersistentActions().clear(); - MacroExecutor.currentBackgroundMoves().clear(); + MacroLifecycle.currentPersistentActions().clear(); + MacroLifecycle.currentBackgroundMoves().clear(); Thread persistentThread = new Thread(() -> { MacroExecutor.CURRENT_RUN.set(runState); try { - while (MacroExecutor.isCurrentRunActive()) { - if (!MacroExecutor.currentPersistentActions().isEmpty() || !MacroExecutor.currentBackgroundMoves().isEmpty()) { + while (MacroLifecycle.isCurrentRunActive()) { + if (!MacroLifecycle.currentPersistentActions().isEmpty() || !MacroLifecycle.currentBackgroundMoves().isEmpty()) { MacroExecutor.RunState scheduledRun = MacroExecutor.CURRENT_RUN.get(); - mc.execute(() -> MacroExecutor.withRunContext(scheduledRun, () -> { + mc.execute(() -> MacroLifecycle.withRunContext(scheduledRun, () -> { ReentrantLock inputLock = MacroExecutor.SHARED_RESOURCE_LOCKS.get(SharedClientResource.INPUT); inputLock.lock(); try { - for (MacroAction pa : MacroExecutor.currentPersistentActions()) { + for (MacroAction pa : MacroLifecycle.currentPersistentActions()) { try { pa.execute(mc); } catch (Exception ignored) { } } - java.util.Iterator> it = MacroExecutor.currentBackgroundMoves().entrySet().iterator(); + java.util.Iterator> it = MacroLifecycle.currentBackgroundMoves().entrySet().iterator(); while (it.hasNext()) { java.util.Map.Entry entry = it.next(); MoveAction bma = entry.getKey(); @@ -68,8 +68,8 @@ final class MacroRunLoop { bma.execute(mc); ticks[0]--; } else { - MacroExecutor.releaseMoveIfUnused(scheduledRun, bma, mc); - MacroExecutor.currentBackgroundMoves().remove(bma); + MacroLifecycle.releaseMoveIfUnused(scheduledRun, bma, mc); + MacroLifecycle.currentBackgroundMoves().remove(bma); } } } finally { @@ -82,12 +82,12 @@ final class MacroRunLoop { CompletableFuture tf = MacroConditionRegistry.waitForNextTick(); tf.get(100, java.util.concurrent.TimeUnit.MILLISECONDS); } catch (Exception e) { - if (!MacroExecutor.isCurrentRunActive()) break; + if (!MacroLifecycle.isCurrentRunActive()) break; } } } finally { - MacroExecutor.releaseBackgroundMoves(MacroExecutor.currentBackgroundMoves(), mc, runState); - MacroExecutor.currentBackgroundMoves().clear(); + MacroLifecycle.releaseBackgroundMoves(MacroLifecycle.currentBackgroundMoves(), mc, runState); + MacroLifecycle.currentBackgroundMoves().clear(); MacroExecutor.CURRENT_RUN.remove(); } }, "Autism-Macro-Persistent-" + runState.id); @@ -95,13 +95,13 @@ final class MacroRunLoop { persistentThread.start(); try { - while (MacroExecutor.isCurrentRunActive() && loopCount < maxLoops) { + while (MacroLifecycle.isCurrentRunActive() && loopCount < maxLoops) { if (macro.actions.isEmpty()) { if (!runState.options.silentLifecycle()) AutismClientMessaging.sendPrefixed("\u00a7cMacro stopped: no actions left."); - MacroExecutor.stopCurrentRun(); + MacroLifecycle.stopCurrentRun(); break; } - MacroExecutor.setCurrentStatus("Loop " + (loopCount + 1) + (maxLoops == Integer.MAX_VALUE ? "" : "/" + maxLoops)); + MacroLifecycle.setCurrentStatus("Loop " + (loopCount + 1) + (maxLoops == Integer.MAX_VALUE ? "" : "/" + maxLoops)); AutismModule module = AutismModule.get(); boolean burstMode = module.usePacketBurstMode(); @@ -114,11 +114,11 @@ final class MacroRunLoop { runState.lastCompletedStep = 0; for (int i = 0; i < macro.actions.size(); i++) { - if (!MacroExecutor.isCurrentRunActive()) break; + if (!MacroLifecycle.isCurrentRunActive()) break; - MacroExecutor.setCurrentStep(i, macro.actions.size()); + MacroLifecycle.setCurrentStep(i, macro.actions.size()); - MacroExecutor.updateStepBoundOverrides(runState, i); + MacroLifecycle.updateStepBoundOverrides(runState, i); if (runState.branchElseStart == i && runState.branchElseCount > 0) { i += runState.branchElseCount - 1; runState.branchElseStart = -1; @@ -182,10 +182,10 @@ final class MacroRunLoop { if (action instanceof FlowAction flow) { if (flow.shouldTake(mc)) { - int newI = MacroExecutor.performFlowJump(runState, macro, i, flow, mc); + int newI = MacroLifecycle.performFlowJump(runState, macro, i, flow, mc); if (newI == Integer.MIN_VALUE) { - MacroExecutor.broadcastStepProgress(runState, i + 1, macro.actions.size(), macro.name); - MacroExecutor.stopCurrentRun(); + MacroLifecycle.broadcastStepProgress(runState, i + 1, macro.actions.size(), macro.name); + MacroLifecycle.stopCurrentRun(); break; } i = newI; @@ -195,7 +195,7 @@ final class MacroRunLoop { MacroPrearm.prearmNextActionWait(mc, macro.actions, i); - EnumSet heldResources = MacroExecutor.acquireClientResources(action); + EnumSet heldResources = MacroLifecycle.acquireClientResources(action); try { if (!MacroActionRunner.waitForGuiBeforeAction(mc, action)) continue; @@ -225,7 +225,7 @@ final class MacroRunLoop { if (da.useTicks) { for (int t = 0; t < da.delayTicks; t++) { - if (!MacroExecutor.isCurrentRunActive()) break; + if (!MacroLifecycle.isCurrentRunActive()) break; CompletableFuture future = MacroConditionRegistry.waitForNextTick(); waitForCondition(future); @@ -236,14 +236,14 @@ final class MacroRunLoop { } } else if (action instanceof CustomMenuAction customMenu) { - MacroExecutor.setCurrentStatus(customMenu.getDisplayName()); + MacroLifecycle.setCurrentStatus(customMenu.getDisplayName()); customMenu.execute(mc); } else if (action instanceof FpsAction fps) { - MacroExecutor.setCurrentStatus(fps.getDisplayName()); + MacroLifecycle.setCurrentStatus(fps.getDisplayName()); if (fps.endMode() == FpsAction.EndMode.TIMEOUT) { - MacroExecutor.clearFpsStepOverride(runState); + MacroLifecycle.clearFpsStepOverride(runState); long fpsDurationNanos = fps.durationMillis() * 1_000_000L; long fpsDeadline = System.nanoTime() + fpsDurationNanos; FpsLimitController.apply(runState.id, Math.max(0, fps.maxFps), fpsDurationNanos); @@ -253,7 +253,7 @@ final class MacroRunLoop { } else { long fpsRemaining; - while (MacroExecutor.isCurrentRunActive() && (fpsRemaining = fpsDeadline - System.nanoTime()) > 0L) { + while (MacroLifecycle.isCurrentRunActive() && (fpsRemaining = fpsDeadline - System.nanoTime()) > 0L) { Thread.sleep(Math.min(25L, fpsRemaining / 1_000_000L + 1L)); } FpsLimitController.clear(runState.id); @@ -264,17 +264,17 @@ final class MacroRunLoop { int covered = fps.endMode() == FpsAction.EndMode.END ? macro.actions.size() - 1 - i : fps.normalizedStepCount(); - int endIndex = MacroExecutor.stepOverrideEndIndex(macro, i, covered); + int endIndex = MacroLifecycle.stepOverrideEndIndex(macro, i, covered); - MacroExecutor.armFpsStepOverride(runState, i, endIndex, Math.max(1, fps.maxFps)); + MacroLifecycle.armFpsStepOverride(runState, i, endIndex, Math.max(1, fps.maxFps)); runState.fpsBackgroundDeadlineNanos = 0L; } } else if (action instanceof SPingAction sping) { - MacroExecutor.setCurrentStatus(sping.getDisplayName()); + MacroLifecycle.setCurrentStatus(sping.getDisplayName()); if (sping.endMode() == SPingAction.EndMode.TIMEOUT) { - MacroExecutor.clearPingStepOverride(runState); + MacroLifecycle.clearPingStepOverride(runState); long spingDurationNanos = sping.durationMillis() * 1_000_000L; long spingDeadline = System.nanoTime() + spingDurationNanos; PingSpoofController.apply(runState.id, Math.max(0, sping.pingDelayMs), @@ -285,7 +285,7 @@ final class MacroRunLoop { } else { long spingRemaining; - while (MacroExecutor.isCurrentRunActive() && (spingRemaining = spingDeadline - System.nanoTime()) > 0L) { + while (MacroLifecycle.isCurrentRunActive() && (spingRemaining = spingDeadline - System.nanoTime()) > 0L) { Thread.sleep(Math.min(25L, spingRemaining / 1_000_000L + 1L)); } PingSpoofController.clearMacro(runState.id); @@ -295,8 +295,8 @@ final class MacroRunLoop { int covered = sping.endMode() == SPingAction.EndMode.END ? macro.actions.size() - 1 - i : sping.normalizedStepCount(); - int endIndex = MacroExecutor.stepOverrideEndIndex(macro, i, covered); - MacroExecutor.armPingStepOverride(runState, i, endIndex, + int endIndex = MacroLifecycle.stepOverrideEndIndex(macro, i, covered); + MacroLifecycle.armPingStepOverride(runState, i, endIndex, Math.max(0, sping.pingDelayMs), sping.realIncoming, sping.realOutgoing); runState.pingBackgroundDeadlineNanos = 0L; } @@ -325,35 +325,35 @@ final class MacroRunLoop { if (prearmed == null) MacroPacketWait.awaitPacket(""); } else { for (int targetIndex = Math.min(startTarget, targets.size()); targetIndex < targets.size(); targetIndex++) { - if (!MacroExecutor.isCurrentRunActive()) break; + if (!MacroLifecycle.isCurrentRunActive()) break; MacroPacketWait.awaitPacket(targets.get(targetIndex)); } } MacroPrearm.copyLastMatchedPacket(packetAction); } else if (action instanceof WaitPacketMatchAction wpma) { - MacroExecutor.setCurrentStatus(wpma.getDisplayName()); + MacroLifecycle.setCurrentStatus(wpma.getDisplayName()); if (!MacroPrearm.waitForPrearmed(wpma, wpma.timeoutMs)) MacroPrearm.waitForPacketMatch(wpma); } else if (action instanceof WaitInventoryPredicateAction wipa) { - MacroExecutor.setCurrentStatus(wipa.getDisplayName()); + MacroLifecycle.setCurrentStatus(wipa.getDisplayName()); if (!MacroPrearm.waitForPrearmed(wipa, wipa.timeoutMs)) waitForPredicate(() -> wipa.matches(mc), wipa.timeoutMs); } else if (action instanceof WaitDurabilityAction wda) { - MacroExecutor.setCurrentStatus(wda.getDisplayName()); + MacroLifecycle.setCurrentStatus(wda.getDisplayName()); if (wda.useNext) MacroDurability.waitForDurabilityUseNext(mc, wda); else if (!MacroPrearm.waitForPrearmed(wda, wda.timeoutMs)) waitForPredicate(() -> wda.matches(mc), wda.timeoutMs); } else if (action instanceof WaitFreeSlotsAction wfsa) { - MacroExecutor.setCurrentStatus(wfsa.getDisplayName()); + MacroLifecycle.setCurrentStatus(wfsa.getDisplayName()); if (!MacroPrearm.waitForPrearmed(wfsa, wfsa.timeoutMs)) waitForPredicate(() -> wfsa.matches(mc), wfsa.timeoutMs); } else if (action instanceof WaitEntityTargetAction weta) { - MacroExecutor.setCurrentStatus(weta.getDisplayName()); + MacroLifecycle.setCurrentStatus(weta.getDisplayName()); if (!MacroPrearm.waitForPrearmed(weta, weta.timeoutMs)) waitForPredicate(() -> weta.matches(mc), weta.timeoutMs); } else if (action instanceof WaitGuiTypeAction wgta) { - MacroExecutor.setCurrentStatus(wgta.getDisplayName()); + MacroLifecycle.setCurrentStatus(wgta.getDisplayName()); if (!MacroPrearm.hasPrearmedWait(wgta)) MacroPrearm.clearCaptureOutputs(wgta); if (MacroPrearm.waitForPrearmed(wgta, wgta.timeoutMs)) { } else if (wgta.waitMode == WaitGuiTypeAction.WaitMode.CLOSE) { @@ -370,7 +370,7 @@ final class MacroRunLoop { } else if (action instanceof WaitForHealthAction) { WaitForHealthAction wh = (WaitForHealthAction) action; - MacroExecutor.setCurrentStatus(wh.waitingStatusText()); + MacroLifecycle.setCurrentStatus(wh.waitingStatusText()); try { if (!MacroPrearm.waitForPrearmed(wh, 0)) { CompletableFuture future = MacroConditionRegistry.waitForHealth( @@ -381,7 +381,7 @@ final class MacroRunLoop { } else if (action instanceof WaitForBlockAction) { WaitForBlockAction wba = (WaitForBlockAction) action; - MacroExecutor.setCurrentStatus(wba.getDisplayName()); + MacroLifecycle.setCurrentStatus(wba.getDisplayName()); try { if (!MacroPrearm.waitForPrearmed(wba, 0)) { CompletableFuture future = MacroConditionRegistry.waitForBlock(wba); @@ -394,11 +394,11 @@ final class MacroRunLoop { if (!MacroPrearm.hasPrearmedWait(wga)) MacroPrearm.clearCaptureOutputs(wga); if (MacroPrearm.waitForPrearmed(wga, 0)) { } else if (wga.waitMode == WaitForGuiAction.WaitMode.CLOSE) { - MacroExecutor.setCurrentStatus("Waiting for GUI close: " + wga.guiTitle); + MacroLifecycle.setCurrentStatus("Waiting for GUI close: " + wga.guiTitle); waitForPredicate(guiClosePredicate(wga, mc), wga.timeoutMs); MacroPrearm.commitStagedCapture(wga); } else { - MacroExecutor.setCurrentStatus("Waiting for GUI: " + wga.guiTitle); + MacroLifecycle.setCurrentStatus("Waiting for GUI: " + wga.guiTitle); waitForPredicate(() -> { var captured = wga.captureGui(mc.gui.screen()); captured.ifPresent(values -> MacroPrearm.stageCapture(wga, values)); @@ -412,7 +412,7 @@ final class MacroRunLoop { ItemTarget cooldownTarget = MacroWorldActions.resolveItemTarget(wca.itemTarget, wca.itemName).resolveTemplate(mc); if (cooldownTarget == null) continue; String cooldownLabel = MacroWorldActions.describeItemTarget(cooldownTarget); - MacroExecutor.setCurrentStatus("Waiting for cooldown: " + + MacroLifecycle.setCurrentStatus("Waiting for cooldown: " + (!cooldownLabel.isEmpty() ? cooldownLabel : (wca.checkMainInteractionHand ? "Main Hand" : "Off Hand"))); try { if (!MacroPrearm.waitForPrearmed(wca, 0)) { @@ -423,7 +423,7 @@ final class MacroRunLoop { } else if (action instanceof WaitPosAction) { WaitPosAction wpa = (WaitPosAction) action; - MacroExecutor.setCurrentStatus("Waiting for Pos: " + String.format("%.0f, %.0f, %.0f", wpa.x, wpa.y, wpa.z)); + MacroLifecycle.setCurrentStatus("Waiting for Pos: " + String.format("%.0f, %.0f, %.0f", wpa.x, wpa.y, wpa.z)); try { if (!MacroPrearm.waitForPrearmed(wpa, 0)) { CompletableFuture future = MacroConditionRegistry.waitForPos( @@ -439,7 +439,7 @@ final class MacroRunLoop { CompletableFuture tickFuture = MacroConditionRegistry.waitForNextTick(); waitForCondition(tickFuture); } else { - for (int t = 0; t < ja.durationTicks && MacroExecutor.isCurrentRunActive(); t++) { + for (int t = 0; t < ja.durationTicks && MacroLifecycle.isCurrentRunActive(); t++) { CompletableFuture tickFuture = MacroConditionRegistry.waitForNextTick(); waitForCondition(tickFuture); } @@ -449,37 +449,37 @@ final class MacroRunLoop { else if (action instanceof SneakAction) { SneakAction sna = (SneakAction) action; if (sna.persistent && sna.sneak) { - MacroExecutor.currentPersistentActions().removeIf(p -> p instanceof SneakAction); - MacroExecutor.currentPersistentActions().add(sna); + MacroLifecycle.currentPersistentActions().removeIf(p -> p instanceof SneakAction); + MacroLifecycle.currentPersistentActions().add(sna); } else if (!sna.sneak) { - MacroExecutor.currentPersistentActions().removeIf(p -> p instanceof SneakAction); + MacroLifecycle.currentPersistentActions().removeIf(p -> p instanceof SneakAction); } - if (sna.persistent || !sna.sneak) MacroClientThread.postOnClientThread(mc, () -> MacroExecutor.applyAggregateSneakState(mc), sna.isTickAligned()); + if (sna.persistent || !sna.sneak) MacroClientThread.postOnClientThread(mc, () -> MacroLifecycle.applyAggregateSneakState(mc), sna.isTickAligned()); else MacroClientThread.postOnClientThread(mc, () -> sna.execute(mc), sna.isTickAligned()); } else if (action instanceof SprintAction) { SprintAction spa = (SprintAction) action; if (spa.persistent && spa.sprint) { - MacroExecutor.currentPersistentActions().removeIf(p -> p instanceof SprintAction); - MacroExecutor.currentPersistentActions().add(spa); + MacroLifecycle.currentPersistentActions().removeIf(p -> p instanceof SprintAction); + MacroLifecycle.currentPersistentActions().add(spa); } else if (!spa.sprint) { - MacroExecutor.currentPersistentActions().removeIf(p -> p instanceof SprintAction); + MacroLifecycle.currentPersistentActions().removeIf(p -> p instanceof SprintAction); } - if (spa.persistent || !spa.sprint) MacroClientThread.postOnClientThread(mc, () -> MacroExecutor.applyAggregateSprintState(mc), spa.isTickAligned()); + if (spa.persistent || !spa.sprint) MacroClientThread.postOnClientThread(mc, () -> MacroLifecycle.applyAggregateSprintState(mc), spa.isTickAligned()); else MacroClientThread.postOnClientThread(mc, () -> spa.execute(mc), spa.isTickAligned()); } else if (action instanceof DisconnectAction) { DisconnectAction da2 = (DisconnectAction) action; - MacroExecutor.broadcastStepProgress(runState, i + 1, macro.actions.size(), macro.name); + MacroLifecycle.broadcastStepProgress(runState, i + 1, macro.actions.size(), macro.name); if (da2.mode == DisconnectAction.DisconnectMode.DISCONNECT) { if (da2.delayMs > 0) Thread.sleep(da2.delayMs); mc.execute(() -> da2.execute(mc)); } else if (da2.mode == DisconnectAction.DisconnectMode.AUTO_DISCONNECT) { - MacroExecutor.setCurrentStatus("Auto Disconnect: waiting for " + da2.trigger.name() + "..."); + MacroLifecycle.setCurrentStatus("Auto Disconnect: waiting for " + da2.trigger.name() + "..."); da2.execute(mc); - MacroExecutor.setCurrentStatus("Auto Disconnect: executed"); + MacroLifecycle.setCurrentStatus("Auto Disconnect: executed"); } else if (da2.mode == DisconnectAction.DisconnectMode.KICK_DUPE && da2.useNextAction) { java.util.List nextActs = new java.util.ArrayList<>(); @@ -516,7 +516,7 @@ final class MacroRunLoop { mc.execute(() -> da2.execute(mc)); } - MacroExecutor.stopCurrentRun(); + MacroLifecycle.stopCurrentRun(); break; } else if (action instanceof RaceAction race) { @@ -536,7 +536,7 @@ final class MacroRunLoop { long delayMs = Math.max(1, nba.delayTicks) * 50L; boolean signedAny = false; for (int b = 0; b < totalBooks; b++) { - if (!MacroExecutor.isCurrentRunActive()) break; + if (!MacroLifecycle.isCurrentRunActive()) break; final int bookIdx = b; java.util.concurrent.CompletableFuture result = new java.util.concurrent.CompletableFuture<>(); mc.execute(() -> result.complete(nba.executeSingleBook(mc, bookIdx, totalBooks))); @@ -562,17 +562,17 @@ final class MacroRunLoop { if (ma.nonBlocking) { mc.execute(() -> ma.execute(mc)); - MacroExecutor.currentBackgroundMoves().put(ma, new int[]{ma.durationTicks - 1}); + MacroLifecycle.currentBackgroundMoves().put(ma, new int[]{ma.durationTicks - 1}); } else { - for (int t = 0; t < ma.durationTicks && MacroExecutor.isCurrentRunActive(); t++) { + for (int t = 0; t < ma.durationTicks && MacroLifecycle.isCurrentRunActive(); t++) { mc.execute(() -> ma.execute(mc)); CompletableFuture tickFuture = MacroConditionRegistry.waitForNextTick(); waitForCondition(tickFuture); } MacroExecutor.RunState movementRun = MacroExecutor.CURRENT_RUN.get(); - mc.execute(() -> MacroExecutor.releaseMoveIfUnused(movementRun, ma, mc)); + mc.execute(() -> MacroLifecycle.releaseMoveIfUnused(movementRun, ma, mc)); } } else if (action instanceof LookAtBlockAction) { @@ -599,9 +599,9 @@ final class MacroRunLoop { int startIdx = i + 1; int endIdx = Math.min(startIdx + ra.stepCount, macro.actions.size()); - for (int rep = 0; rep < ra.repeatCount && MacroExecutor.isCurrentRunActive(); rep++) { - MacroExecutor.setCurrentStatus("Repeat " + (rep + 1) + "/" + ra.repeatCount); - for (int j = startIdx; j < endIdx && MacroExecutor.isCurrentRunActive(); j++) { + for (int rep = 0; rep < ra.repeatCount && MacroLifecycle.isCurrentRunActive(); rep++) { + MacroLifecycle.setCurrentStatus("Repeat " + (rep + 1) + "/" + ra.repeatCount); + for (int j = startIdx; j < endIdx && MacroLifecycle.isCurrentRunActive(); j++) { MacroAction subAction = macro.actions.get(j); if (!subAction.isEnabled()) continue; @@ -623,12 +623,12 @@ final class MacroRunLoop { } else if (action instanceof WaitForChatAction) { WaitForChatAction wca = (WaitForChatAction) action; - MacroExecutor.setCurrentStatus("Waiting for chat: " + wca.pattern); + MacroLifecycle.setCurrentStatus("Waiting for chat: " + wca.pattern); if (!MacroPrearm.waitForPrearmed(wca, wca.timeoutMs)) MacroPacketWait.awaitChat(wca); } else if (action instanceof WaitForEntityAction) { WaitForEntityAction wea = (WaitForEntityAction) action; - MacroExecutor.setCurrentStatus(wea.getDisplayName()); + MacroLifecycle.setCurrentStatus(wea.getDisplayName()); try { if (!MacroPrearm.waitForPrearmed(wea, 0)) { waitForPredicate(() -> wea.matchesEntityTarget(mc), wea.timeoutMs); @@ -638,7 +638,7 @@ final class MacroRunLoop { else if (action instanceof WaitForSoundAction) { WaitForSoundAction wsa = (WaitForSoundAction) action; String sndDesc = wsa.soundIds.isEmpty() ? "any" : wsa.soundIds.get(0); - MacroExecutor.setCurrentStatus("Waiting for sound: " + sndDesc); + MacroLifecycle.setCurrentStatus("Waiting for sound: " + sndDesc); try { if (!MacroPrearm.waitForPrearmed(wsa, 0)) { CompletableFuture future = MacroConditionRegistry.waitForSound(wsa); @@ -656,7 +656,7 @@ final class MacroRunLoop { else if (action instanceof BreakAction breakAction) { MacroExecutor.InlineNextActions nextActions = MacroExecutor.InlineNextActions.empty(); if (breakAction.interact && breakAction.runNextSteps) { - nextActions = MacroExecutor.collectInlineNextActions(macro.actions, i); + nextActions = MacroLifecycle.collectInlineNextActions(macro.actions, i); breakAction.setNextActions(nextActions.actions()); } MacroBreak.runBreakAction(mc, breakAction); @@ -665,7 +665,7 @@ final class MacroRunLoop { else if (action instanceof WaitForSlotChangeAction) { WaitForSlotChangeAction wsca = (WaitForSlotChangeAction) action; - MacroExecutor.setCurrentStatus(wsca.getDisplayName()); + MacroLifecycle.setCurrentStatus(wsca.getDisplayName()); try { if (!MacroPrearm.waitForPrearmed(wsca, 0)) { CompletableFuture future = MacroConditionRegistry.waitForSlotChange(wsca); @@ -674,7 +674,7 @@ final class MacroRunLoop { } catch (CancellationException e) { } } else if (action instanceof WaitForWorldChangeAction world) { - MacroExecutor.setCurrentStatus(world.getDisplayName()); + MacroLifecycle.setCurrentStatus(world.getDisplayName()); try { if (!MacroPrearm.waitForPrearmed(world, 0)) { CompletableFuture future = MacroConditionRegistry.waitForWorldChange(world); @@ -683,7 +683,7 @@ final class MacroRunLoop { } catch (CancellationException e) { } } else if (action instanceof WaitForPositionDeltaAction wpda) { - MacroExecutor.setCurrentStatus(wpda.getDisplayName()); + MacroLifecycle.setCurrentStatus(wpda.getDisplayName()); try { if (!MacroPrearm.waitForPrearmed(wpda, 0)) { CompletableFuture future = MacroConditionRegistry.waitForPositionDelta(wpda.distance, wpda.horizontalOnly); @@ -692,7 +692,7 @@ final class MacroRunLoop { } catch (CancellationException e) { } } else if (action instanceof WaitForTeleportAction teleport) { - MacroExecutor.setCurrentStatus(teleport.getDisplayName()); + MacroLifecycle.setCurrentStatus(teleport.getDisplayName()); try { if (!MacroPrearm.waitForPrearmed(teleport, 0)) { CompletableFuture future = MacroRace.raceConditionFuture(mc, teleport); @@ -701,7 +701,7 @@ final class MacroRunLoop { } catch (CancellationException e) { } } else if (action instanceof WaitGamemodeChangeAction gm) { - MacroExecutor.setCurrentStatus(gm.getDisplayName()); + MacroLifecycle.setCurrentStatus(gm.getDisplayName()); try { if (!MacroPrearm.waitForPrearmed(gm, gm.timeoutMs)) { CompletableFuture future = MacroConditionRegistry.waitForGamemodeChange(gm); @@ -710,7 +710,7 @@ final class MacroRunLoop { } catch (CancellationException e) { } } else if (action instanceof WaitMovementAction wm) { - MacroExecutor.setCurrentStatus(wm.getDisplayName()); + MacroLifecycle.setCurrentStatus(wm.getDisplayName()); try { if (!MacroPrearm.waitForPrearmed(wm, 0)) { CompletableFuture future = MacroRace.raceConditionFuture(mc, wm.resolveSubAction()); @@ -720,7 +720,7 @@ final class MacroRunLoop { } else if (action instanceof WaitForLanStepAction) { WaitForLanStepAction wla = (WaitForLanStepAction) action; - MacroExecutor.setCurrentStatus(wla.getDisplayName()); + MacroLifecycle.setCurrentStatus(wla.getDisplayName()); try { if (!MacroPrearm.waitForPrearmed(wla, 0)) { CompletableFuture future = MacroConditionRegistry.waitForLanStep(wla); @@ -730,19 +730,19 @@ final class MacroRunLoop { } else if (action instanceof WaitForMacroStepAction) { WaitForMacroStepAction wma = (WaitForMacroStepAction) action; - MacroExecutor.setCurrentStatus(wma.getDisplayName()); + MacroLifecycle.setCurrentStatus(wma.getDisplayName()); if (!MacroPrearm.waitForPrearmed(wma, wma.timeoutMs)) MacroRace.waitForMacroStep(wma); } else if (action instanceof StopMacroAction) { - MacroExecutor.setCurrentStatus("Stopping Macro"); + MacroLifecycle.setCurrentStatus("Stopping Macro"); StopMacroAction stopAction = (StopMacroAction) action; if (stopAction.target != StopMacroAction.StopTarget.SELF) { stopAction.execute(mc); break; } - MacroExecutor.broadcastStepProgress(runState, i + 1, macro.actions.size(), macro.name); - MacroExecutor.stopCurrentRun(); + MacroLifecycle.broadcastStepProgress(runState, i + 1, macro.actions.size(), macro.name); + MacroLifecycle.stopCurrentRun(); break; } @@ -755,13 +755,13 @@ final class MacroRunLoop { MacroRender.preGeneratePackets(macro, i + 1, tsa.preGenCount); long targetTick = mc.level.getGameTime() + tsa.tickOffset; - MacroExecutor.setCurrentStatus("Tick Sync -> " + targetTick + " (" + preGenerated.size() + " pkts)"); + MacroLifecycle.setCurrentStatus("Tick Sync -> " + targetTick + " (" + preGenerated.size() + " pkts)"); - while (MacroExecutor.isCurrentRunActive() && mc.level.getGameTime() < targetTick) { + while (MacroLifecycle.isCurrentRunActive() && mc.level.getGameTime() < targetTick) { java.util.concurrent.locks.LockSupport.parkNanos(1_000_000L); } - if (MacroExecutor.isCurrentRunActive()) { + if (MacroLifecycle.isCurrentRunActive()) { MacroRender.executePreGeneratedBurst(mc, preGenerated); i += MacroRender.countPreGeneratedActions(macro, i + 1, preGenerated.size()); AutismClientMessaging.sendPrefixed("Tick sync: " + preGenerated.size() + " pkts sent"); @@ -777,15 +777,15 @@ final class MacroRunLoop { int baseRevision = mc.player.containerMenu.getStateId(); int targetRevision = baseRevision + rsa.revisionOffset; - MacroExecutor.setCurrentStatus("Rev Sync -> " + targetRevision + " (" + preGenerated.size() + " pkts)"); + MacroLifecycle.setCurrentStatus("Rev Sync -> " + targetRevision + " (" + preGenerated.size() + " pkts)"); - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { if (mc.player == null || mc.player.containerMenu == null) break; if (mc.player.containerMenu.getStateId() >= targetRevision) break; java.util.concurrent.locks.LockSupport.parkNanos(500_000L); } - if (MacroExecutor.isCurrentRunActive() && mc.player != null && mc.player.containerMenu != null) { + if (MacroLifecycle.isCurrentRunActive() && mc.player != null && mc.player.containerMenu != null) { MacroRender.executePreGeneratedBurst(mc, preGenerated); i += MacroRender.countPreGeneratedActions(macro, i + 1, preGenerated.size()); AutismClientMessaging.sendPrefixed("Rev sync: " + preGenerated.size() + " pkts sent"); @@ -800,27 +800,27 @@ final class MacroRunLoop { MacroRender.preGeneratePackets(macro, i + 1, stsa.preGenCount); int sampleWaitMs = 0; - while (MacroExecutor.isCurrentRunActive() && !ServerTickTracker.isReady() && sampleWaitMs < stsa.maxWaitMs) { + while (MacroLifecycle.isCurrentRunActive() && !ServerTickTracker.isReady() && sampleWaitMs < stsa.maxWaitMs) { float progress = ServerTickTracker.getWarmupProgress(); - MacroExecutor.setCurrentStatus(String.format("ServerSync warmup %.0f%% (%d samples, %dms)", + MacroLifecycle.setCurrentStatus(String.format("ServerSync warmup %.0f%% (%d samples, %dms)", progress * 100, ServerTickTracker.getSampleCount(), ServerTickTracker.getTrackingTimeMs())); Thread.sleep(50); sampleWaitMs += 50; } - if (!MacroExecutor.isCurrentRunActive()) continue; + if (!MacroLifecycle.isCurrentRunActive()) continue; long optimalTime = ServerTickTracker.getOptimalSendTime(stsa.bufferMs, stsa.ignorePing); long msUntil = (optimalTime - System.nanoTime()) / 1_000_000L; int ping = ServerTickTracker.getPingMs(); String pingStr = stsa.ignorePing ? " (no ping)" : " ping:" + ping + "ms"; - MacroExecutor.setCurrentStatus("ServerSync in " + Math.max(0, msUntil) + "ms" + pingStr + " (" + preGenerated.size() + " pkts)"); + MacroLifecycle.setCurrentStatus("ServerSync in " + Math.max(0, msUntil) + "ms" + pingStr + " (" + preGenerated.size() + " pkts)"); long startWait = System.nanoTime(); long maxWaitNanos = stsa.maxWaitMs * 1_000_000L; - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { long now = System.nanoTime(); if ((now - startWait) >= maxWaitNanos) break; if (now >= optimalTime) break; @@ -833,7 +833,7 @@ final class MacroRunLoop { } } - if (MacroExecutor.isCurrentRunActive()) { + if (MacroLifecycle.isCurrentRunActive()) { MacroRender.executePreGeneratedBurst(mc, preGenerated); i += MacroRender.countPreGeneratedActions(macro, i + 1, preGenerated.size()); long actualDelay = (System.nanoTime() - optimalTime) / 1_000_000L; @@ -919,11 +919,11 @@ final class MacroRunLoop { } else if (action instanceof autismclient.util.macro.StoreItemAction) { autismclient.util.macro.StoreItemAction sia = (autismclient.util.macro.StoreItemAction) action; - MacroExecutor.setCurrentStatus((sia.mode == autismclient.util.macro.StoreItemAction.Mode.LOOT ? "Looting" : "Storing") + MacroLifecycle.setCurrentStatus((sia.mode == autismclient.util.macro.StoreItemAction.Mode.LOOT ? "Looting" : "Storing") + (sia.persistent ? " \u221e" : "")); if (sia.persistent) { - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { try { MacroActionRunner.runStoreItemAction(mc, sia); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } catch (Exception e) { AutismClientMessaging.sendPrefixed("Store error: " + e.getMessage()); } @@ -949,14 +949,14 @@ final class MacroRunLoop { && (xsa.transferMode == XCarryAction.TransferMode.CLICK || xsa.transferMode == XCarryAction.TransferMode.SAFE_CLICK)) { if (xsa.transferMode == XCarryAction.TransferMode.SAFE_CLICK) { - MacroExecutor.setCurrentStatus("XCarry Safe"); + MacroLifecycle.setCurrentStatus("XCarry Safe"); MacroXCarry.runXCarrySafeClickPutIn(mc, xsa); } else { - MacroExecutor.setCurrentStatus("XCarry Click"); + MacroLifecycle.setCurrentStatus("XCarry Click"); MacroXCarry.runXCarryClickPutIn(mc, xsa); } } else { - MacroExecutor.setCurrentStatus(switch (xsa.mode) { + MacroLifecycle.setCurrentStatus(switch (xsa.mode) { case PUT_IN -> "XCarry"; case TAKE_OUT -> "XCarry Out"; case DROP -> "XCarry Drop"; @@ -973,7 +973,7 @@ final class MacroRunLoop { else if (action instanceof InventoryAuditAction auditAction && (auditAction.mode == InventoryAuditAction.Mode.DUPE || auditAction.mode == InventoryAuditAction.Mode.DUPE_SPAM)) { - MacroExecutor.setCurrentStatus("Dupe: " + auditAction.dupeVector.name() + " " + auditAction.openMode.name()); + MacroLifecycle.setCurrentStatus("Dupe: " + auditAction.dupeVector.name() + " " + auditAction.openMode.name()); try { auditAction.executeDupe(mc); } catch (InterruptedException ie) { @@ -989,11 +989,11 @@ final class MacroRunLoop { MacroActionRunner.runPacketBurstAction(mc, burst); } else if (action instanceof BundleDupeV2Action bundleV2) { - MacroExecutor.setCurrentStatus("Bundle Dupe V2"); + MacroLifecycle.setCurrentStatus("Bundle Dupe V2"); bundleV2.execute(mc); } else if (action instanceof RollbackAction rollback) { - MacroExecutor.setCurrentStatus("Rollback"); + MacroLifecycle.setCurrentStatus("Rollback"); try { rollback.executeRollback(mc); } catch (InterruptedException e) { @@ -1028,12 +1028,12 @@ final class MacroRunLoop { postGuiFuture = null; } else { if (placeTarget.hasIdentity() || placeTarget.hasSlot()) { - MacroExecutor.setCurrentStatus("Waiting for " + MacroWorldActions.describeItemTarget(placeTarget)); + MacroLifecycle.setCurrentStatus("Waiting for " + MacroWorldActions.describeItemTarget(placeTarget)); try { MacroWorldActions.waitForItemActionEntry(mc, placeTarget); } catch (java.util.concurrent.CancellationException e) { } } - if (MacroExecutor.isCurrentRunActive()) { + if (MacroLifecycle.isCurrentRunActive()) { final PlaceAction fPlace = place; MacroClientThread.postOnClientThread(mc, () -> { if (PackHideState.isHardLocked()) return; @@ -1055,7 +1055,7 @@ final class MacroRunLoop { java.util.concurrent.CountDownLatch latch = new java.util.concurrent.CountDownLatch(1); MacroExecutor.RunState scheduledRun = MacroExecutor.CURRENT_RUN.get(); - mc.execute(() -> MacroExecutor.withRunContext(scheduledRun, () -> { + mc.execute(() -> MacroLifecycle.withRunContext(scheduledRun, () -> { try { if (PackHideState.isHardLocked()) return; action.execute(mc); @@ -1078,18 +1078,18 @@ final class MacroRunLoop { MacroPrearm.commitConditionOutput(action, mc); - if (postGuiFuture != null && MacroExecutor.isCurrentRunActive()) { + if (postGuiFuture != null && MacroLifecycle.isCurrentRunActive()) { try { waitForCondition(postGuiFuture); } catch (java.util.concurrent.CancellationException e) { } } - if (MacroExecutor.isCurrentRunActive()) { - MacroExecutor.markStepCompleted(i + 1); - MacroExecutor.broadcastStepProgress(runState, i + 1, macro.actions.size(), macro.name); + if (MacroLifecycle.isCurrentRunActive()) { + MacroLifecycle.markStepCompleted(i + 1); + MacroLifecycle.broadcastStepProgress(runState, i + 1, macro.actions.size(), macro.name); } - if (MacroExecutor.isCurrentRunActive() && !MacroActionRunner.isInstantInventoryAction(action)) { + if (MacroLifecycle.isCurrentRunActive() && !MacroActionRunner.isInstantInventoryAction(action)) { if (module != null && module.useInstantExecutionMode()) { int delayUs = module.getActionDelayUs(); if (delayUs > 0) { @@ -1104,21 +1104,21 @@ final class MacroRunLoop { } } finally { MacroRaycastAim.release(); - MacroExecutor.releaseClientResources(heldResources); + MacroLifecycle.releaseClientResources(heldResources); } } if (macro.actions.isEmpty()) { if (!runState.options.silentLifecycle()) AutismClientMessaging.sendPrefixed("\u00a7cMacro stopped: no actions left."); - MacroExecutor.stopCurrentRun(); + MacroLifecycle.stopCurrentRun(); break; } - if (MacroExecutor.isCurrentRunActive()) { + if (MacroLifecycle.isCurrentRunActive()) { PacketGateManager.clearOwnerAndFlushConfigured(runState.id, mc == null ? null : mc.getConnection()); } - if (macro.loop && loopCount < maxLoops - 1 && MacroExecutor.isCurrentRunActive()) { + if (macro.loop && loopCount < maxLoops - 1 && MacroLifecycle.isCurrentRunActive()) { if (module != null && module.useInstantExecutionMode()) { int delayUs = module.getActionDelayUs(); @@ -1144,9 +1144,9 @@ final class MacroRunLoop { loopCount++; } - MacroExecutor.awaitBackgroundTimedOverrides(runState); + MacroLifecycle.awaitBackgroundTimedOverrides(runState); - if (MacroExecutor.isCurrentRunActive()) { + if (MacroLifecycle.isCurrentRunActive()) { if (!runState.options.silentLifecycle()) AutismClientMessaging.sendPrefixed("\u00a7aMacro finished: " + macro.name); } @@ -1158,11 +1158,11 @@ final class MacroRunLoop { MacroRace.runFinallyActions(runState, mc); } PacketGateManager.clearOwnerAndFlushConfigured(runState.id, mc == null ? null : mc.getConnection()); - MacroExecutor.finishCurrentRun(); + MacroLifecycle.finishCurrentRun(); MacroRender.cancelRotation(runState); if (!MacroExecutor.isRunning.get()) MacroConditionRegistry.cancelAll(); - MacroExecutor.broadcastStepProgress(runState, -1, 0, ""); + MacroLifecycle.broadcastStepProgress(runState, -1, 0, ""); } } @@ -1170,12 +1170,12 @@ final class MacroRunLoop { Thread t = Thread.currentThread(); future.whenComplete((v, e) -> java.util.concurrent.locks.LockSupport.unpark(t)); - while (!future.isDone() && MacroExecutor.isCurrentRunActive()) { + while (!future.isDone() && MacroLifecycle.isCurrentRunActive()) { java.util.concurrent.locks.LockSupport.parkNanos(MacroExecutor.MACRO_WAIT_POLL_NANOS); if (Thread.interrupted()) break; } - if (!MacroExecutor.isCurrentRunActive()) { + if (!MacroLifecycle.isCurrentRunActive()) { future.cancel(true); } } @@ -1186,9 +1186,9 @@ final class MacroRunLoop { autismclient.util.multi.PacketTeleportController.startMacro(action))); autismclient.util.multi.PacketTeleportController.MacroHandle handle = handleRef.get(); if (handle == null) return; - MacroExecutor.setCurrentStatus("TP " + action.commandArguments()); + MacroLifecycle.setCurrentStatus("TP " + action.commandArguments()); try { - while (MacroExecutor.isCurrentRunActive() && !handle.completion().isDone()) MacroExecutor.waitOneTick(); + while (MacroLifecycle.isCurrentRunActive() && !handle.completion().isDone()) MacroExecutor.waitOneTick(); } finally { if (!handle.completion().isDone()) { mc.execute(() -> autismclient.util.multi.PacketTeleportController.cancelMacro(handle, "macro stopped")); @@ -1207,7 +1207,7 @@ final class MacroRunLoop { burst[0] = 0; CompletableFuture prev = MAIN_DRAIN_BARRIER.get(); if (prev != null && !prev.isDone()) waitForCondition(prev); - if (!MacroExecutor.isCurrentRunActive()) return; + if (!MacroLifecycle.isCurrentRunActive()) return; CompletableFuture next = new CompletableFuture<>(); MAIN_DRAIN_BARRIER.set(next); try { @@ -1219,7 +1219,7 @@ final class MacroRunLoop { public static void waitForPredicate(java.util.function.BooleanSupplier predicate, int timeoutMs) { long start = System.currentTimeMillis(); - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { try { if (predicate.getAsBoolean()) return; } catch (Throwable ignored) { } diff --git a/src/main/java/autismclient/util/macro/MacroVariables.java b/src/main/java/autismclient/util/macro/MacroVariables.java index 0fb619c..445a492 100644 --- a/src/main/java/autismclient/util/macro/MacroVariables.java +++ b/src/main/java/autismclient/util/macro/MacroVariables.java @@ -65,7 +65,7 @@ public final class MacroVariables { } private static MacroVariableContext context() { - MacroVariableContext active = MacroExecutor.currentVariableContext(); + MacroVariableContext active = MacroLifecycle.currentVariableContext(); return active == null ? FALLBACK.get() : active; } } diff --git a/src/main/java/autismclient/util/macro/MacroWorldActions.java b/src/main/java/autismclient/util/macro/MacroWorldActions.java index c4c3a71..0e23e63 100644 --- a/src/main/java/autismclient/util/macro/MacroWorldActions.java +++ b/src/main/java/autismclient/util/macro/MacroWorldActions.java @@ -26,7 +26,7 @@ final class MacroWorldActions { ItemTarget target = action.resolvedItemTarget().resolveTemplate(mc); if (target == null) return; if (action.waitForItem && target != null && (target.hasIdentity() || target.hasSlot())) { - MacroExecutor.setCurrentStatus("Waiting for " + describeItemTarget(target)); + MacroLifecycle.setCurrentStatus("Waiting for " + describeItemTarget(target)); waitForItemActionEntry(mc, target); } @@ -66,14 +66,14 @@ final class MacroWorldActions { } private static void waitForItemInSpecificHandlerSlot(Minecraft mc, int slotId, ItemTarget target) throws InterruptedException { - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { if (Boolean.TRUE.equals(MacroClientThread.callOnClientThread(mc, () -> handlerSlotMatchesItem(mc, slotId, target), Boolean.FALSE))) return; MacroExecutor.waitOneTick(); } } private static void waitForAnyItemInSpecificHandlerSlot(Minecraft mc, int slotId) throws InterruptedException { - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { if (Boolean.TRUE.equals(MacroClientThread.callOnClientThread(mc, () -> handlerSlotHasAnyItem(mc, slotId), Boolean.FALSE))) return; MacroExecutor.waitOneTick(); } @@ -110,7 +110,7 @@ final class MacroWorldActions { } if (ia.useSlot && ia.targetSlot >= 0) { - MacroExecutor.setCurrentStatus("Waiting for slot " + ia.targetSlot); + MacroLifecycle.setCurrentStatus("Waiting for slot " + ia.targetSlot); waitForAnyItemInSpecificHandlerSlot(mc, ia.targetSlot); } } @@ -122,19 +122,19 @@ final class MacroWorldActions { int slot = resolvedTarget.hasSlot() ? resolvedTarget.slot : -1; if (slot >= 0 && resolvedTarget.hasIdentity()) { - MacroExecutor.setCurrentStatus("Waiting for " + itemLabel); + MacroLifecycle.setCurrentStatus("Waiting for " + itemLabel); waitForItemInSpecificHandlerSlot(mc, slot, resolvedTarget); return; } if (slot >= 0) { - MacroExecutor.setCurrentStatus("Waiting for slot " + slot); + MacroLifecycle.setCurrentStatus("Waiting for slot " + slot); waitForAnyItemInSpecificHandlerSlot(mc, slot); return; } if (resolvedTarget.hasIdentity()) { - MacroExecutor.setCurrentStatus("Waiting for item in GUI: " + itemLabel); + MacroLifecycle.setCurrentStatus("Waiting for item in GUI: " + itemLabel); CompletableFuture waitFuture = MacroConditionRegistry.waitForItemInHandler(resolvedTarget); MacroRunLoop.waitForCondition(waitFuture); } @@ -174,7 +174,7 @@ final class MacroWorldActions { public static void runCraftAction(Minecraft mc, CraftAction craftAction) throws InterruptedException { if (craftAction == null || !craftAction.hasEntries()) { - MacroExecutor.setCurrentStatus("Crafting"); + MacroLifecycle.setCurrentStatus("Crafting"); AutismClientMessaging.sendPrefixed("\u00a7cNo craft recipes selected."); return; } @@ -183,21 +183,21 @@ final class MacroWorldActions { CraftAction.CraftEntry entry = craftAction.entries.get(index); if (entry == null || !entry.hasRecipe()) continue; - MacroExecutor.setCurrentStatus(entry.useMaxAmount + MacroLifecycle.setCurrentStatus(entry.useMaxAmount ? "Crafting " + entry.resultName + " [Max] (" + (index + 1) + "/" + craftAction.entries.size() + ")" : "Crafting " + entry.resultName + " x" + Math.max(1, entry.amount) + " (" + (index + 1) + "/" + craftAction.entries.size() + ")"); AutismCraftingHelper.CraftableRecipeOption option = AutismCraftingHelper.findCraftableRecipe(mc, entry.recipeKey); if (option == null) option = AutismCraftingHelper.findCraftableRecipe(mc, entry.recipeId); if (option == null) { - MacroExecutor.setCurrentStatus("Recipe not found"); + MacroLifecycle.setCurrentStatus("Recipe not found"); AutismClientMessaging.sendPrefixed("\u00a7cRecipe not found: " + (entry.resultName == null || entry.resultName.isBlank() ? "unknown" : entry.resultName)); return; } int desiredAmount = AutismCraftingHelper.getEffectiveRequestedOutput(option, entry.amount, entry.useMaxAmount); if (desiredAmount <= 0) { - MacroExecutor.setCurrentStatus("No space or materials"); + MacroLifecycle.setCurrentStatus("No space or materials"); AutismClientMessaging.sendPrefixed("\u00a7cNo space or materials for " + entry.resultName + "."); return; } @@ -209,12 +209,12 @@ final class MacroWorldActions { desiredAmount ); - MacroExecutor.setCurrentStatus(result.message); + MacroLifecycle.setCurrentStatus(result.message); if (!result.success) { AutismClientMessaging.sendPrefixed("\u00a7c" + result.message); return; } - if (MacroExecutor.isCurrentRunActive()) { + if (MacroLifecycle.isCurrentRunActive()) { CompletableFuture tickFuture = MacroConditionRegistry.waitForNextTick(); MacroRunLoop.waitForCondition(tickFuture); } @@ -222,7 +222,7 @@ final class MacroWorldActions { } public static void runGoToAction(Minecraft mc, GoToAction goToAction) throws InterruptedException { - MacroExecutor.setCurrentStatus(String.format("Going to %.0f,%.0f,%.0f", goToAction.x, goToAction.y, goToAction.z)); + MacroLifecycle.setCurrentStatus(String.format("Going to %.0f,%.0f,%.0f", goToAction.x, goToAction.y, goToAction.z)); if (!AutismCompatManager.isBaritoneAvailable()) { AutismClientMessaging.sendPrefixed("Baritone not installed; skipping goto action."); @@ -241,25 +241,25 @@ final class MacroWorldActions { try { if (!goToAction.waitForArrival) { - MacroExecutor.setCurrentStatus("Goto started"); + MacroLifecycle.setCurrentStatus("Goto started"); return; } long startMs = System.currentTimeMillis(); boolean sawBaritoneActivity = false; - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { boolean goalActive = AutismCompatManager.isBaritoneGoalActive(); boolean baritoneBusy = AutismCompatManager.isBaritoneBusy(); if (goalActive || baritoneBusy) sawBaritoneActivity = true; if (sawBaritoneActivity && !goalActive && !baritoneBusy) { - MacroExecutor.setCurrentStatus("Goto finished"); + MacroLifecycle.setCurrentStatus("Goto finished"); return; } if (!sawBaritoneActivity && System.currentTimeMillis() - startMs >= 1500 && !goalActive && !baritoneBusy) { - MacroExecutor.setCurrentStatus("Goto finished"); + MacroLifecycle.setCurrentStatus("Goto finished"); return; } @@ -267,14 +267,14 @@ final class MacroWorldActions { MacroRunLoop.waitForCondition(tickFuture); } } finally { - if (!MacroExecutor.isCurrentRunActive()) requestOwnedBaritoneStop(run, mc); + if (!MacroLifecycle.isCurrentRunActive()) requestOwnedBaritoneStop(run, mc); else releaseBaritoneOwner(run); } } public static void runMineAction(Minecraft mc, MineAction mineAction) throws InterruptedException { String mineDesc = mineAction.targetBlocks.isEmpty() ? "none" : mineAction.targetBlocks.get(0); - MacroExecutor.setCurrentStatus("Mining: " + mineDesc); + MacroLifecycle.setCurrentStatus("Mining: " + mineDesc); if (mineAction.targetBlocks.isEmpty()) return; if (!AutismCompatManager.isBaritoneAvailable()) { @@ -305,7 +305,7 @@ final class MacroWorldActions { long mineStartMs = System.currentTimeMillis(); boolean sawBaritoneActivity = false; - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { boolean mineActive = AutismCompatManager.isBaritoneMineActive(); boolean baritoneBusy = AutismCompatManager.isBaritoneBusy(); if (mineActive || baritoneBusy) sawBaritoneActivity = true; @@ -316,7 +316,7 @@ final class MacroWorldActions { if (mineTracker != null) { mineTracker.poll(mc); minedDelta = mineTracker.destroyedCount(); - MacroExecutor.setCurrentStatus("Mining: " + mineDesc + " (" + minedDelta + "/" + mineAction.minedCountTarget + ")"); + MacroLifecycle.setCurrentStatus("Mining: " + mineDesc + " (" + minedDelta + "/" + mineAction.minedCountTarget + ")"); if (minedDelta >= mineAction.minedCountTarget) { stopReason = "Mine target reached"; } @@ -339,19 +339,19 @@ final class MacroWorldActions { } if (stopReason != null) { - MacroExecutor.setCurrentStatus(stopReason); + MacroLifecycle.setCurrentStatus(stopReason); requestOwnedBaritoneStop(run, mc); waitForBaritoneIdle(); return; } if (sawBaritoneActivity && !mineActive && !baritoneBusy) { - MacroExecutor.setCurrentStatus("Mine finished"); + MacroLifecycle.setCurrentStatus("Mine finished"); return; } if (!sawBaritoneActivity && System.currentTimeMillis() - mineStartMs >= 1500 && !mineActive && !baritoneBusy) { - MacroExecutor.setCurrentStatus("Mine finished"); + MacroLifecycle.setCurrentStatus("Mine finished"); return; } @@ -360,7 +360,7 @@ final class MacroWorldActions { } } finally { if (run != null && run.activeMineTracker == mineTracker) run.activeMineTracker = null; - if (!MacroExecutor.isCurrentRunActive()) requestOwnedBaritoneStop(run, mc); + if (!MacroLifecycle.isCurrentRunActive()) requestOwnedBaritoneStop(run, mc); else releaseBaritoneOwner(run); } } @@ -407,7 +407,7 @@ final class MacroWorldActions { private static void waitForBaritoneIdle() { long waitStartMs = System.currentTimeMillis(); - while (MacroExecutor.isCurrentRunActive() && AutismCompatManager.isBaritoneBusy() && System.currentTimeMillis() - waitStartMs < 3000L) { + while (MacroLifecycle.isCurrentRunActive() && AutismCompatManager.isBaritoneBusy() && System.currentTimeMillis() - waitStartMs < 3000L) { CompletableFuture tickFuture = MacroConditionRegistry.waitForNextTick(); MacroRunLoop.waitForCondition(tickFuture); } @@ -566,7 +566,7 @@ final class MacroWorldActions { int sent = 0; for (int i = 0; i < targets.size(); i++) { - if (!MacroExecutor.isCurrentRunActive()) break; + if (!MacroLifecycle.isCurrentRunActive()) break; String player = targets.get(i); long perAmount = dividedAmounts != null ? dividedAmounts[i] : resolvedAmount; @@ -591,7 +591,7 @@ final class MacroWorldActions { if (sent > 0 && payAction.delayEnabled && payAction.delayMs > 0) Thread.sleep(payAction.delayMs); - MacroExecutor.setCurrentStatus("Paying " + player + " " + amountLabel + " (" + (sent + 1) + "/" + targets.size() + ")"); + MacroLifecycle.setCurrentStatus("Paying " + player + " " + amountLabel + " (" + (sent + 1) + "/" + targets.size() + ")"); MacroClientThread.runOnClientThread(mc, () -> { try { @@ -609,8 +609,8 @@ final class MacroWorldActions { sent++; if (payAction.confirmMacro != null && !payAction.confirmMacro.isBlank()) { - MacroExecutor.setCurrentStatus("Confirming " + player); - PayAction.runConfirmMacro(payAction.confirmMacro, () -> !MacroExecutor.isCurrentRunActive()); + MacroLifecycle.setCurrentStatus("Confirming " + player); + PayAction.runConfirmMacro(payAction.confirmMacro, () -> !MacroLifecycle.isCurrentRunActive()); } } } diff --git a/src/main/java/autismclient/util/macro/MacroXCarry.java b/src/main/java/autismclient/util/macro/MacroXCarry.java index f8ab2c1..9bb8360 100644 --- a/src/main/java/autismclient/util/macro/MacroXCarry.java +++ b/src/main/java/autismclient/util/macro/MacroXCarry.java @@ -20,7 +20,7 @@ final class MacroXCarry { if (mc == null || mc.player == null || mc.gameMode == null) return; if (xsa.requiresCursorStorage()) { - MacroExecutor.setCurrentStatus("XCarry Cursor"); + MacroLifecycle.setCurrentStatus("XCarry Cursor"); MacroClientThread.runOnClientThread(mc, () -> xsa.execute(mc)); return; } @@ -53,8 +53,8 @@ final class MacroXCarry { if (usingContainer.get()) { for (int slotId : containerSlotIdsRef.get()) { - if (!MacroExecutor.isCurrentRunActive()) return; - MacroExecutor.setCurrentStatus("XCarry Click: collect"); + if (!MacroLifecycle.isCurrentRunActive()) return; + MacroLifecycle.setCurrentStatus("XCarry Click: collect"); MacroClientThread.runOnClientThread(mc, () -> { if (mc.player == null || mc.gameMode == null) return; net.minecraft.world.inventory.AbstractContainerMenu handler = containerHandlerRef.get(); @@ -85,14 +85,14 @@ final class MacroXCarry { MacroClientThread.runOnClientThread(mc, xsa::preparePutInStorageGuard); int xCarryAttempts = 0; - while (MacroExecutor.isCurrentRunActive() && xCarryAttempts++ < 512) { + while (MacroLifecycle.isCurrentRunActive() && xCarryAttempts++ < 512) { XCarryAction.PutInMove move = MacroClientThread.callOnClientThread(mc, () -> { if (mc.player == null) return null; return xsa.findNextPutInMove(mc.player.inventoryMenu); }, null); if (move == null) break; - MacroExecutor.setCurrentStatus("XCarry Click -> " + move.targetSlotId + " x" + move.count); + MacroLifecycle.setCurrentStatus("XCarry Click -> " + move.targetSlotId + " x" + move.count); int targetBefore = MacroClientThread.callOnClientThread(mc, () -> { if (mc.player == null) return 0; net.minecraft.world.inventory.InventoryMenu handler = mc.player.inventoryMenu; @@ -158,7 +158,7 @@ final class MacroXCarry { if (mc == null || mc.player == null || mc.gameMode == null) return; if (xsa.requiresCursorStorage()) { - MacroExecutor.setCurrentStatus("XCarry Safe: Cursor"); + MacroLifecycle.setCurrentStatus("XCarry Safe: Cursor"); MacroClientThread.runOnClientThread(mc, () -> xsa.execute(mc)); return; } @@ -191,8 +191,8 @@ final class MacroXCarry { if (usingContainer.get()) { for (int slotId : containerSlotIdsRef.get()) { - if (!MacroExecutor.isCurrentRunActive()) return; - MacroExecutor.setCurrentStatus("XCarry Safe: collect"); + if (!MacroLifecycle.isCurrentRunActive()) return; + MacroLifecycle.setCurrentStatus("XCarry Safe: collect"); sendContainerClickThenTick(mc, containerHandlerRef.get(), slotId, 0, ContainerInput.QUICK_MOVE); } @@ -218,14 +218,14 @@ final class MacroXCarry { boolean delayAfterPickup = xsa.safeClickDelayAfterPickup; boolean delayBeforeReturn = xsa.safeClickDelayBeforeReturn; int attempts = 0; - while (MacroExecutor.isCurrentRunActive() && attempts++ < 512) { + while (MacroLifecycle.isCurrentRunActive() && attempts++ < 512) { List group = MacroClientThread.callOnClientThread(mc, () -> nextXCarrySafeGroup(mc, xsa), List.of()); if (group.isEmpty()) break; XCarryAction.PutInMove first = group.get(0); int total = 0; for (XCarryAction.PutInMove move : group) total += Math.max(0, move.count()); - MacroExecutor.setCurrentStatus("XCarry Safe -> " + group.size() + " slots x" + total); + MacroLifecycle.setCurrentStatus("XCarry Safe -> " + group.size() + " slots x" + total); if (!executeXCarrySafeGroup(mc, group, safeDelayTicks, delayAfterPickup, delayBeforeReturn)) { rollbackXCarryCursorSafe(mc, first.sourceSlotId(), safeDelayTicks, delayBeforeReturn); @@ -321,7 +321,7 @@ final class MacroXCarry { SafeGroupSnapshot expected = snapshot; if (quickCraftPlan.valid) { - MacroExecutor.setCurrentStatus("XCarry Safe drag -> " + group.size() + " slots x" + quickCraftPlan.placeCount); + MacroLifecycle.setCurrentStatus("XCarry Safe drag -> " + group.size() + " slots x" + quickCraftPlan.placeCount); int start = net.minecraft.world.inventory.AbstractContainerMenu.getQuickcraftMask(0, quickCraftPlan.quickCraftType); int add = net.minecraft.world.inventory.AbstractContainerMenu.getQuickcraftMask(1, quickCraftPlan.quickCraftType); int end = net.minecraft.world.inventory.AbstractContainerMenu.getQuickcraftMask(2, quickCraftPlan.quickCraftType); @@ -432,7 +432,7 @@ final class MacroXCarry { private static boolean placeXCarrySafeDirectCount(Minecraft mc, int targetSlotId, int count, int delayTicks) throws InterruptedException { if (mc == null || count <= 0) return false; int remaining = count; - while (remaining > 0 && MacroExecutor.isCurrentRunActive()) { + while (remaining > 0 && MacroLifecycle.isCurrentRunActive()) { int carriedCount = MacroClientThread.callOnClientThread(mc, () -> { InventoryMenu handler = mc.player == null ? null : mc.player.inventoryMenu; return handler == null ? 0 : handler.getCarried().getCount(); @@ -627,7 +627,7 @@ final class MacroXCarry { private static void waitXCarrySafeDelayTicks(int delayTicks) { int ticks = XCarryAction.clampSafeClickDelayTicks(delayTicks); - for (int i = 0; i < ticks && MacroExecutor.isCurrentRunActive(); i++) { + for (int i = 0; i < ticks && MacroLifecycle.isCurrentRunActive(); i++) { MacroExecutor.waitOneTick(); } } @@ -670,7 +670,7 @@ final class MacroXCarry { private static boolean waitForXCarrySafeLocal(Minecraft mc, int ticks, java.util.function.BooleanSupplier accepted) throws InterruptedException { int maxTicks = Math.max(1, ticks); - for (int i = 0; i < maxTicks && MacroExecutor.isCurrentRunActive(); i++) { + for (int i = 0; i < maxTicks && MacroLifecycle.isCurrentRunActive(); i++) { if (Boolean.TRUE.equals(MacroClientThread.callOnClientThread(mc, () -> accepted != null && accepted.getAsBoolean(), Boolean.FALSE))) return true; MacroExecutor.waitOneTick(); } @@ -680,8 +680,8 @@ final class MacroXCarry { private static void waitForXCarrySafeSettle(Minecraft mc, long startRevision, int minTicks, long maxMs) throws InterruptedException { long deadline = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(Math.max(50L, maxMs)); int ticks = Math.max(1, minTicks); - for (int i = 0; i < ticks && MacroExecutor.isCurrentRunActive(); i++) MacroExecutor.waitOneTick(); - while (MacroExecutor.isCurrentRunActive() && System.nanoTime() < deadline) { + for (int i = 0; i < ticks && MacroLifecycle.isCurrentRunActive(); i++) MacroExecutor.waitOneTick(); + while (MacroLifecycle.isCurrentRunActive() && System.nanoTime() < deadline) { long revision = MacroConditionRegistry.inventorySyncRevision(); if (revision != startRevision) { MacroExecutor.waitOneTick(); @@ -848,7 +848,7 @@ final class MacroXCarry { private static boolean waitForXCarryCondition(Minecraft mc, long timeoutMs, java.util.function.Supplier condition) throws InterruptedException { long deadline = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeoutMs); - while (MacroExecutor.isCurrentRunActive()) { + while (MacroLifecycle.isCurrentRunActive()) { if (Boolean.TRUE.equals(MacroClientThread.callOnClientThread(mc, condition, Boolean.FALSE))) { return true; }