diff --git a/src/main/java/net/runelite/client/plugins/microbot/geflipper/FlipperPlugin.java b/src/main/java/net/runelite/client/plugins/microbot/geflipper/FlipperPlugin.java index 4c38f7b7b5..a422533ffc 100644 --- a/src/main/java/net/runelite/client/plugins/microbot/geflipper/FlipperPlugin.java +++ b/src/main/java/net/runelite/client/plugins/microbot/geflipper/FlipperPlugin.java @@ -23,7 +23,7 @@ isExternal = PluginConstants.IS_EXTERNAL ) public class FlipperPlugin extends Plugin { - public static final String version = "1.1.0"; + public static final String version = "1.2.0"; @Inject private Client client; @Inject diff --git a/src/main/java/net/runelite/client/plugins/microbot/geflipper/FlipperScript.java b/src/main/java/net/runelite/client/plugins/microbot/geflipper/FlipperScript.java index d26398f8ea..b5e51cc3c5 100644 --- a/src/main/java/net/runelite/client/plugins/microbot/geflipper/FlipperScript.java +++ b/src/main/java/net/runelite/client/plugins/microbot/geflipper/FlipperScript.java @@ -38,6 +38,15 @@ enum State { @Slf4j public class FlipperScript extends Script { + private static final int DEFAULT_ACTION_COOLDOWN = 1200; + private static final int ACTION_COOLDOWN_VARIANCE = 600; + private static final int DEFAULT_INTERACTION_TIMEOUT = 33000; + private static final int INTERACTION_TIMEOUT_VARIANCE = 11000; + private static final int INVENTORY_WAIT_TIMEOUT = 5000; + private static final int SCHEDULE_INTERVAL_MS = 600; + private static final int KEY_PRESS_DELAY_MIN = 250; + private static final int KEY_PRESS_DELAY_MAX = 400; + private final WorldArea grandExchangeArea = new WorldArea(3136, 3465, 61, 54, 0); State state = State.GOING_TO_GE; @@ -45,7 +54,8 @@ public class FlipperScript extends Script { private Object suggestionManager; private Object highlightController; private long lastActionTime = 0; - private long actionCooldown = 1500; // randomized cooldown between actions + private long actionCooldown = DEFAULT_ACTION_COOLDOWN; + private long interactionTimeout = DEFAULT_INTERACTION_TIMEOUT; private int[] grandExchangeSlotIds = new int[] { InterfaceID.GeOffers.INDEX_0, @@ -91,7 +101,7 @@ public boolean run() { Rs2Bank.depositAll(); sleepUntil(Rs2Inventory::isEmpty); Rs2Bank.withdrawAll(ItemID.COINS); - Rs2Inventory.waitForInventoryChanges(5000); + Rs2Inventory.waitForInventoryChanges(INVENTORY_WAIT_TIMEOUT); Rs2Bank.closeBank(); sleepUntil(() -> !Rs2Bank.isOpen()); state = State.MONITORING_COPILOT; @@ -104,20 +114,34 @@ public boolean run() { return; } + // Check interaction timeout first - reset ge window state if stuck + long currentTime = System.currentTimeMillis(); + if (Rs2GrandExchange.isOfferScreenOpen() && (currentTime - lastActionTime > interactionTimeout)) { + Rs2GrandExchange.backToOverview(); + + lastActionTime = System.currentTimeMillis(); + actionCooldown = Rs2Random.randomGaussian(DEFAULT_ACTION_COOLDOWN, ACTION_COOLDOWN_VARIANCE); + interactionTimeout = Rs2Random.randomGaussian(DEFAULT_INTERACTION_TIMEOUT, INTERACTION_TIMEOUT_VARIANCE); + + log.info("interactionTimeout reached, returning to GE overview."); + return; + } + // Check for Copilot price/quantity messages in chat if (checkAndPressCopilotKeybind()) return; // Check if we need to abort any offers - if (checkAndAbortIfNeeded()) return; + if (checkAndAbortOrModifyIfNeeded()) return; // Check for highlighted widgets - checkAndClickHighlightedWidgets(); + if (checkAndClickHighlightedWidgets()) return; + break; } } catch (Exception ex) { log.error("Error in FlipperScript: {} - ", ex.getMessage(), ex); } - }, 0, 600, TimeUnit.MILLISECONDS); + }, 0, SCHEDULE_INTERVAL_MS, TimeUnit.MILLISECONDS); return true; } @@ -129,7 +153,7 @@ public void shutdown() suggestionManager = null; highlightController = null; lastActionTime = 0; - actionCooldown = 1500; + actionCooldown = DEFAULT_ACTION_COOLDOWN; super.shutdown(); } @@ -282,7 +306,7 @@ private Widget getWidgetFromOverlay(Object highlightController, String suggestio return null; } - if (Objects.equals(suggestionType, "abort")) + if (Objects.equals(suggestionType, "abort") || Objects.equals(suggestionType, "modify_buy") || Objects.equals(suggestionType, "modify_sell")) { return getHighlightWidgets(highlightController).stream() .filter(Objects::nonNull) @@ -301,10 +325,9 @@ private Widget getWidgetFromOverlay(Object highlightController, String suggestio } } - private boolean checkAndAbortIfNeeded() + private boolean checkAndAbortOrModifyIfNeeded() { - long currentTime = System.currentTimeMillis(); - if (currentTime - lastActionTime < actionCooldown) return true; + if (System.currentTimeMillis() - lastActionTime < actionCooldown) return false; if (flippingCopilot == null || highlightController == null || suggestionManager == null) return false; try @@ -314,20 +337,25 @@ private boolean checkAndAbortIfNeeded() String suggestionType = getSuggestionType(currentSuggestion); - if (!Objects.equals(suggestionType, "abort")) return false; + if (!Objects.equals(suggestionType, "abort") && !Objects.equals(suggestionType, "modify_buy") && !Objects.equals(suggestionType, "modify_sell")) return false; log.info("Found suggestion type '{}'.", suggestionType); Widget abortWidget = getWidgetFromOverlay(highlightController, suggestionType); if (abortWidget != null) - { - NewMenuEntry menuEntry = new NewMenuEntry("Abort offer", "", 2, MenuAction.CC_OP, 2, abortWidget.getId(), false); + { + NewMenuEntry menuEntry; + if (Objects.equals(suggestionType, "modify_buy") || Objects.equals(suggestionType, "modify_sell")) + menuEntry = new NewMenuEntry("Modify offer", "", 3, MenuAction.CC_OP, 2, abortWidget.getId(), false); + else + menuEntry = new NewMenuEntry("Abort offer", "", 2, MenuAction.CC_OP, 2, abortWidget.getId(), false); + Rectangle bounds = abortWidget.getBounds() != null && Rs2UiHelper.isRectangleWithinCanvas(abortWidget.getBounds()) ? abortWidget.getBounds() : Rs2UiHelper.getDefaultRectangle(); Microbot.doInvoke(menuEntry, bounds); lastActionTime = System.currentTimeMillis(); - actionCooldown = Rs2Random.randomGaussian(1200, 300); + actionCooldown = Rs2Random.randomGaussian(DEFAULT_ACTION_COOLDOWN, ACTION_COOLDOWN_VARIANCE); return true; } } @@ -339,24 +367,52 @@ private boolean checkAndAbortIfNeeded() } private boolean checkAndPressCopilotKeybind() { - boolean isChatboxInputOpen = Rs2Widget.isWidgetVisible(InterfaceID.Chatbox.MES_LAYER); - if (!isChatboxInputOpen) return false; - log.info("Found chatbox input open, pressing 'e' then Enter"); - // Press 'e' to trigger FlippingCopilot's keybind - Rs2Keyboard.keyPress(KeyEvent.VK_E); - sleep(250, 400); - Rs2Keyboard.keyPress(KeyEvent.VK_ENTER); - - lastActionTime = System.currentTimeMillis(); - return true; + // 1. Search MES_LAYER_SCROLLCONTENTS for a widget containing "Copilot" (if it's time to select the item suggestion) + Widget scrollContents = Rs2Widget.getWidget(InterfaceID.Chatbox.MES_LAYER_SCROLLCONTENTS); + Widget copilotWidget = null; + + if (scrollContents != null) { + copilotWidget = Rs2Widget.findWidget("Copilot", List.of(scrollContents), false); + if (copilotWidget != null && Rs2Widget.isWidgetVisible(copilotWidget.getId())) { + log.info("Found chat widget '{}'.", copilotWidget.getId()); + // 2. Press only Enter if found in scroll contents (selecting item) + Rs2Keyboard.keyPress(KeyEvent.VK_ENTER); + + // As these widgets tend to disappear quickly sometimes, we sleep after we interact with it to select the suggested item + sleepUntil(() -> System.currentTimeMillis() - lastActionTime < actionCooldown); + lastActionTime = System.currentTimeMillis(); + actionCooldown = Rs2Random.randomGaussian(DEFAULT_ACTION_COOLDOWN, ACTION_COOLDOWN_VARIANCE); + return true; + } + } + + if (System.currentTimeMillis() - lastActionTime < actionCooldown) return false; + + Widget mesLayer = Rs2Widget.getWidget(InterfaceID.Chatbox.MES_LAYER); + if (mesLayer != null) { + copilotWidget = Rs2Widget.findWidget("Copilot", List.of(mesLayer), false); + } + + if (copilotWidget != null && Rs2Widget.isWidgetVisible(copilotWidget.getId())) { + // 3. Press E then Enter (setting price/quantity) + log.info("Found chat widget '{}'.", copilotWidget.getId()); + Rs2Keyboard.keyPress(KeyEvent.VK_E); + sleep(KEY_PRESS_DELAY_MIN, KEY_PRESS_DELAY_MAX); + Rs2Keyboard.keyPress(KeyEvent.VK_ENTER); + lastActionTime = System.currentTimeMillis(); + actionCooldown = Rs2Random.randomGaussian(DEFAULT_ACTION_COOLDOWN, ACTION_COOLDOWN_VARIANCE); + return true; + } + + return false; } - private void checkAndClickHighlightedWidgets() + private boolean checkAndClickHighlightedWidgets() { long currentTime = System.currentTimeMillis(); - if (currentTime - lastActionTime < actionCooldown) return; + if (currentTime - lastActionTime < actionCooldown) return false; - if (flippingCopilot == null || highlightController == null) return; + if (flippingCopilot == null || highlightController == null) return false; try { Widget highlightedWidget = getWidgetFromOverlay(highlightController, ""); @@ -364,14 +420,17 @@ private void checkAndClickHighlightedWidgets() if (isHighlightedVisible) { log.info("Clicking highlighted widget: {}", highlightedWidget.getId()); - Rs2Widget.clickWidget(highlightedWidget); + sleepUntil(() -> Rs2Widget.clickWidget(highlightedWidget)); lastActionTime = currentTime; - actionCooldown = Rs2Random.randomGaussian(1800, 300); + actionCooldown = Rs2Random.randomGaussian(DEFAULT_ACTION_COOLDOWN, ACTION_COOLDOWN_VARIANCE); + return true; } } catch (Exception e) { log.error("Could not process highlight widgets: {} - ", e.getMessage(), e); } + + return false; } } \ No newline at end of file diff --git a/src/main/java/net/runelite/client/plugins/microbot/karambwans/GabulhasKarambwansConfig.java b/src/main/java/net/runelite/client/plugins/microbot/karambwans/GabulhasKarambwansConfig.java index 4a0dc1f15a..0d331581d0 100644 --- a/src/main/java/net/runelite/client/plugins/microbot/karambwans/GabulhasKarambwansConfig.java +++ b/src/main/java/net/runelite/client/plugins/microbot/karambwans/GabulhasKarambwansConfig.java @@ -1,24 +1,57 @@ package net.runelite.client.plugins.microbot.karambwans; import net.runelite.client.config.*; +import net.runelite.client.plugins.microbot.karambwans.enums.KarambwanBankLocation; +import net.runelite.client.plugins.microbot.karambwans.enums.FairyRingAccessMethod; @ConfigGroup("GabulhasKarambwans") @ConfigInformation( + "