Skip to main content

Break Handler

BreakHandlerPlugin is a native break-scheduling plugin registered in runelite-plugin.properties (config group n3breakhandler, disabled by default). The plugin ports PiggyPlugins' ChinBreakHandler onto the n3 surfaces.

Architecture

  • BreakHandlerPlugin - lifecycle, nav button, login-screen/logout state machine, auto bank pin.
  • BreakHandler - @Singleton RxJava3 service bus; registry of consumer plugins, planned/active breaks, and break statistics. The shared coordination point other plugins inject.
  • State - state-machine enum (NULL, LOGIN_SCREEN, INVENTORY, RESUME, LOGOUT*).
  • OptionsConfig / NullConfig - RuneLite config interfaces for the Options tab.
  • ui/ - BreakHandlerPanel (tabbed: Plugins / Accounts / Options), BreakHandlerPluginPanel (per-plugin spinners + AFK/Logout), BreakHandlerStatusPanel (live countdown), BreakHandlerAccountPanel (login source), LoginMode.
  • util/ - ConfigPanel (generic RuneLite config renderer), spinners/formatters, OnOffToggleButton, IntRandomNumberGenerator, SwingUtilExtended.syncExec.

Reactive bus

BreakHandler exposes RxJava3 Observables (PublishSubject.hide()) for plugin registration, active plugins, planned breaks, active breaks, the current break, extra data, and login/logout actions. Panels and the plugin subscribe to drive their UI and the state machine. currentActiveBreaksSubject carries a Map.Entry<Plugin, Instant> (AbstractMap.SimpleImmutableEntry) - the n3 port's replacement for org.apache.commons.lang3.tuple.Pair.

Consumer API

Another plugin injects BreakHandler and calls:

  • registerPlugin(plugin) / unregisterPlugin(plugin) - appear in the panel.
  • startPlugin(plugin) / stopPlugin(plugin) - begin/stop tracking runtime + breaks.
  • isBreakActive(plugin) / shouldBreak(plugin) - gate work loops.
  • setExtraData(plugin, key, value) - surface live status in the panel.

The plugin schedules breaks itself from the per-plugin threshold spinners; a consumer only needs to register, start, and pause its work while a break is active.

Full automation contract

Full automation plugins must integrate with BreakHandler as an active-only runtime requirement:

  • Register with registerPlugin(this) on plugin startup and unregisterPlugin(this) on shutdown.
  • Call startPlugin(this) only while automation is actively running, and stopPlugin(this) when the plugin is idle, disabled, complete, halted, or shutting down.
  • Before issuing gameplay actions, check shouldBreak(this) and isBreakActive(this). If a planned break is due, call startBreak(this), release any input lock, and skip the action tick.

The current required full automation plugins are Market Alcher, Power Skiller, Tree Woodcutter, Woodcutter, Tutorial Island, Guardians of the Rift, Mule Orchestrator, Bank Stander, Wood Fletcher, GE Buyer, and AIO Fighter. Dialogue Helper, Walk Assistant, Questing Assistant, and Combat Awareness are treated as QoL/helper plugins and are intentionally exempt from this hard requirement. Registered suite/support plugins such as Packet Utils, Profiles, Code Console, Break Handler, Agent Server, and Developer Tools are classified separately in the guardrail because they do not own full automation loops.

State machine

onGameTick drives logout (ESC → logout tab → logout button via MousePackets/WidgetPackets) and login-screen re-entry through BlockingEventActions.continueWelcomeScreen(), which resolves visible legacy or Jagex welcome-screen click targets without hard-coded child IDs in Break Handler. seconds() (1 Hz RxJava interval) performs the re-login when all active breaks have elapsed and the client is on the login screen. Auto bank pin types the PIN one digit per tick against widget (213, 0) and blocks key presses via VarClientInt.BLOCK_KEYPRESS.

Login sources (Accounts tab)

LoginModeRe-login behavior
MANUALUsername/password/bank-pin entered directly in the tab (n3breakhandler config).
PROFILESReads the n3 Profiles typed ProfileStore (see below). Enabled only when an n3 Profiles unlock password is configured.
LAUNCHERJagex Launcher session already present; just sets GameState.LOGGING_IN.

Profiles integration (Part C)

When LoginMode.PROFILES is selected, the break handler reads the unified com.n3plugins.n3Profiles.ProfileStore (decrypted with the configured n3 Profiles unlock password), not a local credential cache:

  • The Accounts dropdown lists StoredProfile.getLabel() for every stored profile.
  • seconds() re-login looks up the selected label:
    • LEGACYProfileLoginService.applyLegacyProfile(login, password, false) then GameState.LOGGING_IN.
    • JAGEXProfileLoginService.applyJagexProfile(sessionId, characterId, displayName) then GameState.LOGGING_IN.
  • BreakHandler.getBankPin(ConfigManager) returns the selected LEGACY profile's 4-digit pin, falling back to the manual bank-pin config when the profile has no usable pin or the store is unavailable.

ProfileStore is injected (constructible from ConfigManager alone), so the break handler reads the same encrypted blob without any cross-plugin singleton sharing.

Configuration (Options tab)

stopAfterBreaks, autoBankPin, autoLoginOnDisconnect, avoidWorldsPlayerCount, avoidWorldsNumbers, and the Hopping section (hop-after-break, american, united-kingdom, german, australian). Per-plugin: <plugin>-thresholdfrom/to, <plugin>-breakfrom/to, <plugin>-enabled, <plugin>-logout.

Testing

.\gradlew.bat test --tests com.n3plugins.breakhandler.* --console plain
  • LoginModeTest - parse (case-insensitive, null, unknown).
  • IntRandomNumberGeneratorTest - inclusive range, singleton range.
  • BreakHandlerTest - getBankPin (manual, PROFILES fallback, null guards), getOrDefaultFrom/To, plugin registry, shouldBreak, startBreak counting.
  • AutomationBreakHandlerRegistrationTest - source-level guardrail for required full automation plugin registration, active lifecycle calls, break gating, helper-plugin exemptions, and registered support-plugin classification.

Client-dependent paths (state machine, packet sends, world hopping) are not unit tested - N3Client is null in the test JVM. See Profiles for the store.

Live validation (pending)

Logout/login state machine on rev239, auto bank pin entry, world hopping filters, PROFILES re-login for both LEGACY and JAGEX profiles end-to-end.

Break Handler Integration Flow

The Break Handler manages breaks using an RxJava3 event bus. Active full automation plugins monitor this status to pause execution, and the Break Handler executes logouts/logins as needed.