Skip to content

Harden Island.setRange against distance-mismatch corruption#2980

Merged
tastybento merged 1 commit into
developfrom
harden/island-setrange-distance-mismatch
May 19, 2026
Merged

Harden Island.setRange against distance-mismatch corruption#2980
tastybento merged 1 commit into
developfrom
harden/island-setrange-distance-mismatch

Conversation

@tastybento
Copy link
Copy Markdown
Member

Summary

  • Island.setRange(int) previously accepted any value, allowing a third-party addon to silently overwrite an island's range with a value that doesn't agree with the gamemode's configured distance-between-islands.
  • On the next restart, IslandsManager.loadIsland refuses the island (range != configured distance) and BentoBox panic-disables with Island distance mismatch — taking the whole server's island system down.
  • setRange now refuses to mutate range to a mismatched value when the game mode enforces equal ranges (the default). Game modes that legitimately resize claims (e.g. StrangerRealms) opt out by returning false from GameModeAddon.isEnforceEqualRanges() and are unaffected.

Background

This was hit in production by a buggy listener in StrangerRealms (companion fix: StrangerRealms#11). TeamListener.onTeamKick / onTeamLeave had inverted boolean logic and called resize() on islands that were not in StrangerRealms' world. resize() then invoked Island.setRange(strangerDistance + strangerMemberBonus * (members - 1)) — typically 64 with defaults — directly mutating the range field of AOneBlock / BSkyBlock / Boxed islands. On every subsequent restart, BentoBox disabled itself.

With this hardening, that mutation is refused at the setter, even before StrangerRealms is patched:

[WARN] Refusing Island.setRange(64) on island AOneBlock4449d5f0-… in world 'oneblock_world':
       value does not match configured distance-between-islands (400).
       Caller: world.bentobox.stranger.listeners.TeamListener.resize(TeamListener.java:99)

That gives addon authors an actionable signal pointing at the exact line responsible.

Behavior

Scenario Before After
setRange(x) where x == range no-op no-op
setRange(x) matches IWM.getIslandDistance(world) accepted accepted
setRange(x) mismatches, addon isEnforceEqualRanges() is true (default) silently corrupts refused + WARN with caller
setRange(x) mismatches, addon isEnforceEqualRanges() is false accepted accepted (unchanged)
setRange(x) when world not registered (getIslandDistance == 0, e.g. unit test / deserialization) accepted accepted

Test plan

  • IslandTest.testSetRangeRefusedWhenMismatchesConfiguredDistance — refuses 64 when configured is 100 and enforce==true
  • IslandTest.testSetRangeAcceptedWhenAddonOptsOutOfEqualRanges — accepts 64 when enforce==false
  • IslandTest.testSetRangeAcceptedWhenValueMatchesConfiguredDistance — accepts a matching value
  • IslandTest.testSetRangeAcceptedWhenWorldNotRegistered — passes through when getIslandDistance == 0
  • ./gradlew compileJava — clean (full test suite was not runnable locally due to a transient MockBukkit dependency-resolution issue in the sandbox; CI should run it cleanly)

Companion PRs

🤖 Generated with Claude Code

Island.setRange previously accepted any int value, which let third-party
addons silently overwrite an island's range with a value inconsistent
with the gamemode's configured distance-between-islands. The next time
IslandsManager.load() ran it would refuse to load the island and
BentoBox would panic-disable with "Island distance mismatch".

This was triggered in the wild by an inverted boolean in StrangerRealms'
TeamListener (fixed separately in StrangerRealms#11) which fired
resize() on islands belonging to other game modes during /<gamemode>
team kick / team leave commands, calling setRange with StrangerRealms'
own distance (typically 64) on AOneBlock / BSkyBlock / Boxed islands.

setRange now refuses to change range to a value that disagrees with
IWM.getIslandDistance(world) when the gamemode enforces equal ranges
(the default — isEnforceEqualRanges() returns true). Game modes that
legitimately resize claims (StrangerRealms etc.) opt out by returning
false from isEnforceEqualRanges() and are unaffected. When the world
is not registered (configured distance == 0) we have no authoritative
value to validate against and pass through, preserving existing
unit-test and deserialization paths.

Refusal logs a WARN with the calling stack frame so addon authors can
locate and fix the offending code path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tastybento tastybento merged commit 029e99f into develop May 19, 2026
1 check failed
@tastybento tastybento deleted the harden/island-setrange-distance-mismatch branch May 19, 2026 14:49
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