Repository navigation
Release Microbot 2.6.31: telemetry-driven stability fixes - #1941
Merged
Merged
Conversation
… first CodeRabbit on #1901: if building the upload request throws synchronously (e.g. a malformed -Dmicrobot.apiUrl) the drained batch was lost; requeue it before rethrowing. Close the HTTP response before running the rejection callback so a throwing callback cannot leak it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PKz6YjDRJdva762xPzTaia
Client.getLocalPlayer() is null on the login screen, during world hops and while loading. getWorldLocation_Internal and getPoseAnimation dereferenced it directly and threw NullPointerExceptions on the client thread. Guard those and the sibling accessors that read the local player the same way, returning the existing no-player fallback values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
new Rs2PlayerModel() wraps Client.getLocalPlayer(), which is null during login, world hops and loading. Callers already treat null world location and world view as no player, but the model dereferenced the null actor and threw NPEs from inside the client-thread lambda. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… unavailable PathMinimapOverlay passed ShortestPathPlugin.getMinimapClipArea() straight to Graphics2D.setClip. That returns null when the minimap draw widget is missing or hidden, which removed the clip and made OverlayRenderer's graphics.getClip().equals(clip) throw a NullPointerException every frame. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rs2GameObject's WorldPoint-anchored list queries passed the anchor straight into LocalPoint.fromWorld, which throws when the player's world location is not yet known (login, hop, loading). findBank and the other no-anchor overloads feed Rs2Player.getWorldLocation() into these, so they crashed the calling script instead of finding nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t one Rs2Antiban.actionCooldown() dereferenced playStyle unconditionally, so it threw a NullPointerException whenever usePlayStyle was on but no activity had been set (for example when overwriteScriptSettings makes the script's setup template return before setActivity, or after a forced reset). performActionCooldown now resolves a missing play style the same way setActivity does, from the current activity intensity (EXTREME after a reset) or RANDOM when randomIntervals is enabled. The cooldown timer overlay skips drawing when no play style is set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…walk tail processWalk's finish check dereferenced Rs2Player.getWorldLocation() directly, so a null location during a world hop or loading screen threw an NPE and the walk ended as an exception. Return MOVING (the same not-ready result walkWithStateInternal already uses) and guard the final canvas click and tail diagnostic the same way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
refreshTransports allocated refreshBoostedLevels and then filled it from a client-thread lambda that dereferenced the field. PathfinderConfig.refresh is called from several threads, so a concurrent refresh that finished first reset the field to null before the queued lambda ran, throwing an NPE on the client thread. The lambda and the verification hash now use a local array; the field is still published for hasRequiredLevels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rld view Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…yer example Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…player fix(player): guard Rs2Player accessors against a null local player
…or-model-null-actor
…ll local player gotcha Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(actor): return null positions when Rs2ActorModel wraps no actor
…eobject-null-anchor
…or is null Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(gameobject): return empty when the scene query anchor is null
…ker-null-player-loc
…t null Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(walker): yield instead of NPE when player location is missing at walk tail
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(shortestpath): skip minimap path overlay when minimap clip is unavailable
…iban-null-playstyle
fix(antiban): default the play style when action cooldown runs without one
…hfinder-boosted-levels-race
…vels-race fix(shortestpath): capture refresh boosted-levels array locally
…eitem-null-worldview
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(tileitem): return null location when ground item tile lost its world view
…-actor-offthread fix(walker): read interacting actor location on the client thread
fix(widget): guard null root widget in Rs2Widget.clickWidget (telemetry NPE, 3k events)
fix(dialogue): guard Rs2Dialogue.getQuestion against dialog closing between check and fetch
Expose Hunter plugin instance for AutoHunter
…y-stop fix(autologin): opt-in terminal supply logout with bounded pending suppression
Adds a hidden Release Smoke Harness plugin, scripts/run-release-e2e.sh and docs/RELEASE_E2E.md so a maintainer can run quick or full F2P smoke checks against the release candidate jar before merging development into main. The harness reuses TestRunnerPlugin/test mode, runs ordered checks with per-check and total timeouts, skip handling, cleanups that restore game state, and writes result.json plus a Markdown summary. TestRunnerPlugin gains microbot.test.world to log in to a chosen world. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
… world login Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
LoginManager.login() printed the whole active ConfigProfile, including
login name, encrypted password, bank PIN and Discord webhook URL. Remove
that print, exclude the secret fields from ConfigProfile.toString() so
existing "{}" profile log lines stay safe, and drop the bank PIN, webhook
URL and login name from a few other log messages.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
In Microbot the ConfigProfile name is the account login, and the startup, switch, rename and sync log lines wrote it to stdout and client.log. Log the profile id instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
The export path defaults to the profile name, and an IOException message can contain the webhook URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
A stopped script kept initialized=true, so the next start skipped initialize(): it never re-registered in the registry and resumed from its previous state with stale counters and trace. Stopping now resets the machine and only unregisters the entry it owns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
Stop cancels the loop before resetting, initialisation skips an interrupted (cancelled) step, and snapshot publication and reset share a short lifecycle lock so a step finishing after stop cannot leave a registry entry or stale snapshot behind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
fix(security): stop logging profile credentials to stdout
fix(world-hop): wait for the world switcher to load before hopping
fix(statemachine): re-initialise StateMachineScript on restart
test(release): live release E2E smoke harness
…in fighting BreakHandler V2 - Detect login index 33 (Too many login attempts), press Back once, and pause every LoginManager login for an escalating cooldown (5/10/20/30 min, jittered) that resets after a successful login. - AutoLogin and BreakHandler V2 wait out the cooldown instead of retrying. - AutoLogin defers to BreakHandler V2 while a V2 break is active, so the two no longer log in/out against each other during a logout break. - AutoLogin only starts a login from LOGIN_SCREEN, not during HOPPING/LOADING. - Agent server reports the lockout and returns 429 while the cooldown runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
- Count a lockout only once per appearance of the lockout screen, so a screen that outlives its cooldown does not escalate on its own. - Reset the AutoLogin watchdog while waiting out a lockout. - Agent server /login returns 429 with loginCooldownMs when polling hits the lockout screen, matching the rejected-initiation path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
fix(login): handle "Too many login attempts" lockout; stop AutoLogin fighting BreakHandler V2
AutoLogin reset its retry count and last-attempt time as soon as the client left LOGIN_SCREEN, so every LOGIN_SCREEN -> LOGGING_IN -> LOGIN_SCREEN failure restarted from attempt one and retried within seconds. Stay in ATTEMPTING_LOGIN while the client is logging in or loading, only reset on a confirmed login, and apply the escalating backoff and retry limit when the client falls back to the login screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
fix(autologin): keep retry backoff across failed login attempts
…race and antiban EDT block - Rs2ActorModel.getAnimation returns -1 when the model wraps no actor (new Rs2PlayerModel() while logged out / loading) - Rs2UiHelper.isRectangleWithinCanvas treats a null rectangle as off-canvas, so doInvoke falls back instead of throwing - QuestScript captures the selected quest once instead of re-reading it inside the client-thread lambda, and no longer unboxes an empty Optional - Antiban panel computes Category.isBusy on the refresh timer thread instead of the Swing EDT, which blocked the UI for up to 10 s per tick Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
…ategory once Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
fix(telemetry): null actor animation, null click bounds, quest race, antiban EDT block
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
Contributor
|
Important Review skippedToo many files! This PR contains 135 files, which is 35 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configuration
⛔ Files ignored due to path filters (1)
📒 Files selected for processing (135)
You can disable this status message by setting the
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. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promotes
developmenttomainas 2.6.31. It is mostly stability work driven by the script error telemetry that shipped in 2.6.30.Error telemetry fixes (the largest prod error groups on 2.6.30):
Rs2Player,Rs2ActorModel, the walker tail,Rs2WorldPointand the bank helpers.List.of(null)).Other
Release tree
bb9a7b866fmergesorigin/developmentintomainwith no conflicts.623c09230dbumpsmicrobot.version2.6.30 → 2.6.31.developmentapart from that line. RuneLite stays on 1.13.1.Test plan
:client:runUnitTests: 2283 tests, 0 failures, 2 skipped-PmicrobotClientPath), so Hub CI stays green once 2.6.31 is the latest clientMicrobot release E2E: PASS (full tier)
bootClient version, core plugins, clean startup logloginLogged in with a known player locationstate-cachesSkills, items, varbits/varps and entity queryables at Lumbridge castlewidgetsTab switching by widget click and widget text searchwalker-transportShort walk, closed door and Lumbridge castle stairsbankOpen nearest bank, deposit and withdraw one junk itemnpc-dialogueTalk to a banker, read and pick a dialogue option, exitobject-interactionOpen and close a door, restoring its stateagent-serverAgent Server state, inventory, widgets and skills endpointswalker-mediumLumbridge to Varrock west bankgrand-exchangeOpen and close the Grand Exchange without offersworld-hopHop to another F2P world and backhub-pluginsPlugin Hub manifest, install/start/stop/uninstall a harmless pluginscript-lifecycleStart and stop a built-in script twice without leaked threadslogoutClean logout and full-run client.log scanAfter merge, the Release workflow publishes
microbot-2.6.31.jar, uploads it to Hetzner and updates the version on microbot.cloud. Hub release: chsami/Microbot-Hub#595.🤖 Generated with Claude Code
https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV