# GriefPrevention3D v18.3.1
**Wiki:** https://github.com/castledking/GriefPrevention3D/wiki
## Overview
This maintenance release completes a broad runtime audit of the universal Bukkit JAR against the
1.8.8 API. GP3D already targets Java 8 bytecode and ships legacy compatibility classes, but several
ordinary gameplay paths still linked methods, enum constants, classes, or event shapes which were
introduced after Bukkit 1.8. Those references could let the plugin start and then fail only when a
specific feature was used.
The affected paths now resolve version-dependent behavior through compatibility helpers or stable
names. Current servers keep their current APIs and behavior; older servers use the closest safe
equivalent available to them.
This release also corrects lectern permission handling and a shaped-claim resize case which reported
success without changing the polygon or charging/refunding any claim blocks.
## Bukkit 1.8 compatibility
### Restore-nature and claim auto-extension no longer link modern-only world APIs
The largest compatibility gap was in the terrain analysis shared by `/restorenature`, automatic
nature restoration, and downward claim extension. The code now handles all of the relevant Bukkit
API eras:
- chunk snapshots use the modern material accessor when present and the legacy numeric block ID
accessor on pre-1.13 servers;
- biome reads use the modern three-dimensional accessor or the legacy two-dimensional accessor;
- biome labels no longer invoke the current `Biome` interface directly—on Bukkit 1.8 the type is
a concrete enum/class;
- biome namespaced keys are queried only on versions which provide them;
- block data comparisons tolerate the absence of the 1.13 `BlockData` API;
- custom world environments are matched by name rather than linking the post-1.8 `CUSTOM` enum
constant;
- cardinal block faces are identified from their coordinate modifiers instead of calling the
post-1.8 `BlockFace#isCartesian` and `BlockFace#getDirection` methods; and
- End terrain recognizes both `END_STONE` and its legacy `ENDER_STONE` name, while mushroom and
badlands restoration similarly use the material available on the running server.
The restore material catalogue no longer directly links modern flattened material constants.
Logs, leaves, grass, signs, fences, glass panes, doors, rails, stone bricks, wool, planks, slabs,
beds, cobwebs, pistons, bricks, spawners, enchanting tables, and related blocks are resolved from
both their modern names and their 1.8 aliases. This keeps restored terrain analysis operational
without reducing the modern material coverage.
QuickShop sign protection still checks persistent-data keys on servers with the 1.14+ API. On older
servers, where persistent data does not exist, that check now safely reports no key instead of
making the restore snapshot class fail to load.
The legacy class-loading audit now loads `RestoreNatureProcessingTask` and invokes its biome-name
path with the legacy `DESERT` biome. This specifically guards against reintroducing the class-versus-
interface bytecode failure.
### Interaction and event differences are bridged
Several event APIs changed shape between Bukkit 1.8 and current Paper. The universal JAR now adapts
the following paths:
- hopper transfer protection derives inventory locations from their holders when
`Inventory#getLocation` is unavailable;
- boat collision protection uses the single legacy passenger accessor when the passenger-list API
is unavailable;
- projectile handlers tolerate the absence of `ProjectileHitEvent#getHitBlock`, and cancel only on
server versions where that event implements `Cancellable`;
- Nether portal protection accepts legacy `OBC_DESTINATION` creation events, reads either blocks or
block states from the event, and tolerates the older event not identifying its creating entity;
- block burn protection treats the missing legacy igniting-block accessor as an unknown/spontaneous
source;
- piston warning sounds use the older three-argument explosion overload when the modern
`breakBlocks` flag is unavailable; and
- block-place permission simulations use the constructor and item representation supported by the
running server instead of directly linking the newest `EquipmentSlot` and block/item type APIs.
Player locale detection now falls back to `Player.Spigot#getLocale` on 1.8–1.11. Player bans and
pardons use profile bans on current servers and the legacy name ban list before profile bans were
introduced. bStats also skips its informational configuration header on Bukkit versions which lack
the list-based header method while continuing to save and run metrics normally.
### Legacy materials and entity hierarchies are handled safely
Protection and cleanup code no longer assumes flattened material names or newer entity interfaces:
- leads recognize both `LEAD` and legacy `LEASH`;
- rails recognize both `RAIL` and legacy `RAILS`;
- grass-block checks no longer confuse the block with modern `SHORT_GRASS`;
- end portal frames accept both `ENDER_EYE` and legacy `EYE_OF_ENDER`, and read the inserted-eye
flag through modern block data or legacy metadata;
- falling-block refunds read either modern block data or the legacy material accessor;
- egg refunds fall back to a plain egg before projectile item stacks existed;
- air checks work before `Material#isAir`;
- `Mob`, `AbstractHorse`, newer entity types such as copper golems, and loot-table support are
detected without hard-linking types absent from 1.8; and
- wolf/pet target checks use the legacy `Creature` hierarchy only when the entity actually supports
it, avoiding invalid tameable casts on older Bukkit versions.
These changes cover creative entity cleanup, entity/block damage protection, pet combat, leashing,
projectile block changes, falling-block refunds, and claim interaction checks.
### Boundary visualization remains usable on legacy servers
Modern servers still use collision shapes to decide whether an anti-cheat-compatible fake boundary
block is transparent. Bukkit 1.8 has no collision-shape or API bounding-box support, so legacy
servers now use material occlusion as the fallback. The same compatibility path is used by both the
configured anti-cheat visualization and `BoundaryVisualizationEvent` defaults.
## Lectern trust behavior
Right-clicking a lectern is no longer treated as ordinary container access merely because a lectern
implements `InventoryHolder`.
The intended permission split now applies:
| Action | Required permission |
| --- | --- |
| Read a lectern book | Access trust when `LecternReadingRequiresAccessTrust` is `true` |
| Take the book | Container trust |
| Place a book into the lectern | Container trust |
Previously, the general theft-prevention branch ran first and required container trust even for
reading, making `GriefPrevention.Claims.LecternReadingRequiresAccessTrust` ineffective for players
who had Access but not Container trust. Lecterns are now excluded from that general branch. Reading
continues through the existing access-trust rule, while the dedicated take-book event and
block-place handling retain container protection.
The setting is unchanged and still defaults to `true`:
```yaml
GriefPrevention:
Claims:
LecternReadingRequiresAccessTrust: true
```
## Shaped-claim nib resizing
Resizing from the inner/concave endpoint of a stepped shaped-claim nib now changes the selected
face as expected.
The concave-nib resolver could construct a candidate which passed polygon validation but normalized
back to the original corner list. Because the resize path checked only whether the candidate was
valid, GP3D committed the unchanged polygon, sent `Claim resized`, reported the same available claim
blocks, and ended the resize session.
Nib candidates are now accepted only when they are valid, contain a polygon, **and differ from the
original polygon**. An unchanged candidate is ignored so routing can continue to the normal edge
move. The same guard applies to cardinal and diagonal nib candidates and to both Bukkit shovel
interaction paths.
A regression test uses the reported ten-corner stepped claim and verifies both that the formerly
failing concave drag changes the polygon and that dragging either endpoint of the inner nib face
produces the same resize.
## Upgrade notes
- No claim-data migration is required.
- No permission nodes or message keys were added.
- The lectern setting retains its existing value and default.
- Modern APIs remain the preferred path. Besides the lectern and shaped-resize fixes, the only
intentional modern behavior correction in this pass is recognizing `GRASS_BLOCK`—rather than
the unrelated `SHORT_GRASS` plant—in the sapling placement check.
- The compatibility fallbacks are intentionally conservative where old Bukkit exposes less
information. For example, pre-1.14 portal events cannot identify the creating entity, and pre-1.13
collision transparency is approximated from material occlusion.
## Verification
The full `./gradlew check --no-daemon` pipeline passes. This includes **229 Bukkit tests**, the core
and Fabric test suites, the universal JAR audit, legacy class loading, shaded-core isolation, and the
Fabric boot smoke test against the exact generated universal JAR.
The shaped-nib regression is automated with the reported polygon. The compatibility build verifies
that the edited event handlers, restoration tasks, visualization classes, and plugin entry point
load against the legacy API. Live-server smoke testing is still recommended for 1.8 event behavior,
particularly portals, projectiles, hopper transfers, and terrain restoration.
## Files Changed
```text
M build.gradle.kts
M src/compat/legacy/java/com/griefprevention/compat/legacy/LegacyClassLoadingCheck.java
M src/main/java/com/griefprevention/compat/BlockDataCompat.java
M src/main/java/com/griefprevention/events/BoundaryVisualizationEvent.java
M src/main/java/com/griefprevention/metrics/Metrics.java
M src/main/java/com/griefprevention/protection/InteractionProtectionHandler.java
M src/main/java/com/griefprevention/visualization/impl/AntiCheatCompatVisualization.java
M src/main/java/me/ryanhamshire/GriefPrevention/AutoExtendClaimTask.java
M src/main/java/me/ryanhamshire/GriefPrevention/BlockEventHandler.java
M src/main/java/me/ryanhamshire/GriefPrevention/BlockSnapshot.java
M src/main/java/me/ryanhamshire/GriefPrevention/ClaimToolDispatcher.java
M src/main/java/me/ryanhamshire/GriefPrevention/EntityCleanupTask.java
M src/main/java/me/ryanhamshire/GriefPrevention/EntityDamageHandler.java
M src/main/java/me/ryanhamshire/GriefPrevention/EntityEventHandler.java
M src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java
M src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java
M src/main/java/me/ryanhamshire/GriefPrevention/RestoreNatureExecutionTask.java
M src/main/java/me/ryanhamshire/GriefPrevention/RestoreNatureProcessingTask.java
M src/main/java/me/ryanhamshire/GriefPrevention/compat/CompatUtil.java
M src/main/java/me/ryanhamshire/GriefPrevention/util/BoundingBox.java
A src/test/java/me/ryanhamshire/GriefPrevention/ShapedClaimResizeTest.java
```
Optional dependencies
QuickShop-Hikari
Any compatible version
PlaceholderAPI
Any compatible version
VaultUnlocked
Any compatible version
Developer information
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle.
maven { name = "Modrinth"; url = "https://api.modrinth.com/maven" }