Skip to content

fix: hopToWorld guard rejects valid hops after interactions#1773

Merged
chsami merged 2 commits into
chsami:developmentfrom
runsonmypc:fix/hopping
May 13, 2026
Merged

fix: hopToWorld guard rejects valid hops after interactions#1773
chsami merged 2 commits into
chsami:developmentfrom
runsonmypc:fix/hopping

Conversation

@runsonmypc
Copy link
Copy Markdown
Contributor

@runsonmypc runsonmypc commented May 12, 2026

Summary

  • Microbot.hopToWorld(int) used Player.isInteracting() as a safety guard, but that flag stays true for many seconds after benign actions (closing a shop, talking to an NPC, getting aggro'd) because the engine keeps the interaction pointer set until the player moves / re-engages / combat resets. OSRS does not actually block hops in that state, so plugins were stuck retrying with Local player is interacting, cannot hop worlds indefinitely after Rs2Shop.closeShop() and similar flows.
  • Replaced the isInteracting() check with the conditions that actually block a hop: active combat (Rs2Combat.inCombat()) and blocking widgets (Rs2Bank.isOpen(), Rs2Shop.isOpen(), Rs2Dialogue.isInDialogue()).
  • The Wilderness PvP hop timer remains server-enforced via the existing client.hopToWorld() call — no change there. All other guards (isLoggedIn, isHopping, cantHopWorld, quickHopTargetWorld, world equality, world lookup, createWorld) are untouched.

Closes #1772

Test plan

  • ./gradlew :client:compileJava succeeds (only pre-existing deprecation warnings).
  • :client:run boots; client initializes normally.
  • Reproduce the original symptom: stand idle next to an NPC after Rs2Shop.closeShop() (e.g. Blast Furnace foreman) — call Microbot.hopToWorld(...) and confirm the hop proceeds instead of logging Local player is interacting.
  • Verify the new guards still reject hops while: (a) in combat, (b) bank open, (c) shop open, (d) dialogue open.
  • Confirm Wilderness hops still respect the server-side PvP timer (handled by client.hopToWorld()).

Player.isInteracting() stays true for many seconds after benign actions
(closing a shop, talking to an NPC, getting aggro'd) because the engine
keeps the interaction pointer set until the player moves or combat
resets. OSRS does not block hops in that state, but this guard did,
causing plugins to spin on "Local player is interacting, cannot hop
worlds" forever after Rs2Shop.closeShop() and similar flows.

Replace the isInteracting() check with the conditions that actually
block a hop: active combat (Rs2Combat.inCombat) and blocking widgets
(Rs2Bank/Rs2Shop/Rs2Dialogue). Wilderness PvP timer remains
server-enforced via client.hopToWorld().

Closes chsami#1772
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

Review Change Stack

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.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 22730b16-6e23-4db3-bc3d-03d553688a43

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR updates Microbot.java to enhance world-hopping safety. It adds utility imports for bank, combat, dialogue, inventory items, and shop helpers, then modifies the hopToWorld method to replace a player-interaction check with more specific guards. The new checks block world hopping when the player is in combat or when bank, shop, or dialogue UI panels are open.

Possibly related PRs

  • chsami/Microbot#1482: Adds world-hopping calls in FortisGemStall that depend on the updated hopToWorld safety checks.
  • chsami/Microbot#1666: Modifies Rs2Bank.isOpen() which is directly related to the bank-open detection added in the new world-hop guard logic.
  • chsami/Microbot#1617: Also modifies Microbot.java with bank-related refactoring that touches similar safety check logic.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: hopToWorld guard rejects valid hops after interactions' clearly and concisely summarizes the main change: fixing the overly broad isInteracting() guard that was blocking valid world hops.
Linked Issues check ✅ Passed The PR fully addresses all objectives from issue #1772: replaces Player.isInteracting() with Rs2Combat.inCombat() and widget checks (Rs2Bank.isOpen(), Rs2Shop.isOpen(), Rs2Dialogue.isInDialogue()), leaves server-side Wilderness PvP timer enforced, and restores correct hopping behavior for plugins.
Out of Scope Changes check ✅ Passed All changes are narrowly focused on replacing the overly broad isInteracting() guard with targeted safety checks; no out-of-scope modifications to unrelated functionality are present.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The PR description clearly explains the problem (isInteracting() guard too broad), the solution (replace with specific conditions), and provides test plan with reproduction steps.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

Global.sleep / sleepUntil early-return when invoked on the client
thread, so the post-hop wait inside the runOnClientThreadOptional
lambda was a no-op: the success check fired microseconds after
issuing the request, before the server had processed it. The function
returned false on every call, callers retried via sleepUntil polling,
and Microbot.java logged "Failed to hop to world N" 3-4 times per
actually-successful hop.

Move the wait off the client thread. The lambda now only validates
and issues the hop request. The script thread then sleeps and
sleepUntils for HOPPING / world-change / confirm widget, handles the
confirm-dialog fallback, and waits for the hop to fully land
(GameState.LOGGED_IN on the target world) before returning. Success
is reported as getWorld() == worldNumber, the definitive signal, so
callers can trust the return value.

Also: the "already on target world" guard now returns true (idempotent
success) instead of false, killing the retry loop that triggered the
spam on the second and subsequent calls.

Closes chsami#1550
@chsami chsami merged commit 9fda631 into chsami:development May 13, 2026
2 checks passed
@runsonmypc runsonmypc deleted the fix/hopping branch May 13, 2026 13:36
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