Release 3.16.0#2974
Conversation
When ISLAND_RESPAWN is enabled and the player's home block has been removed, isSafeLocation() returns false and the respawn fell through to world spawn (island at 0,0). Fix: when the home is unsafe, try one block above first (covers slabs / stairs), then scan the island protection-center upward to find any safe spot, mirroring the logic already used by getAsyncSafeHomeLocation. Adds three new unit tests covering the fallback paths. Agent-Logs-Url: https://github.com/BentoBoxWorld/BentoBox/sessions/575de9c2-c8e6-4d36-a9e5-19775b2ea5ab Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
Agent-Logs-Url: https://github.com/BentoBoxWorld/BentoBox/sessions/575de9c2-c8e6-4d36-a9e5-19775b2ea5ab Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
When all quick sync location checks fail (home, home+1, center offsets), anchor the respawn at the island protection center (so the player doesn't appear at world spawn / 0,0) and schedule SafeSpotTeleport on the next tick to scan the island and teleport the player to the nearest truly safe spot. Removes the manual upward Y-scan in favour of this comprehensive async search. Adds testOnPlayerRespawnSafeSpotTeleportFallback unit test and updates testOnPlayerRespawnUnsafeHomeNoSafeIslandLocation to explicitly cover the no-island path (no SafeSpotTeleport triggered). Agent-Logs-Url: https://github.com/BentoBoxWorld/BentoBox/sessions/48ea2d46-020e-47ab-98fe-9d456a85732b Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
…wning-issue fix: ISLAND_RESPAWN sends players to 0,0 when home block is removed
Both AdminTeamSetownerCommand and IslandTeamSetownerCommand previously allowed ownership transfer to a player who already owned their maximum allowed concurrent islands. AdminTeamSetownerCommand only emitted a warning after the fact; IslandTeamSetownerCommand had no check at all. This was a clean bypass of `concurrent-islands` and the per-player `island.number.<n>` permission cap. Both commands now compute the recipient's current concurrent island count and permission-aware cap in canExecute and refuse the transfer when at or above the limit. The user-facing path uses the existing `commands.island.team.setowner.errors.at-max` locale entry; the admin path gets a parallel `commands.admin.team.setowner.errors.at-max` message that includes the count and limit so the admin can adjust the recipient's permission if they really intend to allow it. Closes #2908.
…ds-setowner Refuse setowner when recipient is at the concurrent-islands cap
…tructureGrowEvent - Remove the restrictive material filter from onSpread (was KELP/BAMBOO/BAMBOO_SAPLING only) so vines, cave vines, twisting vines, weeping vines, and all other spreading plants are now blocked when island members are offline - Use e.getSource().getLocation() for the island check in onSpread (source = the plant causing the spread, always on the island) - Add onStructureGrow(StructureGrowEvent) handler so trees and mushrooms that grow from saplings (birch, spruce, acacia, mangrove, etc.) are blocked when offline - Extract repeated island-member check into private checkGrowth() helper - Update testOnSpreadMembersOfflineTree: all spread is now blocked (no material filter) - Add 6 new tests covering the StructureGrowEvent handler (doNothing, membersOnline, membersOffline, nonIsland, nonBentoBoxWorld, boneMealMembersOffline) Agent-Logs-Url: https://github.com/BentoBoxWorld/BentoBox/sessions/31b42c78-d289-4a32-bded-77f467a43797 Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
Agent-Logs-Url: https://github.com/BentoBoxWorld/BentoBox/sessions/4074072d-5ba3-4cdc-aaae-6bc4eabd80c2 Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
…dback) Agent-Logs-Url: https://github.com/BentoBoxWorld/BentoBox/sessions/31b42c78-d289-4a32-bded-77f467a43797 Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
…or multi-island kick Agent-Logs-Url: https://github.com/BentoBoxWorld/BentoBox/sessions/6e406756-8081-4292-bb63-00f6fe227777 Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
…er review feedback Agent-Logs-Url: https://github.com/BentoBoxWorld/BentoBox/sessions/ee9782ec-6693-42a2-a6e3-d0f6775b1387 Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
…on-home-location Add regression test confirming island home location is set on the correct island during concurrent creation
…h-issue Fix OFFLINE_GROWTH: block vine spread and tree growth from saplings
…ck-behavior AdminTeamKick: require x,y,z coordinates when player is on multiple islands
Mirrors OraxenHook / ItemsAdderHook so addons can render the correct icon and display name for CraftEngine custom blocks in panels and GUIs without depending on CraftEngine directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…by-id Add CraftEngineHook.getItemStack(id) lookup
…ght range Agent-Logs-Url: https://github.com/BentoBoxWorld/BentoBox/sessions/dc08b84e-b9de-4e74-9669-11a2a052a6fa Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
…-y-value Fix Dynmap area markers always rendering at y=64
Mirrors the recently-added getItemStack(id) helper. Lets addon command handlers (e.g. /is value hand in Level addon) recognize a held CraftEngine custom item without depending on CraftEngine directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…pers feat(hooks): add CraftEngineHook.getItemId(item) lookup
Introduces WorldSettings#isTeamsDisabled() so game modes can opt out of the team subsystem on a per-world basis. When enabled, every island/admin team sub-command except trust, coop, untrust and uncoop refuses to run and surfaces commands.island.team.errors.teams-disabled. Trust and coop relationships remain available as the supported alternative. Adds the admin team disbandall command for stripping pre-existing team members and sub-owners from every island in a world when flipping the flag on. Trusted and coop players are left alone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
feat: per-world team disable + admin team disbandall (#2965)
Adds commands.admin.team.setowner.errors.at-max to the 22 non-English locale files so the admin setowner cap-exceeded message is localised instead of falling back to the raw key. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Release 3.16.0 update that extends world/team configuration capabilities and fixes multiple gameplay/UX edge cases (offline growth handling, respawn safety, map marker rendering), with accompanying tests and locale updates.
Changes:
- Add “teams disabled” world setting plumbing plus new admin
team disbandallmigration command, and enforce the setting across several team commands. - Improve event handling for offline growth (including StructureGrowEvent) and make island respawn behavior safer via additional fallbacks.
- Adjust Dynmap area/polygon markers to respect world height ranges; add CraftEngine custom item helpers; bump build version and expand regression tests/locales.
Reviewed changes
Copilot reviewed 50 out of 51 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java | Adds regression coverage ensuring island home is set on the correct island instance during creation. |
| src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineGrowthListenerTest.java | Expands offline growth tests (spread materials + StructureGrowEvent). |
| src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListenerTest.java | Adds tests for unsafe-home respawn fallbacks and SafeSpotTeleport scheduling behavior. |
| src/test/java/world/bentobox/bentobox/hooks/DynmapHookTest.java | Adds tests asserting marker Y-range uses world min/max height. |
| src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommandTest.java | Updates/extends tests for ownership transfer concurrency limits. |
| src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommandTest.java | Adds test coverage for “teams disabled” behavior. |
| src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamSetownerCommandTest.java | Adds test for concurrent-islands cap enforcement on admin setowner. |
| src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommandTest.java | Reworks tests for updated admin kick semantics (xyz disambiguation + tab completion). |
| src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamDisbandAllCommandTest.java | New tests for the disbandall confirmation flow and member removal behavior. |
| src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamAddCommandTest.java | Adds test ensuring add is refused when teams are disabled. |
| src/main/resources/locales/zh-HK.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/zh-CN.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/vi.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/uk.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/tr.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/ru.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/ro.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/pt.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/pt-BR.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/pl.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/nl.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/lv.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/ko.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/ja.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/it.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/id.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/hu.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/hr.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/fr.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/es.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/en-US.yml | Adds admin team disbandall strings, adjusts admin kick params, adds teams-disabled message key. |
| src/main/resources/locales/de.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/resources/locales/cs.yml | Adds admin setowner “at max concurrent islands” error translation. |
| src/main/java/world/bentobox/bentobox/managers/IslandWorldManager.java | Exposes isTeamsDisabled(World) based on WorldSettings. |
| src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/OfflineGrowthListener.java | Refactors offline growth checks and adds StructureGrowEvent support. |
| src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListener.java | Adds safe respawn fallbacks and SafeSpotTeleport scheduling when needed. |
| src/main/java/world/bentobox/bentobox/hooks/DynmapHook.java | Sets Dynmap area marker Y-range to world height limits. |
| src/main/java/world/bentobox/bentobox/hooks/CraftEngineHook.java | Adds CraftEngine custom item ↔ ItemStack helper methods. |
| src/main/java/world/bentobox/bentobox/api/configuration/WorldSettings.java | Adds isTeamsDisabled() WorldSettings toggle with Javadoc. |
| src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java | Blocks when teams disabled; enforces concurrent-islands cap on ownership transfer. |
| src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommand.java | Blocks promotion/demotion when teams disabled. |
| src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamLeaveCommand.java | Blocks leave when teams disabled. |
| src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java | Blocks kick when teams disabled. |
| src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommand.java | Blocks invite when teams disabled. |
| src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java | Refuses TEAM invites when teams disabled (trust/coop unaffected). |
| src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamSetownerCommand.java | Enforces concurrent-islands cap when transferring ownership as admin. |
| src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommand.java | Reworks admin kick to support xyz disambiguation + tab completion. |
| src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamDisbandAllCommand.java | New admin migration command to strip members/sub-owners from all islands in-world. |
| src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamCommand.java | Registers the new admin disbandall subcommand. |
| src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamAddCommand.java | Blocks admin team add when teams are disabled. |
| build.gradle.kts | Bumps build version to 3.16.0. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- AdminTeamDisbandAllCommandTest: replace any(Long.class) with anyLong() to avoid an autounbox NPE during Mockito stubbing. - Sync the four keys added in #2975 (admin team disbandall.{description, confirmation,success} + island team errors.teams-disabled) into all 22 bundled locales so non-English servers don't surface raw keys. - Tighten WorldSettings#isTeamsDisabled() Javadoc to list the commands actually blocked rather than the broader "every island team *" claim, and to call out that read-only commands and trust/coop are unaffected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Code Review: PR #2974 — Release 3.16.0 Overview Bundle of 51 files (1209 additions / 82 deletions, 30 commits) merging seven independent fixes/features for the
Strengths
Issues
AdminTeamKickCommand.java:98 (getMemberIslandsXYZ) filters by hasTeam() only: Fix: either exclude owner-islands from the candidate map, or refuse with
Original code sent commands.admin.team.kick.success-all after iterating; the new single-island flow only sends
getItemStack(id) returns Optional; getItemId(item) returns nullable String. Pairs of "lookup by id / id
When all sync fallbacks fail, the player respawns at island.getProtectionCenter() for one tick before
The docstring lists the action commands accurately now (after the recent fix), but IslandTeamInviteRejectCommand
AdminTeamKickCommand now stores both targetUUID and island as instance fields between canExecute and execute. Test Coverage Additions look proportionate:
Gap: no test asserting that AdminTeamKickCommand refuses to kick when the target is the only island's owner — Recommendation Address #1 (owner kick) before tagging — clean inconsistency with low-cost fix and direct user-visible impact. Risk profile is otherwise low: additive API, default-off feature flag, comprehensive locale sync, version bump |
Issue 1: AdminTeamKickCommand could remove an island owner from their own member map. getMemberIslandsXYZ now filters out owner-islands so kick only considers islands where the target is a non-owner member. When all matched team islands are owned by the target, the command refuses with commands.admin.team.kick.cannot-kick-owner and directs the admin to setowner / disband. The same refusal fires when an explicit xyz argument resolves to an island the target owns. The locale message text is updated to mention setowner/disband by name and synced across all 22 translations. Two new test cases cover the owner-protection paths; existing tests are updated so the target is a regular member, not the owner. Issue 2: removed the now-dead commands.admin.team.kick.success-all key from all 22 locale files (en-US never had it; the new single-island flow no longer emits it). Issue 5: WorldSettings#isTeamsDisabled() Javadoc rewritten as an exhaustive list — every command that refuses to run on one side, every command that intentionally remains available on the other (including trust/coop, panel/info commands, invite reject, and the admin commands that operate on existing teams). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous commit added .claude/worktrees/feature-purge-regions-reset as a gitlink (160000) because `git add -A` swept it in. It is a local Claude Code worktree, not a submodule. Remove the gitlink and exclude the worktrees directory going forward. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|



No description provided.