Skip to content

Comments

fix: prevent multiple Login instances in break handler#1524

Merged
chsami merged 1 commit intochsami:developmentfrom
Voxsylvae:bugfix/breakhandler
Sep 17, 2025
Merged

fix: prevent multiple Login instances in break handler#1524
chsami merged 1 commit intochsami:developmentfrom
Voxsylvae:bugfix/breakhandler

Conversation

@Voxsylvae
Copy link
Contributor

@Voxsylvae Voxsylvae commented Sep 16, 2025

  • Fixes login state multiplication by immediately transitioning to LOGGING_IN after creating Login instance in handleLoginRequestedState(). This prevents the repeated execution that was causing multiple login attempts.
  • Prevent immediately login after taking a break and the break has not been ended.

Appreciate further testing, solves the issues on my end. (also test by @Bolado)

Fixes login state multiplication by immediately transitioning to LOGGING_IN
after creating Login instance in handleLoginRequestedState(). This prevents
the repeated execution that was causing multiple login attempts and script
multiplication issues.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 16, 2025

Walkthrough

  • Added @slf4j to BreakHandlerOverlay and replaced render exception prints with log.warn; set overlay layer UNDER_WIDGETS, enabled drag-targeting, and standardized size to STANDARD_WIDTH x 180; rebuilds panel components each render; added extended sleep countdown display during LOGIN_EXTENDED_SLEEP; updated state color mapping to use INGAME_BREAK_ACTIVE and added LOGIN_EXTENDED_SLEEP.
  • BreakHandlerPlugin: formatting-only change (extra blank lines in shutDown).
  • BreakHandlerScript: introduced ban detection/alert/shutdown, intelligent world selection during login, LOGIN_EXTENDED_SLEEP with watchdog, new LOGGING_IN state, refactored in-game break handling, public APIs (isIngameBreakActive, getCurrentState, formatDuration), and Lombok getter for extendedSleepStartTime.
  • BreakHandlerState: enum now stores display names, renamed MICRO_BREAK_ACTIVE to INGAME_BREAK_ACTIVE, added LOGIN_EXTENDED_SLEEP, and overrides toString with dynamic naming.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly and accurately describes the primary fix—preventing multiple Login instances in the break handler—and aligns with the PR objectives and the changes in BreakHandlerScript addressing login state multiplication. It is concise, specific, and clear for a reviewer scanning the commit history.
Description Check ✅ Passed The PR description directly states the two targeted login-flow fixes (transitioning to LOGGING_IN to avoid duplicate Login instances and preventing an immediate login after a break) and is therefore related to the changeset, satisfying this lenient check. The description is concise and on-topic for the primary issues described.
✨ Finishing touches
  • 📝 Generate Docstrings

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (6)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.java (3)

836-839: Window title always says “Microbreak” even for non‑micro in‑game breaks.

When INGAME_BREAK_ACTIVE is due to a normal in‑game break (not micro), the title still shows “In Game Break(Microbreak)”.

Apply:

-            String breakType = state == BreakHandlerState.INGAME_BREAK_ACTIVE ? "In Game Break(Microbreak)" : "Break";
+            boolean micro = Rs2AntibanSettings.microBreakActive;
+            String breakType = state == BreakHandlerState.INGAME_BREAK_ACTIVE
+                    ? (micro ? "In Game Break (Microbreak)" : "In Game Break")
+                    : "Break";

511-513: Log text claims a fallback that doesn’t happen.

Message says “falling back to world selection mode” but the code breaks out and proceeds with default login (no selection).

-                            log.warn("Last world {} is not accessible, falling back to world selection mode", preBreakWorld);
+                            log.warn("Last world {} is not accessible, falling back to default login", preBreakWorld);

103-105: Extended‑sleep “every 5 minutes” log spams once per second during that minute.

Using sleepTime % 5 == 0 logs every tick within that minute. Gate it to once per 5‑minute mark.

@@
-    private static volatile Instant extendedSleepStartTime = null;
+    private static volatile Instant extendedSleepStartTime = null;
+    // last minute mark we logged during extended sleep to avoid per-second spam
+    private static long lastExtendedSleepLogMinute = -1;
@@
-        if (Microbot.isLoggedIn()) {
+        if (Microbot.isLoggedIn()) {
             log.info("Login successful during extended sleep, proceeding to break ending");
             extendedSleepStartTime = null; // reset extended sleep timer
+            lastExtendedSleepLogMinute = -1;
             transitionToState(BreakHandlerState.BREAK_ENDING);
             return;
         }
@@
-        if (extendedSleepStartTime == null) {
+        if (extendedSleepStartTime == null) {
             extendedSleepStartTime = Instant.now();
             log.info("Extended sleep started for {} minutes", config.extendedSleepDuration());
+            lastExtendedSleepLogMinute = -1;
             return;
         }
@@
-        if (sleepTime >= config.extendedSleepDuration()) {
+        if (sleepTime >= config.extendedSleepDuration()) {
             log.info("Extended sleep period completed after {} minutes, resuming login attempts", sleepTime);
             extendedSleepStartTime = null; // reset extended sleep timer
+            lastExtendedSleepLogMinute = -1;
             retryCount.set(0); // reset retry count for fresh attempt
             transitionToState(BreakHandlerState.LOGIN_REQUESTED);
         } else {
-            // still in extended sleep - show progress occasionally
-            if (sleepTime % 5 == 0) { // every 5 minutes
-                long remaining = config.extendedSleepDuration() - sleepTime;
-                log.debug("Extended sleep in progress - {} minutes remaining", remaining);
-            }
+            // still in extended sleep - show progress once per 5-minute mark
+            if (sleepTime % 5 == 0 && sleepTime != lastExtendedSleepLogMinute) {
+                lastExtendedSleepLogMinute = sleepTime;
+                long remaining = config.extendedSleepDuration() - sleepTime;
+                log.debug("Extended sleep in progress - {} minutes remaining", remaining);
+            }
         }

Also applies to: 629-633, 635-639, 643-648, 650-653

runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.java (2)

52-54: Don’t post-process state with replace("_", " ") now that toString() returns display names.

BreakHandlerState.toString() already yields human-friendly labels; replacing underscores is stale logic and can mask future labels.

Apply this diff:

-                    .left("State: " + BreakHandlerScript.getCurrentState().toString().replace("_", " "))
+                    .left("State: " + BreakHandlerScript.getCurrentState().toString())

98-109: Prefer consistent formatDuration overload

Both overloads exist; no compile break. For consistency with other call sites, use the (Duration, String) overload.

-                        .left("Extended sleep: " + BreakHandlerScript.formatDuration(remainingDuration))
+                        .left(BreakHandlerScript.formatDuration(remainingDuration, "Extended sleep:"))
runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerPlugin.java (1)

51-64: Overlay presence check is inconsistent (name vs instance).

Using getName() to detect presence can desync from the actual instance and fail to remove/add correctly. Check by identity to align logic with add/remove using the same instance.

-            boolean hasOverlay = overlayManager.anyMatch(ov -> ov.getName().equalsIgnoreCase(BreakHandlerOverlay.class.getSimpleName()));
+            boolean hasOverlay = overlayManager.anyMatch(ov -> ov == breakHandlerOverlay);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 026771d and f09c1bf.

📒 Files selected for processing (4)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.java (5 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerPlugin.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.java (28 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerState.java (2 hunks)
👮 Files not reviewed due to content moderation or server errors (1)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerState.java
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Voxsylvae
PR: chsami/Microbot#1415
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/pluginscheduler/SchedulerPlugin.java:2341-2366
Timestamp: 2025-08-25T07:26:53.623Z
Learning: In SchedulerPlugin.startLoginMonitoringThread(), do not gate startup on isBreakHandlerEnabled(); rely on isOnBreak() to suppress the monitor only when a break is actually active. This avoids blocking login monitoring whenever BreakHandler is merely enabled.
📚 Learning: 2025-08-25T07:26:53.623Z
Learnt from: Voxsylvae
PR: chsami/Microbot#1415
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/pluginscheduler/SchedulerPlugin.java:2341-2366
Timestamp: 2025-08-25T07:26:53.623Z
Learning: In SchedulerPlugin.startLoginMonitoringThread(), do not gate startup on isBreakHandlerEnabled(); rely on isOnBreak() to suppress the monitor only when a break is actually active. This avoids blocking login monitoring whenever BreakHandler is merely enabled.

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build

Comment on lines +854 to +856
if(scheduledFuture != null && !scheduledFuture.isDone()) {
scheduledFuture.cancel(true);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Cancelling the wrong future risks leaving the main loop running.

run() schedules work on mainScheduledFuture, but shutdown() cancels scheduledFuture. Cancel the main loop too.

         if(scheduledFuture != null && !scheduledFuture.isDone()) {
             scheduledFuture.cancel(true);
         }
+        if (mainScheduledFuture != null && !mainScheduledFuture.isDone()) {
+            mainScheduledFuture.cancel(true);
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(scheduledFuture != null && !scheduledFuture.isDone()) {
scheduledFuture.cancel(true);
}
if(scheduledFuture != null && !scheduledFuture.isDone()) {
scheduledFuture.cancel(true);
}
if (mainScheduledFuture != null && !mainScheduledFuture.isDone()) {
mainScheduledFuture.cancel(true);
}
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.java
around lines 854 to 856, the shutdown path cancels scheduledFuture but not
mainScheduledFuture, which can leave the main loop running; update shutdown() to
also check mainScheduledFuture for null and !isDone(), call
mainScheduledFuture.cancel(true), and perform any same cleanup/reset used for
scheduledFuture (e.g., nulling references or awaiting termination) so the main
loop is stopped reliably.

@chsami chsami merged commit 679a4b6 into chsami:development Sep 17, 2025
2 checks passed
@Voxsylvae Voxsylvae deleted the bugfix/breakhandler branch September 17, 2025 04:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants