19.0.7latestGriefPrevention3D v19.0.7yesterday GriefPrevention3D v19.0.7
Wiki: https://github.com/castledking/GriefPrevention3D/wiki Back upGriefPreventionDatabefore updating.Vehicle damage: container trust parity & configurable build trust
Breaking vehicles (minecarts, boats) in claims has been aligned with upstream GriefPrevention's anti-theft behavior, with a configurable option to enforce build trust. - Container trust default: By default, breaking vehicles in a claim requires container trust (/containertrust), restoring 1:1 parity with upstream GriefPrevention. Players granted container trust can break and pick up vehicles in the claim. - `Claims.VehiclesRequireBuildTrust: false` (default): Added to both Paper and Fabricconfig.yml. When set totrue, breaking vehicles in a claim requires build trust (/trust), protecting minecarts and boats on servers that grant container trust broadly (such as public shops or loot warps).Config
New key added toconfig.ymlon Paper and Fabric:GriefPrevention: Claims: VehiclesRequireBuildTrust: falseUpgrade notes
- Restart the server after replacing the jar. - Both platforms continue to ship in one universalGriefPrevention3D.jar: Spigot/Paper/Purpur/Folia (1.8 through modern) and Fabric (1.21.2 through 1.21.11, and 26.1 through 26.3). Fabric requires Fabric API. - No database migrations are required.19.0.6GriefPrevention3D v19.0.6yesterday GriefPrevention3D v19.0.6
Wiki: https://github.com/castledking/GriefPrevention3D/wiki Back upGriefPreventionDatabefore updating.Fabric: Restore Nature
The Restore Nature feature has been ported to Fabric, bringing full parity with Paper and Spigot for repairing griefed terrain and returning areas to their natural state. - `/restorenature` (/rn,/aclaim restore): Switches the golden shovel into restoration mode. Right-clicking a block inspects and restores a 5-block radius column (from the world's minimum to maximum height) back to natural terrain. - `/restorenatureaggressive` (/rna,/aclaim restore aggressive): Switches to aggressive restoration mode. In addition to standard cleanup, this mode overrides claim boundaries, strips player-placed ores and bedrock, and clears tree canopies (leaves and logs). - `/restorenaturefill [radius]` (/rnf,/aclaim restore fill [radius]): Switches to fill mode with a custom radius between 1 and 10 blocks (default 2), filling holes and hollowed areas in the terrain. - `/basicclaims` (/bc): Exits any active restoration mode and returns the shovel back to standard claim creation.Restoration behavior
- Asynchronous column scan: Terrain processing runs off the main thread. It samples the entire vertical column, strips player-placed blocks (such as chests, crafting tables, furnaces, doors, rails, wool, planks, slabs, stairs, and torches), removes floating blocks (suspended dirt, snow, or logs), and knocks down thin unnatural walls. - Natural fill and surface repair: Terrain holes beneath the surface level are filled in using the dimension's base material (netherrack in the Nether, end stone in the End, dirt in the Overworld). The natural surface block (grass block, sand, red sand, or mycelium) is restored based on the biome. - Claim respect: Standard restoration skips any block located within an existing claim. Aggressive mode can modify claimed blocks. - Entity protection: Players and animals standing within the restoration zone have air cleared at their feet and head to prevent suffocation. Unprotected item drops and hanging entities (item frames, paintings) in the zone are removed. - Visual boundary: After restoration completes on the server, a 5-second glowing boundary preview with lime glazed terracotta corner markers and emerald side markers (matching Paper) outlines the restored zone for the user.New Fabric commands & permissions
| Command | Permission | Default | What it does | |---|---|---|---| |/restorenature(/rn,/aclaim restore) |griefprevention.restorenature| op | Switches the shovel tool to standard restoration mode | |/restorenatureaggressive(/rna,/aclaim restore aggressive) |griefprevention.restorenatureaggressive| op | Switches the shovel tool to aggressive restoration mode | |/restorenaturefill [radius](/rnf,/aclaim restore fill [radius]) |griefprevention.restorenatureaggressive| op | Switches the shovel tool to fill mode with radius 1–10 | |/gpglow [on\|off\|toggle](/claimglow) |griefprevention.visualize| all | Toggles glowing boundary visualization on or off |Boundary visualizations:
- `/gpglow toggle` on Fabric and Paper: Fabric now supports/gpglowtoggle & surface fixes/gpglow(/claimglow) to enable or disable glowing boundary display entities (/gpglow [on|off|toggle]). The setting is persisted toVisualizations.Glowinconfig.ymlwhile preserving comments, and toggling it off immediately despawns active glowing entities. Paper's/gpglowcommand handler now also accepts/gpglow toggledirectly. - Single green glow & consistent blocks: Aligned Fabric restore nature markers with Paper, usinglime_glazed_terracottacorners andemerald_blocksides with a single green glow outline (0x55FF55) instead of separate aqua and green glows. - Surface visualization fix on Paper: Fixed restore nature boundary visualization scanning upwards from the world's minimum bedrock level (minY/ -64), which previously caused boundary markers to get trapped underground in caves beneath the terrain surface. Boundary scanning now correctly anchors to the terrain surface. - Legacy client compatibility (ViaBackwards): Added per-player protocol detection across Paper and Fabric. Clients on versions prior to glazed terracotta (<1.12 / <1.10) automatically receivelime_woolinstead oflime_glazed_terracotta. Glowing display entities are omitted for clients on <1.19.4 which lack BlockDisplay support.Respect disabled commands in
Previously, settingalias.ymlenabled: falseon subcommands or root commands inalias.ymlcould leave standalone command aliases or tab completions active. - Disabled subcommands skip standalone registration: Disabling a subcommand (such aslist) inalias.ymlnow properly skips registering its standalone aliases (such as/claimslist) and excludes it from/claimand/aclaimtab completions. - Disabled root commands skip registration: Settingenabled: falseon a root command (such as/claimor/aclaim) prevents the unified command handler and its associated subcommands from registering. - This applies consistently on both Bukkit/Paper and Fabric platforms.Upstream cleanup: deprecated API removal (#2678)
Merged upstream GriefPrevention's cleanup of long-deprecated legacy classes and methods: - Removed deprecated legacy visualization types and classes (me.ryanhamshire.GriefPrevention.Visualization,VisualizationElement, andVisualizationType). Visualizations continue to use the moderncom.griefprevention.visualizationsystem. - Removed obsolete event classes and deprecated getter methods (PreventBlockBreakEvent,ClaimModifiedEvent, and legacy getters onAccrueClaimBlocksEvent,ClaimExtendEvent,ClaimResizeEvent, andPlayerKickBanEvent).Upgrade notes
- Restart the server after replacing the jar. - Both platforms continue to ship in one universalGriefPrevention3D.jar: Spigot/Paper/Purpur/Folia (1.8 through modern) and Fabric (1.21.2 through 1.21.11, and 26.1 through 26.3). Fabric requires Fabric API. - No database migrations or config conversions are required.19.0.5GriefPrevention3D v19.0.5last week GriefPrevention3D v19.0.5
Wiki: https://github.com/castledking/GriefPrevention3D/wiki Back upGriefPreventionDatabefore updating.Faster large shaped claims
Large shaped edits could stall the server or consume excessive memory while extending a path around an existing claim. Several calculations scanned every block column inside the shape's bounding rectangle, even when most of that rectangle was outside the claim. - Shape unions, cuts, overlap checks and containment checks use compact ranges. They no longer need to allocate a point for every claimed column or walk the entire bounding rectangle. - Path extensions and claim merges use the same optimized geometry on Bukkit/Paper and Fabric. Merge-corridor width and connectivity checks also avoid block-by-block flood fills. - Shaped subdivision checks remain exact. Concave gaps stay outside the claim, and rectangular subdivisions only one block wide still work inside shaped parents. - Claims already at their minimum depth skip the automatic depth scan on Bukkit/Paper. This avoids collecting potentially thousands of chunk snapshots when no downward extension is possible. A regression benchmark uses a real 427-corner coastline covering about 1.56 million block columns. Joining it to a large rectangle took approximately 15 ms with the new geometry; the previous routine exhausted the same 192 MiB test heap. This measures the geometry calculation, not a complete live-server interaction or the work performed by other plugins.Editable tutorial links
The survival, creative and subdivision tutorial links can now be changed separately from their surrounding messages. All 16 bundled message files include these entries:
On Bukkit/Paper, edit the active file inMessages: SurvivalVideoURL: '&3&nbit.ly/mcgpuser&r' CreativeVideoURL: '&3&nbit.ly/mcgpcrea&r' SubdivisionVideoURL: '&3&nbit.ly/mcgpsub&r'plugins/GriefPreventionData/Lang/messages_<locale>.yml. On Fabric, editplugins/GriefPreventionData/messages.yml. Replace the default links with your own URLs and run/gpreloadafter saving. Color codes are supported. The configured links are used by the corresponding tutorial prompts and, on Bukkit/Paper, the survival welcome book. With per-player locales enabled on Bukkit/Paper, the URL follows the player's language file. Existing books already in inventories are not rewritten. Keep{0}inSurvivalBasicsVideo2,CreativeBasicsVideo2,SubdivisionVideo2andBookLinkwhere the link should appear. Existing customized help text is preserved.Upstream cleanup
Synced upstream's removal of obsolete config, numeric material-ID and claim-filename migration helpers. Unrecognized files inClaimDataare now skipped and logged rather than deleted or automatically renamed. Very old installations that still need those conversions should first upgrade through a release that provides them.Upgrade notes
- Restart the server after replacing the jar./gpreloadapplies later message-file edits. - The new message keys are added with the existing tutorial URLs as defaults. No new config options or permission nodes are required. - Current claim files keep the same format; existing shaped claims benefit without being redrawn. - Both platforms continue to ship in one universalGriefPrevention3D.jar. Fabric requires Fabric API.19.0.4GriefPrevention3D v19.0.4last week GriefPrevention3D v19.0.4
Wiki: https://github.com/castledking/GriefPrevention3D/wiki Back upGriefPreventionDatabefore updating.Admin claim trust under
WhenRequireIgnoreClaimsInAdminClaimsGriefPrevention.RequireIgnoreClaimsInAdminClaims: trueis enabled on Spigot or Paper, staff holdinggriefprevention.adminclaimsare no longer blocked before GP3D checks the claim's trust list: - Claim trust works without `/ignoreclaims`. Public grants such as/containertrust public(including trading with villagers and opening public containers), personal trust, and permission trust now apply to staff the same way they apply to any other player. - Untrusted build and container actions still require `/ignoreclaims`. Actions not covered by the claim's trust list continue to return the normal denial message with the/ignoreclaimsreminder. - Administrative subdivisions follow the same rule. Administrative subdivisions inside player claims now enforceRequireIgnoreClaimsInAdminClaimsfor build and container checks unless the action is covered by trust on the subdivision (or inherited from an unrestricted parent claim). Walking through, resizing, and managing trust in administrative subdivisions still work without/ignoreclaims.Upgrade notes
- Only servers withGriefPrevention.RequireIgnoreClaimsInAdminClaims: true(off by default) are affected. - No config or data changes are required, and Fabric behavior is unchanged. - Both platforms continue to ship in one universalGriefPrevention3D.jar. Fabric requires Fabric API.19.0.3GriefPrevention3D v19.0.32 weeks ago GriefPrevention3D v19.0.3
Wiki: https://github.com/castledking/GriefPrevention3D/wiki Back upGriefPreventionDatabefore updating.Prevent climbing on rejected blocks
Players can sometimes use a client-predicted block as a temporary step even though GP3D rejects its placement in a claim. This release adds an optional setback to prevent repeated placements from being used to climb walls. It is available on Bukkit/Paper and Fabric. The option is off by default. To enable it, add or change this setting inplugins/GriefPreventionData/config.yml:
RunGriefPrevention: Claims: PreventBlockPlaceClimbing: true/gpreloadafter saving. When GP3D denies a colliding placement near a player's feet, the protection can return them to a recent position supported by real blocks, including when the upward movement arrives after the placement is denied. The destination is checked for support and clearance before a setback. Ordinary jumps, authorized building, active claim bypass, flying, gliding, swimming and vehicle movement are unaffected. A recent safe position is needed before a setback can occur.Upgrade notes
- Existing servers keep their previous behavior until the new setting is enabled. - No new permission nodes are required. - Both platforms continue to ship in one universalGriefPrevention3D.jar. Fabric requires Fabric API.19.0.2GriefPrevention3D v19.0.22 weeks ago GriefPrevention3D v19.0.2
Wiki: https://github.com/castledking/GriefPrevention3D/wiki Back upGriefPreventionDatabefore updating.Weaving protection on Paper and Fabric
Weaving could create cobwebs inside another player's claim when an affected player or mob died. This update protects those placements on Paper, Purpur, Folia and Fabric. - Player deaths require build trust. Every prospective cobweb is checked at the block where it would appear. Dying outside a claim can no longer place webs across its boundary. Subdivision restrictions and 3D height boundaries are respected, and authorized claim bypass still works. - Mob deaths cannot place cobwebs inside claims. The death does not reliably identify who applied the weaving effect, so claimed blocks are protected regardless of the mob's type. Weaving still works in survival wilderness and in worlds where claims are disabled. - Claimed animals and villagers require container trust to receive weaving potions. Access trust alone is insufficient. This covers splash potions and both standard and custom lingering weaving effects. - Dispensers cannot apply weaving across claim boundaries. They may affect creatures in the same claim as the dispenser, including the same subdivision. A neighboring claim is treated separately even when it has the same owner. Fabric remembers the dispenser's launch location and carries it into the lingering cloud, so the potion's landing position cannot bypass this check. Players may still drink weaving potions and receive their own thrown potion effects. Any cobwebs generated by their death follow the build-permission checks above. Other potion effects are unchanged. The Fabric protection runs in both bundled adapters, covering Minecraft 1.21.2–1.21.11 and 26.1–26.3.Upstream updates
- Removed the obsolete conversion of player names to UUIDs, following upstream GriefPrevention. MySQL support and migration from flat files to the database remain available in GP3D. - Synced upstream's knockback-listener cleanup. GP3D retains its existing handling, which already avoids processing the same entity knockback twice.Upgrade notes
- No new config keys or permission nodes are needed. Existing claims, trust and UUID-based data keep working. - Mob-based cobweb farms inside claims will stop placing webs. Mob-generated cobwebs remain allowed in survival wilderness; player-generated webs in claims require build trust. - Servers whose GP data still uses pre-UUID player names must first update through an older release that performs that conversion, then update to 19.0.2. Both platforms continue to ship in one universalGriefPrevention3D.jar. Fabric requires Fabric API.19.0.1GriefPrevention3D v19.0.12 weeks ago GriefPrevention3D v19.0.1
Wiki: https://github.com/castledking/GriefPrevention3D/wiki Back upGriefPreventionDatabefore updating.Fabric: inactive players' claims expire
Fabric used to ignoreClaims.Expiration. It now cleans up claims as the plugin does, so abandoned claims no longer pile up on long-running servers. - `Claims.Expiration.AllClaims.DaysInactive` (60 days by default) deletes all of a player's claims once they have been away that long. - `Claims.Expiration.ChestClaimDays` (7 days by default) deletes a player's only claim sooner, if it is no bigger than a new player's claim (Claims.AutomaticNewPlayerClaimsRadius, 4 by default, a 9×9 claim). With Fabric's default minimum area of 100 blocks, few claims are that small. - As on the plugin, one claim owner is checked everyAdvanced.ClaimExpirationCheckRateseconds (60 by default), going round every owner in turn. These players keep their claims: - anyone online; - anyone with at leastExceptWhenOwnerHasTotalClaimBlocksclaim blocks (10000 by default), or at leastExceptWhenOwnerHasBonusClaimBlocksbonus blocks (5000 by default); - anyone with `griefprevention.dontexpire`.griefprevention.dontexpireworks with LuckPerms even while the player is offline: their LuckPerms data is loaded for the check and released afterwards, so a grant on a group they belong to counts too. Without LuckPerms, server operators are exempt, which is the permission's default. If the check fails, the claims stay. Expired claims are deleted without theAbandonReturnRatiopenalty, and each one is written to the server log. Other Fabric mods can keep a claim from expiring through the newClaimExpirationCallback, as plugins can withClaimExpirationEvent.When the first claims can expire
Fabric learns when players were last online fromGriefPreventionData/LastSeen.yml, which started recording in 18.4.7 (26 September 2026). Players not seen since then keep their claims, as the plugin keeps the claims of players without a last-played time. With the default 60 days, no claim can expire before late November 2026.New command
| Command | Permission | What it does | |---|---|---| |/checkclaimexpiry [player](/claimcheckexpiry,/aclaim checkexpiry) |griefprevention.checkclaimexpiry| Shows when the owner of the claim you stand in was last seen, when their claims expire, and what keeps them | Checking another player by name also takesgriefprevention.admin.checkclaimexpiry, which only operators have by default, as on the plugin.Spigot and Paper
- Indonesian messages. SetGriefPrevention.Localetoid_ID, or letPerPlayerLocalepick it for players whose client is set to Bahasa Indonesia. - bStats now reports the server software by its name (for example Paper or Purpur), from upstream GriefPrevention (#2667).Config
New Fabricconfig.ymlkeys, matching the plugin. They are added to existing files on startup without changing anything you have set, and/gpreloadrereads them:GriefPrevention: Claims: AutomaticNewPlayerClaimsRadius: 4 Expiration: ChestClaimDays: 7 AllClaims: DaysInactive: 60 ExceptWhenOwnerHasTotalClaimBlocks: 10000 ExceptWhenOwnerHasBonusClaimBlocks: 5000 Advanced: ClaimExpirationCheckRate: 60Upgrade notes
- Expiration is on by default on Fabric, as on the plugin. To keep every claim, set bothDaysInactiveandChestClaimDaysto0. - If a Fabric expiration setting cannot be read, expiration turns off and the error is logged, instead of falling back to the defaults. -Claims.Expiration.UnusedClaimDaysandAutomaticNatureRestorationare not on Fabric yet. Both need restore nature, which Fabric does not have. Both versions still ship in oneGriefPrevention3D.jar: 1.8 through the latest release on Spigot, Paper, Purpur and Folia, and 1.21.2 through 1.21.11 and 26.1 through 26.3 on Fabric.19.0.0GriefPrevention3D v19.0.03 weeks ago GriefPrevention3D v19.0.0
Now a stable build. One universal JAR runs as a Bukkit plugin and as a Fabric dedicated-server mod. Fabric requires Fabric API. Back upGriefPreventionDatabefore updating.Fabric claims and commands
- Create and manage claims. Basic and administrative claims, 2D and 3D subdivisions, claim lookup, abandonment, trust, trust lists, and staff claim management are available through the same command aliases and permission nodes as the plugin. Fabric has no economy integration, so paid claim transfers are refused unless the player has the free-transfer permission. - Shaped claims. EnableGriefPrevention.Claims.AllowShapedClaims, then use/shapedclaims(alias/shapedclaimor/claim mode shaped). With the golden shovel, right-click the outline's corners in order and click the first corner again to close it. The live path and finished claim both show corner nibs and boundary markers. Clicking an existing 2D claim boundary starts a reshape. - Extend claims./extendclaim <numberOfBlocks>(aliases/expandclaimand/resizeclaim) extends or shrinks the most specific claim at your location, or the claim selected with the shovel nib. It supports 2D and 3D claims, subdivisions, and shaped outlines. - Inspect claims. The configured investigation tool (STICKby default) shows the claim at the targeted block; sneak-use it to visualize nearby claims. The golden shovel displays claim boundaries and supports claim selection. - Resize with the scroll wheel./scrollresizepreviews a claim or subdivision while scrolling and applies the change on right-click. Looking down selects the bottom face of a 3D subdivision. A selected corner is range-gated to avoid a corner click registering through to a farther block. Shaped claims are disabled by default.AllowShapedSubClaimsalso defaults tofalse;ShapedMinimumWidthandShapedMinimumAreacontrol their size rules.Allow3DSubdivisionsdefaults totrue. These settings are read from the existingconfig.ymland added on startup when missing.Claim protection
- Explosions respect the configured land-claim and surface explosion protections, including protected entities. - Starting or extending a raid requires build trust in the raid-center claim, or in the triggering player's claim when the raid center is unclaimed.Claims.RaidTriggersRequireBuildTrustdefaults totrue.Compatibility and packaging
- One Modrinth release lists Bukkit, Folia, Paper, Purpur, Spigot, and Fabric, using this combined changelog. - Fabric supports Minecraft 1.21.2–1.21.11 and 26.1–26.3 on dedicated servers. Bukkit-family support starts at Minecraft 1.8. - Modrinth stores one game-version list for all loaders on a release, so this listing advertises the Fabric targets. Bukkit support for older Minecraft releases remains available through Spigot and the universal JAR. - The universal JAR is about 2.2 MB, below the 5 MB target.Upgrade notes
No claim migration is needed. Existing settings remain in place; new config keys are added with the defaults above.18.4.14GriefPrevention3D v18.4.143 weeks ago GriefPrevention3D v18.4.14
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
- Claimed cushions can no longer be broken by untrusted players ([#13](https://github.com/castledking/GriefPrevention3D/issues/1… A cushion is an entity, not a block, so the block protection that covers everything else never applied to it. On top of that, it is a non-living entity: a hit on one raises no damage event at all, so the creature protection that covers armor stands and item frames never saw it either. All of these now need build trust in the cushion's claim: - Paper / Purpur / Folia. Melee, arrows, snowballs, eggs and fire all go through the cushion's break event now. Reeling one in with a fishing rod takes container trust, as with armor stands. - Fabric. Melee and arrows are stopped before the hit lands, and a new mixin on the cushion's own damage handling stops snowballs and eggs, which bypass the melee hook. Sitting on a cushion in a claim you can't build in is still allowed, matchingClaims.PreventCushionMount(default false) on Paper. Reeling one in takes container trust. - Both.EntityDamageHandlerno longer carries a deadCUSHIONentry that could never fire. Cushions only exist on Minecraft 26.3 and later, so older servers are unaffected.New features
- Per-player glow toggle for claim visualizations./claimglow(or/claim glow) lets each player turn the glowing outline on or off for themselves, independently of the server-wideVisualizationGlowsetting. The setting persists across restarts in the player data file./gpglowlets an administrator flip the global setting at runtime; it is always available, while/claimglowonly works while the global setting is on. - Paper:/claimglow [on|off](griefprevention.glow),/gpglow [on|off](griefprevention.debug). - Fabric: the same two commands, registered through the alias system. - Toggling either setting refreshes any visualization the player currently has drawn, so the change shows up immediately.Upgrade notes
Nothing to migrate. The player data file gains a fifth line (glowEnabled, defaulting totrue) the first time a player's data is rewritten; old four-line records keep working and default to glow on. TheVisualizationGlowconfig key is unchanged. Both versions still ship in oneGriefPrevention3D.jar: 1.8 through the latest release on Spigot, Paper, Purpur and Folia, and 1.21.2 through 1.21.11 and 26.1 through 26.3 on Fabric.18.4.13GriefPrevention3D v18.4.133 weeks ago GriefPrevention3D v18.4.13
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
- Sulfur cubes in claims are protected like other creatures ([#12](https://github.com/castledking/GriefPrevention3D/issues/1… Minecraft 26.2's sulfur cubes got past claim protection in three ways. All three now need container trust in the cube's claim, which is what hurting any claimed creature already needs: - Hits. A cube holding a block takes no damage from a hit. The hit knocks it away instead, and fire aspect lights a TNT cube's fuse. Neither fires a damage event, so creature protection never saw them. On Paper and servers built on it, the hit is now stopped before it lands. That covers knockback, fire aspect and a sword killing an empty cube. Spigot has no event for this, so there a hit cube is still put back where it stood, as before. - Arrows and other projectiles. A projectile shot by a player without container trust stops when it hits a claimed cube, so a burning arrow can no longer prime a TNT cube. - Fishing rods. Reeling in a claimed cube now takes container trust, as reeling in animals and armor stands already did. The protection followsClaims.ProtectCreatures: turn that off and sulfur cubes are no more protected than other creatures. Staff using/ignoreclaimsget through as usual. - New claims reach down to everything built under them. When a claim is created, GriefPrevention looks under it for player-built blocks and storage, and lowers the claim's floor to cover them. If the claim's west or north edge was at a negative coordinate, that search skipped the chunks along that edge. Chests and builds under that part of the claim could end up below the claim's floor, unprotected. Ported from upstream GriefPrevention (#2659). 3D claims are not affected, since they keep the heights they were drawn with.Upgrade notes
Nothing to migrate and no new options. Sulfur cubes only exist on Minecraft 26.2 and later, so older servers only get the claim depth fix. The experimental Fabric version in the same jar gains/scrollresize,/trapped, claim alerts and several new protections. They're listed in the Fabric version's changelog on Modrinth. Both versions still ship in oneGriefPrevention3D.jar: 1.8 through the latest release on Spigot, Paper, Purpur and Folia, and 1.21.2 through 1.21.11 and 26.1 through 26.3 on Fabric.18.4.12GriefPrevention3D v18.4.124 weeks ago GriefPrevention3D v18.4.12
Wiki: https://github.com/castledking/GriefPrevention3D/wiki Nothing changes for Spigot and Paper servers in this release. It behaves exactly like v18.4.11, so updating is optional. This update is for the experimental Fabric version in the same jar. Fabric finally has subdivisions, including 3D ones, and its claim tool finds the corner you aim at from any distance, so a corner under water is clickable. The Fabric changes are in the Fabric version's changelog on Modrinth. Both versions still ship in oneGriefPrevention3D.jar: 1.8 through the latest release on Spigot, Paper, Purpur and Folia, and 1.21.2 through 1.21.11 and 26.1 through 26.3 on Fabric.18.4.11GriefPrevention3D v18.4.11Oct 10, 2026 GriefPrevention3D v18.4.11
Wiki: https://github.com/castledking/GriefPrevention3D/wikiNew options
- `AutoIgnoreClaims` (default false). Staff who hold the newgriefprevention.autoignoreclaimspermission start each session with claim protections already off, so they can build wherever they need to without touching every claim first. The grant covers every protection: building, containers, entity damage, PvE and knockback, pets, and the rest. Running/ignoreclaimsturns protections back on for the rest of that session. It is not saved to disk, so it never outlives the session. The new permission defaults toopand is deliberately not a child ofgriefprevention.adminclaims, so granting that one does not hand it out. Grant it on its own:
- `RequireIgnoreClaimsInAdminClaims` (default false). Staff normally walk into administrative claims and build freely. With this on, building and using containers inside an administrative claim additionally requires that the staff member be ignoring claims. Walking through, resizing and managing administrative claims still work as before, sogriefprevention.autoignoreclaims: default: op/adminclaimand friends do not suddenly start refusing. The refusal reads the same way every other protection refuses: each one gives its own reason for that action, followed by the usual "To override, use /ignoreclaims." pointer. No new messages were needed for it. The two options pair up: turnRequireIgnoreClaimsInAdminClaimson and give your buildersgriefprevention.autoignoreclaimsalongsideAutoIgnoreClaims, and staff keep building in admin land while every other claim stays protected. Both options appear in your generatedconfig.ymlbetweenAdminsGetSignNotificationsandVisualizationAntiCheatCompatMode, in this order:GriefPrevention: AdminsGetSignNotifications: true AutoIgnoreClaims: false RequireIgnoreClaimsInAdminClaims: false VisualizationAntiCheatCompatMode: falseUpgrade notes
Nothing to migrate. Both options are off by default, so nothing changes until you turn one on. Staff withoutgriefprevention.autoignoreclaimsare unaffected byAutoIgnoreClaimseven when it is on.Under the hood
- The session grant is a separate field on a player's data from the/ignoreclaimstoggle, and like that toggle it is never written to storage. Protection checks ask whether a player is ignoring claims rather than reading the toggle directly, so every existing protection honours the session grant without each one needing to know about it. - The two/ignoreclaimscode paths, the unified command handler and the legacy one, now share a single toggle so they cannot drift apart. - New tests cover the session grant, the permission gate,/ignoreclaimsturning protections back on, and the administrative claim requirement for building and containers.18.4.10GriefPrevention3D v18.4.10Oct 10, 2026 GriefPrevention3D v18.4.10
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
- A claim transfer an addon cancels now does nothing, and says nothing. When an addon cancels the transfer,/transferclaim,/makeadminand/makebasicleave the claim with its owner and stop quietly. Before, they could still say the claim was transferred or converted and write an admin log entry, though the owner had not changed. - A transfer an addon redirects is no longer mistaken for a cancelled one. If an addon hands a claim someone gives away to a different player, the transfer now counts as done. Before, it was treated as cancelled and the fee refunded, though the claim had changed hands. - Servers running eco and Iris start again. GriefPrevention3D no longer lists Iris as a soft dependency. Iris soft-depends on eco and eco on GriefPrevention, so the loop stopped the server from starting. Nothing in GriefPrevention3D uses Iris.Under the hood
- New tests cover cancelled and redirected transfers. - A new test makes sure a copied claim keeps both of its corners and its area. The copy once took its lesser corner from the original's greater corner, which shrank it to a single column of blocks. That was fixed during the 3D work, and the test now keeps it fixed. Nothing changes in game.Fabric
The experimental Fabric version in the same jar now also runs on Minecraft 1.21.2 through 1.21.10. The details are in the Fabric version's changelog on Modrinth.Upgrade notes
Nothing to migrate.18.4.9GriefPrevention3D v18.4.9Oct 4, 2026 GriefPrevention3D v18.4.9
Wiki: https://github.com/castledking/GriefPrevention3D/wiki Nothing changes for Spigot and Paper servers in this release. It behaves exactly like v18.4.8, so updating is optional. This update is for the experimental Fabric version in the same jar. The Fabric changes are in the Fabric version's changelog on Modrinth.18.4.8GriefPrevention3D v18.4.8Sep 28, 2026 GriefPrevention3D v18.4.8
Wiki: https://github.com/castledking/GriefPrevention3D/wikiGiving claims to other players
/transferclaim <player>, or/claim transfer <player>, now lets players give away a top-level claim they own, once a server turns it on. They confirm by addingconfirmand can be charged through Vault, like/claimpvp:
The recipient needs enough claim blocks and a free claim slot, and is told if they are online. Staff keep the old behavior withGriefPrevention: Claims: TransferClaim: Enabled: false # let players give away their own claims Price: 0.0 # what giving a claim away costsgriefprevention.transferclaim.others(previouslygriefprevention.transferclaim): any claim, at once, for free. New permissionsgriefprevention.transferclaim.freeandgriefprevention.claimpvp.freeskip the transfer and PvP toggle prices. The new messages are translated in every bundled language.Protection
- Tamed pets can no longer attack animals in a claim where their owner couldn't ([GriefPrevention#2642](https://github.com/GriefPrevention/GriefPrevention/issues… - A polar bear guarding cubs in a claim no longer attacks players who aren't allowed to hit it back. - Leashing boats in claims followsClaims.PreventTheft, like leashing animals.Fabric
Nothing changes for the experimental Fabric version in the same jar; these features are for Spigot and Paper.Upgrade notes
Drop-in replacement for v18.4.7. Staff who hadgriefprevention.transferclaimset explicitly should be givengriefprevention.transferclaim.othersto keep transferring other players' claims.18.4.7GriefPrevention3D v18.4.7Sep 27, 2026 GriefPrevention3D v18.4.7
Wiki: https://github.com/castledking/GriefPrevention3D/wiki Nothing changes for Spigot and Paper servers in this release. It behaves exactly like v18.4.6, so updating is optional. This update is for the experimental Fabric version in the same jar, which now runs on Minecraft 26.1 through 26.3 as well as 1.21.11. The Fabric changes are in the Fabric version's changelog on Modrinth.18.4.6GriefPrevention3D v18.4.6Sep 26, 2026 GriefPrevention3D v18.4.6
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
%gp3d_trust_level%and%gp3d_is_trusted%now update live in TAB and other plugins that refresh placeholders in the background. Before, a scoreboard kept showing the trust level from when the player walked into the claim. Toggling/ignoreclaimsor being trusted and untrusted while standing still changed nothing until they walked out and back in./trustliston a subdivision also stops hiding players whose inherited trust is only partly blocked by a deny entry.Trust placeholders
Why it happened
To work out a player's trust level, the expansion calledClaim.checkPermission, which firesClaimPermissionCheckEvent. Paper only allows that event on the main server thread. TAB and similar plugins refresh placeholders on their own thread, so every background refresh threw an error and the plugin kept the last value it had read successfully. That value usually came from when the board was first built./papi parseruns on the main thread, so it always showed the right answer, which made the problem look like a scoreboard configuration mistake.The fix
ClaimgainshasDefaultPermission(Player, ClaimPermission). It runs the same default trust rules ascheckPermissionwithout firing the event: - claim owner -/ignoreclaimswith the bypass permission - admin claims and admin subdivisions - explicit trust, including permission-node trust - public trust - subdivision inheritance and deny entries The placeholders use it, so they are safe to read from any thread. Real permission checks in the game still fire the event exactly as before. Because the event is no longer fired for placeholders, plugins that listen to it (GPFlags, for example) no longer change what the placeholder displays. They still control the actual permission check./trustlist and partly denied inheritance
A subdivision inherits its parent claim's trust unless a deny entry blocks it. A deny for one level, such as#build, only blocks that level. A player who is a builder on the parent and denied#buildin the subdivision still has container trust there, and%gp3d_trust_level%correctly reportsContainer./trustlistgrouped inherited entries by their level on the parent and dropped anyone denied that level. So that player vanished from the list completely, and it looked as though they had no trust in the subdivision at all. Denied inherited entries now move down to the highest level they still hold: | Parent trust | Denied in subdivision | Listed as | |---|---|---| | Builder |#build| Container | | Builder |#buildand#container| Access | | Container |#container| Access | An entry leaves the list only when every level it could inherit is denied.Upgrade notes
No configuration or storage changes. Drop-in replacement for v18.4.5.18.4.5GriefPrevention3D v18.4.5Sep 21, 2026 GriefPrevention3D v18.4.5
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
WithVisualizationGlow: true, players on clients older than 1.19.4 saw claim borders as blocks nudged out of alignment, with an armor stand flickering into view as each one spawned. Those players now get the classic fake block borders instead, while everyone else keeps the glowing ones.Why it happened
Glowing visualization draws each border block as a block display entity, added in Minecraft 1.19.4. A server running ViaVersion accepts clients older than itself, so the server supporting display entities says nothing about what a given player can render. ViaBackwards translates a display into an armor stand wearing the block, which sits slightly off-centre — the nudged border, and the armor stand visible for the instant before it is dressed. The visualization provider only checked the server's own version, so every player got the glowing treatment whether or not their client could draw it.The fix
The provider now considers the viewer as well as the server. A client known to be older than 1.19.4 is shown the fake block visualization, which every version renders correctly. Client versions are read from ViaVersion's API by reflection, so GriefPrevention3D gains no dependency and nothing changes on servers that do not run it: - No ViaVersion installed: every client speaks the server's protocol, so nothing is gated. This is what already happened. - ViaVersion installed: each viewer is checked as their border is drawn. Modern clients keep glowing borders; older ones get fake blocks. - A player ViaVersion cannot identify: treated as speaking the server's protocol, the same as above. Border displays were already spawned per-viewer, so an old client never saw another player's glowing borders either.Also fixed
BoundaryVisualizationdecided whether a failed visualization belonged to GriefPrevention or to another plugin by comparing providers by identity against its own singleton. Building a provider per viewer would have made every internal failure report as coming from an "external visualization provider", so the check now tests the provider's type, and the error fallback path builds a viewer-aware provider as well.Upgrade notes
No configuration or storage changes.VisualizationGlowkeeps its meaning: enable it and every client that can render glowing borders gets them. Drop-in replacement for v18.4.4.18.4.4GriefPrevention3D v18.4.4Sep 20, 2026 GriefPrevention3D v18.4.4
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
Message text can now contain [PlaceholderAPI](https://placeholderapi.com) placeholders. Drop%player_name%,%vault_eco_balance_fixed%or anything else a server-side placeholder provides intomessages.yml— or into any of the bundledLang/messages_*.ymlfiles — and the placeholder is resolved for the player who actually receives the message, in their own language and with their own values.How it works
Previously a placeholder written into a message file appeared literally in chat. Placeholders are now resolved as the message is handed to a player: - `DataStore.getMessage(player, ...)` — the single funnel that resolves a message against a player's locale. With per-player locales enabled this is exactly wheremessages_en.ymlis swapped for the client's language, so a German player gets the German template with their own placeholder values in one step. - The raw message send paths — denial messages built before a player is known (claim guards hand back a message supplier that only resolves at send time), scroll resize status, action bar and delayed/respawn messages. No localized output that reaches a player is left with literal%...%brackets. Placeholders are never expanded for the console or for messages built without a player, because there is nobody to resolve them for — a server-name placeholder in a console log line still makes sense, but nothing player-specific can.Soft dependency, no surprises
PlaceholderAPI has always been an optional soft-depend. That stays true: - PlaceholderAPI absent or disabled → every message is byte-for-byte what it was before; the%...%text is left alone. - PlaceholderAPI present → expansion is wrapped so a placeholder that errors never breaks a message send. - No library is bundled. The plugin still boots fine on a server that has never heard of PlaceholderAPI. The bundled%gp3d_*expansion from v18.x (trust level, subdivision status) is untouched and combines naturally with the new support — e.g. a message can embed%gp3d_trust_level%next to%player_name%.Documented in every language
The header comment of every message file now advertises the feature, translated into each of the fifteen locales — English, Pirate Speak, Czech, German, Spanish, French, Japanese, Malay, Polish, Portuguese (Brazil), Russian, Turkish, Ukrainian and Chinese (Simplified). Successful examples (%vault_eco_balance_fixed%,%player_name%) are spelled out so the format is copy-pastable.Upgrade notes
No configuration or storage changes. Install [PlaceholderAPI](https://placeholderapi.com) on the server (it already sits in the plugin's soft-depend list), restart, and refresh any existingmessages.yml/messages_*.ymlfrom the jar — or just put placeholders into the files you already have. Two things to keep in mind: - Placeholders resolve when a message reaches a player. Anything rendered without a player — such as the welcome book, which is built from locale strings at startup — shows the literal placeholder text unless the book is customised. - A placeholder only generates output while the player and its backing plugin (e.g. Vault) are online. Messages sent to a player who just logged out keep the placeholder text rather than crash. Drop-in replacement for v18.4.3.18.4.3GriefPrevention3D v18.4.3Sep 19, 2026 GriefPrevention3D v18.4.3
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
- Protection fix: container trust was enough to break a claim's minecarts and boats. It now takes build trust. - Locale fix: the bundled Czech translation was registered nowhere, socs_CZcould not be selected at all.Breaking a claimed vehicle now needs build trust
Vehicle damage was checked against container trust — the same level that opening a chest minecart takes. Any claim that grants container trust broadly, such as a public shop or a warp handing out trial loot, therefore let visitors break its minecarts and boats and walk off with the drops. Breaking a vehicle destroys it, so it is now checked against build trust. Nothing else about vehicles changed: - Riding a boat still takes access trust. - Opening a chest or hopper minecart still takes container trust. - Non-player damage — creepers, withers, TNT — is still blocked outright inside claims. The only players who lose anything are those who were never trusted to build in the first place. This is not a Minecraft 26.2 regression, despite when it started being reported. Minecraft 26.3 still routes vehicle damage throughVehicleDamageEventbeforeVehicleDestroyEvent, exactly as earlier versions did, so the events GriefPrevention listens for never stopped arriving — the trust level being asked for was simply the wrong one.Czech locale was never registered
Czech translations shipped in the jar, but the locale was never registered.messages_cs_CZ.ymlwas only known to nothing — neither the list of bundled locale files nor the list of supported locale codes — so it was never extracted to theLang/folder and could not be selected by anything.Locale: cs_CZinconfig.ymlfell back to English, and a Czech client was silently ignored on servers running per-player locales.Two missing registrations
The locale system keeps two lists, andcs_CZwas in neither: - `BUNDLED_LOCALE_FILES` — the files unpacked from the jar intoLang/on first start. An unlisted file stays bundled, unreachable no matter what the configuration asks for. - `SUPPORTED_LOCALE_CODES` — the codes accepted byLocale:inconfig.ymland matched against a client's language for the per-player locale feature.messages_cs_CZ.ymlis now registered in both. Server admins can setLocale: cs_CZ, and Czech clients get their language automatically whenPerPlayerLocaleis left enabled, falling back to English where a message has no Czech translation yet.README: the language situation is now documented
The README previously claimed only Spanish and Portuguese clients were served their own language. A new **Supported Languages** section lists all fourteen bundled locales — English, Czech, German, Spanish, French, Japanese, Malay, Polish, Portuguese (Brazil), Russian, Turkish, Ukrainian, Chinese (Simplified) and Pirate Speak — and clarifies how the per-player locale feature actually behaves. The section links to the [Locale guide](https://github.com/castledking/GriefPrevention3D/wiki/Loc… for customising or adding languages. The same pass tidied the README's feature lists:/scrollresizeis now covered under Key Features, and the v18.4.2 rate limiting under Subtle Changes. Documentation only; no plugin behaviour changed.Also merged: the upstream raid-location fix
The raid trigger check upstream shipped this cycle now looks up the claim at the raid's location rather than the player's. GP3D has done the same since the handler was pulled into its own class — and it additionally falls back to the player's location when no claim is at the raid site — so the merge kept GP3D's version unchanged.Upgrade notes
Players holding only container trust can no longer break vehicles in a claim. If your server relies on visitors breaking carts — a public minecart station where riders pick their cart back up, for instance — those players need build trust, or the carts need to sit outside the claim. No configuration or storage changes. Run the new jar once and the Czech translation is extracted toLang/; it is then selectable asLocale: cs_CZor served to Czech clients automatically. Drop-in replacement for v18.4.2.18.4.2GriefPrevention3D v18.4.2Sep 18, 2026 GriefPrevention3D v18.4.2
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
Denial messages that arrive once per swing, per arrow or per placed block are now rate limited, and the 10 second cooldown behind them was fixed so that throttling one message no longer silences the rest.One cooldown per message
GriefPrevention keeps a 10 second cooldown on rate limited messages, but it stored a single timestamp per player. Any throttled denial therefore silenced every other error for the remainder of the window — a player stopped at a claim border would not be told why their next, unrelated action failed. Cooldowns are now tracked per player per message. Two further fixes came with it: - Lapsed entries are dropped as they are checked, so denials that carry an owner's name cannot accumulate for the length of a session. - A player's cooldowns are forgotten when they disconnect, rather than being held until the next restart.Denials that are now rate limited
These all fire from events that repeat without the player doing anything new: - Projectiles changing blocks — decorated pots, chorus flowers, TNT and pointed dripstone. A cancelled hit leaves the arrow in flight, so it keeps colliding with the block; this was the worst of the set. - Damage to claimed entities — animals, pets, armor stands, item frames, villagers, end crystals and vehicles, each of which messaged once per swing or arrow. - PvP safe zones and spawn immunity — the knockback handler sent its own copies of these on every hit, duplicating denials that were already throttled elsewhere. - Hanging entities, paintings, signs, block and multi-block placement, the creative active-block limit, and automatic claim creation failing because another claim is too close. - Cauldrons, end portal frames, ignition, chorus flower hits and nether portals. - Splash potions thrown at claimed animals. - PvP and siege restrictions on drops, containers, the claim tool and pets, wilderness buckets, and ender pearls denied at a claim border.Repeatable warnings move to the action bar
Three warnings fired once per block placed and had no cooldown at all. They are now rate limited in their own colour, and added to the defaultActionBarMessageslist so a row of blocks no longer fills chat: -NoPistonsOutsideClaims-TooDeepToClaim-NoEnoughBlocksForChestClaimWhat is deliberately unchanged
Golden shovel feedback keeps a specific message for every click, so each denial still explains exactly what was wrong with that click. Chat and command output are untouched as well — a command that replies with nothing reads as a lagging server.Upgrade notes
ActionBarMessagesonly takes its defaults when the list is absent or empty. An existingconfig.ymlalready lists the previous five entries, so add the three above to move them out of chat, or remove the list and let it regenerate. No storage changes. Drop-in replacement for v18.4.1.18.4.1GriefPrevention3D v18.4.1Sep 18, 2026 GriefPrevention3D v18.4.1
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
A dispenser inside a claim could not break that claim's own chorus flowers or decorated pots, so chorus flower farms stopped working once the area was claimed. Armor stands were already exempt; flowers and pots now follow the same rule.Chorus flowers and decorated pots
Two handlers guard projectiles that break blocks, and they disagreed: - TheEntityChangeBlockEventhandler already allowed a projectile fired by a dispenser standing in the same claim. - An earlierProjectileHitEventguard cancelled every hit on a chorus flower or decorated pot that a player did not fire. Since Minecraft 1.20.2 a cancelled hit never reaches the block, so the handler that would have allowed the dispenser never ran. The hit guard now applies the same rule as the change-block handler: a dispenser in the same claim is allowed, as is a mob whenMobProjectilesChangeBlocksis enabled. A dispenser outside the claim shooting in is still blocked, and players still need trust in the claim. The guard is kept for older servers whoseEntityChangeBlockEventdoes not cover these blocks. This affects every projectile that breaks these blocks in vanilla — arrows, snowballs, eggs, tridents, fireballs and wind charges.Armor stands
The armor stand check that allows a dispenser in the same claim now uses the same shared helper. The previous code compared claim IDs directly and could fail on a claim whose ID was not yet assigned. Behaviour is otherwise unchanged.Upgrade notes
No configuration or storage changes. Drop-in replacement for v18.4.0. Reported upstream as [GriefPrevention/GriefPrevention#2278](https://github.com/GriefPrevention/GriefPrevention/issues…18.4.0GriefPrevention3D v18.4.0Sep 16, 2026 GriefPrevention3D v18.4.0
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
Claim protection for the two pieces of furniture added in Minecraft 26.3: - Cushions could be placed in anyone's claim by untrusted players. Placing and breaking one now needs build trust, and sitting on one can optionally need access trust. - Straw beds are not part of the vanillabedstag, so the existing bed rule never covered them. Using one now needs access trust by default. Everything else is unchanged; servers on older Minecraft versions are unaffected.Cushions
Cushions are entities placed from one of sixteen dyed items, so the usual block protections never applied to them. - Placing a cushion in a claim requires build trust, like placing an armor stand. - Breaking a cushion requires build trust, like item frames and armor stands. - Sitting on a cushion is allowed by default, so a claim's furniture stays usable by visitors. Servers that want seats reserved for trusted players can turn on the new option below.
-GriefPrevention: Claims: PreventCushionMount: falsefalse(default): anyone may sit on a cushion. -true: sitting on a cushion inside a claim requires access trust. In creative worlds, cushions also count toward the per-claim entity limit, like armor stands and item frames.Straw beds
Straw beds set a spawn point like a bed, but they break when they are slept in. They are deliberately not in the vanillabedstag, so GriefPrevention's bed rule did not apply to them.
-GriefPrevention: Claims: ProtectStrawBeds: truetrue(default): using a straw bed in a claim requires access trust, the same trust level beds use. This keeps a claim's straw beds from being consumed by passers-by while remaining available to anyone the owner trusts. -false: straw beds may be used by anyone, and are destroyed on use as in vanilla. Placing and breaking a straw bed already requires build trust, because it is an ordinary block.Upgrade notes
Both options are added toconfig.ymlthe next time the server starts. No storage changes. Drop-in replacement for v18.3.14.18.3.14GriefPrevention3D v18.3.14Sep 15, 2026 GriefPrevention3D v18.3.14
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
- New:/scrollresize— resize claims and subdivisions with the mouse wheel and a live preview. - Permissions: every claim and admin command now has its own permission node, so a single command can be negated without removing the rest ofgriefprevention.claimsorgriefprevention.adminclaims. Denials send the plugin's own "no permission" message everywhere. - Changed:/claimpvpnow needs manager trust in the claim instead of edit permission. - Fix:Claims.Allow3DSubdivisionsandClaims.Allow3DAdminClaimsare now written toconfig.yml. - Fix: 3D subdivision outlines that are one block wide or one or two layers tall now draw correctly. - Fix: clicking a second spot on a shaped claim's boundary in/shapedclaimsplaced the segment marker next to the previous one instead of where you clicked./scrollresize
Hold your claim tool and run/scrollresize(or/claim scrollresize, aliases/sr,/src). Which claim: the claim or subdivision you're looking at or standing in — including 3D subdivisions too small to stand inside, like a 1x1x1 — or the claim you selected by right-clicking one of its corners. Which side: the side your line of sight hits. From outside a claim that's the side facing you (the top when you look down on it); from inside, it's the side you're looking at. Right-clicking a corner first limits the resize to the sides at that corner (two on a 2D claim, plus the top or bottom on a 3D claim). On shaped claims and shaped subdivisions the side is the segment you're standing in front of and facing, the same one/expandclaimmoves, or one of the two edges at a selected corner. Scrolling follows your camera: scrolling up pushes the side away from you and scrolling down pulls it toward you, one block per notch. Looking down at a 1x1x1 subdivision, scroll down raises its top and scroll up brings it back to a single layer. Preview: the new outline is drawn through GriefPrevention's normal visualization event, so fake-block and glowing borders — and visualization addons that hook that event — show it. Nearby claims and the parent claim's other subdivisions are shown too. The outline turns red if it would overlap another claim, stick out of its parent, cut into its own subdivisions, or cost more claim blocks than you have; the action bar shows the size and remaining claim blocks. (Servers without an action bar API, such as 1.8.8, get conflicts in chat right away and size updates in chat once you stop scrolling.) Applying and cancelling: - Right-click applies the resize, through the same checks as the golden shovel. If the preview shows a conflict, the session stays open so you can scroll back. - **Left-click, drop (Q), swap hands (F, 1.9+), a number key, switching off the claim tool, changing worlds, or a minute without scrolling** cancels it and restores the claim's real outline. Subdivisions never cost claim blocks. Shaped segments can be pulled inward into a notch, stopping at the last valid shape. New permission: `griefprevention.scrollresize` (defaulttrue, child ofgriefprevention.claims).Per-command permissions
Upstream GriefPrevention gated most claim commands behindgriefprevention.claims, so negating one command meant losing all of them. GP3D now gives each command its own node under a parent bundle: - Commands check their own node.plugin.ymlcommands,/claimand/aclaimsubcommands, and the standalone aliases configured inalias.ymlall check the command's specific permission. For example:/claim untrustchecksgriefprevention.untrust,/claim pvpchecksgriefprevention.claimpvp,/claim trust <player> accesschecksgriefprevention.accesstrust, and/claim abandon allchecksgriefprevention.abandonallclaims. - One denial message. Every denial sendsNoPermissionForCommandfrommessages.yml— including Bukkit's ownplugin.ymlpermission check and dynamically registered aliases, which previously sent generic English text. - New nodes under `griefprevention.claims` (defaulttrue):griefprevention.trustlist,griefprevention.claimalerts(/claim alerts), andgriefprevention.toggleclaimalerts(/claimtogglealerts, which previously used an undeclared node and so only worked for operators). - New nodes under `griefprevention.adminclaims` (defaultop):griefprevention.3dadminclaims,griefprevention.adminclaimslist, andgriefprevention.deletealladminclaims(which also still requiresgriefprevention.deleteclaims)./aclaim transferchecksgriefprevention.transferclaim, and/aclaim deletechecksgriefprevention.deleteclaims,griefprevention.deleteclaimsinworld, orgriefprevention.deletealladminclaimsdepending on what is being deleted. - Previously undeclared nodes are now declared (defaultop):griefprevention.deleteclaimsinworld,griefprevention.deathblow, andgriefprevention.eavesdrop.immune. Everyone who hasgriefprevention.claimsorgriefprevention.adminclaimskeeps the same access as before; the change only makes negating individual commands possible./claimpvp needs manager trust
Toggling PvP in a claim now requires manager trust (owners, players given/managetrust, and staff withgriefprevention.adminclaimson admin claims) instead of edit permission, and the command permission isgriefprevention.claimpvpinstead ofgriefprevention.claims. Players without manager trust see the claim's "you don't have permission to manage permissions here" message.3D config options now generate
Claims.Allow3DSubdivisionsandClaims.Allow3DAdminClaimswere read but never written back, so they never appeared inconfig.yml. They are now added with their current values (defaulttrue) the next time the server starts.3D subdivision previews
Very small 3D subdivisions put several outline markers on the same block: a one-block-wide ring collapses into a column, a one-layer subdivision drew the same ring twice, and the white wool markers of a two-layer subdivision landed on the other ring's corners. Which marker appeared was random, so these subdivisions looked unchanged while resizing. Each block is now drawn once with corners winning, one-layer subdivisions draw a single ring, and the wool markers only appear when there's a gap between the top and bottom rings. This applies everywhere 3D subdivisions are shown, including the golden shovel and investigation tool.Shaped claim segment markers
In/shapedclaims, the first click on a claim boundary places a segment marker and starts a reshape path from it. A second click elsewhere on the same boundary was read as the next point of that path and snapped to the block next to the first marker. A path that hasn't left the boundary yet is now dropped when you click another spot on the same boundary, so the new marker goes exactly where you clicked. Reshaping outward, cuts, and cross-claim merges work as before.Upgrade notes
- alias.yml: existing files keep their values. If yours sets `subcommands.claim.pvp.permission: griefprevention.claims, you can change it togriefprevention.claimpvp`; the command also checksgriefprevention.claimpvpeither way. - New messages are translated into every bundled locale. - No storage changes. Drop-in replacement for v18.3.13.18.3.13GriefPrevention3D v18.3.13Sep 14, 2026 GriefPrevention3D v18.3.13
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
-/extendclaimon a 3D subdivision inside a shaped claim resized the shaped claim instead of the subdivision. - Security: players without edit permission could resize someone else's shaped claim with/extendclaim. - Shaped subdivisions no longer hit the "claim too narrow" / "insufficient area" minimums.
When no claim was selected with the golden shovel,/extendclaimextended the wrong claim/extendclaim(and/claim expand) replaced the claim the player was standing in with its parent. Standing inside a 3D subdivision of a shaped claim therefore targeted the shaped claim, which grows whichever boundary segment the player faces. That edge could be far away, so the command looked like it just flashed and refreshed the visualization without extending anything — while quietly growing the parent claim. Fix: -/extendclaimnow extends the most specific claim you're standing in — including 2D, 3D, and shaped subdivisions — matching upstream GriefPrevention. A claim selected with the golden shovel still takes priority. - Extending a 3D subdivision vertically checked against the parent's raw stored Y values. Shaped claims store only their floor, so a 3D subdivision inside one could never grow upward. The check now uses the parent's real vertical range (the world height limit for 2D parents). - Shaped subdivisions use the shaped segment expansion (the same as shaped claims) instead of the rectangle resize, which would have changed their stored bounds without moving their outline. Behavior note: standing inside a rectangular subdivision,/extendclaimnow grows that subdivision, not the claim around it. To grow the whole claim, stand outside the subdivision or select the claim's corner with the golden shovel first.Security: shaped claims could be resized without permission
The shaped-claim branch of/extendclaimran before the edit-permission check, so any player holding the claim modification tool could expand (or shrink, with a negative amount) another player's shaped claim just by standing in it. The permission check now runs first for every claim type.Shaped subdivisions can be as small as you like
Shaped subdivisions carve up land the owner already paid for, so they now skip the claim size minimums (MinimumWidth/MinimumAreafor rectangular outlines,ShapedMinimumAreafor other outlines) both when created with/shapedsubdivideclaimsand when reshaped or extended. Top-level claims are unaffected. The smallest shaped subdivision is 2×2: a shaped outline can't be one block wide, because that would need a zero-length edge. Use a regular/subdivideclaimssubdivision for 1×1 spaces.Upgrade notes
No configuration or storage changes. Drop-in replacement for v18.3.12.18.3.12GriefPrevention3D v18.3.12Sep 13, 2026 GriefPrevention3D v18.3.12
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
Fix for the per-claim PvP toggle: claims that players turned PvP off before v18.3.10 had PvP enabled again after upgrading, on servers whose global config allows combat in claims. From a player's point of view, "PvP is enabled in all claims".Root cause
v18.3.10 introduced an explicit-toggle marker (PvP Toggle Set/ thepvptoggledcolumn) so that claims nobody ever toggled fall back to the globalPvP.ProtectPlayersInLandClaims.*settings instead of being treated as PvP-on by default. Claims saved before that release hadPvP Enabled: falsebut no marker. They loaded as never-toggled, soclaimIsPvPSafeZoneignored their stored "off" and used the global config instead. On servers whereProtectPlayersInLandClaims.PlayerOwnedClaimsisfalse— typical for servers that let owners opt out of PvP per claim, and the default when siege is enabled in any world — every claim players had disabled became a PvP zone again. Claims toggled after upgrading got the marker and worked, which made the problem easy to miss when testing.Fix
A claim's stored PvP state can only differ from the default (on) because someone explicitly turned PvP off — through/claimpvp false confirm, or a subdivision inheriting a disabled parent. So a storedPvP Enabled: falsenow counts as an explicit toggle when the claim loads, from both flat-file and database storage. - Claims disabled before v18.3.10 are protected again as soon as v18.3.12 starts — no commands or data changes needed. - Claims nobody ever toggled still follow the globalProtectPlayersInLandClaimssettings. - Flat-file saves only write thePvP Toggle Setmarker for claims explicitly toggled on, since "off" already implies it. Existing claim files and cross-platform (Fabric) claim documents are not rewritten with redundant fields. New regression tests cover legacy disabled claims and subdivisions staying protected while the global config allows combat, and untoggled claims still following the global config.Upgrade notes
No configuration or storage changes. Drop-in replacement for v18.3.11. Claims explicitly toggled on before v18.3.10 are stored identically to the default and can't be told apart; they keep following the global config until/claimpvp true confirmis run on them again. If players expect claims that were never toggled to be protected, make sureGriefPrevention.PvP.ProtectPlayersInLandClaims.PlayerOwnedClaimsistrueinconfig.yml.18.3.11GriefPrevention3D v18.3.11Sep 13, 2026 GriefPrevention3D v18.3.11
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
New permission: `griefprevention.maxclaims.<amount>` sets how many claims a player (or a whole rank) may own, so the claim-count limit no longer has to be one number for the entire server./lp group default permission set griefprevention.maxclaims.3 true /lp group vip permission set griefprevention.maxclaims.10 trueHow it works
Until now the only controls were the globalClaims.MaximumNumberOfClaimsPerPlayerconfig value and the all-or-nothinggriefprevention.overrideclaimcountlimitbypass, which only gave two tiers: "limited" and "unlimited". When a player starts a new claim, GP3D now resolves their limit like this: 1. `griefprevention.overrideclaimcountlimit` → no limit (unchanged). 2. Otherwise, the highestgriefprevention.maxclaims.<amount>node the player holds is their limit. Because the highest node wins, ranks that inherit from each other just work — a VIP who also inheritsmaxclaims.3from the default group gets 10. 3. Otherwise, the configuredClaims.MaximumNumberOfClaimsPerPlayerapplies (0= unlimited). Details: - A permission limit applies even when the config value is0, and it can raise or lower a player's limit relative to the config. - Negated nodes, wildcards (griefprevention.maxclaims.*), and zero/negative amounts are ignored. Useoverrideclaimcountlimitfor unlimited claims. - The limit counts top-level claims the player owns; subdivisions don't count. - It is enforced everywhere a claim can be started:/claim create, the golden shovel, and shaped claim mode. The lookup reads the player's effective permissions, so it works with LuckPerms and any other permission plugin, and on every supported Bukkit-family server back to 1.8.8.Also in this release
- New regression tests covering admin-claim/claim pvptoggles (staff can toggle admin claims and their subdivisions; regular players are still denied). - Wiki refresh: shaped subdivisions, shaped claim cuts, administrative subdivisions, PvP/PvE combat trust, and the new claim-count permission are now documented.Upgrade notes
No configuration or storage changes. Servers that don't grant anygriefprevention.maxclaims.*nodes behave exactly as before. The experimental Fabric build still uses the config limit and the override permission only. Drop-in replacement for v18.3.10.18.3.10GriefPrevention3D v18.3.10Sep 2, 2026 GriefPrevention3D v18.3.10
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
Two fixes for the per-claim PvP toggle on admin claims: 1. Admin claims (e.g. a spawn claim) became PvP-enabled automatically — "PvP Enabled" flipped on without anyone toggling it; 2./claim pvp(and its confirm step) was rejected on admin claims even for OP players.Root cause
Auto-enabled PvP
pvpEnableddefaults totrue. The v18.3.8 fix made the per-claim toggle authoritative in both directions:claimIsPvPSafeZonereturned!claim.pvpEnabledwhenever the toggle feature was enabled for that claim type. But that treated every claim's default value as an explicit toggle — so any claim that had never been touched was reported as PvP-enabled, overriding the globalPvP.ProtectPlayersInLandClaims.AdministrativeClaimsprotection. A spawn admin claim silently lost its PvP safety.Cannot toggle admin claims
handlePvpCommandgated onclaim.hasExplicitPermission(player, ClaimPermission.Edit). Admin claims have no owner and no trust lists, so that check can never pass — only the explicit-grant map matters there. OP players were blocked even thoughclaim.checkPermissiondoes honor thegriefprevention.adminclaimspermission on admin claims.Fix
Explicit-toggle tracking
Claims now carry apvpToggleSetmarker that records whetherpvpEnabledwas actually set by a player (/claim pvp … confirm), rather than left at its default.claimIsPvPSafeZoneonly applies the per-claim override when that marker is set. Claims that were never toggled fall back to the global no-combat config, so: - never-toggled claims: followPvP.ProtectPlayersInLandClaims.*exactly as before (admin claims included — no more surprise PvP-on); - explicitly disabled claim: PvP blocked, attacker told why; - explicitly enabled claim: combat allowed, overriding any global no-combat fallback; - the "already toggled" message now only fires for an existing explicit state, so enabling a default-protected claim still arms the override instead of reporting "already enabled". The marker is persisted: - flat file: newPvP Toggle Setkey (defaults to missing/false); - database: newpvptoggled BOOLEAN DEFAULT 0column (auto-added, schema version 13 → 14); - cross-platform claim document: carried as a schema event-field so it survives claim moves. Subdivisions created withSubdivision.DefaultState: INHERITinherit the parent's marker along with itspvpEnabled.Admin-claim permission
Both the toggle command and its confirm step now useclaim.checkPermission(player, ClaimPermission.Edit)instead ofhasExplicitPermission. This lets players holdinggriefprevention.adminclaims(including consoles/ops) enable and disable PvP on admin claims, while everyone else is still denied.Upgrade notes
No configuration changes. Storage upgrades automatically: - Database users: the migration adds thepvptoggledcolumn on startup; no manual SQL needed. - Existing flat-file data: the new key is optional and defaults to false. One behavior note: claims that were explicitly toggled before this release lose their explicit marker once and return to global-config behavior. Re-run/claim pvpon those claims to mark them again. Drop-in replacement for v18.3.9.18.3.9GriefPrevention3D v18.3.9Aug 30, 2026 GriefPrevention3D v18.3.9
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
Fix for the per-claim PvP toggle: attacking a player inside a claim with PvP disabled silently denied the hit — the player was protected but never told why.Root cause
The general melee PvP handler (handlePvpDamageByPlayer) had an early-return gate that skipped all claim PvP checks when both global no-combat configs were off:
Servers running the per-claim PvP toggle typically leave the global "no combat in claims" flags off (combat is decided per claim), so the gate short-circuited andif (attackerData.ignoreClaims || !config_pvp_noCombatInPlayerLandClaims && !config_pvp_noCombatInAdminLandClaims) { return false; }handlePvpInClaimwas never reached. That meantclaimIsPvPSafeZonewas never consulted, the attack was not attributed to the claim, and the "that player is in a PvP safe zone" / "can't fight while protected" message never fired — the protection happened silently.Fix
When the per-claim PvP toggle feature is enabled, the melee handler now bypasses the global-config-only gate and falls through to the normal claim PvP logic.handlePvpInClaimconsultsclaimIsPvPSafeZone, which cancels the attack in a PvP-disabled claim and sends the appropriate protection message to the attacker. To summarize the resulting per-claim toggle behavior after v18.3.8 + this release: - PvP enabled claim: combat works (overrides any global no-combat fallback); - PvP disabled claim: combat is blocked and the attacker is told why; - claims the server didn't enable the toggle for: fall back to the global config as before.Upgrade notes
No configuration, storage, or migration changes. Drop-in replacement for v18.3.8.18.3.8GriefPrevention3D v18.3.8Aug 30, 2026 GriefPrevention3D v18.3.8
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
Fix for the per-claim PvP toggle: turning PvP on via/claim pvp on confirm(or the equivalent) did not actually enable combat — players in the claim remained protected.Root cause
claimIsPvPSafeZoneonly honored the per-claim setting in one direction. When a claim's PvP toggle was turned off, the method correctly returned a safe zone. But when it was turned on, the method fell through to the global config fallback (PvP.ProtectPlayersInLandClaims, etc.). On servers whose global config protected players in claims (the common default), that fallback still reported the claim as a PvP safe zone — so enabling PvP on an individual claim had no effect. The fix also scopes the toggle by claim type. Previously the check keyed off an aggregate "is either toggle enabled" flag, so enabling only the main-claim toggle would also make subdivisions defer to their per-claim value, bypassing the global subdivision config.Fix
claimIsPvPSafeZonenow: - checks the per-claim toggle only for the claim type the server enabled it for (main claim vs subdivision, mirroringgetPvpToggleContextin the command handler); - treats the claim's ownpvpEnabledsetting as authoritative in both directions when that toggle is active — off protects, and on overrides the global "no combat in claims" fallback; - otherwise falls back to the global config, preserving existing behavior on servers that never opted into the per-claim toggle.Upgrade notes
No configuration, storage, or migration changes. Drop-in replacement for v18.3.7.18.3.7GriefPrevention3D v18.3.7Aug 24, 2026 GriefPrevention3D v18.3.7
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
This is a fix release for the shaped claim cuts introduced in v18.3.6. Cut clicks only worked when every click landed at the same Y level; otherwise the path failed to close and players saw "The resulting shape is not valid".Root cause
Cut click classification used the claim's 3D containment check (claim.contains(location, ...)), which requires the clicked block's Y to fall inside the claim's height range. Shaped claims are 2D — their geometry lives entirely in the X/Z plane — so a player clicking on terrain above or below that band produced a point that counted as neither interior nor boundary. The cut path could then never detect closure, and finalization rejected the shape.Fix
All six cut-flow classification checks now test the click's X/Z coordinates against the boundary polygon directly (polygon.containsCell(x, z)) instead of the 3D location check: - interior-cut-click detection (both handler paths); - general interior-click detection; - boundary-closure detection (clicking back onto the boundary to finish the cut). Y level no longer plays any role in shaped claim cuts: you can seed, shape, and close a cut from any elevation.Upgrade notes
No configuration, storage, or migration changes. Drop-in replacement for v18.3.6.18.3.6GriefPrevention3D v18.3.6Aug 24, 2026 GriefPrevention3D v18.3.6
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
This release adds shaped claim cuts — the ability to carve inward cuts from an existing claim boundary using the shaped claim tool. Where v18.3.x introduced outward reshaping (extending claim boundaries into unclaimed land), this release completes the shaped-claim workflow by allowing players to subtract irregular shapes from their own claims. A cut is started by clicking a boundary segment to seed the path, then clicking inward into the claim interior. Each interior click adds an orthogonal corner point (snapped automatically), and the cut is finalized by clicking back onto any boundary point. The carved region is unclaimed.How it works
1. Enter shaped claim mode (/shapedclaimsor equivalent shovel mode). 2. Click a boundary point on your claim — this seeds the cut path from that boundary edge. 3. Click inward into the claim interior — the first interior click starts the cut and shows a warning message. 4. Continue clicking interior points to shape the cut — each point is snapped to be orthogonal with the previous point. 5. Click back onto any boundary point to complete the cut — the shaped interior region is unclaimed.Cut message
When a cut is started, the player sees:Starting a shaped cut of your claim. Continue to shape and merge back to a boundary to complete the cut. Warning: cut means to unclaim that shaped land.
Technical details
- Cut points are validated to be inside the claim polygon (containsCell), not just non-boundary points. This ensures interior cut clicks are distinguished from exterior reshape-extension clicks. - Interior points are automatically snapped to be orthogonal with the previous path point, matching the behavior of the existing shaped-claim extension path. - The cut polygon is constructed by walking the claim boundary between the two cut-edge endpoints and inserting the cut path. The resulting polygon is validated viaOrthogonalPolygonValidator.validatePathfor self-intersection, orthogonal edges, and closed-path requirements. - Same-edge cuts (both cut points on the same boundary edge) produce correct non-overlapping polygon geometry with proper corner-to-cutPoint pairings.Also in this release
- Fix: cut path interior points now snap orthogonally to the previous point when the click is not axis-aligned, matching the extension reshape path behavior.18.3.5GriefPrevention3D v18.3.5Aug 21, 2026 GriefPrevention3D v18.3.5
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
This release adds two new claim trust types — PvP trust and PvE trust — that give claim owners per-player, per-claim consent over combat. They exist because wind charges, mace smash knockback, and the knockback protection introduced in v18.3.x made "who is allowed to shove whom" a real question, and neither of the existing answers was right: - Container trust was the only thing gating animal knockback/damage, so handing someone chest access also handed them the right to yeet your horses across the pen; - Access trust was the only early-allow for player-vs-player knockback, which conflated "can press buttons" with "may fight here". Both new types are opt-in server features, disabled by default. With both flags off this release behaves exactly like v18.3.4 — no new commands appear, no protection rules change.Configuration
The two flags are independent: a PvP server can enable onlyGriefPrevention: Claims: AllowPvPTrust: false # enables /pvptrust, PvP trust checks, and PvP trust in /trustlist AllowPvETrust: false # enables /pvetrust, PvE trust checks, and PvE trust in /trustlistAllowPvPTrust, a PvE server onlyAllowPvETrust./gpreloadapplies flag changes immediately — see Hot reload below.What each trust type does when enabled
| Target | Legacy gate | With flag on | |---|---|---| | Other players (knockback/combat early-allow in claims) | Access trust | PvP trust | | Creatures — animals, villagers, copper golems, sulfur cubes | Container trust | PvE trust | Unchanged on purpose: - armor stands, item frames, and paintings still require Build trust (destruction, not combat); - hostile monsters are never protected; - self-knockback (wind charge jumping at your own feet) never required trust and still doesn't; - PvP safe zones and fresh-spawn immunity are evaluated above the new trust checks, so spawn protection cannot be trusted away; - buttons, levers, and doors triggered by explosions (wind charge flicks) remain an Access-trust question, not a combat one. When a flag turns on, the legacy level stops covering that target entirely: enablingAllowPvETrustmeans container-trusted players can open chests but can no longer hurt or knock back creatures unless separately granted PvE trust. EnablingAllowPvPTrustmeans Access trust no longer acts as the player-combat early-allow. Because the flags default to off, no existing claim changes behavior until an admin asks for it.Standalone by design
PvP/PvE trusts sit outside the normal implication hierarchy in both directions:
GrantingOwner/Edit -> Manage -> Build -> Container -> Access (implies everything below it) PvP, PvE . (implied by nothing, imply nothing)/trust <player>(build) does not silently hand out combat rights after an admin flips the flag on, and granting/pvptrustnever grants access to anything else. Combat trust is stored in its own per-claim sets rather than the interaction trust map, so granting container trust after pvp trust cannot overwrite it, and vice versa. Inheritance matches every other trust level: first-child subdivisions inherit parent grants, nested subdivisions do not, and a subdivision can block an inherited grant with a deny entry (#pvp/#pvesuffixes).Commands
Notes: -/pvptrust <player> standalone; permission griefprevention.pvptrust /pvetrust <player> standalone; permission griefprevention.pvetrust /claim trust <player> pvp|pve typed grant through the unified interface /claim trust permission <node> pvp|pve permission-node grant /aclaim trust permission <node> pvp|pve same, administrative form /untrust <player> revokes combat trust along with everything elsegriefprevention.pvptrustandgriefprevention.pvetrustdefault to allowed and are children ofgriefprevention.claims, mirroring/accesstrustand/containertrust. - Permission-node identifiers ([your.node]) andpublicwork exactly as they do for other trust levels. - Tab completion for the trust-type argument reads the config live, sopvp/pvesuggestions appear and disappear with/gpreload. -/trustlistlists PvP-trusted players in red and PvE-trusted players in aqua, with a legend entry for each — but only while the matching flag is enabled, so servers that never opted in see the exact same output as before.Enforcement details
The knockback protection handlers branch on the flags at event time: -handleKnockbackPlayerrequires an explicit PvP grant where it previously accepted Access; -handleKnockbackEntityrequires PvE instead of Container for protected creatures. Everything downstream of those gates (safe-zone messaging, fresh-spawn immunity, rate-limited errors,/gpdebugknockback tracing) is untouched. Debug output now names the specific rule that fired, e.g.denied: attacker X lacks PvP trust in defender's claim N.Storage
No migration is required or performed; the feature ships inert. - Flat file claims gain optionalPvP Trusted/PvE Trustedlist keys. Older plugin versions ignore them; older files load unchanged. - The database schema moves from version 12 to 13. Startup adds two nullable TEXT columns via JDBC metadata inspection (the MySQL-safe path used for thedeniedcolumn), then rewrites claims once. - The platform-neutralgp3d-coreclaim codec carries both sets through document encode/decode, so PaperFabric claim moves preserve combat trust losslessly. Grants persist even while their feature flag is disabled, so toggling a flag off and back on never loses anyone's trust.
Also in this release
- Neighbor trust (/neighbortrust,/distancetrust,allowAllNeighbors) persistence was hardened on both Bukkit and Fabric, including manual-neighbor survival across flat-file migration. - Upstream merge: interacting with an untamed horse no longer clears its equipment (#2624).18.3.4GriefPrevention3D v18.3.4Aug 13, 2026 GriefPrevention3D v18.3.4
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
This maintenance release restores GriefPrevention's upstream manage-trust behavior. Players with manage trust may once again grant normal trust or manage trust to another player, and manage trust once again includes every lower interaction permission. GP3D v18.3.0 separated manage trust from build, container, and access trust. It also restricted a manager to granting only permissions they separately held themselves, while granting manage trust was reserved for the claim owner. Together, those rules produced two confusing failures: - a manager could grant container trust in some cases, but/trust <player>appeared to do nothing; -/managetrust <player>appeared to do nothing unless the command sender owned the claim. Both restrictions are removed in v18.3.4. Holding manage trust is now the complete authorization needed to manage the claim's grantable trust list, matching upstream GriefPrevention.Manage trust is hierarchical again
The effective trust hierarchy is restored to:
A manager can therefore build, use containers, and access the claim without needing a second trust entry. Manage trust still does not grant owner-only Edit permission: managers cannot resize, delete, transfer, or otherwise perform actions reserved for the claim owner merely because they can manage trust. The hierarchy is applied consistently by the Bukkit claim implementation and the shared trust model used by Fabric. Player UUIDs,Owner/Edit -> Manage -> Build -> Container -> Access -> Neighborpublic, and trusted permission-node identifiers all follow the same ordering when their effective permission is evaluated.Managers can delegate trust
Trust commands now require the sender to hold Manage permission on the selected or current claim. There is no additional requirement that the sender personally hold the level being granted, and granting manage trust is no longer owner-only. A manager may use: -/accesstrust <player>; -/containertrust <player>; -/trust <player>; and -/managetrust <player>. This also applies when the commands are routed through GP3D's unified claim command interfaces. The separate administrative gate for granting trust to arbitrary permission nodes remains in place:/permissiontruststill requiresgriefprevention.permissiontrust.Relationship to the owner-side trust-loss report
The clarification that the command sender owns the claim means the delegation restriction fixed in this release did not block that sender: claim owners already satisfied every grant check. The reported sequence is nevertheless consistent with the separate v18.3.1 storage bug. At that time a claim could store only one trust value per player. An owner could successfully give Linkondorf normal trust and then give him manage trust, but the second command replaced the first entry. Loading the claim appliedManagerslast and could repeat the overwrite. Because manage trust did not include interaction rights in v18.3.1, Linkondorf then appeared to have lost all useful permissions. There is also an important command-name difference between those releases: - In v18.3.1,/permissiontrust Linkondorfwas an alias for granting player manage trust and could trigger the one-slot overwrite. - Since v18.3.2, player manage trust is/managetrust Linkondorf./permissiontrust <permission> <access|container|build|manage>now targets a permission node, so/permissiontrust Linkondorfis not a valid player-trust command. v18.3.2 already fixed the destructive part by storing manage and interaction trust independently. v18.3.4 keeps that safer storage model while restoring the upstream hierarchy: - granting manage trust does not overwrite an explicit build, container, or access grant; - granting normal trust does not remove manage trust; - both tracks survive claim loading and saving; and - a surviving manager entry now provides lower interaction permissions by itself. This means an existing player still listed underManagersregains build, container, and access without a claim-data migration. If old server versions removed both entries entirely, the claim owner must trust the player again. If a player should retain a particular interaction level after their manage trust is later removed, the owner should also grant that interaction level explicitly; the independent entry remains stored separately from manager status.Subdivision scope can look like disappearing trust
Trust granted directly in a subdivision applies inside that subdivision and its inheriting descendants; it does not grant the same permission in the surrounding parent claim. With a 3D subdivision, moving above or below its Y bounds can therefore make working trust appear to vanish even though the subdivision entry is still present. An untrusted parent does not asynchronously erase a direct subdivision grant. GP3D checks explicit trust on the current subdivision before consulting its parent, so the direct grant wins while the player remains inside that subdivision. A later/untrustperformed on the parent can deliberately propagate removal into children which inherit its permissions, but there is no timer which clears a child grant merely because the parent lacks trust. If/trust Linkondorfstill appears ineffective after upgrading, confirm that the owner and Linkondorf are testing the same claim and vertical layer, that no old golden-shovel claim-selection session is targeting a different subdivision, and that/trustlistis being read from that exact claim.Upgrade notes
- No configuration changes are required. - No permission nodes, commands, aliases, or message keys were added. - No claim-data migration or automatic claim rewrite is required. - ExistingManagersentries immediately receive the restored lower permissions. - The independent storage introduced in v18.3.2 remains in place; this release changes effective permission evaluation and command authorization, not the on-disk claim format. -/untrust <player>continues to remove both manage and interaction trust.Verification
New command-level regression tests cover the upstream manager-delegation cases with a manager standing inside another player's claim. They verify that/trust Linkondorfrecords Build trust and that/managetrust Linkondorfrecords Manage trust. A separate owner-path test grants Build and then Manage to the same player and verifies that both entries remain. Hierarchy tests verify that Manage grants Build, Container, and Access while owner-only Edit remains denied. The existing real flat-file round-trip test verifies that a player listed under bothBuildersandManagersretains both entries after a Paper load and save. Fabric evaluator and repository tests cover the same hierarchy for UUID and permission-node trust while retaining the explicit interaction grant alongside manager status. The full./gradlew checkpipeline passes: 439 tests, 0 failures, 0 errors — 250 in the Bukkit plugin, 136 in the shared core, 51 on the Fabric platform, and 2 in the Fabric bootstrap. This also includes the universal JAR audit, Java 8 legacy class loading, shaded-core isolation, and the Fabric boot smoke test against the generated universal JAR.Files Changed
```text M gp3d-core/src/main/java/com/griefprevention/claims/ClaimTrustLevel.java M gp3d-core/src/main/java/com/griefprevention/claims/ClaimTrustSnapshot.java M gp3d-core/src/test/java/com/griefprevention/claims/ClaimTrustLevelTest.java M gp3d-core/src/test/java/com/griefprevention/claims/ClaimTrustSnapshotTest.java M gradle.properties M platforms/fabric-1.21.11/src/test/java/com/griefprevention/fabric/FabricClaimRepositoryTrustTest.java M platforms/fabric-1.21.11/src/test/java/com/griefprevention/fabric/FabricClaimTrustEvaluatorTest.java M pom.xml M src/mai18.3.3GriefPrevention3D v18.3.3Aug 12, 2026 GriefPrevention3D v18.3.3
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
This maintenance release restores claim knockback protection on Canvas servers. Canvas is a Paper fork and provides Paper's cancellable knockback events, but GP3D detects it as its own platform. The knockback listener recognized onlyPAPERandSPIGOT, so it declared itself unsupported when the detected platform wasCANVASand was never registered. The issue was reported through sulfur cubes: an untrusted player could punch a cube holding a block and move it around another player's claim despite both of the relevant settings being enabled. The same registration gap affected every protection handled by the platform knockback listener, not only sulfur cubes.Canvas now uses the Paper knockback path
GP3D has separate listener implementations for the two event APIs exposed by supported Bukkit servers: - Paper and Paper-compatible servers useEntityKnockbackByEntityEventandEntityPushedByEntityAttackEventfrom the Paper API. - Spigot uses Bukkit'sEntityKnockbackByEntityEvent. Canvas includes the Paper events and fires them from the sulfur cube's custom knockback path. GP3D now mapsCANVASto the Paper implementation, checks that the required Paper event classes exist, and registersPaperKnockbackProtectionHandlerjust as it does on Paper. This restores cancellation for player-caused knockback against: - non-hostile creatures protected by container trust, including sulfur cubes; - armor stands and hanging entities protected by build trust; - players covered by GP3D's PvP-safe claim rules or fresh-spawn immunity; and - projectile and attack-driven knockback routed through the same Paper events. Paper and Spigot retain their existing native listener implementations. Unsupported platforms remain rejected before a platform-specific handler class is loaded, preserving the universal JAR's older-server class-loading behavior.Why this appeared as sulfur cube theft
A sulfur cube containing a block is already immune to direct player health damage in Minecraft 26.2. Punching it applies the cube's special knockback instead. On Canvas, that knockback event was available but GP3D had no listener registered to cancel it, allowing the cube to be moved despite the claim denial. Once a cube is moved outside the protected claim, the block it carries can be retrieved where the original claim no longer supplies a denial. This is why the incident can look like the cube was killed and its block stolen even though the vulnerable regular-combat path is movement rather than health damage. The normal creature-damage handler is unchanged. WithGriefPrevention.Claims.ProtectCreatures: true, direct damage to an empty sulfur cube in a claim still requires container trust. A block-holding cube remains immune to player damage at the game level.Configuration and scope
No configuration, permission, message, command, or claim-data changes are required. Existing settings remain authoritative:
Both values already default toGriefPrevention: Claims: PreventTheft: true ProtectCreatures: truetrue. This patch covers punch, projectile, and other player-caused movement which fires the platform knockback events. Walking directly into a block-holding sulfur cube uses Minecraft's body-collision movement path and does not fire the same cancellable attack event; that separate path is not changed in this release.Verification
The regression test records the platform selection directly. It failed before the fix because Canvas resolved toUNSUPPORTED, then passed after Canvas was mapped to the Paper knockback API. Additional assertions keep the existing Paper and Spigot selections from regressing. The full./gradlew checkpipeline passes: 436 tests, 0 failures, 0 errors — 247 in the Bukkit plugin, 136 in the shared core, 51 on the Fabric platform, and 2 in the Fabric bootstrap. This also includes the universal JAR audit, Java 8 legacy class loading, shaded-core isolation, and the Fabric boot smoke test against the generated universal JAR. The Canvas 26.2 API was inspected to confirm that both Paper event classes required by the selected handler are present. Live-server verification should reproduce the original case with an untrusted player punching a block-holding sulfur cube inside another player's claim and confirm that the cube does not receive the denied knockback.Files Changed
M gradle.properties M pom.xml M src/main/java/com/griefprevention/platform/knockback/KnockbackProtectionListener.java A src/test/java/com/griefprevention/platform/knockback/KnockbackProtectionListenerTest.java18.3.2GriefPrevention3D v18.3.2Aug 12, 2026 GriefPrevention3D v18.3.2
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
v18.3.0 restored manage trust as its own track: a manager may edit a claim's trust list but does not implicitly receive build, container, or access trust. That change was correct, but the storage underneath it was not. A claim kept exactly one trust value per player, so granting manage trust overwrote whatever build, container, or access trust that player already had. Before v18.3.0 the overwrite was invisible, because manage trust used to imply every lower permission. After v18.3.0 it silently locked trusted players out of chests, doors, and blocks. This release separates the two tracks in storage so they can be held at the same time, and finishes the/permissiontrustsplit that v18.3.0 started:/permissiontrustis now the command for granting trust to a permission node, and manage trust lives entirely under/managetrust.Manage trust no longer erases interaction trust
A claim now tracks manage trust in its own set, alongside the build/container/access map. -/managetrust <player>adds manage trust and leaves existing trust untouched. -/trust,/containertrust, and/accesstrustno longer remove manage trust. - The order the commands are run in no longer matters. -/untrust <player>still removes everything, as before. The same defect existed on every path that wrote trust, and all of them are fixed: - Loading a claim.Builders,Containers,Accessors, andManagerswere applied in that order, so anyone listed underManagershad their interaction trust stripped on every server start. The lists are now independent. - Saving a claim. A player who holds both is written to both lists and round-trips correctly. The cross-platform document writer had a second copy of the same defect and dropped the build/container/access trust of anyone who was also a manager on its way to disk. - Creating a subdivision. The creating player was force-set to manage trust, discarding the build or container trust that had just been copied down from the parent claim. - Clearing inherited trust. Dropping an inherited copy of one kind of trust also dropped the other. Each track is now dropped on its own. - Permission-node trust. A[permission.node]entry granted manage trust is now evaluated against both tracks, so a node can carry manage trust and interaction trust together. Two related storage bugs are fixed in the same pass: - Neighbor trust entries were written into theAccessorslist, which quietly promoted neighbors to access trust the next time the claim loaded. Neighbor trust has its own list and is no longer written to a bucket that does not belong to it. - The shared claim codec used by the Fabric platform stripped interaction trust from anyone listed underManagers, mirroring the Bukkit bug.Existing claims are not migrated
If a player lost trust after upgrading to v18.3.0 or v18.3.1, the data on disk already lost it — the old code overwrote the value before it was ever saved. This release stops the overwrite but does not grant anything back. Claim owners should re-run/trust,/containertrust, or/accesstrustonce for anyone who is missing access. It will stick this time, in any command order.Permission-node trust is its own command
/permissiontrustno longer aliases/managetrust. It now grants a permission node trust in a claim:
Both the bare dotted form and the Bukkit bracketed form are accepted, and the bracketed form is what gets stored:/permissiontrust <permission> <access|container|build|manage> /aclaim trust permission <permission> <type>
A target without a dot and without brackets is rejected, so a mistyped player name cannot silently become a permission node./permissiontrust myserver.vip container /permissiontrust [myserver.vip] containerinventoryis accepted as a synonym forcontainer, andmanagerformanage.Command and permission changes
| Before | Now | | --- | --- | |/permissiontrust <player>(alias/pt) |/managetrust <player>(alias/mt) | |/claim trust <player> permission|/claim trust <player> manage(alsomanager) | | — |/permissiontrust <permission> <type>(new, alias/pt) | | — |/aclaim trust permission <permission> <type>(new) | | Permission | Default | Purpose | | --- | --- | --- | |griefprevention.managetrust| everyone | Use/managetrust. Child ofgriefprevention.claims. | |griefprevention.permissiontrust| operators | Grant trust to a permission node. Child ofgriefprevention.adminclaims. | Read this before upgrading if you manage permissions explicitly.griefprevention.permissiontrustpreviously granted/managetrustand defaulted totrue. It now means something different and defaults tofalse. Manage trust moved to the newgriefprevention.managetrustnode, which defaults totrueand is inherited fromgriefprevention.claims, so ordinary players keep/managetrustwith no configuration change. If your permission plugin grantsgriefprevention.permissiontrustto a non-staff group, revoke it or those players will be able to hand out trust to arbitrary permission nodes. If you explicitly deniedgriefprevention.permissiontrustto stop players using the old/permissiontrust, that denial no longer affects/managetrust; denygriefprevention.managetrustinstead./managetrustkeeps/mtbut no longer answers to/ptor/permissiontrust. Both of those names now belong to the new permission-node command, so a player who typed/pt <player>out of habit will get a permission error instead of granting manage trust.alias.yml upgrades no longer drop sibling entries
Merging a server's existingalias.ymlagainst the shipped defaults recreated user-owned parent sections, which erased default entries added by an upgrade. Addingaclaim.trustbeside an existingaclaim.restorewould have removed one of them. The merge is now leaf-level: every default value is written first, then every user value is overlaid on top. Customizations still win, and new shipped entries survive the upgrade. This is what allows the new/permissiontrustand/aclaim trust permissionentries to appear in analias.ymlthat already exists.Upgrade notes
- No claim-data migration is required and no claim files are rewritten on upgrade. - No message keys were added. The existingInvalidPermissionIDandCantGrantThatPermissionmessages cover the new command's failures. -griefprevention.permissiontrustchanged meaning and default — see the table above. - A player may now appear in more than one section of/trustlist; a manager who also has build trust is listed in both. That is the intended display. - Trust granted to a permission node still requires the target player to actually hold that node at the time of the check, exactly as before.Verification
The full./gradlew checkpipeline passes: 434 tests, 0 failures, 0 errors — 245 in the Bukkit plugin, 136 in the shared core, 51 on the Fabric platform, and 2 in the Fabric bootstrap. This includes the universal JAR audit, legacy class loading, shaded-core isolation, and the Fabric boot smoke test. New regression coverage asserts that manage trust and interaction trust survive each other through loading, both grant orders, both drop paths, and a save round trip; that neighbor trust is never written as access trust; that the permission-node identifier rules reject bare player names; that/permissiontrustand/managetrustrequire their own permission nodes; that the shipped permission layout keeps them separate; and that analias.ymlmerge preserves both user entries and newly shipped siblings.Files Changed
```text M gp3d-core/src/main/java/com/griefprevention/claims/ClaimTrustLevel.java M gp3d-core/src/main/java/com/griefprevention/claims/ClaimTrustS18.3.1GriefPrevention3D v18.3.1Aug 10, 2026 GriefPrevention3D v18.3.1
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
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 currentBiomeinterface 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.13BlockDataAPI; - custom world environments are matched by name rather than linking the post-1.8CUSTOMenum constant; - cardinal block faces are identified from their coordinate modifiers instead of calling the post-1.8BlockFace#isCartesianandBlockFace#getDirectionmethods; and - End terrain recognizes bothEND_STONEand its legacyENDER_STONEname, 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 loadsRestoreNatureProcessingTaskand invokes its biome-name path with the legacyDESERTbiome. 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 whenInventory#getLocationis unavailable; - boat collision protection uses the single legacy passenger accessor when the passenger-list API is unavailable; - projectile handlers tolerate the absence ofProjectileHitEvent#getHitBlock, and cancel only on server versions where that event implementsCancellable; - Nether portal protection accepts legacyOBC_DESTINATIONcreation 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 modernbreakBlocksflag is unavailable; and - block-place permission simulations use the constructor and item representation supported by the running server instead of directly linking the newestEquipmentSlotand block/item type APIs. Player locale detection now falls back toPlayer.Spigot#getLocaleon 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 bothLEADand legacyLEASH; - rails recognize bothRAILand legacyRAILS; - grass-block checks no longer confuse the block with modernSHORT_GRASS; - end portal frames accept bothENDER_EYEand legacyEYE_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 beforeMaterial#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 legacyCreaturehierarchy 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 andBoundaryVisualizationEventdefaults.Lectern trust behavior
Right-clicking a lectern is no longer treated as ordinary container access merely because a lectern implementsInventoryHolder. The intended permission split now applies: | Action | Required permission | | --- | --- | | Read a lectern book | Access trust whenLecternReadingRequiresAccessTrustistrue| | 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, makingGriefPrevention.Claims.LecternReadingRequiresAccessTrustineffective 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 totrue:GriefPrevention: Claims: LecternReadingRequiresAccessTrust: trueShaped-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, sentClaim 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 edge18.3.0GriefPrevention3D v18.3.0Aug 10, 2026 GriefPrevention3D v18.3.0
Wiki: https://github.com/castledking/GriefPrevention3D/wikiOverview
GP3D originally followed upstream GriefPrevention'smasterbranch. That branch became the development line for v20 and removed several long-standing systems with the expectation that they would move into addons. GP3D still intends to ship those systems in core, so this release audits the fork against upstream'slegacy/v16branch and restores the remaining functionality which was lost through those merges. This is a source-level port, not a rollback. The restored behavior has been fitted around GP3D's 3D claims, shaped claims, current event API, universal 1.8-to-current JAR, and Folia/Canvas region scheduling.Features restored from
legacy/v16Siege is functional again
/siege <player>and/claim siege <player>were still advertised, but the state machine and event rules behind them had been removed upstream. Both commands now start a real siege. A siege may begin when the feature is enabled in the current world, the attacker is close enough, the defender is protected by a player-owned claim, neither player is already fighting or PvP immune, and the player/claim cooldown permits it. Administrative claims cannot be sieged. While the siege is active: - both players must remain near the besieged claim or near one another while giving chase; - logging out, dying, or abandoning the fight forfeits it; - participants cannot drop items, use containers, use the claim shovel, modify claims, or run restricted teleport actions; - outsiders cannot build in or use containers in a besieged claim; - the attacker may break only the configured siege materials; - a claim the defender enters may join the siege when the defender has access there; and - an attacker victory temporarily unlocks buttons and levers, then re-locks the claim and ejects the attacker when the looting window ends. The periodic checkup, unlock/re-lock tasks, player state reads, and ejection are dispatched through the appropriate entity or region scheduler rather than assuming one global server thread. Siege is deliberately disabled by default. Add world names before exposing the command:
The generatedGriefPrevention: Siege: Worlds: [] BreakableBlocks: - DIRT - GRASS_BLOCK - COBBLESTONE - GRAVEL - SAND - GLASS - GLASS_PANE - OAK_PLANKS - WHITE_WOOL - SNOW DoorsOpenDelayInSeconds: 300 CooldownEndInMinutes: 60BreakableBlockslist contains the complete legacy-compatible material set, including old and current names for grass, wood, planks, and wool. New permissions: | Permission | Default | Purpose | | --- | --- | --- | |griefprevention.siege| everyone | Start a siege | |griefprevention.siegeimmune| operators | Prevent other players from sieging this player | |griefprevention.siegeteleport| operators | Bypass siege teleport restrictions | When at least one siege world is configured and the threePvP.ProtectPlayersInLandClaimssettings are absent, their generated defaults becomefalse, as they did in legacy GP. Values already present in an existing config remain authoritative. Review those settings before enabling siege on a production world.Creative-world entity and active-block controls are back
Creative claims once scaled resource limits with their footprint. Those limits and the recurring cleanup pass are restored: - one non-player entity is allowed per 50 claim blocks; - one active block is allowed per 100 claim blocks; - hoppers, beacons, and spawners count as active blocks; - minecarts, armor stands, item frames, hanging entities, spawn eggs, and other entity-producing placements are checked before they are allowed; and - creature spawns are rejected in creative wilderness or when the destination claim is already at its limit. Administrative claims and player claims over 10,000 blocks are exempt from the entity cap. The limits use the top-level claim's 2D footprint, including for 3D subdivisions. The cleanup task starts two minutes after boot, processes ten percent of each creative world's currently loaded chunks per minute, and therefore completes a pass in about ten minutes. It does not intentionally load unloaded chunks. It removes empty boats, invalid minecarts, and non-player entities left in creative wilderness, then trims claims which are already above their entity limit. Each chunk is handled on its owning region. This is an intentionally visible behavior change for creative servers. Wilderness entity displays or mobs which were allowed to accumulate while the upstream code was absent may be removed after upgrading.Small unused creative claims expire again
The legacy low-investment cleanup path is restored with:
It considers only non-administrative creative claims no more than 25 blocks wide or deep and with an investment score below 400. Once the owner has been inactive for the configured number of days, the normal expiration event is fired, the claim is deleted with pet release, and the land is restored to nature. As in legacy GP, this is the fallback after whole-account inactivity expiration. It runs only whenGriefPrevention: Claims: Expiration: UnusedClaimDays: 14Expiration.AllClaims.DaysInactiveis0; a non-zero all-claims policy takes precedence.AFK-aware claim-block accrual is back
Claim-block delivery once distinguished active play from players standing still, sitting in a vehicle, or moving in liquid. That check is restored and still passes through the newerAccrueClaimBlocksEvent, so addons may inspect, modify, or cancel the result.GriefPrevention: Claims: Accrued Idle Threshold: 0 AccruedIdlePercent: 0Accrued Idle Thresholdis the minimum movement distance between accrual checks. The oldAccruedIdleThresholdspelling is also read for compatibility, but the spaced name is written back.AccruedIdlePercentcontrols the percentage of the normal rate awarded when idle;0awards none. Players withgriefprevention.accruals.afkbypassbypass the idle reduction.Permission trust is a separate trust level again
/managetrust—and its legacy/permissiontrustalias—now storesClaimPermission.Manageinstead of translating it into ordinary gameplay trust. A manager may edit a claim's trust list but does not implicitly receive build, container, or access permission. Owners and full-edit trustees retain all lower permissions. A trustee may grant only a permission they possess themselves. For example, a player with access trust cannot grant build trust, and only an owner/full editor can grant manage trust. Denied grants use the newCantGrantThatPermissionmessage.Deleted claims release their owner's pets again
ThereleasePetsargument survived upstream's cleanup but no longer did anything. When a top-level player claim is deleted through a path which requests pet release, GP3D now finds the owner's tamed animals inside the claim, makes them wild, clears inventories on inventory-bearing pets, and makes sittable pets stand. Work is partitioned by chunk for region-threaded servers.WorldGuard-aware claim creation is back
When WorldGuard is installed, rectangular and shaped claims may no longer cover an area where the creator lacks WorldGuard'sBUILDpermission:GriefPrevention: Claims: CreationRequiresWorldGuardBuildPermission: trueWorldGuardandWorldEditare soft dependencies. GP3D still loads without either plugin, and the integration uses reflection so WorldGuard is not pulled into the universal JAR's class-loading surface. A WorldGuard API failure is logged to GP debug output and fails open, allowing claim creation instead of taking the claim system offline.Economy purchase limits and provider lifecycle are restored
Servers may cap purchased bonus claim blocks independently of accrue18.2.20GriefPrevention3D v18.2.20Aug 8, 2026 GriefPrevention3D v18.2.20
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFeatures
Automatic nature restoration is back
Upstream deleted the entire restore-nature feature in [GriefPrevention#2332](https://github.com/GriefPrevention/GriefPrevention/pull/2… (5d0ebdec, July 2024). That commit landed here through a routine upstream merge, so servers that had been running automatic cleanup for years lost it on update with nothing in the changelog pointing at it. The manual half came back incab3d9cf—/restorenature,/restorenatureaggressiveand/restorenaturefillall work, along withRestoreNatureProcessingTaskandRestoreNatureExecutionTask. The automatic half did not.restoreClaimandrestoreChunkexisted nowhere in the source, theAutomaticNatureRestorationconfig key was never read, andCleanupUnusedClaimTaskdeleted expired claims and left the land exactly as the owner abandoned it. There was no setting an admin could flip, because there was no setting. This release reconnects the automatic path to the processing tasks that were already shipping. Config:
Defaults toGriefPrevention: Claims: Expiration: AutomaticNatureRestoration: SurvivalWorlds: falsefalse, matching upstream, so no existing server starts editing terrain after updating. It is written back on the next config save. Where restoration now fires: | Trigger | Restores when | | --- | --- | | Chest claim expiry (Expiration.ChestClaimDays) | creative world, orSurvivalWorlds: true| | Inactivity expiry (Expiration.AllClaims.DaysInactive) | creative world, orSurvivalWorlds: true| | Staff/deleteclaim| creative world, orSurvivalWorlds: true| | Player/abandonclaim| creative world only | That table is upstream's behaviour reproduced exactly, including the asymmetry on the last row.SurvivalWorldswas never consulted on the abandon path — upstream gated it oncreativeRulesApplyalone, and the field comment read *"whether survival claims will be automatically restored to nature when auto-deleted."* A survival player abandoning a claim does not get their build flattened. Restoration is silent when it fires automatically.RestoreNatureExecutionTask.showVisualizationreturns immediately on a null player ID, so nothing is drawn and no message is sent; the only trace is the existing expiry line in the admin log. The size guards are upstream's: admin claims are skipped entirely, and so is anything over 10000 blocks of area, 250 wide or 250 deep.Claim#getArearesolves toClaimBounds#area()— the 2D footprint, orpolygon.cellCount()for a shaped claim — andgetWidth/getHeightare X and Z lengths, so these thresholds mean here what they meant upstream despite this fork's 3D claims.
Both were collateral in the same upstream removal and are needed by the paths above.Claim#removeSurfaceFluidsandMessages.UnclaimCleanupWarningrestoredremoveSurfaceFluidsclears lava and water above sea level before a claim is deleted, only in creative-rules worlds, never in the Nether, and never for admin or oversized claims. It now bounds its scan withGriefPrevention.getWorldMaxYinstead of the oldWorld#getMaxHeight.UnclaimCleanupWarningis back in the enum and translated across all fifteen message files — cs_CZ, de_DE, en, en_PT, es, fr_FR, ja_JP, ms_MY, pl_PL, pt_BR, ru_RU, tr_TR, uk_UA, zh_CN and the basemessages.yml. Each follows the quoting convention and level of formality already used in that file, and reuses that locale's established word for a claim rather than introducing a new one. Servers with a customisedmessages.ymlon disk are unaffected either way: a key absent from the file falls back tomessage.defaultValueinMessageLocalization.populateMessagesArray, so the message appears in English rather than not at all.Technical changes
Two deliberate departures from the code that was deleted, both because this fork supports region threading and upstream did not. Chunk coordinates are derived arithmetically. Upstream'srestoreClaimiteratedClaim#getChunks(), which callsworld.getChunkAt(x, z)and loads chunks on the calling thread — rejected under Folia and Canvas when that thread does not own the region.restoreClaimnow walkslesser.getBlockX() >> 4togreater.getBlockX() >> 4directly and never touches aChunkobject.restoreChunk(Chunk, ...)is kept with upstream's signature for API compatibility and delegates to the coordinate-based path. Block capture happens on the owning region thread. Upstream scheduled the whole operation withrunTaskLaterAsynchronouslyand read blocks from the async task. The work is now split:SchedulerUtil.runAtLocationLater(this, snapshotOrigin, () -> { // snapshot 18x18 columns on the region thread SchedulerUtil.runAsyncNow(this, task); // analysis off-thread }, delayInTicks);RestoreNatureProcessingTaskalready closes the loop itself, dispatchingRestoreNatureExecutionTaskback throughSchedulerUtil.runAtLocationbefore it writes anything. This mirrors how the fork's existing/restorenaturehandler inPlayerEventHandleralready worked, rather than introducing a second convention. Two smaller details: - The vertical window starts atseaLevel - 15, upstream's floor, so caves and mines under a claim are left alone. The fork'sRestoreNatureProcessingTasktreats itsminyparameter as an array index rather than a world Y, so the snapshot array itself starts at that floor and0is passed in — the manual tool, which captures the full column, passes a world minimum that clamps to the same0. - The boundary corners describe the chunk proper,+1and+16off the snapshot origin, not the 18-wide array. The outer ring is reference data the execution task never writes to, andcleanupEntitiesuses those corners to decide which entities are in scope.Notes
- Nothing happens untilExpiration.ChestClaimDaysorExpiration.AllClaims.DaysInactiveis non-zero. Restoration is driven by expiry; with expiry disabled the flag has no effect. - Non-aggressive mode is what the automatic path uses, soRestoreNatureExecutionTaskrunsgetClaimAtper block and skips anything still inside a claim. Neighbouring claims that share a chunk with a deleted one are safe. - Restoration operates per chunk, so it reaches the whole chunk rather than the claim footprint, and for a 3D claim it spans the full column above the floor rather than the claim's Y bounds. The per-block claim check above is what keeps that from mattering. - No data migration. No permission changes. No command changes.Tests
No new tests. The full suite passes — 226 tests, 0 failures, 0 errors. The restore path has no unit coverage and does not gain any here. It needs a live world to snapshot, a region scheduler to dispatch through, and real block writes to assert against; the mock harness provides none of the three. What was verified statically:Claim#getArea,getWidthandgetHeightwere traced throughClaimBoundsto confirm the upstream size thresholds still describe a 2D footprint in this fork;minywas traced through every use inRestoreNatureProcessingTaskto confirm it is an array index and unused inRestoreNatureExecutionTask; and both edited message files were parsed to confirm the apostrophes in the restored string do not break YAML.Files Changed
``` M gradle.properties M pom.xml M src/main/java/com/griefprevention/commands/UnifiedAdminClaimCommand.java M src/main/java/me/ryanhamshire/GriefPrevention/Claim.java M src/main/java/me/ryanhamshire/GriefPrevention/CleanupUnusedClaimTask.java M src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java M src/main/java/me/ryanhamshire/GriefPrevention/Messages.java M src/main/resources/messages.yml M src/main/resources/messages_cs_CZ.yml M src/main/re18.2.19GriefPrevention3D v18.2.19Aug 8, 2026 GriefPrevention3D v18.2.19
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
Sulfur cube buckets placed a mob inside anyone's claim
A player holding aSULFUR_CUBE_BUCKETcould empty it anywhere, including inside a claim they had no trust in. No message, no cancellation — the cube simply appeared. The cause is a quirk of how Mojang built the item. Every other mob bucket carries water:
A sulfur cube is a land mob, so its bucket is built with// Items, Minecraft 26.2 public static final Item AXOLOTL_BUCKET = registerItem(..., p -> new MobBucketItem(EntityTypes.AXOLOTL, Fluids.WATER, SoundEvents.BUCKET_EMPTY_AXOLOTL, p), ...); public static final Item SULFUR_CUBE_BUCKET = registerItem(..., p -> new MobBucketItem(EntityTypes.SULFUR_CUBE, Fluids.EMPTY, SoundEvents.BUCKET_EMPTY_SULFUR_CUBE, p), ...);Fluids.EMPTY.MobBucketItemspecial cases exactly that:@Override public boolean emptyContents(LivingEntity user, Level level, BlockPos pos, BlockHitResult hitResult, Direction direction, BlockPos clicked, ItemStack itemStack, InteractionHand hand) { if (this.content == Fluids.EMPTY) { this.playEmptySound(user, level, pos); return true; // never calls super } return super.emptyContents(user, level, pos, hitResult, direction, clicked, itemStack, hand); }BucketItem.emptyContentsis the only placeCraftEventFactory.callPlayerBucketEmptyEventis called. Returning early skips it, andBucketItem.usethen proceeds tocheckExtraContent→MobBucketItem.spawn→level.addFreshEntityWithPassengers(mob, SpawnReason.BUCKET). So no `PlayerBucketEmptyEvent` is fired at all for sulfur cube buckets. GriefPrevention'sonPlayerBucketEmpty— which has correctly guarded water, lava and every fish bucket for years — was never invoked. There was no event to cancel. Fix: checkPlayerInteractEventinstead, which every mob bucket passes through regardless of what fluid it carries.ServerPlayerGameMode.useItemOnrecords the cancellation:
andthis.interactResult = event.useItemInHand() == Event.Result.DENY;ServerGamePacketListenerImpl.handleUseItemreuses that result for the follow-upServerboundUseItemPacketwhen the position, hand and stack still match — returning beforeuseItem, soBucketItem.usenever runs. Two details of the implementation matter: - The check runs ahead of the block-type branches inonPlayerInteract. Shift-right-clicking setssuppressUsingBlockinuseItemOn, which skips block use and empties the bucket instead. A player with container trust but not build trust could otherwise have placed a cube by shift-clicking a chest, because that click is claimed by the container branch first. - Permission is checked at the block adjacent to the clicked face, not the clicked block. For an empty-fluid bucketplacePosis alwaysdirectionOffsetPos, which is where the mob actually spawns. This is the same relative-block ruleonPlayerBucketEmptyalready applies, and it is what makes the check correct against 3D subdivisions rather than only horizontally. The material set is derived by name — anything ending_BUCKET, minus the empty bucket, water, lava, milk, powder snow and theLEGACY_aliases. On 26.2 that resolves to exactly the seven mob buckets (cod, salmon, pufferfish, tropical fish, axolotl, tadpole, sulfur cube), it is empty on older versions where those materials do not exist, and future mob buckets are picked up with no code change. The water-carrying buckets now have two layers of protection; the fluid-less one has its first. Dispensers were already covered and are unchanged.SULFUR_CUBE_BUCKETis registered with the standardfilledBucketBehavior, andBlockEventHandler.onDispensealready cancels any dispense that crosses a claim boundary in either direction.The punch freeze threw on every swing under region threading
SulfurCubeHandlerundoes an unauthorized push by teleporting the cube back to where it started on the next tick. That teleport usedEntity#teleport, which Folia and Canvas reject:
The entity task was already being scheduled correctly throughjava.lang.UnsupportedOperationException: Must use teleportAsync while in region threading at org.bukkit.craftbukkit.entity.CraftEntity.teleport0(CraftEntity.java:321) at GriefPrevention3D.jar/me.ryanhamshire.GriefPrevention.SulfurCubeHandler.lambda$onPlayerSwing$0(SulfurCubeHandler.java:60)SchedulerUtil.runLaterEntity; the teleport call inside it was the problem. Note where in the sequence this landed: the exception was thrown after the permission check had already failed, so the cube was never moved back andsetVelocitynever ran. On a region-threaded server the push protection did nothing at all except fill the console — one stack trace per denied swing. Fix: teleports go through a newCompatUtil.teleportSafely(Entity, Location), which resolvesteleportAsynconce via reflection and falls back to the blocking call where it does not exist (Spigot, pre-1.19 Paper).PlayerEventHandler.teleportFoliaSafe— a near-identical private copy that only handledPlayer— now delegates to it rather than a second copy being added.Notes
- No configuration changes, no data migration, no message changes. - Denied bucket placements use the existing no-build message and the existing rate limiter, so a player spamming right-click gets one message rather than a stream. - This affects Minecraft 26.2 and newer, where the sulfur cube and its bucket exist. On older versions the material set is empty and the interact check is a no-op. - The bucket bypass has existed since sulfur cube protection was added in v18.1.4. That release covered the punch and right-click paths but not placement, because the bucket was reasonably assumed to behave like the axolotl bucket, whichonPlayerBucketEmptyalready handled. - Upstream GriefPrevention is affected identically — it guards buckets solely throughPlayerBucketEmptyEvent, and the sulfur cube bucket never fires it.Tests
No new tests. The full suite passes — 226 tests, 0 failures, 0 errors. Neither fix has unit coverage. Both need a livePlayerInteractEventagainst a real block, and the teleport path additionally needs a region-threaded server to reproduce at all; the mock harness can construct neither. The item construction and event paths were verified by decompiling the shipped server jar rather than inferred:$ cfr canvas-26.2.jar net/minecraft/world/item/Items.class | grep SULFUR_CUBE_BUCKET public static final Item SULFUR_CUBE_BUCKET = Items.registerItem(ItemIds.SULFUR_CUBE_BUCKET, (Item.Properties p) -> new MobBucketItem(EntityTypes.SULFUR_CUBE, Fluids.EMPTY, SoundEvents.BUCKET_EMPTY_SULFUR_CUBE, p), ...);MobBucketItem.emptyContents,BucketItem.emptyContents,ServerPlayerGameMode.useItemOnandServerGamePacketListenerImpl.handleUseItemwere each read from the same jar to confirm that no bucket-empty event is fired and that cancelling the interact event does suppress the item use.Files Changed
M gradle.properties M pom.xml M src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java M src/main/java/me/ryanhamshire/GriefPrevention/SulfurCubeHandler.java M src/main/java/me/ryanhamshire/GriefPrevention/compat/CompatUtil.java18.2.18GriefPrevention3D v18.2.18Aug 7, 2026 GriefPrevention3D v18.2.18
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
Block explosions were cancelled entirely inside claims, suppressing knockback and every other effect
BlockExplodeEventHandlercancelled the wholeBlockExplodeEventas soon as any affected block was inside a claim:
Cancelling that event does not merely spare the blocks — it suppresses the entire explosion, including the knockback the server delivers to players. Every non-block effect of a block explosion inside a claim has been silently dropped for as long as this class has existed. The most visible symptom was the mace's Wind Burst enchantment: smashing a player inside a claim produced particles, damage, and negated fall damage, but never launched the attacker. The knockback event itself was completely healthy — it reachedClaim claim = this.dataStore.getClaimAt(block.getLocation(), false, null); if (claim != null) { explodeEvent.setCancelled(true); return; }MONITORpriority uncancelled, with a full(0, 2.2, 0)vector, and the velocity really was applied to the attacker server-side. What never happened was the packet that carries that motion to the client, because the explosion it belonged to had been cancelled. The server believed the player was flying while their client kept falling. Two settings that should have governed this were never consulted by the class at all, which is why neither provided a workaround: -GriefPrevention.BlockLandClaimExplosions—config_blockClaimExplosionswas never read -/claimexplosions—claim.areExplosivesAllowedwas never readBlockSurfaceCreeperExplosionsandBlockSurfaceOtherExplosionswere equally irrelevant here. The only configuration that avoided the bug was disabling claims for the whole world. Fix: both branches now strip protected blocks from the explosion instead of cancelling it, matching whatEntityEventHandlerhas always done for entity-caused explosions: -handleExplosionfilters into an allowed-blocks list and honoursconfig_blockClaimExplosionsandclaim.areExplosivesAllowed, so `/claimexplosions` works on this path for the first time -handleExplodeInteractcollects protected blocks and callsblocks.removeAll(removed), and now updatesplayerData.lastClaimlike its entity-side counterpart - Both use the cached-claim lookup instead of passingnullon every iteration Block protection is unchanged: claimed blocks still do not break. Everything else the explosion does — knockback, damage, block triggering — now survives. This class is GP3D-only. It was split out ofEntityEventHandlerfor 1.8.8 compatibility and the split copy was rewritten to cancel rather than filter. Upstream GriefPrevention routesBlockExplodeEventthrough the same sharedhandleExplosion/handleExplodeInteractmethods as entity explosions and is not affected.The investigation tool could not be placed on a shelf
[#10](https://github.com/castledking/GriefPrevention3D/issues/10) — right-clicking a shelf while holding the investigation tool (a stick by default) ran claim investigation instead of storing the item, so the tool could never be placed on a shelf. Item frames were unaffected because they are entities and never reach this handler. Shelves areBlockInventoryHolders, so the interaction reached the container branch ofPlayerEventHandler.onPlayerInteract, which hands off to the claim tool dispatcher whenever the player is holding the investigation or modification tool. The dispatcher consumed the click. Fix: the claim tools no longer intercept right-clicks on shelf blocks, at both dispatcher call sites. Shelves stay protected exactly as before — they are inventory holders, so the container trust check still applies and untrusted players still cannot store or retrieve items in a claim. This only decides whether the claim tools consume the interaction first. Shelves are matched by name (_SHELFsuffix, which excludesBOOKSHELFandCHISELED_BOOKSHELF) so the plugin still compiles and runs on versions predating them, and so future wood variants are covered automatically.Duplicate wind-charge knockback handlers were registered alongside the platform handlers
PaperKnockbackHandlerandSpigotKnockbackHandlerwere GP3D-only classes added here on 2025-12-29 (cab3d9cf). Upstream solved the same problem independently on 2026-01-26 with [GriefPrevention#2549](https://github.com/GriefPrevention/GriefPrevention/pull/2… which introducedcom.griefprevention.platform.knockback. That package arrived via the upstream merge inb084c943, but the older classes were never removed — so two independent listeners inspected and could cancel the same knockback event. The Paper one was the worse of the two. Its wind-charge test was:
which matches any player-sourced explosion knockback, including the mace smash AoE. Both classes are removed;boolean isWindChargeKnockback = causeName.equals("EXPLOSION") && source instanceof Player;KnockbackProtectionListenerand its Paper/Spigot handlers are now the only knockback protection path.Paper's knockback handler processed the same event twice
On Paper,com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEventextendsio.papermc.paper.event.entity.EntityPushedByEntityAttackEvent, and only the baseio.papermc.paper.event.entity.EntityKnockbackEventdeclares aHandlerList— so all three event types share one handler list and both@EventHandlermethods onPaperKnockbackProtectionHandlerran for everyEntityKnockbackByEntityEvent. That meant duplicate claim lookups and permission checks on every melee hit, and a duplicatePreventPvPEventwhenever the first pass did not cancel.onEntityPushedByEntityAttacknow skips events that areEntityKnockbackByEntityEvent. This defect is inherited from upstream, not introduced here — our copy differs from #2549 only in Java 8 desugaring. It has been submitted upstream separately.Features
Knockback tracing under
Knockback protection now logs its decisions through the existing debug channel. Enable with/gpdebug/gpdebug on(permissiongriefprevention.debug); entries are prefixed[GP Debug] [knockback]and are suppressed entirely while debug logging is off, including the claim lookups they would otherwise perform.
Traced branches: self-knockback,[GP Debug] [knockback] EntityKnockbackByEntityEvent cause=ENTITY_ATTACK entity=Player(bob) hitBy=Player(alice) [GP Debug] [knockback] allow: attacker alice has Access trust in defender's claim 2 [GP Debug] [knockback] [in ] EntityKnockbackEvent cause=EXPLOSION entity=Player(alice) standingIn=claim 2 cancelled=false knockback=0.0,2.2,0.0 [GP Debug] [knockback] [out] EntityKnockbackEvent cause=EXPLOSION entity=Player(alice) standingIn=claim 2 cancelled=false knockback=0.0,2.2,0.0ignoreClaims, Access trust in the defender's claim, GP PvP rules disabled for the world, fresh-spawn immunity, defender in a PvP-safe claim, attacker in a PvP-safe claim, another plugin cancellingPreventPvPEvent, and "no GP rule matched". Events GP declines to act on are logged asignored:with the reason. On Paper, the[in ]/[out]pair additionally traces the baseEntityKnockbackEvent— which GP does not otherwise subscribe to, and which is how explosion knockback with no source entity arrives — atLOWESTon arrival and again atMONITORafter every other plugin has run. A knockback that is cancelled or zeroed in between is visible, along with the claim the affected player is standing in. It never modifies the event. This is what isolated the explosion bug above: it proved the knockback event was pristine, which ruled out the entire knockback path and redirected the search to explosion handling.Platform listener registration is logged
PlatformListener.register()now records which handler it registered and on what: ```18.2.17GriefPrevention3D v18.2.17Aug 4, 2026 GriefPrevention3D v18.2.17
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFeatures
Shaped 2D subdivisions
Subdivisions can now be drawn as free-form orthogonal polygons inside a claim, matching the shaped-claims tooling but scoped to a parent claim. Run/shapedsubdivideclaims(aliases:shapedsubdivideclaim,ssc,shapedsubdivide) or/claim mode shapedsubdivideto enter the mode: - Right-click inside one of your claims to place corners, then click your first corner again to close the subdivision. - Click an existing shaped subdivision's boundary to enter a reshape session for it. - A shaped subdivision must stay inside the claim it subdivides. - Shaped subdivisions work inside top-level 2D claims only; a 3D claim cannot be subdivided with this mode, and a shaped subdivision spans the same vertical range as its parent claim. The mode is gated by a newGriefPrevention.Claims.AllowShapedSubClaimssetting, which defaults tofalse. Both/shapedsubdivideclaimsand/claim mode shapedsubdividerefuse to enter the mode while it is disabled. Overlap checks between a shaped polygon and other claims are now column-exact: a 3D claim sitting only inside the shaped claim's rectangular bounding box but over a cavity (a concave notch the polygon does not actually cover) is no longer treated as an overlap, while Y separation between claims is still respected.Admin-controlled subdivisions
Staff can flag an individual subdivision as administered by the server, taking its editing and trust management away from the claim owner. Use/aclaim makeadminand/aclaim makebasic(or the standalone/makeadminand/makebasic) on a subdivision. Staff needgriefprevention.adminclaims.convert. The subdivision has to be selected first by right-clicking one of its corners with the golden shovel; running the command without a selection tells you to select one and run it again. Once a subdivision is administrative: - The claim owner loses Edit and Manage inside it, and cannot resize it, hand out trust inside it, or abandon the claim containing it. - Staff holdinggriefprevention.adminclaimskeep full Edit and Manage inside it. - The owner still controls the claim around it, so an administrative subdivision is not an admin claim — it is a subclaim whose interior is staff-managed. -/aclaim makebasic(ormakeadminon an already-admin subdivision) converts it back. The flag is persisted in both storage backends: the flat-file claim codec carries an `Admin Subdivision` field on the shared claim file, and the database schema growsgriefprevention_claimdata.adminsubdivisionvia the usualADD COLUMN IF NOT EXISTSmigration, so existing files and tables upgrade in place and the two backends stay feature-for-feature.Fixes
Items dropped during combat could be silently deleted when the main inventory was full
During PvP combat withGriefPrevention.PvP.AllowCombatItemDropat its defaultfalse, GriefPrevention cancels item drops so the items stay in the player's inventory. Cancelling a drop only works when the server can put the stack back: the server returns a cancelled drop to the main inventory, so anything dropped from the cursor or an armor or offhand slot — with no main slot to return to — was destroyed when the 36 main slots were full or could not absorb the stack. This is upstream [GriefPrevention issue #2619](https://github.com/GriefPrevention/GriefPrevention/issues… rooted in the server behavior described in [PaperMC/Paper#7726](https://github.com/PaperMC/Paper/issues/7726). Fix: the drop is stopped at the click instead of after the fact, using the community-accepted workaround from [PaperMC/Paper#12475](https://github.com/PaperMC/Paper/pull/12475): -InventoryClickEventdrop actions (DROP_ONE_SLOT/DROP_ALL_SLOT/DROP_ONE_CURSOR/DROP_ALL_CURSOR) are cancelled atLOWESTpriority during combat, so the click is never applied and the item simply stays where it is. - Closing an inventory during combat with an item on the cursor moves that item into the main inventory instead of letting the server drop it; only the portion that cannot fit stays on the cursor. - A leftover drop that still reachesPlayerDropItemEvent(a hack client, or the small cursor remainder on inventory close) falls like vanilla — the item lands on the ground — rather than being deleted. Main-hand Q-drops remain safe: the server splits the stack out of the hotbar slot, so the existing block keeps the item in hand. The fix is being contributed back to upstream GriefPrevention.Notes
- New configuration:GriefPrevention.Claims.AllowShapedSubClaims(defaultfalse). - Existing claims need no conversion: shaped subdivisions and admin flags are new fields, and both flat-file and database stores read them with safe defaults when absent. - The combat-drop fix is not 3D-specific; it ships in GriefPrevention3D and is also queued as an upstream pull request. -MyCommandwas added to the plugin's soft-depend list. - Localization: all existing locale files (de_DE,en_PT,es,fr_FR,ja_JP,ms_MY,pl_PL,pt_BR,ru_RU,tr_TR,uk_UA,zh_CN) picked up translations for the shaped-subdivision, admin-subdivision, and combat-drop messages introduced this release. A newmessages_cs_CZ.yml(Czech) locale file was added with a full translation of all 330 message keys.Tests
-ShapedSubdivisionTestcovers drawing a shaped subdivision inside a parent claim, requiring the parent to be a top-level 2D claim, containment within the parent, and reshaping an existing shaped subdivision. -ClaimBoundsTestcovers column-exact overlap for shaped polygons: cavity columns are not part of a shaped claim, while Y separation between claims is preserved. -AdminSubdivisionTestcovers the owner losing Edit/Manage inside an admin subdivision (while still controlling the surrounding claim), staff keeping both inside it, and normal subdivisions inheriting owner control. -PlayerDropItemEventHandlerTestcovers the combat-drop handlers: drop-click cancellation in combat, cursor-on-close being moved into the main inventory, the full-inventory safety net that drops instead of deleting, and combat state being ignored whenAllowCombatItemDropis enabled.Files Changed
``` M gp3d-core/src/main/java/com/griefprevention/claims/ClaimBounds.java M gp3d-core/src/main/java/com/griefprevention/claims/editor/ClaimEditTargetType.java M gp3d-core/src/main/java/com/griefprevention/claims/editor/ClaimEditorSkeleton.java M gp3d-core/src/main/java/com/griefprevention/claims/persistence/ClaimDataSchema.java M gp3d-core/src/test/java/com/griefprevention/claims/ClaimBoundsTest.java M gp3d-core/src/test/java/com/griefprevention/fabric/FabricClaimFileStoreTest.java M src/main/java/com/griefprevention/commands/UnifiedAdminClaimCommand.java M src/main/java/com/griefprevention/commands/UnifiedClaimCommand.java M src/main/java/me/ryanhamshire/GriefPrevention/Alias.java M src/main/java/me/ryanhamshire/GriefPrevention/Claim.java M src/main/java/me/ryanhamshire/GriefPrevention/ClaimToolDispatcher.java M src/main/java/me/ryanhamshire/GriefPrevention/DataStore.java M src/main/java/me/ryanhamshire/GriefPrevention/DatabaseDataStore.java M src/main/java/me/ryanhamshire/GriefPrevention/EquipShovelProcessingTask.java M src/main/java/me/ryanhamshire/GriefPrevention/FlatFileDataStore.java M src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java M src/main/java/me/ryanhamshire/GriefPrevention/Messages.java M src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java M src/main/java/me/ryanhamshire/GriefPrevention/ShovelMode.java M src/main/java/me/ryanhamshire/GriefPrevention/StartupHeader.java M src/main/resources/alias.yml M src/main/resources/messages.yml M src/main/resources/messages_de_DE.yml M src/main/resources/messages_en.y18.2.16GriefPrevention3D v18.2.16Aug 2, 2026 GriefPrevention3D v18.2.16
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
Interacting with a Citizens horse NPC could erase its equipment
GriefPrevention inherited an old interaction-time repair for untamed inventory-bearing animals. When a player clicked one, the handler reset its owner and cleared its inventory. Citizens horse NPCs can legitimately present as untamed Bukkit horses, so clicking an NPC could silently remove its saddle and armor even though Citizens had configured both correctly. Fix: GriefPrevention no longer mutates an untamed horse while handling interaction. The horse's owner and inventory are left untouched, while the normal claim access checks continue to run. This does not add a Citizens dependency or bypass protection for NPCs; it removes the unrelated destructive repair behavior for Citizens and other plugin-managed horses. Reported by @RocketYota in upstream [GriefPrevention issue #2623](https://github.com/GriefPrevention/GriefPrevention/issues…Experimental Fabric preview
TheGriefPrevention3D.jarrelease asset now also contains the first native Fabric adapter. It can be installed as a Bukkit/Paper plugin or placed unchanged in a Fabric server'smodsdirectory. The Fabric side of v18.2.16 is experimental and still in development: - Fabric is currently limited to Minecraft 1.21.11, Java 21, and a server-side installation. - Fabric API is required. - Stick inspection and golden-shovel create/resize sessions now show client-only fake-block claim boundaries to the player using the tools. No client mod is required. - The adapter reads and writes the sharedplugins/GriefPreventionDataflat-file layout so the same claim graph can be tested when moving between Paper and Fabric. - Existing player and group files are preserved byte-for-byte, including claim-block balances, but Fabric does not enforce claim-block balances yet. - Protection and command parity with the Bukkit plugin is not complete. Back upGriefPreventionDataand test this preview away from a production server. The stable Bukkit/Paper behavior remains available from the same jar across its existing supported version range. Fabric support in this release is advertised only for 1.21.11.Notes
No configuration or data migration is required for the Citizens fix. The fix is on the Bukkit side because Citizens is a Bukkit plugin; Fabric has no equivalent horse-inventory mutation path.Tests
A handler-level regression test models an untamed horse with an inventory and fails if an interaction calls eitherInventory.clear()orTameable.setOwner(null). The universal jar checks also load the Bukkit entry classes on Java 8 and boot the exact same artifact on a Fabric 1.21.11 server.Issue Fix Files
M src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java A src/test/java/me/ryanhamshire/GriefPrevention/PlayerInteractEntityEventHandlerTest.java18.2.15GriefPrevention3D v18.2.15Aug 1, 2026 GriefPrevention3D v18.2.15
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
Two rectangular claims could merge into a narrow Manhattan path
Running/mergeclaimson two rectangular claims could produce a thin, bent connection between them instead of one usable rectangle. The disconnected-polygon union already knew how to make a valid Manhattan connection, so the later bounding-box fallback was never reached. Whether another claim occupied part of the larger rectangle could therefore indirectly change which geometry survived. Fix: a direct merge now chooses its geometry before the generic polygon union runs. When both selected claims have four-corner rectangular boundaries, the result is always the single global bounding rectangle covering both claims: - The rectangle uses the minimum and maximum X/Z coordinates of both selected claims. -GriefPrevention.Claims.AllowShapedClaimsdoes not change this rule. - A claim which carries shaped-claim metadata but still has an actual four-corner boundary is treated as a rectangle. - If the proposed rectangle overlaps another claim, the merge fails with the normal overlap conflict instead of silently falling back to a Manhattan or other non-rectangular shape. This can require more claim blocks than the old narrow connection. The existing final-area claim-block check still runs before anything is changed and reports insufficient blocks in the normal way.Shaped claims keep their Manhattan route, widened by the selected nib depth
The Manhattan route remains the useful behavior for non-rectangular shaped claims, but its old fixed-width path could look and behave like a tiny road between otherwise substantial claim sections. Shaped merges now record the selected boundary edge and the player's position at both ends. A new platform-neutralMergeCorridorgeometry helper uses that information to build one straight rectangle or two rectangles forming an L-shaped Manhattan route: - The player's distance inward from the selected edge controls how deeply the corridor is inset into that nib. - The selected nib keeps its own width while the chosen depth remains inside the narrow section. - If that depth reaches a wider connected parent section, the parent section becomes the width of that corridor leg. - Diagonal claims keep the Manhattan turn; each leg uses the width measured from the nib it leaves or enters. - A shaped claim must have a resolvable boundary edge at both ends, preventing missing nib data from dropping back to an unintended thin connector. The cross-claim shaped-editor/roundabout path already supplies its own connection cells and continues using that path unchanged. This new corridor selection applies to direct/mergeclaimsoperations.Populated-area overlap checks now cover the whole proposed result
The old merge check looked for claims near the first claim's corner. A long rectangle or shaped corridor can extend through chunks well beyond that local search, allowing a claim in the middle or near the second endpoint to be missed. Fix: collision candidates are collected from every chunk beneath the complete proposed merge boundary. The exact polygon intersection check then rejects: - A third claim belonging to another player. - A third claim belonging to the same owner. Only the two explicitly selected claims are collapsed; swallowing a separate same-owner claim would otherwise leave two live claims on the same blocks. - A claim crossing a shaped corridor even when neither polygon has a corner inside the other, such as a narrow horizontal claim crossing a vertical corridor. The two claims explicitly selected for the merge and their subdivisions are still excluded from this conflict list. On conflict, no claim geometry is mutated and the conflicting claim is shown with the existing conflict visualization.The command completion path now checks the second claim's edit permission
Right-click completion already checked edit permission on the second claim, but running/mergeclaimsagain while standing inside the second claim could reach the merge directly. That alternate command path now performs the same edit-permission check before measuring a nib or calling the data store, so a claim the player cannot edit is never absorbed.Notes
No configuration or claim-data migration is required. Existing rectangular claims remain rectangular, existing shaped boundaries remain valid, and stored claim IDs and subdivisions are handled as before.Tests
Eleven regression cases were added acrossMergeClaimsTestandMergeCorridorTest, covering: - The mandatory global bounding rectangle for two rectangular claims, even when edge/depth metadata is present. - Four-corner claims carrying shaped metadata. - Shallow nib depth and widening when that depth reaches a larger parent section. - The complete widened Manhattan route between diagonal shaped claims. - Clear populated areas containing nearby same-owner and other-player claims. - Overlap rejection for both same-owner and other-player claims. - Candidate discovery across the full multi-chunk proposed boundary. - Crossing-polygon conflicts where corner-only intersection checks would fail. - Rejection when the player cannot edit the second selected claim. The full Gradlechecklifecycle passes for the Bukkit plugin,gp3d-core, and the Fabric module.Files Changed
A gp3d-core/src/main/java/com/griefprevention/geometry/MergeCorridor.java A gp3d-core/src/test/java/com/griefprevention/geometry/MergeCorridorTest.java M src/main/java/me/ryanhamshire/GriefPrevention/ClaimToolDispatcher.java M src/main/java/me/ryanhamshire/GriefPrevention/DataStore.java M src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java M src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java A src/test/java/me/ryanhamshire/GriefPrevention/MergeClaimsTest.java18.2.14GriefPrevention3D v18.2.14Aug 1, 2026 GriefPrevention3D v18.2.14
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
Extra spaces after the colon were read as part of the message
v18.2.13 stopped parsing message files as YAML so that color codes work without quoting. The new reader consumes exactly one space or tab afterKey:as the separator and takes the rest of the line literally — which means a value that had been lined up in a column kept its padding as text:BookDisabledChestClaims: Auf diesem Server beansprucht das Platzieren einer Kiste NICHT automatisch Land für dich.
YAML treats every space between the colon and the first non-space character as separator, so this is a regression against how the same file read before v18.2.13. It only affects hand-edited files — Bukkit's YAML writer always emits exactly one space, so anything the plugin had written itself was unaffected.Auf diesem Server beansprucht das Platzieren einer Kiste NICHT automatisch Land für dich.messages_de_DE.ymlis the one bundled locale that hits it, onBookDisabledChestClaims. Fix: leading spaces and tabs between the colon and the value are dropped, matching YAML. Padding a file into columns is now cosmetic, exactly like quoting. Leading spaces that are inside quotes are still preserved, because the quote is the first non-space character and everything after it is the value:Padded: ' two leading spaces, on purpose'
That is howtwo leading spaces, on purposeen_PT,fr_FRanduk_UAindent the same book line, and it read the same way before and after this fix.Notes
No message file needs editing, and saving remains append-only, so your customizations, comments and ordering are left alone.Tests
MessageFileTest— 15 cases. New this release:ignoresExtraSpacesBetweenTheColonAndTheValue, covering both a padded plain value and a padded quoted value whose own leading spaces are kept. The existingreadsBackEveryValueBukkitWouldHaveWrittensweep still round-trips every message inmessages_en.ymlthrough Bukkit's YAML writer and back through the reader, andbundledLocaleFilesParseIntoKnownMessagesparses all 13 bundled locale files.Files Changed
M gradle.properties M pom.xml M src/main/java/me/ryanhamshire/GriefPrevention/MessageFile.java M src/test/java/me/ryanhamshire/GriefPrevention/MessageFileTest.java18.2.13GriefPrevention3D v18.2.13Aug 1, 2026 GriefPrevention3D v18.2.13
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
A color code at the start of a message ate the word after it
Putting a formatting code at the front of a message did not colorize it — it deleted the next word:Messages: IgnoringClaims: &1Now ignoring claims.
The message files were being read by a YAML parser, and to YAML a leadingignoring claims.&is not text — it is an anchor declaration.&1Nowwas consumed as an anchor named1Now, and the value became whatever followed it. Nothing was logged, because as far as YAML was concerned the file was perfectly valid. Quoting the value (IgnoringClaims: '&1Now ignoring claims.') worked around it, but only until the next/gpreload: the plugin re-serialized the whole file through SnakeYAML on load, and SnakeYAML emits scalars unquoted whenever quoting is not strictly required. The quotes were stripped, the value was re-read as an anchor, and the word disappeared again. The same parser rules silently swallowed other perfectly reasonable message text — a#started a comment, and backslashes were escape sequences inside double-quoted values. Fix: message files are no longer parsed as YAML. A newMessageFilereader takes everything afterKey:literally: -&1,&a,$eand hex codes such as&#ff0000work anywhere in a message, including the very first character, with no quoting. -#,\,:and quote characters inside a message are just text. - Quotes are still optional: if a value is wrapped in'…'or"…"the quotes are stripped (with''→'and\"→"), so every existing customizedmessages.ymlkeeps working exactly as it did. - The legacy nested format (SomeMessage:→Text:/Notes:) still reads. - Indentation, comments and blank lines are handled as before.Message files were rewritten on every load
Loading messages re-serialized the active file and saved it back. That is what stripped quoting, but it also normalized comments and key order, and it had a more damaging edge: if a server had both a locale file (messages_de_DE.yml) and amessages.yml, the locale file's contents were saved overmessages.ymlon every load, discarding customizations in it. Fix: saving is now append-only. Existing lines — comments, ordering, whatever quoting style the admin prefers — are left byte-for-byte intact, and only keys that are missing from the file are appended, written single-quoted with the message's notes as a#comment above them.messages.ymlis never written unless it is the file actually in use and it is missing keys.Action bar messages ignored the default message colors
Messages listed underGriefPrevention.ActionBarMessageswere sent as raw legacy text, while the chat path prefixes the message'sTextModecolor. Any action bar message that did not hard-code a color of its own therefore rendered plain white —/gpreloadoutput, warnings and errors all looked identical. Fix: the action bar path now prefixes the sameTextModecolor chat uses, so warnings arrive gold, errors red, successes green and info aqua by default. A color code inside the message still comes after the prefix and still wins, so any custom color an admin has already set is unaffected.UnprotectedChestWarningis the one default action bar message this changes — it isTextMode.Warnwith no color of its own, so it is now gold instead of white. The four boundary-violation messages already carry&6in their text and are unchanged.Upstream
- Rename `/permissiontrust` to `/managetrust` ([#2618](https://github.com/GriefPrevention/GriefPrevention/pull/2618)): merged upstream commita873b55d, which renames the command and removes the last non-hierarchical trust structures left over from #2507./permissiontrust,/ptand/mtremain as aliases in GriefPrevention3D, so existing commands, macros and signs keep working. Thegriefprevention.permissiontrustpermission node is unchanged. The message keyNoPermissionTrustis nowNoManageTrust— if you customized that message, rename the key in your message file; otherwise the default is used.Notes
Quoting message values is now purely cosmetic. Both of these produce the same result:
The one behavior change to be aware of: a value that both begins and ends with a quote character loses those quotes, since that is how existing quoted files are supported. WriteIgnoringClaims: &1Now ignoring claims. IgnoringClaims: '&1Now ignoring claims.'He said "hi" nowrather than"hi"if the quotes are meant to be visible. A handful of entries in the English message files still contain doubled apostrophes (You don''t have permission) inherited from upstream'sMessageFormatera. Message arguments are substituted with a plain string replace, notMessageFormat, so those render literally asdon''ton unquoted lines. Cosmetic only, and unchanged by this release.Tests
MessageFileTest— 9 cases covering unquoted color codes, quote stripping for legacy files, literal#/backslash/colon handling, the nestedText:format, append-only saving, no-write when nothing is missing, section creation, and a parse sweep over all 13 bundled locale files.Files Changed
M gradle.properties M pom.xml M src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java A src/main/java/me/ryanhamshire/GriefPrevention/MessageFile.java M src/main/java/me/ryanhamshire/GriefPrevention/MessageLocalization.java A src/test/java/me/ryanhamshire/GriefPrevention/MessageFileTest.java18.2.12GriefPrevention3D v18.2.12Jul 31, 2026 GriefPrevention3D v18.2.12
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
Trust commands freeze the region/main thread on claims with many subdivisions
Reported in [issue #9](https://github.com/castledking/GriefPrevention3D/issues/9) on Folia 26.1.2: running/trust <player>on a parent claim with a large number of subdivisions stopped the affected region from ticking for 15+ seconds, with the Folia watchdog dumping a stack parked inside SnakeYAML's emitter at 5s, 10s and 15s:
Two separate problems combined here, and both are fixed. #### 1. Quadratic saves — one full claim-tree serialization per subdivision Flat file storage keeps subdivisions inside their root claim's `.yml` file, not in files of their own.org.yaml.snakeyaml.emitter.Emitter.writeLineBreak(Emitter.java:1344) ... org.bukkit.configuration.file.YamlConfiguration.saveToString(YamlConfiguration.java:92) FlatFileDataStore.getYamlForClaim(FlatFileDataStore.java:731) FlatFileDataStore.writeClaimToStorage(FlatFileDataStore.java:810) FlatFileDataStore.writeClaimToStorage(FlatFileDataStore.java:804) DataStore.saveClaim(DataStore.java:831) GriefPrevention.propagateTrustToChildren(GriefPrevention.java:3699)writeClaimToStoragereflects that: given a subdivision, it walks up to the root claim and serializes the entire tree — parent plus every child and grandchild — into one document.propagateTrustToChildrensaved each child as it modified it:
So a claim with N subdivisions performed N full-tree YAML serializations and N file writes, each one proportional to N — quadratic work, all of it on the calling thread, which on Folia is the region thread that owns the player. That is the watchdog stall. Fix:childClaim.setPermission(identifier, permissionLevel); this.dataStore.saveClaim(childClaim); // rewrites the whole tree, once per childpropagateTrustToChildrennow only mutates children in memory and collects them into a list. The caller hands that list to the data store in a single batch, at all three call sites (/trust,/accesstrust,/containertrust,/permissiontrustviahandleTrustCommand, plus both/untrustpaths). Batching is done through a newDataStore.saveClaims(Collection<Claim>): - The default implementation saves each claim individually. This is required for the database backend, which stores one row per claim — saving only the parent there would silently drop the children's permission changes. -FlatFileDataStoreoverrides it to collapse the batch down to the distinct root claims involved and write each root exactly once. Claim IDs are still assigned per claim, so nothing that depended onsaveClaim's ID assignment changes. N subdivisions now cost one write instead of N. #### 2. YAML serialization and disk I/O ran on the tick thread Even a single write of a large claim tree does real work — SnakeYAML emitting, then a blocking file write — and it happened inline on whichever thread ran the command. Fix:writeClaimToStoragenow builds theYamlConfigurationon the calling thread, where the claim data cannot change underneath it, then hands that finished document to a dedicated single daemon writer thread which performssaveToString()and the file write. Claim data is never read off-thread, so this introduces no race with claim mutation. The writer pipeline: - Coalesces writes per claim — if a claim is saved several times before the writer catches up, only the newest data is written and the superseded ones are dropped. - Orders deletes behind writes on the same thread, and drops any pending write for a claim being deleted, so a queued write can never resurrect a deleted claim file. - Drains on shutdown —FlatFileDataStore.close()(called fromonDisable) waits for the writer, then writes anything still pending on the calling thread. If the writer is already shut down, saves and deletes fall back to running synchronously, so no claim data is lost during a normal stop or restart. - Also flushes beforemigrateData, which renames the claim data folder out from under the writer. This benefits every claim save, not just trust changes — resizes, subdivisions, transfers and abandons no longer serialize YAML or touch disk on a tick thread.Notes
Claim saves are now durable a few milliseconds after the command returns, rather than at the moment it returns. A normalstop/restart, plugin disable, or/reloadflushes everything; only an abruptkill -9could lose that sub-second window.DataStore.mergeClaimsstill saves each moved subdivision individually when merging two claims. That path is much cheaper now that serialization and I/O are off-thread, but it is the same pattern and remains a candidate forsaveClaimsin a later release.Files Changed
M gradle.properties M pom.xml M src/main/java/me/ryanhamshire/GriefPrevention/DataStore.java M src/main/java/me/ryanhamshire/GriefPrevention/FlatFileDataStore.java M src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java18.2.11GriefPrevention3D v18.2.11Jul 29, 2026 GriefPrevention3D v18.2.11
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
Dynamically registered commands failing with "Unknown or incomplete command"
This resolves the/acbissue carried as a known issue in v18.2.10, where the command produced a client-side "Unknown or incomplete command" error with **nothing at all in the console** — no exception, no warning, no permission denial.registerDynamicStandaloneCommandandregisterDynamicRootCommandregistered commands by reflecting intoSimpleCommandMap'sknownCommandsmap and callingput()directly:
On Paper (and its forks), commands injected this way never pass through the server's Brigadier command registration, so they are absent from the client's command tree. The client then rejects the command locally and never sends it to the server at all — which is exactly why the console stayed silent.knownCommands.remove(lowerName); knownCommands.put(lowerName, dynamicCommand); knownCommands.put(prefix + ":" + lowerName, dynamicCommand);CommandMap.register()performs the Brigadier-aware registration; a raw mapput()does not. This failure mode was already known in the codebase:syncShapedCommandRegistrationcarries the comment *"Use CommandMap.register() so the implementation (Paper/Brigadier) stays consistent with plugin.yml aliases. Raw knownCommands.put() can leave /shapedclaim broken…"* — that call site had been fixed, but the dynamic standalone and dynamic root command paths were still using raw puts. Fix: both paths now callCommandMap.register()first. Reflection is used only as a fallback when the plain command name is genuinely already taken, in which case the displaced command is still recorded sounregisterAllDynamicCommands()can restore it (behavior added in v18.2.9). When the name is taken and the map cannot be read, a warning is logged noting the command is still reachable as/griefprevention3d:<command>instead of failing silently.Command map reflection broken on server forks (DivineMC, Purpur, etc.)
Two reflection lookups inUnifiedCommandHandlerassumed an exact class layout and threw on any server whose implementation classes sit deeper in the hierarchy: 1.getCommandMap()calledBukkit.getServer().getClass().getDeclaredField("commandMap")— agetDeclaredFieldlookup on the leaf runtime class. A fork that subclassesCraftServerhas no such declared field on the subclass, so this returnednulland dynamic registration was skipped entirely. 2. All threeknownCommandslookups usedmap.getClass().getSuperclass().getDeclaredField("knownCommands"), assuming the field lives exactly one level up. That holds for vanilla CraftBukkit (CraftCommandMap extends SimpleCommandMap) but throwsNoSuchFieldExceptionon any fork that inserts its ownCommandMapsubclass. Notably,GriefPrevention.findKnownCommandsMap()already walked the full class hierarchy correctly —UnifiedCommandHandlersimply had not been brought in line with it. Fix: -getCommandMap()now prefers Paper'sServer#getCommandMap()API (reflectively, so Spigot compatibility is retained), and otherwise walks the server class hierarchy instead of inspecting only the leaf class. - Added afindKnownCommands(CommandMap)helper that walks the command map's class hierarchy, mirroringfindKnownCommandsMap. All three former single-level reflection sites (dynamic standalone registration, dynamic root registration, andunregisterAllDynamicCommands) now use it. -unregisterAllDynamicCommands()logs a warning instead of proceeding when the command map cannot be read. These are the reflection assumptions most likely to break on a non-vanilla server jar, and they fail in a way that produces no diagnostic output — hardening them removes a class of silent, fork-specific command breakage.Notes
The plugin does not platform-detect between Bukkit and Fabric at runtime. The Fabric support inplatforms/fabric-1.21.11is a separate Gradle subproject producing a separate artifact; those classes are not present in the Bukkit jar. The only runtime class detection is feature detection for knockback handlers. A Paper-family fork is always driven through the normal Bukkit code path.Files Changed
M gradle.properties M pom.xml M src/main/java/com/griefprevention/commands/UnifiedCommandHandler.java18.2.10GriefPrevention3D v18.2.10Jul 29, 2026 GriefPrevention3D v18.2.10
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
This is the real cause of the `/abandonclaim` crash. The null guard added in v18.2.9 was in/abandonclaimNullPointerException when any admin claim existsabandonClaimHandlerand was a genuine latent bug, but it was not what players were hitting — the crash happens earlier in the call chain, and is unrelated to theAbandonReturnRatioconfig value. Full stack trace from a v18.2.9 server:Caused by: java.lang.NullPointerException: Cannot invoke "java.util.UUID.equals(Object)" because the return value of "Claim.getOwnerID()" is null at DataStore.cleanupAutoNeighborsOnDelete(DataStore.java:1434) at DataStore.deleteClaimUnchecked(DataStore.java:948) at DataStore.deleteClaimWithResult(DataStore.java:893) at GriefPrevention.abandonClaimHandler(GriefPrevention.java:3609)cleanupAutoNeighborsOnDeleteruns on every claim deletion. It correctly null-checks the deleted claim's owner, then scans every top-level claim in the datastore looking for other claims owned by the same player:
Administrative claims have a null `ownerID`. As soon as that scan reached any admin claim, it threw. The sibling methodfor (Claim otherClaim : this.claims) { if (!otherClaim.inDataStore) continue; if (otherClaim.parent != null) continue; if (otherClaim.id.equals(deletedClaim.id)) continue; if (!otherClaim.getOwnerID().equals(deletedOwner)) continue; // <-- NPEautoGrantNeighborTrustguards exactly this case (if (otherClaim.getOwnerID() == null) continue;) — the guard was simply omitted in the deletion path. Conditions to trigger it (all common, which is why it looked like "nobody can abandon claims"): -MinimumDistancegreater than0(otherwise auto-neighbor cleanup returns early), - at least one administrative claim anywhere in the datastore, - the abandoning player having at least one auto-neighbor entry — which happens automatically between any two nearby claims owned by different players, so it is the norm on a server with adjacent claims. Because the exception is thrown afterdeleteClaimUncheckedhas already removed the claim from memory and from storage, the abandon itself partially succeeded — the player got no success message, no claim blocks refunded message, and a console stack trace, making it look like the command did nothing. Fix: added the missingotherClaim.getOwnerID() == nullguard, matchingautoGrantNeighborTrust. Admin claims can never match a specific deleted owner, so skipping them is the correct behavior.Not caused by the migration or by
For the record, since this was initially suspected: auto-neighbor trust (AbandonReturnRatiocleanupAutoNeighborsOnDelete,autoGrantNeighborTrust,addAutoNeighbor) is a GriefPrevention3D-only feature — it does not exist anywhere in upstream GriefPrevention. Upstream'sdeleteClaimpath has no equivalent code and cannot throw this exception, which is why the crash appeared only after migrating to GP3D. It is triggered purely by having an admin claim plusMinimumDistance > 0; no migrated data, storage backend (File or MySQL), orAbandonReturnRatiosetting is involved.Known issue still under investigation
Still unresolved. The command-map corruption fixed in v18.2.9 (dynamic standalone registration permanently overwriting a/acbproducing no outputplugin.ymlcommand, soplugin.getCommand("acb")returnednullforever and the legacy handler silently attached to nothing) is a real bug and remains fixed, but it has not been confirmed as the cause here. v18.2.9 added a console warning for that exact failure mode. To diagnose, run/gpdebugand restart, then check startup output for:
- If that warning appears, the registration collision is the cause. Removing anyCould not register legacy standalone command 'acb': plugin.getCommand(...) returned null.standalone:entry containingacbfrom theblockssubcommand inalias.ymlwill resolve it, since it is redundant with the dedicated legacy/acbhandler. - If it does not appear,/acbis attached correctly and the failure is elsewhere — the exact observed behavior (silence vs. usage text vs. permission denial) is needed to narrow it down further.Files Changed
M gradle.properties M pom.xml M src/main/java/me/ryanhamshire/GriefPrevention/DataStore.java18.2.9GriefPrevention3D v18.2.9Jul 29, 2026 GriefPrevention3D v18.2.9
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
/abandonclaimthrowing a NullPointerException (unfixed since migration)abandonClaimHandleradjusts a player's accrued claim blocks whenAbandonReturnRatiois configured below1.0, using:claim.ownerID.equals(playerData.playerID)claim.ownerIDisnullfor administrative claims (and any claim whose owner UUID failed to parse on load), and this line dereferenced it with no null check. On any server withGriefPrevention.Claims.AbandonReturnRatioset to something other than the default1.0— a common setting used to penalize abandoning claims — this threw an NPE for every/abandonclaimcall:
The claim was already deleted by this point (org.bukkit.command.CommandException: Unhandled exception executing command 'abandonclaim' Caused by: java.lang.NullPointerExceptiondeleteClaimWithResultruns earlier in the same method), so the abandon itself succeeded — only the claim-block refund step crashed, leaving the player with no success message and a confusing failure. Fix: added the missingclaim.ownerID != nullguard before the equality check.Claim merge could push an owner's claim blocks negative
DataStore.mergeClaimsvalidates the block-limit before applying a merge by computing the union polygon's area (mergedPolygon.cellCount()) and checking it against the acting player's remaining claim blocks. Two issues let this validation be bypassed: 1. Wrong player checked. The check only ran `if (player.getUniqueId().equals(firstClaim.ownerID))` — if the person performing the merge hadEdit/manage trust on the claim but wasn't the owner, the block-limit check was skipped entirely, and the merge applied against the real owner's blocks with no validation at all. 2. Checked area could differ from the applied area. The limit check validated the real union polygon's area, but the shape is later applied viaupdateClaimPolygon(), which callsclaim.setShapedCorners(...). If the merged polygon's corners failed shape validation (e.g. a concave or otherwise irregular union),updateClaimPolygonsilently fell back to the full bounding-box rectangle spanning the merged region — which can be larger than the polygon that was actually checked. The merge would pass the block-limit check, then apply a bigger shape than was validated, driving the owner's remaining claim blocks negative. Fix: - The block-limit check now validates against the claim owner'sPlayerData(falling back to the acting player's data only when they are the owner), so trust-based merges by non-owners are checked correctly. - Before any state is mutated, the merged polygon's corners are now validated the same waysetShapedCornerswould validate them. If that validation would fail, the merge is aborted up front with"Failed to merge claims: invalid resulting shape."instead of silently substituting an oversized bounding-box rectangle after the block check has already passed./acbpermanently hijacked by/aclaim blocksafter a/gpreload/acb(adjustbonusclaimblocks) is registered twice inUnifiedAdminClaimCommand: once as a standalone name for the/aclaim blockssubcommand (Alias.AClaimBlocks, driven byalias.yml), and once directly as the legacy 2-argument command (/acb <player> <amount>). At clean boot both resolve to the same realPluginCommanddeclared inplugin.yml, and since the legacy registration runs second, it wins./gpreloadbroke this permanently, viaUnifiedCommandHandler: 1.registerDynamicStandaloneCommandhas a fallback path for standalone names that aren't found viaplugin.getCommand(name): it force-registers a rawDynamicStandaloneCommanddirectly into Bukkit'sCommandMap, overwriting whatever was at that name. 2.plugin.getCommand(name)only ever returns objects that are `instanceof PluginCommand. Onceacb`'s slot in the command map holds aDynamicStandaloneCommandinstead, every futureplugin.getCommand("acb")call returnsnull— including the legacy registration's own lookup. 3.registerLegacyStandaloneCommandhad noelsebranch for that case — ifplugin.getCommand(name)returnednull, it silently registered nothing. No warning, no log line, nothing in the console. 4.unregisterAllDynamicCommands()(run at the top of every/gpreload, before commands are re-registered) only ever deleted the dynamic command's map entry — it never restored whatever real command had been overwritten to make room for it. Put together: the first timeacb's name ever got claimed by the dynamic path (e.g. during a/gpreloadafter editingalias.yml), it was gone for good. Every reload after that recreatedacbas aDynamicStandaloneCommandbound to whatever/aclaim blocksstandalone configalias.ymlspecified, and the legacy 2-arg handler could never reattach — with no error anywhere to explain why. This also explains the "no permission" reports even for OP/wildcard players: the dynamic command's permission falls back to a hardcodedgriefprevention.claimswhenalias.yml'sblockssubcommand entry doesn't specify one, which is a different node than thegriefprevention.adjustclaimblocksthe legacy handler and most permission setups expect. Console senders bypass permission checks entirely, which is why running it from console "worked." Fix: -registerDynamicStandaloneCommandnow snapshots any real command it's about to overwrite before replacing it. -unregisterAllDynamicCommands()now restores that original command on cleanup instead of just deleting the map entry, so a legitimateplugin.ymlcommand/alias can no longer be permanently orphaned by a reload. -registerLegacyStandaloneCommandnow logs a warning instead of silently registering nothing when it can't resolve the target command, so this failure mode is visible in the console going forward. If you have a customstandalone:entry foracbunder/aclaim blocksinalias.yml, remove it — it's redundant with the dedicated legacy/acbhandler and is what triggers the collision in the first place.Files Changed
M src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java M src/main/java/me/ryanhamshire/GriefPrevention/DataStore.java M src/main/java/com/griefprevention/commands/UnifiedCommandHandler.java18.2.8GriefPrevention3D v18.2.8Jul 26, 2026 GriefPrevention3D v18.2.8
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFixes
Raid Omen bypass of
WhenRaidTriggersRequireBuildTrust(GriefPrevention#2622)RaidTriggersRequireBuildTrustwas enabled,RaidTriggerEventHandleronly checked the claim at the player's location at the moment the raid fired. Because Raid Omen converts to an active raid a few seconds after it is acquired, a player could: 1. Drink an ominous bottle outside the claim boundary to gain Bad Omen. 2. Step toward the village until Bad Omen converted to Raid Omen inside the claim. 3. Walk back outside the claim boundary before the raid started. 4. Have the raid trigger anyway — the player was no longer standing in a claim, so no build-trust check applied. The raid actually centers on the village, not the player, so the location that matters for protection is the raid's location.Fix
RaidTriggerEventHandlernow resolves the claim at `event.getRaid().getLocation()` (the village / raid center) first, and only falls back to the player's location if the raid center is unclaimed. The build-trust check and cancellation are otherwise unchanged: - Raid center inside a claim where the player lacksBuildtrust → raid cancelled, regardless of where the player is standing. - Raid center unclaimed but player standing in a claim → falls back to the player's claim (preserves prior behavior). - Player hasBuildtrust on the claim the raid centers on → raid proceeds.Ender pearl / chorus fruit no longer force the player's camera direction
When teleporting via ender pearl or chorus fruit, some server software overwrites the player's yaw/pitch to match the projectile's direction instead of preserving the player's original look direction.PlayerEventHandlernow copies the player's from yaw/pitch onto the teleport destination so the camera direction is preserved: - On the teleport itself, the destination location's yaw/pitch are set fromevent.getFrom()before the access check runs. - On a denied-pearl rollback, the rollback location keeps the player's current yaw/pitch rather than snapping back to the pre-pearl direction.Wilderness movement no longer blocked in claims-required worlds
InCreative/SurvivalRequiringClaimsworlds,ProtectionHelper.checkPermissionpreviously returned a "no build outside claims" denial for any permission checked in the wilderness. This also deniedAccesspermission, which disrupted movement and ender pearls in the wilderness. The wilderness denial is now scoped toBuild,Container, andInventoryonly.Access(walking, teleporting) is always allowed in wilderness, so enderpearls and movement are no longer interrupted. The automatic-claim chest-placement exception is preserved within the build/container/inventory path.Files Changed
M gradle.properties M pom.xml M src/main/java/com/griefprevention/protection/ProtectionHelper.java M src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java M src/main/java/me/ryanhamshire/GriefPrevention/RaidTriggerEventHandler.java18.2.7GriefPrevention3D v18.2.7Jul 6, 2026 GriefPrevention3D v18.2.7
Wiki: https://github.com/castledking/GriefPrevention3D/wikiNew Features
Per-Claim Alert Toggle (
- New/claim alerts)alertsEnabledfield onClaim(defaulttrue) -/claim alerts [on|off]— toggles alerts for the claim you're standing in -/claimtogglealerts [on|off]— toggles alerts for all your claims at once -/toggleclaimalerts— alias for/claimtogglealerts- Boundary violation messages (liquid/piston) respect the per-claim toggle: if alerts are disabled for the claim at the violation location, the message is suppressedAction Bar Message Routing
- New config optionActionBarMessages(string list underGriefPrevention.) - Default value:[UnprotectedChestWarning, ExternalLiquidBoundaryViolation, InternalLiquidBoundaryViolation, ExternalPistonBoundaryViolation, InternalPistonBoundaryViolation]- These messages render in the action bar (above the hotbar) instead of chat - Graceful fallback to chat ifspigot().sendMessage(ChatMessageType.ACTION_BAR)is unavailable -ClaimBoundaryViolationTrackerroutes throughGriefPrevention.sendMessageso action bar dispatch works automaticallyRate-Limited Chest Warning
- New config options: -GriefPrevention.Claims.UnprotectedChestWarningCooldownSeconds— default300(5 min) -GriefPrevention.Claims.UnprotectedChestWarningDistance— default100(blocks) - "This chest is NOT protected" message only repeats after the cooldown expires or the player moves farther than the distance threshold from the last warned chestLava Placement Near Claims (
- New config optionPreventLavaPlaceNearClaims)GriefPrevention.Claims.PreventLavaPlaceNearClaims— defaulttrue- When enabled andMinimumDistance > 0, lava placement is blocked if withinMinimumDistanceof any claim - Claim owners bypass the check for their own claims - Players with neighbor trust on the nearby claim can also place lava - New message:NoLavaNearClaim("You are too close to a claim to do that!")Persistence
Database Schema v11
- New columnalertsenabled(BOOLEAN DEFAULT 1) ingriefprevention_claimdata-SQL_INSERT_CLAIMupdated to includealertsenabled- Schema migration auto-adds column if missingFlatFile (YAML)
- New fieldAlerts Enabledin claim YAML files - Defaults totruewhen reading legacy files without the fieldNew Messages (all locales updated)
| Key | English Value | |-----------------------|-------------------------------------------------------------------------------| |NoLavaNearClaim| "You are too close to a claim to do that!" | |ClaimAlertsEnabled| "Alerts enabled for this claim." | |ClaimAlertsDisabled| "Alerts disabled for this claim." | |ClaimAlertsEnabledGlobal| "Alerts enabled for all claims." | |ClaimAlertsDisabledGlobal| "Alerts disabled for all claims." | |ClaimAlertsUsage| "Use /claimtogglealerts on\|off to toggle alerts for ALL claims, or stand in a specific claim and try again." | Translated versions added to all 14 bundled locale files (messages_*.yml).Files Changed
M src/main/java/com/griefprevention/commands/UnifiedClaimCommand.java M src/main/java/com/griefprevention/protection/ClaimBoundaryViolationTracker.java M src/main/java/me/ryanhamshire/GriefPrevention/Alias.java M src/main/java/me/ryanhamshire/GriefPrevention/BlockEventHandler.java M src/main/java/me/ryanhamshire/GriefPrevention/Claim.java M src/main/java/me/ryanhamshire/GriefPrevention/DataStore.java M src/main/java/me/ryanhamshire/GriefPrevention/DatabaseDataStore.java M src/main/java/me/ryanhamshire/GriefPrevention/FlatFileDataStore.java M src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java M src/main/java/me/ryanhamshire/GriefPrevention/Messages.java M src/main/java/me/ryanhamshire/GriefPrevention/PlayerData.java M src/main/resources/messages.yml M src/main/resources/messages_*.yml (13 locale files) M src/main/resources/plugin.yml18.2.6GriefPrevention3D v18.2.6Jul 5, 2026 GriefPrevention3D v18.2.6
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
PvP toggle messages synced in every non-English locale
The 16 PvP-toggle message keys introduced in v18.2.5 had only been added to the defaultmessages.ymlandmessages_en.yml. The 12 non-English locale files still carried the old single_NoFee/_WithFeekeys and were missing the new split / state / error / usage keys, causing every PvP toggle prompt (confirmation, fee, success, error) to silently fall back to English on a non-English server. This release adds all 16 new keys, with localized translations, in: -messages_de_DE.yml(German) -messages_es.yml(Spanish) -messages_fr_FR.yml(French) -messages_ja_JP.yml(Japanese) -messages_ms_MY.yml(Malay) -messages_pl_PL.yml(Polish) -messages_pt_BR.yml(Portuguese - Brazil) -messages_ru_RU.yml(Russian) -messages_tr_TR.yml(Turkish) -messages_uk_UA.yml(Ukrainian) -messages_zh_CN.yml(Chinese - Simplified) -messages_en_PT.yml(English - Pirate)Message keys added
| Key | English default | |---|---| |ConfirmPvpToggleEnabledNoFee|Do you want to enable PvP in this {0}?| |ConfirmPvpToggleDisabledNoFee|Do you want to disable PvP in this {0}?| |ConfirmPvpToggleEnabledWithFee|Do you want to pay {0} to enable PvP in this {1}?| |ConfirmPvpToggleDisabledWithFee|Do you want to pay {0} to disable PvP in this {1}?| |PvPToggleEnabled|PvP enabled in this {0}.| |PvPToggleDisabled|PvP disabled in this {0}.| |PvPToggleEnabledWithFee|PvP enabled in this {0} for {1}.| |PvPToggleDisabledWithFee|PvP disabled in this {0} for {1}.| |PvpToggleNotEnabled|PvP toggle commands are not enabled.| |PvpToggleNotEnabledForClaimType|PvP cannot be toggled in this type of claim.| |NoPendingPvpToggle|No pending PvP toggle to confirm.| |PendingPvpToggleExpired|Your pending PvP toggle has expired. Please try again.| |ConfirmPvpToggleInstruction|Type /claim pvp {0} confirm or /claimpvpconfirm to confirm.| |PvpToggleUsage|Usage: /claim pvp [true|false|on|off] [confirm]| |PvpToggleAlreadyEnabled|PvP is already enabled in this {0}.| |PvpToggleAlreadyDisabled|PvP is already disabled in this {0}.|Fixes
Removes orphan PvP toggle keys from locales
The pre-v18.2.5 generic keys are no longer referenced by the plugin (the/claim pvpflow now uses the four split_Enabled/_Disabledvariants) and were removed from all 12 non-English locale files so they match the defaultmessages.yml: -ConfirmPvpToggleNoFee(removed) -ConfirmPvpToggleWithFee(removed)18.2.5GriefPrevention3D v18.2.5Jul 5, 2026 GriefPrevention3D v18.2.5
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFeatures
Improved
The PvP toggle command has been significantly refactored for better usability and code clarity. #### Clearer confirmation flow The confirmation messages have been rewritten to be more explicit about what action will be taken: -/claim pvpcommand UXConfirmPvpToggleEnabledNoFee- "Do you want to enable PvP in this {0}?" -ConfirmPvpToggleDisabledNoFee- "Do you want to disable PvP in this {0}?" -ConfirmPvpToggleEnabledWithFee- "Do you want to pay {0} to enable PvP in this {1}?" -ConfirmPvpToggleDisabledWithFee- "Do you want to pay {0} to disable PvP in this {1}?" Previously all fee/no-fee variants used a single templated message with "enable"/"disable" as a parameter. Now they are separate messages with clear instructions. #### Already-toggled handling Running/claim pvp trueon a claim where PvP is already enabled now shows a specific message instead of silently succeeding. ####/claimpvpconfirmimprovements The/claimpvpconfirmcommand now validates that the player still has edit permission for the claim before executing the toggle, and shows proper error messages (NoPendingPvpToggle,PendingPvpToggleExpired) instead of hardcoded English strings.Vault economy formatting
AddedVaultEconomyFormattingutility class that formats currency amounts using the active Vault economy provider. When Vault is available, it useseconomy.format()for locale-aware currency display; falls back toString.format("%.2f", amount)otherwise. Fee amounts in PvP toggle confirmation and success messages now use this formatted display instead of rawString.format("%.2f", fee).Technical changes
- RefactoredhandlePvpCommand()into smaller helper methods:parsePvpToggleArg(),getPvpToggleContext(),getPvpToggleClaimTypeLabel(),sendPvpToggleConfirmation(),chargePvpToggleFee(),sendPvpToggleSuccess(),clearPendingPvpToggle()- IntroducedPvpToggleContextinner class to bundle fee and claim-type info - AddedVaultEconomyFormattingutility withformat(Server, double)andformat(Economy, double)overloads - UpdatedDataStore.createClaim()to inherit PvP state whenconfig_pvp_subdivisionPvpStateisINHERIT- UpdatedhandleClaimPvpConfirmCommand()to validate edit permission and use message enums - RemovedPvPToggleSuccess/PvPToggleSuccessWithFeemessage keys (replaced by separate enable/disable variants) - AddedClaimLabel,SubdivisionLabelin Messages enum and resource files - Addedgriefprevention.claimpvppermission node as a child ofgriefprevention.claims- Fixed missing&rreset code instartups.txttemplate18.2.4GriefPrevention3D v18.2.4Jul 3, 2026 GriefPrevention3D v18.2.4
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFeatures
PvP toggle command improvements
Fixed several bugs in the/claim pvpcommand to improve usability and reliability. #### Optional confirm suffix Theconfirmsuffix is now optional. Players can use: -/claim pvp true- Shows confirmation message, then type/claim pvp true confirmto execute -/claim pvp true confirm- Executes immediately without confirmation prompt This matches the behavior of other confirmation-based commands in the plugin. #### Fixed empty argument handling Previously, running/claim pvpwith no arguments would throw an error. It now shows proper usage:
#### Improved localization Added translatable messages for PvP state descriptions: -Usage: /claim pvp <true|false> [confirm]PvPToggleEnable- Localizable "enable" text -PvPToggleDisable- Localizable "disable" text These are used in confirmation messages instead of hardcoded English text, allowing proper translation. #### Fixed placeholder documentation Added proper placeholder documentation to confirmation messages: -ConfirmPvpToggleNoFee- Documents placeholders {0}, {1}, {2}, {3} -ConfirmPvPToggleWithFee- Documents placeholders {0}, {1}, {2}, {3}, {4}PvP prevention now actually works
The per-claim PvP toggle was previously stored but not enforced. TheclaimIsPvPSafeZone()method now checks thepvpEnabledfield before falling back to global config settings. When PvP toggling is enabled and a claim haspvpEnabled = false, it is treated as a PvP safe zone and prevents PvP combat regardless of global config settings.Startup header improvements
Minor formatting improvements to the startup header display: - UpdatedPluginTagmessage to use newline instead of space for better formatting - Removed extra newline fromstartups.txttemplate - Removed extra newline fromStartupHeader.buildStartupBlock()methodShaped claim merge improvements
Improved the merge claims feature when working with shaped claims. When merging shaped claims while standing in the nibbed (indented) portions, the system now creates a rectangle between the claims instead of using a Manhattan path. This approach follows the Minkowski sum principle, resulting in more intuitive and efficient claim merging for complex shaped claims. Added new fields to track merge state for shaped claims: -mergeSecondEdgeIndex- Tracks the second claim's edge index for shaped claim merge -mergeFirstDepthPoint- Player position when first claim merge edge was selected (for nib depth) -mergeSecondDepthPoint- Player position when second claim merge edge was selected (for nib depth)Technical changes
- AddedPvPToggleEnableandPvPToggleDisablemessages to Messages enum - UpdatedhandlePvpCommand()to handle optional confirm suffix - Added empty argument check inhandlePvpCommand()- Updated confirmation messages to use translatable state strings - Updated placeholder documentation inConfirmPvpToggleNoFeeandConfirmPvPToggleWithFee- ModifiedclaimIsPvPSafeZone()to checkpvpEnabledfield before global config - UpdatedPluginTagmessage format in Messages.java - Removed extra newline from startups.txt template - Removed extra newline fromStartupHeader.buildStartupBlock()method - Updated plugin.yml usage for claimpvp command to show[confirm]as optional18.2.3GriefPrevention3D v18.2.3Jul 3, 2026 GriefPrevention3D v18.2.3
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Fixes
The/claim pvpsubcommand now works in the alias system/claim pvpsubcommand was missing from both the alias configuration and the unified command handler. Running/claim pvpreturned "Unknown subcommand" and the generatedalias.ymlhad no PvP section. Fix: - AddedClaimPvpentry toAlias.javawith default alias YAML (commands:[pvp], standalone:[claimpvp]) - Registered thepvpsubcommand inUnifiedClaimCommand.javawith tab completion fortrue/false/confirm- RegisteredClaimPvpstandalone alias so the alias system can manage/claimpvp- Theconfig_pvp_toggleCost*gate remains — admins must opt in by settingClaims.PvPToggle.Claim.Enabled: true(or Subdivision) inconfig.ymlStartup console output is now a single log line
The startup header was previously split into individualsendMessage()calls per line, producing separate timestamps. It now sends the entire block as one call, keeping the console log clean.Features
Malay (ms_MY) locale support
The existingmessages_ms_MY.ymlfile was not registered inMessageLocalization.BUNDLED_LOCALE_FILESorSUPPORTED_LOCALE_CODES. It is now active. Players and servers withconfig_locale: ms_MYwill receive localized messages including the new startup strings.Per-locale startup console messages
Four new message keys were added toMessages.java: | Key | English default | |---|---| |AuthorTag|&7by castledking, RoboMWM and BigScary| |PluginTag|&6The self-service anti-griefing plugin for Minecraft servers &b- Now with full 3D subdivisions| |StartupDetails|&fStartup details: {0}| |BootFinished|&7Boot finished in: &a{0}| The startup header instartups.txtwas redesigned around these messages. Instead of hardcoding locale-specific text in eachen1[]/es1[]/pt1[]block, the file now contains only the locale-agnostic ASCII art (p1/p2/p3) with a single${startup}placeholder. The combined startup block — author, plugin tag, details header, and boot time — is built at runtime from the configured locale's translations. This means all 13 supported locales now have localized startup output: | File | Language | |---|---| |messages_en.yml| English | |messages_es.yml| Spanish | |messages_pt_BR.yml| Portuguese (Brazil) | |messages_fr_FR.yml| French | |messages_de_DE.yml| German | |messages_ru_RU.yml| Russian | |messages_zh_CN.yml| Chinese (Simplified) | |messages_ja_JP.yml| Japanese | |messages_ms_MY.yml| Malay | |messages_pl_PL.yml| Polish | |messages_tr_TR.yml| Turkish | |messages_uk_UA.yml| Ukrainian | |messages_en_PT.yml| English (Pirate) | Adding or customizing startup text for any locale is now a one-line change in the correspondingmessages_XX.yml— no need to editstartups.txtor theStartupHeader.javacode.Technical changes
-Alias.java: AddedClaimPvpenum entry with YAML defaults and subcommand arguments -UnifiedClaimCommand.java: Registeredpvpsubcommand, standalone alias,handlePvp()delegating toplugin.handleClaimPvpCommand(), andcreatePvpTabExecutor()with tab completion -MessageLocalization.java: Addedmessages_ms_MY.ymltoBUNDLED_LOCALE_FILESandms_MYtoSUPPORTED_LOCALE_CODES-Messages.java: AddedAuthorTag,PluginTag,StartupDetails,BootFinishedwith docs -StartupHeader.java: Rewrote to build${startup}from locale messages; removed${details}/${startup.time}/${LANG_CODE}replacements (now part of the combined block); added locale-fallback-to-any-entry for p1/p2/p3; removedCOL_WIDTHandformatLine/paddead code -startups.txt: Stripped 9 locale-specific entries (en1-3, es1-3, pt1-3); only p1/p2/p3 remain with${startup}placeholder -messages_XX.yml(all 13 locales + root): AddedAuthorTag,PluginTag,StartupDetails,BootFinishedwith localized translations -GriefPrevention.java:displayEnabledHeader()sends one combinedsendMessage()instead of splitting by newline18.2.2GriefPrevention3D v18.2.2Jul 2, 2026 GriefPrevention3D v18.2.2
Wiki: https://github.com/castledking/GriefPrevention3D/wikiFeatures
PvP can now be toggled per claim and subdivision
Added a new/claim pvpcommand that allows claim owners to enable or disable PvP inside their claims. The command works in both top-level claims and subdivisions, allowing different PvP rules for individual subdivisions if desired.
A standalone alias is also available:/claim pvp <true|false> confirm
Like/claimpvp <true|false> confirm/abandonclaim, the command requires aconfirmsuffix before making any changes.Configurable claim and subdivision support
PvP toggling is disabled by default and can be enabled independently for main claims and subdivisions.
Each scope has its own configurable economy cost, allowing servers to charge different prices (or no price at all) for claim and subdivision PvP changes.Claims: PvPToggle: Claim: Enabled: true Price: 0.0 Subdivision: Enabled: true Price: 0.0 DefaultState: INHERITSubdivision inheritance
New subdivisions can either inherit their parent claim's current PvP state or always use a configured default. `INHERIT` (default) - New subdivisions copy the parent claim's current PvP state. - Existing subdivisions are unaffected if the parent is changed later. `DEFAULT` - Every new subdivision starts with the configured default PvP state regardless of its parent.Economy integration
If a toggle price greater than0is configured: - Requires Vault and a supported economy plugin. - Players must have enough money before confirming. - Payment is only taken after confirmation. - Clear error messages are shown if payment fails.Persistence
The PvP state is persisted across server restarts in both flatfile and database storage.Alias system support
The/claim pvpsubcommand is fully integrated with the alias system: - Available as/claim pvpthrough the unified command handler - Standalone/claimpvpcommand can be disabled viastandalone: falsein alias.yml - Tab completion support fortrue/falseargumentsTechnical changes
- AddedClaim.pvpEnabledfield to store per-claim PvP state (default:true) - Added configurable PvP toggle settings underClaims.PvPTogglein config.yml - AddedhandlePvpCommand()for unified command handling - Registered/claim pvpsubcommand in the unified command handler - Added standalone/claimpvpcommand in plugin.yml - Added Vault economy integration with balance checks and withdrawals - Addedpvpenabledcolumn to database schema (schema version 10) - AddedPvP Enabledkey to flatfile YAML serialization - Added pvpEnabled loading in both flatfile and database storage - Updated alias.yml with/claim pvpsubcommand and/claimpvpstandalone - Added "merge" option to/claim modein alias.yml documentation - Updated wiki documentation (Commands.md, Key-Features.md, Configuration.md)18.2.1GriefPrevention3D v18.2.1Jul 1, 2026 GriefPrevention3D v18.2.1
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Fixes
Fixed a bug where a player's claims could appear duplicated in/claimlistno longer shows duplicate claims; claim blocks no longer go negative/claimlistand their available claim blocks would drift negative. The issue affected players after logout or server restart (whenever theirPlayerDatawas freshly created). Root cause:DataStore.addClaim()added the claim to the globalthis.claimslist first, then calledownerData.getClaims(). When the player'sPlayerDatawas newly created (claims vector == null),getClaims()lazy-initialized by scanningthis.claims— finding the same claim — then the caller added it a second time. Each duplicate causedgetRemainingClaimBlocks()to subtract the claim's area twice, and/claimlistshowed the claim twice. The same bug existed inchangeClaimOwner()(claim transfer). Fix: Guard both.add()calls with acontains()check so a claim is never double-added to the owner's vector after lazy init already picked it up. -DataStore.java:addClaim()andchangeClaimOwner()now check!ownerClaims.contains(claim)before adding.18.2.0GriefPrevention3D v18.2.0Jul 1, 2026 GriefPrevention3D v18.2.0
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Features
DatabaseDataStore now matches FlatFileDataStore feature-for-feature
DatabaseDataStorewas missing three persisted fields thatFlatFileDataStorehas supported for some time. Database users will now get identical behaviour. #### 3D claims (is3d) Theis3dboolean is now persisted in thegriefprevention_claimdatatable. Claims created with 3D enabled (subdivisions that respect Y boundaries) will correctly reload after a restart. - Schema migration v7:ALTER TABLE griefprevention_claimdata ADD COLUMN IF NOT EXISTS is3d BOOLEAN DEFAULT 0-DatabaseDataStore.java: passesis3dfromResultSettonew Claim(…)instead of hardcodingfalse#### Shaped claims (shapecorners) Shaped claim geometry (non-rectangular orthogonal polygons) is now serialized to ashapecorners TEXTcolumn as semicolon-delimitedx,zpairs. Existing rectangular claims are unaffected. - Schema migration v8:ALTER TABLE griefprevention_claimdata ADD COLUMN IF NOT EXISTS shapecorners TEXT DEFAULT ''-DatabaseDataStore.java:serializeCornersForDb()/parseCornersFromDb()helpers convert betweenList<OrthogonalPoint2i>and the DB text format - Reads are passed toclaim.setShapedCorners()on load #### Modified date (modifieddate) Each claim's last-modified timestamp is stored as aBIGINT(epoch millis). On first save after migration, existing claims without a timestamp will get the current time. - Schema migration v9:ALTER TABLE griefprevention_claimdata ADD COLUMN IF NOT EXISTS modifieddate BIGINT DEFAULT 0-DatabaseDataStore.java:claim.modifiedDateis set frommodifieddatecolumn on load (when > 0) and written on every saveTechnical details
| Schema version | What changed | |---|---| | 7 | Addedgriefprevention_claimdata.is3d| | 8 | Addedgriefprevention_claimdata.shapecorners| | 9 | Addedgriefprevention_claimdata.modifieddate| | 10 | CurrentlatestSchemaVersion| All migrations useALTER TABLE … ADD COLUMN IF NOT EXISTS— zero-touch upgrade for existing database users.18.1.10GriefPrevention3D v18.1.10Jun 29, 2026 GriefPrevention3D v18.1.10
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Fixes
Locale resolution no longer falls back to
Fixed a bug where players with a standard English client locale (en_PTfor English playersen_US,en_GB) could receive messages in Pirate Speak (en_PT) instead of plain English. Root cause: The per-player locale resolver's prefix-matching fallback iterated over aHashMapand returned the first key sharing the same 2-letter language prefix. Since bothenanden_PTstart withen, players whose client locale didn't exactly match a loaded locale could non-deterministically receive pirate speak. Fix: The prefix fallback now prefers the exact base locale code (en) over variants (en_PT). A variant is only used when no exact base match exists. English-speaking players will always geten, anden_PTis only selected when the player's client locale is explicitlyen_PT. -DataStore.java:resolvePlayerLocale()prefix loop now tracks exact-base and variant matches separately, returning the exact base first.18.1.9GriefPrevention3D v18.1.9Jun 29, 2026 GriefPrevention3D v18.1.9
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)New Features
9 New Locale Files
Eight new languages added, expanding from 3 to 12 supported locales: | Locale | Language | | ------ | -------- | |fr_FR| French | |de_DE| German | |ru_RU| Russian | |zh_CN| Chinese (Simplified) | |ja_JP| Japanese | |pl_PL| Polish | |tr_TR| Turkish | |uk_UA| Ukrainian | |en_PT| English (Pirate Speak) | Per-player locale will now automatically match the user's Minecraft client language setting for all new locales. All locale files are bundled — no manual file copying required.
Allium Integration for Tab Completion
When the [Allium](https://github.com/castledking/Allium) plugin (with PartyManager) is installed and enabled, tab completions for player names now use Allium's visibility-aware list instead of Bukkit's raw online player list. This means: - Genuinely vanished players are excluded from tab completion - Distance-hidden players (in party by distance) are still included - Falls back to default Bukkit behavior when Allium is absent or disabled Implemented via reflection — zero hard dependency on Allium.Manage-Permission Subdivision Creation
Players with Manage permission on a claim can now create subdivisions inside it, even without Edit permission. This lets server owners grant subdivision management to trusted players without giving them full build/edit rights over the parent claim. - Works with shovel right-click (bothClaimToolDispatcherandPlayerEventHandlerpaths) - The creating player is automatically added as a manager of the new subdivision so they can further subdivide or manage permissions (cascading trust) - Subdivision visualization now correctly draws the initial zone marker for non-3D subdivisionsFixes
- Missing visualization on non-3D subdivision start: Fixed a bug where starting a subdivision in normal (2D) mode would not show the initial block visualization18.1.8GriefPrevention3D v18.1.8Jun 28, 2026 GriefPrevention3D v18.1.8
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)New Features
Per-Player Locale
Players now receive messages in their own language based on their Minecraft client locale — no administrator effort required. Enabled by default withPerPlayerLocale: truein config.yml: - Spanish client locale (es_*) → Spanish messages - Portuguese client locale (pt_*) → Brazilian Portuguese messages - All other locales → server's configured language (GriefPrevention.Locale, defaulten) - Console output always uses the server's configured language No additional locale files need to be copied — the plugin bundles all supported translations (en,es,pt_BR). Disable withPerPlayerLocale: falseto revert to the old behavior where every player sees the same language.Plugin Rename to GriefPrevention3D
- Plugin name changed fromGriefPreventiontoGriefPrevention3Dand JAR renamed accordingly. - Addedprovides: [GriefPrevention]so servers with plugins depending on the old name continue to work.Fixes
- Self-intersection false positives for C/notch/L shaped claims: Polygon validation now passes known polygon corners to intersection detection so legitimate vertex touches (where boundary segments share a corner on the same axis line) are not flagged as self-intersections. This allows valid orthogonal shapes like C, notch, and L profiles that were previously rejected.18.1.7GriefPrevention3D v18.1.7Jun 26, 2026 GriefPrevention3D v18.1.7
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Highlights
- Cross-Claim Shaped Merge — Use/shapedclaimsto reshape your claim and merge it into a neighboring claim. Click the boundary of your claim, draw a path that overlaps the target claim, and close the path. The tool handles the merge automatically — overlapping land is claimed, disconnected components are bridged with a Manhattan path, and the target claim is deleted. - `/mergeclaims` Command — Standalone command that toggles merge mode on your shovel. Visualize nearby claims with a sneak-click, then click the boundary of your target claim to select it. Works with/claim mode mergeas well. - `/claim mode merge` — New merge mode option for the shovel, accessible via/claim mode merge,/mergeclaims, or/shapedclaims(which enters merge mode automatically when drawing cross-claim paths). - Nearby Claim Visualization — Nearby claims are now highlighted with visible borders during shaped edit and merge operations, making it easy to see which claims can be merged into.18.1.6GriefPrevention3D v18.1.6Jun 23, 2026 GriefPrevention3D v18.1.6
Full Release Notes: [v18.1.6.md](https://github.com/castledking/GriefPrevention3D/blob/mas…Highlights
- Minimum Distance Between Claims — New config optionMinimumDistance(default 0 = disabled). When set, players can't create claims within the configured distance of other claims. Conflicting claims are visualized with a CONFLICT_ZONE boundary. - Neighbor Trust — New trust level that lets specific players bypass minimum distance. Use/claim trust <player> neighboror/neighbortrust <player>. Toggle per-claim allow-all with/claim distance toggle. - Auto-Neighbor Trust — Existing claims too close together automatically grant neighbor trust to each other. Auto-removed when claims are abandoned. - Granular Permissions — 27 individual permissions (e.g.griefprevention.neighbortrust,griefprevention.checkclaimdistance) now available undergriefprevention.claims. All default totruevia parent permission. - New Commands —/claim distance check(visualize nearby claims),/claim distance toggle(per-claim bypass),/neighbortrust(alias:/distancetrust). - Translations — Spanish (messages_es.yml) and Portuguese-BR (messages_pt_BR.yml) updated with all new messages.18.1.5GriefPrevention3D v18.1.5Jun 19, 2026 GriefPrevention3D v18.1.5
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Fixes
- Startup banner on pre-1.16 servers: Replaced all hex color codes (&#RRGGBB) instartups.txtheaders and detail lines with legacy Minecraft color codes (&a,&c,&7,&6, etc.) so the banner displays correctly on servers before 1.16 where§xis not supported. - Claim selection session support added for `/transferclaim`, `/checkclaimexpiry`, `/restrictsubclaim`: These commands now respect an active claim resize/selection session, targeting the selected claim instead of the claim at the player's location. [View Docs](https://github.com/castledking/GriefPrevention3D/wiki/Key… - IncompatibleClassChangeError on pre-1.16 servers: Wrappedplayer.getOpenInventory()call in try-catch forIncompatibleClassChangeErrorsinceInventoryViewis a class (not interface) before 1.16. - Add Player to SaveTrappedPlayerEvent (#2617): Merged upstream commit that adds the trappedPlayerreference toSaveTrappedPlayerEventfor downstream API consumers.18.1.4GriefPrevention3D v18.1.4Jun 18, 2026 GriefPrevention3D v18.1.4
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Fixes
YAML string escaping in messages_en.yml
Fixed incorrect YAML quoting acrossmessages_en.yml. Strings using double quotes with embedded literal quotes ("...\"...\"...") were replaced with single-quoted strings and proper apostrophe escaping (''`). This eliminates YAML parser warnings and ensures message text renders correctly. Example fix:# Before (double-quoted with escaped quotes) NoDamageClaimedEntity: "That belongs to {0}." NoDeletePermission: "You don't have permission to delete claims." # After (single-quoted, internal quotes escaped with '') NoDamageClaimedEntity: 'That belongs to {0}.' NoDeletePermission: 'You don''t have permission to delete claims.'MessageLocalization package relocation
MessageLocalization.javamoved fromme.thiagorigonatti.griefprevention.utiltome.ryanhamshire.GriefPrevention, removing stale imports forInputStream,Properties,StandardCharsets, andList. The locale normalization utility (normalizeLocale) and language folder initializer (ensureLanguageFiles) now live in the main package, consistent with the rest of the localization loading inDataStore.loadMessages().Features
Sulfur cube claim protection (Minecraft 26.2+)
Added full claim-based protection for the new Sulfur Cube mob introduced in Minecraft 26.2 "Chaos Cubed". Since sulfur cubes use a unique physics-based push mechanic (not standard entity damage events), two intercept points are required: Punch (left-click) protection —SulfurCubeHandler.java- Listens forPlayerAnimationEvent(ARM_SWING) and raycasts forSULFUR_CUBEentities in the player's line of sight - Checks Build permission in the claim at the cube's location - If denied, the push is undone by teleporting the cube back to its original position and resetting velocity on the next tick - Sends existingNoDamageClaimedEntitymessage - Handles both survival (3-block) and creative (5-block) reach distances Right-click protection —PlayerEventHandler.onPlayerInteractEntity- Blocks block insert/swap/retrieve interactions on sulfur cubes inside claims without Container permission - Gated behindconfig_claims_preventTheft, consistent with Animals/Fish/CopperGolem protection - Uses the sameNoDamageClaimedEntity+IgnoreClaimsAdvertisementmessage pattern Version compatibility: No version detection needed. All checks useEntityType.name().equals("SULFUR_CUBE")string comparison. On pre-26.2 servers, no entity will match — the handlers are no-ops.Compatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.2.x | | Minimum Java | Java 8 | | Bukkit API Target | 1.13 |18.1.3GriefPrevention3D v18.1.3Jun 16, 2026 GriefPrevention3D v18.1.3
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Features
Locale-based message localization
Messages are now loaded from YAML files based on theGriefPrevention.Localeconfig setting, replacing the singlemessages.ymlapproach. File layout: -GriefPreventionData/messages_{locale}.yml— active locale files (e.g.,messages_en.yml,messages_es.yml,messages_pt_BR.yml) -GriefPreventionData/Lang/— reference copies extracted from JAR on every reload (users copy from here) -GriefPreventionData/messages.yml— legacy file, still supported as fallback Priority order: 1.messages_{locale}.ymlmatchingconfig_locale— respects user's locale setting 2.messages.yml— legacy fallback for migrated servers 3. Auto-detect — scans for anymessages_*.ymlif config locale file is missing 4. Extract from JAR — creates the file automatically if nothing exists Auto-detection: Ifconfig_localeis set toenbut onlymessages_es.ymlexists, the plugin auto-switches toesand logs:
Key merging: On every startup, missing keys from the JAR bundled version are merged into the user's locale file and saved, so new messages are automatically available after JAR updates.Locale 'en' didn't match provided messages_es.yml. Auto-switched to 'es'Startup header with localized details
The server startup header now displays localized detail lines with consistent two-column alignment:
- Detail block generated in code viaPlatform: Paper 26.1.2 3D Subdivisions: ON 3D Admin Claims: ON Nested Claims: OFF Shaped Claims: OFF Locale: es Messages loaded: 276 Storage: File Claims Loaded: 0${details}placeholder — consistent formatting across all languages -TextColorutility consolidates$/&color codes and&#RRGGBB/#RRGGBBhex to Minecraft legacy format -PlatformDetection.getServerVersion()shows actual server platform (e.g., "Paper 26.1.2") instead of boolean ON/OFF - Startup header locale matchesconfig_locale(with fallback:pt_BR→pt)MessagesLoaded message
NewMessagesLoadedenum constant outputs localized "Messages loaded: N" in the startup details via${locale.info}placeholder.Claim expiration permissions
Two new permissions added toplugin.yml: -griefprevention.checkclaimexpiry— allows players to check claim expiration status -griefprevention.dontexpire— prevents a player's claims from expiringCompatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 8 | | Bukkit API Target | 1.13 |Migration
No data migration is required. Existingmessages.ymlfiles continue to work as legacy fallback. To use localized messages, copymessages_{locale}.ymlfromGriefPreventionData/Lang/toGriefPreventionData/and setGriefPrevention.Localein config.yml.18.1.2GriefPrevention3D v18.1.2Jun 10, 2026 GriefPrevention3D v18.1.2
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Feature
Permissiontrust users can now toggle claim subdivision restrictions
Previously, only the claim owner could use/restrictsubclaimon the main claim to toggle whether new subdivisions inherit permissions by default. Now, players withManagetrust (granted via/permissiontrust) can also toggle this flag. Before: The command checked only for owner UUID match or thegriefprevention.adminclaimspermission. After: The command also checks forManagetrust level viaclaim.checkPermission(player, ClaimPermission.Manage, null), which grants access to: - The claim owner (implicitly) - Players given/permissiontrustby the owner - Players with thegriefprevention.deleteclaimsbypass permission The other claim flag commands (/claimexplosions,/witherexplosions) already required onlyBuildtrust, whichManagegrants — so those were already accessible to permissiontrust users without changes.Compatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 8 | | Bukkit API Target | 1.13 |Migration
No data migration is required.18.1.1GriefPrevention3D v18.1.1Jun 8, 2026 GriefPrevention3D v18.1.1
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki) Thanks to [@thiagorigonatti](https://github.com/thiagorigonatti) for [fixing this issue](https://github.com/thiagorigonatti/GriefPrevention/commit…Upstream Issue Fixes
Chest force-rotation near claim borders
When placing a chest near a claim border, the plugin's chest connection logic could select a neighboring chest as a valid connection target based solely on claim ownership, without checking whether the two chests could naturally form a double chest in vanilla Minecraft. This caused the plugin to force-rotate the existing chest's facing direction to match the placed chest — producing a visual and functional state that would never occur naturally. Before: The plugin calledsetFacing()on the neighboring chest, rotating it to match the placed chest even when the neighbor was oriented in a different direction. After: The plugin: - Only considers a neighboring chest as a valid connection target if both chests face the same direction (matching vanilla behavior). - Verifies that both chests can connect on the relevant faces before establishing a double chest. - Resets the placed chest toSINGLEbefore reconnecting, preventing stale connection state. - Removes allsetFacing()calls on existing chests — the plugin no longer force-rotates neighbors.Compatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 8 | | Bukkit API Target | 1.13 |Migration
No data migration is required.See Also
- [Fix commit](https://github.com/thiagorigonatti/GriefPrevention/commit… by @thiagorigonatti18.1.0GriefPrevention3D v18.1.0Jun 8, 2026 GriefPrevention3D v18.1.0
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki) Thanks to [@thiagorigonatti](https://github.com/thiagorigonatti) for [fixing this issue](https://github.com/GriefPrevention/GriefPrevention/issues…Upstream Issue Fixes
Inconsistent chest connection choice near claim borders (
When placing a chest near a claim border with two possible single chest neighbors (one inside the claim and one outside), Minecraft's natural double-chest connection priority sometimes chose the wrong side, resulting in a double chest that crossed the claim boundary. Before: The plugin detected the cross-claim connection and forcibly split both chests to#2611)SINGLE, which could break valid connections and produce inconsistent behavior depending on placement direction. After: The plugin: - Detects which side Minecraft already connected to and checks whether that connection crosses a claim boundary. - If the connected side is denied but another valid single chest exists inside the same claim, the plugin reconnects the placed chest to the allowed side, forming a proper double chest within the claim. - If no valid connection exists, the cross-claim double chest is split cleanly. - Handles normal vs. trapped chest type mismatches and only considers left/right sides for valid connection faces. This also fixes visual ghost blocks on the denied connection side.Compatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 8 | | Bukkit API Target | 1.13 |Migration
No data migration is required.See Also
- [Issue #2611](https://github.com/GriefPrevention/GriefPrevention/issues… — Inconsistent chest connection choice near claim borders - [Fix commit](https://github.com/thiagorigonatti/GriefPrevention/commit… by @thiagorigonatti18.0.10GriefPrevention3D v18.0.10Jun 7, 2026 GriefPrevention3D v18.0.10
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki) Thanks to [@thiagorigonatti](https://github.com/thiagorigonatti) for [fixing these issues](https://github.com/GriefPrevention/GriefPrevention/pull/2…Upstream Issue Fixes
Placing a chest next to a claimed double chest breaks the double chest (
Before: Placing a single chest outside a claim adjacent to a double chest fully inside the claim would forcibly split the double chest into two singles — even though no cross-claim double chest was actually formed. After: The double chest is left untouched. Only adjacent single chests are candidates for the cross-claim split logic; existing double chests inside the claim is preserved. The fix adds a guard that skips neighboring chests that are not#2606)Chest.Type.SINGLE, preventing modifications to existing valid double chests fully inside a claim.Single chests on claim borders can be extended into double chests from outside claims (
Before: A player without build permission could place a chest outside an admin claim next to a claimed single chest, and the claimed chest would be extended into a double chest crossing the claim boundary. This happened because both wilderness and admin claims have a#2609)nullowner ID, and the boundary check treated them as the same owner. After: The chests are kept as separate single chests. AsameClaimOwnerhelper uses reference equality for null claims, ensuring wilderness and admin claims are only considered the "same owner" when both are literally null (both wilderness).Compatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 8 | | Bukkit API Target | 1.13 |Migration
No data migration is required.See Also
- [Issue #2606](https://github.com/GriefPrevention/GriefPrevention/issues… — Double chest split bug - [Issue #2609](https://github.com/GriefPrevention/GriefPrevention/issues… — Admin claim chest boundary bug - [PR #2608](https://github.com/GriefPrevention/GriefPrevention/pull/2… — Double chest split fix by @thiagorigonatti - [PR #2610](https://github.com/GriefPrevention/GriefPrevention/pull/2… — Admin claim owner comparison fix by @thiagorigonatti18.0.9GriefPrevention3D v18.0.9Jun 7, 2026 GriefPrevention3D v18.0.9
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki) Thanks to [@thiagorigonatti](https://github.com/thiagorigonatti) for [fixing this issue](https://github.com/GriefPrevention/GriefPrevention/pull/2…Upstream Issue Fix
Single chests on claim borders can be extended into double chests from outside claims (
Before: A player without build permission could place a chest outside a claim adjacent to a single chest inside the claim, and the claimed chest would be extended into a double chest crossing the claim boundary. This was especially exploitable with admin claims: because both wilderness and admin claims have a#2609)nullowner ID, the boundary check treated them as the same owner and allowed the connection. After: The chests are kept as separate single chests when the placed chest would connect to a chest in a claim where the player does not have permission.What changed (and what v18.0.8 already fixed)
The previous release (v18.0.8, porting [PR #2607](https://github.com/GriefPrevention/GriefPrevention/pull/2… fixed a related but different bug ([#2606](https://github.com/GriefPrevention/GriefPrevention/issues… placing a single chest outside a claim adjacent to a double chest inside the claim would forcibly split the double chest. That fix added a guard to skip splitting when the placed chest remainsChest.Type.SINGLE. However, v18.0.8's port did not include thesameClaimOwnerhelper that PR #2607 also introduced. The method still usedObjects.equals(claimOwner, relativeClaimOwner)to decide whether two chests should be allowed to connect. This comparison returnstruewhen both owners arenull, which means wilderness (nullowner) and admin claims (nullowner`) were incorrectly treated as the same owner — allowing cross-claim double chests to form. v18.0.9 ports the missing piece: asameClaimOwnermethod that uses reference equality for null claims, so that wilderness and admin claims are only considered the "same owner" when they are literally the same object (both null = both wilderness). An admin claim and wilderness are now correctly treated as different, preventing the cross-claim extension.Compatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 8 | | Bukkit API Target | 1.13 |Migration
No data migration is required.See Also
- [Issue #2609](https://github.com/GriefPrevention/GriefPrevention/issues… — Upstream bug report - [PR #2610](https://github.com/GriefPrevention/GriefPrevention/pull/2… — Upstream fix by @thiagorigonatti - [PR #2607](https://github.com/GriefPrevention/GriefPrevention/pull/2… — Previous chest fix (v18.0.8) by @thiagorigonatti - [v18.0.8 release notes](v18.0.8.md) — Previous release18.0.8GriefPrevention3D v18.0.8Jun 7, 2026 GriefPrevention3D v18.0.8
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki) Thanks to [@thiagorigonatti](https://github.com/thiagorigonatti) for [fixing this issue](https://github.com/GriefPrevention/GriefPrevention/pull/2…Upstream Issue Fix
Placing a chest next to a claimed double chest breaks the double chest (
Before: Placing a single chest outside a claim adjacent to a double chest fully inside the claim would forcibly split the double chest into two singles — even though no cross-claim double chest was actually formed. After: The double chest is left untouched when the placed chest remains single. The root cause was in#2606)denyConnectingDoubleChestsAcrossClaimBoundary: it assumed any chest placed near a double chest had connected to it, and unconditionally split both blocks. The fix adds a guard that checks the placed chest's type after placement — if it is stillChest.Type.SINGLE, the method returns early and the neighboring double chest is preserved.Compatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 8 | | Bukkit API Target | 1.13 |Migration
No data migration is required.See Also
- [Issue #2606](https://github.com/GriefPrevention/GriefPrevention/issues… — Upstream bug report - [PR #2607](https://github.com/GriefPrevention/GriefPrevention/pull/2… — Upstream fix by @thiagorigonatti18.0.7GriefPrevention3D v18.0.7Jun 2, 2026 GriefPrevention3D v18.0.7
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Highlights
- Added PlaceholderAPI trust status placeholders — Scoreboards can now show whether a player is trusted in the claim or subdivision they are standing in, and what effective trust level they have there. - Customizable trust-level labels — The text returned by%gp3d_trust_level%is backed bymessages.ymlso servers can localize or restyle the displayed labels.PlaceholderAPI
New Placeholders
| Placeholder | Result | | --- | --- | |%gp3d_is_trusted%|truewhen the player has at least access trust in the claim/subdivision they are standing in, otherwisefalse. | |%gp3d_trust_level%| Returns the player's effective claim trust label for the claim/subdivision they are standing in. |%gp3d_trust_level%uses the innermost claim at the player's location, so 3D subdivisions and regular subdivisions are reported instead of only the top-level claim. Effective trust is resolved from highest to lowest: -Owner-Manager-Builder-Container-Access-UntrustedWhen the player is not standing in any claim,%gp3d_trust_level%returnsUnclaimed.New Messages
The followingmessages.ymlkeys are added automatically on startup or reload:Messages: PlaceholderTrustLevelUnclaimed: "Unclaimed" PlaceholderTrustLevelOwner: "Owner" PlaceholderTrustLevelManager: "Manager" PlaceholderTrustLevelBuilder: "Builder" PlaceholderTrustLevelAccess: "Access" PlaceholderTrustLevelContainer: "Container" PlaceholderTrustLevelUntrusted: "Untrusted"Compatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 8 | | Bukkit API Target | 1.13 |Migration
No data migration is required. Existingmessages.ymlfiles will receive the new trust-level keys automatically the next time GP3D loads messages.18.0.6GriefPrevention3D v18.0.6May 29, 2026 GriefPrevention3D v18.0.6
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Highlights
- Java 8 Bytecode — The plugin now compiles to Java 8 bytecode (class version 52.0), allowing it to load on servers running Java 8. This resolvesUnsupportedClassVersionErroron 1.8.8 servers that cannot upgrade beyond Java 8.Java 8 Migration
- Replaced allList.of()/List.of(a)/List.of(a, b, c)withCollections.emptyList()/Collections.singletonList()/Arrays.asList()- Replaced allSet.of()/Set.of(a)/Set.of(a, b)withCollections.emptySet()/Collections.singleton()/Collections.unmodifiableSet(new HashSet<>(Arrays.asList(...)))- Replaced allMap.of()/Map.of(k, v)withCollections.emptyMap()/Collections.singletonMap()- Replaced allMap.copyOf()andList.copyOf()withCollections.unmodifiableMap(new HashMap<>(...))andCollections.unmodifiableList(new ArrayList<>(...))- ReplacedString.isBlank()withCompat.isBlank()(trim + isEmpty) - ReplacedString.repeat(n)withCompat.repeat()(StringBuilder loop) - ReplacedFiles.writeString()andFiles.readString()withFiles.write()/Files.readAllBytes()+ String constructor - ReplacedFileReader(File, Charset)withInputStreamReader(new FileInputStream(file), charset)- Replacedvarwith explicit types - Replaced@Deprecated(since = ...)/@Deprecated(forRemoval = true, ...)with plain@Deprecated- CreatedCompatutility class (com.griefprevention.compat.Compat) forisBlank(),repeat()Compatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 8 | | Bukkit API Target | 1.13 |Migration
No data migration is required. Existing claims, configs, and player data remain compatible.18.0.5GriefPrevention3D v18.0.5May 27, 2026 GriefPrevention3D v18.0.5
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Highlights
- 1.8.8 Runtime Error Fixes — Fixed several runtime errors that occurred when running the plugin on Minecraft 1.8.8 servers with Java 11+. - Expanded PvP Configuration — Added config options to allow container access and respawn anchor usage during PvP combat. - AFK Accrual Bypass Permission — Added permission to bypass AFK checks for claim block accrual. - Claim Tool Bypass Permission — Added permission to allow creating claims via command without holding the modification tool.1.8.8 Compatibility
- FixedNoSuchMethodError: EntityExplodeEvent.getExplosionResult()— Added compatibility methods inCompatUtilto safely access explosion results, which don't exist in 1.8.8. - FixedNoClassDefFoundError: org.bukkit.event.block.BlockExplodeEvent— Created separateBlockExplodeEventHandlerwith conditional registration, as this event doesn't exist in 1.8.8 Spigot. - FixedNoClassDefFoundError: org.bukkit.event.entity.ItemMergeEvent— Created separateItemMergeEventHandlerwith conditional registration, as this event doesn't exist in 1.8.8 Spigot. - FixedNoSuchMethodError: PlayerInventory.getItemInMainHand()— Replaced direct calls withCompatUtil.getItemInMainHand()throughout the codebase for 1.8.8 compatibility.Netty Compatibility
- Note: PaperSpigot 1.8.8 has incompatible Netty epoll transport with Java 11+. Users experiencing "Unable to access address of buffer" errors should: - Switch to regular Spigot 1.8.8 (recommended), or - Add-Dio.netty.transport.noNative=trueJVM flag (may not work on all PaperSpigot builds)New Config Options
Two new options underGriefPrevention.PvPinconfig.yml: | Key | Default | Effect | | --- | --- | --- | |AllowContainerAccess|false| Whentrue, players can access containers (chests, shulker boxes, etc.) during PvP combat. | |AllowRespawnAnchor|false| Whentrue, players can use respawn anchors during PvP combat. | Existing servers will pick up the defaults on first load and have the keys persisted toconfig.ymlautomatically.New Permissions
| Permission | Default | Effect | | --- | --- | --- | |griefprevention.accruals.afkbypass|op| Bypasses the AFK check for claim block accrual. Players with this permission will accrue claim blocks even if they are idle. | |griefprevention.accruals|true| Controls whether a player receives claim blocks at the configured hourly rate when not AFK. Negating this permission disables accruals entirely. | |griefprevention.createclaims.toolbypass|true| Bypasses the need to hold the modification tool when creating claims via command. |Compatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 11 | | Bukkit API Target | 1.13 |Migration
No data migration is required. Existing claims, configs, and player data remain compatible.18.0.4GriefPrevention3D v18.0.4May 27, 2026 GriefPrevention3D v18.0.4
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Highlights
- Fixed a post-death item pickup regression — Players who respawned with PvP fresh-spawn immunity could sometimes be unable to pick up their own items until they left and rejoined.Bugfixes
Item Pickup
- FixedEntityPickupItemEventhandling so fresh-spawn PvP immunity ends when an immune player picks up an item instead of cancelling the pickup. - This resolves a deadlock where an empty-inventory player was expected to pick up an item to lose immunity, but the pickup itself was blocked by that same immunity state. - Hardened locked death-drop ownership checks to compare player UUIDs directly, avoiding server-version differences inPlayer/OfflinePlayerequality behavior.Affected Config
This regression only applied when PvP fresh-spawn protection was active:
No config migration is required.GriefPrevention: PvP: ProtectFreshSpawns: trueCompatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 11 | | Bukkit API Target | 1.13 |Migration
No data migration is required. Existing claims, configs, and player data remain compatible.18.0.3GriefPrevention3D v18.0.3May 25, 2026 GriefPrevention3D v18.0.3
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki)Highlights
- Public visualization API surface — Ported the boundary-visualization extension points from thefeature/gpapiaddon-workspacebranch so addons can drive their own claim visuals without reflection. - Improved 3D claim raytrace logic — Fixed a regression where the second click of a 3D subclaim resize could snap back to an existing claim corner, causing the resize to no-op or collapse the claim into a 1-block sliver. - New claim-selection sessions — Selecting a claim with the modification tool can now keep that claim as the implicit target for follow-up commands (/trust,/abandonclaim, etc.) until the visualization clears. - Configurable selected-claim messaging — Optional alternate selection messages so addons can present richer "claim selected" UX without overridingResizeStart.Visualization API
Thecom.griefprevention.visualizationandcom.griefprevention.eventspackages are now part of the supported public API. Addons can: - Listen forBoundaryVisualizationEventto mutate the boundary set, swap theVisualizationProvider, or short-circuit drawing entirely. - ImplementVisualizationProvider/VisualizationStyleto render claims using their own block palettes, particle effects, glow displays, or packet pipelines. - CallBoundaryVisualization.visualizeClaim(...),visualizeArea(...), andvisualizeNearbyClaims(...)directly to trigger the same visuals GP uses internally. - Reuse the built-inFakeBlockVisualization,LegacyFakeBlockVisualization(1.8.8),AntiCheatCompatVisualization, andGlowingVisualization(1.19.3+) implementations. SeePublic Api.txtfor the full surface and code examples.Bugfixes
Claim Tools
- FixedClaimToolDispatcher.handleModificationToolrunning the 3D-corner snap raycast unconditionally on the second click of a resize. The snap is now gated byClaimToolInteractionState.shouldAttempt3DCornerSelection, mirroring thePlayerEventHandlerpath. - This resolves the report where dragging a 3D subclaim corner down through transparent blocks (e.g. leaves) did nothing, or occasionally collapsed the claim to a 1-block-thin layer. - FetchesPlayerDataonce before the corner raycast so the gate reflects the actual resize/subdivide state.New Config Options
Two new options underGriefPrevention.Claimsinconfig.yml: | Key | Default | Effect | | --- | --- | --- | |UseClaimSelectSessions|true| When you start resizing a claim with the modification tool, that claim becomes the implicit target for subsequent commands until the visualization reverts. | |UseClaimSelectedMessages|false| Whentrue(and sessions are enabled), replaces the legacyResizeStartinstruction with the contextualClaimSelected/ClaimSelectedTopLevel/SubdivisionSelectedmessages. | Existing servers will pick up the defaults on first load and have the keys persisted toconfig.ymlautomatically.Compatibility
| Category | Support | | ------------------ | ------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 11 | | Bukkit API Target | 1.13 |Migration
No data migration is required. Existing claims, configs, and player data remain compatible. If you want the new selection behavior off, set:GriefPrevention: Claims: UseClaimSelectSessions: false UseClaimSelectedMessages: falsePairing
Pairs with GPExpansion v1.1.1 for claim block accrual profile controls. Visualization addons targeting the new public surface should depend onGriefPrevention3D >= 18.0.3.18.0.2GriefPrevention3D v18.0.2May 25, 2026 GriefPrevention3D v18.0.2
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- Fixed golden shovel grass-pathing regression — Right-clicking close grass blocks with the claim modification tool no longer turns them into dirt/grass path blocks while selecting claim corners. - Fixed path-block visualization snapping — Dirt path and legacy grass path blocks are no longer treated as transparent for boundary visualization placement. - Version sync — Updated release metadata to18.0.2in bothpom.xmlandgradle.properties.Fixes
Claim Tools
- Fixed a regression introduced during legacy compatibility work where claim-tool right-clicks could still trigger the shovel's vanilla block interaction. - Claim creation, resizing, subdivision editing, and claim inspection clicks now consume the right-click before Bukkit applies item behavior to the target block. - This prevents accidental terrain changes when selecting claim corners on grass blocks at close range.Visualizations
- Fixed Y-snapped visualizations treatingDIRT_PATHand legacyGRASS_PATHas transparent. - Boundary markers now snap above path blocks instead of dropping below them. - The fix applies to standard, legacy, anti-cheat, and glow plus anti-cheat visualization paths.Compatibility
| Category | Support | | ------------------ | --------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 11 | | Bukkit API Target | 1.13 |Migration
No data migration is required. Existing claims, configs, and player data remain compatible.18.0.1GriefPrevention3D v18.0.1May 24, 2026 GriefPrevention3D v18.0.1
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki?utm…Highlights
Fixed additional 1.8.8 runtime crashes* — Removed more direct references to modern Bukkit enum values from active legacy event paths. Added `/gpdebug`* — Server admins can now toggle debug logging without editing config.yml or running/gpreload. Added release safeguards* — Gradle now fails verification ifgradle.propertiesandpom.xmlversions drift apart. Prepared CurseForge automation* — Release workflows now include an optional CurseForge upload target for the GP3D project.Fixes
Legacy Servers (1.8.8)
* FixedEntityDamageByEntityEventandEntityCombustByEntityEventerrors caused by directAREA_EFFECT_CLOUDenum access. * Fixed related modern entity checks for shulkers, tridents, raiders, vexes, and evoker fangs so they do not crash older Bukkit runtimes. * FixedEntityInteractEventcrop-trample handling on 1.8.8 by supporting the legacySOILmaterial name alongside modernFARMLAND. * Fixed restore-nature player block classification for farmland across legacy and modern material names.Admin Tools
* Added/gpdebug. Added `griefprevention.debug`, defaulting to operators and included under `griefprevention.admin.`. */gpdebugtogglesGriefPrevention.Abridged Logs.Included Entry Types.Debugimmediately and persists it to config.yml. */gpdebug onand/gpdebug offare supported for explicit state changes.Release Workflow
* Added a GradlecheckPomVersionverification task to protect addon compatibility metadata inpom.xml. * WiredcheckPomVersioninto Gradle's normalchecklifecycle. * Added CurseForge release automation for project1552252. * Added workflow inputrun_curseforgeso CurseForge publishing can be enabled or disabled during manual release runs.Compatibility
| Category | Support | | ------------------ | -------------- | | Minecraft Versions | 1.8.8 -> 26.1.x | | Minimum Java | Java 11 | | Bukkit API Target | 1.13 |Migration
No data migration is required. Existing claims, configs, and player data remain compatible.18.0GriefPrevention3D v18.0May 24, 2026 GriefPrevention3D v18.0
Wiki: [GriefPrevention3D Wiki](https://github.com/castledking/GriefPrevention3D/wiki?utm…Highlights
Single build for all supported versions* — Minecraft 1.8.8 through 26.1.x now supported with one Java 11 build. Major legacy compatibility fixes* — Improved claim tool behavior and far-away click handling on older Bukkit/Spigot servers. Improved raycast accuracy* — Fixed water click offset issues and inconsistent targeting across versions. Removed unstable packet injection path* — Disabled legacy Netty interception that could interfere with commands and interactions on 1.8.8.Compatibility
| Category | Support | | ------------------ | -------------- | | Minecraft Versions | 1.8.8 → 26.1.x | | Minimum Java | Java 11 | | Bukkit API Target | 1.13 |Fixes
Legacy Servers (1.8.8–1.12.2)
* Fixed far-away golden shovel/stick interactions. * Fixed duplicate claim creation paths. * Fixed delayed/bursty camera update behavior. * Fixed incorrect claim tool detection with unrelated items. * Removed problematic Netty packet injection behavior.Modern Servers (1.13+)
* Fixed Material API compatibility issues. * Fixed water click offset and fluid raycast inconsistencies. * Refactored Java 21-only features for Java 11 compatibility.Migration
No data migration is required. Existing claims, configs, and player data remain compatible. Recommended: Test v18.0 in a production-clone or staging environment before deploying to a live server, especially on heavily customized or legacy setups.Pairing
Pairs with GPExpansion v1.1.1 for claim block accrual profile controls.Roadmap
* Fabric/Forge ports * Additional compatibility improvements * Raycast and visualization performance optimizations17.5.4GriefPrevention3D v17.5.4May 22, 2026 GriefPrevention3D v17.5.4
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- Restored `ClaimPermission.Inventory` for plugin compatibility - External plugins like BiggerBarrels that referenceClaimPermission.Inventorywill no longer crash withNoSuchFieldError. - Added deprecation notice -Inventoryis now a deprecated alias forContainer; plugin developers should migrate toContainerfor future compatibility.Bug Fixes
The enum constantClaimPermission.Inventorywas removed during previous refactoring work, breaking plugins compiled against older versions of GriefPrevention3D. This release restores it as a deprecated alias pointing toContainer. Plugins affected: - BiggerBarrels (and any plugin referencingClaimPermission.Inventory) The fix ensures backward compatibility while guiding developers toward the newContainerpermission name.Pairing
This release pairs with GPExpansion v1.1.1 for the new claim block accrual profile controls documented at: https://github.com/castledking/GPExpansion/wiki/Claim-Blo…Migration
No data migration required. Existing configs are unchanged. Note for plugin developers: Update your code to useClaimPermission.Containerinstead ofClaimPermission.Inventory. TheInventoryconstant will be removed in a future major release.17.5.3GriefPrevention3D v17.5.3May 21, 2026 GriefPrevention3D v17.5.3
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- Fixed claim resize bug - Resizing claims via/resizeclaimor shovel corner-click no longer incorrectly marks 2D claims as 3D claims. - Fixed visualization issues after resize - Claims now display the correct golden terrain-snapped visualization instead of white wool blocks submerged underground. - Fixed potential claim duplication - The resize operation now correctly preserves the original claim's 3D status, preventing duplicate or overlapping claim entries.Bug Fixes
When we added 3D admin claims and 3D initialize points in previous releases, we introduced a newis3Dparameter to theDataStore.createClaim()method. TheresizeClaim()method was still calling the 12-parameter overload, causing thedryRun=trueflag to be misinterpreted asis3D=true. This meant that resizing any 2D claim would incorrectly mark it as 3D, leading to: - Incorrect visualization (white iron/wool blocks at specific Y levels instead of golden terrain-snapped blocks) - Potential claim duplication or overlapping entries in the chunk cache - Confusion when trying to abandon or reclaim the affected area The fix updatesresizeClaim()to use the correct 13-parameter overload, preserving the original claim's 3D status.Pairing
This release pairs with GPExpansion v1.1.1 for the new claim block accrual profile controls documented at: https://github.com/castledking/GPExpansion/wiki/Claim-Blo…Migration
No data migration required. Existing configs are unchanged. Note for affected claims: If you have claims that were resized while running v17.4.4 through v17.5.2 and are experiencing weird visualization or overlap issues, an admin may need to manually inspect the claims data file to clean up any duplicate entries.17.5.2GriefPrevention3D v17.5.2May 21, 2026 GriefPrevention3D v17.5.2
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- Removed command registration console noise when debug is off - Alias and standalone command setup messages now respect the debug logging setting instead of printing every startup. - Restored legacy claim block command tab completion -/acb,/adjustbonusclaimblocks,/scb, and related legacy commands now complete online player names and amount arguments again. - Lowered the declared Bukkit API version to 1.20 - Paper 1.20.6 no longer rejects the plugin for declaringapi-version: 1.21.Bug Fixes
The unified command registration path was logging every command initialization and standalone registration at normal info level. Those messages are now routed through debug logging, so production consoles stay quiet unless debug logging is enabled. Legacy standalone claim block commands were registered without tab completion metadata after the unified command work. They now provide player-name completion for player-targeted commands and numeric completion for amount arguments. The plugin descriptor now declaresapi-version: "1.20"instead of1.21, allowing the same jar to load on supported 1.20.x servers while still running on newer servers.Pairing
This release pairs with GPExpansion v1.1.1 for the new claim block accrual profile controls documented at: https://github.com/castledking/GPExpansion/wiki/Claim-Blo…Migration
No data migration required. Existing configs are unchanged.17.5.1GriefPrevention3D v17.5.1May 21, 2026 GriefPrevention3D v17.5.1
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- Added configurable `/claim` and `/aclaim` fallbacks -alias.ymlcan now define which subcommand runs when a player executes the root command without arguments, such asfallback: 'help'. - Fixed configurable claim help entries -ClaimHelpEntryandAClaimHelpEntryinmessages.ymlnow control the formatting of each/claim helpand/aclaim helprow. - Allowed messages to be disabled with empty strings - Leaving a message blank now suppresses it instead of sending a visually empty chat line.Bug Fixes
Blank help-related messages are no longer restyled into color-only or newline-only strings during message loading. This lets server owners disable any configured message by setting it to an empty string. The unified claim help renderer now uses theClaimHelpEntryandAClaimHelpEntrymessage templates instead of hardcoding each help row. This allows server owners to change colors, separators, and row formatting frommessages.yml.Configuration
alias.ymlnow supports a root commandfallbackoption:
Leavecommands: claim: fallback: 'help' aclaim: fallback: 'help'fallbackempty to keep the previous built-in root command behavior.Migration
No data migration required. Existingalias.ymlfiles will continue to work; addfallback: 'help'undercommands.claimorcommands.aclaimif you want root commands to open help by default.17.5.0GriefPrevention3D v17.5.0May 20, 2026 GriefPrevention3D v17.5.0
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- Fixed negative claim block balance on `/expandclaim` - Expanding a claim no longer silently bypasses the block-sufficiency check when the player's name lookup returns an unexpected value, which could leave players with a negative block balance.Bug Fix
The block-sufficiency guard inresizeClaimWithCheckscomparedplayer.getName()againstclaim.getOwnerName().getOwnerName()resolves the owner's name through an offline player lookup, which can return"Unknown"or a cached display name that does not exactly match the online player'sgetName(). When the comparison failed, the entire block check was skipped and the resize was allowed to proceed regardless of available blocks — leaving the player with a negative balance after the fact. The check now comparesplayer.getUniqueId()againstclaim.ownerIDdirectly, which is reliable regardless of name resolution state.Migration
No data migration or configuration changes required. Players who ended up with a negative balance will need an admin to restore their blocks via/givepetor/setblocks.17.4.9GriefPrevention3D v17.4.9May 20, 2026 GriefPrevention3D v17.4.9
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- Fixed a resize selection regression - Very small 3D subdivisions and 3D admin claims can be right-clicked with the golden shovel again to start resize selection. - Restored thin claim corner clicks - Claims with a one-block X, Y, or Z dimension no longer silently consume the shovel click without showing the selection message. - Preserved shaped-claim behavior - The fix restores rectangular claim corner handling without changing shaped-claim corner selection.Regression Fix
Recent corner-selection changes regressed resize selection for thin 3D claims. Affected claims could consume the golden shovel right-click without sending the resize/selection message, making them appear impossible to resize. This affected 3D subdivisions and 3D admin claims with any one-block dimension, including1x1x1,1x1x2,1x2x1, and single-layer2x2x1claims. The selection path now recognizes rectangular corners directly, even when the rectangle collapses to a single X or Z coordinate, and shovel targeting resolves visible single-layer markers back to the real claim corner.Technical Changes
- Added regression coverage for one-block X/Z rectangular corner detection. - Kept shaped-claim corner detection on the existing polygon path. - This is not gated byGriefPrevention.Claims.AllowShapedClaims; the affected corner-selection path is shared by normal rectangular claim resizing.Migration
No data migration or configuration changes required.17.4.8GriefPrevention3D v17.4.8May 19, 2026 GriefPrevention3D v17.4.8
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- Fixed WelcomeTask memory leak ([#2483](https://github.com/GriefPrevention/GriefPrevention/issues… — The scheduled welcome task no longer holds a hard reference to thePlayerobject, preventing leakedCraftPlayerinstances when players disconnect before the task runs. - Disable welcome task via config — SettingManualDeliveryDelaySecondsto0or a negative value now skips scheduling the welcome task entirely.WelcomeTask Memory Leak Fix
WelcomeTaskpreviously stored a directPlayerreference. On high-volume servers with a largeManualDeliveryDelaySecondsvalue, every new player who joined and left before the task fired would leave a leakedCraftPlayerin memory until the task eventually ran. The task now stores the player'sUUIDand resolves it viaBukkit.getPlayer()at execution time. If the player is offline, the task exits immediately with no retained references.Disabling the Welcome Task
Servers that don't want the welcome message can now setManualDeliveryDelaySecondsto0(or any negative value) inconfig.ymlto prevent the task from being scheduled at all. Previously, some server operators worked around this by setting extremely high delay values, which caused the leak described above.Migration
No data migration required. ExistingManualDeliveryDelaySecondsvalues continue to work as before. Set to0to disable.17.4.7GriefPrevention3D v17.4.7May 16, 2026 GriefPrevention3D v17.4.7
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- New `INITIALIZE_ZONE_3D` visualization — First-click diamond markers for 3D admin claims and 3D subdivisions now render at the exact clicked Y coordinate instead of snapping to the terrain surface. - Proper visualization pipeline — Replaced a rawsendBlockChangehack with a real visualization type that supports cleanup tracking, glow mode, and event firing.INITIALIZE_ZONE_3D Visualization
3D claims are placed at the exact block the player targets — that's the core difference from 2D claims, which snap to terrain. Previously, the first-click diamond marker didn't respect this: it either usedINITIALIZE_ZONE(which terrain-snaps to the surface) or bypassed the visualization system entirely with a rawsendBlockChange. The newINITIALIZE_ZONE_3Dtype renders the diamond marker at the exact Y of the clicked block. It routes throughdrawRespectingYBoundariesinFakeBlockVisualizationand uses exact placement inGlowingVisualization, consistent with howSUBDIVISION_3DandADMIN_CLAIM_3Dboundary types already work. Both 3D admin claims and 3D subdivisions now use this type for their first-click marker.Migration
No data migration or configuration changes required.17.4.6GriefPrevention3D v17.4.6May 15, 2026 GriefPrevention3D v17.4.6
Wiki: https://github.com/castledking/GriefPrevention3D/wikiBug Fixes
3D Admin Claim Visualization (bottom half)
Fixed 3D admin claim subdivisions rendering with ADMIN_CLAIM_3D visual (pumpkin/glowstone) instead of SUBDIVISION_3D (white/iron) until refreshed. ThedefineBoundaries()method now checksclaim.parent == nullalongsideclaim.isAdminClaim(), so child subdivisions of admin claims inherit the correct visualization type immediately. Also applied the same fix tovisualizeNearbyClaims()for consistency.
FixedvisualizeNearbyClaimsHorizontal Search RadiusDataStore.getNearbyClaims()only checking the player's single chunk (1×1×1 bounding box), ignoring claims in adjacent chunks. Pulled in upstream's 300-block X/Z search radius (location.clone().subtract(150, 0, 150)tolocation.clone().add(150, 0, 150)). 3D admin claims in neighboring chunks are now found during sneak+stick inspection.Vertical Range Filter for 3D Claims in
Added a 16-block vertical range filter so 3D claims far above or below the player are excluded from sneak+stick visualization. 2D claims (full height) are always included. This prevents showing 3D claims hundreds of blocks away while still catching those starting +1 above the target point.visualizeNearbyClaims3D Subdivision Admin Claim Visual on First Render
Fixed a brief window where 3D subdivisions inside admin claims would show with the admin claim visual (ADMIN_CLAIM_3D) until the player refreshed the visualization. ThedefineBoundaries()method now correctly identifies child subdivisions regardless of owner, so the first render is always correct.Admin3D Initialization Visual at Wrong Y
FixedvisualizeArea()rendering the initialization marker at the player's eye Y instead of the clicked block's Y. Added an overload accepting a block-specific Y. Admin3D first/second clicks now usegetTargetBlock()to resolve through replaceable blocks (snow layers), so the marker and claim corners land on the solid block instead.
Changedgriefprevention.extendclaim.toolbypassPermission Defaultgriefprevention.extendclaim.toolbypasspermission default fromfalsetoop. This restores the expected behavior where server operators can extend claims without a modification tool by default.3D Claim
Fixed/extendclaimVertical Extension/extendclaimblocking vertical extension for 3D claims with the "Land claims auto-extend deeper into the ground when you place blocks under them." message. 3D claims can now extend upward (looking up) or downward (looking down) using the command. For 3D subdivisions, the extension is validated to stay within parent claim Y bounds; overlapping another subdivision or exiting parent bounds shows the appropriate error.Pairing
This release should be paired with GPExpansion v1.0.9.Migration
No data migration required. No configuration changes needed.17.4.5GriefPrevention3D v17.4.5May 15, 2026 GriefPrevention3D v17.4.5
Wiki: https://github.com/castledking/GriefPrevention3D/wikiUpstream Merge: Don't block knockback when GP PvP rules are disabled (#2600)
Admins who disable GP PvP rules for a world (to opt out of safe zones, fresh spawn immunity, etc.) but keep world PvP on were seeing knockback silently blocked. GP now skips PvP checks without cancelling the knockback event, matching howEntityDamageHandleralready handles this case. Cherry-picked from upstream GriefPrevention commit75ed5c7. Affected file:KnockbackProtectionHandler.java.Migration
No data migration required. No configuration changes needed.17.4.4GriefPrevention3D v17.4.4May 12, 2026 GriefPrevention3D v17.4.4
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- 3D admin claims — NewAdmin3Dshovel mode creates free, height-bounded administrative claims. Includes/3dadminclaimscommand and/aclaim mode admin3dsubcommand. - Verbose piston feedback — When a piston is broken by a claim boundary, the nearest player with build permission now receives a message explaining where and why, with a conflict-zone visualization of the blocking claim. - Trapped command fixes —handleTrappedCommandbrought to parity with the inline handler: correct check ordering, proper GPFlags destination forwarding, nether/end guard, and silent pending-rescue suppression. - New command aliases — Added/3dsc,/sc3d,/subdivide3d,/3dsubdivide,/adminclaim3d,/adminclaims3d, and others to match the tau fork's alias set.3D Admin Claims
A newAdmin3Dshovel mode lets administrators create free, height-limited claims using exact Y coordinates (not the usual ground-extension offset).Commands
| Command | Aliases | Description | |---------|---------|-------------| |/3dadminclaims|adminclaim3d,adminclaims3d,3dadminclaim| Switch shovel to 3D admin claim mode | |/aclaim mode admin3d| — | Same via unified command | Requires thegriefprevention.adminclaimspermission.Behavior
- Claims created inAdmin3Dmode use the clicked Y coordinates directly as the vertical bounds — no ground-extension offset is applied. - Free to create (no claim blocks consumed) and owner ID is null, making them standard admin claims. - Minimum size and claim block checks are bypassed, identical to regularAdminmode. Affected files:ShovelMode.java,Messages.java,GriefPrevention.java,UnifiedAdminClaimCommand.java,Alias.java,PlayerEventHandler.java,plugin.yml.Verbose Piston Feedback
Previously, when a piston was broken by a claim boundary in precise mode, the player who placed it received no feedback — only the claim owner on the other side was notified viaClaimBoundaryViolationTracker. GP3D now also notifies the piston owner side: the nearest online player with build permission in the piston's claim (or within 32 blocks if the piston is outside any claim) receives: - A warning message: "The piston at x, y, z exploded because it couldn't enter the claim at [location]" - ACONFLICT_ZONEboundary visualization of the claim that blocked the push The existingClaimBoundaryViolationTrackerdedup/burst notifications to the invaded claim's owner are preserved unchanged. Affected file:BlockEventHandler.java,Messages.java.Trapped Command Fix
handleTrappedCommand(used by the unified/claimcommand handler) had several divergences from the inlineonCommandimplementation: - Wrong pending message — sentRescueAbortedMovedwhen/trappedwas already pending; it now silently returns (consistent with tau and the inline handler). - Lost GPFlags destination —SaveTrappedPlayerEventwas fired but its destination was discarded; the destination is now forwarded toPlayerRescueTask. - Missing nether/end guard — rescue is now blocked in the nether and end when no external destination is provided. - Check order —pendingTrappedis now checked before the claim/permission checks, matching the upstream order. - Spurious event cancellation check —SaveTrappedPlayerEventis not cancellable; the deadisCancelled()branch was removed. Affected file:GriefPrevention.java.New Aliases
Added missing aliases to match the tau fork's command set: | Command | New aliases added | |---------|------------------| |3dsubdivideclaims|3dsc,sc3d,subdivide3d,3dsubdivide| |adminclaims|aclaims| |3dadminclaims(new) |adminclaim3d,adminclaims3d,3dadminclaim| |/aclaim modestandalone |3dadminclaims| Affected files:plugin.yml,Alias.java.Migration
No data migration required. The new3dadminclaimscommand and its aliases are registered automatically on server start. No config changes are needed. New permission used (inherits existinggriefprevention.adminclaimsnode — no new node required): -griefprevention.adminclaims— now also gates/3dadminclaimsand/aclaim mode admin3d.17.4.3GriefPrevention3D v17.4.3May 7, 2026 GriefPrevention3D v17.4.3
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- Unified command hardening — Fixed several standalone command edge cases and permission checks. - PlaceholderAPI support — Added a small optional GP3D PlaceholderAPI expansion. - More claim protections — Added protections for animal mounting, entity unleashing, hanging entities, and weaving cobwebs. - QuickShop-Hikari compatibility — Restore-nature now preserves QuickShop shop signs. - Claim expiration exemption — Players with the griefprevention.dontexpire permission are now skipped by inactive-claim cleanup when Vault is installed.Unified Commands
The unified command handler now handles standalone aliases more carefully: - Explicit emptystandalone:lists inalias.ymlnow disable standalone aliases for that subcommand instead of falling back to enum defaults. - Standalone no-argument commands now reject extra arguments instead of forwarding unexpected input. - Standalone commands can now use custom tab completion where needed. - Unified subcommands now check their configured permission before execution. -/shapedclaims,/claim mode shaped,/3dsubdivideclaims, and/claim mode 3dnow consistently enforce their dedicated permissions. Affected files:CommandAliasConfiguration.java,UnifiedCommandHandler.java,UnifiedClaimCommand.java,UnifiedAdminClaimCommand.java,GriefPrevention.java,plugin.yml.PlaceholderAPI
Added optional PlaceholderAPI integration with identifiergp3d. New placeholders: -%gp3d_in_subdivision%—truewhen the player is inside any subdivision. -%gp3d_in_3d_subdivision%—truewhen the player is inside a 3D subdivision. PlaceholderAPI is a soft dependency. The expansion registers automatically when PlaceholderAPI is installed. Affected files:pom.xml,plugin.yml,PlaceholderAPIExpansion.java,GriefPrevention.java.Protection Fixes
Animal mounting requires access trust
Players now need Access trust to mount claimed rideable animals./ignoreclaimsstill bypasses this for administrators. Affected file:PlayerEventHandler.java.Entity unleashing requires container trust
When theft prevention is enabled, players now need Container trust to unleash entities inside claims./ignoreclaimsstill bypasses this for administrators. Affected file:PlayerEventHandler.java.Hanging entity protection
Item frames, paintings, and other hanging entities are now protected from additional edge cases: - physics breaks caused by projectiles or nearby updates while the supporting block still exists - direct non-player damage - player/projectile damage without Build permission - explosion damage events Affected file:EntityEventHandler.java.Weaving cobwebs no longer trip block-change protection
The Weaving potion effect can now create cobwebs from living-entity deaths without being caught by unrelated entity block-change protections. Affected file:EntityEventHandler.java.QuickShop-Hikari Compatibility
Restore-nature now detects QuickShop shop signs by their persistent data key and preserves both: - the shop sign itself - the block supporting the shop sign This prevents GP3D restore-nature operations from silently removing QuickShop shop signs through direct block restoration. Affected files:BlockSnapshot.java,RestoreNatureProcessingTask.java.Claim Expiration Bypass
If Vault is installed, claim expiration now honors: -griefprevention.dontexpirePlayers with that permission are skipped by the inactive-claim cleanup task. Affected files:CleanupUnusedClaimPreTask.java,plugin.yml.Migration
No data migration required. New optional integrations: - Install PlaceholderAPI to use the new%gp3d_*%placeholders. - Install Vault plus a permissions provider to usegriefprevention.dontexpire. New permissions from v17.4.2 remain default-true: -griefprevention.shapedclaims-griefprevention.3dsubdivideclaims17.4.1GriefPrevention3D v17.4.1May 2, 2026 GriefPrevention3D v17.4.1
Wiki: https://github.com/castledking/GriefPrevention3D/wiki This release pulls in fixes for a batch of long-standing upstream GriefPrevention bugs that hadn't been merged in their tracker yet.Upstream Issue Fixes
Workstations no longer treated as theft (
Grindstones, looms, stonecutters, and cartography tables are now usable in claims by players without trust — same as crafting tables. These are pure crafting workstations with no persistent inventory (any items left in them drop to the floor on close), so the PreventTheft path no longer applies to them. Affected file:#2587)PlayerEventHandler.java.TNT-above-sea-level chat spam fixed (
The "TNT will not destroy blocks above sea level" warning is now rate-limited per-player to once every 10 seconds. Map-art builders and large TNT placements no longer flood chat with one message per block. Implementation: a new#2586)tntAboveSeaLevelWarningTimestampfield onPlayerDatagates the message inBlockEventHandler.onBlockPlace.Ender Dragon breath now damages players in PvP-protected claims (
The PvP "lingering potion" handler used to cancel any#2577)AreaEffectClouddamage when the defender was inside a PvP-protected claim. That accidentally included the Ender Dragon's breath attack, which made dragon fights trivial whenever the End island was an admin claim. The handler now only intervenes when the cloud's source is aPlayer. Mob-sourced clouds (the dragon, plus any future mob that produces anAreaEffectCloud) pass through normally. Affected file:EntityDamageHandler.handlePvpDamageByLingeringPotion.Copper trapdoors honor
The trapdoor-locking path now uses a robustLockTrapDoors(#2550)isLockableTrapdoor()helper that checks bothTag.TRAPDOORSand falls back to a_TRAPDOORname suffix match. Copper trapdoors (and any future trapdoor variants) are protected even on Bukkit API versions whereTag.TRAPDOORSdoesn't yet include them. Affected file:PlayerEventHandler.java.Player data corruption on storage read failure (
When the data store (database or flat-file) failed to read a player's record — most commonly a transient MySQL#2589/#666)wait_timeout/EOFException— the failure was silently swallowed and a freshPlayerDatawith default values was returned. On the player's next save, those defaults were written back, permanently destroying the player's accrued and bonus claim blocks. This has been a long-standing upstream bug that resets players to zero blocks even when their actual claims are still on disk. GP3D now flags failed reads via a newloadFailedFromStoragefield onPlayerData. BothDatabaseDataStoreandFlatFileDataStoreset this flag when a read genuinely fails (vs. legitimately returning no row for a brand-new player). The save path in both backends refuses to persist a flaggedPlayerData, so the on-disk record is preserved until a successful re-load happens. The player can still play this session with conservative defaults; their real record stays intact. Affected files:PlayerData.java,DatabaseDataStore.java,FlatFileDataStore.java.Brushing loophole closed
The previous brush protection only ran onPlayerInteractEvent, which fires once when the player starts brushing. Because brushing is tick-driven and the targeted block can change while the player keeps right-click held, players could start brushing a block outside a claim, walk into the claim, and let the brush complete on a claimedSUSPICIOUS_SAND/SUSPICIOUS_GRAVELblock — bypassing the original check. GP3D now also listens toEntityChangeBlockEventand re-checks Build permission at the moment the suspicious block transitions to its loot result. The check is restricted to actual brushing transitions (SUSPICIOUS_SAND -> SAND,SUSPICIOUS_GRAVEL -> GRAVEL) with a held-brush guard, so unrelated entity-driven block changes are not affected. Affected file:PlayerEventHandler.onPlayerBrushComplete.Migration
No configuration changes or data migration required. All fixes are behavior changes that take effect immediately on update.17.4.0GriefPrevention3D v17.4.0May 1, 2026 GriefPrevention3D v17.4.0
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- More translatable messages — AddedCommandRequiresPlayerkey for console-command error messages. - Plugin metadata — Addedauthorsandwebsitefields toplugin.yml.Translatable Messages
Added newMessagesenum key: -CommandRequiresPlayer— Sent when a player-only command is used from console. Default:"This command can only be used by players."This is now used by/buyclaimblocksand/sellclaimblocksinUnifiedClaimCommandinstead of a hardcoded string. Customize it inplugins/GriefPreventionData/messages.yml.Plugin Metadata
Updatedplugin.ymlwith additional metadata: -description: "The self-service anti-griefing plugin for Minecraft servers — now with full 3D subdivisions" -website:https://castled.codes-authors:[CASTLEDKING, RoboMWM, BigScary]Migration
No configuration changes or data migration required. The newCommandRequiresPlayerkey will be added to yourmessages.ymlautomatically on next load if missing.17.3.9GriefPrevention3D v17.3.9Apr 27, 2026 GriefPrevention3D v17.3.9
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- Fix duplicate permission messages - Ender pearl access denial messages now only send once on Purpur/Folia - Folia fix - Boundary violation alert scheduler now correctly uses the Folia-safeSchedulerUtilinstead ofBukkit.getScheduler()directly - Rename back to GriefPrevention - Renaming to 'GriefPrevention3D broke compatibility with GPFlags and other plugins that depend on GriefPrevention by name.Fix Duplicate Permission Messages
On Purpur and Folia servers, bothPlayerTeleportEventandProjectileHitEventfire for ender pearls. Previously, both handlers would send the "You don't have player's permission to use that" message when access was denied, resulting in 2-3 duplicate messages. Fixed by adding a deduplication check inPlayerTeleportEventhandler — it now skips sending the message ifProjectileHitEventalready handled the denial (tracked via the existingrefundedByProjectileHitEventset).Folia Fix
The boundary violation alert scheduler inClaimBoundaryViolationTrackerwas callingBukkit.getScheduler().runTaskLater()directly, which is not available on Folia servers. Fixed to useSchedulerUtil.runLaterGlobal()— the existing Folia-safe adapter used throughout the rest of the plugin. This routes through Folia'sGlobalRegionSchedulerwhen present and falls back toBukkit.getScheduler()on Paper/Spigot.Migration
No configuration changes or data migration required.17.3.8GriefPrevention3D v17.3.8Apr 27, 2026 GriefPrevention3D v17.3.8
Wiki: https://github.com/castledking/GriefPrevention3D/wikiHighlights
- Official plugin rename - Plugin is now officially namedGriefPrevention3D(output jar,plugin.yml, dependency declarations) - Folia fix - Boundary violation alert scheduler now correctly uses the Folia-safeSchedulerUtilinstead ofBukkit.getScheduler()directlyPlugin Rename
The plugin's official name is nowGriefPrevention3Dacross the board: -plugin.ymlname:field changed fromGriefPreventiontoGriefPrevention3D- Output jar is nowGriefPrevention3D.jar- Maven<artifactId>and<name>updated toGriefPrevention3DImpact on addon/dependent plugins
If you have plugins that declare a dependency on this plugin, update yourplugin.yml:
JitPack dependency coordinates also updated to# Before softdepend: [GriefPrevention] # After softdepend: [GriefPrevention3D]com.github.castledking:GriefPrevention3D.Folia Fixes
Two scheduler calls were usingBukkit.getScheduler()directly, which throwsUnsupportedOperationExceptionon Folia/Canvas region threads: -ClaimBoundaryViolationTracker— burst flush task now usesSchedulerUtil.runLaterGlobal()-AutoExtendClaimTask— async fallback now usesSchedulerUtil.runAsyncNow()Both now go through the existingSchedulerUtiladapter, which routes to Folia's schedulers when present and falls back to Bukkit on Paper/Spigot. Thanks to R00tB33rMan for reporting the crash and identifying the affected code (PR #4).Migration
- Server owners: rename the jar file reference in your startup scripts if you have any hardcoded references toGriefPrevention.jar. - Addon developers: updatesoftdepend/dependin yourplugin.ymltoGriefPrevention3D. - No claim data migration required. Existing claims load without modification.17.3.7GriefPrevention3D v17.3.7Apr 24, 2026 GriefPrevention3D v17.3.7
Highlights
- Boundary Violation Alerts - Claim owners are notified when pistons or liquids get blocked at their claim boundary, with smart deduplication and burst detection - Improved Claim Selection Messages - More informative messages when selecting claims and subdivisions - Updated Player Manual - Welcome book now includes GP3D branding and additional commands - New Wiki - https://github.com/castledking/GriefPrevention3D/wikiBoundary Violation Alerts
Pistons and liquids blocked at claim boundaries now send a chat message to the claim owner (if online) explaining where the violation occurred. Covers: - Pistons pushing blocks into or out of claims - Water/lava trying to flow into or out of claimsImproved Claim Selection Messages
- Subdivisions now get a dedicated, verbose message with color-coded command list - Basic claims reference/claim abandon- Top-level claims reference/claim abandon toplevel- All messages better reflect available commandsUpdated Player Manual
- Added "This server is using GriefPrevention3D" branding - Added
/3dSubdivideClaimsand/WitherExplosionsto commands page17.3.6GriefPrevention3D v17.3.6Apr 21, 2026 GriefPrevention v17.3.6
Highlights
- Quick fix for a bug wheregriefprevention.adjustclaimblockswas not checked when/aclaim blockswas used.17.3.5-mc26.1.2GriefPrevention3D v17.3.5 for mc26.1.2Apr 21, 2026 GriefPrevention v17.3.5 (Paper 26.1.2 Experimental)
Highlights
- Experimental support for Paper 26.1.2 (calendar-versioned Paper builds running on Java 25). - Migrated deprecatedPlayerLoginEventtoAsyncPlayerPreLoginEventto comply with Paper 26's re-configuration API requirements. - Thread-safe IP ban tracking for async login handling.Paper 26.1.2 Compatibility
This release targets Paper's new calendar-versioned experimental builds (26.1.2.build.18-alpha) which require Java 25. The plugin has been verified to load and run correctly on: - Paper: 26.1.2.build.18-alpha (Implementing API version 26.1.2.build.18-alpha) - Java: OpenJDK 25.0.2+10-LTS (Temurin)Event System Migration
Paper 26 deprecates listening toPlayerLoginEventbecause it fires between the login and configuration phases, blocking Paper's re-configuration APIs. This release migrates toAsyncPlayerPreLoginEvent: - Login cooldown and spam protection now run asynchronously before the configuration phase. - IP address recording moved toPlayerJoinEventto keep DataStore writes on the main thread. - Smart-ban IP tracking preserved: banned accounts are still recorded for IP-based auto-banning.Thread Safety Improvements
-tempBannedIpschanged fromArrayListtoCopyOnWriteArrayListto safely handle writes from the async login thread while main-thread handlers iterate the list.Technical Changes
-paper-apidependency bumped to26.1.2.build.18-alpha. - Removed deprecatedPlayerLoginEventandPlayerLoginEvent.Resultimports. - AddedAsyncPlayerPreLoginEventimport and handler (onAsyncPlayerPreLogin). - Added offline-safehasSpamBypass(UUID)helper for cooldown bypass checks (falls back to op status; permission-based bypass will be restored in a future update).Notes
- This is an experimental build for Paper 26.1.2. For production servers on Paper 1.21.x, use the standard v17.3.5 release. - Theapi-versioninplugin.ymlremains"1.21"for backward compatibility. - All 108 unit tests pass on Java 25. - No changes to claim mechanics, permissions, or commands — this is purely a compatibility update.
Similar projects
Plugin →VeinMiner
Mine the whole vein on mining a single ore/block. Make the tedious mining experience to something satisfying and fun! FTB Ultimine alternative
99.3MSueta
Simple Voice Chat
A working voice chat in Minecraft!
76.3MSueta
Let Me Despawn
Improves performance by tweaking mob despawn rules. Say bye to pesky unintentional persistent mobs.
26.2MSueta
Chunky
Pre-generates chunks, quickly and efficiently
20.8MSueta
VeinMiner Enchantment
Veinminer Addon - Adds vineminer enchantment to enchanting tables. Only tools with the enchantment can veinmine
18MSueta
JourneyMap
Real-time map used for mapping in-game or your browser as you explore.
14.7MSueta