Перейти к содержимому
Mineforgian

BlockProt Reloaded

An advanced Bukkit protection plugin for chests, furnaces, and more, built with a modern GUI and packed with powerful features and extended functionality.

Загрузки
163
Подписчики
1
Обновлён
9 июля 2026 г.
Лицензия
GPL-3.0-only

Опубликован 19 мая 2026 г.

BlockProt Reloaded

Fork of BlockProt by spnda, maintained by Zar.

Players lock chests, furnaces, and other blocks through a GUI — no commands to memorize. This fork extends the original NBT core with production-ready features for large or long-running servers.

Java 25+ · Paper / Spigot 1.20–26.x


Core Protection

  • Sneak + right-click any lockable block to open the protection GUI
  • Add friends with Read / Write / Manager permission levels
  • Per-block toggles for redstone, hopper, and piston interactions
  • Copy and paste protection settings between blocks
  • Per-player default friend list applied to all new locks

Admin Tools

/bp unlock <player> — opens a paginated GUI listing every block the target player owns. Left-click to inspect contents (read-only). Right-click to remove the protection. Works for offline players.

/bp info <player> — full-page GUI showing every block a player owns with real block icons, coordinates, and lock timestamps. Teleport to any entry with a click.


Access Audit Log

SQLite log recording OPENED, ITEM_TAKEN, ITEM_PLACED, and ACCESS_DENIED events. Viewable in-game via the Clock button on any locked block. Entries are grouped by player with a per-player drill-down view. Auto-pruned at 50,000 rows.


Ownership Transfer

/bp transfer <player> — transfer a single block. /bp transfer all <player> — transfer everything you own at once. The original owner is automatically kept as a friend.


Timed Friend Access

Grant temporary access to a block with human-readable durations: 30s, 1h, 7d, 1mo, or combined units like 1d12h. Access revokes automatically when the timer elapses.


More Features

  • Protection Expiry (opt-in) — set an expiry date on any lock; the block auto-unlocks when the timer runs out
  • Access Notifications (opt-in per player) — action-bar alert when another player opens your block, rate-limited by a configurable cooldown
  • Discord Webhook Alerts (opt-in) — embed alert when a monitored audit event fires, with per-block cooldown and configurable event types
  • Pet Protection (opt-in) — protects tamed animals from damage, interaction, leashing, and shoulder-pickup via a dedicated GUI
  • Statistics — stats list shows the real live block type at each location plus how long ago the block was locked; stale entries filtered automatically
  • Per-World Config — each world can override lockable block lists or disable protection entirely via worlds.yml
  • Hybrid MySQL / NBT Backend (opt-in) — HikariCP pool, async queries, in-memory trust cache; NBT stays the source of truth
  • Automatic Backup — config backup on version upgrade, stored under plugins/BlockProt/backups/
  • Self-Repair — missing config and translation keys merged from JAR defaults on every startup and /bp reload
  • SkinsRestorer Support — correct player heads in offline-mode servers, pre-fetched asynchronously on login

Integrations

Towny · WorldGuard · PlaceholderAPI · Lands · ClaimChunk · SkinsRestorer · WorldEdit / FAWE · Floodgate / Geyser · Folia


Links

Ченджлог

1.3.3Релиз26.1.1, 26.1.2, 26.2 · 9 июля 2026 г.

1.3.3

This page lists what changed in each release, in the order it shipped. Each entry describes the final, working behavior - not the intermediate steps taken to get there.

Coming next

1.3.4 - dialog system research

A community member proposed replacing the current inventory/anvil/chat interaction system with Minecraft's dialog system (issue #1). It would unify every current interaction method into one interface and could add a button to the pause menu. Adopting it means either dropping support for versions below 1.21.6, or maintaining both interaction systems side by side. Research is starting; nothing about this is final yet.

1.3.5 - language overhaul

Every bundled language file except English and Spanish is currently outdated to varying degrees, some carrying leftover content from features that no longer exist in this fork. 1.3.5 replaces every one of those files wholesale with the equivalent file from the upstream project, then reconciles it with the strings this fork adds on top (integrations, per-world config, and so on).

Alongside that, a community translation system is planned: a dedicated languages section on the project's Discord (https://discord.gg/RRcjuMr9Jd), where contributors can submit translation updates and corrections for review instead of relying on a single pass to keep every language current.

1.3.3 is finally out

After a long development cycle, I'm officially releasing 1.3.3. This is the biggest update this fork has shipped: five new plugin integrations (WorldGuard, Lands, Towny, ClaimChunk, PlaceholderAPI), item frame and storage vehicle protection, villager workstation protection, raid detection, a rebuilt lockables GUI, and a long list of inherited and fork-specific bug fixes. Everything below this point describes what actually shipped.

1.3.3

Breaking changes (0.1% of servers affected)

  • All lockable lists are empty by default. On a fresh install, blocks.yml starts with [] for every list, including lockable_entities. The admin configures lockable blocks via /bp lockables in-game, by editing blocks.yml directly, or by running the /bp recommended console command to populate a sensible default set. Existing servers upgrading are unaffected: their blocks.yml is never overwritten.
  • Bidirectional blocks.yml startup conversion re-added with guard. The modern_family_blocks flag now auto-converts blocks.yml format on /bp reload (via convertBlocksFormatIfNeeded()), but only when the file format actually mismatches the flag. This conversion preserves all material selections, only the format changes. On the first reload after changing the flag, the file is converted; subsequent reloads are no-ops. Manual edits are preserved (materials are never dropped, only reformatted). The infinite-reload-loop bug is prevented by suppressNext() before every save.
  • Config file writes only when dirty. cleanLegacyConfigKeys() and mergeMissingConfigKeys() now only write to disk when a change was actually made. This stops the infinite auto-reload loop caused by the plugin overwriting its own config files.
  • File watcher console spam reduced. The watcher logs one short line to the console ("Configuration change detected; reloading...") and one line to the session log per change. Previously it logged two console lines. World scan messages only print when worlds are actually added or patched.
  • Startup banner with ASCII art. BlockProt prints an ASCII "BPR" logo on startup in a light coffee color. The plugin name, version line, and boot status lines that follow print uncolored.
  • /bp recommended console command. Generates a sensible default blocks.yml. Console-only. See "First-start console guide" below for how new admins are pointed to it.
  • Per-world lockable GUI. When per_worlds_config: true, the lockables GUI shows a MAP button (slot 48) that opens a world selection inventory. Each world shows its enabled/disabled status and protected block count. Click a world to configure its individual lockable lists.
  • Auto-disable modern_family_blocks. When all lockable lists become empty via GUI toggling, modern_family_blocks auto-sets to false in config.yml.
  • Translation keys added: worlds.status, worlds.protected_count, worlds.no_worlds, worlds.world_config_hint, worlds.per_world_config, worlds.worlds, worlds.configured.

Additions

Fixed menu layout for all block and entity types

Auto-drop to inventory configuration GUI

A new GUI to configure auto_drop_to_inventory.blocks is accessible from the /bp lockables inventory (DROPPER item at slot 46). The page shows each family (Tile Entities, Shulker Boxes, Blocks, Doors, Entities) with a representative icon and its active/inactive/partial status.

  • Right-click a family toggles all its members at once (enables or disables auto-drop for the entire family).
  • Left-click opens a paged sub-menu listing every material in that family. Each material can be toggled individually.
  • The back button returns to the lockables GUI.

New methods in DefaultConfig: toggleAutoDropMaterial(), toggleAutoDropFamily(), representativeMaterialForFamily(). All toggles persist to blocks.yml on disk.

Lockables GUI blocks no longer move on toggle

The active-status sort was removed. Blocks stay in their family section sorted by name only. Toggling a block on or off no longer changes its position in the inventory.

Fixed crash on non-item materials in auto-drop sub-menu

Materials that cannot be held in an ItemStack (LAVA_CAULDRON, WATER_CAULDRON, POWDER_SNOW_CAULDRON, wall-mounted signs) are resolved to display equivalents before creating ItemStacks. The sub-menu no longer crashes when opening the Blocks family.

The Block Lock menu previously placed its buttons using a counter that incremented for each button actually shown. When a button did not apply to the current block (for example, no Redstone button on a workstation), every button after it shifted one slot to the left. This meant the same menu looked different depending on which block type opened it, and the bottom-row buttons (Inspect, Audit Log, Paste, Copy, Info) ended up in inconsistent slots between block types.

Every button now has one fixed slot, used by every block and entity type. A button that does not apply to the current type simply leaves its slot empty; the other buttons never move.

Fixed slots, top row:

Slot Item Shown for
0 Block icon Always
1 Redstone Storage and traversal blocks
2 Player Head Always, unless friend functionality is disabled
3 Name Tag Always
4 Ender Pearl Always
5 Emerald Workstation blocks only

Fixed slots, bottom row:

Slot Item Shown for
9 Spyglass Storage blocks with an inventory, owner or admin
13 Clock Owner or admin, audit logger active
14 Knowledge Book Manager role, clipboard has data
15 Paper Manager role
16 Compass Manager role or admin
17 Barrier Always

The entity menu (fillForEntity) was fixed the same way: Name Tag stays at slot 0, Redstone and Ender Pearl only appear for storage vehicles (chest boats, storage/hopper minecarts) and always sit at slots 1 and 4, Player Head always sits at slot 2, Spyglass and Clock sit at 9 and 10 for storage vehicles, and Compass sits at 13.

Entity protection rename

The protection system covering tamed animals (wolves, cats, parrots, horses, llamas) was renamed end-to-end from "pet protection" to "entity protection" across class names, package names, config keys, NBT persistent-data keys, and method names. This is purely a naming and organization change; behavior is identical to the previous pet protection feature.

The pet_protection key in config.yml is renamed to entity_protection. Upgrading servers do not need to edit anything: on first startup after the upgrade, the plugin reads the old key, writes its value under the new name, and removes the old entry automatically. Old NBT data stored under the legacy pet_owner / pet_protected keys is migrated to the new keys automatically as well.

Villager workstation protection

A villager whose job-site memory points to a protected workstation block (grindstone, stonecutter, loom, cartography table, smithing table, enchanting table, fletching table, lectern, composter, brewing stand, blast furnace, smoker, barrel, cauldron) inherits that block's protection automatically - no separate configuration is needed per villager.

Protected actions:

  • Damage to the villager by non-owners (melee and projectiles)
  • Trading interaction by non-owners
  • Breaking blocks in a search area around the workstation
  • Interacting with blocks in that area (except the workstation block itself)

The search area is configurable independently of whether the feature is enabled:

villager_workstation_protection:
  enabled: true
  radius: 2            # horizontal search radius in blocks, clamped to 0-8
  vertical_radius: 1   # vertical search radius in blocks, clamped to 0-4

A new Emerald button ("Locate Linked Villager") appears in the lock menu for a protected workstation that has a villager linked to it. Clicking it closes the menu and shows a short particle effect at the villager's location, visible only to the clicking player, for a configurable duration (entity_protection.villager_locate_seconds, 1-10 seconds, default 6). If no villager is linked, nothing happens and no error is shown.

Item frame protection and automatic block linking

ITEM_FRAME and GLOW_ITEM_FRAME are full members of the ENTITIES family under the ITEM_FRAMES sub-family. They appear in /bp lockables with Status: INACTIVE by default (not included in lockable_entities) or ACTIVE when listed.

A frame mounted on the face of a lockable block is automatically linked to that block at the moment it is placed. A linked frame has no protection state of its own: no owner, no friend list, no lock toggle. Interacting with it opens the underlying block's lock menu directly, and the frame's protection always matches the block's exactly - same owner, same friends, locks and unlocks together. The link is stored bidirectionally (the frame stores the block's coordinates, the block stores the frame's entity UUID) so it survives chunk reloads and server restarts, and is validated on each interaction in case the frame or block changed since linking.

A frame not mounted on a lockable block, or mounted on a block that is not currently lockable, keeps the standalone entity-protection flow: sneak and right-click with an empty hand opens the BlockProt entity menu directly, exactly like 1.3.2.

Supported token: *-ITEM_FRAMES to include only frames, or -*ITEM_FRAMES to exclude all frames, in a lockable_entities family expression.

Storage vehicle protection completed

Chest boats, storage minecarts, and hopper minecarts use the same sneak-and-right-click flow as item frames. Once protected:

  • Right-clicking without sneaking is blocked for non-owners and non-friends.
  • Damaging or destroying the vehicle (VehicleDamageEvent, VehicleDestroyEvent) is blocked for everyone except the owner and admins.
  • Hopper-pipeline extraction from the vehicle's inventory is blocked unless the owner has disabled that protection from the in-menu toggle.
  • Placing the vehicle auto-locks it to the placing player if their "lock on place" setting is enabled and they are not sneaking, mirroring the behavior already in place for blocks and item frames.

ChestBoat is resolved at runtime via reflection so the same code path supports both the 1.20.x class location (org.bukkit.entity.ChestBoat) and the 1.21+ location (org.bukkit.entity.boat.ChestBoat).

EntityInfoInventory location display

The info panel for a protected entity shows an Oak Sign in slot 1 displaying the entity's type and current world/coordinates, replacing the Compass-based block-info display that does not apply to entities (entities do not have NBT-stored placement coordinates the way blocks do).

BlockFamilyParser cross-family validation and /bp lockables

BlockFamilyParser parses compact family expressions in blocks.yml and worlds.yml. Expressions are always parsed regardless of the modern_family_blocks flag in config.yml - that flag only controls whether flat material lists are auto-converted to expressions on startup.

A NAME or -NAME token inside an expression is now validated against the family of the config key it appears in. A material that does not belong to that family is rejected with a console warning and discarded, rather than silently producing an incorrect or empty result. For example, FLETCHING_TABLE (a BLOCKS workstation) inside a lockable_tile_entities expression is rejected with a warning, while COPPER_CHEST (a valid CHEST sub-family member) is accepted.

/bp lockables is a new admin command (blockprot.user.admin) that opens a six-row paged GUI listing every block and entity the family system knows about, regardless of whether it is currently enabled. Active entries show a green Status: ACTIVE label; disabled entries show a red Status: INACTIVE label. Left-clicking an entry sends a clickable chat message that copies the material name; right-clicking copies the exclusion token (-MATERIAL_NAME). The info book in the GUI shows server version, client version (via ViaVersion, if installed), and active/inactive counts.

Token reference:

Token Meaning
* All members of the family
*-TAG All members of the named sub-family
-*TAG Exclude all members of the named sub-family
NAME Include one specific material
-NAME Exclude one specific material

Sub-families per config key:

Key Sub-families
lockable_tile_entities CHEST, FURNACE, SHELF, TRANSPORT, MISC, SIGN
lockable_shulker_boxes SHULKERS
lockable_blocks ANVIL, CAULDRON, WORKSTATION, TRAPDOOR, FENCE_GATE
lockable_doors DOORS
lockable_entities CHEST_BOATS, CHEST_MINECARTS, HOPPER_MINECARTS, ITEM_FRAMES

Full syntax guide and worked examples: docs/MODERN SYNTAX AND LEGACY/BLOCK_FAMILY_SYNTAX.md. Both the plain flat-list format (one material per line with -) and the bracketed expression format are accepted, and can be mixed across different lines of the same list - see the "Two valid formats" section of that document.

ViaBackwards and ViaRewind detection

ViaVersionIntegration now detects ViaBackwards and ViaRewind in addition to ViaVersion, logging the version of each detected companion plugin.

WorldGuard integration

WorldGuardIntegration registers a custom region flag, allow-blockprot, defaulting to allow. Setting the flag to deny on a specific region (/rg flag <region> allow-blockprot deny) blocks BlockProt protections from being created or accessed inside that region. Everywhere else behaves exactly as if WorldGuard were not installed. The flag is registered during plugin load, before WorldGuard finishes enabling, per WorldGuard's custom-flag registration timing.

Configured from integrations.yml:

worldguard:
  enabled: true
  enable_flag_functionality: true

Setting enable_flag_functionality: false keeps WorldGuard detected (it still shows Hooked on the startup banner) without ever checking the flag.

Lands integration

LandsPluginIntegration registers a custom role-flag, "Protect containers (BlockProt)", that land owners assign per role. A player without that flag in the claimed area covering a protected block is denied locking or accessing it. Unclaimed wilderness follows a separate config option instead of the role-flag.

An optional second role-flag, "Require "Protect containers" for friends (BlockProt)", lets a land owner require that both the block owner and the friend being added hold the protect-containers flag before that friend can access the block.

Configured from integrations.yml:

lands:
  enabled: true
  allow_protecting_containers_in_wilderness: true
  require_protect_for_friends_flag: false

Both role-flags are registered during plugin load, mirroring WorldGuard's registration timing requirement.

Towny integration

TownyIntegration checks Towny protection on blocks and entities. A player must be a town resident to lock or access protected blocks within that town's claimed area. Ruined towns bypass the resident check entirely (cancelling the lock/access attempt before even checking, rather than allowing it when the resident check fails).

Three bugs fixed in this release:

  1. onLockOnPlace resident check was inverted: a missing ! caused locking to be denied in every town instead of being denied outside towns.
  2. shouldBypassProtectionsInRuinedTowns used || instead of &&: the wrong operator meant all players bypassed protection in ruined towns.
  3. shouldCleanupAfterUnclaim used || instead of &&: protection cleanup ran on every world change instead of only when a town was actually unclaimed.

Configured from integrations.yml:

towny:
  enabled: true
  cleanup_plots_after_unclaim: true
  restrict_access_to_residents: false
  allow_mayor_to_see_block_info: false
  bypass_protection_in_ruined_towns: true

Additional options: restrict_access_to_residents denies lock/access to non-residents even on unlocked blocks; allow_mayor_to_see_block_info grants the /bp info permission to the town mayor; cleanup_plots_after_unclaim removes protections when a plot is cleared or unclaimed; bypass_protection_in_ruined_towns allows container access in ruined towns without owning the block.

ClaimChunk integration

Requested in issue #298.

ClaimChunkIntegration restricts block locking and full access (lock/unlock/edit) to the chunk owner or a trusted member:

  • Locking (onLockOnPlace, onPreLock): only the chunk owner can create protections.
  • Full access (onPreventFullAccess): only the chunk owner (or trusted members, if restrict_access_to_chunk_owner is false) can unlock or edit settings.
  • isFriend(): only the chunk owner is accepted as a "natural friend"; there is no per-chunk friend list of its own, so the standard BlockProt friend-management page continues to work normally for owner-to-owner sharing.

Configured from integrations.yml:

claimchunk:
  enabled: true
  restrict_access_to_chunk_owner: false

Setting restrict_access_to_chunk_owner: true restricts full access (lock/unlock/edit) to the chunk owner only, in addition to locking.

PlaceholderAPI integration

PlaceholderAPIIntegration registers a PlaceholderExpansion providing BlockProt placeholders for the server's PAPI system. Available placeholders:

Placeholder Returns
%blockprot_global_block_count% Total protections on the server
%blockprot_own_block_count% Number of protections owned by the querying player
%blockprot_default_friends% The player's default friend list

Configured from integrations.yml:

placeholderapi:
  enabled: true

ViaVersion integration

ViaVersionIntegration detects ViaVersion, ViaBackwards, and ViaRewind at startup and logs the version of each detected companion plugin. The /bp debug run command includes ViaVersionIntegration.getDetailedStatus() for the full version summary.

Configured from integrations.yml:

viaversion:
  enabled: true

Centralized integrations.yml configuration

All integration configuration is now in a single integrations.yml file inside the plugin data folder (plugins/BlockProtReloaded/integrations.yml). The old per-integration files (integrations/worldguard.yml, integrations/lands.yml, integrations/towny.yml, etc.) are no longer shipped or read.

Each integration section has an enabled: true/false toggle. Setting enabled: false for an integration stops it from registering hooks and listeners without requiring the external plugin to be removed from the server; the integration is simply ignored at startup.

The WorldEdit paste-autolock settings (paste_autolock.enabled, paste_autolock.radius, paste_autolock.delay_ticks, paste_autolock.block_limit) were moved from config.yml into integrations.yml under the worldedit section. Old keys in config.yml are still read (marked @Deprecated in code) but no longer written.

Full integrations.yml structure:

worldguard:
  enabled: true
  enable_flag_functionality: true

lands:
  enabled: true
  allow_protecting_containers_in_wilderness: true
  require_protect_for_friends_flag: false

towny:
  enabled: true
  cleanup_plots_after_unclaim: true
  restrict_access_to_residents: false
  allow_mayor_to_see_block_info: false
  bypass_protection_in_ruined_towns: true

claimchunk:
  enabled: true
  restrict_access_to_chunk_owner: false

worldedit:
  paste_autolock:
    enabled: false
    radius: 24
    max_blocks_per_paste: 5000
    delay_ticks: 20

placeholderapi:
  enabled: true

viaversion:
  enabled: true

First-start console guide

On the very first startup of a fresh install, if no lockable blocks are configured yet, the console prints a short guide directly under the startup banner: use /bp lockables in-game, edit blocks.yml manually, read the full docs on GitHub, or run /bp recommended in console for a sensible default set. The guide prints once per fresh install, tracked by a .first_start_done marker file in the plugin data folder. A server migrated from a legacy install never sees it, since it is not a fresh install.

Debug command expanded

/bp debug run now also tests:

Check What it verifies
Lockable entities Lists all ENTITIES family members with ACTIVE / INACTIVE status
Item frame protection Reads isLockableEntity(ITEM_FRAME) and isLockableEntity(GLOW_ITEM_FRAME) and logs the result
Raid detection config Reads raid_detection.enabled and confirms the audit logger is active
Integrations (expanded) Calls ViaVersionIntegration.getDetailedStatus() for the full Via summary including companion plugins
NBT entity write/read Spawns a temporary ArmorStand, writes an owner UUID, reads it back, then removes the entity

Audit log action classification

Clarified and corrected audit-trail event meanings:

  • ACCESS_DENIED - a player attempted to access a protected block/entity and was blocked
  • OPENED - a player with access opened the inventory of a protected block
  • RAID_EXPLOSION - an explosion affected a protected block
  • ITEM_TAKEN / ITEM_PLACED - a player moved items in a protected inventory

StatHandler rewrite

StatHandler.saveFile() was rewritten. The previous implementation called Files.move(ATOMIC_MOVE) unconditionally, which throws IOException: Failed to swap backup NBT file on Windows and on Linux filesystems that do not support atomic cross-directory moves. The new implementation writes to a temp file, validates it with NBT-API before touching the live file, copies the validated temp file to the backup location, then replaces the live file. When atomic move is unavailable it falls back to a standard copy-and-delete. A synchronized block prevents concurrent writes. The dirty flag is preserved across the rewrite.

Performance improvements

purgeStalePbsEntries now checks World.isChunkLoaded() before calling Block.getType(). Previously, every stored block location whose chunk was not already resident in memory triggered a synchronous chunk load, freezing the server thread for up to 20 seconds for players with large block lists. The fix skips any entry whose chunk is not already loaded and revisits it on a later call.

A Caffeine cache (purgeThrottle, 60-second TTL, 512 entries) throttles the per-player stale-entry scan to at most once per 60 seconds, preventing the scan from running on every block-place event for active players.

Block family expression system

See "BlockFamilyParser cross-family validation and /bp lockables" above for the full token reference and validation behavior.

Config and blocks auto-merge on every reload, with content preserved

reloadConfigAndTranslations() runs all merge and sync operations on every /bp reload call, not only on startup: cleanLegacyConfigKeys(), mergeMissingConfigKeys(), mergeMissingBlocksKeys(), language-file key merging, and the world-config re-scan all run on reload.

The merge guarantee for blocks.yml, config.yml, and worlds.yml is: any top-level section that is entirely missing from the file on disk is added from the bundled JAR defaults, and a console line records what was added. Any key or section that already exists is never overwritten - this means user-configured lockable lists, family expressions, and all other values are preserved across reloads and version upgrades. A future version that adds a brand-new top-level key (for example, a new boolean toggle) will see that key appended automatically; a family expression you already wrote, such as '[*-CHEST_BOATS ITEM_FRAME]', is never rewritten, reordered, or stripped, regardless of how many versions you upgrade through.

Individual entry-level merge (appending new materials to existing flat lists) was removed in 1.3.3 to prevent accidental population of user-configured lists. Only missing top-level sections are merged.

Renamed config keys with automatic migration

worlds_config_enabled is renamed to per_worlds_config. On first startup after upgrading, the plugin reads the old key, writes its value under the new name, and removes the old entry from config.yml. No manual action is required.

auto_reload_configs flag

New config key, default true. When set to false, the ConfigFileWatcher does not start and config files are not reloaded automatically; use /bp reload to apply changes manually. Useful on high-load servers or when editor tooling causes spurious filesystem events.

SQLite usercache moved into plugin folder

blockprot_usercache.sqlite is now created inside plugins/BlockProtReloaded/ rather than next to server.jar. On first startup after upgrading, any file found at the old location is moved automatically.

Legacy folder migration improved

migrateFromLegacyFolders() also calls mergeYamlUserValues() after copying files. Admin values from config.yml and all language files in the legacy folder are merged key-by-key into the new location. The destination's existing value always wins on conflict, so no configured value is ever overwritten by the migration.

Raid detection

RaidDetectionListener monitors every explosion (BlockExplodeEvent and EntityExplodeEvent) for proximity to lockable blocks. It does not cancel the explosion; it only detects and notifies.

Behavior:

  • Any lockable block in the explosion's block list triggers a WARN line in the session log with block type, world, coordinates, and the actor (player name, entity type, or "environment").
  • If the block is protected and its owner is online: an action-bar alert fires immediately, followed by a chat message with full coordinates. If the owner has blockprot.blocks.tp, a clickable [Teleport] link is appended.
  • If the owner is offline: the alert is queued in memory and delivered as a chat message the next time they join, with the teleport link included if they have blockprot.blocks.tp at join time.

Controlled by raid_detection.enabled in config.yml (default true). Set to false to stop all detection and notification without removing the listener.

New translation keys: messages.raid_alert, messages.raid_coords, messages.raid_tp_label, messages.raid_pending.

Support policy change

Starting with 1.3.3, support tiers are:

Version range Tier
26.x (Paper/Purpur/Pufferfish), no upper cap Primary development target
1.21.1 through 1.21.x Active support
1.20.x and below Not supported

The compile target is raised from paper-api:1.20.6 to paper-api:1.21.1. Servers below 1.21.1 no longer load the plugin (enforced by api-version: 1.21.1 in plugin.yml). Legacy 1.20.x users must stay on 1.3.3 or earlier.

Documentation policy change

Starting with 1.3.4, the project's README.md will be condensed to a short summary of all current features rather than documented feature-by-feature in full detail. RELEASE_NOTES.md becomes the single authoritative place where what changed between every version is recorded, including this entry. docs/READ_MEs/MODR_HANG_README.md, the short description used on Modrinth and Hangar, will continue to be updated for store listings but is not a substitute for this file.

BEACON added to lockable tile entities

BEACON is now recognized as a lockable tile entity. It can be locked via flat list (add BEACON to lockable_tile_entities) or family expression (*-MISC catches it as an ungrouped tile entity). The default blocks.yml now includes BEACON.

SIGNS enabled by default in blocks.yml

All sign variants (floor, wall, hanging, wall-hanging for all 12 wood types) are now enabled by default via the family expression [*-SIGN] in lockable_tile_entities. This works in both flat-list and modern-expression modes since family expressions are always parsed.

FLETCHING_TABLE added to WORKSTATION sub-family

FLETCHING_TABLE was present in the default flat list of lockable_blocks but was missing from the isWorkstationMaterial() check in BlockFamilyParser and the blockValidator in DefaultConfig. This meant it was silently rejected during family expression resolution and the loadBlocksFromConfig() validator. It is now a proper member of the *-WORKSTATION sub-family and the lockable_blocks BLOCKS family.

/bp lockables click-to-toggle

Left-clicking a material in /bp lockables toggles it active or inactive and saves the change immediately. Right-click copies the material name; shift-right-click copies the exclusion token (-MATERIAL_NAME). This is permanent, built-in behavior with no config option to disable it. Every toggle is logged to the session log with the player and the resulting state.

/bp lockables modern mode compliance

toggleLockable() now respects modern_family_blocks. In legacy mode, toggling adds/removes flat material names as before. In modern mode, the current config list is parsed into a material set via BlockFamilyParser.parse(), the target material is added or removed, and the set is converted back to a compact family expression via BlockFamilyParser.toFamilyExpression(). This keeps blocks.yml clean and avoids mixing flat names with expressions.

/bp lockables "Enable all" entry per category

A NETHER_STAR "Enable all" entry appears at the top of every category section (Chests, Shulkers, Furnaces, Storage, Signs, Doors, Trapdoors, Fence Gates, Workstations, Interactive, Entities). Clicking it adds the appropriate family expression (e.g. [*-CHEST], [*], [*-WORKSTATION]) to blocks.yml, enabling every material in that category at once. The change is saved to disk and logged.

/bp lockables active-first sorting

Both the category-grouped entries and the entity entries in the lockables GUI are now sorted with active (currently lockable) items first, followed by inactive items. Previously the order was inactive-first.

External plugin API: BlockProtAPI.registerIntegration()

External plugins can now register their own PluginIntegration subclasses to hook into BlockProt's protection flow:

// From onEnable() of the external plugin:
Bukkit.getScheduler().runTaskLater(this, () -> {
    BlockProtAPI api = BlockProtAPI.getInstance();
    if (api != null) {
        api.registerIntegration(new MyIntegration());
    }
}, 1L);

registerIntegration() tracks BlockProt's own lifecycle internally: if BlockProt is already past the load() or enable() phase when the external integration is registered, those phases are called immediately. This means the one-delay-tick pattern above is only needed because BlockProtAPI.getInstance() is not available until BlockProt's onEnable() completes; the register call itself handles lifecycle automatically.

PluginIntegration is fully public and abstract. Subclasses must provide:

  • a name string (used in boot logging)
  • a load() method (runs during BlockProt.onLoad())
  • an enable() method (runs during BlockProt.onEnable())

The ConfigurationSection for the integration is available via getSection(name) (reads from integrations.yml), and the enabled toggle should be checked at the top of enable().

Events available for integration hooks: BlockAccessEvent, BlockAccessMenuEvent, BlockLockOnPlaceEvent, all in de.sean.blockprot.bukkit.events.


Fixed & Improved

Bug fixes

  • README.md stale config reference: The worldedit_paste_autolock section in README.md still listed these as live config.yml options. They were moved to integrations.yml in this release. Changed to a DEPRECATED comment block. The blockprot.debug permission default was also corrected from false to op to match plugin.yml.
  • isKeyInExpressionFormat() ignored modern_family_blocks: false: when the flag was set to false but blocks.yml still contained family expressions like - '[*-CHEST]', every GUI toggle stayed in expression format instead of converting to flat material names. The flag now determines the output format unconditionally: when false, all keys are written as flat sorted material lists regardless of the file's current format.
  • toggleLockable() and toggleFamily() had two code paths: the expression branch parsed both formats correctly, the flat branch only handled flat input. When modern_family_blocks toggled from true to false, the flat branch would not convert existing expressions: toggles silently did nothing. Both methods now use a unified path: parse the raw value (handles both formats), modify the material set, then write in the flag-determined format.
  • blocks.yml key order shuffled: SnakeYAML writes keys in insertion order, so any blocksConfig.set() call moved the modified key to the end. Repeated toggles left the file with keys in random order. Added DefaultConfig.reorderBlocksKeys() which returns a new YamlConfiguration with keys in the fixed order (lockable_tile_entities, lockable_shulker_boxes, lockable_blocks, lockable_doors, lockable_entities, auto_drop_to_inventory). Applied to all save paths: saveBlocksConfig(), mergeMissingBlocksKeys(), and convertBlocksFormatIfNeeded().
  • Auto-format conversion on reload: new convertBlocksFormatIfNeeded() in BlockProt.java runs during every reloadConfigAndTranslations(). It reads blocks.yml, checks if the file's format matches modern_family_blocks, and if not, converts all 5 lockable keys to the correct format (expressions or flat names) while preserving every material selection. This means setting modern_family_blocks: false and doing /bp reload now correctly converts - '[*-CHEST]' to flat names like - CHEST\n- TRAPPED_CHEST\n....
  • Translation incomplete message spammed console on every reload and GUI toggle: loadFromConfigs() logged the "N incomplete key(s)" message to getLogger().info() every time translations were loaded, which happened on every file-watcher-triggered reload (i.e., after every /bp lockables toggle). Changed to a static translationIncompleteLogged flag: the message is printed once per server session.
  • Auto-reload console message was removed entirely: the ConfigFileWatcher previously logged "Configuration change detected; reloading..." to the console but was changed to session-log-only to reduce spam. The message is restored to console (one line): the session log retains the additional detail.
  • Block Lock menu button shifting: every button used a shared incrementing slot counter, so any block type missing one button (for example, no Redstone on a workstation) shifted every later button one slot to the left. The same menu rendered differently for a chest versus a workstation versus a door. Fixed by giving every button a fixed slot in both fill() and fillForEntity() - see "Fixed menu layout" above.
  • StatHandler NBT save crash: Files.move(ATOMIC_MOVE) failed on cross-device paths. Rewritten to temp-write, validate, backup, replace with fallback copy.
  • Server freeze on stats purge: purgeStalePbsEntries called Block.getType() on unloaded chunks, triggering synchronous chunk loads. Fixed with a World.isChunkLoaded() guard.
  • EntityChangeBlockEvent AIR crash: missing early-return for AIR blocks caused a RuntimeException in BlockNBTHandler.
  • Shulker auto-lock NPE: wrote NBT via block.getState() on freshly placed shulkers whose BlockEntity was not yet initialized. Fixed with block.getState(true) and a TileState guard.
  • /bp protdel typo: was registered as protdell (double L); corrected to protdel.
  • /bp protdel missing non-tile-entity blocks: the non-MySQL fallback path only scanned chunk.getTileEntities(), missing all non-tile lockable blocks (doors, trapdoors, fence gates, anvils, cauldrons, workstations, interactive blocks). The fallback now also scans every block in loaded chunks for lockable non-tile types.
  • /bp protdel missing double-chest and door cleanup: handler.clear() was called without handler.applyToOtherContainer(), leaving protection data on the other half of double chests and double doors. Added the missing call.
  • Update checker silent failure: produced no output when running ahead of the latest release; now logs silently instead of erroring.
  • EntitySettingsInventory permission: used the raw string "blockprot.admin" instead of Permissions.USER_ADMIN and lacked an isOp() fallback. Fixed.
  • CraftBukkit error path: the error message shown to plain-CraftBukkit servers is now properly translated instead of showing a raw key string.
  • BlockProtAPI instantiation was too late for external integrations: BlockProtAPI.getInstance() returned null until after all startup logging, the first-run guide, and the banner were printed. new BlockProtAPI(this) is now created right after integrations are enabled, making the API available to external plugins earlier in the startup sequence. Additionally, registerIntegration() now tracks BlockProt's internal lifecycle (integrationsLoaded, integrationsEnabled) and calls load()/enable() on newly registered integrations immediately if BlockProt has already passed that phase; external integrations registered via Bukkit.getScheduler().runTaskLater(..., 1L) no longer skip lifecycle hooks.

Inherited bug fixes

Issue Title Fixed in
#302 1.21.1 not supported properly Upstream
#304 Unknown warning/error occurred Upstream
#305 Taking map from Search Players slot Upstream
#319 Emptying large chests incorrectly on hoppers Upstream
#323 1.21.3 not supported properly Upstream
#326 Redstone protection bugged with trapdoors Upstream
#327 Paper NoClassDefFoundError Container Upstream
#328 Colored shulker boxes reset when broken Upstream
#329 AIR block error on entity change Upstream
#330 Pale oak door/gate cannot be locked Upstream
#332 Unable to use BlockProt on 1.21.7 Upstream
#338 Support for Minecraft 1.21.9 Upstream
#339 Shulker box vanishes when broken Upstream
#165 Random inventory close on interaction Upstream
#266 public_is_friend_by_default setting Upstream
#294 Geyser players missing from friend search Upstream
#185 Hopper protection below chest not working Upstream
#214 Making doors public only half the door Upstream
#224 Locked shulker boxes break without dropping Upstream
#227 Hopper and piston protection swapped Upstream
#235 Lectern protection issues Upstream
#240 Hopper protecting not working Upstream
#250 Can get Player Head from menu Upstream
#256 Can't copy/paste settings between blocks Upstream
#263 Can take Telescope from Menu Upstream
#272 Can't move items as admin/op Upstream
#276 Items can still be placed into chests Upstream
#279 Items being deleted on interact Upstream
#280 Shulker box items deleted after breaking Upstream
#281 Dropper not working after unlock Upstream
#287 Double chest not handled on inventory click Upstream
#289 Chest locked but friends can open Upstream
#296 Item lost on interact Upstream
#297 Item drops can't be picked by hopper Upstream
#321 Wither explosions breaking protected blocks Upstream

Fork-specific fixes

Issue Title Fix
#268 Friend list copy/paste should replace instead of appending Paste replaces friend list
#306 Plugin causes server lag (hopper checks) ProtectedBlockCache with O(1) early-exit
#324 Option to allow all protected blocks to be broken allow_break_protected_blocks config key
(not tracked upstream) Players can access second row of large chest Inventory double-chest gating
#349 Warn spam in console (NBT swap error) StatHandler rewrite with temp-write-validate-replace
#238 Piston Protection Shulker Box Shulker box check added to piston retract logic

Dependency updates

Dependency Old New Reason
paper-api (compile) 1.20.6-R0.1-SNAPSHOT 1.21.1-R0.1-SNAPSHOT Support baseline raise
FoliaLib 0.4.3 0.5.1 Bug fixes, latest stable
item-nbt-api 2.15.6 2.15.7 26.1.x and 1.21.11 support
MockBukkit (test) v1.20:3.93.2 v1.21:4.8.0 Aligns with new compile baseline

Known Issues

  • MockBukkit unresolvable: MockBukkit-v1.21:4.8.0 returns HTTP 401 from jitpack.io. Build with -x test to skip tests.
  • Gradle shadowJar false up-to-date: on some local setups, running :blockprot-spigot:shadowJar after only source changes (no clean) can report BUILD SUCCESSFUL while reusing a stale or absent output if Gradle's up-to-date check does not detect the change. If the jar is missing or unexpectedly small after a build, rerun with --rerun-tasks, or run gradlew clean :blockprot-spigot:shadowJar to force a full rebuild.

Complete Issue Reference (>= #250)

Every non-trivial issue from the upstream repository sorted by category. Issues closed upstream are fixed in this fork by inheritance. Issues open upstream but resolved in this fork are noted as fork-specific fixes.

Bugs fixed upstream (inherited)

These were closed in the upstream repository and are fixed in this fork:

Issue Title
#339 Shulker box vanishes when broken
#338 Support for 1.21.9
#337 Bug (untitled)
#336 Bug (untitled)
#335 Bug (untitled)
#332 Unable to use on 1.21.7 server
#330 Pale oak door/gate cannot be locked
#329 Air block error on entity change
#328 Colored shulker boxes reset when broken
#327 Paper NoClassDefFoundError Container
#326 Redstone protection bugged with trapdoors
#323 1.21.3 not supported properly
#319 Emptying large chests incorrectly on hoppers
#305 Taking map from Search Players slot
#304 Unknown warning or error occurred
#302 1.21.1 not supported properly
#297 Item drops can't be picked by hopper
#296 Item lost on interact
#293 Problem with chests regarding hoppers
#290 Bug (untitled)
#289 Chest locked but friends can open
#281 Dropper not working after unlock
#280 Shulker box items deleted after breaking
#279 Items being deleted on interact
#276 Items can still be placed into chests
#275 Hoppers can take items from protected chests
#274 Players can access second row of large chest
#272 Can't move items as admin/op
#263 Can take Telescope from Menu
#256 Can't copy/paste settings between blocks
#255 Can't remove everyone from settings
#250 Can get Player Head from menu
#240 Hopper protecting not working
#236 Copy Paste not working properly
#235 Lectern protection issues
#232 Sign not in lockable_blocks
#230 Can't unlock wall sign
#227 Hopper and piston protection swapped
#226 Chest unlocked but shown as locked
#224 Locked shulker boxes break without dropping
#221 Chest locked but friends can open
#215 Chests cannot be placed on public
#214 Making doors public only half the door
#185 Hopper protection below chest not working

Bugs open upstream, fixed in fork

Issue Title Fork Fix
#306 Plugin causes server lag ProtectedBlockCache with Caffeine O(1) early-exit
#324 Allow breaking protected blocks allow_break_protected_blocks config key
#349 Warn spam in console (NBT swap error) StatHandler rewrite with temp-write-validate-replace
#344 Console spam (NbtApiException) Same NBT swap warning as #349, covered by the same StatHandler rewrite

Features open upstream, implemented in fork

Issue Title Fork Implementation
#298 Integration support for ClaimChunk ClaimChunkIntegration, see "ClaimChunk integration" above
#295 Lock trapdoors and iron doors Trapdoors are members of the TRAPDOOR sub-family under lockable_blocks; all *_DOOR materials, including IRON_DOOR, are members of the DOORS family under lockable_doors
#318 Ability to configure lockable blocks per world per_worlds_config in config.yml plus worlds.yml, see "Per-world lockable GUI" above
#303 Respect spawn protection radius respect_spawn_protection in config.yml (default true); non-op, non-admin players cannot lock a block inside the server's spawn-protection radius
#282 MySQL Support HybridDatabase, a Hikari-pooled MySQL/MariaDB index configured in mysql/mysql.yml. NBT stays the source of truth for ownership and friends; the database mirrors block locations and global trust lists for auditing and search on large servers
#334 Colored prompt messages Fully supported via both MiniMessage and legacy color codes in Translator
#192 Support Inspect contents block name i18n Inspect contents inventory titles are now localized
#346 New configuration option Added clear_protection_on_shulker_break config
#322 Toggle for simplified hopper logic Added simplified_hopper_logic config
#269 Shows the owner of the box Implemented via Action Bar on interact
#267 Expire locks after owner offline for x time Implemented via world expiry subsystem
#228 Separate Redstone in config Implemented via redstone_disallowed_by_default
#225 Stats more Features Covered by the StatisticListInventory GUI
#183 Support Residence ResidenceIntegration added
#154 Support for GriefPrevention GriefPreventionIntegration added

Reporting an Issue

If you reached this point in the document, thank you for reading. When reporting a bug, please include the following information so the issue can be diagnosed and fixed faster:

Field What to include
Discord (optional) Your Discord username so I can follow up directly
Error description Exactly what the error says and step-by-step how to reproduce it
Multimedia Screenshots or videos showing the issue
Server info Server version, software (Paper / Purpur / Spigot), and a list of other plugins installed
Error log The full error log (use a paste site like https://pastes.dev if it is long)
1.3.2Релиз26.1, 26.1.1, 26.1.2 · 4 июня 2026 г.

Added the option to remove ALL protections from a world individually

1.3.1Релиз1.21.11, 26.1.1, 26.1.2 · 31 мая 2026 г.

Release from 1.3.0-SNAPSHOT-2 New: /bp unlock GUI

The old coordinate-based /bp unlock [world] command has been replaced with a full paginated GUI. Running /bp unlock opens a six-row inventory listing every block currently protected by the target player, using the real block icon for each entry. Left-click any block to inspect its inventory contents in read-only mode — no items can be taken or placed. Right-click any block to remove its protection entirely; an action-bar message confirms the block name, the owner it was removed from, and the coordinates. Supports pagination and works for offline players. Requires blockprot.user.admin. New: Duration Parser

Timed access and protection expiry now share a single DurationParser that accepts human-readable duration strings with combined units. Accepted suffixes: s (seconds), m (minutes), h (hours), d (days), mo / mon (months), y (years). Units can be freely combined: 1d12h30m, 2mo3d, 1y6mo. All max-per-unit limits are enforced and configurable. Previously the timed-access parser was a separate inline implementation with no support for combined units. Fix: Inventory title and item name color injection

All GUI menu titles and item display names are now rendered as plain text, letting Minecraft apply its default white color. Previously LegacyComponentSerializer was used to set display names, which caused section-sign color codes embedded in translation strings or hardcoded prefixes to produce colored text — most visibly the §4Admin §f prefix on the /bp unlock inventory title shown in the screenshot below. Every inventory class has been updated: BlockProtInventory now strips §x and &x codes before passing any string to Component.text(). Lore lines and chat/action-bar messages are unaffected and still support legacy color codes from translation files. Fix: InventoryConstants.singleLine duplicate removed

singleLine was a duplicate constant of lineLength (both equal to 9). All seven call sites across BlockInfoInventory, FriendDetailInventory, FriendManageInventory, and UserSettingsInventory have been migrated to lineLength and the duplicate constant removed. Fix: Unused PlayerTextures import removed from BlockProtInventory Fix: Dead actionIcon() method removed from AuditInventory The method was only used to prepend colored §cX / §aO / §e- / §2+ symbols to audit entry display names. With the color injection fix, display names are now plain text and the symbol-based prefix was replaced by the already-existing actionLabel() string. The dead method has been removed. Fix: Inline color codes removed from TimedAccessInventory, AuditInventory, and AdminMenuInventory

Hardcoded §a / §c / §e / §7 / §8 / §f / §6 prefixes were removed from item labels, audit entry display names, lore lines, and the integrations action-bar output. Text that had no meaningful color intent is now plain; text in lore that was intentionally styled continues to use the legacy serializer from the translation file. Documentation: Command and permission audit

A full cross-reference of all command source files against plugin.yml and the README was performed. Corrections applied: /bp timed is documented as a chat-input flow rather than a tab-completable CLI subcommand (it was never registered in BlockProtCommand's CLI map); /bp friends bare invocation was undocumented and has been added; /bp reload, /bp update, and /bp integrations require op, not blockprot.user.admin — corrected in the README; /bp about and /bp help are CLI-only and are hidden in GUI mode — the incorrect "Universal Commands" section has been removed; the permissions table now distinguishes between permissions declared in plugin.yml (with defaults) and runtime-only nodes (blockprot.debug, blockprot.lockmax, blockprot.locklimit.*) that must be granted manually. Documentation: README User Menu table corrected

The User Menu slot table now reflects the actual UserMenuInventory layout: four items at slots 11–14 (Settings, Friends, Statistics, About). The previous table listed six items across slots 10–16 including Transfer and Timed Access hints that are not present in the current implementation.

1.3.0-SNAPSHOT-2Бета26.1, 26.1.1, 26.1.2 · 21 мая 2026 г.

Here is the release notes for Snapshot 2. The changes were mentioned in the last version. Snapshot 3 is expected sometime this week, but it might be delayed because I have exams to get into high school, so please be patient. I appreciate your support, and if you find any bugs, please report them in this repository. Have a nice evening.

1.3.0-SNAPSHOT-1Бета26.1, 26.1.1, 26.1.2 · 21 мая 2026 г.

Snapshot Release Notes | Development Cycle Consolidation and Core Refactoring

This major snapshot release marks the official deployment and architectural consolidation of development builds Dev 3, Dev 4, and Dev 5 into a single synchronized build.

Versioning Methodology and Release Pipeline

To establish a more rigorous and predictable development cycle, the project infrastructure is transitioning to an automated version tracking pipeline. Moving forward, version sequences will follow a strict milestone rule: upon the compilation and completion of the fifth iterative development build (Dev 5), the release system will automatically transition and generate a new major snapshot release branch.

[!IMPORTANT] Example Progression: Version 1.2.9-dev-5 will automatically trigger the generation of the subsequent major release, 1.3.0-SNAPSHOT-1. This structural framework has been introduced to significantly improve long-term version management, dependency tracking, and update deployment predictability. This specific versioning pipeline is currently provisional and remains subject to modification as the continuous integration requirements evolve.


Technical Performance and Architectural Optimization

  • Console Streamlining and Runtime Efficiency: The core architecture has undergone extensive optimization to enhance processing speeds and overall server stability. A key objective of this refactoring was the drastic reduction of continuous console output logging. By suppressing redundant tracking data and routine informational messages, the build prevents unnecessary disk write overhead, maximizes console readability for administrators, and ensures that critical system errors or alerts are highly visible without log spam.
  • Hierarchical Configuration Documentation: Comprehensive administrative documentation has been embedded directly into the project ecosystem. This asset provides a highly organized structural framework for configuration files. It outlines exactly how properties, values, and localized parameters should be formatted, allowing server operators to maintain organized file directories and deploy custom local alterations with minimal risk of formatting errors.

Security and Protection Infrastructure

  • Pet Protection Subsystem (Disabled by Default): A specialized protection mechanism has been engineered to preserve the safety and security of player-owned pets and tamed entities. When activated, this subsystem completely immunizes protected entities from damage vectors caused by external players, hostile attacks, and unauthorized interactions or physical interventions by non-whitelisted individuals.
  • Isolated MySQL Database Architecture: To maximize database reliability and operational segregation, the data storage layer has been updated. The infrastructure now forces all MySQL directories, storage tables, and configuration outputs to reside within an entirely independent, dedicated sub-folder separate from standard runtime assets.
  • Integrated Protection Feedback Particles: Visual confirmation systems developed and tested during iterations 3 and 4 have been officially compiled into the production build. The engine now triggers real-time particle rendering routines to provide explicit gameplay feedback for security interactions. These custom particle vectors are executed upon successfully locking or unlocking a storage container, enabling local protection filters over active redstone networks, establishing active protection criteria over hoppers, and enforcing security parameters over piston mechanics to prevent illegal block movement.

User Interface and Experience Engineering

  • Action Bar Information Routing: To preserve chat aesthetics and prevent standard text saturation, user query outputs have been completely rerouted. Execution of the friend lookup utility will no longer post raw text blocks or status confirmation strings directly into the global or local player chat log. Instead, the requested user data is sent straight to the client screen via the action bar overlay, ensuring a non-intrusive HUD readout that keeps active gameplay visible.
  • SkinRestorer Integration for Offline-Mode (Cracked) Servers: To enhance player identification thresholds within offline-mode or hybrid network topologies, formal compatibility bridges have been engineered for the SkinRestorer API. The system is now fully capable of pulling, caching, and rendering individual user skin head textures directly inside the plugin's graphical menus and player reference lists. This integration ensures that players operating on cracked servers can instantly recognize and confirm the identity of individuals they add to their trusted access lists via accurate visual cues.

Future Objectives and GUI Migration Roadmap

Development has officially commenced on the upcoming Snapshot 2 build. While the automated bulk-processing macro /bp friends addall has already been fully integrated (successfully addressing the top-voted community request sourced from historical Bukkit discussion comments), the upcoming development phases will follow a specific transitional roadmap from command-line dependencies toward full graphical user interface (GUI) management.

Snapshot 2: Feature Expansion and Command Implementation

The immediate next phase will focus on deploying critical structural features requested by the community alongside essential performance patches. Consequently, Snapshot 2 will introduce a higher volume of manual text commands than traditionally expected. Scheduled implementations include:

  • Authorization and Ownership Transfer Commands (/bp transfer <player>): A secure ownership migration utility allowing a protection builder to permanently delegate full administrative rights over a specific container directly to another verified user identity.
  • Access Control List Replacement Matrix: Addressing GitHub ticket #268, the copy-and-paste utility will abandon entry-appending in favor of an explicit "Replace Mode," entirely flushing pre-existing access lists on target blocks to prevent permission stacking.
  • Temporal and Time-Decaying Access Protocols: An advanced temporal authorization layer allowing users to extend block interaction privileges to auxiliary players that automatically self-terminate after a server-validated timestamp expires.
  • Administrative Verification Utilities (/bp info <player>Code): A comprehensive lookup command granting authorized staff the ability to extract a full location list of all protected coordinates registered to any targeted player profile.

Snapshot 3: Interface Refinement and Visual Migration

To resolve the heavy reliance on manual commands introduced in the previous cycle, Snapshot 3 will be dedicated almost entirely to interface engineering. The objective is to migrate newly added operational commands directly into the visual management GUI. This phase will introduce:

  • Granular Permission Controls via Graphical Interface: Expanding the management menu to support individual permission toggles, allowing users to interactively cycle friend access levels between read-only parameters and full structural write access.
  • Explicit Lock-on-Place State Labels: Deprecating the use of simple enchantment glints as status indicators in favor of definitive, clear textual labels indicating absolute enabled or disabled states within the menu.

Snapshot 4: Complete GUI Standardization

The ultimate milestone for Snapshot 4 is the near-total deprecation of syntax-based execution for standard users. By this release, the objective is to ensure that the vast majority of the plugin's functionalities, configurations, and administrative tools are accessible entirely through intuitive graphical menus, virtually eliminating the need for manual command inputs during standard gameplay.


Development Methodology and Research Documentation

The layout of this development roadmap is dictated by structural user data obtained by monitoring historical platform interactions. To guarantee that future milestones resolve authentic infrastructure demands, an empirical audit was conducted across the following major community nodes:

  • GitHub Repository Infrastructure: Monitored open development logs and high-interaction tickets to isolate mechanical conflicts within file copying utilities, validating the requirement for absolute data-replacement mechanics over standard string appending.
  • SpigotMC Distribution Analytics: Evaluated administrative and end-user review histories regarding menu clarity, establishing a clear technical requirement for replacing implicit texture indications with definitive alphanumeric state labels and transitioning toward interactive GUI-driven permission nodes.
  • Bukkit Community Forum Records: Investigated automation bottlenecks within archival discussion threads, which guided the earlier completion of mass-addition macros and continues to define the trajectory toward full GUI standardization.
  • Network Infrastructure and Economy Case Studies: Evaluated current operational demands within multi-user survival environments. The resulting data demonstrated an immediate necessity for regional block auditing, ownership translation tools, and decay-based permission keys to secure temporary player alliances.

Snapshot 2 will be released within minutes of the release of Snapshot 1, since the optimization changes were minimal. This snapshot (2) will be the version of the plugin with the most commands; this will be addressed in subsequent snapshots.

1.2.9-dev-2Альфа26.1, 26.1.1, 26.1.2 · 19 мая 2026 г.

Added 3. Colored Particle Effects on Lock / Unlock / Settings Toggle

Lock → green dust-particle ring around the block + chest-locked sound. Unlock → red dust-particle ring + sound. Double chests are handled correctly: both halves receive the particle ring simultaneously. Redstone setting toggle → red ↔ white DUST_COLOR_TRANSITION ring + lever click sound. Hopper setting toggle → light-gray ↔ dark-gray transition ring. Piston setting toggle → brown ↔ gray transition ring. All effects respect block_lock_effects: true/false in config.yml (default: true).

  1. Shulker Box — Shift+Right-Click Places Without Protection

Placing a shulker box while sneaking (Shift+right-click) skips the lock-on-place step. The shulker is placed without any owner, so the recipient can open and lock it as their own. Normal placement still auto-locks as configured. Configurable via the existing lock_on_place_by_default flow; no extra config key needed.

  1. Skin Resolution for Cracked / Offline-Mode Servers

SkinCache provides an async Mojang-API fallback for offline servers where UUIDs are name-derived and don't correspond to Mojang profiles:

On first GUI open for a player, a plain (no-texture) head is shown immediately. In the background, BlockProt queries api.mojang.com to resolve the real Mojang UUID from the username, then fetches the skin texture from the session server. On the next GUI open the skinned head is returned from cache. SkinRestorer (if installed) always takes priority over the Mojang fallback. Fetch failures (network errors, rate limits, unknown names) are silently skipped; the plain head continues to be shown without any console errors.

  1. Admin Teleport from Statistics Inventory

In the Statistics → Your Blocks list, players with blockprot.admin permission can click any block entry to teleport directly to that block. The inventory closes after teleporting. Players without the admin permission see no change on click.

  1. Amber Console Colors for BlockProt-Plus Messages

Integration registration and enable messages print in gold/amber via BlockProtConsole. Informational startup messages use §e yellow, success messages use §a green, warnings §c red. Uses Bukkit.getConsoleSender().sendMessage() with legacy color codes — rendered natively by Paper's Log4j2 console renderer on 1.21+ and falls back to plain text on Spigot. Example: §6[BlockProt]§r §6Integration enabled: §eclaimchunk§r

  1. Per-Player Sections in the Access Audit Log

The audit GUI overview now shows one head per unique player with a clear label: §cX §fname (access denied) or §aOK §fname (access granted). Lore shows the last event timestamp, total event count, and world/coordinates. Clicking a player head opens their full personal history (all events in order). The detail view shows individual event timestamps and actions. Navigation arrows are consistent across both views.

Dev 1 is dead kay don´t ask for him, his dead and will never revive, 🥹

1.2.9-SNAPSHOTАльфа26.1, 26.1.1, 26.1.2 · 19 мая 2026 г.

All the information of this SNAPSHOT is in BlockProt - Repo after this release all the changues will be documented on Releases - Github

Комментарии

Загружаем…