Skip to content

Comments

breakhandlerv2#1622

Merged
chsami merged 8 commits intodevelopmentfrom
chsami/breakhandlerv2
Dec 2, 2025
Merged

breakhandlerv2#1622
chsami merged 8 commits intodevelopmentfrom
chsami/breakhandlerv2

Conversation

@chsami
Copy link
Owner

@chsami chsami commented Nov 30, 2025

This PR introduces a comprehensive Break Handler v2 plugin architecture comprising five new classes and one method addition to an existing utility class. The implementation includes a configuration interface defining break timing, behavior, login preferences, and notifications; a state machine enum with ten distinct states; a script class orchestrating state transitions and break scheduling; a plugin class managing lifecycle and dependency injection; and an overlay for displaying break status information. Additionally, two interface methods are implemented in Rs2TileObjectModel for operational compatibility.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 30, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This PR introduces a comprehensive Break Handler v2 plugin architecture comprising five new classes and one method addition to an existing utility class. The implementation includes a configuration interface defining break timing, behavior, login preferences, and notifications; a state machine enum with ten distinct states; a script class orchestrating state transitions and break scheduling; a plugin class managing lifecycle and dependency injection; and an overlay for displaying break status information. Additionally, two interface methods are implemented in Rs2TileObjectModel for operational compatibility.

Possibly related PRs

  • Game objects new simplified api #1606: Modifies Rs2TileObjectModel API with overlapping interface requirements addressed by this PR's additions to the same class.
  • 2.0.41 #1607: Implements Rs2TileObjectModel changes related to the method signatures (getOpOverride, isOpShown) added in this PR.

Pre-merge checks and finishing touches

❌ Failed checks (2 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'breakhandlerv2' is a single generic term that lacks specificity about what aspect of the Break Handler V2 is being introduced or modified. Consider using a more descriptive title like 'Add Break Handler V2 plugin with configuration and state management' to better communicate the scope of this substantial feature addition.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess relevance to the changeset. Add a description explaining the purpose of the Break Handler V2 implementation, its key features, and any relevant context for reviewers.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bd563fe and 2c8fe9f.

📒 Files selected for processing (6)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Config.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Overlay.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Plugin.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Script.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2State.java (1 hunks)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java

📄 CodeRabbit inference engine (AGENTS.md)

runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java: Gameplay automation lives in runelite-client/src/main/java/net/runelite/client/plugins/microbot; keep new scripts and utilities inside this plugin
Register new automation under net.runelite.client.plugins.microbot and reuse the scheduler pattern shown in ExampleScript

Files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2State.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Script.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Overlay.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Config.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Plugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
**/*.java

📄 CodeRabbit inference engine (AGENTS.md)

**/*.java: Keep indentation with tabs, follow the brace placement already in MicrobotPlugin.java, and prefer lines under 120 characters
Use UpperCamelCase for types, lowerCamelCase for members, and prefix configuration interfaces with the plugin name (e.g., ExampleConfig)
Rely on Lombok for boilerplate where already adopted

Files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2State.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Script.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Overlay.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Config.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Plugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/**/*.java

📄 CodeRabbit inference engine (AGENTS.md)

Shared helpers sit under .../microbot/util

Files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
🧠 Learnings (7)
📓 Common learnings
Learnt from: Voxsylvae
Repo: chsami/Microbot PR: 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-11-24T19:05:32.967Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T19:05:32.967Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java : Gameplay automation lives in `runelite-client/src/main/java/net/runelite/client/plugins/microbot`; keep new scripts and utilities inside this plugin

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Script.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Overlay.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Config.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Plugin.java
📚 Learning: 2025-11-24T19:05:32.967Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T19:05:32.967Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java : Register new automation under `net.runelite.client.plugins.microbot` and reuse the scheduler pattern shown in `ExampleScript`

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Script.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Config.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Plugin.java
📚 Learning: 2025-11-24T19:05:32.967Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T19:05:32.967Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/**/*.java : Shared helpers sit under `.../microbot/util`

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Script.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Config.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Plugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
📚 Learning: 2025-11-24T19:05:32.967Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T19:05:32.967Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/**/*.java : Runnable examples live in `.../microbot/example`

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Script.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Plugin.java
📚 Learning: 2025-08-25T07:26:53.623Z
Learnt from: Voxsylvae
Repo: chsami/Microbot PR: 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/breakhandlerv2/BreakHandlerV2Script.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Plugin.java
📚 Learning: 2025-11-24T19:05:32.967Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T19:05:32.967Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/*Plugin.java : When adding panel controls or overlays, update the Microbot navigation panel setup in `MicrobotPlugin` and provide default config values

Applied to files:

  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Overlay.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Config.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Plugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
🧬 Code graph analysis (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Script.java (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/discord/Rs2Discord.java (1)
  • Rs2Discord (19-289)
⏰ 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). (2)
  • GitHub Check: Build
  • GitHub Check: Build

Comment on lines +70 to +90
if (currentState == BreakHandlerV2State.WAITING_FOR_BREAK) {
long secondsUntilBreak = script.getTimeUntilBreak();
//if (secondsUntilBreak >= 0) {
String timeStr = formatDuration(secondsUntilBreak);
panelComponent.getChildren().add(LineComponent.builder()
.left("Next break:")
.right(timeStr)
.rightColor(Color.GREEN)
.build());
//}
} else if (BreakHandlerV2State.isBreakActive()) {
long secondsRemaining = script.getBreakTimeRemaining();
if (secondsRemaining >= 0) {
String timeStr = formatDuration(secondsRemaining);
panelComponent.getChildren().add(LineComponent.builder()
.left("Break ends:")
.right(timeStr)
.rightColor(Color.ORANGE)
.build());
}
}
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 | 🟡 Minor

Inconsistent negative time handling between "Next break" and "Break ends" displays.

The "Break ends" display at line 82 checks secondsRemaining >= 0 before rendering, but the "Next break" display at line 71-78 renders regardless of whether secondsUntilBreak is negative. If the break time has passed but state hasn't transitioned yet, formatDuration() will display negative durations (e.g., "-1m -30s").

Apply this diff to handle negative values consistently:

             if (currentState == BreakHandlerV2State.WAITING_FOR_BREAK) {
                 long secondsUntilBreak = script.getTimeUntilBreak();
-                //if (secondsUntilBreak >= 0) {
+                if (secondsUntilBreak >= 0) {
                     String timeStr = formatDuration(secondsUntilBreak);
                     panelComponent.getChildren().add(LineComponent.builder()
                         .left("Next break:")
                         .right(timeStr)
                         .rightColor(Color.GREEN)
                         .build());
-                //}
+                }
             } else if (BreakHandlerV2State.isBreakActive()) {
📝 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 (currentState == BreakHandlerV2State.WAITING_FOR_BREAK) {
long secondsUntilBreak = script.getTimeUntilBreak();
//if (secondsUntilBreak >= 0) {
String timeStr = formatDuration(secondsUntilBreak);
panelComponent.getChildren().add(LineComponent.builder()
.left("Next break:")
.right(timeStr)
.rightColor(Color.GREEN)
.build());
//}
} else if (BreakHandlerV2State.isBreakActive()) {
long secondsRemaining = script.getBreakTimeRemaining();
if (secondsRemaining >= 0) {
String timeStr = formatDuration(secondsRemaining);
panelComponent.getChildren().add(LineComponent.builder()
.left("Break ends:")
.right(timeStr)
.rightColor(Color.ORANGE)
.build());
}
}
if (currentState == BreakHandlerV2State.WAITING_FOR_BREAK) {
long secondsUntilBreak = script.getTimeUntilBreak();
if (secondsUntilBreak >= 0) {
String timeStr = formatDuration(secondsUntilBreak);
panelComponent.getChildren().add(LineComponent.builder()
.left("Next break:")
.right(timeStr)
.rightColor(Color.GREEN)
.build());
}
} else if (BreakHandlerV2State.isBreakActive()) {
long secondsRemaining = script.getBreakTimeRemaining();
if (secondsRemaining >= 0) {
String timeStr = formatDuration(secondsRemaining);
panelComponent.getChildren().add(LineComponent.builder()
.left("Break ends:")
.right(timeStr)
.rightColor(Color.ORANGE)
.build());
}
}
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Overlay.java
around lines 70 to 90, the "Next break" block renders the formatted duration
even when secondsUntilBreak is negative causing negative time displays; change
that block to only render the "Next break" LineComponent when secondsUntilBreak
>= 0 (same guard used for the "Break ends" block) so negative durations are not
shown, keeping formatDuration usage and panelComponent addition the same but
wrapped inside the secondsUntilBreak >= 0 check.

Comment on lines +377 to +385
*/
private int calculateLoginBackoffDelay(int attemptCount) {
if (attemptCount < INITIAL_FAST_RETRIES) {
return 5000; // 5 seconds for initial retries
}
// Exponential backoff: 30s * (attempt - 3)
int backoffMultiplier = attemptCount - INITIAL_FAST_RETRIES + 1;
return BACKOFF_BASE_DELAY_MS * backoffMultiplier;
}
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 | 🟡 Minor

Comment describes "exponential backoff" but implementation is linear.

The Javadoc and comment claim exponential backoff, but the formula BACKOFF_BASE_DELAY_MS * backoffMultiplier produces linear delays (30s, 60s, 90s, 120s...) rather than exponential (30s, 60s, 120s, 240s...).

Either update the comment to say "linear backoff" or change the formula for actual exponential behavior:

     /**
      * Calculate exponential backoff delay for login retries
-     * First 3 attempts: 5s delay
-     * After that: 30s, 60s, 90s, 120s, etc.
+     * First 3 attempts: 5s delay
+     * After that: linear backoff - 30s, 60s, 90s, 120s, etc.
      */
     private int calculateLoginBackoffDelay(int attemptCount) {

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/breakhandlerv2/BreakHandlerV2Script.java
around lines 377 to 385, the method and comment claim an "exponential backoff"
but currently compute a linear progression; change the implementation to
exponential backoff while keeping the initial fast retries behavior: compute
backoffMultiplier = attemptCount - INITIAL_FAST_RETRIES + 1, then return
BACKOFF_BASE_DELAY_MS multiplied by 2^(backoffMultiplier - 1) (use integer-safe
shift or Math.pow and cast to int) so delays become 30s, 60s, 120s, 240s...;
ensure you still return 5000 for attempts < INITIAL_FAST_RETRIES and update any
inline comment/Javadoc to reflect the corrected exponential formula.

Comment on lines +143 to +151
@Override
public @Nullable String getOpOverride(int index) {
return "";
}

@Override
public boolean isOpShown(int index) {
return false;
}
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 | 🟠 Major

New TileObject methods should delegate to the wrapped tileObject instead of returning constants

Every other TileObject method in this wrapper delegates directly to tileObject, but getOpOverride and isOpShown currently return "" and false unconditionally. That’s inconsistent with the wrapper’s design and may desync behavior from the underlying GameObject/WallObject/etc. (e.g., hiding ops that the base object exposes, or masking any op overrides it defines).

To keep behavior consistent, delegate these calls:

 	@Override
 	public @Nullable String getOpOverride(int index) {
-		return "";
+		return tileObject.getOpOverride(index);
 	}
 
 	@Override
 	public boolean isOpShown(int index) {
-		return false;
+		return tileObject.isOpShown(index);
 	}
📝 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
@Override
public @Nullable String getOpOverride(int index) {
return "";
}
@Override
public boolean isOpShown(int index) {
return false;
}
@Override
public @Nullable String getOpOverride(int index) {
return tileObject.getOpOverride(index);
}
@Override
public boolean isOpShown(int index) {
return tileObject.isOpShown(index);
}
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
around lines 143 to 151, the getOpOverride and isOpShown methods incorrectly
return constant values; change both to delegate to the wrapped tileObject by
returning tileObject.getOpOverride(index) and tileObject.isOpShown(index)
respectively so the wrapper forwards behavior to the underlying
GameObject/WallObject/etc.

Repository owner deleted a comment from coderabbitai bot Dec 2, 2025
@chsami chsami merged commit 4c82dc3 into development Dec 2, 2025
3 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Dec 2, 2025
@coderabbitai coderabbitai bot mentioned this pull request Jan 8, 2026
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.

1 participant