Harden Island.setRange against distance-mismatch corruption#2980
Merged
Conversation
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>
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
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 configureddistance-between-islands.IslandsManager.loadIslandrefuses the island (range != configured distance) and BentoBox panic-disables withIsland distance mismatch— taking the whole server's island system down.setRangenow 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 returningfalsefromGameModeAddon.isEnforceEqualRanges()and are unaffected.Background
This was hit in production by a buggy listener in StrangerRealms (companion fix: StrangerRealms#11).
TeamListener.onTeamKick/onTeamLeavehad inverted boolean logic and calledresize()on islands that were not in StrangerRealms' world.resize()then invokedIsland.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:
That gives addon authors an actionable signal pointing at the exact line responsible.
Behavior
setRange(x)wherex == rangesetRange(x)matchesIWM.getIslandDistance(world)setRange(x)mismatches, addonisEnforceEqualRanges()istrue(default)setRange(x)mismatches, addonisEnforceEqualRanges()isfalsesetRange(x)when world not registered (getIslandDistance == 0, e.g. unit test / deserialization)Test plan
IslandTest.testSetRangeRefusedWhenMismatchesConfiguredDistance— refuses 64 when configured is 100 and enforce==trueIslandTest.testSetRangeAcceptedWhenAddonOptsOutOfEqualRanges— accepts 64 when enforce==falseIslandTest.testSetRangeAcceptedWhenValueMatchesConfiguredDistance— accepts a matching valueIslandTest.testSetRangeAcceptedWhenWorldNotRegistered— passes through whengetIslandDistance == 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