From 8ee914c21fd28ee33299579346041e7f9258d2ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ad=C4=B1n=C4=B1z?= Date: Mon, 23 Mar 2026 14:50:20 +0300 Subject: [PATCH 1/2] Guard AutoRefin against transient GUI/API runtime errors --- .../shared/kopoklesz/behaviour/AutoRefin.java | 84 +++++++++++-------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/src/main/java/dev/shared/kopoklesz/behaviour/AutoRefin.java b/src/main/java/dev/shared/kopoklesz/behaviour/AutoRefin.java index 1ae94a0c..9f04241d 100644 --- a/src/main/java/dev/shared/kopoklesz/behaviour/AutoRefin.java +++ b/src/main/java/dev/shared/kopoklesz/behaviour/AutoRefin.java @@ -54,47 +54,57 @@ public void setConfig(ConfigSetting setting) { // behavior @Override public void onTickBehavior() { - if (!isReadyForRefining()) - return; // check if we can refine - - if (getCargoPercent() < config.triggerPercent) { - // Reset tracking variables when cargo is below trigger percent - if (lastCargoAmount != -1) { - lastCargoAmount = -1; - lastRefineAttemptFailed = false; + try { + if (!isReadyForRefining()) + return; // check if we can refine + + if (getCargoPercent() < config.triggerPercent) { + // Reset tracking variables when cargo is below trigger percent + if (lastCargoAmount != -1) { + lastCargoAmount = -1; + lastRefineAttemptFailed = false; + } + return; } - return; - } - int currentCargo = stats.getCargo(); + int currentCargo = stats.getCargo(); - // If cargo hasn't changed since last failed refine attempt, skip to prevent - // unnecessary API calls - if (lastRefineAttemptFailed && currentCargo == lastCargoAmount) { - return; - } + // If cargo hasn't changed since last failed refine attempt, skip to prevent + // unnecessary API calls + if (lastRefineAttemptFailed && currentCargo == lastCargoAmount) { + return; + } - // Cache maxRefine values to avoid duplicate calculations - Map refineMap = Arrays.stream(Ore.values()) - .filter(this::shouldRefineOre) - .collect(Collectors.toMap( - ore -> ore, - this::maxRefine)); - - lastRefineAttemptFailed = true; // assume refine attempt will fail - lastCargoAmount = currentCargo; // update last cargo amount - - // Find the ore with the highest refineable amount - refineMap.entrySet().stream() - .filter(e -> e.getValue() > 0) - .max(Map.Entry.comparingByValue()) - .ifPresent(entry -> { - darkbotApi.refine( - darkbotApi.readLong(guiManager.getAddress() + 0x78), - entry.getKey(), - entry.getValue()); - lastRefineAttemptFailed = false; // refine attempt succeeded - }); + // Cache maxRefine values to avoid duplicate calculations + Map refineMap = Arrays.stream(Ore.values()) + .filter(this::shouldRefineOre) + .collect(Collectors.toMap( + ore -> ore, + this::maxRefine)); + + lastRefineAttemptFailed = true; // assume refine attempt will fail + lastCargoAmount = currentCargo; // update last cargo amount + + // Find the ore with the highest refineable amount + refineMap.entrySet().stream() + .filter(e -> e.getValue() > 0) + .max(Map.Entry.comparingByValue()) + .ifPresent(entry -> { + long guiAddress = guiManager.getAddress(); + if (guiAddress == 0) + return; + + long tradeWindowAddress = darkbotApi.readLong(guiAddress + 0x78); + if (tradeWindowAddress == 0) + return; + + darkbotApi.refine(tradeWindowAddress, entry.getKey(), entry.getValue()); + lastRefineAttemptFailed = false; // refine attempt succeeded + }); + } catch (RuntimeException ignored) { + // Keep bot alive on transient client/API states (for example while user interacts + // with upgrade windows), retry next tick. + } } /////////////////////////////// helper methods /////////////////////////////// From 9d060f6e26439069a86823cd30f1fc25c1f85f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ad=C4=B1n=C4=B1z?= Date: Mon, 23 Mar 2026 14:55:31 +0300 Subject: [PATCH 2/2] Refine AutoRefin guards and extract trade window offset constant --- .../shared/kopoklesz/behaviour/AutoRefin.java | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/main/java/dev/shared/kopoklesz/behaviour/AutoRefin.java b/src/main/java/dev/shared/kopoklesz/behaviour/AutoRefin.java index 9f04241d..8a3566c7 100644 --- a/src/main/java/dev/shared/kopoklesz/behaviour/AutoRefin.java +++ b/src/main/java/dev/shared/kopoklesz/behaviour/AutoRefin.java @@ -20,6 +20,7 @@ @Feature(name = "Auto refiner", description = "Automatically refine materials") public class AutoRefin implements Behavior, Configurable { + private static final long TRADE_WINDOW_ADDRESS_OFFSET = 0x78L; private final OreAPI ores; private final GuiManager guiManager; @@ -54,57 +55,56 @@ public void setConfig(ConfigSetting setting) { // behavior @Override public void onTickBehavior() { - try { - if (!isReadyForRefining()) - return; // check if we can refine - - if (getCargoPercent() < config.triggerPercent) { - // Reset tracking variables when cargo is below trigger percent - if (lastCargoAmount != -1) { - lastCargoAmount = -1; - lastRefineAttemptFailed = false; - } - return; + if (!isReadyForRefining()) + return; // check if we can refine + + if (getCargoPercent() < config.triggerPercent) { + // Reset tracking variables when cargo is below trigger percent + if (lastCargoAmount != -1) { + lastCargoAmount = -1; + lastRefineAttemptFailed = false; } + return; + } - int currentCargo = stats.getCargo(); + int currentCargo = stats.getCargo(); - // If cargo hasn't changed since last failed refine attempt, skip to prevent - // unnecessary API calls - if (lastRefineAttemptFailed && currentCargo == lastCargoAmount) { - return; - } + // If cargo hasn't changed since last failed refine attempt, skip to prevent + // unnecessary API calls + if (lastRefineAttemptFailed && currentCargo == lastCargoAmount) { + return; + } - // Cache maxRefine values to avoid duplicate calculations - Map refineMap = Arrays.stream(Ore.values()) - .filter(this::shouldRefineOre) - .collect(Collectors.toMap( - ore -> ore, - this::maxRefine)); - - lastRefineAttemptFailed = true; // assume refine attempt will fail - lastCargoAmount = currentCargo; // update last cargo amount - - // Find the ore with the highest refineable amount - refineMap.entrySet().stream() - .filter(e -> e.getValue() > 0) - .max(Map.Entry.comparingByValue()) - .ifPresent(entry -> { + // Cache maxRefine values to avoid duplicate calculations + Map refineMap = Arrays.stream(Ore.values()) + .filter(this::shouldRefineOre) + .collect(Collectors.toMap( + ore -> ore, + this::maxRefine)); + + // Find the ore with the highest refineable amount + refineMap.entrySet().stream() + .filter(e -> e.getValue() > 0) + .max(Map.Entry.comparingByValue()) + .ifPresent(entry -> { + try { long guiAddress = guiManager.getAddress(); if (guiAddress == 0) return; - long tradeWindowAddress = darkbotApi.readLong(guiAddress + 0x78); + long tradeWindowAddress = darkbotApi.readLong(guiAddress + TRADE_WINDOW_ADDRESS_OFFSET); if (tradeWindowAddress == 0) return; + lastRefineAttemptFailed = true; // assume refine attempt will fail + lastCargoAmount = currentCargo; // update last cargo amount darkbotApi.refine(tradeWindowAddress, entry.getKey(), entry.getValue()); lastRefineAttemptFailed = false; // refine attempt succeeded - }); - } catch (RuntimeException ignored) { - // Keep bot alive on transient client/API states (for example while user interacts - // with upgrade windows), retry next tick. - } + } catch (RuntimeException ignored) { + // Keep bot alive on transient client/API states (for example while user + // interacts with upgrade windows), retry next tick. + } + }); } /////////////////////////////// helper methods ///////////////////////////////