
GPExpansion
The ultimate add-on for GriefPrevention 3D Subdivisions
Список изменений
GPExpansion v1.1.14
Teleporting to a claim in the nether — by /claim tp, /claimtp, or clicking through the claim GUIs — landed the player on top of the bedrock roof instead of inside the claim. This release makes the safe-location search ceiling-aware so it resolves to real nether terrain.
No config migration is required and nothing changes in the overworld or the end.
Bug Fixes
Nether claim teleports resolved to the roof
Two things combined to produce it.
World.getHighestBlockYAt() reports the highest non-air block in a column, and in the nether that is always the bedrock roof at y=127. Where a claim had no custom spawn set, ClaimCommand.handleTeleport() derived the destination from that call, so the requested location started life at y=128 — on top of the roof, a couple hundred blocks above the claim.
SafeTeleportUtil then confirmed that as safe rather than correcting it. Its ground scan accepted any solid, non-damaging block as valid footing, and bedrock qualifies: standing at y=128 with roof bedrock below and open air above satisfied every check the validator made. Nothing in the search had a concept of a world ceiling, so both the requested location and the fallback search treated the space above the roof as ordinary terrain.
Claims with a custom spawn were affected too, if that spawn had been set on the roof — the search had no reason to move the player off it.
What changed
SafeTeleportUtil gained a notion of ceilinged worlds, detected generically as getLogicalHeight() < getMaxHeight(). That covers the nether and any Multiverse-style world generated with the nether environment; the overworld and the end report equal values and take none of the new paths.
- Roof bedrock is no longer valid ground. Bedrock within
logicalHeight - 8(the 123–127 slab) is skipped by the downward ground scan, which is what lets the search keep falling through the roof and land on the terrain underneath it. isBlockUnsafe()rejects the roof surface, both standing directly on the slab and standing on anything built above it.getSafeDestination()clamps its starting Y to below the ceiling before searching, and caps its upward search there as well, so it can no longer climb back out.- New
getHighestTeleportY(world, x, z)— a ceiling-aware replacement forgetHighestBlockYAt() + 1that walks down from the ceiling limit, ignoring roof bedrock, and returns the first standable surface below it.ClaimCommand.handleTeleport()andGPBridge.getClaimCenter()now use it. isLocationSafeForSpawn()applies the same two checks, so/claim setspawnon the roof is refused.
Fixing only the validator would have been enough for the default configuration, but not for servers running teleport.safe-location.allow-nearby-fallback: false. That mode skips the search entirely and simply rejects an unsafe request, so every nether claim would have gone from "teleports to the roof" to "refuses to teleport at all". Correcting the source of the Y value is what keeps that path working.
Why not just mark bedrock unsafe
The obvious version of this fix — adding BEDROCK to the material sets SafeTeleportUtil already rejects — breaks the bedrock floor along with the roof. A base sitting on the nether floor at y=5 stands on bedrock at y=4, as does anything at the bottom of an overworld world at y=-64. Under a blanket rule the ground scan would fall past those layers, find nothing solid beneath them, and report the claim unreachable.
The logicalHeight - 8 band is what separates the two. The nether roof occupies y=123–127; the floor is y=0–4. Only the former is excluded, and only in worlds that have a ceiling at all.
Behaviour Changes
/claim setspawnon the nether roof is now refused with the existingclaim.setspawn-unsafemessage. This is a deliberate restriction, not a side effect — the roof is treated as off-limits for claim spawns.- Claim spawns already saved on the roof are not migrated or cleared. Teleporting to one now triggers the standard unsafe-location confirmation (
teleport.safe-location.confirm-unsafe-teleport, on by default) and, once confirmed, moves the player into the nether below rather than to the stored point. Owners who want a stable destination should re-run/claim setspawnsomewhere under the roof. - Players in creative or spectator still bypass all of this while
teleport.safe-location.staff-ignore-unsafe-locationistrue, so staff can still be sent to a roof location.
Configuration
Nothing to migrate. config-version stays at 1.1.2; no keys were added, renamed, or given new defaults. The behaviour is a correction inside the existing teleport.safe-location block and follows whatever it is already set to.
Notes
- No API, permission, placeholder, or command changes.
- The claim GUIs dispatch
claimtpinternally, so they inherit the fix — nothing changed in the GUI classes themselves. - Ban and ejection are not covered.
BanEnforcementListenerand/claim ban's ejection path still fall back togetHighestBlockYAt()when their own search comes up empty, so ejecting someone from a nether claim can still deposit them on the roof. Same one-line helper applies; it was left out as a separate code path from claim teleports. - Pre-existing, untouched:
getSafeDestination()uses-1as its "no ground found" sentinel, which collides with a genuine ground block at y=-1 in 1.18+ worlds. Unrelated to this fix and rare enough in practice not to bundle in. - The change is verified by compilation and by reading the search paths, not by an in-game nether teleport.
